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.

235 lines
7.0 KiB

  1. package cryptoamino
  2. import (
  3. "os"
  4. "reflect"
  5. "testing"
  6. "github.com/stretchr/testify/assert"
  7. "github.com/stretchr/testify/require"
  8. amino "github.com/tendermint/go-amino"
  9. "github.com/tendermint/tendermint/crypto"
  10. "github.com/tendermint/tendermint/crypto/ed25519"
  11. "github.com/tendermint/tendermint/crypto/multisig"
  12. "github.com/tendermint/tendermint/crypto/secp256k1"
  13. "github.com/tendermint/tendermint/crypto/sr25519"
  14. )
  15. type byter interface {
  16. Bytes() []byte
  17. }
  18. func checkAminoBinary(t *testing.T, src, dst interface{}, size int) {
  19. // Marshal to binary bytes.
  20. bz, err := cdc.MarshalBinaryBare(src)
  21. require.Nil(t, err, "%+v", err)
  22. if byterSrc, ok := src.(byter); ok {
  23. // Make sure this is compatible with current (Bytes()) encoding.
  24. assert.Equal(t, byterSrc.Bytes(), bz, "Amino binary vs Bytes() mismatch")
  25. }
  26. // Make sure we have the expected length.
  27. assert.Equal(t, size, len(bz), "Amino binary size mismatch")
  28. // Unmarshal.
  29. err = cdc.UnmarshalBinaryBare(bz, dst)
  30. require.Nil(t, err, "%+v", err)
  31. }
  32. func checkAminoJSON(t *testing.T, src interface{}, dst interface{}, isNil bool) {
  33. // Marshal to JSON bytes.
  34. js, err := cdc.MarshalJSON(src)
  35. require.Nil(t, err, "%+v", err)
  36. if isNil {
  37. assert.Equal(t, string(js), `null`)
  38. } else {
  39. assert.Contains(t, string(js), `"type":`)
  40. assert.Contains(t, string(js), `"value":`)
  41. }
  42. // Unmarshal.
  43. err = cdc.UnmarshalJSON(js, dst)
  44. require.Nil(t, err, "%+v", err)
  45. }
  46. // ExamplePrintRegisteredTypes refers to unknown identifier: PrintRegisteredTypes
  47. //nolint:govet
  48. func ExamplePrintRegisteredTypes() {
  49. cdc.PrintTypes(os.Stdout)
  50. // Output: | Type | Name | Prefix | Length | Notes |
  51. //| ---- | ---- | ------ | ----- | ------ |
  52. //| PubKeyEd25519 | tendermint/PubKeyEd25519 | 0x1624DE64 | 0x20 | |
  53. //| PubKeySr25519 | tendermint/PubKeySr25519 | 0x0DFB1005 | 0x20 | |
  54. //| PubKeySecp256k1 | tendermint/PubKeySecp256k1 | 0xEB5AE987 | 0x21 | |
  55. //| PubKeyMultisigThreshold | tendermint/PubKeyMultisigThreshold | 0x22C1F7E2 | variable | |
  56. //| PrivKeyEd25519 | tendermint/PrivKeyEd25519 | 0xA3288910 | 0x40 | |
  57. //| PrivKeySr25519 | tendermint/PrivKeySr25519 | 0x2F82D78B | 0x20 | |
  58. //| PrivKeySecp256k1 | tendermint/PrivKeySecp256k1 | 0xE1B0F79B | 0x20 | |
  59. }
  60. func TestKeyEncodings(t *testing.T) {
  61. cases := []struct {
  62. privKey crypto.PrivKey
  63. privSize, pubSize, sigSize int // binary sizes
  64. }{
  65. {
  66. privKey: ed25519.GenPrivKey(),
  67. privSize: 69,
  68. pubSize: 37,
  69. sigSize: 65,
  70. },
  71. {
  72. privKey: sr25519.GenPrivKey(),
  73. privSize: 37,
  74. pubSize: 37,
  75. sigSize: 65,
  76. },
  77. {
  78. privKey: secp256k1.GenPrivKey(),
  79. privSize: 37,
  80. pubSize: 38,
  81. sigSize: 65,
  82. },
  83. }
  84. for tcIndex, tc := range cases {
  85. // Check (de/en)codings of PrivKeys.
  86. var priv2, priv3 crypto.PrivKey
  87. checkAminoBinary(t, tc.privKey, &priv2, tc.privSize)
  88. assert.EqualValues(t, tc.privKey, priv2, "tc #%d", tcIndex)
  89. checkAminoJSON(t, tc.privKey, &priv3, false) // TODO also check Prefix bytes.
  90. assert.EqualValues(t, tc.privKey, priv3, "tc #%d", tcIndex)
  91. // Check (de/en)codings of Signatures.
  92. var sig1, sig2 []byte
  93. sig1, err := tc.privKey.Sign([]byte("something"))
  94. assert.NoError(t, err, "tc #%d", tcIndex)
  95. checkAminoBinary(t, sig1, &sig2, tc.sigSize)
  96. assert.EqualValues(t, sig1, sig2, "tc #%d", tcIndex)
  97. // Check (de/en)codings of PubKeys.
  98. pubKey := tc.privKey.PubKey()
  99. var pub2, pub3 crypto.PubKey
  100. checkAminoBinary(t, pubKey, &pub2, tc.pubSize)
  101. assert.EqualValues(t, pubKey, pub2, "tc #%d", tcIndex)
  102. checkAminoJSON(t, pubKey, &pub3, false) // TODO also check Prefix bytes.
  103. assert.EqualValues(t, pubKey, pub3, "tc #%d", tcIndex)
  104. }
  105. }
  106. func TestNilEncodings(t *testing.T) {
  107. // Check nil Signature.
  108. var a, b []byte
  109. checkAminoJSON(t, &a, &b, true)
  110. assert.EqualValues(t, a, b)
  111. // Check nil PubKey.
  112. var c, d crypto.PubKey
  113. checkAminoJSON(t, &c, &d, true)
  114. assert.EqualValues(t, c, d)
  115. // Check nil PrivKey.
  116. var e, f crypto.PrivKey
  117. checkAminoJSON(t, &e, &f, true)
  118. assert.EqualValues(t, e, f)
  119. }
  120. func TestPubKeyInvalidDataProperReturnsEmpty(t *testing.T) {
  121. pk, err := PubKeyFromBytes([]byte("foo"))
  122. require.NotNil(t, err)
  123. require.Nil(t, pk)
  124. }
  125. func TestPubkeyAminoName(t *testing.T) {
  126. tests := []struct {
  127. key crypto.PubKey
  128. want string
  129. found bool
  130. }{
  131. {ed25519.PubKeyEd25519{}, ed25519.PubKeyAminoName, true},
  132. {sr25519.PubKeySr25519{}, sr25519.PubKeyAminoName, true},
  133. {secp256k1.PubKeySecp256k1{}, secp256k1.PubKeyAminoName, true},
  134. {multisig.PubKeyMultisigThreshold{}, multisig.PubKeyMultisigThresholdAminoRoute, true},
  135. }
  136. for i, tc := range tests {
  137. got, found := PubkeyAminoName(cdc, tc.key)
  138. require.Equal(t, tc.found, found, "not equal on tc %d", i)
  139. if tc.found {
  140. require.Equal(t, tc.want, got, "not equal on tc %d", i)
  141. }
  142. }
  143. }
  144. var _ crypto.PrivKey = testPriv{}
  145. var _ crypto.PubKey = testPub{}
  146. var testCdc = amino.NewCodec()
  147. type testPriv []byte
  148. func (privkey testPriv) PubKey() crypto.PubKey { return testPub{} }
  149. func (privkey testPriv) Bytes() []byte {
  150. return testCdc.MustMarshalBinaryBare(privkey)
  151. }
  152. func (privkey testPriv) Sign(msg []byte) ([]byte, error) { return []byte{}, nil }
  153. func (privkey testPriv) Equals(other crypto.PrivKey) bool { return true }
  154. type testPub []byte
  155. func (key testPub) Address() crypto.Address { return crypto.Address{} }
  156. func (key testPub) Bytes() []byte {
  157. return testCdc.MustMarshalBinaryBare(key)
  158. }
  159. func (key testPub) VerifyBytes(msg []byte, sig []byte) bool { return true }
  160. func (key testPub) Equals(other crypto.PubKey) bool { return true }
  161. var (
  162. privAminoName = "registerTest/Priv"
  163. pubAminoName = "registerTest/Pub"
  164. )
  165. func TestRegisterKeyType(t *testing.T) {
  166. RegisterAmino(testCdc)
  167. testCdc.RegisterConcrete(testPriv{}, privAminoName, nil)
  168. testCdc.RegisterConcrete(testPub{}, pubAminoName, nil)
  169. pub := testPub{0x1}
  170. priv := testPriv{0x2}
  171. // Check to make sure key cannot be decoded before registering
  172. _, err := PrivKeyFromBytes(priv.Bytes())
  173. require.Error(t, err)
  174. _, err = PubKeyFromBytes(pub.Bytes())
  175. require.Error(t, err)
  176. // Check that name is not registered
  177. _, found := PubkeyAminoName(testCdc, pub)
  178. require.False(t, found)
  179. // Register key types
  180. RegisterKeyType(testPriv{}, privAminoName)
  181. RegisterKeyType(testPub{}, pubAminoName)
  182. // Name should exist after registering
  183. name, found := PubkeyAminoName(testCdc, pub)
  184. require.True(t, found)
  185. require.Equal(t, name, pubAminoName)
  186. // Decode keys using the encoded bytes from encoding with the other codec
  187. decodedPriv, err := PrivKeyFromBytes(priv.Bytes())
  188. require.NoError(t, err)
  189. require.Equal(t, priv, decodedPriv)
  190. decodedPub, err := PubKeyFromBytes(pub.Bytes())
  191. require.NoError(t, err)
  192. require.Equal(t, pub, decodedPub)
  193. // Reset module codec after testing
  194. cdc = amino.NewCodec()
  195. nameTable = make(map[reflect.Type]string, 3)
  196. RegisterAmino(cdc)
  197. nameTable[reflect.TypeOf(ed25519.PubKeyEd25519{})] = ed25519.PubKeyAminoName
  198. nameTable[reflect.TypeOf(sr25519.PubKeySr25519{})] = sr25519.PubKeyAminoName
  199. nameTable[reflect.TypeOf(secp256k1.PubKeySecp256k1{})] = secp256k1.PubKeyAminoName
  200. nameTable[reflect.TypeOf(multisig.PubKeyMultisigThreshold{})] = multisig.PubKeyMultisigThresholdAminoRoute
  201. }