6
Pseudorandomness

Pseudorandom Functions

If Alice and Bob want to communicate privately in the presence of an adversary, they must share some secret. The longer the shared secret is, the more data they can send.

You just learned about PRGs, which can upgrade a short shared secret into a longer one. This chapter introduces pseudorandom functions, which take the idea of a PRG to an extreme. Using a PRF, Alice and Bob can expand a short shared secret into an effectively unlimited amount of shared secret data.

6.1. Motivating and defining PRFs

Alice and Bob want to appear (to the adversary) as though they have not just a uniformly sampled string but a huge, shared dictionary data structure filled with uniformly sampled strings. A dictionary is like an array that is indexed by strings rather than integers. A dictionary, indexed by nn-bit strings and filled with uniformly sampled mm-bit strings, would be accessed via the following interface:

for each X{0,1}nX \in \bits^n:
L[X]{0,1}m\prftable[X] \gets \bits^m
query(X)\subname{query}(X):
return L[X]\prftable[X]

At each distinct position in this data structure, you'll find an independent, uniformly sampled mm-bit string. Of course, that mm-bit string never changes after it is chosen, so if you call query twice with the same input, you'll get the same output.

We can even consider values of nn like n=λn=\secpar, which cause the dictionary to be exponentially large. In that case, the code written above would require exponential time to initialize the dictionary. On the other hand, a polynomial-time calling program would only be able to access a tiny fraction of its entries. We can use the following trick to implement an “exponentially large” dictionary, in polynomial time: Instead of sampling all entries eagerly at the beginning of time, the library can sample them lazily at the moment they are requested:

eager:\text{eager:}
for each X{0,1}nX \in \bits^n:
L[X]{0,1}m\prftable[X] \gets \bits^m
query(X)\subname{query}(X):
return L[X]\prftable[X]
\equiv
lazy:\text{lazy:}
// L[]\prftable[\cdot] is global, and
// initially undefined everywhere
query(X)\subname{query}(X):
if L[X]\prftable[X] undefined:
L[X]{0,1}m\prftable[X] \gets \bits^m
return L[X]\prftable[X]

This way, if the calling program runs in polynomial time, then the library does too. We refer to this idiom as a lazy random dictionary. The goal of a pseudorandom function is to provide the same functionality as a lazy random dictionary.

A pseudorandom function (PRF) takes two inputs: Just like a PRG, a PRF expects a uniformly chosen seed. A PRF also expects an input corresponding to the value XX in the libraries above, the “index” into the lazy random dictionary. In our usual approach to security definitions, the victim is responsible for choosing the seed: uniformly, secretly, and in this case, reused in every call to the PRF. The other PRF input is left completely under the adversary's control.

Definition 6.1.1 (Pseudorandom function)

A function F:{0,1}λ×{0,1}n{0,1}mF : \bits^\secpar \times \bits^n \to \bits^m is a secure pseudorandom function (PRF) if the following two libraries are indistinguishable:

Lprf-realF\lib{prf-real}^F
K{0,1}λ\key \gets \bits^\secpar
prf.query(X)\prfquery(X):
return F(K,X)F(\key,X)
\indist
Lprf-randF\lib{prf-rand}^F
prf.query(X)\prfquery(X):
if L[X]\prftable[X] undefined:
L[X]{0,1}m\prftable[X] \gets \bits^m
return L[X]\prftable[X]

nn is called the input length and mm is called the output length of the PRF.

Why “function?” A PRF is a function in the sense that a dictionary is like a function that maps nn-bit inputs to mm-bit outputs, represented as a simple truth table. A (lazy) random dictionary is the truth table of a function chosen uniformly from the set of all such functions.

English translation of the PRF security definition

If its key is secret and chosen uniformly, then a PRF's outputs (on distinct inputs) are pseudorandom, no matter how the inputs are chosen.

Key derivation: One of the most common applications of a PRF is key derivation. Imagine Alice and Bob share a secret key, K\key, but want to try out dozens of cryptographic algorithms. As a general rule, it's not safe to reuse the same key for many different algorithms, since the security definition for each algorithm assumes that its key is used for nothing else.

So instead of using their shared key K\key for multiple purposes, they treat it as a “master key” and use a PRF to derive any needed application-specific keys. They can use F(K,xyz)F(\key, \bit{xyz}) as their key for the XYZ algorithm; F(K,abc)F(\key,\bit{abc}) as their key for the ABC algorithm. They can use F(K,this)F(\key,\bit{this}) for this and F(K,that)F(\key,\bit{that}) for that, and so on. The security property of a PRF is that these application-specific keys are indistinguishable from unrelated, independent, uniformly chosen keys.

6.2. How to attack PRFs

Let's gain some intuition about PRFs by seeing attacks against some insecure constructions.

Remember, a PRF is a deterministic function, by design. Don't try to attack a PRF by calling it twice on the same input and observing that the output repeats. This is not an attack, because both Lprf-real\lib{prf-real} and Lprf-rand\lib{prf-rand} repeat outputs when prf.query\prfquery is called on a repeated input.

6.2.1. A first example

Claim 6.2.1 (An insecure PRF)

The function F(K,X)=G(K)XF(\key,X) = G(\key) \oplus X is not a secure PRF, even if GG is a secure PRG. In other words, the following two libraries are not indistinguishable:

Lprf-real\lib{prf-real}
K{0,1}λ\key \gets \bits^\secpar
prf.query(X)\prfquery(X):
// F(K,X)F(\key, X):
return G(K)XG(\key) \oplus X
≊̸\not\indist
Lprf-rand\lib{prf-rand}
prf.query(X)\prfquery(X):
if L[X]\prftable[X] undefined:
L[X]{0,1}m\prftable[X] \gets \bits^m
return L[X]\prftable[X]
Proof:

The output of FF has the form G(K)XG(\key) \oplus X, which always contains the same G(K)G(\key) term. When part of an xor-expression is repeated several times, we can apply the cancellation strategy. Suppose an adversary sees two outputs of FF, which have the form:

Y1=G(K)X1,Y2=G(K)X2.\begin{aligned} Y_1 &= G(\key) \oplus X_1, \\ Y_2 &= G(\key) \oplus X_2.\end{aligned}

Taking the xor of these outputs causes the common term G(K)G(\key) to cancel, resulting in X1X2X_1 \oplus X_2.

On the other hand, imagine probing a random dictionary at distinct points X1X_1 and X2X_2. What is the chance that the results happen to xor to X1X2X_1 \oplus X_2? Not likely! Thus, we can conclude that FF does not behave like a random dictionary. We can formalize the attack as follows. The reasoning from above does not depend on any special properties of X1X_1 or X2X_2, other than the fact that they are distinct. So we can keep the choice of X1X_1 and X2X_2 arbitrary in the description of the attack.

A\A
X1,X2:=X_1, X_2 := {} arbitrary, distinct strings
Y1:=prf.query(X1)Y_1 := \prfquery(X_1)
Y2:=prf.query(X2)Y_2 := \prfquery(X_2)
return Y1Y2==X1X2Y_1 \oplus Y_2 == X_1 \oplus X_2

When A\A is linked to Lprf-real\lib{prf-real}, as we established earlier, Y1Y2=X1X2Y_1 \oplus Y_2 = X_1 \oplus X_2 is always true. The adversary outputs true\mytrue with probability 1 in this case.

When A\A is linked to Lprf-rand\lib{prf-rand}, then since X1X_1 and X2X_2 are distinct, Y1Y_1 and Y2Y_2 are distinct values in the lazy dictionary, L[X1]\prftable[X_1] and L[X2]\prftable[X_2]. Therefore, Y1Y_1 and Y2Y_2 are distributed uniformly and independently. The probability that two uniformly and independently chosen strings have a specific xor (X1X2X_1 \oplus X_2) is 1/2m1/2^m.

The difference between these two output probabilities is nonnegligible, so the attack is successful and we conclude that FF is not a secure PRF.

6.2.2. A second example

Below is an unsuccessful attempt to use a PRF with shorter input length to build one with a larger input length.

Claim 6.2.2 (Another insecure PRF)

