github.com/vipernet-xyz/tm@v0.34.24/crypto/secp256k1/secp256k1_test.go (about)

     1  package secp256k1_test
     2  
     3  import (
     4  	"encoding/hex"
     5  	"math/big"
     6  	"testing"
     7  
     8  	"github.com/btcsuite/btcutil/base58"
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  
    12  	"github.com/vipernet-xyz/tm/crypto"
    13  	"github.com/vipernet-xyz/tm/crypto/secp256k1"
    14  
    15  	underlyingSecp256k1 "github.com/btcsuite/btcd/btcec"
    16  )
    17  
    18  type keyData struct {
    19  	priv string
    20  	pub  string
    21  	addr string
    22  }
    23  
    24  var secpDataTable = []keyData{
    25  	{
    26  		priv: "a96e62ed3955e65be32703f12d87b6b5cf26039ecfa948dc5107a495418e5330",
    27  		pub:  "02950e1cdfcb133d6024109fd489f734eeb4502418e538c28481f22bce276f248c",
    28  		addr: "1CKZ9Nx4zgds8tU7nJHotKSDr4a9bYJCa3",
    29  	},
    30  }
    31  
    32  func TestPubKeySecp256k1Address(t *testing.T) {
    33  	for _, d := range secpDataTable {
    34  		privB, _ := hex.DecodeString(d.priv)
    35  		pubB, _ := hex.DecodeString(d.pub)
    36  		addrBbz, _, _ := base58.CheckDecode(d.addr)
    37  		addrB := crypto.Address(addrBbz)
    38  
    39  		priv := secp256k1.PrivKey(privB)
    40  
    41  		pubKey := priv.PubKey()
    42  		pubT, _ := pubKey.(secp256k1.PubKey)
    43  		pub := pubT
    44  		addr := pubKey.Address()
    45  
    46  		assert.Equal(t, pub, secp256k1.PubKey(pubB), "Expected pub keys to match")
    47  		assert.Equal(t, addr, addrB, "Expected addresses to match")
    48  	}
    49  }
    50  
    51  func TestSignAndValidateSecp256k1(t *testing.T) {
    52  	privKey := secp256k1.GenPrivKey()
    53  	pubKey := privKey.PubKey()
    54  
    55  	msg := crypto.CRandBytes(128)
    56  	sig, err := privKey.Sign(msg)
    57  	require.Nil(t, err)
    58  
    59  	assert.True(t, pubKey.VerifySignature(msg, sig))
    60  
    61  	// Mutate the signature, just one bit.
    62  	sig[3] ^= byte(0x01)
    63  
    64  	assert.False(t, pubKey.VerifySignature(msg, sig))
    65  }
    66  
    67  // This test is intended to justify the removal of calls to the underlying library
    68  // in creating the privkey.
    69  func TestSecp256k1LoadPrivkeyAndSerializeIsIdentity(t *testing.T) {
    70  	numberOfTests := 256
    71  	for i := 0; i < numberOfTests; i++ {
    72  		// Seed the test case with some random bytes
    73  		privKeyBytes := [32]byte{}
    74  		copy(privKeyBytes[:], crypto.CRandBytes(32))
    75  
    76  		// This function creates a private and public key in the underlying libraries format.
    77  		// The private key is basically calling new(big.Int).SetBytes(pk), which removes leading zero bytes
    78  		priv, _ := underlyingSecp256k1.PrivKeyFromBytes(underlyingSecp256k1.S256(), privKeyBytes[:])
    79  		// this takes the bytes returned by `(big int).Bytes()`, and if the length is less than 32 bytes,
    80  		// pads the bytes from the left with zero bytes. Therefore these two functions composed
    81  		// result in the identity function on privKeyBytes, hence the following equality check
    82  		// always returning true.
    83  		serializedBytes := priv.Serialize()
    84  		require.Equal(t, privKeyBytes[:], serializedBytes)
    85  	}
    86  }
    87  
    88  func TestGenPrivKeySecp256k1(t *testing.T) {
    89  	// curve oder N
    90  	N := underlyingSecp256k1.S256().N
    91  	tests := []struct {
    92  		name   string
    93  		secret []byte
    94  	}{
    95  		{"empty secret", []byte{}},
    96  		{
    97  			"some long secret",
    98  			[]byte("We live in a society exquisitely dependent on science and technology, " +
    99  				"in which hardly anyone knows anything about science and technology."),
   100  		},
   101  		{"another seed used in cosmos tests #1", []byte{0}},
   102  		{"another seed used in cosmos tests #2", []byte("mySecret")},
   103  		{"another seed used in cosmos tests #3", []byte("")},
   104  	}
   105  	for _, tt := range tests {
   106  		tt := tt
   107  		t.Run(tt.name, func(t *testing.T) {
   108  			gotPrivKey := secp256k1.GenPrivKeySecp256k1(tt.secret)
   109  			require.NotNil(t, gotPrivKey)
   110  			// interpret as a big.Int and make sure it is a valid field element:
   111  			fe := new(big.Int).SetBytes(gotPrivKey[:])
   112  			require.True(t, fe.Cmp(N) < 0)
   113  			require.True(t, fe.Sign() > 0)
   114  		})
   115  	}
   116  }