我正在尝试使用扩展的欧几里德算法计算RS的d。但是,每次我跑进来都证明是负面的。
这是算法的代码,前提是a是phi,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不应该是负数。知道这里出了什么问题吗?
答案 0 :(得分:0)
扩展Euclidean算法的实现没有任何问题,因为它为加密指数Repl_slave_priv
提供了正确的模块逆Super_priv
。
但是,对于RSA,您确实需要d
的正值。为此,只需:
e
假设您的BigInteger库的d
运算符始终返回非负结果。如果情况并非如此,那么至少结果应该大于d = exEuc(phi, e) % phi;
,在这种情况下你可以做到:
%
这是有效的,因为在modular arithmetic中,加上或减去(整数倍)模数不会改变数字的同余类。特别是,如果-phi
,则d = exEuc(phi, e) % phi;
if ( d < 0 ) d += phi;
。
顺便说一句,您可以对(d*e) % phi == 1
代码进行一些优化。第一个是你实际上并没有真正使用((d+phi)*e) % phi == 1
和exEuc()
值,所以你可以完全摆脱它们,就像这样:
x
第二个优化是,因为我们只对结果模prevX
感兴趣,所以我们实际上可以在计算过程中随时减少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
}
模phi
来保持它从太大(或负面!):
y
(请注意,我重命名了函数及其参数,以更好地描述优化版本的实际功能。另请注意,我包含了一个额外的测试,以确保即使您的BigInteger库的返回值也不能为负值phi
运算符可能会返回负值。)