← All modules
Public-key·50 min

Elliptic Curve Cryptography (ECC / ECDSA)

The same public-key guarantees as RSA, with dramatically smaller keys — because the underlying hard problem is different math entirely.

Developer / EngineerSecurity ArchitectResearcher / Academic

A different hard problem

Elliptic Curve Cryptography builds public-key systems on the algebra of points on an elliptic curve over a finite field, rather than on integer factorization. The hard problem here is the elliptic curve discrete logarithm problem (ECDLP): given a starting point G and a resulting point Q = kG (k applications of a 'point addition' operation), it's computationally infeasible to recover k.

Crucially, no sub-exponential classical algorithm is known for ECDLP the way one exists for factoring — which means ECC achieves equivalent classical security to RSA with far smaller keys. A 256-bit ECC key is considered roughly as strong as a 3072-bit RSA key.

y2=x3+ax+b(modp)y^{2} = x^{3} + ax + b \pmod{p}

The general form of an elliptic curve over a finite field — the set of (x, y) points satisfying this equation, plus a point at infinity.

Q=k⋅GQ = k \cdot G

Public key Q is the base point G "added to itself" k times. Easy forward; recovering k (the private key) is the ECDLP.

Point addition: the operation everything is built from

"Adding" two points on an elliptic curve has a genuinely geometric definition, which is part of why ECC feels less intuitive than RSA's arithmetic at first. To add two distinct points P and Q, draw a straight line through them — since the curve is cubic, that line crosses it at exactly one more point. Reflecting that third point across the x-axis gives P + Q. This isn't a metaphor for the algebra; it's literally how the group operation is defined, and it has a closed-form algebraic formula that a computer evaluates directly, with no actual line-drawing involved.

Doubling a point (adding P to itself, needed whenever a bit of the private key is 1 during scalar multiplication) works the same way in the limit: instead of a line through two distinct points, you use the tangent line at P.

Point addition on a real curve (y² = x³ − 3x + 3): P + Q = R

PQ−RR = P+Q

P and Q sit on the right-hand branch of the curve. The line through them crosses the curve a third time on the left, at −R; reflecting that point across the x-axis gives R = P + Q. Every point drawn here is on the actual curve y² = x³ − 3x + 3 — nothing is approximated for effect.

Scalar multiplication: how kG is actually computed

Computing Q = kG for a 256-bit private key k doesn't mean adding G to itself k times — that would be astronomically slow. Instead, implementations use double-and-add, the same square-and-multiply idea behind fast RSA exponentiation: scan the bits of k, doubling a running point at every step and adding G whenever that bit is 1. A 256-bit scalar multiplication takes on the order of 256 doublings and up to 256 additions — fast enough to run thousands of times per second, while still being, as far as anyone knows, computationally impossible to reverse.

Go deeperMontgomery's ladder: making scalar multiplication constant-time⌄

Double-and-add has a subtle problem that has nothing to do with the underlying math: its running time and operation pattern depend directly on the bits of the secret scalar k. A doubling happens every step, but an addition only happens on a 1-bit — so an attacker who can measure timing or power consumption precisely enough (the side-channel attacks covered elsewhere in this catalog) can potentially read k's bits straight off the execution pattern, one bit-dependent branch at a time.

Montgomery's ladder fixes this by restructuring the algorithm so every single step, regardless of whether the current bit is 0 or 1, performs exactly one doubling and one addition — just applied to different running values depending on the bit. The total work per step never changes, so there's no timing signal tied to the scalar's bit pattern left to leak. This is precisely the algorithm underneath X25519, the Curve25519-based key exchange mentioned earlier in this module, and it's a big part of why Curve25519 implementations are considered easier to write safely than older curves.

double-and-add: 1 doubling every bit, 1 addition only on set bits\text{double-and-add: 1 doubling every bit, 1 addition only on set bits}
Montgomery ladder: 1 doubling AND 1 addition every bit, unconditionally\text{Montgomery ladder: 1 doubling AND 1 addition every bit, unconditionally}

Practice

For a 256-bit scalar with exactly 100 of its bits set to 1: double-and-add performs 1 doubling per bit plus 1 addition per set bit. Montgomery's ladder performs 1 doubling AND 1 addition per bit, every time. How many more total point operations does the ladder perform than double-and-add?

A worked example over a small curve

Real curves use primes hundreds of bits long, but the arithmetic works identically at toy scale. Take the curve y² = x³ + 2x + 2 (mod 17) — a small finite field with only 17 possible values for each coordinate — with base point G = (5, 1).

Computing 2G (doubling G) using the curve's point-doubling formula gives (6, 3). Computing 3G = 2G + G gives (10, 6). An attacker who only sees G and 3G = (10, 6) has to recover the scalar 3 — trivial here with a 17-element field, but the identical computation over a 256-bit field is the ECDLP that underpins every ECC key in production.

