Translations: German 🇩🇪
This essay explains hierarchical deterministic wallets (BIP32) and seed phrases (BIP39)
In my classes, I commonly encounter confusion about public/private extended keys vs individual public/private keys. How it works is quite interesting.
Every address comes from a public key. Also called a pubkey, and different to an extended public key (xPub).
That pubkey comes from a private key (different to an extended private key, or xPrv, and different to “seed”).
The “only” thing a private key does is produce a pubkey and make signatures.
Those signatures prove you have the private key to a pubkey/address, without exposing the private key. An incredible breakthrough by humanity by the way, and used by Satoshi to allow digital ownership in Bitcoin.
If all you have is a private key, then in total you have:
- 1 private key
- 1 public key (from the private key)
- 1 address (from the public key)
This is very limiting and not very private because with only one address, you either have to accept payments to that one address, or make more private keys every time you wanted a fresh address. This would be very tedious, and a relative security risk.
HD wallets (hierarchical deterministic wallets) are from a protocolised algorithm (BIP32 = Bitcoin Improvement Proposal 32) that wallets use to solve this problem. Instead of the user creating a private key, they produce an EXTENDED private key.
If the schematic below doesn’t make a lot of sense, keep reading, I’ll present it again at the end.
I have not included derivation paths in this image for simplicity. It can be thought of as a “second passphrase” which, in a protocolised way for wallet interoperability, affects the type of addresses produced. It’s best to not edit this from the defaults unless you are an expert.
HD wallets allow “limitless” regular private keys, mathematically, and reproducibly (deterministic). Like a SEED!
Note, this is not a seed PHRASE. It’s an extended private key (one giant random-looking number derived from the seed phrase + passphrase).
Each of the child-private keys produces a corresponding single pubkey, and each produces a single address – the collection of 8.6 billion unique addresses is your “wallet” (4.3 billion receiving addresses, 4.3 billion change addresses – see appendix).
The extended private key also produces an EXTENDED Public key (xPub).
The xPub produces a giant list of pubkeys (deterministicly), and, of high importance – the pubkeys are the SAME set produced via all the single private keys (thanks to public/private key cryptographic “magic”).
What does this mean?
It means that if you “feed” a software wallet (eg Electrum) the extended private key OR the extended public key (“feed” meaning using the keys to restore a wallet), you’ll produce the same collection of pubkeys/addresses (ie same wallet).
What’s the point of that option?
Feeding Electrum an xPub allows you to create a watching wallet.
The point of that?
Primarily, it allows you to create a transaction (by referencing a UTXO on the blockchain) that is ready to sign. The UTXO can only be accessed on an internet-connected device (you need to connect to a node to get the UTXO in order to spend it – the UTXO is on the blockchain, not your wallet), but without exposing the private keys on the computer.
The ready-to-sign transaction (“unsigned bitcoin transaction”, commonly included in the usage of the term “partially signed bitcoin transaction” even though it’s not signed at all) is then passed to a signing device (eg HWW or air-gapped computer) for signing.
This device can’t create a transaction (it’s disconnected from the internet), it needs the watching wallet to create it, and then it can do the signing part. After that, the signing device can’t broadcast. It passes the transaction (signed transaction, now valid) back to the watching wallet for broadcasting to a node.
Of course, this is much more tedious than simply putting the seed (ext. Private Key) into an internet-connected computer and generating a full wallet – the generation of the tx, the signing, and broadcasting would then happen all on the single device. Easier, but not as safe.
Sometime after BIP32 (HD wallets), came BIP39, another protocol.
The purpose was to allow a set of words to represent numbers (according to a protocol). This allowed a private number to be recorded in a way that is less error-prone.
The “mnemonic seed phrase”, also called
“seed phrase”, or ambiguously, “seed”, or incorrectly “private key”.
With the BIP39 seed phrase, and an optional passphrase, and a derivation path – in combination, an extended private key is produced (the same type of key as I discussed earlier). Note, for simplicity I have not included the derivation path in the schematic I drew earlier.
The seed phrase is not a KEY – it’s a set of words representing a private number that CONTRIBUTES to the creation of an extended private key. It is a “seed” in a way because it produces the ext private key. Note that the seed phrase can produce more than one extended private key, because it can be combined with different passphrases and derivation paths. For more info, my list of articles on #bitcoin keys…
Have another look at the diagram now that you’ve read the whole essay:
Appendix – What’s Receiving and Change addresses all about?
As mentioned, limitless (8.6 billion) addresses come from the extended public key. There are 4.3 billion receiving addresses and 4.3 billion change addresses.
You don’t need to know the exact calculation of how an address is made unless you are going to develop Bitcoin wallets. The main idea is that the xPub is taken, and combined with a number, which, in a one-way series of functions (hashing) and defined steps, produces an address. That added number is “0” for the first address. The next number is “1”, and so on. Every time the added number is changed, a completely new random-looking address is produced. The memory allocated to the added number is 32 bytes. That size can hold 4,294,967,295 different values (unsigned integers). Each one can produce an address when combined with the xPub.
When you send an invoice to someone, a customer for example, you should allocate an address to them, and only them (adhering to the privacy principle of using addresses once). But you may not know when the customer will pay. Your software wallet has no idea either, nor that you have allocated an address to someone (particularly if the allocation is generated by the customer in an automated way – as is the case with my donation app).
If, before the customer has paid, you make an unrelated transaction from your wallet which requires change (see article on UTXOs for an explanation of what change is), the wallet will automatically send the change to the next unused address. But wait, what if it sends it to an address you’ve already allocated to a customer? If that happens, your change may go to that “unused” address, and later your customer will pay to the same address. Then you’ll have two UTXOs in one address. One may be KYC’d to you, and the other is a customer payment which would normally be completely private (except between you and the customer). The privacy of that coin is then lost because it occupies the same address as your change. The customer coin effectively becomes KYC’d.
This is where change addresses help. They are another set of 4.3 billion addresses that you should not use for invoices. That way, none of them will ever have pending payments from others, and so when your wallet sends change here, there is no risk of there being two payments to the same address.
How are these addresses made? Very similar to the receiving addresses, except that one digit is changed in the derivation path from “0” to “1”, and then the same 32 bytes are allocated for the “added number”, combining with the xPub to produce a new chain of addresses.
Static Lightning Address: firstname.lastname@example.org
On-chain or Lightning