The MATH behind the scenes:

Kyber (ML-KEM) + Dilithium (ML-DSA): A Practical Post-Quantum Handshake 

Quantum computers threaten today’s most widely used public-key cryptography (RSA and classical elliptic curves) by enabling efficient attacks on their underlying math. Post-quantum cryptography (PQC) replaces those assumptions with problems believed to remain hard even for quantum adversaries.

Two flagship PQC families are:

  • Kyber (standardized as ML-KEM): a Key Encapsulation Mechanism (KEM) used to establish a shared secret.

  • Dilithium (standardized as ML-DSA): a Digital Signature Algorithm used to authenticate parties and protect against man-in-the-middle attacks. 

This article explains the core math intuition and then shows a clean “handshake” that combines Kyber for confidentiality (key establishment) and Dilithium for authenticity (signing the transcript). 

  1. The Algebraic Playground: Polynomials Modulo a Ring

Kyber and Dilithium live in a structured polynomial ring. Intuitively, you replace big integers with polynomials, and you do arithmetic modulo both a polynomial and an integer modulus. 

Rq=Zq[x] / (xn+1)R_q = \mathbb{Z}_q[x]\ /\ (x^n + 1)

Elements are polynomials of degree < n with coefficients reduced mod q. Operations are addition and multiplication in the ring. Implementations use fast polynomial multiplication (NTT) for speed. 

  1. Kyber (ML-KEM): A KEM from Learning With Errors

Kyber is based on the hardness of the Module-LWE problem: given “noisy” linear equations, it’s hard to recover the secret. 

2.1) The Module-LWE shape

Think of a public matrix (over the ring) times a secret vector, plus a small noise term:

t=As+e\mathbf{t} = \mathbf{A}\mathbf{s} + \mathbf{e}

Where:

  • A is public (often derived from a seed),

  • s is secret (small coefficients),

  • e is small “error” noise,

  • t is public (part of the public key). 

The “noise” makes solving for s computationally hard, even if you know A and t.

2.2) Kyber in three roles: KeyGen, Encaps, Decaps

Kyber is not a direct “encrypt a message” primitive in modern protocols; it’s a KEM that produces a shared secret used with symmetric crypto (e.g., AES-GCM / ChaCha20-Poly1305). 

(A) Key Generation

  • Generate seed(s) to derive A.

  • Sample small secret s and error e.

  • Compute public t = A s + e.

  • Public key: (seed for A, t)

  • Secret key: s (plus auxiliary values for CCA security in real KEM constructions). 

(B) Encapsulation (Client → Server)
Given the server’s public key, the client produces:

  • a ciphertext c (encapsulation), and

  • a shared secret K (derived via a KDF).

At a high level, the client samples fresh small randomness and creates a ciphertext that “hides” key material. 

(C) Decapsulation (Server)
The server uses its secret key to recover the same shared secret K from c. Real Kyber KEM includes checks and fallback behavior to resist chosen-ciphertext attacks (CCA security). 

  1. Dilithium (ML-DSA): Signatures from Module Lattices

Dilithium is designed for strong security, clean implementation, and resistance to timing pitfalls. It is based on module lattice assumptions (often described via Module-LWE/Module-SIS style hardness). 

3.1) Public key structure

A simplified mental model: the public key contains a “noisy” linear image of a secret, similarly shaped to Kyber’s structure.

t=As1+s2\mathbf{t} = \mathbf{A}\mathbf{s}_1 + \mathbf{s}_2

Where s1, s2 are small secret vectors and A is public. 

3.2) Signing intuition

Dilithium uses a commit–challenge–response style:

  • Pick a fresh random y (small).

  • Compute a commitment w = A y.

  • Hash the message and (part of) w to produce a sparse challenge c.

  • Respond with z = y + c s1, while ensuring values stay within bounds (“rejection sampling”).

c=H(μ∥highbits(w))c = H(\mu \parallel \mathrm{highbits}(\mathbf{w})) z=y+cs1\mathbf{z} = \mathbf{y} + c\mathbf{s}_1

