github.com/pixichain/go-pixicoin@v0.0.0-20220708132717-27ba739265ff/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  	"io/ioutil"
    25  	"math/big"
    26  	"os"
    27  	"testing"
    28  	"time"
    29  
    30  	"github.com/ethereum/go-ethereum/common"
    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 BenchmarkSha3(b *testing.B) {
    46  	a := []byte("hello world")
    47  	amount := 1000000
    48  	start := time.Now()
    49  	for i := 0; i < amount; i++ {
    50  		Keccak256(a)
    51  	}
    52  
    53  	fmt.Println(amount, ":", time.Since(start))
    54  }
    55  
    56  func TestSign(t *testing.T) {
    57  	key, _ := HexToECDSA(testPrivHex)
    58  	addr := common.HexToAddress(testAddrHex)
    59  
    60  	msg := Keccak256([]byte("foo"))
    61  	sig, err := Sign(msg, key)
    62  	if err != nil {
    63  		t.Errorf("Sign error: %s", err)
    64  	}
    65  	recoveredPub, err := Ecrecover(msg, sig)
    66  	if err != nil {
    67  		t.Errorf("ECRecover error: %s", err)
    68  	}
    69  	pubKey := ToECDSAPub(recoveredPub)
    70  	recoveredAddr := PubkeyToAddress(*pubKey)
    71  	if addr != recoveredAddr {
    72  		t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr)
    73  	}
    74  
    75  	// should be equal to SigToPub
    76  	recoveredPub2, err := SigToPub(msg, sig)
    77  	if err != nil {
    78  		t.Errorf("ECRecover error: %s", err)
    79  	}
    80  	recoveredAddr2 := PubkeyToAddress(*recoveredPub2)
    81  	if addr != recoveredAddr2 {
    82  		t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr2)
    83  	}
    84  }
    85  
    86  func TestInvalidSign(t *testing.T) {
    87  	if _, err := Sign(make([]byte, 1), nil); err == nil {
    88  		t.Errorf("expected sign with hash 1 byte to error")
    89  	}
    90  	if _, err := Sign(make([]byte, 33), nil); err == nil {
    91  		t.Errorf("expected sign with hash 33 byte to error")
    92  	}
    93  }
    94  
    95  func TestNewContractAddress(t *testing.T) {
    96  	key, _ := HexToECDSA(testPrivHex)
    97  	addr := common.HexToAddress(testAddrHex)
    98  	genAddr := PubkeyToAddress(key.PublicKey)
    99  	// sanity check before using addr to create contract address
   100  	checkAddr(t, genAddr, addr)
   101  
   102  	caddr0 := CreateAddress(addr, 0)
   103  	caddr1 := CreateAddress(addr, 1)
   104  	caddr2 := CreateAddress(addr, 2)
   105  	checkAddr(t, common.HexToAddress("333c3310824b7c685133f2bedb2ca4b8b4df633d"), caddr0)
   106  	checkAddr(t, common.HexToAddress("8bda78331c916a08481428e4b07c96d3e916d165"), caddr1)
   107  	checkAddr(t, common.HexToAddress("c9ddedf451bc62ce88bf9292afb13df35b670699"), caddr2)
   108  }
   109  
   110  func TestLoadECDSAFile(t *testing.T) {
   111  	keyBytes := common.FromHex(testPrivHex)
   112  	fileName0 := "test_key0"
   113  	fileName1 := "test_key1"
   114  	checkKey := func(k *ecdsa.PrivateKey) {
   115  		checkAddr(t, PubkeyToAddress(k.PublicKey), common.HexToAddress(testAddrHex))
   116  		loadedKeyBytes := FromECDSA(k)
   117  		if !bytes.Equal(loadedKeyBytes, keyBytes) {
   118  			t.Fatalf("private key mismatch: want: %x have: %x", keyBytes, loadedKeyBytes)
   119  		}
   120  	}
   121  
   122  	ioutil.WriteFile(fileName0, []byte(testPrivHex), 0600)
   123  	defer os.Remove(fileName0)
   124  
   125  	key0, err := LoadECDSA(fileName0)
   126  	if err != nil {
   127  		t.Fatal(err)
   128  	}
   129  	checkKey(key0)
   130  
   131  	// again, this time with SaveECDSA instead of manual save:
   132  	err = SaveECDSA(fileName1, key0)
   133  	if err != nil {
   134  		t.Fatal(err)
   135  	}
   136  	defer os.Remove(fileName1)
   137  
   138  	key1, err := LoadECDSA(fileName1)
   139  	if err != nil {
   140  		t.Fatal(err)
   141  	}
   142  	checkKey(key1)
   143  }
   144  
   145  func TestValidateSignatureValues(t *testing.T) {
   146  	check := func(expected bool, v byte, r, s *big.Int) {
   147  		if ValidateSignatureValues(v, r, s, false) != expected {
   148  			t.Errorf("mismatch for v: %d r: %d s: %d want: %v", v, r, s, expected)
   149  		}
   150  	}
   151  	minusOne := big.NewInt(-1)
   152  	one := common.Big1
   153  	zero := common.Big0
   154  	secp256k1nMinus1 := new(big.Int).Sub(secp256k1_N, common.Big1)
   155  
   156  	// correct v,r,s
   157  	check(true, 0, one, one)
   158  	check(true, 1, one, one)
   159  	// incorrect v, correct r,s,
   160  	check(false, 2, one, one)
   161  	check(false, 3, one, one)
   162  
   163  	// incorrect v, combinations of incorrect/correct r,s at lower limit
   164  	check(false, 2, zero, zero)
   165  	check(false, 2, zero, one)
   166  	check(false, 2, one, zero)
   167  	check(false, 2, one, one)
   168  
   169  	// correct v for any combination of incorrect r,s
   170  	check(false, 0, zero, zero)
   171  	check(false, 0, zero, one)
   172  	check(false, 0, one, zero)
   173  
   174  	check(false, 1, zero, zero)
   175  	check(false, 1, zero, one)
   176  	check(false, 1, one, zero)
   177  
   178  	// correct sig with max r,s
   179  	check(true, 0, secp256k1nMinus1, secp256k1nMinus1)
   180  	// correct v, combinations of incorrect r,s at upper limit
   181  	check(false, 0, secp256k1_N, secp256k1nMinus1)
   182  	check(false, 0, secp256k1nMinus1, secp256k1_N)
   183  	check(false, 0, secp256k1_N, secp256k1_N)
   184  
   185  	// current callers ensures r,s cannot be negative, but let's test for that too
   186  	// as crypto package could be used stand-alone
   187  	check(false, 0, minusOne, one)
   188  	check(false, 0, one, minusOne)
   189  }
   190  
   191  func checkhash(t *testing.T, name string, f func([]byte) []byte, msg, exp []byte) {
   192  	sum := f(msg)
   193  	if !bytes.Equal(exp, sum) {
   194  		t.Fatalf("hash %s mismatch: want: %x have: %x", name, exp, sum)
   195  	}
   196  }
   197  
   198  func checkAddr(t *testing.T, addr0, addr1 common.Address) {
   199  	if addr0 != addr1 {
   200  		t.Fatalf("address mismatch: want: %x have: %x", addr0, addr1)
   201  	}
   202  }
   203  
   204  // test to help Python team with integration of libsecp256k1
   205  // skip but keep it after they are done
   206  func TestPythonIntegration(t *testing.T) {
   207  	kh := "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032"
   208  	k0, _ := HexToECDSA(kh)
   209  
   210  	msg0 := Keccak256([]byte("foo"))
   211  	sig0, _ := Sign(msg0, k0)
   212  
   213  	msg1 := common.FromHex("00000000000000000000000000000000")
   214  	sig1, _ := Sign(msg0, k0)
   215  
   216  	t.Logf("msg: %x, privkey: %s sig: %x\n", msg0, kh, sig0)
   217  	t.Logf("msg: %x, privkey: %s sig: %x\n", msg1, kh, sig1)
   218  }