Note
Go to the end to download the full example code or to run this example in your browser via JupyterLite.
Diffie-Hellman: agreeing on a secret over a public channel (1976)#
Diffie and Hellman showed that two people can reach the same secret by exchanging only public values: each raises the other’s public element to their own private exponent, and both arrive at g**(a*b). An eavesdropper sees g**a and g**b but would need a discrete logarithm to continue.
What to look for#
Both parties compute the same shared element without ever sending it. Then a man in the middle substitutes his own public value: the arithmetic still works, but Alice now shares a secret with Mallory. Agreement on a secret is not authentication of the other person.
The history behind this experiment: Breakthroughs in Cryptography. See Exercises: cryptography for a worked solution to the exercise.
Authentication is a separate problem#
Mallory substitutes her own public value. Alice now shares a secret with Mallory, not Bob. Real protocols authenticate the exchange and use a KDF.
mallory_secret = 4
alice_mallory = group.shared(group.public(mallory_secret), alice_secret)
assert alice_mallory == group.shared(alice_public, mallory_secret)
assert alice_mallory != shared
print("After key substitution, Alice's shared element is", alice_mallory)
After key substitution, Alice's shared element is 2
The same exchange in a group too large to search by hand#
big = bk.crypto.TEACHING_GROUP
a, b = 0x1234_5678_9ABC, 0x0FED_CBA9_8765
assert big.shared(big.public(b), a) == big.shared(big.public(a), b)
Exponentiation scrambles the subgroup#
fig, ax = plt.subplots(figsize=(7, 3.8))
exponents = list(range(1, group.q))
ax.scatter(exponents, [group.public(x) for x in exponents], color="#2563eb")
ax.set(
xlabel="private exponent x", ylabel="public element g**x mod p", title="DH in a tiny subgroup"
)
fig.tight_layout()

Exercise#
Exhaustively recover Alice’s exponent from her public value. Why does this experiment say nothing about the cost for a carefully chosen large group?
Total running time of the script: (0 minutes 0.135 seconds)