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