同态加密:CKKS原理之旋转(Rotation)

这篇文章简单地讲了一下CKKS算法中旋转操作的原理。

CKKS的旋转

其实,BFV,BGV,CKKS的旋转操作的原理都是一样的。只不过是对应的代数结构不一样。比如CKKS是在 C \mathbb C C上进行的,而BFV和BGV是在 F p F_p Fp上进行的。

想要理解旋转操作,首先需要理解CKKS的编码和解码。

CKKS的编码和解码

这个操作的原理我在之前的博客已经有所涉及。其原理如下:

考虑 X N + 1 = Φ 2 N ( X ) X^N+1 = \Phi_{2N}(X) XN+1=Φ2N(X),其中 N N N是2的幂。在 C \mathbb C C 上, X N + 1 X^N+1 XN+1的根是 ω j = e − 2 π j i / 2 N \omega_j = e^{-2\pi ji/ 2N} ωj=e2πji/2N j j j是小于 2 N 2N 2N的奇数(共 N N N个),并且两两共轭。为了方便起见,我们记 ω 1 = ω \omega_1 = \omega ω1=ω,此时有 ω j = ω j \omega_j = \omega^j ωj=ωj

于是我们可以做自然嵌入。具体地,我们有一个复向量 v v v,长度为 N / 2 N/2 N/2,目标是生成一个实系数多项式 f f f,使得 f ( ω j ) = v j f(\omega_j) = v_j f(ωj)=vj。上述操作(把复向量弄成实多项式)就叫自然嵌入了。这玩意本质上就是插值运算。

为了满足实系数的约束,我们可以做 f ( ω j ) = v j f(\omega_j) = v_j f(ωj)=vj f ( ω j ˉ ) = v j ˉ f(\bar{\omega_j}) = \bar{v_j} f(ωjˉ)=vjˉ。也可以直接限定多项式系数为实数并求解 f ( ω j ) = v j f(\omega_j) = v_j f(ωj)=vj

CKKS的旋转

举个例子。令 N = 8 N = 8 N=8,其分圆多项式对应的根为 ω j \omega^j ωj j = 1 , 3 , 5 , 7 , 9 , 11 , 13 , 15 j=1,3,5,7,9,11,13,15 j=1,3,5,7,9,11,13,15 ω = e − 2 π i / 8 \omega=e^{-2\pi i/8} ω=e2πi/8

自然的想法是可以用 ω 1 , 3 , 5 , 7 \omega_{1,3,5,7} ω1,3,5,7 来做自然嵌入,但是这样其实不太方便做旋转操作。

因为,从向量的角度来看,旋转干的事情类似于:

[1,3,5,7] --左旋1-> [3,5,7,1] --左旋1-> [5,7,1,3]

这意味着对编码后的向量变换多项式插值。假如我们用的是 ω 1 , 3 , 5 , 7 \omega_{1,3,5,7} ω1,3,5,7 来做自然嵌入,那么旋转之前

f ( ω 1 ) = 1 f(\omega^1) = 1 f(ω1)=1
f ( ω 3 ) = 3 f(\omega^3) = 3 f(ω3)=3
f ( ω 5 ) = 5 f(\omega^5) = 5 f(ω5)=5
f ( ω 7 ) = 7 f(\omega^7) = 7 f(ω7)=7

现在向左旋转1位之后:

f ( ω 1 ) = 3 f(\omega^1) = 3 f(ω1)=3
f ( ω 3 ) = 5 f(\omega^3) = 5 f(ω3)=5
f ( ω 5 ) = 7 f(\omega^5) = 7 f(ω5)=7
f ( ω 7 ) = 1 f(\omega^7) = 1 f(ω7)=1

这种编码方式其实是不太方便做旋转的。因为这些根之间的转换不太方便实现。

不过肯定还是要用这些根,只是根的排列不同。

我们考虑 { 1 , 3 , . . . , 2 N − 1 } m o d    2 N \{1,3,...,2N-1\} \mod 2N {1,3,...,2N1}mod2N 。在这个结构里,整数5的阶是 N N N,5的所有整数次幂可构成阶是 N N N缩系。

