ebellocchia / bip_utils

Generation of mnemonics, seeds, private/public keys and addresses for different types of cryptocurrencies

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Deriving a bip44 address with chain code and PrivateKey swapped

Anynomouss opened this issue · comments

Is it possible to derive a BIP44 wallet with the chain-code and private key swapped?

So instead of the normal:

xpriv = [version][depth][fingerprint][child number][chain code][0x00 || private key]

Change to:
xpriv = [version][depth][fingerprint][child number][private key][0x00 || chain code]

This change in derivation is needed to recover a special wallet. If successful in recovery there are some beers in it for you because bip-utils has proven to be very useful so far.

Hi,
sorry for the late reply. Yeah it's surely possible, I should try but I think constructing from the private key with FromPrivateKey should do the trick, because you can specify everything including the chain code, so you just need to swap them in the parameters. I can provide a code sample if you need it.

Hi @ebellocchia, if you can provide a code example, much appreciated.

priv_key_bytes = binascii.unhexlify(b"e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35")
chain_code_bytes = binascii.unhexlify(b"873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508")

# BIP44 by specifying the coin
bip44_mst_ctx = Bip44.FromPrivateKey(
    priv_key_bytes,
    Bip44Coins.BITCOIN,
    Bip32KeyData(
        chain_code=chain_code_bytes
    )
)

# Generic BIP32 without specifying the coin
bip32_mst_ctx = Bip32Secp256k1.FromPrivateKey(
    priv_key_bytes,
    Bip32KeyData(
        chain_code=chain_code_bytes
    )
)

# If you need to specify everything (same for BIP32)
bip44_mst_ctx = Bip44.FromPrivateKey(
    priv_key_bytes,
    Bip44Coins.BITCOIN,
    Bip32KeyData(
        chain_code=chain_code_bytes,
        depth=1,
        index=2,
        parent_fprint=binascii.unhexlify(b"12345678")
    )
)

I have one problem, the chain_code bytes are 66 bytes, while the privatekey bytes are 64 bytes. Therefore, if I swap them I get ValueError: Invalid chaincode length (66)
Is there a way to ignore errors like this one?
Alternatively I wapped the bytes for the privatekey and and chain_code in the extended privatekey manually:
Bip44.FromPrivateKey(hidden_prv_ext,Bip44Coins.BITCOIN)
Unfortunately I get the error Bip32KeyError: Invalid private key bytes
Not sure how to circumvent these error.

No it's not possible, the chain code is the same length of the private key by definition. I think you are adding another byte to it, maybe the depth. If you need to get back all the parts from an extended key, you can use the Bip32KeyDeserializer class.

Thx again for your help, it turned out I used a wrong example to manually retrieve the chain-code bytes and private-key bytes from the xpub bytes:
https://medium.com/mycrypto/the-journey-from-mnemonic-phrase-to-address-6c5e86e11e14
The private-key in the example contained some additional prepend '00', probably the chain dept as you suggested since it is at the master level which should be '00'.
I confirmed my code now derives addresses correctly, so time to recover that wallet.
If successful I will share 5% of my (modest ) fee with you, and another 5% to another helpful party, so fingers crossed.

Thx for the help and this awesome package. I used it to successfully recover a wallet. As you might have seen, I have send some beers you way to your bip_utils donation wallet.

Cheers!

Anynomous

Ok perfect, I'm glad you recovered the wallet.
Thank you very much for the donation, I appreciate it.