github.com/intfoundation/intchain@v0.0.0-20220727031208-4316ad31ca73/crypto/crypto_test.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 "encoding/hex" 23 "fmt" 24 "github.com/intfoundation/intchain/common/hexutil" 25 "io/ioutil" 26 "math/big" 27 "os" 28 "reflect" 29 "testing" 30 31 "github.com/intfoundation/intchain/common" 32 ) 33 34 var testAddrHex = "970e8128ab834e8eac17ab8e3812f010678cf791" 35 var testPrivHex = "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032" 36 37 // These tests are sanity checks. 38 // They should ensure that we don't e.g. use Sha3-224 instead of Sha3-256 39 // and that the sha3 library uses keccak-f permutation. 40 func TestKeccak256Hash(t *testing.T) { 41 msg := []byte("abc") 42 exp, _ := hex.DecodeString("4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45") 43 checkhash(t, "Sha3-256-array", func(in []byte) []byte { h := Keccak256Hash(in); return h[:] }, msg, exp) 44 } 45 46 func TestToECDSAErrors(t *testing.T) { 47 if _, err := HexToECDSA("0000000000000000000000000000000000000000000000000000000000000000"); err == nil { 48 t.Fatal("HexToECDSA should've returned error") 49 } 50 if _, err := HexToECDSA("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); err == nil { 51 t.Fatal("HexToECDSA should've returned error") 52 } 53 } 54 55 func BenchmarkSha3(b *testing.B) { 56 a := []byte("hello world") 57 for i := 0; i < b.N; i++ { 58 Keccak256(a) 59 } 60 } 61 62 func TestSign(t *testing.T) { 63 key, _ := HexToECDSA(testPrivHex) 64 addr := common.HexToAddress(testAddrHex) 65 66 msg := Keccak256([]byte("foo")) 67 sig, err := Sign(msg, key) 68 if err != nil { 69 t.Errorf("Sign error: %s", err) 70 } 71 recoveredPub, err := Ecrecover(msg, sig) 72 if err != nil { 73 t.Errorf("ECRecover error: %s", err) 74 } 75 pubKey, _ := UnmarshalPubkey(recoveredPub) 76 recoveredAddr := PubkeyToAddress(*pubKey) 77 if addr != recoveredAddr { 78 t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr) 79 } 80 81 // should be equal to SigToPub 82 recoveredPub2, err := SigToPub(msg, sig) 83 if err != nil { 84 t.Errorf("ECRecover error: %s", err) 85 } 86 recoveredAddr2 := PubkeyToAddress(*recoveredPub2) 87 if addr != recoveredAddr2 { 88 t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr2) 89 } 90 } 91 92 func TestUnmarshalPubkey(t *testing.T) { 93 key, err := UnmarshalPubkey(nil) 94 if err != errInvalidPubkey || key != nil { 95 t.Fatalf("expected error, got %v, %v", err, key) 96 } 97 key, err = UnmarshalPubkey([]byte{1, 2, 3}) 98 if err != errInvalidPubkey || key != nil { 99 t.Fatalf("expected error, got %v, %v", err, key) 100 } 101 102 var ( 103 enc, _ = hex.DecodeString("04760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1b01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d") 104 dec = &ecdsa.PublicKey{ 105 Curve: S256(), 106 X: hexutil.MustDecodeBig("0x760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1"), 107 Y: hexutil.MustDecodeBig("0xb01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d"), 108 } 109 ) 110 key, err = UnmarshalPubkey(enc) 111 if err != nil { 112 t.Fatalf("expected no error, got %v", err) 113 } 114 if !reflect.DeepEqual(key, dec) { 115 t.Fatal("wrong result") 116 } 117 } 118 119 func TestInvalidSign(t *testing.T) { 120 if _, err := Sign(make([]byte, 1), nil); err == nil { 121 t.Errorf("expected sign with hash 1 byte to error") 122 } 123 if _, err := Sign(make([]byte, 33), nil); err == nil { 124 t.Errorf("expected sign with hash 33 byte to error") 125 } 126 } 127 128 func TestNewContractAddress(t *testing.T) { 129 key, _ := HexToECDSA(testPrivHex) 130 addr := common.HexToAddress(testAddrHex) 131 fmt.Printf("byte addr=%v\n", addr) 132 genAddr := PubkeyToAddress(key.PublicKey) 133 fmt.Printf("gen addr=%v\n", addr) 134 // sanity check before using addr to create contract address 135 checkAddr(t, genAddr, addr) 136 137 caddr0 := CreateAddress(addr, 0) 138 caddr1 := CreateAddress(addr, 1) 139 caddr2 := CreateAddress(addr, 2) 140 checkAddr(t, common.HexToAddress("3343384b35786b757666344431674c5376684346413467674b73506b7268316f4c31"), caddr0) 141 checkAddr(t, common.HexToAddress("334b713575554c4c594e6e65546831544e7a4352767377626e554a55334a6d6f3773"), caddr1) 142 checkAddr(t, common.HexToAddress("3339416a5166364c48454346596a316e45566a67414d675250723578414d69334b67"), caddr2) 143 } 144 145 func TestLoadECDSAFile(t *testing.T) { 146 keyBytes := common.FromHex(testPrivHex) 147 fileName0 := "test_key0" 148 fileName1 := "test_key1" 149 checkKey := func(k *ecdsa.PrivateKey) { 150 checkAddr(t, PubkeyToAddress(k.PublicKey), common.HexToAddress(testAddrHex)) 151 loadedKeyBytes := FromECDSA(k) 152 if !bytes.Equal(loadedKeyBytes, keyBytes) { 153 t.Fatalf("private key mismatch: want: %x have: %x", keyBytes, loadedKeyBytes) 154 } 155 } 156 157 ioutil.WriteFile(fileName0, []byte(testPrivHex), 0600) 158 defer os.Remove(fileName0) 159 160 key0, err := LoadECDSA(fileName0) 161 if err != nil { 162 t.Fatal(err) 163 } 164 checkKey(key0) 165 166 // again, this time with SaveECDSA instead of manual save: 167 err = SaveECDSA(fileName1, key0) 168 if err != nil { 169 t.Fatal(err) 170 } 171 defer os.Remove(fileName1) 172 173 key1, err := LoadECDSA(fileName1) 174 if err != nil { 175 t.Fatal(err) 176 } 177 checkKey(key1) 178 } 179 180 func TestValidateSignatureValues(t *testing.T) { 181 check := func(expected bool, v byte, r, s *big.Int) { 182 if ValidateSignatureValues(v, r, s, false) != expected { 183 t.Errorf("mismatch for v: %d r: %d s: %d want: %v", v, r, s, expected) 184 } 185 } 186 minusOne := big.NewInt(-1) 187 one := common.Big1 188 zero := common.Big0 189 secp256k1nMinus1 := new(big.Int).Sub(secp256k1N, common.Big1) 190 191 // correct v,r,s 192 check(true, 0, one, one) 193 check(true, 1, one, one) 194 // incorrect v, correct r,s, 195 check(false, 2, one, one) 196 check(false, 3, one, one) 197 198 // incorrect v, combinations of incorrect/correct r,s at lower limit 199 check(false, 2, zero, zero) 200 check(false, 2, zero, one) 201 check(false, 2, one, zero) 202 check(false, 2, one, one) 203 204 // correct v for any combination of incorrect r,s 205 check(false, 0, zero, zero) 206 check(false, 0, zero, one) 207 check(false, 0, one, zero) 208 209 check(false, 1, zero, zero) 210 check(false, 1, zero, one) 211 check(false, 1, one, zero) 212 213 // correct sig with max r,s 214 check(true, 0, secp256k1nMinus1, secp256k1nMinus1) 215 // correct v, combinations of incorrect r,s at upper limit 216 check(false, 0, secp256k1N, secp256k1nMinus1) 217 check(false, 0, secp256k1nMinus1, secp256k1N) 218 check(false, 0, secp256k1N, secp256k1N) 219 220 // current callers ensures r,s cannot be negative, but let's test for that too 221 // as crypto package could be used stand-alone 222 check(false, 0, minusOne, one) 223 check(false, 0, one, minusOne) 224 } 225 226 func checkhash(t *testing.T, name string, f func([]byte) []byte, msg, exp []byte) { 227 sum := f(msg) 228 if !bytes.Equal(exp, sum) { 229 t.Fatalf("hash %s mismatch: want: %x have: %x", name, exp, sum) 230 } 231 } 232 233 func checkAddr(t *testing.T, addr0, addr1 common.Address) { 234 if addr0 != addr1 { 235 t.Fatalf("address mismatch: want: %x have: %x", addr0, addr1) 236 } 237 } 238 239 // test to help Python team with integration of libsecp256k1 240 // skip but keep it after they are done 241 func TestPythonIntegration(t *testing.T) { 242 kh := "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032" 243 k0, _ := HexToECDSA(kh) 244 245 msg0 := Keccak256([]byte("foo")) 246 sig0, _ := Sign(msg0, k0) 247 248 msg1 := common.FromHex("00000000000000000000000000000000") 249 sig1, _ := Sign(msg0, k0) 250 251 t.Logf("msg: %x, privkey: %s sig: %x\n", msg0, kh, sig0) 252 t.Logf("msg: %x, privkey: %s sig: %x\n", msg1, kh, sig1) 253 } 254 255 func TestEthAddress(t *testing.T) { 256 privateKeyHex := "c15c038a5a9f8f948a2ac0eb102c249e4ae1c4fa1e0971b50c63db46dc5fcf8b" 257 privateKey, err := HexToECDSA(privateKeyHex) 258 if err != nil { 259 t.Fatalf("failed to decode private key %v\n", err) 260 } 261 262 publicKey := FromECDSAPub(&privateKey.PublicKey) 263 264 ethAddress := hexutil.Encode(Keccak256(publicKey[1:])[12:]) 265 266 fmt.Printf("ethereum address %v\n", ethAddress) 267 268 addrHex := "0xc84e9eba34cfb0690ae607207a64d662686d17f7" 269 270 addrBytes := common.HexToAddress(addrHex).Big() 271 272 b, _ := new(big.Int).SetString("862381068151338842291839054294319045153034925969", 10) 273 274 addrBig := common.BigToAddress(b).String() 275 276 fmt.Printf("address bytes %v, address big %v\n", addrBytes, addrBig) 277 }