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