MATH2400 3,418 words·18 min read

Cryptosystems

What a Cryptosystem Is#

Everything in this topic is an application of machinery we have already built; nothing genuinely new gets defined. The situation is this: a sender wants to get a message to a receiver over a channel that a third party can listen in on, and wants that third party to learn nothing. The fix is to scramble the message before it goes out and unscramble it at the other end.

Note

Definition
A cryptosystem is a pair of functions: an encryption function which the sender applies to a message to make it unintelligible in transit, and a decryption function which the receiver applies to the received message to recover the original.

Basically, encryption and decryption are inverse functions, and the whole game is arranging things so that the encryption function is easy to apply, easy to invert if you hold one extra piece of information, and hopeless to invert if you do not. The message before encryption is called the plaintext and the message after encryption is the ciphertext.

Two ideas run through this entire lecture. The first is that letters have to be turned into numbers before any arithmetic can happen, and the choice of letter-to-number dictionary matters. The second is that "hard to invert" always ends up meaning some specific computational problem is believed to be slow — factorising for RSA, discrete logarithms for Diffie-Hellman.

The Caesar Shift#

The classic toy cryptosystem is the Caesar shift cypher: shift every letter of the message forward some fixed number of positions in the alphabet, wrapping back around to AA once you pass ZZ. For example, the letters of BABABABA shifted four places down the alphabet become FEFEFEFE.

To do this arithmetically, the encryption function is built in two steps. First we map each letter to a number giving its position in the alphabet, then we shift the numbers modulo 2626:

letter⟶number⟶x↦(x+a) mod 26,\text{letter} \longrightarrow \text{number} \longrightarrow x \mapsto (x + a) \bmod 26,

where aa is a fixed secret integer. The decryption function reverses both steps in the opposite order,

y↦(y−a) mod 26⟶number⟶letter.y \mapsto (y - a) \bmod 26 \longrightarrow \text{number} \longrightarrow \text{letter}.

The letter-to-number dictionary is the usual one, with one quirk. The natural choice is A→1A \to 1, B→2B \to 2, all the way to Z→26Z \to 26; but we are working in Z26={0,1,…,25}\mathbb{Z}_{26} = \{0, 1, \dots, 25\}, and 26=026 = 0 there. So the dictionary we actually use is:

Letter AA BB CC DD EE FF GG HH II JJ KK LL MM
Number 11 22 33 44 55 66 77 88 99 1010 1111 1212 1313
Letter NN OO PP QQ RR SS TT UU VV WW XX YY ZZ
Number 1414 1515 1616 1717 1818 1919 2020 2121 2222 2323 2424 2525 00

In the Caesar shift, ZZ must be sent to 00, not 2626; and going backwards, a 00 decrypts to ZZ, never to "the zeroth letter". This is purely an artefact of reducing mod 2626 and is the single most common slip in these questions. It does not cause any trouble because 26≡0(mod26)26 \equiv 0 \pmod{26}, so the arithmetic is identical either way; it is only the final translation back to letters that needs care.

Example. Encrypt the message JAZZJAZZ using a Caesar shift with a=3a = 3.
Converting to numbers with the table above, J→10J \to 10, A→1A \to 1, and Z→0Z \to 0 (twice). Applying x↦(x+3) mod 26x \mapsto (x+3) \bmod 26,

10+3=13,1+3=4,0+3=3,0+3=3,\begin{align*} 10 + 3 &= 13, \\ 1 + 3 &= 4, \\ 0 + 3 &= 3, \\ 0 + 3 &= 3, \end{align*}

giving the numbers (13,4,3,3)(13, 4, 3, 3), which translate back to MM, DD, CC, CC. Therefore, the ciphertext is MDCCMDCC. As a sanity check by hand, counting three letters forward from ZZ gives A,B,CA, B, C; so Z→CZ \to C, exactly as the arithmetic said.

Example. The message MDCCMDCC was encrypted with a Caesar shift of a=3a = 3. Decrypt it.
Converting to numbers gives (13,4,3,3)(13, 4, 3, 3), and we apply y↦(y−3) mod 26y \mapsto (y - 3) \bmod 26:

13−3=10,4−3=1,3−3=0,3−3=0.\begin{align*} 13 - 3 &= 10, \\ 4 - 3 &= 1, \\ 3 - 3 &= 0, \\ 3 - 3 &= 0. \end{align*}

Now 10→J10 \to J, 1→A1 \to A, and 0→Z0 \to Z twice. Therefore, the plaintext is JAZZJAZZ; notice how the 00 has to be read as ZZ on the way back, which is the same quirk seen from the other side.

