github.com/yimialmonte/fabric@v2.1.1+incompatible/bccsp/idemix/bridge/nymsignaturescheme.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  	"github.com/hyperledger/fabric-amcl/amcl"
    10  	"github.com/hyperledger/fabric/bccsp/idemix/handlers"
    11  
    12  	"github.com/golang/protobuf/proto"
    13  	cryptolib "github.com/hyperledger/fabric/idemix"
    14  	"github.com/pkg/errors"
    15  )
    16  
    17  // NymSignatureScheme encapsulates the idemix algorithms to sign and verify using an idemix
    18  // pseudonym.
    19  type NymSignatureScheme struct {
    20  	NewRand func() *amcl.RAND
    21  }
    22  
    23  // Sign produces a signature over the passed digest. It takes in input, the user secret key (sk),
    24  // the pseudonym public key (Nym) and secret key (RNym), and the issuer public key (ipk).
    25  func (n *NymSignatureScheme) Sign(sk handlers.Big, Nym handlers.Ecp, RNym handlers.Big, ipk handlers.IssuerPublicKey, digest []byte) (res []byte, err error) {
    26  	defer func() {
    27  		if r := recover(); r != nil {
    28  			res = nil
    29  			err = errors.Errorf("failure [%s]", r)
    30  		}
    31  	}()
    32  
    33  	isk, ok := sk.(*Big)
    34  	if !ok {
    35  		return nil, errors.Errorf("invalid user secret key, expected *Big, got [%T]", sk)
    36  	}
    37  	inym, ok := Nym.(*Ecp)
    38  	if !ok {
    39  		return nil, errors.Errorf("invalid nym public key, expected *Ecp, got [%T]", Nym)
    40  	}
    41  	irnym, ok := RNym.(*Big)
    42  	if !ok {
    43  		return nil, errors.Errorf("invalid nym secret key, expected *Big, got [%T]", RNym)
    44  	}
    45  	iipk, ok := ipk.(*IssuerPublicKey)
    46  	if !ok {
    47  		return nil, errors.Errorf("invalid issuer public key, expected *IssuerPublicKey, got [%T]", ipk)
    48  	}
    49  
    50  	sig, err := cryptolib.NewNymSignature(
    51  		isk.E,
    52  		inym.E,
    53  		irnym.E,
    54  		iipk.PK,
    55  		digest,
    56  		n.NewRand())
    57  	if err != nil {
    58  		return nil, errors.WithMessage(err, "failed creating new nym signature")
    59  	}
    60  
    61  	return proto.Marshal(sig)
    62  }
    63  
    64  // Verify checks that the passed signatures is valid with the respect to the passed digest, issuer public key,
    65  // and pseudonym public key.
    66  func (*NymSignatureScheme) Verify(ipk handlers.IssuerPublicKey, Nym handlers.Ecp, signature, digest []byte) (err error) {
    67  	defer func() {
    68  		if r := recover(); r != nil {
    69  			err = errors.Errorf("failure [%s]", r)
    70  		}
    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  	inym, ok := Nym.(*Ecp)
    78  	if !ok {
    79  		return errors.Errorf("invalid nym public key, expected *Ecp, got [%T]", Nym)
    80  	}
    81  
    82  	sig := &cryptolib.NymSignature{}
    83  	err = proto.Unmarshal(signature, sig)
    84  	if err != nil {
    85  		return errors.Wrap(err, "error unmarshalling signature")
    86  	}
    87  
    88  	return sig.Ver(inym.E, iipk.PK, digest)
    89  }