# Skein or Keccak stream cipher construction

I am wondering if using Skein or the Keccak hash algorithm in this construction (as a stream cipher) is secure:

• $H$ = Keccak or Skein hash with a 256 bit output
• $K$ = The main 256 bit random key, pre-shared between sender and receiver
• $K_M$ = A secondary 256 bit random key for creating the MAC, pre-shared between sender and receiver
• $IV$ = A per message 256 bit random initialization vector, sent in the clear with the ciphertext and MAC
• $i$ = counter starting at 0 for each message which increments by 1 every 256 bit block
• $K_i$ = 256 bit block of the generated key for encrypting the corresponding 256 bit block of the plaintext $P_i$
• $P_i$ = 256 bit block of the plaintext. The final plaintext block would be padded to the right with 0 bits, thus the final concatenated plaintext is a multiple of 256 bits and disguises the true plaintext length.
• $C_i$ = 256 bit block of ciphertext
• $|$ = concatenation
• ⊕ = XOR

Encryption:

1. $K_i$ = $H$($K$ | $IV$ | $i$)
2. $C_i$ = $K_i$ ⊕ $P_i$

MAC:

• $H$($K_M$ | $IV$ | $C_i$ ... $C_n$)

I hope I explained that clearly.

My other question: Is there a particular attack on using the same key for encryption and MAC?

-

I am wondering if using Skein or the Keccak hash algorithm in this construction (as a stream cipher) is secure:

In the case of Skein and Keccak it should be secure. However, both of those have defined their own cipher modes which you should IMO prefer. (For compatibility, if not security.)

• The Skein one is defined in section 4.10 of the paper. It uses the underlying primitive directly rather than hashing the key and nonce.

• For Keccak the web site links to a separate paper on an authenticated encryption mode. It uses the sponge to squeeze a larger number of output bits, like the SHAKE modes of the hash function.

Is there a particular attack on using the same key for encryption and MAC?

You must first make sure the MAC invocation can never match an encryption one. I.e. it is not possible for $K|IV|C$ to match any $K|IV|i$.

Easiest would probably be to add a string to make them differ, like $H(K|\text{'E'}|IV|i)$ and $H(K|\text{'A'}|IV|C)$.

Generically, your construction is not necessarily secure. First a hash function doesn't have to be a secure MAC when you prepend the key. Second, a stream cipher must be a PRF, which is a stronger condition than unforgeability for a MAC.

For example, you could define a stupid MAC like: $MAC_k(m)||MAC_k(m)$ and it would be just as strong a MAC as the original, but would make a lousy stream cipher.

(In practice most MACs do seem to also claim to be PRF.)

-
[+1] For what it’s worth: there’s a question handling “Is there a difference between PRF and a hash function?” which provides some additional info (and confirms the later part of this answer). –  e-sushi Aug 5 at 12:43

If you replace $H$ with a MAC that is build using $H$, i.e. NMAC, then it will be provably secure. Encryption will be $C_i = MAC_k(IV | i) \oplus P_i$. You are guaranteed by the MAC security property (existential forgery) that an adversary cannot generate any of the key stream on his own and so you are left with a secure stream cipher. Just using $H$ by itself probably will not have any attacks on it (or else they would lead to some significant weakness in the underlying hash function) but it will not be provably secure.

The problem with your construction in general is that you are assuming some strong hiding property of the hash function that may or may not exist. The main properties of a cryptographic hash function are:

1. Pre-image resistance: for a given $x$, it should be difficult to find a message $m$ such that $H(m) = x$

2. Second pre-image resistance: for a given $x$ and $m$, such that $H(m) = x$, it should be difficult to find $m'$ such that $m \neq m'$ and $H(m') = x$

3. Collision resistance: it should be difficult to find two messages $m$ and $m'$ such that $H(m) = H(m')$

Collision resistance implies second pre-image resistance, and in most cases also implies pre-image resistance, so it is the most useful one to consider. However, a hash function could be collision resistance and still leak many of the bits of the input. For instance, if $H$ is a collision resistant hash function, you can construct $H'$ as follows:

$$H'(m) = \text{first 10 bits of m } | H(m)$$

and it will still be collision resistant. Now, obviously SHA-3 does not have this property, but the point is that it was not tested for strict hiding. If you wanted that you would use an actual cipher which was tested for that. Therefore you should not use it as if it does have that property.

-
Digging around I can see from this answer and this answer that Skein and Keccak are secure as MACs in the form $H$($K$ | $M$) and they have strong collision resistance, second pre-image resistance and pre-image resistance. Shouldn't they have the required hiding property for use as a stream cipher? It seems overkill and slow to need NMAC or HMAC when it is already secure... –  kimi Aug 5 at 1:18
Oh well sure, if it has a built-in MAC mode then you can certainly use that. I wasn't aware of that before. I meant only that you cannot generically use a hash function for encryption like you were proposing, but a MAC would suffice. It doesn't have to be NMAC. –  Travis Mayberry Aug 5 at 2:44
A MAC does not necessarily suffice. $\:$ One needs a PRF. $\;\;\;\;$ –  Ricky Demer Aug 5 at 4:19
Well the hash functions listed above are secure as a generic MAC in the simple $H$($K$ | $M$). Skein does have a built-in MAC mode which is slightly better though. On the Keccak website the authors state: "Unlike SHA-1 and SHA-2, Keccak does not have the length-extension weakness, hence does not need the HMAC nested construction. Instead, MAC computation can be performed by simply prepending the message with the key." So technically the construct in my original post is using the MAC mode and I do not see why you cannot turn it into a stream cipher like that... –  kimi Aug 5 at 4:23
Oh you're right Ricky. I remembered you could encrypt from a MAC but actually you would have to do it one bit at a time. You could have a degenerate MAC that always sets the last bit to one for instance, which would make a bad stream cipher. But you could do something like a Goldreich-Levin hard core predicate and use that to encrypt a single bit. But, you could do the same thing with a hash function so actually my whole point is kind of nullified :D –  Travis Mayberry Aug 5 at 11:21