The Caesar shift is a genuine cryptosystem, but a hopeless one. There are only 2626 possible values of aa, and one of them (a=0a=0) does nothing, so an attacker simply tries all 2525 non-trivial shifts and reads whichever output is English. A cryptosystem whose key space is small enough to enumerate is worthless no matter how clever the operation is. What we want is a system where the operation is still cheap to compute but the key space is astronomically large, and that is exactly what happens if we replace "add a secret number" with "raise to a secret power".

The RSA Cryptosystem#

The upgrade from Caesar is to work modulo a large nn and encrypt by x↦xsx \mapsto x^s rather than x↦x+ax \mapsto x + a. The resulting system is the Rivest–Shamir–Adleman, or RSA, cryptosystem, and it is the system that makes public-key cryptography possible: the sender can publish everything needed to encrypt without giving away how to decrypt.

Note

Definition (RSA)
Set-up. Choose two very large primes pp and qq, and calculate n=pqn = pq. Also select an integer s>1s > 1 that is coprime with ϕ(n)\phi(n).

  • Public information: the modulus nn and the encryption exponent ss.
  • Private information: the primes pp and qq (and the decryption exponent tt).

Encryption. The message is converted in some standard way to a number, or a sequence of numbers, each less than nn. The sender then encrypts these numbers under the encryption function

x↦xs mod n.x \mapsto x^s \bmod n.

Decryption. So long as the receiver knows either pp or qq, they can find ϕ(n)=(p−1)(q−1)\phi(n) = (p-1)(q-1), and then find tt with st≡1(modϕ(n))st \equiv 1 \pmod{\phi(n)} (for example via the EEA). The decryption function is then

y↦yt mod n.y \mapsto y^t \bmod n.

Basically, nn and ss are shouted from the rooftops so that anybody can send you an encrypted message, while the factorisation n=pqn = pq is kept secret; and knowing the factorisation is exactly what lets you compute ϕ(n)\phi(n), which in turn is exactly what lets you compute tt. Everyone can lock the box, only you can open it.

A few points about the set-up that are easy to skip past:

  • We need gcd⁡(s,ϕ(n))=1\gcd(s, \phi(n)) = 1 precisely so that ss is a unit in Zϕ(n)\mathbb{Z}_{\phi(n)} and the decryption exponent t=s−1t = s^{-1} exists at all. If ss is not coprime to ϕ(n)\phi(n) there is no tt whatsoever, and the "cryptosystem" cannot be decrypted by anybody, including the intended receiver.
  • Because n=pqn = pq with p,qp, q distinct primes, ϕ\phi is multiplicative on coprime arguments and ϕ(p)=p−1\phi(p) = p - 1, so ϕ(n)=(p−1)(q−1)\phi(n) = (p-1)(q-1). This is (p−1)(q−1)(p-1)(q-1), not n−1n - 1; writing ϕ(55)=54\phi(55) = 54 instead of 4040 wrecks everything downstream.
  • The plaintext numbers must be smaller than nn, otherwise two different messages could reduce to the same element of Zn\mathbb{Z}_n and decryption would be ambiguous.
  • Finding the two large primes in the first place is done with the tests in Primality Tests; you never need to factorise anything to set up RSA, only to break it.

Why RSA Decryption Works#

The claim we need is that raising to the power ss and then to the power tt gets you back where you started. The source slides justify this in one line with Euler's Theorem, and that line is correct for units; but the messages we actually encrypt are arbitrary numbers less than nn, and some of them will not be units. It is worth doing this properly.

Note

Theorem (RSA decryption)
Let p≠qp \neq q be primes, let n=pqn = pq, and let s,t∈Z+s, t \in \mathbb{Z}^+ satisfy st≡1(modϕ(n))st \equiv 1 \pmod{\phi(n)}. Then for every x∈Znx \in \mathbb{Z}_n, whether or not xx is a unit,

(xs)t=xst=x in Zn.(x^s)^t = x^{st} = x \text{ in } \mathbb{Z}_n.

Proof. Since st≡1(modϕ(n))st \equiv 1 \pmod{\phi(n)} and st≥1st \geq 1, we may write st=1+kϕ(n)st = 1 + k\phi(n) for some integer k≥0k \geq 0, where ϕ(n)=(p−1)(q−1)\phi(n) = (p-1)(q-1).

First suppose gcd⁡(x,n)=1\gcd(x, n) = 1. Then Euler's Theorem from Fermats Little Theorem and Eulers Theorem gives xϕ(n)=1x^{\phi(n)} = 1 in Zn\mathbb{Z}_n, so

