BFV原理(seal库)
设定三个模量
噪声预算由加密的参数所决定;同态操作会消耗掉噪声预算。全同态加密有两种操作,加法和乘法,其中加法基本从原理上几乎不消耗预算,消耗的预算最主要取决于乘法,如果乘法运算进行的太多,噪声预算归零,密文不能解密。
需要设置三个加密参数:
- poly_modulus_degree(多项式模度);
- 系数模量([密文]系数模量);
- 明文模量(明文模量;只适用于BFV方案)。
EncryptionParameter parms(scheme_type::BFV);
第一个参数是‘多项式模’的次数。这一定是2的正次幂,表示2的幂次多项式的次数;较大的poly_modulus_degree使密文的大小更大,所有的操作都更慢,但允许更复杂的加密计算。推荐值为1024、2048、4096、8192、16384、32768。
size_t poly_modulus_degree = 4096;
parms.set_poly_modulus_degree(poly_modulus_degree);
系数模量(coeff_modules)。该参数是一个大整数,它是不同素数的乘积,每个素数的大小最大为60位。它被表示为这些素数的一个向量,每个素数由smallmodules类的一个实例表示.coeff_modules的位长是指它的质数因子的位长之和。更大的coeff_模数意味着更大的噪声预算,因此更加密的计算能力。然而,coeff_modulus_degree确定了coeff_modul_modules总比特长度的上限,对于seal库,具体如下:
| 1024 | 27 |
| 2048 | 54 |
| 4096 | 109 |
| 8192 | 218 |
| 16384 | 438 |
| 32768 | 881 |
明文模量是特定于BFV方案的,在使用CKKS方案时无法设置,它决定了明文的大小范围,同时也影响着加密操作的安全性和效率
生成公钥和私钥
BFV的公钥使用随机种子生成,私钥SK是 random ternary polynomial, 也就是系数取自 R 2 = − 1 , 0 , 1 R_{2}=-1,0,1 R2=−1,0,1 的多项式。
公钥PK是
R
q
R_q
Rq上的多项式,由一对多项式构成:
(
P
K
1
,
P
K
2
)
(PK_1,PK_2)
(PK1,PK2), 定义如下
P
K
1
=
[
−
1
(
a
⋅
S
K
+
e
)
]
q
P
K
2
=
a
\begin{aligned}\mathsf{PK}_1&=[-1(a\cdot\mathsf{SK}+e)]_q\\\mathsf{PK}_2&=a\end{aligned}
PK1PK2=[−1(a⋅SK+e)]q=a
其中 a a a是采样自 R q R_q Rq上的随机多项式, e e e是采样自 χ \chi χ的随机多项式。符号 [ ⋅ ] q [\cdot]_q [⋅]q表示多项式的系数运算以 q q q为模数进行。总之, a a a定义 R q R_q Rq上,所有运算都定义在 Z q Z_q Zq上面模 ( x n + 1 ) (x^n+1) (xn+1)的多项式环。
加解密
·加密:明文
M
M
M,产生三个小的随机多项式,
u
∈
R
2
,
e
1
,
e
2
∈
X
u\in R_2,e_1,e_2\in\mathcal{X}
u∈R2,e1,e2∈X,加密结果
C
=
(
C
1
,
C
2
)
\mathcal{C}=(\mathcal{C}_1,\mathcal{C}_2)
C=(C1,C2),其中缩放系
数
Δ
=
⌊
q
t
⌋
\Delta=\lfloor\frac qt\rfloor
Δ=⌊tq⌋,用于将明文
M
M
M从
Z
t
Z_t
Zt扩展到密文的模空间
Z
q
Z_q
Zq上:
C
1
=
[
P
K
1
⋅
u
+
e
1
+
Δ
M
]
q
C
2
=
[
P
K
2
⋅
u
+
e
2
]
q
\begin{aligned}&\mathsf{C}_1=[\mathsf{PK}_1\cdot u+e_1+\Delta\mathsf{M}]_q\\&\mathsf{C}_2=[\mathsf{PK}_2\cdot u+e_2]_q\end{aligned}
C1=[PK1⋅u+e1+ΔM]qC2=[PK2⋅u+e2]q
·解密:解密过程如下,最后并将加密时应用的缩放系数倒置:
M
=
[
⌊
t
[
C
1
+
C
2
⋅
S
K
]
q
q
⌉
]
t
\mathsf{M}=\left[\left\lfloor\frac{t[\mathsf{C}_1+\mathsf{C}_2\cdot\mathsf{SK}]_q}q\right\rceil\right]_t
M=[⌊qt[C1+C2⋅SK]q⌉]t
·解密过程是可验证的:
C
1
+
C
2
⋅
S
K
=
P
K
1
⋅
u
+
e
1
+
Δ
M
+
(
P
K
2
⋅
u
+
e
2
)
⋅
S
K
=
−
(
a
⋅
S
K
+
e
)
⋅
u
+
e
1
+
Δ
M
+
a
⋅
u
⋅
S
K
+
e
2
⋅
S
K
=
−
a
⋅
u
⋅
S
K
−
e
⋅
u
+
e
1
+
Δ
M
+
a
⋅
u
⋅
S
K
+
e
2
⋅
S
K
v
=
Δ
М
−
e
⋅
u
+
e
1
+
e
2
⋅
SK
=
Δ
M
+
v
\begin{aligned} C_1+C_2\cdot SK& =\mathsf{PK}_1\cdot u+e_1+\Delta\mathsf{M}+(\mathsf{PK}_2\cdot u+e_2)\cdot\mathsf{SK} \\ &=-(a\cdot\mathsf{SK}+e)\cdot u+e_1+\Delta\mathsf{M}+a\cdot u\cdot\mathsf{SK}+e_2\cdot\mathsf{SK} \\ &=-a\cdot u\cdot\mathsf{SK}-e\cdot u+e_1+\Delta\mathsf{M}+a\cdot u\cdot\mathsf{SK}+e_2\cdot\mathsf{SK}v \\ &=\Delta\text{М}-e\cdot u+e_1+e_2\cdot\text{SK} \\ &=\Delta\mathsf{M}+v \end{aligned}
C1+C2⋅SK=PK1⋅u+e1+ΔM+(PK2⋅u+e2)⋅SK=−(a⋅SK+e)⋅u+e1+ΔM+a⋅u⋅SK+e2⋅SK=−a⋅u⋅SK−e⋅u+e1+ΔM+a⋅u⋅SK+e2⋅SKv=ΔМ−e⋅u+e1+e2⋅SK=ΔM+v
解密中的四舍五入 (rounding) 取整可以去除
t
q
⋅
v
\frac tq\cdot v
qt⋅v,最后模t运算去除
t
⋅
r
t\cdot r
t⋅r并恢复得到M。要保证解密成功,必须保证误差多项式
v
v
v:
t
q
⋅
∣
v
∣
<
1
2
\frac tq\cdot|v|<\frac12
qt⋅∣v∣<21。
同态加
同态加,需要将对应的多项式相加:
E
v
a
l
A
d
d
(
C
(
1
)
,
C
(
2
)
)
=
(
[
C
1
(
1
)
+
C
1
(
2
)
]
q
,
[
C
2
(
1
)
+
C
2
(
2
)
]
q
)
=
(
C
1
(
3
)
,
C
2
(
3
)
)
=
C
(
3
)
\mathsf{EvalAdd}(\mathsf{C}^{(1)},\mathsf{C}^{(2)})=([\mathsf{C}_1^{(1)}+\mathsf{C}_1^{(2)}]_q,[\mathsf{C}_2^{(1)}+\mathsf{C}_2^{(2)}]_q)=(\mathsf{C}_1^{(3)},\mathsf{C}_2^{(3)})=\mathsf{C}^{(3)}
EvalAdd(C(1),C(2))=([C1(1)+C1(2)]q,[C2(1)+C2(2)]q)=(C1(3),C2(3))=C(3)
注意到这里随机误差相加,最坏情况是误差都增长一倍(概率很小),但是一般来说,这两个误差不会累加增大。
同态乘
同态乘过程相比加法很复杂,,由于上述解密过程用的是
(
C
(
1
)
⋅
C
(
2
)
)
(
S
K
)
\mathcal{(C}^{(1)}\cdot\mathcal{C}^{(2)})(\mathcal{SK})
(C(1)⋅C(2))(SK), 也就是我们要计算
(
C
1
(
1
)
+
C
2
(
1
)
⋅
S
K
)
⋅
(
C
1
(
2
)
+
C
2
(
2
)
⋅
S
K
)
(\mathsf{C}_1^{(1)}+\mathsf{C}_2^{(1)}\cdot\mathsf{SK})\cdot(\mathsf{C}_1^{(2)}+\mathsf{C}_2^{(2)}\cdot\mathsf{SK})
(C1(1)+C2(1)⋅SK)⋅(C1(2)+C2(2)⋅SK)
因此如果想要用
S
K
SK
SK进行解密,我们需要保留三项中间结果,即密文维度扩展了一维变成三维。
给出其公式:
E
v
a
l
M
u
l
t
(
C
(
1
)
,
C
(
2
)
)
=
(
[
⌊
t
(
C
1
(
1
)
⋅
C
1
(
2
)
)
q
⌉
]
q
,
[
⌊
t
(
C
1
(
1
)
⋅
C
2
(
2
)
+
C
2
(
1
)
⋅
C
1
(
2
)
)
q
⌉
]
q
,
[
⌊
t
(
C
2
(
1
)
⋅
C
2
(
2
)
)
q
⌉
]
q
\begin{aligned} \mathsf{EvalMult}(\mathsf{C}^{(1)},\mathsf{C}^{(2)})& =\left(\left[\left\lfloor\frac{t(\mathsf{C}_1^{(1)}\cdot\mathsf{C}_1^{(2)})}{q}\right\rceil\right]_q,\left[\left\lfloor\frac{t(\mathsf{C}_1^{(1)}\cdot\mathsf{C}_2^{(2)}+\mathsf{C}_2^{(1)}\cdot\mathsf{C}_1^{(2)})}{q}\right\rceil\right]_q,\right. \\ &\left[\left\lfloor\frac{t(\mathsf{C}_2^{(1)}\cdot\mathsf{C}_2^{(2)})}q\right\rceil\right]_q \end{aligned}
EvalMult(C(1),C(2))=
[⌊qt(C1(1)⋅C1(2))⌉]q,[⌊qt(C1(1)⋅C2(2)+C2(1)⋅C1(2))⌉]q,[⌊qt(C2(1)⋅C2(2))⌉]q
由此导致了一个严重的问题,同态乘法进行多次后会使得计算复杂度、密文冗余快速增大,也就是有限次数的同态加密。为了做到全同态加密,BFV方案给出了一个安全并且有效的解决方案:利用额外的评估密钥
E
K
EK
EK进行Relinearization,既可以降维度,又可以减少误差的累积,从而达到全同态加密的效果。
线性重构
这是BFV全同态加密的一个重要部分。这个部分的主要目的是将同态乘积得到的3维密文空间,即从EvalMult产生的那些密文,减少到2维,消去二次项的影响。
C
∗
=
{
C
1
∗
,
C
2
∗
,
C
3
∗
}
\mathbb{C}^*=\{\mathbb{C}_1^*,\mathbb{C}_2^*,\mathbb{C}_3^*\}
C∗={C1∗,C2∗,C3∗},我们需要找到
C
^
∗
=
{
C
^
1
∗
,
C
^
2
∗
}
\hat{\mathbf{C}}^*=\{\hat{\mathbf{C}}_1^*,\hat{\mathbf{C}}_2^*\}
C^∗={C^1∗,C^2∗},使得:
[
C
1
∗
+
C
2
∗
⋅
S
K
+
C
3
∗
⋅
S
K
2
]
q
≈
[
C
^
1
∗
+
C
^
2
∗
⋅
S
K
+
r
]
q
[\mathsf{C}_1^*+\mathsf{C}_2^*\cdot\mathsf{SK}+\mathsf{C}_3^*\cdot\mathsf{SK}^2]_q\approx[\hat{\mathsf{C}}_1^*+\hat{\mathsf{C}}_2^*\cdot\mathsf{SK}+r]_q
[C1∗+C2∗⋅SK+C3∗⋅SK2]q≈[C^1∗+C^2∗⋅SK+r]q
E
K
=
(
E
K
1
,
E
K
2
)
=
(
−
(
a
⋅
S
K
+
e
)
+
S
K
2
,
a
)
\mathsf{EK}=(\mathsf{EK}_1,\mathsf{EK}_2)=(-(a\cdot\mathsf{SK}+e)+\mathsf{SK}^2,a)
EK=(EK1,EK2)=(−(a⋅SK+e)+SK2,a),这就是一个私钥平方
S
K
2
\mathsf{SK}^2
SK2加入掩码进行保护,注意到
E
K
1
+
E
K
2
⋅
S
K
=
S
K
2
−
e
EK_1+EK_2\cdot SK=SK^2-e
EK1+EK2⋅SK=SK2−e,通过如下方法得到
C
∗
^
\hat{C^*}
C∗^:
c
^
1
∗
=
[
C
1
∗
+
E
K
1
⋅
C
3
∗
]
q
c
^
2
∗
=
[
C
2
∗
+
E
K
2
⋅
C
3
∗
]
q
\begin{aligned}\hat{c}_1^*&=[\mathsf{C}_1^*+\mathsf{EK}_1\cdot\mathsf{C}_3^*]_q\\\hat{c}_2^*&=[\mathsf{C}_2^*+\mathsf{EK}_2\cdot\mathsf{C}_3^*]_q\end{aligned}
c^1∗c^2∗=[C1∗+EK1⋅C3∗]q=[C2∗+EK2⋅C3∗]q
此时:
C
^
1
∗
+
C
^
2
∗
⋅
S
K
=
C
1
∗
+
E
K
1
⋅
C
3
∗
+
S
K
⋅
(
C
2
∗
+
E
K
2
⋅
C
3
∗
)
=
C
1
∗
+
C
2
∗
⋅
S
K
+
C
3
∗
⋅
(
E
K
1
+
E
K
2
⋅
S
K
)
=
C
1
∗
+
C
2
∗
⋅
S
K
+
C
3
∗
⋅
S
K
2
+
C
3
∗
⋅
e
\begin{aligned} \hat{\mathsf{C}}_1^*+\hat{\mathsf{C}}_2^*\cdot\mathsf{SK}& =\mathsf{C}_1^*+\mathsf{EK}_1\cdot\mathsf{C}_3^*+\mathsf{SK}\cdot(\mathsf{C}_2^*+\mathsf{EK}_2\cdot\mathsf{C}_3^*) \\ &=\mathsf{C}_1^*+\mathsf{C}_2^*\cdot\mathsf{SK}+\mathsf{C}_3^*\cdot(\mathsf{EK}_1+\mathsf{EK}2\cdot\mathsf{SK}) \\ &=\mathsf{C}_1^*+\mathsf{C}_2^*\cdot\mathsf{SK}+\mathsf{C}_3^*\cdot\mathsf{SK}^2+\mathsf{C}_3^*\cdot e \end{aligned}
C^1∗+C^2∗⋅SK=C1∗+EK1⋅C3∗+SK⋅(C2∗+EK2⋅C3∗)=C1∗+C2∗⋅SK+C3∗⋅(EK1+EK2⋅SK)=C1∗+C2∗⋅SK+C3∗⋅SK2+C3∗⋅e
这就是之前得到的同态乘法对应的正确解密结果加一个误差值,值得注意的是,论文中描述最后一个误差项 C 3 ∗ ⋅ e \mathbb{C}_3^*\cdot e C3∗⋅e可能很大,因为 C 3 ∗ \mathbb{C}_3^* C3∗的系数定义在 Z q Z_q Zq上。