@@ -282,7 +282,13 @@ def get_pubkey_from_xpub(self, xpub, sequence):
282
282
return node .eckey .get_public_key_hex (compressed = True )
283
283
284
284
def get_xpubkey (self , c , i ):
285
- s = '' .join (map (lambda x : bitcoin .int_to_hex (x ,2 ), (c , i )))
285
+ def encode_path_int (path_int ) -> str :
286
+ if path_int < 0xffff :
287
+ hex = bitcoin .int_to_hex (path_int , 2 )
288
+ else :
289
+ hex = 'ffff' + bitcoin .int_to_hex (path_int , 4 )
290
+ return hex
291
+ s = '' .join (map (encode_path_int , (c , i )))
286
292
return 'ff' + bh2u (bitcoin .DecodeBase58Check (self .xpub )) + s
287
293
288
294
@classmethod
@@ -296,11 +302,14 @@ def parse_xpubkey(self, pubkey):
296
302
# derivation:
297
303
dd = pk [78 :]
298
304
s = []
299
- # FIXME: due to an oversight, levels in the derivation are only
300
- # allocated 2 bytes, instead of 4 (in bip32)
301
305
while dd :
302
- n = int (bitcoin .rev_hex (bh2u (dd [0 :2 ])), 16 )
306
+ # 2 bytes for derivation path index
307
+ n = int .from_bytes (dd [0 :2 ], byteorder = "little" )
303
308
dd = dd [2 :]
309
+ # in case of overflow, drop these 2 bytes; and use next 4 bytes instead
310
+ if n == 0xffff :
311
+ n = int .from_bytes (dd [0 :4 ], byteorder = "little" )
312
+ dd = dd [4 :]
304
313
s .append (n )
305
314
assert len (s ) == 2
306
315
return xkey , s
0 commit comments