bip39
authorThomasV <thomasv@gitorious>
Sat, 1 Feb 2014 10:23:29 +0000 (11:23 +0100)
committerThomasV <thomasv@gitorious>
Sat, 1 Feb 2014 10:23:29 +0000 (11:23 +0100)
lib/bitcoin.py
lib/wallet.py

index ff6f555..37cd60f 100644 (file)
@@ -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)
 
index 2d9eb69..f17c08f 100644 (file)
@@ -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
+
+