cryptofun/bls/bls.go
bls/bls.goRaw
1package bls
2
3import (
4 "crypto/rand"
5 "crypto/sha256"
6 "fmt"
7 "math/big"
8
9 "github.com/arnaucube/go-snark/bn128"
10)
11
12// this BLS implementation uses the Go implementation of the BN128 pairing github.com/arnaucube/go-snark/bn128
13
14const bits = 2048
15
16// BLS is the data structure of the BLS signature scheme, including the BN128 pairing curve
17type BLS struct {
18 Bn bn128.Bn128
19}
20type BLSKeys struct {
21 PrivK *big.Int
22 PubK [3]*big.Int
23}
24
25// NewBLS generates a new BLS scheme
26func NewBLS() (BLS, error) {
27 bn, err := bn128.NewBn128()
28 if err != nil {
29 return BLS{}, err
30 }
31 bls := BLS{}
32 bls.Bn = bn
33 return bls, nil
34}
35
36// NewKeys generate new Private Key and Public Key
37func (bls BLS) NewKeys() (BLSKeys, error) {
38 var err error
39 k := BLSKeys{}
40 k.PrivK, err = rand.Prime(rand.Reader, bits)
41 if err != nil {
42 return BLSKeys{}, err
43 }
44
45 // pubK = pk * G
46 k.PubK = bls.Bn.G1.MulScalar(bls.Bn.G1.G, k.PrivK)
47 return k, nil
48}
49
50// Hash hashes a message m
51func (bls BLS) Hash(m []byte) [3][2]*big.Int {
52 h := sha256.New()
53 h.Write(m)
54 hash := h.Sum(nil)
55 r := new(big.Int).SetBytes(hash)
56 // get point over the curve
57 point := bls.Bn.G2.MulScalar(bls.Bn.G2.G, r)
58 return point
59}
60
61// Sign performs the BLS signature of a message m
62func (bls BLS) Sign(privK *big.Int, m []byte) [3][2]*big.Int {
63 // s = pk * H(m)
64 h := bls.Hash(m)
65 sig := bls.Bn.G2.MulScalar(h, privK)
66 return sig
67}
68
69// Verify checks the signature of a message m with the given Public Key
70func (bls BLS) Verify(m []byte, sig [3][2]*big.Int, pubK [3]*big.Int) bool {
71 // checks e(P, G) == e(G, s)
72 p1, err := bls.Bn.Pairing(pubK, bls.Hash(m))
73 if err != nil {
74 return false
75 }
76 p2, err := bls.Bn.Pairing(bls.Bn.G1.G, sig)
77 if err != nil {
78 return false
79 }
80
81 return bls.Bn.Fq12.Equal(p1, p2)
82}
83
84func (bls BLS) AggregateSignatures(signatures ...[3][2]*big.Int) [3][2]*big.Int {
85 aggr := signatures[0]
86 for _, sig := range signatures {
87 aggr = bls.Bn.G2.Add(aggr, sig)
88 }
89 return aggr
90}
91func (bls BLS) VerifyAggregatedSignatures(aggrsig [3][2]*big.Int, pubKArray [][3]*big.Int, mArray [][]byte) bool {
92 if len(pubKArray) != len(mArray) {
93 fmt.Println("pubK array and msg array not with the same number of elements")
94 return false
95 }
96 pairingGS, err := bls.Bn.Pairing(bls.Bn.G1.G, aggrsig)
97 if err != nil {
98 return false
99 }
100 pairingsMul, err := bls.Bn.Pairing(pubKArray[0], bls.Hash(mArray[0]))
101 if err != nil {
102 return false
103 }
104
105 for i := 1; i < len(pubKArray); i++ {
106 e, err := bls.Bn.Pairing(pubKArray[i], bls.Hash(mArray[i]))
107 if err != nil {
108 return false
109 }
110 pairingsMul = bls.Bn.Fq12.Mul(pairingsMul, e)
111 }
112 if !bls.Bn.Fq12.Equal(pairingGS, pairingsMul) {
113 return false
114 }
115 return true
116}