RNS(Residue Number System)介绍
目前RNS并没有一个正式的中文名,若有,请各位大佬指正。
简介
简而言之,剩余数系统就是将一个大一点的数 A ∈ Z Q A\in \mathcal{Z}_Q A∈ZQ,用好几个小一点的数来表示: A ← { a 0 , a 1 , . . . , a k } ∈ Z q i k , A\gets \{a_0,a_1,...,a_k \}\in \mathcal{Z}_{q_i}^k, A←{
a0,a1,...,ak}∈Zqik,
其中 a 0 ≡ A m o d q 0 , a 1 ≡ A m o d q 1 , ⋯ , a k ≡ A m o d q k a_0 \equiv A\bmod q_0,a_1\equiv A\bmod q_1,\cdots,a_k \equiv A \bmod q_k a0≡Amodq0,a1≡Amodq1,⋯,ak≡Amodqk。 Q = q 0 ⋅ q 1 ⋯ q k Q=q_0\cdot q_1 \cdots q_k Q=q0⋅q1⋯qk。要求 i ≠ j , g c d ( q i , q j ) = 1 i\ne j,gcd(q_i,q_j)=1 i=j,gcd(qi,qj)=1,即 q i q_i qi之间两两互素。
应用
剩余数系统目前我所知道的应用是用来进行大整数表示以及运算,比如目前的计算机系统中,int类型的数据结构是32/64比特的,那么假如我有一个235比特的数字 A ∈ Z Q , log 2 ( Q ) ≈ 235 , e . g . log 2 ( Q ) < 252 A\in \mathcal{Z}_Q,\log_2(Q)\approx 235,e.g. \ \log_2(Q)<252 A∈ZQ,log2(Q)≈235,e.g. log2(Q)<252,我就可以用4个63比特的int类型数据来表示这个大整数 a 0 , a 1 , a 2 , a 3 a_0,a_1,a_2,a_3 a0,a1,a2,a3。 a i = A m o d q i ∈ Z q i log 2 ( q i ) = 63 a_i= A\bmod q_i \in \mathcal{Z}_{q_i} \log_2(q_i)=63 ai=Amodqi∈Zqilog2(qi)=63。
假设我要做两个252位以内的大整数的加法或乘法,比如 A ∈ Z Q , B ∈ Z Q A\in \mathcal{Z}_Q,B\in \mathcal{Z}_Q A∈ZQ,B∈ZQ, C = A + B C=A+B C=A+B就可以表示为 c i = a i + b i c_i=a_i+b_i ci=ai+bi, C = A × B C=A\times B C=A×B也就可以表示为 c i = a i × b i c_i=a_i\times b_i ci=ai×bi,而如果采用中国剩余定理对 c i c_i ci进行恢复的话,就可以得到正确的结果 C C C。就我所知,算上拆分和CRT恢复的时间,也比直接在大整数运算上快。所以可以用RNS在计算机上来加速大整数的运算。
举例
假如有一个数157,而我们的计算机居然只支持表示5比特的数(假如),也就是他uint类型的UINT_MAX为 2 5 − 1 = 31 2^5-1=31 25−1=31。那我们找到了这样两个互素的数17,23,那就可以将157表示为 { 4 , 19 } \{4,19\} {
4,19},其中 4 = 157 m o d 17 , 19 = 157 m o d 23 4=157 \bmod 17, 19 = 157 \bmod 23 4=157mod17,19=157mod23。
通过中国剩余定理,我们可以来恢复一下原数,已知:
{ 4 = x m o d 17 19 = x m o d 23 \left\{ \begin{aligned} 4 = x\bmod 17\\ 19 = x\bmod 23 \end{aligned} \right. {
4=xmod1719=xmod23
那么可以求
x = 4 ∗ 23 ∗ 3 + 19 ∗ 17 ∗ 19 = 6413 ≡ 157 m o d ( 17 ∗ 23 = 391 ) x = 4*23*3+19*17*19=6413\equiv 157 \bmod(17*23=391) x=4∗23∗3+19∗17∗19=6413≡157mod(17∗23=391)
其中19是17模23的逆元,3是23模17的逆元。
那假如我们要计算 157 + 35 = 192 m o d 391 157+35=192 \bmod 391 157+35=192mod391,以及 21 = 157 ∗ 35 m o d 391 21=157*35 \bmod 391 21=157∗35mod391
那我们将35也进行RNS表达为 { 1 , 12 } \{1,12\} {
1,12},
5 = 1 + 4 m o d 17 , 8 = 19 + 12 m o d 23 4 = 1 × 4 m o d 17 , 21 = 19 × 12 m o d 23 5=1+4 \bmod 17, 8=19+12 \bmod 23\\ 4=1\times 4 \bmod 17, 21 = 19\times12 \bmod 23 5=1+4mod17,8=19+12mod234=1×4mod17,21=19×12mod23
我们分别对 { 5 , 8 } \{5,8\} {
5,8}, { 4 , 21 } \{4,21\} {
4,21}进行CRT恢复,神奇的事情发生啦,恢复的结果正好为 192 192 192和 21 21 21。
这里举的例子可能不太恰当,因为 157 ∗ 35 157*35 157∗35已经超出了 17 ∗ 23 17*23 17∗23了,如果考虑用多个模数来表示,而不是两个, 157 ∗ 35 157*35 157∗35就不会超过 17 ∗ 23 ∗ 27 ∗ 29 17*23*27*29 17∗23∗27∗29,那么就可以得到正确的乘积值而不是模掉 391 391 391的值了。