github.com/klaytn/klaytn@v1.12.1/crypto/signature_test.go (about)

     1  // Modifications Copyright 2018 The klaytn Authors
     2  // Copyright 2017 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/signature_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  	"reflect"
    27  	"testing"
    28  
    29  	"github.com/klaytn/klaytn/common"
    30  	"github.com/klaytn/klaytn/common/hexutil"
    31  	"github.com/klaytn/klaytn/common/math"
    32  )
    33  
    34  var (
    35  	testmsg     = hexutil.MustDecode("0xce0677bb30baa8cf067c88db9811f4333d131bf8bcf12fe7065d211dce971008")
    36  	testsig     = hexutil.MustDecode("0x90f27b8b488db00b00606796d2987f6a5f59ae62ea05effe84fef5b8b0e549984a691139ad57a3f0b906637673aa2f63d1f55cb1a69199d4009eea23ceaddc9301")
    37  	testpubkey  = hexutil.MustDecode("0x04e32df42865e97135acfb65f3bae71bdc86f4d49150ad6a440b6f15878109880a0a2b2667f7e725ceea70c673093bf67663e0312623c8e091b13cf2c0f11ef652")
    38  	testpubkeyc = hexutil.MustDecode("0x02e32df42865e97135acfb65f3bae71bdc86f4d49150ad6a440b6f15878109880a")
    39  )
    40  
    41  func TestEcrecover(t *testing.T) {
    42  	pubkey, err := Ecrecover(testmsg, testsig)
    43  	if err != nil {
    44  		t.Fatalf("recover error: %s", err)
    45  	}
    46  	if !bytes.Equal(pubkey, testpubkey) {
    47  		t.Errorf("pubkey mismatch: want: %x have: %x", testpubkey, pubkey)
    48  	}
    49  }
    50  
    51  func TestVerifySignature(t *testing.T) {
    52  	sig := testsig[:len(testsig)-1] // remove recovery id
    53  	if !VerifySignature(testpubkey, testmsg, sig) {
    54  		t.Errorf("can't verify signature with uncompressed key")
    55  	}
    56  	if !VerifySignature(testpubkeyc, testmsg, sig) {
    57  		t.Errorf("can't verify signature with compressed key")
    58  	}
    59  
    60  	if VerifySignature(nil, testmsg, sig) {
    61  		t.Errorf("signature valid with no key")
    62  	}
    63  	if VerifySignature(testpubkey, nil, sig) {
    64  		t.Errorf("signature valid with no message")
    65  	}
    66  	if VerifySignature(testpubkey, testmsg, nil) {
    67  		t.Errorf("nil signature valid")
    68  	}
    69  	if VerifySignature(testpubkey, testmsg, append(common.CopyBytes(sig), 1, 2, 3)) {
    70  		t.Errorf("signature valid with extra bytes at the end")
    71  	}
    72  	if VerifySignature(testpubkey, testmsg, sig[:len(sig)-2]) {
    73  		t.Errorf("signature valid even though it's incomplete")
    74  	}
    75  	wrongkey := common.CopyBytes(testpubkey)
    76  	wrongkey[10]++
    77  	if VerifySignature(wrongkey, testmsg, sig) {
    78  		t.Errorf("signature valid with with wrong public key")
    79  	}
    80  }
    81  
    82  // This test checks that VerifySignature rejects malleable signatures with s > N/2.
    83  func TestVerifySignatureMalleable(t *testing.T) {
    84  	sig := hexutil.MustDecode("0x638a54215d80a6713c8d523a6adc4e6e73652d859103a36b700851cb0e61b66b8ebfc1a610c57d732ec6e0a8f06a9a7a28df5051ece514702ff9cdff0b11f454")
    85  	key := hexutil.MustDecode("0x03ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd3138")
    86  	msg := hexutil.MustDecode("0xd301ce462d3e639518f482c7f03821fec1e602018630ce621e1e7851c12343a6")
    87  	if VerifySignature(key, msg, sig) {
    88  		t.Error("VerifySignature returned true for malleable signature")
    89  	}
    90  }
    91  
    92  func TestDecompressPubkey(t *testing.T) {
    93  	key, err := DecompressPubkey(testpubkeyc)
    94  	if err != nil {
    95  		t.Fatal(err)
    96  	}
    97  	if uncompressed := FromECDSAPub(key); !bytes.Equal(uncompressed, testpubkey) {
    98  		t.Errorf("wrong public key result: got %x, want %x", uncompressed, testpubkey)
    99  	}
   100  	if _, err := DecompressPubkey(nil); err == nil {
   101  		t.Errorf("no error for nil pubkey")
   102  	}
   103  	if _, err := DecompressPubkey(testpubkeyc[:5]); err == nil {
   104  		t.Errorf("no error for incomplete pubkey")
   105  	}
   106  	if _, err := DecompressPubkey(append(common.CopyBytes(testpubkeyc), 1, 2, 3)); err == nil {
   107  		t.Errorf("no error for pubkey with extra bytes at the end")
   108  	}
   109  }
   110  
   111  func TestCompressPubkey(t *testing.T) {
   112  	key := &ecdsa.PublicKey{
   113  		Curve: S256(),
   114  		X:     math.MustParseBig256("0xe32df42865e97135acfb65f3bae71bdc86f4d49150ad6a440b6f15878109880a"),
   115  		Y:     math.MustParseBig256("0x0a2b2667f7e725ceea70c673093bf67663e0312623c8e091b13cf2c0f11ef652"),
   116  	}
   117  	compressed := CompressPubkey(key)
   118  	if !bytes.Equal(compressed, testpubkeyc) {
   119  		t.Errorf("wrong public key result: got %x, want %x", compressed, testpubkeyc)
   120  	}
   121  }
   122  
   123  func TestPubkeyRandom(t *testing.T) {
   124  	const runs = 200
   125  
   126  	for i := 0; i < runs; i++ {
   127  		key, err := GenerateKey()
   128  		if err != nil {
   129  			t.Fatalf("iteration %d: %v", i, err)
   130  		}
   131  		pubkey2, err := DecompressPubkey(CompressPubkey(&key.PublicKey))
   132  		if err != nil {
   133  			t.Fatalf("iteration %d: %v", i, err)
   134  		}
   135  		if !reflect.DeepEqual(key.PublicKey, *pubkey2) {
   136  			t.Fatalf("iteration %d: keys not equal", i)
   137  		}
   138  	}
   139  }
   140  
   141  func BenchmarkEcrecoverSignature(b *testing.B) {
   142  	for i := 0; i < b.N; i++ {
   143  		if _, err := Ecrecover(testmsg, testsig); err != nil {
   144  			b.Fatal("ecrecover error", err)
   145  		}
   146  	}
   147  }
   148  
   149  func BenchmarkVerifySignature(b *testing.B) {
   150  	sig := testsig[:len(testsig)-1] // remove recovery id
   151  	for i := 0; i < b.N; i++ {
   152  		if !VerifySignature(testpubkey, testmsg, sig) {
   153  			b.Fatal("verify error")
   154  		}
   155  	}
   156  }
   157  
   158  func BenchmarkDecompressPubkey(b *testing.B) {
   159  	for i := 0; i < b.N; i++ {
   160  		if _, err := DecompressPubkey(testpubkeyc); err != nil {
   161  			b.Fatal(err)
   162  		}
   163  	}
   164  }