Bitcoin Wallets (Databases) do not store Bitcoins. They only store keys
They keys are associated with transactions on the Blockchain
By proving we control the keys coins from the transaction can be spent

Independent Key Generation

Wallet independently generates multiple keys
Keys have to be backed up whenever a new one is created
The keys are independent and did not related to each other
This approach is not used by modern wallets

Deterministic Key Generation

A seed is used to generate the private keys
Seeds are usually 128 to 256 bits long
By knowing the seed and algorithm used the private keys can be regenerated
Saving the seed is sufficient to backup all the private keys

Public Child Key Derivation

Public Key Equation:
Derived public key generated by adding same value of both sides of the equation
e.g.

Alice can generate a public key K and give it to Bob
Bob does not know private key but knows G
Can add any value to K to generate a derived public key
Bob tells Alice the value added to K, she can add same value to the private key
This will generate a derive child private key
This private key will correspond to the public key generated by Bob

Public keys can be generated without knowing anything about the private key
The value added to the public key is called “key tweak”
Using a deterministic algorithm unlimited public key pair can be generated
The person with the private key can use the key tweaks to generate the private keys

Hierarchical Deterministic (HD) Key Generation

Uses deterministic key generation and public child key derivation with an algorithm that generates a tree of keys
There is no limit on the depth of the tree. Used by all modern wallets

Recovery Codes

Recovery Code Types

BIP39

Generates a random sequence of bytes and adds a checksum
Encoded into a sequence of 12 to 24 human-readable words
The words and a optional passphrase is run threw a key stretching algorithm
The output is the seed for the wallet

Electrum v2

Unlike BIP39 does not rely on a global wordlist
The recovery code includes a version number
Supports an optional passphrase
Uses same key-stretching algorithm like BIP39

Aezeed

Uses two version number: internal and external
Internal version is used to resolve issues when upgrading the wallet
External version used to change the properties of the recovery code
The code also includes the wallet birthday. Day the wallet was created
Helps to find the users funds without scanning the whole blockchain
Supports changing passphrase and recovery code without changing seed

Muun

Mun wallet requires spending transactions using multiple keys
It is a Nonword recovery code
Requires additional information for recovery which is provided in a PDF
Recovery code unrelated to the keys. Used to decrypt private key from the PDF

SLIP39

Successor to BIP39
Allows single seed to be recovered from multiple distributed recovery code
On creating recovery code can decide how many would be required to find seed
Supports optional passphrase and uses global wordlist

Recovery Code Limitations

Bitcoin wallets also store additional metadata like transaction description
This information is never published on the blockchain for privacy
Wallets use backup files that are encrypted using private key generated from seed
On recovery after finding the seed the backup file is downloaded and decrypted

In HD wallets each key can have 4 billion children keys
It is impossible for a wallet to calculate all the possible keys
Along with the recovery key the path information also needs to be stored
This information is stored separately from the recovery code

BIP39

Recovery Code Generation

  • Create random sequence of 128 or 256 bits
  • Create a checksum for the sequence
  • Add checksum to the end of the sequence
  • Split the sequence into 11-bit segments
  • Map each segment to a word from the global wordlist
  • The sequence of words is the recovery code

Generating Seed from the Recovery Code

  • Recovery code and salt is used in a key-stretching algorithm (PBKDF2)
  • The salt is “mnemonic” along with option user-defined passphrase
  • PBKDF2 uses 2048 rounds of hashing using HMAC-SHA512 to produce the 512-bit seed value

HD Wallet Seeds

HD wallets pass the seed to a HMAC-SHA512 function
The output becomes the Master Private Key (m) and Mater Chain Code
The master private key is used to create the master public key using
The chain code is used to create entropy in the function for child keys

Child key is derived using the master public key, master chain code & index number Public key and chain code from the previous level become inputs for the next level

Changing the index allows us to create sibling keys at the same level
Using the child key the parent key cannot be found
Similarly knowing one sibling other siblings cannot be found
The child keys are indistinguishable from randomly generated keys
The relation between the keys only exists in the HD wallet

Extended Key = Key + Chain Code
Extended Public key can be used to derive Child Public Keys
Extended Private key can be used to derive Child Public & Private Keys

Extended keys are encoded in base58check for easy import and export
They start with “xprv” or “xpub”

Transaction Flows - Extended Public Key on Web Store

Hardened Child Key Derivation

If a child private key is leaked and the attacker knows the chain code then all other child private keys can be found
Child private key along with the parent chain code can be used to find out the parent private key
The hardened derivation function uses the private key instead of the public key to derive the child chain code

Index Numbers: 0 to - Normal derivation
Index Numbers: to - Hardened derivation
Hardened derivation index notation (2nd hardened key): 1h or 1’

HD Wallet Key Paths

The “/” sign is used to denote the path to the key
Public keys start with “M” and private keys start with “m”

1st child private key: m/0
2nd grandchild public key of 1st child: M/0/1
1st normal grandchild private key from 1st hardened child: m/0’/0

BIP43

Proposed the idea of using a purpose field in the structure
The 2nd field in the path was used to represent the purpose
e.g. m/44'/...: Private key used for purpose 44

BIP44

Expanded on the idea from BIP43 and create a proper framework
Uses the structure: m/purpose'/coin_type'/account'/change/address_index
A wallet can contain multiple account. Each account can have its own keys
Change Field: 0 (Payment), 1 (Change)
Address Index stores the hierarchical path to the key