github.com/okex/exchain@v1.8.0/libs/tendermint/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/okex/exchain/libs/tendermint/crypto"
    13  	"github.com/okex/exchain/libs/tendermint/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  		var priv secp256k1.PrivKeySecp256k1
    40  		copy(priv[:], privB)
    41  
    42  		pubKey := priv.PubKey()
    43  		pubT, _ := pubKey.(secp256k1.PubKeySecp256k1)
    44  		pub := pubT[:]
    45  		addr := pubKey.Address()
    46  
    47  		assert.Equal(t, pub, pubB, "Expected pub keys to match")
    48  		assert.Equal(t, addr, addrB, "Expected addresses to match")
    49  	}
    50  }
    51  
    52  func TestSignAndValidateSecp256k1(t *testing.T) {
    53  	privKey := secp256k1.GenPrivKey()
    54  	pubKey := privKey.PubKey()
    55  
    56  	msg := crypto.CRandBytes(128)
    57  	sig, err := privKey.Sign(msg)
    58  	require.Nil(t, err)
    59  
    60  	assert.True(t, pubKey.VerifyBytes(msg, sig))
    61  
    62  	// Mutate the signature, just one bit.
    63  	sig[3] ^= byte(0x01)
    64  
    65  	assert.False(t, pubKey.VerifyBytes(msg, sig))
    66  }
    67  
    68  // This test is intended to justify the removal of calls to the underlying library
    69  // in creating the privkey.
    70  func TestSecp256k1LoadPrivkeyAndSerializeIsIdentity(t *testing.T) {
    71  	numberOfTests := 256
    72  	for i := 0; i < numberOfTests; i++ {
    73  		// Seed the test case with some random bytes
    74  		privKeyBytes := [32]byte{}
    75  		copy(privKeyBytes[:], crypto.CRandBytes(32))
    76  
    77  		// This function creates a private and public key in the underlying libraries format.
    78  		// The private key is basically calling new(big.Int).SetBytes(pk), which removes leading zero bytes
    79  		priv, _ := underlyingSecp256k1.PrivKeyFromBytes(underlyingSecp256k1.S256(), privKeyBytes[:])
    80  		// this takes the bytes returned by `(big int).Bytes()`, and if the length is less than 32 bytes,
    81  		// pads the bytes from the left with zero bytes. Therefore these two functions composed
    82  		// result in the identity function on privKeyBytes, hence the following equality check
    83  		// always returning true.
    84  		serializedBytes := priv.Serialize()
    85  		require.Equal(t, privKeyBytes[:], serializedBytes)
    86  	}
    87  }
    88  
    89  func TestGenPrivKeySecp256k1(t *testing.T) {
    90  	// curve oder N
    91  	N := underlyingSecp256k1.S256().N
    92  	tests := []struct {
    93  		name   string
    94  		secret []byte
    95  	}{
    96  		{"empty secret", []byte{}},
    97  		{
    98  			"some long secret",
    99  			[]byte("We live in a society exquisitely dependent on science and technology, " +
   100  				"in which hardly anyone knows anything about science and technology."),
   101  		},
   102  		{"another seed used in cosmos tests #1", []byte{0}},
   103  		{"another seed used in cosmos tests #2", []byte("mySecret")},
   104  		{"another seed used in cosmos tests #3", []byte("")},
   105  	}
   106  	for _, tt := range tests {
   107  		tt := tt
   108  		t.Run(tt.name, func(t *testing.T) {
   109  			gotPrivKey := secp256k1.GenPrivKeySecp256k1(tt.secret)
   110  			require.NotNil(t, gotPrivKey)
   111  			// interpret as a big.Int and make sure it is a valid field element:
   112  			fe := new(big.Int).SetBytes(gotPrivKey[:])
   113  			require.True(t, fe.Cmp(N) < 0)
   114  			require.True(t, fe.Sign() > 0)
   115  		})
   116  	}
   117  }