4
Pseudorandomness

Modern Computational Cryptography

Imagine an encryption scheme that can be broken, but the fastest possible attack requires a trillion years of computation. You probably wouldn't worry about such an attack because there is no meaningful difference between a task that takes a trillion years and a task that is simply impossible. But our style of security definitions is completely agnostic to an attack's running time. If there is a calling program that can distinguish two libraries after a trillion years of computation, then those libraries are deemed not interchangeable. An encryption scheme that allows this kind of attack would be deemed insecure.

Now imagine an encryption scheme that can be broken, but the best possible attack is guaranteed to succeed only with extremely low probability. In fact, the probability that the attack succeeds is smaller than the probability of winning the lottery a hundred times in a row. Again, you probably wouldn't worry about this attack because there is no meaningful difference between an event that happens with such a tiny probability and an event that is simply impossible. But our style of security definitions is completely agnostic to an attack's success probability. If there is a calling program that can distinguish two libraries, with output probabilities that are different by the tiniest nonzero amount, then those libraries are deemed not interchangeable. An encryption scheme that allows this kind of attack would be deemed insecure.

The modern approach to provable security builds on the vocabulary that we developed in chapter 2 but dismisses attacks with astronomically high computational cost or astronomically tiny success probability. Instead of proving statements like: No attack against this scheme can succeed at all, not even in principle, we will prove statements like: Every attack against this scheme has either astronomically high computational cost or astronomically small success probability.

We'll start by clarifying precisely what is meant by “astronomically” high costs or low probabilities.

4.1. The concrete approach to provable security

In the concrete approach to provable security, our goal is to be as quantitative as possible about security claims. We rarely say definitively that a cryptographic algorithm “is secure,” as we did when discussing OTP. Instead, we say things like, “any attack that expends at most 2802^{80} effort can succeed with probability no better than 2642^{-64}.” It is up to the user to judge whether this quantitative level of security is acceptable, based on their use-case and risk tolerance.

4.1.1. Huge numbers

The concrete approach requires good intuition about huge numbers (like 21282^{128}) and tiny numbers (like 21282^{-128}). Here are some examples to help put huge computations into perspective:

Example 4.1.1 (Monetary cost of huge computations)

One way to think about huge computations is their monetary cost. Below, I have calculated roughly how much a computation involving 2n2^n CPU cycles would cost on the cheapest available Amazon EC2 cloud computing service:

cycles approx cost (USD) point of reference
2502^{50} $3.50 cup of coffee
2552^{55} $100 good tickets to a Portland Trailblazers game
2652^{65} $130,000 median home price in Chickasaw County, Iowa
2752^{75} $130 million budget of one of the Harry Potter movies
2852^{85} $140 billion GDP of Hungary
2922^{92} $20 trillion GDP of the United States
2992^{99} $2 quadrillion all of human economic activity since 300,000 bce
21282^{128} a lot! a billion human civilizations' worth of effort
Example 4.1.2 (Computational scale of Bitcoin mining)

I don't intend to discuss cryptocurrencies much in this book. Let's just say that cryptocurrencies based on proof-of-work, like Bitcoin, incentivize their users to perform truly obscene amounts of computation. In Bitcoin's proof-of-work mechanism, users race to perform SHA-256 hash computations as fast as possible (it's not important to know what SHA-256 is for this illustration). At the time of writing, the collective Bitcoin network has performed approximately 2952^{95} SHA-256 hashes in total, including 293.62^{93.6} in the last twelve months. The current market cap for Bitcoin is approximately 400 billion USD.

These two examples provide different monetary estimates because Bitcoin mining happens exclusively on special-purpose hardware (ASICs), which can perform Bitcoin mining and do nothing else. Cloud computing services offer general-purpose CPUs, which are orders of magnitude slower and less energy efficient, hence more expensive.

4.1.2. Tiny numbers

Next are some examples to help put tiny probabilities into perspective:

Example 4.1.3 (Tiny probabilities in gambling games)

In the casino game called craps, the gambler rolls a pair of six-sided dice, and loses their bet if the dice add to 7. (This is a great oversimplification.) In 2009, Patricia Demauro rolled 154 consecutive times without getting a 7. This is arguably the most unlikely event ever recorded, with a probability of (30/36)154240.6(30/36)^{154} \approx \hl{2^{-40.6}}.

I can't find a reliable primary source, but many websites claim that the longest streak in roulette happened in 1943, when a gambler spun red 32 times in a row. The probability of spinning the same color 32 times in a row is (18/38)31233.4(18/38)^{31} \approx \hl{2^{-33.4}} (the first spin doesn't matter, but the next 31 must match).

The chance of winning the jackpot in the American Powerball lottery is 228.12^{-28.1}. The chance of winning the Powerball on two consecutive weeks is 256.22^{-56.2}.

Example 4.1.4 (Aliens throwing darts)

This square \blacksquare is approximately 25 square millimeters, or about 1/2641/2^{64} of the surface area of the Earth. If an alien throws a dart toward the Earth from a distant solar system, then with probability 2642^{-64} the dart will land exactly in the black square in your copy of The Joy of Cryptography.

Example 4.1.5 (Earthlings united for a cause)

There are roughly eight billion people on earth. If every one of them uniformly sampled an 80-bit string once per second, nonstop for a million years, then it is more than likely no one ever sampled the all-zeros string. There would have been “only” 277.72^{77.7} attempts in that time.

I encourage you to explore your own ways of understanding extreme numbers.

Take-Home Message

A computation taking 21282^{128} steps will never happen in this universe. An event with probability less than 2802^{-80} is effectively impossible.

The last point about probability deserves some clarification.

  • Events with probability 2802^{-80} happen all the time. Every time you shuffle a deck of fifty-two cards, the probability of getting that particular ordering of the cards is approximately 22252^{-225}. The event that I describe as effectively impossible is that you have a specific ordering in mind before you shuffle, and then observe that ordering after shuffling. In cryptography we are always talking about specific events that are defined a priori. These are effectively impossible if their probability is 2802^{-80}.

  • You must take care to consider the probability of the correct event. There may be an encryption scheme that fails catastrophically (i.e., perhaps it completely leaks the secret key) with probability 2802^{-80} each time the Enc\Enc algorithm is called. However, some attack scenarios might allow the Enc\Enc algorithm to be invoked many times, giving an adversary many chances to trigger this catastrophic event. Of course, the adversary will be satisfied if any one of those chances succeed, so that is the event whose probability is most important. If an adversary causes Enc\Enc to be called 2502^{50} times, then the event that really matters happens not with probability 2802^{-80} but more like 250/280=2302^{50}/2^{80} = 2^{-30}, which is “only” one in a billion.

It is often useful to think about a trade-off between an attack's running time and its success probability:

Definition 4.1.6 (Bits of security)

A cryptographic construction has nn bits of security (informally) if every attack satisfies the following relationship:

cost of attacksuccess probability of attack2n, \displaystyle \frac{ \text{cost of attack} }{ \text{success probability of attack} } \le 2^n,

where “cost of attack” is measured in some low-level unit like CPU cycles or single-bit operations.

Typical cryptographic standards are designed to target at least 128 bits of security.

4.2. The asymptotic approach to provable security

The concrete approach is helpful for answering practical questions like, how large should my keys be to achieve a comfortable security level? But with that level of precision comes the responsibility of managing more tedious quantitative details during a security proof.

