【发布时间】:2012-06-29 12:11:09
【问题描述】:
我正在尝试根据FIPS 186-3 C.3.1 中的描述来实施 Miller-Rabin 素数测试。无论我做什么,我都无法让它发挥作用。说明非常具体,我认为我没有遗漏任何内容,但我得到了true 的非主要值。
我做错了什么?
template <typename R, typename S, typename T>
T POW(R base, S exponent, const T mod){
T result = 1;
while (exponent){
if (exponent & 1)
result = (result * base) % mod;
exponent >>= 1;
base = (base * base) % mod;
}
return result;
}
// used uint64_t to prevent overflow, but only testing with small numbers for now
bool MillerRabin_FIPS186(uint64_t w, unsigned int iterations = 50){
srand(time(0));
unsigned int a = 0;
uint64_t W = w - 1; // dont want to keep calculating w - 1
uint64_t m = W;
while (!(m & 1)){
m >>= 1;
a++;
}
// skipped getting wlen
// when i had this function using my custom arbitrary precision integer class,
// and could get len(w), getting it and using it in an actual RBG
// made no difference
for(unsigned int i = 0; i < iterations; i++){
uint64_t b = (rand() % (W - 3)) + 2; // 2 <= b <= w - 2
uint64_t z = POW(b, m, w);
if ((z == 1) || (z == W))
continue;
else
for(unsigned int j = 1; j < a; j++){
z = POW(z, 2, w);
if (z == W)
continue;
if (z == 1)
return 0;// Composite
}
}
return 1;// Probably Prime
}
这个:
std::cout << MillerRabin_FIPS186(33) << std::endl;
std::cout << MillerRabin_FIPS186(35) << std::endl;
std::cout << MillerRabin_FIPS186(37) << std::endl;
std::cout << MillerRabin_FIPS186(39) << std::endl;
std::cout << MillerRabin_FIPS186(45) << std::endl;
std::cout << MillerRabin_FIPS186(49) << std::endl;
给我:
0
1
1
1
0
1
【问题讨论】:
-
我们能看到
POW吗?我看到了一个错误,它可以将一些素数声明为复合素数,但反过来却什么也没有。对于哪些值,您得到了错误的结果? -
你对战俘的定义在哪里?
-
pow 很好,但无论如何都不能放好
-
顺便说一句,你的随机数是not uniformly distributed——模运算会扭曲结果。
-
如果
result * base或base * base溢出会怎样?
标签: c++ math implementation primality-test