Rudiments of Provable Security
2.1. Attack scenarios as libraries
In the previous chapter, we showed how to formalize an attack scenario in terms of an adversary calling a special subroutine. Later in this book, we will encounter attack scenarios that are not easy to describe with just a single subroutine.
-
In some attack scenarios, the victim can perform several different kinds of actions. For example, the adversary may compel the victim to encrypt one thing, then decrypt another. It is convenient to model fundamentally different actions as separate subroutines.
-
Many attack scenarios feature stateful victims. For example, a victim holds a long-term key that it uses to encrypt many plaintexts. We need a way to describe persistent values that are reused across different subroutine calls.
Instead of using a single subroutine, we can formalize attack scenarios as libraries:
A library is simply a collection of subroutines. We specify libraries as concrete pseudocode, and we have some important conventions about the meaning of that code:
-
All variables are private to their own library's scope and cannot be accessed by the calling program.
-
All variables are global to the library and accessible to all subroutines in the same library.
-
Lines of code outside of any subroutine (always written at the top of the library) are executed at the beginning of time. Usually these lines initialize global variables.
-
Certain types of variables are initialized to a default value so that we don't need to explicitly write their initialization.
boolean variable initialized to integer variable / counter initialized to zero set variable / collection initialized to the empty set associative array / dictionary initialized to the empty map -
Code comments begin with .
The following library has two subroutines and one global variable :
This library models an attack scenario in which a victim holds a 6-sided die. The first line of the library (outside of any subroutine) represents what the victim does at the beginning of time: It rolls the die. Both subroutines access a global variable . The two subroutines represent actions that the adversary can cause, at any time: The adversary can make a guess about the current value of the die and learn whether the guess was correct. The adversary can also instruct the victim to (privately) re-roll the die, learning nothing about the result of that roll.
The adversary plays the role of a calling program that invokes the subroutines of a library. We need a way to write the act of combining a calling program with a library and executing the resulting combined program.
Suppose a program makes calls to subroutines in a library . Then we write to denote the result of linking to in the obvious way, resulting in a combined, self-contained program.
We write to denote the event that the combined program outputs the value . If or are randomized, then the output of is a random variable with an associated probability distribution. We usually care about calling programs that return a boolean output. We define to be the output probability of linked to .
Below is an example calling program linked to the dice-rolling library from example 2.1.2:
The combined program outputs if the victim rolls a 6 in either of its first two rolls. One way to calculate the resulting output probability is the following:
When we reason about security properties, we write a lot of different libraries on the page. But remember, security is about what happens when an adversary is allowed to call the library's subroutines. We just can't write the adversary on the page, because adversaries are always unspecified and arbitrary. Whenever you see the code of a library, always remember to picture an adversary in the role of a calling program.
It is standard in cryptography to define security in terms of adversaries interacting with libraries that play the role of the victims, but the idea of calling them libraries is unique to this book. Elsewhere, you might see libraries called (security) games or (security) experiments.
2.2. Interchangeable libraries
In the previous chapter, we discussed the security of OTP by showing that the following two subroutines have the same behavior; on every input, they generate the same output distribution:
Let's extend this idea from simple subroutines to more complicated libraries. What does it mean for two libraries to “produce the same output behavior,” especially if they have several subroutines, or persistent/static variables? We will say that two libraries and “have the same behavior” if they induce the same output probability in every calling program.
Suppose two libraries and have the same interface: identically named subroutines with identical argument types and return types. We say that and are interchangeable, and we write , if no calling program behaves differently when linked to either of the two libraries. More formally, if, for every calling program with boolean output,
It might help to think of a calling program as a distinguisher whose goal is to determine whether it is linked to or to . The two libraries are interchangeable if no distinguisher can succeed, not even with the smallest change in its output probability.
It is important to understand exactly what information can pass between and in the combined program . In short, the only thing that the calling program can learn about the library's operation is the return value of its subroutines. In particular:
-
The calling program cannot access the variables inside the library. This is what we mean when we say that the library's variables are privately scoped to the library. The calling program can learn about private variables only through what 's subroutines are willing to provide as return values.
-
The calling program cannot measure how long (e.g., number of clock cycles) the library takes to compute the response. The calling program cannot detect cache hits/misses that might indicate whether the library accessed a certain region of memory. Remember, the point of all this is to formally prove things about security. Our calling programs and libraries are clean mathematical abstractions, not literal (messy) physical computers.
You can use the methods in this book to prove security guarantees that involve an adversary who can observe response times and/or CPU cache behaviors, and so on. You simply need to make these channels of information explicit in your libraries; they don't exist automatically like they do when programs are running together on the same physical computer.
It is also important to understand that definition 2.2.1 involves two completely independent program executions. We consider the output probability of linked to , then, separately, consider the output probability of the same linked to . We never consider any scenario in which is linked to both libraries at once, or where one library is swapped for the other during an ongoing execution of .
Claim 1.4.1 can be rephrased as follows: The following two libraries are interchangeable.
In other words, no adversary can tell the difference between OTP ciphertexts and uniformly sampled strings, given the ability to arbitrarily choose the plaintexts, when OTP keys are sampled uniformly and used for only one encryption.
In the proof of claim 1.4.1 we showed that these two subroutines induce identical output distributions for every choice of input. Since the only information passed from library to calling program is this subroutine output, this implies that the libraries are interchangeable.
Finally, definition 2.2.1 puts absolutely no restriction on the calling program. The two libraries must induce identical output probabilities on all calling programs, even those whose running time is astronomical. Only in later chapters will we care about the running time of calling programs.
Ways to be interchangeable: You're probably familiar with many ways that two different programs can “have the same behavior.” Here are a few examples:
Two libraries are interchangeable if:
-
Their only difference happens in unreachable lines of code.
:if :return:if :return -
Their only difference is the value they assign to a variable that is never actually used.
::return::return -
Their only difference is that one library unrolls a loop that occurs in the other library.
:if : returnfor to ::if : returnfor to : -
Their only difference is that one library inlines a subroutine call that occurs in the other library.
::return:
Hopefully it's quite clear why each of these pairs of libraries “have the same behavior.” Each example is extremely simple, yet each one appears somewhere in a proof later in this book.
Most attack scenarios involve randomized libraries, and these can be interchangeable in more interesting ways:
-
Concatenating two strings, which were sampled independently and uniformly, has the same effect as sampling from the uniform distribution over longer strings.
:// “” denotes string concatenation:return:return -
It does not matter when a value is sampled, as long as it is sampled before its first use. In the left library below, is sampled eagerly, at the beginning of time. In the right library, is sampled lazily, at the last possible instant before it is used.
:return// by default:if undefined:return -
If we sample uniformly, but re-sample whenever we get an “undesirable” value, this has the same effect as sampling uniformly from the set of “desirable” values. In the example below, values above 90 are “undesirable”:
:do:whilereturn:return
Kerckhoffs's principle: How is Kerckhoffs's principle reflected in the idea of interchangeability? Two libraries must induce the same output probability in all calling programs, even calling programs whose source code depends arbitrarily on the source code of the libraries. In plain language, the calling program can “know” the source code of the two libraries that it tries to distinguish.
Remember: Even if its source code is public, a library can still have secrets. Knowing that the library executes the statement “” doesn't help you know the specific of value that was chosen at runtime.
2.3. How to distinguish two libraries
Every security definition in this book is phrased in terms of two interchangeable libraries. So when we need to demonstrate that something is insecure, we show that those two libraries are not interchangeable. To do this, it's enough to describe just one calling program that produces different output probabilities in the presence of the two libraries. There are usually many different ways to write such a calling program, making this a good outlet for expressing your creativity.
When you are asked to show that something is insecure, you are being asked to show that two libraries are not interchangeable.
-
First, figure out which two libraries are involved.
-
Write down the code of a calling program. This program's goal is to behave differently in the presence of the two libraries.
-
Calculate the two relevant output probabilities. If they are different, then your attack has succeeded.
Let's see some examples of how to distinguish two libraries. Consider a victim who encrypts many OTP plaintexts (of the adversary's choice) using the same key. We want to show that the resulting ciphertexts will not appear uniformly distributed. We can do so by showing that the following two libraries are not interchangeable:
Library describes an attack scenario in which the key is chosen once at the beginning of time, and reused in each call to . Library describes a scenario in which the adversary sees only “random junk.” Below are a few ways to think about a successful attack distinguishing these libraries:
In OTP, it is possible to obtain the key by requesting an encryption of the all-zeros plaintext. In , making multiple calls of the form will result in the same response every time. We wouldn't expect the same response every time from . We formalize this idea by writing the following adversary program:
When is linked to , as we argued, . Therefore, outputs with probability 1.
However, when is linked to , the values and are distributed uniformly and independently. The probability that is therefore only . Hence:
The probabilities are different, so the two libraries are not interchangeable.
Another observation we might make is that a plaintext is encrypted to the same ciphertext every time. If an adversary calls multiple times with the same , then in the responses will be the same, but in the responses will be sampled independently.
We can formalize this idea by writing the following adversary program:
Using almost identical reasoning as in the previous example, we can calculate:
We reach the same conclusion: The two libraries are not interchangeable.
This attack generalizes the first example, which can be obtained by fixing . In a sense, we have shown that there is nothing particularly special about the all-zeros plaintext.
One useful strategy is to start with a “skeleton” adversary, with many details missing:
We haven't decided yet which values to use as inputs to the subroutine, or how many calls to make. But we know that in the -th response will be . In particular, each expression includes the same term . Using the algebraic properties of xor, we can therefore observe:
The adversary knows every term appearing in the condition , and can therefore check whether it holds. It indeed always holds in , and we might also guess that it doesn't always hold in . The specific choice of doesn't seem to be important, so we can write the details of our adversary as follows:
As in the previous examples, it is possible to show that:
We reach the same conclusion: The two libraries are not interchangeable.
Once again this attack generalizes the previous one, which can be obtained by fixing . When that is the case, and the two conditions (used in the previous attack) and (used in this attack) are logically equivalent. Thus, there is nothing particularly special about calling with a repeated argument.
This final attack example also demonstrates a useful strategy that appears throughout the book:
Express the values that the adversary would see, algebraically as xor expressions. If two expressions have a common term, then xor'ing the values will cause the common term to cancel out, and the result will often be useful in an attack.
2.4. How to prove that two libraries are interchangeable
In cryptography, as in life, you should always break down a complicated problem into small, manageable pieces. In a security proof, we must show that a certain pair of libraries are interchangeable. How can we break such a proof into smaller pieces? Since the operator is transitive, we can use the following idea:
The hybrid proof technique is a way to prove , by demonstrating:
The intermediate libraries (called hybrid libraries) are chosen so that each individual step is easy to justify.
The vast majority of security proofs in the book use this simple but powerful technique. Each individual step in a hybrid proof can be extremely simple. Every situation listed in example 2.2.3 and example 2.2.4 is used in some hybrid proof in this book.
Another common step in a hybrid proof is based on the following observation:
If , then for all , we have . Here we are interpreting as a compound library.
For every calling program , we have:
Steps (1) and (3) follow from the fact that the operator is associative. Step (2) follows from the fact that : These two libraries have the same effect on all calling programs, and is one such calling program.
An example hybrid proof: Let's look at the following example that nicely showcases several common kinds of steps that can be used in a hybrid proof, including claim 2.4.1. Incidentally, the following claim is one of the most useful tools in future security proofs throughout the book.
The following two libraries are interchangeable:
A plain-English translation of this claim would be:
If you want two values whose xor is , you can either sample the first uniformly and solve for the second, or you can sample the second uniformly and solve for the first. Both methods induce the same distribution.
The sequence of hybrid libraries is presented below; it contains five intermediate hybrids besides the starting and ending libraries. Later in the book, we will discuss more intuition and strategies for generating your own hybrid proofs. For now your goal should be to simply understand why each pair of consecutive hybrid libraries are interchangeable—that is, why each change has no effect on any calling program.
Through this sequence of small changes, we proved that the two libraries and are interchangeable.
There is one step the proof that may seem mysterious: We introduced a new variable that always holds the same value as . To see why the new variable was necessary, let's focus on the following step in the proof:
This step works because we have essentially renamed the variable in to the variable in . If we had not introduced the new variable , this step would have gone like this:
If the goal of this step is to rename to , then how do we handle the appearance of in the expression “return ”? It's not possible to change this expression into “return ” because is a private variable, scoped only to . We can, however, recompute from outside , and that's exactly what the line “” does.
2.4.1. The three-hop maneuver
Let's focus more closely on how we moved between the following two hybrids in the proof of claim 2.4.2:
There were three steps:
-
First, we factored out the highlighted lines from the library on the left so that a separate instance of the library appeared.
-
Then, we replaced with , while keeping the “main” library intact, taking advantage of claim 2.4.1.
-
Finally, we inlined into the main library.
The net effect of these three steps was to replace the two lines “; ” with “.”
This sequence of steps—factor out, swap sub-libraries, inline—are standard and appear in every security proof in this book, often several times. This idiom deserves a special name:
The three-hop maneuver consists of the following steps:
-
: Factor out some lines of in terms of explicit subroutine calls to . Other lines of code stay behind, as .
-
: Replace with , while keeping unchanged.
-
: Inline , resulting in a monolithic library .
2.5. Abstract cryptographic primitives
Specific algorithms like OTP are important in cryptography, but OTP is just one instance of an encryption scheme, and it's also important that we can discuss encryption schemes and their security properties in the abstract. In cryptography, useful abstractions like “encryption scheme” are called primitives. Three things are important when defining a cryptographic primitive:
-
The syntax of a primitive specifies its basic raw interface. What are its algorithms? How many inputs and outputs are there, and what are their types?
-
Correctness properties are the basic functionality we expect from the primitive, that do not involve any adversary—things like “decryption should be the inverse of encryption.”
-
Security properties are guarantees that hold in a specific attack scenario, in the presence of an adversary.
Symmetric-key encryption is a primitive whose syntax is defined as follows:
A symmetric-key encryption (SKE) scheme consists of the following algorithms:
-
: a (possibly randomized) algorithm that takes a key and plaintext as input, and outputs a ciphertext .
-
: a deterministic algorithm that takes a key and ciphertext as input, and outputs a plaintext .
The set of possible keys is called the scheme's key space, and similarly and are called the plaintext space and ciphertext space, respectively. We sometimes use to refer to the encryption scheme as a whole, with , , , etc., denoting its constituent algorithms and sets.
An encryption scheme should satisfy a correctness property:
An SKE is correct if encryption and decryption are inverses, in the following sense:
for all and . The definition involves a probability because may be a randomized algorithm.
We will see several security goals for SKE, but the simplest is the one we have been considering for OTP:
An SKE scheme has one-time secrecy if the following two libraries are interchangeable:
We might translate this formal definition into plain language as:
An encryption scheme has one-time secrecy if its ciphertexts are uniformly distributed, when keys are sampled uniformly, kept secret, and used for only one encryption, and no matter how the plaintexts are chosen.
A security definition is a template meant to be filled in. If we have a particular encryption scheme in mind and want to prove (or disprove) its security, we populate the template with the scheme's key space , encryption algorithm , and ciphertext space , then compare the resulting two libraries.
One-time pad (OTP) is defined as follows:
If we populate the template from definition 2.5.3 with these specifics of OTP, we obtain the following two libraries:
As we have already discussed, these two libraries are interchangeable, so we conclude that OTP has one-time secrecy.
Let's revisit the OTP variant from example 1.7.1 that uses and instead of xor.
You may have already noticed that the scheme does not satisfy the correctness property! To see why, consider that the extreme case of the key encrypts every plaintext to the ciphertext .
Regardless of whether the scheme satisfies correctness, we can ask whether it has one-time secrecy. We populate the template from definition 2.5.3 with this scheme's parameters and ask whether the resulting libraries are interchangeable:
In this case, the libraries are not interchangeable, because the following adversary can distinguish them:
-
When is linked to , the ciphertext is always computed as . Therefore, always outputs true: .
-
When is linked to , the value is chosen uniformly. The probability that is . Hence, .
Since these two probabilities are different (for any ), the libraries are not interchangeable, and the encryption scheme does not have one-time secrecy.
There are many other strategies that can successfully distinguish these two libraries. Perhaps you can think of a few and write them formally as calling programs.
2.6. Modular cryptographic constructions
Cryptographic primitives are like building blocks, which we can use to build more complicated things in a modular way. We can use the security properties of the underlying primitives to prove security of the larger construction.
Let's see an example of such a modular construction. It involves a rather indirect approach to encryption. Suppose Alice wants to privately send some message to Bob, and they already share a secret key . Alice can do the following:
-
Sample a new key , uniformly.
-
Use to encrypt , resulting in ciphertext .
-
Use (not !) to encrypt , resulting in .
-
Send both and to Bob.
Bob can decrypt in two steps:
-
Use to decrypt , and learn .
-
Use to decrypt , and learn .
What I have just described is a recipe to construct a new (complicated) encryption scheme out of an existing (simpler) one. The recipe is modular; it doesn't specify exactly how Alice “uses to encrypt ” or how Bob “uses to decrypt .” We can imagine plugging in any encryption scheme into this recipe, and maybe even different schemes for the two different encryption/decryption steps in the recipe! The recipe can be formalized as follows:
Let and be encryption schemes for which (that is, can encrypt keys for ). Define a new scheme as follows:
Construction 2.6.1 is heavy on notation, exactly because it is so modular and refers to arbitrary/unspecified encryption schemes and . Be sure you understand the connection between the notation and the simple informal recipe described above. The new construction supports keys that are the same as 's keys, and plaintexts that are the same as 's plaintexts. The ciphertexts in consist of a pair of ciphertexts, one from each of and .
Construction 2.6.1 is also our first example of an encryption scheme whose algorithm is randomized. The algorithm samples a fresh each time it is called. Thus, encrypting the same plaintext, even under the same key (which is not advised for the encryption schemes we've seen so far) can produce different ciphertexts. Randomized encryption schemes will become important later in the book.
Staying in the realm of abstract, unspecified encryption schemes, we can ask whether the recipe always results in a secure encryption scheme.
If and both have one-time secrecy, then construction 2.6.1 also has one-time secrecy. In other words,
The claim is fundamentally an if-then statement involving three separate instances of one-time secrecy. It therefore involves three different pairs of libraries. Since this is a source of potential confusion, I have changed subroutine names to to help keep track of which scheme's security we are talking about at any given point. Most future constructions and proofs won't be quite so confusing, since they involve security properties of different primitives, involving different-looking libraries.
Because the claim is so abstract/modular, it is less about any particular encryption scheme, and more about the implications of the one-time secrecy definition itself. “One-time secrecy is preserved under this way of combining two encryption schemes.”
We use the hybrid technique to prove that , while assuming the hypotheses and .
2.7. ☆ “Real-or-random” vs. “left-or-right”
Security definitions don't represent some timeless, universal truth, handed down to us from the Cryptography Gods. Rather, we (mere Cryptography Humans) do our best to model a reasonable attack scenario and say something precise about what can happen in that scenario. There could be more than one way to do this.
In this book, the default way to define security is the real-or-random paradigm: Something is “secure” if its outputs look like the uniform distribution. But that's not the only sensible way to define security, at least for encryption. In the left-or-right paradigm, we say that an encryption scheme is “secure” if encryptions of one plaintext look like encryptions of any other plaintext—but not necessarily like the uniform distribution. In the left-or-right paradigm, we formalize an attack scenario in which the adversary chooses two plaintexts but only one of them gets encrypted. The adversary should not be able to determine which of the two plaintexts is encrypted.
An SKE scheme satisfies left-or-right one-time secrecy (OTS) if the following two libraries are interchangeable:
always encrypts the left plaintext, while always encrypts the right one.
We now have two definitions of security for encryption, and, perhaps unfortunately, they are not equivalent. One is a strictly stronger security requirement than the other. Any scheme that satisfies the real-or-random flavor of security also satisfies the left-or-right flavor (see exercise 2.24), but the converse is not true.
We must acknowledge the existence of an uncanny gap between the two definitions, containing schemes that are secure in the left-or-right sense but not the real-or-random sense. However, this gap is relatively insignificant in practice. The schemes that inhabit it are highly unnatural; they look like they were designed just to prove a philosophical point about security definitions—because almost all of them were! I know of only one exception to this rule, a truly natural encryption scheme that we will see later in , which is secure in the left-or-right sense but not the real-or-random sense. Every other encryption scheme we actually care about satisfies both definitions.
So which is the “correct” way to define security of encryption? Neither paradigm is objectively “correct”; they simply demand different things from an encryption scheme. What's most important is to recognize that there is a choice to be made at all! Here are a few more philosophical and cultural differences between the real-or-random and left-or-right paradigms:
-
Left-or-right is the more “traditional” way to define security for encryption. You'll see it appear as the standard approach in most other references and in the research literature.
-
On the other hand, the real-or-random paradigm is the standard (and often, only sensible) way to define security for many other, non-encryption primitives.
-
I find that security definitions in the real-or-random paradigm are more intuitive and easier to use. The adversary provides just one plaintext at a time, not two.
-
Security proofs in the real-or-random paradigm are often half the length of comparable proofs in the left-or-right paradigm. To prove security in the left-or-right paradigm, you need a sequence of hybrids in which the only net change is to replace with . Usually there is a hybrid precisely in the middle of the proof in which ciphertexts are generated uniformly, and the hybrids on either side of this midpoint are like mirror images, with their only difference being vs. . A security proof of real-or-random security is already complete once it reaches that middle point.
-
Left-or-right security is a more minimal definition and fits better with many natural intuitions you probably have about security. Does a secure encryption scheme become suddenly insecure if you append zeros to every ciphertext? What if you repeat every bit in every ciphertext? What if you simply change the definition of the ciphertext space ? It seems silly that such benign changes should have an impact on security.
And indeed, if we define security in the left-or-right paradigm, then all of these changes preserve security (see exercises 2.25 and 2.26). But they break security in the real-or-random sense.
-
When a scheme is insecure according to the left-or-right paradigm, the resulting attack is often easier to appreciate as a security problem. “I can tell whether your ciphertext contains this or that” just feels like more of an attack than “Your ciphertexts don't look uniformly chosen.”
Exercises
-
Show that the following two libraries are not interchangeable:
:return:return -
Show that the following two libraries are not interchangeable:
:return:returnNote that the variable in is static/persistent, and is changed in each call to foo.
-
Give a convincing justification that in example 2.3.3.
-
Let be the variant of OTP that uses boolean-and, and let and be the libraries involved in one-time secrecy (shown in example 2.5.5). Let be the following calling program:
returnCalculate and .
-
Prove formally that the operator is transitive: If and , then .
-
Prove that the following two libraries are interchangeable, for all .
:return:returnThis exercise generalizes claim 2.4.2: Each library generates random and whose sum mod is .
-
h Prove that the following two libraries are interchangeable:
:return:returndenotes the bitwise complement of —that is, the result of flipping every bit in the string .
Write in terms of xor.
-
Prove that the following two libraries are interchangeable:
:return:return -
Below are two pairs of libraries. One pair is interchangeable, one is not. Give a proof and a distinguishing attack:
-
:return:return
-
:return:return
-
-
In abstract algebra, a (finite) group is a finite set of items together with an operator that satisfies the following axioms:
-
Closure: For all , we have .
-
Identity: There is a special identity element that satisfies for all .
-
Associativity: For all , we have .
-
Inverses: For all , there exists an inverse element called such that .
Define the following encryption scheme in terms of an arbitrary group :
-
Prove that is a group with respect to the xor operator. What is the identity element, and what is the inverse of a value ?
-
Fill in the details of the algorithm and prove (using the group axioms) that the scheme satisfies correctness.
-
Prove that the scheme satisfies one-time secrecy.
-
-
Write a different attack that distinguishes the libraries in example 2.5.5, and calculate the two output probabilities. Try to make your attack as different as possible from the one given in the example.
-
Why do you think I did not show the decryption algorithm for the variant of OTP that uses boolean-and, in example 2.5.5?
-
Prove that the following encryption scheme does not have one-time secrecy:
-
h In this exercise you will show that an encryption scheme cannot achieve one-time secrecy if it has fewer keys than plaintexts. Let be an encryption scheme with .
-
Suppose we fix an arbitrary ciphertext , and run the following code:
for each :add to the setif : returnelse: returnArgue that this program outputs with some nonzero probability.
-
Show that the following program can successfully distinguish and (definition 2.5.3):
for each :add to the setif : returnelse: returnCalculate both relevant output probabilities.
In part (a), how does the size of the set compare to ? In part (b), show that and the code from part (a) are interchangeable.
-
-
Let be an SKE scheme and define the following library:
:if :returnelse: //return-
Suppose that has one-time secrecy. Prove that for all calling programs , we have
where is the global variable chosen at the beginning of time in .
-
Prove the converse of part (a). Namely, if does not have one-time secrecy then there is a calling program for which
-
-
Let denote the set of all permutations over , which we write as functions . Show that the following encryption scheme does not have one-time secrecy:
-
Show that construction 2.6.1 satisfies the correctness property for an SKE, if and both do.
-
The proof of claim 2.6.2 first applies the security of , then of , each in a three-hop maneuver. Explain why the proof doesn't work if these three-hop maneuvers are done in the opposite order.
-
Suppose we instantiate the scheme from claim 2.6.2 with OTP. What happens when a victim repeats a key (to )? Show an attack analogous to the ones in section 2.3.
-
Construction 2.6.1 is a randomized encryption scheme. Suppose and we make construction 2.6.1 deterministic with the following change:
Does the resulting still have one-time secrecy after this change? Give either a security proof or an attack.
-
Here is a modular construction that illustrates the intuitive idea that it is safe to encrypt the same plaintext twice, under two independent keys. In other words, perhaps for the sake of redundancy, if we always encrypt all plaintexts twice under independent keys, do we get a secure encryption scheme? (You may wonder why such an “obvious” statement requires proof, but later in the book we study security definitions for which it is not safe.)
Let be an SKE scheme. Define the following new scheme :
Prove that has one-time secrecy if does.
-
Here is a modular construction that illustrates the intuitive idea that it is safe to encrypt a long plaintext by separately encrypting its two halves (under independent keys). (You may wonder why such an “obvious” statement requires proof, but later in the book we study security definitions for which it is not safe.)
Let be an SKE scheme. Define the following new scheme :
Prove that has one-time secrecy if does.
-
Let be an SKE scheme for which , so that it makes sense to treat a ciphertext also as a plaintext that can be encrypted. Prove that if has one-time secrecy, then so does the following scheme :
-
Let be an SKE scheme. Prove that if satisfies real-or-random OTS (definition 2.5.3) then it also satisfies left-or-right OTS (definition 2.7.1).
-
Let be an SKE scheme, and let be the encryption scheme defined by
-
Show that does not have (real-or-random) OTS, even if does.
-
Show that does have left-or-right OTS (definition 2.7.1), if does.
-
-
Let be an SKE scheme, and let be the encryption scheme defined by
-
Show that does not have (real-or-random) OTS, even if does.
-
Show that does have left-or-right OTS (definition 2.7.1), if does.
-
-
Prove that the following two libraries are interchangeable if and only if satisfies left-or-right one-time secrecy:
:return:returnIn other words, these two libraries are an equivalent definition for left-or-right one-time secrecy. You must prove both directions—that is, , and .
-
Prove that the following two libraries are interchangeable if and only if satisfies left-or-right one-time secrecy:
:return:returnIn other words, these two libraries are an equivalent definition for left-or-right one-time secrecy. You must prove both directions—that is, , and .
Chapter Notes
Library-based security is a simplified dialect of the game-hopping methodology for security proofs, introduced by Shoup [206] and by Bellare and Rogaway [29,30]. In the game-based paradigm, security is defined in terms of an abstract interactive game played against an adversary; the programmatic code of the game plays a prominent role in security reasoning. Kilian and Rogaway [133] were the first to prove security in what we would now recognize as the modern game-hopping style. Library-based security shares many similarities with the state-separating proofs methodology, developed independently by Brzuska, Delignat-Lavaud, Fournet, Kohbrok, and Kohlweiss [56]. In both the library-based and state-separation methodologies, secrecy of values is reflected in their scope, and hybrid proofs involve frequently factoring out certain target libraries/modules.
Bellare, Desai, Jokipii, and Rogaway [15] were the first to formalize a security definition for encryption in the left-or-right paradigm. They also described another style of definition, which they called “real-or-random,” but which is different than how we use this term in the book. Theirs is analogous to the definition in exercise 2.27 and is actually equivalent to the left-or-right definition (one definition implies the other). Rogaway, Bellare, Black, and Krovetz [193] were the first to propose a security definition for encryption using our sense of the term “real-or-random.”