§ 02 · Cryptography
Elliptic curves
Easy to multiply, impossible to divide
On this page 7 sections
Your Pearl private key is just a huge random number. Your public key is a point on a curve, made from that number. The magic is that the step from one to the other only works in one direction.
That one-way step is the arithmetic of an elliptic curveElliptic curve: A special curve whose points can be “added” together. Multiplying a point by a number is easy, but undoing it is practically impossible, which is what keeps private keys secret.. Pearl uses the same curve as Bitcoin, called secp256k1secp256k1: The particular elliptic curve Bitcoin uses. Pearl uses exactly the same curve for its keys and Schnorr signatures.. This page builds the idea on a tiny toy curve you can check by hand, then scales it up.
Try it
Pick two points and add them, or multiply a point by a number, and watch the result jump around the dots.
What is an elliptic curve?
It’s the set of points (x, y) that satisfy one equation. Pearl’s curve uses about the simplest one possible:
Over ordinary numbers that draws a smooth curve. But cryptography uses whole numbers with modular arithmeticModular arithmetic: Arithmetic that wraps around after a fixed number, like hours on a clock: with mod 17, 15 + 5 = 3. Elliptic-curve keys and signatures are all computed this way., where everything wraps around at a prime p, like a clock. With p = 17, for example, 15 + 5 = 20 wraps to 3.
On a toy curve with p = 17, only 17 points (x, y) fit the equation. Add one special point, the “point at infinity”, which plays the role of zero, and there are 18 points in all.
How do you add two points?
Geometrically: draw a straight line through the two points. It crosses the curve at exactly one more point. Flip that point to the other side (negate its y) and you have the sum.
To add a point to itself (“doubling”), use the tangent line at that point instead. And adding a point to its mirror image gives the point at infinity, the zero of this arithmetic.
On a modular curve there’s no picture to draw, but the same rule becomes a formula. Here is G + 2G on the toy curve, with G = (6, 6) and 2G = (1, 5), all arithmetic mod 17:
-
The slope
. Dividing by 5 mod 17 means multiplying by 7, because 5 × 7 = 35 = 2 × 17 + 1. So λ = 7.
-
The new x
-
The new y
-
Check
(8, 14): 14² = 196 ≡ 9, and 8³ + 7 = 519 ≡ 9. On the curve. That’s 3G.
Doubling G by hand
For doubling, the slope comes from the tangent: . Mod 17, 108 ≡ 6, and dividing by 12 means multiplying by 10 (12 × 10 = 120 ≡ 1), so λ = 60 ≡ 9.
Then and . So 2G = (1, 5), as the figure shows.
What does it mean to multiply a point?
Multiplying G by a number k means adding G to itself k times: 3G = G + G + G. Here are all the multiples on the toy curve:
| k | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|---|---|---|---|---|---|---|---|---|
| kG | (6,6) | (1,5) | (8,14) | (2,10) | (10,15) | (5,9) | (15,4) | (12,1) | (3,0) |
| k | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| kG | (12,16) | (15,13) | (5,8) | (10,2) | (2,7) | (8,3) | (1,12) | (6,11) | ∞ |
At 18 it wraps back to the point at infinity and starts again. The number of steps before the wrap, 18 here, is called the order.
This is exactly how keys work. Pick a secret number, say 5: that’s the toy private key. Multiply the generator pointGenerator point: A fixed, publicly known point on an elliptic curve. Your public key is the generator point multiplied by your private key.: 5G = (10, 15). That’s the toy public key.
For a real 256-bit key, adding G to itself trillions of trillions of times would take forever. Computers use double-and-add instead: write k in binary, double for every bit and add G for every 1 bit. A 256-bit key takes about 256 doublings, which is instant.
Why can’t anyone work backwards?
Going from 5G back to 5 means asking “how many times was G added?” That’s the discrete logarithm problem.
On the toy curve it’s trivial: try G, 2G, 3G… and you’re done within 18 steps. Nothing smarter is needed. On secp256k1 the same search has about 10⁷⁷ steps, and the best known methods only take that down to about 2¹²⁸ steps, still far beyond every computer on Earth. That gap between “easy forwards” and “impossible backwards” is what keeps a private key private.
What are secp256k1’s real numbers?
secp256k1 is the toy curve with enormous numbers. Same equation, y² = x³ + 7:
| Parameter | Value |
|---|---|
| p (the modulus) | fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f |
| n (the order of G) | fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 |
| G, x-coordinate | 79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 |
A private keyPrivate key: A huge random number (256 bits) that only you should know. It lets you sign transactions that spend your coins, so whoever has it controls them. is any number from 1 to n − 1, about 1.16 × 10⁷⁷ choices. Its public keyPublic key: A number made from your private key with elliptic-curve math. Anyone can use it to check your signatures, but no one can work backwards from it to the private key. is that number times G. Here are the first three, computed with this site’s code:
| Private key | Public key (compressed, 33 bytes) |
|---|---|
| 1 | 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 |
| 2 | 02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5 |
| 3 | 02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9 |
Private key 1 gives G itself. Nobody should use these keys: anyone can compute them.
How is a point written down?
A point is two 32-byte numbers, x and y. Pearl writes it in one of two short forms:
- Compressed, 33 bytes: a prefix
02or03saying whether y is even or odd, then x. Used in extended keys and fingerprints. - X-onlyX-only public key: A public key written as just its 32-byte x-coordinate, with the y-coordinate left implied. Taproot addresses and Schnorr signatures use this short form., 32 bytes: just x, with y assumed even. Everything on chain uses this: Taproot output keys, Schnorr signatures and tapscript keys.
Each x has only two possible y values (y and p − y, one even, one odd), so the short forms lose nothing.
Code: the toy curve in JavaScript
The arithmetic above, for y² = x³ + 7 over a small prime p. null is the point at infinity.
const p = 17;
const mod = (a) => ((a % p) + p) % p;
const inv = (a) => { let r = 1, b = mod(a), e = p - 2; while (e) { if (e & 1) r = (r * b) % p; b = (b * b) % p; e >>= 1; } return r; };
function add(P, Q) {
if (!P) return Q;
if (!Q) return P;
if (P.x === Q.x && mod(P.y + Q.y) === 0) return null; // P + (−P) = ∞
const l = P.x === Q.x
? mod(3 * P.x * P.x * inv(2 * P.y)) // tangent (doubling)
: mod((Q.y - P.y) * inv(Q.x - P.x)); // chord
const x = mod(l * l - P.x - Q.x);
return { x, y: mod(l * (P.x - x) - P.y) };
}
add({ x: 6, y: 6 }, { x: 1, y: 5 }); // { x: 8, y: 14 } = 3G pearld gets the real curve from the decred secp256k1 library, in
btcec.go (node/btcec/btcec.go:23-41 at v1.5.2, on GitHub).