<p>Here's some working code for calculating a <strong>parent extended private key</strong> from a <strong>master extended public key</strong> and <strong>child extended private key</strong>.</p>
<pre><code>#!/usr/bin/env python3

# pip install hdwallet
# pip install bitcoin-utils

import hmac
import hashlib
import struct
from binascii import  unhexlify
from base58check import b58encode
from hdwallet import HDWallet as HDWallet
from hdwallet.symbols import BTC as SYMBOL


# --------------------
# Provided information
# --------------------

# Master Extended Public Key (m)
MASTER_EXTENDED_PUBLIC_KEY: str = &quot;xpub661MyMwAqRbcF2s3gyqdcUgw6dU7DjLGHCwkM9jndzGT8WXJjMxZiYnvNmfuzsEXC13FUn9BTeefy3uYf4Cj5k86iHUFzLS1yatpXN9hq4u&quot;

# Child Extended Private Key (m/44/0/0/1/404)
CHILD_EXTENDED_PRIVATE_KEY: str = &quot;xprvA3WvYTa5Xv4kSXuL9mAFMimc5psTTB1Dq8x4q9HB7R4EmpufsXFuhi9SpVVYXsmyjM5dvoGowU3W9hDuYRrgkQiiE1d881TZrFLhLNxBs7g&quot;


# ------
# Method
# ------

# Initialize a wallet
hdwallet: HDWallet = HDWallet(symbol=SYMBOL)

# Create a HDWallet from the master extended public key
hdwallet.from_xpublic_key(xpublic_key=MASTER_EXTENDED_PUBLIC_KEY, strict=True)

# Get the parent extended public key at m/44/0/0/1
# We need this so that we can calculate the extended private key at m/44/0/0/1 (the level above the child private key that has been revealed)
PARENT_EXTENDED_PUBLIC_KEY = hdwallet.from_path(&quot;m/44/0/0/1&quot;)
PARENT_PUBLIC_KEY: str = PARENT_EXTENDED_PUBLIC_KEY.public_key()
PARENT_CHAIN_CODE: str = PARENT_EXTENDED_PUBLIC_KEY.chain_code()
print(&quot;Parent Extended Public Key (m/44/0/0/1):&quot;, PARENT_EXTENDED_PUBLIC_KEY.xpublic_key())
print(&quot;  Public Key:&quot;, PARENT_PUBLIC_KEY)
print(&quot;  Chain Code:&quot;, PARENT_CHAIN_CODE)
print(&quot;&quot;)

# Extract the raw private key from the child extended private key m/44/0/0/1/404
# We need this so that we can calculate the parent extended private key
child: HDWallet = HDWallet(symbol=SYMBOL)
child.from_xprivate_key(xprivate_key=CHILD_EXTENDED_PRIVATE_KEY, strict=False) # False allows you to initialize from a non-root extended key
CHILD_PRIVATE_KEY: str = child.private_key()
print(&quot;Child Private Key:&quot;, CHILD_PRIVATE_KEY)
print(&quot;&quot;)

# Calculate the parent extended private key for m/44/0/0/1 (this is the mathematical bit)

# Put the chain code and (parent public key + index) through HMAC-SHA512
# This step is used in HD Wallets when deriving non-hardened children for both private and public extended keys
index = struct.pack(&quot;&gt;L&quot;, 404) # Use the same index number as the child extended private key that we know
data = unhexlify(PARENT_PUBLIC_KEY) + index
hmac_result = hmac.new(unhexlify(PARENT_CHAIN_CODE), data, hashlib.sha512).hexdigest()

# Get the left side of the hmac digest (the left 32 bytes)
hmac_result_left = hmac_result[:64]

# Calculate the parent private key (child private key - hmac left)
# Note: All private keys must be modulo the number of points on the Secp256k1 curve
secp256k1_n = 115792089237316195423570985008687907852837564279074904382605163141518161494337
PARENT_PRIVATE_KEY: str = ((int(CHILD_PRIVATE_KEY, 16) - int(hmac_result_left, 16)) % secp256k1_n).to_bytes(32, &quot;big&quot;).hex()
print(&quot;Parent Private Key:&quot;, PARENT_PRIVATE_KEY)

