Long before HKDF became the dominant key derivation function on the internet, standards bodies like ANSI and ISO had already defined their own family of KDFs. They are usually called KDF1, KDF2, and KDF3, and they show up in the ANSI X9.63 standard for elliptic curve cryptography, in IEEE 1363, in ISO/IEC 18033-2 for public-key encryption, and in many older smart card and banking systems. They are also the KDFs used inside the ECIES (Elliptic Curve Integrated Encryption Scheme) construction that you still find in Bitcoin libraries, in some old TLS cipher suites, and in payment terminals.
If you have read about HKDF you may wonder why these older KDFs still exist and what makes them different. The answer is partly historical and partly technical. They came first, they are simpler, and many regulated environments still mandate them. This article walks through what KDF1, KDF2, and KDF3 are, where each one applies, how they differ, and how they relate to modern KDFs like HKDF and the NIST counter-mode KDFs.
The Common Idea: Hash-Based Counter Mode
All three KDFs share a basic structure. You give them an input keying material Z and a desired output length L, and they produce L bytes of output by hashing Z together with a counter that increments for each output block. The hash function is usually SHA-1 in older deployments, or SHA-256 in modern ones.
The pseudocode looks roughly like this:
for i = 1 to ceil(L / hash_output_size): block_i = Hash(Z || counter_encoded(i) || optional_info) output = first L bytes of (block_1 || block_2 || ...)
The differences between KDF1, KDF2, and KDF3 lie in three details: the starting counter value, where the counter is placed in the hash input, and whether and where shared info is included.
This pattern, sometimes called counter-mode hashing, is older than HKDF and predates the formal extract-then-expand paradigm. It assumes the input Z is already high-entropy. In other words, it is purely an Expand-style construction. It does not deal with the messy-entropy case the way HKDF Extract does.
KDF1: The IEEE 1363 Original
KDF1 is the simplest of the three. It is defined in IEEE 1363a-2004, in ISO/IEC 18033-2, and in ANSI X9.42.
The function is:
KDF1(Z, L) = Hash(Z || 0x00000000) || Hash(Z || 0x00000001) || ...
The counter starts at 0 and is encoded as a 32-bit big-endian integer. There is no separate info field; if you want to bind context, you concatenate it into Z yourself.
KDF1 has a known weakness when L is exactly equal to the hash output size and Z is short. In that edge case, an attacker who learns Hash(Z || 0x00000000) can sometimes invert it more easily than expected because of how iterated hashes leak structure. This is mostly a theoretical concern but it motivated the move to KDF2.
KDF1 was the only KDF in older versions of IEEE 1363 and shows up in legacy ECIES implementations, especially those derived from Crypto++ or older Bouncy Castle.
KDF2: Counter Starts at One
KDF2 is defined in ISO/IEC 18033-2 and is the recommended ECIES KDF in many modern banking standards.
The function is identical to KDF1 except that the counter starts at 1 instead of 0:
KDF2(Z, L) = Hash(Z || 0x00000001) || Hash(Z || 0x00000002) || ...
This tiny change avoids the edge case that worried analysts of KDF1. It does not change the construction in any material way for typical use, but it is the version preferred by ISO/IEC 18033-2 and by ANSI X9.63 when used as a KDF.
KDF2 is what most ECIES implementations actually use today, even if the documentation casually says "KDF1." Bouncy Castle, OpenSSL's older ECDH derive functions, and many smart card SDKs use KDF2 under the hood.
KDF3: With Shared Info Field
KDF3 adds a shared info parameter, similar to HKDF's info argument.
The function is:
KDF3(Z, L, SharedInfo) = Hash(counter_i || Z || SharedInfo) for i = 1, 2, 3, ...
Note that the counter comes first, before Z. This is the opposite of KDF1 and KDF2. KDF3 is the version that ISO/IEC 18033-2 recommends when you need explicit context binding. It is also the underlying KDF used in some ECIES variants when the standard requires party identifiers, algorithm OIDs, or session labels mixed into derivation.
The ANSI X9.63 KDF
The KDF defined in ANSI X9.63 (and inherited by SECG SEC 1) is essentially KDF2 with a SharedInfo field appended to each block:
X963KDF(Z, L, SharedInfo) = Hash(Z || counter_i || SharedInfo) for i = 1, 2, 3, ...
The counter is a 32-bit big-endian integer starting at 1. The SharedInfo is a structured byte string containing things like the algorithm identifier, party identifiers, and any context strings the protocol needs.
ANSI X9.63 KDF is the de facto standard for ECIES in payment systems, in EMV chip cards, and in many older TLS cipher suites. NIST SP 800-56A includes a similar construction as one of its approved KDFs for key agreement.
ECIES: The Most Famous Use Case
ECIES, the Elliptic Curve Integrated Encryption Scheme, was introduced by Bellare and Rogaway and standardized in IEEE 1363a, ISO/IEC 18033-2, and SECG SEC 1. It uses an elliptic curve key exchange (typically ECDH) to derive a shared secret, then runs that secret through a KDF (KDF1, KDF2, or X9.63 KDF), and uses the output to key both an AEAD or a separate encryption-and-MAC pair.
The ECIES recipe is:
- Generate ephemeral EC key pair (r, R).
- Compute shared secret Z = r * recipient_public_key.
- Derive (encryption_key, mac_key) = KDF(Z, encryption_key_size + mac_key_size, SharedInfo).
- Encrypt the message under encryption_key.
- MAC the ciphertext under mac_key.
- Send (R, ciphertext, MAC).
This pattern is alive and well today. It powers the encryption in many cryptocurrency wallets (notably ECIES-secp256k1 in Ethereum and Bitcoin libraries), in payment terminal channels, and in some Internet of Things device certificates.
For a more modern alternative built on HKDF, see Hybrid Encryption and HKDF (RFC 5869) Line by Line.
How These KDFs Compare to HKDF
The big differences:
HKDF separates Extract and Expand. KDF1/2/3 only have Expand. They assume the input Z is uniform. If you feed them a non-uniform secret, they may not be safe.
HKDF uses HMAC, which is a stronger primitive than plain hashing for keying. The Bellare-Canetti-Krawczyk security proof for HMAC carries over to HKDF. The KDF1/2/3 family relies on plain hash output behaving as a random oracle when its inputs are concatenated, which is a stronger heuristic assumption.
HKDF has a richer info handling story. KDF3 has SharedInfo but the binding is positional: appended after the counter. Mistakes in encoding SharedInfo can cause domain separation failures. HKDF's structured approach plus HKDF-Expand-Label in TLS 1.3 (RFC 8446) makes context handling more robust.
For new designs, HKDF is the consensus choice. The older KDFs persist mainly because of legacy compatibility, regulated banking and payment standards, and ECIES libraries that have not been updated.
Where You Still See KDF1/2/3 Today
EMV (chip-and-PIN payment cards) uses ANSI X9.63 KDF in its session key derivation for ECC-based card schemes.
Bitcoin and Ethereum wallet libraries that implement ECIES typically use KDF2 or X9.63 KDF.
Some hardware security modules expose KDF1, KDF2, and X9.63 KDF as named primitives; choose the one your standard requires.
Older TLS cipher suites with ECDH key exchange used X9.63 KDF for the premaster-to-master derivation. TLS 1.3 replaced this with HKDF.
ISO/IEC 18033-2 conformance testing in some certified products requires that the KDF be one of KDF1, KDF2, or KDF3.
Common Implementation Mistakes
Confusing KDF1 and KDF2. Many open-source codebases label their function "KDF1" but actually start the counter at 1, which is KDF2. Always check the source.
Reusing the same SharedInfo across different keys. If you derive both an encryption key and a MAC key, the natural approach is to call X9.63 KDF once with the combined length, then split. Calling it twice with the same SharedInfo gives the same key both times.
Using SHA-1 in new code. Many older specifications still cite SHA-1. New deployments should use SHA-256 or SHA-384. NIST has formally retired SHA-1 for most purposes.
Truncating in the middle of a block. The counter-based KDFs produce output one hash block at a time. You should always take a contiguous prefix from the start.
Mixing up byte order. The counter is a big-endian 32-bit integer in all three KDFs. Little-endian implementations will not interoperate.
How NIST SP 800-56A and SP 800-56C Fit In
NIST has formalized similar constructions. SP 800-56A specifies key agreement schemes (Diffie-Hellman, ECDH) and includes its own KDFs that look very much like KDF3. SP 800-56C Rev. 2 explicitly endorses HKDF and the older one-step KDF (which is essentially X9.63 KDF) as approved.
The one-step KDF in SP 800-56C is parameterized by an auxiliary function H, which can be a hash, an HMAC, or a KMAC. This unifies several historical specs under one framework. We cover this in detail in Concat KDF (SP 800-56C).
For counter-mode KDFs that operate on already-uniform keys (rather than ECDH-style messy secrets), SP 800-108 is the relevant document. See NIST SP 800-108 Counter Mode KDFs.
Post-Quantum Considerations
Like HKDF, the KDF1/2/3 family does not break under quantum attack as long as the underlying hash holds. SHA-256 has Grover's-algorithm security around 128 bits, which is fine for symmetric-strength derivation. SHA-384 or SHA-512 give more headroom.
The bigger post-quantum question is what happens to the input Z. In classical ECIES, Z comes from ECDH on a prime curve. ECDH falls to Shor's algorithm on a sufficiently large quantum computer. The mitigation is to replace ECDH with a key encapsulation mechanism, typically ML-KEM (FIPS 203). The KDF step itself does not change. See ML-KEM Explained for how the input shifts but the derivation pattern stays.
In hybrid constructions, you might run both ECDH and ML-KEM and combine their shared secrets before passing to a KDF. The KDF can be HKDF or, in legacy banking environments, X9.63 KDF. As long as both halves contribute entropy, you get the best of both worlds. See Hybrid Encryption for the full pattern.
Frequently Asked Questions
Should I use KDF1, KDF2, or KDF3 in new code?
Probably none of them, unless a standard you must follow specifically mandates one. For new internet-facing protocols, use HKDF. For new closed systems with no compatibility constraints, use HKDF or KMAC.
Is X9.63 KDF the same as KDF3?
They are very close. Both prepend or include a counter and append SharedInfo, both start the counter at 1, and both use a hash function. The exact byte layout differs slightly between specs, so they are not bit-for-bit interoperable.
Can I use SHA-3 with these KDFs?
In principle yes; the construction is hash-agnostic. But standards usually fix the hash to SHA-1 or SHA-2 family. If you need SHA-3, prefer KMAC or HKDF-SHA3.
Why does ECIES still use these old KDFs?
Inertia and standards lock-in. Many payment and smart card standards reference ANSI X9.63 KDF directly. Cryptocurrency libraries inherited the design from older Bouncy Castle code. Replacing them is a multi-year compliance effort.
Are these KDFs FIPS-approved?
X9.63 KDF and the SP 800-56A one-step KDF are approved when used with an approved hash. Generic KDF1 and KDF2 are not by themselves FIPS-listed but a compliant SP 800-56C variant covers the same ground. See NIST FIPS Guide for navigation tips.
Sources
- ISO/IEC 18033-2:2006. "Information technology -- Security techniques -- Encryption algorithms -- Part 2: Asymmetric ciphers." https://www.iso.org/standard/37971.html
- ANSI X9.63-2011. "Public Key Cryptography for the Financial Services Industry: Key Agreement and Key Transport Using Elliptic Curve Cryptography."
- IEEE Std 1363a-2004. "IEEE Standard Specifications for Public-Key Cryptography -- Amendment 1: Additional Techniques."
- NIST SP 800-56C Rev. 2. "Recommendation for Key-Derivation Methods in Key-Establishment Schemes." August 2020. https://csrc.nist.gov/pubs/sp/800/56/c/r2/final
- NIST SP 800-56A Rev. 3. "Recommendation for Pair-Wise Key-Establishment Schemes Using Discrete Logarithm Cryptography." April 2018. https://csrc.nist.gov/pubs/sp/800/56/a/r3/final
- SECG SEC 1: "Elliptic Curve Cryptography." Standards for Efficient Cryptography Group. May 2009. https://www.secg.org/sec1-v2.pdf
Related Articles
- HKDF (RFC 5869) Line by Line
- Concat KDF (SP 800-56C): The Two-Step Approach
- NIST SP 800-108 Counter Mode KDFs Explained
- ML-KEM Explained: How NIST's Lattice KEM Works
- Hybrid Encryption: Why Combining Old and New Crypto Is Stronger
Protect Your Data Before Q-Day Arrives
QNSQY's NIST-standardized post-quantum encryption protects files against both current and quantum-era threats.