Verification checks that the response is consistent with the public key and the challenge, and that z is within safe bounds. 

  1. Why Kyber + Dilithium Together?

A KEM like Kyber gives you confidentiality for a session key. But without authentication, an attacker can do a classic man-in-the-middle (MITM): they establish one key with the client and a different key with the server. 

A signature scheme like Dilithium provides authentication and integrity: the server can sign the handshake transcript so the client knows it is talking to the real server. 

  1. A Clean Post-Quantum Handshake (Simplified)

Below is a protocol-style view of a typical “PQ-TLS-like” flow using:

  • Kyber KEM for ephemeral key establishment

  • Dilithium signatures for authentication

  • A KDF to derive traffic keys 

5.1) Roles and keys

  • Server has long-term Dilithium keypair: (pk_S^sig, sk_S^sig).

  • Server also has a Kyber KEM public key pk_S^kem (either long-term or rotated periodically). 

5.2) Transcript hash

Define a transcript hash TH that accumulates handshake messages:

TH=H(all handshake messages so far)TH = H(\text{all handshake messages so far})

5.3) Handshake steps

Step 1 — ClientHello
C → S: ClientHello, nonce_C, supported = { Kyber/ML-KEM, Dilithium/ML-DSA, AEAD… } 

Step 2 — ServerHello + KEM Public Key + Signature Key
S → C: ServerHello, nonce_S, pk_S^kem, pk_S^sig (or cert chain) 

Step 3 — Kyber Encapsulation (Key Establishment)
Client encapsulates to the server’s KEM public key:

(c,K)←Encaps(pkSkem)(c, K) \leftarrow \mathrm{Encaps}(pk_S^{kem})

C → S: KEMCiphertext c

Now both sides can compute the same shared secret:

  • Client already has K.

  • Server recovers it via decapsulation.

K←Decaps(skSkem,c)K \leftarrow \mathrm{Decaps}(sk_S^{kem}, c)

Step 4 — Derive session keys with a KDF
Use nonces + transcript hash to bind the session key to the handshake:

master=KDF(K, nonceC∥nonceS∥TH)\text{master} = \mathrm{KDF}(K,\ \text{nonce}_C \parallel \text{nonce}_S \parallel TH) ktx,krx=Expand(master)k_{tx}, k_{rx} = \mathrm{Expand}(\text{master})

Step 5 — Server Authentication (Dilithium Signature)
Server signs the transcript hash so the client can verify authenticity:

σ←Sign(skSsig, TH)\sigma \leftarrow \mathrm{Sign}(sk_S^{sig},\ TH)

S → C: Signature σ over TH 

Client verifies:

Verify(pkSsig,TH,σ)=?true\mathrm{Verify}(pk_S^{sig}, TH, \sigma) \stackrel{?}{=} \text{true}

If verification passes, the client trusts it shares keys with the genuine server, not a MITM. 

Step 6 — Encrypted application data
Both sides now switch to symmetric AEAD with k_tx, k_rx for fast encrypted traffic. 

  1. Security Notes (Important in the real world)

  • CCA security matters: practical Kyber KEM constructions include checks and constant-time behavior to avoid side channels and chosen-ciphertext pitfalls.

  • Transcript binding matters: always mix handshake context into key derivation; otherwise, “key substitution” games appear.

  • Hybrid deployments are common: many systems combine classical + PQ (e.g., X25519 + Kyber) during transition for defense-in-depth.

  • Implementations are everything: PQC is robust math, but real security depends on constant-time code, correct randomness, and safe parameter handling. 

  1. Practical Takeaway

Kyber (ML-KEM) gives a fast, quantum-resistant way to establish a shared secret. Dilithium (ML-DSA) gives quantum-resistant authentication via signatures. Together, they form the backbone of modern post-quantum secure handshakes:

  • Kyber: “We now share a secret key.”

  • Dilithium: “And I can prove who I am.” 

That combination is exactly what you want for secure sessions that must survive the “harvest now, decrypt later” era.

GTranslate

The Edu

Location:
Rio de Janeiro, Brazil

Telephone:
+55(21)965 103 777

Email:
iuri@postquantumapps.com