Browse Source

psbt: follow-ups: fix digital bitbox

patch-1
SomberNight 5 years ago
parent
commit
dd14a3fde5
No known key found for this signature in database GPG Key ID: B33B5F232C6271E9
  1. 12
      electrum/bip32.py
  2. 6
      electrum/keystore.py
  3. 4
      electrum/plugins/digitalbitbox/digitalbitbox.py
  4. 10
      electrum/tests/test_bitcoin.py

12
electrum/bip32.py

@ -372,6 +372,18 @@ def normalize_bip32_derivation(s: Optional[str]) -> Optional[str]:
return convert_bip32_intpath_to_strpath(ints)
def is_all_public_derivation(path: Union[str, Iterable[int]]) -> bool:
"""Returns whether all levels in path use non-hardened derivation."""
if isinstance(path, str):
path = convert_bip32_path_to_list_of_uint32(path)
for child_index in path:
if child_index < 0:
raise ValueError('the bip32 index needs to be non-negative')
if child_index & BIP32_PRIME:
return False
return True
def root_fp_and_der_prefix_from_xkey(xkey: str) -> Tuple[Optional[str], Optional[str]]:
"""Returns the root bip32 fingerprint and the derivation path from the
root to the given xkey, if they can be determined. Otherwise (None, None).

6
electrum/keystore.py

@ -707,8 +707,10 @@ class Hardware_KeyStore(KeyStore, Xpub):
def opportunistically_fill_in_missing_info_from_device(self, client):
assert client is not None
if self._root_fingerprint is None:
root_xpub = client.get_xpub('m', xtype='standard')
root_fingerprint = BIP32Node.from_xkey(root_xpub).calc_fingerprint_of_this_node().hex().lower()
# digitalbitbox (at least) does not reveal xpubs corresponding to unhardened paths
# so ask for a direct child, and read out fingerprint from that:
child_of_root_xpub = client.get_xpub("m/0'", xtype='standard')
root_fingerprint = BIP32Node.from_xkey(child_of_root_xpub).fingerprint.hex().lower()
self._root_fingerprint = root_fingerprint
self.is_requesting_to_be_rewritten_to_wallet_file = True

4
electrum/plugins/digitalbitbox/digitalbitbox.py

@ -19,7 +19,7 @@ import copy
from electrum.crypto import sha256d, EncodeAES_base64, EncodeAES_bytes, DecodeAES_bytes, hmac_oneshot
from electrum.bitcoin import (TYPE_ADDRESS, push_script, var_int, public_key_to_p2pkh,
is_address)
from electrum.bip32 import BIP32Node, convert_bip32_intpath_to_strpath
from electrum.bip32 import BIP32Node, convert_bip32_intpath_to_strpath, is_all_public_derivation
from electrum import ecc
from electrum.ecc import msg_magic
from electrum.wallet import Standard_Wallet
@ -741,6 +741,8 @@ class DigitalBitboxPlugin(HW_PluginBase):
def get_xpub(self, device_id, derivation, xtype, wizard):
if xtype not in self.SUPPORTED_XTYPES:
raise ScriptTypeNotSupported(_('This type of script is not supported with {}.').format(self.device))
if is_all_public_derivation(derivation):
raise Exception(f"The {self.device} does not reveal xpubs corresponding to non-hardened paths. (path: {derivation})")
devmgr = self.device_manager()
client = devmgr.client_by_id(device_id)
client.handler = self.create_handler(wizard)

10
electrum/tests/test_bitcoin.py

@ -12,7 +12,7 @@ from electrum.bitcoin import (public_key_to_p2pkh, address_from_private_key,
from electrum.bip32 import (BIP32Node, convert_bip32_intpath_to_strpath,
xpub_from_xprv, xpub_type, is_xprv, is_bip32_derivation,
is_xpub, convert_bip32_path_to_list_of_uint32,
normalize_bip32_derivation)
normalize_bip32_derivation, is_all_public_derivation)
from electrum.crypto import sha256d, SUPPORTED_PW_HASH_VERSIONS
from electrum import ecc, crypto, constants
from electrum.ecc import number_to_string, string_to_number
@ -494,6 +494,14 @@ class Test_xprv_xpub(ElectrumTestCase):
self.assertEqual("m/0/2/1'", normalize_bip32_derivation("m/0/2/-1/"))
self.assertEqual("m/0/1'/1'/5'", normalize_bip32_derivation("m/0//-1/1'///5h"))
def test_is_all_public_derivation(self):
self.assertFalse(is_all_public_derivation("m/0/1'/1'"))
self.assertFalse(is_all_public_derivation("m/0/2/1'"))
self.assertFalse(is_all_public_derivation("m/0/1'/1'/5"))
self.assertTrue(is_all_public_derivation("m"))
self.assertTrue(is_all_public_derivation("m/0"))
self.assertTrue(is_all_public_derivation("m/75/22/3"))
def test_xtype_from_derivation(self):
self.assertEqual('standard', xtype_from_derivation("m/44'"))
self.assertEqual('standard', xtype_from_derivation("m/44'/"))

Loading…
Cancel
Save