2

I have this code:

const bitcoin = require('bitcoinjs-lib');
const keyPair = bitcoin.ECPair.makeRandom({ });

Question: how do I get xpriv and xpub from keyPair

1 Answer 1

4

The short answer is: you probably shouldn't.

That is not a typical way to generate an xpriv/xpub. You are trying to convert a key pair to an extended key pair. The difference is the extended keys include the following (See BIP32 - Serialization Format):

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

BIP32 standard Master Key generation goes like this:

  • Generate a seed byte sequence S of a chosen length (between 128 and 512 bits; 256 bits is advised) from a (P)RNG.
  • Calculate I = HMAC-SHA512(Key = "Bitcoin seed", Data = S)
  • Split I into two 32-byte sequences, IL and IR.
  • Use parse256(IL) as master secret key, and IR as master chain code.

With bitcoinjs-lib, a more standard approach would be:

const mnemonic = 'praise you muffin lion enable neck grocery crumble super myself license ghost'
const seed = bip39.mnemonicToSeed(mnemonic)
const node = bip32.fromSeed(seed)
console.log(node.toBase58())

'xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkTcaMEcjq1vG7XmEEW22S2UiSPbrzTkUeXfcwo7PzRZ4aDiRQu'

If you absolutely had to do it, technically you could (not recommended) replace the private key property of the node object with a buffer of your own private key, i.e. __d:

> const bip32 = require('bip32')
undefined
> let node = bip32.fromBase58('xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi')
undefined
> node
BIP32 {
  __d: <Buffer e8 f3 2e 72 3d ec f4 05 1a ef ac 8e 2c 93 c9 c5 b2 14 31 38 17 cd b0 1a 14 94 b9 17 c8 43 6b 35>,
  __Q: null,
  chainCode: <Buffer 87 3d ff 81 c0 2f 52 56 23 fd 1f e5 16 7e ac 3a 55 a0 49 de 3d 31 4b b4 2e e2 27 ff ed 37 d5 08>,
  depth: 0,
  index: 0,
  network: { wif: 128, bip32: { public: 76067358, private: 76066276 } },
  parentFingerprint: 0 }
> node.__d = Buffer.from('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', 'hex')
<Buffer e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24 27 ae 41 e4 64 9b 93 4c a4 95 99 1b 78 52 b8 55>
> node
BIP32 {
  __d: <Buffer e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24 27 ae 41 e4 64 9b 93 4c a4 95 99 1b 78 52 b8 55>,
  __Q: null,
  chainCode: <Buffer 87 3d ff 81 c0 2f 52 56 23 fd 1f e5 16 7e ac 3a 55 a0 49 de 3d 31 4b b4 2e e2 27 ff ed 37 d5 08>,
  depth: 0,
  index: 0,
  network: { wif: 128, bip32: { public: 76067358, private: 76066276 } },
  parentFingerprint: 0 }

Your Answer

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

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