github.com/bcskill/bcschain/v3@v3.4.9-beta2/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/bcskill/bcschain/v3/common" 30 "github.com/bcskill/bcschain/v3/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 TestLoadECDSA(t *testing.T) { 143 tests := []struct { 144 input string 145 err string 146 }{ 147 // good 148 {input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"}, 149 {input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n"}, 150 {input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n\r"}, 151 {input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\r\n"}, 152 {input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n\n"}, 153 {input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n\r"}, 154 // bad 155 { 156 input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde", 157 err: "key file too short, want 64 hex characters", 158 }, 159 { 160 input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde\n", 161 err: "key file too short, want 64 hex characters", 162 }, 163 { 164 input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdeX", 165 err: "invalid hex character 'X' in private key", 166 }, 167 { 168 input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdefX", 169 err: "invalid character 'X' at end of key file", 170 }, 171 { 172 input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n\n\n", 173 err: "key file too long, want 64 hex characters", 174 }, 175 } 176 177 for _, test := range tests { 178 f, err := ioutil.TempFile("", "loadecdsa_test.*.txt") 179 if err != nil { 180 t.Fatal(err) 181 } 182 filename := f.Name() 183 f.WriteString(test.input) 184 f.Close() 185 186 _, err = LoadECDSA(filename) 187 switch { 188 case err != nil && test.err == "": 189 t.Fatalf("unexpected error for input %q:\n %v", test.input, err) 190 case err != nil && err.Error() != test.err: 191 t.Fatalf("wrong error for input %q:\n %v", test.input, err) 192 case err == nil && test.err != "": 193 t.Fatalf("LoadECDSA did not return error for input %q", test.input) 194 } 195 } 196 } 197 198 func TestSaveECDSA(t *testing.T) { 199 f, err := ioutil.TempFile("", "saveecdsa_test.*.txt") 200 if err != nil { 201 t.Fatal(err) 202 } 203 file := f.Name() 204 f.Close() 205 defer os.Remove(file) 206 207 key, _ := HexToECDSA(testPrivHex) 208 if err := SaveECDSA(file, key); err != nil { 209 t.Fatal(err) 210 } 211 loaded, err := LoadECDSA(file) 212 if err != nil { 213 t.Fatal(err) 214 } 215 if !reflect.DeepEqual(key, loaded) { 216 t.Fatal("loaded key not equal to saved key") 217 } 218 } 219 220 func TestValidateSignatureValues(t *testing.T) { 221 check := func(expected bool, v byte, r, s *big.Int) { 222 if ValidateSignatureValues(v, r, s, false) != expected { 223 t.Errorf("mismatch for v: %d r: %d s: %d want: %v", v, r, s, expected) 224 } 225 } 226 minusOne := big.NewInt(-1) 227 one := common.Big1 228 zero := common.Big0 229 secp256k1nMinus1 := new(big.Int).Sub(secp256k1N, common.Big1) 230 231 // correct v,r,s 232 check(true, 0, one, one) 233 check(true, 1, one, one) 234 // incorrect v, correct r,s, 235 check(false, 2, one, one) 236 check(false, 3, one, one) 237 238 // incorrect v, combinations of incorrect/correct r,s at lower limit 239 check(false, 2, zero, zero) 240 check(false, 2, zero, one) 241 check(false, 2, one, zero) 242 check(false, 2, one, one) 243 244 // correct v for any combination of incorrect r,s 245 check(false, 0, zero, zero) 246 check(false, 0, zero, one) 247 check(false, 0, one, zero) 248 249 check(false, 1, zero, zero) 250 check(false, 1, zero, one) 251 check(false, 1, one, zero) 252 253 // correct sig with max r,s 254 check(true, 0, secp256k1nMinus1, secp256k1nMinus1) 255 // correct v, combinations of incorrect r,s at upper limit 256 check(false, 0, secp256k1N, secp256k1nMinus1) 257 check(false, 0, secp256k1nMinus1, secp256k1N) 258 check(false, 0, secp256k1N, secp256k1N) 259 260 // current callers ensures r,s cannot be negative, but let's test for that too 261 // as crypto package could be used stand-alone 262 check(false, 0, minusOne, one) 263 check(false, 0, one, minusOne) 264 } 265 266 func checkhash(t *testing.T, name string, f func([]byte) []byte, msg, exp []byte) { 267 sum := f(msg) 268 if !bytes.Equal(exp, sum) { 269 t.Fatalf("hash %s mismatch: want: %x have: %x", name, exp, sum) 270 } 271 } 272 273 func checkAddr(t *testing.T, addr0, addr1 common.Address) { 274 if addr0 != addr1 { 275 t.Fatalf("address mismatch: want: %x have: %x", addr0, addr1) 276 } 277 } 278 279 // test to help Python team with integration of libsecp256k1 280 // skip but keep it after they are done 281 func TestPythonIntegration(t *testing.T) { 282 kh := "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032" 283 k0, _ := HexToECDSA(kh) 284 285 msg0 := Keccak256([]byte("foo")) 286 sig0, _ := Sign(msg0, k0) 287 288 msg1 := common.FromHex("00000000000000000000000000000000") 289 sig1, _ := Sign(msg0, k0) 290 291 t.Logf("msg: %x, privkey: %s sig: %x\n", msg0, kh, sig0) 292 t.Logf("msg: %x, privkey: %s sig: %x\n", msg1, kh, sig1) 293 }