xst=x1+kϕ(n)=x(xϕ(n))k=x⋅1k=x in Zn,\begin{align*} x^{st} &= x^{1 + k\phi(n)} \\ &= x \left( x^{\phi(n)} \right)^k \\ &= x \cdot 1^k \\ &= x \text{ in } \mathbb{Z}_n, \end{align*}

which is the easy case. Now drop the assumption and work modulo pp and modulo qq separately. Modulo pp there are two possibilities:

  • If p∣xp \mid x, then x≡0(modp)x \equiv 0 \pmod p, and since st≥1st \geq 1 we get xst≡0≡x(modp)x^{st} \equiv 0 \equiv x \pmod p.
  • If p∤xp \nmid x, then Fermat's Little Theorem gives xp−1≡1(modp)x^{p-1} \equiv 1 \pmod p; and (p−1)∣ϕ(n)(p-1) \mid \phi(n), so writing ϕ(n)=(p−1)m\phi(n) = (p-1)m,

xst=x(x(p−1)m)k≡x⋅1mk≡x(modp).\begin{align*} x^{st} &= x \left( x^{(p-1)m} \right)^k \\ &\equiv x \cdot 1^{mk} \\ &\equiv x \pmod p. \end{align*}

Either way xst≡x(modp)x^{st} \equiv x \pmod p, and the identical argument with qq in place of pp gives xst≡x(modq)x^{st} \equiv x \pmod q. So p∣(xst−x)p \mid (x^{st} - x) and q∣(xst−x)q \mid (x^{st} - x); since pp and qq are distinct primes they are coprime, so pq=npq = n divides xst−xx^{st} - x as well (this is the coprime-divisibility argument behind Simultaneous Congruences and the CRT). Hence xst≡x(modn)x^{st} \equiv x \pmod n for every integer xx. ■\blacksquare

Basically, splitting into the two prime factors rescues the non-units: an xx that is divisible by pp is 00 mod pp and stays 00 forever, which is exactly what we wanted anyway, and it is still a unit mod qq so Fermat handles that half. Do not let anyone tell you RSA "only works on units"; it works on every x∈Znx \in \mathbb{Z}_n, and we will see a message below whose letters EE and TT are genuinely not units mod 5555.

The statement the slides give, xk≡xk mod ϕ(n)(modn)x^k \equiv x^{k \bmod \phi(n)} \pmod n, is the unit version of the same fact, and is the reason the exponents live modulo ϕ(n)\phi(n) rather than modulo nn. Reduce exponents modulo ϕ(n)\phi(n); reduce bases modulo nn. Mixing these two up is the most expensive mistake available in this topic.

Finding the Decryption Function#

Everything in the previous section reduces the practical problem to one line: invert ss modulo ϕ(n)\phi(n). That is a job for the extended Euclidean algorithm from Bezouts Identity and the Extended Euclidean Algorithm. The working method is:

  • Factorise the public modulus as n=pqn = pq.
  • Compute ϕ(n)=(p−1)(q−1)\phi(n) = (p-1)(q-1).
  • Check gcd⁡(s,ϕ(n))=1\gcd(s, \phi(n)) = 1; if not, the system is broken and there is nothing to find.
  • Run the EEA on ss and ϕ(n)\phi(n) to write 1=us+vϕ(n)1 = us + v\phi(n); then t≡u(modϕ(n))t \equiv u \pmod{\phi(n)}.
  • If uu came out negative, add ϕ(n)\phi(n) until it lands in {1,…,ϕ(n)−1}\{1, \dots, \phi(n) - 1\}.
  • The decryption function is y↦yt mod ny \mapsto y^t \bmod n.

Example. An RSA cryptosystem uses the encryption function x↦x27 mod 55x \mapsto x^{27} \bmod 55. Find the decryption function.
The modulus factorises as n=55=5×11n = 55 = 5 \times 11, so p=5p = 5 and q=11q = 11, and

ϕ(55)=(5−1)(11−1)=4×10=40.\begin{align*} \phi(55) &= (5-1)(11-1) \\ &= 4 \times 10 \\ &= 40. \end{align*}

Since 27=3327 = 3^3 and 40=23×540 = 2^3 \times 5 share no prime factors, gcd⁡(27,40)=1\gcd(27, 40) = 1 and the decryption exponent exists. Running the Euclidean algorithm on 2727 and 4040,

