7
Pseudorandomness

Pseudorandom Permutations

In a simple substitution cipher, each letter is replaced with another letter, for example:

ag,ba,cr,db,el,fe,gd,\begin{aligned} \bit{a} &\mapsto \bit{g}, & \bit{b} &\mapsto \bit{a}, & \bit{c} &\mapsto \bit{r}, \\ \bit{d} &\mapsto \bit{b}, & \bit{e} &\mapsto \bit{l}, & \bit{f} &\mapsto \bit{e}, \\ \bit{g} &\mapsto \bit{d}, & & \cdots\end{aligned}

Under this particular substitution, cabbage\bit{cabbage} becomes rgaagdl\bit{rgaagdl}. If we want to be able to reverse this process, then the substitution must be a permutation over the set of letters {a,,z}\{ \bit{a}, \ldots, \bit{z} \}.

Substitution ciphers of individual letters are not difficult to break, and frankly not very interesting. However, a substitution cipher that operates on pairs of letters is slightly more interesting:

aami,abke,acro,adsu,\begin{aligned} \bit{aa} &\mapsto \bit{mi}, & \bit{ab} &\mapsto \bit{ke}, & \bit{ac} &\mapsto \bit{ro}, \\ \bit{ad} &\mapsto \bit{su}, & & \cdots\end{aligned}

In this example, the individual letter a\bit{a} can be mapped to m,i,k,r,\bit{m}, \bit{i}, \bit{k}, \bit{r}, etc., depending on its neighboring letters. The cipher must again be a permutation, this time over the set {aa,,zz}\{ \bit{aa}, \ldots, \bit{zz} \}.

A substitution cipher that operates on large blocks of letters is more interesting still. Here's an example that uses blocks of twenty-four letters:

aaaaaaaaaaaaaaaaaaaaaaaaypkcbrcxirsrzauuakbkwzys,aaaaaaaaaaaaaaaaaaaaaaabnsaplzgbiwfmlybifushgnbj,\begin{aligned} \bit{aaaaaaaaaaaaaaaaaaaaaaaa} &\mapsto \bit{ypkcbrcxirsrzauuakbkwzys}, \\ \bit{aaaaaaaaaaaaaaaaaaaaaaab} &\mapsto \bit{nsaplzgbiwfmlybifushgnbj}, \\ \vdots & \phantom{\mapsto} \vdots\end{aligned}

A substitution cipher like this would require a truly enormous amount of storage—in fact, more bytes than there are atoms in the universe.

Just as a PRF emulates an enormous (lazy) random dictionary, a pseudorandom permutation (PRP) emulates an enormous (lazy) random permutation over large blocks of bits. A PRP can expand a short secret key into a permutation (both the forward and reverse directions) that is indistinguishable from a uniformly sampled permutation.

7.1. Defining PRPs

Pseudorandom permutations operate on blocks of bits, not blocks of characters.

Definition 7.1.1 (Keyed permutation)

A keyed permutation consists of two functions:

F:{0,1}λ×{0,1}n{0,1}n;F1:{0,1}λ×{0,1}n{0,1}n.\begin{aligned} F &: \bits^\secpar \times \bits^n \to \bits^n; \\ F^{-1} &: \bits^\secpar \times \bits^n \to \bits^n.\end{aligned}

The first input to these functions is the key; the second input and the output are blocks.

The functions must satisfy the following correctness property: F1(K,F(K,X))=XF^{-1}(\key, F(\key, X)) = X for all K{0,1}λ\key \in \bits^\secpar and all X{0,1}nX \in \bits^n. In other words, the two functions F(K,)F(\key,\cdot) and F1(K,)F^{-1}(\key,\cdot) are inverses.

We call nn the blocklength of the keyed permutation. We refer to the permutation collectively as F±F^{\pm}.

This chapter's introduction gives some hint about how to define security for a PRP—it should be indistinguishable from a lazy random permutation. But how does one implement a lazy random permutation? We can take inspiration from lazy random dictionaries, and realize that a permutation is simply a dictionary whose entries do not repeat:

query(X)\subname{query}(X):
if L[X]\prftable[X] undefined:
Y{0,1}nYY \gets \bits^n \setminus \mathcal{Y}
Y:=Y{Y}\mathcal{Y} := \mathcal{Y} \cup \{Y\}
L[X]:=Y\prftable[X] := Y
return L[X]\prftable[X]

In this code, Y\mathcal{Y} contains all of the values stored so far in the dictionary. It always samples the next value to avoid repeating any in Y\mathcal{Y}. Thus, the function implemented by query\subname{query} is a permutation.

I can already hear you asking, Wait, that's only the forward direction of a permutation. What about the reverse direction? Indeed, a pseudorandom permutation must implement both directions. However, many applications that use pseudorandom permutations expose only the forward direction to the adversary. So for the purposes of security, we will start with this simple attack scenario, in which the adversary gets access to the forward direction only; it must be indistinguishable from the forward direction of a lazy random substitution. Later, in section 7.5, we introduce a stronger security model that provides the adversary access to both directions of the permutation.

