一句话版本
生成 RSA 密钥要找两个上千位的素数。办法是"随机挑一个奇数,测一测,不是就换一个"。 费马小定理给出最简单的测试:若 是素数,则 。但有一类合数(Carmichael 数,最小的是 )能骗过所有底数。Miller–Rabin 补上了这个漏洞,它利用的是:模素数时, 只有 两个根。
全文分三层:
- 通俗理解:为什么不分解也能判断素数,"随机抽查"的思路
- 实际用处:RSA 密钥生成、OpenSSL,以及素数生成出错的事故
- 数学原理:费马检验、Carmichael 数、Miller–Rabin 的正确性,附 的手算例子
第一层:通俗理解
1.1 判断素数比分解容易得多
" 是不是素数"和" 等于哪两个数相乘"听起来像同一个问题,其实难度天差地别:
- 判断一个 1000 位的数是否为素数:笔记本电脑不到一秒;
- 分解一个 600 位(2048 比特)的 RSA 模数:目前全人类的计算机加起来也做不到。
神奇之处在于,素性检验可以不找出任何因子就断定一个数是合数。就像验钞机不用知道假钞是谁印的,只要发现某个特征不对就行。
1.2 素数够多吗
素数定理说, 附近大约每 个数里有一个素数。对 1024 位的数,;只挑奇数的话,平均试约 355 个就能碰到一个素数。每次测试都很快,所以生成素数并不慢。
1.3 "抽查"的思路
素数一定满足某些性质(比如费马小定理)。我们随机挑一些底数 去检查:
- 只要有一次不满足,肯定是合数;
- 每次都满足,很可能是素数。
关键是设计一种检查,让合数"蒙混过关"的概率足够低。Miller–Rabin 每轮至多 的概率被骗,做 40 轮,被骗概率不超过 ,比硬件出错的概率还低。
第二层:实际用处
- RSA 密钥生成:OpenSSL、BoringSSL、各种硬件安全模块都用"小素数试除 + Miller–Rabin"的组合。先用前几百个小素数做试除,可以很快排除大部分候选数。
- Diffie–Hellman 参数:生成"安全素数" ,需要 和 同时是素数。
- 标准:美国 FIPS 186-5 规定了密钥生成时 Miller–Rabin 的轮数,有时还会加上 Lucas 检验(两者组合叫 Baillie–PSW,至今没找到能骗过它的合数)。
素数生成出错的后果
- 随机数不够随机:2012 年对全网 RSA 公钥的扫描发现,大量路由器、防火墙在开机熵不足时生成了共用素因子的密钥,求个 就能分解(见《RSA与欧拉定理》)。
- 素数有结构:ROCA 漏洞(2017)中,某芯片为了加速而用了特殊形式的素数,结果可以被分解。
- 对手构造的"伪素数":2018 年的研究 Prime and Prejudice 发现,部分加密库对外部传入的数做素性检验时轮数太少或底数固定,攻击者可以专门构造能骗过它的合数,从而注入不安全的 DH 参数。
第三层:数学原理
3.1 费马检验
费马小定理:若 是素数,,则 。(这是 阶为 时的拉格朗日定理。)
检验:随机选 ,算 。不等于 , 一定是合数。
大多数合数都过不了这一关。例如 ,,立刻露馅。
3.2 Carmichael 数
有一类合数,对所有与它互素的 都满足 ,叫 Carmichael 数。
Korselt 判据:合数 是 Carmichael 数,当且仅当 无平方因子,并且对每个素因子 都有 。
最小的例子 : 能被 、、 整除。由中国剩余定理, 在模 、、 下都是 ,所以模 也是 。
1994 年 Alford、Granville、Pomerance 证明了 Carmichael 数有无穷多个。所以单靠费马检验是不行的。
3.3 关键引理:模素数时 只有两个平方根
若 是奇素数,,则 。因为 是域(没有零因子),只能 或 。
反过来,如果找到 但 ,那么 有零因子, 一定是合数(而且 就是一个非平凡因子)。
3.4 Miller–Rabin
把 写成 , 为奇数。随机选 ,看这串数:
每一项是前一项的平方。如果 是素数,由费马小定理最后一项是 ;再由 3.3 的引理,倒着往回开平方,第一次离开 时必须是 。所以素数一定满足:
要么 ,要么这串数里某一项等于 。
不满足就判定合数。Rabin 证明了:对合数 ,至多 的底数 能骗过这个检验。
3.5 手算例子:揭穿
,底数
费马检验:。通过了,被骗。
Miller–Rabin:,所以 ,。
| 项 | 值 |
|---|---|
序列从 直接跳到 ,中间没有经过 。也就是说 但 ,这在素数模下不可能发生,所以 561 是合数。
顺带还能拿到因子:,。(已用 Python 验算。)
3.6 确定性算法
2002 年,Agrawal、Kayal、Saxena 给出了 AKS 算法,第一次证明了素性检验可以在确定性多项式时间内完成(论文题目就叫 PRIMES is in P)。不过它比 Miller–Rabin 慢得多,实际中仍用概率算法。
总结
| 层次 | 要点 |
|---|---|
| 直觉 | 判断素数比分解容易得多;随机抽查,错一次就是合数 |
| 代数 | 费马小定理来自拉格朗日定理;Carmichael 数能骗过它 |
| 关键 | 域里 只有 ;找到别的平方根就证明是合数 |
| 工程 | 试除 + 多轮 Miller–Rabin;随机数质量和轮数都不能省 |