github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/crypto/crypto_test.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:36</date>
    10  //</624450084922200064>
    11  
    12  
    13  package crypto
    14  
    15  import (
    16  	"bytes"
    17  	"crypto/ecdsa"
    18  	"encoding/hex"
    19  	"io/ioutil"
    20  	"math/big"
    21  	"os"
    22  	"reflect"
    23  	"testing"
    24  
    25  	"github.com/ethereum/go-ethereum/common"
    26  	"github.com/ethereum/go-ethereum/common/hexutil"
    27  )
    28  
    29  var testAddrHex = "970e8128ab834e8eac17ab8e3812f010678cf791"
    30  var testPrivHex = "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032"
    31  
    32  //这些测试是健康检查。
    33  //他们应该确保我们不使用sha3-224而不是sha3-256
    34  //Sha3图书馆使用了keccak-f排列。
    35  func TestKeccak256Hash(t *testing.T) {
    36  	msg := []byte("abc")
    37  	exp, _ := hex.DecodeString("4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45")
    38  	checkhash(t, "Sha3-256-array", func(in []byte) []byte { h := Keccak256Hash(in); return h[:] }, msg, exp)
    39  }
    40  
    41  func TestToECDSAErrors(t *testing.T) {
    42  	if _, err := HexToECDSA("0000000000000000000000000000000000000000000000000000000000000000"); err == nil {
    43  		t.Fatal("HexToECDSA should've returned error")
    44  	}
    45  	if _, err := HexToECDSA("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); err == nil {
    46  		t.Fatal("HexToECDSA should've returned error")
    47  	}
    48  }
    49  
    50  func BenchmarkSha3(b *testing.B) {
    51  	a := []byte("hello world")
    52  	for i := 0; i < b.N; i++ {
    53  		Keccak256(a)
    54  	}
    55  }
    56  
    57  func TestUnmarshalPubkey(t *testing.T) {
    58  	key, err := UnmarshalPubkey(nil)
    59  	if err != errInvalidPubkey || key != nil {
    60  		t.Fatalf("expected error, got %v, %v", err, key)
    61  	}
    62  	key, err = UnmarshalPubkey([]byte{1, 2, 3})
    63  	if err != errInvalidPubkey || key != nil {
    64  		t.Fatalf("expected error, got %v, %v", err, key)
    65  	}
    66  
    67  	var (
    68  		enc, _ = hex.DecodeString("04760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1b01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d")
    69  		dec    = &ecdsa.PublicKey{
    70  			Curve: S256(),
    71  			X:     hexutil.MustDecodeBig("0x760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1"),
    72  			Y:     hexutil.MustDecodeBig("0xb01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d"),
    73  		}
    74  	)
    75  	key, err = UnmarshalPubkey(enc)
    76  	if err != nil {
    77  		t.Fatalf("expected no error, got %v", err)
    78  	}
    79  	if !reflect.DeepEqual(key, dec) {
    80  		t.Fatal("wrong result")
    81  	}
    82  }
    83  
    84  func TestSign(t *testing.T) {
    85  	key, _ := HexToECDSA(testPrivHex)
    86  	addr := common.HexToAddress(testAddrHex)
    87  
    88  	msg := Keccak256([]byte("foo"))
    89  	sig, err := Sign(msg, key)
    90  	if err != nil {
    91  		t.Errorf("Sign error: %s", err)
    92  	}
    93  	recoveredPub, err := Ecrecover(msg, sig)
    94  	if err != nil {
    95  		t.Errorf("ECRecover error: %s", err)
    96  	}
    97  	pubKey, _ := UnmarshalPubkey(recoveredPub)
    98  	recoveredAddr := PubkeyToAddress(*pubKey)
    99  	if addr != recoveredAddr {
   100  		t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr)
   101  	}
   102  
   103  //应等于sigtopub
   104  	recoveredPub2, err := SigToPub(msg, sig)
   105  	if err != nil {
   106  		t.Errorf("ECRecover error: %s", err)
   107  	}
   108  	recoveredAddr2 := PubkeyToAddress(*recoveredPub2)
   109  	if addr != recoveredAddr2 {
   110  		t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr2)
   111  	}
   112  }
   113  
   114  func TestInvalidSign(t *testing.T) {
   115  	if _, err := Sign(make([]byte, 1), nil); err == nil {
   116  		t.Errorf("expected sign with hash 1 byte to error")
   117  	}
   118  	if _, err := Sign(make([]byte, 33), nil); err == nil {
   119  		t.Errorf("expected sign with hash 33 byte to error")
   120  	}
   121  }
   122  
   123  func TestNewContractAddress(t *testing.T) {
   124  	key, _ := HexToECDSA(testPrivHex)
   125  	addr := common.HexToAddress(testAddrHex)
   126  	genAddr := PubkeyToAddress(key.PublicKey)
   127  //使用addr创建合同地址前的健全性检查
   128  	checkAddr(t, genAddr, addr)
   129  
   130  	caddr0 := CreateAddress(addr, 0)
   131  	caddr1 := CreateAddress(addr, 1)
   132  	caddr2 := CreateAddress(addr, 2)
   133  	checkAddr(t, common.HexToAddress("333c3310824b7c685133f2bedb2ca4b8b4df633d"), caddr0)
   134  	checkAddr(t, common.HexToAddress("8bda78331c916a08481428e4b07c96d3e916d165"), caddr1)
   135  	checkAddr(t, common.HexToAddress("c9ddedf451bc62ce88bf9292afb13df35b670699"), caddr2)
   136  }
   137  
   138  func TestLoadECDSAFile(t *testing.T) {
   139  	keyBytes := common.FromHex(testPrivHex)
   140  	fileName0 := "test_key0"
   141  	fileName1 := "test_key1"
   142  	checkKey := func(k *ecdsa.PrivateKey) {
   143  		checkAddr(t, PubkeyToAddress(k.PublicKey), common.HexToAddress(testAddrHex))
   144  		loadedKeyBytes := FromECDSA(k)
   145  		if !bytes.Equal(loadedKeyBytes, keyBytes) {
   146  			t.Fatalf("private key mismatch: want: %x have: %x", keyBytes, loadedKeyBytes)
   147  		}
   148  	}
   149  
   150  	ioutil.WriteFile(fileName0, []byte(testPrivHex), 0600)
   151  	defer os.Remove(fileName0)
   152  
   153  	key0, err := LoadECDSA(fileName0)
   154  	if err != nil {
   155  		t.Fatal(err)
   156  	}
   157  	checkKey(key0)
   158  
   159  //同样,这次使用saveecdsa而不是手动保存:
   160  	err = SaveECDSA(fileName1, key0)
   161  	if err != nil {
   162  		t.Fatal(err)
   163  	}
   164  	defer os.Remove(fileName1)
   165  
   166  	key1, err := LoadECDSA(fileName1)
   167  	if err != nil {
   168  		t.Fatal(err)
   169  	}
   170  	checkKey(key1)
   171  }
   172  
   173  func TestValidateSignatureValues(t *testing.T) {
   174  	check := func(expected bool, v byte, r, s *big.Int) {
   175  		if ValidateSignatureValues(v, r, s, false) != expected {
   176  			t.Errorf("mismatch for v: %d r: %d s: %d want: %v", v, r, s, expected)
   177  		}
   178  	}
   179  	minusOne := big.NewInt(-1)
   180  	one := common.Big1
   181  	zero := common.Big0
   182  	secp256k1nMinus1 := new(big.Int).Sub(secp256k1N, common.Big1)
   183  
   184  //正确的V,R,S
   185  	check(true, 0, one, one)
   186  	check(true, 1, one, one)
   187  //不正确的v,正确的r,s,
   188  	check(false, 2, one, one)
   189  	check(false, 3, one, one)
   190  
   191  //不正确的V、不正确/正确的R、S组合在下限
   192  	check(false, 2, zero, zero)
   193  	check(false, 2, zero, one)
   194  	check(false, 2, one, zero)
   195  	check(false, 2, one, one)
   196  
   197  //正确的V代表不正确的R,S组合
   198  	check(false, 0, zero, zero)
   199  	check(false, 0, zero, one)
   200  	check(false, 0, one, zero)
   201  
   202  	check(false, 1, zero, zero)
   203  	check(false, 1, zero, one)
   204  	check(false, 1, one, zero)
   205  
   206  //用max r,s修正sig
   207  	check(true, 0, secp256k1nMinus1, secp256k1nMinus1)
   208  //正确的V,上限不正确的R、S组合
   209  	check(false, 0, secp256k1N, secp256k1nMinus1)
   210  	check(false, 0, secp256k1nMinus1, secp256k1N)
   211  	check(false, 0, secp256k1N, secp256k1N)
   212  
   213  //当前调用方确保r,s不能为负,但我们也要测试一下。
   214  //因为加密包可以独立使用
   215  	check(false, 0, minusOne, one)
   216  	check(false, 0, one, minusOne)
   217  }
   218  
   219  func checkhash(t *testing.T, name string, f func([]byte) []byte, msg, exp []byte) {
   220  	sum := f(msg)
   221  	if !bytes.Equal(exp, sum) {
   222  		t.Fatalf("hash %s mismatch: want: %x have: %x", name, exp, sum)
   223  	}
   224  }
   225  
   226  func checkAddr(t *testing.T, addr0, addr1 common.Address) {
   227  	if addr0 != addr1 {
   228  		t.Fatalf("address mismatch: want: %x have: %x", addr0, addr1)
   229  	}
   230  }
   231  
   232  //测试以帮助Python团队集成libsecp256k1
   233  //跳过,但完成后保留
   234  func TestPythonIntegration(t *testing.T) {
   235  	kh := "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032"
   236  	k0, _ := HexToECDSA(kh)
   237  
   238  	msg0 := Keccak256([]byte("foo"))
   239  	sig0, _ := Sign(msg0, k0)
   240  
   241  	msg1 := common.FromHex("00000000000000000000000000000000")
   242  	sig1, _ := Sign(msg0, k0)
   243  
   244  	t.Logf("msg: %x, privkey: %s sig: %x\n", msg0, kh, sig0)
   245  	t.Logf("msg: %x, privkey: %s sig: %x\n", msg1, kh, sig1)
   246  }
   247