Definition 7.1.2 (Pseudorandom permutation)

A keyed permutation F±F^{\pm} is a secure pseudorandom permutation (PRP) if the following two libraries are indistinguishable:

Lprp-realF\lib{prp-real}^F
K{0,1}λ\key \gets \bits^\secpar
prp.query(X)\prpquery(X):
return F(K,X)F(\key,X)
\indist
Lprp-randF\lib{prp-rand}^F
prp.query(X)\prpquery(X):
if L[X]\prftable[X] undefined:
Y{0,1}nYY \gets \bits^n \setminus \mathcal{Y}
Y:=Y{Y}\mathcal{Y} := \mathcal{Y} \cup \{Y\}
L[X]:=Y\prftable[X] := Y
return L[X]\prftable[X]

PRPs are also commonly called block ciphers, and in this book we will use both names interchangeably.

Be careful! This chapter is about permutations over the set {0,1}n\bits^n, meaning that they map an nn-bit string X{0,1}nX \in \bits^n to another arbitrary nn-bit string YY. We are not talking about rearranging the bits of XX in a regular way (e.g., move bit 1 of XX to bit 10 of the output; move bit 2 of XX to bit 3 of the output). This would be one way to map nn-bit strings to nn-bit strings, but not a very good one (see exercise 7.1).

7.2. Comparing PRPs and PRFs, and the switching lemma

Compare the Lprp-rand\lib{prp-rand} library from the PRP security definition to the Lprf-rand\lib{prf-rand} library from the PRF security definition. The former library samples outputs without replacement, and the latter with replacement. If the PRF/PRP outputs are long enough (specifically, λ\secpar bits) then we expect this difference to be indistinguishable thanks to the birthday bound (lemma 4.5.7). This observation is known as the the (PRF-PRP) switching lemma:

Lemma 7.2.1 (PRF-PRP switching lemma)

The following two libraries are indistinguishable:

query(X)\subname{query}(X):
if L[X]\prftable[X] undefined:
L[X]{0,1}λ\prftable[X] \gets \bits^\secpar
return L[X]\prftable[X]
\indist
query(X)\subname{query}(X):
if L[X]\prftable[X] undefined:
Y{0,1}λYY \gets \bits^\secpar \setminus \mathcal{Y}
Y:=Y{Y}\mathcal{Y} := \mathcal{Y} \cup \{Y\}
L[X]:=Y\prftable[X] := Y
return L[X]\prftable[X]
Proof:

The only difference in the two libraries is whether they sample values with or without replacement. They can be proven indistinguishable by a simple three-hop maneuver involving lemma 4.5.7.

What does it mean that the security goals for PRPs and PRFs are indistinguishable?

Consequences of the switching lemma

If we have a keyed permutation with blocklength λ\secpar, and we wish to show that it is a secure PRP, it's enough to prove that it is a secure PRF.

Conversely, if a certain construction requires a secure PRF with output length λ\secpar, then it is safe to use a secure PRP. A secure PRP with blocklength λ\secpar is a secure PRF!

This is all potentially confusing, but just remember: A PRF and PRP provide very different functionality to someone who knows the key. But when we talk about PRF security, we are talking about the perspective of an adversary who doesn't know the secret key, and who has access only to the forward direction of the function. The PRF security definition says that, in this situation, outputs are pseudorandom. The definition neither demands nor forbids the existence of an inverse. Just knowing that a function is a PRF tells you nothing about whether it is a permutation. Secure PRPs satisfy the definition of PRF security while having an inverse; some other PRFs do not have inverses.

7.3. How to construct a PRP: The Feistel construction

Can we upgrade a PRF into a PRP? How can we add an inverse to a function that may not have one? This section describes a clever way to do just that.

Definition 7.3.1 (Feistel cipher)

An rr-round Feistel cipher with round functions F1,,FrF_1, \ldots, F_r is defined as follows:

F(X0X1)\mathbb{F}( X_0 \| X_1 ):
for i=1i = 1 to rr:
Xi+1:=Xi1Fi(Xi)X_{i+1} := X_{i-1} \oplus F_i(X_i)
return XrXr+1X_r \| X_{r+1}
\qquad

If the round functions each map nn bits to nn bits, then the Feistel cipher F\mathbb{F} maps 2n2n bits to 2n2n bits.

Claim 7.3.2 (Feistel ciphers are permutations)

A Feistel cipher is always a permutation on {0,1}2n\bits^{2n}, regardless of its round functions.

Proof:

Each round of a Feistel cipher computes the next block as:

Xi+1=Xi1Fi(Xi). X_{i+1} = X_{i-1} \oplus F_i(X_i).

To invert this round, we can rearrange the equation to solve for Xi1X_{i-1} in terms of XiX_i and Xi+1X_{i+1}:

Xi1=Xi+1Fi(Xi). X_{i-1} = X_{i+1} \oplus F_i(X_i).

Importantly, we do not require FiF_i to have an inverse. Both the forward and inverse direction of the Feistel cipher evaluate FiF_i in the forward direction!

The diagram below illustrates the case of a single round and its inverse:

