ISE Cryptography — Lecture 06

Digital Signatures, CCA Security, Authenticated Encryption and HPKE

Welcome back

  • Last week we built public-key encryption: DH/ECDH for key agreement, RSA as a trapdoor permutation, hybrid PKE with the OAEP teaser
  • Two threads were left dangling
    • Trust anchor: 3DH closes the MITM problem if Bob’s static key is genuinely his, but we still have no way to verify that for a stranger
    • CCA security: textbook RSA was visibly malleable; we showed why CPA is not enough but didn’t fix it
  • Today closes both threads and finishes the theoretical arc
    • Signatures (UF-CMA), constructions (FDH, Schnorr/ECDSA), trust (PKI)
    • CCA security and OAEP, closing the textbook-RSA loop
    • Encrypt-then-MAC proof and AEAD operational details
    • KEM abstraction, DHKEM, HPKE
    • AEAD edge cases: nonce misuse resistance and key commitment

Signatures vs MACs

The public-key alternative to message authentication.

The Comparison

  • MACs and digital signatures both provide message integrity and authenticity
    • But they differ in a fundamental way
  • MACs are symmetric: both parties share the same secret key
    • Any keyholder can produce and verify tags
    • If Alice and Bob share a key, Bob can verify Alice’s tag, but he could also have produced it himself
    • No non-repudiation: Alice can deny sending a message, and Bob can’t prove otherwise to a third party
  • Digital signatures are asymmetric: only the signer has the secret key
    • Anyone with the public key can verify, but only the signer can produce
    • Non-repudiation: once Alice signs a message, she can’t credibly deny it
    • A judge, a server, or any third party can verify the signature independently
  • MACs prove origin to someone who already trusts you
    • Signatures prove origin to anyone

Signatures as a Public-Key MAC

  • A digital signature scheme \(\mathcal{S} = (G, S, V)\) mirrors the MAC structure:
    • \(G\): probabilistic key generation, outputs \((pk, sk)\)
    • \(S\): probabilistic signing, \(\sigma \leftarrow S(sk, m)\)
    • \(V\): deterministic verification, \(V(pk, m, \sigma)\) outputs accept or reject
  • Correctness: \(\Pr[V(pk, m, S(sk, m)) = \texttt{accept}] = 1\)
  • \(\mathcal{S}\) is defined over \((\mathcal{M}, \Sigma)\)
    • All messages \(m\) lie in a finite message space \(\mathcal{M}\)
    • All signatures \(\sigma\) lie in a finite signature space \(\Sigma\)
  • Unlike a MAC, no shared secret is needed
    • You create a signature with your secret key
    • Anyone can verify that signature with your public key

Use Cases

  • Software distribution: Microsoft signs update \(U\) with its secret key
    • Each customer checks \(V(pk, U, \sigma) = \texttt{accept}\) before installing
    • Public key \(pk\) is obtained from the previous version, not from \(U\)
    • No shared keys, no trusted third party, just public key and signature!
  • Authenticated email (DKIM): domains sign every outgoing email
    • The corresponding public key is published in a DNS record
    • Recipients can verify if an email from notascam.com is authentic
  • Non-repudiation: once Alice signs, she can’t claim she didn’t send it
    • Anyone can verify the signature using her public key
    • This is stronger than MACs, and not always desirable
    • In law, electronic signature \(\neq\) cryptographic digital signature

UF-CMA for Signatures

The same security framework, a new setting.

What Changes in the Public-Key Setting

  • The MAC UF-CMA game from Lecture 04 transfers almost unchanged, but two asymmetries shape the signature version:
  • The adversary has the verification key
    • \(\mathcal{A}\) knows \(pk\) and can use it in their forgery strategy
    • Strictly more information than the MAC adversary, yet \(\mathcal{A}\) must still fail
  • We don’t need verification queries
    • \(\mathcal{A}\) has \(pk\) already, so they can verify anything themselves; no oracle needed
  • Aside: strong unforgeability forbids forgeries even on previously queried messages
    • Worth knowing the term exists, but we’ll generally stick to forgery on new messages

The Security Game

  • The challenger runs \((pk, sk) \leftarrow G()\) and sends \(pk\) to \(\mathcal{A}\)
    • \(\mathcal{A}\) is an efficient \(Q\)-query adversary
  • \(\mathcal{A}\) gets to query the challenger \(Q\) times
    • The \(i\)th signing query is a message \(m_i \in \mathcal{M}\)
    • The challenger computes \(\sigma_i \leftarrow S(sk, m_i)\) and sends \(\sigma_i\) to \(\mathcal{A}\)
  • Eventually, \(\mathcal{A}\) outputs a candidate forgery pair \((m, \sigma)\)
    • \(\mathcal{A}\) wins if \(V(pk, m, \sigma) = \texttt{accept}\) and \(m\) hasn’t been queried before
  • \(\text{SIG}_\text{adv}[\mathcal{A}, \mathcal{S}]\) must be negligible for all efficient adversaries
  • Secure signature schemes are existentially unforgeable under chosen message attack

Signature Security: Attack Game

