Cryptography ‐ HKDF - Arrbat/Veil-Forge GitHub Wiki
Introduction
The HMAC-based Key Derivation Function (HKDF) is a type of Key Derivation Function (KDF).
The primary goal of a KDF is to take some initial source of keying material and derive from it one or more cryptographically strong secret keys.
Why not just divide a key into smaller parts and use them?
For example, imagine you have a securely generated 64-bit key. Suppose you have an encryption function that uses 8 rounds, each requiring its own round key.
If you simply divide the 64-bit key into 8 parts for each round key, that means each round key is 8 bits (64 / 8 = 8 bits).
The problem is: an attacker can brute-force each 8-bit round key separately.
Since each round key is 8 bits, there are 2^8=256 possibilities per round.
There are 8 rounds, so brute-forcing all round keys independently requires (2^8)*8 =2048 attempts.
This is extremely weak compared to brute-forcing the original 64-bit key, which requires 2^64 ≈1.84×10^19 attempts — a number vastly larger and currently infeasible to brute force.
So, simply dividing the key into smaller parts drastically weakens security.
HKDF
HMAC
If you want to deeply understand HKDF you need to know what HMAC is
HKDF
Explanation is described here by using great book:
A Graduate Course in Applied Cryptography
Dan Boneh and Victor Shoup
8.10.5 HKDF
The input to HKDF consists of a secret s, an optional salt value salt, an optional info field, and an output length parameter L. The parameters s, salt, and info are variable length byte strings.
There are 2 stages: extract and expand.
Extract:
t ← HMAC(salt, s)
Expand stage:
-
Use the intermediate key
t
obtained from the extract stage. -
Compute as many HMAC blocks as needed to produce
L
bytes of output. -
Each block
z_i
is calculated as:
z_i ← HMAC(t, z_{i-1} || info || Octet(i))
where:
-
z_0 is the empty string,
-
info is the optional context and application-specific information,
-
Octet(i) is a single byte encoding the integer i.
-
Concatenate all blocks z_1 || z_2 || ... || z_q (where q = ceil(L / HashLen)) and take the first L bytes as the final output key.
Project`s context
The key point is that the string obfuscation-context
is used as the info
parameter. While other values may be used, the info
parameter is generally intended as public context and is not recommended to be private or random.