C++ 在为RSA实现计算D时,D总是为负值

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

我试图用扩展的欧几里德算法计算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 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
}