The asymptotic approach is an alternative that lets us make more qualitative, all-or-nothing statements, at the cost of losing some quantitative precision. “Asymptotic” means considering the behavior of an algorithm in the limit—that is, as the key size approaches infinity. You are probably familiar with asymptotic analysis using big-OO notation. Focusing only on asymptotic behavior allows us to hide many tedious quantitative details. For example, you don't need to carefully calculate that a certain operation takes exactly 16n2+24n+7416n^2 + 24n + 74 steps; you can stop as soon as you realize it takes O(n2)O(n^2) steps.

Review: big-OO

A function f(n)f(n) is O(g(n))O(g(n)) if there is a constant cc such that f(n)cg(n)f(n) \le c \cdot g(n) for all but finitely many values of nn. In other words, a constant multiple of g(n)g(n) eventually overtakes f(n)f(n).

4.2.1. Polynomial running time

In the asymptotic approach, we only consider adversaries that run in polynomial time.

Definition 4.2.1 (Polynomial running time)

An algorithm runs in polynomial time if there is a polynomial pp such that the algorithm takes at most O(p(n))O(p(n)) steps on inputs of length nn.

Cryptographic algorithms typically have several different inputs, so we always measure the running time as a function of the security parameter, which we write as Greek letter lambda λ\lambda. Usually, but not always, the security parameter is the length (in bits) of the secret keys in a cryptographic scheme. We assume that all algorithms and libraries have access to the value of λ\secpar as a global variable, although we don't write it as an explicit input.

Polynomial-time algorithms are closed under composition: A polynomial-time program that calls a polynomial-time subroutine can be combined into a monolithic algorithm whose overall running time is also polynomial. Without this composition property, many aspects of the theory would be problematic or incoherent.

4.2.2. Negligible probabilities

You've seen asymptotic analysis (big-OO) to categorize functions that approach infinity as their input grows, like the running time of an algorithm. Asymptotic analysis tells us how fast a function zooms off toward infinity.

In cryptography we also use asymptotic analysis to describe probabilities that approach zero as the input gets larger. We are interested in how fast these probability functions approach zero. If the probability of some event approaches zero fast enough, we can classify that event as effectively impossible.

Suppose a cryptographic algorithm fails catastrophically with probability 1/λ21/\secpar^2. This probability clearly approaches zero as λ\secpar grows, but does it approach zero fast enough? There may be attack scenarios in which an adversary could have λ2\secpar^2 chances to trigger the catastrophic event, because λ2\secpar^2 is a polynomial, and we consider adversaries that have polynomial running time. With so many chances, the catastrophic event actually has a very good probability of happening in at least one of the attempts. Hence, 1/λ21/\secpar^2 does not seem to approach zero fast enough to ignore.

On the other hand, suppose the catastrophic failure happens with probability 1/2λ1/2^\secpar. If an adversary gets two chances to trigger the catastrophic event, it happens with probability at most 2/2λ2/2^\secpar; if the adversary gets λ2\secpar^2 chances, the probability is at most λ2/2λ\secpar^2/2^\secpar. A polynomial-time adversary can get at most a polynomial number of chances to trigger the catastrophic event, but no matter what polynomial we place in the numerator, the denominator 2λ2^\secpar always “wins,” sending the overall probability to zero in the limit. Hence, 1/2λ1/2^\secpar approaches zero fast enough to be robust for polynomial-time situations.

In the asymptotic approach to cryptography, we require an adversary's success probability to approach zero faster than any reciprocal-polynomial. Formally:

Definition 4.2.2 (Negligible functions)

A function ff is negligible if it approaches zero faster than 1/p(λ)1/p(\secpar), for every polynomial pp. There are a few ways to formalize this:

  • For every polynomial pp, there is a value λ0\secpar_0 such that f(λ)<1/p(λ)f(\secpar) < 1/p(\secpar) for all λ>λ0\secpar > \secpar_0. In other words, beyond λ0\secpar_0, ff is always smaller than 1/p1/p.

  • For every polynomial pp, we have p(λ)O(1/f(λ))p(\secpar) \in O\bigl(1/f(\secpar)\bigr). In case f(λ)=0f(\secpar)=0 for some values of λ\secpar, we interpret 1/01/0 as \infty.

Example 4.2.3

Here are a few examples of negligible functions:

  • f(λ)=1/2λf(\secpar) = 1/2^\secpar is a negligible function because its reciprocal 2λ2^\secpar grows faster than all polynomials.

  • f(λ)=1/2λ/2f(\secpar) =1/2^{\secpar/2} is negligible because 2λ/22^{\secpar/2} also grows faster than all polynomials.

  • If q(λ)q(\secpar) is a polynomial, then f(λ)=q(λ)/2λf(\secpar) =q(\secpar)/2^\secpar is negligible.

Nearly every appearance of a negligible probability in this book will be easy to identify, usually having the form q(λ)2λ\frac{q(\secpar)}{2^\secpar}, where qq is some polynomial.

4.2.3. Comparing concrete vs asymptotic

In this book, we mostly stick to the asymptotic approach. The asymptotic style leads to simpler, cut-and-dry security statements like “every polynomial-time adversary succeeds with only negligible probability," whereas the concrete style demands that we carefully account for an adversary's advantage.

For example, a security theorem in the asymptotic style might read like this:

If FF is a secure PRF, then Σ\Sigma (which uses FF as a subroutine) is a CPA-secure encryption scheme.

It's not important right now to understand what “secure PRF” or “CPA-secure” means; these serve as merely an illustration here. The same theorem in the concrete style might read more like this:

For every calling program A\A there exists a corresponding calling program A\A', with similar runtime, such that:

