<p>First we must understand how BIP 32 derives non-hardened private and public keys.</p>
<p>From BIP 32, deriving a child private key from an extended parent private key:</p>
<blockquote>
<p>let I = HMAC-SHA512(Key = c<sub>par</sub>, Data = ser<sub>P</sub>(point(k<sub>par</sub>))) || ser32(i)).</p>
<p>Split I into two 32-byte sequences, I<sub>L</sub> and I<sub>R</sub>.</p>
<p>The returned child key K<sub>i</sub> is parse<sub>256</sub>(I<sub>L</sub>) + k<sub>par</sub> (mod n).</p>
</blockquote>
<p>The private key is thus the parent private key plus the first 256 bits of the HMAC-SHA512 function where the key is the chaincode of the parent private key and the hashed data is the concatenation of the serialization of the public key that corresponds to the extended private key and the child key index. The important thing here to note is that the HMAC-SHA512 hash is a <strong>hash of the public key, not the private key.</strong></p>
<p>From BIP 32, deriving a child public key from an extended parent public key:</p>
<blockquote>
<p>let I = HMAC-SHA512(Key = c<sub>par</sub>, Data = ser<sub>P</sub>(K<sub>par</sub>) || ser32(i)).</p>
<p>Split I into two 32-byte sequences, I<sub>L</sub> and I<sub>R</sub>.</p>
<p>The returned child key K<sub>i</sub> is point(parse<sub>256</sub>(I<sub>L</sub>)) + K<sub>par</sub>.</p>
</blockquote>
<p>The child public key is the parent public key added with the public key generated from the first 256 bits of the HMAC-SHA512 function where the key is the chaincode of the parent key and data is the concatenation of the parent public key with the index of the child public key.</p>
<p>Notice how when deriving the child private key and the child public key you are actually hashing the same thing? You are performing the HMAC-SHA512 function with the same key (the chaincode of the parent keys) and the same data (the concatenation of the parent public key and the index of the child key). The first 256 bits of that hash become a private key of sorts, and that private key is added to the master private key to become the actual child private key. Its public key is calculated and added with the parent public key to become the child public key.</p>
<p>So to get the master private key, all we need to do is take the child private key that we now have, and subtract from it the private key produced by the HMAC-SHA512 function. To do that, we need three things, the chaincode, the parent public key, and the child key index.</p>
<p>The chaincode and parent public key come from the extended parent public key (<code>xpub</code>) as it encodes both the chaincode and the public key in it.</p>
<p>The child key index can be trivially found by deriving child public keys from the parent public key until we get the public key which corresponds to the child private key that we have and save the key index.</p>
<p>With these three things, we can perform the HMAC-SHA512 function and get the 512 bit hash. Now we can take the child private key and subtract from it the integer that is the first 256 bits of the hash we just generated. Our result is the parent private key. Combine that with the chaincode that we retrieved from the extended parent public key and we have ourselves the extended parent private key.</p>
<hr />
<p>This technique only applies to non-hardened derivation. Hardened derivation protects against this because it generates the child private key by hashing the parent private key. However this also means that you cannot generate the child public key from the parent public key.</p>

CC BY-SA 3.0
2017-07-25T04:38:31.063Z
Can you clarify how this topic is a duplicate of my question here: https://bitcoin.stackexchange.com/questions/57023/recover-the-extended-bip32-master-private-key-from-its-extended-bip32-public-key
The topic is similar but your answer, while great here, wouldn't be suitable for my question.
Erwin Mayer
CC BY-SA 3.0
2017-07-25T04:49:00.290Z
You are asking how to get the extended master private key from the master public key and child private key. The steps to do so are explained here. The only other addition to your question is about WIF and xpub format. Those are just encodings of binary data, so just decode them to get the raw values and perform the operations described in this answer.
Ava Chow
CC BY-SA 3.0
2017-07-26T01:33:00.373Z
Thanks, how to go from a BIP32 seed to a xpub address using Python is precisely my question (sorry if this looks trivial to you), since pybitcointools already has a convenience function to perform the key derivation you outline in your answer (but it requires keys in xpub format). My understanding, at least on Stackoverflow, is that a question should be marked as duplicate only if it can be fully satisfied by the answer of another question, which doesn't seem to be the case here.
Erwin Mayer
CC BY-SA 3.0
2017-07-26T01:42:49.187Z
That may have been the question you intended to ask, but that was not that question that was actually asked. Your question was "Recover the extended BIP32 master private key ..." not "How to get the xprv from a wif key". Your question really shouldn't mention "recover extended master private key" at all as that is unrelated to what you actually want to know about.
Ava Chow
CC BY-SA 3.0
2017-07-21T08:13:23.360Z
2017-07-21T08:13:23.360Z
2020-06-16T11:10:03.350Z
Ava Chow
<p>Quote from <a href="https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki" rel="noreferrer">BIP 32</a>:</p>

