-
Notifications
You must be signed in to change notification settings - Fork 112
Description
Summary: Using the same mnemonic sentence in a MultiBit HD soft wallet and other BIP32-m/0'-compliant wallets (plus account change index 0) produces different keys and addresses.
Steps to reproduce
- Create a new HD soft wallet or restore one using a mnemonic sentence. For the sake of this example, restore a wallet using this mnemonic sentence: skin join dog sponsor camera puppy ritual diagram arrow poverty boy elbow
- Obtain the first receive address.
expected result in this example: 12QxtuyEM8KBG3ngNRe2CZE28hFw3b1KMJ
actual result from MultiBit HD: 1LQ8XnNKqC7Vu7atH5k4X8qVCc9ug2q7WE
The expected result was generated by https://dcpos.github.io/bip39/ using the derivation path m/0'/0, however any BIP32-compliant wallet using the same path should produce the same expected result.
Definitions, just so we're on the same page:
- entropy bits - an array of bits as generated by a CSPRNG or a true entropy source; typically 128 - 256 bits long.
- mnemonic sentence - the result of encoding entropy bits plus a checksum into a BIP39 list of words; typically 12 - 24 words long.
- seed bits - the result of running a mnemonic sentence through PBKDF2; always exactly 512 bits long.
How to reproduce the keys and addresses currently produced by MultiBit HD
- Take the mnemonic sentence (from above) and derive the seed bits. The result is the following 64 bytes:
34, 178, 134, 7, 239, 86, 118, 164, 174, 211, 216, 40, 102, 130, 237, 105, 108, 108, 164, 254, 91, 192, 184, 131, 226, 248, 39, 113, 38, 184, 73, 12, 18, 201, 145, 253, 252, 1, 255, 241, 231, 146, 213, 247, 70, 230, 184, 60, 68, 207, 57, 201, 121, 94, 67, 222, 133, 144, 59, 243, 115, 146, 86, 82 - Take the seed bits, and interpret them as though they were 512 entropy bits.
- Take these 512 entropy bits, and derive a new mnemonic sentence as per BIP39. The result is this 48 word long mnemonic: trim snack gorilla discover coast hat member pig build snake mention balance acoustic neutral asthma swift oven choice human orange smart intact soup wild nice public assume lady wing snake critic enrich say session useful base echo nut emotion fantasy trumpet dog deer basket expand hand surface coach
- Take this new mnemonic sentence, and derive keys and addresses according to BIP32 and a m/0'/0 path (for example at the website mentioned above). The result will be what MultiBit HD is currently producing (1LQ8XnNKqC7Vu7atH5k4X8qVCc9ug2q7WE will be the first address).
The DeterministicSeed constructor selected by overload resolution is the first one below; it takes as its first argument a byte array of entropy bits, but it is being passed a byte array of seed bits instead. Perhaps the second constructor below is the one that was intended, however AFAICT you can't construct a DeterministicSeed unless you either provide it with a mnemonic sentence, or let it generate its own mnemonic sentence (which may complicate the fix)....
DeterministicSeed(byte[] entropy, String passphrase, long creationTimeSeconds)
DeterministicSeed(byte[] seed, List<String> mnemonic, long creationTimeSeconds)( edited for clarity: ) The simplest solution (passing it the mnemonic sentence in addition to the seed bits) probably wouldn't break existing wallets, but it would break the ability to restore existing wallets using only the mnemonic sentence, so I'm not sure what the best path forward is....