hivewallet / hive-js

Hive digital currency wallet
http://www.hivewallet.com
GNU General Public License v2.0
81 stars 57 forks source link

[BIP39.js error] [Please re-direct] Non-ascii characters are not generating valid seeds. #215

Closed dabura667 closed 10 years ago

dabura667 commented 10 years ago

UPDATE: The fix was pretty simple. CryptoJS handles UTF8 fine as-is. So removing 3 lines fixed it. https://github.com/weilu/bip39/pull/15

Please merge. Thanks.


On my repository for generating Japanese BIP39 seeds, I have noticed that the results of the BIP39.js I compiled from Weilu's repository (and thus the one used by hive-js) generates the same seed as trezor-python as long as any non-ascii bytes are not used.

As soon as I feed into it a normalized unicode string. Python-trezor and BIP39.js generate different seeds. (I checked the normalization of both, and the normalized string generated from normalization was the exact same when converted to binary, so the problem lies somewhere in the PBKDF2 function.

I was unable to find the problem, and as hive-js only supports English (ascii-only) at the moment, it won't matter...

but if you ever are considering supporting mnemonics or passphrases with non-ascii entry possible, you should test against python-trezor before hand.

My test vectors (which were generated on hive-js's BIP39.js) are here if you would like to use them. https://github.com/bip32JP/bip32JP.github.io/blob/master/test_JP_BIP39.json

if you feed these into https://github.com/trezor/python-mnemonic/blob/master/mnemonic/mnemonic.py They will all fail. (by fail I mean not match)

Whereas if you feed them into BIP39.js they will match (remember to normalize)

Any ascii mnemonics and passwords will succeed with both.

Please re-direct if this is deemed off-topic for hive-js (I am not sure if you plan implementing non-ascii mnemonics)

dabura667 commented 10 years ago

It seems that the problem lies in the salt. When a utf-8 character is in the salt for PBKDF2 it generates a different hash.

# without a password using python_trezor's mnemonic.py
>>> import mnemonic
>>> m = mnemonic.Mnemonic("japanese")
>>> m.to_seed("あい あい あい あい あい あい あい あい あい あい あい あお").encode("hex")
'bba797f68e98bf66c81b5115ea49a9da4b6a891da4dec4664b2051c2372df7c7fb3cb569d22dc99d52404e7570e65048249a149d0cfd4d983f6c62c69a17be0c'
# bip32jp.github.io/english/ gives (using BIP39.js from weilu's repo)
"bba797f68e98bf66c81b5115ea49a9da4b6a891da4dec4664b2051c2372df7c7fb3cb569d22dc99d52404e7570e65048249a149d0cfd4d983f6c62c69a17be0c"

# with a password using python_trezor's mnemonic.py
>>> import mnemonic
>>> m = mnemonic.Mnemonic("japanese")
>>> m.to_seed("あい あい あい あい あい あい あい あい あい あい あい あお","㍍ガバヴァぱばぐゞちぢ十人十色").encode("hex")
'1ff80dd485191668ebd554f7b87be1edb936d25d55a281b853c3afc250673b50cca471a12bc1a202b7316a2adb4937cd0b9aed1238e7636f4ccf86427a17d743'
# bip32jp.github.io/english/ gives
"486b521785abb98a4d9f056629564cad7d661682ad4bd9cf46320acb4d941831f44fa0d221e529655b72a108d01837dcf03f63876b95c05d33eb690f63dbaa5b"
weilu commented 10 years ago

Fixed by weilu/bip39#15