Documentation

Complexity.Crypto.Computational.Encryption.Hybrid

KEM–DEM hybrid public-key encryption #

A Key Encapsulation Mechanism (KEM) samples a public/secret key pair (pk, sk) ← keyGen n and encapsulates a symmetric key (k, ctKem) ← encaps n pk ([BS23], Exercise 11.9). Its chosen-plaintext / semantic security (KEMINDCPA, Exercise 11.9) asks that replacing the encapsulated key k with an independent uniform n-bit key BitString.sampleList n is computationally indistinguishable to every uniform strict PPT distinguisher receiving (pk, (k, ctKem)).

A Data Encapsulation Mechanism (DEM) over message space Msg encrypts a single challenge message under a fresh uniform n-bit key ([BS23], Section 2.2, Attack Game 2.1, p. 16, and Definition 2.2). As for public-key encryption (Encryption.gameOn), the experiment demGameOn takes a challenge-pair admissibility predicate valid, and an inadmissible pair makes it output false in both experiments. demGame and DEMOneTimeINDCPAOf are the always-true case, DEMOneTimeINDCPA specializes to single-bit messages, and DEMOneTimeWordINDCPA imposes Attack Game 2.1's equal-length rule on bit words.

Combining encaps with encryptSym produces the hybrid public-key encryption scheme hybridEncrypt encaps encryptSym (hybridDecrypt decaps decryptSym, Exercise 11.9(a)). By Boneh and Shoup's Exercise 11.9(b), if the KEM is IND-CPA secure and the DEM is one-time IND-CPA secure, then hybridEncrypt encaps encryptSym is IND-CPA secure: KEMINDCPA.hybrid_indcpa for unrestricted challenge pairs, and KEMINDCPA.hybrid_indcpaOn under an admissibility predicate that ignores the public key, such as the equal-length rule. We formalize both the single hidden-bit KEM distinguisher bound of Exercise 11.9(b) (advantage_hybridGame_le_two_mul) and its two-distinguisher triangle-inequality variant (advantage_hybridGame_le), together with non-vacuous single-bit and n-bit word one-time pad DEM instantiations (otpEncrypt, otpDecrypt, demOneTimeINDCPA_otpEncrypt, KEMINDCPA.hybrid_otpEncrypt_indcpa, otpWordEncrypt, otpWordDecrypt, demOneTimeINDCPA_otpWordEncrypt, demOneTimeWordINDCPA_otpWordEncrypt, KEMINDCPA.hybrid_otpWordEncrypt_indcpa).

Relative to Boneh and Shoup, Exercise 11.9, this development has the following representation conventions:

Main definitions #

Main results #

References #

Key Encapsulation Mechanisms #

def Cslib.Crypto.Encryption.kemRealGame (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encaps : ℕ → List Bool → ProbComp (List Bool × List Bool)) (distinguisher : Distinguisher) (n : ℕ) :

The real KEM IND-CPA experiment ([BS23], Exercise 11.9, Experiment 0): sample (pk, sk) ← keyGen n and (k, ctKem) ← encaps n pk, and pass the encoded triple (pk, (k, ctKem)) to distinguisher n.

