gpt4 book ai didi

c++ - Miller-Rabin 素数测试 FIPS 186-3 实现

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:22:09 28 4
gpt4 key购买 nike

我正在尝试根据 FIPS 186-3 中的描述实现 Miller-Rabin 素性测试C.3.1.无论我做什么,我都无法让它发挥作用。说明非常具体,我认为我没有遗漏任何内容,但对于非素数,我得到了 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

最佳答案

您的实现与维基百科的唯一区别是您忘记了第二个 return 复合语句。您应该在循环结束时返回 0。

编辑:正如丹尼尔所指出的,还有第二个区别。 continue 继续内部循环,而不是像它应该的那样继续外部循环。

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{
int continueOuter = 0;
for(unsigned int j = 1; j < a; j++){
z = POW(z, 2, w);
if (z == W)
continueOuter = 1;
break;
if (z == 1)
return 0;// Composite
}
if (continueOuter) {continue;}
}
return 0; //This is the line you're missing.
}
return 1;// Probably Prime

另外,如果输入是偶数,它可能总是返回素数,因为 a 为 0。您应该在开始时为此添加一个额外的检查。

关于c++ - Miller-Rabin 素数测试 FIPS 186-3 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11236757/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com