github.com/kaituanwang/hyperledger@v2.0.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  }