github.com/lzy4123/fabric@v2.1.1+incompatible/bccsp/idemix/bridge/signaturescheme.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 "crypto/ecdsa" 10 11 "github.com/golang/protobuf/proto" 12 "github.com/hyperledger/fabric-amcl/amcl" 13 "github.com/hyperledger/fabric-amcl/amcl/FP256BN" 14 "github.com/hyperledger/fabric/bccsp" 15 "github.com/hyperledger/fabric/bccsp/idemix/handlers" 16 cryptolib "github.com/hyperledger/fabric/idemix" 17 "github.com/pkg/errors" 18 ) 19 20 // SignatureScheme encapsulates the idemix algorithms to sign and verify using an idemix credential. 21 type SignatureScheme struct { 22 NewRand func() *amcl.RAND 23 } 24 25 // Sign produces an idemix-signature with the respect to the passed serialised credential (cred), 26 // user secret key (sk), pseudonym public key (Nym) and secret key (RNym), issuer public key (ipk), 27 // and attributes to be disclosed. 28 func (s *SignatureScheme) Sign(cred []byte, sk handlers.Big, Nym handlers.Ecp, RNym handlers.Big, ipk handlers.IssuerPublicKey, attributes []bccsp.IdemixAttribute, 29 msg []byte, rhIndex int, criRaw []byte) (res []byte, err error) { 30 defer func() { 31 if r := recover(); r != nil { 32 res = nil 33 err = errors.Errorf("failure [%s]", r) 34 } 35 }() 36 37 isk, ok := sk.(*Big) 38 if !ok { 39 return nil, errors.Errorf("invalid user secret key, expected *Big, got [%T]", sk) 40 } 41 inym, ok := Nym.(*Ecp) 42 if !ok { 43 return nil, errors.Errorf("invalid nym public key, expected *Ecp, got [%T]", Nym) 44 } 45 irnym, ok := RNym.(*Big) 46 if !ok { 47 return nil, errors.Errorf("invalid nym secret key, expected *Big, got [%T]", RNym) 48 } 49 iipk, ok := ipk.(*IssuerPublicKey) 50 if !ok { 51 return nil, errors.Errorf("invalid issuer public key, expected *IssuerPublicKey, got [%T]", ipk) 52 } 53 54 credential := &cryptolib.Credential{} 55 err = proto.Unmarshal(cred, credential) 56 if err != nil { 57 return nil, errors.Wrap(err, "failed unmarshalling credential") 58 } 59 60 cri := &cryptolib.CredentialRevocationInformation{} 61 err = proto.Unmarshal(criRaw, cri) 62 if err != nil { 63 return nil, errors.Wrap(err, "failed unmarshalling credential revocation information") 64 } 65 66 disclosure := make([]byte, len(attributes)) 67 for i := 0; i < len(attributes); i++ { 68 if attributes[i].Type == bccsp.IdemixHiddenAttribute { 69 disclosure[i] = 0 70 } else { 71 disclosure[i] = 1 72 } 73 } 74 75 sig, err := cryptolib.NewSignature( 76 credential, 77 isk.E, 78 inym.E, 79 irnym.E, 80 iipk.PK, 81 disclosure, 82 msg, 83 rhIndex, 84 cri, 85 s.NewRand()) 86 if err != nil { 87 return nil, errors.WithMessage(err, "failed creating new signature") 88 } 89 90 return proto.Marshal(sig) 91 } 92 93 // Verify checks that an idemix signature is valid with the respect to the passed issuer public key, digest, attributes, 94 // revocation index (rhIndex), revocation public key, and epoch. 95 func (*SignatureScheme) Verify(ipk handlers.IssuerPublicKey, signature, digest []byte, attributes []bccsp.IdemixAttribute, rhIndex int, revocationPublicKey *ecdsa.PublicKey, epoch int) (err error) { 96 defer func() { 97 if r := recover(); r != nil { 98 err = errors.Errorf("failure [%s]", r) 99 } 100 }() 101 102 iipk, ok := ipk.(*IssuerPublicKey) 103 if !ok { 104 return errors.Errorf("invalid issuer public key, expected *IssuerPublicKey, got [%T]", ipk) 105 } 106 107 sig := &cryptolib.Signature{} 108 err = proto.Unmarshal(signature, sig) 109 if err != nil { 110 return err 111 } 112 113 disclosure := make([]byte, len(attributes)) 114 attrValues := make([]*FP256BN.BIG, len(attributes)) 115 for i := 0; i < len(attributes); i++ { 116 switch attributes[i].Type { 117 case bccsp.IdemixHiddenAttribute: 118 disclosure[i] = 0 119 attrValues[i] = nil 120 case bccsp.IdemixBytesAttribute: 121 disclosure[i] = 1 122 attrValues[i] = cryptolib.HashModOrder(attributes[i].Value.([]byte)) 123 case bccsp.IdemixIntAttribute: 124 disclosure[i] = 1 125 attrValues[i] = FP256BN.NewBIGint(attributes[i].Value.(int)) 126 default: 127 err = errors.Errorf("attribute type not allowed or supported [%v] at position [%d]", attributes[i].Type, i) 128 } 129 } 130 if err != nil { 131 return 132 } 133 134 return sig.Ver( 135 disclosure, 136 iipk.PK, 137 digest, 138 attrValues, 139 rhIndex, 140 revocationPublicKey, 141 epoch) 142 }