<blockquote>
  <p>One weakness that may not be immediately obvious, is that knowledge of a parent extended public key plus any non-hardened private key descending from it is equivalent to knowing the parent extended private key (and thus every private and public key descending from it). </p>
</blockquote>

<p>How is this done?</p>

<bip32-hd-wallets><deterministic-wallets>
Derivation of parent private key from non-hardened child
meshcollider
# Derivation of parent private key from non-hardened child

(Asked by: username_0 on 2017-07-21)

Quote from [BIP 32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki):

> One weakness that may not be immediately obvious, is that knowledge of a parent extended public key plus any non-hardened private key descending from it is equivalent to knowing the parent extended private key (and thus every private and public key descending from it).

How is this done?

**Tags:** bip32-hd-wallets, deterministic-wallets


---

## 1 answers

### Answer by username_1 on 2017-07-21. Score: 26 | Accepted answer

First we must understand how BIP 32 derives non-hardened private and public keys.

From BIP 32, deriving a child private key from an extended parent private key:

> let I = HMAC-SHA512(Key = cpar, Data = serP(point(kpar))) || ser32(i)).
>
> Split I into two 32-byte sequences, IL and IR.
>
> The returned child key Ki is parse256(IL) + kpar (mod n).

The private key is thus the parent private key plus the first 256 bits of the HMAC-SHA512 function where the key is the chaincode of the parent private key and the hashed data is the concatenation of the serialization of the public key that corresponds to the extended private key and the child key index. The important thing here to note is that the HMAC-SHA512 hash is a **hash of the public key, not the private key.**

From BIP 32, deriving a child public key from an extended parent public key:

> let I = HMAC-SHA512(Key = cpar, Data = serP(Kpar) || ser32(i)).
>
> Split I into two 32-byte sequences, IL and IR.
>
> The returned child key Ki is point(parse256(IL)) + Kpar.

The child public key is the parent public key added with the public key generated from the first 256 bits of the HMAC-SHA512 function where the key is the chaincode of the parent key and data is the concatenation of the parent public key with the index of the child public key.

Notice how when deriving the child private key and the child public key you are actually hashing the same thing? You are performing the HMAC-SHA512 function with the same key (the chaincode of the parent keys) and the same data (the concatenation of the parent public key and the index of the child key). The first 256 bits of that hash become a private key of sorts, and that private key is added to the master private key to become the actual child private key. Its public key is calculated and added with the parent public key to become the child public key.

So to get the master private key, all we need to do is take the child private key that we now have, and subtract from it the private key produced by the HMAC-SHA512 function. To do that, we need three things, the chaincode, the parent public key, and the child key index.

The chaincode and parent public key come from the extended parent public key (`xpub`) as it encodes both the chaincode and the public key in it.

The child key index can be trivially found by deriving child public keys from the parent public key until we get the public key which corresponds to the child private key that we have and save the key index.

With these three things, we can perform the HMAC-SHA512 function and get the 512 bit hash. Now we can take the child private key and subtract from it the integer that is the first 256 bits of the hash we just generated. Our result is the parent private key. Combine that with the chaincode that we retrieved from the extended parent public key and we have ourselves the extended parent private key.

---

This technique only applies to non-hardened derivation. Hardened derivation protects against this because it generates the child private key by hashing the parent private key. However this also means that you cannot generate the child public key from the parent public key.

> **Comments:**
> **username_2**: Can you clarify how this topic is a duplicate of my question here: https://bitcoin.stackexchange.com/questions/57023/recover-the-extended-bip32-master-private-key-from-its-extended-bip32-public-key The topic is similar but your answer, while great here, wouldn't be suitable for my question.  
> **username_1**: You are asking how to get the extended master private key from the master public key and child private key. The steps to do so are explained here. The only other addition to your question is about WIF and xpub format. Those are just encodings of binary data, so just decode them to get the raw values and perform the operations described in this answer.  
> **username_2**: Thanks, how to go from a BIP32 seed to a xpub address using Python is precisely my question (sorry if this looks trivial to you), since pybitcointools already has a convenience function to perform the key derivation you outline in your answer (but it requires keys in xpub format). My understanding, at least on Stackoverflow, is that a question should be marked as duplicate only if it can be fully satisfied by the answer of another question, which doesn't seem to be the case here.  
> **username_1**: That may have been the question you intended to ask, but that was not that question that was actually asked. Your question was "Recover the extended BIP32 master private key ..." not "How to get the xprv from a wif key". Your question really shouldn't mention "recover extended master private key" at all as that is unrelated to what you actually want to know about.  

---