# Create an address for the parent extended private key
# This is so that we can intialize a new HD Wallet using the extended private key and use it to derive children easily using the library

# Get the fingerprint, which can be found from the parent of this parent extended public key
parent_parent_extended_public_key: HDWallet = HDWallet(symbol=SYMBOL)
parent_parent_extended_public_key.from_xpublic_key(xpublic_key=MASTER_EXTENDED_PUBLIC_KEY, strict=True)
parent_fingerprint = parent_parent_extended_public_key.from_path(&quot;m/44/0/0&quot;).finger_print()

# Serialize all the data for the parent extended private key
version = &quot;0488ade4&quot; # xprv (BIP)
depth = &quot;04&quot; # how many levels deep this extended key is from master, so m/44/0/0/1 = 4
index = &quot;00000001&quot; # the index number of this extended key from its parent, which is the last number of m/44/0/0/1
chain_code = PARENT_CHAIN_CODE
data = &quot;00&quot; + PARENT_PRIVATE_KEY
raw = (version + depth + parent_fingerprint + index + chain_code + data)

# Create a checksum for this serialized data (first 4 bytes of the hash256 of the raw data above)
checksum = hashlib.sha256(hashlib.sha256(unhexlify(raw)).digest()).hexdigest()[0:8]

# Create address by converting to base58
PARENT_EXTENDED_PRIVATE_KEY = b58encode(unhexlify(raw + checksum)).decode(&quot;utf-8&quot;)
print(&quot;Parent Extended Private Key (m/44/0/0/1):&quot;, PARENT_EXTENDED_PRIVATE_KEY)
print(&quot;&quot;)


# -----
# Usage
# -----

# Now that we've calculated the extended private key for m/44/0/0/1, we can calculate all of the child keys below it.
# For example, we can calculate the extended private key at m/44/0/0/1/402

# Initialize a new wallet from the address for this parent extended private key at m/44/0/0/1
parent: HDWallet = HDWallet(symbol=SYMBOL)
parent.from_xprivate_key(xprivate_key=PARENT_EXTENDED_PRIVATE_KEY, strict=False) # False allows you to initialize from a non-root extended key

# Derive the extended private key at m/44/0/0/1/402
example = parent.from_path(&quot;m/402&quot;) # Note: This is m/44/0/0/1/402, because we are starting from m/44/0/0/1
print(&quot;Example (m/44/0/0/1/402):&quot;, example.xprivate_key())


# ------
# Checks
# ------

# I already knew the master extended private key for this wallet, so we can use it to check that it derives the same extended private key at m/44/0/0/1/402 as the parent extended private key we calculated.

