Key agreement — compute Diffie–Hellman by hand
Hand-compute Diffie–Hellman key agreement — building a shared key over a wiretapped path — with small primes. Through ECDHE and forward secrecy.
Building a shared key on a wiretapped path
Recall the homework Chapter 2 left us: symmetric encryption protects the traffic fast, but how do we share that first key? And the premise is harsh — the path between browser and server may already be wiretapped. "On a wiretapped path, create a shared secret the wiretapper cannot know" — the problem sounds impossible, and Diffie–Hellman (DH) key agreement solves it.
This chapter has exactly one goal: compute it yourself and be convinced. The only mathematics you need is powers and remainders (mod). If 17 mod 5 = 2 (17 divided by 5 leaves remainder 2) makes sense, you are ready.
The procedure — four steps
You and a server will build a key together. First, both of you agree — in public — on two numbers: a prime p and its companion g. To keep the arithmetic by hand, we use p = 23, g = 5 (the real thing merely uses a p hundreds of digits long; the procedure is identical).
a (say a = 6). The server picks its own secret b (say b = 15). Neither is ever sentA = ga mod p = 56 mod 23 = 8. The server sends B = 515 mod 23 = 19. Both may be wiretapped, and that is fines = Ba mod p = 196 mod 23 = 2. Server: s = Ab mod p = 815 mod 23 = 2gab mod p, so the values always match. From here on, a symmetric key derived from it protects the traffic at speedDon't be intimidated by large exponents. The trick is to square repeatedly, reducing mod p each time. For 56 mod 23: 52 = 25 ≡ 2 → 54 = (52)2 ≡ 4 → 56 = 54 × 52 ≡ 4 × 2 = 8. The intermediate values never exceed 23.
Only the public values A and B travel the path. The secrets a, b and the shared secret s never leave either side's hands.
Practice 3-1 — Run the key agreement with your own hands
The public parameters are p = 23, g = 5. Follow the steps in the text, writing intermediate values on paper.
Q1. Warm-up: what is 53 mod 23?
5³ = 125, and 125 ÷ 23 = 5 remainder 10, so the answer is 10. mod is just 'the remainder' — that single operation carries all of this chapter's calculations.
Q2. Your secret value is a = 6. What public value A = 56 mod 23 do you send? (Hint: build up from 52 mod 23)
5² = 25 ≡ 2, 5⁴ = (5²)² ≡ 2² = 4, 5⁶ = 5⁴ × 5² ≡ 4 × 2 = 8. The answer is 8. Even large powers stay manageable if you square repeatedly and reduce mod p at every step — the numbers never exceed 23.
Q3. The peer's public value B = 19 arrives. With your secret a = 6, what shared secret s = 196 mod 23 do you compute? (Hint: 19 ≡ −4 (mod 23) makes it fast)
19 ≡ −4, so 19⁶ ≡ (−4)⁶ = 4⁶. 4³ = 64 ≡ 18, and 4⁶ = (4³)² ≡ 18² = 324 ≡ 2. The shared secret is 2. The peer computes 8¹⁵ mod 23 = 2 with their secret b = 15. Two independent calculations, one identical value — that is key agreement.
Verify with the simulator
The simulator below reproduces the key agreement with p = 23, g = 5. Drag your secret a and the server's secret b, and confirm two things: the two independently computed shared secrets always match, and no secret ever appears in the eavesdropper-visible values.
What the simulator does (text version): moving the a and b sliders updates the public values A = ga mod p and B = gb mod p, along with your side's computation Ba mod p and the server side's Ab mod p. However you choose a and b, the two results coincide, and the display color-codes which values an eavesdropper can see (p, g, A, B) versus cannot see (a, b, and the shared secret).
Why the eavesdropper learns nothing
The eavesdropper holds p = 23, g = 5, A = 8, B = 19. To get the shared secret they could, say, find the a with 5a mod 23 = 8 — and for p = 23, brute force finds it instantly. It is solvable only because the numbers are tiny.
The real p has hundreds of digits. The "forward" computation — square and reduce — finishes in a flash, while the "reverse" computation of recovering the exponent (the discrete logarithm problem) does not finish in realistic time by any known method. This overwhelming asymmetry between forward and reverse is the entirety of DH's security. Nothing is hidden by encryption; the protection is that the reverse computation cannot keep up.
Actual TLS 1.3 runs the same idea on elliptic curves (ECDH), and the secret values are freshly generated and thrown away per connection (the E in ECDHE, ephemeral). That throwing away is what buys forward secrecy: an attacker who recorded every byte of ciphertext and later obtains the server's long-term private key still cannot reconstruct past session keys — the ephemeral values are long gone.
Practice 3-2 — What the eavesdropper sees, and doesn't
Now replay the key agreement you just computed — from the eavesdropper's seat.
Q4. A third party wiretapped the entire Diffie–Hellman exchange. Which values did they see?
Only p, g, A, and B travel the path. The secrets a and b never leave each party's hands, and the shared secret s is computed locally by each side and never transmitted. "Sharing a secret without ever sending one" is the core of key agreement.
Q5. The eavesdropper sees A = ga mod p. Why can they still not compute the shared secret?
Even knowing g and p, finding the a with g^a mod p = A — the discrete logarithm problem — is not feasible in realistic time once p is hundreds of digits. We could solve it for p = 23 only because the numbers are tiny. A travels in plaintext and p, g are public: the protection is not encryption but the infeasibility of the reverse computation.
Q6. TLS 1.3 performs key agreement with throwaway values for every connection (the E in ECDHE = ephemeral). What does the resulting "forward secrecy" mean?
Per-connection keys are derived from throwaway values that are destroyed after use. An attacker who recorded all the ciphertext and later obtains the server's long-term private key still cannot re-derive past session keys from it. Forward secrecy asks not only "is it safe now" but "does the past stay safe if keys leak later."
But one large hole remains
Now that the hand calculation is done, one mean question: whom did you just agree on a key with?
DH guarantees only that "you now share a secret with whoever exchanged public values with you." Whether that party is the genuine server or an attacker spliced into the path, DH alone cannot say. An attacker who sits in the middle and runs separate key agreements with you and with the real server can decrypt, read, and re-encrypt everything in transit (the man-in-the-middle attack). The next chapter's protagonist — the certificate — is the tool that closes exactly this hole.
What to take from this chapter
- DH key agreement shares a secret without sending one — only public values travel the path
- Security rests on the discrete logarithm being infeasible to reverse, against a fast forward direction
- TLS 1.3 uses throwaway values (ECDHE), buying forward secrecy — past traffic stays safe even if keys leak later
- DH builds a key with someone — it cannot say with whom. Certificates close that hole next