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 }