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