On 16 October 2026 Anthropic published that the fourteen seeds behind the NIST and ANSI X9.62 elliptic curves — a question open since 1997 and carrying a bounty — are outputs of the C library’s lrand48, seeded from Unix timestamps of May 1997 to April 1998, and that six base points come from FreeLIP’s random generator. Every row of that claim that a computation can decide is re-decided here, the same evening, from the POSIX specification of drand48, from ANSI X9.62’s derivation as FIPS 186-2 prints its intermediates, and from FreeLIP’s source — by two programs that share no code with each other or with the claimant’s. All 34 rows hold. The claims beyond the checkable core are listed as readings, each with what would decide it.
The claim: anthropic.com/research/ecdsa-curve-origins as fetched 2026-10-16 (sha256 afb5fba0659f…), its two code blocks pinned as evidence and never run. The published objects: FIPS PUB 186-2 (7384ae9ddbf8…) — for each prime curve p, r, the seed s, c, b, G; for each binary curve the field polynomial, r, and the seed and b in the normal basis — and OpenSSL’s crypto/ec/ec_curve.c at a pinned commit for the five X9.62 example curves, whose standard is paywalled; the two sources must agree on every NIST field or the reader refuses. The specifications: IEEE Std 1003.1 for the drand48 family; FreeLIP 1.1’s lip.c (Lenstra–Leyland, 1997) for zrstarts, zrandom and zrandomb. Pre-registered in corpus/curveseeds/preregistration.json with one dated amendment before any row was decided. Decided: that each published seed is the stated candidate of the stated srand48 run (14 rows); that each seed yields its published curve by X9.62’s SHA-1 procedure (14); that each of six base points is the first point FreeLIP’s generator draws from the stated seed (6). Not decided: the skipped-candidate claim, which needs point counting; the probabilities and the interpretation; anything about the security of the curves.
| curve | srand48 clock (UTC) | srand48 argument | candidate | the published seed | source | verdict |
|---|---|---|---|---|---|---|
| P-192 | 1997-05-18 14:45:34 | 863966734 | 139 | 3045ae6f c8422f64 ed579528 d38120ea e12196d5 | FIPS 186-2 | CERTIFIED |
| P-224 | 1998-04-03 12:52:07 | 891607927 | 7026 | bd713447 99d5c7fc dc45b59f a3b9ab8f 6a948bc5 | FIPS 186-2 | CERTIFIED |
| P-256 | 1997-08-16 01:52:34 | 871696354 | 1842 | c49d3608 86e70493 6a6678e1 139d26b7 819f7e90 | FIPS 186-2 | CERTIFIED |
| P-384 | 1997-08-30 14:50:08 | 872952608 | 2688 | a335926a a319a27a 1d00896a 6773a482 7acdac73 | FIPS 186-2 | CERTIFIED |
| P-521 | 1997-08-08 01:12:04 | 871002724 | 1136 | d09e8800 291cb853 96cc6717 393284aa a0da64ba | FIPS 186-2 | CERTIFIED |
| prime192v2 | 1997-05-18 14:45:34 | 863966734 | 6013 | 31a92ee2 029fd10d 901b113e 990710f0 d21ac6b6 | OpenSSL ec_curve.c (X9.62) | CERTIFIED |
| prime192v3 | 1997-05-18 14:45:34 | 863966734 | 5228 | c4696844 35deb378 c4b65ca9 591e2a57 63059a2e | OpenSSL ec_curve.c (X9.62) | CERTIFIED |
| prime239v1 | 1997-05-15 15:49:03 | 863711343 | 2185 | e43bb460 f0b80cc0 c0b07579 8e948060 f8321b7d | OpenSSL ec_curve.c (X9.62) | CERTIFIED |
| prime239v2 | 1997-05-15 15:49:03 | 863711343 | 2320 | e8b40116 04095303 ca3b8099 982be09f cb9ae616 | OpenSSL ec_curve.c (X9.62) | CERTIFIED |
| prime239v3 | 1997-05-15 15:49:03 | 863711343 | 3048 | 7d737416 8ffe3471 b60a8576 86a19475 d3bfa2ff | OpenSSL ec_curve.c (X9.62) | CERTIFIED |
| B-233 | 1998-04-17 15:24:18 | 446413329 (= ⌊t/2⌋, t = 892826658) | 155 | 74d59ff0 7f6b413d 0ea14b34 4b20a2db 049b50c3 | FIPS 186-2 (normal basis) | CERTIFIED |
| B-283 | 1998-04-17 15:27:44 | 446413432 (= ⌊t/2⌋, t = 892826864) | 32 | 77e2b073 70eb0f83 2a6dd5b6 2dfc88cd 06bb84be | FIPS 186-2 (normal basis) | CERTIFIED |
| B-409 | 1998-04-17 15:30:18 | 446413509 (= ⌊t/2⌋, t = 892827018) | 60 | 4099b5a4 57f9d69f 79213d09 4c4bcd4d 4262210b | FIPS 186-2 (normal basis) | CERTIFIED |
| B-571 | 1998-04-17 15:32:08 | 446413564 (= ⌊t/2⌋, t = 892827128) | 73 | 2aa058f7 3a0e33ab 486b0f61 0410c53a 7f132310 | FIPS 186-2 (normal basis) | CERTIFIED |
A CERTIFIED row says: start the POSIX generator with srand48(argument), take the n-th block of twenty outputs (prime curves: the top byte of each, lrand48() >> 23) or of five outputs (binary curves: each whole 31-bit value as a 32-bit word), and the 160 bits are the published seed. The candidate index is 1-based, as the post defines it ("the first 20 bytes are candidate 1"). The published seeds are read from the pinned FIPS 186-2 text layer (the NIST curves; the binary seeds in the normal basis FIPS gives them in) and from OpenSSL’s table (the X9.62 example curves), never retyped. The four binary runs are 206 seconds apart on the same afternoon under the halved-clock reading; without the halving the srand48 arguments read as February 1984 and the red control shows no seed reproduces.
| curve | field | the chain’s output | against the standard | verdict |
|---|---|---|---|---|
| P-192 | GF(p), 192 bits | c = 3099d2bbbfcb2538… | equals FIPS 186-2’s printed c; b²c + 27 ≡ 0 (mod p) | CERTIFIED |
| P-224 | GF(p), 224 bits | c = 5b056c7e11dd68f4… | equals FIPS 186-2’s printed c; b²c + 27 ≡ 0 (mod p) | CERTIFIED |
| P-256 | GF(p), 256 bits | c = 7efba1662985be94… | equals FIPS 186-2’s printed c; b²c + 27 ≡ 0 (mod p) | CERTIFIED |
| P-384 | GF(p), 384 bits | c = 79d1e655f868f02f… | equals FIPS 186-2’s printed c; b²c + 27 ≡ 0 (mod p) | CERTIFIED |
| P-521 | GF(p), 521 bits | c = b48bfa5f420a3494… | equals FIPS 186-2’s printed c; b²c + 27 ≡ 0 (mod p) | CERTIFIED |
| prime192v2 | GF(p), 192 bits | c = 15038d1d2e1cafee… | no c printed for this curve; b²c + 27 ≡ 0 (mod p) holds | CERTIFIED |
| prime192v3 | GF(p), 192 bits | c = 25191f95024d8395… | no c printed for this curve; b²c + 27 ≡ 0 (mod p) holds | CERTIFIED |
| prime239v1 | GF(p), 239 bits | c = 28b85ec1ecc19efe… | no c printed for this curve; b²c + 27 ≡ 0 (mod p) holds | CERTIFIED |
| prime239v2 | GF(p), 239 bits | c = 1df491e44e7ccaf4… | no c printed for this curve; b²c + 27 ≡ 0 (mod p) holds | CERTIFIED |
| prime239v3 | GF(p), 239 bits | c = 3a4f9dc9a6cefd5f… | no c printed for this curve; b²c + 27 ≡ 0 (mod p) holds | CERTIFIED |
| B-233 | GF(2^233), t^233 + t^74 + 1 | b (normal basis) = 1a003e0962d4f9a8… | equals FIPS 186-2’s normal-basis b, bit for bit | CERTIFIED |
| B-283 | GF(2^283), t^283 + t^12 + t^7 + t^5 + 1 | b (normal basis) = 157261b894739fb5… | equals FIPS 186-2’s normal-basis b, bit for bit | CERTIFIED |
| B-409 | GF(2^409), t^409 + t^87 + 1 | b (normal basis) = 124d0651c3d3772f… | equals FIPS 186-2’s normal-basis b, bit for bit | CERTIFIED |
| B-571 | GF(2^571), t^571 + t^10 + t^5 + t^2 + 1 | b (normal basis) = 3762d0d471160061… | equals FIPS 186-2’s normal-basis b, bit for bit | CERTIFIED |
ANSI X9.62-1998 A.3.3 turns a seed into a curve: with t the field size in bits, s = ⌊(t − 1)/160⌋ and v = t − 160s, the chain is the rightmost v bits of SHA-1(seed) followed by SHA-1(seed + 1) … SHA-1(seed + s). In the prime case the leftmost bit of the first block is cleared and the result is c, with b any solution of b²c ≡ a³ (mod p), a = −3; FIPS 186-2 prints that c, and the calibration that regenerates it is what caught the leftmost-bit rule (amendment 1). In the binary case the chain is b itself, in the normal basis FIPS uses for s and b. This row is the standard’s own promise, not the post’s; it is decided so that one record closes the chain from a 32-bit clock value to the published curve. For the X9.62 example curves no c is printed anywhere open, so the congruence alone decides.
| curve | LIP seed | tries | x produced | Gy | verdict |
|---|---|---|---|---|---|
| P-192 | 20000 | 2 | 188da80eb03090f6… = the published Gx | squares to x³ − 3x + b; the odd root, the smaller | CERTIFIED |
| prime239v1 | 20420 | 3 | ffa963cdca8816cc… = the published Gx | squares to x³ − 3x + b; the even root, the larger | CERTIFIED |
| prime239v2 | 20507 | 2 | 38af09d987277051… = the published Gx | squares to x³ − 3x + b; the even root, the larger | CERTIFIED |
| prime239v3 | 20509 | 1 | 6768ae8e18bb92cf… = the published Gx | squares to x³ − 3x + b; the odd root, the smaller | CERTIFIED |
| prime192v2 | 20512 | 5 | eea2bae7e1497842… = the published Gx | squares to x³ − 3x + b; the odd root, the smaller | CERTIFIED |
| prime192v3 | 20517 | 1 | 7d29778100c65a1d… = the published Gx | squares to x³ − 3x + b; the even root, the smaller | CERTIFIED |
FreeLIP (lip.c): zrstarts(seed) sets the state to the seed and the multiplier to 3¹²¹ mod (2¹⁰⁷ − 1); zrandom(b) advances the state and returns it mod b, redrawing in the rare case the state falls in the top partial block; zrandomb(p) draws one limb more than p has, the first most significant, and reduces mod p. The limb is 26 bits (NBITS in the SINGLE_MUL build of lip.h; 30 bits fails the red control), seven single draws are discarded first (the post’s reading of the generating program; zero fails the red control), and the first x with x³ − 3x + b a quadratic residue is the base point’s abscissa. The post explains no other base point — P-224, P-256, P-384, P-521 and the binary curves stay open — and nothing here changes that.
The point-counting lane for R1 (every candidate below the published index, under a stated root convention for b, with Schoof–Elkies–Atkin in PARI/GP) is outside the standard library and not part of this certificate; if run, its counts will appear here, counted apart.
One amendment to the pre-registration, dated before any row was decided. Amendment 1. the first attempt produced c = fefba166… where FIPS prints 7efba166…; for P-192, b099d2bb against 3099d2bb — the leftmost bit of the first SHA-1 block is cleared. That is ANSI X9.62-1998 A.3.3.1's own rule for the prime case (set the leftmost bit of W0 to 0), omitted from the claims text above; the binary case A.3.3.2 has no such step and B-233's normal-basis b reproduced without it. the prime derivation clears bit v−1 of the first block; a red control is added — the chain without the clearing must not reproduce c. Nothing else changes; the calibration against the standard's own printed intermediate is exactly what caught this.