40=1×27+13,27=2×13+1,13=13×1+0,\begin{align*} 40 &= 1 \times 27 + 13, \\ 27 &= 2 \times 13 + 1, \\ 13 &= 13 \times 1 + 0, \end{align*}

so gcd⁡(27,40)=1\gcd(27,40) = 1 as expected. Back-substituting to get Bézout coefficients,

1=27−2×13=27−2(40−1×27)=3×27−2×40.\begin{align*} 1 &= 27 - 2 \times 13 \\ &= 27 - 2(40 - 1 \times 27) \\ &= 3 \times 27 - 2 \times 40. \end{align*}

Reducing this modulo 4040 kills the 4040 term and leaves 27×3≡1(mod40)27 \times 3 \equiv 1 \pmod{40}, so t=3t = 3. Therefore, the decryption function is

y↦y3 mod 55.y \mapsto y^3 \bmod 55.

As a check, 27×3=81=2×40+127 \times 3 = 81 = 2 \times 40 + 1, so indeed st≡1(mod40)st \equiv 1 \pmod{40}. Always run this one-line check on your tt; it costs one multiplication and catches sign errors from the back-substitution instantly.

Example. Find the decryption function for the RSA encryption function x↦x11 mod 7171x \mapsto x^{11} \bmod 7171.
Here 7171=71×1017171 = 71 \times 101 (both prime), so

ϕ(7171)=70×100=7000,\begin{align*} \phi(7171) &= 70 \times 100 \\ &= 7000, \end{align*}

and gcd⁡(11,7000)=1\gcd(11, 7000) = 1 since 7000=23×53×77000 = 2^3 \times 5^3 \times 7. The Euclidean algorithm gives

7000=636×11+4,11=2×4+3,4=1×3+1,\begin{align*} 7000 &= 636 \times 11 + 4, \\ 11 &= 2 \times 4 + 3, \\ 4 &= 1 \times 3 + 1, \end{align*}

and back-substituting,

1=4−3=4−(11−2×4)=3×4−11=3(7000−636×11)−11=3×7000−1909×11.\begin{align*} 1 &= 4 - 3 \\ &= 4 - (11 - 2 \times 4) \\ &= 3 \times 4 - 11 \\ &= 3(7000 - 636 \times 11) - 11 \\ &= 3 \times 7000 - 1909 \times 11. \end{align*}

So −1909×11≡1(mod7000)-1909 \times 11 \equiv 1 \pmod{7000}, and since we want a positive exponent we take

t=7000−1909=5091.\begin{align*} t &= 7000 - 1909 \\ &= 5091. \end{align*}

Therefore, the decryption function is y↦y5091 mod 7171y \mapsto y^{5091} \bmod 7171; checking, 11×5091=56001=8×7000+111 \times 5091 = 56001 = 8 \times 7000 + 1, as required. Notice how the EEA gave a negative coefficient here and a positive one in the previous example; the sign is not something you can predict, so always finish by normalising tt into the range 1≤t<ϕ(n)1 \leq t < \phi(n).

Example. Find the decryption function for the RSA encryption function x↦x5 mod 26x \mapsto x^5 \bmod 26.
Here 26=2×1326 = 2 \times 13, so ϕ(26)=1×12=12\phi(26) = 1 \times 12 = 12 and gcd⁡(5,12)=1\gcd(5,12) = 1; this one is small enough to spot by inspection, since 5×5=25=2×12+1≡1(mod12)5 \times 5 = 25 = 2 \times 12 + 1 \equiv 1 \pmod{12}. Therefore t=5t = 5 and the decryption function is y↦y5 mod 26y \mapsto y^5 \bmod 26 — the same function as encryption. This happens whenever s2≡1(modϕ(n))s^2 \equiv 1 \pmod{\phi(n)}, and is a reminder that a small modulus gives a rubbish cryptosystem; here anybody who can encrypt can also decrypt.

Decrypting a Full Message#

With the decryption exponent in hand, decrypting is just a pile of modular exponentiations followed by a translation back to letters. For RSA the letters are usually numbered A→1A \to 1, B→2B \to 2, up to Z→26Z \to 26, with no wrap-around quirk, because the modulus is bigger than 2626 and 2626 is a perfectly good element of Zn\mathbb{Z}_n.

Example. An encrypted message using the cryptosystem x↦x27 mod 55x \mapsto x^{27} \bmod 55 is (15,2,25,7,1,4,49,49,4,49,4,15)(15, 2, 25, 7, 1, 4, 49, 49, 4, 49, 4, 15). Decrypt this message.
From the previous section the decryption function is y↦y3 mod 55y \mapsto y^3 \bmod 55. The message only uses seven distinct ciphertext values, namely 15,2,25,7,1,415, 2, 25, 7, 1, 4 and 4949, so we cube each of those once, working in Z55\mathbb{Z}_{55} and using 49=−649 = -6 to keep the numbers small:

