我正在使用已知的强碱{2,7,61}来解决Miller-Rabin。假设我在这段代码中取a = 2,并取n = 5来测试其素数。 n-1的因式分解,所以4是2 * 2 * 1,所以我的m是1。 如果我测试2 ^ 1 = x mod 5,我当然会得到2,即使5是素数,这也会使我的Miller-Rabin测试失败。
async () => {
try {
await user.exists();
await user.verifyPassword(req.body.password);
await user.isApproved();
console.log("Login successful");
} catch(err) {
console.log("ERROR", err);
throw err
}
我最后调用的方法只是检查pow%n = 1还是n-1。
我无法理解我是否误解了Miller-Rabin算法,或者代码中是否存在某些问题。该代码仅适用于某些质数。
我也是新手,所以我很抱歉如果错误是由错误的编码引起的。
更新:
single_base方法的声明:
while(m > 0) {
if(m%2 == 0) {
pow *= a*a;
pow %= n;
m -= 2;
}
else {
pow *= a;
pow %= n;
m -= 1;
}
}
if(miller_rabin_single_base(pow, n) == 0) {
return 0;
}
...
m和pow的声明:
int miller_rabin_single_base(int16 a, int16 n) {
if(a%n == n-1 || a%n == 1) {
return 1;
}
else {
return 0;
}
}
int16是无符号的短裤,我正在用它来测试。
n是可以运行代码的任何人选择的无符号短数字。
如果我测试n = 5、13或29,我得到的不是素数,但是如果我测试7、11或31,我得到的是素数:
int16 nmu = n-1;
int16 m;
int16 k = 0;
while((nmu/2)%2 == 0) {
k++;
nmu = nmu/2;
}
m = nmu/2;
k++;
int16 pow = 1;
答案 0 :(得分:2)
您遗漏了M-R的一半。给定见证人a = 2和n = 5,其中n-1 = 4分解为2 2 ·1,您需要:
计算a 1 mod n = 2并与1和n-1(-1 mod n)比较;如果等于这个见证人说的是素数,则您前进到下一个见证人,但是事实并非如此,并且您在n-1中有2个以上的因数,因此请继续
计算a 1·2 mod n = 4并与n-1比较(仅 not 1);这是平等的,所以这个见证人说素数;通常,您将前进到下一个见证人(或者如果不再声明n可能是素数)。如果不相等,则由于已达到k-1 = 1的因子2,因此声明n个复合点并停止,但是对于包含更多因子2的n-1个值,您将重复此步骤多次。
< / li>在这种情况下,您的其他证人是不必要的; 7 mod 5 = 2,因此产生的结果完全相同,而61 mod 5 = 1和1则见证人说每个数字都是质数,这是没有用的。对于更现实(更大)的n,它们将很有用。
注意计算a m ,a m·2 ,a m·2·2 ,a m·2·2 ·2 ,等等所有的mod n可以通过首先计算x = a m mod n,然后重复计算x = x 2 mod n来更有效地完成。 / p>
请参见example in wikipedia(尽管它们使用不同的变量名)。