Documentation

Complexity.Crypto.Computational.ElGamal

ElGamal and Hashed ElGamal encryption and IND-CPA security under DDH #

Over a PrimeOrderGroupFamily, multiplicative ElGamal encryption ([BS23], Exercise 11.5, p. 459) uses a group description d, a secret exponent α : ZMod (F.order d), and the public key u = α • g. To encrypt a group element m : F.Carrier d with randomness β : ZMod (F.order d), the sender forms the ciphertext (v, e) = (β • g, β • u + m) = (β • g, (α * β) • g + m). Decryption recovers e - α • v = m, and the word-level operations encodeElGamalPublicKey, encodeElGamalEncrypt, and decodeElGamal compute public-key generation, encryption, and decryption in polynomial time from natural-number exponents and encoded group elements using F.generator, F.order, F.smul, and F.add.

We prove IND-CPA security under DDH in the following settings:

  1. Shared typed-message ElGamal reduction (elGamalMsgCPAGameOn, elGamalMsgToDDHDistinguisher, advantage_elGamalMsgCPAGameOn_le, isPPTOn_elGamalMsgToDDHDistinguisher, DDH.negligible_elGamalMsgCPAGameOn). As in Encryption.gameOn, a challenge-pair admissibility predicate valid : ℕ → List Bool → Msg → Msg → Bool sees the security parameter and the public key, and an inadmissible pair makes the game output false in both experiments. The reduction needs valid to be computable in polynomial time and to admit only messages whose encodings are group elements (AdmitsGroupElements). It is instantiated for:
    • Bit ElGamal (elGamalCPAGame, elGamalINDCPA, DDH.elGamalINDCPA): false and true are embedded as 0 and g (bitElement, encodeBit), every pair is admissible, and Encryption.Adversary chooses two challenge bits.
    • Group-element ElGamal (Encryption.WordAdversary, elGamalGroupCPAGameOn, DDH.negligible_elGamalGroupCPAGameOn, [BS23], Exercise 11.5(a), p. 459): a two-stage word-message adversary chooses two words, and valid admits only encoded group elements, in Set.range (F.encode d). Replacing the Diffie–Hellman mask (α * β) • g with an independent uniform γ • g masks any admissible pair perfectly (uniform_smul_generator_add). A PrimeOrderGroupFamily has no membership test, so valid is a parameter; the tests instantiate it on Schnorr groups.
  2. Hashed ElGamal (hashedElGamalEncrypt, hashedElGamalDecrypt, hashedElGamalCPAGame, DDH.negligible_hashedElGamalCPAGame, [BS23], Section 11.5, pp. 445–446, Remark 11.1, and Section 11.5.2, Attack Game 11.3, Definition 11.5, and Theorem 11.5, pp. 448–451): given a deterministic polynomial-time key-derivation hash function H : F.Desc × List Bool → List Bool, the sender masks a message word m with pad = H (d, encode (β • u)) via Cslib.BitString.listXor pad.length [pad, m] (the one-time pad specialization of the E'_EG variant of Remark 11.1). Security reduces to DDH together with key-derivation security (SecureKDF, Attack Game 11.3, p. 448, and Definition 11.5, p. 449: indistinguishability of H (d, encode (γ • g)) from a uniform msgLen n-bit key). The ciphertext length does not depend on the message, and hashedElGamalCPAGame admits every challenge pair, which is stronger than Attack Game 11.1's equal-length rule.

Limitations #

In this module, key generation and challenge encryption in the security games sample exact uniform exponents in ZMod (F.order d) at the PMF level (PMF.uniformOfFintype (ZMod (F.order d))), because an odd prime order F.order d cannot be sampled with exact uniformity by a bounded-time fair-coin ProbComp machine; deterministic public-key computation (encodeElGamalPublicKey), encryption given randomness (encodeElGamalEncrypt, encodeHashedElGamalEncrypt), and decryption (decodeElGamal, decodeHashedElGamal) are certified polynomial time on words. Strict-PPT (IsPPTOn) key generation, KEM encapsulation/decapsulation, and encryption via ProbComp.sampleModNat (connecting to Encryption.KEMINDCPA, Encryption.INDCPAOn, Encryption.WordINDCPA, and Encryption.INDCPA) are provided in Complexity/Crypto/Computational/ElGamal/ProbComp.lean; non-degenerate SecureKDF instantiation (msgLen n > 0) via BitString.LinearHash and the leftover hash lemma is provided in Complexity/Crypto/Computational/ElGamal/KDF.lean.

Main definitions #

Main results #

References #

Group-element ElGamal encryption and decryption #

Algebraic ElGamal encryption of a group element m : F.Carrier d under public key u : F.Carrier d with randomness β : ZMod (F.order d).

Instances For

    Under a genuine public key u = α • g, the second ciphertext component is (α * β) • g + m.

    Algebraic ElGamal decryption of a ciphertext pair (v, e) using secret key α : ZMod (F.order d).

    Instances For
      @[simp]

      ElGamal decryption correctness: decrypting an encryption under u = α • g with secret key α recovers the message m.

      Word-level ElGamal public-key computation: given (d, a), compute encode ((a : ZMod q) • g) as F.smul (d, a, F.encode d (F.generator d)).

      Instances For
        @[simp]

        encodeElGamalPublicKey computes the group encoding of (a : ZMod (F.order d)) • g.

        Word-level ElGamal encryption: given (d, encode u, encode m, b), compute (encode (b • g), encode (b • u + m)).

        Instances For
          @[simp]

          encodeElGamalEncrypt evaluates elGamalEncrypt on encoded group elements.

          Decryption on encoded group elements: given (d, a, encode v, encode e), compute encode (e - a • v) as F.add (d, encode e, F.smul (d, F.order d - a % F.order d, encode v)).

          Instances For

            decodeElGamal computes encode (elGamalDecrypt d a (v, e)) on encoded group elements.

            @[simp]
            theorem Cslib.Crypto.PrimeOrderGroupFamily.decodeElGamal_elGamalEncrypt (F : PrimeOrderGroupFamily) (d : F.Desc) (a : ℕ) (β : ZMod (F.order d)) (m : F.Carrier d) :
            F.decodeElGamal (d, a, F.encode d (F.elGamalEncrypt d (↑a • F.generator d) m β).1, F.encode d (F.elGamalEncrypt d (↑a • F.generator d) m β).2) = F.encode d m

            Encoded ElGamal decryption of an honest encryption recovers the encoded message.

            Shared typed-message ElGamal IND-CPA reduction ([BS23], Exercise 11.5(a)) #

            noncomputable def Cslib.Crypto.PrimeOrderGroupFamily.elGamalMsgCPAGameOn (F : PrimeOrderGroupFamily) {Msg : Type} (valid : ℕ → List Bool → Msg → Msg → Bool) (encodeMsg : F.Desc → Msg → List Bool) (setup : ℕ → PMF F.Desc) (adversary : Encryption.AdversaryOf Msg) (bit : Bool) (n : ℕ) :

            The IND-CPA experiment for multiplicative ElGamal encryption over message type Msg via a word-level message encoder encodeMsg : F.Desc → Msg → List Bool, with challenge-pair admissibility predicate valid ([BS23], Exercise 11.5(a), p. 459, played in Attack Game 11.1, p. 436): draw d ← setup n and a uniform secret key α : ZMod (F.order d), and pass the encoded public key pk = (d, encode (α • g)) to adversary.choose. If valid n pk m₀ m₁ holds, encrypt the selected message m under a fresh uniform exponent β : ZMod (F.order d) via F.add (d, encode ((α * β) • g), encodeMsg d m) and pass the saved state and encoded ciphertext to adversary.guess; otherwise output false, in both experiments, as Encryption.gameOn does.

            Instances For
              def Cslib.Crypto.PrimeOrderGroupFamily.elGamalMsgToDDHDistinguisher (F : PrimeOrderGroupFamily) {Msg : Type} (valid : ℕ → List Bool → Msg → Msg → Bool) (encodeMsg : F.Desc → Msg → List Bool) (adversary : Encryption.AdversaryOf Msg) (bit : Bool) (n : ℕ) (input : F.Desc × List Bool × List Bool × List Bool) :

              The DDH distinguisher constructed from a typed-message ElGamal IND-CPA adversary ([BS23], Exercise 11.5(a), p. 459): given (d, u, v, w), pass pk = (d, u) as the public key; if valid n pk m₀ m₁ holds, mask the selected encoded message encodeMsg d m with w using F.add and return the adversary's guess, and otherwise return false.

              Instances For
                theorem Cslib.Crypto.PrimeOrderGroupFamily.ddhRealGame_elGamalMsgToDDHDistinguisher (F : PrimeOrderGroupFamily) {Msg : Type} (valid : ℕ → List Bool → Msg → Msg → Bool) (encodeMsg : F.Desc → Msg → List Bool) (setup : ℕ → PMF F.Desc) (adversary : Encryption.AdversaryOf Msg) (bit : Bool) (n : ℕ) :
                F.ddhRealGame setup (F.elGamalMsgToDDHDistinguisher valid encodeMsg adversary bit) n = F.elGamalMsgCPAGameOn valid encodeMsg setup adversary bit n

                In the real DDH game, elGamalMsgToDDHDistinguisher simulates elGamalMsgCPAGameOn exactly.

                def Cslib.Crypto.PrimeOrderGroupFamily.AdmitsGroupElements (F : PrimeOrderGroupFamily) {Msg : Type} (encodeMsg : F.Desc → Msg → List Bool) (valid : ℕ → List Bool → Msg → Msg → Bool) :

                The admissibility predicate valid admits only group elements under encodeMsg: at every public key (d, u), an admissible pair (m₀, m₁) has both encodeMsg d m₀ and encodeMsg d m₁ in Set.range (F.encode d).

                Instances For
                  theorem Cslib.Crypto.PrimeOrderGroupFamily.ddhIdealGame_elGamalMsgToDDHDistinguisher_false_eq_true (F : PrimeOrderGroupFamily) {Msg : Type} (valid : ℕ → List Bool → Msg → Msg → Bool) (encodeMsg : F.Desc → Msg → List Bool) (setup : ℕ → PMF F.Desc) (adversary : Encryption.AdversaryOf Msg) (n : ℕ) (hsound : F.AdmitsGroupElements encodeMsg valid) :
                  F.ddhIdealGame setup (F.elGamalMsgToDDHDistinguisher valid encodeMsg adversary false) n = F.ddhIdealGame setup (F.elGamalMsgToDDHDistinguisher valid encodeMsg adversary true) n

                  When valid admits only group elements under encodeMsg, the uniform element γ • g of the ideal DDH game perfectly masks both admissible candidate messages, so the experiments for bit = false and bit = true are identical.

                  theorem Cslib.Crypto.PrimeOrderGroupFamily.advantage_elGamalMsgCPAGameOn_le (F : PrimeOrderGroupFamily) {Msg : Type} (valid : ℕ → List Bool → Msg → Msg → Bool) (encodeMsg : F.Desc → Msg → List Bool) (setup : ℕ → PMF F.Desc) (adversary : Encryption.AdversaryOf Msg) (n : ℕ) (hsound : F.AdmitsGroupElements encodeMsg valid) :
                  (F.elGamalMsgCPAGameOn valid encodeMsg setup adversary false n).advantage (F.elGamalMsgCPAGameOn valid encodeMsg setup adversary true n) ≤ (F.ddhRealGame setup (F.elGamalMsgToDDHDistinguisher valid encodeMsg adversary false) n).advantage (F.ddhIdealGame setup (F.elGamalMsgToDDHDistinguisher valid encodeMsg adversary false) n) + (F.ddhRealGame setup (F.elGamalMsgToDDHDistinguisher valid encodeMsg adversary true) n).advantage (F.ddhIdealGame setup (F.elGamalMsgToDDHDistinguisher valid encodeMsg adversary true) n)

                  Quantitative reduction of typed-message ElGamal IND-CPA to DDH ([BS23], Exercise 11.5(a), p. 459): when valid admits only group elements under encodeMsg, the IND-CPA distinguishing advantage of adversary is bounded by the sum of the DDH advantages of elGamalMsgToDDHDistinguisher valid encodeMsg adversary false and elGamalMsgToDDHDistinguisher valid encodeMsg adversary true.

                  theorem Cslib.Crypto.PrimeOrderGroupFamily.DDH.negligible_elGamalMsgCPAGameOn {F : PrimeOrderGroupFamily} {setup : ℕ → PMF F.Desc} {Msg : Type} {encMsg : Msg ↪ List Bool} {valid : ℕ → List Bool → Msg → Msg → Bool} {encodeMsg : F.Desc → Msg → List Bool} (hDDH : F.DDH setup) (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) (hsound : F.AdmitsGroupElements encodeMsg valid) (hencMsg : Turing.MultiTapeTM.ComputableInPolyTime (fun (p : F.Desc × Msg) => encodeMsg p.1 p.2) (Turing.MultiTapeTM.encPair F.encDesc encMsg) Turing.MultiTapeTM.encBits) {adversary : Encryption.AdversaryOf Msg} (hA : Encryption.AdversaryOf.IsPPT encMsg adversary) :
                  Negligible fun (n : ℕ) => (F.elGamalMsgCPAGameOn valid encodeMsg setup adversary false n).advantage (F.elGamalMsgCPAGameOn valid encodeMsg setup adversary true n)

                  Typed-message ElGamal encryption is IND-CPA secure under the DDH assumption ([BS23], Exercise 11.5(a), p. 459): for a polynomial-time admissibility predicate valid that admits only group elements under encodeMsg, every uniform strict PPT adversary has negligible advantage in elGamalMsgCPAGameOn valid encodeMsg.

                  Bit encryption and IND-CPA security under DDH #

                  Embed a message bit b : Bool into F.Carrier d as 0 (for false) or g (for true).

                  Instances For

                    Distinct message bits map to distinct group elements.

                    Encode a message bit b : Bool as an encoded element of F.Carrier d using F.smul.

                    Instances For

                      Every pair of bit messages encodes group elements, so the always-true predicate admits only group elements under encodeBit.

                      noncomputable def Cslib.Crypto.PrimeOrderGroupFamily.elGamalCPAGame (F : PrimeOrderGroupFamily) (setup : ℕ → PMF F.Desc) (adversary : Encryption.Adversary) (bit : Bool) (n : ℕ) :

                      The IND-CPA experiment for ElGamal bit encryption ([BS23], Exercise 11.5, p. 459): draw d from setup n and a uniform secret key α : ZMod (F.order d), pass the encoded public key (d, encode (α • g)) to adversary.choose, encrypt the selected challenge bit under a fresh uniform exponent β : ZMod (F.order d), and pass the saved state and encoded ciphertext to adversary.guess.

                      Instances For
                        theorem Cslib.Crypto.PrimeOrderGroupFamily.elGamalCPAGame_eq_elGamalMsgCPAGameOn (F : PrimeOrderGroupFamily) (setup : ℕ → PMF F.Desc) (adversary : Encryption.Adversary) (bit : Bool) (n : ℕ) :
                        F.elGamalCPAGame setup adversary bit n = F.elGamalMsgCPAGameOn (fun (x : ℕ) (x_1 : List Bool) (x_2 x_3 : Bool) => true) F.encodeBit setup adversary bit n

                        elGamalCPAGame is the unrestricted encodeBit specialization of elGamalMsgCPAGameOn.

                        IND-CPA security of ElGamal bit encryption over F for a setup law setup: every uniform strict PPT Encryption.Adversary has negligible distinguishing advantage between challenge bit false and challenge bit true.

                        Instances For
                          @[reducible, inline]

                          The DDH distinguisher constructed from an IND-CPA adversary ([BS23], proof of Exercise 11.5(a), p. 459): given (d, u, v, w), pass (d, u) as the public key, encrypt the selected challenge bit by masking with w, and return the adversary's guess.

                          Instances For
                            @[simp]
                            theorem Cslib.Crypto.PrimeOrderGroupFamily.ddhRealGame_elGamalToDDHDistinguisher (F : PrimeOrderGroupFamily) (setup : ℕ → PMF F.Desc) (adversary : Encryption.Adversary) (bit : Bool) (n : ℕ) :
                            F.ddhRealGame setup (F.elGamalToDDHDistinguisher adversary bit) n = F.elGamalCPAGame setup adversary bit n

                            In the real DDH game, elGamalToDDHDistinguisher simulates elGamalCPAGame exactly.

                            In the ideal DDH game, the uniform element γ • g perfectly masks the challenge bit, so the experiments for bit = false and bit = true are identical.

                            Quantitative reduction of ElGamal IND-CPA to DDH ([BS23], Exercise 11.5(a), p. 459): the IND-CPA distinguishing advantage of adversary is bounded by the sum of the DDH advantages of elGamalToDDHDistinguisher adversary false and elGamalToDDHDistinguisher adversary true.

                            ElGamal bit encryption is IND-CPA secure under the DDH assumption ([BS23], Exercise 11.5(a), p. 459).

                            Group-element ElGamal IND-CPA security under DDH #

                            @[reducible, inline]
                            noncomputable abbrev Cslib.Crypto.PrimeOrderGroupFamily.elGamalGroupCPAGameOn (F : PrimeOrderGroupFamily) (valid : ℕ → List Bool → List Bool → List Bool → Bool) (setup : ℕ → PMF F.Desc) (adversary : Encryption.WordAdversary) (bit : Bool) (n : ℕ) :

                            The IND-CPA experiment for group-element ElGamal encryption with challenge-pair admissibility predicate valid ([BS23], Exercise 11.5(a), p. 459): specialization of elGamalMsgCPAGameOn to word messages (Encryption.WordAdversary) with identity message encoding. The message space of Exercise 11.5 is the group, so valid is meant to admit only encoded group elements (AdmitsGroupElements (fun _ m => m) valid).

                            Instances For
                              @[reducible, inline]

                              The DDH distinguisher constructed from a group-element ElGamal IND-CPA adversary ([BS23], Exercise 11.5(a), p. 459): specialization of elGamalMsgToDDHDistinguisher to identity message encoding.

                              Instances For
                                theorem Cslib.Crypto.PrimeOrderGroupFamily.advantage_elGamalGroupCPAGameOn_le (F : PrimeOrderGroupFamily) (valid : ℕ → List Bool → List Bool → List Bool → Bool) (setup : ℕ → PMF F.Desc) (adversary : Encryption.WordAdversary) (n : ℕ) (hsound : F.AdmitsGroupElements (fun (x : F.Desc) (m : List Bool) => m) valid) :
                                (F.elGamalGroupCPAGameOn valid setup adversary false n).advantage (F.elGamalGroupCPAGameOn valid setup adversary true n) ≤ (F.ddhRealGame setup (F.elGamalGroupToDDHDistinguisher valid adversary false) n).advantage (F.ddhIdealGame setup (F.elGamalGroupToDDHDistinguisher valid adversary false) n) + (F.ddhRealGame setup (F.elGamalGroupToDDHDistinguisher valid adversary true) n).advantage (F.ddhIdealGame setup (F.elGamalGroupToDDHDistinguisher valid adversary true) n)

                                Quantitative reduction of group-element ElGamal IND-CPA to DDH ([BS23], Exercise 11.5(a), p. 459): when valid admits only encoded group elements, the IND-CPA distinguishing advantage of adversary is bounded by the sum of the DDH advantages of elGamalGroupToDDHDistinguisher valid adversary false and elGamalGroupToDDHDistinguisher valid adversary true.

                                Group-element ElGamal encryption is IND-CPA secure under the DDH assumption ([BS23], Exercise 11.5(a), p. 459): for a polynomial-time admissibility predicate valid that admits only encoded group elements, every uniform strict PPT Encryption.WordAdversary has negligible advantage in elGamalGroupCPAGameOn valid.

                                Hashed ElGamal encryption and IND-CPA security ([BS23], Section 11.5) #

                                Algebraic Hashed ElGamal encryption ([BS23], Section 11.5, pp. 445–446, Remark 11.1): given key-derivation hash function H : F.Desc × List Bool → List Bool, public key u : F.Carrier d, message word m : List Bool, and randomness β : ZMod (F.order d), derive pad = H (d, encode (β • u)) and output (β • g, Cslib.BitString.listXor pad.length [pad, m]).

                                Instances For

                                  Under a genuine public key u = α • g, Hashed ElGamal masks m with pad = H (d, encode ((α * β) • g)) via Cslib.BitString.listXor pad.length [pad, m].

                                  Algebraic Hashed ElGamal decryption ([BS23], Section 11.5, pp. 445–446, Remark 11.1): given secret key α : ZMod (F.order d) and ciphertext (v, c), derive pad = H (d, encode (α • v)) and recover Cslib.BitString.listXor pad.length [pad, c].

                                  Instances For
                                    @[simp]

                                    Hashed ElGamal decryption correctness: when the message word m has the same length as the derived pad H (d, encode ((α * β) • g)), decrypting an encryption under u = α • g with secret key α recovers m.

                                    Word-level Hashed ElGamal encryption: given (d, encode u, m, b), derive pad = H (d, encode (b • u)) and compute (encode (b • g), Cslib.BitString.listXor pad.length [pad, m]).

                                    Instances For

                                      Word-level Hashed ElGamal decryption: given (d, a, encode v, c), derive pad = H (d, encode (a • v)) and compute Cslib.BitString.listXor pad.length [pad, c].

                                      Instances For
                                        theorem Cslib.Crypto.PrimeOrderGroupFamily.decodeHashedElGamal_hashedElGamalEncrypt (F : PrimeOrderGroupFamily) (H : F.Desc × List Bool → List Bool) (d : F.Desc) (a : ℕ) (β : ZMod (F.order d)) {m : List Bool} (hlen : m.length = (H (d, F.encode d ((↑a * β) • F.generator d))).length) :
                                        F.decodeHashedElGamal H (d, a, F.encode d (F.hashedElGamalEncrypt H d (↑a • F.generator d) m β).1, (F.hashedElGamalEncrypt H d (↑a • F.generator d) m β).2) = m

                                        Word-level Hashed ElGamal decryption of an honest encryption recovers m whenever m has the same length as the derived pad.

                                        The IND-CPA experiment for Hashed ElGamal encryption ([BS23], Section 11.5, pp. 445–446, Remark 11.1, and Section 11.5.2, Theorem 11.5, pp. 449–451): draw d ← setup n and a uniform secret key α : ZMod (F.order d), pass the encoded public key (d, encode (α • g)) to adversary.choose, encrypt the selected message word m under a fresh uniform exponent β : ZMod (F.order d) by masking with pad = H (d, encode ((α * β) • g)) via Cslib.BitString.listXor pad.length [pad, m], and pass the saved state and encoded ciphertext to adversary.guess.

                                        Instances For

                                          Hybrid 1 for Hashed ElGamal ([BS23], Section 11.5.2, proof of Theorem 11.5, pp. 449–451): replace the Diffie–Hellman shared element (α * β) • g with an independent uniform group element γ • g.

                                          Instances For
                                            noncomputable def Cslib.Crypto.PrimeOrderGroupFamily.hashedElGamalUniformPadGame (F : PrimeOrderGroupFamily) (setup : ℕ → PMF F.Desc) (msgLen : ℕ → ℕ) (adversary : Encryption.WordAdversary) (bit : Bool) (n : ℕ) :

                                            Hybrid 2 for Hashed ElGamal ([BS23], Section 11.5.2, proof of Theorem 11.5, pp. 449–451): replace the derived key H (d, encode (γ • g)) with an independent uniform msgLen n-bit key pad ← Cslib.BitString.uniformList (msgLen n).

                                            Instances For
                                              noncomputable def Cslib.Crypto.PrimeOrderGroupFamily.kdfRealGame (F : PrimeOrderGroupFamily) (setup : ℕ → PMF F.Desc) (H : F.Desc × List Bool → List Bool) (distinguisher : ℕ → F.Desc × List Bool × List Bool × List Bool → ProbComp Bool) (n : ℕ) :

                                              The real key-derivation security experiment ([BS23], Section 11.5.2, Attack Game 11.3, Experiment 0, p. 448): draw d ← setup n and independent uniform α, β, γ : ZMod (F.order d), and give the distinguisher (d, encode (α • g), encode (β • g), H (d, encode (γ • g))).

                                              Instances For
                                                noncomputable def Cslib.Crypto.PrimeOrderGroupFamily.kdfIdealGame (F : PrimeOrderGroupFamily) (setup : ℕ → PMF F.Desc) (msgLen : ℕ → ℕ) (distinguisher : ℕ → F.Desc × List Bool × List Bool × List Bool → ProbComp Bool) (n : ℕ) :

                                                The ideal key-derivation security experiment ([BS23], Section 11.5.2, Attack Game 11.3, Experiment 1, p. 448): draw d ← setup n, independent uniform α, β : ZMod (F.order d), and an independent uniform msgLen n-bit key pad ← Cslib.BitString.uniformList (msgLen n), and give the distinguisher (d, encode (α • g), encode (β • g), pad).

                                                Instances For

                                                  Secure key derivation for H over F ([BS23], Section 11.5.2, Attack Game 11.3, p. 448, and Definition 11.5, p. 449): every uniform strict PPT distinguisher has negligible advantage between kdfRealGame and kdfIdealGame. No nondegenerate SecureKDF instance (msgLen n > 0, e.g., via the leftover hash lemma) is constructed in this module.

                                                  Instances For

                                                    The DDH distinguisher constructed from a Hashed ElGamal IND-CPA adversary ([BS23], Section 11.5.2, proof of Theorem 11.5, pp. 449–451): given (d, u, v, w), pass (d, u) as the public key, mask the selected message word with pad = H (d, w) via Cslib.BitString.listXor pad.length [pad, m], and return the adversary's guess.

                                                    Instances For
                                                      @[simp]

                                                      In the real DDH game, hashedElGamalToDDHDistinguisher simulates hashedElGamalCPAGame exactly.

                                                      The KDF distinguisher constructed from a Hashed ElGamal IND-CPA adversary ([BS23], Section 11.5.2, proof of Theorem 11.5, pp. 449–451): given (d, u, v, pad), pass (d, u) as the public key, mask the selected message word with pad via Cslib.BitString.listXor pad.length [pad, m], and return the adversary's guess.

                                                      Instances For
                                                        @[simp]
                                                        theorem Cslib.Crypto.PrimeOrderGroupFamily.kdfIdealGame_hashedElGamalToKDFDistinguisher (F : PrimeOrderGroupFamily) (setup : ℕ → PMF F.Desc) (msgLen : ℕ → ℕ) (adversary : Encryption.WordAdversary) (bit : Bool) (n : ℕ) :
                                                        F.kdfIdealGame setup msgLen (F.hashedElGamalToKDFDistinguisher adversary bit) n = F.hashedElGamalUniformPadGame setup msgLen adversary bit n

                                                        In the ideal KDF game, hashedElGamalToKDFDistinguisher simulates hashedElGamalUniformPadGame exactly.

                                                        In hashedElGamalUniformPadGame, the uniform msgLen n-bit pad masks any challenge message word perfectly via Cslib.BitString.listXor pad.length [pad, m], so the experiments for bit = false and bit = true are identical.

                                                        Quantitative reduction of Hashed ElGamal IND-CPA to DDH and SecureKDF ([BS23], Section 11.5.2, Theorem 11.5, pp. 449–451): the IND-CPA distinguishing advantage of adversary is bounded by the sum of the two DDH advantages of hashedElGamalToDDHDistinguisher and the two KDF advantages of hashedElGamalToKDFDistinguisher.

                                                        Hashed ElGamal encryption is IND-CPA secure under DDH and SecureKDF ([BS23], Section 11.5.2, Theorem 11.5, pp. 449–451): when H is computable in polynomial time, every uniform strict PPT Encryption.WordAdversary has negligible IND-CPA distinguishing advantage. Note that SecureKDF is assumed as a hypothesis; no nondegenerate SecureKDF instance (msgLen n > 0) is constructed in this module.