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 }