package sr25519_test
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/tendermint/tendermint/crypto"
|
|
"github.com/tendermint/tendermint/crypto/sr25519"
|
|
)
|
|
|
|
func TestSignAndValidateSr25519(t *testing.T) {
|
|
privKey := sr25519.GenPrivKey()
|
|
pubKey := privKey.PubKey()
|
|
|
|
msg := crypto.CRandBytes(128)
|
|
sig, err := privKey.Sign(msg)
|
|
require.NoError(t, err)
|
|
|
|
// Test the signature
|
|
assert.True(t, pubKey.VerifySignature(msg, sig))
|
|
assert.True(t, pubKey.VerifySignature(msg, sig))
|
|
|
|
// Mutate the signature, just one bit.
|
|
// TODO: Replace this with a much better fuzzer, tendermint/ed25519/issues/10
|
|
sig[7] ^= byte(0x01)
|
|
|
|
assert.False(t, pubKey.VerifySignature(msg, sig))
|
|
}
|
|
|
|
func TestBatchSafe(t *testing.T) {
|
|
v := sr25519.NewBatchVerifier()
|
|
vFail := sr25519.NewBatchVerifier()
|
|
for i := 0; i <= 38; i++ {
|
|
priv := sr25519.GenPrivKey()
|
|
pub := priv.PubKey()
|
|
|
|
var msg []byte
|
|
if i%2 == 0 {
|
|
msg = []byte("easter")
|
|
} else {
|
|
msg = []byte("egg")
|
|
}
|
|
|
|
sig, err := priv.Sign(msg)
|
|
require.NoError(t, err)
|
|
|
|
err = v.Add(pub, msg, sig)
|
|
require.NoError(t, err)
|
|
|
|
switch i % 2 {
|
|
case 0:
|
|
err = vFail.Add(pub, msg, sig)
|
|
case 1:
|
|
msg[2] ^= byte(0x01)
|
|
err = vFail.Add(pub, msg, sig)
|
|
}
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
ok, valid := v.Verify()
|
|
require.True(t, ok, "failed batch verification")
|
|
for i, ok := range valid {
|
|
require.Truef(t, ok, "sig[%d] should be marked valid", i)
|
|
}
|
|
|
|
ok, valid = vFail.Verify()
|
|
require.False(t, ok, "succeeded batch verification (invalid batch)")
|
|
for i, ok := range valid {
|
|
expected := (i % 2) == 0
|
|
require.Equalf(t, expected, ok, "sig[%d] should be %v", i, expected)
|
|
}
|
|
}
|
|
|
|
func TestJSON(t *testing.T) {
|
|
privKey := sr25519.GenPrivKey()
|
|
|
|
t.Run("PrivKey", func(t *testing.T) {
|
|
b, err := json.Marshal(privKey)
|
|
require.NoError(t, err)
|
|
|
|
// b should be the base64 encoded MiniSecretKey, enclosed by doublequotes.
|
|
b64 := base64.StdEncoding.EncodeToString(privKey.Bytes())
|
|
b64 = "\"" + b64 + "\""
|
|
require.Equal(t, []byte(b64), b)
|
|
|
|
var privKey2 sr25519.PrivKey
|
|
err = json.Unmarshal(b, &privKey2)
|
|
require.NoError(t, err)
|
|
require.Len(t, privKey2.Bytes(), sr25519.PrivKeySize)
|
|
require.EqualValues(t, privKey.Bytes(), privKey2.Bytes())
|
|
})
|
|
|
|
// PubKeys are just []byte, so there is no special handling.
|
|
}
|