# Is it practical to use a stream cipher in a block cipher mode?

My idea is to use a stream cipher encrypting 16 bytes at a time as a primative block cipher in a mode of operation such as CBC mode. Is this practical or useful in any way?

• No, since stream ciphers are very different from block ciphers. $\;$ – user991 May 25 '15 at 11:59
• Cryptography is not an subject where you should endeavor to be creative. What do you hope to accomplish with such a construct? What shortcoming of a stream cipher are you aiming to overcome? – Stephen Touset May 28 '15 at 19:06
• @StephenTouset I couldn't disagree more. I think every subject should have its limits tested. I think every cryptographic concept should be mixed with every other concept at least once to see what happens. Should these untested mixtures be used blindly in critical applications? No, of course not. But I think the moment we stop being creative is the moment we lose innovation. All that being said, one application for using a stream cipher in a block cipher mode is to add an IV to an otherwise IV-less (for lack of a better term) algorithm. – Daffy May 28 '15 at 20:52

The way you propose to use a stream cipher as a drop in replacement for a block cipher is flawed, as the other answer explains nicely.

There is a simple way to convert a stream cipher into a block cipher. In pact, it works for any PRF, regardless of if it is reversible or not.

This presentation perfectly covers how to use a PRG such as a stream cipher to construct a block cipher.

Basically, you use the stream cipher in the following manner:

Take your message m and break it down into an n-bit binary string.

Take your stream cipher $G(k)$ and use it to generate a a stream of length $2 · |k|$. So $G(K) \to K^2$ (output space = double that of keyspace).

Do $k \to G(k)[0]$ and $G(k)[1]$, pick $G(k)[x]$ depending on what the first bit of m is.

Then, compute $G( G(k)[x] )$. You have a message of length two blocks, pick the block corresponding to the second bit of m. Repeat n times.

This can be reversed (decrypted) in the same way Feistel networks are, via the Luby-Rackoff theorem.

• The question was if it was practical not possible. Although the answer of Paŭlo (with alt-gr - shift - 9 u) did not indicate this, it seems possible but not practical. From the same presentation: "Not used in practice due to slow performance". – Maarten Bodewes May 26 '15 at 1:37
• It is n times slower than the underlying stream cipher for a block size of n bits. While not as fast as a stream cipher, this isn't bad. Using these benchmarks for C++ implementation, using the streeam cipher Salsa20, then adjusting Salsa20 in the manner described above, we get speeds of between 3 and 7 Mbps depending on the choice of Salsa20 algo, which is quite practical, although obviously slower than an actual block cipher. – robertkin May 26 '15 at 23:28
• It is not used in practice because there are faster alternatives, but this is not inherently a bad construction, and can have quite practical speeds. – robertkin May 26 '15 at 23:30
• Pretty slow but it does have a configurable block size; that counts for something I suppose. I don't directly see any application, but it is good to get a refresh on Dan's course. – Maarten Bodewes May 26 '15 at 23:56
• Actually, my answer didn't say "you can't convert a stream cipher into a block cipher", but "the way of converting which was proposed in the question doesn't work". I'll try to edit it. – Paŭlo Ebermann May 28 '15 at 18:43

The way proposed in the question to "convert" a stream cipher into a block cipher doesn't work (i.e. is not secure). (Other ways are discussed in Converting a stream cipher into a block cipher and in the other answer here.)

Most stream ciphers (the so-called synchronous ones) work by producing a key stream from a key, which is then XORed with the plaintext to produce a cipher text.

It is important that the same key (or, equivalently, the same part of a keystream) is not used twice, as then it is (more or less) easy to recover the plaintext. If you use only a small part of that keystream repeatedly, like in your proposal, everything breaks down.

$\def\Enc{\operatorname{Enc}}$Let $K = \Enc_k(0)$ the keystream corresponding to one block (16 bytes in your example), so that $\Enc_k(P) = K \oplus P$.

Then using CBC mode with an initialization vector $I$ and a plaintext $P_1, P_2, P_3 \dots P_n$, we get a ciphertext of

$C_1 = \Enc_k(P_1 \oplus I) = K \oplus P_1 \oplus I,$ $C_2 = \Enc_k(P_2 \oplus C_1) = K \oplus P_2 \oplus C_1 = K \oplus P_2 \oplus K \oplus P_1 \oplus I = P_2 \oplus P_1 \oplus I,$ $C_3 = \Enc_k(P_3 \oplus C_2) = K \oplus P_3 \oplus C_2 = K \oplus P_3 \oplus P_2 \oplus P_1 \oplus I,$ $C_4 = \Enc_k(P_4 \oplus C_3) = K \oplus P_4 \oplus C_3 = ... = P_4 \oplus P_3 \oplus P_2 \oplus P_1 \oplus I,$ and so on.

Every second ciphertext block doesn't even depend on the key (but just on the plaintext blocks up to that point and the IV), and from the other ones it is trivial to get $K$ back if some piece of plaintext can be guessed or is known. The original key $k$ is not needed for that.

For a block cipher, we assume it works like a pseudo-random permutation (family), i.e. the result of $\Enc_k(P)$ can not be predicted from $\Enc_k(Q)$, other than same inputs give same results and different inputs give different results. When using a part of a stream cipher in that place, this is obviously not the case.

• In Converting a stream cipher into a block cipher, this is discussed in a more general way – it looks like there is no way to build a block cipher from just a stream cipher, though if you additionally can use a keyed hash function, it might work. (You'll get a block cipher for much larger blocks, though.) – Paŭlo Ebermann May 25 '15 at 16:28
• Most stream ciphers have an IV input in addition to the secret key input, so that each key stream is unique. Well designed stream ciphers are secure even if the IV is chosen/controlled by the attacker. As such, one can use the stream cipher as a pseudorandom function, with the IV as the input and the truncated keystream as the output, and then use a Feistel structure to turn the pseudorandom function into a block cipher (perhaps reserving part of the IV for a round counter to make each round function different). This however would very likely be extremely inefficient. – J.D. May 25 '15 at 16:38
• @J.D. consider adding an answer to the question linked in my previous comment, if that is not already covered by one of the answers there. – Paŭlo Ebermann May 25 '15 at 16:49