github.com/intfoundation/intchain@v0.0.0-20220727031208-4316ad31ca73/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  	"fmt"
    24  	"github.com/intfoundation/intchain/common/hexutil"
    25  	"io/ioutil"
    26  	"math/big"
    27  	"os"
    28  	"reflect"
    29  	"testing"
    30  
    31  	"github.com/intfoundation/intchain/common"
    32  )
    33  
    34  var testAddrHex = "970e8128ab834e8eac17ab8e3812f010678cf791"
    35  var testPrivHex = "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032"
    36  
    37  // These tests are sanity checks.
    38  // They should ensure that we don't e.g. use Sha3-224 instead of Sha3-256
    39  // and that the sha3 library uses keccak-f permutation.
    40  func TestKeccak256Hash(t *testing.T) {
    41  	msg := []byte("abc")
    42  	exp, _ := hex.DecodeString("4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45")
    43  	checkhash(t, "Sha3-256-array", func(in []byte) []byte { h := Keccak256Hash(in); return h[:] }, msg, exp)
    44  }
    45  
    46  func TestToECDSAErrors(t *testing.T) {
    47  	if _, err := HexToECDSA("0000000000000000000000000000000000000000000000000000000000000000"); err == nil {
    48  		t.Fatal("HexToECDSA should've returned error")
    49  	}
    50  	if _, err := HexToECDSA("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); err == nil {
    51  		t.Fatal("HexToECDSA should've returned error")
    52  	}
    53  }
    54  
    55  func BenchmarkSha3(b *testing.B) {
    56  	a := []byte("hello world")
    57  	for i := 0; i < b.N; i++ {
    58  		Keccak256(a)
    59  	}
    60  }
    61  
    62  func TestSign(t *testing.T) {
    63  	key, _ := HexToECDSA(testPrivHex)
    64  	addr := common.HexToAddress(testAddrHex)
    65  
    66  	msg := Keccak256([]byte("foo"))
    67  	sig, err := Sign(msg, key)
    68  	if err != nil {
    69  		t.Errorf("Sign error: %s", err)
    70  	}
    71  	recoveredPub, err := Ecrecover(msg, sig)
    72  	if err != nil {
    73  		t.Errorf("ECRecover error: %s", err)
    74  	}
    75  	pubKey, _ := UnmarshalPubkey(recoveredPub)
    76  	recoveredAddr := PubkeyToAddress(*pubKey)
    77  	if addr != recoveredAddr {
    78  		t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr)
    79  	}
    80  
    81  	// should be equal to SigToPub
    82  	recoveredPub2, err := SigToPub(msg, sig)
    83  	if err != nil {
    84  		t.Errorf("ECRecover error: %s", err)
    85  	}
    86  	recoveredAddr2 := PubkeyToAddress(*recoveredPub2)
    87  	if addr != recoveredAddr2 {
    88  		t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr2)
    89  	}
    90  }
    91  
    92  func TestUnmarshalPubkey(t *testing.T) {
    93  	key, err := UnmarshalPubkey(nil)
    94  	if err != errInvalidPubkey || key != nil {
    95  		t.Fatalf("expected error, got %v, %v", err, key)
    96  	}
    97  	key, err = UnmarshalPubkey([]byte{1, 2, 3})
    98  	if err != errInvalidPubkey || key != nil {
    99  		t.Fatalf("expected error, got %v, %v", err, key)
   100  	}
   101  
   102  	var (
   103  		enc, _ = hex.DecodeString("04760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1b01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d")
   104  		dec    = &ecdsa.PublicKey{
   105  			Curve: S256(),
   106  			X:     hexutil.MustDecodeBig("0x760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1"),
   107  			Y:     hexutil.MustDecodeBig("0xb01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d"),
   108  		}
   109  	)
   110  	key, err = UnmarshalPubkey(enc)
   111  	if err != nil {
   112  		t.Fatalf("expected no error, got %v", err)
   113  	}
   114  	if !reflect.DeepEqual(key, dec) {
   115  		t.Fatal("wrong result")
   116  	}
   117  }
   118  
   119  func TestInvalidSign(t *testing.T) {
   120  	if _, err := Sign(make([]byte, 1), nil); err == nil {
   121  		t.Errorf("expected sign with hash 1 byte to error")
   122  	}
   123  	if _, err := Sign(make([]byte, 33), nil); err == nil {
   124  		t.Errorf("expected sign with hash 33 byte to error")
   125  	}
   126  }
   127  
   128  func TestNewContractAddress(t *testing.T) {
   129  	key, _ := HexToECDSA(testPrivHex)
   130  	addr := common.HexToAddress(testAddrHex)
   131  	fmt.Printf("byte addr=%v\n", addr)
   132  	genAddr := PubkeyToAddress(key.PublicKey)
   133  	fmt.Printf("gen addr=%v\n", addr)
   134  	// sanity check before using addr to create contract address
   135  	checkAddr(t, genAddr, addr)
   136  
   137  	caddr0 := CreateAddress(addr, 0)
   138  	caddr1 := CreateAddress(addr, 1)
   139  	caddr2 := CreateAddress(addr, 2)
   140  	checkAddr(t, common.HexToAddress("3343384b35786b757666344431674c5376684346413467674b73506b7268316f4c31"), caddr0)
   141  	checkAddr(t, common.HexToAddress("334b713575554c4c594e6e65546831544e7a4352767377626e554a55334a6d6f3773"), caddr1)
   142  	checkAddr(t, common.HexToAddress("3339416a5166364c48454346596a316e45566a67414d675250723578414d69334b67"), caddr2)
   143  }
   144  
   145  func TestLoadECDSAFile(t *testing.T) {
   146  	keyBytes := common.FromHex(testPrivHex)
   147  	fileName0 := "test_key0"
   148  	fileName1 := "test_key1"
   149  	checkKey := func(k *ecdsa.PrivateKey) {
   150  		checkAddr(t, PubkeyToAddress(k.PublicKey), common.HexToAddress(testAddrHex))
   151  		loadedKeyBytes := FromECDSA(k)
   152  		if !bytes.Equal(loadedKeyBytes, keyBytes) {
   153  			t.Fatalf("private key mismatch: want: %x have: %x", keyBytes, loadedKeyBytes)
   154  		}
   155  	}
   156  
   157  	ioutil.WriteFile(fileName0, []byte(testPrivHex), 0600)
   158  	defer os.Remove(fileName0)
   159  
   160  	key0, err := LoadECDSA(fileName0)
   161  	if err != nil {
   162  		t.Fatal(err)
   163  	}
   164  	checkKey(key0)
   165  
   166  	// again, this time with SaveECDSA instead of manual save:
   167  	err = SaveECDSA(fileName1, key0)
   168  	if err != nil {
   169  		t.Fatal(err)
   170  	}
   171  	defer os.Remove(fileName1)
   172  
   173  	key1, err := LoadECDSA(fileName1)
   174  	if err != nil {
   175  		t.Fatal(err)
   176  	}
   177  	checkKey(key1)
   178  }
   179  
   180  func TestValidateSignatureValues(t *testing.T) {
   181  	check := func(expected bool, v byte, r, s *big.Int) {
   182  		if ValidateSignatureValues(v, r, s, false) != expected {
   183  			t.Errorf("mismatch for v: %d r: %d s: %d want: %v", v, r, s, expected)
   184  		}
   185  	}
   186  	minusOne := big.NewInt(-1)
   187  	one := common.Big1
   188  	zero := common.Big0
   189  	secp256k1nMinus1 := new(big.Int).Sub(secp256k1N, common.Big1)
   190  
   191  	// correct v,r,s
   192  	check(true, 0, one, one)
   193  	check(true, 1, one, one)
   194  	// incorrect v, correct r,s,
   195  	check(false, 2, one, one)
   196  	check(false, 3, one, one)
   197  
   198  	// incorrect v, combinations of incorrect/correct r,s at lower limit
   199  	check(false, 2, zero, zero)
   200  	check(false, 2, zero, one)
   201  	check(false, 2, one, zero)
   202  	check(false, 2, one, one)
   203  
   204  	// correct v for any combination of incorrect r,s
   205  	check(false, 0, zero, zero)
   206  	check(false, 0, zero, one)
   207  	check(false, 0, one, zero)
   208  
   209  	check(false, 1, zero, zero)
   210  	check(false, 1, zero, one)
   211  	check(false, 1, one, zero)
   212  
   213  	// correct sig with max r,s
   214  	check(true, 0, secp256k1nMinus1, secp256k1nMinus1)
   215  	// correct v, combinations of incorrect r,s at upper limit
   216  	check(false, 0, secp256k1N, secp256k1nMinus1)
   217  	check(false, 0, secp256k1nMinus1, secp256k1N)
   218  	check(false, 0, secp256k1N, secp256k1N)
   219  
   220  	// current callers ensures r,s cannot be negative, but let's test for that too
   221  	// as crypto package could be used stand-alone
   222  	check(false, 0, minusOne, one)
   223  	check(false, 0, one, minusOne)
   224  }
   225  
   226  func checkhash(t *testing.T, name string, f func([]byte) []byte, msg, exp []byte) {
   227  	sum := f(msg)
   228  	if !bytes.Equal(exp, sum) {
   229  		t.Fatalf("hash %s mismatch: want: %x have: %x", name, exp, sum)
   230  	}
   231  }
   232  
   233  func checkAddr(t *testing.T, addr0, addr1 common.Address) {
   234  	if addr0 != addr1 {
   235  		t.Fatalf("address mismatch: want: %x have: %x", addr0, addr1)
   236  	}
   237  }
   238  
   239  // test to help Python team with integration of libsecp256k1
   240  // skip but keep it after they are done
   241  func TestPythonIntegration(t *testing.T) {
   242  	kh := "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032"
   243  	k0, _ := HexToECDSA(kh)
   244  
   245  	msg0 := Keccak256([]byte("foo"))
   246  	sig0, _ := Sign(msg0, k0)
   247  
   248  	msg1 := common.FromHex("00000000000000000000000000000000")
   249  	sig1, _ := Sign(msg0, k0)
   250  
   251  	t.Logf("msg: %x, privkey: %s sig: %x\n", msg0, kh, sig0)
   252  	t.Logf("msg: %x, privkey: %s sig: %x\n", msg1, kh, sig1)
   253  }
   254  
   255  func TestEthAddress(t *testing.T) {
   256  	privateKeyHex := "c15c038a5a9f8f948a2ac0eb102c249e4ae1c4fa1e0971b50c63db46dc5fcf8b"
   257  	privateKey, err := HexToECDSA(privateKeyHex)
   258  	if err != nil {
   259  		t.Fatalf("failed to decode private key %v\n", err)
   260  	}
   261  
   262  	publicKey := FromECDSAPub(&privateKey.PublicKey)
   263  
   264  	ethAddress := hexutil.Encode(Keccak256(publicKey[1:])[12:])
   265  
   266  	fmt.Printf("ethereum address %v\n", ethAddress)
   267  
   268  	addrHex := "0xc84e9eba34cfb0690ae607207a64d662686d17f7"
   269  
   270  	addrBytes := common.HexToAddress(addrHex).Big()
   271  
   272  	b, _ := new(big.Int).SetString("862381068151338842291839054294319045153034925969", 10)
   273  
   274  	addrBig := common.BigToAddress(b).String()
   275  
   276  	fmt.Printf("address bytes %v, address big %v\n", addrBytes, addrBig)
   277  }