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