Research#Reverse engineering

Claude traces the NIST ECDSA curve seeds to lrand48 and Unix timestamps, and the $36,864 bounty goes to ISRG

Anthropic says an internal research model traced the five NIST prime-curve seeds to lrand48 output seeded with 1997 timestamps; the $36,864 bounty went to ISRG.

A three-panel collage in purple, green and black: a purple block over halftone paper on the left, and a striped seed-like shape against a dark background on the right

Anthropic published research on October 16 closing a question that had been open for more than two decades: where the “seeds” for the five NIST prime curves (P-192, P-224, P-256, P-384, P-521) came from. They were not the output of any hash function. They are consecutive blocks of the C library’s lrand48 random number generator, seeded with a Unix timestamp in 1997 and 1998. The writeup is credited to Anthropic’s Frontier Red Team, and the company says an internal research model — called “Claude” throughout the page — did the work “in under half an hour.” For P-256 specifically: the 1,842nd 20-byte candidate from srand48(871696354) (1997-08-16 01:52:34 UTC) is the standard’s published seed, C49D3608 86E70493 6A6678E1 139D26B7 819F7E90.

Key points

  • The bounty and where it went. Filippo Valsorda and 11 named co-funders announced a $12,288 (12 Ki$) bounty on October 5, 2023, tripled if the recipient donated it to a 501(c)(3) charity. Anthropic’s team claimed it on 2026-10-15 at 01:07:51 UTC; the $36,864 went to ISRG, the nonprofit behind Let’s Encrypt.
  • Anthropic’s own framing. The writeup states plainly: “This is not a cryptographic break, new attack, or weakness in the ECDSA curves.” The company says the result makes it more confident the curves were not chosen with a backdoor, and that users have nothing to change.
  • Independent verification. Valsorda reimplemented the whole algorithm in Go, published it in the FiloSottile/mostly-harmless repository, and confirmed the claim. He also argues that even granting the NSA any timestamp in 1997–98 and any of the first 16 prime-order candidates, there were only about 30 bits of freedom — which rules out the attack path Daniel Bernstein and Tanja Lange described in 2017.

Background

The suspicion is nearly as old as the curves. When ANSI X9.62 and then FIPS 186-2 (2000) published them, the seeds came from the NSA with no explanation attached, and questions appeared on Usenet almost immediately — Steve Weis’s 2023 write-up documents the timeline. Neal Koblitz and Alfred Menezes collected the whole dispute in “A Riddle Wrapped in an Enigma,” which also supplied the counter-argument: even with total control over the seed, the NSA would have needed a class of weak curves so large that nobody in academia or industry noticing it for 25 years is implausible.

The most-cited explanation came from Jerry Solinas himself. The longtime NSA employee said in 2015 that the seeds were hashed from a humorous English sentence — something like “Give Bob and Jerry a raise” — with the code written by Bob Reiter, and that neither of them remembered the details. If the archives existed at all, he added, they were “sitting on a hard drive near the Ark of the Covenant.” Solinas died in 2023. Anthropic says several of its employees chased the hash-theory lead and got nowhere. Valsorda’s 2023 announcement gives the motive for the bounty: solid curves carrying an unanswerable cloud of FUD, and the hash-cracking crowd being exactly the people who find preimages for a living.

Chinese coverage has run a narrower version. ITHome’s October 17 piece (published 06:53 local time) frames it as a mystery that troubled cryptographers for 26 years, and stops to explain what a “seed” even is: the raw material fed into a fixed procedure, published so anyone can recompute it and check that the parameters really were produced the stated way. That reading matches the primary source; only the starting year differs.

The facts

Anthropic published a table anyone can check line by line. The timestamp is the input to srand48; the candidate index is which 20-byte block of that run was published:

Curvesrand48 timestamp (UTC)CandidateSeed, first 8 bytes
P-1921997-05-18 14:45:341393045AE6F…
P-2241998-04-03 12:52:077026BD713447…
P-2561997-08-16 01:52:341842C49D3608…
P-3841997-08-30 14:50:082688A335926A…
P-5211997-08-08 01:12:041136D09E8800…

The five ANSI X9.62 example curves fall inside two of the same runs: prime239v1 through v3 come from the May 15, 1997 timestamp, and prime192v2, prime192v3 and P-192 share May 18, 1997.

Finding them was an exercise in reasoning about 1990s software. Anthropic says the model first wrote a scanner that slid along each published seed one bit at a time, testing 34 combinations of generator and output slice. It then noticed a pattern in the top bits: written as five 32-bit words, four of the ten seeds have a zero in the top bit of all 20 words — a pattern that arises by chance with probability 1/5810, and which is the signature of lrand48, a generator that returns only the top 31 bits of a 48-bit state. Recovering the state meant trying all 2¹⁷ values of the 17 hidden bits; the prime-curve seeds kept fewer bits per output, so the state had to come out of a lattice problem solved with LLL reduction, matching the pattern lrand48() >> 23. Stepping each state backwards to the form srand48 would have initialized (low 16 bits equal to 0x330E) produced timestamps between May 1997 and April 1998. The binary-curve runs read as February 1984; doubled, they land on April 17, 1998, which is why Anthropic suggests the original program may have halved the clock. Separately, the base points of the six curves generated in May 1997 — P-192 and the five ANSI examples — come from FreeLIP, Arjen Lenstra’s long-integer package (early NTL shipped the same code), with generator seeds 20000, 20420, 20507, 20509, 20512 and 20517.

