米勒-拉宾(Miller-Rabin)无法正常工作:底数和指数有问题

时间:2018-10-21 11:55:42

标签: c cryptography

我正在使用已知的强碱{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;

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(尽管它们使用不同的变量名)。