快速傅立叶变换FFT与快速数论变换NTT

本文深入探讨了快速傅立叶变换(FFT)和快速数论变换(NTT)的原理及应用,FFT用于多项式卷积加速,时间复杂度从O(n^2)降低至O(n*logn),而NTT则针对循环多项式卷积,适用于密码学场景。文章详细解释了多项式系数表达式与点值表达式的转换,单位根与原根的概念,以及FFT和NTT的具体计算步骤。

FFT与NTT

快速傅立叶变换主要用于多项式卷积的加速。按照逐项相乘在相加的古法,多项式卷积的时间复杂度为$O(n^2)$,而利用FFT的多项式卷积的时间复杂度为O(n*logn)。快速数论变换NTT是在FFT的基础上推导出来的,主要用于循环多项式卷积。

在详细讲解FFT的内容之前,我们先主要回顾一下关于多项式和原根的相关内容:
多项式
系数表达式:若一个n次多项式A(x)=a0+a1x+…+anxnA(x)=a_0+a_1x+\ldots+a_nx^nA(x)=a0+a1x++anxn是由其系数(a0,a1,…,an)(a_0,a_1,\ldots,a_n)(a0,a1,,an)唯一确定,则这种方式被称为多项式的系数表达形式。有时也被写为如下形式:
A(x)=∑i=0naixiA(x)=\sum_{i=0}^n a_ix^iA(x)=i=0naixi
点值表达式:若将多项式定义域内的任意一个值x0x_0x0代入上面的系数表达式,则可以得到多项式的值y0y_0y0。根据多项式插值的思想,一个多项式能够被至少n+1个不同的点(xi,yi),i∈{0,n}(x_i,y_i),i\in \{0,n\}(xi,yi)i{0,n}所唯一确定,这种方式被称为多项式的点值表达式。

单位根与原根
单位根
若想将多项式的系数表达式转化为点值表达式,我们需要取n+1个不同的点来进行计算,由于复平面上的1的原根具有很好的性质,且可以满足我们的要求,故将其作为介绍目标。形式化定义为:wn=1w^n=1wn=1,记为wnw_nwn。对于任意一个正整数n,有n个n次单位根恰好均匀分布在复平面单位圆上。

有欧拉恒等式可得eπi+1=0e^{\pi i}+1=0eπi+1=0,即eπi=−1e^{\pi i}=-1eπi=1。则我们可以得到e2πi=1e^{2\pi i}=1e2πi=1。故我们令
wnk=e2kπin=(e2πin)kw_{n}^{k}=e^{\frac{2k\pi i}{n}}=(e^{\frac{2\pi i}{n}})^kwnk=en2kπi=(en2πi)k
具体例子如下图:

且关于单位根有下面三个重要的定理:
[1]wnk+n2=e2πin(k+n2)=e2πinkeπi=−e2πink=−wnkw_n^{k+\frac{n}{2}}=e^{\frac{2\pi i}{n}(k+\frac{n}{2})}=e^{\frac{2\pi i}{n}k}e^{\pi i}=-e^{\frac{2\pi i}{n}k}=-w_n^{k}wnk+2n=en2πi(k+2n)=en2πikeπi=en2πik=wnk
[2]w2n2k=wnkw_{2n}^{2k}=w_{n}^{k}w2n2k=wnk
[3]wn−k=1e2πin(−k)=e2πie2πin(−k)=e2πin(n−k)=wnn−kw_n^{-k}=1e^{\frac{2\pi i}{n}(-k)}=e^{2\pi i}e^{\frac{2\pi i}{n}(-k)}=e^{\frac{2\pi i}{n}(n-k)}=w_n^{n-k}wnk=1en2πi(k)=e2πien2πi(k)=en2πi(nk)=wnnk

原根
】若r,nr,nr,n是互素的整数,且r≠0,n>0r \neq0,n>0r=0,n>0,使得等式rx≡1(mod n)r^x\equiv 1(mod~n)rx1(mod n)成立的最小正整数xxx称为rrrnnn的阶,通常记为Ordn(r)Ord_n(r)Ordn(r)
欧拉函数】假设nnn是一个正整数,则它的欧拉函数就是小于nnn且与nnn互素正整数的个数,记为ϕ(n)\phi(n)ϕ(n)
原根】若r,nr,nr,n是互素的整数,且r≠0,n>0r \neq0,n>0r=0,n>0Ordn(r)=ϕ(n)Ord_n(r)=\phi(n)Ordn(r)=ϕ(n),则称rrr是模nnn的原根。