We can invert the entire Feistel cipher by inverting each round in this way, starting from the last round:

F1(XrXr+1)\mathbb{F}^{-1}( X_r \| X_{r+1} ):
for i=ri = r down to 11:
Xi1:=Xi+1Fi(Xi)X_{i-1} := X_{i+1} \oplus F_i(X_i)
return X0X1X_0 \| X_1
\qquad
Construction 7.3.3 (Keyed Feistel ciphers)

A Feistel cipher whose round functions are F(K1,),F(K2,),,F(Kr,)F(\key_1, \cdot), F(\key_2, \cdot), \ldots, F(\key_r,\cdot) is called an rr-round keyed Feistel cipher with round function FF.

F(K1Kr, X0X1)\mathbb{F}\Bigl( \key_1 \| \cdots \| \key_r, ~ X_0 \| X_1 \Bigr):
for i=1i = 1 to rr:
Xi+1:=Xi1F(Ki,Xi)X_{i+1} := X_{i-1} \oplus F(\key_i, X_i)
return XrXr+1X_r \| X_{r+1}

The sequence K1,,Kr\key_1, \ldots, \key_r is called the key schedule.

Like any Feistel cipher, a keyed Feistel cipher is invertible. In order to invert a Feistel cipher, you must evaluate its round functions (in the forward direction). If the round functions require a key, then that key is required to evaluate both directions of the Feistel cipher.

Since a Feistel cipher is a keyed permutation, we might ask whether it can be a secure PRP. The answer depends on the number of rounds. In exercise 7.5 you are asked to show that a 2-round Feistel cipher cannot be a secure PRP. However, three rounds is enough, assuming that the round function is a secure PRF:

Theorem 7.3.4 (Security of three-round Feistel cipher)

Let FF be a secure PRF with input/output length λ\secpar. Then a three-round keyed Feistel cipher with round function FF is a secure PRP (with blocklength 2λ2\secpar).

F(K1K2K3, X0X1)\mathbb{F}\Bigl( \key_1\|\key_2 \|\key_3, ~ X_0 \| X_1 \Bigr):
X2:=X0F(K1,X1)X_2 := X_0 \oplus F(\key_1, X_1)
X3:=X1F(K2,X2)X_3 := X_1 \oplus F(\key_2, X_2)
X4:=X2F(K3,X3)X_4 := X_2 \oplus F(\key_3, X_3)
return X3X4X_3 \| X_4
\qquad

We already know that any Feistel cipher is invertible, so it suffices to show that this Feistel cipher is pseudorandom. From lemma 7.2.1, it is enough to show that F\mathbb{F} is a secure PRF. In other words:

if \quad
Lprf-realF\lib{prf-real}^F
K{0,1}λ\key \gets \bits^\secpar
prf.queryF(X)\prfquery_F(X):
return F(K,X)F(\key,X)
\indist
Lprf-randF\lib{prf-rand}^F
prf.queryF(X)\prfquery_F(X):
if L[X]\prftable[X] undefined:
L[X]{0,1}λ\prftable[X] \gets \bits^\secpar
return L[X]\prftable[X]
then \quad
Lprf-realF\lib{prf-real}^{\mathbb{F}}
K1K2K3{0,1}3λ\key_1\|\key_2\|\key_3 \gets \bits^{3\secpar}
prf.queryF(X0X1)\prfquery_{\mathbb{F}}(X_0 \| X_1):
// F(K1K2K3, X0X1)\mathbb{F}\bigl( \key_1\|\key_2 \|\key_3, ~ X_0 \| X_1 \bigr)
X2:=X0F(K1,X1)X_2 := X_0 \oplus F(\key_1, X_1)
X3:=X1F(K2,X2)X_3 := X_1 \oplus F(\key_2, X_2)
X4:=X2F(K3,X3)X_4 := X_2 \oplus F(\key_3, X_3)
return X3X4X_3 \| X_4
\indist
Lprf-randF\lib{prf-rand}^{\mathbb{F}}
prf.queryF(X0X1)\prfquery_{\mathbb{F}}(X_0\|X_1):
if L[X0X1]\prftable[X_0\|X_1] undefined:
L[X0X1]{0,1}2λ\prftable[X_0\|X_1] \gets \bits^{2\secpar}
return L[X0X1]\prftable[X_0\|X_1]

Proof idea: Our goal is to show that the Feistel cipher's outputs are pseudorandom. What can we say about these outputs?

The output is X3X4X_3 \| X_4, and each of these is an xor-expression:

X3=X1F(K2,X2),X4=X2F(K3,X3).\begin{aligned} X_3 &= X_1 \oplus F(\key_2, X_2), \\ X_4 &= X_2 \oplus F(\key_3, X_3). \end{aligned}

We can think of any xor expression as an OTP ciphertext. Here, it makes most sense to think of X1,X2X_1, X_2 as the OTP plaintexts and F(K2,X2)F(\key_2,X_2) and F(K3,X3)F(\key_3,X_3) as OTP keys. Thus, if we can show that these “OTP keys” are pseudorandom, we will be able to easily conclude that X3X_3 and X4X_4 are also pseudorandom. So what can we say about F(K2,X2)F(\key_2, X_2) and F(K3,X3)F(\key_3, X_3)?

