4

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?

Daffy
  • 2,429
  • 20
  • 29

2 Answers2

4

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.

robertkin
  • 448
  • 3
  • 11
3

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.

Paŭlo Ebermann
  • 22,946
  • 7
  • 82
  • 119