MASTER_EXTENDED_PRIVATE_KEY: str = &quot;xprv9s21ZrQH143K2YnaaxJdFLkCYbdcpGcQuz29YmLB5ejUFiCABpeKAkUSXVuqysESjMJhk8yTfhxR3BT6Ag7Z5fYJ1jFgidmrGgfZYNCLnNB&quot;
check: HDWallet = HDWallet(symbol=SYMBOL)
check.from_xprivate_key(xprivate_key=MASTER_EXTENDED_PRIVATE_KEY, strict=True) # False allows you to initialize from a non-root extended key
check.from_path(&quot;m/44/0/0/1/402&quot;)
print(&quot;Check   (m/44/0/0/1/402):&quot;, check.xprivate_key())
</code></pre>
<p>Firstly, two caveats:</p>
<ol>
<li>I'm not very good at Python, and I've not used the <code>hdwallet</code> or <code>bitcoin-utils</code> Python libraries before.</li>
<li>There aren't any built-in methods in these libraries for this, so I worked with what was available. I had to perform some steps manually (e.g. converting a raw private key in to an address).</li>
</ol>
<p>So basically the code is very rough, and I just did the bare minimum to get it working.</p>
<p>Secondly, I've only worked out the extended private key at the <code>m/44/0/0/1</code> level of the tree. This allows you to work out all the child keys below that level only.</p>
<p>Therefore, if you wanted to calculate a child extended private key at <code>m/44/0/0/0/402</code> for example, you would need to work backwards again to calculate the extended private key at <code>m/44/0/0</code> first. This can be achieved by calculating the extended public key at <code>m/44/0/0</code> (from the master extended public key), then using this along with the newly-calculated extended private key at <code>m/44/0/0/1</code> to calculate the parent extended private key above it at <code>m/44/0/0</code>. From here you can then derive down to <code>m/44/0/0/0/402</code>.</p>
<p>The above can be achieved by repeating the relevant parts of code.</p>
<p>I haven't given the exact solution to your challenge, as I didn't want take away from the learning experience, and this contains the code you need to get started.</p>
<p>In fairness, this is a fairly complex challenge that requires understanding of how HD Wallets work, and it's not something that you would be able to solve using the default functions found within a library. It would probably beneficial to write your own library for this kind of stuff.</p>
<p>Nonetheless, hopefully this code helps to get you on the right track.</p>
<p>This page explains some of the details: <a href="https://learnmeabitcoin.com/technical/extended-keys" rel="nofollow noreferrer">https://learnmeabitcoin.com/technical/extended-keys</a></p>
<hr />
<h2>Old reply</h2>
<p>Using a modified version of the example code from here: <a href="https://github.com/meherett/python-hdwallet/blob/master/examples/from_xprivate_key.py" rel="nofollow noreferrer">https://github.com/meherett/python-hdwallet/blob/master/examples/from_xprivate_key.py</a></p>
<pre><code>#!/usr/bin/env python3

from hdwallet import HDWallet as HDWallet
from hdwallet.symbols import BTC as SYMBOL

# Bitcoin root xprivate key
XPRIVATE_KEY: str = &quot;xprv9s21ZrQH143K2YnaaxJdFLkCYbdcpGcQuz29YmLB5ejUFiCABpeKAkUSXVuqysESjMJhk8yTfhxR3BT6Ag7Z5fYJ1jFgidmrGgfZYNCLnNB&quot;

# Initialize Bitcoin mainnet HDWallet
hdwallet: HDWallet = HDWallet(symbol=SYMBOL)

# Get Bitcoin HDWallet from xprivate key
hdwallet.from_xprivate_key(xprivate_key=XPRIVATE_KEY, strict=True)

# Derivation from path
hdwallet.from_path(&quot;m/44/0/0/1/404&quot;)

# Print results
print(&quot;Root XPrivate Key:&quot;, hdwallet.root_xprivate_key())
print(&quot;XPrivate Key:&quot;, hdwallet.xprivate_key())
</code></pre>
<p>You will need to replace the master extended private key with your own. This code just contains an example for testing.</p>
<p>I haven't used this library before, so I can't explain too much about how to use it. But this example should get you going.</p>
<p><strong>EDIT:</strong></p>
<p>Sorry I just realized your asking to derive an extended private key from a master extended public key.</p>
<p>It's not possible to derive private keys from a master extended public key in a HD wallet. Are you sure this is what you're being asked to do with this challenge?</p>