Ciphertext yy Working in Z55\mathbb{Z}_{55} Plaintext y3y^3 Letter
1515 152=515^2 = 5, then 15×5=75=2015 \times 5 = 75 = 20 2020 TT
22 23=82^3 = 8 88 HH
2525 252=2025^2 = 20, then 25×20=500=525 \times 20 = 500 = 5 55 EE
77 73=343=6(55)+137^3 = 343 = 6(55) + 13 1313 MM
11 13=11^3 = 1 11 AA
44 43=64=55+94^3 = 64 = 55 + 9 99 II
4949 49=−649 = -6, so 493=−216=−216+22049^3 = -216 = -216 + 220 44 DD

Now substitute back into the message in order:

Position 11 22 33 44 55 66 77 88 99 1010 1111 1212
Ciphertext yy 1515 22 2525 77 11 44 4949 4949 44 4949 44 1515
Plaintext y3y^3 2020 88 55 1313 11 99 44 44 99 44 99 2020
Letter TT HH EE MM AA II DD DD II DD II TT

Therefore, the decrypted message is THEMAIDDIDITTHEMAIDDIDIT, i.e. "the maid did it". As a check on the whole system, encrypting the first letter again should return the ciphertext: 2027 mod 5520^{27} \bmod 55, and since 203=8000=145×55+2520^3 = 8000 = 145 \times 55 + 25, we get 203=2520^3 = 25, 209=253=520^9 = 25^3 = 5, 2027=53=125=2×55+15=1520^{27} = 5^3 = 125 = 2 \times 55 + 15 = 15, which is exactly the ciphertext we started from.

That last check is worth pausing on. Note that gcd⁡(20,55)=5\gcd(20, 55) = 5 and gcd⁡(5,55)=5\gcd(5, 55) = 5, so the plaintext letters TT and EE are not units in Z55\mathbb{Z}_{55}; Euler's Theorem says nothing at all about them, and yet they encrypt and decrypt perfectly. That is the general decryption theorem doing its job, and it is why we bothered proving the non-unit case.

Example. Decrypt the message (16,5,48,4)(16, 5, 48, 4), given that the encryption function was x↦x13 mod 62x \mapsto x^{13} \bmod 62.
First find tt. We have 62=2×3162 = 2 \times 31, so ϕ(62)=1×30=30\phi(62) = 1 \times 30 = 30, and gcd⁡(13,30)=1\gcd(13, 30) = 1. The Euclidean algorithm gives 30=2×13+430 = 2 \times 13 + 4 and 13=3×4+113 = 3 \times 4 + 1, so

1=13−3×4=13−3(30−2×13)=7×13−3×30,\begin{align*} 1 &= 13 - 3 \times 4 \\ &= 13 - 3(30 - 2 \times 13) \\ &= 7 \times 13 - 3 \times 30, \end{align*}

giving t=7t = 7 (and indeed 13×7=91=3×30+113 \times 7 = 91 = 3 \times 30 + 1). Now compute y7y^7 in Z62\mathbb{Z}_{62} for each ciphertext value by repeated squaring, writing 7=4+2+17 = 4 + 2 + 1:

162=256=4×62+8=8,164=82=64=2,167=2×8×16=256=8,52=25,54=625=10×62+5=5,57=5×25×5=625=5,482=(−14)2=196=3×62+10=10,484=102=100=38,487=38×10×(−14)=380×(−14)=8×(−14)=−112=12,42=16,44=256=8,47=8×16×4=512=8×62+16=16.\begin{align*} 16^2 &= 256 = 4 \times 62 + 8 = 8, \\ 16^4 &= 8^2 = 64 = 2, \\ 16^7 &= 2 \times 8 \times 16 = 256 = 8, \\ 5^2 &= 25, \\ 5^4 &= 625 = 10 \times 62 + 5 = 5, \\ 5^7 &= 5 \times 25 \times 5 = 625 = 5, \\ 48^2 &= (-14)^2 = 196 = 3 \times 62 + 10 = 10, \\ 48^4 &= 10^2 = 100 = 38, \\ 48^7 &= 38 \times 10 \times (-14) = 380 \times (-14) = 8 \times (-14) = -112 = 12, \\ 4^2 &= 16, \\ 4^4 &= 256 = 8, \\ 4^7 &= 8 \times 16 \times 4 = 512 = 8 \times 62 + 16 = 16. \end{align*}

