Cryptography
Diffie-Hellman Key Exchange
Compute g^(ab) mod p without ever transmitting a or b — public-key crypto's foundation
Diffie-Hellman key exchange (DH), invented by Whitfield Diffie and Martin Hellman in 1976 (with prior work by Ralph Merkle), is the first published public-key protocol. Two parties agree on a public prime p and generator g; Alice picks secret a and sends g^a mod p; Bob picks secret b and sends g^b mod p; both compute the shared secret g^(ab) mod p. Security rests on the discrete logarithm problem — given g^a mod p, recovering a is computationally infeasible for p of 2048+ bits. Modern variants: ECDH (elliptic-curve, ~256-bit keys provide 128-bit security), and X25519 (Curve25519, the de-facto standard in TLS 1.3, SSH, Signal). Key exchange is what enables HTTPS, VPNs, and end-to-end encrypted messaging.
- InventedDiffie & Hellman 1976
- SecurityDiscrete log problem
- Recommended FFDH≥ 2048 bit
- Modern variantX25519 (Curve25519)
- TLS 1.3 defaultECDHE
- Forward secrecyYes (with ephemeral keys)
Interactive visualization
Press play, or step through manually. The visualization is yours to drive — try it before reading on.
Watch the 60-second explainer
A condensed visual walkthrough — narrated, captioned, under a minute.
Why Diffie-Hellman matters
- HTTPS handshake. Every TLS 1.3 connection — billions per day — derives its session key via ECDHE. The handshake takes one round-trip, ~50 ms typical, and produces a 256-bit AES key fresh for that connection alone.
- VPN tunnels. WireGuard, OpenVPN, IPsec/IKEv2 all use DH (usually X25519) to bootstrap symmetric encryption between client and gateway. Re-keying happens every 2 minutes (WireGuard default) so even a leaked tunnel key reveals only a 2-minute window.
- Signal protocol. The X3DH (Extended Triple DH) handshake and the Double Ratchet algorithm — used in Signal, WhatsApp, iMessage Contact Key Verification — chain dozens of DH exchanges per conversation for per-message forward secrecy and post-compromise security.
- Forward secrecy. Ephemeral DH (DHE/ECDHE) means recorded ciphertext stays unreadable even if the server's long-term private key is later stolen. Without DH, an adversary could store traffic for a decade and decrypt it after a future key compromise.
- SSH key exchange. Every
ssh user@hostcommand runs ECDH (curve25519-sha256 by default since OpenSSH 6.5, 2014). The SSH session key is independent from your authorized_keys identity. - Smartcard and HSM ephemeral keys. Hardware modules generate per-session DH keys inside tamper-resistant boundaries, used for everything from chip-and-PIN to FIDO2 passkeys.
- Mix networks and Tor. Tor builds three-hop circuits using one DH exchange per relay (ntor handshake on Curve25519), so each relay only knows its predecessor and successor.
Protocol walkthrough with concrete numbers
To make the math concrete, here is DH with toy parameters. Use a prime p = 23 and generator g = 5. (Real DH uses p with at least 2048 bits, around 617 decimal digits.)
- Step 1: Alice picks secret
a = 6. She computesA = 5^6 mod 23 = 15625 mod 23 = 8. She sendsA = 8to Bob over the public channel. - Step 2: Bob picks secret
b = 15. He computesB = 5^15 mod 23 = 30517578125 mod 23 = 19. He sendsB = 19to Alice. - Step 3: Alice computes
s = B^a mod p = 19^6 mod 23 = 47045881 mod 23 = 2. - Step 4: Bob computes
s = A^b mod p = 8^15 mod 23 = ... = 2. - Result: Both sides agree on
s = 2. An attacker on the wire has seenp, g, A, B= (23, 5, 8, 19). To recoverafromA = 8, they would have to solve5^a ≡ 8 (mod 23)— the discrete log problem. For toy 23, brute force is trivial; for 2048-bit p it is infeasible. - Real-world keys. For 2048-bit FFDH (RFC 7919 group ffdhe2048), p is a fixed 2048-bit safe prime and a, b are random 256-bit integers. For X25519, the secret is 32 random bytes (with three bits clamped per Bernstein's spec), and the public key is the resulting 32-byte curve point.
From shared secret to AES key
The raw DH output g^(ab) mod p is not used directly as a symmetric key. It is biased — the high bits leak structure — and for X25519 the output is just 32 raw bytes that need to be domain-separated for different uses (encryption key, MAC key, IV). The standard pipeline:
- Step 1: Extract. Run the raw shared secret through HKDF-Extract with a salt (often the concatenated handshake transcript hash) to produce a uniform-pseudo-random key.
- Step 2: Expand. Run HKDF-Expand with a context label like
"tls13 server traffic"to derive 32 bytes of AES-GCM key, 12 bytes of nonce base, etc. - Step 3: Per-record nonces. Each TLS 1.3 record XORs a 64-bit counter with the nonce base; AES-GCM authenticates and encrypts using the derived key and per-record nonce.
- Re-keying. TLS 1.3 supports
KeyUpdatewhich derives a fresh key from the current one without a new DH round, limiting damage if a single key is exposed.
Choosing parameters safely
- Prime size. 1024-bit DH is broken — Logjam (2015) showed nation-state precomputation can break a single 1024-bit group's discrete logs in months, then break individual sessions in seconds. 2048-bit is the minimum; 3072 or 4096 for long-lived secrets.
- Safe primes. Use p such that (p-1)/2 is also prime — this prevents subgroup confinement attacks. RFC 7919 publishes named groups (ffdhe2048, ffdhe3072, ffdhe4096) so implementations don't have to generate fresh primes.
- Generator.
g = 2org = 5with a safe prime. Avoid generators that produce small subgroups. - Validate received public. Reject A or B values that are 0, 1, or p-1 — these collapse the shared secret. ECDH must verify points lie on the curve. X25519 sidesteps this: every 32-byte string is a valid public key by construction.
- Constant-time exponentiation. The square-and-multiply loop must not branch on secret bits, or timing side-channels leak the secret. Use Montgomery ladders or fixed-window methods.
Common misconceptions
- "DH encrypts data." No. DH only produces a shared secret; an authenticated encryption mode like AES-GCM or ChaCha20-Poly1305 does the actual encryption.
- "DH is vulnerable to MITM, so it's broken." Plain DH is unauthenticated. In practice DH is always combined with authentication — server certificates in TLS, identity keys in Signal, host keys in SSH.
- "RSA replaced DH." The opposite happened. RSA key exchange (encrypting a random key with the server's RSA public key) was removed from TLS 1.3 because it lacks forward secrecy. ECDHE is now the only key-exchange in TLS 1.3.
- "Bigger prime = always more secure." True up to a point, but past 4096 bits the discrete-log work outpaces realistic attacks while CPU cost grows quadratically. For long-term secrets, prefer ECC (X25519) over giant FFDH primes.
- "Quantum-safe." Shor's algorithm breaks DH and ECDH in polynomial time on a sufficiently large quantum computer. Post-quantum hybrid handshakes (X25519 + Kyber768) are rolling out in TLS 1.3 (Cloudflare, Google Chrome, since 2024).
- "Anyone can pick any group." Custom groups are dangerous (Logjam exploited weak custom DH parameters). Use RFC 7919 named groups or X25519.
Performance numbers
- 2048-bit FFDH. ~3 ms per key generation, ~3 ms per shared-secret derivation on a single core (modern x86_64). Public keys are 256 bytes.
- X25519. ~50 microseconds per operation — roughly 60x faster than 2048-bit FFDH. Public keys are 32 bytes (1/8 the size).
- P-256 ECDH. ~150 microseconds; 64-byte uncompressed public keys. Slower than X25519 due to NIST curve arithmetic.
- Hybrid X25519+Kyber768 (post-quantum). Total handshake adds ~1100 bytes and ~150 microseconds — small enough that Cloudflare enabled it by default in 2024.
Frequently asked questions
How does Diffie-Hellman work step by step?
Public parameters: a large prime p (2048+ bits) and a generator g (typically 2 or 5). Step 1: Alice picks secret integer a in [1, p-2] and computes A = g^a mod p, sends A to Bob. Step 2: Bob picks secret b similarly, computes B = g^b mod p, sends B to Alice. Step 3: Alice computes shared secret s = B^a mod p = g^(ab) mod p. Step 4: Bob computes s = A^b mod p = g^(ab) mod p. Both arrive at the same s without ever transmitting a, b, or s. The shared secret is then run through a key derivation function (HKDF) to produce a symmetric AES key.
What is the discrete logarithm problem?
Given a prime p, generator g, and value y = g^x mod p, find x. While computing g^x mod p forward is fast (O(log x) with square-and-multiply, microseconds for 2048-bit), inverting it — recovering x from y — is believed to require sub-exponential time. The best known algorithm, the General Number Field Sieve, takes roughly 2^(112) operations for 2048-bit p, which is infeasible even for nation-state attackers. Doubling p from 2048 to 4096 bits adds about 16 bits of security.
What is forward secrecy?
Forward secrecy (also called perfect forward secrecy, PFS) means past communications cannot be decrypted even if the long-term private key is later compromised. It is achieved by using ephemeral Diffie-Hellman keys (DHE or ECDHE) — generated fresh per session and discarded after. If an attacker records all encrypted TLS traffic and later steals a server's RSA key, static-key TLS sessions are decryptable; ephemeral-DH sessions are not, because the per-session a, b values were never written to disk. TLS 1.3 mandates forward secrecy for all cipher suites.
Why is X25519 the modern default?
X25519 is Diffie-Hellman over Curve25519, designed by Daniel J. Bernstein in 2006. It uses 256-bit keys for ~128-bit security — equivalent to 3072-bit finite-field DH but 10x smaller and ~30x faster. It avoids known timing attacks by design (constant-time scalar multiplication via the Montgomery ladder), needs no parameter validation (every 32-byte string is a valid public key), and uses no NIST-blessed magic constants. Adopted by TLS 1.3 (RFC 8446), SSH, Signal, WireGuard, age, Tor, and Apple's iMessage.
How does MITM attack DH and how is it prevented?
Plain DH has no notion of identity. A man-in-the-middle Mallory intercepts Alice's A, sends his own M_a to Bob; intercepts Bob's B, sends M_b to Alice. Mallory then shares one key with Alice and a different key with Bob, decrypting and re-encrypting all traffic. Prevention: authenticate the DH parameters. In TLS, the server signs (g, A, ...) with its certificate's private key (RSA or ECDSA); the browser verifies the certificate against a trusted root. In Signal, identity keys are pre-published. In SSH, the host key is pinned (TOFU) on first connection.
What is the difference between DH, DHE, and ECDH?
DH (or FFDH, finite-field DH) operates in the multiplicative group of integers mod p. DHE (Ephemeral DH) generates a, b fresh per session for forward secrecy — required in modern TLS. ECDH replaces (Z/pZ)* with the group of points on an elliptic curve; same protocol, much smaller keys (256 vs 3072 bits for equivalent security). ECDHE is ephemeral ECDH and is the TLS 1.3 default. X25519 is a specific ECDH instantiation on Curve25519. Static DH (long-term keys) is now considered legacy because it lacks forward secrecy.