From d91a89ebeb653dedc2d2dceca4f646e36cb6468e Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Tue, 3 Dec 2024 15:11:39 +0100 Subject: [PATCH] BLS signatures --- codexvalidator.nimble | 1 + codexvalidator/signatures.nim | 31 +++++++++++++++++ tests/codexvalidator/testSignatures.nim | 44 +++++++++++++++++++++++++ tests/tests.nim | 1 + 4 files changed, 77 insertions(+) create mode 100644 codexvalidator/signatures.nim create mode 100644 tests/codexvalidator/testSignatures.nim diff --git a/codexvalidator.nimble b/codexvalidator.nimble index 7ecd3bc..d379e0a 100644 --- a/codexvalidator.nimble +++ b/codexvalidator.nimble @@ -5,3 +5,4 @@ license = "MIT" requires "https://github.com/codex-storage/nim-mysticeti >= 0.1.0 & < 0.2.0" requires "https://github.com/codex-storage/nim-stint-versioned.git >= 1.0.0 & < 2.0.0" +requires "https://github.com/mratsim/constantine#bc3845aa492b52f7fef047503b1592e830d1a774" diff --git a/codexvalidator/signatures.nim b/codexvalidator/signatures.nim new file mode 100644 index 0000000..e480f0c --- /dev/null +++ b/codexvalidator/signatures.nim @@ -0,0 +1,31 @@ +import pkg/constantine/ethereum_bls_signatures +import pkg/constantine/csprngs/sysrand + +export Signature + +type + Identity* = SecretKey + Identifier* = PublicKey + +proc random*(_: type Identity, identity: var Identity) = + var randomness: array[32, byte] + var done = false + while not done: + doAssert sysrand(randomness) + done = deserialize_seckey(identity, randomness) == cttCodecScalar_Success + setZero(randomness) + +func identifier*(identity: Identity): Identifier = + derive_pubkey(result, identity) + +func sign*(identity: Identity, message: openArray[byte]): Signature = + sign(result, identity, message) + +func verify*(signature: Signature, identifier: Identifier, message: openArray[byte]): bool = + verify(identifier, message, signature) == cttEthBls_Success + +func `==`*(a, b: Identifier): bool = + pubkeys_are_equal(a, b) + +func `==`*(a, b: Signature): bool = + signatures_are_equal(a, b) diff --git a/tests/codexvalidator/testSignatures.nim b/tests/codexvalidator/testSignatures.nim new file mode 100644 index 0000000..77f1489 --- /dev/null +++ b/tests/codexvalidator/testSignatures.nim @@ -0,0 +1,44 @@ +import std/unittest +import pkg/constantine/ethereum_bls_signatures +import codexvalidator/signatures +import ./examples + +suite "Signature scheme": + + test "uses BLS private key as validator identity": + check signatures.Identity is ethereum_bls_signatures.SecretKey + + test "uses BLS public key as validator identifier": + check signatures.Identifier is ethereum_bls_signatures.PublicKey + + test "uses BLS signatures": + check signatures.Signature is ethereum_bls_signatures.Signature + + test "can create a new random identity": + var identity1, identity2: Identity + Identity.random(identity1) + Identity.random(identity2) + check identity1.identifier != identity2.identifier + + test "derives identifier (public key) from the identity (private key)": + var identity: Identity + Identity.random(identity) + var publicKey: PublicKey + derive_pubkey(publicKey, identity) + check identity.identifier == publicKey + + test "identity can sign messages": + var identity: Identity + Identity.random(identity) + let message = seq[byte].example + let signature1, signature2 = identity.sign(message) + check signature1 == signature2 + + test "signatures can be verified": + var identity1, identity2: Identity + Identity.random(identity1) + Identity.random(identity2) + let message = seq[byte].example + let signature = identity1.sign(message) + check signature.verify(identity1.identifier, message) + check not signature.verify(identity2.identifier, message) diff --git a/tests/tests.nim b/tests/tests.nim index aeebbae..f64b2dd 100644 --- a/tests/tests.nim +++ b/tests/tests.nim @@ -1,3 +1,4 @@ +import ./codexvalidator/testSignatures import ./codexvalidator/testTransaction {.warning[UnusedImport]:off.}