Clearly these values are outputs of a secure PRF FF. So they are pseudorandom, provided that the PRF inputs (in this case, X2X_2 and X3X_3) do not repeat. Most of the proof is devoted to showing that X2X_2 and X3X_3 repeat with only negligible probability.

Proof (details):

The proof follows the outline described above. Indeed, the crux of the proof is to show that X2X_2 and X3X_3 values don't unexpectedly repeat, so that outputs X3:=X1F(K2,X2)X_3 := X_1 \oplus F(\key_2,\hl{X_2}) and X4:=X2F(K3,X3)X_4 := X_2 \oplus F(\key_3,\hl{X_3}) are pseudorandom. We will trigger a bad event when X2X_2 or X3X_3 unexpectedly repeat. To make the bad event's probability easier to analyze, we will move all bad-event logic to the end of time.

Hybrid Sequence:
The starting point is Lprf-realF\lib{prf-real}^{\mathbb F}.
We can add a cache L[]\prftable[\cdot] so that each distinct output is computed only once.
We can replace each PRF instance F(Ki,)F(\key_i,\cdot) with a separate lazy random dictionary Li[]\prftable_i[\cdot]. The standard three-hop maneuvers are not shown.
We expect X2X_2 and X3X_3 to never repeat. So we can use the usual PRF Golden Rule proof strategy to make the assignments to L2[X2]\prftable_2[X_2] and L3[X3]\prftable_3[X_3] unconditional, triggering a bad event if these values were already defined. Later, we must show that the bad event's probability is negligible.
Instead of sampling L2[X2]\prftable_2[X_2] uniformly and then computing X3X_3, we can sample X3X_3 uniformly and compute L2[X2]\prftable_2[X_2]. The same reasoning applies to L3[X3]\prftable_3[X_3] and X4X_4. The standard three-hop maneuver involving claim 2.4.2 is not shown.
Now X3X_3 and X4X_4 are sampled uniformly and concatenated into L[X0X1]\prftable[X_0\|X_1]. These steps can happen as early as possible.
Nothing after the assignment to L[]\prftable[\cdot] affects what the adversary sees; it exists only to determine whether to trigger a bad event. We can therefore move all bad-event logic to the end of time, without changing the bad event's overall probability.
Lprf-realF\lib{prf-real}^{\mathbb F}
K1K2K3{0,1}3λ\key_1 \| \key_2 \| \key_3 \gets \bits^{3\secpar}
prf.queryF\prfquery_{\mathbb{F}}(X0X1X_0\|X_1):
X2:=X0X_2 := X_0 \oplus {}
F(K1,X1)F(\key_1,X_1)
L1[X1]\prftable_1[X_1]
X3:=X1X_3 := X_1 \oplus {}
F(K2,X2)F(\key_2,X_2)
L2[X2]\prftable_2[X_2]
X4:=X2X_4 := X_2 \oplus {}
F(K3,X3)F(\key_3,X_3)
L3[X3]\prftable_3[X_3]
return
X3X4X_3 \| X_4
L[X0X1]\prftable[X_0\|X_1]

The final library is Lprf-randF\lib{prf-rand}^{\mathbb F}, along with some logic at the end of time to determine whether to trigger the bad event. If we can show that the bad event's probability is negligible in this final hybrid, then we have completed the proof.

Our probability analysis uses the fact that the bad-event logic happens at the end of time, after all of the adversary's inputs and outputs have been fixed. There are two cases that trigger the bad event:

  • Case 1: There are two distinct inputs X0X1X_0\|X_1 and X0X1X'_0\|X'_1 that both lead to the same X2X_2 value. This happens if and only if

    X0L1[X1]=X0L1[X1]. X_0 \oplus \prftable_1[X_1] = X'_0 \oplus \prftable_1[X'_1].

    Rearrange this condition to the equivalent:

    X0X0=L1[X1]L1[X1]. X_0 \oplus X'_0 = \prftable_1[X_1] \oplus \prftable_1[X'_1].
    • Case 1a: If X1=X1X_1 = X'_1, then the right-hand-side is zero. We must also have X0X0X_0 \ne X'_0 since X0X1X0X1X_0\|X_1 \ne X_0'\|X'_1. But then the left-hand side is nonzero, and the condition can never be true. We conclude that this case is impossible.

    • Case 1b: If X1X1X_1 \ne X'_1, then L1[X1]\prftable_1[X_1] and L1[X1]\prftable_1[X'_1] were sampled uniformly and independently. Not only that; they were sampled independently of X0X_0 and X0X'_0. So the probability that they satisfy the condition is 1/2λ1/2^\secpar.

    So, two specific inputs X0X1X_0 \| X_1 and X0X1X'_0\|X'_1 induce the same X2X_2 value with probability at most 1/2λ1/2^\secpar. If the adversary makes qq calls to prf.queryF\prfquery_{\mathbb{F}}, then there are at most q2q^2 pairs of inputs that could lead to this bad event. By the union bound, the overall probability of Case 1 is at most q2/2λq^2 / 2^\secpar.

  • Case 2: There are two distinct inputs X0X1X_0\|X_1 and X0X1X'_0\|X'_1 that both lead to the same X3X_3 value. This case is easier because for each distinct input X0X1X_0\|X_1 to prf.query\prfquery, the library samples an X3X_3 value uniformly and independently. Hence, X3X_3 values repeat according to the birthday probability Birthday(q,2λ)\Birthday(q,2^\secpar), where qq is the number of calls to prf.queryF\prfquery_{\mathbb{F}} made by the adversary.

