github.com/klaytn/klaytn@v1.10.2/crypto/crypto_test.go (about)

     1  // Modifications Copyright 2018 The klaytn Authors
     2  // Copyright 2014 The go-ethereum Authors
     3  // This file is part of the go-ethereum library.
     4  //
     5  // The go-ethereum library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The go-ethereum library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  // This file is derived from crypto/crypto_test.go (2018/06/04).
    19  // Modified and improved for the klaytn development.
    20  
    21  package crypto
    22  
    23  import (
    24  	"bytes"
    25  	"crypto/ecdsa"
    26  	"encoding/hex"
    27  	"io/ioutil"
    28  	"math/big"
    29  	"os"
    30  	"reflect"
    31  	"testing"
    32  
    33  	"github.com/klaytn/klaytn/common"
    34  	"github.com/klaytn/klaytn/common/hexutil"
    35  )
    36  
    37  var (
    38  	testAddrHex = "970e8128ab834e8eac17ab8e3812f010678cf791"
    39  	testPrivHex = "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032"
    40  )
    41  
    42  // These tests are sanity checks.
    43  // They should ensure that we don't e.g. use Sha3-224 instead of Sha3-256
    44  // and that the sha3 library uses keccak-f permutation.
    45  func TestKeccak256Hash(t *testing.T) {
    46  	msg := []byte("abc")
    47  	exp, _ := hex.DecodeString("4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45")
    48  	checkhash(t, "Sha3-256-array", func(in []byte) []byte { h := Keccak256Hash(in); return h[:] }, msg, exp)
    49  }
    50  
    51  func TestToECDSAErrors(t *testing.T) {
    52  	if _, err := HexToECDSA("0000000000000000000000000000000000000000000000000000000000000000"); err == nil {
    53  		t.Fatal("HexToECDSA should've returned error")
    54  	}
    55  	if _, err := HexToECDSA("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); err == nil {
    56  		t.Fatal("HexToECDSA should've returned error")
    57  	}
    58  }
    59  
    60  func BenchmarkSha3(b *testing.B) {
    61  	a := []byte("hello world")
    62  	for i := 0; i < b.N; i++ {
    63  		Keccak256(a)
    64  	}
    65  }
    66  
    67  func TestUnmarshalPubkey(t *testing.T) {
    68  	key, err := UnmarshalPubkey(nil)
    69  	if err != errInvalidPubkey || key != nil {
    70  		t.Fatalf("expected error, got %v, %v", err, key)
    71  	}
    72  	key, err = UnmarshalPubkey([]byte{1, 2, 3})
    73  	if err != errInvalidPubkey || key != nil {
    74  		t.Fatalf("expected error, got %v, %v", err, key)
    75  	}
    76  
    77  	var (
    78  		enc, _ = hex.DecodeString("04760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1b01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d")
    79  		dec    = &ecdsa.PublicKey{
    80  			Curve: S256(),
    81  			X:     hexutil.MustDecodeBig("0x760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1"),
    82  			Y:     hexutil.MustDecodeBig("0xb01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d"),
    83  		}
    84  	)
    85  	key, err = UnmarshalPubkey(enc)
    86  	if err != nil {
    87  		t.Fatalf("expected no error, got %v", err)
    88  	}
    89  	if !reflect.DeepEqual(key, dec) {
    90  		t.Fatal("wrong result")
    91  	}
    92  }
    93  
    94  func TestSign(t *testing.T) {
    95  	key, _ := HexToECDSA(testPrivHex)
    96  	addr := common.HexToAddress(testAddrHex)
    97  
    98  	msg := Keccak256([]byte("foo"))
    99  	sig, err := Sign(msg, key)
   100  	if err != nil {
   101  		t.Errorf("Sign error: %s", err)
   102  	}
   103  	recoveredPub, err := Ecrecover(msg, sig)
   104  	if err != nil {
   105  		t.Errorf("ECRecover error: %s", err)
   106  	}
   107  	pubKey, _ := UnmarshalPubkey(recoveredPub)
   108  	recoveredAddr := PubkeyToAddress(*pubKey)
   109  	if addr != recoveredAddr {
   110  		t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr)
   111  	}
   112  
   113  	// should be equal to SigToPub
   114  	recoveredPub2, err := SigToPub(msg, sig)
   115  	if err != nil {
   116  		t.Errorf("ECRecover error: %s", err)
   117  	}
   118  	recoveredAddr2 := PubkeyToAddress(*recoveredPub2)
   119  	if addr != recoveredAddr2 {
   120  		t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr2)
   121  	}
   122  }
   123  
   124  func TestInvalidSign(t *testing.T) {
   125  	if _, err := Sign(make([]byte, 1), nil); err == nil {
   126  		t.Errorf("expected sign with hash 1 byte to error")
   127  	}
   128  	if _, err := Sign(make([]byte, 33), nil); err == nil {
   129  		t.Errorf("expected sign with hash 33 byte to error")
   130  	}
   131  }
   132  
   133  func TestNewContractAddress(t *testing.T) {
   134  	key, _ := HexToECDSA(testPrivHex)
   135  	addr := common.HexToAddress(testAddrHex)
   136  	genAddr := PubkeyToAddress(key.PublicKey)
   137  	// sanity check before using addr to create contract address
   138  	checkAddr(t, genAddr, addr)
   139  
   140  	caddr0 := CreateAddress(addr, 0)
   141  	caddr1 := CreateAddress(addr, 1)
   142  	caddr2 := CreateAddress(addr, 2)
   143  	checkAddr(t, common.HexToAddress("333c3310824b7c685133f2bedb2ca4b8b4df633d"), caddr0)
   144  	checkAddr(t, common.HexToAddress("8bda78331c916a08481428e4b07c96d3e916d165"), caddr1)
   145  	checkAddr(t, common.HexToAddress("c9ddedf451bc62ce88bf9292afb13df35b670699"), caddr2)
   146  }
   147  
   148  func TestLoadECDSAFile(t *testing.T) {
   149  	keyBytes := common.FromHex(testPrivHex)
   150  	fileName0 := "test_key0"
   151  	fileName1 := "test_key1"
   152  	checkKey := func(k *ecdsa.PrivateKey) {
   153  		checkAddr(t, PubkeyToAddress(k.PublicKey), common.HexToAddress(testAddrHex))
   154  		loadedKeyBytes := FromECDSA(k)
   155  		if !bytes.Equal(loadedKeyBytes, keyBytes) {
   156  			t.Fatalf("private key mismatch: want: %x have: %x", keyBytes, loadedKeyBytes)
   157  		}
   158  	}
   159  
   160  	ioutil.WriteFile(fileName0, []byte(testPrivHex), 0o600)
   161  	defer os.Remove(fileName0)
   162  
   163  	key0, err := LoadECDSA(fileName0)
   164  	if err != nil {
   165  		t.Fatal(err)
   166  	}
   167  	checkKey(key0)
   168  
   169  	// again, this time with SaveECDSA instead of manual save:
   170  	err = SaveECDSA(fileName1, key0)
   171  	if err != nil {
   172  		t.Fatal(err)
   173  	}
   174  	defer os.Remove(fileName1)
   175  
   176  	key1, err := LoadECDSA(fileName1)
   177  	if err != nil {
   178  		t.Fatal(err)
   179  	}
   180  	checkKey(key1)
   181  }
   182  
   183  func TestValidateSignatureValues(t *testing.T) {
   184  	check := func(expected bool, v byte, r, s *big.Int) {
   185  		if ValidateSignatureValues(v, r, s, false) != expected {
   186  			t.Errorf("mismatch for v: %d r: %d s: %d want: %v", v, r, s, expected)
   187  		}
   188  	}
   189  	minusOne := big.NewInt(-1)
   190  	one := common.Big1
   191  	zero := common.Big0
   192  	secp256k1nMinus1 := new(big.Int).Sub(secp256k1N, common.Big1)
   193  
   194  	// correct v,r,s
   195  	check(true, 0, one, one)
   196  	check(true, 1, one, one)
   197  	// incorrect v, correct r,s,
   198  	check(false, 2, one, one)
   199  	check(false, 3, one, one)
   200  
   201  	// incorrect v, combinations of incorrect/correct r,s at lower limit
   202  	check(false, 2, zero, zero)
   203  	check(false, 2, zero, one)
   204  	check(false, 2, one, zero)
   205  	check(false, 2, one, one)
   206  
   207  	// correct v for any combination of incorrect r,s
   208  	check(false, 0, zero, zero)
   209  	check(false, 0, zero, one)
   210  	check(false, 0, one, zero)
   211  
   212  	check(false, 1, zero, zero)
   213  	check(false, 1, zero, one)
   214  	check(false, 1, one, zero)
   215  
   216  	// correct sig with max r,s
   217  	check(true, 0, secp256k1nMinus1, secp256k1nMinus1)
   218  	// correct v, combinations of incorrect r,s at upper limit
   219  	check(false, 0, secp256k1N, secp256k1nMinus1)
   220  	check(false, 0, secp256k1nMinus1, secp256k1N)
   221  	check(false, 0, secp256k1N, secp256k1N)
   222  
   223  	// current callers ensures r,s cannot be negative, but let's test for that too
   224  	// as crypto package could be used stand-alone
   225  	check(false, 0, minusOne, one)
   226  	check(false, 0, one, minusOne)
   227  }
   228  
   229  func checkhash(t *testing.T, name string, f func([]byte) []byte, msg, exp []byte) {
   230  	sum := f(msg)
   231  	if !bytes.Equal(exp, sum) {
   232  		t.Fatalf("hash %s mismatch: want: %x have: %x", name, exp, sum)
   233  	}
   234  }
   235  
   236  func checkAddr(t *testing.T, addr0, addr1 common.Address) {
   237  	if addr0 != addr1 {
   238  		t.Fatalf("address mismatch: want: %x have: %x", addr0, addr1)
   239  	}
   240  }
   241  
   242  // test to help Python team with integration of libsecp256k1
   243  // skip but keep it after they are done
   244  func TestPythonIntegration(t *testing.T) {
   245  	kh := "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032"
   246  	k0, _ := HexToECDSA(kh)
   247  
   248  	msg0 := Keccak256([]byte("foo"))
   249  	sig0, _ := Sign(msg0, k0)
   250  
   251  	msg1 := common.FromHex("00000000000000000000000000000000")
   252  	sig1, _ := Sign(msg0, k0)
   253  
   254  	t.Logf("msg: %x, privkey: %s sig: %x\n", msg0, kh, sig0)
   255  	t.Logf("msg: %x, privkey: %s sig: %x\n", msg1, kh, sig1)
   256  }