参考文献:
- [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.
- [AAB+20] Aharoni E, Adir A, Baruch M, et al. Helayers: A tile tensors framework for large neural networks on encrypted data[J]. arxiv preprint arxiv:2011.01805, 2020.
- [CKK20] Cheon J H, Kim D, Kim D. Efficient homomorphic comparison methods with optimal complexity[C]//Advances in Cryptology–ASIACRYPT 2020: 26th International Conference on the Theory and Application of Cryptology and Information Security, Daejeon, South Korea, December 7–11, 2020, Proceedings, Part II 26. Springer International Publishing, 2020: 221-256.
- [CHK+21] Chung C M M, Hwang V, Kannwischer M J, et al. NTT multiplication for NTT-unfriendly rings: New speed records for Saber and NTRU on Cortex-M4 and AVX2[J]. IACR Transactions on Cryptographic Hardware and Embedded Systems, 2021: 159-188.
- [LLL+24] Li Z, Liu Y, Lu X, et al. Faster Bootstrapping via Modulus Raising and Composite NTT[J]. IACR Transactions on Cryptographic Hardware and Embedded Systems, 2024, 2024(1): 563-591.
- [DMP+24] Drucker N, Moshkowich G, Pelleg T, et al. BLEACH: cleaning errors in discrete computations over CKKS[J]. Journal of Cryptology, 2024, 37(1): 3.
- [BCK+24] Bae Y, Cheon J H, Kim J, et al. Bootstrapping Bits with CKKS[C]//Annual International Conference on the Theory and Applications of Cryptographic Techniques. Cham: Springer Nature Switzerland, 2024: 94-123.
- 近似的同态比较:简单多项式的迭代计算
- Key Unrolling,Approximate Gadget Decomposition
- 常见函数的级数展开及推导
- 关于浮点数的原理,误差,以及你想知道的一切
文章目录
- Clean-up
- Polynomial Approximation of Sign Function
- BLEACH strategy
- Bit decomposition
- Tile Tensors
- Tiling
- Operators
- CKKS for Bits
- Modulus Engineering for BTS
- BinBoot
- GateBoot
- Experiments
- Composite NTT
- NTT with Composite Modulus
- Packing Bootstrapping
CKKS 方案使用的是复数 m ∈ C N / 2 m \in \mathbb C^{N/2} m∈CN/2(及其共轭)的定点数编码 f ( X ) = Δ ⋅ i D F T ( m ) ∈ R N [ X ] f(X) = \Delta \cdot iDFT(m) \in \mathbb R_N[X] f(X)=Δ⋅iDFT(m)∈RN[X],对应的解码是 D F T ( f ) / Δ ∈ C N / 2 DFT(f)/\Delta \in \mathbb C^{N/2} DFT(f)/Δ∈CN/2,密文的相位是 f + ϵ + e ∈ Z N [ X ] f+\epsilon+e \in \mathbb Z_N[X] f+ϵ+e∈ZN[X](不取模),其中 ϵ ∈ T N [ X ] \epsilon \in \mathbb T_N[X] ϵ∈TN[X] 是舍入噪声, e ∈ Z N [ X ] e \in \mathbb Z_N[X] e∈ZN[X] 是加密噪声,后者的范数占主导。
由于 DFT 满足 scaled 2-norm isometry,具体地说:对于实系数函数
∀
f
∈
R
N
[
X
]
\forall f \in \mathbb R_N[X]
∀f∈RN[X],其频域是复向量,它的范数由典范内积
⟨
x
,
y
⟩
=
x
†
y
\langle x, y\rangle = x^\dagger y
⟨x,y⟩=x†y 所诱导。由于共轭是实数轴对称的,
f
(
x
)
‾
=
f
(
x
ˉ
)
,
∀
x
∈
C
\overline{f(x)} = f(\bar x), \forall x \in \mathbb C
f(x)=f(xˉ),∀x∈C,因此有
f
(
ζ
k
)
f
(
ζ
k
)
‾
=
(
∑
i
f
i
ζ
i
k
)
(
∑
j
f
j
ζ
ˉ
j
k
)
=
∑
i
,
j
f
i
f
j
ζ
(
i
−
j
)
k
=
∑
i
f
i
2
+
∑
i
≠
j
f
i
f
j
ζ
(
i
−
j
)
k
\begin{aligned} f(\zeta^k)\overline{f(\zeta^k)} &= \left(\sum_i f_i\zeta^{ik}\right)\left(\sum_j f_j\bar\zeta^{jk}\right)\\ &= \sum_{i,j} f_if_j\zeta^{(i-j)k}\\ &= \sum_i f_i^2 + \sum_{i \neq j} f_if_j\zeta^{(i-j)k} \end{aligned}
f(ζk)f(ζk)=(i∑fiζik)(j∑fjζˉjk)=i,j∑fifjζ(i−j)k=i∑fi2+i=j∑fifjζ(i−j)k
那么频域的范数平方就是
∑
k
(
∑
i
f
i
2
+
∑
i
≠
j
f
i
f
j
ζ
(
i
−
j
)
k
)
=
∑
k
∑
i
f
i
2
=
N
⋅
∥
f
∥
2
2
\sum_k(\sum_i f_i^2 + \sum_{i \neq j} f_if_j\zeta^{(i-j)k}) = \sum_k\sum_if_i^2 = N \cdot \|f\|_2^2
∑k(∑ifi2+∑i=jfifjζ(i−j)k)=∑k∑ifi2=N⋅∥f∥22,其中
∑
k
ζ
k
=
0
\sum_k \zeta^k=0
∑kζk=0 被消除。由于频域的一半是另一半的共轭,因此只考虑有效的明文槽,其范数就是
N
/
2
⋅
∥
f
∥
2
\sqrt{N/2} \cdot \|f\|_2
N/2⋅∥f∥2。对于带噪明文多项式
f
+
ϵ
+
e
∈
Z
N
[
X
]
f+\epsilon+e \in \mathbb Z_N[X]
f+ϵ+e∈ZN[X],解码获得带噪的复数
m
+
D
F
T
(
ϵ
+
e
)
/
Δ
∈
C
N
/
2
m + DFT(\epsilon+e)/\Delta \in \mathbb C^{N/2}
m+DFT(ϵ+e)/Δ∈CN/2,噪声的范数是
N
/
2
⋅
∥
ϵ
+
e
∥
2
/
Δ
\sqrt{N/2} \cdot \|\epsilon+e\|_2/\Delta
N/2⋅∥ϵ+e∥2/Δ,因此缩放因子
Δ
\Delta
Δ 应当比
m
m
m 预期的精度增大至少
N
/
2
\sqrt{N/2}
N/2 倍。不过
D
F
T
(
ϵ
+
e
)
/
Δ
∈
C
N
/
2
DFT(\epsilon+e)/\Delta \in \mathbb C^{N/2}
DFT(ϵ+e)/Δ∈CN/2 仅随着
ϵ
+
e
∈
R
N
[
X
]
\epsilon+e \in \mathbb R_N[X]
ϵ+e∈RN[X] 线性增长, 每当 coeff-side 损失
1
1
1 比特精度,那么 slot-side 也恰好损失
1
1
1 比特精度。
假设整体相位规模是 2 p + t 2^{p+t} 2p+t,噪声规模是 2 t 2^t 2t,那么精度就是 p p p 比特。CKKS 本质上并不是一个 FHE(在无界计算的意义下),
- 同态加法: ( f 1 + e 1 ) + ( f 2 + e 2 ) = ( f 1 + f 2 ) + ( e 1 + e 2 ) ∈ Z N [ X ] (f_1+e_1)+(f_2+e_2) = (f_1+f_2) + (e_1+e_2) \in \mathbb Z_N[X] (f1+e1)+(f2+e2)=(f1+f2)+(e1+e2)∈ZN[X],整体相位增大为 2 p + t + 1 2^{p+t+1} 2p+t+1,噪声增大为 2 t + 1 2^{t+1} 2t+1,精度保持为 p p p 比特
- 同态乘法: ( f 1 + e 1 ) ⋅ ( f 2 + e 2 ) = f 1 f 2 + ( f 1 e 2 + f 2 e 1 + e 1 e 2 ) ∈ Z N [ X ] (f_1+e_1) \cdot (f_2+e_2) = f_1f_2 + (f_1e_2+f_2e_1+e_1e_2) \in \mathbb Z_N[X] (f1+e1)⋅(f2+e2)=f1f2+(f1e2+f2e1+e1e2)∈ZN[X],整体相位增大为 2 2 ( p + t ) 2^{2(p+t)} 22(p+t),噪声增大为 2 p + 2 t + 1 2^{p+2t+1} 2p+2t+1,精度缩小为 p − 1 p-1 p−1 比特,需要重缩放 2 p + t 2^{p+t} 2p+t 因子
- 同态数乘: ( f 1 + e 1 ) ⋅ f 2 = f 1 f 2 + f 2 e 1 ∈ Z N [ X ] (f_1+e_1) \cdot f_2 = f_1f_2 + f_2e_1 \in \mathbb Z_N[X] (f1+e1)⋅f2=f1f2+f2e1∈ZN[X],整体相位增大为 2 2 ( p + t ) 2^{2(p+t)} 22(p+t),噪声增大为 2 p + 2 t 2^{p+2t} 2p+2t,精度保持为 p p p 比特,需要重缩放 2 p + t 2^{p+t} 2p+t 因子
由于编码方式的不同,CKKS 和 BGV/BFV 的不同之处:BGV/BFV 的同态乘法不会导致精度损失;BGV/BFV 的同态数乘基本不消耗模数。它们的自举目标也不同:BGV/BFV 通过 HomDec 来消除噪声,CKKS 仅通过 EvalMod 来增大模数(还引入更多的噪声)。随着 CKKS 电路深度的增加,最终消息会完全淹没在运算噪声和自举噪声内,无法执行任意深度的运算。
其实,计算机中的浮点数也有这个问题。对于高次多项式的计算结果并不可信,例如:
>>> np.e
2.718281828459045
>>> (1+1e-10)**1e10
2.7182820532347876
>>> (1+1e-15)**1e15
3.035035206549262
>>> (1+2**(-53))**(2**53)
1.0
>>> (1+1/(2**53-1))**(2**53-1)
7.389056098930647
当然对于常规的运算,浮点数基本都没什么问题,即使是很深的电路。因为这只是编码误差,而非运算错误。但在 CKKS 中就严重的多了,运算本身还会继续引入额外的噪声,仅仅几十层乘法就把有效精度消耗殆尽。
Clean-up
[DMP+24] 假设 CKKS 编码的消息取自某个先验的离散集合,然后使用阶跃函数将带噪的相位映射到最近的离散点(效果就是减小了噪声),从而可以支持无界深度的电路。
Polynomial Approximation of Sign Function
[CKK20] 把符号函数的关键形状提取出来,然后使用低次多项式来近似。
S
i
g
n
(
x
)
=
{
1
,
x
>
0
0
,
x
=
0
−
1
,
x
<
0
Sign(x) = \left\{\begin{aligned} 1, && x>0\\ 0, && x=0\\ -1, && x<0 \end{aligned}\right.
Sign(x)=⎩
⎨
⎧1,0,−1,x>0x=0x<0
它具有三个重要性质:
- 原点对称
- 穿过 ( − 1 , − 1 ) , ( 0 , 0 ) , ( 1 , 1 ) (-1,-1),(0,0),(1,1) (−1,−1),(0,0),(1,1) 三个点
- 在 x = ± 1 x=\pm1 x=±1 快速收敛
因此我们找一个近似的多项式,使得它分别满足:
- f ( − x ) = − f ( x ) f(-x) = -f(x) f(−x)=−f(x)
- f ( − 1 ) = − 1 , f ( 0 ) = f ( 0 ) , f ( 1 ) = f ( 1 ) f(-1)=-1, f(0)=f(0), f(1)=f(1) f(−1)=−1,f(0)=f(0),f(1)=f(1)
- ∂ f ∂ x = c ( 1 − x ) n ( 1 + x n ) \frac{\partial f}{\partial x} = c(1-x)^n(1+x^n) ∂x∂f=c(1−x)n(1+xn)
[CKK20] 根据这三条性质,定义了一族多项式 { f n } \{f_n\} {fn},其中 f 1 ( x ) = − 1 2 x 3 + 3 2 x f_1(x) = -\frac{1}{2}x^3 + \frac{3}{2}x f1(x)=−21x3+23x。为了更加逼近符号函数,他们将 f n f_n fn 迭代复合 d d d 次。
由于上述的多项式近似对于输入/输出的范围和误差都有要求,因此可以把这个程序记为:
S
i
g
n
α
,
β
(
x
)
=
{
1
,
−
1
≤
x
<
−
α
−
1
,
α
<
x
≤
1
undefined
,
otherwise
Sign_{\alpha, \beta}(x) = \left\{\begin{aligned} 1, && -1 \le x <-\alpha\\ -1, && \alpha < x \le 1\\ \text{undefined}, && \text{otherwise} \end{aligned}\right.
Signα,β(x)=⎩
⎨
⎧1,−1,undefined,−1≤x<−αα<x≤1otherwise
满足:
∣
S
i
g
n
α
,
β
(
x
)
−
S
i
g
n
(
x
)
∣
<
β
,
∀
x
∈
[
−
1
,
−
α
)
∪
(
α
,
1
]
|Sign_{\alpha,\beta}(x) - Sign(x)| < \beta,\,\, \forall x \in [-1,-\alpha) \cup (\alpha,1]
∣Signα,β(x)−Sign(x)∣<β,∀x∈[−1,−α)∪(α,1]
根据 [CKK20],这个电路的 size 和 depth 分别是
S
(
α
,
β
)
=
D
(
α
,
β
)
=
O
(
log
(
1
/
α
)
)
+
O
(
log
log
(
1
/
β
)
)
S(\alpha,\beta) = D(\alpha,\beta) = O(\log(1/\alpha)) + O(\log\log(1/\beta))
S(α,β)=D(α,β)=O(log(1/α))+O(loglog(1/β))
精度越高(
α
\alpha
α 控制输入精度,
β
\beta
β 控制输出精度),那么电路的大小和深度都会增大。
[DMP+24] 把符号函数 f 1 ( x ) = − 0.5 x 3 + 1.5 x , ∀ x ∈ [ − 1 , 1 ] f_1(x) = -0.5x^3+1.5x, \forall x \in [-1,1] f1(x)=−0.5x3+1.5x,∀x∈[−1,1] 转换为阶跃函数 h 1 ( x ) = − 2 x 3 + 3 x 2 , ∀ x ∈ [ 0 , 1 ] h_1(x) = -2x^3+3x^2, \forall x \in [0,1] h1(x)=−2x3+3x2,∀x∈[0,1](左右/上下平移 + 缩放),两者是完全等价的, S ( α , β ) , D ( α , β ) S(\alpha,\beta),D(\alpha,\beta) S(α,β),D(α,β) 都不变。
BLEACH strategy
在原始 CKKS 方案下,任意的二元对称布尔门都可以使用二次函数来模拟。
- AND Gate: x ⋅ y x \cdot y x⋅y
- OR Gate: x + y − x ⋅ y x+y-x \cdot y x+y−x⋅y
- XOR Gate: ( x − y ) 2 (x-y)^2 (x−y)2
对于带噪的
x
′
=
x
+
e
x
x'=x+e_x
x′=x+ex 和
y
′
=
y
+
e
y
y'=y+e_y
y′=y+ey,其中
x
,
y
∈
{
0
,
1
}
x,y \in \{0,1\}
x,y∈{0,1} 以及
e
x
,
e
y
<
B
<
0.25
e_x,e_y < B < 0.25
ex,ey<B<0.25,那么就有
∣
G
a
t
e
(
x
′
,
y
′
)
−
G
a
t
e
(
x
,
y
)
∣
<
5
e
|Gate(x',y') - Gate(x,y)| < 5e
∣Gate(x′,y′)−Gate(x,y)∣<5e
换句话说,只要输入的误差不太大,那么 CKKS 模拟出的布尔门的输出的误差就不会增长的太多。由于花费了一层乘法,因此还降低了
1
1
1-bit 精度(注意区分噪声规模和明文精度,它们是两个无关的东西)。定义布尔值的
k
k
k-bit 精度近似
B
k
:
=
{
0
,
1
}
±
2
−
k
B_k := \{0,1\} \pm 2^{-k}
Bk:={0,1}±2−k,那么经过一个布尔运算后的结果落在
B
k
−
1
B_{k-1}
Bk−1 内,我们需要把
B
k
−
1
B_{k-1}
Bk−1 提升回
B
k
B_k
Bk
现在,我们考虑
h
1
h_1
h1 对于错误的纠正能力:
h
1
(
0
+
e
)
=
0
−
2
e
3
+
3
e
2
h
1
(
1
+
e
)
=
1
−
2
e
3
−
3
e
2
\begin{aligned} h_1(0+e) = 0-2e^3 + 3e^2\\ h_1(1+e) = 1-2e^3 - 3e^2\\ \end{aligned}
h1(0+e)=0−2e3+3e2h1(1+e)=1−2e3−3e2
计算一下:
>>> e = lambda x: 2*x**3 + 3*x**2
>>> e(0.3)
0.324
>>> e(0.2)
0.136
>>> e(0.1)
0.032
>>> e(0.01)
0.000302
只要噪声小于 0.2 0.2 0.2,那么噪声就可以降低。如果噪声小于 0.01 0.01 0.01,那么噪声就以大约二次方的速度降低。
[DMP+24] 在每一次 Gate 之后都立即执行 h 1 h_1 h1 来清理噪声,称之为 “漂白” 技术,记为 C l e a n u p ( 2 − ( k + 1 ) , 2 − k ) ( ⋅ ) Cleanup_{(2^{-(k+1)},2^{-k})}(\cdot) Cleanup(2−(k+1),2−k)(⋅),它把 B k B_k Bk 清理为 B k + 1 B_{k+1} Bk+1(降低了噪声,提升了精度)。太保守了:噪声被二次方降低,因此大约是把 B k B_k Bk 清理为了 B 2 k − 2 B_{2k-2} B2k−2(还有个因子 3 3 3 的影响)
另外,由于 CKKS 自举仅仅提升模数,并不清理噪声,可以把这个 clean-up 结合在一起,从而同时实现模数提升和噪声降低。
Bit decomposition
对于更一般的 N N N-bit 整数集合 x ∈ N ∩ [ 0 , 2 N + 1 ) x \in \mathbb N \cap [0,2^{N+1}) x∈N∩[0,2N+1),[DMP+24] 依次提取和清理 MSB,获得各个比特的低噪声模拟,然后再组装回 N N N-bit 整数的低噪声模拟。
提取 MSB 的算法:
数字分解的算法:[DMP+24] 的噪声分析写的很乱
清理整数的算法:
Tile Tensors
[DMP+24] 使用 Tile Tensors 实现了 Conway’s Game of Life,作为 BLEACH 的性能测试。[AAB+20] 为了简化 API,提出了介于 FHE 和 CNN 之间的一个 “瓷砖张量” 框架。
Tiling
对于任意的张量
A
[
n
1
,
n
2
,
⋯
,
n
k
]
A[n_1,n_2,\cdots,n_k]
A[n1,n2,⋯,nk](一个高维数组),[AAB+20] 把它分成形状
[
t
1
,
t
2
,
⋯
,
t
k
]
[t_1,t_2,\cdots,t_k]
[t1,t2,⋯,tk] 的张量(必要的填充),称之为 “瓷砖”,每个瓷砖被打包加密在单个密文中。这些瓷砖组成了一个张量
E
[
e
1
,
e
2
,
⋯
,
e
k
]
E[e_1,e_2,\cdots,e_k]
E[e1,e2,⋯,ek],其中
e
i
=
⌈
n
i
/
t
i
⌉
e_i = \lceil n_i/t_i \rceil
ei=⌈ni/ti⌉,被称为 external tensor。这个过程被记为:
T
A
=
p
a
c
k
(
A
,
[
n
1
t
1
,
⋯
,
n
k
t
k
]
)
T_A = pack\left(A, \left[\frac{n_1}{t_1}, \cdots, \frac{n_k}{t_k} \right]\right)
TA=pack(A,[t1n1,⋯,tknk])
对应的逆过程记为
A
=
u
n
p
a
c
k
(
T
A
)
A = unpack(T_A)
A=unpack(TA)
对于张量 M [ 5 , 6 ] M[5,6] M[5,6],可以有不同的打包方式:
Operators
对于两个张量 A , B A,B A,B,在运算之前需要保证它们的形状是兼容的:
首先把两个张量广播到 mutual expanded shape,然后再做 element-wise 加法/乘法。利用这些基本运算,可以搭建出矩阵乘、二维卷积等高级运算。细节请看 [AAB+20],略。
CKKS for Bits
[DMP+24] 使用原始的 CKKS 方案,自举算法也是以黑盒方式使用的。[BCK+24] 考虑了布尔值明文的特点,对 CKKS 自举给出了专门的优化。
Modulus Engineering for BTS
在 [CHKKS18] 中的 EvalMod 计算的是 x + q 0 I ↦ x x + q_0 I \mapsto x x+q0I↦x 函数,其中 I I I 是有界整数, x x x 是相对于 q q q 很小的实数。先使用 Sine 函数来近似模拟这个函数,然后再用 Poly 去模拟 Sine 函数(对于某些小区间的切比雪夫插值)
方便起见,现在只考虑 CKKS 的实数自举(OpenFHE 似乎也仅支持实数的槽打包)。一般来说,不同阶段的噪声增长是不同的,并且自举过程中的噪声增长会更大一些。
- 为了提高自举精度,在自举之前乘以一个倍率
c
c
c,在自举之后再除以
c
c
c 回到原始的缩放因子,这可以把自举噪声相对缩小
c
c
c 倍。
- 这里的 c c c 被选取为二的幂次(例如 c = 2 4 c=2^4 c=24),除法可直接使用重缩放,而非定点数编码(避免同态数乘的模数消耗)
- 不过模数 q 0 q_0 q0 也要相应的增大,以维持 x x x 和 q 0 q_0 q0 之间的 Gap,保证 Sine 模拟的精度
- 对于 RNS-CKKS 变体,那些 computation levels 模数选取为
Δ
\Delta
Δ 规模(乘法之后的重缩放),而那些 bootstrapping levels 模数则被细粒度地选取为各自的明文的规模。
- StC 步骤的相位是 x x x,规模大约是 Δ \Delta Δ
- CtS 和 EvalMod 步骤的相位是 x + q 0 I ≈ q 0 I x+q_0I \approx q_0I x+q0I≈q0I,这远比 Δ \Delta Δ 更大
自举流程是:
BinBoot
[BCK+24] 仅关注 b ∈ { 0 , 1 } b \in \{0,1\} b∈{0,1} 的场景,因此可以设置 Δ = q 0 / 2 \Delta = q_0/2 Δ=q0/2,那么 Δ ( b + e ) + q 0 I \Delta(b+e) +q_0I Δ(b+e)+q0I 可以缩放为 ( b + e ) / 2 + I (b+e)/2 + I (b+e)/2+I,现在的目标是计算函数 g : ( b + e ) / 2 + I ↦ b g: (b+e)/2 + I \mapsto b g:(b+e)/2+I↦b。由于 b ∈ { 0 , 1 } b \in \{0,1\} b∈{0,1} 以及 e ≪ 1 e \ll 1 e≪1,函数 g g g 定义在区间 ( Z ± e ) ∪ ( Z + 0.5 ± e ) (\mathbb Z\pm e) \cup (\mathbb Z+0.5\pm e) (Z±e)∪(Z+0.5±e),并且 Z ± e ↦ 0 \mathbb Z\pm e \mapsto 0 Z±e↦0 以及 Z + 0.5 ± e ↦ 1 \mathbb Z+0.5\pm e \mapsto 1 Z+0.5±e↦1
这个函数很特殊:
1
1
1-周期函数,定义域只在
I
∪
(
I
+
0.5
)
I \cup (I+0.5)
I∪(I+0.5) 附近,值域是二值的。[BCK+24] 使用如下的函数来模拟它:
f
(
x
)
=
1
2
(
1
−
cos
(
2
π
⋅
x
)
)
f(x) = \frac{1}{2}(1-\cos(2\pi \cdot x))
f(x)=21(1−cos(2π⋅x))
由于 Cosine 在原点的级数是
cos
(
x
)
=
1
−
x
2
2
!
+
x
4
4
!
−
⋯
\cos(x) = 1-\frac{x^2}{2!}+\frac{x^4}{4!}-\cdots
cos(x)=1−2!x2+4!x4−⋯,容易验证:
f
(
(
b
+
e
)
/
2
+
I
)
=
b
+
O
(
e
2
)
f((b+e)/2+I) = b + O(e^2)
f((b+e)/2+I)=b+O(e2)
也就是说:函数
f
f
f 不仅模拟了函数
g
g
g,而且还平方级别的降低了噪声。
算法很简单,只需修改 EvalMod 步骤:
更加精细的噪声分析是:
其中的 B 2 , B 3 , B a p p r B_2,B_3,B_{appr} B2,B3,Bappr 都可以通过调整参数,来降低到远比 ∥ ϵ ∥ ∞ \|\epsilon\|_\infty ∥ϵ∥∞ 小的程度。
在原始的 CKKS 自举中,总是要求 Δ ≪ q 0 \Delta \ll q_0 Δ≪q0,以保证 Sine 模拟的精度。一般地,设置 Δ ≈ q 0 ⋅ 2 − 10 \Delta \approx q_0 \cdot 2^{-10} Δ≈q0⋅2−10,这导致 CtS 和 EvalMod 的模数消耗比其他同态计算过程高了至少 10 10 10-bit,由于 CtS 和 EvalMod 需要十层左右的同态乘法,这导致了约 100-bit 的额外模数消耗。而在 BinBoot 中设置了 Δ = q 0 / 2 \Delta = q_0/2 Δ=q0/2,因此 computation levels 和 bootstrapping levels 可以设置为相似的大小,从而自举后的容量更多。
另外,由于只处理布尔值,因此明文精度也可以设置的很小(保证足以把布尔值和噪声相互分离即可)。假设 BinBoot 之后的容量是 5 层乘法,那么只需要设置明文精度为 10-bit(此时只需要 Δ ≈ N / 2 ⋅ 2 10 \Delta \approx \sqrt{N/2} \cdot 2^{10} Δ≈N/2⋅210),经过 5 层乘法丢失了 5-bit 精度,再利用 BinBoot 把精度拉回 10-bit,如此反复,可以计算无界深度的布尔电路。
GateBoot
类似于 FHEW/TFHE 的思路,[BCK+24] 留出稍大一些的明文空间,在自举之前首先把两个密文做线性运算,然后再执行一次程序自举做非线性运算,从而在自举的同时计算一个布尔门。 由于不需要把系数编码在多项式指数上,这里可以设置明文模数是 3 3 3 而非 4 4 4,对应的缩放因子是 Δ = q 0 / 3 \Delta = q_0/3 Δ=q0/3
现在,自举过程需要计算的函数是: ( b 1 + b 2 + e ) / 3 + I ↦ G a t e ( b 1 , b 2 ) (b_1+b_2+e)/3 + I \mapsto Gate(b_1,b_2) (b1+b2+e)/3+I↦Gate(b1,b2),其中 b 1 , b 2 ∈ { 0 , 1 } b_1,b_2 \in \{0,1\} b1,b2∈{0,1}, e ≪ 1 e \ll 1 e≪1, I ∈ Z I \in \mathbb Z I∈Z,对应的三角函数是:
但是要注意:三角函数只有局部极值的位置,才具有把噪声平方级缩小的功能。在上述的图像中,容易发现都恰好只有一个明文取值是落在了局部极值上。
自举算法:
噪声分析:
为了控制噪声,有三种方法:
- 对于随机明文,以 1 / 3 1/3 1/3 的概率会发生噪声清理,精度加倍;但是不通用。
- 在合理的位置上,额外使用 [DMP+24] 的 “漂白” 技术,手动地清理噪声,计算 h 1 h_1 h1 消耗 2 2 2 层模数;[BCK+24] 采用了这个方法。
- 寻找具有三个局部极值点的其他函数;但是计算复杂度很高。
Experiments
由于 CKKS 自举过程消耗的模数基本不随维度变化,因此维度越高则均摊成本越低。[BCK+24] 给了两组参数,一组用于低延迟的自举,一组用于高吞吐的自举。
选取 N = 2 14 N=2^{14} N=214,BinBoot 和 GateBoot 的计算延迟分别是 1.36 1.36 1.36 秒和 1.39 1.39 1.39 秒。
选取 N = 2 16 N=2^{16} N=216,BinBoot 和 GateBoot 的计算延迟分别是 23.1 23.1 23.1 秒和 23.3 23.3 23.3 秒。
自举之后剩余 28 28 28 层乘法深度,
- 如果使用 BinBoot,每经过 4 层 Gate 再用 h 1 h_1 h1 清理噪声,[1-4]+Cleanup,[7-10]+Cleanup,[13-16]+Cleanup,[19-22]+Cleanup,[25-28]+BinBoot,有效的 Gate 层数是 20 20 20,均摊成本 23.1 s ÷ 2 16 ÷ 20 = 17.6 μ s 23.1s \div 2^{16} \div 20 = 17.6 \mu s 23.1s÷216÷20=17.6μs
- 如果使用 GateBoot,每经过 3 层 Gate 再用 h 1 h_1 h1 清理噪声,[1-3]+Cleanup,[6-8]+Cleanup,[11-13]+Cleanup,[16-18]+Cleanup,[21-23]+Cleanup,[26-28]+GateBoot,有效层数是 16 + 1 16+1 16+1,均摊成本 23.3 s ÷ 2 16 ÷ 17 = 20.9 μ s 23.3\text{ s} \div 2^{16} \div 17 = 20.9 \mu\text{s} 23.3 s÷216÷17=20.9μs
[CGGI16] 的速度是 10.5 ms 10.5\text{ ms} 10.5 ms,因此在均摊成本上加速了 596 596 596 倍。
Composite NTT
[BCK+24] 的实际效率提升远没有达到理论预期,他们说这是因为 RNS-CKKS 的模数链选的很小,导致 NTT 数量太多。可以把两个 30 比特左右的素数组合成 60 比特的较大模数(但保持在机器字内),从而减少 NTT 数量。[BCK+24] 没有描述计算细节,[LLL+24] 中给出了 FHEW-like 的一种 RNS 变体,前者没有引用后者。
NTT with Composite Modulus
FHEW/TFHE 使用的模数 q q q 通常是二的幂次,因此对于二的幂次分圆环,不存在 NTT 所需的本原单位根。利用 [CHK+21] 的技术,把 a , b ∈ R q a,b \in R_q a,b∈Rq 提升到 R R R,它们乘积的系数范围不超过 N q 2 / 4 Nq^2/4 Nq2/4,因此可以选取一些 NTT-friendly 小素数 Q = ∏ i q i ≥ N q 2 / 4 Q=\prod_i q_i \ge Nq^2/4 Q=∏iqi≥Nq2/4,从而快速计算 R q R_q Rq 上的乘法。
由于
Q
Q
Q 是合数,因此
Z
Q
∗
\mathbb Z_Q^*
ZQ∗ 不一定是循环群(仅当
Q
=
4
,
p
k
,
2
p
k
Q=4,p^k,2p^k
Q=4,pk,2pk 时才是),所以如何构造
2
N
2N
2N-th 本原根是个问题。可以递归地构造:假设
Q
1
,
Q
2
Q_1,Q_2
Q1,Q2 下存在
ζ
Q
1
,
ζ
Q
2
\zeta_{Q_1},\zeta_{Q_2}
ζQ1,ζQ2 都是
2
N
2N
2N-th 本原单位根,那么它们的 CRT 合成
ζ
Q
=
ζ
Q
1
Q
2
⋅
[
Q
2
−
1
]
Q
1
+
ζ
Q
2
Q
1
⋅
[
Q
1
−
1
]
Q
2
=
ζ
Q
1
+
ζ
Q
2
⋅
[
(
ζ
Q
2
−
ζ
Q
1
)
⋅
Q
2
−
1
]
Q
1
\begin{aligned} \zeta_Q &= \zeta_{Q_1}Q_2\cdot[Q_2^{-1}]_{Q_1} + \zeta_{Q_2}Q_1\cdot[Q_1^{-1}]_{Q_2}\\ &= \zeta_{Q_1} + \zeta_{Q_2} \cdot [(\zeta_{Q_2}-\zeta_{Q_1}) \cdot Q_2^{-1}]_{Q_1} \end{aligned}
ζQ=ζQ1Q2⋅[Q2−1]Q1+ζQ2Q1⋅[Q1−1]Q2=ζQ1+ζQ2⋅[(ζQ2−ζQ1)⋅Q2−1]Q1
就是
Q
=
Q
1
Q
2
Q=Q_1Q_2
Q=Q1Q2 下的
2
N
2N
2N-th 本原单位根。这可以利用 CRT 来证明。
以二叉树的方式,构造 Q = ∏ i q i Q = \prod_i q_i Q=∏iqi 下的本原单位根:
使用 ζ Q \zeta_Q ζQ 执行 Z Q \mathbb Z_Q ZQ 下的 NTT,这很容易实现。可以将两个 32-bit 素数合并为 64-bit 合数,从而一次性完成两个 NTT 运算(但是 64-bit 乘法需要 128-bit 寄存器,这不一定被计算机支持,可能还要用 Schoolbook 算法来模拟)
Packing Bootstrapping
外积运算本质上就是
R
R
R-模
R
Q
R_Q
RQ 上的数乘。为了控制噪声,采取了数字分解以及模数提升。忽略后者,我们只看
R
R
R-模
R
Q
R_Q
RQ 上的数乘,假如多个
R
Q
1
,
⋯
,
R
Q
l
R_{Q_1},\cdots,R_{Q_l}
RQ1,⋯,RQl 采用了互素的模数
Q
1
,
⋯
,
Q
l
Q_1,\cdots,Q_l
Q1,⋯,Ql,那么根据 CRT 定理,设置
Q
=
∏
i
Q
i
Q = \prod_i Q_i
Q=∏iQi,
R
Q
≅
R
Q
1
×
⋯
×
R
Q
l
R_{Q} \cong R_{Q_1} \times \cdots \times R_{Q_l}
RQ≅RQ1×⋯×RQl
因此
l
l
l 个数乘运算
r
1
⋅
M
1
,
⋯
,
r
l
⋅
M
l
r_1 \cdot M_1, \cdots, r_l \cdot M_l
r1⋅M1,⋯,rl⋅Ml,其中
r
i
∈
R
r_i \in R
ri∈R 以及
M
i
∈
R
Q
i
M_i \in R_{Q_i}
Mi∈RQi,可以写成如下的数乘:
i
C
R
T
(
C
R
T
Q
(
[
r
1
]
Q
1
,
⋯
,
[
r
l
]
Q
l
)
⋅
C
R
T
Q
(
M
1
,
⋯
,
M
l
)
)
iCRT\Big(CRT_Q([r_1]_{Q_1},\cdots,[r_l]_{Q_l}) \cdot CRT_Q(M_1,\cdots,M_l)\Big)
iCRT(CRTQ([r1]Q1,⋯,[rl]Ql)⋅CRTQ(M1,⋯,Ml))
[LLL+24] 利用这个关系,将两个 FHEW/TFHE 自举(模数
P
i
Q
i
P_iQ_i
PiQi 都在
32
32
32-bit 以内?这合理么?)打包起来,加速了 1.7 倍。打包处理的 Key Unrolling 优化的 CMux-based Blind Rotation 算法如下: