math ⇄ art lab — The Key Forge

① the key forge

Forge a real RSA keypair right here: random odd candidates from crypto.getRandomValues (top two bits forced set so p·q has the full bit-length), trial division by every prime < 2000, then 40 Miller–Rabin rounds — all in BigInt. n = p·q, λ(n) = lcm(p−1, q−1), e = 65537 (regenerated until gcd(e, λ) = 1), d = e⁻¹ mod λ by extended Euclid. Nothing leaves this page.

no key yet — forge one, or your last forged key restores automatically
verification: — fingerprint: —
n — modulus (p·q, decimal)
e — public exponent
d — private exponent (e⁻¹ mod λ)
p (prime, bits/2)
q (prime, bits/2)

② textbook encrypt / decrypt

The educational mode: UTF-8 bytes → BigInt → c = mᵉ mod n via square-and-multiply. If the message is ≥ n it is chunked into blocks of bits/8 − 1 bytes, joined with a “.” separator — a teaching simplification; real schemes pad every block. This message is shared by sections ② ③ ④.

m — message as BigInt (hex)
c — ciphertext (hex)
recovered plaintext

textbook RSA — deterministic, unmalleable-free, NO padding. Real systems never do this; see OAEP below.

③ real padding — RSA-OAEP via WebCrypto

The same BigInts become a JWK — n, e, d, p, q plus dp = d mod (p−1), dq = d mod (q−1), qi = q⁻¹ mod p — base64url-encoded big-endian, minimum octets, no sign-bit trouble: JWK integers are unsigned by definition (RFC 7518 §2 — Chromium even rejects a DER-style leading 0x00). Then crypto.subtle does OAEP with SHA-256: randomized, semantically secure, the way it is actually done.

WebCrypto unavailable

④ sign / verify — RSA-PSS

Same key material imported as RSA-PSS (SHA-256, maximum salt length). Signing proves the message came from whoever holds d. Flip the tamper switch to flip one byte of the message before verification — and watch the signature be rejected.

signature: —

⑤ your key as art

Every digit of n becomes a pointy-top hexagon (~18 px): hue rotates digit × 36° (decimal) or digit × 30° (dozenal), a linear gradient sweeps across each cell at digit × 30°, lightness falling 62% → 34%. Glyphs off — colour is the digit. Below: digit frequency vs the uniform expectation (dashed).

forge a key above and its digits will bloom here.

⑥ honesty

How strong is my key?

512-bit  falls in hours to a motivated attacker — RSA-155 was exactly 512 bits, and it fell in 1999.

1024-bit  within reach of well-funded adversaries — RSA-768 took ~2000 core-years (2009).

2048-bit  ≈ 617-digit territory, beyond public factoring records — RSA-250 took 2700 core-years at 829 bits.

For real protocols use audited crypto — WebCrypto, libsodium, age, GnuPG. This forge is for understanding, not production. see the RSA Room · key size on Wikipedia