14
Public-Key Cryptography

Public-Key Encryption

In a symmetric-key encryption scheme, both encryption and decryption use the same key. A public-key scheme disrupts this idea and uses different keys for encryption and decryption. The encryption key can be made public so that anyone can send encrypted messages. The decryption key is kept private, and only the holder of this key can decrypt these messages.

14.1. Security definitions for PKE

We start by introducing the syntax of a public-key encryption scheme. In the public-key setting, there is not one key but a key pair consisting of a private key and public key. These two keys must of course be correlated in some way. Therefore, a public-key encryption scheme must include a separate key generation algorithm KeyGen\KeyGen.

Definition 14.1.1 (Syntax & correctness of public-key encryption)

A public-key encryption (PKE) scheme consists of the following algorithms:

  • KeyGen\KeyGen: a randomized algorithm that takes no inputs (besides the security parameter, which we never write explicitly) and outputs a key pair (PK,SK)(\pk,\sk), where PK\pk is a public key and SK\sk is a private key.

  • Enc\Enc: a randomized algorithm that takes a public key PK\pk and plaintext MM\ptxt \in \M as input and returns a ciphertext CC\ctxt\in \C.

  • Dec\Dec: a deterministic algorithm that takes a private key SK\sk and ciphertext CC\ctxt\in\C as input, and returns a plaintext MM\ptxt\in \M (or raises an error).

A PKE scheme is correct if the following program outputs true\mytrue with probability 1, for all MM\ptxt \in \M:

(PK,SK):=KeyGen()(\pk,\sk) := \KeyGen()
C:=Enc(PK,M)\ctxt := \Enc(\pk,\ptxt)
return M==Dec(SK,C)\ptxt == \Dec(\sk,\ctxt)

What does it mean for a key to be public? In the security definition, the library provides a way for the adversary/calling program to learn it. By making this change to the security definitions for encryption, and also ensuring that the correct key is used for encryption/decryption, we obtain definitions of CPA and CCA security for PKE:

Definition 14.1.2 (CPA security for public-key encryption)

A PKE scheme Σ\Sigma has security against chosen-plaintext attacks (CPA security) if the following two libraries are indistinguishable:

Lpk-cpa-realΣ\lib{pk-cpa-real}^\Sigma
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
cpa.pk()\cpapk(\,):
return PK\pk
cpa.enc(M)\cpaenc(\ptxt):
C:=Σ.Enc(PK,M)\ctxt := \Sigma.\Enc(\pk, \ptxt)
return C\ctxt
\indist
Lpk-cpa-randΣ\lib{pk-cpa-rand}^\Sigma
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
cpa.pk()\cpapk(\,):
return PK\pk
cpa.enc(M)\cpaenc(\ptxt):
CΣ.C(M)\ctxt \gets \Sigma.\C(|\ptxt|)
return C\ctxt
Definition 14.1.3 (CCA security for public-key encryption)

A PKE scheme Σ\Sigma has security against chosen-ciphertext attacks (CCA security) if the following two libraries are indistinguishable:

Lpk-cca-realΣ\lib{pk-cca-real}^\Sigma
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
cca.pk()\ccapk(\,):
return PK\pk
cca.enc(M)\ccaenc(\ptxt):
C:=Σ.Enc(PK,M)\ctxt := \Sigma.\Enc(\pk,\ptxt)
return C\ctxt
cca.dec(C)\ccadec(\ctxt):
return Σ.Dec(SK,C)\Sigma.\Dec(\sk,\ctxt)
\indist
Lpk-cca-randΣ\lib{pk-cca-rand}^\Sigma
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
cca.pk()\ccapk(\,):
return PK\pk
cca.enc(M)\ccaenc(\ptxt):
CΣ.C(M)\ctxt \gets \Sigma.\C(|\ptxt|)
D[C]:=M\mathcal{D}[\ctxt] := \ptxt
return C\ctxt
cca.dec(C)\ccadec(\ctxt):
if D[C]\mathcal{D}[\ctxt] defined: return D[C]\mathcal{D}[\ctxt]
return Σ.Dec(SK,C)\Sigma.\Dec(\sk,\ctxt)

As in the CCA security definition for SKE, ciphertexts generated by cca.enc\ccaenc are called challenge ciphertexts.

After seeing CPA and CCA security defined for PKE, you may also expect a definition of public-key authenticated encryption (AE). The spirit of AE is that no one can generate valid ciphertexts except the person who holds the secret key. But the spirit of public-key encryption is that anyone can encrypt ciphertexts. The two concepts are incompatible, so in the public-key world we will stop at CCA security.

If anyone can encrypt, why can't I tell whether something is an encryption of M\ptxt by re-encrypting M\ptxt myself?
This attack would work if PKE encryption were deterministic. But just like the case of SKE, public-key encryption cannot be deterministic. It is tempting to think that Enc(PK,M)\Enc(\pk,\ptxt) has no secrets, because both of its arguments may be public. But the randomness that Enc\Enc samples is a secret that the adversary doesn't know! The randomness used in an SKE's Enc\Enc algorithm is often included in its output, but this cannot be the case for a public-key scheme.

14.2. One-time vs. many-time encryption

Before describing an actual PKE scheme, let's first discuss a property of PKE that will make future security proofs easier.

In the symmetric-key world, it makes a difference whether a key is used to encrypt many plaintexts or just one. For example, OTP is secure when a key is used to encrypt one plaintext, but insecure when used for many encryptions. In the public-key world, there is no such distinction: Any PKE scheme that is secure for a single encryption is also secure for many. What this means is that if we need to prove CPA security for a PKE scheme, it's enough to prove a simpler property of security for a single encryption.

Claim 14.2.1 (One-time CPA security for public-key encryption)

Let Σ\Sigma be a PKE scheme. If the following two libraries are indistinguishable, then Σ\Sigma has CPA security:

Lpk-1cpa-realΣ\lib{pk-1cpa-real}^\Sigma
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
1cpa.pk()\cpaonepk(\,):
return PK\pk
1cpa.enc(M)\cpaoneenc(\ptxt):
if C\ctxt^* undefined:
C:=Σ.Enc(PK,M)\ctxt^* := \Sigma.\Enc(\pk, \ptxt)
return C\ctxt^*
\indist
Lpk-1cpa-randΣ\lib{pk-1cpa-rand}^\Sigma
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
1cpa.pk()\cpaonepk(\,):
return PK\pk
1cpa.enc(M)\cpaoneenc(\ptxt):
if C\ctxt^* undefined:
CΣ.C(M)\ctxt^* \gets \Sigma.\C(|\ptxt|)
return C\ctxt^*

In these libraries, C\ctxt^* is static/global, and its value is fixed upon the first call to 1cpa.enc\cpaoneenc. Subsequent calls to 1cpa.enc\cpaoneenc don't do anything, so the adversary can obtain only a single ciphertext encrypted under the key pair. These libraries are written somewhat differently than in the definition of one-time secrecy for SKE (definition 5.3.2) since here the adversary is allowed to see PK\pk before choosing its plaintext.

Proof:

The proof uses the following family of hybrids, parameterized by an integer hh:

Lh\L_h
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
cpa.pk()\cpapk(\,):
return PK\pk
cpa.enc(M)\cpaenc(\ptxt):
count:=count+1count := count + 1
if counthcount \le h:
CΣ.C(M)\ctxt \gets \Sigma.\C(|\ptxt|)
else:
C:=Σ.Enc(PK,M)\ctxt := \Sigma.\Enc(\pk, \ptxt)
return C\ctxt

This library responds with uniformly sampled ciphertexts the first hh times cpa.enc\cpaenc is called, and thereafter responds with ciphertexts encrypted in the normal way. Thus:

  • In L0\L_0, the else-branch is always taken, so the library behaves identically to Lpk-cpa-real\lib{pk-cpa-real}. Every output of cpa.enc\cpaenc is an actual encryption of the given plaintext.

  • If qq is the number of queries that the calling program makes to enc then in Lq\L_q the if-branch is always taken, so the library behaves identically to Lpk-cpa-rand\lib{pk-cpa-rand}. Every output of cpa.enc\cpaenc is sampled uniformly.

It therefore suffices to show that LhLh+1\L_h \indist \L_{h+1} for every h{0,,q1}h \in \{0, \dots, q-1\}.

