github.com/Finschia/finschia-sdk@v0.48.1/crypto/keys/ed25519/ed25519_test.go (about)

     1  package ed25519_test
     2  
     3  import (
     4  	stded25519 "crypto/ed25519"
     5  	"encoding/base64"
     6  	"testing"
     7  
     8  	"github.com/Finschia/ostracon/crypto"
     9  	osted25519 "github.com/Finschia/ostracon/crypto/ed25519"
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  
    13  	"github.com/Finschia/finschia-sdk/codec"
    14  	"github.com/Finschia/finschia-sdk/codec/types"
    15  	cryptocodec "github.com/Finschia/finschia-sdk/crypto/codec"
    16  	ed25519 "github.com/Finschia/finschia-sdk/crypto/keys/ed25519"
    17  	"github.com/Finschia/finschia-sdk/crypto/keys/secp256k1"
    18  	cryptotypes "github.com/Finschia/finschia-sdk/crypto/types"
    19  )
    20  
    21  func TestSignAndValidateEd25519(t *testing.T) {
    22  	privKey := ed25519.GenPrivKey()
    23  	pubKey := privKey.PubKey()
    24  
    25  	msg := crypto.CRandBytes(1000)
    26  	sig, err := privKey.Sign(msg)
    27  	require.Nil(t, err)
    28  
    29  	// Test the signature
    30  	assert.True(t, pubKey.VerifySignature(msg, sig))
    31  
    32  	// ----
    33  	// Test cross packages verification
    34  	stdPrivKey := stded25519.PrivateKey(privKey.Key)
    35  	stdPubKey := stdPrivKey.Public().(stded25519.PublicKey)
    36  
    37  	assert.Equal(t, stdPubKey, pubKey.(*ed25519.PubKey).Key)
    38  	assert.Equal(t, stdPrivKey, privKey.Key)
    39  	assert.True(t, stded25519.Verify(stdPubKey, msg, sig))
    40  	sig2 := stded25519.Sign(stdPrivKey, msg)
    41  	assert.True(t, pubKey.VerifySignature(msg, sig2))
    42  
    43  	// ----
    44  	// Mutate the signature, just one bit.
    45  	// TODO: Replace this with a much better fuzzer, tendermint/ed25519/issues/10
    46  	sig[7] ^= byte(0x01)
    47  	assert.False(t, pubKey.VerifySignature(msg, sig))
    48  }
    49  
    50  func TestPubKeyEquals(t *testing.T) {
    51  	ed25519PubKey := ed25519.GenPrivKey().PubKey().(*ed25519.PubKey)
    52  
    53  	testCases := []struct {
    54  		msg      string
    55  		pubKey   cryptotypes.PubKey
    56  		other    cryptotypes.PubKey
    57  		expectEq bool
    58  	}{
    59  		{
    60  			"different bytes",
    61  			ed25519PubKey,
    62  			ed25519.GenPrivKey().PubKey(),
    63  			false,
    64  		},
    65  		{
    66  			"equals",
    67  			ed25519PubKey,
    68  			&ed25519.PubKey{
    69  				Key: ed25519PubKey.Key,
    70  			},
    71  			true,
    72  		},
    73  		{
    74  			"different types",
    75  			ed25519PubKey,
    76  			secp256k1.GenPrivKey().PubKey(),
    77  			false,
    78  		},
    79  	}
    80  
    81  	for _, tc := range testCases {
    82  		t.Run(tc.msg, func(t *testing.T) {
    83  			eq := tc.pubKey.Equals(tc.other)
    84  			require.Equal(t, eq, tc.expectEq)
    85  		})
    86  	}
    87  }
    88  
    89  func TestAddressEd25519(t *testing.T) {
    90  	pk := ed25519.PubKey{[]byte{125, 80, 29, 208, 159, 53, 119, 198, 73, 53, 187, 33, 199, 144, 62, 255, 1, 235, 117, 96, 128, 211, 17, 45, 34, 64, 189, 165, 33, 182, 54, 206}}
    91  	addr := pk.Address()
    92  	require.Len(t, addr, 20, "Address must be 20 bytes long")
    93  }
    94  
    95  func TestPrivKeyEquals(t *testing.T) {
    96  	ed25519PrivKey := ed25519.GenPrivKey()
    97  
    98  	testCases := []struct {
    99  		msg      string
   100  		privKey  cryptotypes.PrivKey
   101  		other    cryptotypes.PrivKey
   102  		expectEq bool
   103  	}{
   104  		{
   105  			"different bytes",
   106  			ed25519PrivKey,
   107  			ed25519.GenPrivKey(),
   108  			false,
   109  		},
   110  		{
   111  			"equals",
   112  			ed25519PrivKey,
   113  			&ed25519.PrivKey{
   114  				Key: ed25519PrivKey.Key,
   115  			},
   116  			true,
   117  		},
   118  		{
   119  			"different types",
   120  			ed25519PrivKey,
   121  			secp256k1.GenPrivKey(),
   122  			false,
   123  		},
   124  	}
   125  
   126  	for _, tc := range testCases {
   127  		t.Run(tc.msg, func(t *testing.T) {
   128  			eq := tc.privKey.Equals(tc.other)
   129  			require.Equal(t, eq, tc.expectEq)
   130  		})
   131  	}
   132  }
   133  
   134  func TestMarshalAmino(t *testing.T) {
   135  	aminoCdc := codec.NewLegacyAmino()
   136  	privKey := ed25519.GenPrivKey()
   137  	pubKey := privKey.PubKey().(*ed25519.PubKey)
   138  
   139  	testCases := []struct {
   140  		desc      string
   141  		msg       codec.AminoMarshaler
   142  		typ       interface{}
   143  		expBinary []byte
   144  		expJSON   string
   145  	}{
   146  		{
   147  			"ed25519 private key",
   148  			privKey,
   149  			&ed25519.PrivKey{},
   150  			append([]byte{64}, privKey.Bytes()...), // Length-prefixed.
   151  			"\"" + base64.StdEncoding.EncodeToString(privKey.Bytes()) + "\"",
   152  		},
   153  		{
   154  			"ed25519 public key",
   155  			pubKey,
   156  			&ed25519.PubKey{},
   157  			append([]byte{32}, pubKey.Bytes()...), // Length-prefixed.
   158  			"\"" + base64.StdEncoding.EncodeToString(pubKey.Bytes()) + "\"",
   159  		},
   160  	}
   161  
   162  	for _, tc := range testCases {
   163  		t.Run(tc.desc, func(t *testing.T) {
   164  			// Do a round trip of encoding/decoding binary.
   165  			bz, err := aminoCdc.Marshal(tc.msg)
   166  			require.NoError(t, err)
   167  			require.Equal(t, tc.expBinary, bz)
   168  
   169  			err = aminoCdc.Unmarshal(bz, tc.typ)
   170  			require.NoError(t, err)
   171  
   172  			require.Equal(t, tc.msg, tc.typ)
   173  
   174  			// Do a round trip of encoding/decoding JSON.
   175  			bz, err = aminoCdc.MarshalJSON(tc.msg)
   176  			require.NoError(t, err)
   177  			require.Equal(t, tc.expJSON, string(bz))
   178  
   179  			err = aminoCdc.UnmarshalJSON(bz, tc.typ)
   180  			require.NoError(t, err)
   181  
   182  			require.Equal(t, tc.msg, tc.typ)
   183  		})
   184  	}
   185  }
   186  
   187  func TestMarshalAmino_BackwardsCompatibility(t *testing.T) {
   188  	aminoCdc := codec.NewLegacyAmino()
   189  	// Create Tendermint keys.
   190  	tmPrivKey := osted25519.GenPrivKey()
   191  	tmPubKey := tmPrivKey.PubKey()
   192  	// Create our own keys, with the same private key as Tendermint's.
   193  	privKey := &ed25519.PrivKey{Key: []byte(tmPrivKey)}
   194  	pubKey := privKey.PubKey().(*ed25519.PubKey)
   195  
   196  	testCases := []struct {
   197  		desc      string
   198  		tmKey     interface{}
   199  		ourKey    interface{}
   200  		marshalFn func(o interface{}) ([]byte, error)
   201  	}{
   202  		{
   203  			"ed25519 private key, binary",
   204  			tmPrivKey,
   205  			privKey,
   206  			aminoCdc.Marshal,
   207  		},
   208  		{
   209  			"ed25519 private key, JSON",
   210  			tmPrivKey,
   211  			privKey,
   212  			aminoCdc.MarshalJSON,
   213  		},
   214  		{
   215  			"ed25519 public key, binary",
   216  			tmPubKey,
   217  			pubKey,
   218  			aminoCdc.Marshal,
   219  		},
   220  		{
   221  			"ed25519 public key, JSON",
   222  			tmPubKey,
   223  			pubKey,
   224  			aminoCdc.MarshalJSON,
   225  		},
   226  	}
   227  
   228  	for _, tc := range testCases {
   229  		t.Run(tc.desc, func(t *testing.T) {
   230  			// Make sure Amino encoding override is not breaking backwards compatibility.
   231  			bz1, err := tc.marshalFn(tc.tmKey)
   232  			require.NoError(t, err)
   233  			bz2, err := tc.marshalFn(tc.ourKey)
   234  			require.NoError(t, err)
   235  			require.Equal(t, bz1, bz2)
   236  		})
   237  	}
   238  }
   239  
   240  func TestMarshalJSON(t *testing.T) {
   241  	require := require.New(t)
   242  	privKey := ed25519.GenPrivKey()
   243  	pk := privKey.PubKey()
   244  
   245  	registry := types.NewInterfaceRegistry()
   246  	cryptocodec.RegisterInterfaces(registry)
   247  	cdc := codec.NewProtoCodec(registry)
   248  
   249  	bz, err := cdc.MarshalInterfaceJSON(pk)
   250  	require.NoError(err)
   251  
   252  	var pk2 cryptotypes.PubKey
   253  	err = cdc.UnmarshalInterfaceJSON(bz, &pk2)
   254  	require.NoError(err)
   255  	require.True(pk2.Equals(pk))
   256  }