The most surprising thing about ECDH is that it lets two parties agree on a shared secret over an insecure channel without ever sending the secret itself, and it does so using math that’s fundamentally about points on a curve.
Imagine Alice and Bob want to establish a secret key for encrypted communication. They both agree on a public "curve" and a public "generator point" on that curve.
Here’s how they do it:
-
Alice’s Setup:
- She picks a private random number, let’s call it
a. This is her secret. - She calculates a new point on the curve by "multiplying" the generator point
Gby her private numbera. In elliptic curve cryptography, this "multiplication" is repeated addition of the point to itself,atimes. The result is a new point,A = a * G. - Alice sends point
Ato Bob. This is public.
- She picks a private random number, let’s call it
-
Bob’s Setup:
- He picks his own private random number, let’s call it
b. This is his secret. - He calculates his own public point:
B = b * G. - Bob sends point
Bto Alice. This is public.
- He picks his own private random number, let’s call it
-
The Magic:
- Alice receives
B: She takes Bob’s public pointBand "multiplies" it by her private numbera. The result isS_A = a * B. - Bob receives
A: He takes Alice’s public pointAand "multiplies" it by his private numberb. The result isS_B = b * A.
- Alice receives
Because of the properties of elliptic curve multiplication, a * B is the same as a * (b * G), which is (a * b) * G. Similarly, b * A is b * (a * G), which is also (b * a) * G. Since a * b = b * a, both Alice and Bob arrive at the exact same point on the curve: (a * b) * G. This shared point is their secret.
An eavesdropper, Eve, sees G, A, and B. To find the shared secret point, she would need to figure out either a from A = a * G or b from B = b * G. This is known as the Elliptic Curve Discrete Logarithm Problem (ECDLP), which is computationally infeasible for well-chosen curves and large numbers.
This is how ECDH works in practice, often used within TLS/SSL to establish session keys.
Consider a simplified example using a hypothetical curve and generator point.
# This is conceptual Python, not actual ECC library code
# In reality, curves and point operations are complex and highly optimized.
class Curve:
def __init__(self, p, a, b):
self.p = p # Prime modulus for field arithmetic
self.a = a
self.b = b
def is_on_curve(self, point):
if point is None: return True # Point at infinity
x, y = point
return (y**2 - (x**3 + self.a*x + self.b)) % self.p == 0
# Define a simple curve (e.g., secp256k1 parameters would be used in real crypto)
# For demonstration, let's imagine a very small curve (this is NOT cryptographically secure!)
# Let's use a curve y^2 = x^3 + 7 mod 17
# Generator point G = (3, 6)
# Curve parameters: p=17, a=0, b=7
curve = Curve(p=17, a=0, b=7)
G = (3, 6)
# Alice's side
alice_private = 5 # Alice's secret random number
# Alice calculates her public point A = alice_private * G
# This involves repeated point addition. For a=5, A = G + G + G + G + G
# Using actual ECC math, A = 5 * (3, 6) = (7, 12)
alice_public = (7, 12) # This would be calculated by the library
# Bob's side
bob_private = 7 # Bob's secret random number
# Bob calculates his public point B = bob_private * G
# Using actual ECC math, B = 7 * (3, 6) = (15, 1)
bob_public = (15, 1) # This would be calculated by the library
# Alice receives Bob's public point B
# Alice calculates the shared secret: S_A = alice_private * B
# S_A = 5 * (15, 1) = (8, 1) # Using actual ECC math
# Bob receives Alice's public point A
# Bob calculates the shared secret: S_B = bob_private * A
# S_B = 7 * (7, 12) = (8, 1) # Using actual ECC math
# Both Alice and Bob arrive at the same shared secret point (8, 1)
shared_secret_point = (8, 1)
print(f"Alice's calculated secret point: {alice_public}")
print(f"Bob's calculated secret point: {bob_public}")
print(f"Shared secret point: {shared_secret_point}")
# Eve, the eavesdropper, sees G=(3,6), A=(7,12), B=(15,1).
# To find the secret point (8,1), Eve needs to solve for 'a' in A=a*G or 'b' in B=b*G.
# For this tiny example, it's easy:
# G=(3,6), 2*G=(10,2), 3*G=(13,12), 4*G=(7,5), 5*G=(7,12) -> Alice's A, so a=5
# 6*G=(10,15), 7*G=(15,1) -> Bob's B, so b=7
# Then Eve could calculate 5*B or 7*A to find the secret.
# However, with real-world parameters (256-bit keys), this calculation takes trillions of years.
The core problem ECDH solves is key exchange: enabling two parties to establish a shared secret over a public channel without risk of that secret being compromised if the channel is monitored. It leverages the algebraic structure of elliptic curves. The "multiplication" operation in ECC is not standard arithmetic multiplication but a specialized group operation. For a point P on an elliptic curve and an integer k, kP denotes adding P to itself k times. The difficulty of finding k given P and kP is the ECDLP.
A critical aspect often overlooked is the choice of elliptic curve. Curves are not arbitrary; they must be carefully selected to resist known attacks. Parameters like the prime modulus p, coefficients a and b in the curve equation y^2 = x^3 + ax + b mod p, and the generator point G are standardized (e.g., NIST curves like P-256, or the curve used in Bitcoin, secp256k1). Using a non-standard or weak curve can make the ECDLP tractable, compromising the security of the entire exchange.
The next step after establishing a shared secret with ECDH is typically to use that secret as a master key to derive session keys for symmetric encryption (like AES), which is much faster for bulk data encryption.