# Blake2B as a KDF

How would one go about using vanilla keyed Blake2B as a KDF with high-entropy inputs. Assume I don't have access to more specialized algorithms such blake2XB, HKDF, etc.

• Salt - high entropy per-encryption salt (32 bytes)
• IKM - high entropy static input keying material (32 bytes)
• Info - a personalization string for the key being derived

Would a construction such as Blake2B(input: $(\text{Salt} \parallel \text{Info})$, key: $\text{IKM}$) be sound?

Taking into account that Blake2 is not prone to length extension attacks, how does the aforementioned construction compare to Blake2B(input: $(\text{Salt} \parallel \text{Info} \parallel \text{IKM})$)?

• I think of blake2b as a function of type $\{0,1\}^* -> \{0,1\}^{256}$. Given that, it isn't clear what you mean by Blake2B(input: (Salt || Info), key: IKM) - how is the key input into blake2b? Also, NIST has a perfectly fine KDF construction using hash and counter (typically SHA512) which could readily be used with any secure hash algorithm. Jun 9, 2017 at 20:26
• @ThomasM.DuBuisson I mean there are a myriad of Blake implementations; Blake, Blake2, Blake2B, Blake2S, Blake2XB, Blake2XS, Blake2BP, Blake2SP. Within most implementations of Blake2B I find some that accept a key as input. Some offer salts and personalization strings... some variable-length outputs (which differs from simple truncation). Frankly. it's a bit overwhelming. Anyway, my question refers to Blake2B implementations that accept a key parameter (or no params other than the input). Regarding what NIST offers - my question is not regarding alternative primitives. Jun 9, 2017 at 21:27
• NISTs method is a way to use a hash, not an alternate primitive. Jun 10, 2017 at 2:19
• "Assume I don't have access to more specialized algorithms such blake2XB, HKDF, etc.". My question is regarding Blake2B. If I specifically pre-empt dismissive suggestions to go with NIST protocols, could you do me the courtesy of not suggesting them? Jun 10, 2017 at 3:21
• @Elias yes - the concept/terminology is borrowed from HKDF Jun 10, 2017 at 12:47

Actually, what you want is possible with plain Blake2b - if your implementation supports the full specification (PDF) (which is marked as optional by RFC 7693).

If this is the case, you'd do the following mappings:

• Feed the info data into the personalization -part of the parameter block.
• Feed the salt data into the salt -part of the parameter block.
• Feed the IKM data into the key-input of the Blake2b.

Alternatively you can also just feed the info into the main hashing input.

Note thought that key is limited to a size of 64 bytes (the maximum for Blake2b). So if you expect your IKM to be regularly larger than that, it might make sense to mandate straight pre-hashing of your IKM so it fits in.

It gets more interesting if your salt and info exceeed 16 bytes in size (which is the maximum defined for Blake2b) or if your Blake2 implementation only supports the key-input.

In this case what you want is to use a proper pairing function, so that a salt of 0xDEADBEEF won't produce the same result as a salt of 0xDEAD and a personalization of 0xBEEF. Now the simplest such pairing function would be to also include the lengths of the inputs. So you would hash info_length || salt_length || info || salt where the lengths are 32- or 64-bit integers (constant-sized!). Alternatively you could fix a maximal length for either input and then append fill up the remaining space with 0xFF(0x00)*.

Shortening the definition of HKDF (for sufficiently short output) it is just:

HMAC(HMAC(XTS, SKM), CTXinfo || 0)

(format: HMAC(key, msg))

Since this is barely more complicated than your example of

Blake2B(input: (Salt || Info), key: IKM)

I would recommend doing that instead. I know you explicitly stated you don't have access to HKDF but I don't see the big difference here.

• Shouldn't it be HMAC(HMAC(XTS, SKM), CTXinfo || 1) (instead of 0) for the first output block? Oct 16, 2020 at 23:47

You can use PBKDF2, using Blake2b as the hash function. One of the parameters to PBKDF2 is the hash function you want to use:

PBKDF2(PRF, Password, Salt, Iterations, DesiredBytes)


So it can be:

Blake2b algorithm has the ability itself to generate keys up to 512 bytes long.

• but if you need an alternative
• or someone is demanding the use of PBKDF2
• or you need a key that is longer than 512-bits

then using a password-based key-derivation function to derive a key from a password also works.

It's also useful information to know, as many people only think of:

• PBKDF2_sha1
• PBKDF2_sha256

and don't realize that you can substitute any hash function you like.

• bcrypt isn't a key-derivation function; it's a password hashing algorithm. In this case we're not using a KDF to add computational time, we're only using it to convert an arbitrary length password into a specific number of bits for an encryption key. E.g. correct horse battery staple ==> 56-bit DES key, hunter2 all i see is asterisks ==> 192-bit AES key. The asker noted that we assume the incoming password already is high-entropy. script and argon2 can also be used as key-derivation functions (in addition to people using them as password hashing algorithms). Feb 5, 2019 at 20:36