github.com/MetalBlockchain/metalgo@v1.11.9/utils/crypto/bls/bls_test.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package bls 5 6 import ( 7 "testing" 8 9 "github.com/stretchr/testify/require" 10 11 "github.com/MetalBlockchain/metalgo/utils" 12 ) 13 14 func TestAggregation(t *testing.T) { 15 type test struct { 16 name string 17 setup func(require *require.Assertions) ([]*PublicKey, []*Signature, []byte) 18 expectedSigAggError error 19 expectedPubKeyAggError error 20 expectedValid bool 21 } 22 23 tests := []test{ 24 { 25 name: "valid", 26 setup: func(require *require.Assertions) ([]*PublicKey, []*Signature, []byte) { 27 sk0, err := NewSecretKey() 28 require.NoError(err) 29 sk1, err := NewSecretKey() 30 require.NoError(err) 31 sk2, err := NewSecretKey() 32 require.NoError(err) 33 34 pks := []*PublicKey{ 35 PublicFromSecretKey(sk0), 36 PublicFromSecretKey(sk1), 37 PublicFromSecretKey(sk2), 38 } 39 40 msg := utils.RandomBytes(1234) 41 42 sigs := []*Signature{ 43 Sign(sk0, msg), 44 Sign(sk1, msg), 45 Sign(sk2, msg), 46 } 47 48 return pks, sigs, msg 49 }, 50 expectedValid: true, 51 }, 52 { 53 name: "valid single key", 54 setup: func(require *require.Assertions) ([]*PublicKey, []*Signature, []byte) { 55 sk, err := NewSecretKey() 56 require.NoError(err) 57 58 pks := []*PublicKey{ 59 PublicFromSecretKey(sk), 60 } 61 62 msg := utils.RandomBytes(1234) 63 64 sigs := []*Signature{ 65 Sign(sk, msg), 66 } 67 68 return pks, sigs, msg 69 }, 70 expectedValid: true, 71 }, 72 { 73 name: "wrong message", 74 setup: func(require *require.Assertions) ([]*PublicKey, []*Signature, []byte) { 75 sk0, err := NewSecretKey() 76 require.NoError(err) 77 sk1, err := NewSecretKey() 78 require.NoError(err) 79 sk2, err := NewSecretKey() 80 require.NoError(err) 81 82 pks := []*PublicKey{ 83 PublicFromSecretKey(sk0), 84 PublicFromSecretKey(sk1), 85 PublicFromSecretKey(sk2), 86 } 87 88 msg := utils.RandomBytes(1234) 89 90 sigs := []*Signature{ 91 Sign(sk0, msg), 92 Sign(sk1, msg), 93 Sign(sk2, msg), 94 } 95 96 msg[0]++ 97 98 return pks, sigs, msg 99 }, 100 expectedValid: false, 101 }, 102 { 103 name: "one sig over different message", 104 setup: func(require *require.Assertions) ([]*PublicKey, []*Signature, []byte) { 105 sk0, err := NewSecretKey() 106 require.NoError(err) 107 sk1, err := NewSecretKey() 108 require.NoError(err) 109 sk2, err := NewSecretKey() 110 require.NoError(err) 111 112 pks := []*PublicKey{ 113 PublicFromSecretKey(sk0), 114 PublicFromSecretKey(sk1), 115 PublicFromSecretKey(sk2), 116 } 117 118 msg := utils.RandomBytes(1234) 119 msg2 := utils.RandomBytes(1234) 120 121 sigs := []*Signature{ 122 Sign(sk0, msg), 123 Sign(sk1, msg), 124 Sign(sk2, msg2), 125 } 126 127 return pks, sigs, msg 128 }, 129 expectedValid: false, 130 }, 131 { 132 name: "one incorrect pubkey", 133 setup: func(require *require.Assertions) ([]*PublicKey, []*Signature, []byte) { 134 sk0, err := NewSecretKey() 135 require.NoError(err) 136 sk1, err := NewSecretKey() 137 require.NoError(err) 138 sk2, err := NewSecretKey() 139 require.NoError(err) 140 sk3, err := NewSecretKey() 141 require.NoError(err) 142 143 pks := []*PublicKey{ 144 PublicFromSecretKey(sk0), 145 PublicFromSecretKey(sk1), 146 PublicFromSecretKey(sk3), 147 } 148 149 msg := utils.RandomBytes(1234) 150 151 sigs := []*Signature{ 152 Sign(sk0, msg), 153 Sign(sk1, msg), 154 Sign(sk2, msg), 155 } 156 157 return pks, sigs, msg 158 }, 159 expectedValid: false, 160 }, 161 { 162 name: "num pubkeys > num sigs", 163 setup: func(require *require.Assertions) ([]*PublicKey, []*Signature, []byte) { 164 sk0, err := NewSecretKey() 165 require.NoError(err) 166 sk1, err := NewSecretKey() 167 require.NoError(err) 168 sk2, err := NewSecretKey() 169 require.NoError(err) 170 171 pks := []*PublicKey{ 172 PublicFromSecretKey(sk0), 173 PublicFromSecretKey(sk1), 174 PublicFromSecretKey(sk2), 175 } 176 177 msg := utils.RandomBytes(1234) 178 179 sigs := []*Signature{ 180 Sign(sk0, msg), 181 Sign(sk1, msg), 182 } 183 184 return pks, sigs, msg 185 }, 186 expectedValid: false, 187 }, 188 { 189 name: "num pubkeys < num sigs", 190 setup: func(require *require.Assertions) ([]*PublicKey, []*Signature, []byte) { 191 sk0, err := NewSecretKey() 192 require.NoError(err) 193 sk1, err := NewSecretKey() 194 require.NoError(err) 195 sk2, err := NewSecretKey() 196 require.NoError(err) 197 198 pks := []*PublicKey{ 199 PublicFromSecretKey(sk0), 200 PublicFromSecretKey(sk1), 201 } 202 203 msg := utils.RandomBytes(1234) 204 205 sigs := []*Signature{ 206 Sign(sk0, msg), 207 Sign(sk1, msg), 208 Sign(sk2, msg), 209 } 210 211 return pks, sigs, msg 212 }, 213 expectedValid: false, 214 }, 215 { 216 name: "no pub keys", 217 setup: func(require *require.Assertions) ([]*PublicKey, []*Signature, []byte) { 218 sk0, err := NewSecretKey() 219 require.NoError(err) 220 sk1, err := NewSecretKey() 221 require.NoError(err) 222 sk2, err := NewSecretKey() 223 require.NoError(err) 224 225 msg := utils.RandomBytes(1234) 226 227 sigs := []*Signature{ 228 Sign(sk0, msg), 229 Sign(sk1, msg), 230 Sign(sk2, msg), 231 } 232 233 return nil, sigs, msg 234 }, 235 expectedPubKeyAggError: ErrNoPublicKeys, 236 expectedValid: false, 237 }, 238 { 239 name: "no sigs", 240 setup: func(require *require.Assertions) ([]*PublicKey, []*Signature, []byte) { 241 sk0, err := NewSecretKey() 242 require.NoError(err) 243 sk1, err := NewSecretKey() 244 require.NoError(err) 245 sk2, err := NewSecretKey() 246 require.NoError(err) 247 248 pks := []*PublicKey{ 249 PublicFromSecretKey(sk0), 250 PublicFromSecretKey(sk1), 251 PublicFromSecretKey(sk2), 252 } 253 254 msg := utils.RandomBytes(1234) 255 return pks, nil, msg 256 }, 257 expectedSigAggError: errNoSignatures, 258 expectedValid: false, 259 }, 260 } 261 262 for _, tt := range tests { 263 t.Run(tt.name, func(t *testing.T) { 264 require := require.New(t) 265 266 pks, sigs, msg := tt.setup(require) 267 268 aggSig, err := AggregateSignatures(sigs) 269 require.ErrorIs(err, tt.expectedSigAggError) 270 271 aggPK, err := AggregatePublicKeys(pks) 272 require.ErrorIs(err, tt.expectedPubKeyAggError) 273 274 valid := Verify(aggPK, aggSig, msg) 275 require.Equal(tt.expectedValid, valid) 276 }) 277 } 278 } 279 280 func TestAggregationThreshold(t *testing.T) { 281 require := require.New(t) 282 283 // People in the network would privately generate their secret keys 284 sk0, err := NewSecretKey() 285 require.NoError(err) 286 sk1, err := NewSecretKey() 287 require.NoError(err) 288 sk2, err := NewSecretKey() 289 require.NoError(err) 290 291 // All the public keys would be registered on chain 292 pks := []*PublicKey{ 293 PublicFromSecretKey(sk0), 294 PublicFromSecretKey(sk1), 295 PublicFromSecretKey(sk2), 296 } 297 298 // The transaction's unsigned bytes are publicly known. 299 msg := utils.RandomBytes(1234) 300 301 // People may attempt time sign the transaction. 302 sigs := []*Signature{ 303 Sign(sk0, msg), 304 Sign(sk1, msg), 305 Sign(sk2, msg), 306 } 307 308 // The signed transaction would specify which of the public keys have been 309 // used to sign it. The aggregator should verify each individual signature, 310 // until it has found a sufficient threshold of valid signatures. 311 var ( 312 indices = []int{0, 2} 313 filteredPKs = make([]*PublicKey, len(indices)) 314 filteredSigs = make([]*Signature, len(indices)) 315 ) 316 for i, index := range indices { 317 pk := pks[index] 318 filteredPKs[i] = pk 319 sig := sigs[index] 320 filteredSigs[i] = sig 321 322 valid := Verify(pk, sig, msg) 323 require.True(valid) 324 } 325 326 // Once the aggregator has the required threshold of signatures, it can 327 // aggregate the signatures. 328 aggregatedSig, err := AggregateSignatures(filteredSigs) 329 require.NoError(err) 330 331 // For anyone looking for a proof of the aggregated signature's correctness, 332 // they can aggregate the public keys and verify the aggregated signature. 333 aggregatedPK, err := AggregatePublicKeys(filteredPKs) 334 require.NoError(err) 335 336 valid := Verify(aggregatedPK, aggregatedSig, msg) 337 require.True(valid) 338 } 339 340 func TestVerify(t *testing.T) { 341 type test struct { 342 name string 343 setup func(*require.Assertions) (pk *PublicKey, sig *Signature, msg []byte) 344 expectedValid bool 345 } 346 347 tests := []test{ 348 { 349 name: "valid", 350 setup: func(require *require.Assertions) (*PublicKey, *Signature, []byte) { 351 sk, err := NewSecretKey() 352 require.NoError(err) 353 pk := PublicFromSecretKey(sk) 354 msg := utils.RandomBytes(1234) 355 sig := Sign(sk, msg) 356 return pk, sig, msg 357 }, 358 expectedValid: true, 359 }, 360 { 361 name: "wrong message", 362 setup: func(require *require.Assertions) (*PublicKey, *Signature, []byte) { 363 sk, err := NewSecretKey() 364 require.NoError(err) 365 pk := PublicFromSecretKey(sk) 366 msg := utils.RandomBytes(1234) 367 sig := Sign(sk, msg) 368 msg[0]++ 369 return pk, sig, msg 370 }, 371 expectedValid: false, 372 }, 373 { 374 name: "wrong pub key", 375 setup: func(require *require.Assertions) (*PublicKey, *Signature, []byte) { 376 sk, err := NewSecretKey() 377 require.NoError(err) 378 msg := utils.RandomBytes(1234) 379 sig := Sign(sk, msg) 380 381 sk2, err := NewSecretKey() 382 require.NoError(err) 383 pk := PublicFromSecretKey(sk2) 384 return pk, sig, msg 385 }, 386 expectedValid: false, 387 }, 388 { 389 name: "wrong sig", 390 setup: func(require *require.Assertions) (*PublicKey, *Signature, []byte) { 391 sk, err := NewSecretKey() 392 require.NoError(err) 393 pk := PublicFromSecretKey(sk) 394 msg := utils.RandomBytes(1234) 395 396 msg2 := utils.RandomBytes(1234) 397 sig2 := Sign(sk, msg2) 398 return pk, sig2, msg 399 }, 400 expectedValid: false, 401 }, 402 } 403 404 for _, tt := range tests { 405 t.Run(tt.name, func(t *testing.T) { 406 require := require.New(t) 407 pk, sig, msg := tt.setup(require) 408 valid := Verify(pk, sig, msg) 409 require.Equal(tt.expectedValid, valid) 410 valid = VerifyProofOfPossession(pk, sig, msg) 411 require.False(valid) 412 }) 413 } 414 } 415 416 func TestVerifyProofOfPossession(t *testing.T) { 417 type test struct { 418 name string 419 setup func(*require.Assertions) (pk *PublicKey, sig *Signature, msg []byte) 420 expectedValid bool 421 } 422 423 tests := []test{ 424 { 425 name: "valid", 426 setup: func(require *require.Assertions) (*PublicKey, *Signature, []byte) { 427 sk, err := NewSecretKey() 428 require.NoError(err) 429 pk := PublicFromSecretKey(sk) 430 msg := utils.RandomBytes(1234) 431 sig := SignProofOfPossession(sk, msg) 432 return pk, sig, msg 433 }, 434 expectedValid: true, 435 }, 436 { 437 name: "wrong message", 438 setup: func(require *require.Assertions) (*PublicKey, *Signature, []byte) { 439 sk, err := NewSecretKey() 440 require.NoError(err) 441 pk := PublicFromSecretKey(sk) 442 msg := utils.RandomBytes(1234) 443 sig := SignProofOfPossession(sk, msg) 444 msg[0]++ 445 return pk, sig, msg 446 }, 447 expectedValid: false, 448 }, 449 { 450 name: "wrong pub key", 451 setup: func(require *require.Assertions) (*PublicKey, *Signature, []byte) { 452 sk, err := NewSecretKey() 453 require.NoError(err) 454 msg := utils.RandomBytes(1234) 455 sig := SignProofOfPossession(sk, msg) 456 457 sk2, err := NewSecretKey() 458 require.NoError(err) 459 pk := PublicFromSecretKey(sk2) 460 return pk, sig, msg 461 }, 462 expectedValid: false, 463 }, 464 { 465 name: "wrong sig", 466 setup: func(require *require.Assertions) (*PublicKey, *Signature, []byte) { 467 sk, err := NewSecretKey() 468 require.NoError(err) 469 pk := PublicFromSecretKey(sk) 470 msg := utils.RandomBytes(1234) 471 472 msg2 := utils.RandomBytes(1234) 473 sig2 := SignProofOfPossession(sk, msg2) 474 return pk, sig2, msg 475 }, 476 expectedValid: false, 477 }, 478 } 479 480 for _, tt := range tests { 481 t.Run(tt.name, func(t *testing.T) { 482 require := require.New(t) 483 pk, sig, msg := tt.setup(require) 484 valid := VerifyProofOfPossession(pk, sig, msg) 485 require.Equal(tt.expectedValid, valid) 486 valid = Verify(pk, sig, msg) 487 require.False(valid) 488 }) 489 } 490 }