Documentation

Complexity.Crypto.Computational.Encryption.CCA

Chosen-ciphertext security for public-key encryption (1CCA / IND-CCA2) #

This module defines the single-challenge adaptive chosen-ciphertext security experiment (1CCA, also called IND-CCA2) for public-key encryption over an arbitrary message type Msg and decryption output type Out, following Boneh and Shoup, Section 12.1, Attack Game 12.1 and Definition 12.2, printed pp. 467–469.

Source Statements ([BS23], Section 12.1, printed pp. 467–469) #

Verbatim from [BS23], Section 12.1 (printed pp. 467–468):

Attack Game 12.1 (CCA security). For a given public-key encryption scheme $\mathcal{E} = (G, E, D)$, defined over $(\mathcal{M}, \mathcal{C})$, and for a given adversary $\mathcal{A}$, we define two experiments. Experiment $b$ ($b = 0, 1$):

  • The challenger computes $(pk, sk) \xleftarrow{R} G()$ and sends $pk$ to the adversary.
  • $\mathcal{A}$ then makes a series of queries to the challenger. Each query can be one of two types:
    • Encryption query: for $i = 1, 2, \ldots$, the $i$th encryption query consists of a pair of messages $(m_{i0}, m_{i1}) \in \mathcal{M}^2$, of the same length. The challenger computes $c_i \xleftarrow{R} E(pk, m_{ib})$ and sends $c_i$ to $\mathcal{A}$.
    • Decryption query: for $j = 1, 2, \ldots$, the $j$th decryption query consists of a ciphertext $\hat{c}_j \in \mathcal{C}$ that is not among the responses to the previous encryption queries, i.e., $$\hat{c}_j \notin \{c_1, c_2, \ldots\}.$$ The challenger computes $\hat{m}_j \leftarrow D(sk, \hat{c}_j)$, and sends $\hat{m}_j$ to $\mathcal{A}$.
  • At the end of the game, the adversary outputs a bit $\hat{b} \in \{0, 1\}$.

Let $W_b$ be the event that $\mathcal{A}$ outputs $1$ in Experiment $b$ and define $\mathcal{A}$'s advantage with respect to $\mathcal{E}$ as $$\text{CCAadv}[\mathcal{A}, \mathcal{E}] := |\Pr[W_0] - \Pr[W_1]|.$$

Definition 12.1 (CCA Security). A public-key encryption scheme $\mathcal{E}$ is called semantically secure against a chosen ciphertext attack, or simply CCA secure, if for all efficient adversaries $\mathcal{A}$, the value $\text{CCAadv}[\mathcal{A}, \mathcal{E}]$ is negligible.

Just as we did in the symmetric-key setting, we can consider a restricted attack game in which the adversary makes only a single encryption query:

Definition 12.2 (1CCA security). In Attack Game 12.1, if the adversary $\mathcal{A}$ is restricted to making a single encryption query, we denote its advantage by $\text{1CCAadv}[\mathcal{A}, \mathcal{E}]$. A public-key encryption scheme $\mathcal{E}$ is one-time semantically secure against chosen ciphertext attack, or simply, 1CCA secure, if for all efficient adversaries $\mathcal{A}$, the value $\text{1CCAadv}[\mathcal{A}, \mathcal{E}]$ is negligible.

And the two-phase decomposition of the 1CCA experiment (printed pp. 468–469):

Initialization phase: the challenger generates $(pk, sk) \xleftarrow{R} G()$ and sends $pk$ to the adversary. Phase 1: the adversary submits a series of decryption queries to the challenger; each such query is a ciphertext $\hat{c} \in \mathcal{C}$, to which the challenger responds with $\hat{m} \leftarrow D(sk, \hat{c})$. Encryption query: the adversary submits a single encryption query $(m_0, m_1)$ to the challenger; in Experiment $b$ (where $b = 0, 1$), the challenger responds with $c \xleftarrow{R} E(pk, m_b)$. Phase 2: the adversary again submits a series of decryption queries to the challenger; each such query is a ciphertext $\hat{c} \in \mathcal{C}$, subject to the restriction that $\hat{c} \ne c$, to which the challenger responds with $\hat{m} \leftarrow D(sk, \hat{c})$. Finish: at the end of the game, the adversary outputs a bit $\hat{b} \in \{0, 1\}$.