Overall, the probability of the bad event is at most:

Pr[bad event]Pr[case 1]+Pr[case 2]q2/2λ+Birthday(q,2λ).\begin{aligned} \PR{ \text{bad event} } &\le \PR{ \text{case 1} } + \PR{ \text{case 2} } \\ &\le q^2 / 2^\secpar + \Birthday(q,2^\secpar). \end{aligned}

which is negligible since qq is polynomial in the security parameter.

If the Feistel cipher has an inverse, why can't the adversary break it by inverting it?
The adversary does not know the round keys, so it cannot evaluate the round function, so it cannot evaluate the Feistel cipher in either direction.

7.4. PRPs in theory and practice

7.4.1. Feistel ciphers in practice

The block ciphers you will encounter in practice are not built from the Feistel cipher recipe presented in lemma 7.3.4, for a few reasons:

  • If we build a Feistel cipher from a PRF, and the PRF is built from a PRG according to construction 6.5.1, the result would be slow. It would require 3λ3\secpar calls to the PRG to evaluate the PRP on a single input.

  • Theorem 7.3.4 doesn't provide great concrete security, which is important in practice. (Recall the discussion of concrete vs. asymptotic security in chapter 4.) The Feistel cipher has blocklength 2λ2\secpar but gives only λ/2\sim\secpar/2 bits of concrete security. The proof of theorem 7.3.4 involves a bad event with probability at most O(q2/2λ)O(q^2/2^\secpar). If an adversary makes q2λ/2q \sim 2^{\secpar/2} queries to prf.query\prfquery, the bound becomes useless, telling us only that the bad event happens with probability at most 1.

In practice, we use fast block ciphers that don't generally have security proofs that reduce their security to simpler components like PRGs. So theorem 7.3.4 does not describe any real-world block ciphers design. However, some real-world PRPs do use the basic structure of the Feistel cipher. So the practical implication of theorem 7.3.4 is to provide justification for a general design principle for real-world PRPs.

Later in the book, many constructions and security proofs do explain exactly how things are built in the real world. For example, the CBC, CTR, GCM constructions explain exactly how to a PRP is used to build real-world encryption schemes.

The Digital Encryption Standard (DES) was the most widely used block cipher in the '80s and '90s. DES is fundamentally a Feistel cipher; thus, its security rests, to a great extent, on the security of its round function. There are a few important differences between the “theoretical” Feistel cipher and a “practical” one like DES:

  • Three rounds are enough for a theoretical Feistel cipher, because in the world of theory you can be confidently assume that your round function is a PRF. (Four rounds are needed to achieve a stronger security property—see section 7.5.) Real-world Feistel ciphers usually have many more rounds, reflecting the fact that the round functions are not proven to be secure PRFs, or even conjectured to be full-fledged PRFs. DES, for example, is a 16-round Feistel cipher.

  • A theoretical Feistel cipher uses the simplest possible key schedule, in which the round keys are independent. The proof of theorem 7.3.4 relies heavily on the fact that the round keys are independent, giving rise to completely independent pseudorandom round functions. A theoretical rr-round Feistel cipher requires a key that is rr times longer than the round function's key. Long keys are inconvenient, so real-world Feistel ciphers derive the round keys from a single, short master key. For example, DES has a 56-bit master key, and each of its 48-bit round keys are simply a different subset of bits from the master key.

7.4.2. Meet-in-the-middle attack

There is another reason for real-world Feistel ciphers deriving round keys from a single, short master key. It has to do with an attack called meet-in-the-middle.

Example 7.4.1 (Meet-in-the-middle attack)

Suppose FF is a PRP that can be decomposed into two phases, such that the first phase depends only on the first half of the (λ\secpar-bit) key, and the second phase depends only on the second half of the key. In other words, FF can be written as:

F(KLKR,X)F\bigl( \key_L\| \key_R, X \bigr):
Y:=A(KL,X)Y := A(\key_L, X)
Z:=B(KR,Y)Z := B(\key_R, Y)
return ZZ
\quad
F1(KLKR,Z)F^{-1}\bigl( \key_L\| \key_R, Z \bigr):
Y:=B1(KR,Z)Y := B^{-1}(\key_R, Z)
X:=A1(KL,Y)X := A^{-1}(\key_L, Y)
return XX

