摘要
本文介绍如何使用小步大步(Baby-Step-Giant-Step,BSGS)优化RLWE同态加密的明文矩阵和密文向量的乘法。使用 n × n n\times n n×n明文矩阵的对角打包和BSGS,可以将密文旋转的次数降低为 O ( n ) O(\sqrt{n}) O(n ).
明文运算
一个矩阵乘以一个向量可以表示为该向量与矩阵的每一行做内积运算。
可以表示为下面4个内积运算:
在基于RLWE的同态加密中,我们往往将一个向量加密为一个密文,从而实现SIMD优化。然而,被加密为一个密文后,向量不同位置之间的元素移动需要密文的旋转。密文旋转操作和明文乘以密文的开销差不多,比较耗时。这使得利用内积运算来计算明文矩阵和密文向量的乘法,变得非常耗时。
对角打包
可以观察到,对明文矩阵进行对角打包后,可以实现明文与密文向量的SIMD运算,从而降低开销。
假设明文矩阵为 A = a i , j \mathbf{A}=a_{i,j} A=ai,j,其中 i , j ∈ { 0 , 1 , 2 , ⋯ , n − 1 } i,j \in \{0,1,2,\cdots,n-1\} i,j∈{0,1,2,⋯,n−1}.
那么对角打包的第 i i i个向量为 a i = [ a i , 0 , a i + 1 , 0 , ⋯ , a i + n − 1 , n − 1 ] \mathbf{a_i}=[a_{i,0},a_{i+1,0}, \cdots, a_{i+n-1,n-1}] ai=[ai,0,ai+1,0,⋯,ai+n−1,n−1],这里下标的计算是模 n n n运算。
令密文向量为 b \mathbf{b} b,那么结果密文 c = ∑ i = 0 n − 1 rot ( a i × b , − i ) \mathbf{c}=\sum_{i=0}^{n-1}\operatorname{rot}(\mathbf{a_i}\times \mathbf{b},-i) c=∑i=0n−1rot(ai×b,−i). 其中 rot ( ⋅ , i ) \operatorname{rot}(\cdot,i) rot(⋅,i)表示密文向左循环旋转 i i i步,负数表示向右循环旋转 − i -i −i步。
从上图看,就是先算蓝色和密文相乘,再算紫色、黄色、绿色。通过 rot \operatorname{rot} rot,把每一个位置需要加起来的乘积旋转到正确的位置。
上面是先乘,再进行旋转。此外,我们还可以先对密文向量进行旋转,然后再乘。如下图所示:
此时,对角打包后的第 i i i个向量为 d i = [ a 0 , i , a 1 , i + 1 , ⋯ , a n − 1 , i + n − 1 ] \mathbf{d_i}=[a_{0,i},a_{1,i+1},\cdots,a_{n-1,i+n-1}] di=[a0,i,a1,i+1,⋯,an−1,i+n−1].
结果密文可表示为 c = ∑ i = 0 n − 1 d i × rot ( b , i ) \mathbf{c}=\sum_{i=0}^{n-1}\mathbf{d_i}\times \operatorname{rot}( \mathbf{b}, i) c=∑i=0n−1di×rot(b,i).
BSGS优化
BSGS的思想是,首先旋转一小步,得到一个块后,再将整个块旋转一大步,从而减少需要的总的旋转次数。
假设 k 1 × k 2 = n k_1\times k_2=n k1×k2=n.
则结果密文可表示为:
c = ∑ j = 0 k 2 − 1 rot ( ∑ i = 0 k 1 − 1 rot ( a j k 1 + i × b , − i ) , − j k 1 ) \mathbf{c}=\sum_{j=0}^{k_2-1}\operatorname{rot}(\sum_{i=0}^{k_1-1}\operatorname{rot}(\mathbf{a_{jk_1+i}}\times \mathbf{b},-i),-jk_1) c=∑j=0k2−1rot(∑i=0k1−1rot(ajk1+i×b,−i),−jk1).
但是我们发现,这样根本达不到优化的效果,需要的旋转次数为 k 1 k 2 + k 2 = n + k 2 k_1k_2+k_2=n+k_2 k1k2+k2=n+k2,比原来还多。
我们尝试使用第二种对角打包:
c = ∑ j = 0 k 2 − 1 rot ( ∑ i = 0 k 1 − 1 rot ( d j k 1 + i , − j k 1 ) × rot ( b , i ) , j k 1 ) \mathbf{c}=\sum_{j=0}^{k_2-1}\operatorname{rot}(\sum_{i=0}^{k_1-1}\operatorname{rot}(\mathbf{d_{jk_1+i}},-jk_1)\times \operatorname{rot}(\mathbf{b},i),jk_1) c=∑j=0k2−1rot(∑i=0k1−1rot(djk1+i,−jk1)×rot(b,i),jk1).
此时, rot ( b , i ) \operatorname{rot}(\mathbf{b},i) rot(b,i)一共只有 k 1 k_1 k1次, j k 1 jk_1 jk1一共有 k 2 k_2 k2次。
而 d j k 1 + i \mathbf{d_{jk_1+i}} djk1+i的旋转是明文的旋转,是便宜的。
因此,密文的旋转只需要 k 1 + k 2 k_1+k_2 k1+k2次。
当 k 1 = k 2 k_1=k_2 k1=k2时, k 1 + k 2 k_1+k_2 k1+k2最小,为 2 n 2\sqrt{n} 2n .
第二种对角打包,达到了减少旋转次数的优化目标。
参考文献
[1] S. Halevi and V. Shoup. Bootstrapping for HElib. In EUROCRYPT (1), volume 9056 of Lecture Notes in Computer Science, pages 641--670. Springer, 2015.