So the plaintext numbers are (8,5,12,16)(8, 5, 12, 16), which read as H,E,L,PH, E, L, P. Therefore, the message is HELPHELP. Notice how replacing 4848 by −14-14 and reducing 380380 to 88 before multiplying kept every intermediate number small; reduce after every single multiplication, never at the end.

Why RSA Is Secure#

An attacker sees the ciphertext, the modulus nn and the exponent ss. To decrypt they need tt, to get tt they need ϕ(n)\phi(n), and to get ϕ(n)\phi(n) they need the factorisation n=pqn = pq. So the security of RSA rests entirely on the following claim:

Note

Fact
The security of the RSA cryptosystem relies on the difficulty of factorising a very large number into two very large primes.

Multiplying two 20482048-bit primes together takes essentially no time; recovering them from the product is, as far as anybody knows, completely infeasible. That gap is the asymmetry the whole system is built on, and it is genuinely remarkable that it exists, since the operation and its inverse look equally innocent written down.

It is worth noticing how thin the margin is. Knowing either prime is enough, since q=n/pq = n/p and then ϕ(n)=(p−1)(q−1)\phi(n) = (p-1)(q-1) falls out. Knowing ϕ(n)\phi(n) is also enough without ever naming the primes, because ϕ(n)=n−p−q+1\phi(n) = n - p - q + 1 gives you p+qp + q, and with pq=npq = n known you can solve the resulting quadratic. So ϕ(n)\phi(n) is every bit as secret as pp and qq; never publish it, and never let a question trick you into thinking it is public information. If pp and qq are chosen badly — too close together, too small, or of a guessable special shape — the system falls apart even though nn is enormous.

The Diffie-Hellman Key Exchange#

RSA solves one problem, but plenty of cryptosystems need the sender and receiver to share a secret key beforehand — and if they have never met, there is no obvious way to agree on one over a channel that is being listened to. The Diffie-Hellman(-Merkle) system solves exactly this: two people who have exchanged nothing private can end up holding a common secret number.

Note

Definition (Diffie-Hellman)
Set-up. Persons AA and BB choose a very large prime pp and a (usually large) primitive element x∈Zp∗x \in \mathbb{Z}_p^*. Person AA chooses some integer s>1s > 1 as their secret key, and Person BB chooses some integer t>1t > 1 as their secret key.

  • Public information: the prime pp and the primitive element xx.
  • Private information: the secret keys ss and tt.

Encryption. Person AA computes yA=xs mod py_A = x^s \bmod p and announces it. Person BB computes yB=xt mod py_B = x^t \bmod p and announces it.
Conversion. Person BB computes (yA)t mod p(y_A)^t \bmod p and Person AA computes (yB)s mod p(y_B)^s \bmod p.

The reason this works is one line of index laws:

(yA)t=(xs)t=xst=(xt)s=(yB)s in Zp,\begin{align*} (y_A)^t &= (x^s)^t \\ &= x^{st} \\ &= (x^t)^s \\ &= (y_B)^s \text{ in } \mathbb{Z}_p, \end{align*}

so both parties end up holding the same number z=xst mod pz = x^{st} \bmod p. Basically, exponentiation commutes, so it does not matter in which order the two secret exponents are applied; AA and BB arrive at the same place along different routes, and neither ever transmitted their own exponent. Nobody listening in ever sees ss or tt — only pp, xx, yAy_A and yBy_B — and zz can then be used as the key for whatever symmetric cypher they like.

The shared secret is xstx^{st}, not xs+tx^{s+t} and not yAyBy_A y_B. Multiplying the two announced numbers together gives xs+tx^{s+t}, which an eavesdropper can compute for free; a surprising number of students write this down.

Recall from Order and Primitive Elements that a primitive element xx of Zp∗\mathbb{Z}_p^* has ord⁡p(x)=ϕ(p)=p−1\operatorname{ord}_p(x) = \phi(p) = p - 1, and that its powers sweep out the whole of Zp∗\mathbb{Z}_p^*. Two consequences matter here: exponents are only ever meaningful modulo p−1p-1, and every possible element of Zp∗\mathbb{Z}_p^* is a candidate value of yAy_A. Reduce Diffie-Hellman exponents modulo p−1p - 1, never modulo pp.

Cracking Diffie-Hellman by Brute Force#

With small numbers you can attack the system directly, by tabulating the powers of xx until you find the announced value. That is a discrete logarithm computation, and doing one by hand is the best way to see why the real system uses gigantic primes.

