Key Derivation Function (KDF)
A key derivation function stretches a password or low-entropy input into a strong cryptographic key suitable for encryption or authentication.
Key Takeaways
- A key derivation function transforms a password or weak secret into a strong cryptographic key by applying deliberate computational work, making brute-force attacks impractical. This process is called key stretching.
- Bitcoin wallets rely on PBKDF2 to convert a seed phrase into a master seed: BIP-39 specifies 2048 rounds of HMAC-SHA512, producing the 512-bit seed that feeds HD wallet derivation.
- Modern KDFs like scrypt and Argon2 add memory hardness on top of iteration count, defending against GPU and ASIC-based attacks that exploit the speed of simple hash functions.
What Is a Key Derivation Function?
A key derivation function (KDF) is a cryptographic algorithm that takes a secret input, such as a password, passphrase, or shared secret, and produces one or more cryptographic keys suitable for encryption or authentication. The core problem KDFs solve is that human-chosen passwords carry far too little entropy to serve directly as cryptographic keys. A typical password contains roughly 6 to 7 bits of entropy per character, making it trivially guessable when used as a raw key.
KDFs address this by applying a pseudorandom function repeatedly, forcing any attacker to spend significant time and resources on each guess. Unlike a plain SHA-256 hash, which a modern GPU can compute billions of times per second, a properly configured KDF makes each password guess deliberately expensive: hundreds of milliseconds of CPU time, megabytes or gigabytes of RAM, or both.
There are two broad categories of KDFs. Password-based KDFs (PBKDF2, scrypt, Argon2) are designed to be intentionally slow, protecting weak human-chosen secrets. Non-password-based KDFs (HKDF) are designed for efficiency, deriving multiple keys from already-strong cryptographic material like Diffie-Hellman shared secrets or master keys.
How It Works
Every password-based KDF follows the same fundamental pattern: take the password, combine it with a salt, and apply a pseudorandom function many times over to produce the output key.
- The user provides a password or passphrase as input
- The system generates a unique random salt (typically 16 to 32 bytes) to prevent precomputed attacks like rainbow tables
- The KDF applies its internal function repeatedly according to configured parameters (iterations, memory, parallelism)
- The output is a fixed-length cryptographic key that appears indistinguishable from random data
The salt is critical: without it, an attacker could precompute a table mapping common passwords to their derived keys. With a 128-bit salt, each password produces a different output for each salt value, making precomputation infeasible.
PBKDF2
PBKDF2 (Password-Based Key Derivation Function 2) was specified in RFC 2898 in 2000 and updated by RFC 8018 in 2017. It works by repeatedly applying a pseudorandom function (PRF), typically HMAC, to the password and salt combination.
Its parameters are:
- Password: the secret input
- Salt: a random value unique to each derivation
- Iterations (c): the number of times the PRF is applied
- PRF: the pseudorandom function (commonly HMAC-SHA-256 or HMAC-SHA-512)
- dkLen: the desired output key length in bytes
PBKDF2 is the most widely deployed KDF due to its simplicity and FIPS-140 compliance. Its main weakness: it requires only CPU time, not memory, making it vulnerable to massively parallel GPU attacks. OWASP currently recommends a minimum of 600,000 iterations for PBKDF2-SHA-256 and 210,000 for PBKDF2-SHA-512.
scrypt
Designed by Colin Percival in 2009 and standardized in RFC 7914 (2016), scrypt introduced memory hardness to key derivation. Unlike PBKDF2, which only consumes CPU cycles, scrypt forces each computation to allocate a large block of RAM.
scrypt takes three core parameters:
- N (CPU/memory cost): must be a power of 2, controls overall work factor
- r (block size): sets the size of the internal hash blocks, typically 8
- p (parallelization): controls how many independent threads can run, typically 1
The memory requirement is approximately 128 × N × r bytes. With N=131072 and r=8, scrypt consumes roughly 128 MB of RAM per derivation. This memory requirement makes GPU and ASIC attacks far more expensive: Percival estimated in 2009 that a hardware brute-force attack against scrypt costs roughly 4,000 times more than against bcrypt and 20,000 times more than against PBKDF2.
Argon2
Argon2 won the Password Hashing Competition in July 2015 and was standardized in RFC 9106 (2021). It was designed by Alex Biryukov, Daniel Dinu, and Dmitry Khovratovich at the University of Luxembourg. Argon2 comes in three variants:
- Argon2d: uses data-dependent memory access, maximizing GPU resistance but vulnerable to side-channel timing attacks
- Argon2i: uses data-independent memory access, resistant to side-channel attacks but requires more passes to achieve the same strength
- Argon2id: a hybrid that uses Argon2i for the first half of the first pass and Argon2d afterward. RFC 9106 recommends Argon2id as the default for most applications
Argon2 exposes three tunable parameters:
- t (time cost): number of passes over memory
- m (memory cost): memory usage in kibibytes
- p (parallelism): number of independent computation lanes
RFC 9106 recommends using Argon2id with 64 MiB of memory (or more), 3 iterations, and 4 threads for general use. Where resources allow, 2 GiB of memory with a single iteration provides stronger protection at equivalent latency.
HKDF
HKDF (HMAC-based Extract-and-Expand Key Derivation Function), specified in RFC 5869 (2010), serves a different purpose from password-based KDFs. Instead of stretching weak passwords, it derives multiple keys from an already-strong secret like a Diffie-Hellman shared secret.
HKDF operates in two stages:
- Extract: compresses the input keying material into a fixed-length pseudorandom key using HMAC with an optional salt
- Expand: generates output keying material of the desired length by iteratively applying HMAC with an optional context string
HKDF is used in TLS 1.3, the Signal Protocol, and the Lightning Network's BOLT 8 transport protocol, where it derives session encryption keys from the Noise_XK handshake ECDH outputs.
KDFs vs. Simple Hash Functions
A common mistake is using a plain hash function like SHA-256 to derive a key from a password. While both KDFs and hash functions produce fixed-length outputs from arbitrary inputs, they solve fundamentally different problems:
| Property | Hash Function (SHA-256) | Password-Based KDF |
|---|---|---|
| Speed | Billions of hashes per second on a GPU | Deliberately slow: milliseconds to seconds per derivation |
| Work factor | Fixed: no tunable parameters | Adjustable: iterations, memory, parallelism |
| Memory usage | Negligible (a few hundred bytes) | Configurable: kilobytes to gigabytes |
| Salt support | Not built in | Mandatory parameter |
| Precomputation resistance | Vulnerable to rainbow tables without manual salting | Resistant by design |
| Ideal use | Data integrity, commitment schemes, proof of work | Password hashing, key derivation from weak secrets |
Hash functions are designed to be fast because their primary use is verifying data integrity: checksumming files, building Merkle trees, or computing proof-of-work puzzles. That same speed is a liability when the input is a human-chosen password, because an attacker can try billions of guesses per second.
Use Cases in Bitcoin and Crypto
BIP-39 Seed Derivation
The most important KDF application in Bitcoin is BIP-39 mnemonic seed generation. When a user creates a wallet, the process works as follows:
- The wallet generates 128 to 256 bits of entropy and encodes it as a 12- or 24-word mnemonic phrase
- The mnemonic is fed into PBKDF2 as the password, with the string "mnemonic" concatenated with an optional passphrase as the salt
- PBKDF2 applies HMAC-SHA512 for exactly 2048 iterations
- The 512-bit (64-byte) output becomes the master seed
// BIP-39 seed derivation (pseudocode)
password = mnemonic_words // "abandon abandon ... about"
salt = "mnemonic" + passphrase // "mnemonic" if no passphrase
seed = PBKDF2(
PRF: HMAC-SHA512,
password: password,
salt: salt,
iterations: 2048,
dkLen: 64 // 512 bits
)This 64-byte seed is then processed by BIP-32 (HMAC-SHA512 with the key "Bitcoin seed") to produce the master private key and chain code for hierarchical deterministic wallet derivation. Different derivation paths then generate the actual signing keys used for transactions.
Wallet Encryption
Desktop wallets use KDFs to encrypt the wallet file with a user-chosen password. When the user enters their password, the KDF derives the AES encryption key. Without the KDF's computational overhead, an attacker who obtains a copy of the encrypted wallet file could attempt billions of password guesses per second. With a properly tuned KDF, each guess takes hundreds of milliseconds, reducing the practical attack surface from seconds to centuries.
Lightning Network Transport
The Lightning Network uses HKDF in its BOLT 8 encrypted transport protocol. During the three-act Noise_XK handshake, HKDF derives temporary encryption keys from each elliptic curve Diffie-Hellman exchange. After the handshake completes, HKDF produces the symmetric session keys used to encrypt all subsequent messages between Lightning peers.
Secure Key Storage
Cryptocurrency exchanges, custodians, and hardware security modules use KDFs when encrypting key material at rest. The KDF ensures that even if an attacker gains access to the encrypted key store, the master password cannot be quickly recovered through brute force. Spark and similar Layer 2 protocols that manage private keys on behalf of users depend on strong KDF-protected storage for operator-side key material.
Comparing Major KDFs
| KDF | Year | Standard | Memory Hard | Notable Use |
|---|---|---|---|---|
| PBKDF2 | 2000 | RFC 8018 | No | BIP-39 seed derivation |
| scrypt | 2009 | RFC 7914 | Yes | Ethereum keystores, Litecoin PoW |
| Argon2id | 2015 | RFC 9106 | Yes | Modern password hashing (OWASP recommended) |
| HKDF | 2010 | RFC 5869 | No (not password-based) | TLS 1.3, Lightning BOLT 8 |
For a deeper look at how these cryptographic primitives protect wallet infrastructure, see the research article on hardware wallet attack vectors and the guide to wallet recovery methods.
Risks and Considerations
Parameter Selection
Choosing the wrong parameters undermines the entire purpose of a KDF. Too few iterations or too little memory and the function becomes trivially fast to brute-force. Too many and legitimate users face unacceptable login delays. The right balance targets roughly 100 milliseconds of computation on the expected hardware, adjusted upward as attacker hardware improves over time.
BIP-39's Fixed Iteration Count
BIP-39 specifies exactly 2048 PBKDF2 iterations: a number chosen in 2013 that has not been updated since. By modern standards, 2048 rounds of PBKDF2-HMAC-SHA512 is relatively low. However, BIP-39 mnemonics already carry 128 to 256 bits of entropy, far exceeding a typical password. The PBKDF2 step in BIP-39 serves less as a brute-force defense (the mnemonic itself is already high-entropy) and more as a one-way transformation that separates the mnemonic from the derived seed, allowing the optional passphrase to act as a 25th word.
No Substitute for Strong Entropy
A KDF cannot create entropy that does not exist in the input. If a user picks a 4-digit PIN as their password, even Argon2 with maximum parameters only slows an attacker: the 10,000 possible PINs will all be tried eventually. KDFs work best when combined with strong entropy sources and proper key management practices.
Side-Channel Attacks
Data-dependent KDFs like Argon2d and scrypt are vulnerable to side-channel attacks where an attacker monitors memory access patterns or timing to extract information about the password. This is why Argon2id (the hybrid variant) is recommended for most applications: it combines Argon2i's side-channel resistance with Argon2d's GPU resistance.
Quantum Resistance
KDFs based on symmetric cryptography (HMAC, SHA-2) are relatively resilient against quantum computers. Grover's algorithm reduces the effective security of symmetric primitives by half (e.g., 256-bit becomes 128-bit equivalent), but this is far less catastrophic than Shor's algorithm's impact on elliptic curve and RSA cryptography. For a broader discussion, see post-quantum cryptography.
This glossary entry is for informational purposes only and does not constitute financial or investment advice. Always do your own research before using any protocol or technology.