大数相乘是公钥密码学中一个非常关键的运算,公钥密码学中往往需要进行大量的大整数相乘运算,它的性能影响着许多公钥密码算法的性能[1]。
最近在阅读格上后量子密钥交换相关论文的过程中,我发现在基于RLWE(Ring learning with errors, 环上容错学习)问题的格密钥交换方案中会进行多项式相乘运算,而其中往往会使用到NTT快速数论变换算法,快速数论变换(NTT)是快速傅里叶变换(FFT)在数论基础上的实现,为了弄懂其中的原理,我对FFT快速傅里叶变换以及NTT快速数论变换的相关知识进行了学习。
在学习FFT以及NTT之前,我们应该先对多项式有一个基本的了解。
多项式有两种基本的表示方法,一种是系数表示,一种是点值表示;对于一个已知的多项式 A ( x ) = a 0 + a 1 x + a 2 x 2 + ⋯ + a n − 1 x n − 1 A(x)=a_0+a_1 x+a_2 x^2+⋯+a_{n-1} x^{n-1} A(x)=a0+a1x+a2x2+⋯+an−1xn−1,
现在有两个多项式 A ( x ) , B ( x ) A(x),B(x) A(x),B(x),两个多项式相乘结果为 C ( x ) C(x) C(x),这个就叫多项式的乘法,多项式乘法的结果又可以叫做这两个多项式的卷积。某种程度上,FFT就是在解决多项式乘法的问题。
快速傅里叶变换(英语:Fast Fourier Transform, FFT),是快速计算串行的离散傅里叶变换(DFT)或其逆变换的方法[2]。直接暴力求解两个多项式的卷积,复杂度是 O ( n 2 ) O(n^2) O(n2)的,而FFT可以将这一过程的复杂度降到 O ( n l o g n ) O(n logn) O(nlogn),具体过程分为两个过程:离散傅里叶变换(DFT)和离散傅里叶逆变换(IDFT)。通俗地来说,多项式由系数表示法转为点值表示法的过程,就是DFT,多项式由点值表示法转化为系数表示法的过程,就是IDFT;而FFT就是通过取某些特殊的x的点值来加速DFT和IDFT的过程[3]。
FFT通过找到一组特殊的点代入到多项式中,从而快速计算出一组 A ( x ) , B ( x ) A(x),B(x) A(x),B(x)的点值,而这组特殊点就是复数中的单位根。在复平面上,一个复数可以用一个向量表示,所有在单位圆上的向量都可以称为一个单位根。考虑将这个单位圆从 x x x轴开始等分成 n n n份,其中得到的这 n n n个单位根,就是 n n n次单位根,其中的第 k k k个可以记为 ω n k ω_n^k ωnk,且 ω n 0 = 1 ω_n^0=1 ωn0=1。
众所周知, e i θ = c o s θ + i ⋅ s i n θ e^iθ=cosθ+i·sinθ eiθ=cosθ+i⋅sinθ,所以
ω n k = c o s ( 2 π ⋅ k n ) + i ⋅ s i n ( 2 π ⋅ k n ) = e 2 π ⋅ k n i ω_n^k=cos(2π·\frac{k}{n})+i·sin(2π·\frac{k}{n})=e^{2π·\frac{k}{n} i} ωnk=cos(2π⋅nk)+i⋅sin(2π⋅nk)=e2π⋅nki
显然,单位根具有以下一些性质:
性质一: ω n k = ω 2 n 2 k ω_n^k=ω_{2n}^{2k} ωnk=ω2n2k
性质二: ω n k + n 2 = − ω n k ω_n^{k+\frac{n}{2}}=-ω_n^k ωnk+2n=−ωnk
性质三: ω n k ⋅ ω n l = ω n k + l ω_n^k·ω_n^l=ω_n^{k+l} ωnk⋅ωnl=ωnk+l
接下来我们来看FFT的具体过程是如何实现的。
考虑一个 n = 2 b n=2^b n=2b项的多项式 A ( x ) A(x) A(x)系数表示为 ( a 0 , a 1 , a 2 , … , a n − 1 ) (a_0,a_1,a_2,…,a_{n-1}) (a0,a1,a2,…,an−1),现在我们代入一组单位根 ( ω n 0 , ω n 1 , ω n 2 , … , ω n n − 1 ) (ω_n^0,ω_n^1,ω_n^2,…,ω_n^{n-1}) (ωn0,ωn1,ωn2,…,ωnn−1),这一过程叫做DFT。FFT之所以快,是因为在DFT计算过程中采用了分治的思想,将多项式分为奇次项和偶次项来处理:
A ( x ) = ( a 0 + a 2 x 2 + ⋯ + a n − 2 x n − 2 ) + ( a 1 x + a 3 x 3 + ⋯ + a n − 1 x n − 1 ) = ( a 0 + a 2 x 2 + ⋯ + a n − 2 x n − 2 ) + x ( a 1 + a 3 x 2 + ⋯ + a n − 1 x n − 2 ) A(x)=(a_0+a_2 x^2+⋯+a_{n-2}x^{n-2})+(a_1 x+a_3 x^3+⋯+a_{n-1}x^{n-1})=(a_0+a_2 x^2+⋯+a_{n-2}x^{n-2})+x(a_1+a_3 x^2+⋯+a_{n-1}x^{n-2}) A(x)=(a0+a2x2+⋯+an−2xn−2)+(a1x+a3x3+⋯+an−1xn−1)=(a0+a2x2+⋯+an−2xn−2)+x(a1+a3x2+⋯+an−1xn−2)
然后我们可以建立新的方程:
A 0 ( x ) = a 0 + a 2 x 1 + ⋯ + a n − 2 x n − 2 2 A0(x)=a_0+a_2 x^1+⋯+a_{n-2}x^{\frac{n-2}{2}} A0(x)=a0+a2x1+⋯+an−2x2n−2
A 1 ( x ) = a 1 + a 3 x 1 + ⋯ + a n − 1 x n − 2 2 A1(x)=a_1+a_3 x^1+⋯+a_{n-1}x^{\frac{n-2}{2}} A1(x)=a1+a3x1+⋯+an−1x2n−2
那么, A ( x ) = A 0 ( x 2 ) + x ⋅ A 1 ( x 2 ) A(x)=A0(x^2 )+x·A1(x^2 ) A(x)=A0(x2)+x⋅A1(x2),并且 A 0 ( x ) A0(x) A0(x)和 A 1 ( x ) A1(x) A1(x)还可以递归地计算下去。
除此之外,还可以利用前面讨论的单位根的性质来降低计算量,例如 0 ≤ k ≤ n 2 0≤k≤\frac{n}{2} 0≤k≤2n:
A ( ω n k ) = A 0 ( ( ω n k ) 2 ) + ω n k ⋅ A 1 ( ( ω n k ) 2 ) = A 0 ( ω n 2 k ) + ω n k ⋅ A 1 ( ω n 2 k ) = A 0 ( ω n 2 k ) + ω n k ⋅ A 1 ( ω n 2 k ) A(ω_n^k )=A0((ω_n^k )^2 )+ω_n^k·A1((ω_n^k )^2 )=A0(ω_n^{2k})+ω_n^k·A1(ω_n^{2k} )=A0(ω_{\frac{n}{2}}^k)+ω_n^k·A1(ω_{\frac{n}{2}}^k ) A(ωnk)=A0((ωnk)2)+ωnk⋅A1((ωnk)2)=A0(ωn2k)+ωnk⋅A1(ωn2k)=A0(ω2nk)+ωnk⋅A1(ω2nk)
A ( ω n k + n 2 ) = A 0 ( ( ω n k + n 2 ) 2 ) + ω n k + n 2 ⋅ A 1 ( ( ω n k + n 2 ) 2 ) = A 0 ( ω n 2 k + n ) + ω n k + n 2 ⋅ A 1 ( ω n 2 k + n ) = A 0 ( ω n 2 k ) − ω n k ⋅ A 1 ( ω n 2 k ) = A 0 ( ω n 2 k ) − ω n k ⋅ A 1 ( ω n 2 k ) A(ω_n^{k+\frac{n}{2})}=A0({(ω_n^{k+\frac{n}{2}} )}^2)+ω_n^{k+\frac{n}{2}}·A1((ω_n^{k+\frac{n}{2}})^2 )=A0(ω_n^{2k+n})+ω_n^{k+\frac{n}{2}}·A1(ω_n^{2k+n})=A0(ω_n^{2k})-ω_n^k·A1(ω_n^{2k} )=A0(ω_{\frac{n}{2}}^k )-ω_n^k·A1(ω_{\frac{n}{2}}^k ) A(ωnk+2n)=A0((ωnk+2n)2)+ωnk+2n⋅A1((ωnk+2n)2)=A0(ωn2k+n)+ωnk+2n⋅A1(ωn2k+n)=A0(ωn2k)−ωnk⋅A1(ωn2k)=A0(ω2nk)−ωnk⋅A1(ω2nk)
这样,仅仅计算 k k k一半的取值范围就可以得到其整个取值范围的结果[4]。
这一步我们要做的是将上一步DFT中得到的点值转换为系数,假设DFT得到的点值为:
( x 0 , x 1 , x 2 , … , x n − 1 ) (x_0,x_1,x_2,…,x_{n-1}) (x0,x1,x2,…,xn−1)
( y 0 , y 1 , y 2 , … , y n − 1 ) (y_0,y_1,y_2,…,y_{n-1}) (y0,y1,y2,…,yn−1)
那么,我们把单位复根代入多项式后可以得到:
[ y 0 y 1 y 2 y 3 ⋯ y n − 1 ] = [ 1 1 1 1 ⋯ 1 1 ω n 1 ω n 2 ω n 3 ⋯ ω n n − 1 1 ω n 2 ω n 4 ω n 6 ⋯ ω n 2 ( n − 1 ) 1 ω n 3 ω n 6 ω n 9 ⋯ ω n 3 ( n − 1 ) ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ 1 ω n n − 1 ω n 2 ( n − 1 ) ω n 3 ( n − 1 ) ⋯ ω n ( n − 1 ) 2 ] [ a 0 a 1 a 2 a 3 ⋯ a n − 1 ] \left[\begin{matrix}y_0\\y_1\\y_2\\y_3\\\cdots\\y_{n-1}\\\end{matrix}\right]=\left[\begin{matrix}1&1&1&1&\cdots&1\\1&\omega_n^1&\omega_n^2&\omega_n^3&\cdots&\omega_n^{n-1}\\1&\omega_n^2&\omega_n^4&\omega_n^6&\cdots&\omega_n^{2(n-1)}\\1&\omega_n^3&\omega_n^6&\omega_n^9&\cdots&\omega_n^{3(n-1)}\\\cdots&\cdots&\cdots&\cdots&\cdots&\cdots\\1&\omega_n^{n-1}&\omega_n^{2(n-1)}&\omega_n^{3(n-1)}&\cdots&\omega_n^{ {(n-1)}^2}\\\end{matrix}\right]\left[\begin{matrix}a_0\\a_1\\a_2\\a_3\\\cdots\\a_{n-1}\\\end{matrix}\right] ⎣⎢⎢⎢⎢⎢⎢⎡y0y1y2y3⋯yn−1⎦⎥⎥⎥⎥⎥⎥⎤=⎣⎢⎢⎢⎢⎢⎢⎢⎡1111⋯11ωn1ωn2ωn3⋯ωnn−11ωn2ωn4ωn6⋯ωn2(n−1)1ωn3ωn6ωn9⋯ωn3(n−1)⋯⋯⋯⋯⋯⋯1ωnn−1ωn2(n−1)ωn3(n−1)⋯ωn(n−1)2⎦⎥⎥⎥⎥⎥⎥⎥⎤⎣⎢⎢⎢⎢⎢⎢⎡a0a1a2a3⋯an−1⎦⎥⎥⎥⎥⎥⎥⎤
我们只需要在等式两边同时左乘这个大矩阵的逆矩阵,就可以计算出所有的系数 ( a 0 , a 1 , a 2 , … , a n − 1 ) (a_0,a_1,a_2,…,a_{n-1}) (a0,a1,a2,…,an−1),而这个矩阵有一个特殊的性质,也就是矩阵的每一项取倒数再除以 n n n,就能得到原矩阵的逆矩阵(具体推导过程略)。
FFT虽然提高了运算速度,但是因为是浮点数运算,所以仍然存在精度上的问题,为此引入了NTT即快速数论变换,它解决的是多项式乘法带模数的情况。
在FFT中,使用的特殊点是复数中的单位根,而在NTT中,使用的这组特殊点则是原根。
在介绍原根之前,我们先了解一下数论中阶的概念。 gimodp,0≤i<p
设 r , n r,n r,n是互素的整数, r ≠ 0 , n > 0 r≠0,n>0 r=0,n>0,使得 r x ≡ 1 ( m o d n ) r^x≡1({mod} n) rx≡1(modn)成立的最小正整数 x x x称为 r r r模 n n n的阶,记为 o r d n r ord_n r ordnr(如 o r d 7 2 = 3 ord_7 2=3 ord72=3)。
然后是欧拉函数:设有一个正整数 n n n,则欧拉函数返回小于 n n n并且与 n n n互素的正整数的个数,记作 φ ( n ) φ(n) φ(n)。
如果 g , n g,n g,n是互素的正整数,当 o r d n g = φ ( n ) ord_n g=φ(n) ordng=φ(n)时,称 g g g是模 n n n的原根,或者 n n n的原根[5]。对于质数 p p p,也就是说 g i m o d p , 0 ≤ i < p g^i mod p,0≤i
我们定义原根为:对于一个 n − 1 n-1 n−1次多项式,
g n k = ( g p − 1 n ) k m o d p , 0 ≤ k ≤ n − 1. g_n^k={(g^{\frac{p-1}{n}})}^k mod p,0≤k≤n-1. gnk=(gnp−1)kmodp,0≤k≤n−1.
在 FFT 中,我们总共用到了单位复根的这些性质:
而原根是否具有这些性质呢?
Ring-LWE和Modular-LWE问题在密码学理论和应用中是被非常广泛地使用的,而其中最为广泛使用的环则是环 R q = Z q [ x ] / Φ m ( x ) R_q=\mathbb{Z}_q\left[x\right]/\Phi_m(x) Rq=Zq[x]/Φm(x)。因此,如何在这个环上快速进行乘法便成了基于Ring/Modular-LWE的密码算法实现中的重要问题[6]。为了提高密码算法实现中的效率,掌握好NTT的知识是十分有必要的。
[1]毛庆,李顺东.快速傅里叶变换乘法的性能研究[J].计算机工程与应用,2014,50(19):16-19.
[2]维基百科编者. 快速傅里叶变换[G/OL]. 维基百科, 2020(20201010)[2020-10-10]. https://zh.wikipedia.org/w/index.php?title=%E5%BF%AB%E9%80%9F%E5%82%85%E9%87%8C%E5%8F%B6%E5%8F%98%E6%8D%A2&oldid=62301078.
[3]月下桃子树. FFT(快速傅里叶变换)0基础详解!附NTT(ACM/OI).[EB/OL]https://zhuanlan.zhihu.com/p/40505277
[4]永远在你身后. 快速傅里叶变换(FFT)求解多项式乘法.[EB/OL]https://zhuanlan.zhihu.com/p/76622485
[5]永远在你身后. 快速数论变换(NTT)及蝴蝶操作构造详解.[EB/OL]https://zhuanlan.zhihu.com/p/80297169
[6]刘炆灵. 数论变换简介.[EB/OL] http://crypto.sjtu.edu.cn:3000/7JvfLxTRQWuvKSSQeTHx7A