github.com/annchain/OG@v0.0.9/ogcrypto/keccak.go (about) 1 // Copyright © 2019 Annchain Authors <EMAIL ADDRESS> 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package ogcrypto 15 16 import ( 17 "crypto/ecdsa" 18 "crypto/elliptic" 19 "crypto/rand" 20 "encoding/hex" 21 "errors" 22 "fmt" 23 "io" 24 "io/ioutil" 25 "math/big" 26 "os" 27 28 "github.com/annchain/commongo/math" 29 "github.com/btcsuite/btcd/btcec" 30 "golang.org/x/crypto/sha3" 31 ) 32 33 var ( 34 secp256k1N, _ = new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16) 35 secp256k1halfN = new(big.Int).Div(secp256k1N, big.NewInt(2)) 36 ) 37 38 var ( 39 Big1 = big.NewInt(1) 40 Big2 = big.NewInt(2) 41 Big3 = big.NewInt(3) 42 Big0 = big.NewInt(0) 43 Big32 = big.NewInt(32) 44 Big256 = big.NewInt(256) 45 Big257 = big.NewInt(257) 46 ) 47 48 var errInvalidPubkey = errors.New("invalid secp256k1 public key") 49 50 // Keccak256 calculates and returns the Keccak256 hash of the input data. 51 func Keccak256(data ...[]byte) []byte { 52 d := sha3.NewLegacyKeccak256() 53 for _, b := range data { 54 d.Write(b) 55 } 56 return d.Sum(nil) 57 } 58 59 // Keccak256Hash calculates and returns the Keccak256 hash of the input data, 60 // converting it to an internal Hash data structure. 61 func Keccak256Hash(data ...[]byte) []byte { 62 d := sha3.NewLegacyKeccak256() 63 for _, b := range data { 64 d.Write(b) 65 } 66 67 return d.Sum([]byte{}) 68 } 69 70 // Keccak512 calculates and returns the Keccak512 hash of the input data. 71 func Keccak512(data ...[]byte) []byte { 72 d := sha3.NewLegacyKeccak512() 73 for _, b := range data { 74 d.Write(b) 75 } 76 return d.Sum(nil) 77 } 78 79 // ToECDSA creates a private key with the given D value. 80 func ToECDSA(d []byte) (*ecdsa.PrivateKey, error) { 81 return toECDSA(d, true) 82 } 83 84 // ToECDSAUnsafe blindly converts a binary blob to a private key. It should almost 85 // never be used unless you are sure the input is valid and want to avoid hitting 86 // errors due to bad origin encoding (0 prefixes cut off). 87 func ToECDSAUnsafe(d []byte) *ecdsa.PrivateKey { 88 priv, _ := toECDSA(d, false) 89 return priv 90 } 91 92 // toECDSA creates a private key with the given D value. The strict parameter 93 // controls whether the key's length should be enforced at the curve size or 94 // it can also accept legacy encodings (0 prefixes). 95 func toECDSA(d []byte, strict bool) (*ecdsa.PrivateKey, error) { 96 priv := new(ecdsa.PrivateKey) 97 priv.PublicKey.Curve = S256() 98 if strict && 8*len(d) != priv.Params().BitSize { 99 return nil, fmt.Errorf("invalid length, need %d bits", priv.Params().BitSize) 100 } 101 priv.D = new(big.Int).SetBytes(d) 102 103 // The priv.D must < N 104 if priv.D.Cmp(secp256k1N) >= 0 { 105 return nil, fmt.Errorf("invalid private key, >=N") 106 } 107 // The priv.D must not be zero or negative. 108 if priv.D.Sign() <= 0 { 109 return nil, fmt.Errorf("invalid private key, zero or negative") 110 } 111 112 priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(d) 113 if priv.PublicKey.X == nil { 114 return nil, errors.New("invalid private key") 115 } 116 return priv, nil 117 } 118 119 // FromECDSA exports a private key into a binary dump. 120 func FromECDSA(priv *ecdsa.PrivateKey) []byte { 121 if priv == nil { 122 return nil 123 } 124 return math.PaddedBigBytes(priv.D, priv.Params().BitSize/8) 125 } 126 127 // UnmarshalPubkey converts bytes to a secp256k1 public key. 128 func UnmarshalPubkey(pub []byte) (*ecdsa.PublicKey, error) { 129 x, y := elliptic.Unmarshal(S256(), pub) 130 if x == nil { 131 return nil, errInvalidPubkey 132 } 133 return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil 134 } 135 136 func FromECDSAPub(pub *ecdsa.PublicKey) []byte { 137 if pub == nil || pub.X == nil || pub.Y == nil { 138 return nil 139 } 140 return elliptic.Marshal(S256(), pub.X, pub.Y) 141 } 142 143 // HexToECDSA parses a secp256k1 private key. 144 func HexToECDSA(hexkey string) (*ecdsa.PrivateKey, error) { 145 b, err := hex.DecodeString(hexkey) 146 if err != nil { 147 return nil, errors.New("invalid hex string") 148 } 149 return ToECDSA(b) 150 } 151 152 // LoadECDSA loads a secp256k1 private key from the given file. 153 func LoadECDSA(file string) (*ecdsa.PrivateKey, error) { 154 buf := make([]byte, 64) 155 fd, err := os.Open(file) 156 if err != nil { 157 return nil, err 158 } 159 defer fd.Close() 160 if _, err := io.ReadFull(fd, buf); err != nil { 161 return nil, err 162 } 163 164 key, err := hex.DecodeString(string(buf)) 165 if err != nil { 166 return nil, err 167 } 168 return ToECDSA(key) 169 } 170 171 // SaveECDSA saves a secp256k1 private key to the given file with 172 // restrictive permissions. The key data is saved hex-encoded. 173 func SaveECDSA(file string, key *ecdsa.PrivateKey) error { 174 data := FromECDSA(key) 175 k := hex.EncodeToString(data) 176 return ioutil.WriteFile(file, []byte(k), 0600) 177 } 178 179 func GenerateKey() (*ecdsa.PrivateKey, error) { 180 return ecdsa.GenerateKey(S256(), rand.Reader) 181 } 182 183 // ValidateSignatureValues verifies whether the signature values are valid with 184 // the given chain rules. The v value is assumed to be either 0 or 1. 185 func ValidateSignatureValues(v byte, r, s *big.Int, homestead bool) bool { 186 if r.Cmp(Big1) < 0 || s.Cmp(Big1) < 0 { 187 return false 188 } 189 // reject upper range of s values (ECDSA malleability) 190 // see discussion in secp256k1/libsecp256k1/include/secp256k1.h 191 if homestead && s.Cmp(secp256k1halfN) > 0 { 192 return false 193 } 194 // Frontier: allow s to be in full N range 195 return r.Cmp(secp256k1N) < 0 && s.Cmp(secp256k1N) < 0 && (v == 0 || v == 1) 196 } 197 198 //func PubkeyToAddress(p ecdsa.PublicKey) og_types.Address { 199 // pubBytes := FromECDSAPub(&p) 200 // addr, _ := og_types.BytesToAddress20(Keccak256(pubBytes[1:])[12:]) 201 // return addr 202 //} 203 204 func zeroBytes(bytes []byte) { 205 for i := range bytes { 206 bytes[i] = 0 207 } 208 } 209 210 // Sign calculates an ECDSA signature. 211 // 212 // This function is susceptible to chosen plaintext attacks that can leak 213 // information about the private key that is used for signing. Callers must 214 // be aware that the given hash cannot be chosen by an adversery. Common 215 // solution is to hash any input before calculating the signature. 216 // 217 // The produced signature is in the [R || S || V] format where V is 0 or 1. 218 func Sign(hash []byte, prv *ecdsa.PrivateKey) ([]byte, error) { 219 if len(hash) != 32 { 220 return nil, fmt.Errorf("hash is required to be exactly 32 bytes (%d)", len(hash)) 221 } 222 if prv.Curve != btcec.S256() { 223 return nil, fmt.Errorf("private key curve is not secp256k1") 224 } 225 sig, err := btcec.SignCompact(btcec.S256(), (*btcec.PrivateKey)(prv), hash, false) 226 if err != nil { 227 return nil, err 228 } 229 // Convert to Ethereum signature format with 'recovery id' v at the end. 230 v := sig[0] - 27 231 copy(sig, sig[1:]) 232 sig[64] = v 233 return sig, nil 234 } 235 236 // VerifySignature checks that the given public key created signature over hash. 237 // The public key should be in compressed (33 bytes) or uncompressed (65 bytes) format. 238 // The signature should have the 64 byte [R || S] format. 239 func VerifySignature(pubkey, hash, signature []byte) bool { 240 if len(signature) != 64 { 241 return false 242 } 243 sig := &btcec.Signature{R: new(big.Int).SetBytes(signature[:32]), S: new(big.Int).SetBytes(signature[32:])} 244 key, err := btcec.ParsePubKey(pubkey, btcec.S256()) 245 if err != nil { 246 return false 247 } 248 // Reject malleable signatures. libsecp256k1 does this check but btcec doesn't. 249 if sig.S.Cmp(secp256k1halfN) > 0 { 250 return false 251 } 252 return sig.Verify(hash, key) 253 } 254 255 // DecompressPubkey parses a public key in the 33-byte compressed format. 256 func DecompressPubkey(pubkey []byte) (*ecdsa.PublicKey, error) { 257 if len(pubkey) != 33 { 258 return nil, errors.New("invalid compressed public key length") 259 } 260 key, err := btcec.ParsePubKey(pubkey, btcec.S256()) 261 if err != nil { 262 return nil, err 263 } 264 return key.ToECDSA(), nil 265 } 266 267 // CompressPubkey encodes a public key to the 33-byte compressed format. 268 func CompressPubkey(pubkey *ecdsa.PublicKey) []byte { 269 return (*btcec.PublicKey)(pubkey).SerializeCompressed() 270 } 271 272 // S256 returns an instance of the secp256k1 curve. 273 func S256() elliptic.Curve { 274 return btcec.S256() 275 }