Half an Hour, One Timestamp, One Old Library Call: How Claude Cracked the NIST Elliptic-Curve Seed Mystery That Stumped Cryptographers for 25 Years
Half an Hour, One Timestamp, One Old LCG Call: How Claude Solved the NIST Elliptic-Curve Seed Mystery
Introduction: A “Backdoor Cold Case” Nobody Dared to Crack
If you use TLS encryption, digital signatures, or cryptocurrency every day, you almost certainly touch NIST-defined elliptic curves—especially P-256, which has long dominated global certificate and signature protocols. Behind each curve’s parameters sits a “seed” written into the standard since 2000: a public byte string used to derive the curve’s coefficients.
The seed was meant to guarantee transparency—publish a hash input, and anyone could verify the coefficients weren’t hand-picked. But for 25 years, cryptographers couldn’t shake a worrying question: where did those five curve seeds actually come from? After the 2013 “Dual_EC_DRBG backdoor” scandal, many suspected the NIST curves might also be NSA-crafted, hiding some subtle vulnerability. Because the original generation process was never public—only the result, not the procedure.
On October 16, Anthropic published a striking finding: an employee handed this decades-old problem to an internal Claude research model, and with no key clues supplied, Claude traced the true origin of all five NIST curve seeds in under half an hour. The result is both surprising and mundane: the seeds came not from a strong hash, but from an ancient C standard-library PRNG, lrand48, seeded with a set of Unix timestamps from 1997–1998.
This was a “case cracked” that broke nothing. It created no new attack, and it did not prove the long-suspected curves were actually broken. Quite the opposite—it drastically lowered the chance these curves were backdoored, because the mystery was solved: it was all just a casual clock read and one outdated line of code. What’s truly worth examining is the reverse-engineering path Claude took: not brute force, but a chain of commonsense about 1990s software ecology, sharp recognition of output fingerprints, and flexible invocation of number-theory tools—a textbook “archeological” inference.
Part One: What a “Seed” Is, and Why It Made Everyone Suspicious
1. Where Standard Curve Parameters Come From
To grasp the stakes, we must return to elliptic-curve parameter selection. A secure curve needs well-defined coefficients a, b (for y² = x³ + ax + b), plus a base point, order, and other parameters. If these were random, anyone could secretly test whether they happened to land in a small set containing a hidden weakness—or if they were deliberately chosen to hide secret structure, only the chooser would know the vulnerability.
So when NIST published these standards in 1999–2000, it used a “seed + hash” verifiable flow:
seed (public)
│
▼
SHA-1 hash ←— one-way, public, verifiable by all
│
▼
derive curve coefficients (a, b)
The ideal: if the seed is honest and random, then seed-to-coefficients is fully public and reproducible—nobody can sneak in rigged values. The problem then collapses to a single point: is the seed itself hand-picked? If whoever built the seed first chose a secret weak-coefficient set and then reverse-derived a “random-looking” seed (with nobody knowing how), the hash process becomes theater. That is the 25-year source of doubt.
2. Rumors, Leads, and the “Humorous Passphrase” Detour
Plenty of theories swirled around these seeds. The most famous claimed the seeds traced back to an internal joke or “humorous passphrase”—supposedly someone used a joke as the passphrase to generate them. Several Anthropic employees previously chased that “humorous passphrase” line without luck, and finally concluded the lead itself was likely wrong.
The suspicion was further fuelled by the 2013 storm: Snowden’s leaks exposed NSA’s backdoor in a cryptographic standard (“Dual_EC_DRBG”), catapulting “maybe NIST curves are dirty too” well beyond the cryptographer inner circle. Filippo Valsorda (maintainer of Go’s crypto libraries) even posted a bounty urging anyone to crack the mystery, out of concern for the curves’ true security.
So this October, an Anthropic employee decided to change tack: rather than chasing rumored leads, he handed the question “how were the seeds generated?” directly to an internal Claude research model.
3. A “No-Hints” Question
The key detail: the employee gave the model none of the rumored “passphrase” leads. Claude had to reason entirely from scratch, reconstructing—under almost empty constraints—a piece of program a 1990s engineer once wrote. In classic “AI answering” terms, this is open-world reasoning: no standard answer, no hints, just a bunch of public seed byte strings and general digital-signature knowledge.
We’ll unpack Claude’s performance below. But first a judgment: the difficulty is that this isn’t a “look up the answer” problem; it’s a “propose the right hypothesis chain” problem. Who would think to suspect a 1998 C library RNG? Who can smell an LCG from a few bytes of statistical pattern? That is what makes this AI solver most impressive.
Part Two: Claude’s “Four-Step Investigation”—A Textbook Reverse-Engineering
Step 1: Abandon Chasing the Passphrase; Instead Infer “How the 1990s Software Probably Worked”
Claude quickly did something humans easily get stuck on and it did naturally: shift the search target from “secret passphrase” to “program behavior.” It began hypothesizing that the 1990s curve-building engineers likely used the pseudorandom generators bundled with C libraries of that era. These early PRNGs are cryptographically weak and their output typically carries recognizable statistical fingerprints.
Once it realized “the output might carry fingerprints,” the next step followed naturally: write a scanner that slides over each public seed bit-by-bit, checking whether adjacent chunks could come from some ’90s RNG. This scan covered 34 combinations of “RNG × output-truncation scheme.”
Step 2: Found a Sea of “Leading Zeros”—the Critical Fingerprint
During scanning, Claude found a pattern in an extremely telling position: the high bits of some seeds were all zero. Writing each seed as five 32-bit words (160 bits total), 4 of the 10 seeds matched; across those 4 seeds’ 20 32-bit words, the highest bit was always 0.
The chance of this happening by chance is roughly 1 in 5,800. It almost only comes from one kind of thing: a linear congruential generator (LCG). Specifically, lrand48 keeps a 48-bit internal state but returns only the top 31 bits—so the output’s leading bit is naturally always 0.
At this step, Claude essentially “recognized the patient’s genes from an X-ray,” pinning the generator’s identity from an otherwise flat byte string.
Step 3: Recovering the 48-bit State from the Top 31 Bits—Enter Lattice Theory
lrand48’s 48-bit state exposes only 31 (or fewer) bits. How to restore the rest? Claude took two routes:
- For the “generous” seeds: directly brute-force the 2^17 = 131,072 hidden bit combinations, then check whether the next words match consecutively—all 4 seeds verified.
- For the prime-curve seeds retaining fewer bits: reach for the heavier tool—this is a classic “truncated-LCG state recovery” problem, solvable with the LLL lattice-reduction algorithm (Lenstra–Lenstra–Lovász). LLL is famous in lattice cryptography for approximating shortest-vector problems in polynomial time. Claude initially didn’t know which state bits the seeds preserved, so it ran the solver over every possible bit window.
The result is deeply compelling: all 5 NIST prime-curve seeds plus 5 from the ANSI X9.62 standard showed the exact same magic pattern: lrand48() >> 23. Each recovered 48-bit state regenerates all 160 bits of its seed exactly. Such cascading exact matches cannot be coincidence.
Step 4: Trace the State Backward Until It Collides with a Unix Timestamp
The beauty of an LCG is that it runs both forward and backward. Claude thus started from each seed’s state and stepped backward, until it reached a state matching srand48’s initialization format—whose low 16 bits must equal 0x330E (a fixed transform srand48 applies when seeding).
Since a state of that form appears on average every 65,536 steps, finding one matching state alone isn’t proof. The real hammer followed:
The srand48 initial values for all 10 prime-curve seeds were interpretable as Unix timestamps, clustered between May 1997 and April 1998. In other words, the original program simply tossed the system clock (a Unix timestamp) into the weak RNG, ran it a few thousand times, chopped the output into 20-byte chunks, and took one chunk as the seed in the standard.
The 4 binary-curve seeds are even more delicious: read directly, their initial values map to February 1984; but double those values and they land exactly on April 17, 1998—about two weeks before P-224’s generation. The program evidently divided the system clock by 2 (perhaps a side effect of a 16-bit read). These details interlock into a complete chain of evidence.
Part Three: Reconstructing the “Seed-Derivation Backbone” in Python
Talk is cheap; let’s put the core skeleton on the table. We obviously can’t reproduce NIST’s whole original flow, but we can demo the most central logic—“recover an LCG state from output, then trace it back to a timestamp”—with a slim Python program, showing the exact mathematical structure Claude faced.
# lcg_forensics.py
# Demo: recognize lrand48-style LCG output fingerprints, and back-derive state toward a timestamp
M = 1 << 48 # lrand48 modulus (2^48)
A = 0x5DEECE66D # lrand48 multiplier (classic LCG constant)
C = 0xB # lrand48 increment
def advance(state):
"""step forward, return new 48-bit state"""
return (A * state + C) % M
def backstep(state):
"""LCG is reversible; step backward one"""
a_inv = pow(A, -1, M)
return (a_inv * (state - C)) % M
def high_bits(state):
"""lrand48 returns the top 31 bits"""
return (state >> 17) & 0x7FFFFFFF
def looks_like_srand48_init(state):
"""srand48 init format: low 16 bits == 0x330E (illustrative)"""
return (state & 0xFFFF) == 0x330E
def trace_back_to_timestamp(final_state, max_steps=200000):
s = final_state
for _ in range(max_steps):
if looks_like_srand48_init(s):
return s, _+1 # hit a state that looks like srand48 seeding
s = backstep(s)
return None, max_steps
# Example: feed a fake 48-bit state and see if trace-back converges
demo = 0x123456789AB
state_found, steps = trace_back_to_timestamp(demo)
print(f"traced back {steps} steps; candidate init state: {state_found is not None}")
print(f"top-31 output: 0x{high_bits(demo):X}")
print(f"note: leading bit always 0 => LCG fingerprint (p≈1/2^17)")
The code is heavily simplified, but exposes two core mathematical facts: an LCG is reversible (so you can go backward), and its output bits carry structural defects (leading-bit zeroing or truncation)—which are both its vulnerability and its “fingerprint” for forensics. The real case had to juggle bit-window combinations, truncation ambiguity, and LLL lattice reduction—far more work than these lines—but this is the skeleton.
A Diagram of Claude’s Reasoning Chain
This ASCII diagram lays out Claude’s full evidence chain, from bytes to timestamps:
NIST seed byte strings (public)
│
▼ scan each seed, 34 RNG×truncate combos
Found: 4 of 10 seeds have all top bits=0 (p≈1/5800)
│ ←─ almost certainly an LCG
▼
Pin: lrand48 top-31 return (lrand48()>>17)
│
▼ recover 48-bit internal state
Prime-curve seeds: more bits lost → need LLL lattice reduction
Run every window → hit lrand48()>>23
│
▼ each recovered state regenerates all 160 bits exactly
Trace backward along the LCG
│
▼ collide with srand48 init format (low16=0x330E)
All 10 init values interpretable as Unix timestamps
│ ←─ May 1997 ~ Apr 1998
▼
Conclusion: C-lib lrand48 + Unix timestamp seed ⇒ not-NSA backdoor, random
Part Four: Why This Matters Far Beyond Solving a Puzzle
1. A Demonstration of “Keyless Problem-Solving”: AI Can Do Open-Ended Reverse Inference
Traditional AI benchmarks are almost always “given the problem → find the known answer.” But the NIST seed problem is open-world: no standard answer, no hints, not even a hint about which technical direction to suspect. Claude solved it not through larger memory, but by weaving “crypto knowledge + 1990s software history + statistical intuition + math tools” into a chain of hypotheses. It proposed “maybe a C-library RNG,” designed its own scan, spotted the zero high bits, and pulled out LLL—all approaches a human cryptographer would take, but at “half an hour” speed.
This suggests: the next stage of AI value may lie precisely in this kind of “no-ready-answer provenance and diagnosis”—whether hunting hidden hardware backdoors, locating a strange binary’s origin, or recognizing “where this line of code actually came from” in a supply chain.
2. It Clears NIST Curves of a 25-Year Suspicion
For the entire internet cryptographic infrastructure, this finding is a huge relief. It essentially rules out “NIST curves are NSA backdoors” as the leading hypothesis—because the seeds now provably come from a ’90s C-library RNG plus a casual clock, not a secret process of hand-tuning parameters to hide weakness. (This is not “absolutely no risk”—one can’t discount every theoretical nitpick—but the evidence chain’s completeness—10 exact matches, all timestamps consistent—lets the vast majority of practitioners set aside years of worry.)
Amusingly, the conclusion also dilutes the urgency of “switch curves”: if NIST curves never hid a backdoor, then the enormous TLS ecosystem built on NIST P-256 has a sturdier security foundation than many feared.
3. A Clean Exercise in Open Source + Bounty
Anthropic did more than publish a blog. It open-sourced reproducible code for anyone to verify. And under bounty rules, the financial ending has a touch of heart: the bounty was originally $12,288; the winners chose to donate it to the Internet Security Research Group (ISRG), which tripled it to $36,864 under the rules. Filippo Valsorda acknowledged and celebrated the solve on his personal blog, with a wry aside about the curves’ eventual fate under post-quantum signatures.
This anecdote shows: good security research is often “community trust + open verification + transparent attribution” turning together.
Part Five: Three Takeaways for Engineers and Practitioners
First, don’t underestimate the staying power of “old code.” A 1998 C-library function lay buried inside infrastructure that became a global crypto standard in 2000, until an AI turned it over in 2026. In security engineering, “archeology” (understanding legacy code, historical random sources, legacy call relationships) may matter far more than we imagine. Every production system’s random source, hash, and key-derivation logic today may hold a similar “time capsule.”
Second, AI’s reasoning edge isn’t just “writing code”; it’s “reading history.” Claude’s strength here was fusing number theory (LLL), statistical intuition (the 1/5800 zeroing probability), and software common sense. Going forward, we must learn how to “hand hard problems to models in a way that lets them venture down open paths, form and verify hypotheses”—more valuable than making a model grind through yet more benchmarks.
Third, verification is still the most important step. Claude didn’t just “say it found it”; it self-justified with multi-way cross-checks (all 10 seeds exactly matching + all timestamps consistent). An AI conclusion is trustworthy only when backed by a reproducible, checkable evidence chain. That is both what makes this solve so valuable, and the bottom line we must keep when we bring AI into high-stakes decisions.
Conclusion
Half an hour, a 1997 clock reading, and one already-outdated lrand48—and so a “backdoor cold case” haunting cryptographers for a quarter-century closed under a model that could pose hypotheses on its own, summon mathematical tools, and complete rigorous reverse-engineering.
It is perhaps 2026’s most elegant “AI-meets-mathematics handshake”: it broke nothing, yet guarded one of the internet’s most basic threads of trust; it posed no threat, yet demonstrated AI’s potential on the path of “open-ended provenance.” As more of our cryptographic infrastructure turns toward the post-quantum era, this “archeological exoneration” of an old curve is a fitting, dignified, and clear-eyed farewell to the past.