For example, FF could be an rr-round Feistel cipher, where AA represents first r/2r/2 rounds (and KL\key_L represents the first r/2r/2 round keys) and BB represents the second r/2r/2 rounds.

If FF has this structure, then it is possible to recover FF's private key in time O(2λ/2)O(2^{\secpar/2}) given just a few input-output samples from FF.

Suppose that Z=F(KLKR,X)Z = F(\key_L\|\key_R,X), and consider the intermediate value YY that is computed during the computation of FF. There are two different ways to compute this YY: one that uses only KL\key_L and another that uses only KR\key_R:

A(KL,X)=Y=B1(KR,Z). A(\key_L, X) = Y = B^{-1}(\key_R, Z).

This fact allows us to brute-force the two halves of the keys separately, if we have an example of an input-output sample (X,Z)(X,Z) from FF:

  • For all possible KL{0,1}λ/2\key_L \in \bits^{\secpar/2}, compute a candidate value Y:=A(KL,X)Y' := A(\key_L,X). Record each candidate YY' along with the key KL\key_L that produced it.

  • For all possible KR{0,1}λ/2\key_R \in \bits^{\secpar/2}, compute a candidate value Y:=B1(KR,Z)Y' := B^{-1}(\key_R,Z). Record each candidate YY' along with the key KR\key_R that produced it.

  • The previous two steps will result in two large lists of candidate YY values. The “correct” value YY, corresponding to the victim's true key, must be in both lists.

If the “correct” YY is the only candidate in both lists, then the adversary has identified the victim's key as the unique KL\key_L and KR\key_R values that gave rise to this YY. If there is more than one candidate in both lists, then we can take a note of the possible candidates for KL\key_L and KR\key_R, discarding the rest, and repeat the attack again on another input-output sample from FF. In practice, the correct key is identified after only a small constant number of input-output samples.

Since this attack brute-forces the two halves of the λ\secpar-bit key separately, its total cost is “only” 22λ/2=O(2λ/2)\sim 2 \cdot 2^{\secpar/2} = O(2^{\secpar/2}). The moral of the story: Don't provide a way to brute-force different parts of the key separately.

The meet-in-the-middle attack requires exponential time 2λ/22^{\secpar/2}, which is why it does not invalidate theorem 7.3.4. Meet-in-the-middle is relevant only when considering concrete security. A block cipher with λ\secpar-bit keys that is vulnerable to a meet-in-the-middle attack can be broken in O(2λ/2)O(2^{\secpar/2}) time; ideally we prefer λ\secpar-bit block ciphers to have λ\secpar bits of concrete security.

7.4.3. Recommendations and Alternatives

DES is the traditional example of a real-world Feistel cipher and a good illustration of how the real world differs from theory. But DES is sorely outdated; you should never use it. The most glaring problem with DES is that its key is only 56 bits long.

DES was supplanted in the early 2000s by its successor, the Advanced Encryption Standard (AES). There are three standardized variants of AES, supporting keys of length 128, 192, and 256 bits. All three variants use a blocklength of 128 bits. AES is still widely regarded as secure, and it should be your default choice of PRP. Thanks to its position as a global standard, fast hardware-accelerated AES operations are now incorporated into many modern CPUs.

AES is not a Feistel cipher; it is designed using an entirely different methodology. Later, in section 12.3, we discuss a theoretical approach for PRPs that is closer to AES's design.

7.5. ☆ Strong PRPs

You may have noticed that the PRP security definition involves only the forward direction FF and not the reverse direction F1F^{-1}. The security definition therefore models an attack scenario in which the adversary can control a victim's inputs only to the PRP's forward direction. This limited attack scenario suffices for many applications of PRPs, which we will see in the next chapters.

However, other applications use PRPs in a way that allows an adversary to control the victims' inputs to both the PRP and its inverse. We need a different security definition for PRPs to reflect this kind of attack scenario.

An adversary who has access to both directions of a PRP should not be able to distinguish what it sees from a lazy random permutation and its inverse. Therefore, the new security definition involves a library that implements a lazy random permutation alongside its inverse. This library is slightly more cumbersome, because it must do significant bookkeeping to efficiently implement a permutation along with its inverse.

Definition 7.5.1 (Strong pseudorandom permutation)

A keyed permutation F±F^{\pm} is a secure strong pseudorandom permutation (SPRP) if the following two libraries are indistinguishable:

Lsprp-realF\lib{sprp-real}^F
K{0,1}λ\key \gets \bits^\secpar
sprp.query+(X)\sprpquery(X):
return F(K,X)F(\key,X)
sprp.query(Y)\sprpinvquery(Y):
return F1(K,Y)F^{-1}(\key,Y)
\indist
Lsprp-randF\lib{sprp-rand}^F
sprp.query+(X)\sprpquery(X):
if L+[X]\prftable^+[X] undefined:
Y{0,1}nYY \gets \bits^n \setminus \mathcal{Y}
L+[X]:=Y;X:=X{X}\prftable^+[X] := Y; \mathcal{X} := \mathcal{X} \cup \{ X \}
L[Y]:=X;Y:=Y{Y}\prftable^-[Y] := X; \mathcal{Y} := \mathcal{Y} \cup \{ Y \}
return L+[X]\prftable^+[X]
sprp.query(Y)\sprpinvquery(Y):
if L[Y]\prftable^-[Y] undefined:
X{0,1}nXX \gets \bits^n \setminus \mathcal{X}
L+[X]:=Y;X:=X{X}\prftable^+[X] := Y; \mathcal{X} := \mathcal{X} \cup \{ X \}
L[Y]:=X;Y:=Y{Y}\prftable^-[Y] := X; \mathcal{Y} := \mathcal{Y} \cup \{ Y \}
return L[Y]\prftable^-[Y]

