- package cryptoamino
-
- import (
- "reflect"
- "testing"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-
- amino "github.com/tendermint/go-amino"
-
- "github.com/tendermint/tendermint/crypto"
- "github.com/tendermint/tendermint/crypto/ed25519"
- "github.com/tendermint/tendermint/crypto/secp256k1"
- "github.com/tendermint/tendermint/crypto/sr25519"
- tmjson "github.com/tendermint/tendermint/libs/json"
- )
-
- type AminoMarshal interface {
- AminoMarshal() ([]byte, error)
- AminoUnmarshal([]byte) error
- }
-
- func checkAminoBinary(t *testing.T, src, dst interface{}, size int) {
- // Marshal to binary bytes.
- bz, err := cdc.MarshalBinaryBare(src)
- require.Nil(t, err, "%+v", err)
- if byterSrc, ok := src.(AminoMarshal); ok {
- // Make sure this is compatible with current (Bytes()) encoding.
- bza, err := byterSrc.AminoMarshal()
- assert.NoError(t, err)
- assert.Equal(t, bza, bz, "Amino binary vs Bytes() mismatch")
- }
- // Make sure we have the expected length.
- assert.Equal(t, size, len(bz), "Amino binary size mismatch")
-
- // Unmarshal.
- err = cdc.UnmarshalBinaryBare(bz, dst)
- require.Nil(t, err, "%+v", err)
- }
-
- func checkJSON(t *testing.T, src interface{}, dst interface{}, isNil bool) {
- // Marshal to JSON bytes.
- js, err := tmjson.Marshal(src)
- require.Nil(t, err, "%+v", err)
- if isNil {
- assert.Equal(t, string(js), `null`)
- } else {
- assert.Contains(t, string(js), `"type":`)
- assert.Contains(t, string(js), `"value":`)
- }
- // Unmarshal.
- err = tmjson.Unmarshal(js, dst)
- require.Nil(t, err, "%+v", err)
- }
-
- func TestKeyEncodings(t *testing.T) {
- cases := []struct {
- privKey crypto.PrivKey
- privSize, pubSize, sigSize int // binary sizes
- }{
- {
- privKey: ed25519.GenPrivKey(),
- privSize: 69,
- pubSize: 37,
- sigSize: 65,
- },
- {
- privKey: sr25519.GenPrivKey(),
- privSize: 37,
- pubSize: 37,
- sigSize: 65,
- },
- {
- privKey: secp256k1.GenPrivKey(),
- privSize: 37,
- pubSize: 38,
- sigSize: 65,
- },
- }
-
- for tcIndex, tc := range cases {
-
- // Check (de/en)codings of PrivKeys.
- var priv2, priv3 crypto.PrivKey
- checkAminoBinary(t, tc.privKey, &priv2, tc.privSize)
- assert.EqualValues(t, tc.privKey, priv2, "tc #%d", tcIndex)
- checkJSON(t, tc.privKey, &priv3, false) // TODO also check Prefix bytes.
- assert.EqualValues(t, tc.privKey, priv3, "tc #%d", tcIndex)
-
- // Check (de/en)codings of Signatures.
- var sig1, sig2 []byte
- sig1, err := tc.privKey.Sign([]byte("something"))
- assert.NoError(t, err, "tc #%d", tcIndex)
- checkAminoBinary(t, sig1, &sig2, tc.sigSize)
- assert.EqualValues(t, sig1, sig2, "tc #%d", tcIndex)
-
- // Check (de/en)codings of PubKeys.
- pubKey := tc.privKey.PubKey()
- var pub2, pub3 crypto.PubKey
- checkAminoBinary(t, pubKey, &pub2, tc.pubSize)
- assert.EqualValues(t, pubKey, pub2, "tc #%d", tcIndex)
- checkJSON(t, pubKey, &pub3, false) // TODO also check Prefix bytes.
- assert.EqualValues(t, pubKey, pub3, "tc #%d", tcIndex)
- }
- }
-
- func TestNilEncodings(t *testing.T) {
-
- // Check nil Signature.
- var a, b []byte
- checkJSON(t, &a, &b, true)
- assert.EqualValues(t, a, b)
-
- // Check nil PubKey.
- var c, d crypto.PubKey
- checkJSON(t, &c, &d, true)
- assert.EqualValues(t, c, d)
-
- // Check nil PrivKey.
- var e, f crypto.PrivKey
- checkJSON(t, &e, &f, true)
- assert.EqualValues(t, e, f)
- }
-
- func TestPubKeyInvalidDataProperReturnsEmpty(t *testing.T) {
- pk, err := PubKeyFromBytes([]byte("foo"))
- require.NotNil(t, err)
- require.Nil(t, pk)
- }
-
- func TestPubkeyAminoName(t *testing.T) {
- tests := []struct {
- key crypto.PubKey
- want string
- found bool
- }{
- {ed25519.PubKey{}, ed25519.PubKeyAminoName, true},
- {sr25519.PubKey{}, sr25519.PubKeyAminoName, true},
- {secp256k1.PubKey{}, secp256k1.PubKeyAminoName, true},
- }
- for i, tc := range tests {
- got, found := PubkeyAminoName(cdc, tc.key)
- require.Equal(t, tc.found, found, "not equal on tc %d", i)
- if tc.found {
- require.Equal(t, tc.want, got, "not equal on tc %d", i)
- }
- }
- }
-
- var _ crypto.PrivKey = testPriv{}
- var _ crypto.PubKey = testPub{}
- var testCdc = amino.NewCodec()
-
- type testPriv []byte
-
- func (privkey testPriv) PubKey() crypto.PubKey { return testPub{} }
- func (privkey testPriv) Bytes() []byte {
- return testCdc.MustMarshalBinaryBare(privkey)
- }
- func (privkey testPriv) Sign(msg []byte) ([]byte, error) { return []byte{}, nil }
- func (privkey testPriv) Equals(other crypto.PrivKey) bool { return true }
- func (privkey testPriv) Type() string { return "testPriv" }
-
- type testPub []byte
-
- func (key testPub) Address() crypto.Address { return crypto.Address{} }
- func (key testPub) Bytes() []byte {
- return testCdc.MustMarshalBinaryBare(key)
- }
- func (key testPub) VerifyBytes(msg []byte, sig []byte) bool { return true }
- func (key testPub) Equals(other crypto.PubKey) bool { return true }
- func (key testPub) String() string { return "" }
- func (key testPub) Type() string { return "testPub" }
-
- var (
- privAminoName = "registerTest/Priv"
- pubAminoName = "registerTest/Pub"
- )
-
- func TestRegisterKeyType(t *testing.T) {
- RegisterAmino(testCdc)
- testCdc.RegisterConcrete(testPriv{}, privAminoName, nil)
- testCdc.RegisterConcrete(testPub{}, pubAminoName, nil)
-
- pub := testPub{0x1}
- priv := testPriv{0x2}
-
- // Check to make sure key cannot be decoded before registering
- _, err := PrivKeyFromBytes(priv.Bytes())
- require.Error(t, err)
- _, err = PubKeyFromBytes(pub.Bytes())
- require.Error(t, err)
-
- // Check that name is not registered
- _, found := PubkeyAminoName(testCdc, pub)
- require.False(t, found)
-
- // Register key types
- RegisterKeyType(testPriv{}, privAminoName)
- RegisterKeyType(testPub{}, pubAminoName)
-
- // Name should exist after registering
- name, found := PubkeyAminoName(testCdc, pub)
- require.True(t, found)
- require.Equal(t, name, pubAminoName)
-
- // Decode keys using the encoded bytes from encoding with the other codec
- decodedPriv, err := PrivKeyFromBytes(priv.Bytes())
- require.NoError(t, err)
- require.Equal(t, priv, decodedPriv)
-
- decodedPub, err := PubKeyFromBytes(pub.Bytes())
- require.NoError(t, err)
- require.Equal(t, pub, decodedPub)
-
- // Reset module codec after testing
- cdc = amino.NewCodec()
- nameTable = make(map[reflect.Type]string, 3)
- RegisterAmino(cdc)
- nameTable[reflect.TypeOf(ed25519.PubKey{})] = ed25519.PubKeyAminoName
- nameTable[reflect.TypeOf(sr25519.PubKey{})] = sr25519.PubKeyAminoName
- nameTable[reflect.TypeOf(secp256k1.PubKey{})] = secp256k1.PubKeyAminoName
- }
|