github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/bccsp/sw/keyderiv.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package sw
    18  
    19  import (
    20  	"crypto/ecdsa"
    21  	"fmt"
    22  
    23  	"errors"
    24  	"math/big"
    25  
    26  	"crypto/hmac"
    27  
    28  	"github.com/hyperledger/fabric/bccsp"
    29  )
    30  
    31  type ecdsaPublicKeyKeyDeriver struct{}
    32  
    33  func (kd *ecdsaPublicKeyKeyDeriver) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, err error) {
    34  	// Validate opts
    35  	if opts == nil {
    36  		return nil, errors.New("Invalid opts parameter. It must not be nil.")
    37  	}
    38  
    39  	ecdsaK := k.(*ecdsaPublicKey)
    40  
    41  	switch opts.(type) {
    42  	// Re-randomized an ECDSA private key
    43  	case *bccsp.ECDSAReRandKeyOpts:
    44  		reRandOpts := opts.(*bccsp.ECDSAReRandKeyOpts)
    45  		tempSK := &ecdsa.PublicKey{
    46  			Curve: ecdsaK.pubKey.Curve,
    47  			X:     new(big.Int),
    48  			Y:     new(big.Int),
    49  		}
    50  
    51  		var k = new(big.Int).SetBytes(reRandOpts.ExpansionValue())
    52  		var one = new(big.Int).SetInt64(1)
    53  		n := new(big.Int).Sub(ecdsaK.pubKey.Params().N, one)
    54  		k.Mod(k, n)
    55  		k.Add(k, one)
    56  
    57  		// Compute temporary public key
    58  		tempX, tempY := ecdsaK.pubKey.ScalarBaseMult(k.Bytes())
    59  		tempSK.X, tempSK.Y = tempSK.Add(
    60  			ecdsaK.pubKey.X, ecdsaK.pubKey.Y,
    61  			tempX, tempY,
    62  		)
    63  
    64  		// Verify temporary public key is a valid point on the reference curve
    65  		isOn := tempSK.Curve.IsOnCurve(tempSK.X, tempSK.Y)
    66  		if !isOn {
    67  			return nil, errors.New("Failed temporary public key IsOnCurve check.")
    68  		}
    69  
    70  		return &ecdsaPublicKey{tempSK}, nil
    71  	default:
    72  		return nil, fmt.Errorf("Unsupported 'KeyDerivOpts' provided [%v]", opts)
    73  	}
    74  }
    75  
    76  type ecdsaPrivateKeyKeyDeriver struct{}
    77  
    78  func (kd *ecdsaPrivateKeyKeyDeriver) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, err error) {
    79  	// Validate opts
    80  	if opts == nil {
    81  		return nil, errors.New("Invalid opts parameter. It must not be nil.")
    82  	}
    83  
    84  	ecdsaK := k.(*ecdsaPrivateKey)
    85  
    86  	switch opts.(type) {
    87  	// Re-randomized an ECDSA private key
    88  	case *bccsp.ECDSAReRandKeyOpts:
    89  		reRandOpts := opts.(*bccsp.ECDSAReRandKeyOpts)
    90  		tempSK := &ecdsa.PrivateKey{
    91  			PublicKey: ecdsa.PublicKey{
    92  				Curve: ecdsaK.privKey.Curve,
    93  				X:     new(big.Int),
    94  				Y:     new(big.Int),
    95  			},
    96  			D: new(big.Int),
    97  		}
    98  
    99  		var k = new(big.Int).SetBytes(reRandOpts.ExpansionValue())
   100  		var one = new(big.Int).SetInt64(1)
   101  		n := new(big.Int).Sub(ecdsaK.privKey.Params().N, one)
   102  		k.Mod(k, n)
   103  		k.Add(k, one)
   104  
   105  		tempSK.D.Add(ecdsaK.privKey.D, k)
   106  		tempSK.D.Mod(tempSK.D, ecdsaK.privKey.PublicKey.Params().N)
   107  
   108  		// Compute temporary public key
   109  		tempX, tempY := ecdsaK.privKey.PublicKey.ScalarBaseMult(k.Bytes())
   110  		tempSK.PublicKey.X, tempSK.PublicKey.Y =
   111  			tempSK.PublicKey.Add(
   112  				ecdsaK.privKey.PublicKey.X, ecdsaK.privKey.PublicKey.Y,
   113  				tempX, tempY,
   114  			)
   115  
   116  		// Verify temporary public key is a valid point on the reference curve
   117  		isOn := tempSK.Curve.IsOnCurve(tempSK.PublicKey.X, tempSK.PublicKey.Y)
   118  		if !isOn {
   119  			return nil, errors.New("Failed temporary public key IsOnCurve check.")
   120  		}
   121  
   122  		return &ecdsaPrivateKey{tempSK}, nil
   123  	default:
   124  		return nil, fmt.Errorf("Unsupported 'KeyDerivOpts' provided [%v]", opts)
   125  	}
   126  }
   127  
   128  type aesPrivateKeyKeyDeriver struct {
   129  	bccsp *impl
   130  }
   131  
   132  func (kd *aesPrivateKeyKeyDeriver) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, err error) {
   133  	// Validate opts
   134  	if opts == nil {
   135  		return nil, errors.New("Invalid opts parameter. It must not be nil.")
   136  	}
   137  
   138  	aesK := k.(*aesPrivateKey)
   139  
   140  	switch opts.(type) {
   141  	case *bccsp.HMACTruncated256AESDeriveKeyOpts:
   142  		hmacOpts := opts.(*bccsp.HMACTruncated256AESDeriveKeyOpts)
   143  
   144  		mac := hmac.New(kd.bccsp.conf.hashFunction, aesK.privKey)
   145  		mac.Write(hmacOpts.Argument())
   146  		return &aesPrivateKey{mac.Sum(nil)[:kd.bccsp.conf.aesBitLength], false}, nil
   147  
   148  	case *bccsp.HMACDeriveKeyOpts:
   149  		hmacOpts := opts.(*bccsp.HMACDeriveKeyOpts)
   150  
   151  		mac := hmac.New(kd.bccsp.conf.hashFunction, aesK.privKey)
   152  		mac.Write(hmacOpts.Argument())
   153  		return &aesPrivateKey{mac.Sum(nil), true}, nil
   154  	default:
   155  		return nil, fmt.Errorf("Unsupported 'KeyDerivOpts' provided [%v]", opts)
   156  	}
   157  }