From b28954e75c20cffa40ddf1b153ffb1b221dc1d82 Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Mon, 28 Jun 2021 10:10:15 +0200 Subject: [PATCH] Add BLS signatures --- abc.nimble | 1 + abc/keys.nim | 12 ++++++++++++ tests/testKeys.nim | 16 ++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/abc.nimble b/abc.nimble index fb12f1c..440bf51 100644 --- a/abc.nimble +++ b/abc.nimble @@ -5,3 +5,4 @@ license = "MIT" requires "https://github.com/markspanbroek/nim-blscurve#fix-nimble" requires "nimcrypto" +requires "stew" diff --git a/abc/keys.nim b/abc/keys.nim index c56d1f7..a4f3f09 100644 --- a/abc/keys.nim +++ b/abc/keys.nim @@ -4,9 +4,11 @@ import pkg/nimcrypto type PrivateKey* = distinct bls.SecretKey PublicKey* = distinct bls.PublicKey + Signature* = distinct bls.Signature proc `==`*(a, b: PrivateKey): bool {.borrow.} proc `==`*(a, b: PublicKey): bool {.borrow.} +proc `==`*(a, b: Signature): bool {.borrow.} proc random*(_: type PrivateKey): PrivateKey = var seed = newSeq[byte](64) @@ -20,3 +22,13 @@ proc erase*(key: var PrivateKey) = proc toPublicKey*(private: PrivateKey): PublicKey = doAssert publicFromSecret(bls.PublicKey(result), bls.SecretKey(private)) +proc sign*(key: PrivateKey, message: openArray[byte]): Signature = + Signature(bls.SecretKey(key).sign(message)) + +proc verify*(key: PublicKey, + message: openArray[byte], + signature: Signature): bool = + ## TODO: not safe w.r.t. rogue public-key attack. Needs implementation of + ## modified BLS multi-signature construction as described in: + ## https://crypto.stanford.edu/~dabo/pubs/papers/BLSmultisig.html + bls.PublicKey(key).verify(message, bls.Signature(signature)) diff --git a/tests/testKeys.nim b/tests/testKeys.nim index 407fd60..51429b0 100644 --- a/tests/testKeys.nim +++ b/tests/testKeys.nim @@ -1,4 +1,5 @@ import std/unittest +import pkg/stew/byteutils import abc/keys suite "Keys": @@ -18,3 +19,18 @@ suite "Keys": check key1.toPublicKey == key1.toPublicKey check key2.toPublicKey == key2.toPublicKey check key1.toPublicKey != key2.toPublicKey + + test "can be used to sign messages": + const message = "hello".toBytes + let key = PrivateKey.random() + let signature = key.sign(message) + check signature != Signature.default + + test "can be used to verify signatures": + let message1 = "hello".toBytes + let message2 = "hallo".toBytes + let private = PrivateKey.random() + let public = private.toPublicKey + let signature = private.sign(message1) + check public.verify(message1, signature) + check not public.verify(message2, signature)