当使用两个uint_32数字的倍数时,模幂运算溢出

时间:2018-08-28 17:20:34

标签: c++ c++11 rsa modular-arithmetic

我正在尝试实施RSA密钥签名和验证。 我正在使用模幂运算,因为整数溢出可能会遇到错误。

uint64_t modmult(uint64_t a,uint64_t b,uint64_t mod)
{

    if (a == 0 || b < mod / a)
        return ((uint64_t)a*b)%mod;
    uint64_t sum;
    sum = 0;
    while(b>0)
    {
        if(b&1)
            sum = (sum + a) % mod;
        a = (2*a) % mod;
        b>>=1;
    }
    return sum;
}
uint64_t modpow( uint64_t a,uint64_t b,uint64_t mod)
{

    uint64_t product,pseq;
    product=1;
    pseq=a%mod;
    while(b>0)
    {
        if(b&1)
            product=modmult(product,pseq,mod);
        pseq=modmult(pseq,pseq,mod);
        b>>=1;
    }
    return product;
}

函数调用

long long d = 2897297195663230443;
uint64_t n = 10136926879504331723;
modpow(1233,d,n);

n是两个无符号uint32_t质数(4063800743,2494444861)的倍数,模幂 结果为3148683887780272464,但应为9640529604970470922

基本上,此实现不能很好地处理n的无符号64个整数值

1 个答案:

答案 0 :(得分:1)

问题在于,由于模数> 2 63 cursor.execute("INSERT INTO test (x) VALUES (10)") connection.commit() 例程中的a + sum步骤可能会溢出,从而造成一点损失。 modmult可能会发生同样的情况。

解决此问题的一种方法是添加一个2*a例程:

modadd

然后,在uint64_t modadd(uint_64_t a, uint64_t b, uint64_t mod) { if (a >= mod) a %= mod; // precondition -- might not be needed if the caller can guarentee it. if (b >= mod) b %= mod; // precondition -- might not be needed if the caller can guarentee it a += b; if (a >= mod || a < b) a -= mod; return a; } 例程中使用modadd(sum, a, mod)modadd(a, a, mod)