- 扩展欧几里得算法
已知整数a、b,扩展欧几里得算法可以在求得a、b的最大公约数的同时,能找到整数x、y(其中一个很可能是负数),使它们满足贝祖等式
ax+by=gcd(a,b)
如果a是负数,可以把问题转化成
|a|(-x)+by=gcd(|a|,b)
,然后令x’=(-x)。
当 (a,b) = 1时,即ax+by=1,可以化成 ax ≡1 (mod b),因此可以用来求RSA中的e以及模逆元。
- 贝祖等式的证明
- 计算过程
sa + tb=(a,b)
注:s(n),t(n),r(n)中的n均为下标。
首先令r(-2)=a,r(-1)=b,s(-2)=1,s(-1)=0,t(-2)=0,t(-1)=1。
(1)如果r(-1)=0,则s=s(-2),t=t(-2),否则计算q(0)=r(-2)//r(-1),r0=-q(0)*r(-1)+r(-2)=r(-2)%r(-1)。
(2)如果r(0)=0,则s=s(-1),t=t(-1),否则计算s(0)=-q(0)*s(-1)+s(-2),t(0)= -q(0)*t(-1)+t(-2)以及q(1)=r(-1)//r(0),r1= -q(1)*r(0)+r(-1)=r(-1)%r(0)。
(3)重复(2)的步骤,直到r(n+1) = 0,此时s=s(n),t=t(n),(a,b)=r(n)。
- 代码
根据计算过程写出代码
#扩展欧几里得算法
#假设a,b是不全为零的非负整数,求s,t使得s*a+s*b=(a.b)
a = int(input())
b = int(input())
s3,s2 = 1,0
t3,t2 = 0,1
q=0
#递推
while True:
if b == 0:
print('s={},t={},(a,b)={}'.format(s3,t3,a))
break
else:
s3,s2 = (-q)*s3+s2,s3
t3,t2 = (-q)*t3+t2,t3
q=a//b
a,b = b,a%b
'''
#递归
def ext_euclid(a, b):
if b == 0:
return 1, 0, a
else:
x, y, q = ext_euclid(b, a % b) # q = gcd(a, b) = gcd(b, a%b)
x, y = y, (x - (a // b) * y)
return x, y, q
x,y,q = ext_euclid(a,b)
print('x={},y={},(a,b)={}'.format(x,y,q))
'''
网上计算 ed ≡ 1(mod φ(n))还有另一种写法:
def ext_euclid(a, b):
if b == 0:
return 1, 0, a
else:
x, y, q = ext_euclid(b, a % b) # q = gcd(a, b) = gcd(b, a%b)
x, y = y, (x - (a // b) * y)
return x, y, q
def mod_inv(a, b):
return ext_euclid(a, b)[0] % b #函数返回的第一个数%b
这里对e进行了模运算,即e = e (mod φ(n)),我觉得应该不需要。因为有如下定理:
设m是一个正整数,a是满足(a,m) = 1的整数,则存在唯一的整数a’ ,1 <= a’ < m,使得a*a’ ≡ 1(mod m)。
存在性证明:
因为(a,m) = 1,所以当k遍历模m的一个最小简化剩余系时,ak也遍历模m的一个简化剩余系。因此,存在整数k=a’,1 <= a’ < m使得aa’属于1的剩余系。
唯一性证明:
若有整数a’ , a’’ (1<= a’,a’’ <m)使得aa’ ≡ 1,aa’’ ≡ 1(mod m),则a(a’-a’’) ≡ 0(mod m),从而a’-a’’ ≡ 0(mod m),故a’=a’’。
因此我们求出的e只有一个,而且e<m,所以不需要进行模m运算。倘若只是为了让函数返回一个值也不是不行。