How to reproduce it

Reproducing this now costs a few dozen lines. Anthropic ships Python on the page, dedicated to the public domain under CC0; Valsorda’s Go version lives at seeds/seeds.go in the FiloSottile/mostly-harmless repository. I reran the core of the Python for P-256 on this machine:

x = (871696354 << 16) | 0x330E     # srand48(1997-08-16 01:52:34 UTC)
for i in range(20 * 1842):         # 20 bytes per candidate
    x = (0x5DEECE66D * x + 0xB) % 2**48
    if i >= 20 * 1841:
        print('%02X' % (x >> 40), end='')

It prints C49D360886E704936A6678E1139D26B7819F7E90, byte for byte the seed printed in FIPS 186 for P-256. Swap the timestamp and the candidate index to check the other four. The Go program additionally derives the curve parameters and the orders; the base-point code exists only in the Python on Anthropic’s page, with no Go counterpart.

What others say

Valsorda’s verification post draws the sharpest conclusion. Even if the NSA had been free to pick any timestamp in 1997–98 and any of the first 16 prime-order candidates per stream — a generous allowance for the unexplained skips — the total freedom was barely 30 bits. That is not enough to target a hypothetical small class of weak curves, and not enough to embed a NOBUS backdoor only the author could use. What this specifically rules out is the path Bernstein and Lange described to Koblitz and Menezes in 2017: 70 bits of freedom aimed at a hypothetical class of 2⁶¹ weak prime-order curves, as reported in a later version of that paper. Valsorda cites the paper; I did not read it directly. He adds a personal verdict: he would now recommend the NIST curves over Curve25519/Ed25519/X25519 — “just in time for them to be retired in favor of post-quantum signatures.” We covered Cloudflare’s plan to become a public CA, which puts post-quantum certificates in the first quarter of 2027.

Anthropic files its own caveat. The team observed viable candidates being skipped: candidate 876 of the P-256 run also yields a prime-order curve of the right size with parameters chosen the same way, the P-224 run passed over three such curves, and the two ANSI example runs passed over seven more. The criteria are unknown. Anthropic’s self-assessment is that “because the number of skipped candidates is small, we do not believe it is plausible that weakened curves were selected.” It also concedes that in principle the seeds could have been chosen by searching over timestamps — but says you would only bother if you intended to disclose the timestamp as evidence of innocence.

The main Hacker News thread (594 points, 248 comments when I checked at 2026-10-16 23:59 UTC) carries the counter-view in its sharpest form. User fidotron argues the result confirms the method of production but says nothing about selection, since discarded candidates are invisible forever. User adastra22 goes further: “This is EXACTLY what a weak curve would look like” — if one key in a thousand or a million were vulnerable to some withheld attack, you could vary the timestamp or the iteration count until you found one, then have plausible deniability afterward. Valsorda replies in the thread, restating the 30-bits argument. A separate and busy subthread is about access rather than mathematics: user slowin says Anthropic can point a model at this kind of cryptography work while an ordinary person attempting the same thing would be blocked, and that the moat is widening. The pushback is specific — dadrian says the guardrails “are absolutely irrelevant to this task, and you will not get blocked”; Retr0id says he worked on this exact problem with Claude and was not blocked, though he did not solve it. Meanwhile jcomp, petesergeant and landr0id each list cases where they were downgraded for prompts containing words like “C&C,” “Vigenère” or reverse engineering.

Our take

For anyone writing code or reviewing an architecture, the practical use of this is narrow but solid. If a compliance note or a design doc still says the NIST curve seeds are of unknown provenance, that sentence can now be replaced with ten lines of Python that anyone can run. P-256 and P-384 underpin a large share of X.509 certificates, and nothing about this finding changes a deployment — Anthropic is explicit that there is no action to take.

The honest lesson is about the limits of the proof. What was proven is how the seeds were generated; the selection process, and especially the discarded candidates, remains invisible. The reassurance rests on a reductio: a class of weak curves would have to be large enough to be hit by roughly 2³⁰ random tries. As Valsorda puts it, finding such a class would be a cryptanalytic breakthrough on the scale of discovering that elliptic curve cryptography is broken. That is a strong assumption, but it is an assumption. Say plainly, too, what is still unsolved: the B-163 seed matches nothing anyone has tried, and the base points of P-224, P-256, P-384, P-521 and the binary curves remain unexplained.

There is a second story here about models doing research. An internal model did the work, in “under half an hour” by the company’s own account, and a whole HN subthread argues about whether an ordinary user would get the same help. We would not adjudicate that either way: the artifact of this task is reproducible code, and anyone can verify it themselves, which is worth far more than a model’s word. This is also not Anthropic’s first “a model found something” release — we covered 950 Claude agents finding a CRISPR-like system, where the first reaction from researchers was that the biology still needed bench work.