diff --git a/lib/bitcoin.py b/lib/bitcoin.py index ff6f5553..37cd60ff 100644 --- a/lib/bitcoin.py +++ b/lib/bitcoin.py @@ -62,9 +62,14 @@ def Hash(x): hash_encode = lambda x: x[::-1].encode('hex') hash_decode = lambda x: x.decode('hex')[::-1] - hmac_sha_512 = lambda x,y: hmac.new(x, y, hashlib.sha512).digest() -mnemonic_hash = lambda x: hmac_sha_512("Bitcoin mnemonic", x).encode('hex') + +def mnemonic_to_seed(mnemonic, passphrase): + from pbkdf2 import PBKDF2 + import hmac + PBKDF2_ROUNDS = 2048 + return PBKDF2(mnemonic, 'mnemonic' + passphrase, iterations = PBKDF2_ROUNDS, macmodule = hmac, digestmodule = hashlib.sha512).read(64) + from version import SEED_PREFIX is_seed = lambda x: hmac_sha_512("Seed version", x).encode('hex')[0:2].startswith(SEED_PREFIX) diff --git a/lib/wallet.py b/lib/wallet.py index 2d9eb698..f17c08f6 100644 --- a/lib/wallet.py +++ b/lib/wallet.py @@ -150,6 +150,9 @@ class WalletStorage: os.chmod(self.path,stat.S_IREAD | stat.S_IWRITE) + + + class Wallet: def __init__(self, storage): @@ -179,12 +182,6 @@ class Wallet: self.next_addresses = storage.get('next_addresses',{}) - if self.seed_version not in [4, 6]: - msg = "This wallet seed is not supported." - if self.seed_version in [5]: - msg += "\nTo open this wallet, try 'git checkout seed_v%d'"%self.seed_version - print msg - sys.exit(1) # This attribute is set when wallet.start_threads is called. self.synchronizer = None @@ -297,7 +294,7 @@ class Wallet: def init_seed(self, seed): - import mnemonic + import mnemonic, unicodedata if self.seed: raise Exception("a seed exists") @@ -307,6 +304,10 @@ class Wallet: self.seed_version = SEED_VERSION return + self.seed_version = SEED_VERSION + self.seed = unicodedata.normalize('NFC', unicode(seed.strip())) + return + # find out what kind of wallet we are try: seed.strip().decode('hex') @@ -682,14 +683,13 @@ class Wallet: return '&'.join(dd) - def get_seed(self, password): s = pw_decode(self.seed, password) if self.seed_version == 4: seed = s self.accounts[0].check_seed(seed) else: - seed = mnemonic_hash(s) + seed = mnemonic_to_seed(s,'').encode('hex') return seed @@ -700,7 +700,6 @@ class Wallet: return ' '.join(mnemonic.mn_encode(s)) else: return s - def get_private_key(self, address, password): @@ -1763,3 +1762,5 @@ class WalletSynchronizer(threading.Thread): # Updated gets called too many times from other places as well; if we use that signal we get the notification three times self.network.trigger_callback("new_transaction") self.was_updated = False + +