Libsodium supports Blake2 for key derivation. It seems like you shouldn't truncate the output to get two keys (eg one encryption/one mac) as the recommended way is to use a counter as the salt for different keys.

Would it be ok to use the encryption key as input keying material for Blake2 to derive a mac key and then still use the encryption key for encryption?

I know it should really be a master key for the input keying material but it's not possible to use a counter as the salt in my case. It's also not really possible to use a random salt in my case.

  • The problem is the salt.
    – Guest
    Feb 7, 2021 at 15:23
  • Gilles nicely wrote a long answer for you. You can upvote and accept it.
    – kelalaka
    Feb 7, 2021 at 21:35

1 Answer 1


First, the premise of this specific question is suspicious: why do you want a MAC key and an encryption key, rather than a single authenticated encryption key? Unless you're implementing some legacy protocol, use AEAD. That being said, I'll answer the question you asked.

No, this is not ok. Never use the same key material for two different things. This is bad, both for cryptographic reasons and for key management reasons.

The cryptographic reason is that different cryptographic mechanisms might involve related calculations. If you feed them the same secret input, some intermediate calculations of one mechanism might coincide with intermediate calculations of the other mechanism. For example, this is what broke OCB2: it's an authenticated encryption mode that didn't sufficiently distinguish the keying material used for the authentication part and for the encryption part, allowing an attacker to obtain an authentication tag by requesting the encryption of some data. Reusing key material directly for different mechanisms at worst leads to trivial attacks, and at best puts you in uncharted territory which is still not acceptable when it comes to cryptography.

The key management reason is that keys used for different purposes usually have different risks, lifetimes, risks and reaction to compromise. For example, if an encryption key is leaked, all data encrypted with that key is compromised. On the other hand, if an authentication key is leaked, data protected by that key is still safe if you can guarantee that it was generated before the leak.

If you need to store a single piece of secret data but you need to use it as a key for multiple purposes, apply a key derivation function (KDF) to that piece of secret data and use disjoint outputs for each purpose. You can get disjoint outputs either by running the KDF once and splitting the output, or by running the KDF multiple times with different non-secret parameters.

Since that stored piece of secret data is used for key derivation, it must not be used for any other purpose.

With libsodium, the recommended way is to treat each key as a subkey, following the example in the documentation:

#define CONTEXT "Guest's application, version 1"
crypto_kdf_derive_from_key(encryption_key, sizeof(encryption_key), 1, CONTEXT, master_key);
crypto_kdf_derive_from_key(authentication_key, sizeof(authentication_key), 2, CONTEXT, master_key);

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .