|
@ -1,185 +1,95 @@ |
|
|
package crypto |
|
|
package crypto |
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
XXX Needs to be refactored to not use go-amino/data |
|
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
import ( |
|
|
"fmt" |
|
|
|
|
|
"strings" |
|
|
|
|
|
"testing" |
|
|
"testing" |
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert" |
|
|
"github.com/stretchr/testify/assert" |
|
|
"github.com/stretchr/testify/require" |
|
|
"github.com/stretchr/testify/require" |
|
|
amino "github.com/tendermint/go-amino" |
|
|
|
|
|
data "github.com/tendermint/go-amino/data" |
|
|
|
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
type byter interface { |
|
|
type byter interface { |
|
|
Bytes() []byte |
|
|
Bytes() []byte |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// go to amino encoding and back
|
|
|
|
|
|
func checkWire(t *testing.T, in byter, reader interface{}, typ byte, size int) { |
|
|
|
|
|
// test to and from binary
|
|
|
|
|
|
bin, err := data.ToWire(in) |
|
|
|
|
|
|
|
|
func checkAminoBinary(t *testing.T, src byter, dst interface{}, size int) { |
|
|
|
|
|
// Marshal to binary bytes.
|
|
|
|
|
|
bz, err := cdc.MarshalBinaryBare(src) |
|
|
require.Nil(t, err, "%+v", err) |
|
|
require.Nil(t, err, "%+v", err) |
|
|
assert.Equal(t, typ, bin[0]) |
|
|
|
|
|
// make sure this is compatible with current (Bytes()) encoding
|
|
|
|
|
|
assert.Equal(t, in.Bytes(), bin) |
|
|
|
|
|
// make sure we have the expected length
|
|
|
|
|
|
assert.Equal(t, size, len(bin)) |
|
|
|
|
|
|
|
|
|
|
|
err = data.FromWire(bin, reader) |
|
|
|
|
|
|
|
|
// Make sure this is compatible with current (Bytes()) encoding.
|
|
|
|
|
|
assert.Equal(t, src.Bytes(), 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) |
|
|
require.Nil(t, err, "%+v", err) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// go to json encoding and back
|
|
|
|
|
|
func checkJSON(t *testing.T, in interface{}, reader interface{}, typ string) { |
|
|
|
|
|
// test to and from binary
|
|
|
|
|
|
js, err := data.ToJSON(in) |
|
|
|
|
|
require.Nil(t, err, "%+v", err) |
|
|
|
|
|
styp := `"` + typ + `"` |
|
|
|
|
|
assert.True(t, strings.Contains(string(js), styp)) |
|
|
|
|
|
|
|
|
|
|
|
err = data.FromJSON(js, reader) |
|
|
|
|
|
|
|
|
func checkAminoJSON(t *testing.T, src interface{}, dst interface{}, isNil bool) { |
|
|
|
|
|
// Marshal to JSON bytes.
|
|
|
|
|
|
js, err := cdc.MarshalJSON(src) |
|
|
require.Nil(t, err, "%+v", err) |
|
|
require.Nil(t, err, "%+v", err) |
|
|
|
|
|
|
|
|
// also check text format
|
|
|
|
|
|
text, err := data.ToText(in) |
|
|
|
|
|
require.Nil(t, err, "%+v", err) |
|
|
|
|
|
parts := strings.Split(text, ":") |
|
|
|
|
|
require.Equal(t, 2, len(parts)) |
|
|
|
|
|
// make sure the first part is the typ string
|
|
|
|
|
|
assert.Equal(t, typ, parts[0]) |
|
|
|
|
|
// and the data is also present in the json
|
|
|
|
|
|
assert.True(t, strings.Contains(string(js), parts[1])) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// make sure go-amino json can still figure this out...
|
|
|
|
|
|
func checkWireJSON(t *testing.T, in interface{}, reader interface{}, typ byte) { |
|
|
|
|
|
// test to and from binary
|
|
|
|
|
|
var err error |
|
|
|
|
|
js := amino.JSONBytes(in) |
|
|
|
|
|
btyp := fmt.Sprintf("[%d,", typ) |
|
|
|
|
|
assert.True(t, strings.HasPrefix(string(js), btyp), string(js), btyp) |
|
|
|
|
|
|
|
|
|
|
|
amino.ReadJSON(reader, js, &err) |
|
|
|
|
|
|
|
|
if isNil { |
|
|
|
|
|
assert.Equal(t, string(js), `null`) |
|
|
|
|
|
} else { |
|
|
|
|
|
assert.Contains(t, string(js), `"type":`) |
|
|
|
|
|
assert.Contains(t, string(js), `"value":`) |
|
|
|
|
|
} |
|
|
|
|
|
// Unmarshal.
|
|
|
|
|
|
err = cdc.UnmarshalJSON(js, dst) |
|
|
require.Nil(t, err, "%+v", err) |
|
|
require.Nil(t, err, "%+v", err) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func TestKeyEncodings(t *testing.T) { |
|
|
func TestKeyEncodings(t *testing.T) { |
|
|
cases := []struct { |
|
|
cases := []struct { |
|
|
privKey PrivKey |
|
|
privKey PrivKey |
|
|
keyType byte |
|
|
|
|
|
keyName string |
|
|
|
|
|
// 1 (type byte) + size of byte array
|
|
|
// 1 (type byte) + size of byte array
|
|
|
privSize, pubSize int |
|
|
privSize, pubSize int |
|
|
}{ |
|
|
}{ |
|
|
{ |
|
|
{ |
|
|
privKey: GenPrivKeyEd25519().Wrap(), |
|
|
|
|
|
keyType: TypeEd25519, |
|
|
|
|
|
keyName: NameEd25519, |
|
|
|
|
|
privSize: 65, |
|
|
|
|
|
pubSize: 33, |
|
|
|
|
|
|
|
|
privKey: GenPrivKeyEd25519(), |
|
|
|
|
|
privSize: 69, |
|
|
|
|
|
pubSize: 37, |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
privKey: GenPrivKeySecp256k1().Wrap(), |
|
|
|
|
|
keyType: TypeSecp256k1, |
|
|
|
|
|
keyName: NameSecp256k1, |
|
|
|
|
|
privSize: 33, |
|
|
|
|
|
pubSize: 34, |
|
|
|
|
|
|
|
|
privKey: GenPrivKeySecp256k1(), |
|
|
|
|
|
privSize: 37, |
|
|
|
|
|
pubSize: 38, |
|
|
}, |
|
|
}, |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
for _, tc := range cases { |
|
|
for _, tc := range cases { |
|
|
// check (de/en)codings of private key
|
|
|
|
|
|
var priv2, priv3, priv4 PrivKey |
|
|
|
|
|
checkWire(t, tc.privKey, &priv2, tc.keyType, tc.privSize) |
|
|
|
|
|
|
|
|
// Check (de/en)codings of PrivKeys.
|
|
|
|
|
|
var priv2, priv3 PrivKey |
|
|
|
|
|
checkAminoBinary(t, tc.privKey, &priv2, tc.privSize) |
|
|
assert.EqualValues(t, tc.privKey, priv2) |
|
|
assert.EqualValues(t, tc.privKey, priv2) |
|
|
checkJSON(t, tc.privKey, &priv3, tc.keyName) |
|
|
|
|
|
|
|
|
checkAminoJSON(t, tc.privKey, &priv3, false) // TODO also check Prefix bytes.
|
|
|
assert.EqualValues(t, tc.privKey, priv3) |
|
|
assert.EqualValues(t, tc.privKey, priv3) |
|
|
checkWireJSON(t, tc.privKey, &priv4, tc.keyType) |
|
|
|
|
|
assert.EqualValues(t, tc.privKey, priv4) |
|
|
|
|
|
|
|
|
|
|
|
// check (de/en)codings of public key
|
|
|
|
|
|
|
|
|
// Check (de/en)codings of PubKeys.
|
|
|
pubKey := tc.privKey.PubKey() |
|
|
pubKey := tc.privKey.PubKey() |
|
|
var pub2, pub3, pub4 PubKey |
|
|
|
|
|
checkWire(t, pubKey, &pub2, tc.keyType, tc.pubSize) |
|
|
|
|
|
|
|
|
var pub2, pub3 PubKey |
|
|
|
|
|
checkAminoBinary(t, pubKey, &pub2, tc.pubSize) |
|
|
assert.EqualValues(t, pubKey, pub2) |
|
|
assert.EqualValues(t, pubKey, pub2) |
|
|
checkJSON(t, pubKey, &pub3, tc.keyName) |
|
|
|
|
|
|
|
|
checkAminoJSON(t, pubKey, &pub3, false) // TODO also check Prefix bytes.
|
|
|
assert.EqualValues(t, pubKey, pub3) |
|
|
assert.EqualValues(t, pubKey, pub3) |
|
|
checkWireJSON(t, pubKey, &pub4, tc.keyType) |
|
|
|
|
|
assert.EqualValues(t, pubKey, pub4) |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func toFromJSON(t *testing.T, in interface{}, recvr interface{}) { |
|
|
|
|
|
js, err := data.ToJSON(in) |
|
|
|
|
|
require.Nil(t, err, "%+v", err) |
|
|
|
|
|
err = data.FromJSON(js, recvr) |
|
|
|
|
|
require.Nil(t, err, "%+v", err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestNilEncodings(t *testing.T) { |
|
|
func TestNilEncodings(t *testing.T) { |
|
|
// make sure sigs are okay with nil
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check nil Signature.
|
|
|
var a, b Signature |
|
|
var a, b Signature |
|
|
toFromJSON(t, a, &b) |
|
|
|
|
|
|
|
|
checkAminoJSON(t, &a, &b, true) |
|
|
assert.EqualValues(t, a, b) |
|
|
assert.EqualValues(t, a, b) |
|
|
|
|
|
|
|
|
// make sure sigs are okay with nil
|
|
|
|
|
|
|
|
|
// Check nil PubKey.
|
|
|
var c, d PubKey |
|
|
var c, d PubKey |
|
|
toFromJSON(t, c, &d) |
|
|
|
|
|
|
|
|
checkAminoJSON(t, &c, &d, true) |
|
|
assert.EqualValues(t, c, d) |
|
|
assert.EqualValues(t, c, d) |
|
|
|
|
|
|
|
|
// make sure sigs are okay with nil
|
|
|
|
|
|
|
|
|
// Check nil PrivKey.
|
|
|
var e, f PrivKey |
|
|
var e, f PrivKey |
|
|
toFromJSON(t, e, &f) |
|
|
|
|
|
|
|
|
checkAminoJSON(t, &e, &f, true) |
|
|
assert.EqualValues(t, e, f) |
|
|
assert.EqualValues(t, e, f) |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
type SigMessage struct { |
|
|
|
|
|
Key PubKey |
|
|
|
|
|
Sig Signature |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (s SigMessage) Bytes() []byte { |
|
|
|
|
|
return amino.BinaryBytes(s) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestEmbededWireEncodings(t *testing.T) { |
|
|
|
|
|
cases := []struct { |
|
|
|
|
|
privKey PrivKey |
|
|
|
|
|
keyType byte |
|
|
|
|
|
keyName string |
|
|
|
|
|
size int // pub + sig size
|
|
|
|
|
|
}{ |
|
|
|
|
|
{ |
|
|
|
|
|
privKey: GenPrivKeyEd25519().Wrap(), |
|
|
|
|
|
keyType: TypeEd25519, |
|
|
|
|
|
keyName: NameEd25519, |
|
|
|
|
|
size: 2 + 32 + 64, |
|
|
|
|
|
}, |
|
|
|
|
|
// {
|
|
|
|
|
|
// privKey: GenPrivKeySecp256k1().Wrap(),
|
|
|
|
|
|
// keyType: TypeSecp256k1,
|
|
|
|
|
|
// keyName: NameSecp256k1,
|
|
|
|
|
|
// size: 2 + 33 + 72, // ugh, either 72 or 73 depending....
|
|
|
|
|
|
// },
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
payload := randBytes(20) |
|
|
|
|
|
for i, tc := range cases { |
|
|
|
|
|
pubKey := tc.privKey.PubKey() |
|
|
|
|
|
sig := tc.privKey.Sign(payload) |
|
|
|
|
|
assert.True(t, pubKey.VerifyBytes(payload, sig), "%d", i) |
|
|
|
|
|
|
|
|
|
|
|
msg := SigMessage{ |
|
|
|
|
|
Key: pubKey, |
|
|
|
|
|
Sig: sig, |
|
|
|
|
|
} |
|
|
|
|
|
var msg2 SigMessage |
|
|
|
|
|
checkWire(t, msg, &msg2, tc.keyType, tc.size) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
*/ |
|
|
|