electrum

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

commit c24482c21a7df7e7dc9d1027a738acfa49044a7e
parent 38a59c0b37448bf6fdc384d4a7f52d63fcd15216
Author: ThomasV <thomasv@gitorious>
Date:   Sat,  5 Apr 2014 10:34:51 +0200

check seed in gui. fixes #622

Diffstat:
Mgui/qt/installwizard.py | 6+++++-
Mgui/qt/main_window.py | 25+++++++++++++++++++++++++
Mlib/bitcoin.py | 20+++++++++++++++++++-
Mlib/wallet.py | 41++++++++++++++---------------------------
4 files changed, 63 insertions(+), 29 deletions(-)

diff --git a/gui/qt/installwizard.py b/gui/qt/installwizard.py @@ -134,6 +134,10 @@ class InstallWizard(QDialog): QMessageBox.warning(None, _('Error'), _('No seed'), _('OK')) return + if not Wallet.is_seed(seed): + QMessageBox.warning(None, _('Error'), _('Invalid seed'), _('OK')) + return + return seed @@ -272,7 +276,7 @@ class InstallWizard(QDialog): elif action == 'restore': seed = self.seed_dialog() - if not seed: + if not Wallet.is_seed(seed): return wallet = Wallet.from_seed(seed, self.storage) ok, old_password, password = self.password_dialog(wallet) diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py @@ -1141,6 +1141,7 @@ class ElectrumWindow(QMainWindow): menu.addAction(_("Copy to clipboard"), lambda: self.app.clipboard().setText(addr)) menu.addAction(_("QR code"), lambda: self.show_qrcode("bitcoin:" + addr, _("Address")) ) menu.addAction(_("Edit label"), lambda: self.edit_label(True)) + menu.addAction(_("Public keys"), lambda: self.show_public_keys(addr)) if self.wallet.seed: menu.addAction(_("Private key"), lambda: self.show_private_key(addr)) menu.addAction(_("Sign/verify message"), lambda: self.sign_verify_message(addr)) @@ -1667,6 +1668,30 @@ class ElectrumWindow(QMainWindow): apply( func, args) + def show_public_keys(self, address): + if not address: return + try: + pubkey_list = self.wallet.get_public_keys(address) + except Exception as e: + traceback.print_exc(file=sys.stdout) + self.show_message(str(e)) + return + + d = QDialog(self) + d.setMinimumSize(600, 200) + d.setModal(1) + vbox = QVBoxLayout() + vbox.addWidget( QLabel(_("Address") + ': ' + address)) + vbox.addWidget( QLabel(_("Public key") + ':')) + keys = QTextEdit() + keys.setReadOnly(True) + keys.setText('\n'.join(pubkey_list)) + vbox.addWidget(keys) + #vbox.addWidget( QRCodeWidget('\n'.join(pk_list)) ) + vbox.addLayout(close_button(d)) + d.setLayout(vbox) + d.exec_() + @protected def show_private_key(self, address, password): if not address: return diff --git a/lib/bitcoin.py b/lib/bitcoin.py @@ -71,7 +71,25 @@ def mnemonic_to_seed(mnemonic, passphrase): 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) +is_new_seed = lambda x: hmac_sha_512("Seed version", x).encode('hex')[0:2].startswith(SEED_PREFIX) + +def is_old_seed(seed): + import mnemonic + words = seed.strip().split() + try: + mnemonic.mn_decode(words) + uses_electrum_words = True + except Exception: + uses_electrum_words = False + + try: + seed.decode('hex') + is_hex = True + except Exception: + is_hex = False + + return is_hex or (uses_electrum_words and len(words) == 12) + # pywallet openssl private key implementation diff --git a/lib/wallet.py b/lib/wallet.py @@ -288,7 +288,7 @@ class NewWallet: # we keep only 13 words, that's approximately 139 bits of entropy words = mnemonic.mn_encode(s)[0:13] seed = ' '.join(words) - if is_seed(seed): + if is_new_seed(seed): break # this will remove 8 bits of entropy nonce += 1 @@ -1781,36 +1781,23 @@ class Wallet(object): @classmethod - def from_seed(self, seed, storage): - import mnemonic + def is_seed(self, seed): if not seed: - return - - words = seed.strip().split() - try: - mnemonic.mn_decode(words) - uses_electrum_words = True - except Exception: - uses_electrum_words = False - - try: - seed.decode('hex') - is_hex = True - except Exception: - is_hex = False - - if is_hex or (uses_electrum_words and len(words) == 12): - #print "old style wallet", len(words), words - w = OldWallet(storage) - w.init_seed(seed) #hex - else: - assert is_seed(seed) - w = NewWallet(storage) - w.init_seed(seed) + return False + elif is_old_seed(seed): + return OldWallet + elif is_new_seed(seed): + return NewWallet + else: + return False + @classmethod + def from_seed(self, seed, storage): + klass = self.is_seed(seed) + w = klass(storage) + w.init_seed(seed) return w - @classmethod def from_mpk(self, mpk, storage):