You open a hardware wallet for the third time, hit "receive," and get a different address again. Different from yesterday's, different from last week's. You start to wonder whether these things are connected or whether the device is just making them up as it goes. They're connected. Every one of them traces back to a single 12- or 24-word seed phrase through a chain of arithmetic that's worth understanding if you're trusting it with anything real.

BIP-32, authored by Pieter Wuille and merged into the Bitcoin codebase in 2012, is the specification that makes this possible. Hierarchical Deterministic: given the same starting point, you always get the same tree of keys, in the same order, forever. No randomness after the seed.

One seed, a billion addresses, zero repetition

The process starts with your seed phrase. A BIP-39 mnemonic (12 or 24 words) encodes 128 or 256 bits of entropy, which gets stretched by PBKDF2 with 2,048 rounds of HMAC-SHA512 into a 512-bit seed. That seed goes into one more HMAC-SHA512 operation, this time keyed with the literal string "Bitcoin seed," producing two 256-bit outputs side by side: the master private key on the left, the master chain code on the right.

The chain code is what most explainers quietly skip over, and it matters enormously. It's a 32-byte salt that travels down through every level of derivation, making each child key depend on both the parent key and that chain code together. Without it, two wallets sharing a key would leak information about each other. With it, they don't.

From the master key, you derive children. The derivation function takes three inputs: the parent key, the parent chain code, and an index number (an unsigned 32-bit integer, so up to roughly 4.3 billion children per node). HMAC-SHA512 digests all three and splits the output. The left 32 bytes get added to the parent key modulo the elliptic curve order, producing the child private key. The right 32 bytes become the child's chain code. Same inputs always produce the same child. Run it with index 1 instead of 0, you get a completely different child. Run it with index 0 again three years later on a different machine, you get the identical key as the first time.

The tree structure is where "hierarchical" earns its name. A standard Bitcoin wallet following BIP-44 derives keys along a path written as m/44'/0'/0'/0/0. Read left to right: m is the master, each number is a child index, the apostrophe marks a "hardened" derivation. Hardened children use the private key directly as input rather than the public key. That distinction is the whole security story.

Why hardening is the piece that actually protects you

Normal (non-hardened) derivation has a genuinely useful property: you can derive child public keys from a parent public key alone, without ever touching the private key. This is how a merchant's server generates fresh deposit addresses on the fly without storing anything sensitive. Elegant. But it creates a specific vulnerability: if someone learns a child private key and the parent public key, they can work backwards mathematically to the parent private key. One leaked child key compromises the whole branch.

Hardened derivation closes that gap. Because hardened children are derived from the private key, knowing a child private key and the parent public key gets an attacker precisely nothing. The tradeoff is that a watch-only wallet (holding only public keys) can't generate hardened children. So real-world wallets use both: hardened derivation for account-level branches (the m/44'/0'/0' part), normal derivation for individual addresses within an account.

I think this two-layer design is underappreciated. It's a rare case in protocol design where the security boundary and the operational boundary happen to sit in exactly the right place.

Consider a worked example. Amara's employer asks her for an extended public key (xpub) to automate payroll. She exports the xpub for her external chain, m/44'/0'/0'/0. Her employer can now generate address 0, 1, 2, on up through 2³¹ minus one, all without any private key material. Her colleague Daniel does the same for his business. Neither person's account branch reveals anything about the other's root, and neither xpub can expose the account-level private keys sitting one hardened step above. The hardened boundary functions like a one-way valve in the derivation tree: information flows down freely, never back up.

So here's the question worth sitting with: if xpub exposure is a privacy risk but not immediately a theft risk, how carefully are you actually treating yours?

If you're sharing it only with services that genuinely need to watch your balance, you're using the system correctly. If it's sitting in a screenshot in your camera roll, that's a real problem even without a private key in sight. Anyone holding that xpub can reconstruct every transaction on that branch, past and future. Privacy and security are not the same thing, and BIP-32 protects both only if you handle the outputs with some care.

The honest caveat: BIP-32 protects key derivation. It says nothing about how a wallet stores the master seed on disk or in memory. The math is sound. The firmware, the USB stack, the operating system underneath it, those are separate questions the specification doesn't answer.

Derive a trillion keys from your seed with perfect cryptographic hygiene, then write the seed on a sticky note and leave it on your monitor. The architecture doesn't collapse at the math. It collapses at the sticky note. That's always been the real attack surface, and no specification changes it.