一般来说超大素数生成都是基于概率的素性检验算法实现的。
这里的基于概率是指这个数可能极大概率是素数,也可能极小概率是合数;但是只要将后者的概率控制在一个非常小的范围内,就能将这个数当作大素数来使用。
一般的大素数生成流程简单的超乎想象,说白了就是挨个数试。试某个数是否是合数,如果是的话就试下一个数;如果不是的话就认定这个数是素数。值得一提的是,这种素数一般被称为伪素数;因为这些被算法判定为非合数的数不一定是真的素数。
说的更清楚一点儿就是:这些算法能够快速的确定大部分数是否是合数,但不能确定所有的数是否是合数;也就是不能确定某个数是否是真的素数。
有很多算法可以实现快速的合数确认;有趣的是,这些算法并不能确定合数的分解因子,但是就是能确认这些数是不是合数。
简单说一下比较常用的几个算法。
第一个算法是基于费马小定理的费马算法。费马小定理是一个很有意思的定理,大意就是随便选一个素数p,再选一个和p不成倍数关系的整数β,必然满足β的p次幂和β对p同余。
那么这个命题的逆否命题就是,不满足β的p次幂和β对p同余的,p必然不是素数。
当然这个算法局限性还是很大的,因为你只能证明某个数不是素数,而无法证明某个数一定是素数。一个经典的伪素数就是561,还有1105和1729,这些“蒙混过关”通过费马算法的伪素数被称为Carmichael整数。
很不幸的是,这一类可以通过费马算法的伪素数有无限个。所以费马算法只适用于初步的简单筛选。
第二个算法是基于欧拉准则和勒让德符号的Solovay-Strassen算法。欧拉准则涉及一个平方剩余的概念,不是很好描述。馒馒来。
首先先说平方剩余。平方剩余指的就是y²和x对奇素数p同余,x<p;这时候存在解y,称x是模p的平方剩余。
这说起来可能有点儿绕口,我们举个简单的例子:4的平方是16(y²=16),16除以11余5(p=11,x=5),那么就称5是模11的平方剩余。
有的数满足这个条件,有的数不满足这个条件。再举个例子,取一个y²,y²除以11余6(p=11,x=6)。我们说找不到这样的数,则称6为模11的非平方剩余。
如果你很闲,把x从1到10算了一遍,就可以得到下述的式子:
1²≡1,2²≡4,3²≡9,4²≡5,5²≡3,6²≡3,7²≡5,8²≡9,9²≡4,10²≡1 (mod 11)
其中≡表示同余符号。说通俗点儿就是前面的那个数除以11余多少。比如7²=49,49除以11等于4余5。(4×11+5=49=7²)
当你把这些数列出来之后,数一数x的值(也就是同余符号右边的那个值),你会发现一个很有趣的现象:这些平方剩余,每个都不多不少,刚刚好有两个。
譬如上面那个例子,刚刚好有两个1,两个4,两个9,两个5,两个3。而剩下的2,6,7,8,10,刚刚好就没有对应y的解,不是平方剩余。
这就引出了一个欧拉准则:元素β是模奇素数p的平方剩余的充要条件是,β的(p-1)/2次幂和1对p同余。证明很简单,既然设了β是平方剩余,那么β必然能写成r²型。r²再(p-1)/2次幂,两个2一约,就是r的p-1次幂,满足费马小定理,证毕。
那么我们再说勒让德符号。这个符号也很简单,写作(a|p)。若a是模p的平方剩余,则(a|p)=1;若a不是模p的平方剩余,则(a|p)=-1;若a和p是整除关系,则(a|p)=0。说白了就是a是不是模p的平方剩余的一个判定式。
那么我们终于可以说Solovay-Strassen算法了。Solovay-Strassen算法的核心就是:若n是一个素数,那么勒让德符号(β|n)≡β的(n-1)/2次幂,mod n。
这一定理的逆定理是不成立的,所以我们只能逐次的进行试验。假设欲测试的大数是n,那么随机选择一个整数β,计算(β|n)和β的(n-1)/2次幂,判定这二者是否同余。假如不同余,则说明未通过测试,该数为合数。假如同余,则说明通过测试,继续选择另外一个β进行测试(因为素数一定可以通过同余测试,但通过同余测试的并不一定是素数),直到重复进行m次后结束。
简单说一下这个定理是怎么证的,他基于的是上面讲过的欧拉准则。当β可以写成平方剩余r²时,勒让德符号(β|n)=1,根据欧拉准则成立。当β不能写成平方剩余r²时,勒让德符号(β|n)=-1,根据欧拉准则β的(n-1)/2次方和1对n不同余。但是根据费马小定理,β的n-1次方和1对n同余。而根据平方差公式,
,而根据前面的欧拉准则,
无法被n整除,所以
必然能被n整除;进而得到
,证毕。
(说句题外话,答主原本不想插公式的……但是后来发现不用公式写更特么麻烦,扶额。嘛反正这段证明也不重要,看得懂就看,看不懂就直接看结论就好。)
而这里面计算勒让德符号(β|n),可以通过二次互反快速得到;计算β的(n-1)/2次幂,可以通过快速求幂和模余运算快速得到。结论就是不断地重复选择不同的β进行判定,当判定次数超过指定次数,得到非素数的概率很低的时候,就可以认为这个大数是一个素数。
第三个算法是Miller-Rabin算法,也是一个概率算法。草率的写一下流程吧,证明就不放了。
输入待测试大数n,对n-1不断地进行除2操作,直到得到一个奇数t。
于是这可以写成
。显然的,待测试大数n肯定是个奇数(废话,是偶数还测个锤子了),那么n-1肯定是个偶数,故s≠0。
选择随机种子a,a<n且与n互素。(这个也很容易做到,如果随便一下子就测出来不互素,那就不用测了)
先设m=t。计算
:
——情况①:当
时,停机,输出“n是一个合数”。
——情况②:当
时,停机,换一个随机种子a再次进行测试。
——情况③:当
不成立时,重新设b为b²(mod n),m为2m;继续循环,直到得到情况①或情况②为止。
这个算法比Solovay-Strassen算法要来的快,重复选择不同的随机种子,很快就能得到一个概率很高的素数。不管怎么说,这三个算法都是基于概率的。在大家眼里看起来精确无比的计算机,很多时候却会执行基于概率的算法——虽然这概率被反复确认到很极端的程度;想想看也挺有趣的不是吗?
以上。感谢您的阅读。