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 }