Hybrid Sequence:
We start with Lh\L_h,
then isolate the case of count==h+1count == h+1 into its own conditional branch.
We can write the body of the new branch in terms of Lpk-1cpa-*\lib{pk-1cpa-*}. Since this branch is executed at most once during the library's execution, this compound library calls 1cpa.enc\cpaoneenc at most once. Importantly, the library can still encrypt ciphertexts in the else-branch, because it knows the public key! This is the step in the proof that would fail with a symmetric-key scheme.
The if and else-if branches can now be unified, and the result is Lh+1\L_{h+1}, as desired.
Lh\L_h
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
cpa.pk\cpapk( ):
return PK\pk
cpa.enc\cpaenc(M\ptxt):
count:=count+1count := count + 1
if countcount \le {}
hh:
h+1h+1:
CΣ.C(M)\ctxt \gets \Sigma.\C(|\ptxt|)
else:
C:=Σ.Enc(PK,M)\ctxt := \Sigma.\Enc(\pk, \ptxt)
return C\ctxt
\link
Lpk-1cpa-real\lib{pk-1cpa-real}
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
1cpa.pk\cpaonepk( ):
return PK\pk
1cpa.enc\cpaoneenc(M\ptxt):
if C\ctxt^* undefined:
C:=Σ.Enc(PK,M)\ctxt^* := \Sigma.\Enc(\pk, \ptxt)
return C\ctxt^*
Lpk-1cpa-rand\lib{pk-1cpa-rand}
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
1cpa.pk\cpaonepk( ):
return PK\pk
1cpa.enc\cpaoneenc(M\ptxt):
if C\ctxt^* undefined:
CΣ.C(M)\ctxt^* \gets \Sigma.\C(|\ptxt|)
return C\ctxt^*

An analogous property is true for CCA security as well. Any PKE scheme that is CCA-secure for a single encryption is secure against many: Its proof is mostly the same as the previous one, and is left as an exercise.

Claim 14.2.2 (One-time CCA security for public-key encryption)

Let Σ\Sigma be a PKE scheme. If the following two libraries are indistinguishable, then Σ\Sigma has CCA security:

Lpk-1cca-realΣ\lib{pk-1cca-real}^\Sigma
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
1cca.pk()\ccaonepk(\,):
return PK\pk
1cca.enc(M)\ccaoneenc(\ptxt):
if C\ctxt^* undefined:
C:=Σ.Enc(PK,M)\ctxt^* := \Sigma.\Enc(\pk, \ptxt)
return C\ctxt^*
1cca.dec(C)\ccaonedec(\ctxt):
return Σ.Dec(SK,C)\Sigma.\Dec(\sk,\ctxt)
\indist
Lpk-1cca-randΣ\lib{pk-1cca-rand}^\Sigma
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
1cca.pk()\ccaonepk(\,):
return PK\pk
1cca.enc(M)\ccaoneenc(\ptxt):
if C\ctxt^* undefined:
CΣ.C(M)\ctxt^* \gets \Sigma.\C(|\ptxt|)
M:=M\ptxt^* := \ptxt
return C\ctxt^*
1cca.dec(C)\ccaonedec(\ctxt):
if C==C\ctxt == \ctxt^*: return M\ptxt^*
return Σ.Dec(SK,C)\Sigma.\Dec(\sk,\ctxt)

The Lpk-1cca-rand\lib{pk-1cca-rand} library does not maintain a dictionary D[]\mathcal{D}[\cdot] as in the usual CCA security definition (definition 14.1.3). This library generates only a single challenge ciphertext, so it would assign only one value to the dictionary, at D[C]\mathcal{D}[\ctxt^*]. Instead, we simply rename D[C]\mathcal{D}[\ctxt^*] to M\ptxt^*.

14.3. El Gamal encryption

Using the tools that you have learned about so far, how would you propose two users exchange secret messages when they don't have any shared secret key? First, they could run a key exchange protocol to establish a shared key. Then, they could use that key to encrypt their secret messages under a symmetric-key encryption scheme.

They can use DHKE for key exchange, but what would be a natural choice for the symmetric-key encryption scheme? In the previous section, we saw that it is enough for a PKE to be secure for only one encryption. Thus, perhaps they can consider something as simple as OTP. And since Diffie-Hellman outputs a key that is a cyclic group element, they could use a variant of OTP that uses the cyclic group operation (group multiplication) instead of xor.

If Bob wants to send Alice a private message M\ptxt following these recommendations, it looks like this:

If this picture makes sense to you, then you already understand our first PKE scheme, called El Gamal encryption after its creator Taher El Gamal. El Gamal encryption is what you get when you label Alice's message the public key and label Bob's two messages as the encryption of M\ptxt.

Construction 14.3.1 (El Gamal encryption)

Let G\G be a cyclic group of order nn with generator gg. El Gamal encryption is defined by the following algorithms:

M=GC=G×G\begin{aligned} \M &= \G \\ \C &= \G \times \G \end{aligned}
KeyGen()\KeyGen(\,):
SKZn\sk \gets \Z_\nmod
PK:=gSK\pk := g^{\sk}
return (PK,SK)(\pk,\sk)
Enc(PK,M)\Enc(\pk, \ptxt):
rZnr \gets \Z_\nmod
C1:=gr\ctxt_1 := g^r
C2:=MPKr\ctxt_2 := \ptxt \cdot \pk^r
return (C1,C2)(\ctxt_1, \ctxt_2)
Dec(SK,(C1,C2))\Dec\bigl(\sk,(\ctxt_1,\ctxt_2)\bigr):
return C2C1SK\ctxt_2 \cdot \ctxt_1^{-\sk}

Compared to the picture above, we have renamed values as follows:

aSKbrCC2APKBC1\begin{aligned} a &\leadsto \sk & b &\leadsto r & C &\leadsto C_2 \\ A &\leadsto \pk & B &\leadsto C_1 \end{aligned}
Claim 14.3.2 (Security of El Gamal)

If the DDH assumption is true, then El Gamal encryption (construction 14.3.1) is CPA-secure.

Proof:

From claim 14.2.1, it suffices to prove that El Gamal is secure when encrypting one ciphertext. In other words, we will show that the following two libraries are indistinguishable:

Lpk-cpa1-real\lib{pk-cpa1-real}
// KeyGen\KeyGen:
SKZn\sk \gets \Z_\nmod
PK:=gSK\pk := g^{\sk}
1cpa.pk()\cpaonepk(\,):
return PK\pk
1cpa.enc(M)\cpaoneenc(\ptxt):
if C\ctxt^* undefined:
// C:=Enc(PK,M)\ctxt^* := \Enc(\pk,\ptxt):
rZnr \gets \Z_\nmod
C1:=gr\ctxt_1 := g^r
C2:=MPKr\ctxt_2 := \ptxt \cdot \pk^r
C:=(C1,C2)\ctxt^* := (\ctxt_1, \ctxt_2)
return C\ctxt^*
\indist
Lpk-cpa1-rand\lib{pk-cpa1-rand}
// KeyGen\KeyGen:
SKZn\sk \gets \Z_\nmod
PK:=gSK\pk := g^{\sk}
1cpa.pk()\cpaonepk(\,):
return PK\pk
1cpa.enc(M)\cpaoneenc(\ptxt):
if C\ctxt^* undefined:
// CC=G×G\ctxt^* \gets \C = \G \times \G
C1G\ctxt_1 \gets \G
C2G\ctxt_2 \gets \G
C:=(C1,C2)\ctxt^* := (\ctxt_1, \ctxt_2)
return C\ctxt^*

Hybrid Sequence:
The starting point is Lpk-1cpa-real\lib{pk-1cpa-real}.
Since C1=gr\ctxt_1 = g^r and PKr\pk^r (used to compute C2\ctxt_2) do not depend on the choice of M\ptxt, they can be sampled at the beginning of time.
At the beginning of time, the library samples gSKg^{\sk}, grg^r, and PKr=gSKr\pk^r = g^{\sk \cdot r}. The DDH assumption says that values distributed in this way are pseudorandom. The three-hop maneuver is not shown.
We can move the selection of C1\ctxt_1 and UU back into 1cpa.enc\cpaoneenc. These values are sampled uniformly.
Now UU is distributed uniformly in G\G, so C2\ctxt_2 is a OTP ciphertext (in a OTP variant that uses the group operation in place of xor; see exercise 2.10). Thus, C2\ctxt_2 is distributed uniformly, independent of M\ptxt. After making this change, the result is Lpk-1cpa-rand\lib{pk-1cpa-rand}.
Lpk-1cpa-real\lib{pk-1cpa-real}
SKZn\sk \gets \Z_\nmod
PK:=gSK\pk := g^{\sk}
1cpa.pk\cpaonepk( ):
return PK\pk
1cpa.enc\cpaoneenc(M\ptxt):
if C\ctxt^* undefined:
rZnr \gets \Z_\nmod
C1\ctxt_1
:=gr{}:= g^r
G{}\gets \G
C2\ctxt_2
:=M{}:= \ptxt \cdot {}
PKr\pk^r
UU
G{}\gets \G
C:=(C1,C2)\ctxt^* := (\ctxt_1, \ctxt_2)
return C\ctxt^*

