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 }