参考文献:
- [CT65] Cooley J W, Tukey J W. An algorithm for the machine calculation of complex Fourier series[J]. Mathematics of computation, 1965, 19(90): 297-301.
- [Shoup95] Shoup V. A new polynomial factorization algorithm and its implementation[J]. Journal of Symbolic Computation, 1995, 20(4): 363-397.
- [CHKKS18] Cheon J H, Han K, Kim A, et al. Bootstrapping for approximate homomorphic encryption[C]//Advances in Cryptology–EUROCRYPT 2018: 37th Annual International Conference on the Theory and Applications of Cryptographic Techniques, Tel Aviv, Israel, April 29-May 3, 2018 Proceedings, Part I 37. Springer International Publishing, 2018: 360-384.
- [CHH18] Cheon J H, Han K, Hhan M. Faster homomorphic discrete fourier transforms and improved fhe bootstrapping[J]. Cryptology ePrint Archive, 2018.
- Nussbaumer Transform 以及 Amortized FHEW bootstrapping
- Chimera:混合的 RLWE-FHE 方案
- 快速乘法技巧:Karatsuba, Toom, Good, Schonhage, Strassen, Nussbaumer
- Paterson-Stockmeyer 多项式求值算法
文章目录
- Baby-Step Giant-Step
- Shoup95
- CT65
- CHKKS18
- Faster Homomorphic DFT
- Sparse-Diagonal matrix Factorization
- Radix-r
- Hybrid method
- Result
Baby-Step Giant-Step
Shoup95
文章 [Shoup95] 研究并实现了 BSGS factoring method,用于将单变元多项式分解为不可约因子。其中使用了 CRT 和 FFT 来表示多项式(比 GHS12 的 Doube-CRT 更早) ,并且实现了多项式的快速乘法、除法、逆元、平方、GCD 等等运算。
多项式分解可以分为三步,
- square-free factorization:将多项式分解为 f = ∏ i f i f = \prod_i f_i f=∏ifi,其中的 f i f_i fi 是平方自由的
- distinct-degree factorization:将平方自由多项式分解为 f i = ∏ j f i , j f_i = \prod_j f_{i,j} fi=∏jfi,j,其中的 f i , j f_{i,j} fi,j 是一些度数都为 j j j 的不可约因式的乘积
- equal-degree factorization:将不可约因式都是相同度数的平方自由多项式 f i , j f_{i,j} fi,j,分解为这些不可约多项式
主要步骤集中在 step 2,[Shoup95] 观察到事实:对于任意的非负整数 a , b ∈ Z + a,b \in \mathbb Z^+ a,b∈Z+,多项式 h a , b ( x ) = x p a − x p b ∈ G F ( p ) [ x ] h_{a,b}(x) = x^{p^a} - x^{p^b} \in GF(p)[x] ha,b(x)=xpa−xpb∈GF(p)[x] 以所有的满足 deg f ∣ ( a − b ) \deg f|(a-b) degf∣(a−b) 的不可约多项式 f f f 为因式。
对于 deg f ≤ n \deg f \le n degf≤n 的平方自由多项式,它的真因子度数不超过 n / 2 n/2 n/2,我们令 f d , 1 ≤ d ≤ n f_d,1 \le d \le n fd,1≤d≤n 是它的全部 d d d 次不可约因子的乘积。我们可以枚举全部的 1 ≤ a − b ≤ n 1\le a-b\le n 1≤a−b≤n,计算出 h a , b ( x ) h_{a,b}(x) ha,b(x),再计算 gcd ( h a , b , f ) \gcd(h_{a,b},f) gcd(ha,b,f) 从而获得这些 f d f_d fd
[Shoup95] 使用 BSGS 算法来计算这些 h a , b h_{a,b} ha,b,设置真因子的度数上界 B B B,将它分为 B = l ⋅ m B=l \cdot m B=l⋅m,Baby-Step 就是 { i : 1 ≤ i ≤ l } \{i:1 \le i \le l\} {i:1≤i≤l},Giant-Step 就是 { l ⋅ j : 1 ≤ j ≤ m } \{l \cdot j:1 \le j \le m\} {l⋅j:1≤j≤m},
然而,如果简单地直接计算 h i , H j h_i,H_j hi,Hj,上述算法依旧是不实用的。[Shoup95] 以迭代的方式计算它们: h i + 1 = h i ( h 1 ) ( m o d f ) h_{i+1} = h_i(h_1) \pmod f hi+1=hi(h1)(modf), H j + 1 = H j ( H 1 ) ( m o d f ) H_{j+1} = H_j(H_1) \pmod f Hj+1=Hj(H1)(modf),现在的问题是如何快速计算这些 modular-composition,形如 g ( h ) ( m o d f ) g(h) \pmod f g(h)(modf)
[Shoup95] 依旧采取 BSGS 算法(类似于 [PS73] 多项式求值算法),选取参数
t
≈
n
t \approx \sqrt n
t≈n,预计算
h
i
(
m
o
d
f
)
,
0
≤
i
≤
t
h^i \pmod f, 0 \le i \le t
hi(modf),0≤i≤t 表格,那么:
g
(
x
)
=
∑
j
=
0
n
/
t
g
j
(
x
)
⋅
y
j
,
y
=
x
t
,
deg
g
j
<
t
g(x) = \sum_{j=0}^{n/t} g_j(x) \cdot y^j,\,\, y=x^t,\,\, \deg g_j < t
g(x)=j=0∑n/tgj(x)⋅yj,y=xt,deggj<t
于是,直接使用预计算表的内容,简单计算加法(以及数乘),
g
j
(
h
)
=
∑
i
=
0
t
g
j
,
i
⋅
h
i
(
m
o
d
f
)
g_j(h) = \sum_{i=0}^t g_{j,i} \cdot h^i \pmod f
gj(h)=i=0∑tgj,i⋅hi(modf)
接着,采取 Horner 法则,计算出
g
(
x
)
=
(
(
g
n
/
t
⋅
h
t
+
⋯
)
⋅
h
t
+
g
1
)
⋅
h
t
+
g
0
g(x) = ((g_{n/t} \cdot h^t + \cdots)\cdot h^t +g_1)\cdot h^t + g_0
g(x)=((gn/t⋅ht+⋯)⋅ht+g1)⋅ht+g0
其中的多项式运算都是以 Double-CRT 方式计算的,总的复杂度为
O
(
n
2.5
+
n
log
n
log
log
n
log
p
)
O(n^{2.5}+n \log n \log\log n\log p)
O(n2.5+nlognloglognlogp)
CT65
[CT65] 给出了递归形式的 DFT 分解,其实也是可以视为一种 BSGS 版本的 FFT 算法。DFT 公式为:
A
j
:
=
∑
k
=
0
N
−
1
a
k
⋅
ζ
j
k
A_j := \sum_{k=0}^{N-1} a_k \cdot \zeta^{jk}
Aj:=k=0∑N−1ak⋅ζjk
采取 BSGS 算法,分解为
N
=
N
1
⋅
N
2
N=N_1 \cdot N_2
N=N1⋅N2,设置索引
j
:
=
N
1
⋅
j
1
+
j
0
,
j
0
∈
[
N
1
]
,
j
1
∈
[
N
2
]
k
:
=
N
2
⋅
k
1
+
k
0
,
k
0
∈
[
N
2
]
,
k
1
∈
[
N
1
]
\begin{aligned} j &:= N_1 \cdot j_1 + j_0,\,\, j_0 \in [N_1], j_1 \in [N_2]\\ k &:= N_2 \cdot k_1 + k_0,\,\, k_0 \in [N_2], k_1 \in [N_1]\\ \end{aligned}
jk:=N1⋅j1+j0,j0∈[N1],j1∈[N2]:=N2⋅k1+k0,k0∈[N2],k1∈[N1]
那么有
A
j
1
,
j
0
:
=
∑
k
0
∈
[
N
2
]
∑
k
1
∈
[
N
1
]
a
k
1
,
k
0
⋅
ζ
j
k
=
∑
k
0
∈
[
N
2
]
(
∑
k
1
∈
[
N
1
]
a
k
1
,
k
0
⋅
ζ
N
2
j
k
1
)
⋅
ζ
j
k
0
=
∑
k
0
∈
[
N
2
]
(
∑
k
1
∈
[
N
1
]
a
k
1
,
k
0
⋅
ζ
N
2
j
k
1
)
⋅
ζ
j
0
k
0
⋅
ζ
N
1
j
1
k
0
\begin{aligned} A_{j_1,j_0} &:= \sum_{k_0 \in [N_2]} \sum_{k_1 \in [N_1]} a_{k_1,k_0} \cdot \zeta^{jk}\\ &= \sum_{k_0 \in [N_2]} \left(\sum_{k_1 \in [N_1]} a_{k_1,k_0} \cdot \zeta^{N_2jk_1}\right) \cdot \zeta^{jk_0}\\ &= \sum_{k_0 \in [N_2]} \left(\sum_{k_1 \in [N_1]} a_{k_1,k_0} \cdot \zeta^{N_2jk_1}\right) \cdot \zeta^{j_0k_0} \cdot \zeta^{N_1j_1k_0}\\ \end{aligned}
Aj1,j0:=k0∈[N2]∑k1∈[N1]∑ak1,k0⋅ζjk=k0∈[N2]∑
k1∈[N1]∑ak1,k0⋅ζN2jk1
⋅ζjk0=k0∈[N2]∑
k1∈[N1]∑ak1,k0⋅ζN2jk1
⋅ζj0k0⋅ζN1j1k0
于是,将
a
N
a_N
aN 按照行主序,排列为形状
N
1
×
N
2
N_1 \times N_2
N1×N2 的矩阵
a
N
1
×
N
2
a_{N_1 \times N_2}
aN1×N2,
-
对于每一个 k 0 k_0 k0,利用形状 N 1 × N 1 N_1 \times N_1 N1×N1 的矩阵
W 1 : = { ζ j 0 k 1 } j 0 , k 1 W_1:=\{\zeta^{j_0k_1}\}_{j_0,k_1} W1:={ζj0k1}j0,k1
计算长度为 N 1 N_1 N1 的各个列矢 a k 0 a_{k_0} ak0 的 NTT 变换(单位根为 { ζ N 1 j 0 , j 0 ∈ [ N 1 ] } \{\zeta_{N_1}^{j_0},j_0 \in [N_1]\} {ζN1j0,j0∈[N1]}),得到形状 N 1 × N 2 N_1 \times N_2 N1×N2 的矩阵
W 1 × a N 1 × N 2 = { A j 0 , k 0 ′ : = ∑ k 1 ∈ [ N 1 ] a k 1 , k 0 ⋅ ζ N 2 j k 1 } j 0 , k 0 W_1 \times a_{N_1 \times N_2} = \left\{A_{j_0,k_0}' := \sum_{k_1 \in [N_1]} a_{k_1,k_0} \cdot \zeta^{N_2jk_1}\right\}_{j_0,k_0} W1×aN1×N2=⎩ ⎨ ⎧Aj0,k0′:=k1∈[N1]∑ak1,k0⋅ζN2jk1⎭ ⎬ ⎫j0,k0 -
利用形状 N 1 × N 2 N_1 \times N_2 N1×N2 的矩阵
W 2 : = { ζ j 0 k 0 } j 0 , k 0 W_2 := \{\zeta^{j_0k_0}\}_{j_0,k_0} W2:={ζj0k0}j0,k0
对它做 Hadamard 乘积,扭曲矩阵 A ′ A' A′ 使得接下来的运算是标准 NTT(否则就需要恰当的扭曲后续 NTT 采用的单位根),此时的结果是形状 N 1 × N 2 N_1 \times N_2 N1×N2 的矩阵
W 2 ⊙ A N 1 × N 2 ′ = { A j 0 , k 0 ′ ′ : = ζ j 0 k 0 ⋅ ∑ k 1 ∈ [ N 1 ] a k 1 , k 0 ⋅ ζ N 2 j k 1 } j 0 , k 0 W_2 \odot A_{N_1 \times N_2}' = \left\{A_{j_0,k_0}'' := \zeta^{j_0k_0} \cdot\sum_{k_1 \in [N_1]} a_{k_1,k_0} \cdot \zeta^{N_2jk_1}\right\}_{j_0,k_0} W2⊙AN1×N2′=⎩ ⎨ ⎧Aj0,k0′′:=ζj0k0⋅k1∈[N1]∑ak1,k0⋅ζN2jk1⎭ ⎬ ⎫j0,k0 -
对于每一个 j 1 j_1 j1,利用形状 N 2 × N 2 N_2 \times N_2 N2×N2 的矩阵
W 3 : = { ζ N 2 j 1 k 0 } j 1 , k 0 W_3 := \{\zeta_{N_2}^{j_1k_0}\}_{j_1,k_0} W3:={ζN2j1k0}j1,k0
计算长度为 N 2 N_2 N2 的各个行矢 A j 0 ′ ′ A_{j_0}'' Aj0′′ 的 NTT 变换(单位根为 { ζ N 2 j 1 , j 1 ∈ [ N 2 ] } \{\zeta_{N_2}^{j_1},j_1 \in [N_2]\} {ζN2j1,j1∈[N2]}),得到形状 N 2 × N 1 N_2 \times N_1 N2×N1 的矩阵
W 3 × ( A N 1 × N 2 ′ ′ ) T = { A j 1 , j 0 } j 1 , j 0 W_3 \times (A_{N_1 \times N_2}'')^T = \{A_{j_1,j_0}\}_{j_1,j_0} W3×(AN1×N2′′)T={Aj1,j0}j1,j0
对于形状 N 2 × N 1 N_2 \times N_1 N2×N1 的矩阵 A N 2 × N 1 A_{N_2 \times N_1} AN2×N1,按照行主序读取为 A N = N T T ( a N ) A_N = NTT(a_N) AN=NTT(aN)
总之,
a
N
,
A
N
a_N, A_N
aN,AN 都按照行主序排列为矩阵(形状不同),那么有:
A
N
2
×
N
1
=
W
3
×
(
W
2
⊙
(
W
1
×
a
N
1
×
N
2
)
)
T
A_{N_2 \times N_1} = W_3 \times \Big(W_2 \odot \big(W_1 \times a_{N_1 \times N_2}\big)\Big)^T
AN2×N1=W3×(W2⊙(W1×aN1×N2))T
其实,这个过程可以用 Nussbaumer Transform 的环同态表示
F
[
x
]
/
(
x
N
−
1
)
≅
(
F
[
y
]
/
(
y
N
1
−
1
)
)
[
x
]
/
(
x
N
2
−
y
)
≅
(
F
[
y
]
/
(
y
N
1
−
1
)
)
[
z
]
/
(
z
N
2
−
1
)
\mathbb F[x]/(x^N-1) \cong \Big(\mathbb F[y]/(y^{N_1}-1)\Big)[x]/(x^{N_2}-y) \cong \Big(\mathbb F[y]/(y^{N_1}-1)\Big)[z]/(z^{N_2}-1)
F[x]/(xN−1)≅(F[y]/(yN1−1))[x]/(xN2−y)≅(F[y]/(yN1−1))[z]/(zN2−1)
CHKKS18
[CHKKS18] 利用 SIMD 技术的 Hadamard 和 Rotate 运算,实现同态的线性运算,它也采取了 BSGS 技巧。 我们默认 index 都是自动 ( m o d n ) \pmod n (modn) 的,基本符号:
- 对于任意的线性变换 M ∈ C n × n M \in \mathbb C^{n \times n} M∈Cn×n,简记 d i a g i ( M ) = [ M 0 , i , M 1 , i + 1 , ⋯ , M n , i + n ] diag_i(M) = [M_{0,i}, M_{1,i+1},\cdots,M_{n,i+n}] diagi(M)=[M0,i,M1,i+1,⋯,Mn,i+n] 是第 i ∈ Z i \in \mathbb Z i∈Z 条对角线(可以是负数 − i -i −i,就是第 n − i n-i n−i 条对角线)
- 对于任意的矢量 v ∈ C n v \in \mathbb C^{n} v∈Cn,简记 r o t i ( v ) = [ v i , v i + 1 , ⋯ , v i + n − 1 ] rot_i(v) = [v_i,v_{i+1},\cdots,v_{i+n-1}] roti(v)=[vi,vi+1,⋯,vi+n−1] 是循环左移 i ∈ Z i \in \mathbb Z i∈Z 距离(可以是负数 − i -i −i,循环右移 i i i 距离)
采取 BSGS 算法,分解 n = l × k n=l \times k n=l×k,线性变换可以表示为:
最优化时选取 k ≈ n k \approx \sqrt n k≈n,计算复杂度为: O ( n ) O(\sqrt n) O(n) 次 Rotate 运算(关于 v v v 的密文), O ( n ) O(n) O(n) 次 Hadamard 运算。对于公开的固定矩阵 M M M,其中的 r o t − k i ( d i a g k i + j ( M ) ) rot_{-ki}(diag_{ki+j}(M)) rot−ki(diagki+j(M)) 是预计算的常数多项式(用 InvDFT 编码),它不需要 CKKS 密文下的 Rotate 运算。
[CHKKS18] 将上述的线性变换转换到 slot-packing CKKS 下同态计算,并利用它来实现 coeff-to-slot,从而批处理 CKKS 自举。用到的线性变换是 DFT 和 InvDFT,[CHKKS18] 将它们视为通用的线性变换,利用这个同态矩阵乘法来实现。
不过,对于公开的线性变换,直接使用 TFHE 提出的那种 Functional Key-Switch,效率要高得多。对于秘密的线性变换,TFHE 也提出了根据 M M M 来构造 KS-Key for M,从而支持 Private Functional Key-Switch。但是如果没有提供这种特殊的 KS-Key for M,而是将 M M M 加密为一般的 CKKS 密文,那么就只能使用上面的同态矩阵乘法,利用 Rotate 和 Hadamard 慢慢计算。
Faster Homomorphic DFT
[CHH18] 观察到 DFT 矩阵拥有稀疏分解(也就是蝴蝶算法),因此对于这种特殊的线性变换,可以比 [CHKKS18] 的通用矩阵乘法,复杂度降低一个 n n n 因子。它可以应用在 [CHKKS18] 的 CKKS 批自举上,计算速度提高了数百倍。
Sparse-Diagonal matrix Factorization
[CHH18] 它说根据 [CT65] 的递归式 FFT,可以将 DFT 矩阵做如下的稀疏分解:
继续迭代地分解前者,最终可以获得:
容易看出,
d
i
a
g
i
(
D
2
i
(
n
)
)
≠
0
⃗
⟺
k
∈
{
0
,
±
n
2
i
}
diag_i(D_{2^i}^{(n)}) \neq \vec 0 \iff k\in \{0,\pm \dfrac{n}{2^i}\}
diagi(D2i(n))=0⟺k∈{0,±2in},只有 3 条对角线是非零的,因此采取斜线乘法来计算是十分高效的,
D
2
i
(
n
)
⋅
v
=
∑
k
∈
{
0
,
±
n
/
2
i
}
d
i
a
g
k
(
D
2
i
(
n
)
)
⊙
r
o
t
k
(
v
)
D_{2^i}^{(n)} \cdot v = \sum_{k\in \{0,\pm n/2^i\}} diag_k(D_{2^i}^{(n)}) \odot rot_{k}(v)
D2i(n)⋅v=k∈{0,±n/2i}∑diagk(D2i(n))⊙rotk(v)
算法为:
注意到 r o t 0 ( v ) = v rot_0(v)=v rot0(v)=v 不必计算,对于特殊情况 i = 1 i=1 i=1 根据 r o t n / 2 i ( v ) = r o t − n / 2 i ( v ) rot_{n/2^i}(v)=rot_{-n/2^i}(v) rotn/2i(v)=rot−n/2i(v) 可节约计算。最终, D F T ⋅ v = ∏ i = 0 log 2 n D 2 i ( n ) ⋅ v DFT \cdot v = \prod_{i=0}^{\log_2 n} D_{2^i}^{(n)} \cdot v DFT⋅v=∏i=0log2nD2i(n)⋅v 的复杂度为 O ( log 2 n ) O(\log_2 n) O(log2n)
对于逆变换,由于 DFT 的逆矩阵恰好是其厄米,
因此很明显 CT 蝴蝶和上述的 GS 蝴蝶一样,也是稀疏对角的,从而也存在类似的快速矩阵乘法。
Radix-r
不过虽然上述的操作次数很小,但是计算深度为 log 2 ( n ) \log_2(n) log2(n),需要多层 Rotate 和 CMult 串行,可能导致噪声控制的问题。我们可以合并某些连续的 k k k 个矩阵,那么深度就降低为 log r n , r = 2 k \log_r n, r=2^k logrn,r=2k,代价是计算复杂度的上升。
根据对角阵的乘法性质:两个对角阵的乘积,依旧是对角阵,
d
i
a
g
i
(
a
)
⋅
d
i
a
g
j
(
b
)
=
d
i
a
g
i
+
j
(
a
⊙
r
o
t
i
(
b
)
)
diag_i(a) \cdot diag_j(b) = diag_{i+j}(a \odot rot_i(b))
diagi(a)⋅diagj(b)=diagi+j(a⊙roti(b))
可以证明,连续
k
k
k 个矩阵的合并
D
k
,
s
=
D
2
s
+
k
(
n
)
⋯
D
2
s
+
2
(
n
)
⋅
D
2
s
+
1
(
n
)
D_{k,s} = D_{2^{s+k}}^{(n)} \cdots D_{2^{s+2}}^{(n)} \cdot D_{2^{s+1}}^{(n)}
Dk,s=D2s+k(n)⋯D2s+2(n)⋅D2s+1(n)
的非零对角线的索引为
e
1
⋅
n
2
s
+
1
+
e
2
⋅
n
2
s
+
2
+
⋯
+
e
t
⋅
n
2
s
+
k
e_1 \cdot \dfrac{n}{2^{s+1}} + e_2 \cdot \dfrac{n}{2^{s+2}} + \cdots + e_t \cdot \dfrac{n}{2^{s+k}}
e1⋅2s+1n+e2⋅2s+2n+⋯+et⋅2s+kn
其中
e
i
∈
{
0
,
±
1
}
e_i \in \{0,\pm1\}
ei∈{0,±1},易知这些 index 都是
n
2
s
+
k
\dfrac{n}{2^{s+k}}
2s+kn 的倍数,绝对值上界为
(
2
k
−
1
)
n
2
s
+
k
\dfrac{(2^k-1)n}{2^{s+k}}
2s+k(2k−1)n,这些 index 的个数至多为
2
k
+
1
−
1
2^{k+1}-1
2k+1−1
此时的 DFT 的复杂度为: O ( r log r n ) O(r \log_r n) O(rlogrn) 次 Rotate 和 Hadamard,深度为 O ( log r n ) O(\log_r n) O(logrn)
Hybrid method
由于上述分解的非零 index 呈现算术级数(都是 n 2 s + k \dfrac{n}{2^{s+k}} 2s+kn 的倍数),因此可以采取 BSGS 技巧,提取出公共的计算部分,进一步提高计算效率。
最优化设置 k 2 ≈ t k_2 \approx \sqrt t k2≈t,此时 DFT 的复杂度为:依旧 O ( r log r n ) O(r \log_r n) O(rlogrn) 次 Hadamard,但是只需 O ( r log r n ) O(\sqrt r \log_r n) O(rlogrn) 次 Ratate(但 r r r 是常数),深度也还是 O ( log r n ) O(\log_r n) O(logrn)
Result
同态 DFT 的执行时间:秒的量级
CKKS 自举时间:2 分钟延迟,均摊 4 毫秒