14.4. The Fujisaki-Okamoto construction

In this section we describe how to efficiently convert any CPA-secure PKE into a CCA-secure one. The construction slightly breaks the usual abstraction of an encryption scheme, in an interesting way:

Definition 14.4.1

An encryption algorithm Enc\Enc is randomized, but in this section it will be useful to run the encryption algorithm with some externally determined random choices. We write Enc(PK,M;R)\Enc(\pk,\ptxt; R) to denote the result of running Enc(PK,M)\Enc(\pk,\ptxt) but setting the random choices of Enc\Enc to be RR. It is traditional to use a semicolon to separate the last argument. Note that Enc(,;)\Enc(\cdot,\cdot;\cdot), with the randomness as an explicit third argument, refers a deterministic algorithm.

Using this new notation, what we usually write as Enc(PK,M)\Enc(\pk,\ptxt) refers to the process:

RRR \gets \mathcal{R}
return Enc(PK,M;R)\Enc(\pk,\ptxt; R)

R\mathcal{R} refers to the space of possible random choices made by Enc\Enc.

Example 14.4.2

The El Gamal encryption algorithm chooses an exponent rZnr \gets \Z_\nmod as its randomness, so R=Zn\mathcal{R} = \Z_\nmod above. Writing the encryption algorithm with this randomness as an explicit argument gives:

Enc(PK,M;r)=(gr,PKrM). \Enc(\pk, \ptxt; r) = (g^r, \pk^r \cdot \ptxt).

In this section we will assume that every encryption algorithm's randomness comes from {0,1}λ\bits^\secpar. This is without loss of generality, because an encryption algorithm may use its randomness argument to seed a PRG and obtain as much randomness as needed.

The Fujisaki-Okamoto construction is a recipe for converting a CPA-secure PKE into a CCA-secure one, in the random oracle model. Its main idea is to encrypt (under the CPA scheme) plaintexts of the form XX using H(X)\ro(X) as the randomness. When the receiver decrypts a ciphertext, she will check that it was encrypted with randomness H(X)\ro(X) as expected—by re-encrypting it herself with that randomness!—and reject if this is not the case.

You may wonder why using H(X)\ro(X) for encryption randomness is useful for CCA security. The reasoning is subtle and clever. “Valid” ciphertexts must have the form Enc(PK,X;H(X))\Enc\bigl(\pk, X; \ro(X) \bigr), and in the random oracle model (it can be argued that) you can't produce a ciphertext of this form without first calling the random oracle at H(X)\ro(X). But if the adversary has previously called the random oracle at input XX, then the library has a chance to compute the ciphertext C=Enc(PK,X;H(X))\ctxt = \Enc\bigl(\pk,X; \ro(X)\bigr) and remember the association CX\ctxt \leadsto X for later. The library is able to know that the decryption of C\ctxt should be XX, but it has deduced this fact without using the private key! When the library no longer needs the private key, we can apply the CPA security of the underlying PKE.

For technical reasons, XX is not the actual plaintext, but has the form X=MSX = \ptxt \|S, where SS is chosen uniformly. Thus, an encryption of M\ptxt has the form Enc(PK,MS;H(MS))\Enc\bigl( \pk, \ptxt \| S; \ro(\ptxt\|S) \bigr).

Construction 14.4.3 (Fujisaki-Okamoto)

Let Σ\Sigma be a PKE scheme, and H\ro be a random oracle with λ\secpar output bits. Assume that Σ.Enc\Sigma.\Enc uses λ\secpar bits of randomness. Then the Fujisaki-Okamoto PKE scheme consists of the following:

Σ.K=Σ.KΣ.C()=Σ.C(+λ)Σ.KeyGen=Σ.KeyGen\begin{aligned}\Sigma^*.\K &= \Sigma.\K \\ \Sigma^*.\C(\ell) &= \Sigma.\C(\ell+\secpar) \\ \Sigma^*.\KeyGen &= \Sigma.\KeyGen \end{aligned}
Σ.Enc(PK,M)\Sigma^*.\Enc(\pk,\ptxt):
S{0,1}λS \gets \bits^\secpar
R:=H(MS)R := \ro(\ptxt \| S)
C:=Σ.Enc(PK,MS;R)\ctxt := \Sigma.\Enc(\pk, \ptxt \| S; R)
return C\ctxt
Σ.Dec(SK,C)\Sigma^*.\Dec(\sk,\ctxt):
MS:=Σ.Dec(SK,C)\ptxt \| S := \Sigma.\Dec(\sk,\ctxt)
R:=H(MS)R := \ro(\ptxt \| S)
if CΣ.Enc(PK,MS;R)\ctxt \ne \Sigma.\Enc(\pk,\ptxt \| S;R):
return err\myerr
return M\ptxt

We will prove the security of Fujisaki-Okamoto using the following assumption about the underlying (CPA-secure) scheme.

Definition 14.4.4 (Unique randomness for a PKE)

An encryption algorithm Enc\Enc has unique randomness if for all PK\pk and all M\ptxt, the function Enc(PK,M;)\Enc(\pk,\ptxt; \cdot) is 1-to-1 (injective).

This property makes the Fujisaki-Okamoto construction easier to prove, but security can also be proven without it; see exercise 14.14.

Theorem 14.4.5 (Security of Fujisaki-Okamoto)

Suppose Σ\Sigma is a CPA-secure PKE scheme with unique randomness. Then construction 14.4.3 is CCA-secure in the random oracle model. From claim 14.2.2 it suffices to show that the scheme is CCA-secure with respect to a single encryption.

In other words, if:

Lpk-cpa-real\lib{pk-cpa-real}
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
cpa.pk()\cpapk(\,):
return PK\pk
cpa.enc(M)\cpaenc(\ptxt):
CΣ.Enc(PK)\ctxt \gets \Sigma.\Enc(\pk)
return C\ctxt
\indist
Lpk-cpa-rand\lib{pk-cpa-rand}
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
cpa.pk()\cpapk(\,):
return PK\pk
cpa.enc(M)\cpaenc(\ptxt):
CΣ.C(M)\ctxt \gets \Sigma.\C(|\ptxt|)
return C\ctxt

then:

Lpk-1cca-real+ro\lib{pk-1cca-real+ro}
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
1cca.pk()\ccaonepk(\,):
return PK\pk
1cca.enc(M)\ccaoneenc(\ptxt):
if C\ctxt^* undefined:
// C:=Enc(PK,M)\ctxt^* := \Enc(\pk,\ptxt)
S{0,1}λS \gets \bits^\secpar
R:=H(MS)R := \ro(\ptxt \| S)
C:=Σ.Enc(PK,MS;R)\ctxt^* := \Sigma.\Enc(\pk, \ptxt \| S; R)
return C\ctxt^*
1cca.dec(C)\ccaonedec(\ctxt):
// return Dec(SK,C)\Dec(\sk,\ctxt)
MS:=Σ.Dec(SK,C)\ptxt \| S := \Sigma.\Dec(\sk,\ctxt)
R:=H(MS)R := \ro(\ptxt \| S)
if CΣ.Enc(PK,MS;R)\ctxt \ne \Sigma.\Enc(\pk,\ptxt\|S;R):
return err\myerr
return M\ptxt
H(A)\ro(A):
if H[A]\rotable[A] undefined: H[A]{0,1}λ\rotable[A] \gets \bits^\secpar
return H[A]\rotable[A]
\indist
Lpk-1cca-rand+ro\lib{pk-1cca-rand+ro}
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
1cca.pk()\ccaonepk(\,):
return PK\pk
1cca.enc(M)\ccaoneenc(\ptxt):
if C\ctxt^* undefined:
CΣ.C(λ)\ctxt^* \gets \Sigma.\C(\secpar)
M:=M\ptxt^* := \ptxt
return C\ctxt^*
1cca.dec(C)\ccaonedec(\ctxt):
if C==C\ctxt == \ctxt^*: return M\ptxt^*
// return Dec(SK,C)\Dec(\sk,\ctxt)
MS:=Σ.Dec(SK,C)\ptxt \| S := \Sigma.\Dec(\sk,\ctxt)
R:=H(MS)R := \ro(\ptxt \| S)
if CΣ.Enc(PK,MS;R)\ctxt \ne \Sigma.\Enc(\pk,\ptxt\|S;R):
return err\myerr
return M\ptxt
H(A)\ro(A):
if H[A]\rotable[A] undefined: H[A]{0,1}λ\rotable[A] \gets \bits^\secpar
return H[A]\rotable[A]
Proof:

One important idea in the proof is that an adversary cannot create a valid ciphertext if they have not already made the expected call to the random oracle H(MS)\ro(\ptxt\|S). We formalize the idea as follows:

