electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit 6361abaf4dad040f0d8cb251c45967dc38a367e4
parent c657212e5b6b0fc795bc764ea07e8e061959aeba
Author: ThomasV <thomasv@gitorious>
Date:   Tue,  9 Sep 2014 11:51:45 +0200

extended seed prefix

Diffstat:
Mgui/qt/installwizard.py | 20++++++++------------
Mlib/bitcoin.py | 7+++++--
Mlib/commands.py | 2+-
Mlib/mnemonic.py | 13+++++++------
Mlib/version.py | 3++-
5 files changed, 23 insertions(+), 22 deletions(-)

diff --git a/gui/qt/installwizard.py b/gui/qt/installwizard.py @@ -127,25 +127,21 @@ class InstallWizard(QDialog): text = ' '.join(text.split()) return text - def is_any(self, seed_e): - text = self.get_seed_text(seed_e) + def is_any(self, text): return Wallet.is_seed(text) or Wallet.is_old_mpk(text) or Wallet.is_xpub(text) or Wallet.is_xprv(text) or Wallet.is_address(text) or Wallet.is_private_key(text) - def is_mpk(self, seed_e): - text = self.get_seed_text(seed_e) + def is_mpk(self, text): return Wallet.is_xpub(text) or Wallet.is_old_mpk(text) - def is_xpub(self, seed_e): - text = self.get_seed_text(seed_e) - return Wallet.is_xpub(text) - - def enter_seed_dialog(self, msg, sid): + def enter_seed_dialog(self, msg, sid, func=None): + if func is None: + func = self.is_any vbox, seed_e = seed_dialog.enter_seed_box(msg, sid) vbox.addStretch(1) hbox, button = ok_cancel_buttons2(self, _('Next')) vbox.addLayout(hbox) button.setEnabled(False) - seed_e.textChanged.connect(lambda: button.setEnabled(self.is_any(seed_e))) + seed_e.textChanged.connect(lambda: button.setEnabled(func(self.get_seed_text(seed_e)))) self.set_layout(vbox) if not self.exec_(): return @@ -167,7 +163,7 @@ class InstallWizard(QDialog): hbox, button = ok_cancel_buttons2(self, _('Next')) vbox.addLayout(hbox) button.setEnabled(False) - f = lambda: button.setEnabled( map(lambda e: self.is_xpub(e), entries) == [True]*len(entries)) + f = lambda: button.setEnabled( map(lambda e: Wallet.is_xpub(self.get_seed_text(e)), entries) == [True]*len(entries)) for e in entries: e.textChanged.connect(f) self.set_layout(vbox) @@ -190,7 +186,7 @@ class InstallWizard(QDialog): vbox.addLayout(hbox) button.setEnabled(False) - f = lambda: button.setEnabled( map(lambda e: self.is_any(e), entries) == [True]*len(entries)) + f = lambda: button.setEnabled( map(lambda e: self.is_any(self.get_seed_text(e)), entries) == [True]*len(entries)) for e in entries: e.textChanged.connect(f) diff --git a/lib/bitcoin.py b/lib/bitcoin.py @@ -23,8 +23,8 @@ import re import sys import hmac +import version from util import print_error -from version import SEED_PREFIX try: import ecdsa @@ -147,7 +147,10 @@ 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() -is_new_seed = lambda x: hmac_sha_512("Seed version", x.encode('utf8')).encode('hex')[0:2].startswith(SEED_PREFIX) + +def is_new_seed(x, prefix=version.SEED_BIP44): + s = hmac_sha_512("Seed version", x.encode('utf8')).encode('hex') + return s.startswith(prefix) def is_old_seed(seed): diff --git a/lib/commands.py b/lib/commands.py @@ -133,7 +133,7 @@ class Commands: def make_seed(self, nbits, custom_entropy, language): from mnemonic import Mnemonic - s = Mnemonic(language).make_seed(nbits, custom_entropy) + s = Mnemonic(language).make_seed(nbits, custom_entropy=custom_entropy) return s.encode('utf8') def check_seed(self, seed, custom_entropy, language): diff --git a/lib/mnemonic.py b/lib/mnemonic.py @@ -27,7 +27,7 @@ import pbkdf2 from util import print_error from bitcoin import is_old_seed, is_new_seed - +import version class Mnemonic(object): # Seed derivation follows BIP39 @@ -89,11 +89,13 @@ class Mnemonic(object): i = self.mnemonic_decode(seed) return i % custom_entropy == 0 - def make_seed(self, num_bits=128, custom_entropy=1): + def make_seed(self, num_bits=128, prefix=version.SEED_BIP44, custom_entropy=1): n = int(math.ceil(math.log(custom_entropy,2))) + # bits of entropy used by the prefix + k = len(prefix)*4 # we add at least 16 bits - n_added = max(16, 8 + num_bits - n) - print_error("make_seed: adding %d bits"%n_added) + n_added = max(16, k + num_bits - n) + print_error("make_seed", prefix, "adding %d bits"%n_added) my_entropy = ecdsa.util.randrange( pow(2, n_added) ) nonce = 0 while True: @@ -103,8 +105,7 @@ class Mnemonic(object): assert i == self.mnemonic_decode(seed) if is_old_seed(seed): continue - # this removes 8 bits of entropy - if is_new_seed(seed): + if is_new_seed(seed, prefix): break print_error('%d words'%len(seed.split())) return seed diff --git a/lib/version.py b/lib/version.py @@ -5,4 +5,5 @@ OLD_SEED_VERSION = 4 # old electrum deterministic generation # The hash of the mnemonic seed must begin with this -SEED_PREFIX = '01' # for BIP44 +SEED_BIP44 = '01' # BIP44 +SEED_2FA = '101' # extended seed for two-factor authentication