github.com/iotexproject/iotex-core@v1.14.1-rc1/ioctl/cmd/hdwallet/hdwallet_test.go (about) 1 // Copyright (c) 2020 IoTeX Foundation 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 package hdwallet 7 8 import ( 9 "encoding/hex" 10 "fmt" 11 "testing" 12 13 ecrypt "github.com/ethereum/go-ethereum/crypto" 14 "github.com/iotexproject/go-pkgs/crypto" 15 "github.com/iotexproject/iotex-core/ioctl/util" 16 hdwallet "github.com/miguelmota/go-ethereum-hdwallet" 17 "github.com/stretchr/testify/require" 18 "github.com/tyler-smith/go-bip39" 19 ) 20 21 func Test_Hdwallet(t *testing.T) { 22 require := require.New(t) 23 24 // simulating 'hdwallet create' here 25 password := "123" 26 27 entropy, _ := bip39.NewEntropy(128) 28 mnemonic, _ := bip39.NewMnemonic(entropy) 29 30 enctxt := append([]byte(mnemonic), util.HashSHA256([]byte(mnemonic))...) 31 enckey := util.HashSHA256([]byte(password)) 32 33 out, err := util.Encrypt(enctxt, enckey) 34 require.NoError(err) 35 36 // simulating 'hdwallet use' here 37 enckey = util.HashSHA256([]byte(password)) 38 39 dectxt, err := util.Decrypt(out, enckey) 40 require.NoError(err) 41 42 dectxtLen := len(dectxt) 43 require.True(dectxtLen > 32) 44 45 mnemonic1, hash := dectxt[:dectxtLen-32], dectxt[dectxtLen-32:] 46 47 require.Equal(hash, util.HashSHA256(mnemonic1)) 48 49 wallet, err := hdwallet.NewFromMnemonic(string(mnemonic)) 50 require.NoError(err) 51 52 derivationPath := fmt.Sprintf("%s/0'/%d/%d", DefaultRootDerivationPath, 1, 2) 53 54 path := hdwallet.MustParseDerivationPath(derivationPath) 55 account, err := wallet.Derive(path, false) 56 require.NoError(err) 57 58 private1, err := wallet.PrivateKey(account) 59 require.NoError(err) 60 61 // simulating 'hdwallet import' here 62 enctxt = append([]byte(mnemonic), util.HashSHA256([]byte(mnemonic))...) 63 enckey = util.HashSHA256([]byte(password)) 64 65 _, err = util.Encrypt(enctxt, enckey) 66 require.NoError(err) 67 68 // compare import and create 69 wallet, err = hdwallet.NewFromMnemonic(string(mnemonic)) 70 require.NoError(err) 71 72 derivationPath = fmt.Sprintf("%s/0'/%d/%d", DefaultRootDerivationPath, 1, 2) 73 74 path = hdwallet.MustParseDerivationPath(derivationPath) 75 account, err = wallet.Derive(path, false) 76 require.NoError(err) 77 78 private2, err := wallet.PrivateKey(account) 79 require.NoError(err) 80 require.Equal(private1, private2) 81 82 //test DeriveKey 83 account1 := 0 84 change := 1 85 index := 2 86 87 derivationPath = fmt.Sprintf("%s/%d'/%d/%d", DefaultRootDerivationPath, account1, change, index) 88 path = hdwallet.MustParseDerivationPath(derivationPath) 89 account, err = wallet.Derive(path, false) 90 require.NoError(err) 91 92 private3, err := wallet.PrivateKey(account) 93 require.NoError(err) 94 95 require.Equal(private2, private3) 96 97 account1 = 123 98 derivationPath = fmt.Sprintf("%s/%d'/%d/%d", DefaultRootDerivationPath, account1, change, index) 99 path = hdwallet.MustParseDerivationPath(derivationPath) 100 account, err = wallet.Derive(path, false) 101 require.NoError(err) 102 103 private4, err := wallet.PrivateKey(account) 104 require.NoError(err) 105 require.NotEqual(private2, private4) 106 } 107 108 func TestEncryptDecryptWithMnemonic(t *testing.T) { 109 require := require.New(t) 110 111 mnemonic := "lake stove quarter shove dry matrix hire split wide attract argue core" 112 password := "123" 113 114 enckey := util.HashSHA256([]byte(password)) 115 116 storedTxt, err := hex.DecodeString("4da6571c2897e88568cbcce59dcf9574355d718da25f2ea6f2e6847b9254fc18eacd852d282f1be7b51024fb05e70ee41bc08c0a8a07c549b0c29f185de0fb35462f98b429ebc4b79bfbcab41b795fe1e59262ae0695a4107dcc57a8bad24eb2323b2c976a9fb3dafc8788a9fccbf5b8c36e3388e458") 117 require.NoError(err) 118 119 dectxt, err := util.Decrypt(storedTxt, enckey) 120 require.NoError(err) 121 122 dectxtLen := len(dectxt) 123 124 mnemonic1, hash := dectxt[:dectxtLen-32], dectxt[dectxtLen-32:] 125 126 require.Equal(mnemonic, string(mnemonic1)) 127 require.Equal(util.HashSHA256(mnemonic1), hash) 128 } 129 130 func TestFixedMnemonicAndDerivationPath(t *testing.T) { 131 require := require.New(t) 132 133 mnemonic := "lake stove quarter shove dry matrix hire split wide attract argue core" 134 wallet, err := hdwallet.NewFromMnemonic(mnemonic) 135 require.NoError(err) 136 137 derivationPath := "m/44'/304'/0'/1/3" 138 139 path := hdwallet.MustParseDerivationPath(derivationPath) 140 account, err := wallet.Derive(path, false) 141 require.NoError(err) 142 143 private, err := wallet.PrivateKey(account) 144 require.NoError(err) 145 prvKey, err := crypto.BytesToPrivateKey(ecrypt.FromECDSA(private)) 146 require.NoError(err) 147 addr := prvKey.PublicKey().Address() 148 require.NotNil(addr) 149 150 require.Equal(addr.String(), "io13hwqt04le40puf73aa9w9zm9fq04qqn7qcjc6z") 151 152 }