C++ 在为RSA实现计算D时,D总是为负值
我试图用扩展的欧几里德算法计算RSA的d。然而,每次我跑进去,结果都是消极的 这是算法的代码,前提是a为φ,e为65537:C++ 在为RSA实现计算D时,D总是为负值,c++,encryption,rsa,C++,Encryption,Rsa,我试图用扩展的欧几里德算法计算RSA的d。然而,每次我跑进去,结果都是消极的 这是算法的代码,前提是a为φ,e为65537: BigInteger exEuc(BigInteger a, BigInteger b){ BigInteger x = 0; BigInteger prevX = 1; //holds the previous value of x BigInteger y = 1; BigInteger prevY = 0; //holds the p
BigInteger exEuc(BigInteger a, BigInteger b){
BigInteger x = 0;
BigInteger prevX = 1; //holds the previous value of x
BigInteger y = 1;
BigInteger prevY = 0; //holds the previous value of y
BigInteger temp, q;
while(b != 0){
q = a / b;
temp = b;
b = a % b;
a = temp;
temp = x;
x = prevX-q*x;
prevX = temp;
temp = y;
y = prevY-q*y;
prevY = temp;
}
return prevY; //this ends up being d
}
我已经用e*d mod phi测试了结果,它给出了1,就像它应该给出的一样,但我知道d不应该是负数。知道这里出了什么问题吗?扩展欧几里德算法的实现没有问题,这一事实表明,它为加密指数
e
提供了正确的模逆d
但是,对于RSA,您确实希望d
为正值。要实现这一点,只需:
d = exEuc(phi, e) % phi;
这是假设BigInteger库的%
运算符始终返回非负结果。如果不是这样,那么至少结果应该大于φ,在这种情况下,您可以简单地执行以下操作:
d = exEuc(phi, e) % phi;
if ( d < 0 ) d += phi;
第二个优化是,由于我们只对结果的模<代码>φ感兴趣,我们实际上可以在计算过程中随时减少模<代码>φ,以防止其变得太大(或负值!):
//计算x模m的模逆
BigInteger modInv(BigInteger x,BigInteger m){
大整数a=x,b=m;
大整数y=1;
biginger prevY=0;//保存y的上一个值
大整数温度,q;
而(b!=0){
q=a/b;
温度=b;
b=a%b;
a=温度;
温度=y;
y=(上一个y-q*y)%m;
prevY=温度;
}
如果(prevY<0)prevY+=m;//可能需要也可能不需要
return prevY;//结果是d
}
(请注意,我重命名了该函数及其参数,以便更好地描述优化版本的实际功能。还请注意,我还包括了一个额外的测试,以确保即使BigInteger库的
%
运算符可能返回负值,返回值也不能为负值。)您是否尝试过使用未签名的大数字?或者将其打印为无符号数字?您是否尝试过使用调试器单步检查代码,以找出其最终为负数的位置和原因?是的,这就是欧几里德算法的工作方式。对于计算倒数,你总是想要正的余数,当我把a或b加回去时,这个数字仍然是负数,在这两种情况下,当我不知道你在说什么时,e*dmodphi=1测试失败,但是如果你把φ加到d上,它将是正的,e*d将等于1 mod phi。
BigInteger exEuc(BigInteger a, BigInteger b){
BigInteger y = 1;
BigInteger prevY = 0; //holds the previous value of y
BigInteger temp, q;
while(b != 0){
q = a / b;
temp = b;
b = a % b;
a = temp;
temp = y;
y = prevY-q*y;
prevY = temp;
}
return prevY; //this ends up being d
}
// calculate the modular inverse of x modulo m
BigInteger modInv(BigInteger x, BigInteger m){
BigInteger a = x, b = m;
BigInteger y = 1;
BigInteger prevY = 0; //holds the previous value of y
BigInteger temp, q;
while(b != 0){
q = a / b;
temp = b;
b = a % b;
a = temp;
temp = y;
y = (prevY-q*y) % m;
prevY = temp;
}
if ( prevY < 0 ) prevY += m; // may or may not be necessary
return prevY; // this ends up being d
}