github.com/jeffallen/go-ethereum@v1.1.4-0.20150910155051-571d3236c49c/crypto/secp256k1/secp256_test.go (about)

     1  // Copyright 2015 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 secp256k1
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"log"
    23  	"testing"
    24  
    25  	"github.com/ethereum/go-ethereum/crypto/randentropy"
    26  )
    27  
    28  const TESTS = 10000 // how many tests
    29  const SigSize = 65  //64+1
    30  
    31  func Test_Secp256_00(t *testing.T) {
    32  
    33  	var nonce []byte = randentropy.GetEntropyCSPRNG(32) //going to get bitcoins stolen!
    34  
    35  	if len(nonce) != 32 {
    36  		t.Fatal()
    37  	}
    38  
    39  }
    40  
    41  //tests for Malleability
    42  //highest bit of S must be 0; 32nd byte
    43  func CompactSigTest(sig []byte) {
    44  
    45  	var b int = int(sig[32])
    46  	if b < 0 {
    47  		log.Panic()
    48  	}
    49  	if ((b >> 7) == 1) != ((b & 0x80) == 0x80) {
    50  		log.Panic("b= %v b2= %v \n", b, b>>7)
    51  	}
    52  	if (b & 0x80) == 0x80 {
    53  		log.Panic("b= %v b2= %v \n", b, b&0x80)
    54  	}
    55  }
    56  
    57  //test pubkey/private generation
    58  func Test_Secp256_01(t *testing.T) {
    59  	pubkey, seckey := GenerateKeyPair()
    60  	if err := VerifySeckeyValidity(seckey); err != nil {
    61  		t.Fatal()
    62  	}
    63  	if err := VerifyPubkeyValidity(pubkey); err != nil {
    64  		t.Fatal()
    65  	}
    66  }
    67  
    68  //test size of messages
    69  func Test_Secp256_02s(t *testing.T) {
    70  	pubkey, seckey := GenerateKeyPair()
    71  	msg := randentropy.GetEntropyCSPRNG(32)
    72  	sig, _ := Sign(msg, seckey)
    73  	CompactSigTest(sig)
    74  	if sig == nil {
    75  		t.Fatal("Signature nil")
    76  	}
    77  	if len(pubkey) != 65 {
    78  		t.Fail()
    79  	}
    80  	if len(seckey) != 32 {
    81  		t.Fail()
    82  	}
    83  	if len(sig) != 64+1 {
    84  		t.Fail()
    85  	}
    86  	if int(sig[64]) > 4 {
    87  		t.Fail()
    88  	} //should be 0 to 4
    89  }
    90  
    91  //test signing message
    92  func Test_Secp256_02(t *testing.T) {
    93  	pubkey1, seckey := GenerateKeyPair()
    94  	msg := randentropy.GetEntropyCSPRNG(32)
    95  	sig, _ := Sign(msg, seckey)
    96  	if sig == nil {
    97  		t.Fatal("Signature nil")
    98  	}
    99  
   100  	pubkey2, _ := RecoverPubkey(msg, sig)
   101  	if pubkey2 == nil {
   102  		t.Fatal("Recovered pubkey invalid")
   103  	}
   104  	if bytes.Equal(pubkey1, pubkey2) == false {
   105  		t.Fatal("Recovered pubkey does not match")
   106  	}
   107  
   108  	err := VerifySignature(msg, sig, pubkey1)
   109  	if err != nil {
   110  		t.Fatal("Signature invalid")
   111  	}
   112  }
   113  
   114  //test pubkey recovery
   115  func Test_Secp256_02a(t *testing.T) {
   116  	pubkey1, seckey1 := GenerateKeyPair()
   117  	msg := randentropy.GetEntropyCSPRNG(32)
   118  	sig, _ := Sign(msg, seckey1)
   119  
   120  	if sig == nil {
   121  		t.Fatal("Signature nil")
   122  	}
   123  	err := VerifySignature(msg, sig, pubkey1)
   124  	if err != nil {
   125  		t.Fatal("Signature invalid")
   126  	}
   127  
   128  	pubkey2, _ := RecoverPubkey(msg, sig)
   129  	if len(pubkey1) != len(pubkey2) {
   130  		t.Fatal()
   131  	}
   132  	for i, _ := range pubkey1 {
   133  		if pubkey1[i] != pubkey2[i] {
   134  			t.Fatal()
   135  		}
   136  	}
   137  	if bytes.Equal(pubkey1, pubkey2) == false {
   138  		t.Fatal()
   139  	}
   140  }
   141  
   142  //test random messages for the same pub/private key
   143  func Test_Secp256_03(t *testing.T) {
   144  	_, seckey := GenerateKeyPair()
   145  	for i := 0; i < TESTS; i++ {
   146  		msg := randentropy.GetEntropyCSPRNG(32)
   147  		sig, _ := Sign(msg, seckey)
   148  		CompactSigTest(sig)
   149  
   150  		sig[len(sig)-1] %= 4
   151  		pubkey2, _ := RecoverPubkey(msg, sig)
   152  		if pubkey2 == nil {
   153  			t.Fail()
   154  		}
   155  	}
   156  }
   157  
   158  //test random messages for different pub/private keys
   159  func Test_Secp256_04(t *testing.T) {
   160  	for i := 0; i < TESTS; i++ {
   161  		pubkey1, seckey := GenerateKeyPair()
   162  		msg := randentropy.GetEntropyCSPRNG(32)
   163  		sig, _ := Sign(msg, seckey)
   164  		CompactSigTest(sig)
   165  
   166  		if sig[len(sig)-1] >= 4 {
   167  			t.Fail()
   168  		}
   169  		pubkey2, _ := RecoverPubkey(msg, sig)
   170  		if pubkey2 == nil {
   171  			t.Fail()
   172  		}
   173  		if bytes.Equal(pubkey1, pubkey2) == false {
   174  			t.Fail()
   175  		}
   176  	}
   177  }
   178  
   179  //test random signatures against fixed messages; should fail
   180  
   181  //crashes:
   182  //	-SIPA look at this
   183  
   184  func randSig() []byte {
   185  	sig := randentropy.GetEntropyCSPRNG(65)
   186  	sig[32] &= 0x70
   187  	sig[64] %= 4
   188  	return sig
   189  }
   190  
   191  func Test_Secp256_06a_alt0(t *testing.T) {
   192  	pubkey1, seckey := GenerateKeyPair()
   193  	msg := randentropy.GetEntropyCSPRNG(32)
   194  	sig, _ := Sign(msg, seckey)
   195  
   196  	if sig == nil {
   197  		t.Fail()
   198  	}
   199  	if len(sig) != 65 {
   200  		t.Fail()
   201  	}
   202  	for i := 0; i < TESTS; i++ {
   203  		sig = randSig()
   204  		pubkey2, _ := RecoverPubkey(msg, sig)
   205  
   206  		if bytes.Equal(pubkey1, pubkey2) == true {
   207  			t.Fail()
   208  		}
   209  
   210  		if pubkey2 != nil && VerifySignature(msg, sig, pubkey2) != nil {
   211  			t.Fail()
   212  		}
   213  
   214  		if VerifySignature(msg, sig, pubkey1) == nil {
   215  			t.Fail()
   216  		}
   217  	}
   218  }
   219  
   220  //test random messages against valid signature: should fail
   221  
   222  func Test_Secp256_06b(t *testing.T) {
   223  	pubkey1, seckey := GenerateKeyPair()
   224  	msg := randentropy.GetEntropyCSPRNG(32)
   225  	sig, _ := Sign(msg, seckey)
   226  
   227  	fail_count := 0
   228  	for i := 0; i < TESTS; i++ {
   229  		msg = randentropy.GetEntropyCSPRNG(32)
   230  		pubkey2, _ := RecoverPubkey(msg, sig)
   231  		if bytes.Equal(pubkey1, pubkey2) == true {
   232  			t.Fail()
   233  		}
   234  
   235  		if pubkey2 != nil && VerifySignature(msg, sig, pubkey2) != nil {
   236  			t.Fail()
   237  		}
   238  
   239  		if VerifySignature(msg, sig, pubkey1) == nil {
   240  			t.Fail()
   241  		}
   242  	}
   243  	if fail_count != 0 {
   244  		fmt.Printf("ERROR: Accepted signature for %v of %v random messages\n", fail_count, TESTS)
   245  	}
   246  }
   247  
   248  func TestInvalidKey(t *testing.T) {
   249  	p1 := make([]byte, 32)
   250  	err := VerifySeckeyValidity(p1)
   251  	if err == nil {
   252  		t.Errorf("pvk %x varify sec key should have returned error", p1)
   253  	}
   254  }