Example. Ada and Byron have set up a Diffie-Hellman cryptosystem with modulus 7979 and primitive element 33. Ada announces that her encrypted number is 7575, and Byron announces that his is 22. Find their shared secret key.
We need ss with 3s=753^s = 75 or tt with 3t=23^t = 2 in Z79\mathbb{Z}_{79}; either one on its own is enough, because once we know one secret exponent we can apply it to the other person's announced number. So tabulate the powers of 33 modulo 7979, reducing at every step:

kk 11 22 33 44 55 66 77 88 99 1010 1111 1212
3k3^k 33 99 2727 22 66 1818 5454 44 1212 3636 2929 88

Byron's number appears almost immediately: 34=81=79+2=23^4 = 81 = 79 + 2 = 2, so Byron's secret key is t=4t = 4. That is all we need. Applying it to Ada's announced number, and writing 75=−475 = -4 in Z79\mathbb{Z}_{79},

z=(yA)t=754=(−4)4=256=3×79+19=19 in Z79.\begin{align*} z &= (y_A)^t \\ &= 75^4 \\ &= (-4)^4 \\ &= 256 \\ &= 3 \times 79 + 19 \\ &= 19 \text{ in } \mathbb{Z}_{79}. \end{align*}

Therefore, the shared secret key is z=19z = 19.

For completeness, let us also find Ada's key by continuing the table until 7575 shows up:

kk 1313 1414 1515 1616 1717 1818 1919 2020 2121 2222 2323 2424 2525 2626 2727 2828 2929 3030
3k3^k 2424 7272 5858 1616 4848 6565 3737 3232 1717 5151 7474 6464 3434 2323 6969 4949 6868 4646
kk 3131 3232 3333 3434 3535 3636 3737 3838 3939 4040 4141 4242 4343 4444 4545 4646 4747 4848
3k3^k 5959 1919 5757 1313 3939 3838 3535 2626 7878 7676 7070 5252 7777 7373 6161 2525 7575 6767

So 347=753^{47} = 75 and Ada's secret key is s=47s = 47. Notice the landmark at k=39k = 39: since 33 is primitive and ord⁡79(3)=78\operatorname{ord}_{79}(3) = 78, we must have 339=−1=783^{39} = -1 = 78, and the table confirms it. That single fact halves the work, because 339+j=−3j3^{39 + j} = -3^j; for instance 38=43^8 = 4 immediately gives

347=339×38=−4=75 in Z79,3^{47} = 3^{39} \times 3^8 = -4 = 75 \text{ in } \mathbb{Z}_{79},

without tabulating anything past k=39k = 39. Cross-checking the shared key three different ways,

(yA)t=754=19,(yB)s=247=19,xst=347×4=3188=3188 mod 78=332=19,\begin{align*} (y_A)^t &= 75^4 = 19, \\ (y_B)^s &= 2^{47} = 19, \\ x^{st} &= 3^{47 \times 4} = 3^{188} = 3^{188 \bmod 78} = 3^{32} = 19, \end{align*}

where the last line reduced the exponent 188=2×78+32188 = 2 \times 78 + 32 modulo the order 7878 and then read 332=193^{32} = 19 straight off the table. All three agree, which is a strong sign that the two discrete logarithms were read correctly.

Example. You and a friend have set up a Diffie-Hellman cryptosystem with modulus 2323 and primitive element 55. Your friend announces that their encrypted number is 88. Find their secret key.
Tabulate the powers of 55 in Z23\mathbb{Z}_{23}:

kk 11 22 33 44 55 66 77 88
5k5^k 55 22 1010 44 2020 88 1717 1616

Reading along, 56=85^6 = 8. Therefore, your friend's secret key is 66. (Strictly, any exponent congruent to 66 modulo ord⁡23(5)=22\operatorname{ord}_{23}(5) = 22 would produce the same announced number, so the key is only determined modulo 2222; the smallest positive choice is 66.)

Why the Base Must Be Primitive#

The last two examples show the whole system being broken by hand in under a minute, which is precisely what a real Diffie-Hellman set-up is trying to make impossible. The defence is to make pp enormous, and — crucially — to insist that xx is a primitive element.

The reason is that a brute-force attacker only ever has to search through the set of numbers that are actually reachable as powers of xx, namely ⟨x⟩\langle x \rangle. If xx is primitive then ⟨x⟩=Zp∗\langle x \rangle = \mathbb{Z}_p^*, which has p−1p - 1 elements and is as large as the search space can possibly be. If xx is not primitive, then ord⁡p(x)\operatorname{ord}_p(x) is a proper divisor of p−1p-1, so it is at most (p−1)/2(p-1)/2; choosing a non-primitive base instantly halves (at best) the number of possibilities an attacker has to check, and usually does far worse than that.

