2.3. Encrypt-then-MAC
Definition2.3.1
\todo
def etmAEAD (se : DetSEAlg K_e M C_e)
(prf : PRFScheme K_m (AD × C_e) T) :
AEADScheme ProbComp M AD (K_e × K_m) (C_e × T) where
keygen := do
let ke ← se.keygen
let km ← prf.keygen
return (ke, km)
encrypt := fun (ke, km) ad m =>
let c := se.encrypt ke m
let t := prf.eval km (ad, c)
(c, t)
decrypt := fun (ke, km) ad (c, t) =>
if t == prf.eval km (ad, c)
then se.decrypt ke c
else none
uses Definition 2.1.1 · github #24
Lean code for Definition2.3.1●1 definition
Associated Lean declarations
-
etmAEAD[complete]
Associated Lean declarations
-
etmAEAD[complete]
-
defdefined in SecureMessaging/AEAD/FromEtM/Construction.leancomplete
def etmAEAD {K_e K_m M AD C_e T : Type} [DecidableEq T] (se : DetSEAlg K_e M C_e) (prf : PRFScheme K_m (AD × C_e) T) : AEADScheme ProbComp M AD (K_e × K_m) (C_e × T)
def etmAEAD {K_e K_m M AD C_e T : Type} [DecidableEq T] (se : DetSEAlg K_e M C_e) (prf : PRFScheme K_m (AD × C_e) T) : AEADScheme ProbComp M AD (K_e × K_m) (C_e × T)
Encrypt-then-MAC composition: build an `AEADScheme` from a deterministic symmetric cipher `se` and a PRF `prf`. NRS14 Figure 2, scheme A5 (outer-tag EtM), adapted: one-time, no nonce. - `encrypt(ke, km, ad, m)`: `c := se.encrypt ke m; t := prf.eval km (ad, c); return (c, t)` - `decrypt(ke, km, ad, (c, t))`: if `t == prf.eval km (ad, c)` then `se.decrypt ke c` else `none` - `keygen`: independent `ke ← se.keygen; km ← prf.keygen`
Theorem2.3.2
Group: Encrypt-then-MAC. (2)
Statement uses 2
Associated Lean declarations
-
etmAEAD_correct[complete]
\todo
theorem etmAEAD_correct (se : DetSEAlg K_e M C_e)
(prf : PRFScheme K_m (AD × C_e) T) (hse : se.Correct) :
(etmAEAD se prf).Correct
uses Definition 2.3.1 · Definition 2.1.3 · github #25
Lean code for Theorem2.3.2●1 theorem
Associated Lean declarations
-
etmAEAD_correct[complete]
Associated Lean declarations
-
etmAEAD_correct[complete]
-
theoremdefined in SecureMessaging/AEAD/FromEtM/Correctness.leancomplete
theorem etmAEAD_correct {K_e K_m M AD C_e T : Type} [DecidableEq T] (se : DetSEAlg K_e M C_e) (prf : PRFScheme K_m (AD × C_e) T) (hse : se.Correct) : (etmAEAD se prf).Correct
theorem etmAEAD_correct {K_e K_m M AD C_e T : Type} [DecidableEq T] (se : DetSEAlg K_e M C_e) (prf : PRFScheme K_m (AD × C_e) T) (hse : se.Correct) : (etmAEAD se prf).Correct
If the base cipher `se` is correct, then `etmAEAD se prf` is correct. The proof is straightforward: the tag comparison `prf.eval km (ad, c) == prf.eval km (ad, c)` is trivially `true`, so `decrypt` always reaches the `se.decrypt` branch, which recovers the plaintext by `hse`.
Theorem2.3.3
Group: Encrypt-then-MAC. (2)
Statement uses 4
Associated Lean declarations
-
etmAEAD_security[complete]
\todo
theorem etmAEAD_security [Inhabited K_e]
(se : DetSEAlg K_e M C_e) (prf : PRFScheme K_m (AD × C_e) T)
(adv : OneTimeCCAAdversary AD M (C_e × T))
(q_d : ℕ) [Fintype T]
(hqd : AEADScheme.decryptQueryBound adv q_d)
[NeverFail prf.keygen] :
AEADScheme.distAdvantage (etmAEAD se prf) adv ≤
PRFScheme.prfAdvantage prf (prfReduction se adv) +
↑q_d * (Fintype.card T : ℝ)⁻¹ +
DetSEAlg.distAdvantage se (encReduction se adv)
uses Definition 2.3.1 · Definition 2.1.4 · Definition 2.1.7 · Definition 2.1.5 · github #26
Lean code for Theorem2.3.3●1 theorem
Associated Lean declarations
-
etmAEAD_security[complete]
Associated Lean declarations
-
etmAEAD_security[complete]
-
theoremdefined in SecureMessaging/AEAD/FromEtM/Security.leancomplete
theorem etmAEAD_security {K_e K_m M AD C_e T : Type} [DecidableEq AD] [DecidableEq C_e] [DecidableEq T] [Inhabited C_e] [Inhabited T] [SampleableType C_e] [SampleableType T] [Inhabited K_e] (se : DetSEAlg K_e M C_e) (prf : PRFScheme K_m (AD × C_e) T) (adv : AEADScheme.OneTimeCCAAdversary AD M (C_e × T)) (q_d : ℕ) [Fintype T] (hqd : AEADScheme.decryptQueryBound adv q_d) [NeverFail prf.keygen] : (etmAEAD se prf).distAdvantage adv ≤ prf.prfAdvantage (prfReduction se adv) + ↑q_d * (↑(Fintype.card T))⁻¹ + se.distAdvantage (encReduction se adv)
theorem etmAEAD_security {K_e K_m M AD C_e T : Type} [DecidableEq AD] [DecidableEq C_e] [DecidableEq T] [Inhabited C_e] [Inhabited T] [SampleableType C_e] [SampleableType T] [Inhabited K_e] (se : DetSEAlg K_e M C_e) (prf : PRFScheme K_m (AD × C_e) T) (adv : AEADScheme.OneTimeCCAAdversary AD M (C_e × T)) (q_d : ℕ) [Fintype T] (hqd : AEADScheme.decryptQueryBound adv q_d) [NeverFail prf.keygen] : (etmAEAD se prf).distAdvantage adv ≤ prf.prfAdvantage (prfReduction se adv) + ↑q_d * (↑(Fintype.card T))⁻¹ + se.distAdvantage (encReduction se adv)
**EtM one-time IND-CCA security** (NRS14 Theorem 1 for A5, adapted). The one-time IND-CCA distinguishing advantage of `etmAEAD se prf` is bounded by the PRF advantage, the tag-guessing probability per decryption query, and the IND$-CPA advantage: `Adv^{ot-cca-ror}_{EtM}(A) ≤ Adv^{prf}(B) + q_d/|T| + Adv^{ind$}(D)` where `B = prfReduction se adv` and `D = encReduction se adv` are explicit reductions (skeleton instantiations), and `q_d` upper-bounds the adversary's number of decryption queries (tied to `adv` via `decryptQueryBound`, i.e. `IsQueryBoundP` on the decrypt-oracle index). The `NeverFail prf.keygen` instance (i.e. `Pr[⊥ | prf.keygen] = 0`) is the explicit form of a losslessness property NRS14 has implicitly: there keys are sampled from a set, so keygen cannot fail. Our `prf.keygen : ProbComp K_m` lives in a more permissive, partiality-aware type, so we state it. It is satisfied by every standard PRF (whose key is a uniform sample `$ᵗ K_m`), so it doesn't rule out any construction of interest. NRS14 Figure 9 bound: `Adv^nAE ≤ Adv^prf_F(B) + Adv^ivE_E(D₁) + q_d/2^τ`. Our one-time adaptation: `Adv^ivE → Adv^{ind$-cpa}`, `2^τ → |T|`.
References:
-
Namprempre et al. (2014) — the construction (Figure 2, scheme A5) and security proof (Theorem 1, Figure 9 bound) this chapter formalizes.
-
Alwen et al. (2019) — the one-time IND-CCA notion being targeted (Definition 1, Figure 1, Definition 2).
-
Dodis et al. (2025) — the AEAD advantage convention (Definition 2.5).