github.com/r8d8/go-ethereum@v5.5.2+incompatible/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/ethereumproject/go-ethereum/common"
    31  	"github.com/ethereumproject/go-ethereum/common/hexutil"
    32  	"github.com/ethereumproject/go-ethereum/crypto/secp256k1"
    33  )
    34  
    35  var testAddrHex = "970e8128ab834e8eac17ab8e3812f010678cf791"
    36  var testPrivHex = "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032"
    37  
    38  var (
    39  	testmsg     = hexutil.MustDecode("0xce0677bb30baa8cf067c88db9811f4333d131bf8bcf12fe7065d211dce971008")
    40  	testsig     = hexutil.MustDecode("0x90f27b8b488db00b00606796d2987f6a5f59ae62ea05effe84fef5b8b0e549984a691139ad57a3f0b906637673aa2f63d1f55cb1a69199d4009eea23ceaddc9301")
    41  	testpubkey  = hexutil.MustDecode("0x04e32df42865e97135acfb65f3bae71bdc86f4d49150ad6a440b6f15878109880a0a2b2667f7e725ceea70c673093bf67663e0312623c8e091b13cf2c0f11ef652")
    42  	testpubkeyc = hexutil.MustDecode("0x02e32df42865e97135acfb65f3bae71bdc86f4d49150ad6a440b6f15878109880a")
    43  )
    44  
    45  func TestEcrecover(t *testing.T) {
    46  	pubkey, err := Ecrecover(testmsg, testsig)
    47  	if err != nil {
    48  		t.Fatalf("recover error: %s", err)
    49  	}
    50  	if !bytes.Equal(pubkey, testpubkey) {
    51  		t.Errorf("pubkey mismatch: want: %x have: %x", testpubkey, pubkey)
    52  	}
    53  }
    54  
    55  // These tests are sanity checks.
    56  // They should ensure that we don't e.g. use Sha3-224 instead of Sha3-256
    57  // and that the sha3 library uses keccak-f permutation.
    58  func TestSha3(t *testing.T) {
    59  	msg := []byte("abc")
    60  	exp, _ := hex.DecodeString("4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45")
    61  	checkhash(t, "Sha3-256", func(in []byte) []byte { return Keccak256(in) }, msg, exp)
    62  }
    63  
    64  func TestSha3Hash(t *testing.T) {
    65  	msg := []byte("abc")
    66  	exp, _ := hex.DecodeString("4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45")
    67  	checkhash(t, "Sha3-256-array", func(in []byte) []byte { h := Keccak256Hash(in); return h[:] }, msg, exp)
    68  }
    69  
    70  func TestSha256(t *testing.T) {
    71  	msg := []byte("abc")
    72  	exp, _ := hex.DecodeString("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad")
    73  	checkhash(t, "Sha256", Sha256, msg, exp)
    74  }
    75  
    76  func TestRipemd160(t *testing.T) {
    77  	msg := []byte("abc")
    78  	exp, _ := hex.DecodeString("8eb208f7e05d987a9b044a8e98c6b087f15a0bfc")
    79  	checkhash(t, "Ripemd160", Ripemd160, msg, exp)
    80  }
    81  
    82  func BenchmarkSha3(b *testing.B) {
    83  	a := []byte("hello world")
    84  	amount := 1000000
    85  	start := time.Now()
    86  	for i := 0; i < amount; i++ {
    87  		Keccak256(a)
    88  	}
    89  
    90  	fmt.Println(amount, ":", time.Since(start))
    91  }
    92  
    93  func Test0Key(t *testing.T) {
    94  	key := common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000")
    95  	_, err := secp256k1.GeneratePubKey(key)
    96  	if err == nil {
    97  		t.Errorf("expected error due to zero privkey")
    98  	}
    99  }
   100  
   101  func TestSign(t *testing.T) {
   102  	key, _ := HexToECDSA(testPrivHex)
   103  	addr := common.HexToAddress(testAddrHex)
   104  
   105  	msg := Keccak256([]byte("foo"))
   106  	sig, err := Sign(msg, key)
   107  	if err != nil {
   108  		t.Errorf("Sign error: %s", err)
   109  	}
   110  	if len(sig) != 65 {
   111  		t.Error("wrong signature length", len(sig))
   112  	}
   113  	recoveredPub, err := Ecrecover(msg, sig)
   114  	if err != nil {
   115  		t.Errorf("ECRecover error: %s", err)
   116  	}
   117  	recoveredAddr := PubkeyToAddress(*ToECDSAPub(recoveredPub))
   118  	if addr != recoveredAddr {
   119  		t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr)
   120  	}
   121  
   122  	// should be equal to SigToPub
   123  	recoveredPub2, err := SigToPub(msg, sig)
   124  	if err != nil {
   125  		t.Errorf("ECRecover error: %s", err)
   126  	}
   127  	recoveredAddr2 := PubkeyToAddress(*recoveredPub2)
   128  	if addr != recoveredAddr2 {
   129  		t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr2)
   130  	}
   131  
   132  }
   133  
   134  func TestInvalidSign(t *testing.T) {
   135  	_, err := Sign(make([]byte, 1), nil)
   136  	if err == nil {
   137  		t.Errorf("expected sign with hash 1 byte to error")
   138  	}
   139  
   140  	_, err = Sign(make([]byte, 33), nil)
   141  	if err == nil {
   142  		t.Errorf("expected sign with hash 33 byte to error")
   143  	}
   144  }
   145  
   146  func TestNewContractAddress(t *testing.T) {
   147  	key, _ := HexToECDSA(testPrivHex)
   148  	addr := common.HexToAddress(testAddrHex)
   149  	genAddr := PubkeyToAddress(key.PublicKey)
   150  	// sanity check before using addr to create contract address
   151  	checkAddr(t, genAddr, addr)
   152  
   153  	caddr0 := CreateAddress(addr, 0)
   154  	caddr1 := CreateAddress(addr, 1)
   155  	caddr2 := CreateAddress(addr, 2)
   156  	checkAddr(t, common.HexToAddress("333c3310824b7c685133f2bedb2ca4b8b4df633d"), caddr0)
   157  	checkAddr(t, common.HexToAddress("8bda78331c916a08481428e4b07c96d3e916d165"), caddr1)
   158  	checkAddr(t, common.HexToAddress("c9ddedf451bc62ce88bf9292afb13df35b670699"), caddr2)
   159  }
   160  
   161  func TestLoadECDSAFile(t *testing.T) {
   162  	keyBytes := common.FromHex(testPrivHex)
   163  	fileName0 := "test_key0"
   164  	fileName1 := "test_key1"
   165  	checkKey := func(k *ecdsa.PrivateKey) {
   166  		checkAddr(t, PubkeyToAddress(k.PublicKey), common.HexToAddress(testAddrHex))
   167  		loadedKeyBytes := FromECDSA(k)
   168  		if !bytes.Equal(loadedKeyBytes, keyBytes) {
   169  			t.Fatalf("private key mismatch: want: %x have: %x", keyBytes, loadedKeyBytes)
   170  		}
   171  	}
   172  
   173  	ioutil.WriteFile(fileName0, []byte(testPrivHex), 0600)
   174  	defer os.Remove(fileName0)
   175  
   176  	f, err := os.Open(fileName0)
   177  	if err != nil {
   178  		t.Fatal(err)
   179  	}
   180  	key0, err := LoadECDSA(f)
   181  	if e := f.Close(); e != nil {
   182  		t.Fatal(e)
   183  	}
   184  	if err != nil {
   185  		t.Fatal(err)
   186  	}
   187  	checkKey(key0)
   188  
   189  	// again, this time with WriteECDSAKey instead of manual save:
   190  	f, err = os.Create(fileName1)
   191  	if err != nil {
   192  		t.Fatal(err)
   193  	}
   194  	_, err = WriteECDSAKey(f, key0)
   195  	if err != nil {
   196  		t.Fatal(err)
   197  	}
   198  	if err := f.Close(); err != nil {
   199  		t.Fatal(err)
   200  	}
   201  	defer os.Remove(fileName1)
   202  
   203  	f1, err := os.Open(fileName1)
   204  	if err != nil {
   205  		t.Fatal(err)
   206  	}
   207  	key1, err := LoadECDSA(f1)
   208  	if err != nil {
   209  		t.Fatal(err)
   210  	}
   211  	if err := f1.Close(); err != nil {
   212  		t.Fatal(err)
   213  	}
   214  	checkKey(key1)
   215  }
   216  
   217  func TestValidateSignatureValues(t *testing.T) {
   218  	check := func(expected bool, v byte, r, s *big.Int) {
   219  		if ValidateSignatureValues(v, r, s, false) != expected {
   220  			t.Errorf("mismatch for v: %d r: %d s: %d want: %v", v, r, s, expected)
   221  		}
   222  	}
   223  	minusOne := big.NewInt(-1)
   224  	one := common.Big1
   225  	zero := new(big.Int)
   226  	secp256k1nMinus1 := new(big.Int).Sub(secp256k1.N, common.Big1)
   227  
   228  	// correct v,r,s
   229  	check(true, 27, one, one)
   230  	check(true, 28, one, one)
   231  	// incorrect v, correct r,s,
   232  	check(false, 30, one, one)
   233  	check(false, 26, one, one)
   234  
   235  	// incorrect v, combinations of incorrect/correct r,s at lower limit
   236  	check(false, 0, zero, zero)
   237  	check(false, 0, zero, one)
   238  	check(false, 0, one, zero)
   239  	check(false, 0, one, one)
   240  
   241  	// correct v for any combination of incorrect r,s
   242  	check(false, 27, zero, zero)
   243  	check(false, 27, zero, one)
   244  	check(false, 27, one, zero)
   245  
   246  	check(false, 28, zero, zero)
   247  	check(false, 28, zero, one)
   248  	check(false, 28, one, zero)
   249  
   250  	// correct sig with max r,s
   251  	check(true, 27, secp256k1nMinus1, secp256k1nMinus1)
   252  	// correct v, combinations of incorrect r,s at upper limit
   253  	check(false, 27, secp256k1.N, secp256k1nMinus1)
   254  	check(false, 27, secp256k1nMinus1, secp256k1.N)
   255  	check(false, 27, secp256k1.N, secp256k1.N)
   256  
   257  	// current callers ensures r,s cannot be negative, but let's test for that too
   258  	// as crypto package could be used stand-alone
   259  	check(false, 27, minusOne, one)
   260  	check(false, 27, one, minusOne)
   261  }
   262  
   263  func checkhash(t *testing.T, name string, f func([]byte) []byte, msg, exp []byte) {
   264  	sum := f(msg)
   265  	if bytes.Compare(exp, sum) != 0 {
   266  		t.Fatalf("hash %s mismatch: want: %x have: %x", name, exp, sum)
   267  	}
   268  }
   269  
   270  func checkAddr(t *testing.T, addr0, addr1 common.Address) {
   271  	if addr0 != addr1 {
   272  		t.Fatalf("address mismatch: want: %x have: %x", addr0, addr1)
   273  	}
   274  }
   275  
   276  // test to help Python team with integration of libsecp256k1
   277  // skip but keep it after they are done
   278  func TestPythonIntegration(t *testing.T) {
   279  	kh := "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032"
   280  	k0, _ := HexToECDSA(kh)
   281  	k1 := FromECDSA(k0)
   282  
   283  	msg0 := Keccak256([]byte("foo"))
   284  	sig0, _ := secp256k1.Sign(msg0, k1)
   285  
   286  	msg1 := common.FromHex("00000000000000000000000000000000")
   287  	sig1, _ := secp256k1.Sign(msg0, k1)
   288  
   289  	fmt.Printf("msg: %x, privkey: %x sig: %x\n", msg0, k1, sig0)
   290  	fmt.Printf("msg: %x, privkey: %x sig: %x\n", msg1, k1, sig1)
   291  }