github.com/dusk-network/dusk-crypto@v0.1.3/bls/bls_test.go (about) 1 package bls 2 3 import ( 4 "bytes" 5 "crypto/rand" 6 "fmt" 7 "io" 8 "math/big" 9 "reflect" 10 "testing" 11 12 "github.com/dusk-network/bn256" 13 "github.com/stretchr/testify/assert" 14 "github.com/stretchr/testify/require" 15 ) 16 17 func randomMessage() []byte { 18 msg := make([]byte, 32) 19 _, _ = rand.Read(msg) 20 return msg 21 } 22 23 func TestCopyApk(t *testing.T) { 24 require := require.New(t) 25 pub, _, err := GenKeyPair(rand.Reader) 26 require.NoError(err) 27 apk := NewApk(pub) 28 29 cpy := apk.Copy() 30 require.True(reflect.DeepEqual(apk, cpy)) 31 } 32 33 func TestCopySig(t *testing.T) { 34 require := require.New(t) 35 pub, priv, err := GenKeyPair(rand.Reader) 36 require.NoError(err) 37 38 sigma, err := Sign(priv, pub, []byte("ciao!!")) 39 require.NoError(err) 40 41 cpy := sigma.Copy() 42 require.True(reflect.DeepEqual(sigma, cpy)) 43 } 44 45 // TestSignVerify 46 func TestSignVerify(t *testing.T) { 47 msg := randomMessage() 48 pub, priv, err := GenKeyPair(rand.Reader) 49 require.NoError(t, err) 50 51 sig, err := UnsafeSign(priv, msg) 52 require.NoError(t, err) 53 require.NoError(t, VerifyUnsafe(pub, msg, sig)) 54 55 // Testing that changing the message, the signature is no longer valid 56 require.NotNil(t, VerifyUnsafe(pub, randomMessage(), sig)) 57 58 // Testing that using a random PK, the signature cannot be verified 59 pub2, _, err := GenKeyPair(rand.Reader) 60 require.NoError(t, err) 61 require.NotNil(t, VerifyUnsafe(pub2, msg, sig)) 62 } 63 64 // TestCombine checks for the Batched form of the BLS signature 65 func TestCombine(t *testing.T) { 66 reader := rand.Reader 67 msg1 := []byte("Get Funky Tonight") 68 msg2 := []byte("Gonna Get Funky Tonight") 69 70 pub1, priv1, err := GenKeyPair(reader) 71 require.NoError(t, err) 72 73 pub2, priv2, err := GenKeyPair(reader) 74 require.NoError(t, err) 75 76 str1, err := pub1.MarshalText() 77 require.NoError(t, err) 78 79 str2, err := pub2.MarshalText() 80 require.NoError(t, err) 81 82 require.NotEqual(t, str1, str2) 83 84 sig1, err := UnsafeSign(priv1, msg1) 85 require.NoError(t, err) 86 require.NoError(t, VerifyUnsafe(pub1, msg1, sig1)) 87 88 sig2, err := UnsafeSign(priv2, msg2) 89 require.NoError(t, err) 90 require.NoError(t, VerifyUnsafe(pub2, msg2, sig2)) 91 92 sig3 := UnsafeAggregate(sig1, sig2) 93 pkeys := []*PublicKey{pub1, pub2} 94 require.NoError(t, VerifyUnsafeBatch(pkeys, [][]byte{msg1, msg2}, sig3)) 95 } 96 97 func TestHashToPoint(t *testing.T) { 98 msg := []byte("test data") 99 g1, err := h0(msg) 100 assert.Equal(t, nil, err) 101 assert.NotEqual(t, nil, g1) 102 } 103 104 func randomInt(r io.Reader) *big.Int { 105 for { 106 k, _ := rand.Int(r, bn256.Order) 107 if k.Sign() > 0 { 108 return k 109 } 110 } 111 } 112 func TestRogueKey(t *testing.T) { 113 reader := rand.Reader 114 pub, _, err := GenKeyPair(reader) 115 require.NoError(t, err) 116 // α is the pseudo-secret key of the attacker 117 alpha := randomInt(reader) 118 // g₂ᵅ 119 g2Alpha := newG2().ScalarBaseMult(alpha) 120 121 // pk⁻¹ 122 rogueGx := newG2() 123 rogueGx.Neg(pub.gx) 124 125 pRogue := newG2() 126 pRogue.Add(g2Alpha, rogueGx) 127 128 sk, pk := &SecretKey{alpha}, &PublicKey{pRogue} 129 130 msg := []byte("test data") 131 rogueSignature, err := UnsafeSign(sk, msg) 132 require.NoError(t, err) 133 134 require.NoError(t, verifyBatch([]*bn256.G2{pub.gx, pk.gx}, [][]byte{msg, msg}, rogueSignature.e, true)) 135 } 136 137 func TestMarshalPk(t *testing.T) { 138 reader := rand.Reader 139 pub, _, err := GenKeyPair(reader) 140 require.NoError(t, err) 141 142 pkByteRepr := pub.Marshal() 143 144 g2 := newG2() 145 _, _ = g2.Unmarshal(pkByteRepr) 146 147 g2ByteRepr := g2.Marshal() 148 require.Equal(t, pkByteRepr, g2ByteRepr) 149 150 pkInt := new(big.Int).SetBytes(pkByteRepr) 151 g2Int := new(big.Int).SetBytes(g2ByteRepr) 152 require.Equal(t, pkInt, g2Int) 153 154 pk, err := UnmarshalPk(pkByteRepr) 155 require.NoError(t, err) 156 require.Equal(t, pub, pk) 157 } 158 159 func TestApkVerificationSingleKey(t *testing.T) { 160 reader := rand.Reader 161 msg := []byte("Get Funky Tonight") 162 163 pub1, priv1, err := GenKeyPair(reader) 164 require.NoError(t, err) 165 166 apk := NewApk(pub1) 167 168 signature, err := Sign(priv1, pub1, msg) 169 require.NoError(t, err) 170 require.NoError(t, Verify(apk, msg, signature)) 171 172 // testing unmarshalling 173 bApk := apk.Marshal() 174 uApk, err := UnmarshalApk(bApk) 175 assert.NoError(t, err) 176 require.NoError(t, Verify(uApk, msg, signature)) 177 } 178 179 func TestApkVerification(t *testing.T) { 180 reader := rand.Reader 181 msg := []byte("Get Funky Tonight") 182 183 pub1, priv1, err := GenKeyPair(reader) 184 require.NoError(t, err) 185 186 pub2, priv2, err := GenKeyPair(reader) 187 require.NoError(t, err) 188 189 apk := NewApk(pub1) 190 assert.NoError(t, apk.Aggregate(pub2)) 191 192 signature, err := Sign(priv1, pub1, msg) 193 require.NoError(t, err) 194 sig2, err := Sign(priv2, pub2, msg) 195 require.NoError(t, err) 196 197 signature.Aggregate(sig2) 198 require.NoError(t, Verify(apk, msg, signature)) 199 } 200 201 func TestApkBatchVerification(t *testing.T) { 202 reader := rand.Reader 203 msg := []byte("Get Funky Tonight") 204 205 pub1, priv1, err := GenKeyPair(reader) 206 require.NoError(t, err) 207 208 pub2, priv2, err := GenKeyPair(reader) 209 require.NoError(t, err) 210 211 apk := NewApk(pub1) 212 assert.NoError(t, apk.Aggregate(pub2)) 213 214 sigma, err := Sign(priv1, pub1, msg) 215 require.NoError(t, err) 216 sig2_1, err := Sign(priv2, pub2, msg) 217 require.NoError(t, err) 218 sig := sigma.Aggregate(sig2_1) 219 require.NoError(t, Verify(apk, msg, sig)) 220 221 msg2 := []byte("Gonna get Shwifty tonight") 222 pub3, priv3, err := GenKeyPair(reader) 223 require.NoError(t, err) 224 apk2 := NewApk(pub2) 225 require.NoError(t, apk2.Aggregate(pub3)) 226 sig2_2, err := Sign(priv2, pub2, msg2) 227 require.NoError(t, err) 228 sig3_2, err := Sign(priv3, pub3, msg2) 229 require.NoError(t, err) 230 sig2 := sig2_2.Aggregate(sig3_2) 231 require.NoError(t, Verify(apk2, msg2, sig2)) 232 233 sigma.Aggregate(sig2) 234 require.NoError(t, VerifyBatch( 235 []*Apk{apk, apk2}, 236 [][]byte{msg, msg2}, 237 sigma, 238 )) 239 } 240 241 func TestSafeCompress(t *testing.T) { 242 msg := randomMessage() 243 pub, priv, err := GenKeyPair(rand.Reader) 244 require.NoError(t, err) 245 246 sig, err := Sign(priv, pub, msg) 247 require.NoError(t, err) 248 require.NoError(t, Verify(NewApk(pub), msg, sig)) 249 250 sigb := sig.Compress() 251 sigTest := &Signature{e: newG1()} 252 require.NoError(t, sigTest.Decompress(sigb)) 253 254 require.Equal(t, sig.Marshal(), sigTest.Marshal()) 255 } 256 257 func TestUnsafeCompress(t *testing.T) { 258 msg := randomMessage() 259 pub, priv, err := GenKeyPair(rand.Reader) 260 require.NoError(t, err) 261 262 sig, err := UnsafeSign(priv, msg) 263 require.NoError(t, err) 264 require.NoError(t, VerifyUnsafe(pub, msg, sig)) 265 266 sigb := sig.Compress() 267 sigTest := &UnsafeSignature{e: newG1()} 268 require.NoError(t, sigTest.Decompress(sigb)) 269 270 sigM := sig.e.Marshal() 271 require.NotEmpty(t, sigM) 272 require.Equal(t, sigM, sigTest.e.Marshal()) 273 } 274 275 func TestAmbiguousCompress(t *testing.T) { 276 msg := randomMessage() 277 pub, priv, err := GenKeyPair(rand.Reader) 278 require.NoError(t, err) 279 280 sig, err := UnsafeSign(priv, msg) 281 require.NoError(t, err) 282 require.NoError(t, VerifyUnsafe(pub, msg, sig)) 283 284 sigb := sig.Compress() 285 require.Equal(t, len(sigb), 33) 286 287 xy1, xy2, err := bn256.DecompressAmbiguous(sigb) 288 require.NoError(t, err) 289 290 if xy1 == nil && xy2 == nil { 291 fmt.Printf("Original signature: %v\n", new(big.Int).SetBytes(sig.Marshal()).String()) 292 fmt.Printf("Compressed signature: %v\n", new(big.Int).SetBytes(sigb).String()) 293 require.Fail(t, "Orcoddue") 294 } 295 296 sigM := sig.e.Marshal() 297 require.NotEmpty(t, sigM) 298 299 if xy1 != nil { 300 sig1 := &UnsafeSignature{xy1} 301 if bytes.Equal(sigM, sig1.e.Marshal()) { 302 return 303 } 304 } 305 if xy2 != nil { 306 sig2 := &UnsafeSignature{xy2} 307 if bytes.Equal(sigM, sig2.e.Marshal()) { 308 return 309 } 310 } 311 312 require.Fail(t, "Decompression failed both xy1 and xy2 are nil") 313 } 314 315 func BenchmarkSign(b *testing.B) { 316 msg := randomMessage() 317 pk, sk, _ := GenKeyPair(rand.Reader) 318 319 b.ReportAllocs() 320 b.StopTimer() 321 b.ResetTimer() 322 323 for i := 0; i < b.N; i++ { 324 b.StartTimer() 325 _, _ = Sign(sk, pk, msg) 326 b.StopTimer() 327 } 328 } 329 330 func aggregateXSignatures(b *testing.B, nr int) { 331 var sigmas = make([]*Signature, nr) 332 reader := rand.Reader 333 msg := []byte("Get Funky Tonight") 334 335 for i := 0; i < nr; i++ { 336 pk, sk, _ := GenKeyPair(reader) 337 sigmas[i], _ = Sign(sk, pk, msg) 338 } 339 340 s, sigmas := sigmas[0], sigmas[1:] 341 342 b.ReportAllocs() 343 b.ResetTimer() 344 for i := 0; i < b.N; i++ { 345 for _, sig := range sigmas { 346 s = s.Aggregate(sig) 347 } 348 } 349 } 350 351 func BenchmarkAggregate10Signatures(b *testing.B) { 352 aggregateXSignatures(b, 10) 353 } 354 355 func BenchmarkAggregate100Signatures(b *testing.B) { 356 aggregateXSignatures(b, 100) 357 } 358 359 func BenchmarkAggregate1000Signatures(b *testing.B) { 360 aggregateXSignatures(b, 1000) 361 } 362 363 func BenchmarkVerifySingleSignature(b *testing.B) { 364 msg := randomMessage() 365 pk, sk, _ := GenKeyPair(rand.Reader) 366 b.StopTimer() 367 b.ResetTimer() 368 b.ReportAllocs() 369 370 for i := 0; i < b.N; i++ { 371 signature, _ := Sign(sk, pk, msg) 372 373 b.StartTimer() 374 _ = Verify(NewApk(pk), msg, signature) 375 b.StopTimer() 376 } 377 } 378 379 func BenchmarkVerifyUnsafeSingleSignature(b *testing.B) { 380 msg := randomMessage() 381 b.StopTimer() 382 b.ResetTimer() 383 384 for i := 0; i < b.N; i++ { 385 pk, sk, _ := GenKeyPair(rand.Reader) 386 signature, _ := UnsafeSign(sk, msg) 387 388 b.StartTimer() 389 _ = VerifyUnsafe(pk, msg, signature) 390 b.StopTimer() 391 } 392 } 393 394 func BenchmarkVerifySingleCompressedSignature(b *testing.B) { 395 msg := randomMessage() 396 b.StopTimer() 397 b.ResetTimer() 398 399 for i := 0; i < b.N; i++ { 400 pk, sk, _ := GenKeyPair(rand.Reader) 401 signature, _ := Sign(sk, pk, msg) 402 sigb := signature.Compress() 403 apk := NewApk(pk) 404 405 b.StartTimer() 406 signature = &Signature{} 407 _ = signature.Decompress(sigb) 408 _ = Verify(apk, msg, signature) 409 b.StopTimer() 410 } 411 } 412 413 func BenchmarkVerifySingleCompressedUnsafeSignature(b *testing.B) { 414 msg := randomMessage() 415 b.StopTimer() 416 b.ResetTimer() 417 418 for i := 0; i < b.N; i++ { 419 pk, sk, _ := GenKeyPair(rand.Reader) 420 signature, _ := UnsafeSign(sk, msg) 421 sigb := signature.Compress() 422 423 b.StartTimer() 424 signature = &UnsafeSignature{} 425 _ = signature.Decompress(sigb) 426 _ = VerifyUnsafe(pk, msg, signature) 427 b.StopTimer() 428 } 429 }