6

BIP44 uses hardening/private derivation on most levels:

m / purpose' / coin_type' / account' / change / address_index

but not on the change and address_index level. First of all, what does hardening achieve and secondly, what would be the disadvantage of always hardening other than having just half of 2³² paths at that level?

As far as I understood, non-hardened paths allow at the presence of just one simple private key, to learn the xpriv key of the address and if that is not hardened, also the next higher xpriv key all the way up to the first hardened path. Is that so and if yes, what advantage would it have, other than providing 2 billion addresses more in that account's external and change path assuming that the overflow into hardened address spaces were allowed?

A little code to see if/what I got right:

    var wallet = HDPrivateKey()
    var hardened = wallet.derive(4, true)
    var nonHardened = hardened.derive(4, false)

    console.log(hardened.publicKey.toAddress().toString())
    // the payee gets this anyway
    console.log(hardened.publicKey.toString())
    // once I spend from my address, I have to reveal this. It's probably secure to
    // re-use the address but better not to.
    console.log(hardened.privateKey.toString())
    // at this point, you can spend funds that are received to above address and
    // only that
    console.log(hardened.xpubkey)
    // you now know all my addresses I could derive from hardened. Do you know any
    // private keys except for the one I explicitly shared a line before?
    console.log(hardened.xprivkey)
    // now you can spend from all the addresses derivable from hardened but learn
    // nothing else about wallet.

    console.log(nonHardened.publicKey.toAddress().toString())
    console.log(nonHardened.publicKey.toString())
    console.log(nonHardened.privateKey.toString())
    console.log(nonHardened.xpubkey)
    // in difference to the hardened case, you would now learn about nonHardened but
    // also (once again) about hardened? What could you actually learn?
    console.log(nonHardened.xprivkey)
    // would this line leak any information that wasn't already leaked in the last
    // block?

The output:

    1c6dKRqvYPiCQx2R3u75pxGfy15g7jfU4
    0342619d3209b6859f4d88e3b1deaa1acee734c94d625b7d59b286b6842c90bd60
    4c461799315979063858208f6c3e8b33f29ceb10c42389690cd0a20427715845
    xpub68GCDysH8nE2Nuodq1ncV4jYiWvajzZyjVr6Pt8N46QAKC3CPxjj8G6AcE7sdvGypzXZFRRHYjRokhTty6LC8MErRifGiJFeTbTBYL9QfTg
    xprv9uGqpULPJQfjARjAizFc7vnpAV66LXr8NGvVbVikVksBSPi3rRRUaTmgkwDii6TFzWWFsch7Qc2v6eM1ZcJAJLv8ybvw7YY4qwLwvfFJoAp

    1NsxMLRhXasbHaskKVQK4qiJpBZgjTs3Aq
    026653baf78fb78cfb9845faa43080dfc452991422edc67f5ba085d02786364670
    afdb89aaf2f02987dfc47cc655fb4e1fb5cdd545af44875b4176805dc8f60852
    xpub69pTp8pV8Fcmkf3HuiWnzGE42MJcMrTtegoZaLApLUSvhugH6YNKgTtVfk2asMNZWKynCpFoCGePbHLfwJqsLtPskSv5cPF6j1FqmdaNCrE
    xprv9vq7QdHbHt4UYAxpogynd8HKUKU7xPk3HTsxmwmCn8uwq7M8Z1458fa1pVZCfWYWUWMG7p7b99NzJnSwZAnQR6EmN4awbcKZrfdrcmXAXqy
5

Why does BIP44 use non-hardened paths at all?

Imagine you have a website where you want to sell things. You need the website to be able to generate addresses, but you don't want it to be able to spend from them.

Well, you can give the website an account-level extended public key, and it can generate the non-hardened addresses you need from that. You wouldn't be able to create hardened addresses; you'd need the account private key to make new hardened addresses.

// you now know all my addresses I could derive from hardened. Do you know any
// private keys except for the one I explicitly shared a line before?

No. I know a private key, but I can't work out the parent key or any siblings.

// in difference to the hardened case, you would now learn about nonHardened but
// also (once again) about hardened? What could you actually learn? 

Even though this key isn't hardened, I don't know the chain code of the parent key, so I can't compromise sibling keys or even associate that key with any of its siblings.

// would this line leak any information that wasn't already leaked in the last
// block?

Nope. However, if you also exposed

wallet.derive("m").xpubkey

then I'd have enough information to compromise your wallet.

  • The account level in BIP44 is hardened, yet it allows to derive the external and change addresses. – Giszmo Mar 19 '15 at 1:31
  • @Giszmo, yes, but its children are not hardened. – Nick ODell Mar 19 '15 at 1:32
  • I can perfectly derive from hardened xpriv and xpub keys. hardened.derive(1, true).derive(1, true).xprivkey is "xprv9zTLKFNn1CmW8oB3s8L1B4Bvn9E4nLmg2juMQv2HwbhhQhufDivMWcNSiio59CiNMXkUCBS4Npi9KAtefwB4KUNkrTkprbECsMLg3yEvJM8". – Giszmo Mar 19 '15 at 1:36
  • 1
    @Giszmo Can you generate a child public key from a hardened public key? – Nick ODell Mar 19 '15 at 1:37
  • something like HDPrivateKey().derive(1,true).hdPublicKey.publicKey.toAddress().toString()? Spits out an address as I would have expected. – Giszmo Mar 19 '15 at 1:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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