Can anyone tell me how I can get the extended public key from an extended private key in python. I know that I need to get the public key from the private key and that the public key + chain key = extended public key. I already have the public key in multiple forms but I don't know which one to use.

Extended Private Key:                    961901f50868df03db40e0a29d40092b3fc26f47a1c20540d1440be1cd70edbef9c82ec85c4f90a24a1f7a4f1de97ddf762bcb20142b12e9b6c3e348e5519b74
Private key:                             961901f50868df03db40e0a29d40092b3fc26f47a1c20540d1440be1cd70edbe
Chain Code:                              f9c82ec85c4f90a24a1f7a4f1de97ddf762bcb20142b12e9b6c3e348e5519b74
PREPENDED:                               80961901F50868DF03DB40E0A29D40092B3FC26F47A1C20540D1440BE1CD70EDBE
PRIV_UNCOMP+CHECKSUM:                    80961901F50868DF03DB40E0A29D40092B3FC26F47A1C20540D1440BE1CD70EDBE223FDFAE
Private_key_WIF_uncompressed_Base58:     5JxPdEGBsaP14hBpr3swh2GZeXctQdLn9ZvjyFEj6diN742em4R
PRIV_COMP+CHECKSUM:                      80961901F50868DF03DB40E0A29D40092B3FC26F47A1C20540D1440BE1CD70EDBE0151EA0003
Private_key_WIF_compressed_Base58:       L2FUruY2zEL7HJNnBVhrPebh6e9PuHQJGpLCfFqaos3a9eeosKVL
('5JxPdEGBsaP14hBpr3swh2GZeXctQdLn9ZvjyFEj6diN742em4R', 'L2FUruY2zEL7HJNnBVhrPebh6e9PuHQJGpLCfFqaos3a9eeosKVL')
Private key hex string:                  961901F50868DF03DB40E0A29D40092B3FC26F47A1C20540D1440BE1CD70EDBE
Private key bytes:                       b'\x96\x19\x01\xf5\x08h\xdf\x03\xdb@\xe0\xa2\x9d@\t+?\xc2oG\xa1\xc2\x05@\xd1D\x0b\xe1\xcdp\xed\xbe'
Verifying key, x and y points (bytes):  b'E.1\xc8Z\x02\xf6\x1e$\x9d\xf1\xcf\xc3\x10\x8ff\x06\x14U\xceL3\xf8\xabO\xbf\x1cr\xe4\xf6\xf1\x1cm\xb9\xc3\x16\xed6\xbb\x0c\xe4\xeaQ\x1b^W\xde\x8d\xd5\xac\x822Z\xea\xcb#\x82\xf1\xda\xb8\x12\xfd\x8f\xa9' <class 'bytes'>
Uncompressed private key (hex):          04452E31C85A02F61E249DF1CFC3108F66061455CE4C33F8AB4FBF1C72E4F6F11C6DB9C316ED36BB0CE4EA511B5E57DE8DD5AC82325AEACB2382F1DAB812FD8FA9
Compressed private key in (hex):         02452E31C85A02F61E249DF1CFC3108F66061455CE4C33F8AB4FBF1C72E4F6F11C
Public compressed key (hex):             13w1yEAhhMGk6E5UU2wGQyy7pP14K1q2tg
Extended Public Key:                     ?


1 Answer 1


From BIP32:

We represent an extended private key as (k, c), with k the normal private key, and c the chain code. An extended public key is represented as (K, c), with K = point(k) and c the chain code.

point(p): returns the coordinate pair resulting from EC point multiplication (repeated application of the EC group operation) of the secp256k1 base point with the integer p.

ser256(p): serializes the integer p as a 32-byte sequence, most significant byte first.

serP(P): serializes the coordinate pair P = (x,y) as a byte sequence using SEC1's compressed form: (0x02 or 0x03) || ser256(x), where the header byte depends on the parity of the omitted y coordinate.

Extended public and private keys are serialized as follows:

  • 4 byte: version bytes (mainnet: 0x0488B21E public, 0x0488ADE4 private; testnet: 0x043587CF public, 0x04358394 private)
  • 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 derived keys, ....
  • 4 bytes: the fingerprint of the parent's key (0x00000000 if master key)
  • 4 bytes: child number. This is ser32(i) for i in xi = xpar/i, with xi the key being serialized. (0x00000000 if master key)
  • 32 bytes: the chain code
  • 33 bytes: the public key or private key data (serP(K) for public keys, 0x00 || ser256(k) for private keys)

This 78 byte structure can be encoded like other Bitcoin data in Base58, by first adding 32 checksum bits (derived from the double SHA-256 checksum), and then converting to the Base58 representation. This results in a Base58-encoded string of up to 112 characters.

Thus the extended public key (xpub) can be derived from the extended private key (xprv) as follows:

  1. Convert the xprv from Base58 to bytes and extract the private key from the last 33 bytes (ignoring the checksum).
  2. Calculate the public key from the private key as per point(p).
  3. Serialize the result:
    • 4 bytes: 0x0488B21E (mainnet) or 0x043587CF (testnet)
    • 41 bytes: depth, parent fingerprint, child number and chain code are the same as in the xprv
    • 33 bytes: public key serialized using serP(K)
  4. Add the 4-byte checksum and convert to Base58.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.