github.com/true-sqn/fabric@v2.1.1+incompatible/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  	"crypto/hmac"
    22  	"errors"
    23  	"fmt"
    24  	"math/big"
    25  
    26  	"github.com/hyperledger/fabric/bccsp"
    27  )
    28  
    29  type ecdsaPublicKeyKeyDeriver struct{}
    30  
    31  func (kd *ecdsaPublicKeyKeyDeriver) KeyDeriv(key bccsp.Key, opts bccsp.KeyDerivOpts) (bccsp.Key, error) {
    32  	// Validate opts
    33  	if opts == nil {
    34  		return nil, errors.New("Invalid opts parameter. It must not be nil.")
    35  	}
    36  
    37  	ecdsaK := key.(*ecdsaPublicKey)
    38  
    39  	// Re-randomized an ECDSA private key
    40  	reRandOpts, ok := opts.(*bccsp.ECDSAReRandKeyOpts)
    41  	if !ok {
    42  		return nil, fmt.Errorf("Unsupported 'KeyDerivOpts' provided [%v]", opts)
    43  	}
    44  
    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  }
    72  
    73  type ecdsaPrivateKeyKeyDeriver struct{}
    74  
    75  func (kd *ecdsaPrivateKeyKeyDeriver) KeyDeriv(key bccsp.Key, opts bccsp.KeyDerivOpts) (bccsp.Key, error) {
    76  	// Validate opts
    77  	if opts == nil {
    78  		return nil, errors.New("Invalid opts parameter. It must not be nil.")
    79  	}
    80  
    81  	ecdsaK := key.(*ecdsaPrivateKey)
    82  
    83  	// Re-randomized an ECDSA private key
    84  	reRandOpts, ok := opts.(*bccsp.ECDSAReRandKeyOpts)
    85  	if !ok {
    86  		return nil, fmt.Errorf("Unsupported 'KeyDerivOpts' provided [%v]", opts)
    87  	}
    88  
    89  	tempSK := &ecdsa.PrivateKey{
    90  		PublicKey: ecdsa.PublicKey{
    91  			Curve: ecdsaK.privKey.Curve,
    92  			X:     new(big.Int),
    93  			Y:     new(big.Int),
    94  		},
    95  		D: new(big.Int),
    96  	}
    97  
    98  	var k = new(big.Int).SetBytes(reRandOpts.ExpansionValue())
    99  	var one = new(big.Int).SetInt64(1)
   100  	n := new(big.Int).Sub(ecdsaK.privKey.Params().N, one)
   101  	k.Mod(k, n)
   102  	k.Add(k, one)
   103  
   104  	tempSK.D.Add(ecdsaK.privKey.D, k)
   105  	tempSK.D.Mod(tempSK.D, ecdsaK.privKey.PublicKey.Params().N)
   106  
   107  	// Compute temporary public key
   108  	tempX, tempY := ecdsaK.privKey.PublicKey.ScalarBaseMult(k.Bytes())
   109  	tempSK.PublicKey.X, tempSK.PublicKey.Y =
   110  		tempSK.PublicKey.Add(
   111  			ecdsaK.privKey.PublicKey.X, ecdsaK.privKey.PublicKey.Y,
   112  			tempX, tempY,
   113  		)
   114  
   115  	// Verify temporary public key is a valid point on the reference curve
   116  	isOn := tempSK.Curve.IsOnCurve(tempSK.PublicKey.X, tempSK.PublicKey.Y)
   117  	if !isOn {
   118  		return nil, errors.New("Failed temporary public key IsOnCurve check.")
   119  	}
   120  
   121  	return &ecdsaPrivateKey{tempSK}, nil
   122  }
   123  
   124  type aesPrivateKeyKeyDeriver struct {
   125  	conf *config
   126  }
   127  
   128  func (kd *aesPrivateKeyKeyDeriver) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (bccsp.Key, error) {
   129  	// Validate opts
   130  	if opts == nil {
   131  		return nil, errors.New("Invalid opts parameter. It must not be nil.")
   132  	}
   133  
   134  	aesK := k.(*aesPrivateKey)
   135  
   136  	switch hmacOpts := opts.(type) {
   137  	case *bccsp.HMACTruncated256AESDeriveKeyOpts:
   138  		mac := hmac.New(kd.conf.hashFunction, aesK.privKey)
   139  		mac.Write(hmacOpts.Argument())
   140  		return &aesPrivateKey{mac.Sum(nil)[:kd.conf.aesBitLength], false}, nil
   141  
   142  	case *bccsp.HMACDeriveKeyOpts:
   143  		mac := hmac.New(kd.conf.hashFunction, aesK.privKey)
   144  		mac.Write(hmacOpts.Argument())
   145  		return &aesPrivateKey{mac.Sum(nil), true}, nil
   146  
   147  	default:
   148  		return nil, fmt.Errorf("Unsupported 'KeyDerivOpts' provided [%v]", opts)
   149  	}
   150  }