使用两个 uint_32 数的倍数时模幂溢出
Modular exponentiation overflows when using multiple of two uint_32 numbers
我正在尝试实施 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 整数值
问题是,由于模数 > 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)
。
我正在尝试实施 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 整数值
问题是,由于模数 > 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)
。