I am trying to recover the extended BIP32 master private key from its extended BIP32 public key (which I already know) and a WIF private key (which I obtained by decrypting a BIP38 seed with a passphrase).

I followed the steps described in this article from Vitalik Buterin, but to use the crack_bip32_privkey function in pybitcointools, I need to have a private key in BIP32 format (not WIF). I can see how to obtain a BIP32 private master key from a BIP32 seed (with bip32_master_key), but not how to do the same from a private key in WIF format.

How can I convert the WIF Private key into a BIP 32 private key (with Python, .NET or Javascript)?


You can't. The BIP 32 extended private key format contains information which is not present in the WIF private key. The extended private key format contains the chaincode of the private key, the index, and the parent fingerprint. Those information come from the derivation of the private key itself and cannot be found elsewhere.

In order to get the parent public key, the only information that you need from the extended public key is the index of the child. This can be trivially found by simply brute forcing through all possible child indexes (2^31 - 1 indexes) until you get a master private key which has a public key that matches the parent public key, or until you have derived the correct child public key from the parent public key.

Here is code that will find you the parent private key. This does the first technique of cycling through possible parent private keys until one is found which has a public key that matches the parent public key. Note that this may be completely inefficient and may take a long time to find a key. Also note that this only works if the child key is directly derived from the parent, not some depth down in the derivation tree.

from pybitcointools.deterministic import raw_crack_bip32_privkey, bip32_deserialize, bip32_serialize, bip32_privtopub
from pybitcointools.main import decode_privkey, encode_privkey

parent_pub = 'xpub661MyMwAqRbcEnKbXcCqD2GT1di5zQxVqoHPAgHNe8dv5JP8gWmDproS6kFHJnLZd23tWevhdn4urGJ6b264DfTGKr8zjmYDjyDTi9U7iyT'
wif_key = encode_privkey(decode_privkey('KyqcQVzcp7cHEMEDHQaz5eaE5azsRHaE4ukkeqwM2vdiQwBYtxeb'), 'bin_compressed')
for i in xrange(2**31 -1):
    priv = (b'\x04\x88\xAD\xE4', 1, 0, i, b'', wif_key)
    pkey =  raw_crack_bip32_privkey(bip32_deserialize(parent_pub), priv)
    final_key = bip32_serialize(pkey)
    if bip32_privtopub(final_key) == parent_pub:
        print final_key
  • Excellent, this is exactly what I needed. Any idea on how to make it complete faster (e.g. days)? Right now it is going to take years :(. I looked into Cython but I would have to cythonize all the dependencies where time is spent. If you knew how to do this directly with the standard Bitcoin C++ library instead of Python that would be awesome. – Erwin Mayer Jul 27 '17 at 4:33
  • It shouldn't take more than a couple of seconds unless your key has a really high index. However if the key is at a depth of more than 1 (i.e. the key is derived from a pubkey that is derived from the parent pubkey and so on) or it is hardened, then the process will loop until all possible indexes are exhausted and it exits with no key found. I suspect that is the case here. To deal with that, you should make sure the key is not hardened, and make sure that you are at the right depth. If not, you will have to derive public keys until you are. – Andrew Chow Jul 27 '17 at 6:03
  • OK, thanks a lot for the advice. I am actually using the two seeds and pubkeys (with depth 0, and "Bitcoin Master Public Key" as per bip32.org provided by Coinbase when generating a multi-sig vault. For each seed, I have been able to retrieve the WIF privkey, but its associated address is not the same as the address derived from the pubkey (with derivation path "Simple: m/i" and the correct index i which I know). So it seems the privkey I have is not the "Master private key", which I would need to derive the private key that has exactly the same address as the pubKey. – Erwin Mayer Jul 27 '17 at 7:12
  • Without the right private key, I am unable to sign a message proving that I own the address associated with the public key. – Erwin Mayer Jul 27 '17 at 7:12
  • 1
    This looks like a case of an XY problem: xyproblem.info. Having the two pubkeys and the coinbase user private key should still allow you to get the information you need, just not with the method you want to use. Since this is kind of off topic now, I suggest that you make a new question asking exactly what you want to do, not what you thought would work to get what you wanted to do. – Andrew Chow Jul 27 '17 at 18:26

Your Answer

