github.com/onflow/flow-go/crypto@v0.24.8/bls_test.go (about)

     1  //go:build relic
     2  // +build relic
     3  
     4  package crypto
     5  
     6  import (
     7  	crand "crypto/rand"
     8  	"encoding/hex"
     9  	"fmt"
    10  	mrand "math/rand"
    11  	"testing"
    12  
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/require"
    15  
    16  	"github.com/onflow/flow-go/crypto/hash"
    17  )
    18  
    19  // TestBLSMainMethods is a sanity check of main signature scheme methods (keyGen, sign, verify)
    20  func TestBLSMainMethods(t *testing.T) {
    21  	// test the key generation seed lengths
    22  	testKeyGenSeed(t, BLSBLS12381, KeyGenSeedMinLen, KeyGenSeedMaxLen)
    23  	// test the consistency with different inputs
    24  	hasher := NewExpandMsgXOFKMAC128("test tag")
    25  	testGenSignVerify(t, BLSBLS12381, hasher)
    26  
    27  	// specific signature test for BLS:
    28  	// Test a signature with a point encoded with a coordinate x not reduced mod p
    29  	// The same signature point with the x coordinate reduced passes verification.
    30  	// This test checks that:
    31  	//  - signature decoding handles input x-coordinates larger than p (doesn't result in an exception)
    32  	//  - signature decoding only accepts reduced x-coordinates to avoid signature malleability
    33  	t.Run("invalid x coordinate larger than p", func(t *testing.T) {
    34  		msg, err := hex.DecodeString("7f26ba692dc2da7ff828ef4675ff1cd6ab855fca0637b6dab295f1df8e51bc8bb1b8f0c6610aabd486cf1f098f2ddbc6691d94e10f928816f890a3d366ce46249836a595c7ea1828af52e899ba2ab627ab667113bb563918c5d5a787c414399487b4e3a7")
    35  		require.NoError(t, err)
    36  		validSig, err := hex.DecodeString("80b0cac2a0f4f8881913edf2b29065675dfed6f6f4e17e9b5d860a845d4e7d476b277d06a493b81482e63d8131f9f2fa")
    37  		require.NoError(t, err)
    38  		invalidSig, err := hex.DecodeString("9AB1DCACDA74DF22642F95A8F5DC123EC276227BE866915AC4B6DD2553FF736B89D37D0555E7B8143CE53D8131F99DA5")
    39  		require.NoError(t, err)
    40  		pkBytes, err := hex.DecodeString("a7ac85ac8ffd9d2611f73721a93ec92115f29d769dfa425fec2e2c26ab3e4e8089a961ab430639104262723e829b75e9190a05d8fc8d22a7ac78a18473cc3df146b5c4c9c8e46d5f208039384fe2fc018321f14c01641c3afff7558a2eb06463")
    41  		require.NoError(t, err)
    42  		pk, err := DecodePublicKey(BLSBLS12381, pkBytes)
    43  		require.NoError(t, err)
    44  		// sanity check of valid signature (P_x < p)
    45  		valid, err := pk.Verify(validSig, msg, hasher)
    46  		require.NoError(t, err)
    47  		require.True(t, valid)
    48  		// invalid signature (P'_x = P_x + p )
    49  		valid, err = pk.Verify(invalidSig, msg, hasher)
    50  		require.NoError(t, err)
    51  		assert.False(t, valid)
    52  	})
    53  
    54  	t.Run("private key equal to 1 and -1", func(t *testing.T) {
    55  		sk1Bytes := make([]byte, PrKeyLenBLSBLS12381)
    56  		sk1Bytes[PrKeyLenBLSBLS12381-1] = 1
    57  		sk1, err := DecodePrivateKey(BLSBLS12381, sk1Bytes)
    58  		require.NoError(t, err)
    59  
    60  		skMinus1Bytes := make([]byte, PrKeyLenBLSBLS12381)
    61  		copy(skMinus1Bytes, BLS12381Order)
    62  		skMinus1Bytes[PrKeyLenBLSBLS12381-1] -= 1
    63  		skMinus1, err := DecodePrivateKey(BLSBLS12381, skMinus1Bytes)
    64  		require.NoError(t, err)
    65  
    66  		for _, sk := range []PrivateKey{sk1, skMinus1} {
    67  			input := make([]byte, 100)
    68  			_, err = crand.Read(input)
    69  			require.NoError(t, err)
    70  			s, err := sk.Sign(input, hasher)
    71  			require.NoError(t, err)
    72  			pk := sk.PublicKey()
    73  
    74  			// test a valid signature
    75  			result, err := pk.Verify(s, input, hasher)
    76  			assert.NoError(t, err)
    77  			assert.True(t, result,
    78  				"Verification should succeed:\n signature:%s\n message:%x\n private key:%s", s, input, sk)
    79  		}
    80  	})
    81  }
    82  
    83  // Signing bench
    84  func BenchmarkBLSBLS12381Sign(b *testing.B) {
    85  	halg := NewExpandMsgXOFKMAC128("bench tag")
    86  	benchSign(b, BLSBLS12381, halg)
    87  }
    88  
    89  // Verifying bench
    90  func BenchmarkBLSBLS12381Verify(b *testing.B) {
    91  	halg := NewExpandMsgXOFKMAC128("bench tag")
    92  	benchVerify(b, BLSBLS12381, halg)
    93  }
    94  
    95  // utility function to generate a random BLS private key
    96  func randomSK(t *testing.T, rand *mrand.Rand) PrivateKey {
    97  	seed := make([]byte, KeyGenSeedMinLen)
    98  	n, err := rand.Read(seed)
    99  	require.Equal(t, n, KeyGenSeedMinLen)
   100  	require.NoError(t, err)
   101  	sk, err := GeneratePrivateKey(BLSBLS12381, seed)
   102  	require.NoError(t, err)
   103  	return sk
   104  }
   105  
   106  // utility function to generate a non BLS private key
   107  func invalidSK(t *testing.T) PrivateKey {
   108  	seed := make([]byte, KeyGenSeedMinLen)
   109  	n, err := crand.Read(seed)
   110  	require.Equal(t, n, KeyGenSeedMinLen)
   111  	require.NoError(t, err)
   112  	sk, err := GeneratePrivateKey(ECDSAP256, seed)
   113  	require.NoError(t, err)
   114  	return sk
   115  }
   116  
   117  // BLS tests
   118  func TestBLSBLS12381Hasher(t *testing.T) {
   119  	rand := getPRG(t)
   120  	// generate a key pair
   121  	sk := randomSK(t, rand)
   122  	sig := make([]byte, SignatureLenBLSBLS12381)
   123  	msg := []byte("message")
   124  
   125  	// empty hasher
   126  	t.Run("Empty hasher", func(t *testing.T) {
   127  		_, err := sk.Sign(msg, nil)
   128  		assert.Error(t, err)
   129  		assert.True(t, IsNilHasherError(err))
   130  		_, err = sk.PublicKey().Verify(sig, msg, nil)
   131  		assert.Error(t, err)
   132  		assert.True(t, IsNilHasherError(err))
   133  	})
   134  
   135  	// short size hasher
   136  	t.Run("short size hasher", func(t *testing.T) {
   137  		s, err := sk.Sign(msg, hash.NewSHA2_256())
   138  		assert.Error(t, err)
   139  		assert.True(t, IsInvalidHasherSizeError(err))
   140  		assert.Nil(t, s)
   141  
   142  		valid, err := sk.PublicKey().Verify(sig, msg, hash.NewSHA2_256())
   143  		assert.Error(t, err)
   144  		assert.True(t, IsInvalidHasherSizeError(err))
   145  		assert.False(t, valid)
   146  	})
   147  
   148  	t.Run("NewExpandMsgXOFKMAC128 sanity check", func(t *testing.T) {
   149  		// test the parameter lengths of NewExpandMsgXOFKMAC128 are in the correct range
   150  		// h would be nil if the kmac inputs are invalid
   151  		h := internalExpandMsgXOFKMAC128(blsSigCipherSuite)
   152  		assert.NotNil(t, h)
   153  	})
   154  
   155  	t.Run("constants sanity check", func(t *testing.T) {
   156  		// test that the ciphersuites exceed 16 bytes as per draft-irtf-cfrg-hash-to-curve
   157  		// The tags used by internalExpandMsgXOFKMAC128 are at least len(ciphersuite) long
   158  		assert.GreaterOrEqual(t, len(blsSigCipherSuite), 16)
   159  		assert.GreaterOrEqual(t, len(blsPOPCipherSuite), 16)
   160  	})
   161  
   162  	t.Run("orthogonal PoP and signature hashing", func(t *testing.T) {
   163  		data := []byte("random_data")
   164  		// empty tag hasher
   165  		sigKmac := NewExpandMsgXOFKMAC128("")
   166  		h1 := sigKmac.ComputeHash(data)
   167  
   168  		// PoP hasher
   169  		h2 := popKMAC.ComputeHash(data)
   170  		assert.NotEqual(t, h1, h2)
   171  	})
   172  
   173  }
   174  
   175  // TestBLSEncodeDecode tests encoding and decoding of BLS keys
   176  func TestBLSEncodeDecode(t *testing.T) {
   177  	// generic tests
   178  	testEncodeDecode(t, BLSBLS12381)
   179  
   180  	// specific tests for BLS
   181  
   182  	//  zero private key
   183  	skBytes := make([]byte, PrKeyLenBLSBLS12381)
   184  	sk, err := DecodePrivateKey(BLSBLS12381, skBytes)
   185  	require.Error(t, err, "decoding identity private key should fail")
   186  	assert.True(t, IsInvalidInputsError(err))
   187  	assert.Nil(t, sk)
   188  
   189  	//  identity public key
   190  	pkBytes := make([]byte, PubKeyLenBLSBLS12381)
   191  	pkBytes[0] = infinityPointHeader
   192  	pk, err := DecodePublicKey(BLSBLS12381, pkBytes)
   193  	require.NoError(t, err, "decoding identity public key should succeed")
   194  	assert.True(t, pk.Equals(IdentityBLSPublicKey()))
   195  
   196  	// invalid point
   197  	pkBytes = make([]byte, PubKeyLenBLSBLS12381)
   198  	pkBytes[0] = invalidBLSSignatureHeader
   199  	pk, err = DecodePublicKey(BLSBLS12381, pkBytes)
   200  	require.Error(t, err, "the key decoding should fail - key value is invalid")
   201  	assert.True(t, IsInvalidInputsError(err))
   202  	assert.Nil(t, pk)
   203  
   204  	// Test a public key serialization with a point encoded with a coordinate x with
   205  	// x[0] or x[1] not reduced mod p.
   206  	// The same public key point with x[0] and x[1] reduced passes decoding.
   207  	// This test checks that:
   208  	//  - public key decoding handles input x-coordinates with x[0] and x[1] larger than p (doesn't result in an exception)
   209  	//  - public key decoding only accepts reduced x[0] and x[1] to insure key serialization uniqueness.
   210  	// Although uniqueness of public key respresentation isn't a security property, some implementations
   211  	// may implicitely rely on the property.
   212  
   213  	// valid pk with x[0] < p and x[1] < p
   214  	validPk, err := hex.DecodeString("818d72183e3e908af5bd6c2e37494c749b88f0396d3fbc2ba4d9ea28f1c50d1c6a540ec8fe06b6d860f72ec9363db3b8038360809700d36d761cb266af6babe9a069dc7364d3502e84536bd893d5f09ec2dd4f07cae1f8a178ffacc450f9b9a2")
   215  	require.NoError(t, err)
   216  	_, err = DecodePublicKey(BLSBLS12381, validPk)
   217  	assert.NoError(t, err)
   218  	// invalidpk1 with x[0]+p and same x[1]
   219  	invalidPk1, err := hex.DecodeString("9B8E840277BE772540D913E47A94F94C00003BBE60C4CEEB0C0ABCC9E876034089000EC7AF5AB6D81AF62EC9363D5E63038360809700d36d761cb266af6babe9a069dc7364d3502e84536bd893d5f09ec2dd4f07cae1f8a178ffacc450f9b9a2")
   220  	require.NoError(t, err)
   221  	_, err = DecodePublicKey(BLSBLS12381, invalidPk1)
   222  	assert.Error(t, err)
   223  	// invalidpk1 with same x[0] and x[1]+p
   224  	invalidPk2, err := hex.DecodeString("818d72183e3e908af5bd6c2e37494c749b88f0396d3fbc2ba4d9ea28f1c50d1c6a540ec8fe06b6d860f72ec9363db3b81D84726AD080BA07C1385A1CF2B758C104E127F8585862EDEB843E798A86E6C2E1894F067C35F8A132FEACC450F9644D")
   225  	require.NoError(t, err)
   226  	_, err = DecodePublicKey(BLSBLS12381, invalidPk2)
   227  	assert.Error(t, err)
   228  }
   229  
   230  // TestBLSEquals tests equal for BLS keys
   231  func TestBLSEquals(t *testing.T) {
   232  	testEquals(t, BLSBLS12381, ECDSAP256)
   233  }
   234  
   235  // TestBLSUtils tests some utility functions
   236  func TestBLSUtils(t *testing.T) {
   237  	rand := getPRG(t)
   238  	// generate a key pair
   239  	sk := randomSK(t, rand)
   240  	// test Algorithm()
   241  	testKeysAlgorithm(t, sk, BLSBLS12381)
   242  	// test Size()
   243  	testKeySize(t, sk, PrKeyLenBLSBLS12381, PubKeyLenBLSBLS12381)
   244  }
   245  
   246  // BLS Proof of Possession test
   247  func TestBLSPOP(t *testing.T) {
   248  	rand := getPRG(t)
   249  	seed := make([]byte, KeyGenSeedMinLen)
   250  	input := make([]byte, 100)
   251  
   252  	t.Run("PoP tests", func(t *testing.T) {
   253  		loops := 10
   254  		for j := 0; j < loops; j++ {
   255  			n, err := rand.Read(seed)
   256  			require.Equal(t, n, KeyGenSeedMinLen)
   257  			require.NoError(t, err)
   258  			sk, err := GeneratePrivateKey(BLSBLS12381, seed)
   259  			require.NoError(t, err)
   260  			_, err = rand.Read(input)
   261  			require.NoError(t, err)
   262  			s, err := BLSGeneratePOP(sk)
   263  			require.NoError(t, err)
   264  			pk := sk.PublicKey()
   265  
   266  			// test a valid PoP
   267  			result, err := BLSVerifyPOP(pk, s)
   268  			require.NoError(t, err)
   269  			assert.True(t, result, "Verification should succeed:\n signature:%s\n private key:%s", s, sk)
   270  
   271  			// test with a valid but different key
   272  			seed[0] ^= 1
   273  			wrongSk, err := GeneratePrivateKey(BLSBLS12381, seed)
   274  			require.NoError(t, err)
   275  			result, err = BLSVerifyPOP(wrongSk.PublicKey(), s)
   276  			require.NoError(t, err)
   277  			assert.False(t, result, "Verification should fail:\n signature:%s\n private key:%s", s, sk)
   278  		}
   279  	})
   280  
   281  	t.Run("invalid inputs", func(t *testing.T) {
   282  		// ecdsa key
   283  		sk := invalidSK(t)
   284  		s, err := BLSGeneratePOP(sk)
   285  		assert.True(t, IsNotBLSKeyError(err))
   286  		assert.Nil(t, s)
   287  
   288  		s = make([]byte, SignatureLenBLSBLS12381)
   289  		result, err := BLSVerifyPOP(sk.PublicKey(), s)
   290  		assert.True(t, IsNotBLSKeyError(err))
   291  		assert.False(t, result)
   292  	})
   293  }
   294  
   295  // BLS multi-signature
   296  // signature aggregation sanity check
   297  //
   298  // Aggregate n signatures of the same message under different keys, and compare
   299  // it against the signature of the message under an aggregated private key.
   300  // Verify the aggregated signature using the multi-signature verification with
   301  // one message.
   302  func TestBLSAggregateSignatures(t *testing.T) {
   303  	rand := getPRG(t)
   304  	// random message
   305  	input := make([]byte, 100)
   306  	_, err := rand.Read(input)
   307  	require.NoError(t, err)
   308  	// hasher
   309  	kmac := NewExpandMsgXOFKMAC128("test tag")
   310  	// number of signatures to aggregate
   311  	sigsNum := mrand.Intn(100) + 1
   312  	sigs := make([]Signature, 0, sigsNum)
   313  	sks := make([]PrivateKey, 0, sigsNum)
   314  	pks := make([]PublicKey, 0, sigsNum)
   315  	var aggSig, expectedSig Signature
   316  
   317  	// create the signatures
   318  	for i := 0; i < sigsNum; i++ {
   319  		sk := randomSK(t, rand)
   320  		s, err := sk.Sign(input, kmac)
   321  		require.NoError(t, err)
   322  		sigs = append(sigs, s)
   323  		sks = append(sks, sk)
   324  		pks = append(pks, sk.PublicKey())
   325  	}
   326  
   327  	// all signatures are valid
   328  	t.Run("all valid signatures", func(t *testing.T) {
   329  		// aggregate private keys
   330  		aggSk, err := AggregateBLSPrivateKeys(sks)
   331  		require.NoError(t, err)
   332  		expectedSig, err := aggSk.Sign(input, kmac)
   333  		require.NoError(t, err)
   334  		// aggregate signatures
   335  		aggSig, err := AggregateBLSSignatures(sigs)
   336  		require.NoError(t, err)
   337  		// First check: check the signatures are equal
   338  		assert.Equal(t, aggSig, expectedSig,
   339  			"incorrect signature %s, should be %s, private keys are %s, input is %x",
   340  			aggSig, expectedSig, sks, input)
   341  		// Second check: Verify the aggregated signature
   342  		valid, err := VerifyBLSSignatureOneMessage(pks, aggSig, input, kmac)
   343  		require.NoError(t, err)
   344  		assert.True(t, valid,
   345  			"Verification of %s failed, signature should be %s private keys are %s, input is %x",
   346  			aggSig, expectedSig, sks, input)
   347  	})
   348  
   349  	// check if one signature is not correct
   350  	t.Run("one invalid signature", func(t *testing.T) {
   351  		input[0] ^= 1
   352  		randomIndex := mrand.Intn(sigsNum)
   353  		sigs[randomIndex], err = sks[randomIndex].Sign(input, kmac)
   354  		input[0] ^= 1
   355  		aggSig, err = AggregateBLSSignatures(sigs)
   356  		require.NoError(t, err)
   357  		assert.NotEqual(t, aggSig, expectedSig,
   358  			"signature %s shouldn't be %s private keys are %s, input is %x",
   359  			aggSig, expectedSig, sks, input)
   360  		valid, err := VerifyBLSSignatureOneMessage(pks, aggSig, input, kmac)
   361  		require.NoError(t, err)
   362  		assert.False(t, valid,
   363  			"verification of signature %s should fail, it shouldn't be %s private keys are %s, input is %x",
   364  			aggSig, expectedSig, sks, input)
   365  		sigs[randomIndex], err = sks[randomIndex].Sign(input, kmac)
   366  		require.NoError(t, err)
   367  	})
   368  
   369  	// check if one the public keys is not correct
   370  	t.Run("one invalid public key", func(t *testing.T) {
   371  		randomIndex := mrand.Intn(sigsNum)
   372  		newSk := randomSK(t, rand)
   373  		sks[randomIndex] = newSk
   374  		pks[randomIndex] = newSk.PublicKey()
   375  		aggSk, err := AggregateBLSPrivateKeys(sks)
   376  		require.NoError(t, err)
   377  		expectedSig, err = aggSk.Sign(input, kmac)
   378  		require.NoError(t, err)
   379  		assert.NotEqual(t, aggSig, expectedSig,
   380  			"signature %s shouldn't be %s, private keys are %s, input is %x, wrong key is of index %d",
   381  			aggSig, expectedSig, sks, input, randomIndex)
   382  		valid, err := VerifyBLSSignatureOneMessage(pks, aggSig, input, kmac)
   383  		require.NoError(t, err)
   384  		assert.False(t, valid,
   385  			"signature %s should fail, shouldn't be %s, private keys are %s, input is %x, wrong key is of index %d",
   386  			aggSig, expectedSig, sks, input, randomIndex)
   387  	})
   388  
   389  	t.Run("invalid inputs", func(t *testing.T) {
   390  		// test aggregating an empty signature list
   391  		aggSig, err = AggregateBLSSignatures(sigs[:0])
   392  		assert.Error(t, err)
   393  		assert.True(t, IsBLSAggregateEmptyListError(err))
   394  		assert.Nil(t, aggSig)
   395  
   396  		// test verification with an empty key list
   397  		result, err := VerifyBLSSignatureOneMessage(pks[:0], aggSig, input, kmac)
   398  		assert.Error(t, err)
   399  		assert.True(t, IsBLSAggregateEmptyListError(err))
   400  		assert.False(t, result)
   401  
   402  		// test with a signature of a wrong length
   403  		shortSig := sigs[0][:signatureLengthBLSBLS12381-1]
   404  		aggSig, err = AggregateBLSSignatures([]Signature{shortSig})
   405  		assert.Error(t, err)
   406  		assert.True(t, IsInvalidSignatureError(err))
   407  		assert.Nil(t, aggSig)
   408  
   409  		// test with an invalid signature of a correct length
   410  		invalidSig := BLSInvalidSignature()
   411  		aggSig, err = AggregateBLSSignatures([]Signature{invalidSig})
   412  		assert.Error(t, err)
   413  		assert.True(t, IsInvalidSignatureError(err))
   414  		assert.Nil(t, aggSig)
   415  
   416  		// test the empty key list
   417  		aggSk, err := AggregateBLSPrivateKeys(sks[:0])
   418  		assert.Error(t, err)
   419  		assert.True(t, IsBLSAggregateEmptyListError(err))
   420  		assert.Nil(t, aggSk)
   421  
   422  		// test with an invalid key type
   423  		sk := invalidSK(t)
   424  		aggSk, err = AggregateBLSPrivateKeys([]PrivateKey{sk})
   425  		assert.Error(t, err)
   426  		assert.True(t, IsNotBLSKeyError(err))
   427  		assert.Nil(t, aggSk)
   428  	})
   429  }
   430  
   431  // BLS multi-signature
   432  // public keys aggregation sanity check
   433  //
   434  // Aggregate n public keys and their respective private keys and compare
   435  // the public key of the aggregated private key is equal to the aggregated
   436  // public key
   437  func TestBLSAggregatePubKeys(t *testing.T) {
   438  	rand := getPRG(t)
   439  	// number of keys to aggregate
   440  	pkNum := mrand.Intn(100) + 1
   441  	pks := make([]PublicKey, 0, pkNum)
   442  	sks := make([]PrivateKey, 0, pkNum)
   443  
   444  	// create the signatures
   445  	for i := 0; i < pkNum; i++ {
   446  		sk := randomSK(t, rand)
   447  		sks = append(sks, sk)
   448  		pks = append(pks, sk.PublicKey())
   449  	}
   450  
   451  	// consistent private and public key aggregation
   452  	t.Run("correctness check", func(t *testing.T) {
   453  		// aggregate private keys
   454  		aggSk, err := AggregateBLSPrivateKeys(sks)
   455  		require.NoError(t, err)
   456  		expectedPk := aggSk.PublicKey()
   457  		// aggregate public keys
   458  		aggPk, err := AggregateBLSPublicKeys(pks)
   459  		assert.NoError(t, err)
   460  		assert.True(t, expectedPk.Equals(aggPk),
   461  			"incorrect public key %s, should be %s, public keys are %s",
   462  			aggPk, expectedPk, pks)
   463  	})
   464  
   465  	// aggregate an empty list
   466  	t.Run("empty list", func(t *testing.T) {
   467  		// private keys
   468  		aggSk, err := AggregateBLSPrivateKeys(sks[:0])
   469  		assert.Error(t, err)
   470  		assert.True(t, IsBLSAggregateEmptyListError(err))
   471  		assert.Nil(t, aggSk)
   472  		// public keys
   473  		aggPk, err := AggregateBLSPublicKeys(pks[:0])
   474  		assert.Error(t, err)
   475  		assert.True(t, IsBLSAggregateEmptyListError(err))
   476  		assert.Nil(t, aggPk)
   477  	})
   478  
   479  	// aggregate a list that includes the identity key,
   480  	// to check that identity key is indeed the identity element with regards to aggregation.
   481  	t.Run("aggregate a list that includes the identity key", func(t *testing.T) {
   482  		// aggregate the identity key with a non identity key
   483  		keys := []PublicKey{pks[0], IdentityBLSPublicKey()}
   484  		aggPkWithIdentity, err := AggregateBLSPublicKeys(keys)
   485  		assert.NoError(t, err)
   486  		assert.True(t, aggPkWithIdentity.Equals(pks[0]),
   487  			"incorrect public key %s, should be %s",
   488  			aggPkWithIdentity, pks[0])
   489  	})
   490  
   491  	t.Run("invalid inputs", func(t *testing.T) {
   492  		// empty list
   493  		aggPK, err := AggregateBLSPublicKeys(pks[:0])
   494  		assert.Error(t, err)
   495  		assert.True(t, IsBLSAggregateEmptyListError(err))
   496  		assert.Nil(t, aggPK)
   497  
   498  		// test with an invalid key type
   499  		pk := invalidSK(t).PublicKey()
   500  		aggPK, err = AggregateBLSPublicKeys([]PublicKey{pk})
   501  		assert.Error(t, err)
   502  		assert.True(t, IsNotBLSKeyError(err))
   503  		assert.Nil(t, aggPK)
   504  	})
   505  
   506  	// check that the public key corresponding to the zero private key is indeed identity
   507  	// The package doesn't allow to generate a zero private key. One way to obtain a zero
   508  	// private key is via aggrgeting opposite private keys
   509  	t.Run("public key of zero private key", func(t *testing.T) {
   510  		// sk1 is group order of bls12-381 minus one
   511  		groupOrderMinus1 := []byte{0x73, 0xED, 0xA7, 0x53, 0x29, 0x9D, 0x7D, 0x48, 0x33, 0x39,
   512  			0xD8, 0x08, 0x09, 0xA1, 0xD8, 0x05, 0x53, 0xBD, 0xA4, 0x02, 0xFF, 0xFE,
   513  			0x5B, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00}
   514  		sk1, err := DecodePrivateKey(BLSBLS12381, groupOrderMinus1)
   515  		require.NoError(t, err)
   516  		// sk2 is 1
   517  		one := make([]byte, PrKeyLenBLSBLS12381)
   518  		one[PrKeyLenBLSBLS12381-1] = 1
   519  		sk2, err := DecodePrivateKey(BLSBLS12381, one)
   520  		require.NoError(t, err)
   521  		aggSK, err := AggregateBLSPrivateKeys([]PrivateKey{sk1, sk2})
   522  		require.NoError(t, err)
   523  		assert.True(t, aggSK.PublicKey().Equals(IdentityBLSPublicKey()))
   524  	})
   525  }
   526  
   527  // BLS multi-signature
   528  // public keys removal sanity check
   529  func TestBLSRemovePubKeys(t *testing.T) {
   530  	rand := getPRG(t)
   531  	// number of keys to aggregate
   532  	pkNum := mrand.Intn(100) + 1
   533  	pks := make([]PublicKey, 0, pkNum)
   534  
   535  	// generate public keys
   536  	for i := 0; i < pkNum; i++ {
   537  		sk := randomSK(t, rand)
   538  		pks = append(pks, sk.PublicKey())
   539  	}
   540  	// aggregate public keys
   541  	aggPk, err := AggregateBLSPublicKeys(pks)
   542  	require.NoError(t, err)
   543  
   544  	// random number of keys to remove (at least one key is left)
   545  	pkToRemoveNum := mrand.Intn(pkNum)
   546  	expectedPatrialPk, err := AggregateBLSPublicKeys(pks[pkToRemoveNum:])
   547  	require.NoError(t, err)
   548  
   549  	// check correctness
   550  	t.Run("equality check", func(t *testing.T) {
   551  		partialPk, err := RemoveBLSPublicKeys(aggPk, pks[:pkToRemoveNum])
   552  		require.NoError(t, err)
   553  
   554  		BLSkey, ok := expectedPatrialPk.(*pubKeyBLSBLS12381)
   555  		require.True(t, ok)
   556  
   557  		assert.True(t, BLSkey.Equals(partialPk),
   558  			"incorrect key %s, should be %s, keys are %s, index is %d",
   559  			partialPk, BLSkey, pks, pkToRemoveNum)
   560  	})
   561  
   562  	// remove an extra key and check inequality
   563  	t.Run("inequality check", func(t *testing.T) {
   564  		extraPk := randomSK(t, rand).PublicKey()
   565  		partialPk, err := RemoveBLSPublicKeys(aggPk, []PublicKey{extraPk})
   566  		assert.NoError(t, err)
   567  
   568  		BLSkey, ok := expectedPatrialPk.(*pubKeyBLSBLS12381)
   569  		require.True(t, ok)
   570  		assert.False(t, BLSkey.Equals(partialPk),
   571  			"incorrect key %s, should not be %s, keys are %s, index is %d, extra key is %s",
   572  			partialPk, BLSkey, pks, pkToRemoveNum, extraPk)
   573  	})
   574  
   575  	// specific test to remove all keys
   576  	t.Run("remove all keys", func(t *testing.T) {
   577  		identityPk, err := RemoveBLSPublicKeys(aggPk, pks)
   578  		require.NoError(t, err)
   579  		// identity public key is expected
   580  		randomPk := randomSK(t, rand).PublicKey()
   581  		randomPkPlusIdentityPk, err := AggregateBLSPublicKeys([]PublicKey{randomPk, identityPk})
   582  		require.NoError(t, err)
   583  
   584  		BLSRandomPk, ok := randomPk.(*pubKeyBLSBLS12381)
   585  		require.True(t, ok)
   586  
   587  		assert.True(t, BLSRandomPk.Equals(randomPkPlusIdentityPk),
   588  			"incorrect key %s, should be infinity point, keys are %s",
   589  			identityPk, pks)
   590  	})
   591  
   592  	// specific test with an empty slice of keys to remove
   593  	t.Run("remove empty list", func(t *testing.T) {
   594  		partialPk, err := RemoveBLSPublicKeys(aggPk, []PublicKey{})
   595  		require.NoError(t, err)
   596  
   597  		aggBLSkey, ok := aggPk.(*pubKeyBLSBLS12381)
   598  		require.True(t, ok)
   599  
   600  		assert.True(t, aggBLSkey.Equals(partialPk),
   601  			"incorrect key %s, should be %s",
   602  			partialPk, aggBLSkey)
   603  	})
   604  
   605  	t.Run("invalid inputs", func(t *testing.T) {
   606  		pk := invalidSK(t).PublicKey()
   607  		partialPk, err := RemoveBLSPublicKeys(pk, pks)
   608  		assert.Error(t, err)
   609  		assert.True(t, IsNotBLSKeyError(err))
   610  		assert.Nil(t, partialPk)
   611  
   612  		partialPk, err = RemoveBLSPublicKeys(aggPk, []PublicKey{pk})
   613  		assert.Error(t, err)
   614  		assert.True(t, IsNotBLSKeyError(err))
   615  		assert.Nil(t, partialPk)
   616  	})
   617  }
   618  
   619  // BLS multi-signature
   620  // batch verification
   621  //
   622  // Verify n signatures of the same message under different keys using the fast
   623  // batch verification technique and compares the result to verifying each signature
   624  // separately.
   625  func TestBLSBatchVerify(t *testing.T) {
   626  	rand := getPRG(t)
   627  	// random message
   628  	input := make([]byte, 100)
   629  	_, err := rand.Read(input)
   630  	require.NoError(t, err)
   631  	// hasher
   632  	kmac := NewExpandMsgXOFKMAC128("test tag")
   633  	// number of signatures to aggregate
   634  	sigsNum := rand.Intn(100) + 2
   635  	sigs := make([]Signature, 0, sigsNum)
   636  	sks := make([]PrivateKey, 0, sigsNum)
   637  	pks := make([]PublicKey, 0, sigsNum)
   638  	expectedValid := make([]bool, 0, sigsNum)
   639  
   640  	// create the signatures
   641  	for i := 0; i < sigsNum; i++ {
   642  		sk := randomSK(t, rand)
   643  		s, err := sk.Sign(input, kmac)
   644  		require.NoError(t, err)
   645  		sigs = append(sigs, s)
   646  		sks = append(sks, sk)
   647  		pks = append(pks, sk.PublicKey())
   648  		expectedValid = append(expectedValid, true)
   649  	}
   650  
   651  	// all signatures are valid
   652  	t.Run("all signatures are valid", func(t *testing.T) {
   653  		valid, err := BatchVerifyBLSSignaturesOneMessage(pks, sigs, input, kmac)
   654  		require.NoError(t, err)
   655  		assert.Equal(t, valid, expectedValid,
   656  			"Verification of %s failed, private keys are %s, input is %x, results is %v",
   657  			sigs, sks, input, valid)
   658  	})
   659  
   660  	// one valid signature
   661  	t.Run("one valid signature", func(t *testing.T) {
   662  		valid, err := BatchVerifyBLSSignaturesOneMessage(pks[:1], sigs[:1], input, kmac)
   663  		require.NoError(t, err)
   664  		assert.Equal(t, valid, expectedValid[:1],
   665  			"Verification of %s failed, private keys are %s, input is %x, results is %v",
   666  			sigs, sks, input, valid)
   667  	})
   668  
   669  	// pick a random number of invalid signatures
   670  	invalidSigsNum := rand.Intn(sigsNum-1) + 1
   671  	// generate a random permutation of indices to pick the
   672  	// invalid signatures.
   673  	indices := make([]int, 0, sigsNum)
   674  	for i := 0; i < sigsNum; i++ {
   675  		indices = append(indices, i)
   676  	}
   677  	rand.Shuffle(sigsNum, func(i, j int) {
   678  		indices[i], indices[j] = indices[j], indices[i]
   679  	})
   680  
   681  	// some signatures are invalid
   682  	t.Run("some signatures are invalid", func(t *testing.T) {
   683  
   684  		for i := 0; i < invalidSigsNum; i++ { // alter invalidSigsNum random signatures
   685  			alterSignature(sigs[indices[i]])
   686  			expectedValid[indices[i]] = false
   687  		}
   688  
   689  		valid, err := BatchVerifyBLSSignaturesOneMessage(pks, sigs, input, kmac)
   690  		require.NoError(t, err)
   691  		assert.Equal(t, expectedValid, valid,
   692  			"Verification of %s failed\n private keys are %s\n input is %x\n results is %v",
   693  			sigs, sks, input, valid)
   694  	})
   695  
   696  	// all signatures are invalid
   697  	t.Run("all signatures are invalid", func(t *testing.T) {
   698  		for i := invalidSigsNum; i < sigsNum; i++ { // alter the remaining random signatures
   699  			alterSignature(sigs[indices[i]])
   700  			expectedValid[indices[i]] = false
   701  			if i%5 == 0 {
   702  				sigs[indices[i]] = sigs[indices[i]][:3] // test the short signatures
   703  			}
   704  		}
   705  
   706  		valid, err := BatchVerifyBLSSignaturesOneMessage(pks, sigs, input, kmac)
   707  		require.NoError(t, err)
   708  		assert.Equal(t, valid, expectedValid,
   709  			"Verification of %s failed, private keys are %s, input is %x, results is %v",
   710  			sigs, sks, input, valid)
   711  	})
   712  
   713  	// test the empty list case
   714  	t.Run("empty list", func(t *testing.T) {
   715  		valid, err := BatchVerifyBLSSignaturesOneMessage(pks[:0], sigs[:0], input, kmac)
   716  		require.Error(t, err)
   717  		assert.True(t, IsBLSAggregateEmptyListError(err))
   718  		assert.Equal(t, valid, []bool{},
   719  			"verification should fail with empty list key, got %v", valid)
   720  	})
   721  
   722  	// test incorrect inputs
   723  	t.Run("inconsistent inputs", func(t *testing.T) {
   724  		valid, err := BatchVerifyBLSSignaturesOneMessage(pks[:len(pks)-1], sigs, input, kmac)
   725  		require.Error(t, err)
   726  		assert.True(t, IsInvalidInputsError(err))
   727  		assert.Equal(t, valid, []bool{},
   728  			"verification should fail with incorrect input lenghts, got %v", valid)
   729  	})
   730  
   731  	// test wrong hasher
   732  	t.Run("invalid hasher", func(t *testing.T) {
   733  		for i := 0; i < sigsNum; i++ {
   734  			expectedValid[i] = false
   735  		}
   736  		valid, err := BatchVerifyBLSSignaturesOneMessage(pks, sigs, input, nil)
   737  		require.Error(t, err)
   738  		assert.True(t, IsNilHasherError(err))
   739  
   740  		assert.Equal(t, valid, expectedValid,
   741  			"verification should fail with nil hasher, got %v", valid)
   742  	})
   743  
   744  	// test wrong key
   745  	t.Run("wrong key", func(t *testing.T) {
   746  		for i := 0; i < sigsNum; i++ {
   747  			expectedValid[i] = false
   748  		}
   749  		pks[0] = invalidSK(t).PublicKey()
   750  		valid, err := BatchVerifyBLSSignaturesOneMessage(pks, sigs, input, kmac)
   751  		require.Error(t, err)
   752  		assert.True(t, IsNotBLSKeyError(err))
   753  
   754  		assert.Equal(t, valid, expectedValid,
   755  			"verification should fail with invalid key, got %v", valid)
   756  	})
   757  }
   758  
   759  // alter or fix a signature
   760  func alterSignature(s Signature) {
   761  	// this causes the signature to remain in G1 and be invalid
   762  	// OR to be a non-point in G1 (either on curve or not)
   763  	// which tests multiple error cases.
   764  	s[10] ^= 1
   765  }
   766  
   767  // Batch verify bench in the happy (all signatures are valid)
   768  // and unhappy path (only one signature is invalid)
   769  func BenchmarkBatchVerify(b *testing.B) {
   770  	// random message
   771  	input := make([]byte, 100)
   772  	_, err := crand.Read(input)
   773  	require.NoError(b, err)
   774  	// hasher
   775  	kmac := NewExpandMsgXOFKMAC128("bench tag")
   776  	sigsNum := 100
   777  	sigs := make([]Signature, 0, sigsNum)
   778  	pks := make([]PublicKey, 0, sigsNum)
   779  	seed := make([]byte, KeyGenSeedMinLen)
   780  
   781  	// create the signatures
   782  	for i := 0; i < sigsNum; i++ {
   783  		_, err := crand.Read(seed)
   784  		require.NoError(b, err)
   785  		sk, err := GeneratePrivateKey(BLSBLS12381, seed)
   786  		require.NoError(b, err)
   787  		s, err := sk.Sign(input, kmac)
   788  		require.NoError(b, err)
   789  		sigs = append(sigs, s)
   790  		pks = append(pks, sk.PublicKey())
   791  	}
   792  
   793  	// Batch verify bench when all signatures are valid
   794  	// (2) pairing compared to (2*n) pairings for the batch verification.
   795  	b.Run("happy path", func(b *testing.B) {
   796  		b.ResetTimer()
   797  		for i := 0; i < b.N; i++ {
   798  			// all signatures are valid
   799  			_, err := BatchVerifyBLSSignaturesOneMessage(pks, sigs, input, kmac)
   800  			require.NoError(b, err)
   801  		}
   802  		b.StopTimer()
   803  	})
   804  
   805  	// Batch verify bench when some signatures are invalid
   806  	// - if only one signaure is invalid (a valid point in G1):
   807  	// less than (2*2*log(n)) pairings compared to (2*n) pairings for the simple verification.
   808  	// - if all signatures are invalid (valid points in G1):
   809  	// (2*2*(n-1)) pairings compared to (2*n) pairings for the simple verification.
   810  	b.Run("unhappy path", func(b *testing.B) {
   811  		// only one invalid signature
   812  		alterSignature(sigs[sigsNum/2])
   813  		b.ResetTimer()
   814  		for i := 0; i < b.N; i++ {
   815  			// all signatures are valid
   816  			_, err := BatchVerifyBLSSignaturesOneMessage(pks, sigs, input, kmac)
   817  			require.NoError(b, err)
   818  		}
   819  		b.StopTimer()
   820  	})
   821  }
   822  
   823  // BLS multi-signature
   824  // signature aggregation sanity check
   825  //
   826  // Aggregate n signatures of distinct messages under different keys,
   827  // and verify the aggregated signature using the multi-signature verification with
   828  // many message.
   829  func TestBLSAggregateSignaturesManyMessages(t *testing.T) {
   830  	rand := getPRG(t)
   831  
   832  	// number of signatures to aggregate
   833  	sigsNum := mrand.Intn(20) + 1
   834  	sigs := make([]Signature, 0, sigsNum)
   835  
   836  	// number of keys
   837  	keysNum := mrand.Intn(sigsNum) + 1
   838  	sks := make([]PrivateKey, 0, keysNum)
   839  	// generate the keys
   840  	for i := 0; i < keysNum; i++ {
   841  		sk := randomSK(t, rand)
   842  		sks = append(sks, sk)
   843  	}
   844  
   845  	// number of messages (could be larger or smaller than the number of keys)
   846  	msgsNum := mrand.Intn(sigsNum) + 1
   847  	messages := make([][20]byte, msgsNum)
   848  	for i := 0; i < msgsNum; i++ {
   849  		_, err := rand.Read(messages[i][:])
   850  		require.NoError(t, err)
   851  	}
   852  
   853  	inputMsgs := make([][]byte, 0, sigsNum)
   854  	inputPks := make([]PublicKey, 0, sigsNum)
   855  	inputKmacs := make([]hash.Hasher, 0, sigsNum)
   856  
   857  	// create the signatures
   858  	for i := 0; i < sigsNum; i++ {
   859  		kmac := NewExpandMsgXOFKMAC128("test tag")
   860  		// pick a key randomly from the list
   861  		skRand := mrand.Intn(keysNum)
   862  		sk := sks[skRand]
   863  		// pick a message randomly from the list
   864  		msgRand := mrand.Intn(msgsNum)
   865  		msg := messages[msgRand][:]
   866  		// generate a signature
   867  		s, err := sk.Sign(msg, kmac)
   868  		require.NoError(t, err)
   869  		// update signatures and api inputs
   870  		sigs = append(sigs, s)
   871  		inputPks = append(inputPks, sk.PublicKey())
   872  		inputMsgs = append(inputMsgs, msg)
   873  		inputKmacs = append(inputKmacs, kmac)
   874  	}
   875  	var aggSig Signature
   876  
   877  	t.Run("correctness check", func(t *testing.T) {
   878  		// aggregate signatures
   879  		var err error
   880  		aggSig, err = AggregateBLSSignatures(sigs)
   881  		require.NoError(t, err)
   882  		// Verify the aggregated signature
   883  		valid, err := VerifyBLSSignatureManyMessages(inputPks, aggSig, inputMsgs, inputKmacs)
   884  		require.NoError(t, err)
   885  		assert.True(t, valid,
   886  			"Verification of %s failed, should be valid, private keys are %s, inputs are %x, input public keys are %s",
   887  			aggSig, sks, inputMsgs, inputPks)
   888  	})
   889  
   890  	// check if one of the signatures is not correct
   891  	t.Run("one signature is invalid", func(t *testing.T) {
   892  		randomIndex := mrand.Intn(sigsNum) // pick a random signature
   893  		messages[0][0] ^= 1                // make sure the signature is different
   894  		var err error
   895  		sigs[randomIndex], err = sks[0].Sign(messages[0][:], inputKmacs[0])
   896  		require.NoError(t, err)
   897  		messages[0][0] ^= 1
   898  		aggSig, err = AggregateBLSSignatures(sigs)
   899  		require.NoError(t, err)
   900  		valid, err := VerifyBLSSignatureManyMessages(inputPks, aggSig, inputMsgs, inputKmacs)
   901  		require.NoError(t, err)
   902  		assert.False(t, valid,
   903  			"Verification of %s should fail, private keys are %s, inputs are %x, input public keys are %s",
   904  			aggSig, sks, inputMsgs, inputPks)
   905  	})
   906  
   907  	// test the empty keys case
   908  	t.Run("empty list", func(t *testing.T) {
   909  		valid, err := VerifyBLSSignatureManyMessages(inputPks[:0], aggSig, inputMsgs, inputKmacs)
   910  		assert.Error(t, err)
   911  		assert.True(t, IsBLSAggregateEmptyListError(err))
   912  		assert.False(t, valid,
   913  			"verification should fail with an empty key list")
   914  	})
   915  
   916  	// test inconsistent input arrays
   917  	t.Run("inconsistent inputs", func(t *testing.T) {
   918  		// inconsistent lengths
   919  		valid, err := VerifyBLSSignatureManyMessages(inputPks, aggSig, inputMsgs[:sigsNum-1], inputKmacs)
   920  		assert.Error(t, err)
   921  		assert.True(t, IsInvalidInputsError(err))
   922  		assert.False(t, valid, "verification should fail with inconsistent messages and hashers")
   923  
   924  		// empty key list
   925  		valid, err = VerifyBLSSignatureManyMessages(inputPks[:0], aggSig, inputMsgs, inputKmacs)
   926  		assert.Error(t, err)
   927  		assert.True(t, IsBLSAggregateEmptyListError(err))
   928  		assert.False(t, valid, "verification should fail with empty list key")
   929  
   930  		// nil hasher
   931  		tmp := inputKmacs[0]
   932  		inputKmacs[0] = nil
   933  		valid, err = VerifyBLSSignatureManyMessages(inputPks, aggSig, inputMsgs, inputKmacs)
   934  		assert.Error(t, err)
   935  		assert.True(t, IsNilHasherError(err))
   936  		assert.False(t, valid, "verification should fail with nil hasher")
   937  		inputKmacs[0] = tmp
   938  
   939  		// wrong key
   940  		tmpPK := inputPks[0]
   941  		inputPks[0] = invalidSK(t).PublicKey()
   942  		valid, err = VerifyBLSSignatureManyMessages(inputPks, aggSig, inputMsgs, inputKmacs)
   943  		assert.Error(t, err)
   944  		assert.True(t, IsNotBLSKeyError(err))
   945  		assert.False(t, valid, "verification should fail with nil hasher")
   946  		inputPks[0] = tmpPK
   947  	})
   948  }
   949  
   950  // TestBLSErrorTypes verifies working of error-type-detecting functions
   951  // such as `IsInvalidInputsError`.
   952  func TestBLSErrorTypes(t *testing.T) {
   953  	t.Run("aggregateEmptyListError sanity", func(t *testing.T) {
   954  		err := blsAggregateEmptyListError
   955  		invInpError := invalidInputsErrorf("")
   956  		otherError := fmt.Errorf("some error")
   957  		assert.True(t, IsBLSAggregateEmptyListError(err))
   958  		assert.False(t, IsInvalidInputsError(err))
   959  		assert.False(t, IsBLSAggregateEmptyListError(invInpError))
   960  		assert.False(t, IsBLSAggregateEmptyListError(otherError))
   961  		assert.False(t, IsBLSAggregateEmptyListError(nil))
   962  	})
   963  
   964  	t.Run("notBLSKeyError sanity", func(t *testing.T) {
   965  		err := notBLSKeyError
   966  		invInpError := invalidInputsErrorf("")
   967  		otherError := fmt.Errorf("some error")
   968  		assert.True(t, IsNotBLSKeyError(err))
   969  		assert.False(t, IsInvalidInputsError(err))
   970  		assert.False(t, IsNotBLSKeyError(invInpError))
   971  		assert.False(t, IsNotBLSKeyError(otherError))
   972  		assert.False(t, IsNotBLSKeyError(nil))
   973  	})
   974  }
   975  
   976  // VerifyBLSSignatureManyMessages bench
   977  // Bench the slowest case where all messages and public keys are distinct.
   978  // (2*n) pairings without aggrgetion Vs (n+1) pairings with aggregation.
   979  // The function is faster whenever there are redundant messages or public keys.
   980  func BenchmarkVerifySignatureManyMessages(b *testing.B) {
   981  	// inputs
   982  	sigsNum := 100
   983  	inputKmacs := make([]hash.Hasher, 0, sigsNum)
   984  	sigs := make([]Signature, 0, sigsNum)
   985  	pks := make([]PublicKey, 0, sigsNum)
   986  	inputMsgs := make([][]byte, 0, sigsNum)
   987  	kmac := NewExpandMsgXOFKMAC128("bench tag")
   988  	seed := make([]byte, KeyGenSeedMinLen)
   989  
   990  	// create the signatures
   991  	for i := 0; i < sigsNum; i++ {
   992  		input := make([]byte, 100)
   993  		_, err := crand.Read(input)
   994  		require.NoError(b, err)
   995  
   996  		_, err = crand.Read(seed)
   997  		require.NoError(b, err)
   998  		sk, err := GeneratePrivateKey(BLSBLS12381, seed)
   999  		require.NoError(b, err)
  1000  		s, err := sk.Sign(input, kmac)
  1001  		require.NoError(b, err)
  1002  		sigs = append(sigs, s)
  1003  		pks = append(pks, sk.PublicKey())
  1004  		inputKmacs = append(inputKmacs, kmac)
  1005  		inputMsgs = append(inputMsgs, input)
  1006  	}
  1007  	aggSig, err := AggregateBLSSignatures(sigs)
  1008  	require.NoError(b, err)
  1009  	b.ResetTimer()
  1010  	for i := 0; i < b.N; i++ {
  1011  		_, err := VerifyBLSSignatureManyMessages(pks, aggSig, inputMsgs, inputKmacs)
  1012  		require.NoError(b, err)
  1013  	}
  1014  	b.StopTimer()
  1015  }
  1016  
  1017  // Bench of all aggregation functions
  1018  func BenchmarkAggregate(b *testing.B) {
  1019  	seed := make([]byte, KeyGenSeedMinLen)
  1020  	// random message
  1021  	input := make([]byte, 100)
  1022  	_, _ = crand.Read(input)
  1023  	// hasher
  1024  	kmac := NewExpandMsgXOFKMAC128("bench tag")
  1025  	sigsNum := 1000
  1026  	sigs := make([]Signature, 0, sigsNum)
  1027  	sks := make([]PrivateKey, 0, sigsNum)
  1028  	pks := make([]PublicKey, 0, sigsNum)
  1029  
  1030  	// create the signatures
  1031  	for i := 0; i < sigsNum; i++ {
  1032  		_, err := crand.Read(seed)
  1033  		require.NoError(b, err)
  1034  		sk, err := GeneratePrivateKey(BLSBLS12381, seed)
  1035  		require.NoError(b, err)
  1036  		s, err := sk.Sign(input, kmac)
  1037  		if err != nil {
  1038  			b.Fatal()
  1039  		}
  1040  		sigs = append(sigs, s)
  1041  		sks = append(sks, sk)
  1042  		pks = append(pks, sk.PublicKey())
  1043  	}
  1044  
  1045  	// private keys
  1046  	b.Run("PrivateKeys", func(b *testing.B) {
  1047  		b.ResetTimer()
  1048  		for i := 0; i < b.N; i++ {
  1049  			_, err := AggregateBLSPrivateKeys(sks)
  1050  			require.NoError(b, err)
  1051  		}
  1052  		b.StopTimer()
  1053  	})
  1054  
  1055  	// public keys
  1056  	b.Run("PublicKeys", func(b *testing.B) {
  1057  		b.ResetTimer()
  1058  		for i := 0; i < b.N; i++ {
  1059  			_, err := AggregateBLSPublicKeys(pks)
  1060  			require.NoError(b, err)
  1061  		}
  1062  		b.StopTimer()
  1063  	})
  1064  
  1065  	// signatures
  1066  	b.Run("Signatures", func(b *testing.B) {
  1067  		b.ResetTimer()
  1068  		for i := 0; i < b.N; i++ {
  1069  			_, err := AggregateBLSSignatures(sigs)
  1070  			require.NoError(b, err)
  1071  		}
  1072  		b.StopTimer()
  1073  	})
  1074  }
  1075  
  1076  func TestBLSIdentity(t *testing.T) {
  1077  	rand := getPRG(t)
  1078  
  1079  	var identitySig []byte
  1080  	msg := []byte("random_message")
  1081  	hasher := NewExpandMsgXOFKMAC128("")
  1082  
  1083  	t.Run("identity signature comparison", func(t *testing.T) {
  1084  		// verify that constructed identity signatures are recognized as such by IsBLSSignatureIdentity.
  1085  		// construct identity signature by summing (aggregating) a random signature and its inverse.
  1086  
  1087  		assert.True(t, IsBLSSignatureIdentity(identityBLSSignature))
  1088  
  1089  		// sum up a random signature and its inverse to get identity
  1090  		sk := randomSK(t, rand)
  1091  		sig, err := sk.Sign(msg, hasher)
  1092  		require.NoError(t, err)
  1093  		oppositeSig := make([]byte, signatureLengthBLSBLS12381)
  1094  		copy(oppositeSig, sig)
  1095  		oppositeSig[0] ^= 0x20 // flip the last 3rd bit to flip the point sign
  1096  		aggSig, err := AggregateBLSSignatures([]Signature{sig, oppositeSig})
  1097  		require.NoError(t, err)
  1098  		assert.True(t, IsBLSSignatureIdentity(aggSig))
  1099  	})
  1100  
  1101  	t.Run("verification with identity key", func(t *testing.T) {
  1102  		// all verification methods should return (false, nil) when verified against
  1103  		// an identity public key.
  1104  		idPk := IdentityBLSPublicKey()
  1105  		valid, err := idPk.Verify(identitySig, msg, hasher)
  1106  		assert.NoError(t, err)
  1107  		assert.False(t, valid)
  1108  
  1109  		valid, err = VerifyBLSSignatureOneMessage([]PublicKey{idPk}, identitySig, msg, hasher)
  1110  		assert.NoError(t, err)
  1111  		assert.False(t, valid)
  1112  
  1113  		valid, err = VerifyBLSSignatureManyMessages([]PublicKey{idPk}, identitySig, [][]byte{msg}, []hash.Hasher{hasher})
  1114  		assert.NoError(t, err)
  1115  		assert.False(t, valid)
  1116  
  1117  		validSlice, err := BatchVerifyBLSSignaturesOneMessage([]PublicKey{idPk}, []Signature{identitySig}, msg, hasher)
  1118  		assert.NoError(t, err)
  1119  		assert.False(t, validSlice[0])
  1120  
  1121  		valid, err = BLSVerifyPOP(idPk, identitySig)
  1122  		assert.NoError(t, err)
  1123  		assert.False(t, valid)
  1124  	})
  1125  }