Browse Source

wallet: faster decrypt_message for Imported_Wallet

hard-fail-on-bad-server-string
SomberNight 5 years ago
parent
commit
ea62027599
No known key found for this signature in database GPG Key ID: B33B5F232C6271E9
  1. 16
      electrum/keystore.py
  2. 12
      electrum/wallet.py

16
electrum/keystore.py

@ -107,11 +107,11 @@ class KeyStore(Logger, ABC):
pass pass
@abstractmethod @abstractmethod
def sign_message(self, sequence, message, password) -> bytes: def sign_message(self, sequence: 'AddressIndexGeneric', message, password) -> bytes:
pass pass
@abstractmethod @abstractmethod
def decrypt_message(self, sequence, message, password) -> bytes: def decrypt_message(self, sequence: 'AddressIndexGeneric', message, password) -> bytes:
pass pass
@abstractmethod @abstractmethod
@ -185,7 +185,8 @@ class Software_KeyStore(KeyStore):
pass pass
@abstractmethod @abstractmethod
def get_private_key(self, *args, **kwargs) -> Tuple[bytes, bool]: def get_private_key(self, sequence: 'AddressIndexGeneric', password) -> Tuple[bytes, bool]:
"""Returns (privkey, is_compressed)"""
pass pass
@ -196,7 +197,7 @@ class Imported_KeyStore(Software_KeyStore):
def __init__(self, d): def __init__(self, d):
Software_KeyStore.__init__(self, d) Software_KeyStore.__init__(self, d)
self.keypairs = d.get('keypairs', {}) self.keypairs = d.get('keypairs', {}) # type: Dict[str, str]
def is_deterministic(self): def is_deterministic(self):
return False return False
@ -231,7 +232,7 @@ class Imported_KeyStore(Software_KeyStore):
def delete_imported_key(self, key): def delete_imported_key(self, key):
self.keypairs.pop(key) self.keypairs.pop(key)
def get_private_key(self, pubkey, password): def get_private_key(self, pubkey: str, password):
sec = pw_decode(self.keypairs[pubkey], password, version=self.pw_hash_version) sec = pw_decode(self.keypairs[pubkey], password, version=self.pw_hash_version)
txin_type, privkey, compressed = deserialize_privkey(sec) txin_type, privkey, compressed = deserialize_privkey(sec)
# this checks the password # this checks the password
@ -541,7 +542,7 @@ class BIP32_KeyStore(Xpub, Deterministic_KeyStore):
self.add_xprv(node.to_xprv()) self.add_xprv(node.to_xprv())
self.add_key_origin_from_root_node(derivation_prefix=derivation, root_node=rootnode) self.add_key_origin_from_root_node(derivation_prefix=derivation, root_node=rootnode)
def get_private_key(self, sequence, password): def get_private_key(self, sequence: Sequence[int], password):
xprv = self.get_master_private_key(password) xprv = self.get_master_private_key(password)
node = BIP32Node.from_xkey(xprv).subkey_at_private_derivation(sequence) node = BIP32Node.from_xkey(xprv).subkey_at_private_derivation(sequence)
pk = node.eckey.get_secret_bytes() pk = node.eckey.get_secret_bytes()
@ -633,7 +634,7 @@ class Old_KeyStore(MasterPublicKeyMixin, Deterministic_KeyStore):
pk = number_to_string(secexp, ecc.CURVE_ORDER) pk = number_to_string(secexp, ecc.CURVE_ORDER)
return pk return pk
def get_private_key(self, sequence, password): def get_private_key(self, sequence: Sequence[int], password):
seed = self.get_hex_seed(password) seed = self.get_hex_seed(password)
secexp = self.stretch_key(seed) secexp = self.stretch_key(seed)
self._check_seed(seed, secexp=secexp) self._check_seed(seed, secexp=secexp)
@ -772,6 +773,7 @@ class Hardware_KeyStore(Xpub, KeyStore):
KeyStoreWithMPK = Union[KeyStore, MasterPublicKeyMixin] # intersection really... KeyStoreWithMPK = Union[KeyStore, MasterPublicKeyMixin] # intersection really...
AddressIndexGeneric = Union[Sequence[int], str] # can be hex pubkey str
def bip39_normalize_passphrase(passphrase): def bip39_normalize_passphrase(passphrase):

12
electrum/wallet.py

@ -57,7 +57,7 @@ from .bitcoin import (COIN, is_address, address_to_script,
is_minikey, relayfee, dust_threshold) is_minikey, relayfee, dust_threshold)
from .crypto import sha256d from .crypto import sha256d
from . import keystore from . import keystore
from .keystore import load_keystore, Hardware_KeyStore, KeyStore, KeyStoreWithMPK from .keystore import load_keystore, Hardware_KeyStore, KeyStore, KeyStoreWithMPK, AddressIndexGeneric
from .util import multisig_type from .util import multisig_type
from .storage import StorageEncryptionVersion, WalletStorage from .storage import StorageEncryptionVersion, WalletStorage
from . import transaction, bitcoin, coinchooser, paymentrequest, ecc, bip32 from . import transaction, bitcoin, coinchooser, paymentrequest, ecc, bip32
@ -421,7 +421,7 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
return self.get_address_index(address)[0] == 1 return self.get_address_index(address)[0] == 1
@abstractmethod @abstractmethod
def get_address_index(self, address): def get_address_index(self, address: str) -> Optional[AddressIndexGeneric]:
pass pass
@abstractmethod @abstractmethod
@ -1730,7 +1730,7 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
index = self.get_address_index(address) index = self.get_address_index(address)
return self.keystore.sign_message(index, message, password) return self.keystore.sign_message(index, message, password)
def decrypt_message(self, pubkey, message, password) -> bytes: def decrypt_message(self, pubkey: str, message, password) -> bytes:
addr = self.pubkeys_to_address([pubkey]) addr = self.pubkeys_to_address([pubkey])
index = self.get_address_index(addr) index = self.get_address_index(addr)
return self.keystore.decrypt_message(index, message, password) return self.keystore.decrypt_message(index, message, password)
@ -2040,11 +2040,15 @@ class Imported_Wallet(Simple_Wallet):
def pubkeys_to_address(self, pubkeys): def pubkeys_to_address(self, pubkeys):
pubkey = pubkeys[0] pubkey = pubkeys[0]
for addr in self.db.get_imported_addresses(): for addr in self.db.get_imported_addresses(): # FIXME slow...
if self.db.get_imported_address(addr)['pubkey'] == pubkey: if self.db.get_imported_address(addr)['pubkey'] == pubkey:
return addr return addr
return None return None
def decrypt_message(self, pubkey: str, message, password) -> bytes:
# this is significantly faster than the implementation in the superclass
return self.keystore.decrypt_message(pubkey, message, password)
class Deterministic_Wallet(Abstract_Wallet): class Deterministic_Wallet(Abstract_Wallet):

Loading…
Cancel
Save