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  }