freecoding.school100% FREE · NO SIGNUP
Proof PeaksISSUE #2 of 38

elliptic curves · group law · secp256k1 vs bn254

ZeekaVSThe Collision
Zeeka saysAn elliptic curve over a finite field is a set of points with a geometric "addition" law — the hard-to-reverse engine behind almost every blockchain key.

An elliptic curve is the set of points (x, y) satisfying y² = x³ + ax + b over a finite field, plus a special "point at infinity" that acts as zero. A chord-and-tangent rule defines how to add two points, and that operation turns the points into a group. A public key is just a secret scalar k multiplied into a fixed base point G, written k·G — repeated point addition.

Security comes from the discrete-log problem: given G and k·G it is infeasible to recover k. Bitcoin and Ethereum keys use secp256k1; pairing- and ZK-friendly systems use curves like bn254 and bls12-381. The toy curve below over GF(97) uses the exact same group law — just small enough to print every point.

Power-ups you unlock

The Collision attacks — common mistakes

Boss battleOn y² = x³ + 2x + 3 over GF(97), find a base point G and verify that G + 2G equals 3G.

Example code

<!doctype html><html><head><meta charset="utf-8"></head>
<body style="background:#06040d;color:#e6e0ff;font-family:monospace;padding:20px"><pre id="o"></pre>
<script>
const p = 97, A = 2, B = 3;                // curve y² = x³ + 2x + 3 over GF(97)
const mod = (n)=> ((n % p) + p) % p;
const pw = (a,e)=>{ let r=1; a=mod(a); while(e>0){ if(e&1) r=mod(r*a); a=mod(a*a); e>>=1; } return r; };
const inv = (a)=> pw(a, p-2);
const onCurve = (P)=> P===null || mod(P.y*P.y) === mod(P.x*P.x*P.x + A*P.x + B);
function addP(P,Q){
  if(P===null) return Q; if(Q===null) return P;
  if(P.x===Q.x && mod(P.y+Q.y)===0) return null;                  // P + (−P) = O
  const m = (P.x===Q.x && P.y===Q.y)
    ? mod((3*P.x*P.x + A) * inv(2*P.y))                            // doubling
    : mod((Q.y - P.y) * inv(Q.x - P.x));                          // addition
  const x = mod(m*m - P.x - Q.x), y = mod(m*(P.x - x) - P.y);
  return { x, y };
}
function mulP(k,P){ let R=null,Q=P; while(k>0){ if(k&1) R=addP(R,Q); Q=addP(Q,Q); k>>=1; } return R; }
let G=null; for(let x=0;x<p&&!G;x++) for(let y=0;y<p;y++) if(mod(y*y)===mod(x*x*x+A*x+B)){ G={x,y}; break; }
const G2 = mulP(2,G), G3 = mulP(3,G);
document.getElementById('o').textContent = [
  'curve y² = x³ + 2x + 3  over GF(97)',
  'base point G = (' + G.x + ',' + G.y + ')   on curve: ' + onCurve(G),
  '2G = (' + G2.x + ',' + G2.y + ')   3G = (' + G3.x + ',' + G3.y + ')',
  'group law check  G + 2G == 3G ?  ' + (JSON.stringify(addP(G,G2)) === JSON.stringify(G3))
].join('\n');
</script></body></html>
▶ Open the interactive comic issue
‹ Finite Fields · Modular Arithmetic For CryptoPairing-Based Crypto · Bilinear Maps ›