The function H(K1K2,X1X2)=F(K1,X1)F(K2,X2)H\bigl(\key_1 \| \key_2 ,X_1 \| X_2 \bigr) = F(\key_1, X_1) \oplus F(\key_2,X_2) is not a secure PRF, even if FF is a secure PRF. In other words, the following two libraries are not indistinguishable:

Lprf-real\lib{prf-real}
K1K2{0,1}2λ\key_1 \| \key_2 \gets \bits^{2\secpar}
prf.query(X1X2)\prfquery(X_1 \| X_2):
// H(K1K2,X1X2)H(\key_1\|\key_2, X_1 \| X_2):
return F(K1,X1)F(K2,X2)F(\key_1,X_1) \oplus F(\key_2,X_2)
≊̸\not\indist
Lprf-rand\lib{prf-rand}
prf.query(X1X2)\prfquery(X_1\|X_2):
if L[X1X2]\prftable[X_1\|X_2] undefined:
L[X1X2]{0,1}m\prftable[X_1\|X_2] \gets \bits^m
return L[X1X2]\prftable[X_1\|X_2]
Proof:

Whenever two inputs to HH share a common first half X1X_1, the corresponding outputs of HH have a common term F(K1,X1)F(\key_1, X_1). We can turn this observation into a proper attack with the cancellation strategy.

Suppose the adversary calls prf.query\prfquery on two inputs ABA\|B and ABA\|B' where BBB \ne B'. The outputs then have the form:

