Although the reply of @Marcelo Uchimura answers the question, I think it does not answer what the code is for, even mentions that this would be for messages, where it is not a point.
HKDF is a KDF using HMAC, there’s a definition of it here. Well, a KDF has as input a data "not so random" and another data, this is uniformly random. A good example of use is when a key is awakened via ECDH, since the key is "mathematical answer", so it is not indistinguishable from completely random data, so the use of KDF is necessary. Similarly, you may want to have multiple keys using only one, so HKDF can also be used, *even if the key needs to more bytes than the original value.*
The HKDF is divided into two parts, one the extractor and the other the expander. This is the extractor:
prk = hmac_sha256(salt, ikm)
The idea here is to include the salt
and the ikm
. Presumes that the salt
is distinguishable from a uniformly random datum, whereas the ikm
maybe it is, but it doesn’t have to be.
Its result, the prk
, is a uniformly random datum, assuming that the hmac_sha256
is a safe PRF, or that at least the SHA256 compression is a PRF.
After that we have the expander, that consumes the prk
, he’s in:
for i in range(ceil(length / hash_len)):
t = hmac_sha256(prk, t + info + bytes([1+i]))
Note that the prk
is used as a key in this step. That is, the key generated by the extractor is used in the expander. The expander will create n required bytes, so there is the range
to repeat the process until it reaches the required amount of bytes.
This process is formally described as:
K(1) = HMAC(PRK, CTXinfo || 0),
K(i + 1) = HMAC(PRK, K(i) || CTXinfo || i), 1 ≤ i < t,
The CTXinfo
is additional information, may be omitted. So basically the input of HMAC is: the previous result (if i > 1) concatenated with the information added and concatenated with i, being i
a single byte, sequential.
In the case of this implementation, as defined in t = b""
, there will be no difference between the first or last execution.
Finally the okm[:length]
will only cut the output, since the hash has fixed size (in the case of SHA-256), so if you want nonmultiple values of 256, for example, you won’t be able to without truncating.
Thank you very much! Now I understand!
– Lucas