You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
3.4 KiB

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