Hash-and-Sign

  • Public key signature schemes typically work on short inputs (hash-and-sign extends the domain)
  • Hash functions extend the domain, as usual
    • Given \(\mathcal{S} = (G, S, V)\) over \((\mathcal{M}, \Sigma)\) where \(\mathcal{M}\) is short
    • Let \(H : \mathcal{M}' \to \mathcal{M}\) be a hash function (e.g. SHA-256)
    • \(S'(sk, m) = S(sk, H(m))\)
    • \(V'(pk, m, \sigma) = V(pk, H(m), \sigma)\)
  • Security: \(\text{SIG}_\text{adv}[\mathcal{A}, \mathcal{S}'] \leq \text{SIG}_\text{adv}[\mathcal{B}_S, \mathcal{S}] + \text{CR}_\text{adv}[\mathcal{B}_H, H]\)

RSA Signatures

Digital signatures with trapdoors.

Attempt 1: Textbook RSA Signatures

  • The naive approach: reuse the trapdoor in reverse
    • Sign \(m\) by computing \(\sigma = m^d \mod n\)
    • Verify by checking \(\sigma^e \mod n = m\)
  • Broken by multiplicative homomorphism
    • Given \(\sigma_1 = m_1^d\) and \(\sigma_2 = m_2^d\)
    • Compute \(\sigma = \sigma_1 \cdot \sigma_2 = (m_1 \cdot m_2)^d \mod n\)
    • This is a valid signature on \(m_1 \cdot m_2\) without knowing \(d\)
  • An existential forgery: \(\mathcal{A}\) wins the UF-CMA game
    • Request signatures on \(m_1\) and \(m_2\), forge a signature on their product
    • The algebraic structure of RSA is the attack surface, so we need to destroy it before signing
  • Given signatures \(\sigma_1\) on \(m_1\) and \(\sigma_2\) on \(m_2\), can you forge on \(m_1^2\)? On \(m_1 / m_2 \mod n\)? What about on \(m_1 + m_2\)?
    • Ironically, this is a desirable property for homomorphic encryption, but a fatal flaw for signatures

Attempt 2: PKCS#1 v1.5

  • Pre-process the message before applying \(m \mapsto m^d\):
    • Hash \(m\), then embed the hash inside a padded structure that fills \(\mathbb{Z}_n^*\)
    • Then sign the padded value with the textbook trapdoor
  • Deployed everywhere: this is what almost every X.509 certificate is signed with
  • But: no security proof
    • The FDH proof (next slide) breaks down for partial-domain hashes
    • The structure mostly destroys the homomorphism, but a careless verifier may not notice if the structure is wrong
  • Bleichenbacher’s 2006 signature-forgery attack exploits exactly that
    • Verifiers that don’t check the full padding accept forgeries the adversary builds without the secret key
    • Distinct from his 1998 encryption padding oracle (covered in CCA Security below)

Attempt 3: Full Domain Hash (FDH)

  • A cleaner fix: hash to the full RSA domain, then invert
    • The hash destroys the algebraic structure that enables the homomorphism, for real this time
  • Given a trapdoor permutation \(\mathcal{T} = (G, F, I)\) over \(\mathcal{X}\) and a hash \(H : \mathcal{M} \to \mathcal{X}\)
    • Sign: \(\sigma \leftarrow I(sk, H(m))\) (hash the message, then invert)
    • Verify: check if \(F(pk, \sigma) = H(m)\)
  • With RSA: \(\sigma = H(m)^d \mod n\), verify by checking \(\sigma^e \mod n = H(m)\)
  • \(\mathcal{S}_\text{FDH}\) is provably secure in the random oracle model (ROM)
    • The ROM from Lecture 04: treat \(H\) as a truly random function
    • Security reduces to the RSA assumption
  • But not actually deployed: PKCS#1 v1.5 was already entrenched by the time FDH had a clean proof

Attempt 4: RSA-PSS

  • RSA-PSS: the provably secure version that did get deployed
    • Adds a random salt: same FDH idea, but probabilistic
    • Provably reduces to RSA hardness in the ROM (Bellare-Rogaway 1996)
    • Standardised in RFC 8017; should be used for any new RSA signature application
  • Signatures are still ~256 bytes for 2048-bit RSA; the size cost is intrinsic to the modulus
  • RSA’s strong suit is verification: extremely fast (just one \(\sigma^e\) exponentiation)
    • Sign offline, verify online; ideal for code signing and X.509

Schnorr Signatures and ECDSA

Discrete log-based signatures.

Schnorr Signatures

  • Schnorr signatures are the cleanest discrete log-based scheme
    • Security reduces directly to the discrete log problem (in the ROM)
  • Setup: group \(\mathbb{G}\) of prime order \(q\) with generator \(g\), hash function \(H\)
    • Secret key: \(\alpha \xleftarrow{R} \mathbb{Z}_q\)
    • Public key: \(u = g^\alpha\)
  • Signing message \(m\):
    • Pick random \(\beta \xleftarrow{R} \mathbb{Z}_q\), compute \(u_t = g^\beta\) (the commitment)
    • Compute challenge \(c = H(m \| u_t)\)
    • Compute response \(\alpha_z = \beta - \alpha c \mod q\)
    • Signature: \(\sigma = (u_t, \alpha_z)\)
  • Verification: check that \(g^{\alpha_z} \cdot u^c = u_t\) where \(c = H(m \| u_t)\)
    • This works because \(g^{\beta - \alpha c} \cdot g^{\alpha c} = g^\beta = u_t\)
  • What would go wrong if the challenge were \(c = H(m)\) instead of \(c = H(m \| u_t)\)?

Schnorr and Fiat-Shamir

  • Schnorr was originally an identification protocol, a way for Alice to prove to Bob she knows \(\alpha\) without revealing it
  • It follows a 3-move shape called a Sigma protocol
    • Alice \(\to\) Bob: commitment \(u_t = g^\beta\) for fresh random \(\beta\)
    • Bob \(\to\) Alice: random challenge \(c \xleftarrow{R} \mathbb{Z}_q\)
    • Alice \(\to\) Bob: response \(\alpha_z = \beta - \alpha c\)
    • Bob accepts if \(g^{\alpha_z} \cdot u^c = u_t\)
  • Why does it need to be interactive? Bob’s challenge has to be unpredictable to Alice
    • If Alice could pick \(c\), she could choose \((\beta, c, \alpha_z)\) in any order that satisfies the verification equation and forge a transcript without knowing \(\alpha\)
    • The interactive challenge forces her to commit to \(u_t\) before she sees \(c\)

Schnorr and Fiat-Shamir (cont.)

  • Fiat-Shamir transform (1986): replace the live verifier with a hash
    • Alice computes \(c = H(m \| u_t)\) herself
    • In the ROM the hash output is unpredictable to Alice until \(u_t\) is fixed as input, so she can’t grind for a convenient \(c\)
    • The three-move dialogue collapses to a single transcript \(\sigma = (u_t, \alpha_z)\): a non-interactive signature
  • Why do we care? Most modern signatures (Schnorr, EdDSA/Ed25519, post-quantum ML-DSA) follow the same structure
    • Design a sound Sigma protocol, hash the challenge, get a UF-CMA-secure signature in the ROM

Schnorr: A Worked Example

  • Toy parameters: \(p = 23\), \(q = 11\) (the order-11 subgroup of \(\mathbb{Z}_{23}^*\)), generator \(g = 2\)
    • Check: \(2^{11} = 2048 \equiv 1 \mod 23\), so \(g\) has order \(q\) as required
  • Key generation
    • Secret \(\alpha = 3\)
    • Public \(u = g^\alpha = 2^3 = 8 \mod 23\)
  • Sign message \(m\) (assume the hash gives \(c = 4\)):
    • Pick \(\beta = 7\); commitment \(u_t = g^\beta = 2^7 = 128 \equiv 13 \mod 23\)
    • Response \(\alpha_z = \beta - \alpha c \mod q = 7 - 12 \equiv 6 \mod 11\)
    • Signature \(\sigma = (u_t, \alpha_z) = (13, 6)\)
  • Verify: compute \(g^{\alpha_z} \cdot u^c \mod p = 2^6 \cdot 8^4 \mod 23 = 18 \cdot 2 = 36 \equiv 13 \mod 23\)
    • Equal to \(u_t = 13\), so verification accepts
  • Real Schnorr uses primes hundreds of bits long; the algebra is identical

ECDSA

  • ECDSA is the standardised variant using elliptic curves
    • Used in TLS, code signing, cryptocurrency (Bitcoin, Ethereum)
    • Based on the same discrete log structure as Schnorr, but with a different construction
  • ECDSA signatures are short (64 bytes on a 256-bit curve, for 128-bit security)
    • Compared to 256+ bytes for RSA signatures
    • A significant advantage for bandwidth-constrained protocols

The Catastrophic Failure: Nonce Reuse

  • Both Schnorr and ECDSA require a fresh random nonce \(\beta\) for every signature
  • Nonce reuse is catastrophic: if the same \(\beta\) is used for two different messages \(m_1, m_2\):
    • The commitment \(u_t = g^\beta\) is identical in both signatures
    • The adversary has two equations with two unknowns (\(\alpha\) and \(\beta\))
    • They can solve for the secret key \(\alpha\)!
  • ECDSA’s algebra is shaped differently, but the consequence is identical
    • Two signatures with the same nonce → solve a linear system in two unknowns → recover the secret key
  • Of course, no self-respecting company would ever make this mistake
    • So this is purely a theoretical concern, right?
    • …right?

Sony PS3 ECDSA Attack (2010)

  • Sony made a tiny mistake in their ECDSA implementation for the PlayStation 3
    • They used the same nonce for every signature
    • The private signing key was recovered, enabling homebrew software
    • One constant nonce, total key compromise
  • Modern remediation: derive \(\beta\) deterministically from the message and key
    • RFC 6979 specifies \(\beta = \text{HMAC}(sk, m)\) for ECDSA
  • This is yet another instance of a general principle: randomness failure is catastrophic in cryptographic protocols
    • The same principle applies to nonce discipline for AEAD

PKI and Certificates

How does the verifier get the right public key?

The Trust Problem

  • Digital signatures are useless if the verifier has the wrong public key
    • If Mallory gives Bob her public key and claims it’s Alice’s…
    • Bob will accept Mallory’s signatures as if they came from Alice
  • Two simple alternatives, both with limits:
    • Embed the key: ship Alice’s \(pk\) inside Bob’s software
      • Works for software updates, but doesn’t scale
    • Trust on first use (TOFU): accept whatever key shows up the first time, then pin it and reject changes
      • This is what SSH does, and why “host key changed” warnings exist
  • Neither scales to “Bob has never met Alice and there is no installer”
    • Which is exactly the problem we face on the open web
      • How does your browser know the real \(pk\) for google.com?
      • Or, indeed, the real \(pk\) for crypto.eoin.ai?
    • For that, we need an outsourced trust anchor

Certificates

  • A certificate is a signature by a trusted authority over a public key binding
    • The CA verifies Alice’s identity
    • The CA signs a statement: “public key \(pk\) belongs to Alice”
    • The CA signs with its own secret key: \(\sigma_\text{CA} \leftarrow S(sk_\text{CA}, m)\)
    • The result \((m, \sigma_\text{CA})\) is Alice’s certificate
  • Bob verifies using the CA’s public key \(pk_\text{CA}\)
    • \(pk_\text{CA}\) is pre-installed in browsers and operating systems
  • Chain of trust: CAs can delegate to intermediate CAs
    • Root CA signs intermediate CA’s certificate
    • Intermediate CA signs end-entity certificates
    • Verification follows the chain up to a trusted root
  • Pause: a CA’s secret key leaks. What happens to the certificates it issued before the leak? After? Why is the answer different for the two?

When Trust Breaks: DigiNotar

  • The trust model’s critical weakness is not cryptographic
    • It’s the assumption that CAs are trustworthy: a governance problem, not a mathematical one
  • DigiNotar (2011): a Dutch CA was compromised
    • Attackers issued fraudulent certificates for google.com, *.google.com, and others
    • Used to intercept Gmail traffic of Iranian dissidents
    • The forged certificates were cryptographically valid
    • The fix was governance, not cryptography: browsers revoked the root, and the industry agreed certificate issuance had to become auditable
  • Certificate Transparency (CT) is the structural fix
    • All issued certificates must be logged in public, append-only logs
    • Anyone can audit the logs for fraudulent certificates
    • Browsers can refuse certificates that aren’t logged

CCA Security

The right security target for encryption.

Motivation: Why IND-CPA is Not Enough

  • IND-CPA security protects against passive adversaries
    • The adversary can encrypt arbitrary messages, but nothing more
  • Real adversaries are active: they can submit ciphertexts for decryption
    • A server’s error response to a malformed ciphertext is information
    • Even “decryption failed” vs “padding error” is a useful oracle

The Bleichenbacher Padding Oracle (1998)

  • Setting: a server receiving PKCS#1 v1.5 RSA ciphertexts (e.g. an SSL handshake)
    • Decrypt, check the padding format, return “ok” or “padding error”
  • This looks harmless: no plaintext ever leaves the server, just a single bit
  • But the bit is an oracle on the underlying plaintext
    • PKCS#1 v1.5 padding starts with the bytes 0x00 0x02; “valid padding” means the decrypted RSA output starts with that prefix
    • So “ok” tells the adversary something about the high-order bits of \(m\)

Bleichenbacher’s Iteration

  • Tool: RSA’s multiplicative homomorphism. Submit \(c \cdot r^e\), and the server decrypts to \(r \cdot m \mod n\)
  • Each chosen \(r\) asks the oracle: “does \(r \cdot m \mod n\) start with 0x00 0x02?”
    • A “yes” response constrains \(r \cdot m\) to a known interval, hence constrains \(m\)
  • Iterate over millions of carefully chosen \(r\):
    • Each “yes” response halves (roughly) the range of possible \(m\)
    • After \(\sim 2^{20}\) queries, \(m\) is fully recovered
  • The adversary never sees decrypted plaintext; just yes/no answers
    • This is exactly what a CCA2 decryption oracle provides

IND-CCA2: Formal Definition

  • We’ve looked at several notions of security based on ciphertext indistinguishability:
    • IND-CPA: adversary can encrypt arbitrary messages
    • IND-CCA1: adversary can also decrypt, but only before the challenge (non-adaptive)
    • IND-CCA2: adversary can decrypt before and after the challenge (adaptive)
  • Each level gives \(\mathcal{A}\) strictly more power:
    • IND-CCA2 \(\implies\) IND-CCA1 \(\implies\) IND-CPA

Public Key CCA Attack Game

  • Let \(\mathcal{E} = (G, E, D)\), defined over message space \(\mathcal{M}\) and ciphertext space \(\mathcal{C}\)
  • Two experiments for \(b \in \{0, 1\}\)
  • Challenger generates \((pk, sk) \leftarrow G()\) and sends \(pk\) to \(\mathcal{A}\)
  • \(\mathcal{A}\) may submit encryption queries
    • Submit \((m_{i0}, m_{i1}) \in \mathcal{M}^2\), receive \(c_i \leftarrow E(pk, m_{ib})\)
  • \(\mathcal{A}\) may submit decryption queries
    • Submit \(\hat{c}_j \in \mathcal{C}\), receive \(\hat{m}_j = D(sk, \hat{c}_j)\)
    • \(\hat{c}_j\) can’t be the result of an encryption query: \(\hat{c}_j \notin \{c_1, c_2, \ldots\}\)
  • \(\mathcal{A}\) outputs a bit \(\hat{b} \in \{0, 1\}\)
  • Let \(W_b\) be the event that \(\mathcal{A}\) outputs \(1\) in experiment \(b\); the advantage is \(\text{CCA}_\text{adv}[\mathcal{A}, \mathcal{E}] = |\Pr[W_0] - \Pr[W_1]|\)
  • \(\mathcal{E}\) is CCA-secure if \(\text{CCA}_\text{adv}[\mathcal{A}, \mathcal{E}]\) is negligible for all efficient \(\mathcal{A}\)

CCA Security: Attack Game

CCA and Malleability

  • Plenty of ciphers we’ve studied are malleable
    • Given a ciphertext, we can create a new ciphertext for a related plaintext
    • With a stream cipher: XORing bits of the ciphertext flips bits of the plaintext
    • With RSA: multiplying ciphertexts multiplies plaintexts
  • If ciphertexts are malleable, then CCA security fails
    • The adversary modifies the challenge ciphertext and submits it for decryption
    • The decryption oracle reveals information about the original plaintext
  • CCA security \(\implies\) non-malleability
    • We already know how to achieve this for symmetric ciphers: Encrypt-then-MAC (Lecture 04)
    • For public key encryption: we need OAEP

RSA-OAEP

Closing the loop on textbook RSA.

The Problem with Textbook RSA

  • In Lecture 05, we flagged that textbook RSA (\(c = m^e \mod n\)) is deterministic
    • Therefore not IND-CPA secure, let alone IND-CCA2
  • RSA’s multiplicative homomorphism makes it malleable
    • Given \(c = m^e\), compute \(c' = r^e \cdot c = (rm)^e\) for any chosen \(r\)
    • Submit \(c'\) for decryption, get \(rm\), divide by \(r\) to recover \(m\)

OAEP: Randomised Padding

  • Optimal Asymmetric Encryption Padding (OAEP) randomises every encryption
  • The encryptor samples a fresh seed \(r\) each time
    • \(r \xleftarrow{R} \{0,1\}^{\text{hLen}}\), where \(\text{hLen}\) is the hash output length (e.g. 256 bits for SHA-256)
    • This randomness is what makes the encryption non-deterministic
  • The data block \(z\) packages the message inside a structured payload
    • \(z = (\ell \| \texttt{00}\ldots\texttt{01} \| m)\), where \(\ell\) is a fixed integrity prefix used to detect tampering at decryption
    • \(z\) is sized to fill the rest of the RSA modulus: \(|z| = t - \text{hLen} - 8\) bits, where \(t\) is the bit-length of \(n\)
  • Two independent hash functions sit in a Feistel-like structure
    • \(W : \{0,1\}^{\text{hLen}} \to \{0,1\}^{|z|}\) expands the seed to mask the data block
    • \(H : \{0,1\}^{|z|} \to \{0,1\}^{\text{hLen}}\) compresses the masked data block to mask the seed
  • The padded value \(x\) is the input to RSA: \(c = x^e \mod n\)
    • \(x\) depends on both \(m\) and the random \(r\), so the same plaintext yields different ciphertexts each time

OAEP: Padding Algorithm

  • \(P(m, r, \ell)\) produces the padded value \(x\) in four steps:
  • Build the data block: \(z \leftarrow \ell \| \texttt{00}\ldots\texttt{01} \| m\)
    • Sized so that \(|z| = t - \text{hLen} - 8\) bits
  • Mask the data block with the expanded seed: \(z' \leftarrow z \oplus W(r)\)
  • Mask the seed with a hash of the masked data block: \(r' \leftarrow r \oplus H(z')\)
  • Concatenate to form the RSA input: \(x \leftarrow \texttt{00}^8 \| r' \| z'\)
    • The leading zero byte ensures \(x < n\); total length \(|x| = t\) bits
  • Unpadding reverses each step and rejects any input where the parsed \(\ell\) doesn’t match

OAEP: Padding Structure

OAEP: Unpadding Structure

Security of RSA-OAEP

  • RSA-OAEP is IND-CCA2 secure in the random oracle model
    • Security requires RSA to be a partial one-way function
    • If RSA is one-way (the standard assumption), it is also partial one-way
    • So RSA-OAEP is CCA-secure under the standard RSA assumption
  • This closes the loop from Lecture 05:
    • RSA trapdoor permutation (the primitive)
    • Textbook RSA encryption (IND-CPA broken, deterministic)
    • RSA-OAEP (IND-CCA2 secure, randomised)
  • The progression illustrates that randomisation is essential for public key encryption security
    • The same principle as IND-CPA requiring randomised encryption in the symmetric setting
  • The Web Crypto API provides an implementation of RSA-OAEP
    • Please don’t attempt to roll your own…

Authenticated Encryption

From CCA security to practical AEAD.

From CCA to Authenticated Encryption

  • We just saw two approaches to CCA-secure encryption:
    • RSA-OAEP: randomised padding for public-key encryption
    • But what about symmetric encryption?
  • In Lecture 04, we stated the Encrypt-then-MAC theorem:
    • Combining a CPA-secure cipher with a secure MAC via Encrypt-then-MAC achieves IND-CCA2 security
  • Earlier in this lecture, we defined IND-CCA2 formally and saw why it matters
    • Active adversaries with decryption oracles can break CPA-secure ciphers
    • The Bleichenbacher attack demonstrated this in practice
  • Now let’s prove the theorem

Recall: The CCA Theorem

  • In Lecture 04, we stated: Encrypt-then-MAC with a CPA-secure cipher and a secure MAC achieves IND-CCA2 security
  • The argument has two steps:
    • Step 1: The MAC prevents the adversary from using the decryption oracle effectively
    • Step 2: Without useful decryption queries, the adversary faces only CPA security

Step 1: The MAC Neuters the Decryption Oracle

  • In the CCA2 game, the adversary can submit ciphertexts \((c, t)\) for decryption
    • But they can’t submit any \((c_i, t_i)\) received from an encryption query
  • For any other \((c', t')\), the MAC verification \(V(k_m, c', t')\) must pass
    • If the MAC is secure (UF-CMA), the adversary can’t produce a valid tag for a ciphertext they didn’t receive
    • The probability of a valid forgery is \(\text{MAC}_\text{adv}[\mathcal{A}, \mathcal{I}]\), which is negligible
  • So with overwhelming probability, every decryption query returns reject
    • The decryption oracle gives the adversary no useful information!

Step 2: CPA Security Handles the Rest

  • With the decryption oracle effectively disabled, the adversary is left with:
    • The public parameters
    • Encryption queries (which they can make freely)
    • Decryption queries that always return reject (useless)
  • This is functionally equivalent to the CPA game
    • The CPA-secure cipher handles this case
  • Formally: \(\text{CCA}_\text{adv}[\mathcal{A}, \mathcal{E}_\text{EtM}] \leq \text{CPA}_\text{adv}[\mathcal{B}, \mathcal{E}] + \text{MAC}_\text{adv}[\mathcal{C}, \mathcal{I}]\)
    • Both terms are negligible, so the combined advantage is negligible
  • This is why Encrypt-then-MAC is the gold standard for symmetric authenticated encryption

Encrypt-then-MAC

MAC-then-Encrypt

  • The alternative composition: compute a tag on the plaintext, then encrypt everything
    • \(t \leftarrow S(k_m, m)\), then \(c \leftarrow E(k_e, m \| t)\)
  • This is not generally CCA-secure
    • The encryption layer hides the tag from the verifier
    • The decryptor must remove padding and parse the plaintext before it can check the tag
  • This creates a padding oracle vulnerability:
    • If the server leaks whether the padding is valid (before checking the MAC), the adversary gets an oracle
    • Lucky 13 (2013) and Vaudenay (2002) exploited exactly this in TLS 1.0-1.2 CBC suites; the related POODLE attack (2014) targeted SSL 3.0
    • Even a single bit of information (“valid padding” vs “invalid padding”) can be enough
  • TLS 1.3 dropped all CBC cipher suites, requiring AEAD-only
    • Encrypt-then-MAC (or integrated AEAD) avoids the problem entirely

MAC-then-Encrypt

Nonce-Based AEAD

  • In practice, authenticated encryption is packaged as a single primitive: AEAD
    • Authenticated Encryption with Associated Data
  • A nonce-based AEAD cipher \(\mathcal{E} = (E, D)\) is defined over \((\mathcal{K}, \mathcal{M}, \mathcal{C}, \mathcal{D}, \mathcal{N})\):
    • \(E(k, m, d, n) \to c\): encrypt message \(m\) with associated data \(d\) and nonce \(n\)
    • \(D(k, c, d, n) \to m\) or reject: decrypt or reject if tampered
  • Correctness: for all \(k, m, d, n\): \(D(k, E(k, m, d, n), d, n) = m\)
  • Security requires two properties:
    • Ciphertext indistinguishability: the ciphertext reveals nothing about the plaintext
    • Ciphertext integrity: no efficient adversary can produce a valid ciphertext that wasn’t generated by the encryption oracle
  • The nonce \(n\) must be unique per encryption under the same key
    • It need not be secret, but repeating it is catastrophic

AEAD: Operational Details

AES-GCM internals and nonce misuse resistance.

GCM Structure

  • Galois Counter Mode (GCM) is the most widely deployed AEAD cipher
    • Standardized by NIST in 2007; used in TLS 1.3, IPsec, and many other protocols
  • GCM follows encrypt-then-MAC internally:
    • Encryption: AES in counter mode (CTR)
    • Authentication: Carter-Wegman MAC using GHASH over \(\text{GF}(2^{128})\)
  • The encryption key is \(k\) itself; the GHASH authentication subkey \(H\) is derived from it
    • \(H \leftarrow E(k, 0^{128})\) (encrypt the zero block); standard NIST naming, distinct from the OAEP/hash \(H\) above
  • Within this section \(H\) refers to the GHASH subkey only; the OAEP hash function from RSA-OAEP is out of scope here

GCM Encryption

  • Input: key \(k\), message \(m\), associated data \(d\), nonce \(N \in \{0, 1\}^{96}\)
  • Derive the GHASH subkey: \(H \leftarrow E(k, 0^{128})\)
    • One AES key drives both roles: \(k\) encrypts data, \(H\) authenticates it
  • Build the initial counter block: \(x \leftarrow N \| 0^{31} \| 1 \in \{0, 1\}^{128}\)
    • \(x\) is reserved as the per-message tag mask; encryption counters live one above it
  • Encrypt under CTR starting at \(x + 1\): \(c \leftarrow \text{CTR-Encrypt}(k, x + 1, m)\)
    • Standard CTR keystream: each plaintext block XORed with \(E(k, x+i)\)
  • Zero-pad the AAD and ciphertext to 128-bit boundaries: \(d' \leftarrow \text{ZeroPad}(d, 128)\), \(c' \leftarrow \text{ZeroPad}(c, 128)\)
    • GHASH’s polynomial evaluation must align to block boundaries
  • Authenticate everything with GHASH: \(h \leftarrow \text{GHASH}(H,\; d' \| c' \| \text{length}(d) \| \text{length}(c))\)
    • The 64-bit length fields stop an attacker from shifting bytes between the AAD and ciphertext sections
  • Mask the GHASH output to produce the tag: \(t \leftarrow h \oplus E(k, x)\)
  • Return \((c, t)\)

GCM Encryption Structure

GCM: Nonces and Data Limits

  • The NIST spec (SP 800-38D) allows IV lengths from 1 bit to \(2^{64}-1\) bits, but 96 bits is strongly recommended
    • With \(|N| = 96\) the initial counter is built deterministically: \(J_0 = N \| 0^{31} \| 1\)
    • Any other length needs \(J_0 = \text{GHASH}(H, N \| \text{pad} \| \text{length}(N))\), which is more expensive AND can collide (GHASH isn’t a permutation)
  • Nonce strategy matters; the two sane options have different consequences
    • Sequential (counter): no collision until \(2^{96}\), effectively never; preferred for high-throughput systems
    • Random 96-bit nonces: birthday bound bites at \(\sim 2^{48}\) samples, with collision probability \(\sim 2^{-32}\) at \(2^{32}\) messages
  • Per-message limit: at most \(2^{32}\) blocks (\(\approx 64\) GB) per single encryption
    • The CTR counter has only 32 free bits before it wraps to \(J_0\) and collides with the tag mask

GCM: Nonces and Data Limits (cont.)

  • Per-key limit: rekey before \(2^{32}\) messages; this applies to both nonce strategies, but for different reasons
    • Random IVs: birthday-collision probability climbs past \(2^{-32}\) around \(2^{32}\) messages
    • Sequential IVs avoid birthday collisions, but GHASH’s forgery advantage scales with the total blocks authenticated under the same subkey \(H\)
    • At \(\sim 2^{32}\) messages of up to \(2^{32}\) blocks each (\(\sigma \approx 2^{64}\) total blocks), the bound \(\sigma / 2^{128}\) reaches \(2^{-64}\), NIST’s rekey threshold
  • Why pick sequential when the worst-case bound matches?
    • The sequential bound assumes max-sized messages; for typical traffic (a few KB each) it lasts far longer
    • Random adds the birthday risk on top of the forgery bound, so its safe envelope is strictly smaller
    • A random-IV collision is catastrophic (identical keystreams, identical tag masks, immediate forgery), while the sequential GHASH bound is a slow probabilistic creep
  • Standard recommendation: 96-bit sequential nonce, rekey after \(2^{32}\) messages (aggregate per key), and cap each single encryption at \(\sim 64\) GB of plaintext

GHASH

  • GHASH is a Carter-Wegman MAC over \(\text{GF}(2^{128})\)
    • Carter-Wegman recap (Lecture 04): a universal hash function whose output is masked by a fresh PRF value, giving a one-time MAC tag for each message
    • Here the UHF is polynomial evaluation in \(\text{GF}(2^{128})\) and the PRF mask is \(E(k, x)\) from the GCM tag step
  • \(\text{GF}(2^{128})\) is a Galois field defined by an irreducible polynomial
    • \(g(X) = X^{128} + X^7 + X^2 + X + 1\)
    • Elements are 128-bit bitstrings; addition is XOR, multiplication is modulo \(g(X)\)
  • \(\text{GHASH}(k, z)\) for \(z = (z_0, z_1, \ldots, z_{v-1}) \in \text{GF}(2^{128})^v\):
    • \(z_0 \cdot k^v + z_1 \cdot k^{v-1} + \ldots + z_{v-1} \cdot k \in \text{GF}(2^{128})\)
    • Evaluable incrementally via Horner’s method (streaming)
  • Modern processors have hardware support for Galois field multiplication
    • AES-GCM is extremely fast with AES-NI and PCLMULQDQ instructions

ChaCha20-Poly1305

  • The alternative when AES hardware support is unavailable
    • ChaCha20 (stream cipher from Lecture 02) + Poly1305 (one-time MAC)
    • Combined as an AEAD cipher in RFC 8439
  • Poly1305 is a one-time MAC based on polynomial evaluation
    • The same polynomial MAC construction from Lecture 04
    • One-time key derived from ChaCha20’s keystream for each message
  • Both AES-GCM and ChaCha20-Poly1305 are available in TLS 1.3

Key Encapsulation Mechanisms

The public-key abstraction that makes hybrid encryption clean.

What is a KEM?

  • A key encapsulation mechanism \(\mathcal{K} = (G, \text{Encaps}, \text{Decaps})\) over a symmetric key space \(\mathcal{K}_\text{sym}\):
    • \(G() \to (pk, sk)\): probabilistic key generation
    • \(\text{Encaps}(pk) \to (k, c)\): probabilistic; generates and encapsulates a fresh key \(k \in \mathcal{K}_\text{sym}\)
    • \(\text{Decaps}(sk, c) \to k\) or \(\texttt{reject}\): deterministic
  • Correctness: if \((k, c) \leftarrow \text{Encaps}(pk)\), then \(\text{Decaps}(sk, c) = k\)
  • Why a separate primitive from PKE?
    • PKE encrypts arbitrary messages; KEMs encapsulate random keys only
    • Weaker requirement, easier to prove secure, composes cleanly with any symmetric cipher

KEM Security: IND-CCA

  • Adapted from the CCA Security game above:
    • Challenger generates \((pk, sk) \leftarrow G()\) and computes \((k_0, c^*) \leftarrow \text{Encaps}(pk)\)
    • Samples \(k_1 \xleftarrow{R} \mathcal{K}_\text{sym}\) uniformly
    • In experiment \(b\): send \((k_b, c^*)\) to \(\mathcal{A}\)
    • \(\mathcal{A}\) may make decapsulation queries \(\hat{c} \neq c^*\)
    • \(\mathcal{A}\) outputs guess \(\hat{b}\)
  • \(\text{KEM}_\text{adv}[\mathcal{A}, \mathcal{K}] = |\Pr[W_0] - \Pr[W_1]|\) must be negligible
  • Plain English: \(\mathcal{A}\) can’t tell a real encapsulated key from a uniform random one

KEM Security: Attack Game

The KEM/DEM Composition Theorem

  • Theorem (Boneh-Shoup 12.2): if \(\mathcal{K}\) is a CCA-secure KEM and \(\mathcal{E}_s\) is a CCA-secure symmetric cipher, the hybrid scheme \(\mathcal{E}_\text{hy}\) is CCA-secure

\[ \begin{aligned} &\textbf{Encrypt}(pk, m): \\ &\quad (k, c_\text{KEM}) \leftarrow \text{Encaps}(pk) \\ &\quad c_\text{DEM} \leftarrow E_s(k, m) \\ &\quad \textbf{return } (c_\text{KEM}, c_\text{DEM}) \\[4pt] &\textbf{Decrypt}(sk, (c_\text{KEM}, c_\text{DEM})): \\ &\quad k \leftarrow \text{Decaps}(sk, c_\text{KEM}) \\ &\quad \textbf{return } D_s(k, c_\text{DEM}) \end{aligned} \]

  • Bound: \(\text{CCA}_\text{adv}[\mathcal{A}, \mathcal{E}_\text{hy}] \leq \text{KEM}_\text{adv}[\mathcal{B}, \mathcal{K}] + \text{CCA}_\text{adv}[\mathcal{C}, \mathcal{E}_s]\)

KEM/DEM Hybrid Encryption

Why the Composition Works

  • Same two-step proof template as the Encrypt-then-MAC argument above
    • Step 1: replace the real encapsulated key with a uniform random one (KEM CCA security)
    • Step 2: with an independent random key, \(\mathcal{A}\) now faces a CCA-secure DEM in isolation
  • Each layer discharges one cryptographic assumption, leaving an easier game beneath
  • The same shape recurs in every modern hybrid encryption proof

DHKEM

The KEM behind almost every deployed hybrid scheme.

ElGamal: Diffie-Hellman as Encryption

  • ElGamal is Diffie-Hellman with asymmetric roles
    • In DH key exchange, both parties pick fresh shares and exchange them live to compute \(g^{\alpha\beta}\)
    • In ElGamal, the recipient’s share \(g^\alpha\) is published once as their long-term public key; the sender does a one-sided DH against it with a fresh \(g^\beta\) per message
  • The consequence: no round-trip and no liveness requirement
    • The recipient can be offline when encryption happens, and decrypts whenever they come back
    • Sender’s \(g^\beta\) travels with the ciphertext; recipient combines it with their static \(\alpha\) to recover \(g^{\alpha\beta}\)
  • The shared \(g^{\alpha\beta}\) acts as the encapsulated secret
    • But the raw DH output is a structured group element, not a uniform key

Hashed ElGamal as a KEM

  • Hashed ElGamal KEM: extract a uniform key from the structured DH output via a hash
    • \(G()\): sample \(\alpha \xleftarrow{R} \mathbb{Z}_q\), set \(pk \leftarrow g^\alpha\), \(sk \leftarrow \alpha\)
    • \(\text{Encaps}(pk)\): sample \(\beta \xleftarrow{R} \mathbb{Z}_q\); set \(c \leftarrow g^\beta\), \(k \leftarrow H(g^{\alpha\beta}, g^\beta)\)
    • \(\text{Decaps}(sk, c)\): compute \(k \leftarrow H(c^\alpha, c)\)
  • Including \(g^\beta\) in the hash binds the key to the encapsulation
  • In practice \(H\) is HKDF (covered in L07)
  • When instantiated with X25519 and HKDF-SHA256, this is exactly the DHKEM specified by HPKE

HPKE

Hybrid public-key encryption: RFC 9180.

HPKE Overview

  • Hybrid Public Key Encryption (HPKE) (RFC 9180) composes a KEM, a KDF and an AEAD into a complete hybrid encryption scheme
  • Three stages: KEM produces a shared secret; KDF derives keying material; AEAD encrypts the data
  • Sender setup returns an encapsulation \(\text{enc}\) and an encryption context; receiver setup re-derives the same context from \(\text{enc}\) and their secret key
  • The context manages nonces and supports streaming multiple ciphertexts under one key

HPKE: Three-Stage Pipeline

HPKE Key Schedule

  • Bridges the KEM output to AEAD inputs in four labeled HKDF calls
  • Extract a master secret from the shared secret and any PSK:
    • \(\text{secret} \leftarrow \text{LabeledExtract}(\text{shared_secret}, \text{“secret”}, \text{psk})\)
  • Expand into the AEAD key:
    • \(\text{key} \leftarrow \text{LabeledExpand}(\text{secret}, \text{“key”}, L_k)\)
  • Expand into the base nonce:
    • \(\text{base_nonce} \leftarrow \text{LabeledExpand}(\text{secret}, \text{“base_nonce”}, L_n)\)
  • Expand into an exporter secret for application-specific keying:
    • \(\text{exporter_secret} \leftarrow \text{LabeledExpand}(\text{secret}, \text{“exp”}, L_h)\)
  • All \(\text{Labeled}\) operations include a ciphersuite identifier for domain separation
  • Per-message nonce for sequence counter \(i\):
    • \(n_i = \text{base_nonce} \oplus i\)

Cryptographic Agility

  • Cryptographic agility: the ability to swap one cryptographic primitive for another without redesigning the system around it
  • Why we need it
    • Algorithms break: MD5 and SHA-1 (collisions), RSA-512 (factoring), DES (key length), RC4 (biases)
    • Standards evolve: NIST/IETF deprecations, new modes, new families (e.g. ML-KEM, ML-DSA replacing RSA/ECC under quantum threat)
    • Hardware shifts: AES-NI, PCLMULQDQ, SHA extensions changed which primitives are fastest
    • Without agility, every successor primitive becomes a forklift upgrade

Cryptographic Agility (cont.)

  • What it looks like in practice
    • Algorithm identifiers in protocols (TLS ciphersuite IDs, X.509 OIDs, JOSE alg, HPKE ciphersuite IDs)
    • Negotiation so endpoints converge on a mutually supported algorithm
    • Hybrid constructions for transitions (X25519Kyber768 runs classical and post-quantum in parallel)
    • Public registries (IANA, NIST) so identifiers are interoperable
  • The cost: complexity and downgrade attacks
    • An active adversary forces the weakest option both endpoints support (Logjam, FREAK, POODLE all exploited this)
    • Mitigations: deprecation lists, version pinning, signed transcript hashes that prevent rollback
  • HPKE is a textbook example of agility-by-design: every component is selected by one identifier from a public registry

HPKE Ciphersuites

  • An HPKE ciphersuite is a triple \((\text{KEM}, \text{KDF}, \text{AEAD})\)
    • E.g. \((\text{DHKEM(X25519, HKDF-SHA256)}, \text{HKDF-SHA256}, \text{AES-128-GCM})\)
  • IANA maintains a registry mapping 16-bit identifiers to algorithms in each category
  • KDFs are limited: HKDF-SHA256, HKDF-SHA384, HKDF-SHA512
  • AEADs are limited: AES-128-GCM, AES-256-GCM, ChaCha20-Poly1305, “Export-only”
  • KEMs have more variety
    • DHKEM over X25519, X448, P-256, P-384, P-521
    • Post-quantum: X25519Kyber768 hybrid, ML-KEM family
  • Be wary of downgrade attacks during ciphersuite negotiation

HPKE Modes

Mode Extra input Sender auth Typical use case
Base (0x00) None No Anonymous (TLS-ECH, OHTTP)
PSK (0x01) PSK + PSK_ID PSK only IoT bootstrapping
Auth (0x02) Sender static key Yes Secure logging
Auth-PSK (0x03) Both Yes Hardened channels
  • Base: only the recipient’s \(pk\) is used; the sender is anonymous
  • PSK: a pre-shared symmetric key (e.g. from device provisioning, or established out-of-band) is mixed into the key schedule alongside the KEM output, giving a second layer of security if the KEM is broken or the recipient’s static key leaks
  • Auth: the sender contributes their static key in the DH; the recipient learns who sent it
  • The key schedule handles all four uniformly (PSK defaults to empty, sender key omitted in Base/PSK)

HPKE Security

  • HPKE provides IND-CCA2 in all four modes
    • For DHKEM variants, the proof is in the random oracle model under Gap-CDH
    • Gap-CDH = CDH plus access to a DDH oracle: you have to compute \(g^{\alpha\beta}\) from \((g^\alpha, g^\beta)\), but you’re allowed to ask “is this triple a DH triple?” along the way
    • Slightly stronger than CDH, weaker than DDH, still believed hard; the deeper analysis is in L08
    • Foundation: the KEM/DEM composition theorem above
  • The AEAD layer carries over its standard guarantees
    • Ciphertext indistinguishability and ciphertext integrity
  • Nonce management is internal: the sender must not exceed \(2^{L_n}\) messages per context, but the protocol enforces this; the caller does not

HPKE Forward Secrecy

  • HPKE is asymmetric in its forward-secrecy guarantees
  • Sender compromise: forward secret
    • The sender’s ephemeral key is destroyed after encapsulation; nobody can re-derive past keys
  • Recipient compromise: not forward secret
    • The recipient’s static key persists; if it leaks, all past ciphertexts to that key are decryptable
  • Why the asymmetry? Receivers need a long-lived key to decrypt incoming messages; senders only ever need their key once
  • For full forward secrecy in both directions, use an interactive protocol (TLS 1.3 with ephemeral DH on both sides). HPKE is one-shot
  • Replay protection is protocol-dependent; HPKE itself does not prevent replay

Nonce Misuse Resistance and Key Commitment

Two AEAD edge cases worth knowing.

AES-GCM-SIV

  • Standard AES-GCM has no nonce misuse resistance
    • Nonce reuse catastrophically breaks both confidentiality and integrity (Lecture 04)
  • AES-GCM-SIV (RFC 8452) protects against nonce reuse via the Synthetic IV (SIV) construction
    • Derive a tag from (nonce, AAD, plaintext) using POLYVAL (a GHASH variant)
    • Use the tag as the CTR-mode IV; encryption depends on the entire input

\[ \begin{aligned} &(k_\text{auth}, k_\text{enc}) \leftarrow \text{DeriveKeys}(k, N) \\ &s \leftarrow \text{POLYVAL}(k_\text{auth}, d, m) \oplus N \\ &\text{tag} \leftarrow E(k_\text{enc}, s) \\ &c \leftarrow \text{AES-CTR}(k_\text{enc}, \text{tag}, m) \\ &\textbf{return } (c, \text{tag}) \end{aligned} \]

  • Keys are derived per-nonce, adding extra isolation between sessions

AES-GCM-SIV Encryption Structure

AES-GCM-SIV: Properties

  • If the nonce repeats but the plaintext differs:
    • POLYVAL output differs (it depends on the plaintext), so the tag differs
    • Different tags mean different CTR IVs, so the ciphertexts differ
    • Confidentiality is preserved
  • If both nonce and plaintext repeat:
    • The ciphertext is identical, leaking only that the same message was sent twice
  • Authentication is never broken by nonce reuse (unlike standard GCM)
  • Cost: two passes over the data (POLYVAL + CTR), slightly slower than GCM
    • Worthwhile when nonce uniqueness cannot be guaranteed
    • Supported in BoringSSL, the Web Crypto API, modern TLS stacks

Key Commitment

  • Key commitment: a ciphertext binds to exactly one key
    • Negligible probability that the same \((c, t, d, n)\) decrypts successfully under two distinct keys \(k_1 \neq k_2\)
  • Standard AEAD security (IND-CCA2) does not guarantee this
    • The security game gives the adversary only one key; nothing constrains multi-key behaviour
  • GCM fails because GHASH is a polynomial MAC over \(\text{GF}(2^{128})\)
    • An adversary holding two keys can craft a ciphertext that satisfies both polynomial evaluations simultaneously
  • Invisible salamanders (Dodis et al., 2022) exploited this in Facebook’s message-franking
    • An encrypted message decrypted to different content under different keys, both with valid tags
    • Used to frame other users in abuse-report flows

Fixing Key Commitment

  • KC-GCM: a simple wrapper that makes GCM key-committing
    • Encrypt an all-zero block as the first plaintext block
    • On decryption, check that the first block decrypts to \(0^{128}\); reject if not
    • Different keys produce different AES outputs on a fixed input (PRP security); collisions are negligible
  • Alternative: include \(\text{HMAC}(k, \text{“commitment”})\) alongside the ciphertext
  • ChaCha20-Poly1305 has the same problem (Poly1305 is also polynomial)
  • Design rule: if your protocol involves multiple keys per ciphertext (message franking, key rotation, multi-device sync), use a committing AEAD
  • The check must be constant-time to avoid side-channel leaks

Conclusion

What did we learn?

So, what did we learn?

  • Digital signatures: the \((G, S, V)\) triple and UF-CMA security
    • RSA failure cascade: textbook → PKCS#1 v1.5 (deployed but no proof) → FDH (provable in ROM) → RSA-PSS (provable and deployed)
    • Schnorr and ECDSA: discrete-log signatures, Fiat-Shamir, and the nonce-reuse cliff
  • PKI and certificates: trust as governance, not cryptography
    • DigiNotar showed the failure mode; Certificate Transparency is the structural fix
  • CCA security: why IND-CPA is not enough
    • Bleichenbacher’s single-bit padding oracle recovers the plaintext
    • Malleability implies CCA failure; non-malleability is the real target
  • RSA-OAEP: randomised padding closes the textbook-RSA loop, IND-CCA2 in the ROM

So, what did we learn? (contd.)

  • Encrypt-then-MAC: the proof object behind every modern symmetric AEAD
    • MAC neuters the decryption oracle; CPA security handles the rest
    • M-t-E and the padding-oracle vulnerability that broke TLS CBC
  • AEAD in practice: AES-GCM, ChaCha20-Poly1305, GHASH polynomial MAC
  • KEM abstraction: \((G, \text{Encaps}, \text{Decaps})\), IND-CCA, KEM/DEM composition theorem
    • Hashed ElGamal as the canonical KEM, instantiated as DHKEM in HPKE
  • HPKE (RFC 9180): KEM + KDF + AEAD as a single standardised hybrid primitive
    • Four modes; IND-CCA2; asymmetric forward secrecy
  • Operational fragility: AES-GCM-SIV for nonce-misuse resistance; KC-GCM for key commitment

Where Do We Go from Here?

  • This was the last examinable lecture; the EPIC project is what every primitive in this lecture is for
  • L07 (operational stack): HKDF and password hashing
  • Weeks 8, 9 and 10: full focus on the EPIC
    • Deeper HPKE engineering
    • We might vote on some optional topics based on interest and time:
      • Post-quantum KEMs and signatures (ML-KEM, ML-DSA, SLH-DSA)
      • Cryptography for user authentication
      • Secure messaging protocols (Signal)
      • Or anything else you want to see!
  • Cryptography is a huge field. There’s a lot more to explore if you’re interested!
    • I’ll share some resources for further reading during the next few weeks
    • I’ll also recommend some CTFs for hands-on practice with cryptanalysis!

For Next Time

  • Complete some assigned reading:
    • Boneh and Shoup, Chapters 9 (authenticated encryption), 12 (KEMs and hybrid PKE), and 18 (signatures)
  • And some optional reading for next week (please don’t prioritise this over the exam!):

Questions?

Ask now, catch me after class, or email eoin@eoin.ai