I'm trying to wrap my head around the concept of SIV in the context of encryption. I understand the aspect of nonce misuse, etc. And I understand that the key feature for SIV is that they ensure that while encrypting the same message with the same key will reveal that it is identical, it will not reveal anything else.
In particular, using the same key on different messages will not have the catastrophic issue with nonce reuse in other system.
If I understand correctly, you can build a SIV mode of operation using:
def encrypt(msg, key):
siv = hash_shake256(bits=192, msg)
return xchacha20(key, siv, msg), siv
In other words, we first compute a keyed hash on the message, then use that value as the nonce for the actual encryption.
The output is the cipher text as well as the generated siv
, both of them are safe to share without revealing anything to an adversary.
The security comes from the keyed hash function non reversible nature and the fact that for each msg
we pass as input, we are ensured that we won't have a duplicate nonce.
- Am I understanding things correctly?
- Is it safe to use the same key for both keyed hash and encryption?
- I assume actual
siv
usage is a bit more than just hashing the input?
hash_shake256
is used over just the message, but that you talk about "security comes from the keyed hash function". SHAKE256 is not a keyed hash function at all, you'd use e.g. KMAC for that (this is basically the same as SHA-256 vs HMAC-SHA-256). $\endgroup$