Instances For
    noncomputable def Cslib.Crypto.Encryption.kemIdealGame (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encaps : ℕ → List Bool → ProbComp (List Bool × List Bool)) (distinguisher : Distinguisher) (n : ℕ) :

    The ideal KEM IND-CPA experiment ([BS23], Exercise 11.9, Experiment 1): sample (pk, sk) ← keyGen n, (k, ctKem) ← encaps n pk, and an independent uniform n-bit key kIdeal ← BitString.sampleList n, and pass (pk, (kIdeal, ctKem)) to distinguisher n.

    Instances For

      The real KEM IND-CPA experiment is uniform strict PPT when key generation, encapsulation, and the distinguisher have native certificates.

      The ideal KEM IND-CPA experiment is uniform strict PPT when key generation, encapsulation, and the distinguisher have native certificates.

      IND-CPA / semantic security for a Key Encapsulation Mechanism ([BS23], Exercise 11.9): every uniform strict PPT distinguisher has negligible advantage between kemRealGame and kemIdealGame.

      Instances For

        One-Time Symmetric Encryption (DEM) #

        noncomputable def Cslib.Crypto.Encryption.demGameOn {Msg : Type} (valid : ℕ → List Bool → Msg → Msg → Bool) (encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)) (adversary : AdversaryOf Msg) (bit : Bool) (n : ℕ) :

        The one-time symmetric chosen-plaintext experiment over message space Msg with challenge-pair admissibility predicate valid ([BS23], Section 2.2, Attack Game 2.1, p. 16): sample a uniform n-bit key k ← BitString.sampleList n and invoke adversary.choose n []; the adversary receives the empty public key [], and valid is evaluated at it. If the chosen pair is valid, encrypt the selected message under encryptSym n k and pass the saved state and challenge ciphertext to adversary.guess n; otherwise return false, in both experiments.

        Instances For
          @[reducible, inline]
          noncomputable abbrev Cslib.Crypto.Encryption.demGame {Msg : Type} (encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)) (adversary : AdversaryOf Msg) (bit : Bool) (n : ℕ) :

          The unrestricted one-time symmetric experiment: demGameOn with every challenge pair admissible.

          Instances For
            theorem Cslib.Crypto.Encryption.eval_demGame_restrict {Msg : Type} (valid : ℕ → List Bool → Msg → Msg → Bool) (encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)) (adversary : AdversaryOf Msg) (bit : Bool) (n : ℕ) :
            (demGame encryptSym (AdversaryOf.restrict valid adversary) bit n).eval = (demGameOn valid encryptSym adversary bit n).eval

            Running the unrestricted demGame on adversary.restrict valid has the same output distribution as running demGameOn valid on adversary.

            theorem Cslib.Crypto.Encryption.isPPTOn_demGameOn {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) {encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)} (hencrypt : Probability.IsPPTOn (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encUnary (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encBits encMsg)) Turing.MultiTapeTM.encBits fun (p : ℕ × List Bool × Msg) => encryptSym p.1 p.2.1 p.2.2) {adversary : AdversaryOf Msg} (hadversary : AdversaryOf.IsPPT encMsg adversary) {α : Type} {input : α ↪ List Bool} {n : α → ℕ} {bit : α → Bool} (hn : Turing.MultiTapeTM.ComputableInPolyTime n input Turing.MultiTapeTM.encUnary) (hbit : Turing.MultiTapeTM.ComputableInPolyTime bit input Turing.MultiTapeTM.encBool) :
            Probability.IsPPTOn input Turing.MultiTapeTM.encBool fun (a : α) => demGameOn valid encryptSym adversary (bit a) (n a)

            The one-time symmetric experiment demGameOn valid has a strict polynomial clock when valid is computable in polynomial time and symmetric encryption and both adversary stages have native certificates.

            theorem Cslib.Crypto.Encryption.isPPTOn_demGame {Msg : Type} {encMsg : Msg ↪ List Bool} {encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)} (hencrypt : Probability.IsPPTOn (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encUnary (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encBits encMsg)) Turing.MultiTapeTM.encBits fun (p : ℕ × List Bool × Msg) => encryptSym p.1 p.2.1 p.2.2) {adversary : AdversaryOf Msg} (hadversary : AdversaryOf.IsPPT encMsg adversary) {α : Type} {input : α ↪ List Bool} {n : α → ℕ} {bit : α → Bool} (hn : Turing.MultiTapeTM.ComputableInPolyTime n input Turing.MultiTapeTM.encUnary) (hbit : Turing.MultiTapeTM.ComputableInPolyTime bit input Turing.MultiTapeTM.encBool) :
            Probability.IsPPTOn input Turing.MultiTapeTM.encBool fun (a : α) => demGame encryptSym adversary (bit a) (n a)

            The unrestricted one-time symmetric experiment has a strict polynomial clock when symmetric encryption and both adversary stages have native certificates.

            def Cslib.Crypto.Encryption.DEMOneTimeINDCPAOn {Msg : Type} (valid : ℕ → List Bool → Msg → Msg → Bool) (encMsg : Msg ↪ List Bool) (encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)) :

            One-time symmetric IND-CPA / semantic security over message encoding encMsg with challenge-pair admissibility predicate valid ([BS23], Section 2.2, Attack Game 2.1, p. 16, and Definition 2.2): every uniform strict PPT Encryption.AdversaryOf Msg has negligible distinguishing advantage between demGameOn valid encryptSym adversary false and demGameOn valid encryptSym adversary true.

            Instances For
              @[reducible, inline]
              abbrev Cslib.Crypto.Encryption.DEMOneTimeINDCPAOf {Msg : Type} (encMsg : Msg ↪ List Bool) (encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)) :

              One-time symmetric IND-CPA with every challenge pair admissible. For List Bool messages this is stronger than the textbook notion, which DEMOneTimeWordINDCPA states.

              Instances For
                theorem Cslib.Crypto.Encryption.DEMOneTimeINDCPAOf.demOneTimeINDCPAOn {Msg : Type} {encMsg : Msg ↪ List Bool} {valid : ℕ → List Bool → Msg → Msg → Bool} {encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)} (h : DEMOneTimeINDCPAOf encMsg encryptSym) (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) :
                DEMOneTimeINDCPAOn valid encMsg encryptSym

                Unrestricted one-time symmetric IND-CPA implies one-time symmetric IND-CPA under every polynomial-time admissibility predicate.

                @[reducible, inline]

                One-time symmetric IND-CPA / semantic security for single-bit encryption.

                Instances For
                  @[reducible, inline]

                  One-time symmetric IND-CPA / semantic security for bit-word encryption under Attack Game 2.1's equal-length rule ([BS23], Section 2.2, p. 16): challenge pairs with m₀.length ≠ m₁.length are inadmissible.

                  Instances For

                    Hybrid Encryption Construction and Correctness #

                    def Cslib.Crypto.Encryption.hybridEncrypt {Msg : Type} (encaps : ℕ → List Bool → ProbComp (List Bool × List Bool)) (encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)) (n : ℕ) (pk : List Bool) (msg : Msg) :

                    KEM–DEM hybrid encryption ([BS23], Exercise 11.9): encapsulate a symmetric key (k, ctKem) ← encaps n pk, encrypt the plaintext message under k via ctDem ← encryptSym n k msg, and encode (ctKem, ctDem) using encPair encBits encBits.

                    Instances For
                      def Cslib.Crypto.Encryption.hybridDecrypt {Msg : Type} (decaps : ℕ → List Bool → List Bool → List Bool) (decryptSym : ℕ → List Bool → List Bool → Msg) (n : ℕ) (sk ct : List Bool) :
                      Msg

                      Deterministic KEM–DEM hybrid decryption ([BS23], Exercise 11.9): decode the hybrid ciphertext ct into ctKem = unframe ct and ctDem = dropFrame ct, decapsulate k = decaps n sk ctKem, and return decryptSym n k ctDem.

                      Instances For
                        theorem Cslib.Crypto.Encryption.hybridDecrypt_encPair {Msg : Type} (decaps : ℕ → List Bool → List Bool → List Bool) (decryptSym : ℕ → List Bool → List Bool → Msg) (n : ℕ) (sk ctKem ctDem : List Bool) :
                        hybridDecrypt decaps decryptSym n sk ((Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encBits Turing.MultiTapeTM.encBits) (ctKem, ctDem)) = decryptSym n (decaps n sk ctKem) ctDem

                        Hybrid decryption on an encoded ciphertext pair (ctKem, ctDem) decapsulates ctKem and decrypts ctDem under the resulting key.

                        theorem Cslib.Crypto.Encryption.hybridDecrypt_hybridEncrypt {Msg : Type} {encaps : ℕ → List Bool → ProbComp (List Bool × List Bool)} {decaps : ℕ → List Bool → List Bool → List Bool} {encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)} {decryptSym : ℕ → List Bool → List Bool → Msg} {n : ℕ} {pk sk ct : List Bool} {msg : Msg} (hkem : ∀ (k ctKem : List Bool), (k, ctKem) ∈ (encaps n pk).eval.support → decaps n sk ctKem = k) (hdem : ∀ (k ctDem : List Bool), (∃ (ctKem : List Bool), (k, ctKem) ∈ (encaps n pk).eval.support) → ctDem ∈ (encryptSym n k msg).eval.support → decryptSym n k ctDem = msg) (hct : ct ∈ (hybridEncrypt encaps encryptSym n pk msg).eval.support) :
                        hybridDecrypt decaps decryptSym n sk ct = msg

                        Hybrid decryption correctness: if decaps n sk recovers the encapsulated key k on every supported output (k, ctKem) of encaps n pk, and decryptSym n k recovers msg on every supported output of encryptSym n k msg, then hybridDecrypt recovers msg on every supported ciphertext of hybridEncrypt.

                        Boneh–Shoup Exercise 11.9(b) Reductions and Asymptotic Security #

                        noncomputable def Cslib.Crypto.Encryption.hybridIdealGame {Msg : Type} (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encaps : ℕ → List Bool → ProbComp (List Bool × List Bool)) (encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)) (adversary : AdversaryOf Msg) (bit : Bool) (n : ℕ) :

                        The intermediate hybrid game $G_1$ for the standard hybrid argument of [BS23], Exercise 11.9(b): identical to Encryption.game keyGen (hybridEncrypt encaps encryptSym) except that the symmetric key passed to encryptSym is an independent uniform n-bit key kIdeal ← BitString.sampleList n rather than encapsulated.1.

                        Instances For
                          def Cslib.Crypto.Encryption.hybridToKEMDistinguisher {Msg : Type} (encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)) (adversary : AdversaryOf Msg) (bit : Bool) :

                          Direct per-bit KEM distinguisher $D_{\mathrm{kem}, b}$ constructed from an Encryption.AdversaryOf Msg and DEM encryption encryptSym (for the two-distinguisher variant of [BS23], Exercise 11.9(b)): given an encoded KEM challenge (pk, (k, ctKem)), run adversary.choose n pk, encrypt the bit-selected message under k, and run adversary.guess on (ctKem, ctDem).

                          Instances For
                            noncomputable def Cslib.Crypto.Encryption.hybridToKEMHiddenBitDistinguisher {Msg : Type} (encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)) (adversary : AdversaryOf Msg) :

                            Single hidden-bit KEM distinguisher $\mathcal{B}_{\mathrm{kem}}$ for [BS23], Exercise 11.9(b): given an encoded KEM challenge (pk, (k, ctKem)), run adversary.choose n pk, sample a fair challenge bit bit ← ProbComp.uniform Bool, encrypt the selected message under k, run adversary.guess, and return guess ^^ bit.

                            Instances For
                              def Cslib.Crypto.Encryption.hybridToDEMAdversary {Msg : Type} (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encaps : ℕ → List Bool → ProbComp (List Bool × List Bool)) (adversary : AdversaryOf Msg) :

                              Two-stage DEM adversary $\mathcal{B}_{\mathrm{s}}$ constructed from keyGen, encaps, and a hybrid Encryption.AdversaryOf Msg for [BS23], Exercise 11.9(b): stage 1 samples (pk, sk) ← keyGen n and (k, ctKem) ← encaps n pk, runs adversary.choose n pk, and saves encPair encBits encBits (ctKem, choice.2); stage 2 combines ctKem with the DEM challenge ciphertext ctDem and runs adversary.guess.

                              Instances For
                                theorem Cslib.Crypto.Encryption.isPPT_hybridToKEMDistinguisher {Msg : Type} {encMsg : Msg ↪ List Bool} {encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)} {adversary : AdversaryOf Msg} (hencryptSym : Probability.IsPPTOn (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encUnary (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encBits encMsg)) Turing.MultiTapeTM.encBits fun (p : ℕ × List Bool × Msg) => encryptSym p.1 p.2.1 p.2.2) (hadversary : AdversaryOf.IsPPT encMsg adversary) (bit : Bool) :

                                hybridToKEMDistinguisher is uniform strict PPT whenever symmetric encryption and the hybrid adversary are.

                                hybridToKEMHiddenBitDistinguisher is uniform strict PPT whenever symmetric encryption and the hybrid adversary are.

                                hybridToDEMAdversary is an admissible uniform strict PPT Encryption.AdversaryOf Msg whenever key generation, encapsulation, and the hybrid adversary are.

                                @[simp]
                                theorem Cslib.Crypto.Encryption.eval_kemRealGame_hybridToKEMDistinguisher {Msg : Type} (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encaps : ℕ → List Bool → ProbComp (List Bool × List Bool)) (encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)) (adversary : AdversaryOf Msg) (bit : Bool) (n : ℕ) :
                                (kemRealGame keyGen encaps (hybridToKEMDistinguisher encryptSym adversary bit) n).eval = (game keyGen (hybridEncrypt encaps encryptSym) adversary bit n).eval

                                In the real KEM experiment, hybridToKEMDistinguisher reproduces the actual hybrid encryption experiment Encryption.game keyGen (hybridEncrypt encaps encryptSym).

                                @[simp]
                                theorem Cslib.Crypto.Encryption.eval_kemIdealGame_hybridToKEMDistinguisher {Msg : Type} (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encaps : ℕ → List Bool → ProbComp (List Bool × List Bool)) (encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)) (adversary : AdversaryOf Msg) (bit : Bool) (n : ℕ) :
                                (kemIdealGame keyGen encaps (hybridToKEMDistinguisher encryptSym adversary bit) n).eval = (hybridIdealGame keyGen encaps encryptSym adversary bit n).eval

                                In the ideal KEM experiment, hybridToKEMDistinguisher reproduces the intermediate game hybridIdealGame.

                                @[simp]
                                theorem Cslib.Crypto.Encryption.eval_demGame_hybridToDEMAdversary {Msg : Type} (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encaps : ℕ → List Bool → ProbComp (List Bool × List Bool)) (encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)) (adversary : AdversaryOf Msg) (bit : Bool) (n : ℕ) :
                                (demGame encryptSym (hybridToDEMAdversary keyGen encaps adversary) bit n).eval = (hybridIdealGame keyGen encaps encryptSym adversary bit n).eval

                                In the one-time symmetric DEM experiment, hybridToDEMAdversary reproduces the intermediate game hybridIdealGame.

                                theorem Cslib.Crypto.Encryption.eval_kemRealGame_hybridToKEMHiddenBitDistinguisher {Msg : Type} (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encaps : ℕ → List Bool → ProbComp (List Bool × List Bool)) (encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)) (adversary : AdversaryOf Msg) (n : ℕ) :
                                (kemRealGame keyGen encaps (hybridToKEMHiddenBitDistinguisher encryptSym adversary) n).eval = do let bit ← Probability.PMF.uniformOfFintype Bool PMF.map (fun (guess : Bool) => guess ^^ bit) (game keyGen (hybridEncrypt encaps encryptSym) adversary bit n).eval

                                In the real KEM experiment, hybridToKEMHiddenBitDistinguisher averages the two hybrid chosen-message games, complementing the second.

                                theorem Cslib.Crypto.Encryption.eval_kemIdealGame_hybridToKEMHiddenBitDistinguisher {Msg : Type} (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encaps : ℕ → List Bool → ProbComp (List Bool × List Bool)) (encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)) (adversary : AdversaryOf Msg) (n : ℕ) :
                                (kemIdealGame keyGen encaps (hybridToKEMHiddenBitDistinguisher encryptSym adversary) n).eval = do let bit ← Probability.PMF.uniformOfFintype Bool PMF.map (fun (guess : Bool) => guess ^^ bit) (hybridIdealGame keyGen encaps encryptSym adversary bit n).eval

                                In the ideal KEM experiment, hybridToKEMHiddenBitDistinguisher averages the two intermediate games hybridIdealGame, complementing the second.

                                theorem Cslib.Crypto.Encryption.probability_kemRealGame_hybridToKEMHiddenBitDistinguisher {Msg : Type} (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encaps : ℕ → List Bool → ProbComp (List Bool × List Bool)) (encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)) (adversary : AdversaryOf Msg) (n : ℕ) :
                                ↑(Game.succProbability (kemRealGame keyGen encaps (hybridToKEMHiddenBitDistinguisher encryptSym adversary) n).eval) = (1 + ↑(Game.succProbability (game keyGen (hybridEncrypt encaps encryptSym) adversary false n).eval) - ↑(Game.succProbability (game keyGen (hybridEncrypt encaps encryptSym) adversary true n).eval)) / 2

                                Success probability of hybridToKEMHiddenBitDistinguisher in kemRealGame is one half plus half the signed hybrid chosen-message gap.

                                theorem Cslib.Crypto.Encryption.probability_kemIdealGame_hybridToKEMHiddenBitDistinguisher {Msg : Type} (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encaps : ℕ → List Bool → ProbComp (List Bool × List Bool)) (encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)) (adversary : AdversaryOf Msg) (n : ℕ) :
                                ↑(Game.succProbability (kemIdealGame keyGen encaps (hybridToKEMHiddenBitDistinguisher encryptSym adversary) n).eval) = (1 + ↑(Game.succProbability (hybridIdealGame keyGen encaps encryptSym adversary false n).eval) - ↑(Game.succProbability (hybridIdealGame keyGen encaps encryptSym adversary true n).eval)) / 2

                                Success probability of hybridToKEMHiddenBitDistinguisher in kemIdealGame is one half plus half the signed hybridIdealGame gap.

                                theorem Cslib.Crypto.Encryption.advantage_hybridGame_le {Msg : Type} (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encaps : ℕ → List Bool → ProbComp (List Bool × List Bool)) (encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)) (adversary : AdversaryOf Msg) (n : ℕ) :
                                Game.advantage (game keyGen (hybridEncrypt encaps encryptSym) adversary false n).eval (game keyGen (hybridEncrypt encaps encryptSym) adversary true n).eval ≤ Game.advantage (kemRealGame keyGen encaps (hybridToKEMDistinguisher encryptSym adversary false) n).eval (kemIdealGame keyGen encaps (hybridToKEMDistinguisher encryptSym adversary false) n).eval + Game.advantage (kemRealGame keyGen encaps (hybridToKEMDistinguisher encryptSym adversary true) n).eval (kemIdealGame keyGen encaps (hybridToKEMDistinguisher encryptSym adversary true) n).eval + Game.advantage (demGame encryptSym (hybridToDEMAdversary keyGen encaps adversary) false n).eval (demGame encryptSym (hybridToDEMAdversary keyGen encaps adversary) true n).eval

                                Quantitative KEM–DEM reduction via two per-bit KEM distinguishers (two-distinguisher variant of [BS23], Exercise 11.9(b)): the hybrid IND-CPA advantage is bounded by the sum of the KEM advantages of hybridToKEMDistinguisher encryptSym adversary false and hybridToKEMDistinguisher encryptSym adversary true, plus the DEM advantage of hybridToDEMAdversary keyGen encaps adversary.

                                theorem Cslib.Crypto.Encryption.advantage_hybridGame_le_two_mul {Msg : Type} (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encaps : ℕ → List Bool → ProbComp (List Bool × List Bool)) (encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)) (adversary : AdversaryOf Msg) (n : ℕ) :
                                Game.advantage (game keyGen (hybridEncrypt encaps encryptSym) adversary false n).eval (game keyGen (hybridEncrypt encaps encryptSym) adversary true n).eval ≤ 2 * Game.advantage (kemRealGame keyGen encaps (hybridToKEMHiddenBitDistinguisher encryptSym adversary) n).eval (kemIdealGame keyGen encaps (hybridToKEMHiddenBitDistinguisher encryptSym adversary) n).eval + Game.advantage (demGame encryptSym (hybridToDEMAdversary keyGen encaps adversary) false n).eval (demGame encryptSym (hybridToDEMAdversary keyGen encaps adversary) true n).eval

                                Quantitative KEM–DEM reduction via a single hidden-bit KEM distinguisher ([BS23], Exercise 11.9(b)): the hybrid IND-CPA advantage is at most twice the KEM advantage of hybridToKEMHiddenBitDistinguisher encryptSym adversary, plus the DEM advantage of hybridToDEMAdversary keyGen encaps adversary.

                                IND-CPA security of KEM–DEM hybrid encryption ([BS23], Exercise 11.9(b)): if (keyGen, encaps) is an IND-CPA secure KEM and encryptSym is a one-time IND-CPA secure DEM over encMsg (with uniform strict PPT honest algorithms), then hybridEncrypt encaps encryptSym is IND-CPA secure over encMsg.

                                theorem Cslib.Crypto.Encryption.eval_demGame_hybridToDEMAdversary_restrict {Msg : Type} (valid : ℕ → List Bool → Msg → Msg → Bool) (hpk : ∀ (n : ℕ) (pk : List Bool) (m₀ m₁ : Msg), valid n pk m₀ m₁ = valid n [] m₀ m₁) (keyGen : ℕ → ProbComp (List Bool × List Bool)) (encaps : ℕ → List Bool → ProbComp (List Bool × List Bool)) (encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)) (adversary : AdversaryOf Msg) (bit : Bool) (n : ℕ) :
                                (demGame encryptSym (hybridToDEMAdversary keyGen encaps (AdversaryOf.restrict valid adversary)) bit n).eval = (demGameOn valid encryptSym (hybridToDEMAdversary keyGen encaps (AdversaryOf.restrict valid adversary)) bit n).eval

                                When valid ignores the public key, running the unrestricted demGame on the DEM adversary built from adversary.restrict valid has the same output distribution as running demGameOn valid on it: an invalid pair already makes the restricted adversary's guess false.

                                theorem Cslib.Crypto.Encryption.KEMINDCPA.hybrid_indcpaOn {Msg : Type} {encMsg : Msg ↪ List Bool} {valid : ℕ → List Bool → Msg → Msg → Bool} {keyGen : ℕ → ProbComp (List Bool × List Bool)} {encaps : ℕ → List Bool → ProbComp (List Bool × List Bool)} {encryptSym : ℕ → List Bool → Msg → ProbComp (List Bool)} (hkem : KEMINDCPA keyGen encaps) (hdem : DEMOneTimeINDCPAOn valid encMsg encryptSym) (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) (hpk : ∀ (n : ℕ) (pk : List Bool) (m₀ m₁ : Msg), valid n pk m₀ m₁ = valid n [] m₀ m₁) (hkeyGen : Probability.IsPPTOn Turing.MultiTapeTM.encUnary (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encBits Turing.MultiTapeTM.encBits) keyGen) (hencaps : Probability.IsPPTOn (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encUnary Turing.MultiTapeTM.encBits) (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encBits Turing.MultiTapeTM.encBits) fun (p : ℕ × List Bool) => encaps p.1 p.2) (hencryptSym : Probability.IsPPTOn (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encUnary (Turing.MultiTapeTM.encPair Turing.MultiTapeTM.encBits encMsg)) Turing.MultiTapeTM.encBits fun (p : ℕ × List Bool × Msg) => encryptSym p.1 p.2.1 p.2.2) :
                                INDCPAOn valid encMsg keyGen (hybridEncrypt encaps encryptSym)

                                IND-CPA security of KEM–DEM hybrid encryption under an admissibility predicate ([BS23], Exercise 11.9(b)), for a polynomial-time predicate valid that ignores the public key, such as the equal-length rule: if (keyGen, encaps) is an IND-CPA secure KEM and encryptSym satisfies DEMOneTimeINDCPAOn valid encMsg, then hybridEncrypt encaps encryptSym satisfies INDCPAOn valid encMsg.

                                Non-vacuous One-Time Pad DEMs #

                                One-time pad single-bit symmetric encryption: XOR the first key bit k.headD false with the plaintext bit bit.

                                Instances For

                                  One-time pad single-bit symmetric decryption: XOR the first key bit k.headD false with the first ciphertext bit ct.headD false.

                                  Instances For

                                    One-time pad decryption inverts one-time pad encryption on every supported ciphertext.

                                    For 1 ≤ n, a uniform n-bit key masks the challenge bit perfectly in demGame otpEncrypt, so the false and true experiment distributions are identical.

                                    For 1 ≤ n, every adversary has exact advantage 0 in demGame otpEncrypt.

                                    The one-time pad is unconditionally one-time IND-CPA secure (DEMOneTimeINDCPA otpEncrypt).

                                    KEM-to-PKE corollary: combining any IND-CPA secure KEM with the one-time pad DEM yields an IND-CPA secure public-key bit-encryption scheme.

                                    One-time pad n-bit word symmetric encryption: XOR the n-bit key k with the plaintext word m at width n using BitString.listXor n [k, m].

                                    Instances For

                                      One-time pad n-bit word symmetric decryption: XOR the n-bit key k with the ciphertext word ct at width n using BitString.listXor n [k, ct].

                                      Instances For

                                        One-time pad word decryption inverts one-time pad word encryption on every n-bit plaintext word m.

                                        A uniform n-bit key masks any challenge word perfectly in demGame otpWordEncrypt, so the false and true experiment distributions are identical for every n.

                                        KEM-to-word-PKE corollary: combining any IND-CPA secure KEM with the n-bit word one-time pad DEM yields a public-key word-encryption scheme satisfying WordINDCPA, through the equal-length instance of KEMINDCPA.hybrid_indcpaOn.