FFT
为了方便理解,假设我们的计算目标是C(x)=A(x)B(x),且多项式A(x)和B(x)分别是a,b。令n=a+b。
核心思想:利用拉格朗日插值的思想,实现多项式的系数表达式和点值表达式之间的转换。

主要工具
离散傅立叶变换:(DFT)
Xk=∑j=0n−1xje2πinkjX_k=\sum_{j=0}^{n-1}x_je^{\frac{2\pi i}{n}kj}Xk=j=0n1xjen2πikj
离散傅立叶逆变换:(IDFT)
xj=1n∑k=0n−1Xke−2πinjkx_j=\frac{1}{n}\sum_{k=0}^{n-1}X_ke^{-\frac{2\pi i}{n}jk}xj=n1k=0n1Xken2πijk

具体步骤
[1]:取n个单位根:wn0w_n^0wn0wn1w_n^1wn1,…,wnn−1w_n^{n-1}wnn1
[2]:将n个不同的单位根代入多项式A(x)A(x)A(x)B(x)B(x)B(x),即计算A(wnk)A(w_n^k)A(wnk)B(wnk)B(w_n^k)B(wnk)
[3]:计算C(wnk)=A(wnk)B(wnk)C(w_n^k)=A(w_n^k)B(w_n^k)C(wnk)=A(wnk)B(wnk)
[4]:令D(x)=C0+C1x1+…+Cn−1xn−1D(x)=C_0+C_1x^1+\ldots+C_{n-1}x^{n-1}D(x)=C0+C1x1++Cn1xn1,并计算D(wnk)D(w_n^k)D(wnk)
[5]:计算多项式C(x)C(x)C(x)的系数cj=1nD(wnn−j)c_j=\frac{1}{n}D(w_n^{n-j})cj=n1D(wnnj)

详细过程:由于第[1]、[3]步比较简单,我们直接跳过。
【2】计算A(wnk)A(w_n^k)A(wnk)B(wnk)B(w_n^k)B(wnk)
最直接将n个单位根代入多项式,但是这样的时间复杂度比较高。故这里我们采用分治的思想来进行加速。举个例子:
假设有一个多项式H(x)=h0+h1x1+h2x2+h3x3H(x)=h_0+h_1x^1+h_2x^2+h_3x^3H(x)=h0+h1x1+h2x2+h3x3,将该多项式写成按奇偶项拆分成两个子多项式的和,则有:
H(x)=(h0+h2x2)+(h1x1+h3x3)=(h0+h2x2)+x(h1+h3x2)H(x)=(h_0+h_2x^2)+(h_1x^1+h_3x^3)=(h_0+h_2x^2)+x(h_1+h_3x^2)H(x)=(h0+h2x2)+(h1x1+h3x3)=(h0+h2x2)+x(h1+h3x2)
H(x)=H1(x2)+xH2(x2)H(x)=H_1(x^2)+xH_2(x^2)H(x)=H1(x2)+xH2(x2)
若将这种思想用在计算A(wnk)A(w_n^k)A(wnk)B(wnk)B(w_n^k)B(wnk)上,我们以计算A(wnk)A(w_n^k)A(wnk)为例,0≤k<n20\leq k <\frac{n}{2}0k<2n,有:
当单位值在复平面单位圆的上部分时:
A(wnk)=A1(wn2k)+wnkA2(wn2k)=A1(wn2k)+wnkA2(wn2k)A(w_n^k)=A_1(w_n^{2k})+w_n^{k}A_2(w_n^{2k})=A_1(w_{\frac{n}{2}}^{k})+w_n^{k}A_2(w_{\frac{n}{2}}^{k})A(wnk)=A1(wn2k)+wnkA2(wn2k)=A1(w2nk)+wnkA2(w2nk)
当单位值在复平面单位圆的下部分时:
A(wnk+n2)=A1(wn2k+n)+wnk+n2A2(wn2k+n)=A1(wn2k)−wnkA2(wn2k)==A1(wn2k)−wnkA2(wn2k)A(w_n^{k+\frac{n}{2}})=A_1(w_n^{2k+n})+w_n^{k+\frac{n}{2}}A_2(w_n^{2k+n})=A_1(w_{n}^{2k})-w_n^{k}A_2(w_{n}^{2k})==A_1(w_{\frac{n}{2}}^{k})-w_n^{k}A_2(w_{\frac{n}{2}}^{k})A(wnk+2n)=A1(wn2k+n)+wnk+2nA2(wn2k+n)=A1(wn2k)wnkA2(wn2k)==A1(w2nk)wnkA2(w2nk)
由此可见,kkk只需取一半范围的值就可以得到整个范围的计算结果。事实上,多项式A1A_1A1A2A_2A2的计算可以利用分治的思想,这里明白即可,不再赘述。