If Enc\Enc has unique randomness then the following algorithm returns true\mytrue with probability at most 1/2λ1/2^\secpar:

guess(PK,X,C)\subname{guess}(\pk, X, \ctxt):
// C:=Enc(PK,X)\ctxt^* := \Enc(\pk,X):
R{0,1}λR \gets \bits^\secpar
C:=Enc(PK,X;R)\ctxt^* := \Enc(\pk,X; R)
return C==C\ctxt == \ctxt^*

The subroutine generates an encryption of XX and returns true\mytrue if the caller successfully predicted the resulting ciphertext. The encryption randomness RR is playing the role of a random oracle output that has not yet been sampled/observed. There are 2λ2^\secpar choices of RR, and since Enc\Enc has unique randomness, each choice of RR leads to a distinct outcome C\ctxt^*. Since the caller's “guess” C\ctxt is fixed before C\ctxt^* is chosen, uniformly among 2λ2^\secpar possibilities, the algorithm returns true\mytrue with probability at most 1/2λ1/2^\secpar. (It may also be the case that C\ctxt is not one of the 2λ2^\secpar possible ciphertexts, in which case the probability is zero.)

The formal details of the proof follow.

Hybrid Sequence:
The starting point of the proof is Lpk-1cca-real+ro\lib{pk-1cca-real+ro}.
We can inline the calls to H\ro made in 1cca.enc\ccaoneenc and 1cca.dec\ccaonedec. We can also remember the decryption of the challenge ciphertext C\ctxt^*, as D[C]\mathcal{D}[\ctxt^*], so that 1cca.dec\ccaonedec does not need to recompute it. The reason we introduce a dictionary D[]\mathcal{D}[\cdot], even though the library assigns only one position in it, is because later hybrids will use more of it.
Suppose that in some call to 1cca.dec(C)\ccaonedec(\ctxt), we see that H[MS]\rotable[\ptxt\|S] is undefined; the adversary has not called the random oracle on this input. The library will return an error unless the adversary has somehow successfully anticipated the result of Σ.Enc\Sigma.\Enc, with fresh randomness H[MS]\rotable[\ptxt\|S]. Following the reasoning described earlier, such a prediction is successful only with negligible probability at most 1/2λ1/2^\secpar, when Σ\Sigma has unique randomness. It makes a negligible difference to simply always return an error in this case.
Now 1cca.dec()\ccaonedec() returns an error unless the ciphertext has the form Enc(PK,X;H(X))\Enc(\pk,X; \ro(X)), and the adversary has already called H(X)\ro(X). So instead of decrypting ciphertexts the usual way in 1cca.dec()\ccaonedec(), we can compute the associated ciphertext at the time H(X)\ro(X) is called, and store its decryption for later use in 1cca.dec()\ccaonedec(). The change has no effect on the calling program.
Modify 1cca.enc()\ccaoneenc() so that, instead of using H(MS)\ro(\ptxt\|S^*) as randomness for Σ.Enc\Sigma.\Enc, it uses a freshly sampled value RR unrelated to the random oracle. This changes the library's overall behavior only in the bad event that the adversary also queries H(MS)\ro(\ptxt\|S^*). We can mark the change with a bad event, and later argue that it has negligible probability.
Now 1cca.enc()\ccaoneenc() uses randomness for Σ.Enc\Sigma.\Enc that is used for nothing else. This is exactly equivalent to calling Σ.Enc()\Sigma.\Enc() the usual way (i.e., as a randomized algorithm, without externally fixing its randomness). Furthermore, the secret key of Σ\Sigma is no longer used anywhere in the library. Hence, we can apply the CPA security of Σ\Sigma to replace ciphertext C\ctxt^* with a uniformly chosen one. The three-hop maneuver is not shown.
Now SS^* in 1cca.enc()\ccaoneenc() is used only to trigger the bad event, and does not affect what the adversary sees. We can therefore defer the choice of SS^* to the end of time.
Finally, we can undo a previous change, moving decryption logic from H()\ro() back to 1cca.dec()\ccaonedec(). Then the only value in D[]\mathcal{D}[\cdot] that is used is D[C]\mathcal{D}[\ctxt^*], which we rename simply to M\ptxt^*. As a result, we obtain Lpk-1cca-rand+ro\lib{pk-1cca-rand+ro}, plus some end-of-time logic relating to a bad event.
Lpk-1cca-real+ro\lib{pk-1cca-real+ro}
(PK,SK):=(\pk,\sk) := {}
Σ.KeyGen()\Sigma.\KeyGen()
Σ.KeyGen\Sigma.\KeyGen
Σ.KeyGen()\Sigma.\KeyGen()
1cca.pk\ccaonepk( ):
return PK\pk
1cca.enc\ccaoneenc(M\ptxt):
if C\ctxt^* undefined:
// C:=Enc(PK,M)\ctxt^* := \Enc(\pk,\ptxt)
S{0,1}λS^* \gets \bits^\secpar
RR
:={}:= {}
H(MS)\ro(\ptxt \| S^*)
H[MS]\rotable[\ptxt \| S^*]
{0,1}λ{}\gets \bits^\secpar
C\ctxt^*
:=Σ.Enc(PK,MS;R){}:= \Sigma.\Enc(\pk, \ptxt \| S^*; R)
Σ.C(M+λ){}\gets \Sigma.\C\bigr( |\ptxt| + \secpar \bigr)
return C\ctxt^*
1cca.dec\ccaonedec(C\ctxt):
// return
Dec(SK,C)\Dec(\sk,\ctxt)
Dec(C)\Dec(\ctxt):
MS:=Σ.Dec(SK,C)\ptxt \| S := \Sigma.\Dec(\sk,\ctxt)
R:=H(MS)R := \ro(\ptxt \| S)
if CΣ.Enc(PK,MS;\ctxt \ne \Sigma.\Enc(\pk,\ptxt\|S;
R)R):
H[MS])\rotable[\ptxt\|S]):
R)R):
return err\myerr
return M\ptxt
H\ro(AA):
if H[A]\rotable[A] undefined:
H[A]{0,1}λ\rotable[A] \gets \bits^\secpar
return H[A]\rotable[A]

We complete the proof by arguing that the bad event has negligible probability. If the adversary makes qq queries to the random oracle, then at the end of time A\mathcal{A} contains at most qq values, and the bad event happens with probability at most q/2λq/2^\secpar, which is negligible.

Real-world Impact: Because the Fujisaki-Okamoto construction adds CCA security to a PKE with almost no overhead, it is used in many standard (and candidate standard) PKE algorithms. The US National Institute of Standards & Technology recently held a competition to standardize the next generation of public-key encryption schemes, holding the first round of submissions in 2017. Out of the forty-six PKE schemes proposed, twenty-five used the Fujisaki-Okamoto technique to achieve CCA security. All four schemes that advanced to the final round of the selection process use Fujisaki-Okamoto or similar variant.

14.5. Hybrid encryption

Public-key cryptography is much, much slower than symmetric-key cryptography. As a simple demonstration, one invocation of the AES block cipher requires only a few CPU cycles, but encrypting in a PKE scheme can take millions. In this section we explore a clever way to get the best of both worlds: the features of PKE, with cost as close as possible to SKE.

Suppose Alice has published her public key PK\pk, and Bob wants to send her a large file. Using PKE directly on a large file would be incredibly expensive. Instead, Bob can do the following:

  • Sample a fresh key K\key for a symmetric-key encryption scheme.

  • Encrypt K\key under PK\pk, using PKE, and send it to Alice. Although PKE encryption is slow, we are encrypting only a small value K\key.

  • Encrypt the large file under K\key, using SKE, and send it to Alice. SKE encryption is fast for this large file.

When Alice receives this data, she can decrypt the PKE ciphertext to learn K\key, then decrypt the SKE ciphertext with K\key to obtain the large file. The overall functionality is the same as PKE: Bob can encrypt data to Alice, knowing only her public key.

This method of public-key encryption is called hybrid encryption, where “hybrid” in this context means that the scheme consists of a combination of PKE and SKE.

Construction 14.5.1 (Hybrid encryption)

Let Σpke\Sigma_{\text{pke}} be a PKE scheme and Σske\Sigma_{\text{ske}} be a SKE scheme, such that Σske.KΣpke.M\Sigma_{\text{ske}}.\K \subseteq \Sigma_{\text{pke}}.\M (i.e., it is possible for Σpke\Sigma_{\text{pke}} to encrypt keys from Σske\Sigma_{\text{ske}}). Then hybrid encryption is defined by the following algorithms:

