二十五年里,密码学界一直以为答案是一句话。
据说是句玩笑,一说写着给鲍勃和杰瑞涨工资,一说是鲍勃和杰瑞说了算。这句话要是真找到,悬案就结了。
没人找到。2026 年 10 月,Anthropic 一位员工把这个问题交给内部的研究模型,只问这些种子是怎么生成的,没给任何线索。模型用了不到半小时,给出了答案。
答案不是一句话,是一串从 1997 年流过来的时间戳。
悬案到底在问什么打开网银或者购物网站,地址栏那把小锁背后就是一次签名验证,服务器得先证明自己确实是它,你才敢往下输密码。做这件事最常用的算法之一,是 ECDSA。
它要用的那条椭圆曲线,不是画出来的图,是一组定死的数字。一个素数划定数字的范围,一个方程 y² = x³ + ax + b 决定曲线长什么样,一个基点标出起点,一个阶说明沿着曲线绕一整圈要走多少步。这组数字叫曲线参数,全部公开。
用这条曲线的系统必须拿同一套参数,签名才能互认。所以它改不得,也不能只对某个人公开。参数里埋一点东西,受影响的是所有用这条曲线的人。
麻烦在于,a 和 b 这两个系数不都是死的。a 被标准定成一个固定值,b 只能由种子算出来。NIST 先定一个种子,把它丢进 SHA-1,算出一串哈希值,再用这串值定出 b。
哈希就像一台压模机,喂进去什么,都压出一串固定长度的数字,同样的输入永远得到同样的结果。种子公开,任何人都能从头算一遍,算出来的 b 和标准里一样,就说明 b 不是手写的。
这道工序只解决一半。它证明 b 是从种子算出来的,证明不了种子是怎么来的。先试一万个,挑一个满意的,流程照样对得上。
悬案就卡在这个种子上。它是二十个字节的十六进制,没有生成方法,没有署名,没有日期。标准文档在它后面只留了一行注,由 NSA 提供。
一整套基础设施的安全,最后落在一个说不清来源的常数上。后面二十五年的故事,都是从这个问号长出来的。
一个没人解释过的参数2000 年,NIST 把 ECDSA 写进 FIPS 186-2 数字签名标准,一起收录的还有五条推荐的椭圆曲线,P-192,P-224,P-256,P-384,P-521。今天 HTTPS 站点的证书签名,主流是其中的 P-256,P-384 也不少见。
五条曲线的种子也一并公布了,每个二十个字节。P-256 的种子是 C49D3608 86E70493 6A6678E1 139D26B7 819F7E90,后面没有别的解释。
2015 年,Neal Koblitz 和 Alfred Menezes 写过一篇长文,标题叫《A Riddle Wrapped in an Enigma》,把这桩争议的来龙去脉梳理了一遍。
2023 年 10 月,密码学家 Filippo Valsorda 出钱设了一笔悬赏,12,288 美元,中奖者如果选择捐给慈善机构,奖金翻三倍。
悬赏挂出去三年,没有人交卷。
所有人都找错了方向最有名的一条线索指向 NSA 的 Jerry Solinas。1997 年那批种子据说是他生成的。2015 年他留下一段回忆,说种子是对一句玩笑话做哈希得来的,具体细节记不清了。按他的说法,真正写代码的是 Bob Reiter,Reiter 也记不清。
"Nor were we able to find archives from so long ago. If they exist, they are no doubt sitting on a hard drive near the Ark of the Covenant."
那么久以前的存档,我们也没找到。要是它们还在,多半躺在某块硬盘上,跟约柜一样找不着了。Jerry Solinas,2015 年
这版说法流传最广。有人猜短语,有人跑字典,有人翻旧资料。2023 年 Solinas 去世,这条路彻底断了。
Anthropic 的研究员 Steve Weis 也追过,2023 年写过一篇博客把线索列了一遍。后来他在 X 上说,有四个人跟他讲过「鲍勃和杰瑞」这个说法,包括 Solinas 本人,可没有一个人讲对。
图1、Steve Weis 宣布找到种子,当天一万赞
不猜话,猜软件模型没有去猜英语短语。它换了个方向,先想当年那套生成曲线的程序会怎么写。
1990 年代的 C 标准库自带伪随机数发生器,拿来就能用。所谓伪随机,就是拿一个起点,用公式一步步算出看起来像随机的数列。起点定了,后面每一个数就都定了。
模型写了一个扫描器,把每条种子按比特一位一位地滑开,逐段试 34 种随机数发生器,每种配上不同的截取位置,看相邻几段是不是同一个发生器连着吐出来的。
图2、四颗种子的每个数,最高位都是 0
十颗种子摆在一起,其中四颗露出同一个痕迹。它们各自拆成五个数,每个数占 32 位,一共二十个。每个数最左边那一位,也就是最高位,都是 0。换成十六进制看,每个数都以 0 到 7 开头。
纯属巧合的概率是 5810 分之一。这个特征属于 lrand48。它肚子里记着 48 位的状态,对外却只交出最高的 31 位,所以输出最左边那一位永远是 0。
图3、48 位状态里,输出只取高 31 位或高 8 位
曲线分两类。P-192 到 P-521 这五条建在素数上,叫素域曲线。B-163 这类建在二进制的多项式上,叫二进制曲线。两种算法不一样,得分开攻。
二进制曲线这边就是解方程。每个数对应一次输出,可 31 位盖不住 48 位的状态,另外 17 位没露出来。这 17 位只有 2 的 17 次方种可能,十三万多个,全试一遍,再用后面四个数核对,状态就回来了。
素域曲线那边碎得多。P-192 到 P-521 这五颗,每一轮只留下 8 位,碎得拼不起来。模型换了一种数学工具,叫 LLL 格基约减,专门从残缺的数据里倒推原来的状态。
答案是一串时间戳这种发生器每一步都能倒着算。模型把状态一步步往回退,退到 srand48 刚初始化时的样子。那个样子有个固定特征,末尾 16 位等于 0x330E。可这个特征每 65,536 步就冒一次,光退到它不算证据。
真正的证据在后面一步。srand48 的参数是一个 32 位整数,当年的习惯是直接塞一个 Unix 时间戳。把这些状态换算回时刻,五条 NIST 曲线和另外五颗 ANSI 示例曲线的种子,全部落在 1997 年 5 月到 1998 年 4 月(UTC)之间。
这是种子生成的年份,二十五年的悬案从这批曲线写进标准算起,是个约数。
P-256 的种子来自 1997 年 8 月 16 日 01:52:34 那次启动,是那一串候选里的第 1842 个。P-192 只用到第 139 个,P-224 用到第 7026 个。
图4、五条曲线的种子与各自的生成时刻
每算一轮出 20 个字节,就是一个候选种子。拿它按 ANSI X9.62 的流程算出一条曲线,参数合格就留下,不合格丢掉,接着往下试。
程序会一直试下去,于是一次运行可能连着产出好几条曲线的种子。1997 年 5 月 18 日那次就出了三颗公布的种子,除了 P-192,还有两条 ANSI 示例曲线。
Anthropic 把复现代码公开了,CC0 授权,谁都能跑一遍,逐字节对上。结论不靠信任,靠复算。
这不是一次破解Anthropic 在文章里的措辞很克制。不是密码学破解,不是新的攻击,也不是 ECDSA 的弱点,读者不需要做任何事。
种子是公开参数,不是私钥。知道它怎么来的,拿不到任何人的签名密钥。反过来,整个过程从时钟起步,谁都能复现,想在里面做手脚,反而更容易露出来。
Valsorda 在 10 月 15 日 01:07:51(UTC)认领了悬赏,用 Go 把方法重写了一遍做验证,还补了一段定量分析。
这段分析针对的是悬案里最重的一条质疑。2017 年,Daniel Bernstein 和 Tanja Lange 向 Koblitz 和 Menezes 描述过一种手法,说种子上只要有大约 70 位自由度,就能瞄准一类假设存在的弱素域曲线,那类曲线一共 2 的 61 次方条。这套推测,是怀疑一直散不掉的重要原因。
二进制里,每多一位,可能就翻一倍。照这次的结果看,当年能动手脚的空间没这么大。1997 到 1998 这两年,按秒算大约 6300 万个时刻,约合 26 位,再乘上前 16 个候选,总共 30 位左右。
两者之间差了 2 的 40 次方倍。30 位这点空间,既不足以专门瞄准那类弱曲线,也不足以埋下一个只有自己知道的后门。
12,288 美元的悬赏按规则翻三倍,36,864 美元捐给了 Internet Security Research Group,也就是 Let's Encrypt 背后那家非营利组织。
模型在推理过程里还犹豫过一次,先怀疑自己是不是在一个模拟环境里,然后反问,这么明显的事二十五年没人发现,难道不可疑吗。
这句话被人截图发到 X 上,配文是 Claude 在内涵我们。
还有没解完的故事到这里没有完全闭合。B-163 的种子仍然不明,五条二进制曲线里只有它没对上。
基点也是一笔糊涂账。它不是种子,是曲线上的一个固定坐标。P-224,P-256,P-384,P-521 这四条的基点来源没找到,二进制曲线的基点同样没着落。目前只有 P-192 和五条 ANSI 示例曲线的基点摸清了配方,用的是 Arjen Lenstra 大整数库 FreeLIP 里的随机数发生器。
被跳过的候选更值得看。P-256 公布的是第 1842 个候选,可第 876 个同样能生成一条参数合格的曲线,当年被跳过了。P-224 那次跳过了三条,两次 ANSI 示例曲线的运行一共跳过七条。
图5、被跳过的可用候选,标准至今不明
Anthropic 说筛选标准不明。Valsorda 复算后找出一条,如果曲线绕一圈的步数,比那个素数还大,这个种子就丢掉,但另一条没能还原。合格候选因此大约是公布数量的两倍。
多出来的那些,Valsorda 试了几种解释都没对上。可能是同一台发生器也被拿去验证种子,先用掉了一部分输出,把一些候选挤掉了,而且挤掉的位置并不规律。也可能是当年的程序有 bug。
这些计算今天几分钟就能跑完,1997 年还是顶尖水平。
约翰霍普金斯大学的密码学家 Matthew Green 在 X 上留了一句,真正有意思的地方在这里。
图6、Green 贴出的官方未解问题一节
二十五年里,人们一直在找那句话。可它根本不存在。1997 年的一次开机,程序读了系统时间,种子就这么算了出来。
这次被改写的可能不是曲线,而是一类问题的解法。那些写在标准里,来源没人解释,又被所有人当作前提的常数,现在可以交给模型查一遍。