【4】在计算C(wnk)=A(wnk)B(wnk)C(w_n^k)=A(w_n^k)B(w_n^k)C(wnk)=A(wnk)B(wnk)之后,后面的主要工作是利用IDFT将(wnk,C(wnk))(w_n^k,C(w_n^k))(wnk,C(wnk))转化为系数表达式,即求cjc_jcj。为了方便描述和形式化表达,我们这里引入一个n-1次多项式D(x)=C0+C1x1+…+Cn−1xn−1=∑k=0n−1CkxkD(x)=C_0+C_1x^1+\ldots+C_{n-1}x^{n-1}= \sum_{k=0}^{n-1}C_kx^kD(x)=C0+C1x1++Cn1xn1=k=0n1Ckxk,且Ck=C(wnk)C_k=C(w_n^k)Ck=C(wnk)已经在【3】步中计算完毕。
【5】由IDFT可得:
cj=1n∑k=0n−1Cke−2πinjk=1n∑k=0n−1Ck(wn−j)k=1n∑k=0n−1Ck(wnn−j)k=1nD(wnn−j)c_j=\frac{1}{n}\sum_{k=0}^{n-1}C_ke^{-\frac{2\pi i}{n}jk}=\frac{1}{n}\sum_{k=0}^{n-1}C_k(w_n^{-j})^k=\frac{1}{n}\sum_{k=0}^{n-1}C_k(w_n^{n-j})^k=\frac{1}{n}D(w_n^{n-j})cj=n1k=0n1Cken2πijk=n1k=0n1Ck(wnj)k=n1k=0n1Ck(wnnj)k=n1D(wnnj)
若将上述的过程中的D(x)D(x)D(x)看作一个系数已知的多项式,其求cjc_jcj的过程也可以使用分治的思想进行加速。

注意:关于DFT和IDFT的证明可以直接在网上搜索,比较简单,不进行叙述。

NTT
由于在密码学中,多项式的卷积并不是像FFT中的一样,它们往往是循环多项式的卷积,即在多项式的卷积后要模上一个大素数。故我们需要对FFT进行相应的改造,即NTT。

需要说明的是,在FFT中我们选取的是复平面的单位根,而在NTT中我们使用的是相应的原根。这是因为假设当ppp是一个奇素数,ggg是模nnn的原根,当0<i,j<p0<i,j<p0<i,j<p,有gi≡gj(mod p)g^i\equiv g^j(mod~p)gigj(mod p),当且仅当i=ji=ji=j。该性质与单位根十分类似,但由于在NTT中我们所取的不同根的个数是与多项式的次数是相关的,而上面i,ji,ji,j的最大值只能取到p−1p-1p1,即只能取ppp个不同的值,故我们要对原根继续进行改造:

给定模数M=c∗2k+1M=c*2^k+1M=c2k+1(这是满足密码学中多项式循环卷积的模数形式的)及其原根ggg以及正整数n=2ln=2^ln=2l(通常是多项式的次数),且l≤kl\leq klk,则有:
M−1=c∗2kM-1=c*2^kM1=c2k
M−1n=c∗2k2l=c∗2k−l\frac{M-1}{n}=\frac{c*2^k}{2^l}=c*2^{k-l}nM1=2lc2k=c2kl
若令a=gM−1na=g^{\frac{M-1}{n}}a=gnM1,则刚好能够构造出nnnmod Mmod~Mmod M不同值,满足ai≡(gM−1n)i≡(gM−1)in≡1(mod M)a^i\equiv (g^{\frac{M-1}{n}})^i \equiv (g^{M-1})^{\frac{i}{n}}\equiv 1(mod~M)ai(gnM1)i(gM1)ni1(mod M)
下面是原根满足的两个性质:
[1]:an≡1(mod M)a^n\equiv 1(mod~M)an1(mod M)
[2]:an2≡−1(mod M)a^{\frac{n}{2}}\equiv -1(mod~M)a2n1(mod M)

主要工具:对于次数为N=2lN=2^lN=2l(不足2的整数次幂的可以通过补0来扩张)且系数元素均小于MMM的多项式系数序列x(n)x(n)x(n),nnn表示第n个系数,有相应的快速数论变换:
快速数论变换:(NTT)
X(m)≡∑n=0N−1x(n)amn     mod MX(m)\equiv \sum_{n=0}^{N-1}x(n)a^{mn} ~~~~~mod~MX(m)n=0N1x(n)amn     mod M
快速数论逆变换:(INTT)
x(n)=1N∑m=0N−1X(m)a−mn     mod Mx(n)=\frac{1}{N}\sum_{m=0}^{N-1}X(m)a^{-mn} ~~~~~mod~Mx(n)=N1m=0N1X(m)amn     mod M