K=Σpke.KM=Σske.MC=Σpke.C×Σske.CKeyGen=Σpke.KeyGen\begin{aligned} \K &= \Sigma_{\text{pke}}.\K \\ \M &= \Sigma_{\text{ske}}.\M \\ \C &= \Sigma_{\text{pke}}.\C \times \Sigma_{\text{ske}}.\C \\ \KeyGen &= \Sigma_{\text{pke}}.\KeyGen \end{aligned}
Enc(PK,M)\Enc(\pk,\ptxt):
KΣske.K\key \gets \Sigma_{\text{ske}}.\K
Cpke:=Σpke.Enc(PK,K)\ctxt_{\text{pke}} := \Sigma_{\text{pke}}.\Enc(\pk,\key)
Cske:=Σske.Enc(K,M)\ctxt_{\text{ske}} := \Sigma_{\text{ske}}.\Enc(\key,\ptxt)
return (Cpke,Cske)(\ctxt_{\text{pke}}, \ctxt_{\text{ske}})
Dec(SK,(Cpke,Cske))\Dec(\sk,(\ctxt_{\text{pke}},\ctxt_{\text{ske}})):
K:=Σpke.Dec(SK,Cpke)\key := \Sigma_{\text{pke}}.\Dec(\sk,\ctxt_{\text{pke}})
if K==err\key == \myerr: return err\myerr
return Σske.Dec(K,Cske)\Sigma_{\text{ske}}.\Dec(\key,\ctxt_{\text{ske}})

The value K\key chosen in Enc\Enc is called the ephemeral key.

Each ephemeral key is used to encrypt just a single plaintext, and therefore the symmetric-key scheme Σske\Sigma_{\text{ske}} only needs to have one-time secrecy for the overall hybrid scheme to have CPA security.

Claim 14.5.2 (Security of hybrid encryption)

If Σpke\Sigma_{\text{pke}} is a CPA-secure PKE and Σske\Sigma_{\text{ske}} is a one-time secret SKE, then hybrid encryption (construction 14.5.1) is CPA-secure.

Proof:

The proof is an easy consequence of the definitions.

Hybrid Sequence:
Starting with Lpk-cpa-real\lib{pk-cpa-real},
we can immediately apply the CPA-security of Σpke\Sigma_{\text{pke}}. The simple three-hop maneuver is not shown.
With the ephemeral key K\key no longer used except to encrypt M\ptxt, we can apply the one-time secrecy property. Again, the three-hop maneuver is not shown, and the result is Lpk-cpa-rand\lib{pk-cpa-rand}, completing the proof.
Lpk-cpa-real\lib{pk-cpa-real}
(PK,SK)Σpke.KeyGen(\pk,\sk) \gets \Sigma_{\text{pke}}.\KeyGen
cpa.pk\cpapk( ):
return PK\pk
cpa.enc\cpaenc(M\ptxt):
// Σhyb.Enc\Sigma_{hyb}.\Enc:
KΣske.K\key \gets \Sigma_{\text{ske}}.\K
Cpke\ctxt_{\text{pke}}
:=Σpke.Enc(PK,K){}:= \Sigma_{\text{pke}}.\Enc(\pk,\key)
Σpke.C{}\gets \Sigma_{\text{pke}}.\C
Cske\ctxt_{\text{ske}}
:=Σske.Enc(K,M){}:= \Sigma_{\text{ske}}.\Enc(\key,\ptxt)
Σske.C(M){}\gets \Sigma_{\text{ske}}.\C( |\ptxt| )
return (Cpke,Cske)(\ctxt_{\text{pke}}, \ctxt_{\text{ske}})

CCA Security: The situation of CCA security for hybrid encryption is more subtle. Our usual way of using the real-or-random paradigm to define security doesn't quite work, in the sense that even if both the underlying PKE and SKE are (real-or-random) CCA-secure, the resulting hybrid scheme may not be.

Claim 14.5.3

There exists a (real-or-random) CCA-secure PKE Σpke\Sigma_{\text{pke}} and (real-or-random) CCA-secure SKE Σske\Sigma_{\text{ske}}, such that the resulting hybrid encryption (construction 14.5.1) is not (real-or-random) CCA-secure.

However, if we consider the left-or-right paradigm for CCA security, then the property we hope to be true about hybrid encryption is true. Hybrid encryption achieves (left-or-right) CCA security if both its underlying PKE and SKE do.

Claim 14.5.4

If Σpke\Sigma_{\text{pke}} is a left-or-right CCA-secure PKE and Σske\Sigma_{\text{ske}} is a left-or-right CCA-secure symmetric encryption scheme, then hybrid encryption (construction 14.5.1) is left-or-right CCA-secure.

Proofs of these two claims are left as exercises.

Hybrid encryption is the only example I know of a completely natural encryption scheme for which the distinction between left-or-right and real-or-random security is significant. In every other case, the encryption schemes we care about in practice satisfy both flavors of security.

14.6. Key encapsulation

Because of hybrid encryption, there is rarely any need to use “true” PKE for anything other than encrypting uniformly sampled values. A key encapsulation mechanism (KEM) is a specialized PKE that is capable of only that; it can encrypt only pseudorandom plaintexts. In a PKE we tell the encryption algorithm our choice of plaintext, but in a KEM we let the encryption algorithm itself choose the plaintext. Although this might seem like a strange modification to make to a PKE, the benefit is that a KEM ciphertext can be shorter than a traditional PKE ciphertext.

To differentiate KEMs from traditional PKE, we usually refer to the algorithms of a KEM as encapsulation/decapsulation rather than encryption/decryption.

Definition 14.6.1 (Key encapsulation mechanism)

A key encapsulation mechanism (KEM) consists of the following algorithms:

  • KeyGen\KeyGen: same as in a PKE scheme, a randomized algorithm that takes no inputs and outputs a keypair (PK,SK)(\pk,\sk).

  • Encaps\Encaps: a randomized algorithm that takes only a public key PK\pk as input and returns both a ciphertext CC\ctxt\in \C and plaintext MM\ptxt\in\M.

  • Decaps\Decaps: same as in a PKE scheme, a deterministic algorithm that takes a private key SK\sk and ciphertext CC\ctxt\in\C as input, and returns a plaintext MM\ptxt\in \M (or raises an error).

A KEM is correct if the following process outputs true\mytrue with probability 1:

(PK,SK):=KeyGen()(\pk,\sk) := \KeyGen()
(C,M):=Encaps(PK)(\ctxt, \ptxt) := \Encaps(\pk)
M:=Decaps(SK,C)\ptxt' := \Decaps(\sk,\ctxt)
return M==M\ptxt == \ptxt'

The definitions of CPA and CCA security for KEMs are similar to those for traditional PKE. The adversary's cpa.enc\cpaenc interface now takes no arguments, since a KEM's Encaps\Encaps algorithm does not take a plaintext argument. In addition to requiring that the ciphertext is pseudorandom, the definitions also require that the plaintext is pseudorandom (and independent of the ciphertext).

Definition 14.6.2 (CPA security for key encapsulation)

A KEM Σ\Sigma has security against chosen-plaintext attacks (CPA security) if the following two libraries are indistinguishable:

Lkem-cpa-realΣ\lib{kem-cpa-real}^\Sigma
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
cpa.pk()\cpapk(\,):
return PK\pk
cpa.enc()\cpaenc(\,):
return Σ.Encaps(PK)\Sigma.\Encaps(\pk)
\indist
Lkem-cpa-randΣ\lib{kem-cpa-rand}^\Sigma
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
cpa.pk()\cpapk(\,):
return PK\pk
cpa.enc()\cpaenc(\,):
CΣ.C\ctxt \gets \Sigma.\C
MΣ.M\ptxt \gets \Sigma.\M
return (C,M)(\ctxt, \ptxt)
Definition 14.6.3 (CCA security for key encapsulation)

A KEM Σ\Sigma has security against chosen-ciphertext attacks (CCA security) if the following two libraries are indistinguishable:

Lkem-cca-realΣ\lib{kem-cca-real}^\Sigma
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
cca.pk()\ccapk(\,):
return PK\pk
cca.enc()\ccaenc(\,):
return Σ.Encaps(PK)\Sigma.\Encaps(\pk)
cca.dec(C)\ccadec(\ctxt):
return Σ.Decaps(SK,C)\Sigma.\Decaps(\sk,\ctxt)
\indist
Lkem-cca-randΣ\lib{kem-cca-rand}^\Sigma
(PK,SK):=Σ.KeyGen()(\pk,\sk) :=\Sigma.\KeyGen()
cca.pk()\ccapk(\,):
return PK\pk
cca.enc()\ccaenc(\,):
MΣ.M\ptxt \gets \Sigma.\M
CΣ.C\ctxt \gets \Sigma.\C
D[C]:=M\mathcal{D}[\ctxt] := \ptxt
return (C,M)(\ctxt, \ptxt)
cca.dec(C)\ccadec(\ctxt):
if D[C]\mathcal{D}[\ctxt] defined: return D[C]\mathcal{D}[\ctxt]
return Σ.Decaps(SK,C)\Sigma.\Decaps(\sk,\ctxt)

