github.com/anjalikarhana/fabric@v2.1.1+incompatible/idemix/idemix_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package idemix 8 9 import ( 10 "bytes" 11 "testing" 12 13 "github.com/hyperledger/fabric-amcl/amcl/FP256BN" 14 "github.com/stretchr/testify/assert" 15 ) 16 17 func TestIdemix(t *testing.T) { 18 // Test weak BB sigs: 19 // Test KeyGen 20 rng, err := GetRand() 21 assert.NoError(t, err) 22 wbbsk, wbbpk := WBBKeyGen(rng) 23 24 // Get random message 25 testmsg := RandModOrder(rng) 26 27 // Test Signing 28 wbbsig := WBBSign(wbbsk, testmsg) 29 30 // Test Verification 31 err = WBBVerify(wbbpk, wbbsig, testmsg) 32 assert.NoError(t, err) 33 34 // Test idemix functionality 35 AttributeNames := []string{"Attr1", "Attr2", "Attr3", "Attr4", "Attr5"} 36 attrs := make([]*FP256BN.BIG, len(AttributeNames)) 37 for i := range AttributeNames { 38 attrs[i] = FP256BN.NewBIGint(i) 39 } 40 41 // Test issuer key generation 42 if err != nil { 43 t.Fatalf("Error getting rng: \"%s\"", err) 44 return 45 } 46 // Create a new key pair 47 key, err := NewIssuerKey(AttributeNames, rng) 48 if err != nil { 49 t.Fatalf("Issuer key generation should have succeeded but gave error \"%s\"", err) 50 return 51 } 52 53 // Check that the key is valid 54 err = key.GetIpk().Check() 55 if err != nil { 56 t.Fatalf("Issuer public key should be valid") 57 return 58 } 59 60 // Make sure Check() is invalid for a public key with invalid proof 61 proofC := key.Ipk.GetProofC() 62 key.Ipk.ProofC = BigToBytes(RandModOrder(rng)) 63 assert.Error(t, key.Ipk.Check(), "public key with broken zero-knowledge proof should be invalid") 64 65 // Make sure Check() is invalid for a public key with incorrect number of HAttrs 66 hAttrs := key.Ipk.GetHAttrs() 67 key.Ipk.HAttrs = key.Ipk.HAttrs[:0] 68 assert.Error(t, key.Ipk.Check(), "public key with incorrect number of HAttrs should be invalid") 69 key.Ipk.HAttrs = hAttrs 70 71 // Restore IPk to be valid 72 key.Ipk.ProofC = proofC 73 h := key.Ipk.GetHash() 74 assert.NoError(t, key.Ipk.Check(), "restored public key should be valid") 75 assert.Zero(t, bytes.Compare(h, key.Ipk.GetHash()), "IPK hash changed on ipk Check") 76 77 // Create public with duplicate attribute names should fail 78 _, err = NewIssuerKey([]string{"Attr1", "Attr2", "Attr1"}, rng) 79 assert.Error(t, err, "issuer key generation should fail with duplicate attribute names") 80 81 // Test issuance 82 sk := RandModOrder(rng) 83 ni := RandModOrder(rng) 84 m := NewCredRequest(sk, BigToBytes(ni), key.Ipk, rng) 85 86 cred, err := NewCredential(key, m, attrs, rng) 87 assert.NoError(t, err, "Failed to issue a credential: \"%s\"", err) 88 89 assert.NoError(t, cred.Ver(sk, key.Ipk), "credential should be valid") 90 91 // Issuing a credential with the incorrect amount of attributes should fail 92 _, err = NewCredential(key, m, []*FP256BN.BIG{}, rng) 93 assert.Error(t, err, "issuing a credential with the incorrect amount of attributes should fail") 94 95 // Breaking the ZK proof of the CredRequest should make it invalid 96 proofC = m.GetProofC() 97 m.ProofC = BigToBytes(RandModOrder(rng)) 98 assert.Error(t, m.Check(key.Ipk), "CredRequest with broken ZK proof should not be valid") 99 100 // Creating a credential from a broken CredRequest should fail 101 _, err = NewCredential(key, m, attrs, rng) 102 assert.Error(t, err, "creating a credential from an invalid CredRequest should fail") 103 m.ProofC = proofC 104 105 // A credential with nil attribute should be invalid 106 attrsBackup := cred.GetAttrs() 107 cred.Attrs = [][]byte{nil, nil, nil, nil, nil} 108 assert.Error(t, cred.Ver(sk, key.Ipk), "credential with nil attribute should be invalid") 109 cred.Attrs = attrsBackup 110 111 // Generate a revocation key pair 112 revocationKey, err := GenerateLongTermRevocationKey() 113 assert.NoError(t, err) 114 115 // Create CRI that contains no revocation mechanism 116 epoch := 0 117 cri, err := CreateCRI(revocationKey, []*FP256BN.BIG{}, epoch, ALG_NO_REVOCATION, rng) 118 assert.NoError(t, err) 119 err = VerifyEpochPK(&revocationKey.PublicKey, cri.EpochPk, cri.EpochPkSig, int(cri.Epoch), RevocationAlgorithm(cri.RevocationAlg)) 120 assert.NoError(t, err) 121 122 // make sure that epoch pk is not valid in future epoch 123 err = VerifyEpochPK(&revocationKey.PublicKey, cri.EpochPk, cri.EpochPkSig, int(cri.Epoch)+1, RevocationAlgorithm(cri.RevocationAlg)) 124 assert.Error(t, err) 125 126 // Test bad input 127 _, err = CreateCRI(nil, []*FP256BN.BIG{}, epoch, ALG_NO_REVOCATION, rng) 128 assert.Error(t, err) 129 _, err = CreateCRI(revocationKey, []*FP256BN.BIG{}, epoch, ALG_NO_REVOCATION, nil) 130 assert.Error(t, err) 131 132 // Test signing no disclosure 133 Nym, RandNym := MakeNym(sk, key.Ipk, rng) 134 135 disclosure := []byte{0, 0, 0, 0, 0} 136 msg := []byte{1, 2, 3, 4, 5} 137 rhindex := 4 138 sig, err := NewSignature(cred, sk, Nym, RandNym, key.Ipk, disclosure, msg, rhindex, cri, rng) 139 assert.NoError(t, err) 140 141 err = sig.Ver(disclosure, key.Ipk, msg, nil, 0, &revocationKey.PublicKey, epoch) 142 if err != nil { 143 t.Fatalf("Signature should be valid but verification returned error: %s", err) 144 return 145 } 146 147 // Test signing selective disclosure 148 disclosure = []byte{0, 1, 1, 1, 0} 149 sig, err = NewSignature(cred, sk, Nym, RandNym, key.Ipk, disclosure, msg, rhindex, cri, rng) 150 assert.NoError(t, err) 151 152 err = sig.Ver(disclosure, key.Ipk, msg, attrs, rhindex, &revocationKey.PublicKey, epoch) 153 assert.NoError(t, err) 154 155 // Test NymSignatures 156 nymsig, err := NewNymSignature(sk, Nym, RandNym, key.Ipk, []byte("testing"), rng) 157 assert.NoError(t, err) 158 159 err = nymsig.Ver(Nym, key.Ipk, []byte("testing")) 160 if err != nil { 161 t.Fatalf("NymSig should be valid but verification returned error: %s", err) 162 return 163 } 164 }