比如说,在 N = 8 N=8 N=8 的情况下,整数5构成的缩系是
{ 5 = 5 1 m o d    16 , 9 = 5 2 m o d    16 , 13 = 5 3 m o d    16 , 1 = 5 4 m o d    16 } \{5=5^1\mod16, 9=5^2\mod16, 13=5^3\mod16, 1=5^4\mod16\} {5=51mod16,9=52mod16,13=53mod16,1=54mod16}
对这个缩系中的元素都乘-1,得到
{ 11 = − 5 m o d    16 , 7 = − 9 m o d    16 , 3 = − 13 m o d    16 , 15 = − 1 m o d    16 } \{11=-5\mod16, 7=-9\mod16, 3=-13\mod16, 15=-1\mod16\} {11=5mod16,7=9mod16,3=13mod16,15=1mod16}

把这两个集合做不交并就生成了完整的 { 1 , 3 , . . . , 2 N − 1 } m o d    2 N \{1,3,...,2N-1\} \mod 2N {1,3,...,2N1}mod2N

现在我们改变一下编码方式:
f ( ω 5 ) = 1 = f ( ω 5 ) f(\omega^5) = 1 = f(\omega^5) f(ω5)=1=f(ω5)
f ( ω 25 ) = 3 = f ( ω 9 ) f(\omega^{25}) = 3 = f(\omega^9) f(ω25)=3=f(ω9)
f ( ω 125 ) = 5 = f ( ω 13 ) f(\omega^{125}) = 5 = f(\omega^{13}) f(ω125)=5=f(ω13)
f ( ω 625 ) = 7 = f ( ω 1 ) f(\omega^{625}) = 7 = f(\omega^1) f(ω625)=7=f(ω1)

计算5次幂(意味着旋转一位),就得到
f ( ( ω 5 ) 5 ) = 1 = f ( ω 25 ) = f ( ω 9 ) f((\omega^5)^5) = 1 = f(\omega^{25}) = f(\omega^9) f((ω5)5)=1=f(ω25)=f(ω9)
f ( ( ω 25 ) 5 ) = 3 = f ( ω 125 ) = f ( ω 13 ) f((\omega^{25})^5) = 3 = f(\omega^{125}) = f(\omega^{13}) f((ω25)5)=3=f(ω125)=f(ω13)
f ( ( ω 125 ) 5 ) = 5 = f ( ω 625 ) = f ( ω 1 ) f((\omega^{125})^5) = 5 = f(\omega^{625}) = f(\omega^1) f((ω125)5)=5=f(ω625)=f(ω1)
f ( ( ω 625 ) 5 ) = 7 = f ( ω 3125 ) = f ( ω 5 ) f((\omega^{625})^5) = 7 = f(\omega^{3125}) = f(\omega^5) f((ω625)5)=7=f(ω3125)=f(ω5)

计算25次幂(意味着旋转两位),可以自行计算。

具体地,在CKKS的编码操作完成之后,会从向量 v v v得到一个多项式 f ( x ) f(x) f(x)
我们把多项式的未定元从 x x x换成 x 5 x^5 x5,就可以实现上面的旋转一位的操作。

在密文情况下,因为 c 0 ( x ) + c 1 ( x ) s ( x ) = m ( x ) c_0(x) + c_1(x)s(x) = m(x) c0(x)+c1(x)s(x)=m(x),所以做旋转的时候有 c 0 ( x 5 ) + c 1 ( x 5 ) s ( x 5 ) = m ( x 5 ) c_0(x^5) + c_1(x^5)s(x^5) = m(x^5) c0(x5)+c1(x5)s(x5)=m(x5)。这意味着,我们需要为每一个旋转步数生成一个转换密钥,目的是把 s ( x k ) s(x^k) s(xk)弄成 s ( x ) s(x) s(x)。为了简便起见,我这里直接称为旋转密钥。在SEAL库的实现中,他们依据2的幂来进行生成旋转密钥:比如生成旋转1, 2, 4, 8…位的密钥,在旋转具体步数时再进行拆分。

下面这张图简单地概括了一下我上面所说旋转操作的原理。
同态加密:CKKS原理之旋转(Rotation)_第1张图片

总结一下,不论是在 C \mathbb C C上还是 F p \mathbb F_p Fp上做旋转,本质上都是需要找到一个缩系生成元和一个共轭元,然后利用生成元进行嵌入(编码),就可以支持旋转操作了。

你可能感兴趣的:(同态加密,抽象代数,同态加密)