electrum

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

commit cf01788c863e75827e859051560ab9fd2a586ca9
parent 468c35e60548e82c22f1d276cbeb9f9855b79f75
Author: ThomasV <thomasv@electrum.org>
Date:   Tue, 21 May 2019 09:52:05 +0200

Merge pull request #5367 from SomberNight/issue_5366

keystore/transactions: fix overflow of derivation path indices
Diffstat:
Melectrum/keystore.py | 17+++++++++++++----
Melectrum/tests/test_transaction.py | 5+++++
2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/electrum/keystore.py b/electrum/keystore.py @@ -282,7 +282,13 @@ class Xpub: return node.eckey.get_public_key_hex(compressed=True) def get_xpubkey(self, c, i): - s = ''.join(map(lambda x: bitcoin.int_to_hex(x,2), (c, i))) + def encode_path_int(path_int) -> str: + if path_int < 0xffff: + hex = bitcoin.int_to_hex(path_int, 2) + else: + hex = 'ffff' + bitcoin.int_to_hex(path_int, 4) + return hex + s = ''.join(map(encode_path_int, (c, i))) return 'ff' + bh2u(bitcoin.DecodeBase58Check(self.xpub)) + s @classmethod @@ -296,11 +302,14 @@ class Xpub: # derivation: dd = pk[78:] s = [] - # FIXME: due to an oversight, levels in the derivation are only - # allocated 2 bytes, instead of 4 (in bip32) while dd: - n = int(bitcoin.rev_hex(bh2u(dd[0:2])), 16) + # 2 bytes for derivation path index + n = int.from_bytes(dd[0:2], byteorder="little") dd = dd[2:] + # in case of overflow, drop these 2 bytes; and use next 4 bytes instead + if n == 0xffff: + n = int.from_bytes(dd[0:4], byteorder="little") + dd = dd[4:] s.append(n) assert len(s) == 2 return xkey, s diff --git a/electrum/tests/test_transaction.py b/electrum/tests/test_transaction.py @@ -838,6 +838,11 @@ class TestTransactionTestnet(TestCaseForTestnet): txid = 'ba5c88e07a4025a39ad3b85247cbd4f556a70d6312b18e04513c7cec9d45d6ac' self._run_naive_tests_on_tx(raw_tx, txid) + def test_txid_partial_issue_5366(self): + raw_tx = '45505446ff000200000000010127523d70642dabd999fb43191ff6763f5b04150ba4cf38d2cfb53edf6a40ac4f0100000000fdffffff013286010000000000160014e79c7ac0b390a9caf52dc002e1095a5fbc042a18feffffffffa08601000000000000000201ff57ff045f1cf60157e9eb7a8000000038fa0b3a9c155ff3390ca0d639783d97af3b3bf66ebb69a31dfe8317fae0a7fe0324bc048fc0002253dfec9d6299711d708175f950ecee8e09db3518a5685741830000ffffcf01010043281700' + txid = 'a0c159616073dc7a4a482092dab4e8516c83dddb769b65919f23f6df63d33eb8' + self._run_naive_tests_on_tx(raw_tx, txid) + # end partial txns <---