

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer

I understand that for a stream cipher to be useful, there must be a way to verify that the message was not tampered with (bits were flipped by an attacker).

So, instead of using some cryptographic hash function, like SHA-2, with HMAC, what if I used a much simpler (and faster) hash function, like FNV hash algorithm, and encode its output together with the plaintext?

Like, suppose I have a 1000 bytes plaintext message, then I hash it with Fowler–Noll–Vo of 256 bits output, then concatenate them both, having a message+MAC with 1032 bytes.

Then I XOR this 1032 bytes message+MAC with 1032 bytes output of some stream cipher (the ordinary encode operation of most of them, like RC4 or those in eSTREAM portfolio).

What is the problem of this approach?

share|improve this question
Consider universal hashing(such as Poly1305) or SipHash. Are those fast enough for you? If you use Salsa20 from the eStream portfolio, it's standard library NaCl comes with a Salsa20+Poly1305 implementation by default. – CodesInChaos Jan 22 '13 at 17:40
I don't really understand your scheme. Do you want to append an unkeyed hash of the plaintext, concat that with the message, and encrypt both? That's a really bad idea, even with secure hashes. Check How do unkeyed hash functions (for MDCs) provide security? – CodesInChaos Jan 22 '13 at 17:42
up vote 6 down vote accepted

If I understand you correctly, you want to use $C = \mathrm{Enc}_{K,N}(m || \mathrm{hash}(m))$ as authenticated encryption. This is a bad idea, even for cryptographically secure hashes.

Consider an attacker who knows your plaintext $m$ and wants to replace it by $m^\prime$. He calculates $C^\prime = C \oplus (m || \mathrm{hash}(m)) \oplus (m^\prime || \mathrm{hash}(m^\prime))$ which is the valid ciphertext for $m^\prime$.

We had two related questions: How do unkeyed hash functions (for MDCs) provide security? and Is the encryption of a hash a good MAC?.

As alternatives to hash based MACs, you could consider:

  1. Universal hashing
    A bit annoying to implement, but features a security reduction to the security of the cipher.

    • AES-GCM is one a popular choice, but its performance isn't so great in software without specific instructions(AES-NI&co). With those instructions it's really fast, and it's a standard.
    • Salsa20-Poly1305 is an alternative. It has a fast implementation in NaCl which avoids timing attacks. Poly1305 can be used with any stream cipher and is fast in software.
  2. SipHash

    Fast in software, especially for short messages. It produces 64 bit MACs, which should be sufficient because MACs guard against online attacks. It's pretty easy to implement.

    The main issue is that it's rather new and thus hasn't seen much analysis. I would only use it if security isn't super important.

share|improve this answer

Your Answer