Hybrid encryption is sometimes called the KEM-DEM paradigm, where DEM (the symmetric-key encryption scheme) stands for data encapsulation mechanism.

14.6.1. One-time vs. many-time

Just like PKE, if a KEM is secure for a single encryption, then it is secure against many encryptions. Hence we have the following results, analogous to the ones in section 14.2. Because KEM encapsulation takes no plaintext argument, these libraries are slightly simpler than their PKE counterparts; the ciphertext and plaintext can be generated at the beginning of time.

Claim 14.6.4 (One-time security for key encapsulation)

Let Σ\Sigma be a KEM scheme. If the following two libraries are indistinguishable, then Σ\Sigma has CPA security:

Lkem-1cpa-realΣ\lib{kem-1cpa-real}^\Sigma
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
(C,M):=Σ.Encaps(PK)(\ctxt^*,\ptxt^*) := \Sigma.\Encaps(\pk)
1cpa.pk()\cpaonepk(\,):
return PK\pk
1cpa.enc()\cpaoneenc(\,):
return (C,M)(\ctxt^*,\ptxt^*)
\indist
Lkem-1cpa-randΣ\lib{kem-1cpa-rand}^\Sigma
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
CΣ.C\ctxt^* \gets \Sigma.\C
MΣ.M\ptxt^* \gets \Sigma.\M
1cpa.pk()\cpaonepk(\,):
return PK\pk
1cpa.enc()\cpaoneenc(\,):
return (C,M)(\ctxt^*, \ptxt^*)

If the following two libraries are indistinguishable, then Σ\Sigma has CCA security:

