META-BTS: Bootstrapping Precision Beyond the Limit
Abstract
Bootstrapping 是HE中必不可少的步骤,它通过恢复密文模数来实现可以无限次同态操作的FHE。然而Bootstrapping是HE中最消耗时间和内存的操作。且随着Bootstrapping精度的增加,大量的计算资源也被需要。特别地,先前所设计的所有Bootstrapping操作,其精度都受限于Rescaling的精度。
本文提出了一种新的Bootstrapping算法用于CKKS,该算法需要重复使用先前已知的Bootstrapping算法,所以称其为"Meta-BTS"。通过重复两次原始Bootstrapping,可以获得一个新的精度翻倍的Bootstrapping。当密文尺寸足够大,该算法可以被归纳为 k − f o l d k-fold k−fold Bootstrapping操作,其中 k > 1 k>1 k>1。
Keywords: FHE, CKKS, Approximate Bootstrapping, High Precision, Small parameters.
1 Introduction
HE指的是一类允许在加密数据上进行计算的加密方案。CKKS由于其天然以实数和复数向量作为明文空间,因此它成为目前最显著的HE方案。
为了支持复杂的应用程序,HE应该有更快的同态操作以及能够评估巨大深度的电路。然而由于同态操作的前进,密文模数会降低,直到模数足够小而不能维持进一步的操作。为了解决这个问题,提出了重加密密文的操作,即Bootstrapping,它可以刷新密文从而让模数得到恢复,以支持更多的同态操作。
在CKKS中对密文进行Bootstrapping操作实际上是同态地评估一个必不可少的模约减函数。CKKS本身仅支持同态加法和同态乘法,但是可以通过这些操作近似组合得到模约减函数的近似评估,但是很明显这会消耗大量的模量和计算资源,这也是制约CKKS的瓶颈。
此外,在HE的实际使用中,有许多情况都需要高精度的Bootstrapping。因为密文在每次同态操作和Bootstrapping操作中都会损失一定的精度。
为了解决该问题,本文提出了一个新颖的Bootstrapping算法,称为"Meta-BTS"。
1.1 Over of Our Algorithm
CKKS Bootstrapping可以理解为解密电路的同态评估以重加密密文。在每次的Bootstrapping操作中,都会给密文添加Bootstrapping误差,原因是模约减函数是通过评估近似多项式实现的。这里简单给出 "Meta-BTS"算法的主要idea。
(1)使用Bootstraped Ciphertext减去Original Ciphertext来提取Bootstrapping error。
(2)对Bootstrapping error 进行一次Bootstrap,得到Bootstraped error。
(3)使用Bootstraped Ciphertext 减去Bootstraped error。
通过重复该步骤,可以在一定程度上从Bootstraped Ciphertext中移除Bootstrapping error,从而获得更高精度的自举密文。
Techniques
如图1所示,本文描述了如何使用n-bit精度的Bootstrapping算法 B T S ( 1 ) BTS^{(1)} BTS(1)实现新的2n-bit精度的bootstrapping算法 B T S ( 2 ) BTS^{(2)} BTS(2)。
在定义bootstrapping和它的精度之前,我们首先定义一下CKSK的密文为: c t ( m , q ) ∈ R q 2 ct(m,q)\in R_q^2 ct(m,q)∈Rq2表示模q下对m加密得到的密文。
现在我们定义bootstrapping的精度。通过对密文 c t ( 2 r m , q ) ct(2^rm,q) ct(2rm,q)应用bootstrapping操作,我们可以获得一个新的密文 c t B T S ( 2 r m + 2 − n e , Q r e m ) ct_{BTS}(2^rm+2^{-n}e,Q_{rem}) ctBTS(2rm+2−ne,Qrem), Q r e m Q_{rem} Qrem是bootstrapping后密文模数, ∣ ∣ e ∣ ∣ ∞ ≤ 1 ||e||_\infin \leq 1 ∣∣e∣∣∞≤1。此时,我们定义这个Bootstrapping的精度为"r+n"。
2-fold Bootstrapping 是Meta-BTS中最简单的情况,包含两次Bootstrapping操作:Bootstrapping the Ciphertext 和Bootstrapping the error。
Bootstrapping of a Ciphertext
给定一个密文 c t I = c t ( 2 n ⋅ m , 2 n ⋅ q ) ct_I=ct(2^n·m,2^n·q) ctI=ct(2n⋅m,2n⋅q),其中 ∣ ∣ m ∣ ∣ ∞ ≤ 1 ||m||_\infin \leq 1 ∣∣m∣∣∞≤1,然后通过 2 n 2^n 2n重缩放该密文,然后得到新的密文 c t 1 = c t ( m , q ) ct_1=ct(m,q) ct1=ct(m,q)。
然后对密文 c t 1 ct_1 ct1执行n-bit 精度的 B T S ( 1 ) BTS^{(1)} BTS(1),获得新的密文 c t 2 = c t ( m + 2 − n ⋅ e 1 , Q r e m ) ct_2=ct(m+2^{-n}·e_1,Q_{rem}) ct2=ct(m+2−n⋅e1,Qrem),其中 ∣ ∣ e 1 ∣ ∣ ∞ ≤ 1 ||e_1||_{\infin}\leq 1 ∣∣e1∣∣∞≤1。然后给 c t 2 ct_2 ct2乘以 2 n 2^n 2n,获得新的密文 c t 3 = c t ( 2 n ⋅ m + e 1 , Q r e m ) ct_3=ct(2^n·m+e_1,Q_{rem}) ct3=ct(2n⋅m+e1,Qrem)。
然后计算Bootstrapping error, c t e r r o r = [ c t 3 ] q − [ c t I ] q = c t ( e 1 , q ) ct_{error} = [ct_3]_q-[ct_I]_q=ct(e_1,q) cterror=[ct3]q−[ctI]q=ct(e1,q)。现在我们获得了密文的自举误差 e 1 e_1 e1。
Bootstrapping error
现在,对密文 c t e r r o r ct_{error} cterror执行n-bit精度的 B T S ( 1 ) BTS^{(1)} BTS(1),获得新的密文 c t 4 = c t ( e 1 + 2 − n ⋅ e 2 , Q r e m ) ct_4=ct(e_1+2^{-n}·e_2,Q_{rem}) ct4=ct(e1+2−n⋅e2,Qrem),其中 ∣ ∣ e 2 ∣ ∣ ∞ ≤ 1 ||e_2||_{\infin} \leq 1 ∣∣e2∣∣∞≤1。
最后,我们计算 c t o = c t 3 − c t 4 = c t ( 2 n ⋅ m − 2 − n ⋅ e 2 , Q r e m ) ct_o=ct_3-ct_4=ct(2^n·m-2^{-n}·e_2,Q_{rem}) cto=ct3−ct4=ct(2n⋅m−2−n⋅e2,Qrem),其中 ∣ ∣ e 2 ∣ ∣ ∞ ≤ 1 ||e_2||_{\infin} \leq 1 ∣∣e2∣∣∞≤1。因此我们使用n-bit 精度的 B T S ( 1 ) BTS^{(1)} BTS(1)得到了2n-bit精度的 B T S ( 2 ) BTS^{(2)} BTS(2)。
此外,可以看到"Meta-BTS"可以很容易的扩展为迭代两次以上的BTS。
1.2 Our Contributions
本文提出了"Meta-BTS"算法,该算法可以通过迭代低精度的Bootstrapping算法获得更高精度的Bootstrapping算法。也就是说,给定FHE参数,该算法可能构建出一个精度超过现有参数限制的Bootstrapping算法。
给定一个n-bit精度的 B T S ( 1 ) BTS^{(1)} BTS(1),以及一个范围在 [ − 1 , 1 ] [-1, 1] [−1,1]中的输入,则我们只需要迭代k次就可以获得一个kn-bit精度的 B T S ( k ) BTS^{(k)} BTS(k)。从这里可以看到,"Meta-BTS"不需要改变FHE参数就可以得到更高精度的Bootstrapping算法。
本文所提算法将自举算法视为黑盒,也就是说该算法适用于所有的CKKS自举算法,可以使用现有的自举算法来构建更高精度的自举算法。
1.3 Related Works
2 Background
2.1 Notation
2.2 The CKKS scheme
2.3 Bootstrapping of the CKKS scheme
针对CKKS的Bootstrapping的研究已经足够广泛,尽管它们在细节方面不同,但是所有的CKKS自举程序都包含四个步骤: StC, ModRaise, Cts, EvalMod。
Slot to Coefficient(StC). 在CKKS中,标准嵌入可以将复数向量编码为一个多项式。同态操作执行在slot-wise,而改变密文的模数大小,仅仅能应用于密文多项式的系数中。因此,为了模增加,所以需要执行同态线性变换,将slot中的值移动到系数上。
Modulus raising(ModRaise).ModRaise 增加密文模数到更大的模数以恢复密文的级别。设 c t ( m , Q l ) = ( b = − a s + m ( X ) + e , a ) m o d Q l ct(m,Q_l)=(b=-as+m(X)+e,a) \ \ mod \ Q_l ct(m,Ql)=(b=−as+m(X)+e,a) mod Ql是一个密文,其中 m ( X ) = E c d ( m , Δ ) m(X)=Ecd(m,\Delta) m(X)=Ecd(m,Δ)。仅仅通过改变该密文的模数,则可以得到新的密文 c t ( m ′ , Q L ) ct(m',Q_L) ct(m′,QL),其中 Q l < Q L Q_l<Q_L Ql<QL。且有 m ′ = D c d ( m ( X ) + Q l I ( X ) , Δ ) m'=Dcd(m(X)+Q_lI(X),\Delta) m′=Dcd(m(X)+QlI(X),Δ),其中 I ( X ) ∈ Z [ X ] / ( X N + 1 ) I(X)\in \mathbb{Z}[X]/(X^N+1) I(X)∈Z[X]/(XN+1)。
Coefficient to Slot (CtS).为了计算模约减函数,需要执行一个同态线性变换从而将系数上的值移动到solt中。然后密文中的每个solt中的值分别为 m i + Q l I i m_i+Q_lI_i mi+QlIi,其中 m i + Q l I i m_i+Q_lI_i mi+QlIi是多项式 m ( X ) + Q l I ( X ) m(X)+Q_lI(X) m(X)+QlI(X)的第 i i i个系数。
Approximate Evaluation of the Modular Reduction(EvalMod).在这一步需要执行模约减函数的近似评估。模约减函数不能被加法和减法精确的表达,但是它可以通过多项式来近似。正是因为这种近似,引入了Bootstrapping误差,该误差远大于同态操作期间由Rescaling操作引入的误差。已经有各种各样的研究来减小这种近似所带来的误差。
Definition 2.1 (BTS) : Bootstrapping算法是一种允许重加密密文并使得同态操作可以持续进行的算法。Bootstrapping简称为BTS,如下所示:
- B T S ( c t ( m , q ) , b t k ) → c t B T S = c t ( m ′ , Q r e m ) BTS(ct(m,q),btk)\rightarrow ct_{BTS}=ct(m',Q_{rem}) BTS(ct(m,q),btk)→ctBTS=ct(m′,Qrem):给定Bootstrapping计算公钥 b t k btk btk和一个密文 c t ( m , q ) ct(m,q) ct(m,q),其中消息 ∣ ∣ m ∣ ∣ ∞ ≤ 2 r ||m||_{\infin}\leq 2^r ∣∣m∣∣∞≤2r,对于某些r。然后Bootstrapping算法返回一个密文 c t B T S ( m ′ , Q r e m ) ct_{BTS}(m',Q_{rem}) ctBTS(m′,Qrem),其中 Q r e m > q Q_{rem}>q Qrem>q是Bootstrapping算法之后得到的密文模数。
其中 ∣ ∣ m ∣ ∣ ∞ ||m||_\infin ∣∣m∣∣∞的上界限 2 r 2^r 2r被称为BTS的输入界限,当输入界限为1时,称此时的BTS是标准的。
Definition 2.2(
P
E
R
F
B
T
S
PERF_{BTS}
PERFBTS):给定一个bootstrapping算法BTS,
P
E
R
F
B
T
S
PERF_{BTS}
PERFBTS是一种测量BTS性能的方法:
P
E
R
F
B
T
S
=
(
P
r
e
c
i
s
i
o
n
,
R
e
m
a
i
n
M
o
d
u
l
u
s
,
T
i
m
e
)
PERF_{BTS}=(Precision,RemainModulus,Time)
PERFBTS=(Precision,RemainModulus,Time)
- P E R F B T S . P r e s i o n → r + n PERF_{BTS}.Presion \rightarrow r+n PERFBTS.Presion→r+n:
- P E R F B T S . R e m a i n M o d u l u s → Q r e m / q PERF_{BTS}.RemainModulus\rightarrow Q_{rem}/q PERFBTS.RemainModulus→Qrem/q:
- P E R F B T S . T i m e → t PERF_{BTS}.Time\rightarrow t PERFBTS.Time→t: 返回BTS的运行时间。
由于Bootstrapping是由同态操作组成的,故在自举后的密文中添加了一个误差。通过定义2.1和2.2,自举后的密文包含一个自举后的消息 m ′ = m + m + 2 − 2 e m'=m+m+2^{-2}e m′=m+m+2−2e,其中 m m m是输入密文中的消息, ∣ ∣ m ∣ ∣ ∞ ≤ 2 r ||m||_{\infin}\leq 2^r ∣∣m∣∣∞≤2r, ∣ ∣ e ∣ ∣ ∞ ≤ 1 ||e||_{\infin}\leq 1 ∣∣e∣∣∞≤1。
3 The Meta-BTS Algorithm
在本节,我们提出"Meta-BTS",一种迭代自举算法,以获得高精度的bootstrapping算法。这里我们结合不同的Bootstrapping算法来描述一个2-fold Bootstrapping算法。由于Meta-BTS将使用的Bootstrapping算法视为黑盒,故它也可以使用到未来的新的Bootstrapping算法。
3.1 Difficulties in improving the performance of bootstrapping
在CKKS的自举算法中,需要对加密数据执行模约减函数。由于CKKS仅支持同态加和同态乘操作,故需要使用多项式来近似评估模约减函数。在自举过程中,自举误差是由多项式近似的同态运算以及多次带误差的rescaling引起的。
为了获得高精度的自举,可以通过增加缩放因子 Δ \Delta Δ或者增加近似多项式的幂次来减小自举误差。由于高精度的自举算法消耗大量的密文模数,所以增加自举精度会显著降低密文模数,并导致HE参数增大。
3.2 Algorithm description
本小节中提出了一个新的算法,对自举引入的误差再进行一次自举从而得到高精度的bootstrapping。此外,本文还提出了本文方法的归纳,即重复两次以上的自举算法。在使用RNS-CKKS时,每次rescaling操作 2 n 2^n 2n意味着我们通过要给接近 2 n 2^n 2n的模数rescaling密文。
3.2.1 2-fold Bootstrapping.
本文提出一个算法,使用n-bit 精度的Bootstrapping B T S ( 1 ) BTS^{(1)} BTS(1)来构建一个2n-bit精度的Bootstrapping B T S ( 2 ) BTS^{(2)} BTS(2)。
我们以 P E R F B T S ( 1 ) = ( n , Q r e m , t ) PERF_{BTS^{(1)}}=(n,Q_{rem},t) PERFBTS(1)=(n,Qrem,t)的标准Bootstrapping算法 B T S ( 1 ) BTS^{(1)} BTS(1)开始。换句话说, B T S ( 1 ) BTS^{(1)} BTS(1)将密文 c t ( m , q ) ct(m,q) ct(m,q)转变为 c t ( m + 2 − n e , Q r e m ) ct(m+2^{-n}e,Q_{rem}) ct(m+2−ne,Qrem),其中 ∣ ∣ m ∣ ∣ ∞ ≤ 1 ||m||_{\infin}\leq 1 ∣∣m∣∣∞≤1, ∣ ∣ e ∣ ∣ ∞ ≤ 1 ||e||_{\infin}\leq 1 ∣∣e∣∣∞≤1。
B T S ( 2 ) BTS^{(2)} BTS(2)如下:
(1)给定输入密文 c t I = c t ( 2 n ⋅ m , 2 n ⋅ q ) ct_I=ct(2^n·m,2^n·q) ctI=ct(2n⋅m,2n⋅q),其中 ∣ ∣ m ∣ ∣ ∞ ≤ 1 ||m||_{\infin} \leq 1 ∣∣m∣∣∞≤1。使用 2 n 2^n 2n来Rescale c t I ct_I ctI来约减消息大小,使其适用于 B T S ( 1 ) BTS^{(1)} BTS(1)。
此时Rescale后,得到新密文 c t 1 = c t ( m + e r s , q ) ct_1=ct(m+e_{rs},q) ct1=ct(m+ers,q)。在这里,我们假设rescale 误差 e r s e_{rs} ers小于 B T S ( 1 ) BTS^{(1)} BTS(1)的误差,所以满足 ∣ ∣ e r s ∣ ∣ ∞ ≤ 2 − n ||e_{rs}||_{\infin}\leq 2^{-n} ∣∣ers∣∣∞≤2−n。
(2)然后应用 B T S ( 1 ) BTS^{(1)} BTS(1)到 c t 1 ct_{1} ct1,得到新密文 c t 2 = c t ( m + e r s + 2 − n e 1 , Q r e m ) ct_2=ct(m+e_{rs}+2^{-n}e_1,Q_{rem}) ct2=ct(m+ers+2−ne1,Qrem),其中 ∣ ∣ e 1 ∣ ∣ ∞ ||e_1||_{\infin} ∣∣e1∣∣∞。
(3)提取误差,给密文 c t 2 ct_2 ct2乘以 2 n 2^n 2n,得到新密文 c t 3 = 2 n ∗ c t 2 = c t ( 2 n m + 2 n e r s + e 1 , Q r e m ) ct_3=2^n*ct_2=ct(2^nm+2^ne_{rs}+e_1,Q_{rem}) ct3=2n∗ct2=ct(2nm+2ners+e1,Qrem)。
(4)为了在密文 c t I ct_I ctI和 c t 3 ct_3 ct3之间进行计算,我们需要对密文 c t 3 ct_3 ct3进行降模。获得新的密文 c t 4 = [ c t 3 ] 2 n q = c t ( 2 n m + 2 n e r s + e 1 , 2 n q ) ct_4=[ct_3]_{2^nq}=ct(2^nm+2^ne_{rs}+e_1,2^nq) ct4=[ct3]2nq=ct(2nm+2ners+e1,2nq)。
(5)然后计算 c t 4 − c t 1 ct_4-ct_1 ct4−ct1,获得新密文 c t 5 = c t 4 − c t I = c t ( 2 n e r s + e 1 , 2 n q ) ct_5=ct_4-ct_I=ct(2^ne_{rs}+e_1,2^nq) ct5=ct4−ctI=ct(2ners+e1,2nq)。这里,我们获得的密文 c t 5 ct_5 ct5是rescale误差和bootstrapping误差和 2 n e r s + e 1 2^ne_{rs}+e_1 2ners+e1的加密。由于 ∣ ∣ 2 n e r s + e 1 ∣ ∣ ∞ ≤ 1 ||2^ne_{rs}+e_1||_{\infin}\leq 1 ∣∣2ners+e1∣∣∞≤1。
(6)然后应用 B T S ( 1 ) BTS^{(1)} BTS(1)到密文 c t 5 ct_5 ct5,得到新密文 c t 6 = c t ( 2 n e r s + e 1 + 2 − n e 2 , Q r e m ) ct_6=ct(2^ne_{rs}+e_1+2^{-n}e_2,Q_{rem}) ct6=ct(2ners+e1+2−ne2,Qrem)。
(7)最后,计算 c t 3 − c t 6 ct_3-ct_6 ct3−ct6,得到新密文 c t o = c t ( 2 n m − 2 − n e 2 , Q r e m ) ct_o=ct(2^nm-2^{-n}e_2,Q_{rem}) cto=ct(2nm−2−ne2,Qrem)。
(8)得到 B T S ( 2 ) BTS^{(2)} BTS(2)的输出为 c t o ct_o cto。
上述所有步骤如下图2所示:
Theorem 3.1(2-fold Bootstrapping Algorithm). Given a standard bootstrapping algorithm
B
T
S
(
1
)
BTS^{(1)}
BTS(1) with performance
P
E
R
F
B
T
S
(
1
)
=
(
n
,
Q
r
e
m
/
q
,
t
)
PERF_{BTS^{(1)}}=(n,Q_{rem}/q,t)
PERFBTS(1)=(n,Qrem/q,t)
there is a bootstrapping algorithm
B
T
S
(
2
)
BTS^{(2)}
BTS(2) whose performance is
P
E
R
F
B
T
S
(
2
)
=
(
2
n
,
Q
r
e
m
/
(
2
n
q
)
,
2
t
)
PERF_{BTS^{(2)}}=(2n,Q_{rem}/(2^nq),2t)
PERFBTS(2)=(2n,Qrem/(2nq),2t)
if
Q
r
e
m
/
(
2
n
q
)
≥
1
Q_{rem}/(2^nq) \geq 1
Qrem/(2nq)≥1
3.3.3 k-fold bootstrapping.
本文提出了一个算法,通过使用n-bit精度的 B T S ( 1 ) BTS^{(1)} BTS(1)来构建一个kn-bit精度的 B T S ( k ) BTS^{(k)} BTS(k),其中k是正整数。
设 B T S ( 1 ) BTS^{(1)} BTS(1)是一个标准bootstrapping算法,其性能为 ( n , Q r e m / q , t ) (n,Q_{rem}/q,t) (n,Qrem/q,t)。假设 B T S ( k ) BTS^{(k)} BTS(k)对于正整数k满足以下条件:
(1) Input : c t ( 2 ( k − 1 ) n ⋅ m , 2 ( k − 1 ) n ⋅ q ) ct(2^{(k-1)n}·m,2^{(k-1)n}·q) ct(2(k−1)n⋅m,2(k−1)n⋅q)。
(2) Output : c t ( 2 ( k − 1 ) n m + 2 − n e k , Q r e m ) ct(2^{(k-1)n}m+2^{-n}e_k,Q_{rem}) ct(2(k−1)nm+2−nek,Qrem),其中 ∣ ∣ m ∣ ∣ ∞ , ∣ ∣ e k ∣ ∣ ∞ ≤ 1 ||m||_{\infin},||e_k||_{\infin}\leq 1 ∣∣m∣∣∞,∣∣ek∣∣∞≤1。
(3) P E R F B T S ( k ) = ( k n , Q r e m / ( 2 ( k − 1 ) n q ) , k t ) PERF_{BTS^{(k)}}=(kn,Q_{rem}/(2^{(k-1)n}q),kt) PERFBTS(k)=(kn,Qrem/(2(k−1)nq),kt)。
文中提出使用归纳法来证明,感兴趣可以尝试一下。
4 Implementation
这里的实现,使用OpenFHE库中的官方教程代码:
#include "openfhe.h"
using namespace lbcrypto;
using namespace std;
void IterativeBootstrapExample();
int main() {
IterativeBootstrapExample();
}
double CalculateApproximationError(const vector<complex<double>>& result, const vector<complex<double>>& expectedResult) {
/*
* 参数: result:真实结果,expectedResult:期待结果
* 功能:用于真实值和期待值之间的最大计算近似误差
*/
if (result.size() != expectedResult.size()) { // 比较二者的尺寸是否相同
OPENFHE_THROW("Cannot compare vectors with different numbers of elements"); // 不相同的情况下抛出异常
}
double maxError = 0;
// 使用for循环得到真实值和期待值之间,最大的误差值
for (size_t i = 0; i < result.size(); i++) { // 遍历元素
double error = abs(result[i].real() - expectedResult[i].real()); // 真实值减去期待值的绝对值
if (maxError < error) {
maxError = error;
}
}
return abs(log2(maxError)); // 返回最大误差对应的log2(*)的绝对值
}
void IterativeBootstrapExample() {
// 1. 设置rns-ckks参数,以及bootstrapping参数
CCParams<CryptoContextCKKSRNS> parameters; // 声明rns-ckks参数对象
SecretKeyDist secretKeyDist = UNIFORM_TERNARY; // 指定密钥分布形式
parameters.SetSecretKeyDist(secretKeyDist); // 选择密钥分布形式
parameters.SetSecurityLevel(HEStd_NotSet); // 选择安全级别
parameters.SetRingDim(1<<12); // 设置Ringim
ScalingTechnique rescaleTech = FLEXIBLEAUTO; // 指定rescale技术类别
usint dcrtBits = 59; // 设置模链中的模大小
usint firstMod = 60; // 设置模链中第一个模的大小
parameters.SetScalingModSize(dcrtBits); // 选择模链大小
parameters.SetScalingTechnique(rescaleTech); // 选择rescale技术
parameters.SetFirstModSize(firstMod); // 选择模链第一个模的大小
uint32_t numIterations = 2; // 设置迭代自举的次数
vector<uint32_t> levelBudget = {3, 3}; // 设置自举过程中同态编码和解码消耗的级别预算
vector<uint32_t> bsgsDim = {0, 0}; // ???
uint32_t levelsAvailableAfterBootstrap = 10; // 设置自举后期待密文拥有的深度
usint depth = levelsAvailableAfterBootstrap // 设置初始rns-ckks深度
+ FHECKKSRNS::GetBootstrapDepth(levelBudget, secretKeyDist)
+ (numIterations - 1);
parameters.SetMultiplicativeDepth(depth); // 设置深度
// 2. 根据参数创建context
CryptoContext<DCRTPoly> context = GenCryptoContext(parameters); // 根据上述参数创建context
cout << "CKKS scheme is using ring dimension " << context->GetRingDimension() << endl;
// 3. 使能各种操作
context->Enable(PKE); // 使能公钥方案
context->Enable(KEYSWITCH); // 使能key switching
context->Enable(LEVELEDSHE); // 使能leveledshe
context->Enable(ADVANCEDSHE); // 使能advancedshe
context->Enable(FHE); // 使能fhe
// 4. 初始化bootstrapping
uint32_t numSlots = 8; //使用稀疏打包方式
context->EvalBootstrapSetup(levelBudget, bsgsDim, numSlots); // 自举初始化
// 5. 创建各种key,仅有私钥和公钥是被提取出来的,其余的各种计算公钥key均蕴含在context对象中
auto keys = context->KeyGen(); // 密钥对生成
auto sk = keys.secretKey; // 提取解密私钥
auto pk = keys.publicKey; // 提取加密公钥
context->EvalMultKeyGen(sk); // 重线性化计算公钥生成
context->EvalBootstrapKeyGen(sk, numSlots); // 自举计算公钥生成
// 6. 创建消息向量
vector<double> x = {0.5, 0.2, 0.1, 0.6, 0.7, 0.8, 0.1, 0.2}; // 消息向量
// 7. 编码为明文多项式
Plaintext pt = context->MakeCKKSPackedPlaintext(x, 1, depth-1, nullptr, numSlots); // 编码
pt->SetLength(numSlots);
cout << "Input : " << pt << endl;
// 8. 加密得到密文
auto ct = context->Encrypt(pk, pt); // 加密
// 9. 对密文进行一次自举,即BTS^(1)
auto ciphertextAfter = context->EvalBootstrap(ct); // 对密文进行自举
// 10. 解密自举后的密文
Plaintext result; // 声明一个空的明文多项式
context->Decrypt(sk, ciphertextAfter, &result); // 解密
result->SetLength(numSlots);
// 11. 调用CalculateApproximationError()函数,查看自举一次后的精度值
uint32_t precision = floor(CalculateApproximationError(result->GetCKKSPackedValue(), pt->GetCKKSPackedValue())); // 精度
// 12. 打印输出
cout << "一次迭代自举得到的密文精度为 : " << precision << endl;
// 13.
// precision = 17;
cout << "Precision input to algorithm : " << precision << endl;
// 14. 对原密文进行二次迭代自举,即Meta-BTS(BTS^(2))
auto ciphertextTwoIterations = context->EvalBootstrap(ct, numIterations, precision);
// 15. 解密自举后的密文
Plaintext resultTwoIterations;
context->Decrypt(sk, ciphertextTwoIterations, &resultTwoIterations);
result->SetLength(numSlots);
auto actualResult = resultTwoIterations->GetCKKSPackedValue();
cout << "两次自举得到的密文结果为 : " << actualResult << endl;
// 16. 调用CalculateApproximationError()函数,查看二次迭代自举后的精度值
double precisionMultipleIterations = CalculateApproximationError(actualResult, pt->GetCKKSPackedValue());
cout << "两次迭代自举得到的密文精度为 : " << precisionMultipleIterations << endl;
cout << "两次迭代自举后得到的密文保留的深度为 : " << depth - ciphertextTwoIterations->GetLevel() - (ciphertextTwoIterations->GetNoiseScaleDeg() - 1) << endl;
}
5 Conclusion
本文提出了CKKS的高精度Bootstrapping算法,称为"Meta-BTS"。