RNS(Residue Number System)介绍

目前RNS并没有一个正式的中文名,若有,请各位大佬指正。

简介

简而言之,剩余数系统就是将一个大一点的数 A ∈ Z Q A\in \mathcal{Z}_Q AZQ,用好几个小一点的数来表示: 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 a0Amodq0,a1Amodq1,,akAmodqk Q = q 0 ⋅ q 1 ⋯ q k Q=q_0\cdot q_1 \cdots q_k Q=q0q1qk。要求 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 AZQ,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=AmodqiZqilog2(qi)=63
假设我要做两个252位以内的大整数的加法或乘法,比如 A ∈ Z Q , B ∈ Z Q A\in \mathcal{Z}_Q,B\in \mathcal{Z}_Q AZQ,BZQ 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 251=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=4233+191719=6413157mod(1723=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=15735mod391
那我们将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 15735已经超出了 17 ∗ 23 17*23 1723了,如果考虑用多个模数来表示,而不是两个, 157 ∗ 35 157*35 15735就不会超过 17 ∗ 23 ∗ 27 ∗ 29 17*23*27*29 17232729,那么就可以得到正确的乘积值而不是模掉 391 391 391的值了。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