c++ - 使用两个 uint_32 数的倍数时模幂运算溢出

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

我正在尝试实现 RSA key 签名和验证。 我在使用模幂时遇到可能由于整数溢出导致的错误。

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 整数值

最佳答案

问题是,由于模数 > 263,您的 modmult 例程中的 a + sum 步骤可能会溢出,失去一点。 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;
}

然后,在 modmult 例程中使用 modadd(sum, a, mod)modadd(a, a, mod)

关于c++ - 使用两个 uint_32 数的倍数时模幂运算溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52063315/

相关文章:

c++ - 在 C++ 中确定字符串的每个单词中的字母数量

c++ - 使用 BOOST ASIO 缓冲器

c++ - lambda捕获的"this"不正确。 GCC 编译器错误?

rsa - BouncyCaSTLe 算法标识符

java - Java中的确定性RSA加密

c++ - 我的 RSA 加密每次生成 2^64 (C++)

c++ - 如何同时旋转和平移我的 Sprite ? cocos2dx 3.2

c++ - 在 C++ 中如何将自引用作为参数传递?

c++ - 当引用指向父类的指针时,对象会丢失其成员的数据

c++ - 根据形参函数实参类型重载函数模板