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