信息安全数学基础——扩展欧几里得算法


一、欧几里得算法的严格证明

  设a,b是任意两个正整数。记r-2 = a,r-1 = b,反复运用带余除法,有
    r-2 = q0r-1 + r0 , 0 ≤ r0 < r-1
    r-1 = q1r0 + r1 , 0 ≤ r1 < r0
     r0 = q2r1 + r2 , 0 ≤ r2 < r1
      …
    rn-3 = qn-1rn-2 + rn-1 , 0 ≤ rn-1 < rn-2
    rn-2 = qnrn-1 + rn , 0 ≤ rn < rn-1
    rn-1 = qn+1rn + rn+1 , rn+1 = 0
随着n的增加,rn减小,由于rn+1 ≥ 0,因此,rn+1 = 0。
上述过程即从数列r-2,r-1,r0,…,rn前两项依次求出第三项,直到最后一项的过程。有(a,b)=(r-2,r-1)=(r-1,r0)= … =(rn-1,rn)=(rn,rn+1)=(rn,0)=rn
如果将这一过程反方向写出,有
    rn = rn-2 – qnrn-1
    rn-1 = rn-3 – qn-1rn-2
      …
    r2 = r0 – q2r1
    r1 = r-1 – q1r0
    r0 = r-2 – q0r-1
即rn,rn-1,…,r1,r0中每一项均可以用后两项表示。于是rn可以用r-2,r-1表示,即可以找到整数s,t,使得

sa + tb = rn = (a,b)

二、扩展欧几里得算法

定理1.13

  设a,b是任意两个正整数,则