CC BY-SA 4.0
2024-01-06T22:55:35.210Z
Given a parent xpub, and a child private key that is (non-hardened) derived from it, one can compute the parent xprv. This is pointed out in BIP32, and is the reason why hardened derivation exists.
Pieter Wuille
CC BY-SA 4.0
2024-01-07T10:53:57.047Z
Hello @inersha, Thanks for responding to my post. I apologise I think I was not able to explain my problem properly check my question I've modified and added exact problem statement.
Ankit Tiwari
CC BY-SA 4.0
2024-01-07T11:20:38.333Z
@PieterWuille Thank you, I didn't realize a private key was also being given away.
inersha
CC BY-SA 4.0
2024-01-07T14:03:03.350Z
Hi @inersha, I've updated my question can you please check.
Ankit Tiwari
CC BY-SA 4.0
2024-01-07T21:14:50.167Z
@AnkitTiwari I've updated my reply. Sorry for the delay and my misunderstanding.
inersha
CC BY-SA 4.0
2024-01-08T07:20:08.913Z
Hello @inersha, Thanks for your answer it's working. I wanted to know is it possible to get private key of this path `m/44/0/0/0/402` without need to find parent `xpriv` just by using parent `xpub` & child `xpriv`?
Ankit Tiwari
CC BY-SA 4.0
2024-01-08T12:30:37.790Z
@AnkitTiwari You've only got the extended private key for `m/44/0/0/1` for now, so this can only generate children for `m/44/0/0/1/X`. To work out keys within `m/44/0/0/0/X`, you would need to work out the extended private key for `m/44/0/0`. This can be done by re-using the script, but this time calculating the parent extended public key at `m/44/0/0`, and using the newly-calculated child extended private key at `m/44/0/0/1`. You will then have the extended private key for `m/44/0/0`, which can be used to derive down to `m/44/0/0/0/402`. So you basically need to go a level up the tree first.
inersha
CC BY-SA 4.0
2024-01-08T13:00:40.807Z
@AnkitTiwari The parent extended private key you calculate for `m/44/0/0` should be `xprv9z75bqka4L6nQrCX2vJBLWpX8dhkJEDJSAASarQhZ46YFxw7xEukKTiJ5XJSzkREMVLKkWYM1upX3g3vtEVE1X6SgMZcVvupzbtaxUWUfvY`
inersha
CC BY-SA 4.0
2024-01-06T22:31:30.257Z
2024-01-07T21:14:20.700Z
2024-01-07T21:14:20.700Z
inersha
<p>I am currently working on a challenge that involves deriving a non-hardened extended private key for a specific search path in Bitcoin. The challenge provides the following information:</p>
<p>Bitcoin root extended public key (starting with xpub...)
Bitcoin non-hardened extended private key for the derivation path <strong><code>m/44/0/0/1/404</code></strong> (starting with xprv...)
Search path for which I need to derive the associated (non-hardened) extended private key: <strong><code>m/44/0/0/0/402</code></strong>
The task is to derive the non-hardened extended private key for the given search path, and the submission should be encoded as per the BIP 32 specification.</p>
<p>I've attempted to use the <a href="https://pypi.org/project/pycoin/" rel="nofollow noreferrer"><code>pycoin</code></a> and <a href="https://github.com/meherett/python-hdwallet" rel="nofollow noreferrer"><code>python-hdwallet</code></a> libraries, but I'm facing difficulties understanding the process and obtaining the correct result. Could someone provide guidance or a step-by-step approach on how to achieve this using these libraries or any other relevant tools?</p>
<p>Additionally, if there are specific functions or methods within these libraries that are suitable for this task, please provide examples to help me grasp the implementation better.</p>
<p>I appreciate any assistance and clarification on this matter. Thank you!</p>
<h2>Update</h2>
<p>Here's the original problem statement:</p>
<blockquote>
<p>The challenge data consists of: A Bitcoin root extended public key
(for the derivation path m, as it is the root) starting with xpub... A
Bitcoin non-hardened extended private key for the derivation path
m/44/0/0/1/404 starting with  xprv... A search path for which you have
to derive the associated (non-hardened) extended private key (as a
string). This path will be something like: m/44/0/0/0/402 Your task is
it to derive the non-hardened extended private key for this search
path, this is your flag. Your  submission of the searched extended
private key should be encoded as the one you received from the
server, i.e., serialized string starting with xprv... according to the
specification in BIP 39.</p>
</blockquote>

