扩展的欧几里得算法
扩展的欧几里得算法不仅可以计算最大公约数d,而且还可以得到两个整数x,y 使得 ax+by = d = gcd(a, b)。有两个数a,b,对它们进行辗转相除法,可得它们的最大公约数。然后收集辗转相除法中产生的中间量,倒推可以得到ax+by=gcd(a,b)的一组整数解。这就是扩展的欧几里得算法。
辗转相除法产生的中间量为当前状态下a, b的余数,我们设存在x0,y0,x1,y1使得:
d = a*x0 + b*y0
辗转相除法其中一步的a,b
d = b*x1 + (a % b)*y1
辗转相除法上一步的a = b,b = a % b
化简第二个式子有:
d = b*x1 + (a - a//b * b) * y1
= b*x1 + a*y1 - a//b * b * y1
= a*y1 + b * (x1 - a//b * y1)
在拿第一个式子来看
d = a*x0 + b*y0
d = a*y1 + b * (x1 - a//b * y1)
则当以下条件满足时
x0 = y1
y0 = (x1 - a//b * y1)
由此可以逆推回去可以得到一组x,y使得ax+by = d = gcd(a,b)
由于gcd(a, b)的结果为最后一步的a,所以x,y的初值为1,0。
def ext_euclid(a, b):
if b == 0:
return 1, 0, a
else:
x, y, q = ext_euclid(b, a % b)
x, y = y, (x - (a // b) * y)
return x, y, q
RSA共模攻击
生成秘钥的过程中使用了相同的模数n,此时用不同的秘钥e加密同一信息m即:
c1 = m^e1 % n
c2 = m^e2 %n
若两个秘钥e互素根据扩展的欧几里得算法则存在s1,s2有:
e1s1 + e2s2 = gcd(e1, e2) = 1
结合以上所有信息,可以得到一个结论:
(c1^s1 * c2^s2) %n
= (m^e1 % n)^s1 * (m^e2 %n)^s2 % n
= m^(e1 * s1 + e2 * s2) % n
= m%n
= m
也就是在完全不知道私钥的情况下,得到了明文m
m = (c1^s1 * c2^s2) %n