github.com/klaytn/klaytn@v1.10.2/crypto/crypto.go (about) 1 // Modifications Copyright 2018 The klaytn Authors 2 // Copyright 2014 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from crypto/crypto.go (2018/06/04). 19 // Modified and improved for the klaytn development. 20 21 package crypto 22 23 import ( 24 "crypto/ecdsa" 25 "crypto/elliptic" 26 "crypto/rand" 27 "encoding/hex" 28 "errors" 29 "fmt" 30 "io" 31 "io/ioutil" 32 "math/big" 33 "os" 34 35 "github.com/klaytn/klaytn/common" 36 "github.com/klaytn/klaytn/common/math" 37 "github.com/klaytn/klaytn/crypto/sha3" 38 "github.com/klaytn/klaytn/rlp" 39 ) 40 41 // SignatureLength indicates the byte length required to carry a signature with recovery id. 42 const SignatureLength = 64 + 1 // 64 bytes ECDSA signature + 1 byte recovery id 43 44 // RecoveryIDOffset points to the byte offset within the signature that contains the recovery id. 45 const RecoveryIDOffset = 64 46 47 // DigestLength sets the signature digest exact length 48 const DigestLength = 32 49 50 var ( 51 secp256k1N, _ = new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16) 52 secp256k1halfN = new(big.Int).Div(secp256k1N, common.Big2) 53 ) 54 55 var errInvalidPubkey = errors.New("invalid secp256k1 public key") 56 57 // Keccak256 calculates and returns the Keccak256 hash of the input data. 58 func Keccak256(data ...[]byte) []byte { 59 d := sha3.NewKeccak256() 60 for _, b := range data { 61 d.Write(b) 62 } 63 return d.Sum(nil) 64 } 65 66 // Keccak256Hash calculates and returns the Keccak256 hash of the input data, 67 // converting it to an internal Hash data structure. 68 func Keccak256Hash(data ...[]byte) (h common.Hash) { 69 d := sha3.NewKeccak256() 70 for _, b := range data { 71 d.Write(b) 72 } 73 d.Sum(h[:0]) 74 return h 75 } 76 77 // Keccak512 calculates and returns the Keccak512 hash of the input data. 78 func Keccak512(data ...[]byte) []byte { 79 d := sha3.NewKeccak512() 80 for _, b := range data { 81 d.Write(b) 82 } 83 return d.Sum(nil) 84 } 85 86 // CreateAddress creates a Klaytn address given the bytes and the nonce 87 func CreateAddress(b common.Address, nonce uint64) common.Address { 88 data, _ := rlp.EncodeToBytes(struct { 89 Addr common.Address 90 Nonce uint64 91 }{b, nonce}) 92 return common.BytesToAddress(Keccak256(data)[12:]) 93 } 94 95 // CreateAddress2 creates a Klaytn address given the address bytes, initial 96 // contract code hash and a salt. 97 func CreateAddress2(b common.Address, salt [32]byte, inithash []byte) common.Address { 98 return common.BytesToAddress(Keccak256([]byte{0xff}, b.Bytes(), salt[:], inithash)[12:]) 99 } 100 101 // ToECDSA creates a private key with the given D value. 102 func ToECDSA(d []byte) (*ecdsa.PrivateKey, error) { 103 return toECDSA(d, true) 104 } 105 106 // ToECDSAUnsafe blindly converts a binary blob to a private key. It should almost 107 // never be used unless you are sure the input is valid and want to avoid hitting 108 // errors due to bad origin encoding (0 prefixes cut off). 109 func ToECDSAUnsafe(d []byte) *ecdsa.PrivateKey { 110 priv, _ := toECDSA(d, false) 111 return priv 112 } 113 114 // toECDSA creates a private key with the given D value. The strict parameter 115 // controls whether the key's length should be enforced at the curve size or 116 // it can also accept legacy encodings (0 prefixes). 117 func toECDSA(d []byte, strict bool) (*ecdsa.PrivateKey, error) { 118 priv := new(ecdsa.PrivateKey) 119 priv.PublicKey.Curve = S256() 120 if strict && 8*len(d) != priv.Params().BitSize { 121 return nil, fmt.Errorf("invalid length, need %d bits", priv.Params().BitSize) 122 } 123 priv.D = new(big.Int).SetBytes(d) 124 125 // The priv.D must < N 126 if priv.D.Cmp(secp256k1N) >= 0 { 127 return nil, fmt.Errorf("invalid private key, >=N") 128 } 129 // The priv.D must not be zero or negative. 130 if priv.D.Sign() <= 0 { 131 return nil, fmt.Errorf("invalid private key, zero or negative") 132 } 133 134 priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(d) 135 if priv.PublicKey.X == nil { 136 return nil, errors.New("invalid private key") 137 } 138 return priv, nil 139 } 140 141 // FromECDSA exports a private key into a binary dump. 142 func FromECDSA(priv *ecdsa.PrivateKey) []byte { 143 if priv == nil { 144 return nil 145 } 146 return math.PaddedBigBytes(priv.D, priv.Params().BitSize/8) 147 } 148 149 // UnmarshalPubkey converts bytes to a secp256k1 public key. 150 func UnmarshalPubkey(pub []byte) (*ecdsa.PublicKey, error) { 151 x, y := elliptic.Unmarshal(S256(), pub) 152 if x == nil { 153 return nil, errInvalidPubkey 154 } 155 return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil 156 } 157 158 func FromECDSAPub(pub *ecdsa.PublicKey) []byte { 159 if pub == nil || pub.X == nil || pub.Y == nil { 160 return nil 161 } 162 return elliptic.Marshal(S256(), pub.X, pub.Y) 163 } 164 165 // HexToECDSA parses a secp256k1 private key. 166 func HexToECDSA(hexkey string) (*ecdsa.PrivateKey, error) { 167 b, err := hex.DecodeString(hexkey) 168 if err != nil { 169 return nil, errors.New("invalid hex string") 170 } 171 return ToECDSA(b) 172 } 173 174 // LoadECDSA loads a secp256k1 private key from the given file. 175 func LoadECDSA(file string) (*ecdsa.PrivateKey, error) { 176 buf := make([]byte, 64) 177 fd, err := os.Open(file) 178 if err != nil { 179 return nil, err 180 } 181 defer fd.Close() 182 if _, err := io.ReadFull(fd, buf); err != nil { 183 return nil, err 184 } 185 186 key, err := hex.DecodeString(string(buf)) 187 if err != nil { 188 return nil, err 189 } 190 return ToECDSA(key) 191 } 192 193 // SaveECDSA saves a secp256k1 private key to the given file with 194 // restrictive permissions. The key data is saved hex-encoded. 195 func SaveECDSA(file string, key *ecdsa.PrivateKey) error { 196 k := hex.EncodeToString(FromECDSA(key)) 197 return ioutil.WriteFile(file, []byte(k), 0o600) 198 } 199 200 func GenerateKey() (*ecdsa.PrivateKey, error) { 201 return ecdsa.GenerateKey(S256(), rand.Reader) 202 } 203 204 // ValidateSignatureValues verifies whether the signature values are valid with 205 // the given chain rules. The v value is assumed to be either 0 or 1. 206 func ValidateSignatureValues(v byte, r, s *big.Int, homestead bool) bool { 207 if r.Cmp(common.Big1) < 0 || s.Cmp(common.Big1) < 0 { 208 return false 209 } 210 // reject upper range of s values (ECDSA malleability) 211 // see discussion in secp256k1/libsecp256k1/include/secp256k1.h 212 if homestead && s.Cmp(secp256k1halfN) > 0 { 213 return false 214 } 215 // Frontier: allow s to be in full N range 216 return r.Cmp(secp256k1N) < 0 && s.Cmp(secp256k1N) < 0 && (v == 0 || v == 1) 217 } 218 219 func PubkeyToAddress(p ecdsa.PublicKey) common.Address { 220 pubBytes := FromECDSAPub(&p) 221 return common.BytesToAddress(Keccak256(pubBytes[1:])[12:]) 222 } 223 224 func zeroBytes(bytes []byte) { 225 for i := range bytes { 226 bytes[i] = 0 227 } 228 }