github.com/CommerciumBlockchain/go-commercium@v0.0.0-20220709212705-b46438a77516/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 "crypto/rand" 23 "encoding/hex" 24 "io/ioutil" 25 "math/big" 26 "os" 27 "reflect" 28 "testing" 29 30 "github.com/CommerciumBlockchain/go-commercium/common" 31 "github.com/CommerciumBlockchain/go-commercium/common/hexutil" 32 "github.com/CommerciumBlockchain/go-commercium/crypto/fixed" 33 ) 34 35 var testAddrHex = "970e8128ab834e8eac17ab8e3812f010678cf791" 36 var testPrivHex = "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032" 37 38 // These tests are sanity checks. 39 // They should ensure that we don't e.g. use Sha3-224 instead of Sha3-256 40 // and that the sha3 library uses keccak-f permutation. 41 func TestKeccak256Hash(t *testing.T) { 42 msg := []byte("abc") 43 exp, _ := hex.DecodeString("4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45") 44 checkhash(t, "Sha3-256-array", func(in []byte) []byte { h := Keccak256Hash(in); return h[:] }, msg, exp) 45 } 46 47 func TestToECDSAErrors(t *testing.T) { 48 if _, err := HexToECDSA("0000000000000000000000000000000000000000000000000000000000000000"); err == nil { 49 t.Fatal("HexToECDSA should've returned error") 50 } 51 if _, err := HexToECDSA("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); err == nil { 52 t.Fatal("HexToECDSA should've returned error") 53 } 54 } 55 56 func BenchmarkSha3(b *testing.B) { 57 a := []byte("hello world") 58 for i := 0; i < b.N; i++ { 59 Keccak256(a) 60 } 61 } 62 63 func TestUnmarshalPubkey(t *testing.T) { 64 key, err := UnmarshalPubkey(nil) 65 if err != errInvalidPubkey || key != nil { 66 t.Fatalf("expected error, got %v, %v", err, key) 67 } 68 key, err = UnmarshalPubkey([]byte{1, 2, 3}) 69 if err != errInvalidPubkey || key != nil { 70 t.Fatalf("expected error, got %v, %v", err, key) 71 } 72 73 var ( 74 enc, _ = hex.DecodeString("04760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1b01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d") 75 dec = &ecdsa.PublicKey{ 76 Curve: S256(), 77 X: hexutil.MustDecodeBig("0x760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1"), 78 Y: hexutil.MustDecodeBig("0xb01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d"), 79 } 80 ) 81 key, err = UnmarshalPubkey(enc) 82 if err != nil { 83 t.Fatalf("expected no error, got %v", err) 84 } 85 if !reflect.DeepEqual(key, dec) { 86 t.Fatal("wrong result") 87 } 88 } 89 90 func TestSign(t *testing.T) { 91 key, _ := HexToECDSA(testPrivHex) 92 addr := common.HexToAddress(testAddrHex) 93 94 msg := Keccak256([]byte("foo")) 95 sig, err := Sign(msg, key) 96 if err != nil { 97 t.Errorf("Sign error: %s", err) 98 } 99 recoveredPub, err := Ecrecover(msg, sig) 100 if err != nil { 101 t.Errorf("ECRecover error: %s", err) 102 } 103 pubKey, _ := UnmarshalPubkey(recoveredPub) 104 recoveredAddr := PubkeyToAddress(*pubKey) 105 if addr != recoveredAddr { 106 t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr) 107 } 108 109 // should be equal to SigToPub 110 recoveredPub2, err := SigToPub(msg, sig) 111 if err != nil { 112 t.Errorf("ECRecover error: %s", err) 113 } 114 recoveredAddr2 := PubkeyToAddress(*recoveredPub2) 115 if addr != recoveredAddr2 { 116 t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr2) 117 } 118 } 119 120 func TestInvalidSign(t *testing.T) { 121 if _, err := Sign(make([]byte, 1), nil); err == nil { 122 t.Errorf("expected sign with hash 1 byte to error") 123 } 124 if _, err := Sign(make([]byte, 33), nil); err == nil { 125 t.Errorf("expected sign with hash 33 byte to error") 126 } 127 } 128 129 func TestNewContractAddress(t *testing.T) { 130 key, _ := HexToECDSA(testPrivHex) 131 addr := common.HexToAddress(testAddrHex) 132 genAddr := PubkeyToAddress(key.PublicKey) 133 // sanity check before using addr to create contract address 134 checkAddr(t, genAddr, addr) 135 136 caddr0 := CreateAddress(addr, 0) 137 caddr1 := CreateAddress(addr, 1) 138 caddr2 := CreateAddress(addr, 2) 139 checkAddr(t, common.HexToAddress("333c3310824b7c685133f2bedb2ca4b8b4df633d"), caddr0) 140 checkAddr(t, common.HexToAddress("8bda78331c916a08481428e4b07c96d3e916d165"), caddr1) 141 checkAddr(t, common.HexToAddress("c9ddedf451bc62ce88bf9292afb13df35b670699"), caddr2) 142 } 143 144 func TestLoadECDSA(t *testing.T) { 145 tests := []struct { 146 input string 147 err string 148 }{ 149 // good 150 {input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"}, 151 {input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n"}, 152 {input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n\r"}, 153 {input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\r\n"}, 154 {input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n\n"}, 155 {input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n\r"}, 156 // bad 157 { 158 input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde", 159 err: "key file too short, want 64 hex characters", 160 }, 161 { 162 input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde\n", 163 err: "key file too short, want 64 hex characters", 164 }, 165 { 166 input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdeX", 167 err: "invalid hex character 'X' in private key", 168 }, 169 { 170 input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdefX", 171 err: "invalid character 'X' at end of key file", 172 }, 173 { 174 input: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n\n\n", 175 err: "key file too long, want 64 hex characters", 176 }, 177 } 178 179 for _, test := range tests { 180 f, err := ioutil.TempFile("", "loadecdsa_test.*.txt") 181 if err != nil { 182 t.Fatal(err) 183 } 184 filename := f.Name() 185 f.WriteString(test.input) 186 f.Close() 187 188 _, err = LoadECDSA(filename) 189 switch { 190 case err != nil && test.err == "": 191 t.Fatalf("unexpected error for input %q:\n %v", test.input, err) 192 case err != nil && err.Error() != test.err: 193 t.Fatalf("wrong error for input %q:\n %v", test.input, err) 194 case err == nil && test.err != "": 195 t.Fatalf("LoadECDSA did not return error for input %q", test.input) 196 } 197 } 198 } 199 200 func TestSaveECDSA(t *testing.T) { 201 f, err := ioutil.TempFile("", "saveecdsa_test.*.txt") 202 if err != nil { 203 t.Fatal(err) 204 } 205 file := f.Name() 206 f.Close() 207 defer os.Remove(file) 208 209 key, _ := HexToECDSA(testPrivHex) 210 if err := SaveECDSA(file, key); err != nil { 211 t.Fatal(err) 212 } 213 loaded, err := LoadECDSA(file) 214 if err != nil { 215 t.Fatal(err) 216 } 217 if !reflect.DeepEqual(key, loaded) { 218 t.Fatal("loaded key not equal to saved key") 219 } 220 } 221 222 func TestValidateSignatureValues(t *testing.T) { 223 check := func(expected bool, v byte, r, s *big.Int) { 224 if ValidateSignatureValues(v, r, s, false) != expected { 225 t.Errorf("mismatch for v: %d r: %d s: %d want: %v", v, r, s, expected) 226 } 227 } 228 minusOne := big.NewInt(-1) 229 one := common.Big1 230 zero := common.Big0 231 secp256k1nMinus1 := new(big.Int).Sub(secp256k1N, common.Big1) 232 233 // correct v,r,s 234 check(true, 0, one, one) 235 check(true, 1, one, one) 236 // incorrect v, correct r,s, 237 check(false, 2, one, one) 238 check(false, 3, one, one) 239 240 // incorrect v, combinations of incorrect/correct r,s at lower limit 241 check(false, 2, zero, zero) 242 check(false, 2, zero, one) 243 check(false, 2, one, zero) 244 check(false, 2, one, one) 245 246 // correct v for any combination of incorrect r,s 247 check(false, 0, zero, zero) 248 check(false, 0, zero, one) 249 check(false, 0, one, zero) 250 251 check(false, 1, zero, zero) 252 check(false, 1, zero, one) 253 check(false, 1, one, zero) 254 255 // correct sig with max r,s 256 check(true, 0, secp256k1nMinus1, secp256k1nMinus1) 257 // correct v, combinations of incorrect r,s at upper limit 258 check(false, 0, secp256k1N, secp256k1nMinus1) 259 check(false, 0, secp256k1nMinus1, secp256k1N) 260 check(false, 0, secp256k1N, secp256k1N) 261 262 // current callers ensures r,s cannot be negative, but let's test for that too 263 // as crypto package could be used stand-alone 264 check(false, 0, minusOne, one) 265 check(false, 0, one, minusOne) 266 } 267 268 func checkhash(t *testing.T, name string, f func([]byte) []byte, msg, exp []byte) { 269 sum := f(msg) 270 if !bytes.Equal(exp, sum) { 271 t.Fatalf("hash %s mismatch: want: %x have: %x", name, exp, sum) 272 } 273 } 274 275 func checkAddr(t *testing.T, addr0, addr1 common.Address) { 276 if addr0 != addr1 { 277 t.Fatalf("address mismatch: want: %x have: %x", addr0, addr1) 278 } 279 } 280 281 // test to help Python team with integration of libsecp256k1 282 // skip but keep it after they are done 283 func TestPythonIntegration(t *testing.T) { 284 kh := "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032" 285 k0, _ := HexToECDSA(kh) 286 287 msg0 := Keccak256([]byte("foo")) 288 sig0, _ := Sign(msg0, k0) 289 290 msg1 := common.FromHex("00000000000000000000000000000000") 291 sig1, _ := Sign(msg0, k0) 292 293 t.Logf("msg: %x, privkey: %s sig: %x\n", msg0, kh, sig0) 294 t.Logf("msg: %x, privkey: %s sig: %x\n", msg1, kh, sig1) 295 } 296 297 func TestFixedKeccak(t *testing.T) { 298 x := make([]byte, 20) 299 rand.Read(x) 300 if got, want := fixed.LegacyKeccak20(common.BytesToAddress(x)), Keccak256(x); !bytes.Equal(got[:], want) { 301 t.Errorf("error, want %x, got %x", want, got) 302 } 303 304 k := make([]byte, 32) 305 rand.Read(k) 306 if got, want := fixed.LegacyKeccak32(common.BytesToHash(k)), Keccak256(k); !bytes.Equal(got[:], want) { 307 t.Errorf("error, want %x, got %x", want, got) 308 } 309 } 310 311 func BenchmarkKeccakHash(b *testing.B) { 312 x := make([]byte, 20) 313 rand.Read(x) 314 y := common.BytesToAddress(x) 315 316 k := make([]byte, 32) 317 rand.Read(k) 318 l := common.BytesToHash(k) 319 320 b.Run("generic-20", func(b *testing.B) { 321 b.ReportAllocs() 322 for i := 0; i < b.N; i++ { 323 Keccak256(x) 324 } 325 }) 326 b.Run("fixed-20", func(b *testing.B) { 327 b.ReportAllocs() 328 for i := 0; i < b.N; i++ { 329 fixed.LegacyKeccak20(y) 330 } 331 }) 332 b.Run("generic-32", func(b *testing.B) { 333 b.ReportAllocs() 334 for i := 0; i < b.N; i++ { 335 Keccak256(k) 336 } 337 }) 338 b.Run("fixed-32", func(b *testing.B) { 339 b.ReportAllocs() 340 for i := 0; i < b.N; i++ { 341 fixed.LegacyKeccak32(l) 342 } 343 }) 344 }