AdvcpaΣ(A)AdvprfF(A)+q22λ, \textsf{Adv}_{\textsf{cpa}}^\Sigma(\A) \le \textsf{Adv}_{\textsf{prf}}^F(\A') + \frac{q^2}{2^\secpar},

where:

  • AdvcpaΣ(A)\textsf{Adv}_{\textsf{cpa}}^\Sigma(\A) denotes the probability of A\mathcal{A} successfully distinguishing the libraries from the CPA security definition for scheme Σ\Sigma. (This quantity is defined as A\A's advantage below.)

  • AdvprfF(A)\textsf{Adv}_{\textsf{prf}}^F(\A') denotes the probability of A\mathcal{A}' successfully distinguishing the libraries from the PRF security definition for FF.

  • qq is the number of times A\A calls its library.

Both the concrete and asymptotic approaches have clear merit, and both are common in the research literature. And it's important to acknowledge that everything we prove in this book in the asymptotic style could also be proven in a concrete style. Our fundamental approach of defining security in terms of libraries and distinguishers is compatible with both styles.

The concrete approach is necessary when determining proper key sizes. A security theorem in the asymptotic approach tells you only about a system's eventual behavior, in the limit as key sizes approach infinity. It tells you very little about its behavior for any specific key size.

Another important distinction between the concrete and asymptotic approaches is what happens if P = NP. For almost any cryptographic primitive, the problem of breaking it (asymptotically) is in the complexity class NP. So if P = NP, almost all of cryptography can be broken in polynomial time; asymptotic security is doomed in this case, but concrete security may still be viable.

4.3. Indistinguishability

In chapter 2, we said that two libraries were interchangeable if they induce identical output probabilities, for all adversaries. In the modern (asymptotic) approach, we say that two libraries are indistinguishable if they induce negligibly close output probabilities, for all polynomial-time adversaries:

Definition 4.3.1 (Indistinguishability)

Let L1\lib{1} and L2\lib{2} be two libraries with the same interface. If A\A is a calling program, then the advantage of A\A in distinguishing L1\lib{1} and L2\lib{2} is defined to be:

Pr[AL1true]Pr[AL2true]. \Bigl| \PR{\A \link \lib{1} \outputs \mytrue } - \PR{\A \link \lib{2} \outputs \mytrue } \Bigr|.

Libraries L1\lib{1} and L2\lib{2} are indistinguishable, written L1L2\hl{\lib{1} \indist \lib{2}}, if every polynomial-time calling program has only negligible advantage in distinguishing L1\lib{1} and L2\lib{2}. In other words, swapping L1\lib{1} for L2\lib{2} changes the behavior of a polynomial-time calling program by only a negligible amount.

Below are some facts about indistinguishability that are useful in security proofs:

Lemma 4.3.2 (Properties of indistinguishability)

For all polynomial-time libraries L1,L2,\L_{1}, \L_{2}, and L3\L_{3}:

  1. If L1L2\L_{1} \equiv \L_{2} then L1L2.\L_{1} \indist \L_2.

  2. (transitivity) If L1L2L3\L_{1} \indist \L_{2} \indist \L_{3} then L1L3.\L_{1} \indist \L_{3}.

  3. (chain rule) If L1L2\L_{1} \indist \L_{2} then L3L1L3L2.\L_{3} \link \L_{1} \indist \L_{3} \link \L_{2}.

Proof:

For (1), L1L2\L_{1} \equiv \L_{2} means that all calling programs—including the polynomial-time ones—have zero advantage distinguishing the libraries, and the constant function f(λ)=0f(\secpar)=0 is indeed negligible. Thus, L1L2\L_{1} \indist \L_{2}.

For (2) we can use two important facts:

  • If ff and gg are negligible functions, then f+gf+g is too (exercise 4.1).

  • (1-dimensional triangle inequality) If a,b,ca,b,c are real numbers, then acab+bc|a-c| \le |a-b| + |b-c|.

Now, consider an arbitrary polynomial-time calling program A\A and define pi=Pr[ALitrue]p_i = \PR{ \A \link \L_i \outputs \mytrue}, which is A\A's output probability when linked to Li\L_i. Now A\A's advantage distinguishing L1\L_{1} from L3\L_{3} is simply p1p3|p_1 - p_3|. But,

p1p3p1p2+p2p3.\begin{aligned} | p_1 - p_3 | \le | p_1 - p_2 | + | p_2 - p_3 | .\end{aligned}

The last two terms are simply A\A's advantage distinguishing L1\L_{1} from L2\L_{2}, and its advantage distinguishing L2\L_{2} from L3\L_{3}, both of which we are assuming are negligible since L1L2L3\L_{1} \indist \L_{2} \indist \L_{3}. Hence A\A's advantage distinguishing L1\L_{1} from L3\L_{3} is negligible as well.

(3) is proven in essentially the same way as claim 2.4.1.

4.3.1. Hybrid proofs using indistinguishability

Indistinguishability is transitive, but there is an important subtlety: The negligible advantages “pile up.” Suppose L0L2Lq\L_{0} \indist \L_{2} \indist \cdots \indist \L_{q}, and suppose Li1\L_{i-1} can't be distinguished from Li\L_{i} with advantage better than ϵi(λ)\epsilon_i(\secpar), as a function of the security parameter λ\secpar. Then, the advantage when distinguishing L0\L_{0} from Lq\L_{q} could be as high as ϵ1(λ)++ϵq(λ)\epsilon_1(\secpar) + \cdots + \epsilon_q(\secpar).

In simple security proofs like the ones we've seen so far, the number of hybrids qq does not depend on the security parameter, and everything works out as you might expect. The sum of a constant number of negligible functions is also negligible, and thus L0Lq\L_{0} \indist \L_{q} in the example above.

However, we will soon see proofs in which the number of hybrids qq depends on the security parameter. For example, in some upcoming proofs qq is the number of times the adversary calls the library. Since the adversary is assumed to run in polynomial time, qq is some unspecified polynomial function of the security parameter. These situations are more delicate, because the sum of a non-constant number of negligible functions might not be negligible (see exercise 4.3). Despite this, it is still possible to prove something like the following:

Claim 4.3.3 (Bounded transitivity of indistinguishability)

(Informally stated:) If L0L1LqL\L_0 \indist \L_1 \indist \cdots \indist \L_q \equiv \L^* and qq is a polynomial function of the security parameter, then L0L\L_0 \indist \L^*.

Claim 4.3.3 is a simplification of the truth, but it captures the intuition needed to understand proofs later in this book: It is generally safe to write a proof with a polynomial number of hybrids.

You can safely stop at the informal statement of claim 4.3.3 if you prefer, but here are the gory details for those of you who are interested. It's not enough that Li1Li\L_{i-1} \indist \L_i (for all ii), because this condition involves first fixing ii and then considering the libraries' asymptotic behavior as the security parameter approaches infinity. Instead, we must demand that Li1Li\L_{i-1} \indist \L_i, even against an adversary who can choose ii, because this new scenario allows ii to depend on the security parameter.

Claim 4.3.4 (Transitivity of indistinguishability, the fine print)

(Formal restatement of claim 4.3.3:) Let L\L^* and L0,L1,\L_{0}, \L_1, \ldots be polynomial-time libraries. Suppose the following conditions hold:

  • “There are a polynomial number of hybrids, where the polynomial can depend on the calling program”: Formally, for every polynomial-time calling program A\A, there exists a polynomial q(λ)q(\secpar) such that Lq(λ)\L_{q(\secpar)} behaves exactly like L\L^*, from the perspective of A\A:

    Pr[ALq(λ)1]=Pr[AL1]. \PR{ \A \link \L_{q(\secpar)} \outputs 1 } = \PR{ \A \link \L^* \outputs 1}.
  • “Consecutive hybrids Li1\L_{i-1} and Li\L_i are indistinguishable, even to an adversary who is allowed to choose the parameter ii. Formally, the following two libraries are indistinguishable:

    Lleft\lib{left}
    init(i)\subname{init}(i):
    if 0<iq(λ)0 < i \le q(\secpar):
    become an instance of Li1\L_{i-1}
    \indist
    Lright\lib{right}
    init(i)\subname{init}(i):
    if 0<iq(λ)0 < i \le q(\secpar):
    become an instance of Li\L_{i}

    When one of these libraries “becomes an instance” of Li\L_i, it means the library starts running the code of Li\L_i and behaving exactly like it in all respects. That is, it adopts the interface of Li\L_i and responds to subroutine calls exactly as Li\L_i does (and stops responding to init\subname{init}).

If these conditions hold, then L0L\L_0 \indist \L^*.

Every security proof in this book is compatible with the conditions of claim 4.3.4. But for the sake of simplicity, we won't write proofs in terms of this precise language and will instead use the more informal style of claim 4.3.3—that is, we will say things like “L0L1LqL\L_0 \indist \L_1 \indist \cdots \indist \L_q \equiv \L^*, and qq is a polynomial in the security parameter, so therefore L0L\L_0 \indist \L^*.

4.4. The bad-event technique

In this section we will introduce a new technique that can be used to prove indistinguishability:

Lemma 4.4.1 (Bad events)

Let L1\lib{1} and L2\lib{2} be libraries that each include a boolean variable named bad\badvar, and assume that after bad\badvar is set to true\mytrue it remains true\mytrue forever. We say that the bad event is triggered if the library ever sets bad:=true\badvar := \mytrue. If L1\lib{1} and L2\lib{2} have identical source code, except for statements reachable only when bad:=true\badvar:=\mytrue, then,

Pr[AL1true]Pr[AL2true]Pr[AL1 triggers bad event]. \Big| \PR{ \A \link \lib{1} \outputs \mytrue } - \PR{ \A \link \lib{2} \outputs \mytrue } \Big| \le \PR{ \A \link \lib{1} \text{ triggers bad event} }.

In other words, the calling program's advantage is bounded by the probability that it can trigger the bad event.

The lemma is a bit abstract, so before proving it, let's see an example where it applies:

Example 4.4.2 (The bad-event technique)

Consider the following libraries:

L1\lib{1}
predict(X)\subname{predict}(X):
R{0,1}λR \gets \bits^\secpar
return R==XR == X
\quad
L2\lib{2}
predict(X)\subname{predict}(X):
return false\myfalse

These libraries describe a scenario in which an adversary tries to guess which value the victim will sample from {0,1}λ\bits^\secpar. The only difference between these libraries is that the predict\subname{predict} subroutine in L1\lib{1} can return true\mytrue but in L2\lib{2} it cannot. This discrepancy is exposed only if the adversary's prediction of RR is correct. We can prove that these libraries are indistinguishable using the bad-event technique.

First, we can introduce bad events to L1\lib{1} and L2\lib{2} as follows:

L1\lib{1}
predict(X)\subname{predict}(X):
R{0,1}λR \gets \bits^\secpar
return R==XR == X
\equiv
L1\lib{1}'
predict(X)\subname{predict}(X):
R{0,1}λR \gets \bits^\secpar
if R==XR == X:
bad:=true\badvar := \mytrue
return true\mytrue
return false\myfalse
?\overset{?}{\indist}
L2\lib{2}'
predict(X)\subname{predict}(X):
R{0,1}λR \gets \bits^\secpar
if R==XR == X:
bad:=true\badvar := \mytrue
return false\myfalse
return false\myfalse
\equiv
L2\lib{2}
predict(X)\subname{predict}(X):
return false\myfalse

You can easily check that L1L1\lib{1} \equiv \lib{1}' and L2L2\lib{2} \equiv \lib{2}': In L1\lib{1} and L1\lib{1}', predict\subname{predict} returns the result of X==RX == R, while in L2\lib{2} and L2\lib{2}' it always returns false\myfalse. The other differences involve internal variables that do not affect what the adversary sees.

Thus it suffices to show that L1L2\lib{1}' \indist \lib{2}'. These two libraries differ only in one line, which can only be reached when bad\badvar is true\mytrue, so lemma 4.4.1 applies. The adversary's distinguishing advantage is bounded by the probability that the bad event is triggered.

Each call to predict\subname{predict} triggers the bad event with probability 1/2λ1/2^\secpar, because RR is chosen uniformly from {0,1}λ\bits^\secpar, and independently of XX. A polynomial-time calling program can make only a polynomial number of calls to the predict\subname{predict} subroutine. Let q(λ)q(\secpar) be the number of times it does so, then by the union bound the overall probability of the bad event happening is at most q(λ)/2λq(\secpar)/2^\secpar. Since qq is a polynomial function of λ\secpar, the bad-event probability q(λ)/2λq(\secpar)/2^\secpar is negligible, and we conclude that the libraries are indistinguishable.

The proof of the bad-event lemma uses conditional probabilities, which are briefly reviewed below. But don't worry! Once we prove the lemma, we never need to deal directly with conditional probabilities again.

Notation & Review

If YY is some event, then we write Y\overline Y to denote the complement event—that is, the event that YY does not happen. For all events YY, we have

Pr[Y]+Pr[Y]=1. \PR{ Y } + \PR{ \overline Y } = 1.

We write Pr[XY]\PR{ X \mid Y } to denote the probability of XX, conditioned on the event YY. Conditional probability is defined as:

Pr[XY]=Pr[XY] / Pr[Y], \PR{ X \mid Y } = \PR{ X \land Y } ~ / ~ \PR{ Y },

and it satisfies the important identity for all events XX and YY:

Pr[X]=Pr[XY]Pr[Y]+Pr[XY]Pr[Y]. \PR{ X } = \PR{ X \mid Y } \PR{Y} + \PR{ X \mid \overline{Y} } \PR{ \overline{Y} }.

Other concepts from probability are reviewed in section A.2.

We now prove lemma 4.4.1:

Proof:

Fix a calling program A\A, and define the following events:

  • B1\B_1: the bad event is triggered in AL1\A \link \lib{1}.

  • B2\B_2: the bad event is triggered in AL2\A \link \lib{2}.

We can write the overall output probabilities of A\A in terms of conditional probabilities:

Pr[AL1true]=Pr[AL1trueB1]Pr[B1]+Pr[AL1trueB1]Pr[B1];Pr[AL2true]=Pr[AL2trueB2]Pr[B2]+Pr[AL2trueB2]Pr[B2].\begin{aligned} \PR{ \A \link \lib{1} \outputs \mytrue } &= \PR{ \A \link \lib{1} \outputs \mytrue \mid \B_1 } \PR{ \B_1 } \\ &+ \PR{ \A \link \lib{1} \outputs \mytrue \mid \overline{\B_1} } \PR{ \overline{\B_1} }; \\ \PR{ \A \link \lib{2} \outputs \mytrue } &= \PR{ \A \link \lib{2} \outputs \mytrue \mid \B_2 } \PR{ \B_2 } \\ &+ \PR{ \A \link \lib{2} \outputs \mytrue \mid \overline{\B_2} } \PR{ \overline{\B_2} } .\end{aligned}

Next, we can make two observations:

  • Pr[B1]=Pr[B2]\PR{ \B_1 } = \PR{ \B_2 }: The two libraries trigger the bad event with identical probabilities. This is because both libraries execute identical lines of code while bad\badvar is false\myfalse, including the line of code (if any) which ultimately triggers the bad event. Let us call this probability α\alpha.

  • Pr[AL1trueB1]=Pr[AL2trueB2]\PR{ \A \link \lib{1} \outputs \mytrue \mid \overline{\B_1} } = \PR{ \A \link \lib{2} \outputs \mytrue \mid \overline{\B_2} }: The two libraries induce identical output distributions in the calling program, conditioned on the bad event not being triggered. This is because, again, the libraries execute identical lines of code in this case. Let us call this probability β\beta.

Substituting these values α\alpha and β\beta into the conditional-probability expressions above, we obtain:

Pr[AL1true]=Pr[AL1trueB1]α+β(1α),Pr[AL2true]=Pr[AL2trueB2]α+β(1α).\begin{aligned} \PR{ \A \link \lib{1} \outputs \mytrue } &= \PR{ \A \link \lib{1} \outputs \mytrue \mid \B_1 } \alpha + \beta (1-\alpha), \\ \PR{ \A \link \lib{2} \outputs \mytrue } &= \PR{ \A \link \lib{2} \outputs \mytrue \mid \B_2 } \alpha + \beta (1-\alpha).\end{aligned}

Finally, we can calculate the calling program's advantage adv\textsf{adv} as:

adv=Pr[AL1true]Pr[AL1true]=(Pr[AL1trueB1]α+β(1α))(Pr[AL2trueB2]α+β(1α))=(Pr[AL1trueB1]Pr[AL2trueB2])α=Pr[AL1trueB1]Pr[AL2trueB2]αα.\begin{aligned} \textsf{adv} &= \Bigl| \PR{ \A \link \lib{1} \outputs \mytrue } - \PR{ \A \link \lib{1} \outputs \mytrue } \Bigr| \\ &= \left| \begin{array}{r} \Bigl( \PR{ \A \link \lib{1} \outputs \mytrue \mid \B_1 } \alpha + \beta (1-\alpha) \Bigr) \\ - \Bigl( \PR{ \A \link \lib{2} \outputs \mytrue \mid \B_2 } \alpha + \beta (1-\alpha) \Bigr) \\ \end{array} \right| \\ &= \left| \Bigl( \PR{ \A \link \lib{1} \outputs \mytrue \mid \B_1 } - \PR{ \A \link \lib{2} \outputs \mytrue \mid \B_2 } \Bigr) \cdot \alpha \right| \displaybreak \\ &= \Bigl| \PR{ \A \link \lib{1} \outputs \mytrue \mid \B_1 } - \PR{ \A \link \lib{2} \outputs \mytrue \mid \B_2 } \Bigr| \cdot \alpha \\ &\le \alpha.\end{aligned}

The final inequality follows from the fact that the difference between two (conditional) probabilities can be at most 1. Since α\alpha is the probability that the bad event is triggered (in either library), this completes the proof.

More strategies for the bad-event technique: The previous example featured a bad event whose probability is relatively easy to understand and bound. We are not always so lucky. Bad events often involve values chosen by the adversary, so we can't assume anything about how they are distributed. In particular, we can't assume independence, which is often important.

For example, consider the difference between the following two libraries:

L1\lib{1}
guess(X)\subname{guess}(X):
R{0,1}λR \gets \bits^\secpar
return R==XR == X
vs.\quad\text{vs.}\quad
L2\lib{2}
R{0,1}λR \gets \bits^\secpar
cheat()\subname{cheat}(\,):
return RR
guess(X)\subname{guess}(X):
return R==XR == X

In both libraries, the guess subroutine returns R==XR ==X, and in both libraries RR is sampled uniformly. We might be tempted to say that Pr[R==X]=1/2λ\PR{ R == X } = 1/2^\secpar in both libraries. However, this probability is correct only when RR is independent of XX! This is the case in L1\lib{1} but not (necessarily) in L2\lib{2}. In L1\lib{1}, RR is chosen after XX. In L2\lib{2}, the adversary can call cheat to learn RR and then call guess with R=XR=X. Clearly this strategy leads to an XX that is not independent of RR.

This section describes some strategies to deal with bad events involving adversarially chosen values. The strategies rely on two important facts about the bad-event technique:

  • Lemma 4.4.1 is symmetric with respect to L1\lib{1} and L2\lib{2}. When using the bad-event technique to show that L1L2\lib{1} \indist \lib{2}, we can calculate the bad-event probability in either L1\lib{1} or L2\lib{2}, whichever is more convenient for the analysis.

  • The only thing that matters for the bad-event technique is the probability that the bad event is eventually triggered. It doesn't matter when the bad event is triggered. In other words, we could modify a library so that the bad event is triggered at a different time—potentially making our probability analysis easier—but with the same eventual probability.

The following example takes advantage of these facts and demonstrates the strategy:

Example 4.4.3 (Another bad event)

Consider the following two libraries:

L1\lib{1}
R{0,1}λR \gets \bits^\secpar
predict(X)\subname{predict}(X):
return R==XR == X
\quad
L2\lib{2}
predict(X)\subname{predict}(X):
return false\myfalse

L1\lib{1} samples RR, once at the beginning of time, and then gives the adversary many guesses of this value. This is slightly different than the previous example, where each call to predict\subname{predict} sampled a fresh value of RR. We can take a similar approach to the previous example, and introduce a bad event:

L1\lib{1}
R{0,1}λR \gets \bits^\secpar
predict(X)\subname{predict}(X):
return R==XR == X
\equiv
L1\lib{1}'
R{0,1}λR \gets \bits^\secpar
predict(X)\subname{predict}(X):
if R==XR == X:
bad:=true\badvar := \mytrue
return true\mytrue
return false\myfalse
?\overset{?}{\indist}
L2\lib{2}'
R{0,1}λR \gets \bits^\secpar
predict(X)\subname{predict}(X):
if R==XR == X:
bad:=true\badvar := \mytrue
return false\myfalse
return false\myfalse
\equiv
L2\lib{2}
predict(X)\subname{predict}(X):
return false\myfalse

As before, it is not hard to see that L1L1\lib{1} \equiv \lib{1}' and L2L2\lib{2} \equiv \lib{2}'. Furthermore, L1\lib{1}' and L2\lib{2}' differ only in a line that is reachable only after the bad event is triggered. So it suffices to show that this bad-event probability is negligible, but what is that probability?

In L1\lib{1}', the predict subroutine reveals a small amount of information about RR to the adversary, so its choice of XX is not necessarily independent of RR. It would therefore be difficult to analyze the bad-event probability with respect to L1\lib{1}'.

Since we have a choice, we should choose to analyze the bad-event probability in L2\lib{2}'. It is the better choice because RR does not affect the library's output, only its decision to trigger the bad event. We can make this observation even clearer, and make our analysis even easier, by changing when the bad event is triggered. Consider the following library L2\lib{2}^{\prime\prime}:

L2\lib{2}'
R{0,1}λR \gets \bits^\secpar
predict(X)\subname{predict}(X):
if R==XR == X:
bad:=true\badvar := \mytrue
return false\myfalse
return false\myfalse
\equiv
L2\lib{2}^{\prime\prime}
predict(X)\subname{predict}(X):
X:=X{X}\mathcal{X} := \mathcal{X} \cup \{X\}
return false\myfalse
end of time:
R{0,1}λR \gets \bits^\secpar
if RXR \in \mathcal{X}: bad:=true\badvar := \mytrue

These libraries have identical behavior: Their predict\subname{predict} subroutines both respond false\myfalse to every input. Both libraries sample RR uniformly (once), although L2\lib{2}^{\prime\prime} does so at the end of time—just as the calling program terminates. Furthermore, they both have identical bad-event probabilities: A bad event is triggered if and only if the adversary calls predict\subname{predict} with input RR. L2\lib{2}' checks the bad-event condition as predict\subname{predict} is being called, and L2\lib{2}^{\prime\prime} checks it retrospectively, at the end of time, having kept a list X\mathcal{X} of the adversary's inputs to predict\subname{predict}.

The analysis of L2\lib{2}^{\prime\prime} is simple, because it samples RR after the adversary has chosen its inputs to predict\subname{predict}; it is clear that RR is independent of these values. If the adversary makes qq calls to predict\subname{predict}, then Xq|\mathcal{X}| \le q, and the bad event's probability is X/2λq/2λ|\mathcal{X}|/2^\secpar \le q/2^\secpar. If the adversary is polynomial-time, then qq is a polynomial in the security parameter and the bad-event probability is negligible. Finally, the bad-event probability in L2\lib{2}^{\prime\prime} is identical to that of L2\lib{2}', so we can use the bad-event lemma to conclude that L1L2\lib{1}' \indist \lib{2}'.

This example illustrates an important strategy for the bad-event technique:

End-of-time strategy for bad events

Rewrite a library so that all its bad-event logic happens at the end of time. This can make it easier to analyze the bad-event probability, especially if the bad event involves values chosen by the adversary.

Finally, remember that the goal of the bad-event technique is to show that the bad event is triggered with negligible probability. We don't need to calculate the probability exactly; it's enough to prove a negligible upper bound.

4.5. Birthday probabilities

Many randomized cryptographic algorithms will fail in some way (i.e., lose their security) if two executions of that algorithm happen to sample the same random choices. Thus, it is important to understand the probability of such an event.

The Birthday Problem

In a collection of qq people, what is the probability that two of them have the same birthday? This question is known as the birthday problem or birthday paradox, and it is famous because the answer is highly unintuitive to most people.

A more general form of the question is:

If we take qq independent, uniform samples from a set of NN items, what is the probability that some value gets chosen more than once?

Let us give a name to this probability:

Definition 4.5.1 (Birthday probabilities)

Birthday(q,N)\Birthday(q,N) is defined as the probability that some value is chosen more than once, when taking qq independent and uniform samples from a set of NN items.

It is possible to write an exact formula for this probability:

Lemma 4.5.2 (A formula for birthday probabilities)

For all qNq \le N: Birthday(q,N)=1i=1q1(1iN)\Birthday(q,N) = 1 - \displaystyle\prod_{i=1}^{q-1} \left( 1- \frac{i}{N} \right).

Proof:

It is helpful to imagine the sampling process as an algorithm:

sample(q,N)\subname{sample}(q,N):
R:=\mathcal{R} := \emptyset
do qq times:
R{1,,N}R \gets \{ 1, \ldots, N \}
if RRR \in \mathcal{R}:
return repeat\texttt{repeat}
R:=R{R}\mathcal{R} := \mathcal{R} \cup \{ R \}
return distinct\texttt{distinct}

This algorithm chooses (up to) qq samples from the set {1,,N}\{1, \ldots, N\}, and keeps track of which values it has seen before, in the set R\mathcal{R}. Birthday(q,N)\Birthday(q,N) is the probability that sample(q,N)\subname{sample}(q,N) outputs repeat.

It is actually easier to calculate the complementary probability instead:

Pr[sample(q,N) outputs distinct]=1Birthday(q,N). \PR{ \subname{sample}(q,N) \text{ outputs } \texttt{distinct} } = 1 - \Birthday(q,N).

Let's consider the probability that sample(q,N)\subname{sample}(q,N) survives the iith iteration of its main loop, without outputting repeat. At the beginning of the iith iteration, there must be i1i-1 values in the set R\mathcal{R} (otherwise, the algorithm would have terminated earlier). The algorithm survives the iteration if RR is chosen to avoid these i1i-1 previously seen values; this happens with probability 1(i1)/N1 - (i-1)/N.

In order to finally output distinct, the algorithm must survive all qq iterations of the loop. Thus, we multiply the survival probabilities for each iteration, to get:

Pr[sample(q,N) outputs distinct]=(10N)(11N)(12N)(1q1N)=i=1q(1i1N).\begin{aligned} \PR{ \subname{sample}(q,N) \text{ outputs } \texttt{distinct} } &= \left( 1 - \frac{0}{N} \right) \left( 1 - \frac{1}{N} \right) \left( 1 - \frac{2}{N} \right) \cdots \left( 1 - \frac{q-1}{N} \right) \\ &= \prod_{i=1}^{q} \left( 1 - \frac{i-1}{N} \right).\end{aligned}

Returning to the probability Birthday(q,N)\Birthday(q,N) that we care about, and re-indexing the product (its first term is 1), we obtain the desired equation:

Birthday(q,N)=1Pr[sample(q,N) outputs distinct]=1i=1q1(1iN).\begin{aligned} \Birthday(q,N) &= 1 - \PR{ \subname{sample}(q,N) \text{ outputs } \texttt{distinct} } \\ &= 1 - \prod_{i=1}^{q-1} \left( 1 - \frac{i}{N} \right).\end{aligned}
Example 4.5.3 (The classic birthday problem)

Below is a plot of Birthday(q,N)\Birthday(q,N) for N=365N=365, corresponding to the classic question about literal birthdays:

With only q=23q=23 people, the probability of a shared birthday is just above 50 percent. The graph could be extended to the right (all the way to q=365q=365), but even at q=70q=70 the probability already exceeds 99.9 percent.

Example 4.5.4 (World cup rosters)

The birthday paradox lived up to expectation at the 2014 FIFA World Cup in Brazil. Each team consisted of twenty-three players, meaning that the probability of a shared birthday in any particular team was Birthday(23,365)0.507\Birthday(23,365) \approx 0.507, roughly 50 percent. (We are conveniently assuming that birthdays are uniformly distributed, and that February 29 doesn't exist.) Indeed, exactly half of the teams (16 of 32) contained a shared birthday among their players.

Asymptotic bounds: The exact formula for Birthday(q,N)\Birthday(q,N) is cumbersome. It is much more convenient to use the following approximations:

Lemma 4.5.5 (Birthday bounds)

For all N>0N > 0 and q2Nq \le \sqrt{2N}:

0.632q(q1)2NBirthday(q,N)q(q1)2N. \displaystyle 0.632 \frac{q(q-1)}{2N} \le \Birthday(q,N) \le \frac{q(q-1)}{2N}.
Review

You remember that 1+2++n=i=1ni=n(n+1)/21 + 2 + \cdots + n = \displaystyle\sum_{i=1}^n i = n(n+1)/2, right?

Proof:

To prove the upper bound, we use the fact that when xx and yy are positive,

(1x)(1y)=1(x+y)+xy1(x+y).\begin{aligned} (1-x)(1-y) &= 1 - (x+y) + xy \\ &\ge 1 - (x+y).\end{aligned}

More generally, when all terms xix_i are positive, i(1xi)1ixi\prod_i (1-x_i) \ge 1 - \sum_i x_i. Hence,

1i(1xi)1(1ixi)=ixi.\textstyle 1 - \prod_i (1-x_i) \le 1 - (1 - \sum_i x_i) = \sum_i x_i.

Applying that fact,

Birthday(q,N)=1i=1q1(1iN)i=1q1iN=i=1q1iN=q(q1)2N.\begin{aligned} \Birthday(q,N) &= 1 - \prod_{i=1}^{q-1} \left( 1- \frac{i}{N} \right) \le \sum_{i=1}^{q-1} \frac{i}{N} = \frac{\sum_{i=1}^{q-1} i}{N} = \frac{q(q-1)}{2N}.\end{aligned}

Next, to prove the lower bound, we use the fact that when 0x10 \le x \le 1,

1xex10.632x. 1-x \le e^{-x} \le 1 - 0.632 x.

This fact is illustrated below. The significance of 0.6320.632 is that 11e=0.632121 - \frac1e = 0.63212\ldots

We can use both of these upper and lower bounds on exe^{-x} to show the following:

i=1q1(1iN)i=1q1eiN=ei=1q1iN=eq(q1)2N10.632q(q1)2N.\begin{aligned} \prod_{i=1}^{q-1} \left( 1- \frac{i}{N} \right) &\le \prod_{i=1}^{q-1} e^{- \frac{i}{N}} = e^{-\sum_{i=1}^{q-1} \frac{i}{N}} = e^{-\frac{q(q-1)}{2 N}} \le 1 - 0.632 \frac{q(q-1)}{2N}.\end{aligned}

With the last inequality we used the fact that q2Nq \le \sqrt{2N}, and therefore q(q1)2N1\frac{q(q-1)}{2N} \le 1 (this is necessary to apply the inequality ex10.632xe^{-x} \le 1 - 0.632x). Hence:

Birthday(q,N)=1i=1q1(1iN)1(10.632q(q1)2N)=0.632q(q1)2N.\begin{aligned} \Birthday(q,N) &= 1 - \prod_{i=1}^{q-1} \left( 1- \frac{i}{N} \right) \\ &\ge 1 - \left(1 - 0.632 \frac{q(q-1)}{2N}\right) = 0.632 \frac{q(q-1)}{2N}.\end{aligned}

This completes the proof.

Example 4.5.6 (Exact birthday probability vs birthday bounds)

Below is a plot of Birthday(q,N)\Birthday(q,N) compared to these upper and lower bounds (for N=365N=365):

Birthday probabilities: take-home message

When taking repeated samples from a set of NN items,

  • Concretely: The probability of a repeat after 2N\sqrt{2N} samples is roughly 0.63. If N=2nN=2^n then 2N=2n+122n/2\sqrt{2N} = 2^{\frac{n+1}{2}} \approx 2^{n/2}.

  • Asymptotically: When the number of samples qq is much smaller than NN, the probability of a repeat is roughly q2/Nq^2/N. In particular, when qq is polynomial function of λ\secpar, and NN an exponential function of λ\secpar, Birthday(q,N)q2/N\Birthday(q,N) \le q^2/N is negligible.

We can express the birthday bound using libraries, which makes it convenient to use in a security proof:

Lemma 4.5.7 (Sampling with/without replacement)

The following two libraries are indistinguishable:

Lsamp-rand\lib{samp-rand}
bday.samp()\bdaysamp(\,):
R{0,1}λR \gets \bits^\secpar
return RR
\indist
Lsamp-uniq\lib{samp-uniq}
bday.samp()\bdaysamp(\,):
R{0,1}λRR \gets \bits^\secpar \setminus \mathcal{R}
R:=R{R}\mathcal{R} := \mathcal{R} \cup \{ R \}
return RR

Here, {0,1}λR\bits^\secpar \setminus \mathcal{R} denotes the set of all λ\secpar-bit strings, excluding those in the set R\mathcal{R}. Lsamp-uniq\lib{samp-uniq} samples from {0,1}λR\bits^\secpar \setminus \mathcal{R} to guarantee that bday.samp\bdaysamp never returns the same value twice.

Proof:

The proof is a simple application of the bad-event lemma. It uses the fact that Birthday(q(λ),2λ)\Birthday(q(\secpar),2^\secpar) is negligible, when qq is any polynomial.

Hybrid Sequence:
Modify Lsamp-rand\lib{samp-rand} to keep track of values that have been chosen previously and record whether a repeat occurs (with a bad event). These changes are all internal to the library and do not affect its output behavior.
Modify the library to re-sample RR in the case of a repeat. The library's behavior changes only after a bad event, whose probability is Birthday(q(λ),2λ)\Birthday(q(\secpar),2^\secpar), if the adversary makes q(λ)q(\secpar) calls to bday.samp\bdaysamp. As mentioned above, this probability is negligible since qq is a polynomial. Hence, the change is indistinguishable.
The logic of the if-statement has the effect that bday.samp\bdaysamp ultimately samples uniformly from {0,1}λR\bits^\secpar \setminus \mathcal{R}. Thus, the library's code can be simplified, resulting in Lsamp-uniq\lib{samp-uniq}.
Lsamp-rand\lib{samp-rand}
bday.samp\bdaysamp( ):
R{0,1}λR \gets \bits^\secpar
return RR

In some security proofs we can use lemma 4.5.7 to avoid explicitly reasoning about bad events. However, bad events cannot always be avoided, especially when they involve values chosen by the adversary.

Exercises

  1. Suppose that ff and gg are negligible functions. Prove that f+gf+g and fgf\cdot g are negligible.

  2. Suppose ff is a negligible function and pp is a polynomial. Prove that fpf\cdot p is negligible.

  3. For any integer ii, define the function

    fi(n)={1 if ni0 if n>i. f_i(n) = \begin{cases} 1 & \text{ if } n \le i \\ 0 & \text{ if } n > i \end{cases}.
    1. Prove that for each ii, fif_i is a negligible function.

    2. Consider the sum of many fif_i's, where the number of terms in the sum depends on λ\secpar:

      g(λ)=i=1λfi(λ) g(\secpar) = \sum_{i=1}^{\hl{\secpar}} f_i (\secpar)

      Show that gg is not negligible.

    3. Our convention is that all libraries have access to the security parameter λ\secpar as a global variable. For every integer ii, define the following library:

      Li\L_i
      query()\subname{query}(\,):
      if λi\secpar \le i:
      return 0λ\bit0^\secpar
      else
      R{0,1}λR \gets \bits^\secpar
      return RR

      Prove that for all integers ii, we have Li1Li\L_{i-1} \indist \L_i. Remember, we are fixing ii and the considering the asymptotic behavior of of Li\L_i, as λ\secpar approaches infinity.

    4. With Li\L_i defined as above, is L0Lλ\L_0 \indist \L_\secpar? In this question, the parameter ii is growing along with the security parameter λ\secpar.

  4. Prove that the following two libraries are indistinguishable:

    L1\lib{1}
    a(A)\subname{a}(A):
    if AAA \in \mathcal{A}:
    return true\mytrue
    else:
    A:=A{A}\mathcal{A} := \mathcal{A} \cup \{A\}
    return false\myfalse
    b(B)\subname{b}(B):
    if BBB \in \mathcal{B}:
    return true\mytrue
    else:
    B:=B{B}\mathcal{B} := \mathcal{B} \cup \{B\}
    return false\myfalse
    \indist
    L2\lib{2}
    K{0,1}λ\key \gets \bits^\secpar
    a(A)\subname{a}(A):
    if AXA \in \mathcal{X}:
    return true\mytrue
    else:
    X:=X{A}\mathcal{X} := \mathcal{X} \cup \{A\}
    return false\myfalse
    b(B)\subname{b}(B):
    if BKXB \oplus \key \in \mathcal{X}:
    return true\mytrue
    else:
    X:=X{BK}\mathcal{X} := \mathcal{X} \cup \{B \oplus \key\}
    return false\myfalse

    Let's call arguments to aAA-values” and arguments to bBB-values.” Library L1\lib{1} checks for repeats among the AA-values and repeats among the BB-values. Library L2\lib{2} checks whether there is any repeat among any combination of AA-values and values of the form BKB \oplus \key, where K\key is a global secret.

  5. Prove that the following two libraries are indistinguishable:

    L1\lib{1}
    R{0,1}λR \gets \bits^\secpar
    guess(X)\subname{guess}(X):
    if LL undefined or LXRL \oplus X \ne R:
    L:=XL := X
    return false\myfalse
    else: // LX==RL \oplus X == R
    L:=XL := X
    return true\mytrue
    \indist
    L2\lib{2}
    guess(X)\subname{guess}(X):
    return false\myfalse

    In L1\lib{1}, the guess\subname{guess} subroutine returns true\mytrue if called twice on consecutive inputs that xor to RR. It uses LL to store the previous input to guess\subname{guess}.

  6. Prove that the following two libraries are indistinguishable:

    L1\lib{1}
    samp(X)\subname{samp}(X):
    Y{0,1}λY \gets \bits^\secpar
    X:=X{X}\mathcal{X} := \mathcal{X} \cup \{X\}
    Y:=Y{Y}\mathcal{Y} := \mathcal{Y} \cup \{Y\}
    if XYX \in \mathcal{Y} or YXY \in \mathcal{X}:
    return true\mytrue
    else: return false\myfalse
    \indist
    L2\lib{2}
    samp(X)\subname{samp}(X):
    return false\myfalse

    In L1\lib{1}, each call to samp\subname{samp} involves an XX-value (chosen by the adversary) and a YY-value (uniformly sampled, and secret). It returns true\mytrue if any XX-value matches any YY-value (possibly from different calls to samp\subname{samp}).

  7. Prove that the following two libraries are indistinguishable:

    L1\lib{1}
    a()\subname{a}(\,):
    A{0,1}λA \gets \bits^\secpar
    return AA
    b()\subname{b}(\,):
    B{0,1}λB \gets \bits^\secpar
    return BB
    \indist
    L2\lib{2}
    a()\subname{a}(\,):
    A{0,1}λBA \gets \bits^\secpar \hl{\setminus \mathcal B}
    A:=A{A}\A := \A \cup \{ A \}
    return AA
    b()\subname{b}(\,):
    B{0,1}λAB \gets \bits^\secpar \hl{\setminus \mathcal A}
    B:=B{B}\mathcal{B} := \mathcal{B} \cup \{ B \}
    return BB

    In L2\lib{2}, the two subroutines will never output a common value, although each subroutine can repeat a value individually.

  8. Prove that the following two libraries are indistinguishable:

    L1\lib{1}
    samp(M)\subname{samp}(M):
    R{0,1}λR \gets \bits^\secpar
    return RR
    \indist
    L2\lib{2}
    samp(M)\subname{samp}(M):
    do
    R{0,1}λR \gets \bits^\secpar
    until MR∉XM \oplus R \not\in \mathcal{X}
    X:=X{MR}\mathcal{X} := \mathcal{X} \cup \{M \oplus R\}
    return RR

    Each call to samp\subname{samp} takes MM as input and gives RR as output. In L2\lib{2}, it is guaranteed that MRM \oplus R never repeats.

  9. Prove that the following two libraries are indistinguishable:

    L1\lib{1}
    // S\mathcal{S} is a set of strings
    samp(S)\subname{samp}(\mathcal{S}):
    R{0,1}λR \gets \bits^\secpar
    return RR
    \indist
    L2\lib{2}
    // S\mathcal{S} is a set of strings
    samp(S)\subname{samp}(\mathcal{S}):
    R{0,1}λSR \gets \bits^\secpar \setminus \mathcal{S}
    return RR

    Assume that the set S\mathcal{S} is passed as an explicit list. That is, if the calling program runs in polynomial time, then S\mathcal{S} can have only polynomially many items.

Chapter Notes

Although concrete, quantitative treatments of provable security appeared previously and implicitly, the modern concrete approach was pioneered and explicitly advocated in the work of Bellare and Rogaway, together with several groups of coauthors, during the mid-1990s [20,18,15].

The monetary costs in example 4.1.1 were estimated as follows. At the time of writing, the cheapest class of CPU on Amazon's EC2 cloud computing platform that is suitable for a CPU-bound brute force computation is c6g.medium, which is a 2.5 GHz CPU that performs 2432^{43} clock cycles per hour. The cheapest rate that I was able to find for this CPU is 0.0157 USD per hour. Thus, the cost for a single clock cycle is roughly 2482^{-48} USD. The monetary value for “all of human economic activity” is based on estimates of historical gross world product (GWP), due to J. Bradford DeLong [81], combined with more recent modern GWP data.

The estimate of total Bitcoin hashing in example 4.1.2 is based on historical data obtained from blockchain.info.

The extremely unlikely outcomes for casino games in example 4.1.3 are taken from an excellent video by Matt Parker (https://youtu.be/8Ko3TdPy0TU). For more information about the record for most consecutive craps rolls, see: [131].

Definition 4.1.6 is a folklore definition of “nn-bit security,” although it does not apply equally well to both search (e.g., key recovery) and decision (e.g., distinguishing two libraries) problems. Micciancio and Walter discuss the subtleties of “bit security” and propose a proper formalization [162].

In the modern approach to cryptography, we define security by considering the computational difficulty of attacks, not the total absence of attacks in principle. The earliest hints this approach can be found in the pioneering work of Claude Shannon from 1949 [201]:

Although it is always possible in principle to determine these solutions (by trial of each possible key for example), different enciphering systems show a wide variation in the amount of work required. \ldots A good practical secrecy system is one in which the [amount of work needed to break it] remains sufficiently high \ldots to prevent the enemy from actually carrying out the solution, or to delay it to such an extent that the information is then obsolete.

Later in 1955, the famous mathematician and economist John Nash sent several letters to the United States National Security Agency (NSA) regarding cryptography. What is notable about Nash's letters is that he explicitly identifies the importance of asymptotic running time (how the cost scales with increasing key sizes) and makes a qualitative distinction between polynomial-time computations as “feasible” and exponential-time computations as “infeasible.”

So a logical way to classify enciphering processes is by the way in which the computation length for the computation of the key increases with increasing length of the key. This is at best exponential and at worst probably a relatively small power of [the key length] rr, ar2ar^2 or ar3ar^3, as in substitution ciphers.

These remarks are almost a decade ahead of their time. Polynomial time was eventually adopted in algorithms research as a formal definition for “feasible” computation, but not until the work of Cobham [66] and Edmonds [93] in the mid-1960s. Nash's letters to the NSA were declassified in 2012 and made part of an exhibit at the National Cryptologic Museum [171]. The original handwritten letters can be seen at https://joyofcryptography.com/files/nash.pdf.

It is nontrivial to formally define “polynomial time” in a coherent way for interactive programs like the adversaries in our definition of indistinguishability. Hofheinz, Unruh, and Müller-Quade [123] give a thorough treatment of the issue, including a discussion of why the “obvious” approaches fail. When we consider whether L1\lib{1} and L2\lib{2} are indistinguishable, the most important condition is that the combined (and self-contained) programs AL1\A \link \lib{1} and AL2\A \link \lib{2} both run in polynomial time.

The idea of indistinguishable distributions was first proposed by Yao [220].

Suppose LL0L1LqL\L \equiv \L_{0} \indist \L_{1} \indist \cdots \indist \L_{q} \equiv \L^*, where the number of hybrids qq depends on the security parameter. Fischlin & Mittelbach [102] point out important subtleties and pitfalls that arise when attempting to deduce that LL\L \indist \L^*. Exercise 4.3 is from their paper, and claim 4.3.4 is inspired by their formalization.

The bad-event lemma presented here in lemma 4.4.1 is from Bellare and Rogaway [29,30]. Earlier versions of the bad-event lemma were given by Bellare, Krovetz, and Rogaway [22] and by Shoup [204].

Example 4.5.4 is inspired by a BBC Radio feature about the birthday paradox, by James Fletcher (https://www.bbc.com/news/magazine-27835311).

  1. Previous Chapter3. ☆ Secret Sharing
  2. Next Chapter5. Pseudorandom Generators