|
|
@ -1,224 +0,0 @@ |
|
|
|
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.PubKeyName, true}, |
|
|
|
{sr25519.PubKey{}, sr25519.PubKeyName, true}, |
|
|
|
{secp256k1.PubKey{}, secp256k1.PubKeyName, 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.PubKeyName |
|
|
|
nameTable[reflect.TypeOf(sr25519.PubKey{})] = sr25519.PubKeyName |
|
|
|
nameTable[reflect.TypeOf(secp256k1.PubKey{})] = secp256k1.PubKeyName |
|
|
|
} |