github.com/Gessiux/neatchain@v1.3.1/utilities/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/sha256" 23 "encoding/hex" 24 "fmt" 25 "io/ioutil" 26 "math/big" 27 "os" 28 "reflect" 29 "testing" 30 31 "github.com/Gessiux/neatchain/utilities/common/hexutil" 32 "github.com/btcsuite/btcutil/base58" 33 34 "github.com/Gessiux/neatchain/utilities/common" 35 ) 36 37 var testAddrHex = "970e8128ab834e8eac17ab8e3812f010678cf791" 38 var testNEATAddrHex = "3334536a7873394177526a356d437978374166784a755a783566393142714a353333" 39 40 var testNEATAddr = "NEATb437dSzaqRGxhTgW4qCq877ytYxb" 41 var testPrivHex = "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032" 42 43 func TestKeccak256Hash(t *testing.T) { 44 msg := []byte("abc") 45 exp, _ := hex.DecodeString("4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45") 46 checkhash(t, "Sha3-256-array", func(in []byte) []byte { h := Keccak256Hash(in); return h[:] }, msg, exp) 47 } 48 49 func TestToECDSAErrors(t *testing.T) { 50 if _, err := HexToECDSA("0000000000000000000000000000000000000000000000000000000000000000"); err == nil { 51 t.Fatal("HexToECDSA should've returned error") 52 } 53 if _, err := HexToECDSA("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); err == nil { 54 t.Fatal("HexToECDSA should've returned error") 55 } 56 } 57 58 func BenchmarkSha3(b *testing.B) { 59 a := []byte("hello world") 60 for i := 0; i < b.N; i++ { 61 Keccak256(a) 62 } 63 } 64 65 func TestSign(t *testing.T) { 66 key, _ := HexToECDSA(testPrivHex) 67 addr := common.HexToAddress(testNEATAddrHex) 68 69 msg := Keccak256([]byte("foo")) 70 sig, err := Sign(msg, key) 71 if err != nil { 72 t.Errorf("Sign error: %s", err) 73 } 74 recoveredPub, err := Ecrecover(msg, sig) 75 if err != nil { 76 t.Errorf("ECRecover error: %s", err) 77 } 78 pubKey, _ := UnmarshalPubkey(recoveredPub) 79 recoveredAddr := PubkeyToAddress(*pubKey) 80 if addr != recoveredAddr { 81 t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr) 82 } 83 84 // should be equal to SigToPub 85 recoveredPub2, err := SigToPub(msg, sig) 86 if err != nil { 87 t.Errorf("ECRecover error: %s", err) 88 } 89 recoveredAddr2 := PubkeyToAddress(*recoveredPub2) 90 if addr != recoveredAddr2 { 91 t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr2) 92 } 93 } 94 95 func TestUnmarshalPubkey(t *testing.T) { 96 key, err := UnmarshalPubkey(nil) 97 if err != errInvalidPubkey || key != nil { 98 t.Fatalf("expected error, got %v, %v", err, key) 99 } 100 key, err = UnmarshalPubkey([]byte{1, 2, 3}) 101 if err != errInvalidPubkey || key != nil { 102 t.Fatalf("expected error, got %v, %v", err, key) 103 } 104 105 var ( 106 enc, _ = hex.DecodeString("04760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1b01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d") 107 dec = &ecdsa.PublicKey{ 108 Curve: S256(), 109 X: hexutil.MustDecodeBig("0x760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1"), 110 Y: hexutil.MustDecodeBig("0xb01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d"), 111 } 112 ) 113 key, err = UnmarshalPubkey(enc) 114 if err != nil { 115 t.Fatalf("expected no error, got %v", err) 116 } 117 if !reflect.DeepEqual(key, dec) { 118 t.Fatal("wrong result") 119 } 120 } 121 122 func TestInvalidSign(t *testing.T) { 123 if _, err := Sign(make([]byte, 1), nil); err == nil { 124 t.Errorf("expected sign with hash 1 byte to error") 125 } 126 if _, err := Sign(make([]byte, 33), nil); err == nil { 127 t.Errorf("expected sign with hash 33 byte to error") 128 } 129 } 130 131 func TestNewContractAddress(t *testing.T) { 132 key, _ := HexToECDSA(testPrivHex) 133 addr := common.HexToAddress(testNEATAddrHex) 134 fmt.Printf("byte addr=%v\n", addr) 135 genAddr := PubkeyToAddress(key.PublicKey) 136 fmt.Printf("gen addr=%v\n", addr) 137 checkAddr(t, genAddr, addr) 138 139 caddr0 := CreateAddress(addr, 0) 140 caddr1 := CreateAddress(addr, 1) 141 caddr2 := CreateAddress(addr, 2) 142 checkAddr(t, common.HexToAddress("3343384b35786b757666344431674c5376684346413467674b73506b7268316f4c31"), caddr0) 143 checkAddr(t, common.HexToAddress("334b713575554c4c594e6e65546831544e7a4352767377626e554a55334a6d6f3773"), caddr1) 144 checkAddr(t, common.HexToAddress("3339416a5166364c48454346596a316e45566a67414d675250723578414d69334b67"), caddr2) 145 } 146 147 func TestLoadECDSAFile(t *testing.T) { 148 keyBytes := common.FromHex(testPrivHex) 149 fileName0 := "test_key0" 150 fileName1 := "test_key1" 151 checkKey := func(k *ecdsa.PrivateKey) { 152 checkAddr(t, PubkeyToAddress(k.PublicKey), common.HexToAddress(testAddrHex)) 153 loadedKeyBytes := FromECDSA(k) 154 if !bytes.Equal(loadedKeyBytes, keyBytes) { 155 t.Fatalf("private key mismatch: want: %x have: %x", keyBytes, loadedKeyBytes) 156 } 157 } 158 159 ioutil.WriteFile(fileName0, []byte(testPrivHex), 0600) 160 defer os.Remove(fileName0) 161 162 key0, err := LoadECDSA(fileName0) 163 if err != nil { 164 t.Fatal(err) 165 } 166 checkKey(key0) 167 168 err = SaveECDSA(fileName1, key0) 169 if err != nil { 170 t.Fatal(err) 171 } 172 defer os.Remove(fileName1) 173 174 key1, err := LoadECDSA(fileName1) 175 if err != nil { 176 t.Fatal(err) 177 } 178 checkKey(key1) 179 } 180 181 func TestValidateSignatureValues(t *testing.T) { 182 check := func(expected bool, v byte, r, s *big.Int) { 183 if ValidateSignatureValues(v, r, s, false) != expected { 184 t.Errorf("mismatch for v: %d r: %d s: %d want: %v", v, r, s, expected) 185 } 186 } 187 minusOne := big.NewInt(-1) 188 one := common.Big1 189 zero := common.Big0 190 secp256k1nMinus1 := new(big.Int).Sub(secp256k1N, common.Big1) 191 192 // correct v,r,s 193 check(true, 0, one, one) 194 check(true, 1, one, one) 195 // incorrect v, correct r,s, 196 check(false, 2, one, one) 197 check(false, 3, one, one) 198 199 // incorrect v, combinations of incorrect/correct r,s at lower limit 200 check(false, 2, zero, zero) 201 check(false, 2, zero, one) 202 check(false, 2, one, zero) 203 check(false, 2, one, one) 204 205 // correct v for any combination of incorrect r,s 206 check(false, 0, zero, zero) 207 check(false, 0, zero, one) 208 check(false, 0, one, zero) 209 210 check(false, 1, zero, zero) 211 check(false, 1, zero, one) 212 check(false, 1, one, zero) 213 214 // correct sig with max r,s 215 check(true, 0, secp256k1nMinus1, secp256k1nMinus1) 216 // correct v, combinations of incorrect r,s at upper limit 217 check(false, 0, secp256k1N, secp256k1nMinus1) 218 check(false, 0, secp256k1nMinus1, secp256k1N) 219 check(false, 0, secp256k1N, secp256k1N) 220 221 // current callers ensures r,s cannot be negative, but let's test for that too 222 // as crypto package could be used stand-alone 223 check(false, 0, minusOne, one) 224 check(false, 0, one, minusOne) 225 } 226 227 func checkhash(t *testing.T, name string, f func([]byte) []byte, msg, exp []byte) { 228 sum := f(msg) 229 if !bytes.Equal(exp, sum) { 230 t.Fatalf("hash %s mismatch: want: %x have: %x", name, exp, sum) 231 } 232 } 233 234 func checkAddr(t *testing.T, addr0, addr1 common.Address) { 235 if addr0 != addr1 { 236 t.Fatalf("address mismatch: want: %x have: %x", addr0, addr1) 237 } 238 } 239 240 func TestPythonIntegration(t *testing.T) { 241 kh := "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032" 242 k0, _ := HexToECDSA(kh) 243 244 msg0 := Keccak256([]byte("foo")) 245 sig0, _ := Sign(msg0, k0) 246 247 msg1 := common.FromHex("00000000000000000000000000000000") 248 sig1, _ := Sign(msg0, k0) 249 250 t.Logf("msg: %x, privkey: %s sig: %x\n", msg0, kh, sig0) 251 t.Logf("msg: %x, privkey: %s sig: %x\n", msg1, kh, sig1) 252 } 253 254 func TestNewNEATAddr(t *testing.T) { 255 key, _ := HexToECDSA(testPrivHex) 256 pubKeyBytes := FromECDSAPub(&key.PublicKey) 257 fmt.Printf("pubkeybytes=%v\n\n", pubKeyBytes) 258 fmt.Printf("pubkeyHex=%v\n\n", hexutil.Encode(pubKeyBytes)) 259 260 pubkey := ToECDSAPub(pubKeyBytes) 261 fmt.Printf("toecdsapub pubkey=%v\n\n", pubkey) 262 263 fmt.Printf("pubKey=%v\n", key.PublicKey) 264 fmt.Printf("x=%v\n", key.PublicKey.X.Bytes()) 265 fmt.Printf("y=%v\n\n", key.PublicKey.Y.Bytes()) 266 267 addr := NewNEATScriptAddr(pubKeyBytes) 268 fmt.Printf("address=%v\n", addr) 269 270 pubByte, _ := hexutil.Decode("0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") 271 pubAddr := NewNEATPubkeyAddr(pubByte) 272 fmt.Printf("0x040000 address %v\n", pubAddr) 273 274 data, _ := hexutil.Decode("0x0095027ab391b1a5327c6e64548e9340f1212b0b5b") 275 fmt.Printf("data %v\n", data) 276 checkByte := calcHash(calcHash(data, sha256.New()), sha256.New()) 277 fmt.Printf("checkByte %v\n", checkByte[:4]) 278 preDataCheck := append(data[:], checkByte[:4]...) 279 fmt.Printf("preDataCheck %v\n", preDataCheck) 280 bs58checkAddress := base58.Encode(preDataCheck) 281 fmt.Printf("bs58checkAddress %v\n", bs58checkAddress) 282 283 inputStr := "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 284 result, version, _ := CheckDecode(inputStr) 285 fmt.Printf("result %v, version %v\n", hexutil.Encode(result), version) 286 287 inputStr2 := "1EaterAddressDontSendAssetToFFFFFF" 288 result2, version2, _ := CheckDecode(inputStr2) 289 fmt.Printf("result %v, version %v\n", hexutil.Encode(result2), version2) 290 291 fffByte, _ := hexutil.Decode("0x00ffffffffffffffffffffffffffffffffffffffffffffffff") 292 fffStr := base58.Encode(fffByte) 293 fmt.Printf("fffStr %v\n", fffStr) 294 295 binAddr := common.StringToAddress(addr) 296 fmt.Printf("binary address=%v\n", binAddr) 297 298 hexAddr := common.BytesToAddress(binAddr[:]).Hex() 299 fmt.Printf("hex address=%v\n", hexAddr) 300 301 strAddr := binAddr.String() 302 fmt.Printf("string address=%v\n\n", strAddr) 303 304 checkNEATAddr(t, addr, testNEATAddr) 305 } 306 307 func BenchmarkCreateNEATAddress(b *testing.B) { 308 for i := 0; i < 100; i++ { 309 key, _ := GenerateKey() 310 addr := NewNEATScriptAddr(FromECDSAPub(&key.PublicKey)) 311 fmt.Printf("NEAT address %v\n", addr) 312 addrLen := len([]byte(addr)) 313 if addrLen != common.NEATAddressLength { 314 b.Errorf("NEAT address %v lenght mismatch want %v, but %v\n", addr, common.NEATAddressLength, addrLen) 315 } 316 } 317 } 318 319 type addressTest struct { 320 Address string 321 Valid bool 322 } 323 324 var addressList = []*addressTest{ 325 {Address: "NEATb437dSzaqRGxhTgW4qCq877ytYxb", Valid: true}, 326 {Address: "NEATb437dSzaqRGxhTgW4qCq877ytYx", Valid: false}, 327 {Address: "NEAHb437dSzaqRGxhTgW4qCq877ytYxb", Valid: false}, 328 {Address: "nEATb437dSzaqRGxhTgW4qCq877ytYxb", Valid: false}, 329 {Address: "NeATb437dSzaqRGxhTgW4qCq877ytYxb", Valid: false}, 330 {Address: "NEaTb437dSzaqRGxhTgW4qCq877ytYxb", Valid: false}, 331 {Address: "NEAtb437dSzaqRGxhTgW4qCq877ytYxb", Valid: false}, 332 {Address: "neaTb437dSzaqRGxhTgW4qCq877ytYxb", Valid: false}, 333 {Address: "neATb437dSzaqRGxhTgW4qCq877ytYxb", Valid: false}, 334 {Address: "NeaTb437dSzaqRGxhTgW4qCq877ytYxb", Valid: false}, 335 {Address: "NEatb437dSzaqRGxhTgW4qCq877ytYxb", Valid: false}, 336 {Address: "nEAtb437dSzaqRGxhTgW4qCq877ytYxb", Valid: false}, 337 {Address: "NeAtb437dSzaqRGxhTgW4qCq877ytYxb", Valid: false}, 338 {Address: "nEatb437dSzaqRGxhTgW4qCq877ytYxb", Valid: false}, 339 {Address: "b437dSzaqRGxhTgW4qCq877ytYxb", Valid: false}, 340 {Address: "NEAT", Valid: false}, 341 {Address: "NEATb43ldSzaqRGxhTgW4qCq877ytYxb", Valid: false}, 342 {Address: "NEATb43IdSzaqRGxhTgW4qCq877ytYxb", Valid: false}, 343 {Address: "NEATb430dSzaqRGxhTgW4qCq877ytYxb", Valid: false}, 344 {Address: "NEATb43OdSzaqRGxhTgW4qCq877ytYxb", Valid: false}, 345 } 346 347 func TestValidateNEATAddress(t *testing.T) { 348 for _, v := range addressList { 349 b := ValidateNEATAddr(v.Address) 350 if b == v.Valid { 351 t.Log("pass") 352 } else { 353 t.Errorf("address %v invalid, want %v but %v", v.Address, v.Valid, b) 354 } 355 } 356 357 } 358 359 func TestHexToAddress(t *testing.T) { 360 addr := common.HexToAddress("0x494e5433437046756b32634a31746539575a563177385933776b51436341355a") 361 fmt.Printf("addr=%v\n", addr.String()) 362 fmt.Printf("addr=%v\n", len(addr)) 363 fmt.Printf("testNEATAddrHex=%v\n", []byte(testNEATAddrHex)) 364 } 365 366 func checkNEATAddr(t *testing.T, addr0, addr1 string) { 367 if addr0 != addr1 { 368 t.Fatalf("address mismatch want: %s have: %s", addr0, addr1) 369 } 370 } 371 372 func TestEthAddress(t *testing.T) { 373 privateKeyHex := "c15c038a5a9f8f948a2ac0eb102c249e4ae1c4fa1e0971b50c63db46dc5fcf8b" 374 privateKey, err := HexToECDSA(privateKeyHex) 375 if err != nil { 376 t.Fatalf("failed to decode private key %v\n", err) 377 } 378 379 publicKey := FromECDSAPub(&privateKey.PublicKey) 380 381 ethAddress := hexutil.Encode(Keccak256(publicKey[1:])[12:]) 382 383 fmt.Printf("ethereum address %v\n", ethAddress) 384 } 385 386 func TestByte(t *testing.T) { 387 name := "LikeToken" 388 symbol := "LC" 389 390 byte1 := hexutil.Encode([]byte(name)) 391 byte2 := hexutil.Encode([]byte(symbol)) 392 fmt.Printf("name %v, symbol %v\n", byte1, byte2) 393 } 394 395 var messageByte = []byte("") 396 397 func CheckDecode(input string) (result []byte, version byte, err error) { 398 decoded := base58.Decode(input) 399 if len(decoded) < 5 { 400 return nil, 0, nil 401 } 402 version = decoded[0] 403 var cksum [4]byte 404 copy(cksum[:], decoded[len(decoded)-4:]) 405 //if checksum(decoded[:len(decoded)-4]) != cksum { 406 // return nil, 0, ErrChecksum 407 //} 408 payload := decoded[1 : len(decoded)-4] 409 result = append(result, payload...) 410 return 411 }