1
- // Package bls provides BLS signatures instantiated with the BLS12-381 pairing curve.
1
+ // Package bls provides BLS signatures using the BLS12-381 pairing curve.
2
+ //
3
+ // This packages implements the IETF/CFRG draft for BLS signatures [1].
4
+ // Currently only the BASIC mode (one of the three modes specified
5
+ // in the draft) is supported. The pairing function is instantiated
6
+ // with the BLS12-381 curve.
7
+ //
8
+ // # Groups
9
+ //
10
+ // The BLS signature scheme can be instantiated with keys in one of the
11
+ // two groups: G1 or G2, which correspond to the input domain of a pairing
12
+ // function e(G1,G2) -> Gt.
13
+ // Thus, choosing keys in G1 implies that signature values are internally
14
+ // represented in G2; or viceversa. Use the types KeyG1SigG2 or KeyG2SigG1
15
+ // to express this preference.
16
+ //
17
+ // # Serialization
18
+ //
19
+ // The serialization of elements in G1 and G2 follows the recommendation
20
+ // given in [2], in order to be compatible with other implementations of
21
+ // BLS12-381 curve.
22
+ //
23
+ // # References
24
+ //
25
+ // [1] https://datatracker.ietf.org/doc/draft-irtf-cfrg-bls-signature/
26
+ //
27
+ // [2] https://github.com/zkcrypto/bls12_381/blob/0.7.0/src/notes/serialization.rs
2
28
package bls
3
29
4
30
import (
@@ -12,6 +38,19 @@ import (
12
38
"golang.org/x/crypto/hkdf"
13
39
)
14
40
41
+ var (
42
+ ErrInvalid = errors .New ("bls: invalid BLS instance" )
43
+ ErrInvalidKey = errors .New ("bls: invalid key" )
44
+ ErrKeyGen = errors .New ("bls: too many unsuccessful key generation tries" )
45
+ ErrShortIKM = errors .New ("bls: IKM material shorter than 32 bytes" )
46
+ ErrAggregate = errors .New ("bls: error while aggregating signatures" )
47
+ )
48
+
49
+ const (
50
+ dstG1 = "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_"
51
+ dstG2 = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_"
52
+ )
53
+
15
54
type Signature = []byte
16
55
17
56
type (
@@ -44,6 +83,8 @@ type PublicKey[K KeyGroup] struct{ key K }
44
83
45
84
func (k * PrivateKey [K ]) Public () crypto.PublicKey { return k .PublicKey () }
46
85
86
+ // PublicKey computes the corresponding public key. The key is cached
87
+ // for further invocations to this function.
47
88
func (k * PrivateKey [K ]) PublicKey () * PublicKey [K ] {
48
89
if k .pub == nil {
49
90
k .pub = new (PublicKey [K ])
@@ -64,14 +105,30 @@ func (k *PrivateKey[K]) PublicKey() *PublicKey[K] {
64
105
65
106
func (k * PrivateKey [K ]) Equal (x crypto.PrivateKey ) bool {
66
107
xx , ok := x .(* PrivateKey [K ])
108
+ if ! ok {
109
+ return false
110
+ }
111
+
112
+ switch (interface {})(k ).(type ) {
113
+ case * PrivateKey [G1 ], * PrivateKey [G2 ]:
114
+ return k .key .IsEqual (& xx .key ) == 1
115
+ default :
116
+ panic (ErrInvalid )
117
+ }
118
+ }
119
+
120
+ // Validate explicitly determines if a private key is valid.
121
+ func (k * PrivateKey [K ]) Validate () bool {
67
122
switch (interface {})(k ).(type ) {
68
123
case * PrivateKey [G1 ], * PrivateKey [G2 ]:
69
- return ok && k .key .IsEqual ( & xx . key ) == 1
124
+ return k .key .IsZero ( ) == 0
70
125
default :
71
126
panic (ErrInvalid )
72
127
}
73
128
}
74
129
130
+ // MarshalBinary returns a slice with the representation of
131
+ // the underlying PrivateKey scalar (in big-endian order).
75
132
func (k * PrivateKey [K ]) MarshalBinary () ([]byte , error ) {
76
133
switch (interface {})(k ).(type ) {
77
134
case * PrivateKey [G1 ], * PrivateKey [G2 ]:
@@ -84,12 +141,20 @@ func (k *PrivateKey[K]) MarshalBinary() ([]byte, error) {
84
141
func (k * PrivateKey [K ]) UnmarshalBinary (data []byte ) error {
85
142
switch (interface {})(k ).(type ) {
86
143
case * PrivateKey [G1 ], * PrivateKey [G2 ]:
87
- return k .key .UnmarshalBinary (data )
144
+ if err := k .key .UnmarshalBinary (data ); err != nil {
145
+ return err
146
+ }
147
+ if ! k .Validate () {
148
+ return ErrInvalidKey
149
+ }
150
+ k .pub = nil
151
+ return nil
88
152
default :
89
153
panic (ErrInvalid )
90
154
}
91
155
}
92
156
157
+ // Validate explicitly determines if a public key is valid.
93
158
func (k * PublicKey [K ]) Validate () bool {
94
159
switch (interface {})(k ).(type ) {
95
160
case * PublicKey [G1 ]:
@@ -105,20 +170,26 @@ func (k *PublicKey[K]) Validate() bool {
105
170
106
171
func (k * PublicKey [K ]) Equal (x crypto.PublicKey ) bool {
107
172
xx , ok := x .(* PublicKey [K ])
173
+ if ! ok {
174
+ return false
175
+ }
176
+
108
177
switch (interface {})(k ).(type ) {
109
178
case * PublicKey [G1 ]:
110
179
xxx := (interface {})(xx .key ).(G1 )
111
180
kk := (interface {})(k .key ).(G1 )
112
- return ok && kk .g .IsEqual (& xxx .g )
181
+ return kk .g .IsEqual (& xxx .g )
113
182
case * PublicKey [G2 ]:
114
183
xxx := (interface {})(xx .key ).(G2 )
115
184
kk := (interface {})(k .key ).(G2 )
116
- return ok && kk .g .IsEqual (& xxx .g )
185
+ return kk .g .IsEqual (& xxx .g )
117
186
default :
118
187
panic (ErrInvalid )
119
188
}
120
189
}
121
190
191
+ // MarshalBinary returns a slice with the compressed
192
+ // representation of the underlying element in G1 or G2.
122
193
func (k * PublicKey [K ]) MarshalBinary () ([]byte , error ) {
123
194
switch (interface {})(k ).(type ) {
124
195
case * PublicKey [G1 ]:
@@ -145,7 +216,13 @@ func (k *PublicKey[K]) UnmarshalBinary(data []byte) error {
145
216
}
146
217
}
147
218
219
+ // KeyGen derives a private key for the specified group (G1 or G2).
220
+ // The length of ikm material should be at least 32 bytes length.
221
+ // The salt value should be either empty or a uniformly random
222
+ // bytes whose length equals the output length of SHA-256.
148
223
func KeyGen [K KeyGroup ](ikm , salt , keyInfo []byte ) (* PrivateKey [K ], error ) {
224
+ // Implements recommended method at:
225
+ // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-05#name-keygen
149
226
if len (ikm ) < 32 {
150
227
return nil , ErrShortIKM
151
228
}
@@ -179,7 +256,13 @@ func KeyGen[K KeyGroup](ikm, salt, keyInfo []byte) (*PrivateKey[K], error) {
179
256
return nil , ErrKeyGen
180
257
}
181
258
259
+ // Sign computes a signature of a message using a key (defined in
260
+ // G1 or G1).
182
261
func Sign [K KeyGroup ](k * PrivateKey [K ], msg []byte ) Signature {
262
+ if ! k .Validate () {
263
+ panic (ErrInvalidKey )
264
+ }
265
+
183
266
switch (interface {})(k ).(type ) {
184
267
case * PrivateKey [G1 ]:
185
268
var Q GG.G2
@@ -196,6 +279,8 @@ func Sign[K KeyGroup](k *PrivateKey[K], msg []byte) Signature {
196
279
}
197
280
}
198
281
282
+ // Verify returns true if the signature of a message is valid for the
283
+ // corresponding public key.
199
284
func Verify [K KeyGroup ](pub * PublicKey [K ], msg []byte , sig Signature ) bool {
200
285
var (
201
286
a , b interface {
@@ -236,6 +321,9 @@ func Verify[K KeyGroup](pub *PublicKey[K], msg []byte, sig Signature) bool {
236
321
return res .IsIdentity ()
237
322
}
238
323
324
+ // Aggregate produces a unified signature given a list of signatures.
325
+ // To specify the group of keys pass either G1{} or G2{} as the first
326
+ // parameter.
239
327
func Aggregate [K KeyGroup ](k K , sigs []Signature ) (Signature , error ) {
240
328
if len (sigs ) == 0 {
241
329
return nil , ErrAggregate
@@ -269,6 +357,9 @@ func Aggregate[K KeyGroup](k K, sigs []Signature) (Signature, error) {
269
357
}
270
358
}
271
359
360
+ // VerifyAggregate returns true if the aggregated signature is valid for
361
+ // the list of messages and public keys provided. The slices must have
362
+ // equal size and have at least one element.
272
363
func VerifyAggregate [K KeyGroup ](pubs []* PublicKey [K ], msgs [][]byte , aggSig Signature ) bool {
273
364
if len (pubs ) != len (msgs ) || len (pubs ) == 0 || len (msgs ) == 0 {
274
365
return false
@@ -279,6 +370,10 @@ func VerifyAggregate[K KeyGroup](pubs []*PublicKey[K], msgs [][]byte, aggSig Sig
279
370
listG2 := make ([]* GG.G2 , n + 1 )
280
371
listExp := make ([]int , n + 1 )
281
372
373
+ listG1 [n ] = GG .G1Generator ()
374
+ listG2 [n ] = GG .G2Generator ()
375
+ listExp [n ] = - 1
376
+
282
377
switch (interface {})(pubs ).(type ) {
283
378
case []* PublicKey [G1 ]:
284
379
for i := range msgs {
@@ -290,13 +385,10 @@ func VerifyAggregate[K KeyGroup](pubs []*PublicKey[K], msgs [][]byte, aggSig Sig
290
385
listExp [i ] = 1
291
386
}
292
387
293
- listG2 [n ] = new (GG.G2 )
294
388
err := listG2 [n ].SetBytes (aggSig )
295
389
if err != nil {
296
390
return false
297
391
}
298
- listG1 [n ] = GG .G1Generator ()
299
- listExp [n ] = - 1
300
392
301
393
case []* PublicKey [G2 ]:
302
394
for i := range msgs {
@@ -308,13 +400,10 @@ func VerifyAggregate[K KeyGroup](pubs []*PublicKey[K], msgs [][]byte, aggSig Sig
308
400
listExp [i ] = 1
309
401
}
310
402
311
- listG1 [n ] = new (GG.G1 )
312
403
err := listG1 [n ].SetBytes (aggSig )
313
404
if err != nil {
314
405
return false
315
406
}
316
- listG2 [n ] = GG .G2Generator ()
317
- listExp [n ] = - 1
318
407
319
408
default :
320
409
panic (ErrInvalid )
@@ -323,15 +412,3 @@ func VerifyAggregate[K KeyGroup](pubs []*PublicKey[K], msgs [][]byte, aggSig Sig
323
412
C := GG .ProdPairFrac (listG1 , listG2 , listExp )
324
413
return C .IsIdentity ()
325
414
}
326
-
327
- var (
328
- ErrInvalid = errors .New ("bls: invalid BLS instance" )
329
- ErrKeyGen = errors .New ("bls: too many unsuccessful key generation tries" )
330
- ErrShortIKM = errors .New ("bls: IKM material shorter than 32 bytes" )
331
- ErrAggregate = errors .New ("bls: error while aggregating signatures" )
332
- )
333
-
334
- const (
335
- dstG1 = "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_"
336
- dstG2 = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_"
337
- )
0 commit comments