You can understand how Lsprp-rand\lib{sprp-rand} implements a lazy random permutation through the following invariants:

  • If L+[X]\prftable^+[X] is defined, then L[L+[X]]=X\prftable^-[\prftable^+[X]] = X.

  • If L[Y]\prftable^-[Y] is defined, then L+[L[Y]]=Y\prftable^+[\prftable^-[Y]] = Y.

  • X\mathcal X stores the set of values XX on which L+[X]\prftable^+[X] is defined.

  • Y\mathcal Y stores the set of values YY on which L[Y]\prftable^-[Y] is defined.

Modern real-world block ciphers are designed to be secure SPRPs.

Exercises

  1. Let FF be a secure PRP with blocklength \ell bits (think of \ell as a small integer, like 7 or 8). For this exercise we will interpret inputs and outputs of FF not as \ell-bit strings, but as numbers in the range {1,,2}\{1, \ldots, 2^\ell\} in the natural way.

    Now consider the following keyed permutation FF', with blocklength 22^\ell:

    F(K,X)F'(\key,X):
    for i=1i=1 to nn:
    // iith bit of YY = F(K,i)F(\key,i)'th bit of XX
    Y[i]:=X[F(K,i)]Y[i] := X\bigl[ F(\key,i) \bigr]
    return YY

    Thus, FF' rearranges the bits of XX according to the permutation FF. Show that FF' is not a secure PRP.

  2. Let F1F_1 and F2F_2 be keyed permutations, both with blocklength nn, and define the following function HH:

    H(K1K2,X)=F2(K2,F1(K1,X)). H\bigl( \key_1 \| \key_2, X \bigr) = F_2\bigl( \key_2, F_1(\key_1, X) \bigr).

    Prove that HH is a secure PRP if either of F1F_1 or F2F_2 is a secure PRP. The proof should be split into two cases. In the first case, assume that F1F_1 is secure, and assume nothing from F2F_2 other than the fact that it is indeed a keyed permutation (i.e., it has an inverse). In the second case, swap the roles of F1F_1 and F2F_2.

  3. Lemma 7.2.1 requires the PRP to have blocklength (at least) λ\secpar. Suppose that FF is a secure PRP with blocklength only n=16n=16. Are the libraries from lemma 7.2.1 still indistinguishable?

  4. Show that an rr-round keyed Feistel cipher is not a secure PRP, for any rr, if its round function is F(Ki,X)=KiXF(\key_i,X) = \key_i \oplus X.

  5. Show that a 2-round keyed Feistel cipher cannot be a secure PRP, even if the round function is a secure PRF.

  6. Let FF be a secure PRF with input and output length λ\secpar, and consider the three-round Feistel cipher with round function FF. Its key schedule normally consists of three independent keys (K1,K2,K3)(\key_1, \key_2, \key_3); in this problem we consider the security of simpler key schedules.

    1. Show that the cipher is not a secure PRP if K1=K3\key_1 = \key_3 (and K2\key_2 is chosen independently).

    2. Prove that the cipher is a secure PRP if K1=K2\key_1 = \key_2 (and K3\key_3 is chosen independently).

    3. Prove that the cipher is a secure PRP if K2=K3\key_2 = \key_3 (and K1\key_1 is chosen independently).

  7. Let FF be a secure PRF with input and output length λ\secpar. In this problem we consider a Feistel cipher variant where the key schedule is K1=K2=\key_1 = \key_2 = \cdots, but where the last round function is iterated twice. The three- and four-round variants are therefore:

    F(K,X0X1)\mathbb{F}( \key, X_0 \| X_1 ):
    X2:=X0F(K,X1)X_2 := X_0 \oplus F(\key, X_1)
    X3:=X1F(K,X2)X_3 := X_1 \oplus F(\key, X_2)
    X4:=X2F(K,F(K,X3))X_4 := X_2 \oplus F\bigl(\key,F(\key, X_3)\bigr)
    return X3X4X_3 \| X_4
    \quad
    F(K,X0X1)\mathbb{F}( \key, X_0 \| X_1 ):
    X2:=X0F(K,X1)X_2 := X_0 \oplus F(\key, X_1)
    X3:=X1F(K,X2)X_3 := X_1 \oplus F(\key, X_2)
    X4:=X2F(K,X3)X_4 := X_2 \oplus F(\key, X_3)
    X5:=X3F(K,F(K,X4))X_5 := X_3 \oplus F\bigl(\key,F(\key, X_4)\bigr)
    return X4X5X_4 \| X_5
    1. Show that the three-round variant above is not a secure PRP.

    2. \star Prove that the four-round variant above is a secure PRP.

  8. A standard PRF is secure against an adversary who chooses the PRF inputs. Suppose we do not allow the adversary to choose the inputs; instead, the victim will sample inputs uniformly, and tell the adversary the choice of input. If a PRF's outputs are pseudorandom in this attack scenario, we call it a weak PRF. More formally, F\mathbb{F} is a weak PRF if the following two libraries are indistinguishable:

    Lwprf-real\lib{wprf-real}
    K{0,1}λ\key \gets \bits^\secpar
    wprf.query()\subname{wprf.query}(\,):
    X{0,1}nX \gets \bits^n
    return (X,F(K,X))\bigl(\hl{X,} \mathbb{F}(\key,X)\bigr)
    \indist
    Lwprf-rand\lib{wprf-rand}
    wprf.query()\subname{wprf.query}(\,):
    X{0,1}nX \gets \bits^n
    if L[X]\prftable[X] undefined:
    L[X]{0,1}m\prftable[X] \gets \bits^m
    return (X,L[X])\bigl(\hl{X,} \prftable[X]\bigr)
    1. Prove that a 2-round keyed Feistel cipher (with independent round keys) is a weak PRF, if its round function is a secure PRF.

    2. How does the answer change if the 2-round Feistel cipher uses the trivial key schedule K1=K2K_1 = K_2?

  9. Describe a more detailed implementation of the meet-in-the-middle attack in example 7.4.1. What data structures should you use, and how should you identify values common to two sets, to ensure that the overall running time remains O(2λ/2)O(2^{\secpar/2})?

  10. Show that a 3-round keyed Feistel cipher is not a secure strong PRP (definition 7.5.1), even if its round function is a secure PRF.

  11. \star Prove that a 4-round keyed Feistel cipher (using independent round keys) is a secure strong PRP (definition 7.5.1) if its round function is a secure PRF.

  12. \star Let F±F^\pm be a secure SPRP with blocklength λ\secpar. In this exercise we will construct a new PRP HH that is almost identical to FF but with two of its inputs swapped. Specifically, let X0:=F1(K,0λ)X_0 := F^{-1}(\key, \bit0^\secpar) and let X1:=F1(K,1λ)X_1 := F^{-1}(\key, \bit1^\secpar). Then HH will be identical to FF except that it will swap the outputs for X0\overline{X_0} (the bitwise complement of X0X_0) and X1X_1.

    H(K,X)H(\key, X):
    X0:=F1(K,0λ)X_0 := F^{-1}(\key, \bit0^\secpar)
    X1:=F1(K,1λ)X_1 := F^{-1}(\key, \bit1^\secpar)
    if X==X0X == \overline{X_0}:
    return 1λ\bit1^\secpar
    else if X==X1X == X_1:
    return F(K,X0)F(\key, \overline{X_0})
    else:
    return F(K,X)F(\key, X)
    \quad
    H1(K,Y)H^{-1}(\key, Y):
    X0:=F1(K,0λ)X_0 := F^{-1}(\key, \bit0^\secpar)
    X1:=F1(K,1λ)X_1 := F^{-1}(\key, \bit1^\secpar)
    if Y==1λY == \bit1^\secpar:
    return X0\overline{X_0}
    else if Y==F(K,X0)Y == F(\key, \overline{X_0}):
    return X1X_1
    else:
    return F1(K,Y)F^{-1}(\key, Y)

    Pictorially:

    H1H^{-1} cannot be a secure PRP: H1(K,0λ)H^{-1}(\key, \bit0^\secpar) and H1(K,1λ)H^{-1}(\key, \bit1^\secpar) are always bitwise complements, and so H1H^{-1} is easily distinguished from a random dictionary.

    Despite that, prove that HH is a (plain) PRP. Thus, it is possible for HH to be a secure PRP while H1H^{-1} is not.

Chapter Notes

The Feistel cipher methodology first appeared in the Lucifer block cipher, developed by Horst Feistel at IBM in 1971 [100]. Luby and Rackoff were the first to prove that a three-round Feistel cipher is a secure PRP (theorem 7.3.4) if the round function is a secure PRF [149]. Patarin proved that a four-round Feistel cipher is a secure strong PRP (exercise 7.11) [176].

The results of exercise 7.6, involving simplifications to the key schedule of a three-round Feistel cipher, were shown by Ohnishi [173] (in Japanese, as reported in [222]). The attack on a three-round Feistel cipher with key schedule K1=K2=K3\key_1 = \key_2 = \key_3 was also shown independently by Rueppel [197]. The secure (four-round) single-key Feistel cipher variant from exercise 7.7 was proposed by Pieprzyk [182]; the attack against the three-round variant (and many generalizations thereof) was given by Zheng, Matsumoto, and Imai [222].

  1. Previous Chapter6. Pseudorandom Functions
  2. Next Chapter8. Chosen-Plaintext Attacks Against Encryption