github.com/core-coin/go-core/v2@v2.1.9/crypto/crypto_test.go (about)

     1  // Copyright 2014 by the Authors
     2  // This file is part of the go-core library.
     3  //
     4  // The go-core 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-core 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-core library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package crypto
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/hex"
    22  	"io/ioutil"
    23  	"os"
    24  	"reflect"
    25  	"testing"
    26  
    27  	"github.com/core-coin/go-core/v2/common"
    28  )
    29  
    30  var testAddrHex = "cb82a5fd22b9bee8b8ab877c86e0a2c21765e1d5bfc5"
    31  var testPrivHex = "69bb68c3a00a0cd9cbf2cab316476228c758329bbfe0b1759e8634694a9497afea05bcbf24e2aa0627eac4240484bb71de646a9296872a3c0e"
    32  
    33  // These tests are sanity checks.
    34  // They should ensure that we don't e.g. use Sha3-224 instead of Sha3-256
    35  // and that the sha3 library uses keccak-f permutation.
    36  func TestSHA3Hash(t *testing.T) {
    37  	msg := []byte("abc")
    38  	exp, _ := hex.DecodeString("3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532")
    39  	checkhash(t, "Sha3-256-array", func(in []byte) []byte { h := SHA3Hash(in); return h[:] }, msg, exp)
    40  }
    41  
    42  func TestToEDDSAErrors(t *testing.T) {
    43  	if _, err := UnmarshalPrivateKeyHex("0000000000000000000000000000000000000000000000000000000000000000"); err == nil {
    44  		t.Fatal("UnmarshalPrivateKeyHex should've returned error")
    45  	}
    46  	if _, err := UnmarshalPrivateKeyHex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); err == nil {
    47  		t.Fatal("UnmarshalPrivateKeyHex should've returned error")
    48  	}
    49  }
    50  
    51  func BenchmarkSha3(b *testing.B) {
    52  	a := []byte("hello world")
    53  	for i := 0; i < b.N; i++ {
    54  		SHA3(a)
    55  	}
    56  }
    57  
    58  func TestUnmarshalPubkey(t *testing.T) {
    59  	key, err := UnmarshalPubKey(nil)
    60  	if err != errInvalidPubkey || key != nil {
    61  		t.Fatalf("expected error, got %v, %v", err, key)
    62  	}
    63  	key, err = UnmarshalPubKey([]byte{1, 2, 3})
    64  	if err != errInvalidPubkey || key != nil {
    65  		t.Fatalf("expected error, got %v, %v", err, key)
    66  	}
    67  
    68  	var (
    69  		enc, _ = hex.DecodeString("aaee47e4f7afb3a0dfd813320278e8ce0c9b1f94bded9a7e0ad9f9250c3360e16cbb3d90484ccc59805be6398b6ca774959d37a8a4cdc81faf")
    70  	)
    71  	key, err = UnmarshalPubKey(enc)
    72  	if err != nil {
    73  		t.Fatalf("expected no error, got %v", err)
    74  	}
    75  }
    76  
    77  func TestSign(t *testing.T) {
    78  	key, _ := UnmarshalPrivateKeyHex(testPrivHex)
    79  	addr, err := common.HexToAddress(testAddrHex)
    80  	if err != nil {
    81  		t.Error(err)
    82  	}
    83  	msg := SHA3([]byte("foo"))
    84  	sig, err := Sign(msg, key)
    85  	if err != nil {
    86  		t.Errorf("Sign error: %s", err)
    87  	}
    88  	recoveredPub, err := Ecrecover(msg, sig)
    89  	if err != nil {
    90  		t.Errorf("ECRecover error: %s", err)
    91  	}
    92  	pubKey, _ := UnmarshalPubKey(recoveredPub)
    93  	recoveredAddr := PubkeyToAddress(pubKey)
    94  	if addr != recoveredAddr {
    95  		t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr)
    96  	}
    97  
    98  	// should be equal to SigToPub
    99  	recoveredPub2, err := SigToPub(msg, sig)
   100  	if err != nil {
   101  		t.Errorf("ECRecover error: %s", err)
   102  	}
   103  	recoveredAddr2 := PubkeyToAddress(recoveredPub2)
   104  	if addr != recoveredAddr2 {
   105  		t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr2)
   106  	}
   107  }
   108  
   109  func TestInvalidSign(t *testing.T) {
   110  	if _, err := Sign(make([]byte, 1), nil); err == nil {
   111  		t.Errorf("expected sign with hash 1 byte to error")
   112  	}
   113  	if _, err := Sign(make([]byte, 33), nil); err == nil {
   114  		t.Errorf("expected sign with hash 33 byte to error")
   115  	}
   116  }
   117  
   118  func TestNewContractAddress(t *testing.T) {
   119  	key, _ := UnmarshalPrivateKeyHex(testPrivHex)
   120  	addr, err := common.HexToAddress(testAddrHex)
   121  	if err != nil {
   122  		t.Error(err)
   123  	}
   124  	pub := DerivePublicKey(key)
   125  	genAddr := PubkeyToAddress(pub)
   126  	// sanity check before using addr to create contract address
   127  	checkAddr(t, genAddr, addr)
   128  	caddr0 := CreateAddress(addr, 0)
   129  	caddr1 := CreateAddress(addr, 1)
   130  	caddr2 := CreateAddress(addr, 2)
   131  
   132  	addr0, err := common.HexToAddress("cb57718e2b338b99d2587a6dd6c01fc2b97a4296449f")
   133  	if err != nil {
   134  		t.Error(err)
   135  	}
   136  	addr1, err := common.HexToAddress("cb812bae2e00797890802e8aa6c162aac5cac4d8990c")
   137  	if err != nil {
   138  		t.Error(err)
   139  	}
   140  	addr2, err := common.HexToAddress("cb98c562c98ac1be66b1302be0cac7f8da9694900b09")
   141  	if err != nil {
   142  		t.Error(err)
   143  	}
   144  	checkAddr(t, addr0, caddr0)
   145  	checkAddr(t, addr1, caddr1)
   146  	checkAddr(t, addr2, caddr2)
   147  }
   148  
   149  func TestLoadEDDSA(t *testing.T) {
   150  	tests := []struct {
   151  		input string
   152  		err   string
   153  	}{
   154  		// good
   155  		{input: "69bb68c3a00a0cd9cbf2cab316476228c758329bbfe0b1759e8634694a9497afea05bcbf24e2aa0627eac4240484bb71de646a9296872a3c0e"},
   156  		{input: "69bb68c3a00a0cd9cbf2cab316476228c758329bbfe0b1759e8634694a9497afea05bcbf24e2aa0627eac4240484bb71de646a9296872a3c0e\n"},
   157  		{input: "69bb68c3a00a0cd9cbf2cab316476228c758329bbfe0b1759e8634694a9497afea05bcbf24e2aa0627eac4240484bb71de646a9296872a3c0e\n\r"},
   158  		{input: "69bb68c3a00a0cd9cbf2cab316476228c758329bbfe0b1759e8634694a9497afea05bcbf24e2aa0627eac4240484bb71de646a9296872a3c0e\r\n"},
   159  		{input: "69bb68c3a00a0cd9cbf2cab316476228c758329bbfe0b1759e8634694a9497afea05bcbf24e2aa0627eac4240484bb71de646a9296872a3c0e\n\n"},
   160  		{input: "69bb68c3a00a0cd9cbf2cab316476228c758329bbfe0b1759e8634694a9497afea05bcbf24e2aa0627eac4240484bb71de646a9296872a3c0e\n\r"},
   161  		// bad
   162  		{
   163  			input: "69bb68c3a00a0cd9cbf2cab316476228c758329bbfe0b1759e8634694a9497afea05bcbf24e2aa0627eac4240484bb71de646a9296872a3c0",
   164  			err:   "key file too short, want 57 hex characters",
   165  		},
   166  		{
   167  			input: "69bb68c3a00a0cd9cbf2cab316476228c758329bbfe0b1759e8634694a9497afea05bcbf24e2aa0627eac4240484bb71de646a9296872a3c0\n",
   168  			err:   "key file too short, want 57 hex characters",
   169  		},
   170  		{
   171  			input: "69bb68c3a00a0cd9cbf2cab316476228c758329bbfe0b1759e8634694a9497afea05bcbf24e2aa0627eac4240484bb71de646a9296872a3c0X",
   172  			err:   "invalid hex character 'X' in private key",
   173  		},
   174  		{
   175  			input: "69bb68c3a00a0cd9cbf2cab316476228c758329bbfe0b1759e8634694a9497afea05bcbf24e2aa0627eac4240484bb71de646a9296872a3c0eX",
   176  			err:   "invalid character 'X' at end of key file",
   177  		},
   178  		{
   179  			input: "69bb68c3a00a0cd9cbf2cab316476228c758329bbfe0b1759e8634694a9497afea05bcbf24e2aa0627eac4240484bb71de646a9296872a3c0e\n\n\n",
   180  			err:   "key file too long, want 57 hex characters",
   181  		},
   182  	}
   183  
   184  	for _, test := range tests {
   185  		f, err := ioutil.TempFile("", "loaded448_test.*.txt")
   186  		if err != nil {
   187  			t.Fatal(err)
   188  		}
   189  		filename := f.Name()
   190  		f.WriteString(test.input)
   191  		f.Close()
   192  
   193  		_, err = LoadEDDSA(filename)
   194  		switch {
   195  		case err != nil && test.err == "":
   196  			t.Fatalf("unexpected error for input %q:\n  %v", test.input, err)
   197  		case err != nil && err.Error() != test.err:
   198  			t.Fatalf("wrong error for input %q:\n  %v", test.input, err)
   199  		case err == nil && test.err != "":
   200  			t.Fatalf("LoadEDDSA did not return error for input %q", test.input)
   201  		}
   202  	}
   203  }
   204  
   205  func TestSaveEDDSA(t *testing.T) {
   206  	f, err := ioutil.TempFile("", "saveed448_test.*.txt")
   207  	if err != nil {
   208  		t.Fatal(err)
   209  	}
   210  	file := f.Name()
   211  	f.Close()
   212  	defer os.Remove(file)
   213  
   214  	key, _ := UnmarshalPrivateKeyHex(testPrivHex)
   215  	if err := SaveEDDSA(file, key); err != nil {
   216  		t.Fatal(err)
   217  	}
   218  	loaded, err := LoadEDDSA(file)
   219  	if err != nil {
   220  		t.Fatal(err)
   221  	}
   222  	if !reflect.DeepEqual(key, loaded) {
   223  		t.Fatal("loaded key not equal to saved key")
   224  	}
   225  }
   226  
   227  func checkhash(t *testing.T, name string, f func([]byte) []byte, msg, exp []byte) {
   228  	sum := f(msg)
   229  	if !bytes.Equal(exp, sum) {
   230  		t.Fatalf("hash %s mismatch: want: %x have: %x", name, exp, sum)
   231  	}
   232  }
   233  
   234  func checkAddr(t *testing.T, addr0, addr1 common.Address) {
   235  	if addr0 != addr1 {
   236  		t.Fatalf("address mismatch: want: %x have: %x", addr0, addr1)
   237  	}
   238  }