github.com/lzy4123/fabric@v2.1.1+incompatible/bccsp/idemix/bridge/credrequest.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 package bridge 7 8 import ( 9 "bytes" 10 11 "github.com/golang/protobuf/proto" 12 "github.com/hyperledger/fabric-amcl/amcl" 13 "github.com/hyperledger/fabric/bccsp/idemix/handlers" 14 cryptolib "github.com/hyperledger/fabric/idemix" 15 "github.com/pkg/errors" 16 ) 17 18 // CredRequest encapsulates the idemix algorithms to produce (sign) a credential request 19 // and verify it. Recall that a credential request is produced by a user, 20 // and it is verified by the issuer at credential creation time. 21 type CredRequest struct { 22 NewRand func() *amcl.RAND 23 } 24 25 // Sign produces an idemix credential request. It takes in input a user secret key and 26 // an issuer public key. 27 func (cr *CredRequest) Sign(sk handlers.Big, ipk handlers.IssuerPublicKey, nonce []byte) (res []byte, err error) { 28 defer func() { 29 if r := recover(); r != nil { 30 res = nil 31 err = errors.Errorf("failure [%s]", r) 32 } 33 }() 34 35 isk, ok := sk.(*Big) 36 if !ok { 37 return nil, errors.Errorf("invalid user secret key, expected *Big, got [%T]", sk) 38 } 39 iipk, ok := ipk.(*IssuerPublicKey) 40 if !ok { 41 return nil, errors.Errorf("invalid issuer public key, expected *IssuerPublicKey, got [%T]", ipk) 42 } 43 if len(nonce) != cryptolib.FieldBytes { 44 return nil, errors.Errorf("invalid issuer nonce, expected length %d, got %d", cryptolib.FieldBytes, len(nonce)) 45 } 46 47 rng := cr.NewRand() 48 49 credRequest := cryptolib.NewCredRequest( 50 isk.E, 51 nonce, 52 iipk.PK, 53 rng) 54 55 return proto.Marshal(credRequest) 56 } 57 58 // Verify checks that the passed credential request is valid with the respect to the passed 59 // issuer public key. 60 func (*CredRequest) Verify(credentialRequest []byte, ipk handlers.IssuerPublicKey, nonce []byte) (err error) { 61 defer func() { 62 if r := recover(); r != nil { 63 err = errors.Errorf("failure [%s]", r) 64 } 65 }() 66 67 credRequest := &cryptolib.CredRequest{} 68 err = proto.Unmarshal(credentialRequest, credRequest) 69 if err != nil { 70 return err 71 } 72 73 iipk, ok := ipk.(*IssuerPublicKey) 74 if !ok { 75 return errors.Errorf("invalid issuer public key, expected *IssuerPublicKey, got [%T]", ipk) 76 } 77 78 err = credRequest.Check(iipk.PK) 79 if err != nil { 80 return err 81 } 82 83 // Nonce checks 84 if len(nonce) != cryptolib.FieldBytes { 85 return errors.Errorf("invalid issuer nonce, expected length %d, got %d", cryptolib.FieldBytes, len(nonce)) 86 } 87 if !bytes.Equal(nonce, credRequest.IssuerNonce) { 88 return errors.Errorf("invalid nonce, expected [%v], got [%v]", nonce, credRequest.IssuerNonce) 89 } 90 91 return nil 92 }