Hardened vs Non-Hardened Addresses
By mordom
Your wallet does NOT generate infinite addresses
You send a transaction. The wallet says “sent.”
Then you wait.
After an hour it’s still unconfirmed. After a few hours you start to worry.
The exchange doesn’t credit, the payment doesn’t arrive, the recipient messages you.
At that point, it feels like there’s nothing you can do.
In reality, you can do something — but only if you understand what’s actually happening.
The myth of “infinite addresses”
From a user perspective, it feels simple:
click “receive” → new address. Again → new address. It looks like an endless stream.
In reality, you’re just moving through a structure that already exists.
All addresses come from a single starting point: the root key. They’re not created on demand. They are calculated along a path.
Think of it like a pre-filled contact list, You’re not inventing new entries each time.
You’re just moving to the next one.
The derivation path is a coordinate system
A string like:
m / 84' / 0' / 0' / 0 / 0
is not developer jargon. It’s a precise location. It tells you:
- where you start
- which branch you’re in
- where you are exactly
Every address is a coordinate. If you know the path, you can always find that address again.
Indices: where things actually happen

The last numbers:
/0/0, /0/1, /0/2 … look trivial.
They’re not. This is where your wallet actually operates. When you request a new address:
- the path stays the same
- only the index changes
- it increments by 1
No randomness. Just sequence. And here’s what most people miss:
indices are not infinite.
- non-hardened range:
0to2³¹ - 1→ 2,147,483,647 values - total space: up to
2³² - 1→ 4,294,967,295 values
Huge numbers. But still finite.
Why this actually matters
The index is not just a counter. It is part of the input that generates the key.
Every increment changes the result.
So:
- you’re not “creating” addresses
- you’re selecting which one to use
And this is exactly where hardened vs non-hardened starts to matter.
Non-hardened: continuity
Non-hardened derivation is what makes wallets usable in the real world. There’s a key property here:
there is a mathematical link between the parent public key and child public keys.
In practice:
you can start from an extended public key (xpub/zpub) and keep generating all future public keys. Without ever touching a private key.
This is what enables:
- watch-only wallets
- server-side address generation
- separation between custody and operations
Hardened: isolation
Hardened derivation breaks that continuity.
Indices change: they move into the higher range (those with ')
Here, the link between public keys is intentionally removed. There is no way to derive child keys from the parent public key alone.
You need the private key.
The result is simple: that branch becomes isolated.
Why you can’t have a “useful zpub” if everything is hardened
At this point, the implication is clear. zpubs only work because, at some level, derivation remains non-hardened.
If you made the final levels hardened:
m / 84' / 0' / 0' / 0' / 10'
you would lose that ability entirely.
In practice:
- no automatic address generation
- no functional watch-only wallet
- no full wallet visibility without private keys
Each address would have to be:
- generated on the device holding the private key
- transferred manually
The wallet would become more isolated.
But also far less usable.
Why wallets combine both

A standard path like:
m / 84' / 0' / 0' / 0 / 0
is not arbitrary.
- up to the account → hardened
- after that → non-hardened
This is the exact point where you “open the door”.
It defines:
- what remains isolated
- what becomes operational
This allows:
- secure account separation
- flexible address generation
- compatibility with external systems
What you should take away
Your wallet does not generate addresses.
It walks through them.
Indices drive that progression. Derivation rules define what is possible along that path. If you understand where hardened stops and non-hardened begins, you understand how your wallet actually works.
Technical notes
- If you see an apostrophe (e.g.
44'), that index is shifted into the higher range: →2³¹ + 44
Derivation inputs
- Non-hardened:
Parent Public Key + Index - Hardened:
0x00 + Parent Private Key + Index
The 0x00 byte ensures proper formatting and distinguishes the hardened process.
Derivation formulas (simplified)
Given:
k_parent= private keyK_parent= public keyc_parent= chain code
Non-hardened:
I = HMAC-SHA512(c_parent, K_parent || index)k_child = (k_parent + I_L) mod nK_child = K_parent + I_L · G
→ HMAC uses only the public key
Hardened:
I = HMAC-SHA512(c_parent, 0x00 || k_parent || index)k_child = (k_parent + I_L) mod nK_child = k_child · G
→ HMAC uses the private key
This difference in input is exactly what:
- preserves the link (non-hardened)
- or breaks it (hardened)

