Add BLS signatures

This commit is contained in:
Mark Spanbroek 2021-06-28 10:10:15 +02:00
parent 6c5113e08a
commit b28954e75c
3 changed files with 29 additions and 0 deletions

View File

@ -5,3 +5,4 @@ license = "MIT"
requires "https://github.com/markspanbroek/nim-blscurve#fix-nimble" requires "https://github.com/markspanbroek/nim-blscurve#fix-nimble"
requires "nimcrypto" requires "nimcrypto"
requires "stew"

View File

@ -4,9 +4,11 @@ import pkg/nimcrypto
type type
PrivateKey* = distinct bls.SecretKey PrivateKey* = distinct bls.SecretKey
PublicKey* = distinct bls.PublicKey PublicKey* = distinct bls.PublicKey
Signature* = distinct bls.Signature
proc `==`*(a, b: PrivateKey): bool {.borrow.} proc `==`*(a, b: PrivateKey): bool {.borrow.}
proc `==`*(a, b: PublicKey): bool {.borrow.} proc `==`*(a, b: PublicKey): bool {.borrow.}
proc `==`*(a, b: Signature): bool {.borrow.}
proc random*(_: type PrivateKey): PrivateKey = proc random*(_: type PrivateKey): PrivateKey =
var seed = newSeq[byte](64) var seed = newSeq[byte](64)
@ -20,3 +22,13 @@ proc erase*(key: var PrivateKey) =
proc toPublicKey*(private: PrivateKey): PublicKey = proc toPublicKey*(private: PrivateKey): PublicKey =
doAssert publicFromSecret(bls.PublicKey(result), bls.SecretKey(private)) 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))

View File

@ -1,4 +1,5 @@
import std/unittest import std/unittest
import pkg/stew/byteutils
import abc/keys import abc/keys
suite "Keys": suite "Keys":
@ -18,3 +19,18 @@ suite "Keys":
check key1.toPublicKey == key1.toPublicKey check key1.toPublicKey == key1.toPublicKey
check key2.toPublicKey == key2.toPublicKey check key2.toPublicKey == key2.toPublicKey
check key1.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)