100%确定性的快速素性测试?

时间:2012-12-11 22:01:40

标签: c++ algorithm math primes gmp

我正在使用GMP(使用MPIR)来处理任意大小的数据类型。我也使用它的素数测试函数,它使用米勒 - 拉宾方法,但它不准确。这就是我想解决的问题。

我能够通过使用暴力来确认数字18446744073709551253是素数,并采用sqrt方法。

有没有办法检查大数是否是素数,准确度是否达到100%?

  • 它不应该使用太多的内存/存储空间,可以接受几兆字节。

  • 它应该比我使用的sqrt方法更快。

  • 它适用于大小至少为64位或更大的数字。

  • 最后,它应该是100%准确,没有maybes!

我有什么选择?

我可以忍受蛮力方法(对于64位数字)但是出于兴趣,我想要更快和更好大。此外,64位数字检查太慢:总共43秒!

4 个答案:

答案 0 :(得分:6)

对于非常大的数字,AKS primality test是在时间O(log 7.5 n log log n)中运行的确定性素性测试,其中n是感兴趣的数量。这比O(√n)算法快得多。但是,该算法具有较大的常数因子,因此在您的数字变得相当大之前它是不实用的。

希望这有帮助!

答案 1 :(得分:3)

作为一般说法,在物理计算机上不可能100%确定,因为某些组件无形中失败并且最终给出的答案不正确的可能性很小但有限。鉴于这一事实,那么您可以运行足够的概率Miller-Rabin测试,即合成数的概率远小于硬件失败的概率。测试高达1 ^ 2 ^ 256级别的确定性并不困难:

boolean isPrime(num)
  limit <- 256
  certainty <- 0
  while (certainty < limit)
    if (millerRabin returns notPrime)
      return false
      exit
    else
      certainty <- certainty + 2
    endif
  endwhile
  return true
end isPrime

这将测试该数字是素数,直到2 ^ 256的确定性。每次M-R测试都会增加4倍的确定性。我已经看到所谓的素数被称为“工业强度素数”,足以满足所有实际目的,但并不完全符合理论数学确定性。

答案 2 :(得分:1)

对于小 n ,试验分工;限制可能在10 ^ 12左右。对于稍微大一点的 n ,有各种研究(参见Gerhard Jaeschke和Zhou Zhang的着作),它们计算了Miller-Rabin各种基因的最小假荧光;这将带你到大约10 ^ 25。在那之后,事情变得艰难。

素性证明的“大枪”是APRCL方法(可称为雅可比和或高斯和)和ECPP方法(基于椭圆曲线)。两者都很复杂,所以你会想要找到一个实现,不要自己编写。这些方法都可以处理数百个数字。

AKS方法被证明是多项式时间,易于实现,但比例常数非常高,因此在实践中没有用。

如果你可以将 n -1因子,或者甚至部分地考虑它,Pocklington的方法可以确定 n 的素数。 Pocklington的方法本身很快,但分解可能不是。

对于所有这些,你想要在你试图证明它之前合理地确定一个数字是素数。如果你的数字不是素数,那么所有这些方法都会正确地确定,但首先他们会浪费很多时间来证明复合数是素数。

我的博客上有AKSPocklington的实现。

答案 3 :(得分:0)

证明方法取决于您要证明的素数的类型(例如,梅森素数具有证明仅适用于它们的素数的特殊方法)和十进制数字的大小。如果您正在查看数百个数字,那么只有一个解决方案,虽然不够:AKS算法。对于足够大的素数来说,它比其他素性证明算法更快,但是当它变得有用时,它将花费很长时间才真的不值得麻烦。

证明大数字的原始性仍然是一个尚未充分解决的问题。如果是这样的话,EFF奖项将全部授予,密码学将有一些问题,不是素数列表,而是用于找到它们的方法。

我相信,在不久的将来,将会出现一种新的证明素数的算法,该算法不依赖于预先生成的素数列表,直到n的平方根,并且不会做粗暴的 - force方法确保平方根下的所有素数(以及许多非素数)都被用作n的素数的见证。这种新算法可能依赖于比分析数理论更简单的数学概念。素数中有模式,可以肯定的是。识别这些模式完全是另一回事。