无符号长long溢出,数字在[10 ^ 5,10 ^ 10]范围内

时间:2014-05-21 13:30:06

标签: c++ integer-overflow

我已经实现了重复的方乘乘法算法,用于求和密码学手册(http:// cacr.uwaterloo.ca/hac/about/chap2.pdf - Algorithm 2.143) ),计算数量(a ^ k)mod n。 数字a,k和n的范围是[10 ^ 5,10 ^ 10]。

代码有效,但有些情况似乎发生溢出,我不知道为什么,因为10 ^ 10< 2 ^ 63 -1。

一个特殊的错误案例: a = 3807869923; k = 1735393391; n = 6748918117;

结果应为65(http://www.wolframalpha.com/input/?i=%283807869923%5E1735393391%29+mod+6748918117),但代码返回2608265009.

代码:

/*This function calculates (a^k) mod n.
It implements the algorithm 2.143 from book "Handbook of Applied Cryptography", */
{
    int shifts=0;
    unsigned long long b, f;
    b=1;

    if (k == 0) return b;

    //Gets the number of bits of number k
    while ((k >> shifts) != 0) shifts++;

    f = a;

    //Binary shift to extract the value of bit in position 0

    if (((k >> 0) & 1) == 1)
        b = a;


    for (int i=1; i < shifts; i++)
    {
        f = ((f%n)*(f%n)) % n;

        //Binary shift to extract the value of bit in position i

        if (((k >> i) & 1) == 1)
            b = ((f%n)*(b%n)) % n;

    }
    return b;
}

1 个答案:

答案 0 :(得分:2)

在以下代码行中:

f = ((f%n)*(f%n)) % n;

你自己可能有多个n-1n可以与10^10一样大,这意味着(n-1)^2几乎可以10^20溢出2^63 - 1

正如下面的评论中指出的barak manos你正在使用&#34; unsigned long long&#34;这意味着限制为2^64-1,而不是2^63-1。但这并没有改变问题。