<blockquote>
  <p>Why does BIP44 use non-hardened paths at all?</p>
</blockquote>

<p>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.</p>

<p>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.</p>

<pre><code>// 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?
</code></pre>

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

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

<p>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.</p>

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

<p>Nope. However, if you also exposed</p>

<pre><code>wallet.derive("m").xpubkey
</code></pre>

<p>then I'd have enough information to compromise your wallet.</p>

CC BY-SA 3.0
2015-03-19T01:31:32.687Z
The account level in BIP44 is hardened, yet it allows to derive the external and change addresses.
Giszmo
CC BY-SA 3.0
2015-03-19T01:32:41.493Z
@Giszmo, yes, but its children are not hardened.
Nick ODell
CC BY-SA 3.0
2015-03-19T01:36:07.300Z
I can perfectly derive from hardened xpriv and xpub keys. `hardened.derive(1, true).derive(1, true).xprivkey is 
"xprv9zTLKFNn1CmW8oB3s8L1B4Bvn9E4nLmg2juMQv2HwbhhQhufDivMWcNSiio59CiNMXkUCBS4Npi9KAtefwB4KUNkrTkprbECsMLg3yEvJM8"`.
Giszmo
CC BY-SA 3.0
2015-03-19T01:37:35.770Z
@Giszmo Can you generate a child public key from a hardened public key?
Nick ODell
CC BY-SA 3.0
2015-03-19T01:44:27.210Z
something like `HDPrivateKey().derive(1,true).hdPublicKey.publicKey.toAddress().toString()`? Spits out an address as I would have expected.
Giszmo
CC BY-SA 3.0
2015-03-19T01:45:18.083Z
@Giszmo No, a **child** public key.
Nick ODell
CC BY-SA 3.0
2015-03-19T02:59:13.467Z
[Extended chat log.](http://pastebin.com/raw.php?i=mPqwAs1g)
Nick ODell
CC BY-SA 3.0
2015-03-19T03:14:05.163Z
Ok so xpriv (hardened or not) can be derived to any hardened or not, private or public sub key while xpub (hardened or not) can only be derived to the non-hardened public sub keys.
Giszmo
CC BY-SA 3.0
2015-03-18T21:55:36.350Z
2015-03-20T04:39:39.163Z
2015-03-20T04:39:39.163Z
Nick ODell
<p><a href="https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki" rel="noreferrer">BIP44</a> uses <a href="https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki" rel="noreferrer">hardening/private derivation</a> on most levels:</p>

<pre><code>m / purpose' / coin_type' / account' / change / address_index
</code></pre>

<p>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?</p>

<p>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?</p>

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

<pre><code>    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?
</code></pre>

<p>The output:</p>

<pre><code>    1c6dKRqvYPiCQx2R3u75pxGfy15g7jfU4
    0342619d3209b6859f4d88e3b1deaa1acee734c94d625b7d59b286b6842c90bd60
    4c461799315979063858208f6c3e8b33f29ceb10c42389690cd0a20427715845
    xpub68GCDysH8nE2Nuodq1ncV4jYiWvajzZyjVr6Pt8N46QAKC3CPxjj8G6AcE7sdvGypzXZFRRHYjRokhTty6LC8MErRifGiJFeTbTBYL9QfTg
    xprv9uGqpULPJQfjARjAizFc7vnpAV66LXr8NGvVbVikVksBSPi3rRRUaTmgkwDii6TFzWWFsch7Qc2v6eM1ZcJAJLv8ybvw7YY4qwLwvfFJoAp

    1NsxMLRhXasbHaskKVQK4qiJpBZgjTs3Aq
    026653baf78fb78cfb9845faa43080dfc452991422edc67f5ba085d02786364670
    afdb89aaf2f02987dfc47cc655fb4e1fb5cdd545af44875b4176805dc8f60852
    xpub69pTp8pV8Fcmkf3HuiWnzGE42MJcMrTtegoZaLApLUSvhugH6YNKgTtVfk2asMNZWKynCpFoCGePbHLfwJqsLtPskSv5cPF6j1FqmdaNCrE
    xprv9vq7QdHbHt4UYAxpogynd8HKUKU7xPk3HTsxmwmCn8uwq7M8Z1458fa1pVZCfWYWUWMG7p7b99NzJnSwZAnQR6EmN4awbcKZrfdrcmXAXqy
</code></pre>

<bip32-hd-wallets><bip44>
Why does BIP44 use non-hardened paths at all?
Giszmo
# Why does BIP44 use non-hardened paths at all?

(Asked by: username_0 on 2015-03-18)

[BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) uses [hardening/private derivation](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) 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

```

**Tags:** bip32-hd-wallets, bip44


---

## 1 answers

### Answer by username_1 on 2015-03-18. Score: 6 | Accepted answer

> 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.

> **Comments:**
> **username_0**: The account level in BIP44 is hardened, yet it allows to derive the external and change addresses.  
> **username_1**: @username_0, yes, but its children are not hardened.  
> **username_0**: I can perfectly derive from hardened xpriv and xpub keys. `hardened.derive(1, true).derive(1, true).xprivkey is  "xprv9zTLKFNn1CmW8oB3s8L1B4Bvn9E4nLmg2juMQv2HwbhhQhufDivMWcNSiio59CiNMXkUCBS4Npi9KAtefwB4KUNkrTkprbECsMLg3yEvJM8"`.  
> **username_1**: @username_0 Can you generate a child public key from a hardened public key?  
> **username_0**: something like `HDPrivateKey().derive(1,true).hdPublicKey.publicKey.toAddress().toString()`? Spits out an address as I would have expected.  
> **username_1**: @username_0 No, a **child** public key.  
> **username_1**: [Extended chat log.](http://pastebin.com/raw.php?i=mPqwAs1g)  
> **username_0**: Ok so xpriv (hardened or not) can be derived to any hardened or not, private or public sub key while xpub (hardened or not) can only be derived to the non-hardened public sub keys.  

---

