之前看了好多资料,发现对于BGV的介绍都比较少,大家都主要关注于CKKS。其实在一些整数域上面的计算BGV还是很有优势的,与CKKS相比,BGV是一个确定性的加密方案,与BFV相比,BGV的乘法在RNS下实现要简单非常多。所以在某些场景下(比如有限域上的MPC与HE结合)会更加偏向于使用BGV方案,而且BGV方案也相对最易懂。
最初的BGV文章,但是主要关注于LWE上面。
关于BGV的两篇优化,作者都是(Gentry,Halevi,Smart),所以叫做GHS优化。
这篇文章是将SIMD的,SIMD技术可以说是RLWE对于LWE的一个碾压性的优势之一了。作者是Smart和Vercauteren。
上面三篇文章都是Halevi和Shoup写的,关于Helib中如何实现BGV方案并优化,以及如何对于BGV做Bootstrapping。
首先BGV最基本的加密形式是:
在这里我们只看对称加密,因为公钥加密与对称加密的密文形式是一致的。
对于LWE类型的密文来说,
首先有一些公开参数:明文模数 t t t,密文模数 q q q,向量维度 n n n
取私钥为 s ∈ Z q n \mathbf{s} \in \Z_q^n s∈Zqn,对于明文 m ∈ Z t m\in \Z_t m∈Zt
选取 a ∈ Z q n \mathbf{a}\in \Z_q^n a∈Zqn, b = ⟨ a , s ⟩ + m + t e m o d q b=\langle \mathbf{a},\mathbf{s}\rangle + m +te \bmod q b=⟨a,s⟩+m+temodq。 e e e是从高斯分布中选取的整数。
令密文 c = ( b , a ) c=(b,\mathbf{a}) c=(b,a)。
则解密为
先计算 μ = b − ⟨ a , s ⟩ = m + t e m o d q \mu = b- \langle \mathbf{a},\mathbf{s} \rangle = m+te \bmod q μ=b−⟨a,s⟩=m+temodq。然后计算 m = [ μ ] t = m m=[\mu]_t=m m=[μ]t=m。
这里的 ⟨ ⋅ ⟩ \langle \cdot \rangle ⟨⋅⟩为内积操作,对于 a = ( a 0 , . . . , a n − 1 ) , s = ( s 0 , . . . , s n − 1 ) \mathbf{a}=(a_0,...,a_{n-1}),\mathbf{s}=(s_0,...,s_{n-1}) a=(a0,...,an−1),s=(s0,...,sn−1)来说, ⟨ a , s ⟩ = a 0 s 0 + a 1 s 1 + ⋯ + a n − 1 s n − 1 ∈ Z \langle \mathbf{a},\mathbf{s}\rangle=a_0s_0+a_1s_1+\cdots+a_{n-1}s_{n-1}\in\Z ⟨a,s⟩=a0s0+a1s1+⋯+an−1sn−1∈Z。
[ μ ] t [\mu]_t [μ]t其实等价于 μ m o d t \mu \bmod t μmodt。
对于RLWE类型的密文来说,
公开参数为:明文模数 t t t,多项式空间 R = Z [ X ] / X n + 1 \mathcal{R}=\Z[X]/X^n+1 R=Z[X]/Xn+1,以及系数模 q q q的多项式空间 R q = Z q [ X ] / X n + 1 \mathcal{R}_q=\Z_q[X]/X^n+1 Rq=Zq[X]/Xn+1。
取私钥为 s ∈ R q s\in \mathcal{R}_q s∈Rq,对于明文 m ∈ R t m\in R_t m∈Rt:
选取 a ∈ R q , b = a s + m + t e ∈ R q a\in \mathcal{R}_q,b=as+m+te \in \mathcal{R}_q a∈Rq,b=as+m+te∈Rq, e e e是一个系数满足高斯分布的多项式。
令密文为 c = ( b , a ) c=(b,a) c=(b,a)
则解密为
先计算 μ = b − a s = m + t e ∈ R q \mu = b-as=m+te\in \mathcal{R}_q μ=b−as=m+te∈Rq,然后计算 m = [ μ ] t ∈ R t m=[\mu]_t\in\mathcal{R}_t m=[μ]t∈Rt。
这里可以看到RLWE类型的密文相对于LWE类型的密文来说的一个优势在于,一个LWE的密文的长度是 n + 1 n+1 n+1,对应的明文是 Z t \Z_t Zt内的,相当于有效信息只有1个,利用率为 1 n + 1 \frac{1}{n+1} n+11;而RLWE的密文长度是 2 n 2n 2n,对应的明文是 R t \mathcal{R}_t Rt内的,有效信息最多有 n n n个,利用率为 1 2 \frac{1}{2} 21。如果使用SIMD的技术的话,可以将这 n n n位都有效的利用起来。
关于SIMD的技术,SV的文章我还没有看,但现在BGV和BFV类型的SIMD应该都用的是INTT来做encoding的吧,可以参考一下CKKS的Encoding。思想是类似的。
注意到在解密过程中,是先得到了 m + t e m o d q m+te \bmod q m+temodq,然后再模 t t t得到 m m m的。这里一个很重要的条件就是 ( m + t e ) < q (m+te)(m+te)<q
,BGV将 φ s ( c ) = b − a s = m + t e \varphi_s(c)=b-as=m+te φs(c)=b−as=m+te这一项称作噪声,一个很重要的条件就是噪声的大小要 < q <q
。如果是一个中心取模的方案,还要额外地要求噪声的大小 < q 2 <\frac{q}{2} <2q。
注:后面的符号表示都是针对基于RLWE的BGV方案了。
感觉BGV里面最核心的技术应该就是Modulus Switching了,因为只有这个方案这么用,像Key Switching那种,基本所有同态方案都有使用。
首先,Modulus Switching是干什么的,直观上理解,modulus switching是将一个密文模数 q q q转换到另一个密文模数 q ′ q' q′上。
但这样有什么用处呢?
那首先要看一下乘法的密文噪声:
前面我们已经定义了,所谓的噪声就是 φ s ( c ) = ( m + t e ) \varphi_s(c)=(m+te) φs(c)=(m+te),对于两个不同的密文, c 1 = E n c ( m 1 ) , c 2 = E n c ( m 2 ) c_1 = Enc(m_1),c_2=Enc(m_2) c1=Enc(m1),c2=Enc(m2), φ ( c 1 ) = m 1 + t e 1 , φ ( c 2 ) = m 2 + t e 2 \varphi(c_1)=m_1+te_1,\varphi(c_2)=m_2+te_2 φ(c1)=m1+te1,φ(c2)=m2+te2。两个的乘法的噪声为 φ ( c 1 c 2 ) = φ ( c 1 ) ⋅ φ ( c 2 ) = ( m 1 + t e 1 ) ( m 2 + t e 2 ) = m 1 m 2 ⏟ < t 2 + t ( m 1 e 2 + m 2 e 1 ) ⏟ < t 2 ∣ e ∣ + t 2 e 1 e 2 ⏟ < t 2 ∣ e ∣ 2 \varphi(c_1c_2) = \varphi(c_1)\cdot \varphi(c_2)=(m_1+t e_1)(m_2+te_2) \\ =\underbrace{m_1m_2}_{
可以看到相比原来的噪声大小 φ ( c ) = m + t e ⏟ < t ∣ e ∣ \varphi(c)=\underbrace{m+te}_{
乘法之后的噪声是翻倍了。而如果我们需要正确解密的话,需要噪声大小 φ ( c ) < q / / ( φ ( c ) < q / 2 ) \varphi(c)φ(c)<q//(φ(c)<q/2)
。假设我们初始的噪声大小为 t ∣ e ∣ = B t|e|=B t∣e∣=B,则乘法之后的噪声大小为 B 2 B^2 B2,再进行一次乘法变为 B 4 B^4 B4,进行 ℓ \ell ℓ次乘法之后噪声大小为 B 2 ℓ B^{2^\ell} B2ℓ。若要求 B 2 ℓ < q B^{2^\ell}B2ℓ<q
,则最多做 ℓ ≈ log 2 ( log B ( q ) ) − 1 \ell\approx \log_2(\log_B(q))-1 ℓ≈log2(logB(q))−1次乘法。
如何减少这种噪声的扩张呢?,其实BGV,BFV,CKKS给出了三种不同的解决方法,其中BGV和CKKS比较类似,都是把密文和模数同时减少(区别在于,CKKS缩小完模数之后会对明文产生影响,变为一个近似的结果;而BGV不会)。BFV则是一个scale invariant的方法,即模数不会变,通过乘法后除以一个扩张因子来保持噪声规模。
为什么模数减小噪声也会变小:考虑以下情况:
φ ( c ) = m + t e m o d q , φ ( p q c ) = p q m + p q t e ⏟ < p q B m o d p \varphi(c)=m+te \bmod q,\varphi(\frac{p}{q} c)=\underbrace{\frac{p}{q}m+\frac{p}{q}te}_{<\frac{p}{q}B} \bmod p φ(c)=m+temodq,φ(qpc)=<qpB qpm+qptemodp
通过对密文整体进行缩放,模数从 q q q变为 p p p,噪声从 B B B变为 p q B \frac{p}{q}B qpB,那这里疑问就产生了:噪声和模数的比例关系没变啊,还是 B q = p q B p \frac{B}{q}=\frac{\frac{p}{q}B}{p} qB=pqpB,为什么说减少了噪声呢?
这里举个例子:比如 B = 2 , q = 131072 , p = 1 2 q = 65536 B=2,q=131072,p=\frac{1}{2}q=65536 B=2,q=131072,p=21q=65536。那么不使用MS的噪声扩张为
2 m o d 131072 → m u l t i p l y 4 m o d 131072 → m u l t i p l y 16 m o d 131072 → m u l t i p l y 256 m o d 131072 → m u l t i p l y 65536 m o d 131072 → m u l t i p l y ( × ) 6553 6 2 m o d 131072 2 \bmod 131072 \stackrel{multiply}{\to}4 \bmod 131072 \stackrel{multiply}{\to} 16 \bmod 131072\stackrel{multiply}{\to} 256 \bmod 131072\stackrel{multiply}{\to} 65536 \bmod 131072\stackrel{multiply(\times)}{\to} 65536^2 \bmod 131072 2mod131072→multiply4mod131072→multiply16mod131072→multiply256mod131072→multiply65536mod131072→multiply(×)655362mod131072
总共能做4层乘法。
如果我们在第一次乘法之后做一个MS,即将 B → p q B B\to \frac{p}{q}B B→qpB, q → p q\to p q→p。则噪声扩张为
2 m o d 131072 → m u l t i p l y 4 m o d 131072 → M S 2 m o d 65536 → m u l t i p l y 4 m o d 65536 → m u l t i p l y 4 m o d 65536 → m u l t i p l y 16 m o d 65536 → m u l t i p l y 256 m o d 65536 → m u l t i p l y ( × ) 65536 m o d 65536 2 \bmod 131072 \stackrel{multiply}{\to} 4 \bmod 131072\stackrel{MS}{\to} 2 \bmod 65536\stackrel{multiply}{\to} 4 \bmod 65536\stackrel{multiply}{\to} 4 \bmod 65536\stackrel{multiply}{\to} 16 \bmod 65536\stackrel{multiply}{\to} 256 \bmod 65536\stackrel{multiply(\times)}{\to} 65536 \bmod 65536 2mod131072→multiply4mod131072→MS2mod65536→multiply4mod65536→multiply4mod65536→multiply16mod65536→multiply256mod65536→multiply(×)65536mod65536
能做5层乘法。
那再考虑另一种情况,每次乘法完都做一次modulus switching,将 B → 1 2 B , q → 1 2 q B\to \frac{1}{2}B,q \to \frac{1}{2}q B→21B,q→21q:
则噪声扩张变为:
2 m o d 131072 → m u l t i p l y 4 m o d 131072 → M S 2 m o d 65536 → m u l t i p l y 4 m o d 65536 → M S 2 m o d 32768 → m u l t i p l y 4 m o d 32768 → M S 2 m o d 16384 → m u l t i p l y 4 m o d 16384 → M S 2 m o d 8192 → m u l t i p l y 4 m o d 8192 → M S 2 m o d 4096 → m u l t i p l y 4 m o d 4096 → M S 2 m o d 2048 → m u l t i p l y 4 m o d 2048 → M S 2 m o d 1024 → m u l t i p l y 4 m o d 1024 → M S 2 m o d 512 → m u l t i p l y 4 m o d 512 → M S 2 m o d 256 → m u l t i p l y 4 m o d 256 → M S 2 m o d 128 → m u l t i p l y 4 m o d 128 → M S 2 m o d 64 → m u l t i p l y 4 m o d 64 → M S 2 m o d 32 → m u l t i p l y 4 m o d 32 → M S 2 m o d 16 → m u l t i p l y 4 m o d 16 → M S 2 m o d 8 → m u l t i p l y 4 m o d 8 → M S 2 m o d 4 → m u l t i p l y ( × ) 4 m o d 4 2 \bmod 131072 \stackrel{multiply}{\to} 4 \bmod 131072\stackrel{MS}{\to} \\2 \bmod 65536 \stackrel{multiply}{\to} 4 \bmod 65536 \stackrel{MS}{\to} \\2 \bmod 32768\stackrel{multiply}{\to} 4 \bmod 32768\stackrel{MS}{\to} \\ 2 \bmod 16384\stackrel{multiply}{\to} 4 \bmod 16384\stackrel{MS}{\to} \\ 2 \bmod 8192\stackrel{multiply}{\to} 4 \bmod 8192\stackrel{MS}{\to} \\ 2 \bmod 4096\stackrel{multiply}{\to} 4 \bmod 4096\stackrel{MS}{\to} \\ 2 \bmod 2048\stackrel{multiply}{\to} 4 \bmod 2048\stackrel{MS}{\to} \\ 2 \bmod 1024\stackrel{multiply}{\to} 4 \bmod 1024\stackrel{MS}{\to}\\ 2 \bmod 512\stackrel{multiply}{\to} 4 \bmod 512\stackrel{MS}{\to}\\ 2 \bmod 256\stackrel{multiply}{\to} 4 \bmod 256\stackrel{MS}{\to}\\ 2 \bmod 128\stackrel{multiply}{\to} 4 \bmod 128\stackrel{MS}{\to}\\ 2 \bmod 64\stackrel{multiply}{\to} 4 \bmod 64\stackrel{MS}{\to}\\ 2 \bmod 32\stackrel{multiply}{\to} 4 \bmod 32\stackrel{MS}{\to}\\ 2 \bmod 16\stackrel{multiply}{\to} 4 \bmod 16\stackrel{MS}{\to}\\ 2 \bmod 8\stackrel{multiply}{\to} 4 \bmod 8\stackrel{MS}{\to}\\ 2 \bmod 4\stackrel{multiply(\times)}{\to} 4 \bmod 4 2mod131072→multiply4mod131072→MS2mod65536→multiply4mod65536→MS2mod32768→multiply4mod32768→MS2mod16384→multiply4mod16384→MS2mod8192→multiply4mod8192→MS2mod4096→multiply4mod4096→MS2mod2048→multiply4mod2048→MS2mod1024→multiply4mod1024→MS2mod512→multiply4mod512→MS2mod256→multiply4mod256→MS2mod128→multiply4mod128→MS2mod64→multiply4mod64→MS2mod32→multiply4mod32→MS2mod16→multiply4mod16→MS2mod8→multiply4mod8→MS2mod4→multiply(×)4mod4
总计有15层乘法。
总结:
由此可见,MS不改变噪声和模数的比例关系,但是噪声的扩张速度是被减少了的。每次缩小噪声从而导致模数变小,在BGV里面称作密文到达了下一层,也就如为上面的写法一样,一层拥有对应模数。通过模数缩减可以使原本 ℓ ≈ log 2 ( log B ( q ) ) − 1 \ell\approx \log_2(\log_B(q)) -1 ℓ≈log2(logB(q))−1次乘法。变为 ℓ ≈ ( log B ( q ) − 1 \ell\approx (\log_B(q) -1 ℓ≈(logB(q)−1次乘法。
其实在上面的例子里面已经有设计到如何做MS的问题了,对于一个密文 c = ( a , b ) c=(a,b) c=(a,b)。对于 L L L层乘法,取多个 Q : { Q 0 , Q 1 , . . . , Q L } Q:\{Q_0,Q_1,...,Q_L\} Q:{Q0,Q1,...,QL},满足 Q i + 1 ≈ B ⋅ Q i Q_{i+1}\approx B\cdot Q_i Qi+1≈B⋅Qi的关系。
modulus switching:
c = c L = ( a , b ) m o d Q L → M S L → L − 1 c L − 1 = ( Q L − 1 Q L a , Q L − 1 Q L b ) m o d Q L − 1 c=c_{L}=(a,b) \bmod Q_{L} \stackrel{MS_{L\to L-1}}\to c_{L-1}=(\frac{Q_{L-1}}{Q_{L}}a,\frac{Q_{L-1}}{Q_{L}}b) \bmod Q_{L-1} c=cL=(a,b)modQL→MSL→L−1cL−1=(QLQL−1a,QLQL−1b)modQL−1
φ ( c L ) = b − a s = m + t e m o d Q L , φ ( c L − 1 ) = Q L − 1 Q L b − Q L − 1 Q L a s = Q L − 1 Q L m + Q L − 1 Q L t e m o d Q L − 1 \varphi(c_L)=b-as = m+te \bmod Q_L,\varphi(c_{L-1})=\frac{Q_{L-1}}{Q_{L}}b-\frac{Q_{L-1}}{Q_{L}}as=\frac{Q_{L-1}}{Q_{L}}m+\frac{Q_{L-1}}{Q_{L}}te \bmod Q_{L-1} φ(cL)=b−as=m+temodQL,φ(cL−1)=QLQL−1b−QLQL−1as=QLQL−1m+QLQL−1temodQL−1。
现在问题是如何使得 Q L − 1 Q L m = m m o d t \frac{Q_{L-1}}{Q_{L}}m =m \bmod t QLQL−1m=mmodt且 Q L − 1 Q L t ≡ t m o d Q L − 1 \frac{Q_{L-1}}{Q_{L}}t\equiv t\bmod Q_{L-1} QLQL−1t≡tmodQL−1,也就是让解密后得到的结果还是 m m m。其实解决方法很容易,就是令 Q i ≡ 1 m o d t Q_i \equiv 1\bmod t Qi≡1modt就行了。
KeySwitching其实不算是BGV特有的技术,所以不准备放在BGV里面介绍。这里说一下大概的思路。
对于一个用 s s s加密的密文 c c c来说,他由两部分组成, ( a , b ) (a,b) (a,b),其中 b = a s + m + t e b=as+m+te b=as+m+te。
如果说我要将这个密文转为由密钥 s ′ s' s′加密,则我先使用 s ′ s' s′加密 s s s,得到 k s k = ( a k , b k ) ksk=(a_k,b_k) ksk=(ak,bk)其中 b k = a k s ′ + s + t e k b_k=a_ks'+s+te_k bk=aks′+s+tek。
key switch可以理解为得到 c ′ = ( a ′ , b ′ ) = ( 0 , b ) − a ⋅ ( a k , b k ) = ( − a ⋅ a k , b − a ⋅ b k ) c'=(a',b')=(0,b)-a\cdot(a_k,b_k)=(-a\cdot a_k,b-a\cdot b_k) c′=(a′,b′)=(0,b)−a⋅(ak,bk)=(−a⋅ak,b−a⋅bk)。
对 ( a ′ , b ′ ) (a',b') (a′,b′)用 s ′ s' s′解密得到
b ′ − a ′ s ′ = b − a ⋅ b k + a ⋅ a k ⋅ s ′ = b − a ( a k s ′ + s + t e ) + ( a k s ′ ) = b − a ( s + t e k ) = b − a s + a t e k = m + t e + a t e k = m + t e ′ \begin{aligned} b'-a's' &=b-a\cdot b_k+a\cdot a_k \cdot s' \\&=b-a(a_ks'+s+te)+(a_k s') \\&=b-a(s+te_k) \\&=b-as+ate_k \\&=m+te+ate_{k} \\&=m+te' \end{aligned} b′−a′s′=b−a⋅bk+a⋅ak⋅s′=b−a(aks′+s+te)+(aks′)=b−a(s+tek)=b−as+atek=m+te+atek=m+te′
所以 c ′ c' c′是一个由 s ′ s' s′加密的密文。
重线性化可以类似的理解一下,乘法之后的密文变为由 s 2 s^2 s2加密的密文,所以将 s 2 s^2 s2keyswitch回 s s s,就可以继续使用 s s s解密了。