2

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)?

Erwin Mayer
  • 175
  • 2
  • 13
  • You've already asked this question, and it was closed as a duplicate of https://bitcoin.stackexchange.com/questions/56916/derivation-of-parent-private-key-from-non-hardened-child . – Pieter Wuille Jul 25 '17 at 05:22
  • I have edited the question with what he actually wanted to ask about: https://bitcoin.stackexchange.com/questions/56916/derivation-of-parent-private-key-from-non-hardened-child/56921?noredirect=1#comment65158_56921 – Ava Chow Jul 26 '17 at 01:47

1 Answers1

4

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
        break
Ava Chow
  • 70,382
  • 5
  • 81
  • 161
  • 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 04: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. – Ava Chow Jul 27 '17 at 06: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 http://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 07: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 07:12
  • What are you talking about and how is it related to this question? – Ava Chow Jul 27 '17 at 07:38
  • Sorry for the confusion. I am just trying to provide some background information about how the keys have been generated initially. The objective of my question is to obtain a privkey for which the address is the same as the address of the derived pubkey at index m/14. – Erwin Mayer Jul 27 '17 at 15:14
  • Right now I have: (1) a master pubkey in BIP32 extended format (provided by Coinbase), (2) a derived pubkey at index m/14 that corresponds to the address for which I need to prove ownership, (3) a private key in WIF format (provided by Coinbase when generating the vault, I don't know if it is hardened, nor the depth). – Erwin Mayer Jul 27 '17 at 15:19
  • I am not sure how to enter them in your script and which parameters to change in the line priv = (b'\x04\x88\xAD\xE4', 1, 0, i, b'', wif_key) to obtain the BIP32 private key that will have the same address as the derived pubkey. – Erwin Mayer Jul 27 '17 at 15:20
  • 1
    This looks like a case of an XY problem: http://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. – Ava Chow Jul 27 '17 at 18:26
  • Anyways, I'm guessing (not sure as I don't have access to my coinbase account right now to check) that the user key they give you is a private key which is then used to derive the private key that corresponds to the master public key they gave you. That derivation is probably a hardened derivation and likely uses the BIP 44 derivation path. So you should be able to just derive the private key that corresponds to the public key by using the BIP 44 derivation path, and from there just derive the private key that you need. – Ava Chow Jul 27 '17 at 18:38
  • You're exactly right. I tried to generalize my problem but probably shouldn't have. I have posted the more appropriate question here: https://bitcoin.stackexchange.com/questions/57207/how-to-derive-the-private-key-associated-with-a-coinbase-multi-sig-vault-address. Thanks a lot for your help. – Erwin Mayer Jul 28 '17 at 03:43