y2=x3+2x+2(mod17),G=(5,1)y^{2} = x^{3} + 2x + 2 \pmod{17}, \quad G = (5,1)
2G=(6,3)3G=(10,6)2G = (6,3) \qquad 3G = (10,6)

Point addition, worked with the actual formula

The chord-and-tangent picture is the geometry; here's the algebra a computer actually evaluates. To add two distinct points P = (x₁, y₁) and Q = (x₂, y₂), compute the slope m = (y₂ − y₁) / (x₂ − x₁) — using the modular inverse for that division — then x₃ = m² − x₁ − x₂ and y₃ = m(x₁ − x₃) − y₁, all reduced mod p. Doubling a point uses the tangent slope instead: m = (3x₁² + a) / (2y₁).

Worked example: on the same curve, compute 2G + 3G using 2G = (6, 3) and 3G = (10, 6). The slope is m = (6−3)/(10−6) = 3/4 mod 17. The modular inverse of 4 mod 17 is 13 (since 4×13 = 52 ≡ 1), so m = 3×13 mod 17 = 39 mod 17 = 5. Then x₃ = 5² − 6 − 10 = 9 mod 17, and y₃ = 5×(6−9) − 3 = −18 mod 17 = 16. So 2G + 3G = (9, 16) — which is exactly 5G, confirming the arithmetic is consistent.

m=y2−y1x2−x1(modp)x3=m2−x1−x2y3=m(x1−x3)−y1m = \frac{y_2 - y_1}{x_2 - x_1} \pmod{p} \qquad x_3 = m^2 - x_1 - x_2 \qquad y_3 = m(x_1 - x_3) - y_1

Practice

On the curve y² = x³ + 2x + 2 (mod 17), 3G = (10, 6) and 4G = (3, 1). Using the point-addition formula, compute 3G + 4G (which should equal 7G). Give the result as x,y.

The order of a curve, and why it matters

Just as the integers mod p form a group of size p−1 under multiplication, the points on an elliptic curve mod p form a group too — and counting every point (including the point at infinity) gives the curve's order. Hasse's theorem guarantees this count stays close to p+1, but the exact value matters enormously: if the order has small factors, the same small-subgroup confinement attack covered in the Diffie-Hellman module works against ECC too, forcing a shared secret into a tiny, brute-forceable set of possibilities.

The toy curve used throughout this module happens to have exactly 19 points (18 finite points plus infinity) — and 19 is prime. That's not a coincidence for a well-chosen curve: real production curves like secp256k1 and P-256 are specifically selected to have prime (or near-prime) order precisely so there are no small subgroups for an attacker to confine anything into.

∣p+1−#E(Fp)∣≤2p(Hasse’s theorem)|p + 1 - \#E(\mathbb{F}_p)| \leq 2\sqrt{p} \quad \text{(Hasse's theorem)}
Go deeperPohlig-Hellman: when a smooth curve order breaks everything⌄

"Small factors in the order" isn't just a small-subgroup annoyance — if the order factors completely into small primes (a "smooth" order), the Pohlig-Hellman algorithm breaks the ECDLP entirely, no matter how large the curve's field is. The idea directly reuses two tools already covered in this catalog: solve the discrete log separately inside each small prime-order subgroup (fast, since each one is individually tiny — brute force or baby-step giant-step handles it), then stitch those partial results back together into the full private key using the Chinese Remainder Theorem from the math foundations module.

This is exactly why curve order matters as much as field size: a 256-bit field with a smooth, small-factor order is not a 256-bit-secure curve at all — its real security is bounded by the largest prime factor of the order, not by the field's bit length. Production curves are chosen with prime (or near-prime) order specifically to make Pohlig-Hellman's divide-and-conquer approach have nothing to divide.

n=p1×p2×⋯×pk  ⇒  solve ECDLP mod each pi, combine via CRTn = p_1 \times p_2 \times \cdots \times p_k \;\Rightarrow\; \text{solve ECDLP mod each } p_i, \text{ combine via CRT}

Practice

A poorly chosen curve has order n = 223,092,870 — the product of the first nine primes (2×3×5×7×11×13×17×19×23). Brute-forcing the discrete log directly costs up to n steps. Pohlig-Hellman's dominant cost is solving the ECDLP in the largest prime-order subgroup, 23. Roughly how many times faster is Pohlig-Hellman, expressed as n ÷ 23?

Brute-forcing a small elliptic curve discrete log

On the toy curve (order 19), the ECDLP is small enough to brute force by hand: starting from G and repeatedly adding G, check after each addition whether the running point matches the target Q. With only 19 possible scalars, this terminates fast — but the exact same search against a 256-bit curve would need to check roughly 2²⁵⁶ points, which is the entire reason ECC is considered secure at that scale.

Practice

