Curve orrery
Nearly every TLS and SSH connection agrees its keys on an elliptic curve. We'll take one apart in six exhibits: chords, finite fields, orbits, scalar multiplication that doesn't leak, key agreement and how real curves get chosen.
Everything runs in this tab. The toy arithmetic is this page's own code, checked against RFC 7748, and the real key agreement is the browser's Web Crypto. Keys are fresh for each visit and never stored or sent. Only your progress is saved.
Lab exploredThat's the whole orrery. If you want to see what an agreed key goes on to protect, the Vault lab is next door.
The chord and tangent law
An elliptic curve is the set of points with y² = x³ + ax + b, plus one extra point, O, the point at infinity. You can add its points: draw the line through P and Q, find the third place it meets the curve, and reflect that point in the x-axis. The reflection is P + Q.
Drag P (gold) and Q (teal) along the curve, or use the sliders. Put Q on P and the chord becomes the tangent. Put Q on P's mirror image and the line turns vertical: that sum is O. Then move a and b to find the curves where the law breaks.
y² = x³ − x + 1
Singular
The maths
λ = (y2 − y1) / (x2 − x1) for a chord, λ = (3x12 + a) / (2y1) for the tangent when P = Q
x3 = λ2 − x1 − x2, y3 = λ(x1 − x3) − y1, P + Q = (x3, y3)
Why x3 is λ2 − x1 − x2. Put the line y = λx + c into the curve's equation and you get a cubic, x3 − λ2x2 + … = 0, whose three roots are the three places the line meets the curve. The roots of a cubic add up to minus its x2 coefficient, here λ2. Two of them are x1 and x2, so the third is what's left. The tangent slope comes from differentiating: 2y dy = (3x2 + a) dx.
Why the reflection. Declare that three points on a line add up to O and the law becomes a group. O is the identity, −P is P's mirror image, and the order of the points never matters. Associativity, (P + Q) + R = P + (Q + R), is a theorem about cubics, and no picture makes it obvious. The tests behind this page check it on every toy curve.
Why singular curves are excluded. When 4a3 + 27b2 = 0 the cubic has a repeated root. There both partial derivatives of y2 − x3 − ax − b vanish, so there's no single tangent and P + P is undefined. The other points still add, but it's only the field's own arithmetic in disguise, which hides nothing. Standards require 4a3 + 27b2 ≠ 0.
In practiceNo protocol draws this picture. TLS, SSH and messaging apps use the same law over a finite field of about 2256 elements, where division becomes a modular inverse. That's the next exhibit.
DefenceNever invent curve parameters. Use a standard curve (X25519, P-256, Ed25519) through a vetted library, because nothing in the formulas warns you when a curve is weak.
The same law, mod p
Now do all the arithmetic modulo a prime p. The coordinates are whole numbers from 0 to p − 1, so the curve turns into a finite scatter of dots on a p by p grid. It's mirrored about its middle row. The chord and tangent formulas still work, with division swapped for a modular inverse from the extended Euclidean algorithm.
Click a dot for P and another for Q (or use the arrow keys and Enter). The page shows the slope as a fraction and the inverse step by step. Finish the sum by hand and check it, then count the points against Hasse's bound.
y² = x³ + x + 1 over F23
Pick a point for P, then one for Q.
| Row | r | q | t |
|---|
The maths
#E = p + 1 + ∑x χ(x3 + ax + b), χ(v) = v(p−1)/2 mod p ∈ {1, −1, 0}
|#E − (p + 1)| ≤ 2√p (Hasse), ri+1 = ri−1 − qiri, ti+1 = ti−1 − qiti
Why the count works. For each x the curve needs y2 = v. A nonzero square v has exactly two square roots mod p, zero has one, and a non-square has none, which is 1 + χ(v) points. Add that up over every x, then add O. Why Euler's criterion. By Fermat's little theorem vp−1 = 1, so v(p−1)/2 is a square root of 1, which means it's 1 or −1. It's 1 exactly when v is itself a square.
Why the inverse table works. Start with r = p (t = 0) and r = d (t = 1). Every row keeps r ≡ t × d (mod p), because each new row is the row two above minus q times the row above. The remainders shrink to gcd(d, p) = 1, and the row where r = 1 says 1 ≡ t × d, so that t is d−1. Hasse proved in the 1930s that the count never strays more than 2√p from p + 1. The difference is called the trace.
In practiceReal curves use primes of 255 or 256 bits, far too big to count point by point. Their counts come from Schoof's algorithm, run once when the curve was designed and published with it.
DefenceA received point is two numbers. Check that both are below p and satisfy the curve's equation. The addition formulas never use b, so a point from another curve would quietly be computed on that curve.
A generator's orbit
Add a point G to itself again and again: G, 2G, 3G and so on. With finitely many points the sequence has to come back, and it always comes back through O. The number of steps is the order n of G, and the points it visits form a subgroup, drawn here as an orbit.
Some orbits are short. Protocols use a generator of the largest prime-order subgroup. When the curve has more points than that (a cofactor h above 1), they multiply by h to land in it.
| G | Order n | #E / n | What it is |
|---|
The maths
〈G〉 = {O, G, 2G, …, (n − 1)G}, n | #E (Lagrange), h = #E / q for the largest prime q dividing #E
q × (hP) = (#E)P = O for every point P, so hP lies in the subgroup of order q
Why n divides #E. The multiples of G form a subgroup, and Lagrange's theorem says a subgroup's size divides the group's. Every coset of 〈G〉 has exactly n points, and the cosets split the whole curve. That's also how the page finds an order quickly: start from #E and divide out each prime while the multiple is still O.
Why prime order matters for key agreement. If q is prime, every point of the subgroup except O has order q. Each one generates the whole group, and every secret from 1 to q − 1 gives a different public key. With a composite order, some points live in small subgroups, and there a secret has only a few possible values. Cofactor clearing multiplies by h to push any point into the prime-order part, and X25519 does it by making every secret a multiple of 8.
In practiceP-256 has prime order (cofactor 1). Curve25519 has 8q points with q a 253-bit prime, which is why X25519 clears the cofactor inside its scalar.
DefenceCheck that a received point lies in the prime-order subgroup (qP = O), or clear the cofactor, before a secret multiplies it.
Scalar multiplication that doesn't leak k
A public key is kG for a secret k. Adding G to itself k − 1 times would never finish at real sizes, so implementations read k's bits: double for every bit and add G for every 1. That's fast, but the rhythm depends on the secret, because more set bits mean more additions.
The Montgomery ladder does one addition and one doubling per bit, whatever the bit is, so the sequence of operations says nothing about k. Run both below on y² = x³ + 6x + 2 over F1009 (1,021 points, G = (0, 439)) and compare the timelines. the ladder's timeline is boring on purpose lol.
D a doubling A an addition. Equal work draws equal length.
The maths
double-and-add: L − 1 doublings + popcount(k) − 1 additions, repeated addition: k − 1 additions, ladder: L additions + L doublings
bit 0: (R0, R1) ← (2R0, R0 + R1), bit 1: (R0, R1) ← (R0 + R1, 2R1), starting from (O, G)
Why double-and-add works. Reading k from its top bit, doubling shifts the bits read so far one place left and adding G sets the new bottom bit. After every step R is the prefix of k read so far, times G. With L the bit length of k, the cost is about 1.5 L operations instead of k: for a 256-bit key, 384 operations instead of 2256.
Why the ladder's invariant holds. It starts with R1 − R0 = G − O = G. After a 0 bit the difference is (R0 + R1) − 2R0 = R1 − R0. After a 1 bit it is 2R1 − (R0 + R1) = R1 − R0. Either way it stays G, and R0 ends as kG. Only which register gets which result depends on the bit, and real code does that with a constant-time conditional swap, as RFC 7748 does for X25519's 255 steps.
In practiceX25519 runs the ladder over all 255 bit positions with the same field operations every time, and swaps registers with arithmetic masks instead of branches. Libraries for P-256 use fixed-window tables read in constant time. Timing leaks in scalar multiplication have been measured across a network (Brumley and Tuveri, 2011), which is why this matters.
Watch outThis page's BigInt arithmetic isn't constant time, so it shows the idea and protects no key. Real code never branches on a secret bit or indexes a table with one.
Two secrets, one point
Alice picks a secret a and publishes aG. Bob picks b and publishes bG. Each multiplies the other's point by their own secret, and both arrive at abG without ever sending a secret. Getting abG from aG and bG alone is the elliptic-curve Diffie-Hellman problem, and it's believed hard on a big enough curve.
First on the toy curve from Exhibit IV, then for real with the browser's X25519 and P-256. This page's own X25519 is checked against the browser and RFC 7748, and HKDF turns the shared secret into an AES key.
Checking whether this browser offers X25519 in Web Crypto.
The ladder written in this page (255 steps, the RFC's formulas and conditional swaps) run on the published test vectors.
Agree an X25519 or P-256 key first. Both sides then derive their own AES key.
The maths
a(bG) = (ab)G = (ba)G = b(aG), computed as (ab mod q)G
X25519 clamping: k[0] &= 248, k[31] &= 127, k[31] |= 64 (a little-endian 255-bit scalar: 2254 + 8 × a number below 2251)
Why both sides agree. bG is G added to itself b times, and adding that a times adds G to itself ab times. The group is commutative, so the order of the two multiplications can't matter. Because qG = O, only ab mod q counts.
Why clamping. Clearing the three low bits makes every secret a multiple of 8, Curve25519's cofactor, so any small-order part of a received point is multiplied away. Clearing bit 255 and setting bit 254 gives every secret the same length, so the ladder always runs 255 steps. Why a KDF. A shared secret is a curve coordinate, so its values aren't equally likely and it carries no context. HKDF extracts a uniform key and binds in what the key is for, so one agreement never serves two purposes.
In practiceTLS 1.3 key shares are X25519 or P-256 points like these, and the shared secret goes into an HKDF key schedule that mixes in the handshake transcript. SSH, Signal and WireGuard use X25519 too.
DefenceValidate what you receive: a P-256 point must be on the curve and not O, and an all-zero X25519 secret must be rejected (RFC 7748 section 6). Run every shared secret through a KDF, and never reuse an ephemeral key pair.
What makes a curve fit for use
A curve is fit for use when its prime-order subgroup is large and its cofactor is small and handled. The constants should come from a rule anyone can rerun, and the formulas should have no exceptional cases. The toy curves on this page fail the first test by design.
Below: the security level of every toy curve, the published key-size equivalences, and a measurement of why elliptic curves won key agreement.
| Curve | #E | Largest prime q | h | √(πq/4) | Security |
|---|
| Security | Symmetric | RSA modulus | Curve order |
|---|---|---|---|
| 80 bits | 2TDEA | 1,024 | 160 to 223 |
| 112 bits | 3TDEA | 2,048 | 224 to 255 |
| 128 bits | AES-128 | 3,072 | 256 to 383 |
| 192 bits | AES-192 | 7,680 | 384 to 511 |
| 256 bits | AES-256 | 15,360 | 512 and up |
| Operation | Median | Public key |
|---|
- A large prime-order subgroup. Security is about half the bits of q, so 128-bit security needs q near 2256.
- A small cofactor, handled. P-256 has h = 1. Curve25519 has cofactor 8 and clears it by clamping. Its twist also has a large prime subgroup, so an x-only ladder that never checks the curve stays safe.
- The field. A prime like 2255 − 19 makes reduction cheap and fits 32 bytes.
- Rigid constants. RFC 7748 Appendix A takes the smallest A meeting stated rules, so nobody had room to choose a curve with a hidden weakness. Its rules also forbid a trace of 0 or 1, the anomalous and supersingular kinds.
- Complete formulas. The textbook law has special cases (O, P = Q, P = −Q) that code must branch on. The ladder's formulas and the Edwards addition law work for every input, and complete formulas now exist for P-256 too (Renes, Costello and Batina, 2016).
For v² = u³ + Au² + u, try A = 6, 10, 14 and so on (A − 2 divisible by 4). Stop when the curve's point count is a prime times 8 and its twist's is a prime times 4 (4 and 4 when p is 3 mod 4). For 2255 − 19 the rule stops at A = 486662.
| A | #E | Twist | Verdict |
|---|
The maths
generic cost ≈ √(πq / 4) group operations, security ≈ log2 √(πq / 4) = ½ log2 q − 0.17 bits
The square-root law. Pollard's rho method (1978) needs about √(πq/4) steps in a group of prime order q. Shoup (1997) proved that no generic method, one that only adds and compares points, does much better than √q. So a b-bit prime order gives about b/2 bits of security. The page states this bound and runs no solver.
Why RSA needs so much more. Factoring has sub-exponential methods (the number field sieve), so RSA keys must grow much faster than the security they buy. Well-chosen curves have no known method better than the generic one. That's the gap in the table: 128 bits of security takes a 256-bit curve or a 3,072-bit modulus.
In practiceX25519 and P-256 give about 128-bit security with 32-byte secrets, where RSA needs 3,072 bits. TLS now also deploys hybrid key agreement (X25519 with ML-KEM) against a future quantum computer, which would break every curve here.
DefenceUse a standard curve through a maintained library that validates points and clears cofactors. Retire RSA key agreement, and plan the move to hybrid post-quantum key exchange.