蝶形操作:在FFT中,将多项式的系数表达式转化为点值表达式的过程中,我们主要采取分治的思想进行加速。而在NTT中,我们采用的是迭代算法——碟形操作。我们采用数学归纳法来进行说明,具体过程如下:
(1)当N=22N=2^2N=22时,则多项式系数为x(0),x(1),x(2),x(3)x(0),x(1),x(2),x(3)x(0),x(1),x(2),x(3),同时m=0,1,2,3m=0,1,2,3m=0,1,2,3。NTT可以写为下面的形式:
X(m)≡∑n=03x(n)amn     mod M   , m=0,1,2,3X(m)\equiv \sum_{n=0}^{3}x(n)a^{mn} ~~~~~mod~M~~~,~m=0,1,2,3X(m)n=03x(n)amn     mod M   , m=0,1,2,3
而将m,nm,nm,n写成二进制表达式为:
m=2m1+m0=(m1,m0)2m=2m_1+m_0=(m_1,m_0)_2m=2m1+m0=(m1,m0)2
n=2n1+n0=(n1,n0)2n=2n_1+n_0=(n_1,n_0)_2n=2n1+n0=(n1,n0)2
所以NTT又可改写如下:
在这里插入图片描述
上式成立,因为aN≡1(mod M)a^N\equiv 1(mod~M)aN1(mod M),且N=22N=2^2N=22,则
a22m1n1≡1(mod M)a^{2^2m_1n_1}\equiv 1(mod~M)a22m1n11(mod M)
然后,令x(n1,n0)=x0(n1,n0)x(n_1,n_0)=x_0(n_1,n_0)x(n1,n0)=x0(n1,n0),且
x1(m0,n0)=∑n1=01x0(n1,n0)a2n1m0=x0(0,n0)+x0(1,n0)a2m0    (mod M)x_1(m_0,n_0)=\sum_{n_1=0}^{1}x_0(n_1,n_0)a^{2n_1m_0}=x_0(0,n_0)+x_0(1,n_0)a^{2m_0}~~~~(mod ~M)x1(m0,n0)=n1=01x0(n1,n0)a2n1m0=x0(0,n0)+x0(1,n0)a2m0    (mod M)
则,遍历所有m0,n0m_0,n_0m0,n0的值,我们可得到:
在这里插入图片描述
相应的蝶形操作如为:
在这里插入图片描述
x1(m0,n0)x_1(m_0,n_0)x1(m0,n0)代入到原式中有:
x2(m0,m1)=∑n0=01x1(m0,n0)a(2m1+m0)n0=x1(m0,0)+x1(m0,1)a2m1+m0    (mod M)x_2(m_0,m_1)=\sum_{n_0=0}^{1}x_1(m_0,n_0)a^{(2m_1+m_0)n_0}=x_1(m_0,0)+x_1(m_0,1)a^{2m_1+m_0}~~~~(mod ~M)x2(m0,m1)=n0=01x1(m0,n0)a(2m1+m0)n0=x1(m0,0)+x1(m0,1)a2m1+m0    (mod M)
进一步有:
X(m1,m0)=x2(m0,m1)    (mod M)X(m_1,m_0)=x_2(m_0,m_1)~~~~(mod ~M)X(m1,m0)=x2(m0,m1)    (mod M)
相应的蝶形操作如下图:
在这里插入图片描述
(2)当N=23N=2^3N=23时,同理可得:
在这里插入图片描述
将红色部分提取出来有:
x1(m0,n1,n0)=x0(0,n1,n0)+x0(1,n1,n0)a4m0    (mod M)x_1(m_0,n_1,n_0)=x_0(0,n_1,n_0)+x_0(1,n_1,n_0)a^{4m_0}~~~~(mod ~M)x1(m0,n1,n0)=x0(0,n1,n0)+x0(1,n1,n0)a4m0    (mod M)
遍历m0,n1,n0m_0,n_1,n_0m0,n1,n0的值,我们可以得到下图的蝶形操作图:
在这里插入图片描述
x1(m0,n1,n0)x_1(m_0,n_1,n_0)x1(m0,n1,n0)代入到原式可得:
X(m2,m1,m0)=∑n0=01(∑n1=01x1(m0,n1,n0)a(22m1+m0)n1)a(22m2+2m1+m0)n0    (mod M)X(m_2,m_1,m_0)=\sum_{n_0=0}^{1}(\sum_{n_1=0}^{1}x_1(m_0,n_1,n_0)a^{(2^2m_1+m_0)n_1})a^{(2^2m_2+2m_1+m_0)n_0}~~~~(mod ~M)X(m2,m1,m0)=n0=01(n1=01x1(m0,n1,n0)a(22m1+m0)n1)a(22m2+2m1+m0)n0    (mod M)
将括号内的式子提取出来,并令:
x2(m0,m1,n0)=∑n1=01x1(m0,n1,n0)a(22m1+m0)n1=x1(m0,0,n0)+x1(m0,1,n0)a4m1+2m0    (mod M)x_2(m_0,m_1,n_0)=\sum_{n_1=0}^{1}x_1(m_0,n_1,n_0)a^{(2^2m_1+m_0)n_1}=x_1(m_0,0,n_0)+x_1(m_0,1,n_0)a^{4m_1+2m_0}~~~~(mod ~M)x2(m0,m1,n0)=n1=01x1(m0,n1,n0)a(22m1+m0)n1=x1(m0,0,n0)+x1(m0,1,n0)a4m1+2m0    (mod M)
遍历m0,m1,n0m_0,m_1,n_0m0,m1,n0的值,我们可以得到下图的蝶形操作图:
在这里插入图片描述
再将x2(m0,m1,n0)x_2(m_0,m_1,n_0)x2(m0,m1,n0)代回到原式,我们可以得到:
x3(m0,m1,m2)=∑n0=01x2(m0,m1,n0)a(22m2+2m1+m0)n0=x2(m0,m1,0)+x2(m0,m1,1)a4m2+2m1+m0    (mod M)x_3(m_0,m_1,m_2)=\sum_{n_0=0}^{1}x_2(m_0,m_1,n_0)a^{(2^2m_2+2m_1+m_0)n_0}=x_2(m_0,m_1,0)+x_2(m_0,m_1,1)a^{4m_2+2m_1+m_0}~~~~(mod ~M)x3(m0,m1,m2)=n0=01x2(m0,m1,n0)a(22m2+2m1+m0)n0=x2(m0,m1,0)+x2(m0,m1,1)a4m2+2m1+m0    (mod M)
同样遍历m0,m1,m2m_0,m_1,m_2m0,m1,m2的值,我们可以得到下图的蝶形操作图:
在这里插入图片描述
(3)根据数学归纳法,我们可以得到N=2lN=2^lN=2l的情况:
NTT中的正整数序列m,nm,nm,n可以写为二进制形式:
在这里插入图片描述
在这里插入图片描述
amna^{mn}amn可以计算为:
在这里插入图片描述
进而NTT可以写为下面的形式:
在这里插入图片描述
利用(1)、(2)中的思想,将红色内容提取出来有:
在这里插入图片描述
根据数学归纳法,我们可以得到xr(m0,…,mr−1,nl−r−1,…,n0)x_r(m_0,\ldots ,m_{r-1},n_{l-r-1},\ldots,n_0)xr(m0,,mr1,nlr1,,n0)的一般递推式:
在这里插入图片描述
最后,就可以得到:
在这里插入图片描述
上面内容就是NTT的一般化流程,而每一次红色部分内容的提出本质上就是蝶形操作的一轮。下面就以rrr轮为例,详细说明蝶形操作的具体流程,即上面的公式(2.7)。在上面的公式中,我们可以容易地发现xrx_rxrxr−1x_{r-1}xr1中除了nl−rn_{l-r}nlr不同外,其他部分都一样,故为了方面描述,我们可以简写为:
在这里插入图片描述
公式(2.7)可以写为:
在这里插入图片描述
因为mr−1m_{r-1}mr1nl−rn_{l-r}nlr的取值为0和1,故对应的蝶形操作为:
在这里插入图片描述
其中,关于ppp有下面的结论:
在这里插入图片描述
证明过程如下,已知a2l−1=−a0a^{2^{l-1}}=-a^0a2l1=a0
[1]当r=1r=1r=1
在这里插入图片描述
[2]当r>1r>1r>1
在这里插入图片描述
注意:以上部分就是NTT具体数学推导流程,而INTT的思想与NTT完全一致,除了需要在最后的结果上乘上1N=12l\frac{1}{N}=\frac{1}{2^{l}}N1=2l1。而关于NTT在实现方面是有许多改进和注意的地方,这是后续的工作内容,这里就先不叙述了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值