中国剩余定理(CRT)详解—从孙子定理到 RSA 应用
“有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二,问物几何?”——《孙子算经》
这就是中国剩余定理(CRT)的起源。在 CTF 密码学中,CRT 无处不在:RSA 加速解密、共模攻击、广播攻击、Elliptic Curve 点合并……不会 CRT,密码学题基本做不动。
1. 定理内容
给定一组同余方程:
1 | x ≡ a₁ (mod m₁) |
如果 m₁, m₂, …, mₖ 两两互质,则存在唯一解 mod M = m₁ × m₂ × … × mₖ。
2. 标准 CRT 实现
1 | def crt(remainders, moduli): |
3. 扩展 CRT(模数不互质)
实际题目中模数经常不互质。这时候需要用扩展 CRT。
思路:两两合并。先解前两个方程:
1 | x ≡ a₁ (mod m₁) |
设 x = a₁ + k·m₁,代入第二个方程:
1 | a₁ + k·m₁ ≡ a₂ (mod m₂) |
设 g = gcd(m₁, m₂)。如果 (a₂-a₁) 不能被 g 整除,无解。否则解出 k mod (m₂/g),合并为新的同余方程。
1 | from math import gcd |
4. CTF 实战:RSA CRT 加速
RSA 中,解密 m = c^d mod n。如果知道 p 和 q,可以用 CRT 加速:
1 | dp = d mod (p-1) |
比直接算 c^d mod n 快 4 倍左右。
5. CTF 实战:RSA 共模攻击
如果两组 (e1, n) 和 (e2, n) 用同一个 n 加密同一条明文 m:
1 | c1 = m^e1 mod n |
找 s1, s2 使得 s1·e1 + s2·e2 = 1(扩展欧几里得),则:
1 | m = c1^s1 · c2^s2 mod n |
1 | def common_modulus_attack(c1, c2, e1, e2, n): |
6. CTF 实战:RSA 广播攻击
如果 e=3 且同一条明文 m 用三个不同的模数 n1, n2, n3 加密:
1 | c1 = m³ mod n1 |
用 CRT 合并 c1, c2, c3 和 n1, n2, n3,得到 m³ mod (n1·n2·n3)。因为 m < n1, n2, n3,所以 m³ < n1·n2·n3,直接开立方根就得到 m。
1 | def broadcast_attack(c1, c2, c3, n1, n2, n3): |
7. CTF 实战:CRT 拆分 ECC 点
椭圆曲线中,如果知道点 P 在多个子群上的投影,可以用 CRT 合并回来。这在 Smart 攻击和 Pohlig-Hellman 中常用。
总结
CRT 是数论密码学的核心工具。记住:
- 标准 CRT:模数两两互质,直接套公式
- 扩展 CRT:模数不互质,两两合并
- RSA 中:共模攻击、广播攻击、CRT 加速解密
- ECC 中:Pohlig-Hellman 的 CRT 合并
实际做题时,sympy 有现成的 crp_crt 函数,但理解原理比调库重要。