Lkem-1cca-realΣ\lib{kem-1cca-real}^\Sigma
(PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
(C,M):=Σ.Encaps(PK)(\ctxt^*,\ptxt^*) := \Sigma.\Encaps(\pk)
1cca.pk()\ccaonepk(\,):
return PK\pk
1cca.enc()\ccaoneenc(\,):
return (C,M)(\ctxt^*, \ptxt^*)
1cca.dec(C)\ccaonedec(\ctxt):
return Σ.Decaps(SK,C)\Sigma.\Decaps(\sk,\ctxt)
\indist
Lkem-1cca-randΣ\lib{kem-1cca-rand}^\Sigma
(PK,SK):=Σ.KeyGen()(\pk,\sk) :=\Sigma.\KeyGen()
CΣ.C\ctxt^* \gets \Sigma.\C
MΣ.M\ptxt^* \gets \Sigma.\M
1cca.pk()\ccaonepk(\,):
return PK\pk
1cca.enc()\ccaoneenc(\,):
return (C,M)(\ctxt^*, \ptxt^*)
cca.dec(C)\ccadec(\ctxt):
if C==C\ctxt == \ctxt^*: return M\ptxt^*
return Σ.Decaps(SK,C)\Sigma.\Decaps(\sk,\ctxt)

The proofs follow the same structure as those in section 14.2, and are left as exercises.

14.6.2. El Gamal KEM

One reason for studying KEMs is that their ciphertexts can be smaller than those of a PKE; El Gamal encryption provides a great example. Recall that El Gamal ciphertexts consist of a pair of group elements that have the form (gr,PKrM)(g^r, \pk^r \cdot \ptxt). The security proof argues that PKr\pk^r hides the plaintext, because PKr\pk^r is pseudorandom given PK\pk and grg^r. But if PKr\pk^r is pseudorandom, why not just consider PKr\pk^r to be the plaintext and let grg^r alone be the ciphertext? The result is El Gamal KEM, and its ciphertexts consist of just a single group element.

Construction 14.6.5 (El Gamal KEM)

Let G\G be a cyclic group of order n\nmod with generator gg. Then El Gamal KEM is defined by the following:

KeyGen()\KeyGen(\,):
SKZn\sk \gets \Z_\nmod
PK:=gSK\pk := g^{\sk}
return (PK,SK)(\pk,\sk)
Encaps(PK)\Encaps(\pk):
rZnr \gets \Z_\nmod
C:=gr\ctxt := g^r
M:=PKr\ptxt := \pk^r
return (C,M)(\ctxt, \ptxt)
Decaps(SK,C)\Decaps(\sk,\ctxt):
return CSK\ctxt^{\sk}
Claim 14.6.6 (Security of El Gamal KEM)

El Gamal KEM (construction 14.6.5) is CPA-secure if the DDH assumption holds.

The proof is extremely similar to that of claim 14.3.2, and is left as an exercise.

Exercises

  1. Prove that if a PKE scheme has a deterministic Enc\Enc algorithm, then it cannot have CPA security.

  2. Let Σ\Sigma be a PKE scheme with M={0,1}n\M = \bits^n, and let Σ2\Sigma^2 be defined as follows:

    M={0,1}2nC=(Σ.C)2KeyGen=Σ.KeyGen\begin{aligned} \M &= \bits^{2n} \\ \C &= (\Sigma.\C)^2 \\ \KeyGen &= \Sigma.\KeyGen \end{aligned}
    Enc(PK,M1M2)\Enc(\pk,\ptxt_1 \| \ptxt_2):
    // each Mi\ptxt_i is nn bits
    C1:=Enc(PK,M1)\ctxt_1 := \Enc(\pk,\ptxt_1)
    C2:=Enc(PK,M2)\ctxt_2 := \Enc(\pk,\ptxt_2)
    return (C1,C2)(\ctxt_1, \ctxt_2)
    Dec(SK,(C1,C2))\Dec\bigl( \sk, (\ctxt_1,\ctxt_2) \bigr):
    M1:=Dec(SK,C1)\ptxt_1 := \Dec(\sk,\ctxt_1)
    M2:=Dec(SK,C2)\ptxt_2 := \Dec(\sk,\ctxt_2)
    return M1M2\ptxt_1\|\ptxt_2
    1. Prove that Σ2\Sigma^2 is CPA-secure if Σ\Sigma is.

    2. Prove that Σ2\Sigma^2 is not CCA-secure (even if Σ\Sigma is).

  3. h Let Σ\Sigma be a CPA-secure symmetric-key encryption scheme, and suppose it has an additional randomized algorithm ReRandomize\textsf{ReRandomize} such that the following libraries are indistinguishable:

    Lrerand-realΣ\lib{rerand-real}^\Sigma
    rerand(K,C)\subname{rerand}(\key,\ctxt):
    return Σ.ReRandomize(C)\Sigma.\textsf{ReRandomize}(\ctxt)
    \indist
    Lrerand-fakeΣ\lib{rerand-fake}^\Sigma
    rerand(K,C)\subname{rerand}(\key,\ctxt):
    M:=Σ.Dec(K,C)\ptxt := \Sigma.\Dec(\key,\ctxt)
    return Σ.Enc(K,M)\Sigma.\Enc(\key,\ptxt)

    The idea behind ReRandomize\textsf{ReRandomize} is that when its input is an encryption of M\ptxt, then its output is also an encryption of M\ptxt. Not only do the input and output ciphertexts encrypt the same thing, the output ciphertext is distributed just like a fresh re-encryption of M\ptxt. And ReRandomize\textsf{ReRandomize} is able to do this all without knowing M\ptxt or the key K\key.

    Describe how to use this Σ\Sigma to construct a PKE, and prove that your construction is CPA-secure.

    From exercise 14.2 it is enough to construct a PKE whose plaintext space is M={0,1}\M = \{\bit0,\bit1\}. The public key in your PKE scheme should include C0=Enc(SK,0)\ctxt_0 = \Enc(\sk,\bit0) and C1=Enc(SK,1)\ctxt_1 = \Enc(\sk,\bit1).

  4. Prove claim 14.2.2 (one-time CCA security implies many-time CCA security).

  5. Below are parameters for El Gamal encryption (prime pp, generator gg, and a user's private key) and an El Gamal ciphertext (C1,C2)(C_1, C_2).

    p=820352377101055884914460791538599368437918206431245996677118212255669324388510923534966153248485697321865777338727602021579688760726401763871773605863599043632214034707416231834019537149866575202482386776278066585668125927276425009779822325780293591260030911095663277044721309804734814551532256818493g=2SK=306033152423344432110873337270518746079412713693849345056658514895080413997457075906501550362842203171386314578226690305048842904885022025641077841375072635002329298772202663102727543201221833570076490977067539007385463977153703095726422723750680937329958625495800630322994618237566748102114046656069C1=462054157245413467558826072791385044036879483117702714989843900229935194869085734295713385708063663647004475374447278157812605079099785722745766123633236262309194634963603597800630964317028376563068090101355339547855197628919380823904604547121058779885144513823662739084822466772834215530613199671852C2=363997211863183238889564744554761007626218766957232278199695792262726404818908096009225062142352538150744210033702637001010465153129696735055444199306708284949138506063666875862705763978705223762919549775254323612712554068732510778676226769703774955995845877873850997054909183025915660486248217201296\begin{aligned} p &= \longnum{820352377101055884914460791538599368437918206431245996677118212255669324388510923534966153248485697321865777338727602021579688760726401763871773605863599043632214034707416231834019537149866575202482386776278066585668125927276425009779822325780293591260030911095663277044721309804734814551532256818493} \\ g &= 2 \\ \sk &= \longnum{306033152423344432110873337270518746079412713693849345056658514895080413997457075906501550362842203171386314578226690305048842904885022025641077841375072635002329298772202663102727543201221833570076490977067539007385463977153703095726422723750680937329958625495800630322994618237566748102114046656069} \\ C_1 &= \longnum{462054157245413467558826072791385044036879483117702714989843900229935194869085734295713385708063663647004475374447278157812605079099785722745766123633236262309194634963603597800630964317028376563068090101355339547855197628919380823904604547121058779885144513823662739084822466772834215530613199671852} \\ C_2 &= \longnum{363997211863183238889564744554761007626218766957232278199695792262726404818908096009225062142352538150744210033702637001010465153129696735055444199306708284949138506063666875862705763978705223762919549775254323612712554068732510778676226769703774955995845877873850997054909183025915660486248217201296}\end{aligned}
    1. What is the corresponding public key, and how did you compute it?

    2. What is the result of decrypting the ciphertext, and how did you compute it?

  6. Show that El Gamal is not a CCA-secure PKE.

  7. h Suppose you are given a passively secure key exchange protocol (definition 13.3.3) Σ\Sigma, in which each user sends only one protocol message. Formally describe how to use Σ\Sigma to build a CPA-secure PKE scheme, and prove its security. Assume that the KE protocol generates a key from K={0,1}λ\K = \bits^\secpar.

    Take inspiration from the relationship between DHKE and El Gamal.

  8. h Suppose you are given a CPA-secure PKE scheme Σ\Sigma. Formally describe how to use Σ\Sigma to build a passively secure key exchange protocol (definition 13.3.3), and prove its security.

    The security definition for KE says that the key should be pseudorandom, but it does not require both parties to “contribute” to the key.

  9. Given a plaintext consisting of two group elements, it is possible to encrypt each element with El Gamal, independently (exercise 14.2). This would result in a ciphertext consisting of four group elements. Consider the following variant of El Gamal, which can encrypt two plaintext group elements to a ciphertext of three group elements:

    M=G2C=G3\begin{aligned} \M &= \G^2 \\ \C &= \G^3 \end{aligned}
    KeyGen()\KeyGen(\,):
    SK1Zn\sk_1 \gets \Z_\nmod
    SK2Zn\sk_2 \gets \Z_\nmod
    SK:=(SK1,SK2)\sk := (\sk_1,\sk_2)
    PK:=(gSK1,gSK2)\pk := (g^{\sk_1}, g^{\sk_2})
    return (PK,SK)(\pk,\sk)
    Enc(PK,(M1,M2))\Enc\bigl(\pk, (\ptxt_1, \ptxt_2)\bigr):
    (PK1,PK2):=PK(\pk_1, \pk_2) := \pk
    rZnr \gets \Z_\nmod
    C0:=gr\ctxt_0 := g^r
    C1:=M1(PK1)r\ctxt_1 := \ptxt_1 \cdot (\pk_1)^r
    C2:=M2(PK2)r\ctxt_2 := \ptxt_2 \cdot (\pk_2)^r
    return (C0,C1,C2)(\ctxt_0, \ctxt_1, \ctxt_2)
    Dec(SK,(C0,C1,C2))\Dec\bigl(\sk,(\ctxt_0,\ctxt_1,\ctxt_2)\bigr):
    M1:=C1(C0)SK1\ptxt_1 := \ctxt_1 \cdot (\ctxt_0)^{-\sk_1}
    M2:=C2(C0)SK2\ptxt_2 := \ctxt_2 \cdot (\ctxt_0)^{-\sk_2}
    return (M1,M2)(\ptxt_1, \ptxt_2)

    Prove that this scheme is CPA-secure if the DDH assumption is true in G\G.

  10. The scheme in the previous exercise has a longer public key than standard El Gamal. Suppose we compress the public key by letting SK2=2SK1\sk_2 = 2 \cdot \sk_1, and thus PK2:=(PK1)2\pk_2 := (\pk_1)^2:

    M=G2C=G3\begin{aligned} \M &= \G^2 \\ \C &= \G^3 \end{aligned}
    KeyGen()\KeyGen(\,):
    SKZn\sk \gets \Z_\nmod
    PK:=gSK\pk := g^{\sk}
    return (PK,SK)(\pk,\sk)
    Enc(PK,(M1,M2))\Enc\bigl(\pk, (\ptxt_1, \ptxt_2)\bigr):
    rZnr \gets \Z_\nmod
    C0:=gr\ctxt_0 := g^r
    C1:=M1PKr\ctxt_1 := \ptxt_1 \cdot \hl{\pk}^r
    C2:=M2(PK2)r\ctxt_2 := \ptxt_2 \cdot \hl{(\pk^2)}^r
    return (C0,C1,C2)(\ctxt_0, \ctxt_1, \ctxt_2)
    Dec(SK,(C0,C1,C2))\Dec\bigl(\sk,(\ctxt_0,\ctxt_1,\ctxt_2)\bigr):
    M1:=C1(C0)SK\ptxt_1 := \ctxt_1 \cdot (\ctxt_0)^{-\hl{\sk}}
    M2:=C2(C0)2SK\ptxt_2 := \ctxt_2 \cdot (\ctxt_0)^{-\hl{2 \cdot \sk}}
    return (M1,M2)(\ptxt_1, \ptxt_2)

    Show that this scheme is not CPA-secure.

  11. Suppose you are given an El Gamal ciphertext (C1,C2)(\ctxt_1, \ctxt_2) encrypting M\ptxt. Show how to construct a different ciphertext encrypting the same M\ptxt, even if you don't know M\ptxt or the private key. You can assume that the public key is known.

  12. Suppose you are given two El Gamal ciphertexts: (C1,C2)(\ctxt_1, \ctxt_2) encrypting M\ptxt, and (C1,C2)(\ctxt'_1, \ctxt'_2) encrypting M\ptxt'. Show how to construct a ciphertext encrypting MM\ptxt \cdot \ptxt', even if you don't know M\ptxt or M\ptxt', or the private key. You can assume that the public key is known.

  13. h Describe a randomized algorithm ReRandomize\textsf{ReRandomize} with the following properties. It should take as input an El Gamal public key PK\pk and ciphertext C\ctxt, and output a new ciphertext C\ctxt'. The output C\ctxt' should be distributed identically to the output of Enc(PK,Dec(SK,C))\Enc(\pk,\Dec(\sk,\ctxt)). In other words, the output should be a ciphertext encrypting the same plaintext as C\ctxt, and distributed precisely as a fresh encryption. The ReRandomize\textsf{ReRandomize} algorithm should do all of this without knowing M\ptxt or the El Gamal private key SK\sk.

    Use exercise 14.12 with C\ctxt and a fresh encryption of 1.

  14. Our security proof for Fujisaki-Okamoto (theorem 14.4.5) assumes that the encryption algorithm has unique randomness. However, this assumption is not strictly necessary.

    1. Prove that if Σ\Sigma is a CPA-secure PKE, then the following two libraries are indistinguishable:

      (PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
      getpk()\subname{getpk}(\,):
      return PK\pk
      test(M,C)\subname{test}(\ptxt,\ctxt):
      C:=Σ.Enc(PK,M)\ctxt' := \Sigma.\Enc(\pk,\ptxt)
      return C==C\ctxt' == \ctxt
      \indist
      (PK,SK):=Σ.KeyGen()(\pk,\sk) := \Sigma.\KeyGen()
      getpk()\subname{getpk}(\,):
      return PK\pk
      test(M,C)\subname{test}(\ptxt,\ctxt):
      return false\myfalse
    2. Prove the security of Fujisaki-Okamoto without assuming the unique randomness property.

  15. Below is an attempt to use the Fujisaki-Okamoto technique to construct a KEM, rather than a PKE:

    Encaps(PK)\Encaps^*(\pk):
    S{0,1}λS \gets \bits^\secpar
    C:=Σ.Enc(PK,S;H(S))\ctxt := \Sigma.\Enc(\pk, S; \ro(S))
    return (C,S)(\ctxt, S)
    Decaps(SK,C)\Decaps^*(\sk,\ctxt):
    S:=Σ.Dec(SK,C)S := \Sigma.\Dec(\sk,\ctxt)
    if CΣ.Enc(PK,S;H(S))\ctxt \ne \Sigma.\Enc(\pk,S;\ro(S)):
    return err\myerr
    return SS

    Show that this construction is not a CCA-secure KEM (it's not even CPA-secure!).

  16. Below is another attempt to use the Fujisaki-Okamoto technique to construct a KEM, rather than a PKE. It requires a random oracle H\ro whose outputs have length 2λ2\secpar.

    Encaps(PK)\Encaps^*(\pk):
    S{0,1}λS \gets \bits^\secpar
    MR:=H(S)\ptxt \| R := \ro(S)
    C:=Σ.Enc(PK,S;R)\ctxt := \Sigma.\Enc(\pk, S; R)
    return (C,M)(\ctxt, \ptxt)
    Decaps(SK,C)\Decaps^*(\sk,\ctxt):
    S:=Σ.Dec(SK,C)S := \Sigma.\Dec(\sk,\ctxt)
    MR:=H(S)\ptxt \| R := \ro(S)
    if CΣ.Enc(PK,S;R)\ctxt \ne \Sigma.\Enc(\pk,S;R):
    return err\myerr
    return M\ptxt

    This KEM is more efficient that construction 14.4.3 because it uses Σ.Enc\Sigma.\Enc to encrypt a plaintext of length λ\secpar instead of 2λ2\secpar.

    1. Prove that this construction is a CCA-secure KEM in the random oracle model, if Σ\Sigma is CPA-secure.

    2. Even though the end result of this construction is a KEM, it requires the underlying scheme Σ\Sigma to be a PKE, not a KEM. What is the difficulty of applying the Fujisaki-Okamoto technique to an underlying KEM?

  17. \star Construct a PKE and SKE which both have (real-or-random) CCA security, but whose combination as a hybrid encryption scheme does not have (real-or-random) CCA security (claim 14.5.3).

    1. Given a (real-or-random) CCA-secure PKE, construct a new one that is also CCA-secure, and that has the property that a uniformly chosen ciphertext will raise a decryption error with high probability. Prove that your new PKE is CCA-secure.

    2. Given a (real-or-random) CCA-secure SKE, construct a new one that is also CCA-secure, but in which the Dec\Dec algorithm never raises an error. Prove that your new SKE is CCA-secure.

    3. Show that the combination of these two new schemes as a hybrid encryption scheme does not have (real-or-random) CCA security.

  18. h\star The previous exercise considered hybrid encryption where the underlying SKE never has decryption error. Suppose we instead insist that the SKE is AE-secure. Can you still construct a (real-or-random) CCA-secure PKE and (real-or-random) AE-secure SKE whose composition as a hybrid scheme is not (real-or-random) CCA-secure?

    A PKE scheme can be CCA-secure and also have the property that a uniformly chosen ciphertext decrypts to a known, fixed value, like 0λ\bit0^\secpar, with high probability.

  19. Prove that hybrid encryption is (left-or-right) CCA-secure, if its underlying PKE and SKE both are (claim 14.5.4).

  20. Formally prove claim 14.6.4 (one-time security implies many-time security, for a KEM).

  21. Prove claim 14.6.6 (security of El Gamal KEM).

  22. Formally describe a variant of hybrid encryption (construction 14.5.1) that uses a KEM rather than PKE to encrypt the ephemeral symmetric key. Formally prove its CPA security, using the CPA security of the underlying KEM.

  23. Any PKE scheme can be converted into a KEM, by simply using the PKE scheme to encrypt a uniformly chosen plaintext. Formally describe this KEM construction, and prove that it is CPA-secure if the underlying PKE scheme is CPA-secure.

  24. Consider a variant of El Gamal KEM in which the plaintext is not PKr\pk^r but H(PKr)\ro(\pk^r). Prove that this variant is a secure KEM in the random oracle model, assuming the CDH assumption (defined in exercise 13.8).

  25. Let H\ro be a random oracle, let G\G be a cyclic group of order n\nmod, and let g1g_1 and g2g_2 be two different generators. The Kurosawa-Desmedt KEM is defined as follows:

    KeyGen()\KeyGen(\,):
    a1Zna_1 \gets \Z_\nmod
    a2Zna_2 \gets \Z_\nmod
    b1Znb_1 \gets \Z_\nmod
    b2Znb_2 \gets \Z_\nmod
    A:=g1a1g2a2A := g_1^{a_1} g_2^{a_2}
    B:=g1b1g2b2B := g_1^{b_1} g_2^{b_2}
    SK:=(a1,a2,b1,b2)\sk := (a_1,a_2,b_1,b_2)
    PK:=(A,B)\pk := (A,B)
    return (PK,SK)(\pk,\sk)
    Encaps(PK)\Encaps(\pk):
    (A,B):=PK(A,B) := \pk
    rZnr \gets \Z_\nmod
    C1:=g1rC_1 := g_1^r
    C2:=g2rC_2 := g_2^r
    h:=H(C1,C2)h := \ro(C_1, C_2)
    K:=(AhB)r\key := (A^h B)^r
    return ((C1,C2),K)\bigl( (C_1,C_2), \key \bigr)
    Decaps(SK,(C1,C2))\Decaps(\sk, (C_1,C_2)):
    (a1,a2,b1,b2):=SK(a_1,a_2,b_1,b_2) := \sk
    h:=H(C1,C2)h := \ro(C_1, C_2)
    K:=C1ha1+b1C2ha2+b2\key := C_1^{h \cdot a_1 + b_1} C_2^{h \cdot a_2 + b_2}
    1. Show that the KEM satisfies correctness.

    2. h\star Show that the KEM is not CCA-secure. You can assume that the order n\nmod of the cyclic group is prime.

    Let C=(C1,C2)\ctxt = (C_1, C_2) be an arbitrary ciphertext. Suppose an adversary chooses exponents xx and yy, and defines the new ciphertexts Cx:=(C1x,C2x)\ctxt_x := (C_1^x, C_2^x) and Cy:=(C1y,C2y)\ctxt_y := (C_1^y, C_2^y). Show how the decapsulations of Cx\ctxt_x and Cy\ctxt_y can be used to predict the decapsulation of C\ctxt.

  26. Prove that Σ\Sigma is a CPA-secure KEM if and only if the following is a passively secure KE protocol:

    alice()\subname{alice}(\,):
    (PK,SK):=Σ.KeyGen(\pk,\sk) := \Sigma.\KeyGen
    send PK\pk
    recv C\ctxt
    return Σ.Decaps(SK,C)\Sigma.\Decaps(\sk,\ctxt)
    \rightleftharpoons
    bob()\subname{bob}(\,):
    recv PK\pk
    (C,M):=Σ.Encaps(PK)(\ctxt, \ptxt) := \Sigma.\Encaps(\pk)
    send C\ctxt
    return M\ptxt

Chapter Notes

Public-key encryption was first conceived in 1970 by James Ellis, who was employed at British GCHQ at the time [97]. As such, his involvement in the history of public-key cryptography remained classified until 1997. He called his idea “non-secret encryption,” but was not able to propose a plausibly secure mechanism. Three years later another GCHQ employee, Clifford Cocks, proposed a non-secret encryption scheme which is identical to the well-known RSA scheme (chapter 15).

In 1974, Ralph Merkle proposed an asymmetric key exchange protocol, in a proposal for an undergraduate class project [159]. His contributions to the history of public-key cryptography were not recognized until around a decade later. Diffie and Hellman were the first to receive public recognition for the invention of public-key cryptography, in 1976 [83]. Bellare, Desai, Pointcheval, and Rogaway [16] study a variety of security definitions for public-key encryption, showing separations, equivalences, and implications among them.

El Gamal encryption is named after its creator, Taher El Gamal [96]. A security proof for El Gamal, based on the DDH assumption, was first given by Tsiounis and Yung [211].

Unsurprisingly, the Fujisaki-Okamoto construction is named for its creators, Fujisaki and Okamoto [104]. See Hofheinz, Hövelmanns, and Kiltz [122] for a comprehensive analysis of the scheme and its many variants.

Hybrid encryption is a natural way to combine public-key and symmetric-key encryption schemes. Its security was first formalized by Cramer and Shoup [76].

The KEM in exercise 14.25 was proposed by Kurosawa and Desmedt [144]. The attack against its CCA security was first shown by Choi, Herranz, Hofheinz, Hwang, Kiltz, Lee, and Yung [65].

Key encapsulation schemes were first defined by Shoup [203].

  1. Previous Chapter13. Key Exchange
  2. Next Chapter15. RSA