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.

183 lines
4.4 KiB

  1. package crypto
  2. import (
  3. "fmt"
  4. "strings"
  5. "testing"
  6. "github.com/stretchr/testify/assert"
  7. "github.com/stretchr/testify/require"
  8. wire "github.com/tendermint/go-wire"
  9. data "github.com/tendermint/go-wire/data"
  10. )
  11. type byter interface {
  12. Bytes() []byte
  13. }
  14. // go to wire encoding and back
  15. func checkWire(t *testing.T, in byter, reader interface{}, typ byte, size int) {
  16. // test to and from binary
  17. bin, err := data.ToWire(in)
  18. require.Nil(t, err, "%+v", err)
  19. assert.Equal(t, typ, bin[0])
  20. // make sure this is compatible with current (Bytes()) encoding
  21. assert.Equal(t, in.Bytes(), bin)
  22. // make sure we have the expected length
  23. assert.Equal(t, size, len(bin))
  24. err = data.FromWire(bin, reader)
  25. require.Nil(t, err, "%+v", err)
  26. }
  27. // go to json encoding and back
  28. func checkJSON(t *testing.T, in interface{}, reader interface{}, typ string) {
  29. // test to and from binary
  30. js, err := data.ToJSON(in)
  31. require.Nil(t, err, "%+v", err)
  32. styp := `"` + typ + `"`
  33. assert.True(t, strings.Contains(string(js), styp))
  34. err = data.FromJSON(js, reader)
  35. require.Nil(t, err, "%+v", err)
  36. // also check text format
  37. text, err := data.ToText(in)
  38. require.Nil(t, err, "%+v", err)
  39. parts := strings.Split(text, ":")
  40. require.Equal(t, 2, len(parts))
  41. // make sure the first part is the typ string
  42. assert.Equal(t, typ, parts[0])
  43. // and the data is also present in the json
  44. assert.True(t, strings.Contains(string(js), parts[1]))
  45. }
  46. // make sure go-wire json can still figure this out...
  47. func checkWireJSON(t *testing.T, in interface{}, reader interface{}, typ byte) {
  48. // test to and from binary
  49. var err error
  50. js := wire.JSONBytes(in)
  51. btyp := fmt.Sprintf("[%d,", typ)
  52. assert.True(t, strings.HasPrefix(string(js), btyp), string(js), btyp)
  53. wire.ReadJSON(reader, js, &err)
  54. require.Nil(t, err, "%+v", err)
  55. }
  56. func TestKeyEncodings(t *testing.T) {
  57. cases := []struct {
  58. privKey PrivKey
  59. keyType byte
  60. keyName string
  61. // 1 (type byte) + size of byte array
  62. privSize, pubSize int
  63. }{
  64. {
  65. privKey: GenPrivKeyEd25519().Wrap(),
  66. keyType: TypeEd25519,
  67. keyName: NameEd25519,
  68. privSize: 65,
  69. pubSize: 33,
  70. },
  71. {
  72. privKey: GenPrivKeySecp256k1().Wrap(),
  73. keyType: TypeSecp256k1,
  74. keyName: NameSecp256k1,
  75. privSize: 33,
  76. pubSize: 34,
  77. },
  78. }
  79. for _, tc := range cases {
  80. // check (de/en)codings of private key
  81. var priv2, priv3, priv4 PrivKey
  82. checkWire(t, tc.privKey, &priv2, tc.keyType, tc.privSize)
  83. assert.EqualValues(t, tc.privKey, priv2)
  84. checkJSON(t, tc.privKey, &priv3, tc.keyName)
  85. assert.EqualValues(t, tc.privKey, priv3)
  86. checkWireJSON(t, tc.privKey, &priv4, tc.keyType)
  87. assert.EqualValues(t, tc.privKey, priv4)
  88. // check (de/en)codings of public key
  89. pubKey := tc.privKey.PubKey()
  90. var pub2, pub3, pub4 PubKey
  91. checkWire(t, pubKey, &pub2, tc.keyType, tc.pubSize)
  92. assert.EqualValues(t, pubKey, pub2)
  93. checkJSON(t, pubKey, &pub3, tc.keyName)
  94. assert.EqualValues(t, pubKey, pub3)
  95. checkWireJSON(t, pubKey, &pub4, tc.keyType)
  96. assert.EqualValues(t, pubKey, pub4)
  97. }
  98. }
  99. func toFromJSON(t *testing.T, in interface{}, recvr interface{}) {
  100. js, err := data.ToJSON(in)
  101. require.Nil(t, err, "%+v", err)
  102. err = data.FromJSON(js, recvr)
  103. require.Nil(t, err, "%+v", err)
  104. }
  105. func TestNilEncodings(t *testing.T) {
  106. // make sure sigs are okay with nil
  107. var a, b Signature
  108. toFromJSON(t, a, &b)
  109. assert.EqualValues(t, a, b)
  110. // make sure sigs are okay with nil
  111. var c, d PubKey
  112. toFromJSON(t, c, &d)
  113. assert.EqualValues(t, c, d)
  114. // make sure sigs are okay with nil
  115. var e, f PrivKey
  116. toFromJSON(t, e, &f)
  117. assert.EqualValues(t, e, f)
  118. }
  119. type SigMessage struct {
  120. Key PubKey
  121. Sig Signature
  122. }
  123. func (s SigMessage) Bytes() []byte {
  124. return wire.BinaryBytes(s)
  125. }
  126. func TestEmbededWireEncodings(t *testing.T) {
  127. assert := assert.New(t)
  128. cases := []struct {
  129. privKey PrivKey
  130. keyType byte
  131. keyName string
  132. size int // pub + sig size
  133. }{
  134. {
  135. privKey: GenPrivKeyEd25519().Wrap(),
  136. keyType: TypeEd25519,
  137. keyName: NameEd25519,
  138. size: 2 + 32 + 64,
  139. },
  140. // {
  141. // privKey: GenPrivKeySecp256k1().Wrap(),
  142. // keyType: TypeSecp256k1,
  143. // keyName: NameSecp256k1,
  144. // size: 2 + 33 + 72, // ugh, either 72 or 73 depending....
  145. // },
  146. }
  147. payload := randBytes(20)
  148. for i, tc := range cases {
  149. pubKey := tc.privKey.PubKey()
  150. sig := tc.privKey.Sign(payload)
  151. assert.True(pubKey.VerifyBytes(payload, sig), "%d", i)
  152. msg := SigMessage{
  153. Key: pubKey,
  154. Sig: sig,
  155. }
  156. var msg2 SigMessage
  157. checkWire(t, msg, &msg2, tc.keyType, tc.size)
  158. }
  159. }