github.com/trustbloc/kms-go@v1.1.2/crypto/tinkcrypto/primitive/bbs/bbs_primitive_factory_test.go (about)

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package bbs
     8  
     9  import (
    10  	"crypto/rand"
    11  	"testing"
    12  
    13  	"github.com/golang/protobuf/proto"
    14  	"github.com/google/tink/go/core/cryptofmt"
    15  	"github.com/google/tink/go/core/primitiveset"
    16  	"github.com/google/tink/go/keyset"
    17  	commonpb "github.com/google/tink/go/proto/common_go_proto"
    18  	tinkpb "github.com/google/tink/go/proto/tink_go_proto"
    19  	"github.com/google/tink/go/signature"
    20  	"github.com/google/tink/go/subtle"
    21  	"github.com/google/tink/go/testkeyset"
    22  	"github.com/google/tink/go/testutil"
    23  	"github.com/google/tink/go/tink"
    24  	"github.com/stretchr/testify/require"
    25  	"github.com/trustbloc/bbs-signature-go/bbs12381g2pub"
    26  
    27  	"github.com/trustbloc/kms-go/crypto/tinkcrypto/primitive/bbs/api"
    28  	bbspb "github.com/trustbloc/kms-go/crypto/tinkcrypto/primitive/proto/bbs_go_proto"
    29  )
    30  
    31  func TestSignerVerifierFactory(t *testing.T) {
    32  	primaryPrivProto := generatePrivateKeyProto(t)
    33  	sPrimaryPriv, e := proto.Marshal(primaryPrivProto)
    34  	require.NoError(t, e)
    35  
    36  	secondPrivProto := generatePrivateKeyProto(t)
    37  	sSecondPriv, e := proto.Marshal(secondPrivProto)
    38  	require.NoError(t, e)
    39  
    40  	tests := []struct {
    41  		name   string
    42  		prefix tinkpb.OutputPrefixType
    43  		keyURL string
    44  	}{
    45  		{
    46  			name:   "run bbs with Tink prefixed keys success",
    47  			prefix: tinkpb.OutputPrefixType_TINK,
    48  			keyURL: bbsSignerKeyTypeURL,
    49  		},
    50  		{
    51  			name:   "run bbs with raw (no prefix) keys success",
    52  			prefix: tinkpb.OutputPrefixType_RAW,
    53  			keyURL: bbsSignerKeyTypeURL,
    54  		},
    55  		{
    56  			name:   "run bbs with Legacy prefixed keys success",
    57  			prefix: tinkpb.OutputPrefixType_LEGACY,
    58  			keyURL: bbsSignerKeyTypeURL,
    59  		},
    60  		{
    61  			name:   "run bbs with Crunchy prefixed keys success",
    62  			prefix: tinkpb.OutputPrefixType_CRUNCHY,
    63  			keyURL: bbsSignerKeyTypeURL,
    64  		},
    65  		{
    66  			name:   "run bbs with Tink prefixed keys and invalid key URL",
    67  			prefix: tinkpb.OutputPrefixType_TINK,
    68  			keyURL: "bad/url",
    69  		},
    70  		{
    71  			name:   "run bbs with RAW prefixed keys and invalid key URL",
    72  			prefix: tinkpb.OutputPrefixType_RAW,
    73  			keyURL: "bad/url",
    74  		},
    75  	}
    76  
    77  	for _, test := range tests {
    78  		tc := test
    79  		t.Run(tc.name, func(t *testing.T) {
    80  			primaryPrivKey := testutil.NewKey(
    81  				testutil.NewKeyData(tc.keyURL, sPrimaryPriv, tinkpb.KeyData_ASYMMETRIC_PRIVATE),
    82  				tinkpb.KeyStatusType_ENABLED, 5, tc.prefix)
    83  
    84  			secondPrivKey := testutil.NewKey(
    85  				testutil.NewKeyData(tc.keyURL, sSecondPriv, tinkpb.KeyData_ASYMMETRIC_PRIVATE),
    86  				tinkpb.KeyStatusType_ENABLED, 9, tc.prefix)
    87  
    88  			privKeys := []*tinkpb.Keyset_Key{primaryPrivKey, secondPrivKey}
    89  			privKeyset := testutil.NewKeyset(privKeys[0].KeyId, privKeys)
    90  			khPriv, err := testkeyset.NewHandle(privKeyset)
    91  			require.NoError(t, err)
    92  
    93  			tmpKeyURL := tc.keyURL
    94  			khPub, err := khPriv.Public()
    95  			if tc.keyURL == bbsSignerKeyTypeURL {
    96  				require.NoError(t, err)
    97  			} else {
    98  				// set valid keyURL temporarily to rebuild public keyset handle and continue tests
    99  				tc.keyURL = bbsSignerKeyTypeURL
   100  
   101  				// build valid public keyset handle to continue tests
   102  				tmpPrimaryPrivKey := testutil.NewKey(
   103  					testutil.NewKeyData(tc.keyURL, sPrimaryPriv, tinkpb.KeyData_ASYMMETRIC_PRIVATE),
   104  					tinkpb.KeyStatusType_ENABLED, 5, tc.prefix)
   105  
   106  				tmpSecondPrivKey := testutil.NewKey(
   107  					testutil.NewKeyData(tc.keyURL, sSecondPriv, tinkpb.KeyData_ASYMMETRIC_PRIVATE),
   108  					tinkpb.KeyStatusType_ENABLED, 9, tc.prefix)
   109  
   110  				tmpPrivKeys := []*tinkpb.Keyset_Key{tmpPrimaryPrivKey, tmpSecondPrivKey}
   111  				tmpPrivKeyset := testutil.NewKeyset(tmpPrivKeys[0].KeyId, tmpPrivKeys)
   112  
   113  				var tmpKHPriv *keyset.Handle
   114  
   115  				tmpKHPriv, err = testkeyset.NewHandle(tmpPrivKeyset)
   116  				require.NoError(t, err)
   117  
   118  				khPub, err = tmpKHPriv.Public()
   119  				require.NoError(t, err)
   120  
   121  				// reset tc.KeyURL
   122  				tc.keyURL = tmpKeyURL
   123  			}
   124  
   125  			t.Run("create signer with public key should fail", func(t *testing.T) {
   126  				_, err = NewSigner(khPub)
   127  				require.EqualError(t, err, "bbs_signer_factory: not a BBS Signer primitive", "using a"+
   128  					"public keyset handle in NewSigner() should fail since the handle must point to a private bbs key")
   129  			})
   130  
   131  			bbsSigner, err := NewSigner(khPriv)
   132  			if tc.keyURL == bbsSignerKeyTypeURL {
   133  				require.NoError(t, err)
   134  			} else {
   135  				// building new signer with private keyset handle that has a bad Tink key url parameter should fail
   136  				require.EqualError(t, err, "bbs_sign_factory: cannot obtain primitive set: "+
   137  					"registry.PrimitivesWithKeyManager: cannot get primitive from key: registry.GetKeyManager: "+
   138  					"unsupported key type: bad/url")
   139  
   140  				// set valid keyURL temporarily to rebuild a valid signer and continue test
   141  				tc.keyURL = bbsSignerKeyTypeURL
   142  
   143  				tmpPrimaryPrivKey := testutil.NewKey(
   144  					testutil.NewKeyData(tc.keyURL, sPrimaryPriv, tinkpb.KeyData_ASYMMETRIC_PRIVATE),
   145  					tinkpb.KeyStatusType_ENABLED, 5, tc.prefix)
   146  
   147  				tmpSecondPrivKey := testutil.NewKey(
   148  					testutil.NewKeyData(tc.keyURL, sSecondPriv, tinkpb.KeyData_ASYMMETRIC_PRIVATE),
   149  					tinkpb.KeyStatusType_ENABLED, 9, tc.prefix)
   150  
   151  				tmpPrivKeys := []*tinkpb.Keyset_Key{tmpPrimaryPrivKey, tmpSecondPrivKey}
   152  				tmpPrivKeyset := testutil.NewKeyset(tmpPrivKeys[0].KeyId, tmpPrivKeys)
   153  
   154  				var tmpKHPriv *keyset.Handle
   155  
   156  				tmpKHPriv, err = testkeyset.NewHandle(tmpPrivKeyset)
   157  				require.NoError(t, err)
   158  
   159  				khPub, err = tmpKHPriv.Public()
   160  				require.NoError(t, err)
   161  
   162  				bbsSigner, err = NewSigner(tmpKHPriv)
   163  				require.NoError(t, err)
   164  
   165  				t.Run("test newWrappedSigner with one key other than primary key is invalid", func(t *testing.T) {
   166  					// now try to directly call newWrappedSigner with a bad primitive set.
   167  					var badPS *primitiveset.PrimitiveSet
   168  
   169  					badPS, err = tmpKHPriv.PrimitivesWithKeyManager(nil)
   170  					require.NoError(t, err)
   171  
   172  					// create an ECDSA tink key
   173  					var serializedECKey []byte
   174  
   175  					serializedECKey, err = proto.Marshal(testutil.NewRandomECDSAPrivateKey(commonpb.HashType_SHA256,
   176  						commonpb.EllipticCurveType_NIST_P256))
   177  					require.NoError(t, err)
   178  
   179  					ecPrivKey := testutil.NewKey(
   180  						testutil.NewKeyData("type.googleapis.com/google.crypto.tink.EcdsaPrivateKey",
   181  							serializedECKey, tinkpb.KeyData_ASYMMETRIC_PRIVATE),
   182  						tinkpb.KeyStatusType_ENABLED, 11, tc.prefix)
   183  
   184  					tmpPrivKeys = []*tinkpb.Keyset_Key{ecPrivKey}
   185  					tmpPrivKeyset = testutil.NewKeyset(tmpPrivKeys[0].KeyId, tmpPrivKeys)
   186  					tmpKHPriv, err = testkeyset.NewHandle(tmpPrivKeyset)
   187  					require.NoError(t, err)
   188  
   189  					var (
   190  						ecPrimitives *primitiveset.PrimitiveSet
   191  						prefix       string
   192  					)
   193  
   194  					ecPrimitives, err = tmpKHPriv.Primitives()
   195  					require.NoError(t, err)
   196  
   197  					prefix, err = cryptofmt.OutputPrefix(ecPrivKey)
   198  					require.NoError(t, err)
   199  
   200  					// copy the ec primitive into badPS to force an error on a bad entry other than the primary one
   201  					badPS.Entries[prefix] = ecPrimitives.Entries[prefix]
   202  
   203  					_, err = newWrappedSigner(badPS)
   204  					require.EqualError(t, err, "bbs_signer_factory: not a BBS Signer primitive")
   205  				})
   206  
   207  				tc.keyURL = tmpKeyURL
   208  			}
   209  
   210  			messagesBytes := [][]byte{
   211  				[]byte("message1 test ABC"),
   212  				[]byte("message2 test DEF"),
   213  				[]byte("message3 test GHI"),
   214  				[]byte("message4 test JKL"),
   215  				[]byte("message5 test MNO"),
   216  			}
   217  
   218  			sig, err := bbsSigner.Sign(messagesBytes)
   219  			if tc.keyURL == bbsSignerKeyTypeURL {
   220  				require.NoError(t, err)
   221  
   222  				if tc.prefix != tinkpb.OutputPrefixType_LEGACY {
   223  					_, err = bbsSigner.Sign([][]byte{})
   224  					require.EqualError(t, err, "messages are not defined")
   225  				}
   226  			} else {
   227  				tc.keyURL = bbsSignerKeyTypeURL
   228  
   229  				// rebuild valid signer to continue tests
   230  				tmpPrimaryPrivKey := testutil.NewKey(
   231  					testutil.NewKeyData(tc.keyURL, sPrimaryPriv, tinkpb.KeyData_ASYMMETRIC_PRIVATE),
   232  					tinkpb.KeyStatusType_ENABLED, 5, tc.prefix)
   233  
   234  				tmpSecondPrivKey := testutil.NewKey(
   235  					testutil.NewKeyData(tc.keyURL, sSecondPriv, tinkpb.KeyData_ASYMMETRIC_PRIVATE),
   236  					tinkpb.KeyStatusType_ENABLED, 9, tc.prefix)
   237  
   238  				tmpPrivKeys := []*tinkpb.Keyset_Key{tmpPrimaryPrivKey, tmpSecondPrivKey}
   239  				tmpPrivKeyset := testutil.NewKeyset(tmpPrivKeys[0].KeyId, tmpPrivKeys)
   240  
   241  				var tmpKHPriv *keyset.Handle
   242  
   243  				tmpKHPriv, err = testkeyset.NewHandle(tmpPrivKeyset)
   244  				require.NoError(t, err)
   245  
   246  				khPub, err = tmpKHPriv.Public()
   247  				require.NoError(t, err)
   248  
   249  				bbsSigner, err = NewSigner(tmpKHPriv)
   250  				require.NoError(t, err)
   251  
   252  				var tmpBBSSigner api.Signer
   253  
   254  				tmpBBSSigner, err = NewSigner(tmpKHPriv)
   255  				require.NoError(t, err)
   256  
   257  				sig, err = bbsSigner.Sign(messagesBytes)
   258  				require.NoError(t, err)
   259  
   260  				var serializedECKey []byte
   261  
   262  				serializedECKey, err = proto.Marshal(testutil.NewRandomECDSAPrivateKey(commonpb.HashType_SHA256,
   263  					commonpb.EllipticCurveType_NIST_P256))
   264  				require.NoError(t, err)
   265  
   266  				ecPrivKey := testutil.NewKey(
   267  					testutil.NewKeyData("type.googleapis.com/google.crypto.tink.EcdsaPrivateKey",
   268  						serializedECKey, tinkpb.KeyData_ASYMMETRIC_PRIVATE),
   269  					tinkpb.KeyStatusType_ENABLED, 5, tc.prefix)
   270  
   271  				tmpPrivKeys = []*tinkpb.Keyset_Key{ecPrivKey}
   272  				tmpPrivKeyset = testutil.NewKeyset(tmpPrivKeys[0].KeyId, tmpPrivKeys)
   273  				tmpKHPriv, err = testkeyset.NewHandle(tmpPrivKeyset)
   274  				require.NoError(t, err)
   275  
   276  				// import Tink signature package to force init() and initialize its key managers.
   277  				var ecSigner tink.Signer
   278  
   279  				ecSigner, err = signature.NewSigner(tmpKHPriv)
   280  				require.NoError(t, err)
   281  
   282  				_, err = ecSigner.Sign([]byte("loremipsum"))
   283  				require.NoError(t, err)
   284  
   285  				// now try to directly call newWrappedSigner with a bad primitive set.
   286  				var badPS *primitiveset.PrimitiveSet
   287  
   288  				badPS, err = tmpKHPriv.PrimitivesWithKeyManager(nil)
   289  				require.NoError(t, err)
   290  
   291  				_, err = newWrappedSigner(badPS)
   292  				require.EqualError(t, err, "bbs_signer_factory: not a BBS Signer primitive")
   293  
   294  				t.Run("execute Sign() with a signer containing bad primary primitive", func(t *testing.T) {
   295  					var (
   296  						ecPrimitives *primitiveset.PrimitiveSet
   297  						prefix       string
   298  					)
   299  
   300  					ecPrimitives, err = tmpKHPriv.Primitives()
   301  					require.NoError(t, err)
   302  
   303  					prefix, err = cryptofmt.OutputPrefix(ecPrivKey)
   304  					require.NoError(t, err)
   305  
   306  					// copy the ec primitive into badPS to force an error on a bad entry other than the primary one
   307  					badPS.Entries[prefix] = ecPrimitives.Entries[prefix]
   308  
   309  					wSigner, ok := tmpBBSSigner.(*wrappedSigner)
   310  					require.True(t, ok)
   311  
   312  					wSigner.ps = badPS
   313  
   314  					_, err = wSigner.Sign(messagesBytes)
   315  					require.EqualError(t, err, "bbs_signer_factory: not a BBS Signer primitive")
   316  				})
   317  
   318  				tc.keyURL = tmpKeyURL
   319  			}
   320  
   321  			bbsVerifier, err := NewVerifier(khPub)
   322  			require.NoError(t, err)
   323  
   324  			if tc.keyURL == bbsSignerKeyTypeURL {
   325  				t.Run("create verifier with private key should fail", func(t *testing.T) {
   326  					_, err = NewVerifier(khPriv)
   327  					require.EqualError(t, err, "bbs_verifier_factory: not a Verifier primitive", "using a"+
   328  						"private keyset handle in NewVerifier should fail since it expects a public bbs key")
   329  				})
   330  			} else {
   331  				t.Run("create bbs verifier with invalid primary public key should fail", func(t *testing.T) {
   332  					var sPubKey []byte
   333  
   334  					pubKeyProto := primaryPrivProto.PublicKey
   335  					sPubKey, err = proto.Marshal(pubKeyProto)
   336  					require.NoError(t, err)
   337  
   338  					// create public key with invalid keyURL
   339  					tmpPrimaryPubKey := testutil.NewKey(
   340  						testutil.NewKeyData(tc.keyURL, sPubKey, tinkpb.KeyData_ASYMMETRIC_PUBLIC),
   341  						tinkpb.KeyStatusType_ENABLED, 5, tc.prefix)
   342  
   343  					tmpPubKeys := []*tinkpb.Keyset_Key{tmpPrimaryPubKey}
   344  					tmpPrivKeyset := testutil.NewKeyset(tmpPubKeys[0].KeyId, tmpPubKeys)
   345  
   346  					var tmpKHPub *keyset.Handle
   347  
   348  					tmpKHPub, err = testkeyset.NewHandle(tmpPrivKeyset)
   349  					require.NoError(t, err)
   350  
   351  					_, err = NewVerifier(tmpKHPub)
   352  					require.EqualError(t, err, "bbs_verifier_factory: cannot obtain primitive set: "+
   353  						"registry.PrimitivesWithKeyManager: cannot get primitive from key: registry.GetKeyManager: "+
   354  						"unsupported key type: bad/url")
   355  				})
   356  
   357  				t.Run("create bbs verifier with invalid non primary public key should fail", func(t *testing.T) {
   358  					var sPrimaryPubKey []byte
   359  
   360  					sPrimaryPubKey, err = proto.Marshal(primaryPrivProto.PublicKey)
   361  					require.NoError(t, err)
   362  
   363  					// create primary public key with valid keyURL
   364  					tmpPrimaryPubKey := testutil.NewKey(
   365  						testutil.NewKeyData(bbsVerifierKeyTypeURL, sPrimaryPubKey, tinkpb.KeyData_ASYMMETRIC_PUBLIC),
   366  						tinkpb.KeyStatusType_ENABLED, 5, tc.prefix)
   367  
   368  					// create second public key as ecdsa key to cause an error on second key
   369  					var serializedECKey []byte
   370  
   371  					serializedECKey, err = proto.Marshal(testutil.NewRandomECDSAPublicKey(commonpb.HashType_SHA256,
   372  						commonpb.EllipticCurveType_NIST_P256))
   373  					require.NoError(t, err)
   374  
   375  					tmpSecondPubKey := testutil.NewKey(
   376  						testutil.NewKeyData("type.googleapis.com/google.crypto.tink.EcdsaPublicKey",
   377  							serializedECKey, tinkpb.KeyData_ASYMMETRIC_PUBLIC),
   378  						tinkpb.KeyStatusType_ENABLED, 9, tc.prefix)
   379  
   380  					tmpPubKeys := []*tinkpb.Keyset_Key{tmpPrimaryPubKey, tmpSecondPubKey}
   381  					tmpPubKeyset := testutil.NewKeyset(tmpPubKeys[0].KeyId, tmpPubKeys)
   382  
   383  					var tmpKHPub *keyset.Handle
   384  
   385  					tmpKHPub, err = testkeyset.NewHandle(tmpPubKeyset)
   386  					require.NoError(t, err)
   387  
   388  					_, err = NewVerifier(tmpKHPub)
   389  					require.EqualError(t, err, "bbs_verifier_factory: not a Verifier primitive")
   390  				})
   391  
   392  				t.Run("create bbs verifier with non bbs key should fail", func(t *testing.T) {
   393  					var serializedECKey []byte
   394  
   395  					serializedECKey, err = proto.Marshal(testutil.NewRandomECDSAPrivateKey(commonpb.HashType_SHA256,
   396  						commonpb.EllipticCurveType_NIST_P256))
   397  					require.NoError(t, err)
   398  
   399  					ecPrivKey := testutil.NewKey(
   400  						testutil.NewKeyData("type.googleapis.com/google.crypto.tink.EcdsaPrivateKey",
   401  							serializedECKey, tinkpb.KeyData_ASYMMETRIC_PRIVATE),
   402  						tinkpb.KeyStatusType_ENABLED, 5, tc.prefix)
   403  
   404  					tmpPrivKeys := []*tinkpb.Keyset_Key{ecPrivKey}
   405  					tmpPrivKeyset := testutil.NewKeyset(tmpPrivKeys[0].KeyId, tmpPrivKeys)
   406  
   407  					var (
   408  						tmpKHPriv *keyset.Handle
   409  						tmpPubKH  *keyset.Handle
   410  					)
   411  
   412  					tmpKHPriv, err = testkeyset.NewHandle(tmpPrivKeyset)
   413  					require.NoError(t, err)
   414  
   415  					tmpPubKH, err = tmpKHPriv.Public()
   416  					require.NoError(t, err)
   417  
   418  					_, err = NewVerifier(tmpPubKH)
   419  					require.EqualError(t, err, "bbs_verifier_factory: not a Verifier primitive")
   420  				})
   421  			}
   422  
   423  			err = bbsVerifier.Verify(messagesBytes, sig)
   424  			if tc.keyURL == bbsSignerKeyTypeURL {
   425  				require.NoError(t, err)
   426  
   427  				err = bbsVerifier.Verify([][]byte{}, sig)
   428  				require.EqualError(t, err, "bbs_verifier_factory: invalid signature")
   429  			} else {
   430  				t.Run("bbs verifier calls with invalid primary public key should fail", func(t *testing.T) {
   431  					// create primary public key as ecdsa key to cause an error in a BBS verifier
   432  					var (
   433  						serializedECKey []byte
   434  						sPrimaryPubKey  []byte
   435  					)
   436  
   437  					serializedECKey, err = proto.Marshal(testutil.NewRandomECDSAPublicKey(commonpb.HashType_SHA256,
   438  						commonpb.EllipticCurveType_NIST_P256))
   439  					require.NoError(t, err)
   440  
   441  					invalidPrimaryPubKey := testutil.NewKey(
   442  						testutil.NewKeyData("type.googleapis.com/google.crypto.tink.EcdsaPublicKey",
   443  							serializedECKey, tinkpb.KeyData_ASYMMETRIC_PUBLIC),
   444  						tinkpb.KeyStatusType_ENABLED, 5, tc.prefix)
   445  
   446  					// create valid public key to be able to create a temporary valid verifier
   447  					sPrimaryPubKey, err = proto.Marshal(primaryPrivProto.PublicKey)
   448  					require.NoError(t, err)
   449  					validSecondPubKey := testutil.NewKey(
   450  						testutil.NewKeyData(bbsVerifierKeyTypeURL, sPrimaryPubKey, tinkpb.KeyData_ASYMMETRIC_PUBLIC),
   451  						tinkpb.KeyStatusType_ENABLED, 11, tc.prefix)
   452  
   453  					invalidPubKeys := []*tinkpb.Keyset_Key{invalidPrimaryPubKey}
   454  					invalidPubKeyset := testutil.NewKeyset(invalidPubKeys[0].KeyId, invalidPubKeys)
   455  
   456  					validPubKeys := []*tinkpb.Keyset_Key{validSecondPubKey}
   457  					validPubKeyset := testutil.NewKeyset(validPubKeys[0].KeyId, validPubKeys)
   458  
   459  					var (
   460  						validKHPub   *keyset.Handle
   461  						invalidKHPub *keyset.Handle
   462  						tmpVerifier  api.Verifier
   463  					)
   464  
   465  					invalidKHPub, err = testkeyset.NewHandle(invalidPubKeyset)
   466  					require.NoError(t, err)
   467  
   468  					validKHPub, err = testkeyset.NewHandle(validPubKeyset)
   469  					require.NoError(t, err)
   470  
   471  					// create temporary verifier with valid public keyset handle
   472  					tmpVerifier, err = NewVerifier(validKHPub)
   473  					require.NoError(t, err)
   474  
   475  					var badPS *primitiveset.PrimitiveSet
   476  
   477  					badPS, err = invalidKHPub.PrimitivesWithKeyManager(nil)
   478  					require.NoError(t, err)
   479  
   480  					invalidVerifier, ok := tmpVerifier.(*wrappedVerifier)
   481  					require.True(t, ok)
   482  
   483  					// inject bad primitive set in wrappedVerifier to invoke Verify()/DeriveProof()/VerifyProof()
   484  					// and test the expected error.
   485  					invalidVerifier.ps = badPS
   486  
   487  					err = invalidVerifier.Verify(messagesBytes, sig)
   488  					require.EqualError(t, err, "bbs_verifier_factory: not a Verifier primitive")
   489  
   490  					_, err = invalidVerifier.DeriveProof(messagesBytes, sig, []byte{}, []int{0})
   491  					require.EqualError(t, err, "bbs_verifier_factory: not a Verifier primitive")
   492  
   493  					var proof []byte
   494  
   495  					proof, err = bbsVerifier.DeriveProof(messagesBytes, sig, []byte{}, []int{0})
   496  					require.NoError(t, err)
   497  
   498  					err = invalidVerifier.VerifyProof(messagesBytes, proof, []byte{})
   499  					require.EqualError(t, err, "bbs_verifier_factory: not a Verifier primitive")
   500  				})
   501  			}
   502  
   503  			revealedIndexes := []int{1, 3}
   504  			nonce := make([]byte, 10)
   505  
   506  			_, err = rand.Read(nonce)
   507  			require.NoError(t, err)
   508  
   509  			proof, err := bbsVerifier.DeriveProof(messagesBytes, sig, nonce, revealedIndexes)
   510  			require.NoError(t, err)
   511  
   512  			_, err = bbsVerifier.DeriveProof([][]byte{}, sig, nonce, revealedIndexes)
   513  			require.EqualError(t, err, "bbs_verifier_factory: invalid signature proof")
   514  
   515  			revealedMessages := make([][]byte, len(revealedIndexes))
   516  			for i, ind := range revealedIndexes {
   517  				revealedMessages[i] = messagesBytes[ind]
   518  			}
   519  
   520  			err = bbsVerifier.VerifyProof(revealedMessages, proof, nonce)
   521  			require.NoError(t, err)
   522  
   523  			err = bbsVerifier.VerifyProof([][]byte{{}, {}}, proof, nonce)
   524  			require.EqualError(t, err, "bbs_verifier_factory: invalid signature proof")
   525  		})
   526  	}
   527  }
   528  
   529  func generatePrivateKeyProto(t *testing.T) *bbspb.BBSPrivateKey {
   530  	seed := make([]byte, 32)
   531  	hashType := commonpb.HashType_SHA256
   532  
   533  	_, err := rand.Read(seed)
   534  	require.NoError(t, err)
   535  
   536  	pubKey, privKey, err := bbs12381g2pub.GenerateKeyPair(subtle.GetHashFunc(hashType.String()), seed)
   537  	require.NoError(t, err)
   538  
   539  	pubKeyBytes, err := pubKey.Marshal()
   540  	require.NoError(t, err)
   541  
   542  	pubKeyProto := &bbspb.BBSPublicKey{
   543  		Version: bbsVerifierKeyVersion,
   544  		Params: &bbspb.BBSParams{
   545  			HashType: hashType,
   546  			Curve:    bbspb.BBSCurveType_BLS12_381,
   547  			Group:    bbspb.GroupField_G2,
   548  		},
   549  		KeyValue: pubKeyBytes,
   550  	}
   551  
   552  	privKeyBytes, err := privKey.Marshal()
   553  	require.NoError(t, err)
   554  
   555  	return &bbspb.BBSPrivateKey{
   556  		Version:   bbsSignerKeyVersion,
   557  		PublicKey: pubKeyProto,
   558  		KeyValue:  privKeyBytes,
   559  	}
   560  }