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