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