一句话版本
若 m,n 互素,则 Zmn≅Zm×Zn 是环同构:一个模 mn 的数,和它"模 m 的余数、模 n 的余数"这一对数,是一回事。
于是一个大问题可以拆成几个小问题分头算,再拼回来。RSA 加速、Pohlig–Hellman 攻击、全同态加密的 RNS 表示、NTT 快速乘法,背后都是它。
全文分三层:
- 通俗理解:韩信点兵
- 实际用处:密码学里 CRT 出现的五个地方
- 数学原理:环同构、构造性证明、多项式版本,附手算例子
第一层:通俗理解
1.1 韩信点兵
《孙子算经》(约公元 4 世纪)里的题目:
今有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?
答案是 23。民间口诀叫"韩信点兵":士兵三人一排、五人一排、七人一排,只报每次剩几个人,就能推出总人数(在 105 以内唯一)。
1.2 一个数,两种"身份证"
0 到 14 的每个数,都可以用"除以 3 的余数、除以 5 的余数"这一对数来唯一表示:
| x |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
| xmod3 |
0 |
1 |
2 |
0 |
1 |
2 |
0 |
1 |
2 |
0 |
1 |
2 |
0 |
1 |
2 |
| xmod5 |
0 |
1 |
2 |
3 |
4 |
0 |
1 |
2 |
3 |
4 |
0 |
1 |
2 |
3 |
4 |
15 个数,15 种不同的余数对,一一对应。而且更妙的是:加法和乘法可以分开在两边算。比如 4×7=28≡13(mod15);用余数对算:
(1,4)×(1,2)=(1⋅1mod3, 4⋅2mod5)=(1,3),
查表,(1,3) 对应的正是 13。
1.3 为什么这很有用
大数运算的代价随位数增长很快(乘法大约是位数的平方)。把一个 2048 位的数拆成两个 1024 位的余数,每边的乘法便宜 4 倍,而且两边可以并行。这就是"分而治之"。
第二层:实际用处
| 出现的地方 |
CRT 干了什么 |
详见 |
| RSA 解密 / 签名加速 |
把模 n=pq 的幂运算拆成模 p、模 q,快 3 到 4 倍 |
RSA与欧拉定理 |
| Pohlig–Hellman 攻击 |
群的阶有小因子时,把离散对数拆碎逐个解,再拼回来 |
Diffie–Hellman与离散对数 |
| Håstad 广播攻击 |
同一消息用 e=3 发给三个人,三个密文用 CRT 拼成整数 m3 |
RSA与欧拉定理 |
| 全同态加密的 RNS 表示 |
几百位的模数 q=q0q1⋯qL 拆成一串 64 位素数,每个都能用机器字直接算;模切换就是"扔掉一个素数" |
同态加密 |
| NTT 快速多项式乘法 |
多项式版本的 CRT:F[x]/(xn−1)≅Fn |
后量子密码 |
此外,素性检验里分析 Carmichael 数、Shamir秘密分享的拉格朗日插值,也是 CRT 的同类思想(拉格朗日插值本身就是多项式环上的 CRT)。
拆开算也带来风险
RSA-CRT 如果只在其中一半出了计算错误,攻击者用一个 gcd 就能分解模数(Bellcore 故障攻击)。
第三层:数学原理
3.1 定理
设 m1,…,mk 两两互素,M=m1⋯mk。则映射
π:ZM→Zm1×⋯×Zmk,x↦(xmodm1,…,xmodmk)
是环同构。
证明思路(抽象代数标准做法):
- 先看 π~:Z→∏Zmi,它显然是环同态(每个分量都是取模同态);
- 核是"同时被所有 mi 整除的数",由两两互素,就是 MZ;
- 由第一同构定理,Z/MZ≅imπ~;
- 两边都有 M 个元素,单射即满射,所以是同构。
更一般的版本:交换环 R 中两两互素(Ii+Ij=R)的理想 I1,…,Ik 满足 R/(I1⋯Ik)≅R/I1×⋯×R/Ik。
3.2 怎么拼回来(构造逆映射)
令 Mi=M/mi,求 yi=Mi−1modmi(互素保证存在,用扩展欧几里得算法)。则
x=i∑riMiyimodM.
道理:ei=Miyi 满足"模 mi 是 1,模其他 mj 是 0",它是第 i 个分量的"单位向量"。这和Shamir秘密分享里的拉格朗日基多项式 Lj(x) 是完全一样的思路。
3.3 手算例子:韩信点兵
x≡2(mod3),x≡3(mod5),x≡2(mod7)
M=105。
| i |
mi |
Mi |
Mimodmi |
yi=Mi−1 |
ei=Miyi |
| 1 |
3 |
35 |
2 |
2(2⋅2=4≡1) |
70 |
| 2 |
5 |
21 |
1 |
1 |
21 |
| 3 |
7 |
15 |
1 |
1 |
15 |
x=2⋅70+3⋅21+2⋅15=140+63+30=233≡23(mod105).
检查:23=7⋅3+2=4⋅5+3=3⋅7+2。✓
《孙子算经》的口诀"三人同行七十稀,五树梅花廿一枝,七子团圆正半月,除百零五便得知"里的 70、21、15,正是表中的 ei。(已用 Python 验算。)
3.4 多项式版本
把 Z 换成 F[x],把互素的整数换成互素的多项式,定理照样成立。若 f(x)=∏i(x−αi),αi 两两不同,则
F[x]/(f)≅F×F×⋯×F,g(x)↦(g(α1),…,g(αn)).
左边的乘法是多项式乘法(卷积,慢);右边是逐点相乘(快)。这正是 FFT / NTT 的代数本质:取 αi 为单位根时,正反两个方向都能用分治在 O(nlogn) 内完成。
总结
| 层次 |
要点 |
| 直觉 |
一个数 = 一组余数;运算可以分开算再拼回 |
| 代数 |
Zmn≅Zm×Zn,由第一同构定理得到 |
| 构造 |
找"单位向量" ei,和拉格朗日插值同一个思路 |
| 应用 |
RSA 加速、Pohlig–Hellman、Håstad、RNS、NTT |