mirror of
https://github.com/arnaucube/cryptofun.git
synced 2026-02-28 05:16:46 +01:00
bls: doing aggregated signatures
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
Boneh–Lynn–Shacham (BLS) signature scheme implemented in Go.
|
||||
https://en.wikipedia.org/wiki/Boneh%E2%80%93Lynn%E2%80%93Shacham
|
||||
|
||||
This package uses the BN128 Go implementation from https://github.com/arnaucube/go-snark/tree/master/bn128
|
||||
This package uses the BN128 Pairing Go implementation from https://github.com/arnaucube/go-snark/tree/master/bn128
|
||||
|
||||
### Usage
|
||||
```go
|
||||
|
||||
64
bls/bls.go
64
bls/bls.go
@@ -3,6 +3,7 @@ package bls
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/arnaucube/go-snark/bn128"
|
||||
@@ -14,27 +15,36 @@ const bits = 2048
|
||||
|
||||
// BLS is the data structure of the BLS signature scheme, including the BN128 pairing curve
|
||||
type BLS struct {
|
||||
Bn bn128.Bn128
|
||||
Bn bn128.Bn128
|
||||
}
|
||||
type BLSKeys struct {
|
||||
PrivK *big.Int
|
||||
PubK [3]*big.Int
|
||||
}
|
||||
|
||||
// NewKeys generate new Private Key and Public Key
|
||||
func NewKeys() (BLS, error) {
|
||||
// NewBLS generates a new BLS scheme
|
||||
func NewBLS() (BLS, error) {
|
||||
bn, err := bn128.NewBn128()
|
||||
if err != nil {
|
||||
return BLS{}, err
|
||||
}
|
||||
bls := BLS{}
|
||||
bls.Bn = bn
|
||||
bls.PrivK, err = rand.Prime(rand.Reader, bits)
|
||||
return bls, nil
|
||||
}
|
||||
|
||||
// NewKeys generate new Private Key and Public Key
|
||||
func (bls BLS) NewKeys() (BLSKeys, error) {
|
||||
var err error
|
||||
k := BLSKeys{}
|
||||
k.PrivK, err = rand.Prime(rand.Reader, bits)
|
||||
if err != nil {
|
||||
return BLS{}, err
|
||||
return BLSKeys{}, err
|
||||
}
|
||||
|
||||
// pubK = pk * G
|
||||
bls.PubK = bls.Bn.G1.MulScalar(bls.Bn.G1.G, bls.PrivK)
|
||||
return bls, nil
|
||||
k.PubK = bls.Bn.G1.MulScalar(bls.Bn.G1.G, k.PrivK)
|
||||
return k, nil
|
||||
}
|
||||
|
||||
// Hash hashes a message m
|
||||
@@ -49,17 +59,17 @@ func (bls BLS) Hash(m []byte) [3][2]*big.Int {
|
||||
}
|
||||
|
||||
// Sign performs the BLS signature of a message m
|
||||
func (bls BLS) Sign(m []byte) [3][2]*big.Int {
|
||||
func (bls BLS) Sign(privK *big.Int, m []byte) [3][2]*big.Int {
|
||||
// s = pk * H(m)
|
||||
h := bls.Hash(m)
|
||||
sig := bls.Bn.G2.MulScalar(h, bls.PrivK)
|
||||
sig := bls.Bn.G2.MulScalar(h, privK)
|
||||
return sig
|
||||
}
|
||||
|
||||
// Verify checks the signature of a message m with the given Public Key
|
||||
func (bls BLS) Verify(m []byte, sig [3][2]*big.Int, pubK [3]*big.Int) bool {
|
||||
// checks e(P, G) == e(G, s)
|
||||
p1, err := bls.Bn.Pairing(bls.PubK, bls.Hash(m))
|
||||
p1, err := bls.Bn.Pairing(pubK, bls.Hash(m))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@@ -70,3 +80,37 @@ func (bls BLS) Verify(m []byte, sig [3][2]*big.Int, pubK [3]*big.Int) bool {
|
||||
|
||||
return bls.Bn.Fq12.Equal(p1, p2)
|
||||
}
|
||||
|
||||
func (bls BLS) AggregateSignatures(signatures ...[3][2]*big.Int) [3][2]*big.Int {
|
||||
aggr := signatures[0]
|
||||
for _, sig := range signatures {
|
||||
aggr = bls.Bn.G2.Add(aggr, sig)
|
||||
}
|
||||
return aggr
|
||||
}
|
||||
func (bls BLS) VerifyAggregatedSignatures(aggrsig [3][2]*big.Int, pubKArray [][3]*big.Int, mArray [][]byte) bool {
|
||||
if len(pubKArray) != len(mArray) {
|
||||
fmt.Println("pubK array and msg array not with the same number of elements")
|
||||
return false
|
||||
}
|
||||
pairingGS, err := bls.Bn.Pairing(bls.Bn.G1.G, aggrsig)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
pairingsMul, err := bls.Bn.Pairing(pubKArray[0], bls.Hash(mArray[0]))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := 1; i < len(pubKArray); i++ {
|
||||
e, err := bls.Bn.Pairing(pubKArray[i], bls.Hash(mArray[i]))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
pairingsMul = bls.Bn.Fq12.Mul(pairingsMul, e)
|
||||
}
|
||||
if !bls.Bn.Fq12.Equal(pairingGS, pairingsMul) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -2,23 +2,46 @@ package bls
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestBls(t *testing.T) {
|
||||
bls, err := NewKeys()
|
||||
bls, err := NewBLS()
|
||||
assert.Nil(t, err)
|
||||
keys0, err := bls.NewKeys()
|
||||
assert.Nil(t, err)
|
||||
|
||||
fmt.Println("privK:", bls.PrivK)
|
||||
fmt.Println("pubK:", bls.PubK)
|
||||
fmt.Println("privK:", keys0.PrivK)
|
||||
fmt.Println("pubK:", keys0.PubK)
|
||||
|
||||
m := []byte("test")
|
||||
sig := bls.Sign(m)
|
||||
fmt.Println("signature:", sig)
|
||||
m0 := []byte("message0")
|
||||
sig0 := bls.Sign(keys0.PrivK, m0)
|
||||
fmt.Println("signature:", sig0)
|
||||
|
||||
verified := bls.Verify(m, sig, bls.PubK)
|
||||
fmt.Println("verified:", verified)
|
||||
verified := bls.Verify(m0, sig0, keys0.PubK)
|
||||
fmt.Println("one signature verified:", verified)
|
||||
assert.True(t, verified)
|
||||
|
||||
// signature aggregation
|
||||
keys1, err := bls.NewKeys()
|
||||
assert.Nil(t, err)
|
||||
m1 := []byte("message1")
|
||||
sig1 := bls.Sign(keys1.PrivK, m1)
|
||||
|
||||
keys2, err := bls.NewKeys()
|
||||
assert.Nil(t, err)
|
||||
m2 := []byte("message2")
|
||||
sig2 := bls.Sign(keys2.PrivK, m2)
|
||||
|
||||
aggr := bls.AggregateSignatures(sig0, sig1, sig2)
|
||||
|
||||
pubKArray := [][3]*big.Int{keys0.PubK, keys1.PubK, keys2.PubK}
|
||||
mArray := [][]byte{m0, m1, m2}
|
||||
verified = bls.VerifyAggregatedSignatures(aggr, pubKArray, mArray)
|
||||
fmt.Println("signature aggregation verified:", verified)
|
||||
assert.True(t, verified)
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user