擴展的歐幾里得算法
擴展的歐幾里得算法不僅可以計算最大公約數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