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