On the curve y² = x³ + 2x + 2 (mod 17) with G = (5, 1), find k (between 1 and 19) such that kG = Q = (7, 6).

Smaller keys, real consequences

Smaller keys mean less data to transmit and store, faster key generation, and faster signing operations — which is why ECC dominates mobile, IoT, and high-volume TLS deployments. Curve25519 (for key exchange, as X25519) and Curve448 are widely used modern curves chosen partly to avoid pitfalls found in some earlier NIST-standardized curves.

NIST P-256 (secp256r1)

  • •Standardized by NIST in 1999, still the most widely deployed curve in TLS certificates
  • •Parameters generated from an unexplained random seed — a long-running source of community distrust
  • •Implementation is more prone to subtle timing side-channels if not written carefully

Curve25519 (X25519)

  • •Designed by Daniel J. Bernstein in 2005 specifically to make safe implementation easier
  • •Every parameter choice is publicly justified — no unexplained constants
  • •Default key exchange curve in TLS 1.3, SSH, Signal, and WireGuard

ECDSA: signatures on curves

The Elliptic Curve Digital Signature Algorithm (ECDSA) uses ECC to produce digital signatures — proof that a message came from the holder of a private key, without revealing that key. It's the signature scheme behind most modern TLS certificates and behind Bitcoin and Ethereum transaction signing.

ECDSA requires a fresh, truly random per-signature value (the nonce) for every signature. Reusing a nonce, or generating it with a weak random number generator, leaks the private key directly — this has caused real-world key compromises, including a widely cited 2010 Sony PlayStation 3 signing-key leak caused by a static nonce.

ECDSA sign and verify

  1. 1

    Sign

    Hash the message, generate a fresh random nonce k, and combine them with the private key to produce a signature pair (r, s).

  2. 2

    Publish

    The message and signature (r, s) travel together; the private key never leaves the signer.

  3. 3

    Verify

    Anyone with the public key Q recomputes a value from (r, s) and the message hash, and checks it matches r.

  4. 4

    Accept or reject

    A match proves the signer holds the private key for Q — without Q ever having been used to sign anything itself.

r=(k⋅G)x mod ns=k−1(H(m)+r⋅d) mod nr = (k \cdot G)_x \bmod n \qquad s = k^{-1}(H(m) + r \cdot d) \bmod n

The signature is the pair (r, s); k is the per-signature nonce, d is the private key, n is the curve's group order.

How a leaked nonce leaks the entire private key

The ECDSA signing formula involves the nonce k algebraically alongside the private key d. If an attacker ever learns k for even one signature — through a weak RNG, a side-channel leak, or (as in the PS3 case) the same k reused across two different signatures — they can rearrange the signing equation to solve directly for d. This is a one-shot, deterministic break, not a probabilistic weakening: a single exposed nonce is equivalent to publishing the private key outright.

Go deeperCurveball: forging trust without ever learning the private key⌄

Not every real-world ECDSA break needs a leaked nonce. CVE-2020-0601 — nicknamed "Curveball", disclosed by the NSA in January 2020 — exploited a validation gap in Windows' CryptoAPI: it checked whether a certificate's public key point matched a trusted root's public key, but never checked that the certificate's explicit curve parameters (specifically, the base point G) matched the standard, fixed generator for that named curve.

That gap is enough to forge a trusted certificate without factoring anything or learning any real private key. An attacker picks their own secret integer k, then computes a new base point G′ = k⁻¹ · Q, where Q is the real root CA's already-trusted public key. Now k · G′ = k · (k⁻¹ · Q) = Q exactly — so the point Q, which Windows already trusts, is also a valid "public key" under the attacker's own private key k and their substituted generator G′. The attacker can sign anything with k, present G′ as the certificate's domain parameters, and a vulnerable verifier that only checks "does the public key point equal Q" accepts it — never noticing the generator itself was swapped out from under it.

G′=k−1⋅Q  ⇒  k⋅G′=Q(the trusted public key, forged without knowing the real private key)G' = k^{-1} \cdot Q \;\Rightarrow\; k \cdot G' = Q \quad \text{(the trusted public key, forged without knowing the real private key)}

Practice

On a curve with point order n = 19, an attacker picks k = 7 as their own private key and needs G′ = k⁻¹ · Q. What is k⁻¹ mod 19?

Why it matters for the PQC conversation

ECC's smaller keys and wide deployment make it, if anything, a more urgent migration target than RSA in some contexts — it's cryptographically broken by the same Shor's algorithm class of quantum attack, but it's embedded in more places (TLS 1.3 defaults, most modern certificate authorities, cryptocurrency).

Knowledge check

Test what you just learned →

10 quick questions, with an explanation for every answer.

Up next

Diffie-Hellman key exchange →

Two parties agree on a shared secret over a public channel, without ever transmitting the secret itself — the idea that started public-key cryptography.