中国剩余定理

算法介绍

中国剩余定理(Chinese Remainder Theorem)即孙子定理,是中国古代求解一次同余式组的方法,又称中国余数定理。在《孙子算经》中,“物不知数”的问题下:有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?如果用现代语言描述,可以给出一元线性同余方程组:

\[(S):\begin{cases} x \equiv a_1 \; (mod \; m_1) \\ x \equiv a_2 \; (mod \; m_2) \\ \cdots \\ x \equiv a_n \; (mod \; m_n) \end{cases} \]

假设整数 \(m_1, m_2, \cdots, m_n\) 两两互质,则对任意的整数 \(a_1, a_2, \cdots, a_n\),方程组有解,并且通解可以用如下方式构造得到:

  1. \(M = \prod_{i=1}^{n} m_i\),是整数 \(m_1, m_2, \cdots ,m_n\) 的乘积,并设 \(M_i = M / m_i\) 是除 \(m_i\) 以外的 \(m\) 个数的乘积
  2. \(t_i = M_i^{-1}\)\(M_i\)\(m_i\) 的逆元,\(t_i M_i \equiv 1 \; (mod \; m_i)\)
  3. 方程组 \((S)\) 的通解形式为

\[x = \sum_{i=1}^{n} a_i t_i M_i \; (mod \; M) \]

需要注意,中国剩余定理的前提条件是模数互素

算法流程图

crt

具体代码(python)

def ex_gcd(a: int, b: int) -> (int, int, int):
    """
    :return: gcd x y
    """
    if a == 0 and b == 0:
        return None
    else:
        x1, y1, x2, y2 = 1, 0, 0, 1  # 初始化x1,y1,x2,y2
        while b:
            q, r = divmod(a, b)
            a, b = b, r  # gcd(a,b)=gcd(b,a%b)
            x1, y1, x2, y2 = x2, y2, x1 - q * x2, y1 - q * y2
        # 返回一个三元组,依次是(gcd,x,y),使得 xa+yb=gcd
        return (a, x1, y1) if a > 0 else (-a, -x1, -y1)


def crt(r_lst: list, m_lst: list):
    """
    :param r_lst: 余数列表
    :param m_lst: 模数列表
    :return: 同余式的解 x
    """
    r_lst = [r % m for (r, m) in zip(r_lst, m_lst)]  # 预先初始化
    M, res = 1, 0
    # M = m1*m2*...*mn
    for m in m_lst:
        M = M * m
    for r, m in zip(r_lst, m_lst):
        temp = r * M // m * ex_gcd(M // m, m)[1]
        res = (res + temp) % M
    return res

测试样例及结果

#样例一
r1 = 0
r2 = 0
r3 = 0

m1 = 23
m2 = 28
m3 = 33
# 结果
x = 0
#样例二
r1 = 5
r2 = 20
r3 = 34

m1 = 23
m2 = 28
m3 = 33
# 结果
x = 19900
#样例三
r1 = 283
r2 = 102
r3 = 23

m1 = 23
m2 = 28
m3 = 33
# 结果
x = 9230
# 样例四
r1 = 802310684485241212312289432691586430708135062249
r2 = 961714109955647014172499578071923389425123540027
r3 = 1381194006087304024683552712488022595194097928701

m1 = 489808178709479466279507878773770708214878979673
m2 = 896234965496726578561614071442814700467907036641
m3 = 1213827005758305602466882992172310409456053868843
# 结果
x = 509678885274099350362023393352578082708427568899031846709831030150136786034479833877558685987430752184856829540175601138538702893016912367204417
# 样例五
r1 = 8157969540288411637818433039558323184074779086100165504668538221920170369774913261335059602331627321130656458962980224196880533337839226059601303464776145
r2 = 9699616044315021194953572561076502992783130623216574220426043600142343504101508838526221359049417564415801914072315788919275792502477693022853881785198116
r3 = 7832693802256371667866514213119452199821916193668106904135812283217637737600922381702016472708855675649121271702977408217814917908566132517503707494037556

m1 = 13392316081651420877308875276166772808601812122052371442339078877740399569281672683820206196320955005869072002883847646526584107260355414977120453263391947
m2 = 9734466939658282823343760206593283968765904848250021580218634383869090913086348857668999272399075016287736914000854272239315769632719896968098820774563511
m3 = 9460200357790728398862913232664036038694521858415765931064505193755202156521446156499075450033429983317127589636591133111239548821251790171694322930011927
# 结果
x = 140572312041533061939584609644717750021442788242435867722409828434892657662537831184923189181096394076478262531889424668688702308599804777751973228204825311287964733040400616834339634575632758809487770732820709381703577738588480472947498776340910097209045550068926957348504285471095081384232331643227847899239

用途

中国剩余定理用于求解同余方程组,可以优化算法 RSA 的解密

参考资料:《密码学实验教程》

posted @ 2021-07-07 16:58  kentle  阅读(1381)  评论(0编辑  收藏  举报