Scope and Specializations #

Main definitions #

Main results #

References #

A single-challenge adaptive chosen-ciphertext (1CCA, [BS23], Section 12.1, Attack Game 12.1 and Definition 12.2, printed pp. 467–469) adversary over message space Msg. Both stages have access to the single-channel decryption oracle (Operation = Unit).

Instances For
    structure Cslib.Crypto.Encryption.CCA2AdversaryOf.IsPPT {Msg : Type} (encMsg : Msg ↪ List Bool) (adversary : CCA2AdversaryOf Msg) :

    Uniform strict oracle PPT admissibility of both stages of a CCA2AdversaryOf Msg with respect to message encoding encMsg.

    Instances For

      Per-stage decryption-query bound (Q₁ n, Q₂ n) for a CCA2AdversaryOf Msg.

      Instances For
        theorem Cslib.Crypto.Encryption.CCA2AdversaryOf.IsPPT.query_bounds {Msg : Type} {encMsg : Msg ↪ List Bool} {adversary : CCA2AdversaryOf Msg} (hA : IsPPT encMsg adversary) :
        ∃ (c₁ : ℕ) (d₁ : ℕ) (c₂ : ℕ) (d₂ : ℕ) (cs : ℕ) (ds : ℕ), (∀ (n : ℕ) (pk : List Bool), ProbOracleComp.IsQueryBounded (adversary.choose n pk) (c₁ * (n + pk.length + 2) ^ d₁)) ∧ (∀ (n : ℕ) (state ct : List Bool), ProbOracleComp.IsQueryBounded (adversary.guess n state ct) (c₂ * (n + state.length + ct.length + 2) ^ d₂)) ∧ ∀ (n : ℕ) (pk : List Bool) (State : Type) (oracle : Unit × List Bool → StateT State PMF (List Bool)) (s s' : State) (choice : (Msg × Msg) × List Bool), (choice, s') ∈ ((OracleComp.interpret (ProbOracleComp.handler (fun (m : ℕ) => StateT.lift (ProbComp.unifOracle m)) oracle) (adversary.choose n pk)).run s).support → choice.2.length ≤ cs * (n + pk.length + 2) ^ ds

        Every strict oracle PPT CCA2AdversaryOf Msg has polynomial bounds on its Phase 1 queries, Phase 2 queries, and saved-state length in terms of (n, pk.length, ct.length).

        @[reducible, inline]

        Single-bit 1CCA adversary (Msg = Bool).

        Instances For
          @[reducible, inline]

          Native uniform strict oracle PPT admissibility for a bit 1CCA adversary.

          Instances For
            @[reducible, inline]

            Bit-string 1CCA adversary (Msg = List Bool).

            Instances For
              @[reducible, inline]

              Native uniform strict oracle PPT admissibility for a bit-string 1CCA adversary.

              Instances For
                def Cslib.Crypto.Encryption.cca2Phase1Oracle {Out : Type} (encOut : Out ↪ List Bool) (decrypt : ℕ → List Bool → List Bool → Option Out) (n : ℕ) (sk : List Bool) (request : Unit × List Bool) :

                Phase 1 decryption oracle ([BS23], Section 12.1, Attack Game 12.1 and Definition 12.2, printed pp. 467–468): answer every decryption query request.2 with encOption encOut (decrypt n sk request.2).

                Instances For
                  def Cslib.Crypto.Encryption.cca2Phase2Oracle {Out : Type} (encOut : Out ↪ List Bool) (decrypt : ℕ → List Bool → List Bool → Option Out) (n : ℕ) (sk ct : List Bool) (request : Unit × List Bool) :

                  Phase 2 decryption oracle ([BS23], Section 12.1, Attack Game 12.1 and Definition 12.2, printed pp. 467–468): reject the challenge ciphertext (request.2 == ct) with [] (encOption encOut none), and answer all other queries request.2 ≠ ct with encOption encOut (decrypt n sk request.2). Since the adversary receives ct as input to guess and can simulate the constant [] reply on ct itself, returning [] on ct is equivalent to forbidding the query ĉ = c (matching SymmetricCipher.ccaOracle in Complexity/Crypto/Computational/Encryption/Authenticated.lean).

                  Instances For
                    noncomputable def Cslib.Crypto.Encryption.cca2GameOn {Msg Out : Type} (valid : ℕ → List Bool → Msg → Msg → Bool) (encOut : Out ↪ List Bool) (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encrypt : ℕ → List Bool → Msg → ProbComp (List Bool)) (decrypt : ℕ → List Bool → List Bool → Option Out) (adversary : CCA2AdversaryOf Msg) (bit : Bool) (n : ℕ) :

                    Single-challenge 1CCA experiment ([BS23], Section 12.1, Attack Game 12.1 and Definition 12.2, printed pp. 467–468) with challenge-pair admissibility predicate valid : ℕ → List Bool → Msg → Msg → Bool: sample (pk, sk) ← keyGen n, run Phase 1 (choose) against cca2Phase1Oracle, check valid n pk m₀ m₁ (returning false in both experiments when invalid), encrypt if bit then m₁ else m₀ to obtain ct, and run Phase 2 (guess) against cca2Phase2Oracle rejecting ct.

                    Instances For
                      @[reducible, inline]
                      noncomputable abbrev Cslib.Crypto.Encryption.cca2Game {Msg Out : Type} (encOut : Out ↪ List Bool) (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encrypt : ℕ → List Bool → Msg → ProbComp (List Bool)) (decrypt : ℕ → List Bool → List Bool → Option Out) (adversary : CCA2AdversaryOf Msg) (bit : Bool) (n : ℕ) :

                      Unconditional single-challenge 1CCA experiment (valid := fun _ _ _ _ => true), for fixed-length message spaces Msg where every pair (m₀, m₁) : Msg × Msg is admissible.

                      Instances For
                        def Cslib.Crypto.Encryption.INDCCA2On {Msg Out : Type} (valid : ℕ → List Bool → Msg → Msg → Bool) (encMsg : Msg ↪ List Bool) (encOut : Out ↪ List Bool) (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encrypt : ℕ → List Bool → Msg → ProbComp (List Bool)) (decrypt : ℕ → List Bool → List Bool → Option Out) :

                        Single-challenge 1CCA security ([BS23], Section 12.1, Definition 12.2, printed p. 468) with respect to challenge-pair admissibility predicate valid, message encoding encMsg, and decryption output encoding encOut.

                        Instances For
                          @[reducible, inline]
                          abbrev Cslib.Crypto.Encryption.INDCCA2Of {Msg Out : Type} (encMsg : Msg ↪ List Bool) (encOut : Out ↪ List Bool) (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encrypt : ℕ → List Bool → Msg → ProbComp (List Bool)) (decrypt : ℕ → List Bool → List Bool → Option Out) :

                          Single-challenge 1CCA security ([BS23], Section 12.1, Definition 12.2, printed p. 468) over a fixed-length message space Msg (valid := fun _ _ _ _ => true).

                          Instances For
                            @[reducible, inline]
                            abbrev Cslib.Crypto.Encryption.INDCCA2 (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encrypt : ℕ → List Bool → Bool → ProbComp (List Bool)) (decrypt : ℕ → List Bool → List Bool → Option Bool) :

                            Single-challenge 1CCA security for bit encryption (Msg = Bool, Out = Bool).

                            Instances For
                              @[reducible, inline]
                              abbrev Cslib.Crypto.Encryption.WordINDCCA2 (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encrypt : ℕ → List Bool → List Bool → ProbComp (List Bool)) (decrypt : ℕ → List Bool → List Bool → Option (List Bool)) :

                              Single-challenge 1CCA security for bit-string encryption (Msg = List Bool, Out = List Bool) under Attack Game 12.1's equal-length challenge rule m₀.length == m₁.length.

                              Instances For
                                theorem Cslib.Crypto.Encryption.isPPTOn_cca2GameOn {Msg Out : Type} {encMsg : Msg ↪ List Bool} {encOut : Out ↪ List Bool} {valid : ℕ → List Bool → Msg → Msg → Bool} {keyGen : ℕ → ProbComp (List Bool × List Bool)} {encrypt : ℕ → List Bool → Msg → ProbComp (List Bool)} {decrypt : ℕ → List Bool → List Bool → Option Out} {adversary : CCA2AdversaryOf Msg} (hvalid : Turing.MultiTapeTM.ComputableInPolyTime (fun (p : ℕ × List Bool × Msg × Msg) => valid p.1 p.2.1 p.2.2.1 p.2.2.2) (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encUnary (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encBits (Turing.MultiTapeTM.encPair encMsg encMsg))) Turing.MultiTapeTM.encBool) (hkeyGen : Probability.IsPPTOn Turing.MultiTapeTM.encUnary (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encBits Turing.MultiTapeTM.encBits) keyGen) (hencrypt : Probability.IsPPTOn (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encUnary (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encBits encMsg)) Turing.MultiTapeTM.encBits fun (p : ℕ × List Bool × Msg) => encrypt p.1 p.2.1 p.2.2) (hdecrypt : Turing.MultiTapeTM.ComputableInPolyTime (fun (p : ℕ × List Bool × List Bool) => decrypt p.1 p.2.1 p.2.2) (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encUnary (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encBits Turing.MultiTapeTM.encBits)) (Turing.MultiTapeTM.encOption encOut)) (hA : CCA2AdversaryOf.IsPPT encMsg adversary) (bit : Bool) :
                                Probability.IsPPTOn Turing.MultiTapeTM.encUnary Turing.MultiTapeTM.encBool (cca2GameOn valid encOut keyGen encrypt decrypt adversary bit)

                                The complete cca2GameOn experiment is uniformly strict PPT on the unary security parameter whenever valid, keyGen, encrypt, decrypt, and adversary are admissible.

                                The complete cca2Game experiment is uniformly strict PPT on the unary security parameter whenever keyGen, encrypt, decrypt, and adversary are admissible.

                                Playing a restricted 1CCA game inside the unrestricted one #

                                def Cslib.Crypto.Encryption.CCA2AdversaryOf.restrict {Msg : Type} (valid : ℕ → List Bool → Msg → Msg → Bool) (adversary : CCA2AdversaryOf Msg) :

                                The adversary that plays cca2GameOn valid inside the unrestricted cca2Game. Its choose runs adversary.choose n pk and puts the bit valid n pk m₀ m₁ in front of the saved state; its guess returns false when that bit is false and otherwise runs adversary.guess on the rest of the state. The challenge pair itself is passed on unchanged.

                                Instances For
                                  theorem Cslib.Crypto.Encryption.eval_cca2Game_restrict {Msg Out : Type} (valid : ℕ → List Bool → Msg → Msg → Bool) (encOut : Out ↪ List Bool) (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encrypt : ℕ → List Bool → Msg → ProbComp (List Bool)) (decrypt : ℕ → List Bool → List Bool → Option Out) (adversary : CCA2AdversaryOf Msg) (bit : Bool) (n : ℕ) :
                                  (cca2Game encOut keyGen encrypt decrypt (CCA2AdversaryOf.restrict valid adversary) bit n).eval = (cca2GameOn valid encOut keyGen encrypt decrypt adversary bit n).eval

                                  Running the unrestricted cca2Game on adversary.restrict valid has the same output distribution as running cca2GameOn valid on adversary.

                                  theorem Cslib.Crypto.Encryption.CCA2AdversaryOf.IsPPT.restrict {Msg : Type} {encMsg : Msg ↪ List Bool} {valid : ℕ → List Bool → Msg → Msg → Bool} (hvalid : Turing.MultiTapeTM.ComputableInPolyTime (fun (p : ℕ × List Bool × Msg × Msg) => valid p.1 p.2.1 p.2.2.1 p.2.2.2) (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encUnary (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encBits (Turing.MultiTapeTM.encPair encMsg encMsg))) Turing.MultiTapeTM.encBool) {adversary : CCA2AdversaryOf Msg} (hadversary : IsPPT encMsg adversary) :
                                  IsPPT encMsg (CCA2AdversaryOf.restrict valid adversary)

                                  Restricting a uniform strict oracle PPT 1CCA adversary by a polynomial-time admissibility predicate keeps it uniform strict oracle PPT: choose additionally evaluates valid and prepends one bit to the saved state, and guess branches on that bit without querying the oracle when it is false.

                                  theorem Cslib.Crypto.Encryption.INDCCA2Of.indcca2On {Msg Out : Type} {encMsg : Msg ↪ List Bool} {encOut : Out ↪ List Bool} {valid : ℕ → List Bool → Msg → Msg → Bool} {keyGen : ℕ → ProbComp (List Bool × List Bool)} {encrypt : ℕ → List Bool → Msg → ProbComp (List Bool)} {decrypt : ℕ → List Bool → List Bool → Option Out} (h : INDCCA2Of encMsg encOut keyGen encrypt decrypt) (hvalid : Turing.MultiTapeTM.ComputableInPolyTime (fun (p : ℕ × List Bool × Msg × Msg) => valid p.1 p.2.1 p.2.2.1 p.2.2.2) (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encUnary (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encBits (Turing.MultiTapeTM.encPair encMsg encMsg))) Turing.MultiTapeTM.encBool) :
                                  INDCCA2On valid encMsg encOut keyGen encrypt decrypt

                                  Unrestricted 1CCA security implies 1CCA security under every polynomial-time admissibility predicate.

                                  theorem Cslib.Crypto.Encryption.INDCCA2Of.wordINDCCA2 {keyGen : ℕ → ProbComp (List Bool × List Bool)} {encrypt : ℕ → List Bool → List Bool → ProbComp (List Bool)} {decrypt : ℕ → List Bool → List Bool → Option (List Bool)} (h : INDCCA2Of Turing.MultiTapeTM.encBits Turing.MultiTapeTM.encBits keyGen encrypt decrypt) :
                                  WordINDCCA2 keyGen encrypt decrypt

                                  Unrestricted bit-word 1CCA security implies WordINDCCA2.

                                  1CCA implies IND-CPA #

                                  Lift a chosen-plaintext AdversaryOf Msg to a 0-query CCA2AdversaryOf Msg.

                                  Instances For
                                    @[reducible, inline]

                                    Lift a chosen-plaintext bit Adversary to a 0-query CCA2Adversary.

                                    Instances For
                                      theorem Cslib.Crypto.Encryption.CCA2AdversaryOf.isPPT_ofCPA {Msg : Type} {encMsg : Msg ↪ List Bool} {adversary : AdversaryOf Msg} (hA : AdversaryOf.IsPPT encMsg adversary) :
                                      IsPPT encMsg (ofCPA adversary)

                                      Lifting a strict PPT AdversaryOf Msg yields a strict oracle PPT CCA2AdversaryOf Msg.

                                      theorem Cslib.Crypto.Encryption.CCA2Adversary.isPPT_ofCPA {adversary : Adversary} (hA : adversary.IsPPT) :
                                      (ofCPA adversary).IsPPT

                                      Lifting a strict PPT bit Adversary yields a strict oracle PPT CCA2Adversary.

                                      theorem Cslib.Crypto.Encryption.CCA2AdversaryOf.isQueryBounded_ofCPA {Msg : Type} (adversary : AdversaryOf Msg) :
                                      (ofCPA adversary).IsQueryBounded (fun (x : ℕ) => 0) fun (x : ℕ) => 0

                                      A lifted CPA adversary makes 0 decryption queries in both stages.

                                      theorem Cslib.Crypto.Encryption.CCA2Adversary.isQueryBounded_ofCPA (adversary : Adversary) :
                                      CCA2AdversaryOf.IsQueryBounded (ofCPA adversary) (fun (x : ℕ) => 0) fun (x : ℕ) => 0

                                      A lifted bit CPA adversary makes 0 decryption queries in both stages.

                                      theorem Cslib.Crypto.Encryption.eval_cca2GameOn_ofCPA {Msg Out : Type} (valid : ℕ → List Bool → Msg → Msg → Bool) (encOut : Out ↪ List Bool) (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encrypt : ℕ → List Bool → Msg → ProbComp (List Bool)) (decrypt : ℕ → List Bool → List Bool → Option Out) (adversary : AdversaryOf Msg) (bit : Bool) (n : ℕ) :
                                      (cca2GameOn valid encOut keyGen encrypt decrypt (CCA2AdversaryOf.ofCPA adversary) bit n).eval = (gameOn valid keyGen encrypt adversary bit n).eval

                                      Running a lifted CPA adversary in cca2GameOn has the same output distribution as the CPA gameOn with the same challenge-pair admissibility predicate valid.

                                      theorem Cslib.Crypto.Encryption.eval_cca2Game_ofCPA {Msg Out : Type} (encOut : Out ↪ List Bool) (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encrypt : ℕ → List Bool → Msg → ProbComp (List Bool)) (decrypt : ℕ → List Bool → List Bool → Option Out) (adversary : AdversaryOf Msg) (bit : Bool) (n : ℕ) :
                                      (cca2Game encOut keyGen encrypt decrypt (CCA2AdversaryOf.ofCPA adversary) bit n).eval = (game keyGen encrypt adversary bit n).eval

                                      Running a lifted CPA adversary in cca2Game has the same output distribution as the CPA game.

                                      theorem Cslib.Crypto.Encryption.INDCCA2On.indcpaOn {Msg Out : Type} {valid : ℕ → List Bool → Msg → Msg → Bool} {encMsg : Msg ↪ List Bool} {encOut : Out ↪ List Bool} {keyGen : ℕ → ProbComp (List Bool × List Bool)} {encrypt : ℕ → List Bool → Msg → ProbComp (List Bool)} {decrypt : ℕ → List Bool → List Bool → Option Out} (h : INDCCA2On valid encMsg encOut keyGen encrypt decrypt) :
                                      INDCPAOn valid encMsg keyGen encrypt

                                      1CCA security implies IND-CPA security under any challenge-pair admissibility predicate valid: any encryption scheme satisfying INDCCA2On valid also satisfies INDCPAOn valid.

                                      theorem Cslib.Crypto.Encryption.INDCCA2Of.indcpaOf {Msg Out : Type} {encMsg : Msg ↪ List Bool} {encOut : Out ↪ List Bool} {keyGen : ℕ → ProbComp (List Bool × List Bool)} {encrypt : ℕ → List Bool → Msg → ProbComp (List Bool)} {decrypt : ℕ → List Bool → List Bool → Option Out} (h : INDCCA2Of encMsg encOut keyGen encrypt decrypt) :
                                      INDCPAOf encMsg keyGen encrypt

                                      Unrestricted 1CCA security implies unrestricted IND-CPA security: any encryption scheme satisfying INDCCA2Of encMsg encOut also satisfies INDCPAOf encMsg.

                                      theorem Cslib.Crypto.Encryption.INDCCA2Of.indcpa {Out : Type} {encOut : Out ↪ List Bool} {keyGen : ℕ → ProbComp (List Bool × List Bool)} {encrypt : ℕ → List Bool → Bool → ProbComp (List Bool)} {decrypt : ℕ → List Bool → List Bool → Option Out} (h : INDCCA2Of Turing.MultiTapeTM.encBool encOut keyGen encrypt decrypt) :
                                      INDCPA keyGen encrypt

                                      1CCA security implies IND-CPA security: any bit encryption scheme satisfying INDCCA2Of also satisfies INDCPA.

                                      theorem Cslib.Crypto.Encryption.INDCCA2.indcpa {keyGen : ℕ → ProbComp (List Bool × List Bool)} {encrypt : ℕ → List Bool → Bool → ProbComp (List Bool)} {decrypt : ℕ → List Bool → List Bool → Option Bool} (h : INDCCA2 keyGen encrypt decrypt) :
                                      INDCPA keyGen encrypt

                                      Specialization of INDCCA2Of.indcpa to INDCCA2.

                                      theorem Cslib.Crypto.Encryption.WordINDCCA2.wordINDCPA {keyGen : ℕ → ProbComp (List Bool × List Bool)} {encrypt : ℕ → List Bool → List Bool → ProbComp (List Bool)} {decrypt : ℕ → List Bool → List Bool → Option (List Bool)} (h : WordINDCCA2 keyGen encrypt decrypt) :
                                      WordINDCPA keyGen encrypt

                                      Word 1CCA security implies word IND-CPA security: any bit-string encryption scheme satisfying WordINDCCA2 also satisfies WordINDCPA.