s n a + t n b = ( a , b ) (式 1.3 ) s_na + t_nb = (a,b)(式1.3) sna+tnb=(a,b)(式1.3
对于j = 0,1,…,n-1,这里sj,tj归纳定义为
s − 2 = 1 , s − 1 = 0 , s j = s j − 2 − q j s j − 1 s_{-2} =1,s_{-1}=0,s_j=s_{j-2}-q_js_{j-1} s2=1,s1=0,sj=sj2qjsj1
t − 2 = 0 , t − 1 = 1 , t j = t j − 2 − q j t j − 1 (式 1.4 ) t_{-2}=0,t_{-1}=1,t_j=t_{j-2} -q_jt_{j-1}(式1.4) t2=0,t1=1,tj=tj2qjtj1(式1.4
其中j = 0,1,2,…,n-1,n。qi = [rj-2 / rj-1]是上式的不完全商。设x∈R,[x]表示不超过x的最大整数,称为实数x的整数部分。

证明:
  只需证明:对于j = -2,-1,0,1,…,n-1
s j a + t j b = r j ( 式 1.5 ) s_ja+t_jb =r_j(式1.5) sja+tjb=rj(1.5
其中rj = rj-2 - qjrj-1是(式1.5)中的余数。因为(a,b)= rn,所以
s n a + t n b = ( a , b ) s_na+t_nb=(a,b) sna+tnb=(a,b)
  对j用数学归纳法来证明式(1.5)。当j = -2时,有s-2 = 1,t-2 = 0以及
s − 2 a + t − 2 b = a = r − 2 s_{-2}a+t_{-2}b=a=r_{-2} s2a+t2b=a=r2
  式(1.5)对于j = -2成立。
  j = -1时,有s-1 = 0,t-1 = 1,以及
s − 1 a + t − 1 b = b = r − 1 s_{-1}a+t_{-1}b=b=r_{-1} s1a+t1b=b=r1
  式(1.5)对于j = -1成立。
  假设式(1.5)对于-2 ≤ j ≤ k-1成立,即
s j a + t j b = r j s_ja+t_jb=r_j sja+tjb=rj
  对于j = k,有
r k = r k − 2 − q k r k − 1 r_k=r_{k-2} - q_kr_{k-1} rk=rk2qkrk1
  利用归纳假设,得到
r k = ( s k − 2 a + t k − 2 b ) − q k ( s k − 1 a + t k − 1 b ) r_k =(s_{k-2}a+t_{k-2}b)-q_k(s_{k-1}a+t_{k-1}b) rk=(sk2a+tk2b)qk(sk1a+tk1b)
r k = ( s k − 2 − q k s k − 1 ) a + ( t k − 2 − q k t k − 1 ) b r_k=(s_{k-2}-q_ks_{k-1})a+(t_{k-2}-q_kt_{k-1})b rk=(sk2qksk1)a+(tk2qktk1)b
r k = s k a + t k b r_k=s_ka+t_kb rk=ska+tkb
因此,式(1.5)对于j = k成立。
  根据数学归纳法,式(1.5)对所有的j = -2,-1,0,1,…,n-1成立。
  下面根据上面的证明设计一个算法:假设a和b是不全为零的非负整数,计算s,t使得sa + tb =(a,b)。
  首先,令
r − 2 = a r − 1 = b r_{-2}=a\qquad r_{-1}=b r2=ar1=b
s − 2 = 1 s − 1 = 0 s_{-2}=1\qquad s_{-1} = 0 s2=1s1=0
t − 2 = 0 t − 1 = 1 t_{-2}=0\qquad t_{-1}=1 t2=0t1=1
这是因为rk = ska + tkb,所以r-2 = s-2a + t-2b = 1✖a + 0✖b = a,r-1 = s-1a + t-1b = 0✖a + 1✖b = b。
  (1)如果r-1 = 0,则令
s = s − 2 t = t − 2 s = s_{-2}\qquad t = t_{-2} s=s2t=t2
  否则,计算
q 0 = [ r − 2 / r − 1 ] r 0 = r − 2 − q 0 r − 1 q_0=[r_{-2}/r_{-1}]\qquad r_0=r_{-2}-q_0r_{-1} q0=[r2/r1]r0=r2q0r1
  (2)如果r0 = 0,则令
s = s − 1 t = t − 1 s=s_{-1}\qquad t = t_{-1} s=s1t=t1
  否则,计算
s 0 = s − 2 − q 0 s − 1 t 0 = t − 2 − q 0 t − 1 s_0=s_{-2}-q_0s_{-1}\qquad t_0=t_{-2}-q_0t_{-1} s0=s2q0s1t0=t2q0t1
  以及
q 1 = [ r − 1 / r 0 ] r 1 = r − 1 − q 1 r 0 q_1=[r_{-1}/r_0]\qquad r_1=r_{-1}-q_1r_0 q1=[r1/r0]r1=r1q1r0
  (3)如果r1 = 0,则令
s = s 0 t = t 0 s = s_0\qquad t = t_0 s=s0t=t0
  否则,计算
s 1 = s − 1 − q 1 s 0 t 1 = t − 1 − q 1 t 0 s_1=s_{-1}-q_1s_0\qquad t_1=t_{-1}-q_1t_0 s1=s1q1s0t1=t1q1t0
  以及
q 2 = [ r 0 / r 1 ] r 2 = r 0 − q 2 r 1 q_2 = [r_0/r_1]\qquad r_2 = r_0 - q_2r_1 q2=[r0/r1]r2=r0q2r1
. . . ... ...
  (j+1)如果rj-1 = 0(j ≥ 3),则令
s = s j − 2 t = t j − 2 s = s_{j-2}\qquad t = t_{j-2} s=sj2t=tj2
  否则,计算
s j − 1 = s j − 3 − q j − 1 s j − 2 s_{j-1}=s_{j-3}-q_{j-1}s_{j-2} sj1=sj3qj1sj2
t j − 1 = t j − 3 − q j − 1 t j − 2 t_{j-1}=t_{j-3}-q_{j-1}t_{j-2} tj1=tj3qj1tj2
  以及
q j = [ r j − 2 / r j − 1 ] r j = r j − 2 − q j r j − 1 q_j=[r_{j-2}/r_{j-1}]\quad r_j=r_{j-2}-q_jr_{j-1} qj=[rj2/rj1]rj=rj2qjrj1
  最后,一定有rn+1 = 0。这时,令
s = s n t = t n s=s_n\qquad t=t_n s=snt=tn
  总之,可以找到整数s,t,使得
s a + t b = r n = ( a , b ) sa+tb=r_n=(a,b) sa+tb=rn=(a,b)

  将上述算法可写成以下python代码:

算法代码实现

from euclid import *


def func(a, b):
    r = [a, b]
    q = [0, 0]
    s = [1, 0]
    t = [0, 1]
    i = 2
    if r[1] == 0:
        return s[0], t[0]
    else:
        next_q = r[0] // r[1]
        next_r = r[0] - next_q * r[1]
        r.append(next_r)
        q.append(next_q)
    while r[i] != 0:
        next_s = s[i-2] - q[i] * s[i-1]
        next_t = t[i-2] - q[i] * t[i-1]
        next_q = r[i-1] // r[i]
        next_r = r[i-1] - next_q * r[i]
        r.append(next_r)
        q.append(next_q)
        s.append(next_s)
        t.append(next_t)
        i += 1
    return s[i-1], t[i-1]


print(func(202, 282))
print('202 *', func(202, 282)[0], ' + 282 *', func(202, 282)[1], '=', gcdIter(202, 282))
print(func(1613, 3589))
print('1613 *', func(1613, 3589)[0], ' + 3589 *', func(1613, 3589)[1], '=', gcdIter(1613, 3589))
print(func(1859, 1573))
print('1859 *', func(1859, 1573)[0], ' + 1573 *', func(1859, 1573)[1], '=', gcdIter(1859, 1573))

  其中eculid模块是自己编写的用来求解最大公约数,详情可以参考信息安全数学基础——欧几里得算法

总结

  本文主要介绍了扩展欧几里得算法,其在求解乘法逆元时会非常有帮助。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值