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

     1  //go:build relic
     2  // +build relic
     3  
     4  package crypto
     5  
     6  import (
     7  	crand "crypto/rand"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  func TestSPOCKProveVerifyAgainstData(t *testing.T) {
    15  	// test the consistency with different data
    16  	seed := make([]byte, KeyGenSeedMinLen)
    17  	data := make([]byte, 100)
    18  
    19  	n, err := crand.Read(seed)
    20  	require.Equal(t, n, KeyGenSeedMinLen)
    21  	require.NoError(t, err)
    22  	sk, err := GeneratePrivateKey(BLSBLS12381, seed)
    23  	require.NoError(t, err)
    24  	_, err = crand.Read(data)
    25  	require.NoError(t, err)
    26  
    27  	// generate a SPoCK proof
    28  	kmac := NewExpandMsgXOFKMAC128("spock test")
    29  	s, err := SPOCKProve(sk, data, kmac)
    30  	require.NoError(t, err)
    31  	pk := sk.PublicKey()
    32  
    33  	// SPoCK verify against the data (happy path)
    34  	t.Run("correctness check", func(t *testing.T) {
    35  		result, err := SPOCKVerifyAgainstData(pk, s, data, kmac)
    36  		require.NoError(t, err)
    37  		assert.True(t, result,
    38  			"Verification should succeed:\n signature:%s\n message:%s\n private key:%s", s, data, sk)
    39  	})
    40  
    41  	// test with a different message (unhappy path)
    42  	t.Run("invalid message", func(t *testing.T) {
    43  		data[0] ^= 1
    44  		result, err := SPOCKVerifyAgainstData(pk, s, data, kmac)
    45  		require.NoError(t, err)
    46  		assert.False(t, result,
    47  			"Verification should fail:\n signature:%s\n message:%s\n private key:%s", s, data, sk)
    48  		data[0] ^= 1
    49  	})
    50  
    51  	// test with a valid but different key (unhappy path)
    52  	t.Run("invalid key", func(t *testing.T) {
    53  		seed[0] ^= 1
    54  		wrongSk, err := GeneratePrivateKey(BLSBLS12381, seed)
    55  		require.NoError(t, err)
    56  		result, err := SPOCKVerifyAgainstData(wrongSk.PublicKey(), s, data, kmac)
    57  		require.NoError(t, err)
    58  		assert.False(t, result,
    59  			"Verification should fail:\n signature:%s\n message:%s\n private key:%s", s, data, sk)
    60  	})
    61  
    62  	// test with an invalid key type
    63  	t.Run("invalid key type", func(t *testing.T) {
    64  		wrongSk := invalidSK(t)
    65  		result, err := SPOCKVerifyAgainstData(wrongSk.PublicKey(), s, data, kmac)
    66  		require.Error(t, err)
    67  		assert.True(t, IsNotBLSKeyError(err))
    68  		assert.False(t, result)
    69  	})
    70  
    71  	// test with an identity public key
    72  	t.Run("identity proof", func(t *testing.T) {
    73  		// verifying with a pair of (proof, publicKey) equal to (identity_signature, identity_key) should
    74  		// return false
    75  		identityProof := identityBLSSignature
    76  		result, err := SPOCKVerifyAgainstData(IdentityBLSPublicKey(), identityProof, data, kmac)
    77  		assert.NoError(t, err)
    78  		assert.False(t, result)
    79  	})
    80  }
    81  
    82  // tests of happy and unhappy paths of SPOCKVerify
    83  func TestSPOCKProveVerify(t *testing.T) {
    84  	// test the consistency with different data
    85  	seed1 := make([]byte, KeyGenSeedMinLen)
    86  	seed2 := make([]byte, KeyGenSeedMinLen)
    87  	data := make([]byte, 100)
    88  
    89  	// data
    90  	_, err := crand.Read(data)
    91  	require.NoError(t, err)
    92  	// sk1
    93  	n, err := crand.Read(seed1)
    94  	require.Equal(t, n, KeyGenSeedMinLen)
    95  	require.NoError(t, err)
    96  	sk1, err := GeneratePrivateKey(BLSBLS12381, seed1)
    97  	require.NoError(t, err)
    98  	// sk2
    99  	n, err = crand.Read(seed2)
   100  	require.Equal(t, n, KeyGenSeedMinLen)
   101  	require.NoError(t, err)
   102  	sk2, err := GeneratePrivateKey(BLSBLS12381, seed2)
   103  	require.NoError(t, err)
   104  
   105  	// generate SPoCK proofs
   106  	kmac := NewExpandMsgXOFKMAC128("spock test")
   107  	pr1, err := SPOCKProve(sk1, data, kmac)
   108  	require.NoError(t, err)
   109  	pr2, err := SPOCKProve(sk2, data, kmac)
   110  	require.NoError(t, err)
   111  
   112  	// SPoCK verify against the data, happy path
   113  	t.Run("correctness check", func(t *testing.T) {
   114  		result, err := SPOCKVerify(sk1.PublicKey(), pr1, sk2.PublicKey(), pr2)
   115  		require.NoError(t, err)
   116  		assert.True(t, result,
   117  			"Verification should succeed:\n proofs:%s\n %s\n private keys:%s\n %s\n data:%x",
   118  			pr1, pr2, sk1, sk2, data)
   119  	})
   120  
   121  	// test with a different message, verification should fail for proofs
   122  	// of different messages.
   123  	t.Run("inconsistent proofs", func(t *testing.T) {
   124  		data[0] ^= 1 // alter the data
   125  		pr2bis, err := SPOCKProve(sk2, data, kmac)
   126  		require.NoError(t, err)
   127  		result, err := SPOCKVerify(sk1.PublicKey(), pr1, sk2.PublicKey(), pr2bis)
   128  		require.NoError(t, err)
   129  		assert.False(t, result,
   130  			"Verification should fail:\n proofs:%s\n %s\n private keys:%s\n %s \n data:%x",
   131  			pr1, pr2bis, sk1, sk2, data)
   132  		data[0] ^= 1 // restore the data
   133  	})
   134  
   135  	// test with a different key, verification should fail if the public keys are not
   136  	// matching the private keys used to generate the proofs.
   137  	t.Run("invalid public key", func(t *testing.T) {
   138  		seed2[0] ^= 1 // alter the seed
   139  		sk2bis, err := GeneratePrivateKey(BLSBLS12381, seed2)
   140  		require.NoError(t, err)
   141  		result, err := SPOCKVerify(sk1.PublicKey(), pr1, sk2bis.PublicKey(), pr2)
   142  		require.NoError(t, err)
   143  		assert.False(t, result,
   144  			"Verification should succeed:\n proofs:%s\n %s\n private keys:%s\n %s \n data:%s",
   145  			pr1, pr2, sk1, sk2bis, data)
   146  	})
   147  
   148  	// test with an invalid key type
   149  	t.Run("invalid key type", func(t *testing.T) {
   150  		wrongSk := invalidSK(t)
   151  
   152  		pr, err := SPOCKProve(wrongSk, data, kmac)
   153  		require.Error(t, err)
   154  		assert.True(t, IsNotBLSKeyError(err))
   155  		assert.Nil(t, pr)
   156  
   157  		result, err := SPOCKVerify(wrongSk.PublicKey(), pr1, sk2.PublicKey(), pr2)
   158  		require.Error(t, err)
   159  		assert.True(t, IsNotBLSKeyError(err))
   160  		assert.False(t, result)
   161  
   162  		result, err = SPOCKVerify(sk1.PublicKey(), pr1, wrongSk.PublicKey(), pr2)
   163  		require.Error(t, err)
   164  		assert.True(t, IsNotBLSKeyError(err))
   165  		assert.False(t, result)
   166  	})
   167  
   168  	// test with identity public key and proof
   169  	t.Run("identity proof", func(t *testing.T) {
   170  		// verifying with either pair of (proof, publicKey) equal to (identity_signature, identity_key) should
   171  		// return falsen with any other (proof, key) pair.
   172  		identityProof := identityBLSSignature
   173  		result, err := SPOCKVerify(IdentityBLSPublicKey(), identityProof, sk2.PublicKey(), pr2)
   174  		assert.NoError(t, err)
   175  		assert.False(t, result)
   176  
   177  		result, err = SPOCKVerify(sk1.PublicKey(), pr1, IdentityBLSPublicKey(), identityProof)
   178  		assert.NoError(t, err)
   179  		assert.False(t, result)
   180  
   181  		result, err = SPOCKVerify(IdentityBLSPublicKey(), identityProof, IdentityBLSPublicKey(), identityProof)
   182  		assert.NoError(t, err)
   183  		assert.False(t, result)
   184  	})
   185  }