F(K1,A)F(K2,B);F(K1,A)F(K2,B).\begin{aligned} F(\key_1, A) \oplus F(\key_2, B); \\ F(\key_1, A) \oplus F(\key_2, B').\end{aligned}

We can xor the two outputs together to cancel the common term, and obtain the value

(F(K1,A)F(K2,B))(F(K1,A)F(K2,B))=F(K2,B)F(K2,B). \Bigl( F(\key_1, A) \oplus F(\key_2, B) \Bigr) \oplus \Bigl( F(\key_1, A) \oplus F(\key_2,B') \Bigr) = F(\key_2, B) \oplus F(\key_2, B').

It may not be obvious how this value is helpful in an attack. What's important is that we have obtained a value that depends only on BB and BB', and not at all on AA. If we performed the same steps with the same choice of BB and BB', but different AA', we would get the same result!

In more detail, suppose the adversary calls prf.query\prfquery on four inputs: ABA\|B, ABA\|B', ABA'\|B, ABA'\|B', where AAA \ne A' and BBB \ne B'. Call the resulting outputs Y1,Y2,Y3,Y4Y_1, Y_2, Y_3, Y_4, then:

Y1=F(K1,A)F(K2,B);Y2=F(K1,A)F(K2,B);Y3=F(K1,A)F(K2,B);Y4=F(K1,A)F(K2,B).\begin{aligned} Y_1 &= F(\key_1, A) \oplus F(\key_2, B); \\ Y_2 &= F(\key_1, A) \oplus F(\key_2, B'); \\ Y_3 &= F(\key_1, A') \oplus F(\key_2, B); \\ Y_4 &= F(\key_1, A') \oplus F(\key_2, B').\end{aligned}

As we observed above:

Y1Y2=F(K2,B)F(K2,B);Y3Y4=F(K2,B)F(K2,B).\begin{aligned} Y_1 \oplus Y_2 &= F(\key_2,B) \oplus F(\key_2, B'); \\ Y_3 \oplus Y_4 &= F(\key_2,B) \oplus F(\key_2, B').\end{aligned}

Thus, Y1Y2=Y3Y4Y_1 \oplus Y_2 = Y_3 \oplus Y_4. This relationship seems unlikely to happen if Y1,Y2,Y3,Y4Y_1, Y_2, Y_3, Y_4 were sampled independently.

We formalize the attack as the following calling program:

A\A
A,A:=A, A' := {}arbitrary, distinct strings from {0,1}n\bits^n
B,B:=B, B' := {}arbitrary, distinct strings from {0,1}n\bits^n
Y1:=prf.query(AB)Y_1 := \prfquery(A \| B)
Y2:=prf.query(AB)Y_2 := \prfquery(A \| B')
Y3:=prf.query(AB)Y_3 := \prfquery(A' \| B)
Y4:=prf.query(AB)Y_4 := \prfquery(A' \| B')
return Y1Y2==Y3Y4Y_1 \oplus Y_2 == Y_3 \oplus Y_4
  • When A\A is linked to Lprf-real\lib{prf-real}, then Y1Y2=Y3Y4Y_1 \oplus Y_2 = Y_3 \oplus Y_4, as we reasoned above. The calling program returns true\mytrue with probability 1.

  • Since AAA \ne A' and BBB \ne B', the calling program calls prf.query\prfquery on four distinct inputs. So when A\A is linked to Lprf-rand\lib{prf-rand}, each YiY_i is independently and uniformly distributed. Rewrite the return condition of A\A as the equivalent expression Y1Y2Y3==Y4Y_1 \oplus Y_2 \oplus Y_3 == Y_4. Consider the moment when Y1,Y2,Y3Y_1, Y_2, Y_3 have already been sampled but Y4Y_4 has not yet been sampled. There is only one choice of Y4Y_4 (namely, Y1Y2Y3Y_1 \oplus Y_2 \oplus Y_3) that causes A\A to output true\mytrue. Since Y4Y_4 is uniform, this happens with exactly probability 1/2m1/2^m.

The difference in output probabilities is nonnegligible, so the attack is successful and the construction is not a secure PRF.

Here's a slightly different way to think about this attack. Imagine xor'ing all four of these expressions together:

Y1=F(K1,A)F(K2,B);Y2=F(K1,A)F(K2,B);Y3=F(K1,A)F(K2,B);Y4=F(K1,A)F(K2,B).\begin{aligned} Y_1 &= F(\key_1, A) \oplus F(\key_2, B); \\ Y_2 &= F(\key_1, A) \oplus F(\key_2, B'); \\ Y_3 &= F(\key_1, A') \oplus F(\key_2, B); \\ Y_4 &= F(\key_1, A') \oplus F(\key_2, B').\end{aligned}

Each term of the form F(,)F(\cdot,\cdot) appears exactly twice overall, meaning that every term will cancel when the values are xor'ed. Hence, Y1Y2Y3Y4=0mY_1 \oplus Y_2 \oplus Y_3 \oplus Y_4 = \bit 0^m, which is equivalent to the condition Y1Y2=Y3Y4Y_1 \oplus Y_2 = Y_3 \oplus Y_4 used in the attack above.

The Golden Rule: The previous attack involved finding inputs to HH that led to repeated inputs to the underlying PRF FF. This is the first example of a more general principle that applies whenever a PRF is used as a component in a larger construction. Remember, a PRF produces pseudorandom outputs only when it is called on distinct inputs.

The Golden Rule of PRFs

If a PRF FF is being used as a component in a larger construction HH, then security usually rests on how well HH can ensure distinct inputs to FF.

  • When trying to attack HH, choose inputs to HH (according to its attack scenario) that will cause FF to be called on a repeated input. Remember, don't try to directly distinguish FF's outputs from uniform. Attack the erroneous way that HH is using FF!

  • When trying to prove security of HH, you will most likely need to establish that inputs to FF do not unexpectedly repeat, except with negligible probability.

In the next sections, we will see examples of how this Golden Rule appears in security proofs.

6.3. An example proof involving PRFs

Now let's see an example of a security proof involving PRFs. In this case, we show that composing a PRF with itself, using independent keys, results in a secure PRF.

Claim 6.3.1 (Cascading two PRFs)

If FF is a secure PRF with input/output length λ\secpar, then the following function HH, also with input/output length λ\secpar, is also a secure PRF:

H(K1K2,X)H\bigl(\key_1 \| \key_2, X\bigr):
Y:=F(K1,X)Y := F(\key_1, X)
return F(K2,Y)F(\key_2, Y)

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-realH\lib{prf-real}^H
K1K2{0,1}2λ\key_1 \| \key_2 \gets \bits^{2\secpar}
prf.queryH(X)\prfquery_H(X):
// return H(K1K2,X)H(\key_1 \| \key_2, X)
Y:=F(K1,X)Y := F(\key_1, X)
return F(K2,Y)F(\key_2, Y)
\indist
Lprf-randH\lib{prf-rand}^H
prf.queryH(X)\prfquery_H(X):
if L[X]\prftable[X] undefined:
L[X]{0,1}λ\prftable[X] \gets \bits^\secpar
return L[X]\prftable[X]
..

Since both pairs of libraries are from the Lprf-*\lib{prf-*} family, I have added subscripts to prf.query\prfquery to disambiguate.

Proof idea: The goal is to show that HH is a secure PRF—that is, when HH is called on distinct inputs, its outputs are pseudorandom. Working backward from our goal, what can we say about the outputs of HH?

Outputs of HH are computed as direct outputs of FF, which is itself a secure PRF. But remember to be careful, don't forget the Golden Rule! A PRF's outputs are pseudorandom only when its inputs are distinct. The PRF inputs in question are the intermediate values labeled YY in the construction. Indeed, if two different inputs for HH produce the same YY, then they will produce identical outputs from HH. So can we say anything about these YY values being distinct (for distinct XX)?

It might not be immediately clear whether the YY values can repeat, but what is hopefully clear is that they are computed as outputs of F(K1,)F(\key_1,\cdot), where FF is a secure PRF. Furthermore, the inputs to this FF are the inputs to HH, which we are assuming to be distinct. Thus, the YY values are pseudorandom; they are indistinguishable from uniformly sampled values.

But uniformly sampled values repeat only with negligible probability (if they are sufficiently long, as they are here); that is precisely the lesson of the birthday bound (section 4.5). This is the final puzzle piece in the proof.

The formal details of the proof follow below. Pay close attention to how these main ideas are formalized: (1) YY-values are pseudorandom and, therefore, indistinguishable from uniformly chosen values; (2) uniformly chosen values repeat only with negligible probability; and (3) distinct YY-values lead to pseudorandom outputs of HH.

Proof (details):

Hybrid Sequence:
The starting point is Lprf-realH\lib{prf-real}^H:
We first separate K1\key_1 from K2\key_2, since they will be treated separately during the proof. We can also add a dictionary L[]\prftable^*[\cdot] to cache past answers of prf.queryH()\prfquery_H(\cdot) so that they are not recomputed twice.
We can apply the PRF security of FF in a three-hop maneuver, replacing F(K1,)F(\key_1,\cdot) with a lazy random dictionary, which we name L1[]\prftable_1[\cdot].
We can again apply the PRF security of FF, this time replacing all calls to F(K2,)F(\key_2,\cdot) with a lazy random dictionary. This is a new dictionary, which we call L2\prftable_2. The repetitive three-hop maneuver is not shown.
The “if L1[X]\prftable_1[X] undefined” condition is always true, because L1[X]\prftable_1[X] and L[X]\prftable^*[X] are always assigned during the same call to prf.queryH(X)\prfquery_H(X), and we only reach this if-statement if L[X]\prftable^*[X] is undefined. Thus, this if-statement's body can be made unconditional.
Now L1[]\prftable_1[\cdot] is not needed, so it can be eliminated.
Uniformly sampled YY-values are indistinguishable from values sampled without replacement. The three-hop maneuver involving lemma 4.5.7 is omitted.
In this hybrid, the YY-values are guaranteed to not repeat. Thus, the inner if-statement is always taken, and its body can be made unconditional.
Now the overall effect of the if-statement's body is to assign a uniformly sampled value to L[X]\prftable^*[X]. The same logic can be written more directly, without YY, Y\mathcal{Y}, or L2[]\prftable_2[\cdot]. The result of these simplification is Lprf-randH\lib{prf-rand}^H, which completes the proof.
Lprf-realH\lib{prf-real}^H
K1\key_1
K2{0,1}2λ\| \key_2 \gets \bits^{2\secpar}
{0,1}λ{}\gets \bits^\secpar
prf.queryH\prfquery_H(XX):
YY
:={}:= {}
F(K1,X)F(\key_1, X)
prf.queryF(X)\prfquery_F(X)
L1[X]\prftable_1[X]
{0,1}λ{}\gets \bits^\secpar
Y{} \setminus \mathcal{Y}
return
F(K2,Y)F(\key_2, Y)
L[X]\prftable^*[X]
\link
Lprf-realF\lib{prf-real}^F
K{0,1}λ\key \gets \bits^\secpar
prf.queryF\prfquery_F(XX):
return F(K,X)F(\key, X)
Lprf-randF\lib{prf-rand}^F
if L[X]\prftable[X] undefined:
L[X]{0,1}λ\prftable[X] \gets \bits^\secpar
return L[X]\prftable[X]

6.4. Building a PRG from a PRF: The CTR construction

A PRG is in many ways a simpler object than a PRF, because a PRG is “allowed” to generate its entire output as a monolithic string. A PRF must provide easy access to individual blocks of its output. (I hesitate to call this random access, since it invokes a different meaning of the word random.)

For theoretical and pedagogical purposes, it is natural to use simpler objects (PRG) to build more complex objects (PRF), as in the previous section. In practice, however, it's more common to have access to a PRF than to a PRG. If we want a PRG, we must therefore construct one from a PRF. It is not hard to do so, since this is the “easy direction”—a simple object built from a more complex one.

Construction 6.4.1 (The CTR construction)

Let FF be a PRF with input length nn and output length mm, and let kk be an integer less than 2n2^n. Define the function G:{0,1}λ{0,1}kmG: \bits^\secpar \to \bits^{k m} as:

G(S)G(\seed):
for i=0i = 0 to k1k-1:
Xi:=F(S,i)X_i := F(\seed, i)
return X0Xk1X_0 \| \cdots \| X_{k-1}

When we write F(S,i)F(\seed,i), we mean that the integer ii is written as an nn-bit binary integer in the standard way. The construction is called the CTR construction because it uses a simple counter ii as the input to FF.

Claim 6.4.2 (Security of the CTR construction)

If FF is a secure PRF, then construction 6.4.1 is a secure PRG. In other words,

if \quad
Lprf-realF\lib{prf-real}^F
K{0,1}λ\key \gets \bits^\secpar
prf.query(X)\prfquery(X):
return F(K,X)F(\key,X)
\indist
Lprf-randF\lib{prf-rand}^F
prf.query(X)\prfquery(X):
if L[X]\prftable[X] undefined:
L[X]{0,1}λ\prftable[X] \gets \bits^\secpar
return L[X]\prftable[X]
then \quad
Lprg-realG\lib{prg-real}^G
prg.sample()\prgsamp(\,):
S{0,1}λ\seed \gets \bits^\secpar
// return G(S)G(\seed)
for i=0i = 0 to k1k-1:
Xi:=F(S,i)X_i := F(\seed, i)
return X0Xk1X_0 \| \cdots \| X_{k-1}
\indist
Lprg-randG\lib{prg-rand}^G
prg.sample()\prgsamp(\,):
Y{0,1}kmY \gets \bits^{km}
return YY

The intuition for the CTR construction is reasonably clear. If FF is a secure PRF and we call it on distinct inputs 0,1,,k10, 1, \ldots, k-1, then the resulting outputs F(S,0),F(S,1),,F(S,k1)F(\seed,0), F(\seed,1), \ldots, F(\seed,k-1) look independently pseudorandom. However, the proof is not as simple as you might expect because of a mismatch between the PRG and PRF security games:

  • In the PRG security definition, the libraries model many instances of the PRG. Each call to prg.sample\prgsamp represents a new instance of the PRG with a freshly sampled seed.

  • In the PRF security definition, the libraries model a single instance of the PRF, with a single PRF key that is used for the entire lifetime of the computation. All calls to prf.query\prfquery use that same key.

We want to prove that construction 6.4.1 is a secure PRG. In the Lprg-realG\lib{prg-real}^G library, the construction GG will be invoked many times, each time on a freshly sampled seed S\seed. Then GG proceeds to use S\seed as a PRF key. When we apply the security of a PRF in a hybrid proof, we can reason only about a single PRF key.

To account for this mismatch, we use a proof with a sequence of many hybrids—one hybrid for each call that the adversary makes to prg.sample\prgsamp. Hybrid #hh acts like Lprg-rand\lib{prg-rand} for the first hh calls to prg.sample\prgsamp, and acts like Lprg-real\lib{prg-real} for the remaining calls. Then hybrids hh and h+1h+1 are different only in how they respond to the adversary's (h+1)(h+1)th call to prg.sample\prgsamp. This difference involves only a single call to GG, and, therefore, only a single PRF seed. We can use the security of the PRF FF to argue that hybrids hh and h+1h+1 are indistinguishable.

Proof:

We introduce the following library Lh\L_h with an integer parameter hh:

Lh\L_h
prg.sample()\prgsamp(\,):
count:=count+1count := count + 1
if counthcount \le h:
Y{0,1}kmY \gets \bits^{km}
return YY
else:
S{0,1}λ\seed \gets \bits^\secpar
// G(S)G(\seed):
for i=0i = 0 to k1k-1:
Xi:=F(S,i)X_i := F(\seed, i)
return X0Xk1X_0 \| \cdots \| X_{k-1}

The proof is divided into three steps:

  • Lprg-realGL0\lib{prg-real}^G \equiv \L_0. This is easy to see because the else-branch is always taken.

  • Lprg-randGLq\lib{prg-rand}^G \equiv \L_{q}, where qq is the number of calls that the calling program makes to prg.sample\prgsamp. Again, this is easy to see because the if-branch is always taken.

  • For every h{0,,q1}h \in \{0, \ldots, q-1\}, we have LhLh+1\L_h \indist \L_{h+1}.

These three facts prove the claim because they imply that:

Lprg-realGL0L1LqLprg-randG. \lib{prg-real}^G \equiv \L_0 \indist \L_1 \indist \cdots \indist \L_{q} \equiv \lib{prg-rand}^G.

Since the calling program runs in polynomial time, qq is a polynomial function of the security parameter.

Hybrid Sequence:
The starting point is Lh\L_h.
We can create a separate branch of the if-statement to isolate the adversary's (h+1)(h+1)th call to prg.sample\prgsamp. This allows us to give a name S\seed^* to the PRG's seed in this call.
We can apply the PRF-security of FF to the (h+1)(h+1)th call to prg.sample\prgsamp. This is a three-hop maneuver that replaces calls to F(S,)F(\seed^*,\cdot) with a lazy random dictionary.
The condition “if L[i]\prftable[i] undefined” is always true, because ii takes on distinct values. We can therefore make the body of the if-statement unconditional:
Now the “if” and “else if” branches behave identically: They uniformly sample a kmkm-bit string. Unifying them into one branch results in Lh+1\L_{h+1}, which completes the proof.
Lh\L_h
prg.sample\prgsamp( ):
count:=count+1count := count + 1
if countcount \le {}
hh:
h+1h + 1:
Y{0,1}kmY \gets \bits^{km}
return YY
else:
S{0,1}λ\seed \gets \bits^\secpar
for i=0i = 0 to k1k-1:
Xi:=F(S,i)X_i := F(\seed, i)
return X0Xk1X_0 \| \cdots \| X_{k-1}
\link
Lprf-real\lib{prf-real}
K{0,1}λ\key \gets \bits^\secpar
prf.query\prfquery(XX):
return F(K,X)F(\key,X)
Lprf-rand\lib{prf-rand}
prf.query\prfquery(XX):
if L[X]\prftable[X] undefined:
L[X]{0,1}λ\prftable[X] \gets \bits^\secpar
return L[X]\prftable[X]

6.5. ☆ Building a PRF from a PRG: The GGM construction

We can construct a PRF from a PRG by cleverly connecting many PRG invocations together in a binary tree. Each leaf of the tree corresponds to one of the PRF's outputs. We can compute one of those outputs—without computing them all—by traversing a path from the root to the leaf. We can use the bits of the PRF input XX to decide whether to go left or right at each step of the traversal. If XX has nn bits, then the binary tree has nn levels.

Construction 6.5.1 (The GGM construction)

Let GG be a length-doubling PRG. Then the GGM construction—named after its creators Goldreich, Goldwasser, and Micali—is defined as the following function F:{0,1}λ×{0,1}n{0,1}λF : \bits^\secpar \times \bits^n \to \bits^\secpar:

F(K,X)F(\key,X):
R:=KR := \key
for i=1i = 1 to nn:
S0S1:=G(R)S_0 \| S_1 := G(R)
R:=SX[i]R := S_{X[i]}
return RR
\quad

X[i]X[i] denotes the iith bit of the string XX, numbering the bits from 1 to nn.

It's important to keep in mind that the GGM algorithm computes only a single path in this binary tree. It never computes the entire tree—it would be too large. The binary tree is only a conceptual tool, for understanding this construction, just like how an exponentially large random dictionary is a conceptual tool that helps us understand a lazy random dictionary.

Claim 6.5.2 (Security of the GGM construction)

If GG is a secure length-doubling PRG, then the GGM construction (construction 6.5.1) is a secure PRF. In other words,

if \quad
Lprg-realG\lib{prg-real}^G
prg.sample()\prgsamp(\,):
S{0,1}λ\seed \gets \bits^\secpar
return G(S)G(\seed)
\indist
Lprg-randG\lib{prg-rand}^G
prg.sample()\prgsamp(\,):
Y{0,1}2λY \gets \bits^{2\secpar}
return YY
then \quad
Lprf-realF\lib{prf-real}^F
K{0,1}λ\key \gets \bits^\secpar
prf.query(X)\prfquery(X):
// return F(K,X)F(\key,X)
R:=KR := \key
for i=1i = 1 to nn:
S0S1:=G(R)S_0 \| S_1 := G(R)
R:=SX[i]R := S_{X[i]}
return RR
\indist
Lprf-randF\lib{prf-rand}^F
prf.query(X)\prfquery(X):
if L[X]\prftable[X] undefined:
L[X]{0,1}λ\prftable[X] \gets \bits^\secpar
return L[X]\prftable[X]

To build intuition about the proof, let's just imagine an algorithm that generated the entire GGM binary tree, ignoring the fact that this would take exponential time. Proving that the values on the leaves are pseudorandom would be similar to previous proofs that involve several PRG instances connected together (claim 5.4.3). In our binary tree, the root node has uniform input and sends outputs of GG to its children. Such a tree is indistinguishable from a similar one that skips the root level and directly sends truly uniform values to the nodes of the second level. After this change, the two nodes in the second level now have uniform input, so this modified tree is indistinguishable from one that skips the first two levels and directly sends truly uniform values to the nodes of the third level.

A picture is forming of one hybrid for each level of the tree. In hybrid #hh, the top hh levels of the tree are skipped, and inputs to layer hh of the tree are sampled uniformly.

This picture gives a good intuition about the necessary sequence of hybrids. However, all of these hybrids would require exponential time if the tree is sufficiently tall. We can avoid this, however, by generating these truncated binary trees in a lazy manner, just how Lprf-rand\lib{prf-rand} generates a random dictionary in a lazy manner. All of the difficulty in this proof stems from generating the binary tree lazily.

Proof:

We introduce the following library Lh\L_h with an integer parameter hh:

Lh\L_{h}
prf.query(X)\prfquery(X):
P:=first h bits of XP := \text{first } h \text{ bits of } X
if L[P]\prftable[P] undefined:
L[P]{0,1}λ\prftable[P] \gets \bits^\secpar
R:=L[P]R := \prftable[P]
for i=h+1i = h+1 to nn:
S0S1:=G(R)S_0 \| S_1 := G(R)
R:=SX[i]R := S_{X[i]}
return RR
\quad

Lh\L_h implements a binary tree that skips the first hh layers and gives uniform inputs to nodes at layer h+1h+1. However, Lh\L_h implements this tree lazily by storing the uniform values at layer hh in a lazy random dictionary. Using this library Lh\L_h, we will break the proof into three steps:

  1. Lprf-realFL0\lib{prf-real}^F \equiv \L_0.

  2. Lprf-randFLn\lib{prf-rand}^F \equiv \L_n, where nn is the input length of the PRF construction.

  3. For every h{1,,n}h \in \{1, \ldots, n\}, we have Lh1Lh\L_{h-1} \indist \L_h.

These three facts prove the claim because they imply that:

Lprf-realFL0L1LnLprf-randF. \lib{prf-real}^F \equiv \L_0 \indist \L_1 \indist \cdots \indist \L_n \equiv \lib{prf-rand}^F.

First, let's see why L0\L_0 is identical to Lprf-realF\lib{prf-real}^F. In L0\L_0, PP is always the empty string ϵ\epsilon. The only part of L[]\prftable[\cdot] that is ever accessed is the single value L[ϵ]\prftable[\epsilon]. If we give L[ϵ]\prftable[\epsilon] a simpler name like “K\key,” and sample it at the beginning of time instead of the first time it is used, we obtain exactly Lprf-realF\lib{prf-real}^F:

L0\L_0
prf.query(X)\prfquery(X):
P:=P := first 0 bits of XX
// \Rightarrow P:=ϵP := \epsilon
if L[P]\prftable[P] undefined:
L[P]{0,1}λ\prftable[P] \gets \bits^\secpar
R:=L[P]R := \prftable[P]
for i=1i = \hl{1} to nn:
S0S1:=G(R)S_0 \| S_1 := G(R)
R:=SX[i]R := S_{X[i]}
return RR
\equiv
Lprf-realF\lib{prf-real}^F
// K=L[ϵ]\key = \prftable[\epsilon]
K{0,1}λ\key \gets \bits^\secpar
prf.query(X)\prfquery(X):
R:=KR := K
for i=1i = 1 to nn:
S0S1:=G(R)S_0 \| S_1 := G(R)
R:=SX[i]R := S_{X[i]}
return RR

Next, let's see why Ln\L_n is identical to Lprf-randF\lib{prf-rand}^F. In Ln\L_n, PP equals the entire input XX. The for-loop ranges “from n+1n+1 to nn,” so it is never taken. Removing the for-loop, and replacing every reference to PP with a corresponding reference to XX, we obtain Lprf-randF\lib{prf-rand}^F:

Ln\L_{n}
prf.query(X)\prfquery(X):
P:=P := first nn bits of XX
// \Rightarrow P:=XP := X
if L[P]\prftable[P] undefined:
L[P]{0,1}λ\prftable[P] \gets \bits^\secpar
R:=L[P]R := \prftable[P]
// for-loop never taken:
for i=n+1i = \hl{n+1} to nn:
S0S1:=G(R)S_0 \| S_1 := G(R)
R:=SX[i]R := S_{X[i]}
return RR
\equiv
Lprf-randF\lib{prf-rand}^F
prf.query(X)\prfquery(X):
if L[X]\prftable[X] undefined:
L[X]{0,1}λ\prftable[X] \gets \bits^\secpar
return L[X]\prftable[X]

Finally, we need to show that Lh1Lh\L_{h-1} \indist \L_h, for h{1,,n}h \in \{1, \ldots, n\}. We do so with the following sequence of hybrids.

Hybrid Sequence:
The starting point is Lh1\L_{h-1}.
Unroll the first iteration of the for-loop (i=hi=h). Since h{1,,n}h \in \{1, \ldots, n\}, the loop indeed has a first iteration. The change has no effect on the calling program.
Replace a redundant variable to clean things up.
We can rename S0S_0 and S1S_1 to L[P0]\prftable[P\|\bit0] and L[P1]\prftable[P\|\bit1]. Then we can select the correct one using the entire hh-bit prefix PP' of XX, not just the hh-th individual bit.
The library samples L[P]\prftable[P] and then later (perhaps many times) computes G(L[P])G(\prftable[P]). We could instead compute G(L[P])G(\prftable[P]) immediately when L[P]\prftable[P] is sampled and store the results for later.
The library assigns L[P]\prftable[P] and L[P]\prftable[P'] at the same time, for all possible pairs PP and PP', so it doesn't matter which of L[P]\prftable[P] or L[P]\prftable[P'] we use in the if-condition.
Now L[P]\prftable[P] is used only as the seed to the PRG, so we can apply the security of the PRG GG. The standard three-hop maneuver is not shown.
The library simultaneously samples both L[P]\prftable[P'] and its “sibling”: the same string as PP' with last bit flipped. But only one of these values is needed in a single call to prf.query\prfquery. Since these values are sampled independently, we can sample only the needed one and defer the sibling value until later (if needed). The result is Lh\L_{h}, which completes the proof.
Lh1\L_{h-1}
prf.query\prfquery(XX):
P:=first h1 bits of XP := \text{first } h-1 \text{ bits of } X
if
L[P]\prftable[P] undefined:
L[P]\prftable[P'] undefined:
L[P]{0,1}λ\prftable[P] \gets \bits^\secpar
R:=L[P]R := \prftable[P]
for i=i = {}
hh to nn:
h+1h+1 to nn:
S0S1:=G(R)S_0 \| S_1 := G(R)
R:=SX[i]R := S_{X[i]}
return RR

6.6. PRFs for long inputs: The CBC-MAC construction

We frequently require a PRF that supports long inputs. The PRF in construction 6.5 can support inputs of any length, but it uses a PRG as its main primitive. In practice, PRG implementations are not typically available, but PRFs for short inputs (e.g., λ\secpar bits) are. This section describes a classic way to use a PRF for short inputs to build a PRF for long inputs. The method is called CBC-MAC, a name that may require some explanation:

  • CBC refers to cipher-block chaining, which we will see later in the context of encryption (see section 8.5).

  • MAC refers to message authentication code, which is a different cryptographic primitive closely related to PRFs. The name CBC-MAC reflects its traditional use as a MAC. We will eventually discuss MACs in detail in section 9.4.

Be sure not to miss the important caveat about CBC-MAC's security, at the end of this section.

Construction 6.6.1 (CBC-MAC)

Let FF be a PRF with input/output length λ\secpar. For any 1\ell \ge 1, define \ell-block CBC-MAC to be the following new function FcbcF^\ell_{\textsf{cbc}} with input length λ\ell\secpar and output length λ\secpar:

// each XiX_i is exactly λ\secpar bits:
Fcbc(K,X1X2X)F^\ell_{\textsf{cbc}}(\key, X_1 \| X_2 \| \cdots \| X_\ell):
Y0:=0λY_0 := \bit0^\secpar
for i=1i = 1 to \ell:
Yi:=F(K,Yi1Xi)Y_i := F(\key, Y_{i-1} \oplus X_i)
return YY_\ell

Claim 6.6.2 (Security of CBC-MAC (for fixed input lengths))

If FF is a secure PRF with input/output length λ\secpar, then \ell-block CBC-MAC is also a secure PRF, for any \ell. Below we will prove only the special case of =2\ell=2:

Fcbc2(K,X1X2)F^2_{\textsf{cbc}}(\key, X_1 \| X_2):
Y1:=F(K,X1)Y_1 := F(\key,X_1)
Y2:=F(K,Y1X2)Y_2 := F(\key,Y_1 \oplus X_2)
return Y2Y_2
\qquad

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-realcbc-2\lib{prf-real}^{\textsf{cbc-2}}
K{0,1}λ\key \gets \bits^\secpar
prf.querycbc-2(X1X2)\prfquery_{\textsf{cbc-2}}(X_1 \| X_2):
// return Fcbc2(K,X)F_{\textsf{cbc}}^2(\key,X)
Y1:=F(K,X1)Y_1 := F(\key,X_1)
Y2:=F(K,Y1X2)Y_2 := F(\key,Y_1 \oplus X_2)
return Y2Y_2
\indist
Lprf-randcbc-2\lib{prf-rand}^{\textsf{cbc-2}}
prf.querycbc-2(X1X2)\prfquery_{\textsf{cbc-2}}(X_1 \| X_2):
if L[X1X2]\prftable[X_1 \| X_2] undefined:
L[X1X2]{0,1}λ\prftable[X_1 \| X_2] \gets \bits^\secpar
return L[X1X2]\prftable[X_1 \| X_2]

The final output of (2-block) CBC-MAC is computed as F(K,Y1X2)F(\key, Y_1 \oplus X_2). Therefore, following the golden rule of PRFs, our goal will be to show that these Y1X2Y_1 \oplus X_2 values do not repeat (except with negligible probability). We do this using the technique of moving the library's bad-event logic to the end of time.

Proof:

Hybrid Sequence:
The starting point is Lprf-real\lib{prf-real}.
We can add a cache L[]\prftable[\cdot] so that each output is computed only once.
We can replace the calls to PRF FF with corresponding lookups in a lazy random dictionary R[]R[\cdot]. Note: There is a single dictionary R[]R[\cdot], which the library will access on both X1X_1 and Y1X2Y_1 \oplus X_2. The standard three-hop maneuver has been omitted.
This hybrid contains an if-statement “if R[Y1X2]R[Y_1 \oplus X_2] undefined.” Consider another hybrid in which the body of this if-statement is performed unconditionally. The two hybrids behave identically unless/until R[Y1X2]R[Y_1 \oplus X_2] is already defined. So, to show that the hybrids are indistinguishable, we can trigger a bad event in that case and later show that the bad event has negligible probability.
We can swap the assignment order of L[X1X2]\prftable[X_1 \| X_2] and R[Y1X2]R[Y_1 \oplus X_2].
We can move L[X1X2]{0,1}λ\prftable[X_1\|X_2] \gets \bits^\secpar earlier. After doing so, it is clear that R[]R[\cdot] does not affect the output of prf.query\prfquery: It is used only to determine whether to trigger the bad event.
Instead of triggering the bad event as prf.query\prfquery is called, we can do so at the end of time. This will not change the bad event's probability.
Lprf-real\lib{prf-real}
K{0,1}λ\key \gets \bits^\secpar
prf.query\prfquery(X1X2X_1 \| X_2):
Y1:=Y_1 := {}
F(K,X1)F(\key,X_1)
R[X1]R[X_1]
Y2:=F(K,Y1X2)Y_2 := F(\key,Y_1 \oplus X_2)
return
Y2Y_2
L[X1X2]\prftable[X_1\|X_2]
The final hybrid library is clearly just Lprf-rand\lib{prf-rand}, with some extra steps at the end of time that don't affect what the adversary sees; they only determine whether to (internally) trigger a bad event. Thus, to complete the proof that Lprf-realLprf-rand\lib{prf-real} \indist \lib{prf-rand}, we must show that the bad-event probability in this final library is negligible.

Each iteration of the end-of-time loop writes to R[]R[\cdot] in at most two positions, and has one opportunity to trigger the bad event, if it finds R[]R[\cdot] already defined at a certain position. Fix a particular choice of X1X2X_1\|X_2 and X1X2X'_1 \| X'_2; what is the probability that a bad event is triggered while processing X1X2X'_1 \| X'_2, because of something assigned to R[]R[\cdot] while processing X1X2X_1 \| X_2? This event can happen in the following ways:

  • Case 1: While processing X1X2X_1\|X_2, the library writes to R[X1]R[X_1]. Later, X1X2X'_1 \| X'_2 satisfies

    R[X1]X2=X1. R[X'_1] \oplus X'_2 = X_1.

    Then a bad event is triggered because R[X1]R[X_1] is already defined. Since R[X1]R[X'_1] is chosen uniformly, and independent of X1,X2,X1,X_1, X_2, X'_1, and X2X'_2, the above condition holds with probability 1/2λ1/2^\secpar.

  • Case 2: While processing X1X2X_1\|X_2, the library computes Y1=R[X1]X2Y_1 = R[X_1] \oplus X_2 and writes to R[Y1]R[Y_1]. Later, X1X2X'_1 \| X'_2 satisfies

    R[X1]X2=Y1=R[X1]X2. R[X'_1] \oplus X'_2 = Y_1 = R[X_1] \oplus X_2.

    Then a bad event is triggered because R[Y1]R[Y_1] is already defined. The condition can be rewritten as:

    R[X1]R[X1]=X2X2. R[X_1] \oplus R[X'_1] = X_2 \oplus X'_2.
    • Case 2a: If X1=X1X_1 = X'_1 and X2=X2X_2 = X'_2, then the two strings are actually equal. But Case 2 in general requires two different iterations through the end-of-time loop, and therefore different strings. This subcase can never happen.

    • Case 2b: If X1=X1X_1 = X'_1 and X2X2X_2 \ne X'_2, then the left-hand side of the condition is 0λ\bit0^\secpar and the right-hand side is nonzero. This subcase can also never happen.

    • Case 2c: If X1X1X_1 \ne X'_1, then R[X1]R[X_1] and R[X1]R[X'_1] are chosen uniformly and independently (of each other and of X2,X2X_2, X_2'). The condition is satisfied with probability only 1/2λ1/2^\secpar.

So the probability that two particular strings interact to trigger a bad event is at most 2/2λ2/2^\secpar. If the adversary makes qq calls to prf.query\prfquery, then there are at most qq strings processed in the end-of-time loop, and at most q2q^2 pairs of such strings. Then by the union bound, the overall probability of the bad event is:

Pr[bad event]=Pr[X1X2,X1X2X:X1X2 and X1X2 interfere]q2Pr[specific strings X1X2 and X1X2 interfere]q2(2/2λ).\begin{aligned} \displaystyle \PR{ \text{bad event} } &= \PR{ \exists X_1 \| X_2, X'_1 \| X'_2 \in \mathcal{X} : X_1 \| X_2 \text{ and } X'_1 \| X'_2 \text{ interfere} } \\ &\le q^2 \PR{ \text{specific strings } X_1 \| X_2 \text{ and } X'_1 \| X'_2 \text{ interfere}} \\ &\le q^2 \left( 2/2^\secpar \right).\end{aligned}

Since the adversary can make only a polynomial number qq of calls to prf.query\prfquery, this probability is negligible.

The Golden Rule of PRF proofs: The proof included a step in which a hybrid library was changed in the following way:

A common idiom in proofs that use PRFs
\cdots
if L[X]\prftable[X] undefined:
L[X]{0,1}λ\prftable[X] \gets \bits^\secpar
\cdots
\indist
\cdots
if L[X]\prftable[X] defined: bad:=true\badvar := \mytrue
L[X]{0,1}λ\prftable[X] \gets \bits^\secpar
\cdots

Perhaps you can see the Golden Rule of PRFs reflected in this idiom: When a PRF appears as a component in a larger system, we often need to argue that PRF inputs do not repeat. In the example above, XX plays the role of an input to the PRF (lazy random dictionary). The left library implements a lazy random dictionary, correctly accounting for repeated inputs. The right library has been optimized to behave as if repeated inputs will never happen. So the two libraries behave differently only in the case that XX repeats. We can trigger a bad event in this case; the libraries are indistinguishable if we can later show that the bad-event probability is negligible.

6.6.1. Fixed input length vs. variable input length

CBC-MAC has fragile security, and claim 6.6.2 must be interpreted carefully. There is an important distinction to be made between a fixed-input-length PRF and variable-input-length PRF:

  • When we use CBC-MAC as a fixed-input-length PRF, we choose a single value of \ell at the time we sample a key. That key is used only for inputs with exactly \ell blocks. To prove security of a fixed-input-length PRF, the value \ell in the Lprf-*\lib{prf-*} libraries is fixed throughout the entire execution. All of the adversary's inputs to prf.query\prfquery must be of that same length.

  • When we use CBC-MAC as a variable-input-length PRF, we use a single key together with inputs of different lengths. To prove security of a variable-input-length PRF, we let each input to prf.query\prfquery in the Lprf-*\lib{prf-*} libraries determine its own value of \ell. Within a single execution, the adversary may use inputs of different lengths to prf.query\prfquery.

Claim 6.6.2 is about the security of CBC-MAC as a fixed-input-length PRF. For any value of \ell, the CBC-MAC construction provides a secure PRF for inputs of length exactly λ\ell \secpar bits. However:

Claim 6.6.3 (Insecurity of CBC-MAC)

CBC-MAC is not secure as a variable-input-length PRF.

Proof:

The idea of the attack can be summarized in the following two pictures. First, the adversary asks for the PRF output for two 2-block inputs X1X2X_1\|X_2 and X3X4X_3\|X_4:

Then, the adversary can “splice” the two computations together to obtain a 4-block input that gives the same PRF output as X3X4X_3\|X_4:

The attack can be formalized by the following calling program:

A\A
X1,X2,X3,X4:=X_1, X_2, X_3, X_4 := {}arbitrary strings of length λ\secpar
Y:=prf.query(X1X2)Y := \prfquery(X_1 \| X_2)
Y:=prf.query(X3X4)Y' := \prfquery(X_3 \| X_4)
Z:=prf.query(X1X2(X3Y)X4)Z := \prfquery\bigl( X_1 \big\| X_2 \big\| (X_3 \oplus Y) \big\| X_4 \bigr)
return Y==ZY' == Z

When the calling program is linked to Lprf-real\lib{prf-real}, it outputs true\mytrue with probability 1. When it is linked to Lprf-rand\lib{prf-rand}, it outputs true\mytrue only with probability 1/2λ1/2^\secpar, since ZZ is uniform and independent of YY'.

There are simple ways to modify CBC-MAC to obtain a secure variable-input-length PRF; one is shown in exercise 6.31, and others are discussed later in chapter 11. However, never forget that plain CBC-MAC is fragile. If you use plain CBC-MAC as a PRF, you must be absolutely sure that each key is used only for inputs of a single length.

Exercises

  1. We usually consider calling programs that output a single bit, but in this exercise we allow calling programs to output a longer string. Suppose there is a polynomial-time algorithm A\A such that, with nonnegligible probability the combined program ALprf-realF\A \link \lib{prf-real}^F outputs the correct value of K\key (the private variable in Lprf-real\lib{prf-real}). Prove that FF is not a secure PRF by using A\A as a subroutine in an attack that can distinguish Lprf-real\lib{prf-real} from Lprf-rand\lib{prf-rand}. Equivalently, if FF is a secure PRF, then no efficient algorithm can output K\key with better than negligible probability when linked to Lprf-real\lib{prf-real}. Our PRF security definition therefore implies that key-recovery attacks are hard.

    Remember: A\A can often output the “wrong” guess for K\key. When you use A\A as a subroutine, it may not be obvious whether A\A has produced the correct value K\key or not. You'll have to find a way to deal with these cases in your analysis.

  2. Let FF be a secure PRF. Suppose K\key is sampled uniformly, and strings XX and XX' differ in only 1 bit. How many bits of F(K,X)F(\key,X) and F(K,X)F(\key,X') are expected to match, and why?

  3. In claim 6.2.1 the adversary chooses arbitrary but distinct strings X1X_1 and X2X_2. What would be the adversary's advantage distinguishing the two libraries if instead we used X1=X2X_1 = X_2?

  4. Our attack against the construction in claim 6.2.2 required four calls to prf.query\prfquery. Prove that the construction is secure against adversaries who make at most three calls to prf.query\prfquery.

  5. Show that the following function is not a secure PRF, even if FF is:

    H(K,X)=F(K,X)F(K,F(K,X)). H\bigl( \key, X \bigr) = F(\key, X) \,\big\|\, F\bigl(\key, F(\key, X)\bigr).
  6. Show that the following function is not a secure PRF, even if FF is:

    H(K,X1X2)=F(K,X10)F(K,X21). H\bigl( \key, X_1 \| X_2 \bigr) = F(\key,X_1 \| 0) \,\big\|\, F(\key, X_2\|1).
  7. Show that the following function is not a secure PRF, even if FF is:

    H(K,X1X2)=F(K,X1)F(K,X1F(K,X2)). H\bigl( \key, X_1 \| X_2 \bigr) = F(\key, X_1) \,\big\|\, F\bigl(\key, X_1 \oplus F(\key, X_2)\bigr).

    If the first block of output is removed, then this construction becomes exactly 2-block CBC-MAC.

  8. Show that the following function is not a secure PRF, even if FF is:

    H(K,X1X2)=F(K,X1)F(K,F(K,X1)F(K,X2)). H\bigl( \key, X_1 \| X_2 \bigr) = F(\key, X_1) \,\big\|\, F\bigl(\key, F(\key,X_1) \oplus F(\key, X_2)\bigr).
  9. Show that the following function is not a secure PRF, even if FF is:

    H(K,X)=F(K,X)F(K,0n). H( \key, X ) = F(\key, X) \oplus F(\key, \bit 0^n).
  10. Prove that if FF is a secure PRF, then the following function HH is too:

    H(K,X)=F(K,X)X. H( \key, X ) = F(\key, X) \oplus X.
  11. Prove that if FF is a secure PRF, then the following function HH is too:

    H(K,X)=F(K,X). H( \key, X ) = \overline{ F(\key, X) }.
  12. Let F:{0,1}λ×{0,1}n{0,1}λF : \bits^\secpar \times \bits^n \to \bits^\secpar be a secure PRF, and let G:{0,1}λ{0,1}λ+G : \bits^\secpar \to \bits^{\secpar+\ell} be a secure PRG. Show that the following function HH is a secure PRF:

    H(K,X)=G(F(K,X)). H( \key, X ) = G\bigl( F(\key,X) \bigr).
  13. Prove that if FF is a secure PRF with output length λ\secpar, then the following function HH is too:

    H(K1K2,X)=F(K1,X)F(K2,X)K1. H\bigl( \key_1\|\key_2, X \bigr) = F(\key_1, X) \oplus F(\key_2, X) \oplus \key_1.
  14. Prove that the following function HH is a secure PRF, if either F1F_1 or F2F_2 is secure:

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

    Your proof should consider two cases: In the first case, assume that F1F_1 is a secure PRF, but assume nothing about F2F_2. Then prove the same with the roles of F1F_1 and F2F_2 swapped.

  15. Let FF be a secure PRF with input length n+1n+1. Prove that the following function HH is also a secure PRF with input length nn:

    H(K,X)=F(K,0X)F(K,1X). H( \key, X ) = F(\key,\bit0 \| X) \,\big\|\, F(\key, \bit1 \| X).
  16. Let FF be a secure PRF with input length n+1n+1. Prove that the following two libraries are indistinguishable:

    K{0,1}λ\key \gets \bits^\secpar
    prf.query0(X)\prfquery_0(X):
    return F(K,0X)F(\key, \bit0\|X)
    prf.query1(X)\prfquery_1(X):
    return F(K,1X)F(\key, \bit1\|X)
    \indist
    prf.query0(X)\prfquery_0(X):
    if L0[X]\prftable_0[X] undefined:
    L0[X]{0,1}m\prftable_0[X] \gets \bits^m
    return L0[X]\prftable_0[X]
    prf.query1(X)\prfquery_1(X):
    if L1[X]\prftable_1[X] undefined:
    L1[X]{0,1}m\prftable_1[X] \gets \bits^m
    return L1[X]\prftable_1[X]

    In other words, the two functions F(K,0)F(\key,\bit0\|\cdot) and F(K,1)F(\key,\bit1\|\cdot) act like independent random dictionaries, even though they use the same key.

  17. Let F:{0,1}λ×{0,1}λ{0,1}λF : \bits^\secpar \times \bits^\secpar \to \bits^\secpar be a secure PRF. One of the following functions is a secure PRF, and the other is not. Give an attack and a security proof:

    H1(K,X)={0λ, if X=0λF(K,X), otherwiseH2(K,X)={0λ, if K=0λF(K,X), otherwise.\begin{aligned} H_1(\key,X) &= \begin{cases} \bit0^\secpar, & \text{ if } \hl{X} = \bit0^\secpar \\ F(\key,X), & \text{ otherwise} \end{cases} \\ H_2(\key,X) &= \begin{cases} \bit0^\secpar, & \text{ if } \hl{\key} = \bit0^\secpar \\ F(\key,X), & \text{ otherwise.} \end{cases} \end{aligned}
  18. h Let FF be a secure PRF with input length λ\secpar. Prove that the following function HH is a secure PRF:

    H(K1K2,X)=F(K1,X)F(K1,K2). H\bigl( \key_1\|\key_2, X \bigr) = F(\key_1, X) \oplus F(\key_1, \key_2).

    Define a bad event in the case that the adversary manages to call HH on input X=K2X = \key_2. Use the end-of-time strategy to analyze the bad-event probability.

  19. h Let FF be a secure PRF with input and output length λ\secpar. Prove that the following function is also a secure PRF:

    H(K1K2,X)H\bigl(\key_1 \| \key_2, X\bigr):
    Y:=F(K1,X)Y := F(\key_1, X)
    Z:=F(K1,XK2)Z := F(\key_1, X \oplus \key_2)
    return YZY \| Z

    Define a bad event in the case that the adversary calls HH at inputs XX and XX' where XX=K2X \oplus X' = \key_2. Use the end-of-time strategy to analyze the bad-event probability.

  20. h Let FF be a secure PRF with input and output length λ\secpar. Prove that the following function is also a secure PRF:

    H(K,X)=F(K,F(K,X)). H(\key ,X) = F\bigl(\key, F(\key, X)\bigr).

    This construction is similar to claim 6.3.1, except that only one key is used.

    In the computation of H(K,X)H(\key,X), let YY denote the intermediate internal value Y=F(K,X)Y=F(\key,X). Define a bad event in the case that the adversary calls HH at an input that is the internal value of another call to HH. In other words, the adversary calls HH at input XX, and at some other time (either before or after), calls HH at input Y=F(K,X)Y=F(\key,X). Use the end-of-time strategy to analyze the bad-event probability.

  21. Let FF be a secure PRF with input and output length λ\secpar. Prove that for any parameter kk, the following is a secure PRG:

    G(S)G(\seed):
    X0:=0λX_0 := \bit0^\secpar
    for i=1i = 1 to kk:
    Xi:=F(S,Xi1)X_i := F(\seed, X_{i-1})
    return X1XkX_1 \| \cdots \| X_k
  22. Let FF be a secure PRF with input and output length λ\secpar. Prove that the following PRF (with input length 2λ2\secpar) is also a secure PRF:

    H(K,X1X2)=F(F(K,X1),X2). H(\key, X_1 \| X_2) = F\bigl( F(\key,X_1), X_2 \bigr).

    Use a hybrid proof with a variable number of hybrids, based on the following approach:

    Lh\L_h
    prf.query(X1X2)\prfquery(X_1 \| X_2):
    if X1∉AX_1 \not\in A and count<hcount < h:
    count:=count+1count := count + 1
    A:=A{X1}A := A \cup \{ X_1 \}
    if X1AX_1 \in A:
    if L[X1X2]\prftable'[X_1 \| X_2] undefined: L[X1X2]{0,1}λ\prftable'[X_1 \| X_2 ] \gets \bits^\secpar
    return L[X1X2]\prftable'[X_1 \| X_2]
    else:
    if L[X1]\prftable[X_1] undefined: L[X1]{0,1}λ\prftable[X_1] \gets \bits^\secpar
    return F(L[X1],X2)F( \prftable[X_1], X_2 )

    This library acts like Lprf-rand\lib{prf-rand} for the first hh distinct values of X1X_1 that it sees, and acts like Lprf-real\lib{prf-real} for the remaining ones.

    Let qq be the number of calls to prf.query\prfquery made by the calling program. Show that

    Lprf-realL0LhLh+1LqLprf-rand. \lib{prf-real} \equiv \L_0 \indist \cdots \indist \L_h \indist \L_{h+1} \indist \cdots \indist \L_q \equiv \lib{prf-rand}.
  23. Consider swapping the role of key and input in the GGM construction. In other words, we are considering the following function:

    F(K,X)F(\key,X):
    R:=XR := \hl{X}
    for i=1i = 1 to nn:
    S0S1:=G(R)S_0 \| S_1 := G(R)
    R:=SK[i]R := S_{\hl{\key}[i]}
    return RR

    Show that when this construction is instantiated with the secure PRG from exercise 5.17, the result is not a secure PRF.

  24. Show that the GGM PRF (construction 6.5.1) is not secure as a variable-input-length PRF.

  25. h\star Describe a construction of a secure variable-input-length PRF (for inputs of any length, not just a multiple of λ\secpar bits) from a PRG, based on construction 6.5.1. Prove that your construction is secure.

    Use a binary tree of length-tripling PRGs, where one third of the output is sent to the left child, one third sent to the right child, and one third is used as an output.

  26. \star Prove that \ell-block CBC-MAC is a secure (fixed-input-length) PRF, for any \ell (not just =2\ell=2), if its underlying FF is a secure PRF.

  27. The output of CBC-MAC is the last block. Suppose instead that the output is the xor of all blocks. Show that the resulting function is not a secure variable-input-length PRF:

    // input may be any number of blocks:
    H(K,X1X)H\bigl(\key, X_1 \| \cdots \| X_\ell\bigr):
    Y0:=0λY_0 := \bit0^\secpar
    Z:=0λZ := \bit0^\secpar
    for i=1i = 1 to \ell:
    Yi:=F(K,Yi1Xi)Y_i := F(\key, Y_{i-1} \oplus X_i)
    Z:=ZYiZ := Z \oplus Y_i
    return ZZ
  28. Show that the following variant of CBC-MAC is not secure as a variable-input-length PRF, even if the underlying FF is a secure PRF:

    // input may be any number of blocks:
    H(K,X1X)H\bigl(\key, X_1 \| \cdots \| X_\ell\bigr):
    Y0:=0λY_0 := \bit0^\secpar
    for i=1i = 1 to \ell:
    Yi:=F(K,Yi1Xi)Y_i := F(\key, Y_{i-1} \oplus X_i)
    // write \ell as a λ\secpar-bit binary integer:
    Y:=F(K,Y)Y^* := F(\key, Y_\ell \oplus \ell)
    return YY^*
  29. Show that the following variant of CBC-MAC is not secure as a variable-input-length PRF, even if the underlying FF is a secure PRF:

    // input may be any number of blocks:
    H(K,X1X)H\bigl(\key, X_1 \| \cdots \| X_\ell\bigr):
    Y0:=0λY_0 := \bit0^\secpar
    for i=1i = 1 to \ell:
    Yi:=F(K,Yi1Xi)Y_i := F(\key, Y_{i-1} \oplus X_i)
    // apply FF once more, for good measure:
    Y:=F(K,Y)Y^* := F(\key, Y_\ell)
    return YY^*
  30. Show that the following variant of CBC-MAC is not secure as a variable-input-length PRF, even if the underlying FF is a secure PRF:

    // input may be any number of blocks:
    H(K1K2,X1X)H\bigl(\key_1\|\key_2, X_1 \| \cdots \| X_\ell\bigr):
    Y0:=0λY_0 := \bit0^\secpar
    for i=1i = 1 to \ell:
    Yi:=F(K1,Yi1Xi)Y_i := F(\key_1, Y_{i-1} \oplus X_i)
    return YK2Y_\ell \oplus \key_2

    If K2\key_2 is applied before the final call to FF, the result actually is a secure variable-input-length PRF (see exercise 11.13).

  31. One natural way to modify CBC-MAC into a variable-input-length PRF is to derive an independent CBC-MAC key for each input length.

    More formally, let FF be a secure PRP with input/output length λ\secpar. Define the following function HH below, which accepts inputs of any number of blocks—that is, the value \ell is not fixed but part of the input:

    // input may be any number of blocks:
    H(K,X1X)H\bigl(\key, X_1 \| \cdots \| X_\ell\bigr):
    // write \ell in binary as a string:
    K:=F(K,)\key^* := F(\key, \ell)
    Y0:=0λY_0 := \bit0^\secpar
    for i=1i = 1 to \ell:
    Yi:=F(K,Yi1Xi)Y_i := F(\key^*, Y_{i-1} \oplus X_i)
    return YY_\ell

    Prove that HH is a secure variable-input-length PRF. You may use the fact that CBC-MAC is a secure fixed-input-length PRF for any number of blocks \ell (claim 6.6.2).

Chapter Notes

Pseudorandom functions were first introduced and defined by Goldreich, Goldwasser, and Micali [112]. In that same work they describe how to construct a PRF from a PRG, using the construction that we present in section 6.5.

The security of CBC-MAC was first proven formally by Bellare, Kilian, and Rogaway [20], with an alternate, shorter proof given later by Bernstein [35]. Plain CBC-MAC is secure as a fixed-input-length PRF. The more general statement, first proven by Petrank and Rackoff [181], is that plain CBC-MAC is secure when no two inputs are prefixes of each other. The idea of using a PRF to derive separate CBC-MAC keys for each input length (exercise 6.31) was first proposed by Bellare, Kilian, and Rogaway [20].

The attack in exercise 6.30 is attributed to Bellare in [43].

  1. Previous Chapter5. Pseudorandom Generators
  2. Next Chapter7. Pseudorandom Permutations