github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/app/crypto/hd/algorithm_test.go (about)

     1  package hd
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/require"
     8  
     9  	"github.com/ethereum/go-ethereum/common"
    10  	ethcrypto "github.com/ethereum/go-ethereum/crypto"
    11  
    12  	hdwallet "github.com/miguelmota/go-ethereum-hdwallet"
    13  
    14  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/crypto/keys"
    15  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/crypto/keys/hd"
    16  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/tests"
    17  
    18  	"github.com/fibonacci-chain/fbc/app/crypto/ethsecp256k1"
    19  	ethermint "github.com/fibonacci-chain/fbc/app/types"
    20  )
    21  
    22  func TestEthermintKeygenFunc(t *testing.T) {
    23  	privkey, err := ethsecp256k1.GenerateKey()
    24  	require.NoError(t, err)
    25  
    26  	testCases := []struct {
    27  		name    string
    28  		privKey []byte
    29  		algo    keys.SigningAlgo
    30  		expPass bool
    31  	}{
    32  		{
    33  			"valid ECDSA privKey",
    34  			ethcrypto.FromECDSA(privkey.ToECDSA()),
    35  			EthSecp256k1,
    36  			true,
    37  		},
    38  		{
    39  			"nil bytes, valid algo",
    40  			nil,
    41  			EthSecp256k1,
    42  			true,
    43  		},
    44  		{
    45  			"empty bytes, valid algo",
    46  			[]byte{},
    47  			EthSecp256k1,
    48  			true,
    49  		},
    50  		{
    51  			"invalid algo",
    52  			nil,
    53  			keys.MultiAlgo,
    54  			false,
    55  		},
    56  	}
    57  
    58  	for _, tc := range testCases {
    59  		privkey, err := EthermintKeygenFunc(tc.privKey, tc.algo)
    60  		if tc.expPass {
    61  			require.NoError(t, err, tc.name)
    62  		} else {
    63  			require.Error(t, err, tc.name)
    64  			require.Nil(t, privkey, tc.name)
    65  		}
    66  	}
    67  }
    68  
    69  func TestKeyring(t *testing.T) {
    70  	dir, cleanup := tests.NewTestCaseDir(t)
    71  	mockIn := strings.NewReader("")
    72  	t.Cleanup(cleanup)
    73  
    74  	kr, err := keys.NewKeyring("ethermint", keys.BackendTest, dir, mockIn, EthSecp256k1Options()...)
    75  	require.NoError(t, err)
    76  
    77  	// fail in retrieving key
    78  	info, err := kr.Get("foo")
    79  	require.Error(t, err)
    80  	require.Nil(t, info)
    81  
    82  	mockIn.Reset("password\npassword\n")
    83  	info, mnemonic, err := kr.CreateMnemonic("foo", keys.English, ethermint.BIP44HDPath, EthSecp256k1, "")
    84  	require.NoError(t, err)
    85  	require.NotEmpty(t, mnemonic)
    86  	require.Equal(t, "foo", info.GetName())
    87  	require.Equal(t, "local", info.GetType().String())
    88  	require.Equal(t, EthSecp256k1, info.GetAlgo())
    89  
    90  	params := *hd.NewFundraiserParams(0, ethermint.Bip44CoinType, 0)
    91  	hdPath := strings.Trim(params.String(), "m/")
    92  
    93  	bz, err := DeriveKey(mnemonic, keys.DefaultBIP39Passphrase, hdPath, keys.Secp256k1)
    94  	require.NoError(t, err)
    95  	require.NotEmpty(t, bz)
    96  
    97  	bz, err = DeriveSecp256k1(mnemonic, keys.DefaultBIP39Passphrase, hdPath)
    98  	require.NoError(t, err)
    99  	require.NotEmpty(t, bz)
   100  
   101  	bz, err = DeriveKey(mnemonic, keys.DefaultBIP39Passphrase, hdPath, keys.SigningAlgo(""))
   102  	require.Error(t, err)
   103  	require.Empty(t, bz)
   104  
   105  	bz, err = DeriveSecp256k1(mnemonic, keys.DefaultBIP39Passphrase, "/wrong/hdPath")
   106  	require.Error(t, err)
   107  	require.Empty(t, bz)
   108  
   109  	bz, err = DeriveKey(mnemonic, keys.DefaultBIP39Passphrase, hdPath, EthSecp256k1)
   110  	require.NoError(t, err)
   111  	require.NotEmpty(t, bz)
   112  
   113  	privkey := ethsecp256k1.PrivKey(bz)
   114  	addr := common.BytesToAddress(privkey.PubKey().Address().Bytes())
   115  
   116  	wallet, err := hdwallet.NewFromMnemonic(mnemonic)
   117  	require.NoError(t, err)
   118  
   119  	path := hdwallet.MustParseDerivationPath(hdPath)
   120  
   121  	account, err := wallet.Derive(path, false)
   122  	require.NoError(t, err)
   123  	require.Equal(t, addr.String(), account.Address.String())
   124  }
   125  
   126  func TestDerivation(t *testing.T) {
   127  	mnemonic := "picnic rent average infant boat squirrel federal assault mercy purity very motor fossil wheel verify upset box fresh horse vivid copy predict square regret"
   128  
   129  	bz, err := DeriveSecp256k1(mnemonic, keys.DefaultBIP39Passphrase, ethermint.BIP44HDPath)
   130  	require.NoError(t, err)
   131  	require.NotEmpty(t, bz)
   132  
   133  	badBz, err := DeriveSecp256k1(mnemonic, keys.DefaultBIP39Passphrase, "44'/60'/0'/0/0")
   134  	require.NoError(t, err)
   135  	require.NotEmpty(t, badBz)
   136  
   137  	require.NotEqual(t, bz, badBz)
   138  
   139  	privkey, err := EthermintKeygenFunc(bz, EthSecp256k1)
   140  	require.NoError(t, err)
   141  	require.NotEmpty(t, privkey)
   142  
   143  	badPrivKey, err := EthermintKeygenFunc(badBz, EthSecp256k1)
   144  	require.NoError(t, err)
   145  	require.NotEmpty(t, badPrivKey)
   146  
   147  	require.NotEqual(t, privkey, badPrivKey)
   148  
   149  	wallet, err := hdwallet.NewFromMnemonic(mnemonic)
   150  	require.NoError(t, err)
   151  
   152  	path := hdwallet.MustParseDerivationPath(ethermint.BIP44HDPath)
   153  	account, err := wallet.Derive(path, false)
   154  	require.NoError(t, err)
   155  
   156  	badPath := hdwallet.MustParseDerivationPath("44'/60'/0'/0/0")
   157  	badAccount, err := wallet.Derive(badPath, false)
   158  	require.NoError(t, err)
   159  
   160  	// Equality of Address BIP44
   161  	require.Equal(t, account.Address.String(), "0xA588C66983a81e800Db4dF74564F09f91c026351")
   162  	require.Equal(t, badAccount.Address.String(), "0xF8D6FDf2B8b488ea37e54903750dcd13F67E71cb")
   163  	// Inequality of wrong derivation path address
   164  	require.NotEqual(t, account.Address.String(), badAccount.Address.String())
   165  	// Equality of Ethermint implementation
   166  	require.Equal(t, common.BytesToAddress(privkey.PubKey().Address().Bytes()).String(), "0xA588C66983a81e800Db4dF74564F09f91c026351")
   167  	require.Equal(t, common.BytesToAddress(badPrivKey.PubKey().Address().Bytes()).String(), "0xF8D6FDf2B8b488ea37e54903750dcd13F67E71cb")
   168  
   169  	// Equality of Eth and Ethermint implementation
   170  	require.Equal(t, common.BytesToAddress(privkey.PubKey().Address()).String(), account.Address.String())
   171  	require.Equal(t, common.BytesToAddress(badPrivKey.PubKey().Address()).String(), badAccount.Address.String())
   172  
   173  	// Inequality of wrong derivation path of Eth and Ethermint implementation
   174  	require.NotEqual(t, common.BytesToAddress(privkey.PubKey().Address()).String(), badAccount.Address.String())
   175  	require.NotEqual(t, common.BytesToAddress(badPrivKey.PubKey().Address()).String(), account.Address.Hex())
   176  }