CC BY-SA 4.0
2024-01-05T22:56:23.313Z
Does https://bitcoin.stackexchange.com/questions/56916/derivation-of-parent-private-key-from-non-hardened-child/56921#56921 answer your question?
Ava Chow
CC BY-SA 4.0
2024-01-06T14:18:25.537Z
Hello @AvaChow, Yes I want same like that but I don't know how it's done using python can you provide me some guidance please.
Ankit Tiwari
CC BY-SA 4.0
2024-01-07T15:38:09.367Z
Try with [this answer](https://bitcoin.stackexchange.com/questions/120036/i-need-to-get-btc-addresses-from-a-12-word-phrase-but-i-dont-understand-what-t/120046#120046). I wrote it for BIP84, but the process is same, just change the path.
dassd
CC BY-SA 4.0
2024-01-10T21:53:48.820Z
Wasn't aware of this answer from @AvaChow. Nice. Was going to share https://bitcoin.stackexchange.com/a/117823/101498 but i think we can close it in favour of hers.
Antoine Poinsot
<bip32-hd-wallets><python><xpub><pycoin>
Need Help Deriving Extended Private Key from Bitcoin Root Extended Public Key and Non-Hardened Extended Private Key
Ankit Tiwari
# Need Help Deriving Extended Private Key from Bitcoin Root Extended Public Key and Non-Hardened Extended Private Key

(Asked by: username_0 on 2024-01-03)

I am currently working on a challenge that involves deriving a non-hardened extended private key for a specific search path in Bitcoin. The challenge provides the following information:

Bitcoin root extended public key (starting with xpub...)
Bitcoin non-hardened extended private key for the derivation path **`m/44/0/0/1/404`** (starting with xprv...)
Search path for which I need to derive the associated (non-hardened) extended private key: **`m/44/0/0/0/402`**
The task is to derive the non-hardened extended private key for the given search path, and the submission should be encoded as per the BIP 32 specification.

I've attempted to use the [`pycoin`](https://pypi.org/project/pycoin/) and [`python-hdwallet`](https://github.com/meherett/python-hdwallet) libraries, but I'm facing difficulties understanding the process and obtaining the correct result. Could someone provide guidance or a step-by-step approach on how to achieve this using these libraries or any other relevant tools?

Additionally, if there are specific functions or methods within these libraries that are suitable for this task, please provide examples to help me grasp the implementation better.

I appreciate any assistance and clarification on this matter. Thank you!

## Update

Here's the original problem statement:

> The challenge data consists of: A Bitcoin root extended public key
> (for the derivation path m, as it is the root) starting with xpub... A
> Bitcoin non-hardened extended private key for the derivation path
> m/44/0/0/1/404 starting with xprv... A search path for which you have
> to derive the associated (non-hardened) extended private key (as a
> string). This path will be something like: m/44/0/0/0/402 Your task is
> it to derive the non-hardened extended private key for this search
> path, this is your flag. Your submission of the searched extended
> private key should be encoded as the one you received from the
> server, i.e., serialized string starting with xprv... according to the
> specification in BIP 39.

**Tags:** bip32-hd-wallets, python, xpub, pycoin

> **Comments:**
> **username_1**: Does https://bitcoin.stackexchange.com/questions/56916/derivation-of-parent-private-key-from-non-hardened-child/56921#56921 answer your question?  
> **username_0**: Hello @username_1, Yes I want same like that but I don't know how it's done using python can you provide me some guidance please.  
> **username_2**: Try with [this answer](https://bitcoin.stackexchange.com/questions/120036/i-need-to-get-btc-addresses-from-a-12-word-phrase-but-i-dont-understand-what-t/120046#120046). I wrote it for BIP84, but the process is same, just change the path.  
> **username_3**: Wasn't aware of this answer from @username_1. Nice. Was going to share https://bitcoin.stackexchange.com/a/117823/101498 but i think we can close it in favour of hers.  

---

## 1 answers

### Answer by username_4 on 2024-01-06. Score: 2 | Accepted answer

Here's some working code for calculating a **parent extended private key** from a **master extended public key** and **child extended private key**.

```
#!/usr/bin/env python3

# pip install hdwallet
# pip install bitcoin-utils

import hmac
import hashlib
import struct
from binascii import  unhexlify
from base58check import b58encode
from hdwallet import HDWallet as HDWallet
from hdwallet.symbols import BTC as SYMBOL

# --------------------
# Provided information
# --------------------

# Master Extended Public Key (m)
MASTER_EXTENDED_PUBLIC_KEY: str = "xpub661MyMwAqRbcF2s3gyqdcUgw6dU7DjLGHCwkM9jndzGT8WXJjMxZiYnvNmfuzsEXC13FUn9BTeefy3uYf4Cj5k86iHUFzLS1yatpXN9hq4u"

# Child Extended Private Key (m/44/0/0/1/404)
CHILD_EXTENDED_PRIVATE_KEY: str = "xprvA3WvYTa5Xv4kSXuL9mAFMimc5psTTB1Dq8x4q9HB7R4EmpufsXFuhi9SpVVYXsmyjM5dvoGowU3W9hDuYRrgkQiiE1d881TZrFLhLNxBs7g"

# ------
# Method
# ------

# Initialize a wallet
hdwallet: HDWallet = HDWallet(symbol=SYMBOL)

# Create a HDWallet from the master extended public key
hdwallet.from_xpublic_key(xpublic_key=MASTER_EXTENDED_PUBLIC_KEY, strict=True)

# Get the parent extended public key at m/44/0/0/1
# We need this so that we can calculate the extended private key at m/44/0/0/1 (the level above the child private key that has been revealed)
PARENT_EXTENDED_PUBLIC_KEY = hdwallet.from_path("m/44/0/0/1")
PARENT_PUBLIC_KEY: str = PARENT_EXTENDED_PUBLIC_KEY.public_key()
PARENT_CHAIN_CODE: str = PARENT_EXTENDED_PUBLIC_KEY.chain_code()
print("Parent Extended Public Key (m/44/0/0/1):", PARENT_EXTENDED_PUBLIC_KEY.xpublic_key())
print("  Public Key:", PARENT_PUBLIC_KEY)
print("  Chain Code:", PARENT_CHAIN_CODE)
print("")

# Extract the raw private key from the child extended private key m/44/0/0/1/404
# We need this so that we can calculate the parent extended private key
child: HDWallet = HDWallet(symbol=SYMBOL)
child.from_xprivate_key(xprivate_key=CHILD_EXTENDED_PRIVATE_KEY, strict=False) # False allows you to initialize from a non-root extended key
CHILD_PRIVATE_KEY: str = child.private_key()
print("Child Private Key:", CHILD_PRIVATE_KEY)
print("")

# Calculate the parent extended private key for m/44/0/0/1 (this is the mathematical bit)

# Put the chain code and (parent public key + index) through HMAC-SHA512
# This step is used in HD Wallets when deriving non-hardened children for both private and public extended keys
index = struct.pack(">L", 404) # Use the same index number as the child extended private key that we know
data = unhexlify(PARENT_PUBLIC_KEY) + index
hmac_result = hmac.new(unhexlify(PARENT_CHAIN_CODE), data, hashlib.sha512).hexdigest()

# Get the left side of the hmac digest (the left 32 bytes)
hmac_result_left = hmac_result[:64]

# Calculate the parent private key (child private key - hmac left)
# Note: All private keys must be modulo the number of points on the Secp256k1 curve
secp256k1_n = 115792089237316195423570985008687907852837564279074904382605163141518161494337
PARENT_PRIVATE_KEY: str = ((int(CHILD_PRIVATE_KEY, 16) - int(hmac_result_left, 16)) % secp256k1_n).to_bytes(32, "big").hex()
print("Parent Private Key:", PARENT_PRIVATE_KEY)

# Create an address for the parent extended private key
# This is so that we can intialize a new HD Wallet using the extended private key and use it to derive children easily using the library

# Get the fingerprint, which can be found from the parent of this parent extended public key
parent_parent_extended_public_key: HDWallet = HDWallet(symbol=SYMBOL)
parent_parent_extended_public_key.from_xpublic_key(xpublic_key=MASTER_EXTENDED_PUBLIC_KEY, strict=True)
parent_fingerprint = parent_parent_extended_public_key.from_path("m/44/0/0").finger_print()

# Serialize all the data for the parent extended private key
version = "0488ade4" # xprv (BIP)
depth = "04" # how many levels deep this extended key is from master, so m/44/0/0/1 = 4
index = "00000001" # the index number of this extended key from its parent, which is the last number of m/44/0/0/1
chain_code = PARENT_CHAIN_CODE
data = "00" + PARENT_PRIVATE_KEY
raw = (version + depth + parent_fingerprint + index + chain_code + data)

# Create a checksum for this serialized data (first 4 bytes of the hash256 of the raw data above)
checksum = hashlib.sha256(hashlib.sha256(unhexlify(raw)).digest()).hexdigest()[0:8]

# Create address by converting to base58
PARENT_EXTENDED_PRIVATE_KEY = b58encode(unhexlify(raw + checksum)).decode("utf-8")
print("Parent Extended Private Key (m/44/0/0/1):", PARENT_EXTENDED_PRIVATE_KEY)
print("")

# -----
# Usage
# -----

# Now that we've calculated the extended private key for m/44/0/0/1, we can calculate all of the child keys below it.
# For example, we can calculate the extended private key at m/44/0/0/1/402

# Initialize a new wallet from the address for this parent extended private key at m/44/0/0/1
parent: HDWallet = HDWallet(symbol=SYMBOL)
parent.from_xprivate_key(xprivate_key=PARENT_EXTENDED_PRIVATE_KEY, strict=False) # False allows you to initialize from a non-root extended key

# Derive the extended private key at m/44/0/0/1/402
example = parent.from_path("m/402") # Note: This is m/44/0/0/1/402, because we are starting from m/44/0/0/1
print("Example (m/44/0/0/1/402):", example.xprivate_key())

# ------
# Checks
# ------

# I already knew the master extended private key for this wallet, so we can use it to check that it derives the same extended private key at m/44/0/0/1/402 as the parent extended private key we calculated.

MASTER_EXTENDED_PRIVATE_KEY: str = "xprv9s21ZrQH143K2YnaaxJdFLkCYbdcpGcQuz29YmLB5ejUFiCABpeKAkUSXVuqysESjMJhk8yTfhxR3BT6Ag7Z5fYJ1jFgidmrGgfZYNCLnNB"
check: HDWallet = HDWallet(symbol=SYMBOL)
check.from_xprivate_key(xprivate_key=MASTER_EXTENDED_PRIVATE_KEY, strict=True) # False allows you to initialize from a non-root extended key
check.from_path("m/44/0/0/1/402")
print("Check   (m/44/0/0/1/402):", check.xprivate_key())

```

Firstly, two caveats:

1. I'm not very good at Python, and I've not used the `hdwallet` or `bitcoin-utils` Python libraries before.
2. There aren't any built-in methods in these libraries for this, so I worked with what was available. I had to perform some steps manually (e.g. converting a raw private key in to an address).

So basically the code is very rough, and I just did the bare minimum to get it working.

Secondly, I've only worked out the extended private key at the `m/44/0/0/1` level of the tree. This allows you to work out all the child keys below that level only.

Therefore, if you wanted to calculate a child extended private key at `m/44/0/0/0/402` for example, you would need to work backwards again to calculate the extended private key at `m/44/0/0` first. This can be achieved by calculating the extended public key at `m/44/0/0` (from the master extended public key), then using this along with the newly-calculated extended private key at `m/44/0/0/1` to calculate the parent extended private key above it at `m/44/0/0`. From here you can then derive down to `m/44/0/0/0/402`.

The above can be achieved by repeating the relevant parts of code.

I haven't given the exact solution to your challenge, as I didn't want take away from the learning experience, and this contains the code you need to get started.

In fairness, this is a fairly complex challenge that requires understanding of how HD Wallets work, and it's not something that you would be able to solve using the default functions found within a library. It would probably beneficial to write your own library for this kind of stuff.

Nonetheless, hopefully this code helps to get you on the right track.

This page explains some of the details: <https://learnmeabitcoin.com/technical/extended-keys>

---

## Old reply

Using a modified version of the example code from here: <https://github.com/meherett/python-hdwallet/blob/master/examples/from_xprivate_key.py>

```
#!/usr/bin/env python3

from hdwallet import HDWallet as HDWallet
from hdwallet.symbols import BTC as SYMBOL

# Bitcoin root xprivate key
XPRIVATE_KEY: str = "xprv9s21ZrQH143K2YnaaxJdFLkCYbdcpGcQuz29YmLB5ejUFiCABpeKAkUSXVuqysESjMJhk8yTfhxR3BT6Ag7Z5fYJ1jFgidmrGgfZYNCLnNB"

# Initialize Bitcoin mainnet HDWallet
hdwallet: HDWallet = HDWallet(symbol=SYMBOL)

# Get Bitcoin HDWallet from xprivate key
hdwallet.from_xprivate_key(xprivate_key=XPRIVATE_KEY, strict=True)

# Derivation from path
hdwallet.from_path("m/44/0/0/1/404")

# Print results
print("Root XPrivate Key:", hdwallet.root_xprivate_key())
print("XPrivate Key:", hdwallet.xprivate_key())

```

You will need to replace the master extended private key with your own. This code just contains an example for testing.

I haven't used this library before, so I can't explain too much about how to use it. But this example should get you going.

**EDIT:**

Sorry I just realized your asking to derive an extended private key from a master extended public key.

It's not possible to derive private keys from a master extended public key in a HD wallet. Are you sure this is what you're being asked to do with this challenge?

> **Comments:**
> **username_5**: Given a parent xpub, and a child private key that is (non-hardened) derived from it, one can compute the parent xprv. This is pointed out in BIP32, and is the reason why hardened derivation exists.  
> **username_0**: Hello @username_4, Thanks for responding to my post. I apologise I think I was not able to explain my problem properly check my question I've modified and added exact problem statement.  
> **username_4**: @username_5 Thank you, I didn't realize a private key was also being given away.  
> **username_0**: Hi @username_4, I've updated my question can you please check.  
> **username_4**: @username_0 I've updated my reply. Sorry for the delay and my misunderstanding.  
> **username_0**: Hello @username_4, Thanks for your answer it's working. I wanted to know is it possible to get private key of this path `m/44/0/0/0/402` without need to find parent `xpriv` just by using parent `xpub` & child `xpriv`?  
> **username_4**: @username_0 You've only got the extended private key for `m/44/0/0/1` for now, so this can only generate children for `m/44/0/0/1/X`. To work out keys within `m/44/0/0/0/X`, you would need to work out the extended private key for `m/44/0/0`. This can be done by re-using the script, but this time calculating the parent extended public key at `m/44/0/0`, and using the newly-calculated child extended private key at `m/44/0/0/1`. You will then have the extended private key for `m/44/0/0`, which can be used to derive down to `m/44/0/0/0/402`. So you basically need to go a level up the tree first.  
> **username_4**: @username_0 The parent extended private key you calculate for `m/44/0/0` should be `xprv9z75bqka4L6nQrCX2vJBLWpX8dhkJEDJSAASarQhZ46YFxw7xEukKTiJ5XJSzkREMVLKkWYM1upX3g3vtEVE1X6SgMZcVvupzbtaxUWUfvY`  

---