The extreme case makes the point vividly. Suppose someone chose x=p−1≡−1(modp)x = p - 1 \equiv -1 \pmod p. Then

xk=(−1)k={1,k even,−1,k odd,\begin{align*} x^k &= (-1)^k \\ &= \begin{cases} 1, & k \text{ even}, \\ -1, & k \text{ odd},\end{cases} \end{align*}

so the only numbers that can ever be announced are 11 and −1-1, the shared secret is one of two values, and an attacker guesses it on the first or second try. All the size of pp has bought you is nothing at all; the security came from the order of the base, not the size of the modulus. This is the same lesson as the 2626-key Caesar shift, dressed up differently.

Note

Fact
The security of the Diffie-Hellman cryptosystem relies on the difficulty of calculating discrete logarithms, that is, of finding ss given xx, pp and xs mod px^s \bmod p.

Basically, computing xs mod px^s \bmod p by repeated squaring is fast even when ss has hundreds of digits, while going backwards from xsx^s to ss has no known fast method for a general large prime pp. That one-way behaviour is the entire foundation, and it is a different hard problem from the factorising problem that props up RSA; if somebody found a fast factorising algorithm tomorrow, Diffie-Hellman would not automatically fall with it (and vice versa).

Common Exam Traps#

Almost every mark lost in this topic comes from one of the following, so it is worth reading this list before an exam.

  • ss must be coprime to ϕ(n)\phi(n). If gcd⁡(s,ϕ(n))≠1\gcd(s, \phi(n)) \neq 1 then no decryption exponent exists at all. Check the gcd before you start the EEA rather than discovering it halfway through.
  • Exponents live modulo ϕ(n)\phi(n), bases live modulo nn. Solve st≡1(modϕ(n))st \equiv 1 \pmod{\phi(n)}, never (modn)\pmod n. In Diffie-Hellman the corresponding modulus for exponents is p−1p - 1, never pp.
  • ϕ(pq)=(p−1)(q−1)\phi(pq) = (p-1)(q-1), not pq−1pq - 1. For n=55n = 55 this is 4040, not 5454. Every subsequent number is wrong if this one is.
  • Normalise tt to a positive value. The EEA cheerfully returns things like −1909-1909; add ϕ(n)\phi(n) until tt lands in {1,…,ϕ(n)−1}\{1, \dots, \phi(n) - 1\}, then verify st≡1st \equiv 1 by direct multiplication.
  • Do not reduce the exponent modulo the order of a non-unit. In the x↦x27 mod 55x \mapsto x^{27} \bmod 55 system, the plaintexts 55 and 2020 are not units mod 5555; the decryption theorem covers them, but Euler's Theorem applied blindly does not.
  • Get the letter dictionary right. For the Caesar shift, Z→0Z \to 0 because we work in Z26\mathbb{Z}_{26}; for RSA the standard is A→1A \to 1 through Z→26Z \to 26 with no wrap. Check which one the question is using before converting anything.
  • In Diffie-Hellman, you only need one of the two secret keys. Once you have found tt from yBy_B, apply it to yAy_A; there is no need to solve the second discrete logarithm as well, and doing so wastes exam time.
  • The Diffie-Hellman shared secret is xstx^{st}. It is not xs+tx^{s+t}, and it is not yAyBy_A y_B.
  • Reduce at every step of a modular exponentiation and use small negative representatives (49=−649 = -6 mod 5555, 75=−475 = -4 mod 7979); this is the same advice as in Modular Arithmetic and it is what keeps these computations doable by hand.
  • Remember what is public. In the RSA set-up the pair (n,s)(n, s) is public and p,q,ϕ(n),tp, q, \phi(n), t are all secret; in the Diffie-Hellman set-up the pair (p,x)(p, x) is public along with the announced yA,yBy_A, y_B, while ss, tt and zz are secret. Questions frequently hinge on noticing that ϕ(n)\phi(n) is not public information.

Finally, keep the definition of a cryptosystem in mind as the frame for the whole topic: everything here is a pair of mutually inverse functions, and the interesting content is never the algebra (which is just index laws and Euler's Theorem) but the asymmetry — the gap between how hard the forward map is and how hard the backward map is without the key. That is also what distinguishes this lecture from Codes, where the enemy is random noise rather than an eavesdropper, and where we happily publish everything.