该方法BigInteger.isProbablePrime()
很奇怪。从文档中可以看出,数字是否为素数,概率为1 - 1 / 2^arg
,其中arg
整数参数为。
它已经存在于JDK中很长时间了,因此,它必须具有用途。我对计算机科学和算法(以及数学)的有限了解告诉我,知道一个数字是否“可能”是质数而不是完全是质数并没有什么意义。
那么,在什么情况下想使用此方法呢?密码学?
该方法BigInteger.isProbablePrime()
很奇怪。从文档中可以看出,数字是否为素数,概率为1 - 1 / 2^arg
,其中arg
整数参数为。
它已经存在于JDK中很长时间了,因此,它必须具有用途。我对计算机科学和算法(以及数学)的有限了解告诉我,知道一个数字是否“可能”是质数而不是完全是质数并没有什么意义。
那么,在什么情况下想使用此方法呢?密码学?
Answers:
是的,此方法可用于密码学。 RSA加密涉及发现巨大的质数,有时质数约为1024位(约300位)。RSA的安全性取决于以下事实:分解由这些质数中的2个相乘构成的数字非常困难且耗时。但是要使其正常工作,它们必须是一流的。
事实证明,证明这些数字是素数也是困难的。但是Miller-Rabin素数检验(一种素数检验使用by isProbablePrime
)之一是检测到一个数字是合成的或未给出结论。运行此测试n
时间可以使您得出结论:该数字实际上是复合的,几率为2 n。100
乘以该倍数可得出此数字为2 100的可接受风险。
isProbablyPrime
(据我所知)的实现是完全确定的。运行测试n
时间将如何提高正确结果的几率?(即使这是随机性的一种因素,也需要使多个通话的随机性独立,以按照您所描述的方式影响风险。)
如果测试告诉您整数不是素数,则可以肯定为100%。
如果测试告诉您整数是“可能的质数”,那么这只是问题的另一方面,您可能会怀疑。以不同的“碱基”重复测试可以使虚假成功“模仿”素数(相对于多个碱基为强伪素数)的概率尽可能小。
测试的实用性在于它的速度和简便性。不一定会以“可能的质数”作为最终答案的状态感到满意,但一定会避免在引入素数测试的大手笔之前,通过使用此例程来浪费几乎所有复合数的时间。
与分解整数的难度的比较有点像是鲱鱼。众所周知,整数的素数可以在多项式时间内确定,并且确实有证据表明,将Miller-Rabin检验扩展到足够多的基数是确定的(在检测素数中,而不是可能的素数中),但这假设采用了广义黎曼假设,因此不确定性不如(更昂贵的)AKS素数检验。
probablePrime
方法,而不是isProbablePrime
方法)
标准用例BigInteger.isProbablePrime(int)
是在密码学中。具体而言,某些加密算法(例如RSA)需要随机选择的大素数。但是,重要的是,这些算法并不需要真正保证这些数字是质数,而仅是很有可能需要质数。
有多高有多高?好吧,在加密应用程序中,通常会.isProbablePrime()
用一个介于128到256之间的参数来调用。因此,非素数通过此类测试的概率小于2 128或2 256中的一个。
让我们把在视角:如果你有10个十亿台计算机,各发电每秒10张十亿可能的素数(这将意味着任何一个现代CPU每数少于一个时钟周期),并且这些数字的素数与测试.isProbablePrime(128)
,你平均而言,我们希望每1000亿年中有一个非质数下降。
就是这样,如果那100亿台计算机可以在不经历任何硬件故障的情况下全部运行数千亿年。但在实践中,这是一个很大更有可能随机宇宙射线在正确的时间和地点翻转返回值来打击你的电脑中.isProbablePrime(128)
,从虚假到真实的,不会造成任何其它可检测的效果,比它是一个非-素数在该确定性水平上实际通过概率素性检验。
当然,同样的随机宇宙射线和其他硬件故障的风险也适用于诸如AKS之类的确定性素数测试。因此,实际上,由于随机硬件故障(更不用说所有其他可能的错误源,例如实现错误),即使是这些测试也具有(非常小的)基准误报率。
由于可以很容易地将所使用的Miller-Rabin素数测试的固有假阳性率推到.isProbablePrime()
远低于此基准率的程度,只需重复多次测试即可,并且即使重复了如此多次,Miller-Rabin测试仍然是在实践中,它比最著名的确定性素数测试(例如AKS)快得多,它仍然是密码学应用程序的标准素数测试。
(此外,即使您偶然偶然选择了一个强大的伪素数作为RSA模数的因素之一,通常也不会导致灾难性的失败。通常,此类伪素数将是两个(或很少有更多)素数的乘积。长度的一半,这意味着您将得到一个多素数的RSA密钥,只要没有一个因素太小(如果是,则素数测试应该抓住了它们),RSA算法将仍然可以正常工作,并且该密钥,尽管对某些类型的攻击比同等长度的普通RSA密钥要弱一些,但是如果您不必无视密钥长度,则仍应是相当安全的。)
一个可能的用例是测试给定数字的素数(在测试中它本身有很多用途)。该isProbablePrime
算法将比一种精确算法运行得快得多,因此,如果该算法失败了isProbablePrime
,那么就不必花钱运行更昂贵的算法。
查找可能的素数是密码学中的重要问题。事实证明,找到可能的k位素数的合理策略是重复选择一个随机的k位数字,并使用类似的方法测试它的可能素数。isProbablePrime()
。
有关更多讨论,请参见 《应用密码学手册》第4.4.1节。
另请参阅Brandt和Damgård通过增量搜索生成可能的素数。
诸如RSA密钥生成之类的算法依赖于能够确定数字是否为质数。
但是,在将该isProbablePrime
方法添加到JDK时(1997年2月),还没有行之有效的方法来确定在合理的时间内数字是否为质数。当时最著名的方法是Miller-Rabin算法-一种概率算法,有时会给出误报(即,将非素数报告为素数),但可以进行调整以降低误报的可能性,但为此付出了代价运行时间的适度增加。
从那时起,就发现了可以确定性地快速确定数是否为质数的算法,例如AKS算法。2002年8月发现。但是,应该指出的是,这些算法仍然不如Miller-Rabin快。
也许更好的问题是,为什么isPrime
自2002年以来没有向JDK添加任何方法。