你能很迅速地找出两个比 1000 大的素数吗?你能很迅速地分辨 754729 是哪两个素数的乘积吗?实际上,因为素数相对密集,所以我们可以相对迅速地找出两个大的素数。但是,现在还没有已知算法能够有效地分解乘机中的因子。因此,在现代密码学中,利用这个时间差距,计算机科学家们发明了安全的加密系统,如 RSA 与 Rabin。
简单来说,加密信息的人需要随机地找出两个素数并且公开它们的乘积,如果他人想要破解信息的话必须分解被公开的乘积。这样,只要加密的人找到两个足够大的素数,第三方就没有方法破解信息。
但是,加密信息的人寻找素数时怎么才能知道一个随机的很大的数字到底是不是一个素数呢?他当然可以挨个数字尝试做除法检查,但是那样太耗时,毕竟他随机找出的是一个几百位长的数字。我们需要一个更有效率的算法。
1. 费马素性检验
我们接下来了解费马素性检验,虽然这个算法在现实中不常用,但是却构成了绝大多数素性检验算法的底层逻辑。
首先,我们需要了解费马小定理(Fermat’s Little Theorem)。
定理 1:
假如 a 是一个整数,p 是一个素数,且 a 不是 p 的倍数,那么 ap−1≡1(mod p)
比如,7 是一个素数,对任何一个不是 7 的倍数的整数 a 来说 a6≡1(mod 7)。
费马素性检验算法如下:
- 已知正整数 p,在 [2,p−1] 的范围内随机选择 a ;
- 计算 ap−1(mod p);
- 如果结果不等于 1,输出不是素数(是合数);
- 如果结果等于 1,输出可能是素数。
费马素性检验实际上就是费马小定理本身,如果一个数不满足费马小定理,则判断该数为合数;如果一个数满足费马小定理,则判断该数可能为素数。
费马小定理能够完全准确地判断一个数是不是素数,但它只能几乎完全准确的判断一个数是不是素数。比如,6 不是素数因为 25 ≡1(mod 6),9 不是素数因为 28 ≡1(mo