diff --git a/lib/client.go b/lib/client.go index 98e2d33d9..3654c19da 100644 --- a/lib/client.go +++ b/lib/client.go @@ -532,7 +532,7 @@ func (c *Client) newIdemixCredentialRequest(nonce *fp256bn.BIG, ipkBytes []byte) if err != nil { return nil, nil, err } - return idemix.NewCredRequest(sk, nonce, issuerPubKey, rng), sk, nil + return idemix.NewCredRequest(sk, idemix.BigToBytes(nonce), issuerPubKey, rng), sk, nil } func (c *Client) getIssuerPubKey(ipkBytes []byte) (*idemix.IssuerPublicKey, error) { diff --git a/lib/server/idemix/enroll_test.go b/lib/server/idemix/enroll_test.go index 85f5b0a95..e4f34dad4 100644 --- a/lib/server/idemix/enroll_test.go +++ b/lib/server/idemix/enroll_test.go @@ -543,5 +543,5 @@ func newIdemixCredentialRequest(t *testing.T, nonce *fp256bn.BIG) (*idemix.CredR return nil, nil, err } sk := idemix.RandModOrder(rng) - return idemix.NewCredRequest(sk, nonce, ik.Ipk, rng), sk, nil + return idemix.NewCredRequest(sk, idemix.BigToBytes(nonce), ik.Ipk, rng), sk, nil } diff --git a/vendor/github.com/hyperledger/fabric/bccsp/factory/swfactory.go b/vendor/github.com/hyperledger/fabric/bccsp/factory/swfactory.go index e77f5e323..151175959 100644 --- a/vendor/github.com/hyperledger/fabric/bccsp/factory/swfactory.go +++ b/vendor/github.com/hyperledger/fabric/bccsp/factory/swfactory.go @@ -52,8 +52,10 @@ func (f *SWFactory) Get(config *FactoryOpts) (bccsp.BCCSP, error) { return nil, errors.Wrapf(err, "Failed to initialize software key store") } ks = fks + } else if swOpts.InmemKeystore != nil { + ks = sw.NewInMemoryKeyStore() } else { - // Default to DummyKeystore + // Default to ephemeral key store ks = sw.NewDummyKeyStore() } @@ -70,6 +72,7 @@ type SwOpts struct { Ephemeral bool `mapstructure:"tempkeys,omitempty" json:"tempkeys,omitempty"` FileKeystore *FileKeystoreOpts `mapstructure:"filekeystore,omitempty" json:"filekeystore,omitempty" yaml:"FileKeyStore"` DummyKeystore *DummyKeystoreOpts `mapstructure:"dummykeystore,omitempty" json:"dummykeystore,omitempty"` + InmemKeystore *InmemKeystoreOpts `mapstructure:"inmemkeystore,omitempty" json:"inmemkeystore,omitempty"` } // Pluggable Keystores, could add JKS, P12, etc.. @@ -78,3 +81,6 @@ type FileKeystoreOpts struct { } type DummyKeystoreOpts struct{} + +// InmemKeystoreOpts - empty, as there is no config for the in-memory keystore +type InmemKeystoreOpts struct{} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/bccsp.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/bccsp.go new file mode 100644 index 000000000..478028faf --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/bccsp.go @@ -0,0 +1,171 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ +package idemix + +import ( + "reflect" + + "github.com/hyperledger/fabric/bccsp/idemix/bridge" + + "github.com/hyperledger/fabric/bccsp/idemix/handlers" + + "github.com/hyperledger/fabric/bccsp" + "github.com/hyperledger/fabric/bccsp/sw" + "github.com/pkg/errors" +) + +type csp struct { + *sw.CSP +} + +func New(keyStore bccsp.KeyStore) (*csp, error) { + base, err := sw.New(keyStore) + if err != nil { + return nil, errors.Wrap(err, "failed instantiating base bccsp") + } + + csp := &csp{CSP: base} + + // key generators + base.AddWrapper(reflect.TypeOf(&bccsp.IdemixIssuerKeyGenOpts{}), &handlers.IssuerKeyGen{Issuer: &bridge.Issuer{NewRand: bridge.NewRandOrPanic}}) + base.AddWrapper(reflect.TypeOf(&bccsp.IdemixUserSecretKeyGenOpts{}), &handlers.UserKeyGen{User: &bridge.User{NewRand: bridge.NewRandOrPanic}}) + base.AddWrapper(reflect.TypeOf(&bccsp.IdemixRevocationKeyGenOpts{}), &handlers.RevocationKeyGen{Revocation: &bridge.Revocation{}}) + + // key derivers + base.AddWrapper(reflect.TypeOf(handlers.NewUserSecretKey(nil, false)), &handlers.NymKeyDerivation{ + User: &bridge.User{NewRand: bridge.NewRandOrPanic}, + }) + + // signers + base.AddWrapper(reflect.TypeOf(handlers.NewUserSecretKey(nil, false)), &userSecreKeySignerMultiplexer{ + signer: &handlers.Signer{SignatureScheme: &bridge.SignatureScheme{NewRand: bridge.NewRandOrPanic}}, + nymSigner: &handlers.NymSigner{NymSignatureScheme: &bridge.NymSignatureScheme{NewRand: bridge.NewRandOrPanic}}, + credentialRequestSigner: &handlers.CredentialRequestSigner{CredRequest: &bridge.CredRequest{NewRand: bridge.NewRandOrPanic}}, + }) + base.AddWrapper(reflect.TypeOf(handlers.NewIssuerSecretKey(nil, false)), &handlers.CredentialSigner{ + Credential: &bridge.Credential{NewRand: bridge.NewRandOrPanic}, + }) + base.AddWrapper(reflect.TypeOf(handlers.NewRevocationSecretKey(nil, false)), &handlers.CriSigner{ + Revocation: &bridge.Revocation{}, + }) + + // verifiers + base.AddWrapper(reflect.TypeOf(handlers.NewIssuerPublicKey(nil)), &issuerPublicKeyVerifierMultiplexer{ + verifier: &handlers.Verifier{SignatureScheme: &bridge.SignatureScheme{NewRand: bridge.NewRandOrPanic}}, + credentialRequestVerifier: &handlers.CredentialRequestVerifier{CredRequest: &bridge.CredRequest{NewRand: bridge.NewRandOrPanic}}, + }) + base.AddWrapper(reflect.TypeOf(handlers.NewNymPublicKey(nil)), &handlers.NymVerifier{ + NymSignatureScheme: &bridge.NymSignatureScheme{NewRand: bridge.NewRandOrPanic}, + }) + base.AddWrapper(reflect.TypeOf(handlers.NewUserSecretKey(nil, false)), &handlers.CredentialVerifier{ + Credential: &bridge.Credential{NewRand: bridge.NewRandOrPanic}, + }) + base.AddWrapper(reflect.TypeOf(handlers.NewRevocationPublicKey(nil)), &handlers.CriVerifier{ + Revocation: &bridge.Revocation{}, + }) + + // importers + base.AddWrapper(reflect.TypeOf(&bccsp.IdemixUserSecretKeyImportOpts{}), &handlers.UserKeyImporter{ + User: &bridge.User{}, + }) + base.AddWrapper(reflect.TypeOf(&bccsp.IdemixIssuerPublicKeyImportOpts{}), &handlers.IssuerPublicKeyImporter{ + Issuer: &bridge.Issuer{}, + }) + base.AddWrapper(reflect.TypeOf(&bccsp.IdemixNymPublicKeyImportOpts{}), &handlers.NymPublicKeyImporter{ + User: &bridge.User{}, + }) + base.AddWrapper(reflect.TypeOf(&bccsp.IdemixRevocationPublicKeyImportOpts{}), &handlers.RevocationPublicKeyImporter{}) + + return csp, nil +} + +// Sign signs digest using key k. +// The opts argument should be appropriate for the primitive used. +// +// Note that when a signature of a hash of a larger message is needed, +// the caller is responsible for hashing the larger message and passing +// the hash (as digest). +// Notice that this is overriding the Sign methods of the sw impl. to avoid the digest check. +func (csp *csp) Sign(k bccsp.Key, digest []byte, opts bccsp.SignerOpts) (signature []byte, err error) { + // Validate arguments + if k == nil { + return nil, errors.New("Invalid Key. It must not be nil.") + } + // Do not check for digest + + keyType := reflect.TypeOf(k) + signer, found := csp.Signers[keyType] + if !found { + return nil, errors.Errorf("Unsupported 'SignKey' provided [%s]", keyType) + } + + signature, err = signer.Sign(k, digest, opts) + if err != nil { + return nil, errors.Wrapf(err, "Failed signing with opts [%v]", opts) + } + + return +} + +// Verify verifies signature against key k and digest +// Notice that this is overriding the Sign methods of the sw impl. to avoid the digest check. +func (csp *csp) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (valid bool, err error) { + // Validate arguments + if k == nil { + return false, errors.New("Invalid Key. It must not be nil.") + } + if len(signature) == 0 { + return false, errors.New("Invalid signature. Cannot be empty.") + } + // Do not check for digest + + verifier, found := csp.Verifiers[reflect.TypeOf(k)] + if !found { + return false, errors.Errorf("Unsupported 'VerifyKey' provided [%v]", k) + } + + valid, err = verifier.Verify(k, signature, digest, opts) + if err != nil { + return false, errors.Wrapf(err, "Failed verifing with opts [%v]", opts) + } + + return +} + +type userSecreKeySignerMultiplexer struct { + signer *handlers.Signer + nymSigner *handlers.NymSigner + credentialRequestSigner *handlers.CredentialRequestSigner +} + +func (s *userSecreKeySignerMultiplexer) Sign(k bccsp.Key, digest []byte, opts bccsp.SignerOpts) (signature []byte, err error) { + switch opts.(type) { + case *bccsp.IdemixSignerOpts: + return s.signer.Sign(k, digest, opts) + case *bccsp.IdemixNymSignerOpts: + return s.nymSigner.Sign(k, digest, opts) + case *bccsp.IdemixCredentialRequestSignerOpts: + return s.credentialRequestSigner.Sign(k, digest, opts) + default: + return nil, errors.New("invalid opts, expected *bccsp.IdemixSignerOpt or *bccsp.IdemixNymSignerOpts or *bccsp.IdemixCredentialRequestSignerOpts") + } +} + +type issuerPublicKeyVerifierMultiplexer struct { + verifier *handlers.Verifier + credentialRequestVerifier *handlers.CredentialRequestVerifier +} + +func (v *issuerPublicKeyVerifierMultiplexer) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (valid bool, err error) { + switch opts.(type) { + case *bccsp.IdemixSignerOpts: + return v.verifier.Verify(k, signature, digest, opts) + case *bccsp.IdemixCredentialRequestSignerOpts: + return v.credentialRequestVerifier.Verify(k, signature, digest, opts) + default: + return false, errors.New("invalid opts, expected *bccsp.IdemixSignerOpts or *bccsp.IdemixCredentialRequestSignerOpts") + } +} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/credential.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/credential.go new file mode 100644 index 000000000..ae5859b44 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/credential.go @@ -0,0 +1,118 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ +package bridge + +import ( + "bytes" + + "github.com/golang/protobuf/proto" + "github.com/hyperledger/fabric-amcl/amcl" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" + "github.com/hyperledger/fabric/bccsp" + "github.com/hyperledger/fabric/bccsp/idemix/handlers" + cryptolib "github.com/hyperledger/fabric/idemix" + "github.com/pkg/errors" +) + +// Credential encapsulates the idemix algorithms to produce (sign) a credential +// and verify it. Recall that a credential is produced by the Issuer upon a credential request, +// and it is verified by the requester. +type Credential struct { + NewRand func() *amcl.RAND +} + +// Sign produces an idemix credential. It takes in input the issuer secret key, +// a serialised credential request, and a list of attribute values. +// Notice that attributes should not contain attributes whose type is IdemixHiddenAttribute +// cause the credential needs to carry all the attribute values. +func (c *Credential) Sign(key handlers.IssuerSecretKey, credentialRequest []byte, attributes []bccsp.IdemixAttribute) (res []byte, err error) { + defer func() { + if r := recover(); r != nil { + res = nil + err = errors.Errorf("failure [%s]", r) + } + }() + + iisk, ok := key.(*IssuerSecretKey) + if !ok { + return nil, errors.Errorf("invalid issuer secret key, expected *Big, got [%T]", key) + } + + cr := &cryptolib.CredRequest{} + err = proto.Unmarshal(credentialRequest, cr) + if err != nil { + return nil, errors.Wrap(err, "failed unmarshalling credential request") + } + + attrValues := make([]*FP256BN.BIG, len(attributes)) + for i := 0; i < len(attributes); i++ { + switch attributes[i].Type { + case bccsp.IdemixBytesAttribute: + attrValues[i] = cryptolib.HashModOrder(attributes[i].Value.([]byte)) + case bccsp.IdemixIntAttribute: + attrValues[i] = FP256BN.NewBIGint(attributes[i].Value.(int)) + default: + return nil, errors.Errorf("attribute type not allowed or supported [%v] at position [%d]", attributes[i].Type, i) + } + } + + cred, err := cryptolib.NewCredential(iisk.SK, cr, attrValues, c.NewRand()) + if err != nil { + return nil, errors.WithMessage(err, "failed creating new credential") + } + + return proto.Marshal(cred) +} + +// Verify checks that an idemix credential is cryptographically correct. It takes +// in input the user secret key (sk), the issuer public key (ipk), the serialised credential (credential), +// and a list of attributes. The list of attributes is optional, in case it is specified, Verify +// checks that the credential carries the specified attributes. +func (*Credential) Verify(sk handlers.Big, ipk handlers.IssuerPublicKey, credential []byte, attributes []bccsp.IdemixAttribute) (err error) { + defer func() { + if r := recover(); r != nil { + err = errors.Errorf("failure [%s]", r) + } + }() + + isk, ok := sk.(*Big) + if !ok { + return errors.Errorf("invalid user secret key, expected *Big, got [%T]", sk) + } + iipk, ok := ipk.(*IssuerPublicKey) + if !ok { + return errors.Errorf("invalid issuer public key, expected *IssuerPublicKey, got [%T]", sk) + } + + cred := &cryptolib.Credential{} + err = proto.Unmarshal(credential, cred) + if err != nil { + return err + } + + for i := 0; i < len(attributes); i++ { + switch attributes[i].Type { + case bccsp.IdemixBytesAttribute: + if !bytes.Equal( + cryptolib.BigToBytes(cryptolib.HashModOrder(attributes[i].Value.([]byte))), + cred.Attrs[i]) { + return errors.Errorf("credential does not contain the correct attribute value at position [%d]", i) + } + case bccsp.IdemixIntAttribute: + if !bytes.Equal( + cryptolib.BigToBytes(FP256BN.NewBIGint(attributes[i].Value.(int))), + cred.Attrs[i]) { + return errors.Errorf("credential does not contain the correct attribute value at position [%d]", i) + } + case bccsp.IdemixHiddenAttribute: + continue + default: + return errors.Errorf("attribute type not allowed or supported [%v] at position [%d]", attributes[i].Type, i) + } + } + + return cred.Ver(isk.E, iipk.PK) +} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/credrequest.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/credrequest.go new file mode 100644 index 000000000..a7e1c6389 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/credrequest.go @@ -0,0 +1,92 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ +package bridge + +import ( + "bytes" + + "github.com/golang/protobuf/proto" + "github.com/hyperledger/fabric-amcl/amcl" + "github.com/hyperledger/fabric/bccsp/idemix/handlers" + cryptolib "github.com/hyperledger/fabric/idemix" + "github.com/pkg/errors" +) + +// CredRequest encapsulates the idemix algorithms to produce (sign) a credential request +// and verify it. Recall that a credential request is produced by a user, +// and it is verified by the issuer at credential creation time. +type CredRequest struct { + NewRand func() *amcl.RAND +} + +// Sign produces an idemix credential request. It takes in input a user secret key and +// an issuer public key. +func (cr *CredRequest) Sign(sk handlers.Big, ipk handlers.IssuerPublicKey, nonce []byte) (res []byte, err error) { + defer func() { + if r := recover(); r != nil { + res = nil + err = errors.Errorf("failure [%s]", r) + } + }() + + isk, ok := sk.(*Big) + if !ok { + return nil, errors.Errorf("invalid user secret key, expected *Big, got [%T]", sk) + } + iipk, ok := ipk.(*IssuerPublicKey) + if !ok { + return nil, errors.Errorf("invalid issuer public key, expected *IssuerPublicKey, got [%T]", ipk) + } + if len(nonce) != cryptolib.FieldBytes { + return nil, errors.Errorf("invalid issuer nonce, expected length %d, got %d", cryptolib.FieldBytes, len(nonce)) + } + + rng := cr.NewRand() + + credRequest := cryptolib.NewCredRequest( + isk.E, + nonce, + iipk.PK, + rng) + + return proto.Marshal(credRequest) +} + +// Verify checks that the passed credential request is valid with the respect to the passed +// issuer public key. +func (*CredRequest) Verify(credentialRequest []byte, ipk handlers.IssuerPublicKey, nonce []byte) (err error) { + defer func() { + if r := recover(); r != nil { + err = errors.Errorf("failure [%s]", r) + } + }() + + credRequest := &cryptolib.CredRequest{} + err = proto.Unmarshal(credentialRequest, credRequest) + if err != nil { + return err + } + + iipk, ok := ipk.(*IssuerPublicKey) + if !ok { + return errors.Errorf("invalid issuer public key, expected *IssuerPublicKey, got [%T]", ipk) + } + + err = credRequest.Check(iipk.PK) + if err != nil { + return err + } + + // Nonce checks + if len(nonce) != cryptolib.FieldBytes { + return errors.Errorf("invalid issuer nonce, expected length %d, got %d", cryptolib.FieldBytes, len(nonce)) + } + if !bytes.Equal(nonce, credRequest.IssuerNonce) { + return errors.Errorf("invalid nonce, expected [%v], got [%v]", nonce, credRequest.IssuerNonce) + } + + return nil +} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/issuer.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/issuer.go new file mode 100644 index 000000000..6ef2f6083 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/issuer.go @@ -0,0 +1,125 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ +package bridge + +import ( + "fmt" + + "github.com/golang/protobuf/proto" + "github.com/hyperledger/fabric-amcl/amcl" + "github.com/hyperledger/fabric/bccsp" + "github.com/hyperledger/fabric/bccsp/idemix/handlers" + cryptolib "github.com/hyperledger/fabric/idemix" + "github.com/pkg/errors" +) + +// IssuerPublicKey encapsulate an idemix issuer public key. +type IssuerPublicKey struct { + PK *cryptolib.IssuerPublicKey +} + +func (o *IssuerPublicKey) Bytes() ([]byte, error) { + return proto.Marshal(o.PK) +} + +func (o *IssuerPublicKey) Hash() []byte { + return o.PK.Hash +} + +// IssuerPublicKey encapsulate an idemix issuer secret key. +type IssuerSecretKey struct { + SK *cryptolib.IssuerKey +} + +func (o *IssuerSecretKey) Bytes() ([]byte, error) { + return proto.Marshal(o.SK) +} + +func (o *IssuerSecretKey) Public() handlers.IssuerPublicKey { + return &IssuerPublicKey{o.SK.Ipk} +} + +// Issuer encapsulates the idemix algorithms to generate issuer key-pairs +type Issuer struct { + NewRand func() *amcl.RAND +} + +// NewKey generates a new issuer key-pair +func (i *Issuer) NewKey(attributeNames []string) (res handlers.IssuerSecretKey, err error) { + defer func() { + if r := recover(); r != nil { + res = nil + err = errors.Errorf("failure [%s]", r) + } + }() + + sk, err := cryptolib.NewIssuerKey(attributeNames, i.NewRand()) + if err != nil { + return + } + + res = &IssuerSecretKey{SK: sk} + + return +} + +func (*Issuer) NewPublicKeyFromBytes(raw []byte, attributes []string) (res handlers.IssuerPublicKey, err error) { + defer func() { + if r := recover(); r != nil { + res = nil + err = errors.Errorf("failure [%s]", r) + } + }() + + ipk := new(cryptolib.IssuerPublicKey) + err = proto.Unmarshal(raw, ipk) + if err != nil { + return nil, errors.WithStack(&bccsp.IdemixIssuerPublicKeyImporterError{ + Type: bccsp.IdemixIssuerPublicKeyImporterUnmarshallingError, + ErrorMsg: "failed to unmarshal issuer public key", + Cause: err}) + } + + err = ipk.SetHash() + if err != nil { + return nil, errors.WithStack(&bccsp.IdemixIssuerPublicKeyImporterError{ + Type: bccsp.IdemixIssuerPublicKeyImporterHashError, + ErrorMsg: "setting the hash of the issuer public key failed", + Cause: err}) + } + + err = ipk.Check() + if err != nil { + return nil, errors.WithStack(&bccsp.IdemixIssuerPublicKeyImporterError{ + Type: bccsp.IdemixIssuerPublicKeyImporterValidationError, + ErrorMsg: "invalid issuer public key", + Cause: err}) + } + + if len(attributes) != 0 { + // Check the attributes + if len(attributes) != len(ipk.AttributeNames) { + return nil, errors.WithStack(&bccsp.IdemixIssuerPublicKeyImporterError{ + Type: bccsp.IdemixIssuerPublicKeyImporterNumAttributesError, + ErrorMsg: fmt.Sprintf("invalid number of attributes, expected [%d], got [%d]", + len(ipk.AttributeNames), len(attributes)), + }) + } + + for i, attr := range attributes { + if ipk.AttributeNames[i] != attr { + return nil, errors.WithStack(&bccsp.IdemixIssuerPublicKeyImporterError{ + Type: bccsp.IdemixIssuerPublicKeyImporterAttributeNameError, + ErrorMsg: fmt.Sprintf("invalid attribute name at position [%d]", i), + }) + } + } + } + + res = &IssuerPublicKey{PK: ipk} + + return +} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/math.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/math.go new file mode 100644 index 000000000..f04d65c8d --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/math.go @@ -0,0 +1,33 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ +package bridge + +import ( + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" + "github.com/hyperledger/fabric/idemix" +) + +// Big encapsulate an amcl big integer +type Big struct { + E *FP256BN.BIG +} + +func (b *Big) Bytes() ([]byte, error) { + return idemix.BigToBytes(b.E), nil +} + +// Ecp encapsulate an amcl elliptic curve point +type Ecp struct { + E *FP256BN.ECP +} + +func (o *Ecp) Bytes() ([]byte, error) { + var res []byte + res = append(res, idemix.BigToBytes(o.E.GetX())...) + res = append(res, idemix.BigToBytes(o.E.GetY())...) + + return res, nil +} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/nymsignaturescheme.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/nymsignaturescheme.go new file mode 100644 index 000000000..1cdd6da7f --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/nymsignaturescheme.go @@ -0,0 +1,89 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ +package bridge + +import ( + "github.com/hyperledger/fabric-amcl/amcl" + "github.com/hyperledger/fabric/bccsp/idemix/handlers" + + "github.com/golang/protobuf/proto" + cryptolib "github.com/hyperledger/fabric/idemix" + "github.com/pkg/errors" +) + +// NymSignatureScheme encapsulates the idemix algorithms to sign and verify using an idemix +// pseudonym. +type NymSignatureScheme struct { + NewRand func() *amcl.RAND +} + +// Sign produces a signature over the passed digest. It takes in input, the user secret key (sk), +// the pseudonym public key (Nym) and secret key (RNym), and the issuer public key (ipk). +func (n *NymSignatureScheme) Sign(sk handlers.Big, Nym handlers.Ecp, RNym handlers.Big, ipk handlers.IssuerPublicKey, digest []byte) (res []byte, err error) { + defer func() { + if r := recover(); r != nil { + res = nil + err = errors.Errorf("failure [%s]", r) + } + }() + + isk, ok := sk.(*Big) + if !ok { + return nil, errors.Errorf("invalid user secret key, expected *Big, got [%T]", sk) + } + inym, ok := Nym.(*Ecp) + if !ok { + return nil, errors.Errorf("invalid nym public key, expected *Ecp, got [%T]", Nym) + } + irnym, ok := RNym.(*Big) + if !ok { + return nil, errors.Errorf("invalid nym secret key, expected *Big, got [%T]", RNym) + } + iipk, ok := ipk.(*IssuerPublicKey) + if !ok { + return nil, errors.Errorf("invalid issuer public key, expected *IssuerPublicKey, got [%T]", ipk) + } + + sig, err := cryptolib.NewNymSignature( + isk.E, + inym.E, + irnym.E, + iipk.PK, + digest, + n.NewRand()) + if err != nil { + return nil, errors.WithMessage(err, "failed creating new nym signature") + } + + return proto.Marshal(sig) +} + +// Verify checks that the passed signatures is valid with the respect to the passed digest, issuer public key, +// and pseudonym public key. +func (*NymSignatureScheme) Verify(ipk handlers.IssuerPublicKey, Nym handlers.Ecp, signature, digest []byte) (err error) { + defer func() { + if r := recover(); r != nil { + err = errors.Errorf("failure [%s]", r) + } + }() + + iipk, ok := ipk.(*IssuerPublicKey) + if !ok { + return errors.Errorf("invalid issuer public key, expected *IssuerPublicKey, got [%T]", ipk) + } + inym, ok := Nym.(*Ecp) + if !ok { + return errors.Errorf("invalid nym public key, expected *Ecp, got [%T]", Nym) + } + + sig := &cryptolib.NymSignature{} + err = proto.Unmarshal(signature, sig) + if err != nil { + return errors.Wrap(err, "error unmarshalling signature") + } + + return sig.Ver(inym.E, iipk.PK, digest) +} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/rand.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/rand.go new file mode 100644 index 000000000..629f416ed --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/rand.go @@ -0,0 +1,20 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ +package bridge + +import ( + "github.com/hyperledger/fabric-amcl/amcl" + cryptolib "github.com/hyperledger/fabric/idemix" +) + +// NewRandOrPanic return a new amcl PRG or panic +func NewRandOrPanic() *amcl.RAND { + rng, err := cryptolib.GetRand() + if err != nil { + panic(err) + } + return rng +} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/revocation.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/revocation.go new file mode 100644 index 000000000..9170bb43c --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/revocation.go @@ -0,0 +1,70 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ +package bridge + +import ( + "crypto/ecdsa" + + "github.com/golang/protobuf/proto" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" + "github.com/hyperledger/fabric/bccsp" + cryptolib "github.com/hyperledger/fabric/idemix" + "github.com/pkg/errors" +) + +// Revocation encapsulates the idemix algorithms for revocation +type Revocation struct { +} + +// NewKey generate a new revocation key-pair. +func (*Revocation) NewKey() (*ecdsa.PrivateKey, error) { + return cryptolib.GenerateLongTermRevocationKey() +} + +// Sign generates a new CRI with the respect to the passed unrevoked handles, epoch, and revocation algorithm. +func (*Revocation) Sign(key *ecdsa.PrivateKey, unrevokedHandles [][]byte, epoch int, alg bccsp.RevocationAlgorithm) (res []byte, err error) { + defer func() { + if r := recover(); r != nil { + res = nil + err = errors.Errorf("failure [%s]", r) + } + }() + + handles := make([]*FP256BN.BIG, len(unrevokedHandles)) + for i := 0; i < len(unrevokedHandles); i++ { + handles[i] = FP256BN.FromBytes(unrevokedHandles[i]) + } + cri, err := cryptolib.CreateCRI(key, handles, epoch, cryptolib.RevocationAlgorithm(alg), NewRandOrPanic()) + if err != nil { + return nil, errors.WithMessage(err, "failed creating CRI") + } + + return proto.Marshal(cri) +} + +// Verify checks that the passed serialised CRI (criRaw) is valid with the respect to the passed revocation public key, +// epoch, and revocation algorithm. +func (*Revocation) Verify(pk *ecdsa.PublicKey, criRaw []byte, epoch int, alg bccsp.RevocationAlgorithm) (err error) { + defer func() { + if r := recover(); r != nil { + err = errors.Errorf("failure [%s]", r) + } + }() + + cri := &cryptolib.CredentialRevocationInformation{} + err = proto.Unmarshal(criRaw, cri) + if err != nil { + return err + } + + return cryptolib.VerifyEpochPK( + pk, + cri.EpochPk, + cri.EpochPkSig, + int(cri.Epoch), + cryptolib.RevocationAlgorithm(cri.RevocationAlg), + ) +} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/signaturescheme.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/signaturescheme.go new file mode 100644 index 000000000..7ccd1a13e --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/signaturescheme.go @@ -0,0 +1,142 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ +package bridge + +import ( + "crypto/ecdsa" + + "github.com/golang/protobuf/proto" + "github.com/hyperledger/fabric-amcl/amcl" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" + "github.com/hyperledger/fabric/bccsp" + "github.com/hyperledger/fabric/bccsp/idemix/handlers" + cryptolib "github.com/hyperledger/fabric/idemix" + "github.com/pkg/errors" +) + +// SignatureScheme encapsulates the idemix algorithms to sign and verify using an idemix credential. +type SignatureScheme struct { + NewRand func() *amcl.RAND +} + +// Sign produces an idemix-signature with the respect to the passed serialised credential (cred), +// user secret key (sk), pseudonym public key (Nym) and secret key (RNym), issuer public key (ipk), +// and attributes to be disclosed. +func (s *SignatureScheme) Sign(cred []byte, sk handlers.Big, Nym handlers.Ecp, RNym handlers.Big, ipk handlers.IssuerPublicKey, attributes []bccsp.IdemixAttribute, + msg []byte, rhIndex int, criRaw []byte) (res []byte, err error) { + defer func() { + if r := recover(); r != nil { + res = nil + err = errors.Errorf("failure [%s]", r) + } + }() + + isk, ok := sk.(*Big) + if !ok { + return nil, errors.Errorf("invalid user secret key, expected *Big, got [%T]", sk) + } + inym, ok := Nym.(*Ecp) + if !ok { + return nil, errors.Errorf("invalid nym public key, expected *Ecp, got [%T]", Nym) + } + irnym, ok := RNym.(*Big) + if !ok { + return nil, errors.Errorf("invalid nym secret key, expected *Big, got [%T]", RNym) + } + iipk, ok := ipk.(*IssuerPublicKey) + if !ok { + return nil, errors.Errorf("invalid issuer public key, expected *IssuerPublicKey, got [%T]", ipk) + } + + credential := &cryptolib.Credential{} + err = proto.Unmarshal(cred, credential) + if err != nil { + return nil, errors.Wrap(err, "failed unmarshalling credential") + } + + cri := &cryptolib.CredentialRevocationInformation{} + err = proto.Unmarshal(criRaw, cri) + if err != nil { + return nil, errors.Wrap(err, "failed unmarshalling credential revocation information") + } + + disclosure := make([]byte, len(attributes)) + for i := 0; i < len(attributes); i++ { + if attributes[i].Type == bccsp.IdemixHiddenAttribute { + disclosure[i] = 0 + } else { + disclosure[i] = 1 + } + } + + sig, err := cryptolib.NewSignature( + credential, + isk.E, + inym.E, + irnym.E, + iipk.PK, + disclosure, + msg, + rhIndex, + cri, + s.NewRand()) + if err != nil { + return nil, errors.WithMessage(err, "failed creating new signature") + } + + return proto.Marshal(sig) +} + +// Verify checks that an idemix signature is valid with the respect to the passed issuer public key, digest, attributes, +// revocation index (rhIndex), revocation public key, and epoch. +func (*SignatureScheme) Verify(ipk handlers.IssuerPublicKey, signature, digest []byte, attributes []bccsp.IdemixAttribute, rhIndex int, revocationPublicKey *ecdsa.PublicKey, epoch int) (err error) { + defer func() { + if r := recover(); r != nil { + err = errors.Errorf("failure [%s]", r) + } + }() + + iipk, ok := ipk.(*IssuerPublicKey) + if !ok { + return errors.Errorf("invalid issuer public key, expected *IssuerPublicKey, got [%T]", ipk) + } + + sig := &cryptolib.Signature{} + err = proto.Unmarshal(signature, sig) + if err != nil { + return err + } + + disclosure := make([]byte, len(attributes)) + attrValues := make([]*FP256BN.BIG, len(attributes)) + for i := 0; i < len(attributes); i++ { + switch attributes[i].Type { + case bccsp.IdemixHiddenAttribute: + disclosure[i] = 0 + attrValues[i] = nil + case bccsp.IdemixBytesAttribute: + disclosure[i] = 1 + attrValues[i] = cryptolib.HashModOrder(attributes[i].Value.([]byte)) + case bccsp.IdemixIntAttribute: + disclosure[i] = 1 + attrValues[i] = FP256BN.NewBIGint(attributes[i].Value.(int)) + default: + err = errors.Errorf("attribute type not allowed or supported [%v] at position [%d]", attributes[i].Type, i) + } + } + if err != nil { + return + } + + return sig.Ver( + disclosure, + iipk.PK, + digest, + attrValues, + rhIndex, + revocationPublicKey, + epoch) +} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/user.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/user.go new file mode 100644 index 000000000..a0300487f --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/bridge/user.go @@ -0,0 +1,86 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ +package bridge + +import ( + "github.com/hyperledger/fabric-amcl/amcl" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" + "github.com/hyperledger/fabric/bccsp/idemix/handlers" + cryptolib "github.com/hyperledger/fabric/idemix" + "github.com/pkg/errors" +) + +// User encapsulates the idemix algorithms to generate user secret keys and pseudonym. +type User struct { + NewRand func() *amcl.RAND +} + +// NewKey generates an idemix user secret key +func (u *User) NewKey() (res handlers.Big, err error) { + defer func() { + if r := recover(); r != nil { + res = nil + err = errors.Errorf("failure [%s]", r) + } + }() + + res = &Big{E: cryptolib.RandModOrder(u.NewRand())} + + return +} + +func (*User) NewKeyFromBytes(raw []byte) (res handlers.Big, err error) { + if len(raw) != int(FP256BN.MODBYTES) { + return nil, errors.Errorf("invalid length, expected [%d], got [%d]", FP256BN.MODBYTES, len(raw)) + } + + res = &Big{E: FP256BN.FromBytes(raw)} + + return +} + +// MakeNym generates a new pseudonym key-pair derived from the passed user secret key (sk) and issuer public key (ipk) +func (u *User) MakeNym(sk handlers.Big, ipk handlers.IssuerPublicKey) (r1 handlers.Ecp, r2 handlers.Big, err error) { + defer func() { + if r := recover(); r != nil { + r1 = nil + r2 = nil + err = errors.Errorf("failure [%s]", r) + } + }() + + isk, ok := sk.(*Big) + if !ok { + return nil, nil, errors.Errorf("invalid user secret key, expected *Big, got [%T]", sk) + } + iipk, ok := ipk.(*IssuerPublicKey) + if !ok { + return nil, nil, errors.Errorf("invalid issuer public key, expected *IssuerPublicKey, got [%T]", ipk) + } + + ecp, big := cryptolib.MakeNym(isk.E, iipk.PK, u.NewRand()) + + r1 = &Ecp{E: ecp} + r2 = &Big{E: big} + + return +} + +func (*User) NewPublicNymFromBytes(raw []byte) (r handlers.Ecp, err error) { + defer func() { + if r := recover(); r != nil { + r = nil + err = errors.Errorf("failure [%s]", r) + } + }() + + // raw is the concatenation of two big integers + lHalve := len(raw) / 2 + + r = &Ecp{E: FP256BN.NewECPbigs(FP256BN.FromBytes(raw[:lHalve]), FP256BN.FromBytes(raw[lHalve:]))} + + return +} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/cred.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/cred.go new file mode 100644 index 000000000..83e792819 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/cred.go @@ -0,0 +1,115 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ +package handlers + +import ( + "github.com/hyperledger/fabric/bccsp" + "github.com/pkg/errors" +) + +// CredentialRequestSigner produces credential requests +type CredentialRequestSigner struct { + // CredRequest implements the underlying cryptographic algorithms + CredRequest CredRequest +} + +func (c *CredentialRequestSigner) Sign(k bccsp.Key, digest []byte, opts bccsp.SignerOpts) ([]byte, error) { + userSecretKey, ok := k.(*userSecretKey) + if !ok { + return nil, errors.New("invalid key, expected *userSecretKey") + } + credentialRequestSignerOpts, ok := opts.(*bccsp.IdemixCredentialRequestSignerOpts) + if !ok { + return nil, errors.New("invalid options, expected *IdemixCredentialRequestSignerOpts") + } + if credentialRequestSignerOpts.IssuerPK == nil { + return nil, errors.New("invalid options, missing issuer public key") + } + issuerPK, ok := credentialRequestSignerOpts.IssuerPK.(*issuerPublicKey) + if !ok { + return nil, errors.New("invalid options, expected IssuerPK as *issuerPublicKey") + } + + return c.CredRequest.Sign(userSecretKey.sk, issuerPK.pk, credentialRequestSignerOpts.IssuerNonce) +} + +// CredentialRequestVerifier verifies credential requests +type CredentialRequestVerifier struct { + // CredRequest implements the underlying cryptographic algorithms + CredRequest CredRequest +} + +func (c *CredentialRequestVerifier) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (bool, error) { + issuerPublicKey, ok := k.(*issuerPublicKey) + if !ok { + return false, errors.New("invalid key, expected *issuerPublicKey") + } + credentialRequestSignerOpts, ok := opts.(*bccsp.IdemixCredentialRequestSignerOpts) + if !ok { + return false, errors.New("invalid options, expected *IdemixCredentialRequestSignerOpts") + } + + err := c.CredRequest.Verify(signature, issuerPublicKey.pk, credentialRequestSignerOpts.IssuerNonce) + if err != nil { + return false, err + } + + return true, nil +} + +type CredentialSigner struct { + Credential Credential +} + +func (s *CredentialSigner) Sign(k bccsp.Key, digest []byte, opts bccsp.SignerOpts) (signature []byte, err error) { + issuerSecretKey, ok := k.(*issuerSecretKey) + if !ok { + return nil, errors.New("invalid key, expected *issuerSecretKey") + } + credOpts, ok := opts.(*bccsp.IdemixCredentialSignerOpts) + if !ok { + return nil, errors.New("invalid options, expected *IdemixCredentialSignerOpts") + } + + signature, err = s.Credential.Sign(issuerSecretKey.sk, digest, credOpts.Attributes) + if err != nil { + return nil, err + } + + return +} + +type CredentialVerifier struct { + Credential Credential +} + +func (v *CredentialVerifier) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (valid bool, err error) { + userSecretKey, ok := k.(*userSecretKey) + if !ok { + return false, errors.New("invalid key, expected *userSecretKey") + } + credOpts, ok := opts.(*bccsp.IdemixCredentialSignerOpts) + if !ok { + return false, errors.New("invalid options, expected *IdemixCredentialSignerOpts") + } + if credOpts.IssuerPK == nil { + return false, errors.New("invalid options, missing issuer public key") + } + ipk, ok := credOpts.IssuerPK.(*issuerPublicKey) + if !ok { + return false, errors.New("invalid issuer public key, expected *issuerPublicKey") + } + if len(signature) == 0 { + return false, errors.New("invalid signature, it must not be empty") + } + + err = v.Credential.Verify(userSecretKey.sk, ipk.pk, signature, credOpts.Attributes) + if err != nil { + return false, err + } + + return true, nil +} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/idemix.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/idemix.go new file mode 100644 index 000000000..47fb51e37 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/idemix.go @@ -0,0 +1,162 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ +package handlers + +import ( + "crypto/ecdsa" + + "github.com/hyperledger/fabric/bccsp" +) + +// IssuerPublicKey is the issuer public key +type IssuerPublicKey interface { + + // Bytes returns the byte representation of this key + Bytes() ([]byte, error) + + // Hash returns the hash representation of this key. + // The output is supposed to be collision-resistant + Hash() []byte +} + +// IssuerPublicKey is the issuer secret key +type IssuerSecretKey interface { + + // Bytes returns the byte representation of this key + Bytes() ([]byte, error) + + // Public returns the corresponding public key + Public() IssuerPublicKey +} + +// Issuer is a local interface to decouple from the idemix implementation +type Issuer interface { + // NewKey generates a new idemix issuer key w.r.t the passed attribute names. + NewKey(AttributeNames []string) (IssuerSecretKey, error) + + // NewPublicKeyFromBytes converts the passed bytes to an Issuer public key + // It makes sure that the so obtained public key has the passed attributes, if specified + NewPublicKeyFromBytes(raw []byte, attributes []string) (IssuerPublicKey, error) +} + +// Big represent a big integer +type Big interface { + // Bytes returns the byte representation of this key + Bytes() ([]byte, error) +} + +// Ecp represents an elliptic curve point +type Ecp interface { + // Bytes returns the byte representation of this key + Bytes() ([]byte, error) +} + +// User is a local interface to decouple from the idemix implementation +type User interface { + // NewKey generates a new User secret key + NewKey() (Big, error) + + // NewKeyFromBytes converts the passed bytes to a User secret key + NewKeyFromBytes(raw []byte) (Big, error) + + // MakeNym creates a new unlinkable pseudonym + MakeNym(sk Big, key IssuerPublicKey) (Ecp, Big, error) + + // NewPublicNymFromBytes converts the passed bytes to a public nym + NewPublicNymFromBytes(raw []byte) (Ecp, error) +} + +// CredRequest is a local interface to decouple from the idemix implementation +// of the issuance of credential requests. +type CredRequest interface { + // Sign creates a new Credential Request, the first message of the interactive credential issuance protocol + // (from user to issuer) + Sign(sk Big, ipk IssuerPublicKey, nonce []byte) ([]byte, error) + + // Verify verifies the credential request + Verify(credRequest []byte, ipk IssuerPublicKey, nonce []byte) error +} + +// CredRequest is a local interface to decouple from the idemix implementation +// of the issuance of credentials. +type Credential interface { + + // Sign issues a new credential, which is the last step of the interactive issuance protocol + // All attribute values are added by the issuer at this step and then signed together with a commitment to + // the user's secret key from a credential request + Sign(key IssuerSecretKey, credentialRequest []byte, attributes []bccsp.IdemixAttribute) ([]byte, error) + + // Verify cryptographically verifies the credential by verifying the signature + // on the attribute values and user's secret key + Verify(sk Big, ipk IssuerPublicKey, credential []byte, attributes []bccsp.IdemixAttribute) error +} + +// Revocation is a local interface to decouple from the idemix implementation +// the revocation-related operations +type Revocation interface { + + // NewKey generates a long term signing key that will be used for revocation + NewKey() (*ecdsa.PrivateKey, error) + + // Sign creates the Credential Revocation Information for a certain time period (epoch). + // Users can use the CRI to prove that they are not revoked. + // Note that when not using revocation (i.e., alg = ALG_NO_REVOCATION), the entered unrevokedHandles are not used, + // and the resulting CRI can be used by any signer. + Sign(key *ecdsa.PrivateKey, unrevokedHandles [][]byte, epoch int, alg bccsp.RevocationAlgorithm) ([]byte, error) + + // Verify verifies that the revocation PK for a certain epoch is valid, + // by checking that it was signed with the long term revocation key. + // Note that even if we use no revocation (i.e., alg = ALG_NO_REVOCATION), we need + // to verify the signature to make sure the issuer indeed signed that no revocation + // is used in this epoch. + Verify(pk *ecdsa.PublicKey, cri []byte, epoch int, alg bccsp.RevocationAlgorithm) error +} + +// SignatureScheme is a local interface to decouple from the idemix implementation +// the sign-related operations +type SignatureScheme interface { + // Sign creates a new idemix signature (Schnorr-type signature). + // The attributes slice steers which attributes are disclosed: + // If attributes[i].Type == bccsp.IdemixHiddenAttribute then attribute i remains hidden and otherwise it is disclosed. + // We require the revocation handle to remain undisclosed (i.e., attributes[rhIndex] == bccsp.IdemixHiddenAttribute). + // Parameters are to be understood as follow: + // cred: the serialized version of an idemix credential; + // sk: the user secret key; + // (Nym, RNym): Nym key-pair; + // ipk: issuer public key; + // attributes: as described above; + // msg: the message to be signed; + // rhIndex: revocation handle index relative to attributes; + // cri: the serialized version of the Credential Revocation Information (it contains the epoch this signature + // is created in reference to). + Sign(cred []byte, sk Big, Nym Ecp, RNym Big, ipk IssuerPublicKey, attributes []bccsp.IdemixAttribute, + msg []byte, rhIndex int, cri []byte) ([]byte, error) + + // Verify verifies an idemix signature. + // The attribute slice steers which attributes it expects to be disclosed + // If attributes[i].Type == bccsp.IdemixHiddenAttribute then attribute i remains hidden and otherwise + // attributes[i].Value is expected to contain the disclosed attribute value. + // In other words, this function will check that if attribute i is disclosed, the i-th attribute equals attributes[i].Value. + // Parameters are to be understood as follow: + // ipk: issuer public key; + // signature: signature to verify; + // msg: message signed; + // attributes: as described above; + // rhIndex: revocation handle index relative to attributes; + // revocationPublicKey: revocation public key; + // epoch: revocation epoch. + Verify(ipk IssuerPublicKey, signature, msg []byte, attributes []bccsp.IdemixAttribute, rhIndex int, revocationPublicKey *ecdsa.PublicKey, epoch int) error +} + +// NymSignatureScheme is a local interface to decouple from the idemix implementation +// the nym sign-related operations +type NymSignatureScheme interface { + // Sign creates a new idemix pseudonym signature + Sign(sk Big, Nym Ecp, RNym Big, ipk IssuerPublicKey, digest []byte) ([]byte, error) + + // Verify verifies an idemix NymSignature + Verify(pk IssuerPublicKey, Nym Ecp, signature, digest []byte) error +} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/issuer.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/issuer.go new file mode 100644 index 000000000..b98efafbf --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/issuer.go @@ -0,0 +1,136 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ +package handlers + +import ( + "github.com/hyperledger/fabric/bccsp" + "github.com/pkg/errors" +) + +// issuerSecretKey contains the issuer secret key +// and implements the bccsp.Key interface +type issuerSecretKey struct { + // sk is the idemix reference to the issuer key + sk IssuerSecretKey + // exportable if true, sk can be exported via the Bytes function + exportable bool +} + +func NewIssuerSecretKey(sk IssuerSecretKey, exportable bool) *issuerSecretKey { + return &issuerSecretKey{sk: sk, exportable: exportable} +} + +func (k *issuerSecretKey) Bytes() ([]byte, error) { + if k.exportable { + return k.sk.Bytes() + } + + return nil, errors.New("not exportable") +} + +func (k *issuerSecretKey) SKI() []byte { + pk, err := k.PublicKey() + if err != nil { + return nil + } + + return pk.SKI() +} + +func (*issuerSecretKey) Symmetric() bool { + return false +} + +func (*issuerSecretKey) Private() bool { + return true +} + +func (k *issuerSecretKey) PublicKey() (bccsp.Key, error) { + return &issuerPublicKey{k.sk.Public()}, nil +} + +// issuerPublicKey contains the issuer public key +// and implements the bccsp.Key interface +type issuerPublicKey struct { + pk IssuerPublicKey +} + +func NewIssuerPublicKey(pk IssuerPublicKey) *issuerPublicKey { + return &issuerPublicKey{pk} +} + +func (k *issuerPublicKey) Bytes() ([]byte, error) { + return k.pk.Bytes() +} + +func (k *issuerPublicKey) SKI() []byte { + return k.pk.Hash() +} + +func (*issuerPublicKey) Symmetric() bool { + return false +} + +func (*issuerPublicKey) Private() bool { + return false +} + +func (k *issuerPublicKey) PublicKey() (bccsp.Key, error) { + return k, nil +} + +// IssuerKeyGen generates issuer secret keys. +type IssuerKeyGen struct { + // exportable is a flag to allow an issuer secret key to be marked as exportable. + // If a secret key is marked as exportable, its Bytes method will return the key's byte representation. + Exportable bool + // Issuer implements the underlying cryptographic algorithms + Issuer Issuer +} + +func (g *IssuerKeyGen) KeyGen(opts bccsp.KeyGenOpts) (k bccsp.Key, err error) { + o, ok := opts.(*bccsp.IdemixIssuerKeyGenOpts) + if !ok { + return nil, errors.New("invalid options, expected *bccsp.IdemixIssuerKeyGenOpts") + } + + // Create a new key pair + key, err := g.Issuer.NewKey(o.AttributeNames) + if err != nil { + return nil, err + } + + return &issuerSecretKey{exportable: g.Exportable, sk: key}, nil +} + +// IssuerPublicKeyImporter imports issuer public keys +type IssuerPublicKeyImporter struct { + // Issuer implements the underlying cryptographic algorithms + Issuer Issuer +} + +func (i *IssuerPublicKeyImporter) KeyImport(raw interface{}, opts bccsp.KeyImportOpts) (k bccsp.Key, err error) { + der, ok := raw.([]byte) + if !ok { + return nil, errors.New("invalid raw, expected byte array") + } + + if len(der) == 0 { + return nil, errors.New("invalid raw, it must not be nil") + } + + o, ok := opts.(*bccsp.IdemixIssuerPublicKeyImportOpts) + if !ok { + return nil, errors.New("invalid options, expected *bccsp.IdemixIssuerPublicKeyImportOpts") + } + + pk, err := i.Issuer.NewPublicKeyFromBytes(raw.([]byte), o.AttributeNames) + if err != nil { + return nil, err + } + + return &issuerPublicKey{pk}, nil +} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/big.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/big.go new file mode 100644 index 000000000..5730fb807 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/big.go @@ -0,0 +1,93 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package mock + +import ( + "sync" + + "github.com/hyperledger/fabric/bccsp/idemix/handlers" +) + +type Big struct { + BytesStub func() ([]byte, error) + bytesMutex sync.RWMutex + bytesArgsForCall []struct{} + bytesReturns struct { + result1 []byte + result2 error + } + bytesReturnsOnCall map[int]struct { + result1 []byte + result2 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *Big) Bytes() ([]byte, error) { + fake.bytesMutex.Lock() + ret, specificReturn := fake.bytesReturnsOnCall[len(fake.bytesArgsForCall)] + fake.bytesArgsForCall = append(fake.bytesArgsForCall, struct{}{}) + fake.recordInvocation("Bytes", []interface{}{}) + fake.bytesMutex.Unlock() + if fake.BytesStub != nil { + return fake.BytesStub() + } + if specificReturn { + return ret.result1, ret.result2 + } + return fake.bytesReturns.result1, fake.bytesReturns.result2 +} + +func (fake *Big) BytesCallCount() int { + fake.bytesMutex.RLock() + defer fake.bytesMutex.RUnlock() + return len(fake.bytesArgsForCall) +} + +func (fake *Big) BytesReturns(result1 []byte, result2 error) { + fake.BytesStub = nil + fake.bytesReturns = struct { + result1 []byte + result2 error + }{result1, result2} +} + +func (fake *Big) BytesReturnsOnCall(i int, result1 []byte, result2 error) { + fake.BytesStub = nil + if fake.bytesReturnsOnCall == nil { + fake.bytesReturnsOnCall = make(map[int]struct { + result1 []byte + result2 error + }) + } + fake.bytesReturnsOnCall[i] = struct { + result1 []byte + result2 error + }{result1, result2} +} + +func (fake *Big) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.bytesMutex.RLock() + defer fake.bytesMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *Big) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ handlers.Big = new(Big) diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/credential.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/credential.go new file mode 100644 index 000000000..faccd9154 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/credential.go @@ -0,0 +1,195 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package mock + +import ( + "sync" + + "github.com/hyperledger/fabric/bccsp" + "github.com/hyperledger/fabric/bccsp/idemix/handlers" +) + +type Credential struct { + SignStub func(key handlers.IssuerSecretKey, credentialRequest []byte, attributes []bccsp.IdemixAttribute) ([]byte, error) + signMutex sync.RWMutex + signArgsForCall []struct { + key handlers.IssuerSecretKey + credentialRequest []byte + attributes []bccsp.IdemixAttribute + } + signReturns struct { + result1 []byte + result2 error + } + signReturnsOnCall map[int]struct { + result1 []byte + result2 error + } + VerifyStub func(sk handlers.Big, ipk handlers.IssuerPublicKey, credential []byte, attributes []bccsp.IdemixAttribute) error + verifyMutex sync.RWMutex + verifyArgsForCall []struct { + sk handlers.Big + ipk handlers.IssuerPublicKey + credential []byte + attributes []bccsp.IdemixAttribute + } + verifyReturns struct { + result1 error + } + verifyReturnsOnCall map[int]struct { + result1 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *Credential) Sign(key handlers.IssuerSecretKey, credentialRequest []byte, attributes []bccsp.IdemixAttribute) ([]byte, error) { + var credentialRequestCopy []byte + if credentialRequest != nil { + credentialRequestCopy = make([]byte, len(credentialRequest)) + copy(credentialRequestCopy, credentialRequest) + } + var attributesCopy []bccsp.IdemixAttribute + if attributes != nil { + attributesCopy = make([]bccsp.IdemixAttribute, len(attributes)) + copy(attributesCopy, attributes) + } + fake.signMutex.Lock() + ret, specificReturn := fake.signReturnsOnCall[len(fake.signArgsForCall)] + fake.signArgsForCall = append(fake.signArgsForCall, struct { + key handlers.IssuerSecretKey + credentialRequest []byte + attributes []bccsp.IdemixAttribute + }{key, credentialRequestCopy, attributesCopy}) + fake.recordInvocation("Sign", []interface{}{key, credentialRequestCopy, attributesCopy}) + fake.signMutex.Unlock() + if fake.SignStub != nil { + return fake.SignStub(key, credentialRequest, attributes) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fake.signReturns.result1, fake.signReturns.result2 +} + +func (fake *Credential) SignCallCount() int { + fake.signMutex.RLock() + defer fake.signMutex.RUnlock() + return len(fake.signArgsForCall) +} + +func (fake *Credential) SignArgsForCall(i int) (handlers.IssuerSecretKey, []byte, []bccsp.IdemixAttribute) { + fake.signMutex.RLock() + defer fake.signMutex.RUnlock() + return fake.signArgsForCall[i].key, fake.signArgsForCall[i].credentialRequest, fake.signArgsForCall[i].attributes +} + +func (fake *Credential) SignReturns(result1 []byte, result2 error) { + fake.SignStub = nil + fake.signReturns = struct { + result1 []byte + result2 error + }{result1, result2} +} + +func (fake *Credential) SignReturnsOnCall(i int, result1 []byte, result2 error) { + fake.SignStub = nil + if fake.signReturnsOnCall == nil { + fake.signReturnsOnCall = make(map[int]struct { + result1 []byte + result2 error + }) + } + fake.signReturnsOnCall[i] = struct { + result1 []byte + result2 error + }{result1, result2} +} + +func (fake *Credential) Verify(sk handlers.Big, ipk handlers.IssuerPublicKey, credential []byte, attributes []bccsp.IdemixAttribute) error { + var credentialCopy []byte + if credential != nil { + credentialCopy = make([]byte, len(credential)) + copy(credentialCopy, credential) + } + var attributesCopy []bccsp.IdemixAttribute + if attributes != nil { + attributesCopy = make([]bccsp.IdemixAttribute, len(attributes)) + copy(attributesCopy, attributes) + } + fake.verifyMutex.Lock() + ret, specificReturn := fake.verifyReturnsOnCall[len(fake.verifyArgsForCall)] + fake.verifyArgsForCall = append(fake.verifyArgsForCall, struct { + sk handlers.Big + ipk handlers.IssuerPublicKey + credential []byte + attributes []bccsp.IdemixAttribute + }{sk, ipk, credentialCopy, attributesCopy}) + fake.recordInvocation("Verify", []interface{}{sk, ipk, credentialCopy, attributesCopy}) + fake.verifyMutex.Unlock() + if fake.VerifyStub != nil { + return fake.VerifyStub(sk, ipk, credential, attributes) + } + if specificReturn { + return ret.result1 + } + return fake.verifyReturns.result1 +} + +func (fake *Credential) VerifyCallCount() int { + fake.verifyMutex.RLock() + defer fake.verifyMutex.RUnlock() + return len(fake.verifyArgsForCall) +} + +func (fake *Credential) VerifyArgsForCall(i int) (handlers.Big, handlers.IssuerPublicKey, []byte, []bccsp.IdemixAttribute) { + fake.verifyMutex.RLock() + defer fake.verifyMutex.RUnlock() + return fake.verifyArgsForCall[i].sk, fake.verifyArgsForCall[i].ipk, fake.verifyArgsForCall[i].credential, fake.verifyArgsForCall[i].attributes +} + +func (fake *Credential) VerifyReturns(result1 error) { + fake.VerifyStub = nil + fake.verifyReturns = struct { + result1 error + }{result1} +} + +func (fake *Credential) VerifyReturnsOnCall(i int, result1 error) { + fake.VerifyStub = nil + if fake.verifyReturnsOnCall == nil { + fake.verifyReturnsOnCall = make(map[int]struct { + result1 error + }) + } + fake.verifyReturnsOnCall[i] = struct { + result1 error + }{result1} +} + +func (fake *Credential) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.signMutex.RLock() + defer fake.signMutex.RUnlock() + fake.verifyMutex.RLock() + defer fake.verifyMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *Credential) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ handlers.Credential = new(Credential) diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/credrequest.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/credrequest.go new file mode 100644 index 000000000..caeaa087f --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/credrequest.go @@ -0,0 +1,187 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package mock + +import ( + "sync" + + "github.com/hyperledger/fabric/bccsp/idemix/handlers" +) + +type CredRequest struct { + SignStub func(sk handlers.Big, ipk handlers.IssuerPublicKey, nonce []byte) ([]byte, error) + signMutex sync.RWMutex + signArgsForCall []struct { + sk handlers.Big + ipk handlers.IssuerPublicKey + nonce []byte + } + signReturns struct { + result1 []byte + result2 error + } + signReturnsOnCall map[int]struct { + result1 []byte + result2 error + } + VerifyStub func(credRequest []byte, ipk handlers.IssuerPublicKey, nonce []byte) error + verifyMutex sync.RWMutex + verifyArgsForCall []struct { + credRequest []byte + ipk handlers.IssuerPublicKey + nonce []byte + } + verifyReturns struct { + result1 error + } + verifyReturnsOnCall map[int]struct { + result1 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *CredRequest) Sign(sk handlers.Big, ipk handlers.IssuerPublicKey, nonce []byte) ([]byte, error) { + var nonceCopy []byte + if nonce != nil { + nonceCopy = make([]byte, len(nonce)) + copy(nonceCopy, nonce) + } + fake.signMutex.Lock() + ret, specificReturn := fake.signReturnsOnCall[len(fake.signArgsForCall)] + fake.signArgsForCall = append(fake.signArgsForCall, struct { + sk handlers.Big + ipk handlers.IssuerPublicKey + nonce []byte + }{sk, ipk, nonceCopy}) + fake.recordInvocation("Sign", []interface{}{sk, ipk, nonceCopy}) + fake.signMutex.Unlock() + if fake.SignStub != nil { + return fake.SignStub(sk, ipk, nonce) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fake.signReturns.result1, fake.signReturns.result2 +} + +func (fake *CredRequest) SignCallCount() int { + fake.signMutex.RLock() + defer fake.signMutex.RUnlock() + return len(fake.signArgsForCall) +} + +func (fake *CredRequest) SignArgsForCall(i int) (handlers.Big, handlers.IssuerPublicKey, []byte) { + fake.signMutex.RLock() + defer fake.signMutex.RUnlock() + return fake.signArgsForCall[i].sk, fake.signArgsForCall[i].ipk, fake.signArgsForCall[i].nonce +} + +func (fake *CredRequest) SignReturns(result1 []byte, result2 error) { + fake.SignStub = nil + fake.signReturns = struct { + result1 []byte + result2 error + }{result1, result2} +} + +func (fake *CredRequest) SignReturnsOnCall(i int, result1 []byte, result2 error) { + fake.SignStub = nil + if fake.signReturnsOnCall == nil { + fake.signReturnsOnCall = make(map[int]struct { + result1 []byte + result2 error + }) + } + fake.signReturnsOnCall[i] = struct { + result1 []byte + result2 error + }{result1, result2} +} + +func (fake *CredRequest) Verify(credRequest []byte, ipk handlers.IssuerPublicKey, nonce []byte) error { + var credRequestCopy []byte + if credRequest != nil { + credRequestCopy = make([]byte, len(credRequest)) + copy(credRequestCopy, credRequest) + } + var nonceCopy []byte + if nonce != nil { + nonceCopy = make([]byte, len(nonce)) + copy(nonceCopy, nonce) + } + fake.verifyMutex.Lock() + ret, specificReturn := fake.verifyReturnsOnCall[len(fake.verifyArgsForCall)] + fake.verifyArgsForCall = append(fake.verifyArgsForCall, struct { + credRequest []byte + ipk handlers.IssuerPublicKey + nonce []byte + }{credRequestCopy, ipk, nonceCopy}) + fake.recordInvocation("Verify", []interface{}{credRequestCopy, ipk, nonceCopy}) + fake.verifyMutex.Unlock() + if fake.VerifyStub != nil { + return fake.VerifyStub(credRequest, ipk, nonce) + } + if specificReturn { + return ret.result1 + } + return fake.verifyReturns.result1 +} + +func (fake *CredRequest) VerifyCallCount() int { + fake.verifyMutex.RLock() + defer fake.verifyMutex.RUnlock() + return len(fake.verifyArgsForCall) +} + +func (fake *CredRequest) VerifyArgsForCall(i int) ([]byte, handlers.IssuerPublicKey, []byte) { + fake.verifyMutex.RLock() + defer fake.verifyMutex.RUnlock() + return fake.verifyArgsForCall[i].credRequest, fake.verifyArgsForCall[i].ipk, fake.verifyArgsForCall[i].nonce +} + +func (fake *CredRequest) VerifyReturns(result1 error) { + fake.VerifyStub = nil + fake.verifyReturns = struct { + result1 error + }{result1} +} + +func (fake *CredRequest) VerifyReturnsOnCall(i int, result1 error) { + fake.VerifyStub = nil + if fake.verifyReturnsOnCall == nil { + fake.verifyReturnsOnCall = make(map[int]struct { + result1 error + }) + } + fake.verifyReturnsOnCall[i] = struct { + result1 error + }{result1} +} + +func (fake *CredRequest) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.signMutex.RLock() + defer fake.signMutex.RUnlock() + fake.verifyMutex.RLock() + defer fake.verifyMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *CredRequest) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ handlers.CredRequest = new(CredRequest) diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/ecp.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/ecp.go new file mode 100644 index 000000000..90db59f07 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/ecp.go @@ -0,0 +1,93 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package mock + +import ( + "sync" + + "github.com/hyperledger/fabric/bccsp/idemix/handlers" +) + +type Ecp struct { + BytesStub func() ([]byte, error) + bytesMutex sync.RWMutex + bytesArgsForCall []struct{} + bytesReturns struct { + result1 []byte + result2 error + } + bytesReturnsOnCall map[int]struct { + result1 []byte + result2 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *Ecp) Bytes() ([]byte, error) { + fake.bytesMutex.Lock() + ret, specificReturn := fake.bytesReturnsOnCall[len(fake.bytesArgsForCall)] + fake.bytesArgsForCall = append(fake.bytesArgsForCall, struct{}{}) + fake.recordInvocation("Bytes", []interface{}{}) + fake.bytesMutex.Unlock() + if fake.BytesStub != nil { + return fake.BytesStub() + } + if specificReturn { + return ret.result1, ret.result2 + } + return fake.bytesReturns.result1, fake.bytesReturns.result2 +} + +func (fake *Ecp) BytesCallCount() int { + fake.bytesMutex.RLock() + defer fake.bytesMutex.RUnlock() + return len(fake.bytesArgsForCall) +} + +func (fake *Ecp) BytesReturns(result1 []byte, result2 error) { + fake.BytesStub = nil + fake.bytesReturns = struct { + result1 []byte + result2 error + }{result1, result2} +} + +func (fake *Ecp) BytesReturnsOnCall(i int, result1 []byte, result2 error) { + fake.BytesStub = nil + if fake.bytesReturnsOnCall == nil { + fake.bytesReturnsOnCall = make(map[int]struct { + result1 []byte + result2 error + }) + } + fake.bytesReturnsOnCall[i] = struct { + result1 []byte + result2 error + }{result1, result2} +} + +func (fake *Ecp) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.bytesMutex.RLock() + defer fake.bytesMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *Ecp) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ handlers.Ecp = new(Ecp) diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/issuer.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/issuer.go new file mode 100644 index 000000000..fd48f1c4c --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/issuer.go @@ -0,0 +1,186 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package mock + +import ( + "sync" + + "github.com/hyperledger/fabric/bccsp/idemix/handlers" +) + +type Issuer struct { + NewKeyStub func(AttributeNames []string) (handlers.IssuerSecretKey, error) + newKeyMutex sync.RWMutex + newKeyArgsForCall []struct { + AttributeNames []string + } + newKeyReturns struct { + result1 handlers.IssuerSecretKey + result2 error + } + newKeyReturnsOnCall map[int]struct { + result1 handlers.IssuerSecretKey + result2 error + } + NewPublicKeyFromBytesStub func(raw []byte, attributes []string) (handlers.IssuerPublicKey, error) + newPublicKeyFromBytesMutex sync.RWMutex + newPublicKeyFromBytesArgsForCall []struct { + raw []byte + attributes []string + } + newPublicKeyFromBytesReturns struct { + result1 handlers.IssuerPublicKey + result2 error + } + newPublicKeyFromBytesReturnsOnCall map[int]struct { + result1 handlers.IssuerPublicKey + result2 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *Issuer) NewKey(AttributeNames []string) (handlers.IssuerSecretKey, error) { + var AttributeNamesCopy []string + if AttributeNames != nil { + AttributeNamesCopy = make([]string, len(AttributeNames)) + copy(AttributeNamesCopy, AttributeNames) + } + fake.newKeyMutex.Lock() + ret, specificReturn := fake.newKeyReturnsOnCall[len(fake.newKeyArgsForCall)] + fake.newKeyArgsForCall = append(fake.newKeyArgsForCall, struct { + AttributeNames []string + }{AttributeNamesCopy}) + fake.recordInvocation("NewKey", []interface{}{AttributeNamesCopy}) + fake.newKeyMutex.Unlock() + if fake.NewKeyStub != nil { + return fake.NewKeyStub(AttributeNames) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fake.newKeyReturns.result1, fake.newKeyReturns.result2 +} + +func (fake *Issuer) NewKeyCallCount() int { + fake.newKeyMutex.RLock() + defer fake.newKeyMutex.RUnlock() + return len(fake.newKeyArgsForCall) +} + +func (fake *Issuer) NewKeyArgsForCall(i int) []string { + fake.newKeyMutex.RLock() + defer fake.newKeyMutex.RUnlock() + return fake.newKeyArgsForCall[i].AttributeNames +} + +func (fake *Issuer) NewKeyReturns(result1 handlers.IssuerSecretKey, result2 error) { + fake.NewKeyStub = nil + fake.newKeyReturns = struct { + result1 handlers.IssuerSecretKey + result2 error + }{result1, result2} +} + +func (fake *Issuer) NewKeyReturnsOnCall(i int, result1 handlers.IssuerSecretKey, result2 error) { + fake.NewKeyStub = nil + if fake.newKeyReturnsOnCall == nil { + fake.newKeyReturnsOnCall = make(map[int]struct { + result1 handlers.IssuerSecretKey + result2 error + }) + } + fake.newKeyReturnsOnCall[i] = struct { + result1 handlers.IssuerSecretKey + result2 error + }{result1, result2} +} + +func (fake *Issuer) NewPublicKeyFromBytes(raw []byte, attributes []string) (handlers.IssuerPublicKey, error) { + var rawCopy []byte + if raw != nil { + rawCopy = make([]byte, len(raw)) + copy(rawCopy, raw) + } + var attributesCopy []string + if attributes != nil { + attributesCopy = make([]string, len(attributes)) + copy(attributesCopy, attributes) + } + fake.newPublicKeyFromBytesMutex.Lock() + ret, specificReturn := fake.newPublicKeyFromBytesReturnsOnCall[len(fake.newPublicKeyFromBytesArgsForCall)] + fake.newPublicKeyFromBytesArgsForCall = append(fake.newPublicKeyFromBytesArgsForCall, struct { + raw []byte + attributes []string + }{rawCopy, attributesCopy}) + fake.recordInvocation("NewPublicKeyFromBytes", []interface{}{rawCopy, attributesCopy}) + fake.newPublicKeyFromBytesMutex.Unlock() + if fake.NewPublicKeyFromBytesStub != nil { + return fake.NewPublicKeyFromBytesStub(raw, attributes) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fake.newPublicKeyFromBytesReturns.result1, fake.newPublicKeyFromBytesReturns.result2 +} + +func (fake *Issuer) NewPublicKeyFromBytesCallCount() int { + fake.newPublicKeyFromBytesMutex.RLock() + defer fake.newPublicKeyFromBytesMutex.RUnlock() + return len(fake.newPublicKeyFromBytesArgsForCall) +} + +func (fake *Issuer) NewPublicKeyFromBytesArgsForCall(i int) ([]byte, []string) { + fake.newPublicKeyFromBytesMutex.RLock() + defer fake.newPublicKeyFromBytesMutex.RUnlock() + return fake.newPublicKeyFromBytesArgsForCall[i].raw, fake.newPublicKeyFromBytesArgsForCall[i].attributes +} + +func (fake *Issuer) NewPublicKeyFromBytesReturns(result1 handlers.IssuerPublicKey, result2 error) { + fake.NewPublicKeyFromBytesStub = nil + fake.newPublicKeyFromBytesReturns = struct { + result1 handlers.IssuerPublicKey + result2 error + }{result1, result2} +} + +func (fake *Issuer) NewPublicKeyFromBytesReturnsOnCall(i int, result1 handlers.IssuerPublicKey, result2 error) { + fake.NewPublicKeyFromBytesStub = nil + if fake.newPublicKeyFromBytesReturnsOnCall == nil { + fake.newPublicKeyFromBytesReturnsOnCall = make(map[int]struct { + result1 handlers.IssuerPublicKey + result2 error + }) + } + fake.newPublicKeyFromBytesReturnsOnCall[i] = struct { + result1 handlers.IssuerPublicKey + result2 error + }{result1, result2} +} + +func (fake *Issuer) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.newKeyMutex.RLock() + defer fake.newKeyMutex.RUnlock() + fake.newPublicKeyFromBytesMutex.RLock() + defer fake.newPublicKeyFromBytesMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *Issuer) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ handlers.Issuer = new(Issuer) diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/issuer_public_key.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/issuer_public_key.go new file mode 100644 index 000000000..cb7dd5c22 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/issuer_public_key.go @@ -0,0 +1,144 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package mock + +import ( + "sync" + + "github.com/hyperledger/fabric/bccsp/idemix/handlers" +) + +type IssuerPublicKey struct { + BytesStub func() ([]byte, error) + bytesMutex sync.RWMutex + bytesArgsForCall []struct{} + bytesReturns struct { + result1 []byte + result2 error + } + bytesReturnsOnCall map[int]struct { + result1 []byte + result2 error + } + HashStub func() []byte + hashMutex sync.RWMutex + hashArgsForCall []struct{} + hashReturns struct { + result1 []byte + } + hashReturnsOnCall map[int]struct { + result1 []byte + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *IssuerPublicKey) Bytes() ([]byte, error) { + fake.bytesMutex.Lock() + ret, specificReturn := fake.bytesReturnsOnCall[len(fake.bytesArgsForCall)] + fake.bytesArgsForCall = append(fake.bytesArgsForCall, struct{}{}) + fake.recordInvocation("Bytes", []interface{}{}) + fake.bytesMutex.Unlock() + if fake.BytesStub != nil { + return fake.BytesStub() + } + if specificReturn { + return ret.result1, ret.result2 + } + return fake.bytesReturns.result1, fake.bytesReturns.result2 +} + +func (fake *IssuerPublicKey) BytesCallCount() int { + fake.bytesMutex.RLock() + defer fake.bytesMutex.RUnlock() + return len(fake.bytesArgsForCall) +} + +func (fake *IssuerPublicKey) BytesReturns(result1 []byte, result2 error) { + fake.BytesStub = nil + fake.bytesReturns = struct { + result1 []byte + result2 error + }{result1, result2} +} + +func (fake *IssuerPublicKey) BytesReturnsOnCall(i int, result1 []byte, result2 error) { + fake.BytesStub = nil + if fake.bytesReturnsOnCall == nil { + fake.bytesReturnsOnCall = make(map[int]struct { + result1 []byte + result2 error + }) + } + fake.bytesReturnsOnCall[i] = struct { + result1 []byte + result2 error + }{result1, result2} +} + +func (fake *IssuerPublicKey) Hash() []byte { + fake.hashMutex.Lock() + ret, specificReturn := fake.hashReturnsOnCall[len(fake.hashArgsForCall)] + fake.hashArgsForCall = append(fake.hashArgsForCall, struct{}{}) + fake.recordInvocation("Hash", []interface{}{}) + fake.hashMutex.Unlock() + if fake.HashStub != nil { + return fake.HashStub() + } + if specificReturn { + return ret.result1 + } + return fake.hashReturns.result1 +} + +func (fake *IssuerPublicKey) HashCallCount() int { + fake.hashMutex.RLock() + defer fake.hashMutex.RUnlock() + return len(fake.hashArgsForCall) +} + +func (fake *IssuerPublicKey) HashReturns(result1 []byte) { + fake.HashStub = nil + fake.hashReturns = struct { + result1 []byte + }{result1} +} + +func (fake *IssuerPublicKey) HashReturnsOnCall(i int, result1 []byte) { + fake.HashStub = nil + if fake.hashReturnsOnCall == nil { + fake.hashReturnsOnCall = make(map[int]struct { + result1 []byte + }) + } + fake.hashReturnsOnCall[i] = struct { + result1 []byte + }{result1} +} + +func (fake *IssuerPublicKey) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.bytesMutex.RLock() + defer fake.bytesMutex.RUnlock() + fake.hashMutex.RLock() + defer fake.hashMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *IssuerPublicKey) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ handlers.IssuerPublicKey = new(IssuerPublicKey) diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/issuer_secret_key.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/issuer_secret_key.go new file mode 100644 index 000000000..d73557992 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/issuer_secret_key.go @@ -0,0 +1,144 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package mock + +import ( + "sync" + + "github.com/hyperledger/fabric/bccsp/idemix/handlers" +) + +type IssuerSecretKey struct { + BytesStub func() ([]byte, error) + bytesMutex sync.RWMutex + bytesArgsForCall []struct{} + bytesReturns struct { + result1 []byte + result2 error + } + bytesReturnsOnCall map[int]struct { + result1 []byte + result2 error + } + PublicStub func() handlers.IssuerPublicKey + publicMutex sync.RWMutex + publicArgsForCall []struct{} + publicReturns struct { + result1 handlers.IssuerPublicKey + } + publicReturnsOnCall map[int]struct { + result1 handlers.IssuerPublicKey + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *IssuerSecretKey) Bytes() ([]byte, error) { + fake.bytesMutex.Lock() + ret, specificReturn := fake.bytesReturnsOnCall[len(fake.bytesArgsForCall)] + fake.bytesArgsForCall = append(fake.bytesArgsForCall, struct{}{}) + fake.recordInvocation("Bytes", []interface{}{}) + fake.bytesMutex.Unlock() + if fake.BytesStub != nil { + return fake.BytesStub() + } + if specificReturn { + return ret.result1, ret.result2 + } + return fake.bytesReturns.result1, fake.bytesReturns.result2 +} + +func (fake *IssuerSecretKey) BytesCallCount() int { + fake.bytesMutex.RLock() + defer fake.bytesMutex.RUnlock() + return len(fake.bytesArgsForCall) +} + +func (fake *IssuerSecretKey) BytesReturns(result1 []byte, result2 error) { + fake.BytesStub = nil + fake.bytesReturns = struct { + result1 []byte + result2 error + }{result1, result2} +} + +func (fake *IssuerSecretKey) BytesReturnsOnCall(i int, result1 []byte, result2 error) { + fake.BytesStub = nil + if fake.bytesReturnsOnCall == nil { + fake.bytesReturnsOnCall = make(map[int]struct { + result1 []byte + result2 error + }) + } + fake.bytesReturnsOnCall[i] = struct { + result1 []byte + result2 error + }{result1, result2} +} + +func (fake *IssuerSecretKey) Public() handlers.IssuerPublicKey { + fake.publicMutex.Lock() + ret, specificReturn := fake.publicReturnsOnCall[len(fake.publicArgsForCall)] + fake.publicArgsForCall = append(fake.publicArgsForCall, struct{}{}) + fake.recordInvocation("Public", []interface{}{}) + fake.publicMutex.Unlock() + if fake.PublicStub != nil { + return fake.PublicStub() + } + if specificReturn { + return ret.result1 + } + return fake.publicReturns.result1 +} + +func (fake *IssuerSecretKey) PublicCallCount() int { + fake.publicMutex.RLock() + defer fake.publicMutex.RUnlock() + return len(fake.publicArgsForCall) +} + +func (fake *IssuerSecretKey) PublicReturns(result1 handlers.IssuerPublicKey) { + fake.PublicStub = nil + fake.publicReturns = struct { + result1 handlers.IssuerPublicKey + }{result1} +} + +func (fake *IssuerSecretKey) PublicReturnsOnCall(i int, result1 handlers.IssuerPublicKey) { + fake.PublicStub = nil + if fake.publicReturnsOnCall == nil { + fake.publicReturnsOnCall = make(map[int]struct { + result1 handlers.IssuerPublicKey + }) + } + fake.publicReturnsOnCall[i] = struct { + result1 handlers.IssuerPublicKey + }{result1} +} + +func (fake *IssuerSecretKey) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.bytesMutex.RLock() + defer fake.bytesMutex.RUnlock() + fake.publicMutex.RLock() + defer fake.publicMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *IssuerSecretKey) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ handlers.IssuerSecretKey = new(IssuerSecretKey) diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/nymsignature_scheme.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/nymsignature_scheme.go new file mode 100644 index 000000000..358dd27e4 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/nymsignature_scheme.go @@ -0,0 +1,193 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package mock + +import ( + "sync" + + "github.com/hyperledger/fabric/bccsp/idemix/handlers" +) + +type NymSignatureScheme struct { + SignStub func(sk handlers.Big, Nym handlers.Ecp, RNym handlers.Big, ipk handlers.IssuerPublicKey, digest []byte) ([]byte, error) + signMutex sync.RWMutex + signArgsForCall []struct { + sk handlers.Big + Nym handlers.Ecp + RNym handlers.Big + ipk handlers.IssuerPublicKey + digest []byte + } + signReturns struct { + result1 []byte + result2 error + } + signReturnsOnCall map[int]struct { + result1 []byte + result2 error + } + VerifyStub func(pk handlers.IssuerPublicKey, Nym handlers.Ecp, signature, digest []byte) error + verifyMutex sync.RWMutex + verifyArgsForCall []struct { + pk handlers.IssuerPublicKey + Nym handlers.Ecp + signature []byte + digest []byte + } + verifyReturns struct { + result1 error + } + verifyReturnsOnCall map[int]struct { + result1 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *NymSignatureScheme) Sign(sk handlers.Big, Nym handlers.Ecp, RNym handlers.Big, ipk handlers.IssuerPublicKey, digest []byte) ([]byte, error) { + var digestCopy []byte + if digest != nil { + digestCopy = make([]byte, len(digest)) + copy(digestCopy, digest) + } + fake.signMutex.Lock() + ret, specificReturn := fake.signReturnsOnCall[len(fake.signArgsForCall)] + fake.signArgsForCall = append(fake.signArgsForCall, struct { + sk handlers.Big + Nym handlers.Ecp + RNym handlers.Big + ipk handlers.IssuerPublicKey + digest []byte + }{sk, Nym, RNym, ipk, digestCopy}) + fake.recordInvocation("Sign", []interface{}{sk, Nym, RNym, ipk, digestCopy}) + fake.signMutex.Unlock() + if fake.SignStub != nil { + return fake.SignStub(sk, Nym, RNym, ipk, digest) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fake.signReturns.result1, fake.signReturns.result2 +} + +func (fake *NymSignatureScheme) SignCallCount() int { + fake.signMutex.RLock() + defer fake.signMutex.RUnlock() + return len(fake.signArgsForCall) +} + +func (fake *NymSignatureScheme) SignArgsForCall(i int) (handlers.Big, handlers.Ecp, handlers.Big, handlers.IssuerPublicKey, []byte) { + fake.signMutex.RLock() + defer fake.signMutex.RUnlock() + return fake.signArgsForCall[i].sk, fake.signArgsForCall[i].Nym, fake.signArgsForCall[i].RNym, fake.signArgsForCall[i].ipk, fake.signArgsForCall[i].digest +} + +func (fake *NymSignatureScheme) SignReturns(result1 []byte, result2 error) { + fake.SignStub = nil + fake.signReturns = struct { + result1 []byte + result2 error + }{result1, result2} +} + +func (fake *NymSignatureScheme) SignReturnsOnCall(i int, result1 []byte, result2 error) { + fake.SignStub = nil + if fake.signReturnsOnCall == nil { + fake.signReturnsOnCall = make(map[int]struct { + result1 []byte + result2 error + }) + } + fake.signReturnsOnCall[i] = struct { + result1 []byte + result2 error + }{result1, result2} +} + +func (fake *NymSignatureScheme) Verify(pk handlers.IssuerPublicKey, Nym handlers.Ecp, signature []byte, digest []byte) error { + var signatureCopy []byte + if signature != nil { + signatureCopy = make([]byte, len(signature)) + copy(signatureCopy, signature) + } + var digestCopy []byte + if digest != nil { + digestCopy = make([]byte, len(digest)) + copy(digestCopy, digest) + } + fake.verifyMutex.Lock() + ret, specificReturn := fake.verifyReturnsOnCall[len(fake.verifyArgsForCall)] + fake.verifyArgsForCall = append(fake.verifyArgsForCall, struct { + pk handlers.IssuerPublicKey + Nym handlers.Ecp + signature []byte + digest []byte + }{pk, Nym, signatureCopy, digestCopy}) + fake.recordInvocation("Verify", []interface{}{pk, Nym, signatureCopy, digestCopy}) + fake.verifyMutex.Unlock() + if fake.VerifyStub != nil { + return fake.VerifyStub(pk, Nym, signature, digest) + } + if specificReturn { + return ret.result1 + } + return fake.verifyReturns.result1 +} + +func (fake *NymSignatureScheme) VerifyCallCount() int { + fake.verifyMutex.RLock() + defer fake.verifyMutex.RUnlock() + return len(fake.verifyArgsForCall) +} + +func (fake *NymSignatureScheme) VerifyArgsForCall(i int) (handlers.IssuerPublicKey, handlers.Ecp, []byte, []byte) { + fake.verifyMutex.RLock() + defer fake.verifyMutex.RUnlock() + return fake.verifyArgsForCall[i].pk, fake.verifyArgsForCall[i].Nym, fake.verifyArgsForCall[i].signature, fake.verifyArgsForCall[i].digest +} + +func (fake *NymSignatureScheme) VerifyReturns(result1 error) { + fake.VerifyStub = nil + fake.verifyReturns = struct { + result1 error + }{result1} +} + +func (fake *NymSignatureScheme) VerifyReturnsOnCall(i int, result1 error) { + fake.VerifyStub = nil + if fake.verifyReturnsOnCall == nil { + fake.verifyReturnsOnCall = make(map[int]struct { + result1 error + }) + } + fake.verifyReturnsOnCall[i] = struct { + result1 error + }{result1} +} + +func (fake *NymSignatureScheme) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.signMutex.RLock() + defer fake.signMutex.RUnlock() + fake.verifyMutex.RLock() + defer fake.verifyMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *NymSignatureScheme) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ handlers.NymSignatureScheme = new(NymSignatureScheme) diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/revocation.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/revocation.go new file mode 100644 index 000000000..0b71708ce --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/revocation.go @@ -0,0 +1,244 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package mock + +import ( + "crypto/ecdsa" + "sync" + + "github.com/hyperledger/fabric/bccsp" + "github.com/hyperledger/fabric/bccsp/idemix/handlers" +) + +type Revocation struct { + NewKeyStub func() (*ecdsa.PrivateKey, error) + newKeyMutex sync.RWMutex + newKeyArgsForCall []struct{} + newKeyReturns struct { + result1 *ecdsa.PrivateKey + result2 error + } + newKeyReturnsOnCall map[int]struct { + result1 *ecdsa.PrivateKey + result2 error + } + SignStub func(key *ecdsa.PrivateKey, unrevokedHandles [][]byte, epoch int, alg bccsp.RevocationAlgorithm) ([]byte, error) + signMutex sync.RWMutex + signArgsForCall []struct { + key *ecdsa.PrivateKey + unrevokedHandles [][]byte + epoch int + alg bccsp.RevocationAlgorithm + } + signReturns struct { + result1 []byte + result2 error + } + signReturnsOnCall map[int]struct { + result1 []byte + result2 error + } + VerifyStub func(pk *ecdsa.PublicKey, cri []byte, epoch int, alg bccsp.RevocationAlgorithm) error + verifyMutex sync.RWMutex + verifyArgsForCall []struct { + pk *ecdsa.PublicKey + cri []byte + epoch int + alg bccsp.RevocationAlgorithm + } + verifyReturns struct { + result1 error + } + verifyReturnsOnCall map[int]struct { + result1 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *Revocation) NewKey() (*ecdsa.PrivateKey, error) { + fake.newKeyMutex.Lock() + ret, specificReturn := fake.newKeyReturnsOnCall[len(fake.newKeyArgsForCall)] + fake.newKeyArgsForCall = append(fake.newKeyArgsForCall, struct{}{}) + fake.recordInvocation("NewKey", []interface{}{}) + fake.newKeyMutex.Unlock() + if fake.NewKeyStub != nil { + return fake.NewKeyStub() + } + if specificReturn { + return ret.result1, ret.result2 + } + return fake.newKeyReturns.result1, fake.newKeyReturns.result2 +} + +func (fake *Revocation) NewKeyCallCount() int { + fake.newKeyMutex.RLock() + defer fake.newKeyMutex.RUnlock() + return len(fake.newKeyArgsForCall) +} + +func (fake *Revocation) NewKeyReturns(result1 *ecdsa.PrivateKey, result2 error) { + fake.NewKeyStub = nil + fake.newKeyReturns = struct { + result1 *ecdsa.PrivateKey + result2 error + }{result1, result2} +} + +func (fake *Revocation) NewKeyReturnsOnCall(i int, result1 *ecdsa.PrivateKey, result2 error) { + fake.NewKeyStub = nil + if fake.newKeyReturnsOnCall == nil { + fake.newKeyReturnsOnCall = make(map[int]struct { + result1 *ecdsa.PrivateKey + result2 error + }) + } + fake.newKeyReturnsOnCall[i] = struct { + result1 *ecdsa.PrivateKey + result2 error + }{result1, result2} +} + +func (fake *Revocation) Sign(key *ecdsa.PrivateKey, unrevokedHandles [][]byte, epoch int, alg bccsp.RevocationAlgorithm) ([]byte, error) { + var unrevokedHandlesCopy [][]byte + if unrevokedHandles != nil { + unrevokedHandlesCopy = make([][]byte, len(unrevokedHandles)) + copy(unrevokedHandlesCopy, unrevokedHandles) + } + fake.signMutex.Lock() + ret, specificReturn := fake.signReturnsOnCall[len(fake.signArgsForCall)] + fake.signArgsForCall = append(fake.signArgsForCall, struct { + key *ecdsa.PrivateKey + unrevokedHandles [][]byte + epoch int + alg bccsp.RevocationAlgorithm + }{key, unrevokedHandlesCopy, epoch, alg}) + fake.recordInvocation("Sign", []interface{}{key, unrevokedHandlesCopy, epoch, alg}) + fake.signMutex.Unlock() + if fake.SignStub != nil { + return fake.SignStub(key, unrevokedHandles, epoch, alg) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fake.signReturns.result1, fake.signReturns.result2 +} + +func (fake *Revocation) SignCallCount() int { + fake.signMutex.RLock() + defer fake.signMutex.RUnlock() + return len(fake.signArgsForCall) +} + +func (fake *Revocation) SignArgsForCall(i int) (*ecdsa.PrivateKey, [][]byte, int, bccsp.RevocationAlgorithm) { + fake.signMutex.RLock() + defer fake.signMutex.RUnlock() + return fake.signArgsForCall[i].key, fake.signArgsForCall[i].unrevokedHandles, fake.signArgsForCall[i].epoch, fake.signArgsForCall[i].alg +} + +func (fake *Revocation) SignReturns(result1 []byte, result2 error) { + fake.SignStub = nil + fake.signReturns = struct { + result1 []byte + result2 error + }{result1, result2} +} + +func (fake *Revocation) SignReturnsOnCall(i int, result1 []byte, result2 error) { + fake.SignStub = nil + if fake.signReturnsOnCall == nil { + fake.signReturnsOnCall = make(map[int]struct { + result1 []byte + result2 error + }) + } + fake.signReturnsOnCall[i] = struct { + result1 []byte + result2 error + }{result1, result2} +} + +func (fake *Revocation) Verify(pk *ecdsa.PublicKey, cri []byte, epoch int, alg bccsp.RevocationAlgorithm) error { + var criCopy []byte + if cri != nil { + criCopy = make([]byte, len(cri)) + copy(criCopy, cri) + } + fake.verifyMutex.Lock() + ret, specificReturn := fake.verifyReturnsOnCall[len(fake.verifyArgsForCall)] + fake.verifyArgsForCall = append(fake.verifyArgsForCall, struct { + pk *ecdsa.PublicKey + cri []byte + epoch int + alg bccsp.RevocationAlgorithm + }{pk, criCopy, epoch, alg}) + fake.recordInvocation("Verify", []interface{}{pk, criCopy, epoch, alg}) + fake.verifyMutex.Unlock() + if fake.VerifyStub != nil { + return fake.VerifyStub(pk, cri, epoch, alg) + } + if specificReturn { + return ret.result1 + } + return fake.verifyReturns.result1 +} + +func (fake *Revocation) VerifyCallCount() int { + fake.verifyMutex.RLock() + defer fake.verifyMutex.RUnlock() + return len(fake.verifyArgsForCall) +} + +func (fake *Revocation) VerifyArgsForCall(i int) (*ecdsa.PublicKey, []byte, int, bccsp.RevocationAlgorithm) { + fake.verifyMutex.RLock() + defer fake.verifyMutex.RUnlock() + return fake.verifyArgsForCall[i].pk, fake.verifyArgsForCall[i].cri, fake.verifyArgsForCall[i].epoch, fake.verifyArgsForCall[i].alg +} + +func (fake *Revocation) VerifyReturns(result1 error) { + fake.VerifyStub = nil + fake.verifyReturns = struct { + result1 error + }{result1} +} + +func (fake *Revocation) VerifyReturnsOnCall(i int, result1 error) { + fake.VerifyStub = nil + if fake.verifyReturnsOnCall == nil { + fake.verifyReturnsOnCall = make(map[int]struct { + result1 error + }) + } + fake.verifyReturnsOnCall[i] = struct { + result1 error + }{result1} +} + +func (fake *Revocation) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.newKeyMutex.RLock() + defer fake.newKeyMutex.RUnlock() + fake.signMutex.RLock() + defer fake.signMutex.RUnlock() + fake.verifyMutex.RLock() + defer fake.verifyMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *Revocation) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ handlers.Revocation = new(Revocation) diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/signature_scheme.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/signature_scheme.go new file mode 100644 index 000000000..4e7a5197f --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/signature_scheme.go @@ -0,0 +1,229 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package mock + +import ( + "crypto/ecdsa" + "sync" + + "github.com/hyperledger/fabric/bccsp" + "github.com/hyperledger/fabric/bccsp/idemix/handlers" +) + +type SignatureScheme struct { + SignStub func(cred []byte, sk handlers.Big, Nym handlers.Ecp, RNym handlers.Big, ipk handlers.IssuerPublicKey, attributes []bccsp.IdemixAttribute, msg []byte, rhIndex int, cri []byte) ([]byte, error) + signMutex sync.RWMutex + signArgsForCall []struct { + cred []byte + sk handlers.Big + Nym handlers.Ecp + RNym handlers.Big + ipk handlers.IssuerPublicKey + attributes []bccsp.IdemixAttribute + msg []byte + rhIndex int + cri []byte + } + signReturns struct { + result1 []byte + result2 error + } + signReturnsOnCall map[int]struct { + result1 []byte + result2 error + } + VerifyStub func(pk handlers.IssuerPublicKey, signature, digest []byte, attributes []bccsp.IdemixAttribute, hIndex int, revocationPublicKey *ecdsa.PublicKey, epoch int) error + verifyMutex sync.RWMutex + verifyArgsForCall []struct { + pk handlers.IssuerPublicKey + signature []byte + digest []byte + attributes []bccsp.IdemixAttribute + hIndex int + revocationPublicKey *ecdsa.PublicKey + epoch int + } + verifyReturns struct { + result1 error + } + verifyReturnsOnCall map[int]struct { + result1 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *SignatureScheme) Sign(cred []byte, sk handlers.Big, Nym handlers.Ecp, RNym handlers.Big, ipk handlers.IssuerPublicKey, attributes []bccsp.IdemixAttribute, msg []byte, rhIndex int, cri []byte) ([]byte, error) { + var credCopy []byte + if cred != nil { + credCopy = make([]byte, len(cred)) + copy(credCopy, cred) + } + var attributesCopy []bccsp.IdemixAttribute + if attributes != nil { + attributesCopy = make([]bccsp.IdemixAttribute, len(attributes)) + copy(attributesCopy, attributes) + } + var msgCopy []byte + if msg != nil { + msgCopy = make([]byte, len(msg)) + copy(msgCopy, msg) + } + var criCopy []byte + if cri != nil { + criCopy = make([]byte, len(cri)) + copy(criCopy, cri) + } + fake.signMutex.Lock() + ret, specificReturn := fake.signReturnsOnCall[len(fake.signArgsForCall)] + fake.signArgsForCall = append(fake.signArgsForCall, struct { + cred []byte + sk handlers.Big + Nym handlers.Ecp + RNym handlers.Big + ipk handlers.IssuerPublicKey + attributes []bccsp.IdemixAttribute + msg []byte + rhIndex int + cri []byte + }{credCopy, sk, Nym, RNym, ipk, attributesCopy, msgCopy, rhIndex, criCopy}) + fake.recordInvocation("Sign", []interface{}{credCopy, sk, Nym, RNym, ipk, attributesCopy, msgCopy, rhIndex, criCopy}) + fake.signMutex.Unlock() + if fake.SignStub != nil { + return fake.SignStub(cred, sk, Nym, RNym, ipk, attributes, msg, rhIndex, cri) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fake.signReturns.result1, fake.signReturns.result2 +} + +func (fake *SignatureScheme) SignCallCount() int { + fake.signMutex.RLock() + defer fake.signMutex.RUnlock() + return len(fake.signArgsForCall) +} + +func (fake *SignatureScheme) SignArgsForCall(i int) ([]byte, handlers.Big, handlers.Ecp, handlers.Big, handlers.IssuerPublicKey, []bccsp.IdemixAttribute, []byte, int, []byte) { + fake.signMutex.RLock() + defer fake.signMutex.RUnlock() + return fake.signArgsForCall[i].cred, fake.signArgsForCall[i].sk, fake.signArgsForCall[i].Nym, fake.signArgsForCall[i].RNym, fake.signArgsForCall[i].ipk, fake.signArgsForCall[i].attributes, fake.signArgsForCall[i].msg, fake.signArgsForCall[i].rhIndex, fake.signArgsForCall[i].cri +} + +func (fake *SignatureScheme) SignReturns(result1 []byte, result2 error) { + fake.SignStub = nil + fake.signReturns = struct { + result1 []byte + result2 error + }{result1, result2} +} + +func (fake *SignatureScheme) SignReturnsOnCall(i int, result1 []byte, result2 error) { + fake.SignStub = nil + if fake.signReturnsOnCall == nil { + fake.signReturnsOnCall = make(map[int]struct { + result1 []byte + result2 error + }) + } + fake.signReturnsOnCall[i] = struct { + result1 []byte + result2 error + }{result1, result2} +} + +func (fake *SignatureScheme) Verify(pk handlers.IssuerPublicKey, signature []byte, digest []byte, attributes []bccsp.IdemixAttribute, hIndex int, revocationPublicKey *ecdsa.PublicKey, epoch int) error { + var signatureCopy []byte + if signature != nil { + signatureCopy = make([]byte, len(signature)) + copy(signatureCopy, signature) + } + var digestCopy []byte + if digest != nil { + digestCopy = make([]byte, len(digest)) + copy(digestCopy, digest) + } + var attributesCopy []bccsp.IdemixAttribute + if attributes != nil { + attributesCopy = make([]bccsp.IdemixAttribute, len(attributes)) + copy(attributesCopy, attributes) + } + fake.verifyMutex.Lock() + ret, specificReturn := fake.verifyReturnsOnCall[len(fake.verifyArgsForCall)] + fake.verifyArgsForCall = append(fake.verifyArgsForCall, struct { + pk handlers.IssuerPublicKey + signature []byte + digest []byte + attributes []bccsp.IdemixAttribute + hIndex int + revocationPublicKey *ecdsa.PublicKey + epoch int + }{pk, signatureCopy, digestCopy, attributesCopy, hIndex, revocationPublicKey, epoch}) + fake.recordInvocation("Verify", []interface{}{pk, signatureCopy, digestCopy, attributesCopy, hIndex, revocationPublicKey, epoch}) + fake.verifyMutex.Unlock() + if fake.VerifyStub != nil { + return fake.VerifyStub(pk, signature, digest, attributes, hIndex, revocationPublicKey, epoch) + } + if specificReturn { + return ret.result1 + } + return fake.verifyReturns.result1 +} + +func (fake *SignatureScheme) VerifyCallCount() int { + fake.verifyMutex.RLock() + defer fake.verifyMutex.RUnlock() + return len(fake.verifyArgsForCall) +} + +func (fake *SignatureScheme) VerifyArgsForCall(i int) (handlers.IssuerPublicKey, []byte, []byte, []bccsp.IdemixAttribute, int, *ecdsa.PublicKey, int) { + fake.verifyMutex.RLock() + defer fake.verifyMutex.RUnlock() + return fake.verifyArgsForCall[i].pk, fake.verifyArgsForCall[i].signature, fake.verifyArgsForCall[i].digest, fake.verifyArgsForCall[i].attributes, fake.verifyArgsForCall[i].hIndex, fake.verifyArgsForCall[i].revocationPublicKey, fake.verifyArgsForCall[i].epoch +} + +func (fake *SignatureScheme) VerifyReturns(result1 error) { + fake.VerifyStub = nil + fake.verifyReturns = struct { + result1 error + }{result1} +} + +func (fake *SignatureScheme) VerifyReturnsOnCall(i int, result1 error) { + fake.VerifyStub = nil + if fake.verifyReturnsOnCall == nil { + fake.verifyReturnsOnCall = make(map[int]struct { + result1 error + }) + } + fake.verifyReturnsOnCall[i] = struct { + result1 error + }{result1} +} + +func (fake *SignatureScheme) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.signMutex.RLock() + defer fake.signMutex.RUnlock() + fake.verifyMutex.RLock() + defer fake.verifyMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *SignatureScheme) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ handlers.SignatureScheme = new(SignatureScheme) diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/user.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/user.go new file mode 100644 index 000000000..87d532f1e --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/mock/user.go @@ -0,0 +1,308 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package mock + +import ( + "sync" + + "github.com/hyperledger/fabric/bccsp/idemix/handlers" +) + +type User struct { + NewKeyStub func() (handlers.Big, error) + newKeyMutex sync.RWMutex + newKeyArgsForCall []struct{} + newKeyReturns struct { + result1 handlers.Big + result2 error + } + newKeyReturnsOnCall map[int]struct { + result1 handlers.Big + result2 error + } + NewKeyFromBytesStub func(raw []byte) (handlers.Big, error) + newKeyFromBytesMutex sync.RWMutex + newKeyFromBytesArgsForCall []struct { + raw []byte + } + newKeyFromBytesReturns struct { + result1 handlers.Big + result2 error + } + newKeyFromBytesReturnsOnCall map[int]struct { + result1 handlers.Big + result2 error + } + MakeNymStub func(sk handlers.Big, key handlers.IssuerPublicKey) (handlers.Ecp, handlers.Big, error) + makeNymMutex sync.RWMutex + makeNymArgsForCall []struct { + sk handlers.Big + key handlers.IssuerPublicKey + } + makeNymReturns struct { + result1 handlers.Ecp + result2 handlers.Big + result3 error + } + makeNymReturnsOnCall map[int]struct { + result1 handlers.Ecp + result2 handlers.Big + result3 error + } + NewPublicNymFromBytesStub func(raw []byte) (handlers.Ecp, error) + newPublicNymFromBytesMutex sync.RWMutex + newPublicNymFromBytesArgsForCall []struct { + raw []byte + } + newPublicNymFromBytesReturns struct { + result1 handlers.Ecp + result2 error + } + newPublicNymFromBytesReturnsOnCall map[int]struct { + result1 handlers.Ecp + result2 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *User) NewKey() (handlers.Big, error) { + fake.newKeyMutex.Lock() + ret, specificReturn := fake.newKeyReturnsOnCall[len(fake.newKeyArgsForCall)] + fake.newKeyArgsForCall = append(fake.newKeyArgsForCall, struct{}{}) + fake.recordInvocation("NewKey", []interface{}{}) + fake.newKeyMutex.Unlock() + if fake.NewKeyStub != nil { + return fake.NewKeyStub() + } + if specificReturn { + return ret.result1, ret.result2 + } + return fake.newKeyReturns.result1, fake.newKeyReturns.result2 +} + +func (fake *User) NewKeyCallCount() int { + fake.newKeyMutex.RLock() + defer fake.newKeyMutex.RUnlock() + return len(fake.newKeyArgsForCall) +} + +func (fake *User) NewKeyReturns(result1 handlers.Big, result2 error) { + fake.NewKeyStub = nil + fake.newKeyReturns = struct { + result1 handlers.Big + result2 error + }{result1, result2} +} + +func (fake *User) NewKeyReturnsOnCall(i int, result1 handlers.Big, result2 error) { + fake.NewKeyStub = nil + if fake.newKeyReturnsOnCall == nil { + fake.newKeyReturnsOnCall = make(map[int]struct { + result1 handlers.Big + result2 error + }) + } + fake.newKeyReturnsOnCall[i] = struct { + result1 handlers.Big + result2 error + }{result1, result2} +} + +func (fake *User) NewKeyFromBytes(raw []byte) (handlers.Big, error) { + var rawCopy []byte + if raw != nil { + rawCopy = make([]byte, len(raw)) + copy(rawCopy, raw) + } + fake.newKeyFromBytesMutex.Lock() + ret, specificReturn := fake.newKeyFromBytesReturnsOnCall[len(fake.newKeyFromBytesArgsForCall)] + fake.newKeyFromBytesArgsForCall = append(fake.newKeyFromBytesArgsForCall, struct { + raw []byte + }{rawCopy}) + fake.recordInvocation("NewKeyFromBytes", []interface{}{rawCopy}) + fake.newKeyFromBytesMutex.Unlock() + if fake.NewKeyFromBytesStub != nil { + return fake.NewKeyFromBytesStub(raw) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fake.newKeyFromBytesReturns.result1, fake.newKeyFromBytesReturns.result2 +} + +func (fake *User) NewKeyFromBytesCallCount() int { + fake.newKeyFromBytesMutex.RLock() + defer fake.newKeyFromBytesMutex.RUnlock() + return len(fake.newKeyFromBytesArgsForCall) +} + +func (fake *User) NewKeyFromBytesArgsForCall(i int) []byte { + fake.newKeyFromBytesMutex.RLock() + defer fake.newKeyFromBytesMutex.RUnlock() + return fake.newKeyFromBytesArgsForCall[i].raw +} + +func (fake *User) NewKeyFromBytesReturns(result1 handlers.Big, result2 error) { + fake.NewKeyFromBytesStub = nil + fake.newKeyFromBytesReturns = struct { + result1 handlers.Big + result2 error + }{result1, result2} +} + +func (fake *User) NewKeyFromBytesReturnsOnCall(i int, result1 handlers.Big, result2 error) { + fake.NewKeyFromBytesStub = nil + if fake.newKeyFromBytesReturnsOnCall == nil { + fake.newKeyFromBytesReturnsOnCall = make(map[int]struct { + result1 handlers.Big + result2 error + }) + } + fake.newKeyFromBytesReturnsOnCall[i] = struct { + result1 handlers.Big + result2 error + }{result1, result2} +} + +func (fake *User) MakeNym(sk handlers.Big, key handlers.IssuerPublicKey) (handlers.Ecp, handlers.Big, error) { + fake.makeNymMutex.Lock() + ret, specificReturn := fake.makeNymReturnsOnCall[len(fake.makeNymArgsForCall)] + fake.makeNymArgsForCall = append(fake.makeNymArgsForCall, struct { + sk handlers.Big + key handlers.IssuerPublicKey + }{sk, key}) + fake.recordInvocation("MakeNym", []interface{}{sk, key}) + fake.makeNymMutex.Unlock() + if fake.MakeNymStub != nil { + return fake.MakeNymStub(sk, key) + } + if specificReturn { + return ret.result1, ret.result2, ret.result3 + } + return fake.makeNymReturns.result1, fake.makeNymReturns.result2, fake.makeNymReturns.result3 +} + +func (fake *User) MakeNymCallCount() int { + fake.makeNymMutex.RLock() + defer fake.makeNymMutex.RUnlock() + return len(fake.makeNymArgsForCall) +} + +func (fake *User) MakeNymArgsForCall(i int) (handlers.Big, handlers.IssuerPublicKey) { + fake.makeNymMutex.RLock() + defer fake.makeNymMutex.RUnlock() + return fake.makeNymArgsForCall[i].sk, fake.makeNymArgsForCall[i].key +} + +func (fake *User) MakeNymReturns(result1 handlers.Ecp, result2 handlers.Big, result3 error) { + fake.MakeNymStub = nil + fake.makeNymReturns = struct { + result1 handlers.Ecp + result2 handlers.Big + result3 error + }{result1, result2, result3} +} + +func (fake *User) MakeNymReturnsOnCall(i int, result1 handlers.Ecp, result2 handlers.Big, result3 error) { + fake.MakeNymStub = nil + if fake.makeNymReturnsOnCall == nil { + fake.makeNymReturnsOnCall = make(map[int]struct { + result1 handlers.Ecp + result2 handlers.Big + result3 error + }) + } + fake.makeNymReturnsOnCall[i] = struct { + result1 handlers.Ecp + result2 handlers.Big + result3 error + }{result1, result2, result3} +} + +func (fake *User) NewPublicNymFromBytes(raw []byte) (handlers.Ecp, error) { + var rawCopy []byte + if raw != nil { + rawCopy = make([]byte, len(raw)) + copy(rawCopy, raw) + } + fake.newPublicNymFromBytesMutex.Lock() + ret, specificReturn := fake.newPublicNymFromBytesReturnsOnCall[len(fake.newPublicNymFromBytesArgsForCall)] + fake.newPublicNymFromBytesArgsForCall = append(fake.newPublicNymFromBytesArgsForCall, struct { + raw []byte + }{rawCopy}) + fake.recordInvocation("NewPublicNymFromBytes", []interface{}{rawCopy}) + fake.newPublicNymFromBytesMutex.Unlock() + if fake.NewPublicNymFromBytesStub != nil { + return fake.NewPublicNymFromBytesStub(raw) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fake.newPublicNymFromBytesReturns.result1, fake.newPublicNymFromBytesReturns.result2 +} + +func (fake *User) NewPublicNymFromBytesCallCount() int { + fake.newPublicNymFromBytesMutex.RLock() + defer fake.newPublicNymFromBytesMutex.RUnlock() + return len(fake.newPublicNymFromBytesArgsForCall) +} + +func (fake *User) NewPublicNymFromBytesArgsForCall(i int) []byte { + fake.newPublicNymFromBytesMutex.RLock() + defer fake.newPublicNymFromBytesMutex.RUnlock() + return fake.newPublicNymFromBytesArgsForCall[i].raw +} + +func (fake *User) NewPublicNymFromBytesReturns(result1 handlers.Ecp, result2 error) { + fake.NewPublicNymFromBytesStub = nil + fake.newPublicNymFromBytesReturns = struct { + result1 handlers.Ecp + result2 error + }{result1, result2} +} + +func (fake *User) NewPublicNymFromBytesReturnsOnCall(i int, result1 handlers.Ecp, result2 error) { + fake.NewPublicNymFromBytesStub = nil + if fake.newPublicNymFromBytesReturnsOnCall == nil { + fake.newPublicNymFromBytesReturnsOnCall = make(map[int]struct { + result1 handlers.Ecp + result2 error + }) + } + fake.newPublicNymFromBytesReturnsOnCall[i] = struct { + result1 handlers.Ecp + result2 error + }{result1, result2} +} + +func (fake *User) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.newKeyMutex.RLock() + defer fake.newKeyMutex.RUnlock() + fake.newKeyFromBytesMutex.RLock() + defer fake.newKeyFromBytesMutex.RUnlock() + fake.makeNymMutex.RLock() + defer fake.makeNymMutex.RUnlock() + fake.newPublicNymFromBytesMutex.RLock() + defer fake.newPublicNymFromBytesMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *User) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ handlers.User = new(User) diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/nym.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/nym.go new file mode 100644 index 000000000..ed29bf36f --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/nym.go @@ -0,0 +1,167 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ +package handlers + +import ( + "crypto/sha256" + + "github.com/hyperledger/fabric/bccsp" + "github.com/pkg/errors" +) + +// nymSecretKey contains the nym secret key +type nymSecretKey struct { + // SKI of this key + ski []byte + // sk is the idemix reference to the nym secret + sk Big + // pk is the idemix reference to the nym public part + pk Ecp + // exportable if true, sk can be exported via the Bytes function + exportable bool +} + +func computeSKI(serialise func() ([]byte, error)) ([]byte, error) { + raw, err := serialise() + if err != nil { + return nil, err + } + + hash := sha256.New() + hash.Write(raw) + return hash.Sum(nil), nil + +} + +func NewNymSecretKey(sk Big, pk Ecp, exportable bool) (*nymSecretKey, error) { + ski, err := computeSKI(sk.Bytes) + if err != nil { + return nil, err + } + + return &nymSecretKey{ski: ski, sk: sk, pk: pk, exportable: exportable}, nil +} + +func (k *nymSecretKey) Bytes() ([]byte, error) { + if k.exportable { + return k.sk.Bytes() + } + + return nil, errors.New("not supported") +} + +func (k *nymSecretKey) SKI() []byte { + c := make([]byte, len(k.ski)) + copy(c, k.ski) + return c +} + +func (*nymSecretKey) Symmetric() bool { + return false +} + +func (*nymSecretKey) Private() bool { + return true +} + +func (k *nymSecretKey) PublicKey() (bccsp.Key, error) { + ski, err := computeSKI(k.pk.Bytes) + if err != nil { + return nil, err + } + return &nymPublicKey{ski: ski, pk: k.pk}, nil +} + +type nymPublicKey struct { + // SKI of this key + ski []byte + // pk is the idemix reference to the nym public part + pk Ecp +} + +func NewNymPublicKey(pk Ecp) *nymPublicKey { + return &nymPublicKey{pk: pk} +} + +func (k *nymPublicKey) Bytes() ([]byte, error) { + return k.pk.Bytes() +} + +func (k *nymPublicKey) SKI() []byte { + c := make([]byte, len(k.ski)) + copy(c, k.ski) + return c +} + +func (*nymPublicKey) Symmetric() bool { + return false +} + +func (*nymPublicKey) Private() bool { + return false +} + +func (k *nymPublicKey) PublicKey() (bccsp.Key, error) { + return k, nil +} + +// NymKeyDerivation derives nyms +type NymKeyDerivation struct { + // Exportable is a flag to allow an issuer secret key to be marked as Exportable. + // If a secret key is marked as Exportable, its Bytes method will return the key's byte representation. + Exportable bool + // User implements the underlying cryptographic algorithms + User User +} + +func (kd *NymKeyDerivation) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, err error) { + userSecretKey, ok := k.(*userSecretKey) + if !ok { + return nil, errors.New("invalid key, expected *userSecretKey") + } + nymKeyDerivationOpts, ok := opts.(*bccsp.IdemixNymKeyDerivationOpts) + if !ok { + return nil, errors.New("invalid options, expected *IdemixNymKeyDerivationOpts") + } + if nymKeyDerivationOpts.IssuerPK == nil { + return nil, errors.New("invalid options, missing issuer public key") + } + issuerPK, ok := nymKeyDerivationOpts.IssuerPK.(*issuerPublicKey) + if !ok { + return nil, errors.New("invalid options, expected IssuerPK as *issuerPublicKey") + } + + Nym, RandNym, err := kd.User.MakeNym(userSecretKey.sk, issuerPK.pk) + if err != nil { + return nil, err + } + + return NewNymSecretKey(RandNym, Nym, kd.Exportable) +} + +// NymPublicKeyImporter imports nym public keys +type NymPublicKeyImporter struct { + // User implements the underlying cryptographic algorithms + User User +} + +func (i *NymPublicKeyImporter) KeyImport(raw interface{}, opts bccsp.KeyImportOpts) (k bccsp.Key, err error) { + bytes, ok := raw.([]byte) + if !ok { + return nil, errors.New("invalid raw, expected byte array") + } + + if len(bytes) == 0 { + return nil, errors.New("invalid raw, it must not be nil") + } + + pk, err := i.User.NewPublicNymFromBytes(bytes) + if err != nil { + return nil, err + } + + return &nymPublicKey{pk: pk}, nil +} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/nymsigner.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/nymsigner.go new file mode 100644 index 000000000..651795727 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/nymsigner.go @@ -0,0 +1,95 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ +package handlers + +import ( + "github.com/hyperledger/fabric/bccsp" + "github.com/pkg/errors" +) + +type NymSigner struct { + NymSignatureScheme NymSignatureScheme +} + +func (s *NymSigner) Sign(k bccsp.Key, digest []byte, opts bccsp.SignerOpts) ([]byte, error) { + userSecretKey, ok := k.(*userSecretKey) + if !ok { + return nil, errors.New("invalid key, expected *userSecretKey") + } + + signerOpts, ok := opts.(*bccsp.IdemixNymSignerOpts) + if !ok { + return nil, errors.New("invalid options, expected *IdemixNymSignerOpts") + } + + // Issuer public key + if signerOpts.IssuerPK == nil { + return nil, errors.New("invalid options, missing issuer public key") + } + ipk, ok := signerOpts.IssuerPK.(*issuerPublicKey) + if !ok { + return nil, errors.New("invalid issuer public key, expected *issuerPublicKey") + } + + // Nym + if signerOpts.Nym == nil { + return nil, errors.New("invalid options, missing nym key") + } + nymSk, ok := signerOpts.Nym.(*nymSecretKey) + if !ok { + return nil, errors.New("invalid nym key, expected *nymSecretKey") + } + + sigma, err := s.NymSignatureScheme.Sign( + userSecretKey.sk, + nymSk.pk, nymSk.sk, + ipk.pk, + digest) + if err != nil { + return nil, err + } + + return sigma, nil +} + +type NymVerifier struct { + NymSignatureScheme NymSignatureScheme +} + +func (v *NymVerifier) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (bool, error) { + nymPublicKey, ok := k.(*nymPublicKey) + if !ok { + return false, errors.New("invalid key, expected *nymPublicKey") + } + + signerOpts, ok := opts.(*bccsp.IdemixNymSignerOpts) + if !ok { + return false, errors.New("invalid options, expected *IdemixNymSignerOpts") + } + + if signerOpts.IssuerPK == nil { + return false, errors.New("invalid options, missing issuer public key") + } + ipk, ok := signerOpts.IssuerPK.(*issuerPublicKey) + if !ok { + return false, errors.New("invalid issuer public key, expected *issuerPublicKey") + } + + if len(signature) == 0 { + return false, errors.New("invalid signature, it must not be empty") + } + + err := v.NymSignatureScheme.Verify( + ipk.pk, + nymPublicKey.pk, + signature, + digest) + if err != nil { + return false, err + } + + return true, nil +} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/revocation.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/revocation.go new file mode 100644 index 000000000..e84434d15 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/revocation.go @@ -0,0 +1,219 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ +package handlers + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/sha256" + "crypto/x509" + "encoding/pem" + "fmt" + "reflect" + + "github.com/hyperledger/fabric/bccsp" + "github.com/pkg/errors" +) + +// revocationSecretKey contains the revocation secret key +// and implements the bccsp.Key interface +type revocationSecretKey struct { + // sk is the idemix reference to the revocation key + privKey *ecdsa.PrivateKey + // exportable if true, sk can be exported via the Bytes function + exportable bool +} + +func NewRevocationSecretKey(sk *ecdsa.PrivateKey, exportable bool) *revocationSecretKey { + return &revocationSecretKey{privKey: sk, exportable: exportable} +} + +// Bytes converts this key to its byte representation, +// if this operation is allowed. +func (k *revocationSecretKey) Bytes() ([]byte, error) { + if k.exportable { + return k.privKey.D.Bytes(), nil + } + + return nil, errors.New("not exportable") +} + +// SKI returns the subject key identifier of this key. +func (k *revocationSecretKey) SKI() []byte { + // Marshall the public key + raw := elliptic.Marshal(k.privKey.Curve, k.privKey.PublicKey.X, k.privKey.PublicKey.Y) + + // Hash it + hash := sha256.New() + hash.Write(raw) + return hash.Sum(nil) +} + +// Symmetric returns true if this key is a symmetric key, +// false if this key is asymmetric +func (k *revocationSecretKey) Symmetric() bool { + return false +} + +// Private returns true if this key is a private key, +// false otherwise. +func (k *revocationSecretKey) Private() bool { + return true +} + +// PublicKey returns the corresponding public key part of an asymmetric public/private key pair. +// This method returns an error in symmetric key schemes. +func (k *revocationSecretKey) PublicKey() (bccsp.Key, error) { + return &revocationPublicKey{&k.privKey.PublicKey}, nil +} + +type revocationPublicKey struct { + pubKey *ecdsa.PublicKey +} + +func NewRevocationPublicKey(pubKey *ecdsa.PublicKey) *revocationPublicKey { + return &revocationPublicKey{pubKey: pubKey} +} + +// Bytes converts this key to its byte representation, +// if this operation is allowed. +func (k *revocationPublicKey) Bytes() (raw []byte, err error) { + raw, err = x509.MarshalPKIXPublicKey(k.pubKey) + if err != nil { + return nil, fmt.Errorf("Failed marshalling key [%s]", err) + } + return +} + +// SKI returns the subject key identifier of this key. +func (k *revocationPublicKey) SKI() []byte { + // Marshall the public key + raw := elliptic.Marshal(k.pubKey.Curve, k.pubKey.X, k.pubKey.Y) + + // Hash it + hash := sha256.New() + hash.Write(raw) + return hash.Sum(nil) +} + +// Symmetric returns true if this key is a symmetric key, +// false if this key is asymmetric +func (k *revocationPublicKey) Symmetric() bool { + return false +} + +// Private returns true if this key is a private key, +// false otherwise. +func (k *revocationPublicKey) Private() bool { + return false +} + +// PublicKey returns the corresponding public key part of an asymmetric public/private key pair. +// This method returns an error in symmetric key schemes. +func (k *revocationPublicKey) PublicKey() (bccsp.Key, error) { + return k, nil +} + +// RevocationKeyGen generates revocation secret keys. +type RevocationKeyGen struct { + // exportable is a flag to allow an revocation secret key to be marked as exportable. + // If a secret key is marked as exportable, its Bytes method will return the key's byte representation. + Exportable bool + // Revocation implements the underlying cryptographic algorithms + Revocation Revocation +} + +func (g *RevocationKeyGen) KeyGen(opts bccsp.KeyGenOpts) (bccsp.Key, error) { + // Create a new key pair + key, err := g.Revocation.NewKey() + if err != nil { + return nil, err + } + + return &revocationSecretKey{exportable: g.Exportable, privKey: key}, nil +} + +// RevocationPublicKeyImporter imports revocation public keys +type RevocationPublicKeyImporter struct { +} + +func (i *RevocationPublicKeyImporter) KeyImport(raw interface{}, opts bccsp.KeyImportOpts) (k bccsp.Key, err error) { + der, ok := raw.([]byte) + if !ok { + return nil, errors.New("invalid raw, expected byte array") + } + + if len(der) == 0 { + return nil, errors.New("invalid raw, it must not be nil") + } + + blockPub, _ := pem.Decode(raw.([]byte)) + if blockPub == nil { + return nil, errors.New("Failed to decode revocation ECDSA public key") + } + revocationPk, err := x509.ParsePKIXPublicKey(blockPub.Bytes) + if err != nil { + return nil, errors.Wrap(err, "Failed to parse revocation ECDSA public key bytes") + } + ecdsaPublicKey, isECDSA := revocationPk.(*ecdsa.PublicKey) + if !isECDSA { + return nil, errors.Errorf("key is of type %v, not of type ECDSA", reflect.TypeOf(revocationPk)) + } + + return &revocationPublicKey{ecdsaPublicKey}, nil +} + +type CriSigner struct { + Revocation Revocation +} + +func (s *CriSigner) Sign(k bccsp.Key, digest []byte, opts bccsp.SignerOpts) ([]byte, error) { + revocationSecretKey, ok := k.(*revocationSecretKey) + if !ok { + return nil, errors.New("invalid key, expected *revocationSecretKey") + } + criOpts, ok := opts.(*bccsp.IdemixCRISignerOpts) + if !ok { + return nil, errors.New("invalid options, expected *IdemixCRISignerOpts") + } + + return s.Revocation.Sign( + revocationSecretKey.privKey, + criOpts.UnrevokedHandles, + criOpts.Epoch, + criOpts.RevocationAlgorithm, + ) +} + +type CriVerifier struct { + Revocation Revocation +} + +func (v *CriVerifier) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (bool, error) { + revocationPublicKey, ok := k.(*revocationPublicKey) + if !ok { + return false, errors.New("invalid key, expected *revocationPublicKey") + } + criOpts, ok := opts.(*bccsp.IdemixCRISignerOpts) + if !ok { + return false, errors.New("invalid options, expected *IdemixCRISignerOpts") + } + if len(signature) == 0 { + return false, errors.New("invalid signature, it must not be empty") + } + + err := v.Revocation.Verify( + revocationPublicKey.pubKey, + signature, + criOpts.Epoch, + criOpts.RevocationAlgorithm, + ) + if err != nil { + return false, err + } + + return true, nil +} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/signer.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/signer.go new file mode 100644 index 000000000..c94f83aeb --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/signer.go @@ -0,0 +1,101 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ +package handlers + +import ( + "github.com/hyperledger/fabric/bccsp" + "github.com/pkg/errors" +) + +type Signer struct { + SignatureScheme SignatureScheme +} + +func (s *Signer) Sign(k bccsp.Key, digest []byte, opts bccsp.SignerOpts) ([]byte, error) { + userSecretKey, ok := k.(*userSecretKey) + if !ok { + return nil, errors.New("invalid key, expected *userSecretKey") + } + + signerOpts, ok := opts.(*bccsp.IdemixSignerOpts) + if !ok { + return nil, errors.New("invalid options, expected *IdemixSignerOpts") + } + + // Issuer public key + if signerOpts.IssuerPK == nil { + return nil, errors.New("invalid options, missing issuer public key") + } + ipk, ok := signerOpts.IssuerPK.(*issuerPublicKey) + if !ok { + return nil, errors.New("invalid issuer public key, expected *issuerPublicKey") + } + + // Nym + if signerOpts.Nym == nil { + return nil, errors.New("invalid options, missing nym key") + } + nymSk, ok := signerOpts.Nym.(*nymSecretKey) + if !ok { + return nil, errors.New("invalid nym key, expected *nymSecretKey") + } + + sigma, err := s.SignatureScheme.Sign( + signerOpts.Credential, + userSecretKey.sk, + nymSk.pk, nymSk.sk, + ipk.pk, + signerOpts.Attributes, + digest, + signerOpts.RhIndex, + signerOpts.CRI, + ) + if err != nil { + return nil, err + } + + return sigma, nil +} + +type Verifier struct { + SignatureScheme SignatureScheme +} + +func (v *Verifier) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (bool, error) { + issuerPublicKey, ok := k.(*issuerPublicKey) + if !ok { + return false, errors.New("invalid key, expected *issuerPublicKey") + } + + signerOpts, ok := opts.(*bccsp.IdemixSignerOpts) + if !ok { + return false, errors.New("invalid options, expected *IdemixSignerOpts") + } + + rpk, ok := signerOpts.RevocationPublicKey.(*revocationPublicKey) + if !ok { + return false, errors.New("invalid options, expected *revocationPublicKey") + } + + if len(signature) == 0 { + return false, errors.New("invalid signature, it must not be empty") + } + + err := v.SignatureScheme.Verify( + issuerPublicKey.pk, + signature, + digest, + signerOpts.Attributes, + signerOpts.RhIndex, + rpk.pubKey, + signerOpts.Epoch, + ) + if err != nil { + return false, err + } + + return true, nil +} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/user.go b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/user.go new file mode 100644 index 000000000..273bb2222 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemix/handlers/user.go @@ -0,0 +1,99 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ +package handlers + +import ( + "crypto/sha256" + + "github.com/hyperledger/fabric/bccsp" + "github.com/pkg/errors" +) + +// userSecretKey contains the User secret key +type userSecretKey struct { + // sk is the idemix reference to the User key + sk Big + // Exportable if true, sk can be exported via the Bytes function + exportable bool +} + +func NewUserSecretKey(sk Big, exportable bool) *userSecretKey { + return &userSecretKey{sk: sk, exportable: exportable} +} + +func (k *userSecretKey) Bytes() ([]byte, error) { + if k.exportable { + return k.sk.Bytes() + } + + return nil, errors.New("not exportable") +} + +func (k *userSecretKey) SKI() []byte { + raw, err := k.sk.Bytes() + if err != nil { + return nil + } + hash := sha256.New() + hash.Write(raw) + return hash.Sum(nil) +} + +func (*userSecretKey) Symmetric() bool { + return true +} + +func (*userSecretKey) Private() bool { + return true +} + +func (k *userSecretKey) PublicKey() (bccsp.Key, error) { + return nil, errors.New("cannot call this method on a symmetric key") +} + +type UserKeyGen struct { + // Exportable is a flag to allow an issuer secret key to be marked as Exportable. + // If a secret key is marked as Exportable, its Bytes method will return the key's byte representation. + Exportable bool + // User implements the underlying cryptographic algorithms + User User +} + +func (g *UserKeyGen) KeyGen(opts bccsp.KeyGenOpts) (bccsp.Key, error) { + sk, err := g.User.NewKey() + if err != nil { + return nil, err + } + + return &userSecretKey{exportable: g.Exportable, sk: sk}, nil +} + +// UserKeyImporter import user keys +type UserKeyImporter struct { + // Exportable is a flag to allow a secret key to be marked as Exportable. + // If a secret key is marked as Exportable, its Bytes method will return the key's byte representation. + Exportable bool + // User implements the underlying cryptographic algorithms + User User +} + +func (i *UserKeyImporter) KeyImport(raw interface{}, opts bccsp.KeyImportOpts) (k bccsp.Key, err error) { + der, ok := raw.([]byte) + if !ok { + return nil, errors.New("invalid raw, expected byte array") + } + + if len(der) == 0 { + return nil, errors.New("invalid raw, it must not be nil") + } + + sk, err := i.User.NewKeyFromBytes(raw.([]byte)) + if err != nil { + return nil, err + } + + return &userSecretKey{exportable: i.Exportable, sk: sk}, nil +} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemixerrs.go b/vendor/github.com/hyperledger/fabric/bccsp/idemixerrs.go new file mode 100644 index 000000000..b05d0bd55 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemixerrs.go @@ -0,0 +1,34 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ +package bccsp + +import ( + "fmt" +) + +type IdemixIIssuerPublicKeyImporterErrorType int + +const ( + IdemixIssuerPublicKeyImporterUnmarshallingError IdemixIIssuerPublicKeyImporterErrorType = iota + IdemixIssuerPublicKeyImporterHashError + IdemixIssuerPublicKeyImporterValidationError + IdemixIssuerPublicKeyImporterNumAttributesError + IdemixIssuerPublicKeyImporterAttributeNameError +) + +type IdemixIssuerPublicKeyImporterError struct { + Type IdemixIIssuerPublicKeyImporterErrorType + ErrorMsg string + Cause error +} + +func (r *IdemixIssuerPublicKeyImporterError) Error() string { + if r.Cause != nil { + return fmt.Sprintf("%s: %s", r.ErrorMsg, r.Cause) + } + + return fmt.Sprintf("%s", r.ErrorMsg) +} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/idemixopts.go b/vendor/github.com/hyperledger/fabric/bccsp/idemixopts.go index 4ee4c0805..a138d0e8b 100644 --- a/vendor/github.com/hyperledger/fabric/bccsp/idemixopts.go +++ b/vendor/github.com/hyperledger/fabric/bccsp/idemixopts.go @@ -5,13 +5,23 @@ SPDX-License-Identifier: Apache-2.0 */ package bccsp -import "crypto" +import ( + "crypto" +) + +// RevocationAlgorithm identifies the revocation algorithm +type RevocationAlgorithm int32 const ( // IDEMIX constant to identify Idemix related algorithms IDEMIX = "IDEMIX" ) +const ( + // AlgNoRevocation means no revocation support + AlgNoRevocation RevocationAlgorithm = iota +) + // IdemixIssuerKeyGenOpts contains the options for the Idemix Issuer key-generation. // A list of attribytes may be optionally passed type IdemixIssuerKeyGenOpts struct { @@ -32,6 +42,24 @@ func (o *IdemixIssuerKeyGenOpts) Ephemeral() bool { return o.Temporary } +// IdemixIssuerPublicKeyImportOpts contains the options for importing of an Idemix issuer public key. +type IdemixIssuerPublicKeyImportOpts struct { + Temporary bool + // AttributeNames is a list of attributes to ensure the import public key has + AttributeNames []string +} + +// Algorithm returns the key generation algorithm identifier (to be used). +func (*IdemixIssuerPublicKeyImportOpts) Algorithm() string { + return IDEMIX +} + +// Ephemeral returns true if the key to generate has to be ephemeral, +// false otherwise. +func (o *IdemixIssuerPublicKeyImportOpts) Ephemeral() bool { + return o.Temporary +} + // IdemixUserSecretKeyGenOpts contains the options for the generation of an Idemix credential secret key. type IdemixUserSecretKeyGenOpts struct { Temporary bool @@ -48,6 +76,22 @@ func (o *IdemixUserSecretKeyGenOpts) Ephemeral() bool { return o.Temporary } +// IdemixUserSecretKeyImportOpts contains the options for importing of an Idemix credential secret key. +type IdemixUserSecretKeyImportOpts struct { + Temporary bool +} + +// Algorithm returns the key generation algorithm identifier (to be used). +func (*IdemixUserSecretKeyImportOpts) Algorithm() string { + return IDEMIX +} + +// Ephemeral returns true if the key to generate has to be ephemeral, +// false otherwise. +func (o *IdemixUserSecretKeyImportOpts) Ephemeral() bool { + return o.Temporary +} + // IdemixNymKeyDerivationOpts contains the options to create a new unlinkable pseudonym from a // credential secret key with the respect to the specified issuer public key type IdemixNymKeyDerivationOpts struct { @@ -74,11 +118,33 @@ func (o *IdemixNymKeyDerivationOpts) IssuerPublicKey() Key { return o.IssuerPK } +// IdemixNymPublicKeyImportOpts contains the options to import the public part of a pseudonym +type IdemixNymPublicKeyImportOpts struct { + // Temporary tells if the key is ephemeral + Temporary bool +} + +// Algorithm returns the key derivation algorithm identifier (to be used). +func (*IdemixNymPublicKeyImportOpts) Algorithm() string { + return IDEMIX +} + +// Ephemeral returns true if the key to derive has to be ephemeral, +// false otherwise. +func (o *IdemixNymPublicKeyImportOpts) Ephemeral() bool { + return o.Temporary +} + // IdemixCredentialRequestSignerOpts contains the option to create a Idemix credential request. type IdemixCredentialRequestSignerOpts struct { // Attributes contains a list of indices of the attributes to be included in the // credential. The indices are with the respect to IdemixIssuerKeyGenOpts#AttributeNames. Attributes []int + // IssuerPK is the public-key of the issuer + IssuerPK Key + // IssuerNonce is generated by the issuer and used by the client to generate the credential request. + // Once the issuer gets the credential requests, it checks that the nonce is the same. + IssuerNonce []byte // HashFun is the hash function to be used H crypto.Hash } @@ -87,9 +153,37 @@ func (o *IdemixCredentialRequestSignerOpts) HashFunc() crypto.Hash { return o.H } +// IssuerPublicKey returns the issuer public key used to derive +// a new unlinkable pseudonym from a credential secret key +func (o *IdemixCredentialRequestSignerOpts) IssuerPublicKey() Key { + return o.IssuerPK +} + +// IdemixAttributeType represents the type of an idemix attribute +type IdemixAttributeType int + +const ( + // IdemixHiddenAttribute represents an hidden attribute + IdemixHiddenAttribute IdemixAttributeType = iota + // IdemixStringAttribute represents a sequence of bytes + IdemixBytesAttribute + // IdemixIntAttribute represents an int + IdemixIntAttribute +) + +type IdemixAttribute struct { + // Type is the attribute's type + Type IdemixAttributeType + // Value is the attribute's value + Value interface{} +} + // IdemixCredentialSignerOpts contains the options to produce a credential starting from a credential request type IdemixCredentialSignerOpts struct { - Attributes []int + // Attributes to include in the credentials. IdemixHiddenAttribute is not allowed here + Attributes []IdemixAttribute + // IssuerPK is the public-key of the issuer + IssuerPK Key // HashFun is the hash function to be used H crypto.Hash } @@ -101,6 +195,10 @@ func (o *IdemixCredentialSignerOpts) HashFunc() crypto.Hash { return o.H } +func (o *IdemixCredentialSignerOpts) IssuerPublicKey() Key { + return o.IssuerPK +} + // IdemixSignerOpts contains the options to generate an Idemix signature type IdemixSignerOpts struct { // Nym is the pseudonym to be used @@ -109,10 +207,22 @@ type IdemixSignerOpts struct { IssuerPK Key // Credential is the byte representation of the credential signed by the issuer Credential []byte - // Disclosure specifies which attribute should be disclosed. If Disclosure[i] = 0 + // Attributes specifies which attribute should be disclosed and which not. + // If Attributes[i].Type = IdemixHiddenAttribute // then the i-th credential attribute should not be disclosed, otherwise the i-th // credential attribute will be disclosed. - Disclosure []byte + // At verification time, if the i-th attribute is disclosed (Attributes[i].Type != IdemixHiddenAttribute), + // then Attributes[i].Value must be set accordingly. + Attributes []IdemixAttribute + // RhIndex is the index of attribute containing the revocation handler. + // Notice that this attributed cannot be discloused + RhIndex int + // CRI contains the credential revocation information + CRI []byte + // Epoch is the revocation epoch the signature should be produced against + Epoch int + // RevocationPublicKey is the revocation public key + RevocationPublicKey Key // H is the hash function to be used H crypto.Hash } @@ -137,3 +247,51 @@ type IdemixNymSignerOpts struct { func (o *IdemixNymSignerOpts) HashFunc() crypto.Hash { return o.H } + +// IdemixRevocationKeyGenOpts contains the options for the Idemix revocation key-generation. +type IdemixRevocationKeyGenOpts struct { + // Temporary tells if the key is ephemeral + Temporary bool +} + +// Algorithm returns the key generation algorithm identifier (to be used). +func (*IdemixRevocationKeyGenOpts) Algorithm() string { + return IDEMIX +} + +// Ephemeral returns true if the key to generate has to be ephemeral, +// false otherwise. +func (o *IdemixRevocationKeyGenOpts) Ephemeral() bool { + return o.Temporary +} + +// IdemixRevocationPublicKeyImportOpts contains the options for importing of an Idemix revocation public key. +type IdemixRevocationPublicKeyImportOpts struct { + Temporary bool +} + +// Algorithm returns the key generation algorithm identifier (to be used). +func (*IdemixRevocationPublicKeyImportOpts) Algorithm() string { + return IDEMIX +} + +// Ephemeral returns true if the key to generate has to be ephemeral, +// false otherwise. +func (o *IdemixRevocationPublicKeyImportOpts) Ephemeral() bool { + return o.Temporary +} + +// IdemixCRISignerOpts contains the options to generate an Idemix CRI. +// The CRI is supposed to be generated by the Issuing authority and +// can be verified publicly by using the revocation public key. +type IdemixCRISignerOpts struct { + Epoch int + RevocationAlgorithm RevocationAlgorithm + UnrevokedHandles [][]byte + // H is the hash function to be used + H crypto.Hash +} + +func (o *IdemixCRISignerOpts) HashFunc() crypto.Hash { + return o.H +} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/mocks/mocks.go b/vendor/github.com/hyperledger/fabric/bccsp/mocks/mocks.go index c20ccc55a..b394ac0c9 100644 --- a/vendor/github.com/hyperledger/fabric/bccsp/mocks/mocks.go +++ b/vendor/github.com/hyperledger/fabric/bccsp/mocks/mocks.go @@ -17,13 +17,12 @@ limitations under the License. package mocks import ( + "bytes" "crypto" "errors" "hash" "reflect" - "bytes" - "github.com/hyperledger/fabric/bccsp" ) diff --git a/vendor/github.com/hyperledger/fabric/bccsp/sw/aeskey.go b/vendor/github.com/hyperledger/fabric/bccsp/sw/aeskey.go index 659171308..6f3f5b0b3 100644 --- a/vendor/github.com/hyperledger/fabric/bccsp/sw/aeskey.go +++ b/vendor/github.com/hyperledger/fabric/bccsp/sw/aeskey.go @@ -16,9 +16,8 @@ limitations under the License. package sw import ( - "errors" - "crypto/sha256" + "errors" "github.com/hyperledger/fabric/bccsp" ) diff --git a/vendor/github.com/hyperledger/fabric/bccsp/sw/ecdsakey.go b/vendor/github.com/hyperledger/fabric/bccsp/sw/ecdsakey.go index 78e2e28f1..7c9cb4b46 100644 --- a/vendor/github.com/hyperledger/fabric/bccsp/sw/ecdsakey.go +++ b/vendor/github.com/hyperledger/fabric/bccsp/sw/ecdsakey.go @@ -17,14 +17,11 @@ package sw import ( "crypto/ecdsa" - "crypto/x509" - "fmt" - + "crypto/elliptic" "crypto/sha256" - + "crypto/x509" "errors" - - "crypto/elliptic" + "fmt" "github.com/hyperledger/fabric/bccsp" ) diff --git a/vendor/github.com/hyperledger/fabric/bccsp/sw/fileks.go b/vendor/github.com/hyperledger/fabric/bccsp/sw/fileks.go index 791ee3a72..194a126da 100644 --- a/vendor/github.com/hyperledger/fabric/bccsp/sw/fileks.go +++ b/vendor/github.com/hyperledger/fabric/bccsp/sw/fileks.go @@ -17,25 +17,23 @@ package sw import ( "bytes" - "io/ioutil" - "os" - "sync" - - "errors" - "strings" - "crypto/ecdsa" "crypto/rsa" "encoding/hex" + "errors" "fmt" + "io/ioutil" + "os" "path/filepath" + "strings" + "sync" "github.com/hyperledger/fabric/bccsp" "github.com/hyperledger/fabric/bccsp/utils" ) // NewFileBasedKeyStore instantiated a file-based key store at a given position. -// The key store can be encrypted if a non-empty password is specifiec. +// The key store can be encrypted if a non-empty password is specified. // It can be also be set as read only. In this case, any store operation // will be forbidden func NewFileBasedKeyStore(pwd []byte, path string, readOnly bool) (bccsp.KeyStore, error) { diff --git a/vendor/github.com/hyperledger/fabric/bccsp/sw/impl.go b/vendor/github.com/hyperledger/fabric/bccsp/sw/impl.go index a7089476e..59f22bb57 100644 --- a/vendor/github.com/hyperledger/fabric/bccsp/sw/impl.go +++ b/vendor/github.com/hyperledger/fabric/bccsp/sw/impl.go @@ -36,14 +36,14 @@ var ( type CSP struct { ks bccsp.KeyStore - keyGenerators map[reflect.Type]KeyGenerator - keyDerivers map[reflect.Type]KeyDeriver - keyImporters map[reflect.Type]KeyImporter - encryptors map[reflect.Type]Encryptor - decryptors map[reflect.Type]Decryptor - signers map[reflect.Type]Signer - verifiers map[reflect.Type]Verifier - hashers map[reflect.Type]Hasher + KeyGenerators map[reflect.Type]KeyGenerator + KeyDerivers map[reflect.Type]KeyDeriver + KeyImporters map[reflect.Type]KeyImporter + Encryptors map[reflect.Type]Encryptor + Decryptors map[reflect.Type]Decryptor + Signers map[reflect.Type]Signer + Verifiers map[reflect.Type]Verifier + Hashers map[reflect.Type]Hasher } func New(keyStore bccsp.KeyStore) (*CSP, error) { @@ -74,7 +74,7 @@ func (csp *CSP) KeyGen(opts bccsp.KeyGenOpts) (k bccsp.Key, err error) { return nil, errors.New("Invalid Opts parameter. It must not be nil.") } - keyGenerator, found := csp.keyGenerators[reflect.TypeOf(opts)] + keyGenerator, found := csp.KeyGenerators[reflect.TypeOf(opts)] if !found { return nil, errors.Errorf("Unsupported 'KeyGenOpts' provided [%v]", opts) } @@ -107,7 +107,7 @@ func (csp *CSP) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, er return nil, errors.New("Invalid opts. It must not be nil.") } - keyDeriver, found := csp.keyDerivers[reflect.TypeOf(k)] + keyDeriver, found := csp.KeyDerivers[reflect.TypeOf(k)] if !found { return nil, errors.Errorf("Unsupported 'Key' provided [%v]", k) } @@ -140,7 +140,7 @@ func (csp *CSP) KeyImport(raw interface{}, opts bccsp.KeyImportOpts) (k bccsp.Ke return nil, errors.New("Invalid opts. It must not be nil.") } - keyImporter, found := csp.keyImporters[reflect.TypeOf(opts)] + keyImporter, found := csp.KeyImporters[reflect.TypeOf(opts)] if !found { return nil, errors.Errorf("Unsupported 'KeyImportOpts' provided [%v]", opts) } @@ -180,7 +180,7 @@ func (csp *CSP) Hash(msg []byte, opts bccsp.HashOpts) (digest []byte, err error) return nil, errors.New("Invalid opts. It must not be nil.") } - hasher, found := csp.hashers[reflect.TypeOf(opts)] + hasher, found := csp.Hashers[reflect.TypeOf(opts)] if !found { return nil, errors.Errorf("Unsupported 'HashOpt' provided [%v]", opts) } @@ -201,7 +201,7 @@ func (csp *CSP) GetHash(opts bccsp.HashOpts) (h hash.Hash, err error) { return nil, errors.New("Invalid opts. It must not be nil.") } - hasher, found := csp.hashers[reflect.TypeOf(opts)] + hasher, found := csp.Hashers[reflect.TypeOf(opts)] if !found { return nil, errors.Errorf("Unsupported 'HashOpt' provided [%v]", opts) } @@ -230,7 +230,7 @@ func (csp *CSP) Sign(k bccsp.Key, digest []byte, opts bccsp.SignerOpts) (signatu } keyType := reflect.TypeOf(k) - signer, found := csp.signers[keyType] + signer, found := csp.Signers[keyType] if !found { return nil, errors.Errorf("Unsupported 'SignKey' provided [%s]", keyType) } @@ -256,7 +256,7 @@ func (csp *CSP) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerO return false, errors.New("Invalid digest. Cannot be empty.") } - verifier, found := csp.verifiers[reflect.TypeOf(k)] + verifier, found := csp.Verifiers[reflect.TypeOf(k)] if !found { return false, errors.Errorf("Unsupported 'VerifyKey' provided [%v]", k) } @@ -277,7 +277,7 @@ func (csp *CSP) Encrypt(k bccsp.Key, plaintext []byte, opts bccsp.EncrypterOpts) return nil, errors.New("Invalid Key. It must not be nil.") } - encryptor, found := csp.encryptors[reflect.TypeOf(k)] + encryptor, found := csp.Encryptors[reflect.TypeOf(k)] if !found { return nil, errors.Errorf("Unsupported 'EncryptKey' provided [%v]", k) } @@ -293,7 +293,7 @@ func (csp *CSP) Decrypt(k bccsp.Key, ciphertext []byte, opts bccsp.DecrypterOpts return nil, errors.New("Invalid Key. It must not be nil.") } - decryptor, found := csp.decryptors[reflect.TypeOf(k)] + decryptor, found := csp.Decryptors[reflect.TypeOf(k)] if !found { return nil, errors.Errorf("Unsupported 'DecryptKey' provided [%v]", k) } @@ -318,21 +318,21 @@ func (csp *CSP) AddWrapper(t reflect.Type, w interface{}) error { } switch dt := w.(type) { case KeyGenerator: - csp.keyGenerators[t] = dt + csp.KeyGenerators[t] = dt case KeyImporter: - csp.keyImporters[t] = dt + csp.KeyImporters[t] = dt case KeyDeriver: - csp.keyDerivers[t] = dt + csp.KeyDerivers[t] = dt case Encryptor: - csp.encryptors[t] = dt + csp.Encryptors[t] = dt case Decryptor: - csp.decryptors[t] = dt + csp.Decryptors[t] = dt case Signer: - csp.signers[t] = dt + csp.Signers[t] = dt case Verifier: - csp.verifiers[t] = dt + csp.Verifiers[t] = dt case Hasher: - csp.hashers[t] = dt + csp.Hashers[t] = dt default: return errors.Errorf("wrapper type not valid, must be on of: KeyGenerator, KeyDeriver, KeyImporter, Encryptor, Decryptor, Signer, Verifier, Hasher") } diff --git a/vendor/github.com/hyperledger/fabric/bccsp/sw/inmemoryks.go b/vendor/github.com/hyperledger/fabric/bccsp/sw/inmemoryks.go new file mode 100644 index 000000000..101934cb1 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric/bccsp/sw/inmemoryks.go @@ -0,0 +1,68 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package sw + +import ( + "encoding/hex" + "sync" + + "github.com/hyperledger/fabric/bccsp" + "github.com/pkg/errors" +) + +// NewInMemoryKeyStore instantiates an ephemeral in-memory keystore +func NewInMemoryKeyStore() bccsp.KeyStore { + eks := &inmemoryKeyStore{} + eks.keys = make(map[string]bccsp.Key) + return eks +} + +type inmemoryKeyStore struct { + // keys maps the hex-encoded SKI to keys + keys map[string]bccsp.Key + m sync.RWMutex +} + +// ReadOnly returns false - the key store is not read-only +func (ks *inmemoryKeyStore) ReadOnly() bool { + return false +} + +// GetKey returns a key object whose SKI is the one passed. +func (ks *inmemoryKeyStore) GetKey(ski []byte) (bccsp.Key, error) { + if len(ski) == 0 { + return nil, errors.New("ski is nil or empty") + } + + skiStr := hex.EncodeToString(ski) + + ks.m.RLock() + defer ks.m.RUnlock() + if key, found := ks.keys[skiStr]; found { + return key, nil + } + return nil, errors.Errorf("no key found for ski %x", ski) +} + +// StoreKey stores the key k in this KeyStore. +func (ks *inmemoryKeyStore) StoreKey(k bccsp.Key) error { + if k == nil { + return errors.New("key is nil") + } + + ski := hex.EncodeToString(k.SKI()) + + ks.m.Lock() + defer ks.m.Unlock() + + if _, found := ks.keys[ski]; found { + return errors.Errorf("ski %x already exists in the keystore", k.SKI()) + } + ks.keys[ski] = k + + return nil +} diff --git a/vendor/github.com/hyperledger/fabric/bccsp/sw/keyderiv.go b/vendor/github.com/hyperledger/fabric/bccsp/sw/keyderiv.go index 077426dd8..70b3a684d 100644 --- a/vendor/github.com/hyperledger/fabric/bccsp/sw/keyderiv.go +++ b/vendor/github.com/hyperledger/fabric/bccsp/sw/keyderiv.go @@ -18,13 +18,11 @@ package sw import ( "crypto/ecdsa" - "fmt" - + "crypto/hmac" "errors" + "fmt" "math/big" - "crypto/hmac" - "github.com/hyperledger/fabric/bccsp" ) diff --git a/vendor/github.com/hyperledger/fabric/bccsp/sw/keyimport.go b/vendor/github.com/hyperledger/fabric/bccsp/sw/keyimport.go index 19c82b241..b2003fb5b 100644 --- a/vendor/github.com/hyperledger/fabric/bccsp/sw/keyimport.go +++ b/vendor/github.com/hyperledger/fabric/bccsp/sw/keyimport.go @@ -17,12 +17,11 @@ limitations under the License. package sw import ( - "errors" - "fmt" - "crypto/ecdsa" "crypto/rsa" "crypto/x509" + "errors" + "fmt" "reflect" "github.com/hyperledger/fabric/bccsp" @@ -149,11 +148,11 @@ func (ki *x509PublicKeyImportOptsKeyImporter) KeyImport(raw interface{}, opts bc switch pk.(type) { case *ecdsa.PublicKey: - return ki.bccsp.keyImporters[reflect.TypeOf(&bccsp.ECDSAGoPublicKeyImportOpts{})].KeyImport( + return ki.bccsp.KeyImporters[reflect.TypeOf(&bccsp.ECDSAGoPublicKeyImportOpts{})].KeyImport( pk, &bccsp.ECDSAGoPublicKeyImportOpts{Temporary: opts.Ephemeral()}) case *rsa.PublicKey: - return ki.bccsp.keyImporters[reflect.TypeOf(&bccsp.RSAGoPublicKeyImportOpts{})].KeyImport( + return ki.bccsp.KeyImporters[reflect.TypeOf(&bccsp.RSAGoPublicKeyImportOpts{})].KeyImport( pk, &bccsp.RSAGoPublicKeyImportOpts{Temporary: opts.Ephemeral()}) default: diff --git a/vendor/github.com/hyperledger/fabric/bccsp/sw/new.go b/vendor/github.com/hyperledger/fabric/bccsp/sw/new.go index b2dcb970c..9959fab44 100644 --- a/vendor/github.com/hyperledger/fabric/bccsp/sw/new.go +++ b/vendor/github.com/hyperledger/fabric/bccsp/sw/new.go @@ -51,23 +51,23 @@ func NewWithParams(securityLevel int, hashFamily string, keyStore bccsp.KeyStore // Notice that errors are ignored here because some test will fail if one // of the following call fails. - // Set the encryptors + // Set the Encryptors swbccsp.AddWrapper(reflect.TypeOf(&aesPrivateKey{}), &aescbcpkcs7Encryptor{}) - // Set the decryptors + // Set the Decryptors swbccsp.AddWrapper(reflect.TypeOf(&aesPrivateKey{}), &aescbcpkcs7Decryptor{}) - // Set the signers + // Set the Signers swbccsp.AddWrapper(reflect.TypeOf(&ecdsaPrivateKey{}), &ecdsaSigner{}) swbccsp.AddWrapper(reflect.TypeOf(&rsaPrivateKey{}), &rsaSigner{}) - // Set the verifiers + // Set the Verifiers swbccsp.AddWrapper(reflect.TypeOf(&ecdsaPrivateKey{}), &ecdsaPrivateKeyVerifier{}) swbccsp.AddWrapper(reflect.TypeOf(&ecdsaPublicKey{}), &ecdsaPublicKeyKeyVerifier{}) swbccsp.AddWrapper(reflect.TypeOf(&rsaPrivateKey{}), &rsaPrivateKeyVerifier{}) swbccsp.AddWrapper(reflect.TypeOf(&rsaPublicKey{}), &rsaPublicKeyKeyVerifier{}) - // Set the hashers + // Set the Hashers swbccsp.AddWrapper(reflect.TypeOf(&bccsp.SHAOpts{}), &hasher{hash: conf.hashFunction}) swbccsp.AddWrapper(reflect.TypeOf(&bccsp.SHA256Opts{}), &hasher{hash: sha256.New}) swbccsp.AddWrapper(reflect.TypeOf(&bccsp.SHA384Opts{}), &hasher{hash: sha512.New384}) diff --git a/vendor/github.com/hyperledger/fabric/bccsp/sw/rsakey.go b/vendor/github.com/hyperledger/fabric/bccsp/sw/rsakey.go index 462ed15a5..00d26a98e 100644 --- a/vendor/github.com/hyperledger/fabric/bccsp/sw/rsakey.go +++ b/vendor/github.com/hyperledger/fabric/bccsp/sw/rsakey.go @@ -17,14 +17,11 @@ package sw import ( "crypto/rsa" - "crypto/x509" - "fmt" - "crypto/sha256" - - "errors" - + "crypto/x509" "encoding/asn1" + "errors" + "fmt" "math/big" "github.com/hyperledger/fabric/bccsp" diff --git a/vendor/github.com/hyperledger/fabric/idemix/credential.go b/vendor/github.com/hyperledger/fabric/idemix/credential.go index 981090451..28ebc2df9 100644 --- a/vendor/github.com/hyperledger/fabric/idemix/credential.go +++ b/vendor/github.com/hyperledger/fabric/idemix/credential.go @@ -47,27 +47,52 @@ func NewCredential(key *IssuerKey, m *CredRequest, attrs []*FP256BN.BIG, rng *am // Place a BBS+ signature on the user key and the attribute values // (For BBS+, see e.g. "Constant-Size Dynamic k-TAA" by Man Ho Au, Willy Susilo, Yi Mu) + // or http://eprint.iacr.org/2016/663.pdf, Sec. 4.3. + + // For a credential, a BBS+ signature consists of the following three elements: + // 1. E, random value in the proper group + // 2. S, random value in the proper group + // 3. A as B^Exp where B=g_1 \cdot h_r^s \cdot h_sk^sk \cdot \prod_{i=1}^L h_i^{m_i} and Exp = \frac{1}{e+x} + // Notice that: + // h_r is h_0 in http://eprint.iacr.org/2016/663.pdf, Sec. 4.3. + + // Pick randomness E and S E := RandModOrder(rng) S := RandModOrder(rng) + // Set B as g_1 \cdot h_r^s \cdot h_sk^sk \cdot \prod_{i=1}^L h_i^{m_i} and Exp = \frac{1}{e+x} B := FP256BN.NewECP() - B.Copy(GenG1) + B.Copy(GenG1) // g_1 Nym := EcpFromProto(m.Nym) - B.Add(Nym) - B.Add(EcpFromProto(key.Ipk.HRand).Mul(S)) + B.Add(Nym) // in this case, recall Nym=h_sk^sk + B.Add(EcpFromProto(key.Ipk.HRand).Mul(S)) // h_r^s - // Use Mul2 instead of Mul as much as possible + // Append attributes + // Use Mul2 instead of Mul as much as possible for efficiency reasones for i := 0; i < len(attrs)/2; i++ { - B.Add(EcpFromProto(key.Ipk.HAttrs[2*i]).Mul2(attrs[2*i], EcpFromProto(key.Ipk.HAttrs[2*i+1]), attrs[2*i+1])) + B.Add( + // Add two attributes in one shot + EcpFromProto(key.Ipk.HAttrs[2*i]).Mul2( + attrs[2*i], + EcpFromProto(key.Ipk.HAttrs[2*i+1]), + attrs[2*i+1], + ), + ) } + // Check for residue in case len(attrs)%2 is odd if len(attrs)%2 != 0 { B.Add(EcpFromProto(key.Ipk.HAttrs[len(attrs)-1]).Mul(attrs[len(attrs)-1])) } + // Set Exp as \frac{1}{e+x} Exp := Modadd(FP256BN.FromBytes(key.GetIsk()), E, GroupOrder) Exp.Invmodp(GroupOrder) + // Finalise A as B^Exp A := B.Mul(Exp) + // The signature is now generated. + // Notice that here we release also B, this does not harm security cause + // it can be compute publicly from the BBS+ signature itself. CredAttrs := make([][]byte, len(attrs)) for index, attribute := range attrs { CredAttrs[index] = BigToBytes(attribute) @@ -84,26 +109,33 @@ func NewCredential(key *IssuerKey, m *CredRequest, attrs []*FP256BN.BIG, rng *am // Ver cryptographically verifies the credential by verifying the signature // on the attribute values and user's secret key func (cred *Credential) Ver(sk *FP256BN.BIG, ipk *IssuerPublicKey) error { + // Validate Input - // parse the credential + // - parse the credential A := EcpFromProto(cred.GetA()) B := EcpFromProto(cred.GetB()) E := FP256BN.FromBytes(cred.GetE()) S := FP256BN.FromBytes(cred.GetS()) - // verify that all attribute values are present + // - verify that all attribute values are present for i := 0; i < len(cred.GetAttrs()); i++ { if cred.Attrs[i] == nil { return errors.Errorf("credential has no value for attribute %s", ipk.AttributeNames[i]) } } - // verify cryptographic signature on the attributes and the user secret key + // - verify cryptographic signature on the attributes and the user secret key BPrime := FP256BN.NewECP() BPrime.Copy(GenG1) BPrime.Add(EcpFromProto(ipk.HSk).Mul2(sk, EcpFromProto(ipk.HRand), S)) for i := 0; i < len(cred.Attrs)/2; i++ { - BPrime.Add(EcpFromProto(ipk.HAttrs[2*i]).Mul2(FP256BN.FromBytes(cred.Attrs[2*i]), EcpFromProto(ipk.HAttrs[2*i+1]), FP256BN.FromBytes(cred.Attrs[2*i+1]))) + BPrime.Add( + EcpFromProto(ipk.HAttrs[2*i]).Mul2( + FP256BN.FromBytes(cred.Attrs[2*i]), + EcpFromProto(ipk.HAttrs[2*i+1]), + FP256BN.FromBytes(cred.Attrs[2*i+1]), + ), + ) } if len(cred.Attrs)%2 != 0 { BPrime.Add(EcpFromProto(ipk.HAttrs[len(cred.Attrs)-1]).Mul(FP256BN.FromBytes(cred.Attrs[len(cred.Attrs)-1]))) @@ -112,12 +144,17 @@ func (cred *Credential) Ver(sk *FP256BN.BIG, ipk *IssuerPublicKey) error { return errors.Errorf("b-value from credential does not match the attribute values") } + // Verify BBS+ signature. Namely: e(w \cdot g_2^e, A) =? e(g_2, B) a := GenG2.Mul(E) a.Add(Ecp2FromProto(ipk.W)) a.Affine() - if !FP256BN.Fexp(FP256BN.Ate(a, A)).Equals(FP256BN.Fexp(FP256BN.Ate(GenG2, B))) { + left := FP256BN.Fexp(FP256BN.Ate(a, A)) + right := FP256BN.Fexp(FP256BN.Ate(GenG2, B)) + + if !left.Equals(right) { return errors.Errorf("credential is not cryptographically valid") } + return nil } diff --git a/vendor/github.com/hyperledger/fabric/idemix/credrequest.go b/vendor/github.com/hyperledger/fabric/idemix/credrequest.go index 8536b2fd1..6d3b18280 100644 --- a/vendor/github.com/hyperledger/fabric/idemix/credrequest.go +++ b/vendor/github.com/hyperledger/fabric/idemix/credrequest.go @@ -30,15 +30,22 @@ const credRequestLabel = "credRequest" // 4) The user verifies the issuer's signature and stores the credential that consists of // the signature value, a randomness used to create the signature, the user secret, and the attribute values -// NewCredRequest creates a new Credential Request, the first message of the interactive credential issuance protocol (from user to issuer) -func NewCredRequest(sk *FP256BN.BIG, IssuerNonce *FP256BN.BIG, ipk *IssuerPublicKey, rng *amcl.RAND) *CredRequest { +// NewCredRequest creates a new Credential Request, the first message of the interactive credential issuance protocol +// (from user to issuer) +func NewCredRequest(sk *FP256BN.BIG, IssuerNonce []byte, ipk *IssuerPublicKey, rng *amcl.RAND) *CredRequest { + // Set Nym as h_{sk}^{sk} HSk := EcpFromProto(ipk.HSk) Nym := HSk.Mul(sk) - // Create ZK Proof + // generate a zero-knowledge proof of knowledge (ZK PoK) of the secret key + + // Sample the randomness needed for the proof rSk := RandModOrder(rng) - t := HSk.Mul(rSk) + // Step 1: First message (t-values) + t := HSk.Mul(rSk) // t = h_{sk}^{r_{sk}}, cover Nym + + // Step 2: Compute the Fiat-Shamir hash, forming the challenge of the ZKP. // proofData is the data being hashed, it consists of: // the credential request label // 3 elements of G1 each taking 2*FieldBytes+1 bytes @@ -50,15 +57,17 @@ func NewCredRequest(sk *FP256BN.BIG, IssuerNonce *FP256BN.BIG, ipk *IssuerPublic index = appendBytesG1(proofData, index, t) index = appendBytesG1(proofData, index, HSk) index = appendBytesG1(proofData, index, Nym) - index = appendBytesBig(proofData, index, IssuerNonce) + index = appendBytes(proofData, index, IssuerNonce) copy(proofData[index:], ipk.Hash) - proofC := HashModOrder(proofData) - proofS := Modadd(FP256BN.Modmul(proofC, sk, GroupOrder), rSk, GroupOrder) + // Step 3: reply to the challenge message (s-values) + proofS := Modadd(FP256BN.Modmul(proofC, sk, GroupOrder), rSk, GroupOrder) // s = r_{sk} + C \cdot sk + + // Done return &CredRequest{ Nym: EcpToProto(Nym), - IssuerNonce: BigToBytes(IssuerNonce), + IssuerNonce: IssuerNonce, ProofC: BigToBytes(proofC), ProofS: BigToBytes(proofS)} } @@ -66,7 +75,7 @@ func NewCredRequest(sk *FP256BN.BIG, IssuerNonce *FP256BN.BIG, ipk *IssuerPublic // Check cryptographically verifies the credential request func (m *CredRequest) Check(ipk *IssuerPublicKey) error { Nym := EcpFromProto(m.GetNym()) - IssuerNonce := FP256BN.FromBytes(m.GetIssuerNonce()) + IssuerNonce := m.GetIssuerNonce() ProofC := FP256BN.FromBytes(m.GetProofC()) ProofS := FP256BN.FromBytes(m.GetProofS()) @@ -76,21 +85,20 @@ func (m *CredRequest) Check(ipk *IssuerPublicKey) error { return errors.Errorf("one of the proof values is undefined") } + // Verify Proof + + // Recompute t-values using s-values t := HSk.Mul(ProofS) - t.Sub(Nym.Mul(ProofC)) + t.Sub(Nym.Mul(ProofC)) // t = h_{sk}^s / Nym^C - // proofData is the data being hashed, it consists of: - // the credential request label - // 3 elements of G1 each taking 2*FieldBytes+1 bytes - // hash of the issuer public key of length FieldBytes - // issuer nonce of length FieldBytes + // Recompute challenge proofData := make([]byte, len([]byte(credRequestLabel))+3*(2*FieldBytes+1)+2*FieldBytes) index := 0 index = appendBytesString(proofData, index, credRequestLabel) index = appendBytesG1(proofData, index, t) index = appendBytesG1(proofData, index, HSk) index = appendBytesG1(proofData, index, Nym) - index = appendBytesBig(proofData, index, IssuerNonce) + index = appendBytes(proofData, index, IssuerNonce) copy(proofData[index:], ipk.Hash) if *ProofC != *HashModOrder(proofData) { diff --git a/vendor/github.com/hyperledger/fabric/idemix/idemix.pb.go b/vendor/github.com/hyperledger/fabric/idemix/idemix.pb.go index d88356d4c..83e0d8708 100644 --- a/vendor/github.com/hyperledger/fabric/idemix/idemix.pb.go +++ b/vendor/github.com/hyperledger/fabric/idemix/idemix.pb.go @@ -1,25 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: idemix/idemix.proto -/* -Package idemix is a generated protocol buffer package. - -It is generated from these files: - idemix/idemix.proto - -It has these top-level messages: - ECP - ECP2 - IssuerPublicKey - IssuerKey - Credential - CredRequest - Signature - NonRevocationProof - NymSignature - CredentialRevocationInformation -*/ -package idemix +package idemix // import "github.com/hyperledger/fabric/idemix" import proto "github.com/golang/protobuf/proto" import fmt "fmt" @@ -39,14 +21,36 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package // ECP is an elliptic curve point specified by its coordinates // ECP corresponds to an element of the first group (G1) type ECP struct { - X []byte `protobuf:"bytes,1,opt,name=x,proto3" json:"x,omitempty"` - Y []byte `protobuf:"bytes,2,opt,name=y,proto3" json:"y,omitempty"` + X []byte `protobuf:"bytes,1,opt,name=x,proto3" json:"x,omitempty"` + Y []byte `protobuf:"bytes,2,opt,name=y,proto3" json:"y,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *ECP) Reset() { *m = ECP{} } -func (m *ECP) String() string { return proto.CompactTextString(m) } -func (*ECP) ProtoMessage() {} -func (*ECP) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } +func (m *ECP) Reset() { *m = ECP{} } +func (m *ECP) String() string { return proto.CompactTextString(m) } +func (*ECP) ProtoMessage() {} +func (*ECP) Descriptor() ([]byte, []int) { + return fileDescriptor_idemix_ea623f6980eee47e, []int{0} +} +func (m *ECP) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ECP.Unmarshal(m, b) +} +func (m *ECP) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ECP.Marshal(b, m, deterministic) +} +func (dst *ECP) XXX_Merge(src proto.Message) { + xxx_messageInfo_ECP.Merge(dst, src) +} +func (m *ECP) XXX_Size() int { + return xxx_messageInfo_ECP.Size(m) +} +func (m *ECP) XXX_DiscardUnknown() { + xxx_messageInfo_ECP.DiscardUnknown(m) +} + +var xxx_messageInfo_ECP proto.InternalMessageInfo func (m *ECP) GetX() []byte { if m != nil { @@ -65,16 +69,38 @@ func (m *ECP) GetY() []byte { // ECP2 is an elliptic curve point specified by its coordinates // ECP2 corresponds to an element of the second group (G2) type ECP2 struct { - Xa []byte `protobuf:"bytes,1,opt,name=xa,proto3" json:"xa,omitempty"` - Xb []byte `protobuf:"bytes,2,opt,name=xb,proto3" json:"xb,omitempty"` - Ya []byte `protobuf:"bytes,3,opt,name=ya,proto3" json:"ya,omitempty"` - Yb []byte `protobuf:"bytes,4,opt,name=yb,proto3" json:"yb,omitempty"` + Xa []byte `protobuf:"bytes,1,opt,name=xa,proto3" json:"xa,omitempty"` + Xb []byte `protobuf:"bytes,2,opt,name=xb,proto3" json:"xb,omitempty"` + Ya []byte `protobuf:"bytes,3,opt,name=ya,proto3" json:"ya,omitempty"` + Yb []byte `protobuf:"bytes,4,opt,name=yb,proto3" json:"yb,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *ECP2) Reset() { *m = ECP2{} } -func (m *ECP2) String() string { return proto.CompactTextString(m) } -func (*ECP2) ProtoMessage() {} -func (*ECP2) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } +func (m *ECP2) Reset() { *m = ECP2{} } +func (m *ECP2) String() string { return proto.CompactTextString(m) } +func (*ECP2) ProtoMessage() {} +func (*ECP2) Descriptor() ([]byte, []int) { + return fileDescriptor_idemix_ea623f6980eee47e, []int{1} +} +func (m *ECP2) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ECP2.Unmarshal(m, b) +} +func (m *ECP2) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ECP2.Marshal(b, m, deterministic) +} +func (dst *ECP2) XXX_Merge(src proto.Message) { + xxx_messageInfo_ECP2.Merge(dst, src) +} +func (m *ECP2) XXX_Size() int { + return xxx_messageInfo_ECP2.Size(m) +} +func (m *ECP2) XXX_DiscardUnknown() { + xxx_messageInfo_ECP2.DiscardUnknown(m) +} + +var xxx_messageInfo_ECP2 proto.InternalMessageInfo func (m *ECP2) GetXa() []byte { if m != nil { @@ -110,22 +136,44 @@ func (m *ECP2) GetYb() []byte { // proof_c, proof_s compose a zero-knowledge proof of knowledge of the secret key // hash is a hash of the public key appended to it type IssuerPublicKey struct { - AttributeNames []string `protobuf:"bytes,1,rep,name=attribute_names,json=attributeNames" json:"attribute_names,omitempty"` - HSk *ECP `protobuf:"bytes,2,opt,name=h_sk,json=hSk" json:"h_sk,omitempty"` - HRand *ECP `protobuf:"bytes,3,opt,name=h_rand,json=hRand" json:"h_rand,omitempty"` - HAttrs []*ECP `protobuf:"bytes,4,rep,name=h_attrs,json=hAttrs" json:"h_attrs,omitempty"` - W *ECP2 `protobuf:"bytes,5,opt,name=w" json:"w,omitempty"` - BarG1 *ECP `protobuf:"bytes,6,opt,name=bar_g1,json=barG1" json:"bar_g1,omitempty"` - BarG2 *ECP `protobuf:"bytes,7,opt,name=bar_g2,json=barG2" json:"bar_g2,omitempty"` - ProofC []byte `protobuf:"bytes,8,opt,name=proof_c,json=proofC,proto3" json:"proof_c,omitempty"` - ProofS []byte `protobuf:"bytes,9,opt,name=proof_s,json=proofS,proto3" json:"proof_s,omitempty"` - Hash []byte `protobuf:"bytes,10,opt,name=hash,proto3" json:"hash,omitempty"` -} - -func (m *IssuerPublicKey) Reset() { *m = IssuerPublicKey{} } -func (m *IssuerPublicKey) String() string { return proto.CompactTextString(m) } -func (*IssuerPublicKey) ProtoMessage() {} -func (*IssuerPublicKey) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + AttributeNames []string `protobuf:"bytes,1,rep,name=attribute_names,json=attributeNames,proto3" json:"attribute_names,omitempty"` + HSk *ECP `protobuf:"bytes,2,opt,name=h_sk,json=hSk,proto3" json:"h_sk,omitempty"` + HRand *ECP `protobuf:"bytes,3,opt,name=h_rand,json=hRand,proto3" json:"h_rand,omitempty"` + HAttrs []*ECP `protobuf:"bytes,4,rep,name=h_attrs,json=hAttrs,proto3" json:"h_attrs,omitempty"` + W *ECP2 `protobuf:"bytes,5,opt,name=w,proto3" json:"w,omitempty"` + BarG1 *ECP `protobuf:"bytes,6,opt,name=bar_g1,json=barG1,proto3" json:"bar_g1,omitempty"` + BarG2 *ECP `protobuf:"bytes,7,opt,name=bar_g2,json=barG2,proto3" json:"bar_g2,omitempty"` + ProofC []byte `protobuf:"bytes,8,opt,name=proof_c,json=proofC,proto3" json:"proof_c,omitempty"` + ProofS []byte `protobuf:"bytes,9,opt,name=proof_s,json=proofS,proto3" json:"proof_s,omitempty"` + Hash []byte `protobuf:"bytes,10,opt,name=hash,proto3" json:"hash,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IssuerPublicKey) Reset() { *m = IssuerPublicKey{} } +func (m *IssuerPublicKey) String() string { return proto.CompactTextString(m) } +func (*IssuerPublicKey) ProtoMessage() {} +func (*IssuerPublicKey) Descriptor() ([]byte, []int) { + return fileDescriptor_idemix_ea623f6980eee47e, []int{2} +} +func (m *IssuerPublicKey) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_IssuerPublicKey.Unmarshal(m, b) +} +func (m *IssuerPublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_IssuerPublicKey.Marshal(b, m, deterministic) +} +func (dst *IssuerPublicKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_IssuerPublicKey.Merge(dst, src) +} +func (m *IssuerPublicKey) XXX_Size() int { + return xxx_messageInfo_IssuerPublicKey.Size(m) +} +func (m *IssuerPublicKey) XXX_DiscardUnknown() { + xxx_messageInfo_IssuerPublicKey.DiscardUnknown(m) +} + +var xxx_messageInfo_IssuerPublicKey proto.InternalMessageInfo func (m *IssuerPublicKey) GetAttributeNames() []string { if m != nil { @@ -201,14 +249,36 @@ func (m *IssuerPublicKey) GetHash() []byte { // ISk - the issuer secret key and // IssuerPublicKey - the issuer public key type IssuerKey struct { - Isk []byte `protobuf:"bytes,1,opt,name=isk,proto3" json:"isk,omitempty"` - Ipk *IssuerPublicKey `protobuf:"bytes,2,opt,name=ipk" json:"ipk,omitempty"` + Isk []byte `protobuf:"bytes,1,opt,name=isk,proto3" json:"isk,omitempty"` + Ipk *IssuerPublicKey `protobuf:"bytes,2,opt,name=ipk,proto3" json:"ipk,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IssuerKey) Reset() { *m = IssuerKey{} } +func (m *IssuerKey) String() string { return proto.CompactTextString(m) } +func (*IssuerKey) ProtoMessage() {} +func (*IssuerKey) Descriptor() ([]byte, []int) { + return fileDescriptor_idemix_ea623f6980eee47e, []int{3} +} +func (m *IssuerKey) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_IssuerKey.Unmarshal(m, b) +} +func (m *IssuerKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_IssuerKey.Marshal(b, m, deterministic) +} +func (dst *IssuerKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_IssuerKey.Merge(dst, src) +} +func (m *IssuerKey) XXX_Size() int { + return xxx_messageInfo_IssuerKey.Size(m) +} +func (m *IssuerKey) XXX_DiscardUnknown() { + xxx_messageInfo_IssuerKey.DiscardUnknown(m) } -func (m *IssuerKey) Reset() { *m = IssuerKey{} } -func (m *IssuerKey) String() string { return proto.CompactTextString(m) } -func (*IssuerKey) ProtoMessage() {} -func (*IssuerKey) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } +var xxx_messageInfo_IssuerKey proto.InternalMessageInfo func (m *IssuerKey) GetIsk() []byte { if m != nil { @@ -228,17 +298,39 @@ func (m *IssuerKey) GetIpk() *IssuerPublicKey { // a, b, e, s - signature value // attrs - attribute values type Credential struct { - A *ECP `protobuf:"bytes,1,opt,name=a" json:"a,omitempty"` - B *ECP `protobuf:"bytes,2,opt,name=b" json:"b,omitempty"` - E []byte `protobuf:"bytes,3,opt,name=e,proto3" json:"e,omitempty"` - S []byte `protobuf:"bytes,4,opt,name=s,proto3" json:"s,omitempty"` - Attrs [][]byte `protobuf:"bytes,5,rep,name=attrs,proto3" json:"attrs,omitempty"` + A *ECP `protobuf:"bytes,1,opt,name=a,proto3" json:"a,omitempty"` + B *ECP `protobuf:"bytes,2,opt,name=b,proto3" json:"b,omitempty"` + E []byte `protobuf:"bytes,3,opt,name=e,proto3" json:"e,omitempty"` + S []byte `protobuf:"bytes,4,opt,name=s,proto3" json:"s,omitempty"` + Attrs [][]byte `protobuf:"bytes,5,rep,name=attrs,proto3" json:"attrs,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *Credential) Reset() { *m = Credential{} } -func (m *Credential) String() string { return proto.CompactTextString(m) } -func (*Credential) ProtoMessage() {} -func (*Credential) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } +func (m *Credential) Reset() { *m = Credential{} } +func (m *Credential) String() string { return proto.CompactTextString(m) } +func (*Credential) ProtoMessage() {} +func (*Credential) Descriptor() ([]byte, []int) { + return fileDescriptor_idemix_ea623f6980eee47e, []int{4} +} +func (m *Credential) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Credential.Unmarshal(m, b) +} +func (m *Credential) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Credential.Marshal(b, m, deterministic) +} +func (dst *Credential) XXX_Merge(src proto.Message) { + xxx_messageInfo_Credential.Merge(dst, src) +} +func (m *Credential) XXX_Size() int { + return xxx_messageInfo_Credential.Size(m) +} +func (m *Credential) XXX_DiscardUnknown() { + xxx_messageInfo_Credential.DiscardUnknown(m) +} + +var xxx_messageInfo_Credential proto.InternalMessageInfo func (m *Credential) GetA() *ECP { if m != nil { @@ -281,16 +373,38 @@ func (m *Credential) GetAttrs() [][]byte { // proof_c, proof_s - a zero-knowledge proof of knowledge of the // user secret inside Nym type CredRequest struct { - Nym *ECP `protobuf:"bytes,1,opt,name=nym" json:"nym,omitempty"` - IssuerNonce []byte `protobuf:"bytes,2,opt,name=issuer_nonce,json=issuerNonce,proto3" json:"issuer_nonce,omitempty"` - ProofC []byte `protobuf:"bytes,3,opt,name=proof_c,json=proofC,proto3" json:"proof_c,omitempty"` - ProofS []byte `protobuf:"bytes,4,opt,name=proof_s,json=proofS,proto3" json:"proof_s,omitempty"` + Nym *ECP `protobuf:"bytes,1,opt,name=nym,proto3" json:"nym,omitempty"` + IssuerNonce []byte `protobuf:"bytes,2,opt,name=issuer_nonce,json=issuerNonce,proto3" json:"issuer_nonce,omitempty"` + ProofC []byte `protobuf:"bytes,3,opt,name=proof_c,json=proofC,proto3" json:"proof_c,omitempty"` + ProofS []byte `protobuf:"bytes,4,opt,name=proof_s,json=proofS,proto3" json:"proof_s,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CredRequest) Reset() { *m = CredRequest{} } +func (m *CredRequest) String() string { return proto.CompactTextString(m) } +func (*CredRequest) ProtoMessage() {} +func (*CredRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_idemix_ea623f6980eee47e, []int{5} +} +func (m *CredRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CredRequest.Unmarshal(m, b) +} +func (m *CredRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CredRequest.Marshal(b, m, deterministic) +} +func (dst *CredRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_CredRequest.Merge(dst, src) +} +func (m *CredRequest) XXX_Size() int { + return xxx_messageInfo_CredRequest.Size(m) +} +func (m *CredRequest) XXX_DiscardUnknown() { + xxx_messageInfo_CredRequest.DiscardUnknown(m) } -func (m *CredRequest) Reset() { *m = CredRequest{} } -func (m *CredRequest) String() string { return proto.CompactTextString(m) } -func (*CredRequest) ProtoMessage() {} -func (*CredRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } +var xxx_messageInfo_CredRequest proto.InternalMessageInfo func (m *CredRequest) GetNym() *ECP { if m != nil { @@ -327,29 +441,51 @@ func (m *CredRequest) GetProofS() []byte { // nonce - a fresh nonce used for the signature // nym - a fresh pseudonym (a commitment to to the user secret) type Signature struct { - APrime *ECP `protobuf:"bytes,1,opt,name=a_prime,json=aPrime" json:"a_prime,omitempty"` - ABar *ECP `protobuf:"bytes,2,opt,name=a_bar,json=aBar" json:"a_bar,omitempty"` - BPrime *ECP `protobuf:"bytes,3,opt,name=b_prime,json=bPrime" json:"b_prime,omitempty"` - ProofC []byte `protobuf:"bytes,4,opt,name=proof_c,json=proofC,proto3" json:"proof_c,omitempty"` - ProofSSk []byte `protobuf:"bytes,5,opt,name=proof_s_sk,json=proofSSk,proto3" json:"proof_s_sk,omitempty"` - ProofSE []byte `protobuf:"bytes,6,opt,name=proof_s_e,json=proofSE,proto3" json:"proof_s_e,omitempty"` - ProofSR2 []byte `protobuf:"bytes,7,opt,name=proof_s_r2,json=proofSR2,proto3" json:"proof_s_r2,omitempty"` - ProofSR3 []byte `protobuf:"bytes,8,opt,name=proof_s_r3,json=proofSR3,proto3" json:"proof_s_r3,omitempty"` - ProofSSPrime []byte `protobuf:"bytes,9,opt,name=proof_s_s_prime,json=proofSSPrime,proto3" json:"proof_s_s_prime,omitempty"` - ProofSAttrs [][]byte `protobuf:"bytes,10,rep,name=proof_s_attrs,json=proofSAttrs,proto3" json:"proof_s_attrs,omitempty"` - Nonce []byte `protobuf:"bytes,11,opt,name=nonce,proto3" json:"nonce,omitempty"` - Nym *ECP `protobuf:"bytes,12,opt,name=nym" json:"nym,omitempty"` - ProofSRNym []byte `protobuf:"bytes,13,opt,name=proof_s_r_nym,json=proofSRNym,proto3" json:"proof_s_r_nym,omitempty"` - RevocationEpochPk *ECP2 `protobuf:"bytes,14,opt,name=revocation_epoch_pk,json=revocationEpochPk" json:"revocation_epoch_pk,omitempty"` - RevocationPkSig []byte `protobuf:"bytes,15,opt,name=revocation_pk_sig,json=revocationPkSig,proto3" json:"revocation_pk_sig,omitempty"` - Epoch int64 `protobuf:"varint,16,opt,name=epoch" json:"epoch,omitempty"` - NonRevocationProof *NonRevocationProof `protobuf:"bytes,17,opt,name=non_revocation_proof,json=nonRevocationProof" json:"non_revocation_proof,omitempty"` -} - -func (m *Signature) Reset() { *m = Signature{} } -func (m *Signature) String() string { return proto.CompactTextString(m) } -func (*Signature) ProtoMessage() {} -func (*Signature) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } + APrime *ECP `protobuf:"bytes,1,opt,name=a_prime,json=aPrime,proto3" json:"a_prime,omitempty"` + ABar *ECP `protobuf:"bytes,2,opt,name=a_bar,json=aBar,proto3" json:"a_bar,omitempty"` + BPrime *ECP `protobuf:"bytes,3,opt,name=b_prime,json=bPrime,proto3" json:"b_prime,omitempty"` + ProofC []byte `protobuf:"bytes,4,opt,name=proof_c,json=proofC,proto3" json:"proof_c,omitempty"` + ProofSSk []byte `protobuf:"bytes,5,opt,name=proof_s_sk,json=proofSSk,proto3" json:"proof_s_sk,omitempty"` + ProofSE []byte `protobuf:"bytes,6,opt,name=proof_s_e,json=proofSE,proto3" json:"proof_s_e,omitempty"` + ProofSR2 []byte `protobuf:"bytes,7,opt,name=proof_s_r2,json=proofSR2,proto3" json:"proof_s_r2,omitempty"` + ProofSR3 []byte `protobuf:"bytes,8,opt,name=proof_s_r3,json=proofSR3,proto3" json:"proof_s_r3,omitempty"` + ProofSSPrime []byte `protobuf:"bytes,9,opt,name=proof_s_s_prime,json=proofSSPrime,proto3" json:"proof_s_s_prime,omitempty"` + ProofSAttrs [][]byte `protobuf:"bytes,10,rep,name=proof_s_attrs,json=proofSAttrs,proto3" json:"proof_s_attrs,omitempty"` + Nonce []byte `protobuf:"bytes,11,opt,name=nonce,proto3" json:"nonce,omitempty"` + Nym *ECP `protobuf:"bytes,12,opt,name=nym,proto3" json:"nym,omitempty"` + ProofSRNym []byte `protobuf:"bytes,13,opt,name=proof_s_r_nym,json=proofSRNym,proto3" json:"proof_s_r_nym,omitempty"` + RevocationEpochPk *ECP2 `protobuf:"bytes,14,opt,name=revocation_epoch_pk,json=revocationEpochPk,proto3" json:"revocation_epoch_pk,omitempty"` + RevocationPkSig []byte `protobuf:"bytes,15,opt,name=revocation_pk_sig,json=revocationPkSig,proto3" json:"revocation_pk_sig,omitempty"` + Epoch int64 `protobuf:"varint,16,opt,name=epoch,proto3" json:"epoch,omitempty"` + NonRevocationProof *NonRevocationProof `protobuf:"bytes,17,opt,name=non_revocation_proof,json=nonRevocationProof,proto3" json:"non_revocation_proof,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Signature) Reset() { *m = Signature{} } +func (m *Signature) String() string { return proto.CompactTextString(m) } +func (*Signature) ProtoMessage() {} +func (*Signature) Descriptor() ([]byte, []int) { + return fileDescriptor_idemix_ea623f6980eee47e, []int{6} +} +func (m *Signature) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Signature.Unmarshal(m, b) +} +func (m *Signature) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Signature.Marshal(b, m, deterministic) +} +func (dst *Signature) XXX_Merge(src proto.Message) { + xxx_messageInfo_Signature.Merge(dst, src) +} +func (m *Signature) XXX_Size() int { + return xxx_messageInfo_Signature.Size(m) +} +func (m *Signature) XXX_DiscardUnknown() { + xxx_messageInfo_Signature.DiscardUnknown(m) +} + +var xxx_messageInfo_Signature proto.InternalMessageInfo func (m *Signature) GetAPrime() *ECP { if m != nil { @@ -472,14 +608,36 @@ func (m *Signature) GetNonRevocationProof() *NonRevocationProof { // NonRevocationProof contains proof that the credential is not revoked type NonRevocationProof struct { - RevocationAlg int32 `protobuf:"varint,1,opt,name=revocation_alg,json=revocationAlg" json:"revocation_alg,omitempty"` - NonRevocationProof []byte `protobuf:"bytes,2,opt,name=non_revocation_proof,json=nonRevocationProof,proto3" json:"non_revocation_proof,omitempty"` + RevocationAlg int32 `protobuf:"varint,1,opt,name=revocation_alg,json=revocationAlg,proto3" json:"revocation_alg,omitempty"` + NonRevocationProof []byte `protobuf:"bytes,2,opt,name=non_revocation_proof,json=nonRevocationProof,proto3" json:"non_revocation_proof,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *NonRevocationProof) Reset() { *m = NonRevocationProof{} } +func (m *NonRevocationProof) String() string { return proto.CompactTextString(m) } +func (*NonRevocationProof) ProtoMessage() {} +func (*NonRevocationProof) Descriptor() ([]byte, []int) { + return fileDescriptor_idemix_ea623f6980eee47e, []int{7} +} +func (m *NonRevocationProof) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_NonRevocationProof.Unmarshal(m, b) +} +func (m *NonRevocationProof) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_NonRevocationProof.Marshal(b, m, deterministic) +} +func (dst *NonRevocationProof) XXX_Merge(src proto.Message) { + xxx_messageInfo_NonRevocationProof.Merge(dst, src) +} +func (m *NonRevocationProof) XXX_Size() int { + return xxx_messageInfo_NonRevocationProof.Size(m) +} +func (m *NonRevocationProof) XXX_DiscardUnknown() { + xxx_messageInfo_NonRevocationProof.DiscardUnknown(m) } -func (m *NonRevocationProof) Reset() { *m = NonRevocationProof{} } -func (m *NonRevocationProof) String() string { return proto.CompactTextString(m) } -func (*NonRevocationProof) ProtoMessage() {} -func (*NonRevocationProof) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } +var xxx_messageInfo_NonRevocationProof proto.InternalMessageInfo func (m *NonRevocationProof) GetRevocationAlg() int32 { if m != nil { @@ -508,13 +666,35 @@ type NymSignature struct { // proof_s_r_nym is the s-value proving knowledge of the pseudonym secret ProofSRNym []byte `protobuf:"bytes,3,opt,name=proof_s_r_nym,json=proofSRNym,proto3" json:"proof_s_r_nym,omitempty"` // nonce is a fresh nonce used for the signature - Nonce []byte `protobuf:"bytes,4,opt,name=nonce,proto3" json:"nonce,omitempty"` + Nonce []byte `protobuf:"bytes,4,opt,name=nonce,proto3" json:"nonce,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *NymSignature) Reset() { *m = NymSignature{} } +func (m *NymSignature) String() string { return proto.CompactTextString(m) } +func (*NymSignature) ProtoMessage() {} +func (*NymSignature) Descriptor() ([]byte, []int) { + return fileDescriptor_idemix_ea623f6980eee47e, []int{8} +} +func (m *NymSignature) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_NymSignature.Unmarshal(m, b) +} +func (m *NymSignature) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_NymSignature.Marshal(b, m, deterministic) +} +func (dst *NymSignature) XXX_Merge(src proto.Message) { + xxx_messageInfo_NymSignature.Merge(dst, src) +} +func (m *NymSignature) XXX_Size() int { + return xxx_messageInfo_NymSignature.Size(m) +} +func (m *NymSignature) XXX_DiscardUnknown() { + xxx_messageInfo_NymSignature.DiscardUnknown(m) } -func (m *NymSignature) Reset() { *m = NymSignature{} } -func (m *NymSignature) String() string { return proto.CompactTextString(m) } -func (*NymSignature) ProtoMessage() {} -func (*NymSignature) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } +var xxx_messageInfo_NymSignature proto.InternalMessageInfo func (m *NymSignature) GetProofC() []byte { if m != nil { @@ -546,21 +726,43 @@ func (m *NymSignature) GetNonce() []byte { type CredentialRevocationInformation struct { // epoch contains the epoch (time window) in which this CRI is valid - Epoch int64 `protobuf:"varint,1,opt,name=epoch" json:"epoch,omitempty"` + Epoch int64 `protobuf:"varint,1,opt,name=epoch,proto3" json:"epoch,omitempty"` // epoch_pk is the public key that is used by the revocation authority in this epoch - EpochPk *ECP2 `protobuf:"bytes,2,opt,name=epoch_pk,json=epochPk" json:"epoch_pk,omitempty"` + EpochPk *ECP2 `protobuf:"bytes,2,opt,name=epoch_pk,json=epochPk,proto3" json:"epoch_pk,omitempty"` // epoch_pk_sig is a signature on the EpochPK valid under the revocation authority's long term key EpochPkSig []byte `protobuf:"bytes,3,opt,name=epoch_pk_sig,json=epochPkSig,proto3" json:"epoch_pk_sig,omitempty"` // revocation_alg denotes which revocation algorithm is used - RevocationAlg int32 `protobuf:"varint,4,opt,name=revocation_alg,json=revocationAlg" json:"revocation_alg,omitempty"` + RevocationAlg int32 `protobuf:"varint,4,opt,name=revocation_alg,json=revocationAlg,proto3" json:"revocation_alg,omitempty"` // revocation_data contains data specific to the revocation algorithm used - RevocationData []byte `protobuf:"bytes,5,opt,name=revocation_data,json=revocationData,proto3" json:"revocation_data,omitempty"` + RevocationData []byte `protobuf:"bytes,5,opt,name=revocation_data,json=revocationData,proto3" json:"revocation_data,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CredentialRevocationInformation) Reset() { *m = CredentialRevocationInformation{} } +func (m *CredentialRevocationInformation) String() string { return proto.CompactTextString(m) } +func (*CredentialRevocationInformation) ProtoMessage() {} +func (*CredentialRevocationInformation) Descriptor() ([]byte, []int) { + return fileDescriptor_idemix_ea623f6980eee47e, []int{9} +} +func (m *CredentialRevocationInformation) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CredentialRevocationInformation.Unmarshal(m, b) +} +func (m *CredentialRevocationInformation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CredentialRevocationInformation.Marshal(b, m, deterministic) +} +func (dst *CredentialRevocationInformation) XXX_Merge(src proto.Message) { + xxx_messageInfo_CredentialRevocationInformation.Merge(dst, src) +} +func (m *CredentialRevocationInformation) XXX_Size() int { + return xxx_messageInfo_CredentialRevocationInformation.Size(m) +} +func (m *CredentialRevocationInformation) XXX_DiscardUnknown() { + xxx_messageInfo_CredentialRevocationInformation.DiscardUnknown(m) } -func (m *CredentialRevocationInformation) Reset() { *m = CredentialRevocationInformation{} } -func (m *CredentialRevocationInformation) String() string { return proto.CompactTextString(m) } -func (*CredentialRevocationInformation) ProtoMessage() {} -func (*CredentialRevocationInformation) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } +var xxx_messageInfo_CredentialRevocationInformation proto.InternalMessageInfo func (m *CredentialRevocationInformation) GetEpoch() int64 { if m != nil { @@ -610,9 +812,9 @@ func init() { proto.RegisterType((*CredentialRevocationInformation)(nil), "CredentialRevocationInformation") } -func init() { proto.RegisterFile("idemix/idemix.proto", fileDescriptor0) } +func init() { proto.RegisterFile("idemix/idemix.proto", fileDescriptor_idemix_ea623f6980eee47e) } -var fileDescriptor0 = []byte{ +var fileDescriptor_idemix_ea623f6980eee47e = []byte{ // 816 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x55, 0xdd, 0x6e, 0xe2, 0x46, 0x14, 0xd6, 0x60, 0x9b, 0x84, 0x83, 0x13, 0xb2, 0x93, 0xa8, 0x3b, 0xfd, 0x53, 0x59, 0xab, 0xdb, diff --git a/vendor/github.com/hyperledger/fabric/idemix/issuerkey.go b/vendor/github.com/hyperledger/fabric/idemix/issuerkey.go index b69cc5b2b..6092b8da2 100644 --- a/vendor/github.com/hyperledger/fabric/idemix/issuerkey.go +++ b/vendor/github.com/hyperledger/fabric/idemix/issuerkey.go @@ -25,7 +25,11 @@ import ( // NewIssuerKey creates a new issuer key pair taking an array of attribute names // that will be contained in credentials certified by this issuer (a credential specification) +// See http://eprint.iacr.org/2016/663.pdf Sec. 4.3, for references. func NewIssuerKey(AttributeNames []string, rng *amcl.RAND) (*IssuerKey, error) { + // validate inputs + + // check for duplicated attributes attributeNamesMap := map[string]bool{} for _, name := range AttributeNames { if attributeNamesMap[name] { @@ -53,9 +57,11 @@ func NewIssuerKey(AttributeNames []string, rng *amcl.RAND) (*IssuerKey, error) { key.Ipk.HAttrs[i] = EcpToProto(GenG1.Mul(RandModOrder(rng))) } + // generate base for the secret key HSk := GenG1.Mul(RandModOrder(rng)) key.Ipk.HSk = EcpToProto(HSk) + // generate base for the randomness HRand := GenG1.Mul(RandModOrder(rng)) key.Ipk.HRand = EcpToProto(HRand) @@ -65,11 +71,17 @@ func NewIssuerKey(AttributeNames []string, rng *amcl.RAND) (*IssuerKey, error) { BarG2 := BarG1.Mul(ISk) key.Ipk.BarG2 = EcpToProto(BarG2) - // generate a zero-knowledge proof of knowledge (ZK PoK) of the secret key + // generate a zero-knowledge proof of knowledge (ZK PoK) of the secret key which + // is in W and BarG2. + + // Sample the randomness needed for the proof r := RandModOrder(rng) - t1 := GenG2.Mul(r) - t2 := BarG1.Mul(r) + // Step 1: First message (t-values) + t1 := GenG2.Mul(r) // t1 = g_2^r, cover W + t2 := BarG1.Mul(r) // t2 = (\bar g_1)^r, cover BarG2 + + // Step 2: Compute the Fiat-Shamir hash, forming the challenge of the ZKP. proofData := make([]byte, 18*FieldBytes+3) index := 0 index = appendBytesG2(proofData, index, t1) @@ -82,21 +94,25 @@ func NewIssuerKey(AttributeNames []string, rng *amcl.RAND) (*IssuerKey, error) { proofC := HashModOrder(proofData) key.Ipk.ProofC = BigToBytes(proofC) - proofS := Modadd(FP256BN.Modmul(proofC, ISk, GroupOrder), r, GroupOrder) + // Step 3: reply to the challenge message (s-values) + proofS := Modadd(FP256BN.Modmul(proofC, ISk, GroupOrder), r, GroupOrder) // // s = r + C \cdot ISk key.Ipk.ProofS = BigToBytes(proofS) + // Hash the public key serializedIPk, err := proto.Marshal(key.Ipk) if err != nil { return nil, errors.Wrap(err, "failed to marshal issuer public key") } key.Ipk.Hash = BigToBytes(HashModOrder(serializedIPk)) + // We are done return key, nil } // Check checks that this issuer public key is valid, i.e. // that all components are present and a ZK proofs verifies func (IPk *IssuerPublicKey) Check() error { + // Unmarshall the public key NumAttrs := len(IPk.GetAttributeNames()) HSk := EcpFromProto(IPk.GetHSk()) HRand := EcpFromProto(IPk.GetHRand()) @@ -110,6 +126,7 @@ func (IPk *IssuerPublicKey) Check() error { ProofC := FP256BN.FromBytes(IPk.GetProofC()) ProofS := FP256BN.FromBytes(IPk.GetProofS()) + // Check that the public key is well-formed if NumAttrs < 0 || HSk == nil || HRand == nil || @@ -126,14 +143,18 @@ func (IPk *IssuerPublicKey) Check() error { } } - // Check Proof + // Verify Proof + + // Recompute challenge proofData := make([]byte, 18*FieldBytes+3) index := 0 + // Recompute t-values using s-values t1 := GenG2.Mul(ProofS) - t1.Add(W.Mul(FP256BN.Modneg(ProofC, GroupOrder))) + t1.Add(W.Mul(FP256BN.Modneg(ProofC, GroupOrder))) // t1 = g_2^s \cdot W^{-C} + t2 := BarG1.Mul(ProofS) - t2.Add(BarG2.Mul(FP256BN.Modneg(ProofC, GroupOrder))) + t2.Add(BarG2.Mul(FP256BN.Modneg(ProofC, GroupOrder))) // t2 = {\bar g_1}^s \cdot {\bar g_2}^C index = appendBytesG2(proofData, index, t1) index = appendBytesG1(proofData, index, t2) @@ -142,6 +163,7 @@ func (IPk *IssuerPublicKey) Check() error { index = appendBytesG2(proofData, index, W) index = appendBytesG1(proofData, index, BarG2) + // Verify that the challenge is the same if *ProofC != *HashModOrder(proofData) { return errors.Errorf("zero knowledge proof in public key invalid") } diff --git a/vendor/github.com/hyperledger/fabric/idemix/nonrevocation-prover.go b/vendor/github.com/hyperledger/fabric/idemix/nonrevocation-prover.go index b7ec943e6..fd259abc6 100644 --- a/vendor/github.com/hyperledger/fabric/idemix/nonrevocation-prover.go +++ b/vendor/github.com/hyperledger/fabric/idemix/nonrevocation-prover.go @@ -12,21 +12,29 @@ import ( "github.com/pkg/errors" ) +// nonRevokedProver is the Prover of the ZK proof system that handles revocation. type nonRevokedProver interface { + // getFSContribution returns the non-revocation contribution to the Fiat-Shamir hash, forming the challenge of the ZKP, getFSContribution(rh *FP256BN.BIG, rRh *FP256BN.BIG, cri *CredentialRevocationInformation, rng *amcl.RAND) ([]byte, error) + + // getNonRevokedProof returns a proof of non-revocation with the respect to passed challenge getNonRevokedProof(chal *FP256BN.BIG) (*NonRevocationProof, error) } + +// nopNonRevokedProver is an empty nonRevokedProver type nopNonRevokedProver struct{} func (prover *nopNonRevokedProver) getFSContribution(rh *FP256BN.BIG, rRh *FP256BN.BIG, cri *CredentialRevocationInformation, rng *amcl.RAND) ([]byte, error) { return nil, nil } + func (prover *nopNonRevokedProver) getNonRevokedProof(chal *FP256BN.BIG) (*NonRevocationProof, error) { ret := &NonRevocationProof{} ret.RevocationAlg = int32(ALG_NO_REVOCATION) return ret, nil } +// getNonRevocationProver returns the nonRevokedProver bound to the passed revocation algorithm func getNonRevocationProver(algorithm RevocationAlgorithm) (nonRevokedProver, error) { switch algorithm { case ALG_NO_REVOCATION: diff --git a/vendor/github.com/hyperledger/fabric/idemix/nonrevocation-verifier.go b/vendor/github.com/hyperledger/fabric/idemix/nonrevocation-verifier.go index a7a96abc0..75526342d 100644 --- a/vendor/github.com/hyperledger/fabric/idemix/nonrevocation-verifier.go +++ b/vendor/github.com/hyperledger/fabric/idemix/nonrevocation-verifier.go @@ -11,15 +11,20 @@ import ( "github.com/pkg/errors" ) +// nonRevokedProver is the Verifier of the ZK proof system that handles revocation. type nonRevocationVerifier interface { + // recomputeFSContribution recomputes the contribution of the non-revocation proof to the ZKP challenge recomputeFSContribution(proof *NonRevocationProof, chal *FP256BN.BIG, epochPK *FP256BN.ECP2, proofSRh *FP256BN.BIG) ([]byte, error) } + +// nopNonRevocationVerifier is an empty nonRevocationVerifier that produces an empty contribution type nopNonRevocationVerifier struct{} func (verifier *nopNonRevocationVerifier) recomputeFSContribution(proof *NonRevocationProof, chal *FP256BN.BIG, epochPK *FP256BN.ECP2, proofSRh *FP256BN.BIG) ([]byte, error) { return nil, nil } +// getNonRevocationVerifier returns the nonRevocationVerifier bound to the passed revocation algorithm func getNonRevocationVerifier(algorithm RevocationAlgorithm) (nonRevocationVerifier, error) { switch algorithm { case ALG_NO_REVOCATION: diff --git a/vendor/github.com/hyperledger/fabric/idemix/nymsignature.go b/vendor/github.com/hyperledger/fabric/idemix/nymsignature.go index 68a58ea92..061fb5b1a 100644 --- a/vendor/github.com/hyperledger/fabric/idemix/nymsignature.go +++ b/vendor/github.com/hyperledger/fabric/idemix/nymsignature.go @@ -14,6 +14,7 @@ import ( // NewSignature creates a new idemix pseudonym signature func NewNymSignature(sk *FP256BN.BIG, Nym *FP256BN.ECP, RNym *FP256BN.BIG, ipk *IssuerPublicKey, msg []byte, rng *amcl.RAND) (*NymSignature, error) { + // Validate inputs if sk == nil || Nym == nil || RNym == nil || ipk == nil || rng == nil { return nil, errors.Errorf("cannot create NymSignature: received nil input") } @@ -25,15 +26,16 @@ func NewNymSignature(sk *FP256BN.BIG, Nym *FP256BN.ECP, RNym *FP256BN.BIG, ipk * // The rest of this function constructs the non-interactive zero knowledge proof proving that // the signer 'owns' this pseudonym, i.e., it knows the secret key and randomness on which it is based. + // Recall that (Nym,RNym) is the output of MakeNym. Therefore, Nym = h_{sk}^sk \cdot h_r^r - // take the randomness used to compute the commitment values (aka t-values) for the ZKP + // Sample the randomness needed for the proof rSk := RandModOrder(rng) rRNym := RandModOrder(rng) - // Compute the commitment (aka t-value) - t := HSk.Mul2(rSk, HRand, rRNym) + // Step 1: First message (t-values) + t := HSk.Mul2(rSk, HRand, rRNym) // t = h_{sk}^{r_sk} \cdot h_r^{r_{RNym} - // Next, we compute the Fiat-Shamir hash, forming the challenge of the ZKP. + // Step 2: Compute the Fiat-Shamir hash, forming the challenge of the ZKP. // proofData will hold the data being hashed, it consists of: // - the signature label // - 2 elements of G1 each taking 2*FieldBytes+1 bytes @@ -49,7 +51,6 @@ func NewNymSignature(sk *FP256BN.BIG, Nym *FP256BN.ECP, RNym *FP256BN.BIG, ipk * index = index + FieldBytes copy(proofData[index:], msg) c := HashModOrder(proofData) - // combine the previous hash and the nonce and hash again to compute the final Fiat-Shamir value 'ProofC' index = 0 proofData = proofData[:2*FieldBytes] @@ -57,9 +58,9 @@ func NewNymSignature(sk *FP256BN.BIG, Nym *FP256BN.ECP, RNym *FP256BN.BIG, ipk * index = appendBytesBig(proofData, index, Nonce) ProofC := HashModOrder(proofData) - // Finally, we compute the s-values, which form the response answering challenge c - ProofSSk := Modadd(rSk, FP256BN.Modmul(ProofC, sk, GroupOrder), GroupOrder) - ProofSRNym := Modadd(rRNym, FP256BN.Modmul(ProofC, RNym, GroupOrder), GroupOrder) + // Step 3: reply to the challenge message (s-values) + ProofSSk := Modadd(rSk, FP256BN.Modmul(ProofC, sk, GroupOrder), GroupOrder) // s_{sk} = r_{sk} + C \cdot sk + ProofSRNym := Modadd(rRNym, FP256BN.Modmul(ProofC, RNym, GroupOrder), GroupOrder) // s_{RNym} = r_{RNym} + C \cdot RNym // The signature consists of the Fiat-Shamir hash (ProofC), the s-values (ProofSSk, ProofSRNym), and the nonce. return &NymSignature{ @@ -74,21 +75,18 @@ func (sig *NymSignature) Ver(nym *FP256BN.ECP, ipk *IssuerPublicKey, msg []byte) ProofC := FP256BN.FromBytes(sig.GetProofC()) ProofSSk := FP256BN.FromBytes(sig.GetProofSSk()) ProofSRNym := FP256BN.FromBytes(sig.GetProofSRNym()) - Nonce := FP256BN.FromBytes(sig.GetNonce()) HRand := EcpFromProto(ipk.HRand) HSk := EcpFromProto(ipk.HSk) + // Verify Proof + + // Recompute t-values using s-values t := HSk.Mul2(ProofSSk, HRand, ProofSRNym) - t.Sub(nym.Mul(ProofC)) - - // proofData is the data being hashed, it consists of: - // the signature label - // 2 elements of G1 each taking 2*FieldBytes+1 bytes - // one bigint (hash of the issuer public key) of length FieldBytes - // disclosed attributes - // message being signed + t.Sub(nym.Mul(ProofC)) // t = h_{sk}^{s_{sk} \ cdot h_r^{s_{RNym} + + // Recompute challenge proofData := make([]byte, len([]byte(signLabel))+2*(2*FieldBytes+1)+FieldBytes+len(msg)) index := 0 index = appendBytesString(proofData, index, signLabel) @@ -97,12 +95,12 @@ func (sig *NymSignature) Ver(nym *FP256BN.ECP, ipk *IssuerPublicKey, msg []byte) copy(proofData[index:], ipk.Hash) index = index + FieldBytes copy(proofData[index:], msg) - c := HashModOrder(proofData) index = 0 proofData = proofData[:2*FieldBytes] index = appendBytesBig(proofData, index, c) index = appendBytesBig(proofData, index, Nonce) + if *ProofC != *HashModOrder(proofData) { return errors.Errorf("pseudonym signature invalid: zero-knowledge proof is invalid") } diff --git a/vendor/github.com/hyperledger/fabric/idemix/revocation_authority.go b/vendor/github.com/hyperledger/fabric/idemix/revocation_authority.go index 0ab1345d7..5d2712fc5 100644 --- a/vendor/github.com/hyperledger/fabric/idemix/revocation_authority.go +++ b/vendor/github.com/hyperledger/fabric/idemix/revocation_authority.go @@ -8,12 +8,10 @@ package idemix import ( "crypto/ecdsa" - + "crypto/elliptic" "crypto/rand" "crypto/sha256" - "crypto/elliptic" - "github.com/golang/protobuf/proto" "github.com/hyperledger/fabric-amcl/amcl" "github.com/hyperledger/fabric-amcl/amcl/FP256BN" diff --git a/vendor/github.com/hyperledger/fabric/idemix/signature.go b/vendor/github.com/hyperledger/fabric/idemix/signature.go index 73ad01838..47550fa50 100644 --- a/vendor/github.com/hyperledger/fabric/idemix/signature.go +++ b/vendor/github.com/hyperledger/fabric/idemix/signature.go @@ -8,14 +8,16 @@ package idemix import ( "crypto/ecdsa" - "sort" "github.com/hyperledger/fabric-amcl/amcl" "github.com/hyperledger/fabric-amcl/amcl/FP256BN" + "github.com/hyperledger/fabric/common/flogging" "github.com/pkg/errors" ) +var idemixLogger = flogging.MustGetLogger("idemix") + // signLabel is the label used in zero-knowledge proof (ZKP) to identify that this ZKP is a signature of knowledge const signLabel = "sign" @@ -47,8 +49,9 @@ func hiddenIndices(Disclosure []byte) []int { // The []byte Disclosure steers which attributes are disclosed: // if Disclosure[i] == 0 then attribute i remains hidden and otherwise it is disclosed. // We require the revocation handle to remain undisclosed (i.e., Disclosure[rhIndex] == 0). -// We use the zero-knowledge proof by http://eprint.iacr.org/2016/663.pdf to prove knowledge of a BBS+ signature +// We use the zero-knowledge proof by http://eprint.iacr.org/2016/663.pdf, Sec. 4.5 to prove knowledge of a BBS+ signature func NewSignature(cred *Credential, sk *FP256BN.BIG, Nym *FP256BN.ECP, RNym *FP256BN.BIG, ipk *IssuerPublicKey, Disclosure []byte, msg []byte, rhIndex int, cri *CredentialRevocationInformation, rng *amcl.RAND) (*Signature, error) { + // Validate inputs if cred == nil || sk == nil || Nym == nil || RNym == nil || ipk == nil || rng == nil || cri == nil { return nil, errors.Errorf("cannot create idemix signature: received nil input") } @@ -61,68 +64,106 @@ func NewSignature(cred *Credential, sk *FP256BN.BIG, Nym *FP256BN.ECP, RNym *FP2 return nil, errors.Errorf("Attribute %d is disclosed but also used as revocation handle attribute, which should remain hidden.", rhIndex) } + // locate the indices of the attributes to hide and sample randomness for them HiddenIndices := hiddenIndices(Disclosure) - // Start sig + // Generate required randomness r_1, r_2 r1 := RandModOrder(rng) r2 := RandModOrder(rng) + // Set r_3 as \frac{1}{r_1} r3 := FP256BN.NewBIGcopy(r1) r3.Invmodp(GroupOrder) + // Sample a nonce Nonce := RandModOrder(rng) + // Parse credential A := EcpFromProto(cred.A) B := EcpFromProto(cred.B) - APrime := FP256BN.G1mul(A, r1) // A' = A^{r1} + // Randomize credential + + // Compute A' as A^{r_!} + APrime := FP256BN.G1mul(A, r1) + + // Compute ABar as A'^{-e} b^{r1} ABar := FP256BN.G1mul(B, r1) - ABar.Sub(FP256BN.G1mul(APrime, FP256BN.FromBytes(cred.E))) // barA = A'^{-e} b^{r1} + ABar.Sub(FP256BN.G1mul(APrime, FP256BN.FromBytes(cred.E))) + // Compute B' as b^{r1} / h_r^{r2}, where h_r is h_r BPrime := FP256BN.G1mul(B, r1) HRand := EcpFromProto(ipk.HRand) + // Parse h_{sk} from ipk HSk := EcpFromProto(ipk.HSk) - BPrime.Sub(FP256BN.G1mul(HRand, r2)) // b' = b^{r1} h_r^{-r2} + BPrime.Sub(FP256BN.G1mul(HRand, r2)) S := FP256BN.FromBytes(cred.S) E := FP256BN.FromBytes(cred.E) + + // Compute s' as s - r_2 \cdot r_3 sPrime := Modsub(S, FP256BN.Modmul(r2, r3, GroupOrder), GroupOrder) - // Construct ZK proof + // The rest of this function constructs the non-interactive zero knowledge proof + // that links the signature, the non-disclosed attributes and the nym. + + // Sample the randomness used to compute the commitment values (aka t-values) for the ZKP rSk := RandModOrder(rng) re := RandModOrder(rng) rR2 := RandModOrder(rng) rR3 := RandModOrder(rng) rSPrime := RandModOrder(rng) rRNym := RandModOrder(rng) + rAttrs := make([]*FP256BN.BIG, len(HiddenIndices)) for i := range HiddenIndices { rAttrs[i] = RandModOrder(rng) } - // compute non-revoked proof + // First compute the non-revocation proof. + // The challenge of the ZKP needs to depend on it, as well. prover, err := getNonRevocationProver(RevocationAlgorithm(cri.RevocationAlg)) if err != nil { return nil, err } - nonRevokedProofHashData, err := prover.getFSContribution(FP256BN.FromBytes(cred.Attrs[rhIndex]), rAttrs[sort.SearchInts(HiddenIndices, rhIndex)], cri, rng) + nonRevokedProofHashData, err := prover.getFSContribution( + FP256BN.FromBytes(cred.Attrs[rhIndex]), + rAttrs[sort.SearchInts(HiddenIndices, rhIndex)], + cri, + rng, + ) if err != nil { return nil, errors.Wrap(err, "failed to compute non-revoked proof") } - t1 := APrime.Mul2(re, HRand, rR2) - t2 := FP256BN.G1mul(HRand, rSPrime) - t2.Add(BPrime.Mul2(rR3, HSk, rSk)) + // Step 1: First message (t-values) + + // t1 is related to knowledge of the credential (recall, it is a BBS+ signature) + t1 := APrime.Mul2(re, HRand, rR2) // A'^{r_E} \cdot h_r^{r_{r2}} + // t2: is related to knowledge of the non-disclosed attributes that signed in (A,B,S,E) + t2 := FP256BN.G1mul(HRand, rSPrime) // h_r^{r_{s'}} + t2.Add(BPrime.Mul2(rR3, HSk, rSk)) // B'^{r_{r3}} \cdot h_{sk}^{r_{sk}} for i := 0; i < len(HiddenIndices)/2; i++ { - t2.Add(EcpFromProto(ipk.HAttrs[HiddenIndices[2*i]]).Mul2(rAttrs[2*i], EcpFromProto(ipk.HAttrs[HiddenIndices[2*i+1]]), rAttrs[2*i+1])) + t2.Add( + // \cdot h_{2 \cdot i}^{r_{attrs,i} + EcpFromProto(ipk.HAttrs[HiddenIndices[2*i]]).Mul2( + rAttrs[2*i], + EcpFromProto(ipk.HAttrs[HiddenIndices[2*i+1]]), + rAttrs[2*i+1], + ), + ) } if len(HiddenIndices)%2 != 0 { t2.Add(FP256BN.G1mul(EcpFromProto(ipk.HAttrs[HiddenIndices[len(HiddenIndices)-1]]), rAttrs[len(HiddenIndices)-1])) } - t3 := HSk.Mul2(rSk, HRand, rRNym) + // t3 is related to the knowledge of the secrets behind the pseudonym, which is also signed in (A,B,S,E) + t3 := HSk.Mul2(rSk, HRand, rRNym) // h_{sk}^{r_{sk}} \cdot h_r^{r_{rnym}} + // Step 2: Compute the Fiat-Shamir hash, forming the challenge of the ZKP. + + // Compute the Fiat-Shamir hash, forming the challenge of the ZKP. // proofData is the data being hashed, it consists of: // the signature label // 7 elements of G1 each taking 2*FieldBytes+1 bytes @@ -154,23 +195,29 @@ func NewSignature(cred *Credential, sk *FP256BN.BIG, Nym *FP256BN.ECP, RNym *FP2 index = appendBytesBig(proofData, index, c) index = appendBytesBig(proofData, index, Nonce) ProofC := HashModOrder(proofData) - ProofSSk := Modadd(rSk, FP256BN.Modmul(ProofC, sk, GroupOrder), GroupOrder) - ProofSE := Modsub(re, FP256BN.Modmul(ProofC, E, GroupOrder), GroupOrder) - ProofSR2 := Modadd(rR2, FP256BN.Modmul(ProofC, r2, GroupOrder), GroupOrder) - ProofSR3 := Modsub(rR3, FP256BN.Modmul(ProofC, r3, GroupOrder), GroupOrder) - ProofSSPrime := Modadd(rSPrime, FP256BN.Modmul(ProofC, sPrime, GroupOrder), GroupOrder) - ProofSRNym := Modadd(rRNym, FP256BN.Modmul(ProofC, RNym, GroupOrder), GroupOrder) + // Step 3: reply to the challenge message (s-values) + ProofSSk := Modadd(rSk, FP256BN.Modmul(ProofC, sk, GroupOrder), GroupOrder) // s_sk = rSK + C \cdot sk + ProofSE := Modsub(re, FP256BN.Modmul(ProofC, E, GroupOrder), GroupOrder) // s_e = re + C \cdot E + ProofSR2 := Modadd(rR2, FP256BN.Modmul(ProofC, r2, GroupOrder), GroupOrder) // s_r2 = rR2 + C \cdot r2 + ProofSR3 := Modsub(rR3, FP256BN.Modmul(ProofC, r3, GroupOrder), GroupOrder) // s_r3 = rR3 + C \cdot r3 + ProofSSPrime := Modadd(rSPrime, FP256BN.Modmul(ProofC, sPrime, GroupOrder), GroupOrder) // s_S' = rSPrime + C \cdot sPrime + ProofSRNym := Modadd(rRNym, FP256BN.Modmul(ProofC, RNym, GroupOrder), GroupOrder) // s_RNym = rRNym + C \cdot RNym ProofSAttrs := make([][]byte, len(HiddenIndices)) for i, j := range HiddenIndices { - ProofSAttrs[i] = BigToBytes(Modadd(rAttrs[i], FP256BN.Modmul(ProofC, FP256BN.FromBytes(cred.Attrs[j]), GroupOrder), GroupOrder)) + ProofSAttrs[i] = BigToBytes( + // s_attrsi = rAttrsi + C \cdot cred.Attrs[j] + Modadd(rAttrs[i], FP256BN.Modmul(ProofC, FP256BN.FromBytes(cred.Attrs[j]), GroupOrder), GroupOrder), + ) } + // Compute the revocation part nonRevokedProof, err := prover.getNonRevokedProof(ProofC) if err != nil { return nil, err } + // We are done. Return signature return &Signature{ APrime: EcpToProto(APrime), ABar: EcpToProto(ABar), @@ -197,6 +244,7 @@ func NewSignature(cred *Credential, sk *FP256BN.BIG, Nym *FP256BN.ECP, RNym *FP2 // attributeValues contains the desired attribute values. // This function will check that if attribute i is disclosed, the i-th attribute equals attributeValues[i]. func (sig *Signature) Ver(Disclosure []byte, ipk *IssuerPublicKey, msg []byte, attributeValues []*FP256BN.BIG, rhIndex int, revPk *ecdsa.PublicKey, epoch int) error { + // Validate inputs if ipk == nil || revPk == nil { return errors.Errorf("cannot verify idemix signature: received nil input") } @@ -211,6 +259,7 @@ func (sig *Signature) Ver(Disclosure []byte, ipk *IssuerPublicKey, msg []byte, a HiddenIndices := hiddenIndices(Disclosure) + // Parse signature APrime := EcpFromProto(sig.GetAPrime()) ABar := EcpFromProto(sig.GetABar()) BPrime := EcpFromProto(sig.GetBPrime()) @@ -230,13 +279,14 @@ func (sig *Signature) Ver(Disclosure []byte, ipk *IssuerPublicKey, msg []byte, a for i, b := range sig.ProofSAttrs { ProofSAttrs[i] = FP256BN.FromBytes(b) } - Nonce := FP256BN.FromBytes(sig.GetNonce()) + // Parse issuer public key W := Ecp2FromProto(ipk.W) HRand := EcpFromProto(ipk.HRand) HSk := EcpFromProto(ipk.HSk) + // Verify signature if APrime.Is_infinity() { return errors.Errorf("signature invalid: APrime = 1") } @@ -248,25 +298,28 @@ func (sig *Signature) Ver(Disclosure []byte, ipk *IssuerPublicKey, msg []byte, a return errors.Errorf("signature invalid: APrime and ABar don't have the expected structure") } + // Verify ZK proof + + // Recover t-values + + // Recompute t1 t1 := APrime.Mul2(ProofSE, HRand, ProofSR2) temp := FP256BN.NewECP() temp.Copy(ABar) temp.Sub(BPrime) t1.Sub(FP256BN.G1mul(temp, ProofC)) + // Recompute t2 t2 := FP256BN.G1mul(HRand, ProofSSPrime) t2.Add(BPrime.Mul2(ProofSR3, HSk, ProofSSk)) - for i := 0; i < len(HiddenIndices)/2; i++ { t2.Add(EcpFromProto(ipk.HAttrs[HiddenIndices[2*i]]).Mul2(ProofSAttrs[2*i], EcpFromProto(ipk.HAttrs[HiddenIndices[2*i+1]]), ProofSAttrs[2*i+1])) } if len(HiddenIndices)%2 != 0 { t2.Add(FP256BN.G1mul(EcpFromProto(ipk.HAttrs[HiddenIndices[len(HiddenIndices)-1]]), ProofSAttrs[len(HiddenIndices)-1])) } - temp = FP256BN.NewECP() temp.Copy(GenG1) - for index, disclose := range Disclosure { if disclose != 0 { temp.Add(FP256BN.G1mul(EcpFromProto(ipk.HAttrs[index]), attributeValues[index])) @@ -274,9 +327,11 @@ func (sig *Signature) Ver(Disclosure []byte, ipk *IssuerPublicKey, msg []byte, a } t2.Add(FP256BN.G1mul(temp, ProofC)) + // Recompute t3 t3 := HSk.Mul2(ProofSSk, HRand, ProofSRNym) t3.Sub(Nym.Mul(ProofC)) + // add contribution from the non-revocation proof nonRevokedVer, err := getNonRevocationVerifier(RevocationAlgorithm(sig.NonRevocationProof.RevocationAlg)) if err != nil { return err @@ -289,6 +344,7 @@ func (sig *Signature) Ver(Disclosure []byte, ipk *IssuerPublicKey, msg []byte, a return err } + // Recompute challenge // proofData is the data being hashed, it consists of: // the signature label // 7 elements of G1 each taking 2*FieldBytes+1 bytes @@ -317,9 +373,35 @@ func (sig *Signature) Ver(Disclosure []byte, ipk *IssuerPublicKey, msg []byte, a proofData = proofData[:2*FieldBytes] index = appendBytesBig(proofData, index, c) index = appendBytesBig(proofData, index, Nonce) + if *ProofC != *HashModOrder(proofData) { + // This debug line helps identify where the mismatch happened + idemixLogger.Debugf("Signature Verification : \n"+ + " [t1:%v]\n,"+ + " [t2:%v]\n,"+ + " [t3:%v]\n,"+ + " [APrime:%v]\n,"+ + " [ABar:%v]\n,"+ + " [BPrime:%v]\n,"+ + " [Nym:%v]\n,"+ + " [nonRevokedProofBytes:%v]\n,"+ + " [ipk.Hash:%v]\n,"+ + " [Disclosure:%v]\n,"+ + " [msg:%v]\n,", + EcpToBytes(t1), + EcpToBytes(t2), + EcpToBytes(t3), + EcpToBytes(APrime), + EcpToBytes(ABar), + EcpToBytes(BPrime), + EcpToBytes(Nym), + nonRevokedProofBytes, + ipk.Hash, + Disclosure, + msg) return errors.Errorf("signature invalid: zero-knowledge proof is invalid") } + // Signature is valid return nil } diff --git a/vendor/github.com/hyperledger/fabric/idemix/util.go b/vendor/github.com/hyperledger/fabric/idemix/util.go index 28905948e..43a336dca 100644 --- a/vendor/github.com/hyperledger/fabric/idemix/util.go +++ b/vendor/github.com/hyperledger/fabric/idemix/util.go @@ -60,6 +60,12 @@ func appendBytesG1(data []byte, index int, E *FP256BN.ECP) int { E.ToBytes(data[index:index+length], false) return index + length } +func EcpToBytes(E *FP256BN.ECP) []byte { + length := 2*FieldBytes + 1 + res := make([]byte, length) + E.ToBytes(res, false) + return res +} func appendBytesG2(data []byte, index int, E *FP256BN.ECP2) int { length := 4 * FieldBytes E.ToBytes(data[index : index+length]) @@ -78,6 +84,8 @@ func appendBytesString(data []byte, index int, s string) int { // MakeNym creates a new unlinkable pseudonym func MakeNym(sk *FP256BN.BIG, IPk *IssuerPublicKey, rng *amcl.RAND) (*FP256BN.ECP, *FP256BN.BIG) { + // Construct a commitment to the sk + // Nym = h_{sk}^sk \cdot h_r^r RandNym := RandModOrder(rng) Nym := EcpFromProto(IPk.HSk).Mul2(sk, EcpFromProto(IPk.HRand), RandNym) return Nym, RandNym diff --git a/vendor/vendor.json b/vendor/vendor.json index 83ec28c88..dc22041a1 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -425,10 +425,10 @@ "revisionTime": "2018-03-16T15:29:36Z" }, { - "checksumSHA1": "S0hEPC6nm2AwSsGQsEP1LRQOfFg=", + "checksumSHA1": "SciKezSPmS5x+LFe2AB2ERbxtF0=", "path": "github.com/hyperledger/fabric/bccsp", - "revision": "e01301116758fbabc54c688b461cb72fbc84862d", - "revisionTime": "2018-08-10T18:42:28Z", + "revision": "5b2b5616d49538ace14aa9e08a482b9089c78df8", + "revisionTime": "2018-12-05T11:40:09Z", "tree": true }, { @@ -456,10 +456,11 @@ "revisionTime": "2018-08-10T18:42:28Z" }, { - "checksumSHA1": "xIdsmorF1r6jym6Tz5UmzAvxhN8=", + "checksumSHA1": "PZEB7eAHAev0KuBWBfDvfGGIO9c=", "path": "github.com/hyperledger/fabric/idemix", - "revision": "4db57a3e5205a096e54bfbc5f5f07d6bd678220f", - "revisionTime": "2018-05-31T12:12:45Z" + "revision": "5b2b5616d49538ace14aa9e08a482b9089c78df8", + "revisionTime": "2018-12-05T11:40:09Z", + "tree": true }, { "checksumSHA1": "40vJyUB4ezQSn/NSadsKEOrudMc=",