Skip to content

Commit 6b60049

Browse files
authored
Remove unncessary requirements for HDWallet derivation (#463)
* Remove unncessary requirements for HDWallet derivation * Fix type check
1 parent 2de335e commit 6b60049

File tree

2 files changed

+67
-11
lines changed

2 files changed

+67
-11
lines changed

pycardano/crypto/bip32.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,12 @@ class HDWallet:
8282

8383
def __init__(
8484
self,
85-
root_xprivate_key: bytes,
86-
root_public_key: bytes,
87-
root_chain_code: bytes,
88-
xprivate_key: bytes,
89-
public_key: bytes,
90-
chain_code: bytes,
85+
root_xprivate_key: Optional[bytes] = None,
86+
root_public_key: Optional[bytes] = None,
87+
root_chain_code: Optional[bytes] = None,
88+
xprivate_key: Optional[bytes] = None,
89+
public_key: Optional[bytes] = None,
90+
chain_code: Optional[bytes] = None,
9191
path: str = "m",
9292
seed: Optional[bytes] = None,
9393
mnemonic: Optional[str] = None,
@@ -322,28 +322,36 @@ def derive(
322322
if not isinstance(index, int):
323323
raise ValueError("Bad index, Please import only integer number!")
324324

325-
if not self._root_xprivate_key and not self._root_public_key:
326-
raise ValueError("Missing root keys. Can't do derivation.")
327-
328325
if hardened:
329326
index += 2**31
330327

331328
if private:
329+
if self._xprivate_key is None:
330+
raise ValueError("Missing private key. Can't do private derivation.")
331+
332332
private_node = (
333333
self._xprivate_key[:32],
334334
self._xprivate_key[32:],
335335
self._public_key,
336336
self._chain_code,
337337
self._path,
338338
)
339-
return self._derive_private_child_key_by_index(private_node, index)
339+
340+
if any(x is None for x in private_node):
341+
raise ValueError(f"None values in private node: {private_node}")
342+
343+
return self._derive_private_child_key_by_index(private_node, index) # type: ignore
340344

341345
public_node = (
342346
self._public_key,
343347
self._chain_code,
344348
self._path,
345349
)
346-
return self._derive_public_child_key_by_index(public_node, index)
350+
351+
if any(x is None for x in public_node):
352+
raise ValueError(f"None values in public node: {public_node}")
353+
354+
return self._derive_public_child_key_by_index(public_node, index) # type: ignore
347355

348356
def _derive_private_child_key_by_index(
349357
self, private_pnode: Tuple[bytes, bytes, bytes, bytes, str], index: int

test/pycardano/crypto/test_bip32.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,3 +387,51 @@ def test_is_entropy_wrong_input():
387387
def test_is_entropy_value_error():
388388
is_entropy = HDWallet.is_entropy("*(#_")
389389
assert is_entropy is False
390+
391+
392+
def test_non_harden_public_derivation():
393+
public_key = bytes.fromhex(
394+
"601c86a2310f438079fff07454f4df4ce416bd181d972cd4c4615f15a733ba15"
395+
)
396+
chain_code = bytes.fromhex(
397+
"8a34b66a32c9d2d61d1d7a0e8fcf167efae3fb556af74808cd1ba8a22251c031"
398+
)
399+
hdwallet = HDWallet(chain_code=chain_code, public_key=public_key)
400+
hdwallet = hdwallet.derive(0, private=False, hardened=False)
401+
child1 = hdwallet.derive(0, private=False, hardened=False)
402+
child2 = hdwallet.derive(1, private=False, hardened=False)
403+
child3 = hdwallet.derive(2, private=False, hardened=False)
404+
405+
assert (
406+
child1.public_key.hex()
407+
== "b3f354cbdc2837f823c5e0585995d3bd2d6edf1dc9fc8a1a90d01840c519408d"
408+
)
409+
assert (
410+
child2.public_key.hex()
411+
== "363aa29a3c93085859310ccddb182abcca18db6f6897a4f936ae82ba0a15af90"
412+
)
413+
assert (
414+
child3.public_key.hex()
415+
== "db58a4102f555ccb64a0db45259799cbd42fac14f7f6fd1059557fef3961e2c0"
416+
)
417+
418+
419+
def test_non_harden_public_derivation_without_pubkey():
420+
chain_code = bytes.fromhex(
421+
"8a34b66a32c9d2d61d1d7a0e8fcf167efae3fb556af74808cd1ba8a22251c031"
422+
)
423+
hdwallet = HDWallet(chain_code=chain_code)
424+
with pytest.raises(ValueError):
425+
hdwallet.derive(0, private=False, hardened=False)
426+
427+
428+
def test_non_harden_private_derivation_without_privkey():
429+
public_key = bytes.fromhex(
430+
"601c86a2310f438079fff07454f4df4ce416bd181d972cd4c4615f15a733ba15"
431+
)
432+
chain_code = bytes.fromhex(
433+
"8a34b66a32c9d2d61d1d7a0e8fcf167efae3fb556af74808cd1ba8a22251c031"
434+
)
435+
hdwallet = HDWallet(chain_code=chain_code, public_key=public_key)
436+
with pytest.raises(ValueError):
437+
hdwallet.derive(0, private=True, hardened=False)

0 commit comments

Comments
 (0)