CKKS EXPLAINED, PART 4: MULTIPLICATION AND RELINEARIZATION

CKKS EXPLAINED, PART 4: MULTIPLICATION AND RELINEARIZATION

Introduction

在之前的文章《解释CKKS,第3部分:加密和解密》中,我们看到了如何基于RLWE问题创建同态加密方案,并实现同态加法和密文-明文乘法。

尽管密文-明文乘法很容易实现,但密文-密文乘法要复杂得多,正如我们将看到的。事实上,我们需要处理许多事情,例如找到合适的操作,使得解密后我们得到两个密文的乘积,并管理密文的大小。

因此,本文将介绍密文-密文乘法和重线性化的概念,以减小结果密文的大小。

Recap of basic operations

为了了解在CKKS中如何进行密文-密文乘法,让我们回顾一下在之前的文章中所讨论的内容。

首先,请记住我们在多项式空间 R q = Z q [ X ] / ( X N + 1 ) \mathcal{R}_q=\mathbb{Z}_q[X]/(X^N+1) Rq=Zq[X]/(XN+1) 上进行操作。我们选择一个作为秘密密钥的多项式 s s s,然后可以安全地生成一个公钥 p = ( b , a ) = ( − a ⋅ s + e , a ) p = (b, a) = (-a \cdot s + e, a) p=(b,a)=(as+e,a),其中 a a a 是在 R q \mathcal{R}_q Rq 上均匀采样的多项式, e e e 是一个小的随机多项式。

然后,我们有加密操作 E n c r y p t ( μ , p ) = c = ( c 0 , c 1 ) = ( μ , 0 ) + p = ( b + μ , a ) ∈ R q 2 Encrypt(\mu, p) = c = (c_0, c_1) = (\mu, 0) + p = (b + \mu, a) \in \mathcal{R}^2_{q} Encrypt(μ,p)=c=(c0,c1)=(μ,0)+p=(b+μ,a)Rq2,用于对明文 μ ∈ Z q [ X ] / ( X N + 1 ) \mu \in \mathbb{Z}_q[X]/(X^N+1) μZq[X]/(XN+1) 使用公钥 p p p 进行加密。

为了使用秘密密钥解密密文 c c c,我们进行以下操作: D e c r y p t ( c , s ) = c 0 + c 1 ⋅ s = μ + e Decrypt(c, s) = c_0 + c_1 \cdot s = \mu + e Decrypt(c,s)=c0+c1s=μ+e

然后,我们看到定义密文加法 C A d d ( c , c ′ ) CAdd(c, c') CAdd(c,c) 很容易,这样一旦我们对 C A d d CAdd CAdd 的输出进行解密,我们将近似得到两个底层明文的加法。

具体做法是将 C A d d CAdd CAdd 定义为: C A d d ( c , c ′ ) = ( c 0 + c 0 ′ , c 1 + c 1 ′ ) = c + c ′ = c a d d CAdd(c, c') = (c_0 + c'_0, c_1 + c'_1) = c + c' = c_{add} CAdd(c,c)=(c0+c0,c1+c1)=c+c=cadd

实际上,如果我们对其应用解密操作,我们会得到:

D e c r y p t ( c a d d , s ) = c 0 + c 0 ′ + ( c 1 + c 1 ′ ) ⋅ s = c 0 + c 1 ⋅ s + c 0 ′ + c 1 ′ ⋅ s = D e c r y p t ( c , s ) + D e c r y p t ( c ′ , s ) ≈ μ + μ ′ Decrypt(c_{add}, s) = c_0 + c'_0 + (c_1 + c'_1) \cdot s = c_0 + c_1 \cdot s + c'_0 + c'_1 \cdot s = Decrypt(c, s) + Decrypt(c', s) \approx \mu + \mu' Decrypt(cadd,s)=c0+c0+(c1+c1)s=c0+c1s+c0+c1s=Decrypt(c,s)+Decrypt(c,s)μ+μ

在这里,我们可以看到密文的加法操作非常简单,我们只需要将两个密文相加,然后使用常规的解密操作对结果进行解密,以获得两个底层明文的加法。

当进行密文-密文乘法时,我们将看到乘法和解密操作都更加复杂。

Ciphertext-ciphertext multiplication

现在我们已经看到了,我们的目标是找到操作 CMult \text{CMult} CMult DecryptMult \text{DecryptMult} DecryptMult,使得对于两个密文 c c c c ′ c' c​,我们有:

DecryptMult ( CMult ( c , c ′ ) , s ) = Decrypt ( c , s ) ⋅ Decrypt ( c ′ , s ) \text{DecryptMult}(\text{CMult}(c,c'),s) = \text{Decrypt}(c,s) \cdot \text{Decrypt}(c',s) DecryptMult(CMult(c,c),s)=Decrypt(c,s)Decrypt(c,s)

请记住, Decrypt ( c , s ) = c 0 + c 1 ⋅ s \text{Decrypt}(c,s) = c_0 + c_1 \cdot s Decrypt(c,s)=c0+c1s。因此,如果我们展开上面的表达式,我们得到:

Decrypt ( c , s ) ⋅ Decrypt ( c ′ , s ) = ( c 0 + c 1 ⋅ s ) ⋅ ( c 0 ′ + c 1 ′ ⋅ s ) = c 0 ⋅ c 0 ′ + ( c 0 ⋅ c 1 ′ + c 0 ′ ⋅ c 1 ) ⋅ s + c 1 ⋅ c 1 ′ ⋅ s 2 = d 0 + d 1 ⋅ s + d 2 ⋅ s 2 \text{Decrypt}(c,s) \cdot \text{Decrypt}(c',s) = (c_0 + c_1 \cdot s) \cdot (c'_0 + c'_1 \cdot s) = c_0 \cdot c'_0 + (c_0 \cdot c'_1 + c'_0 \cdot c_1) \cdot s + c_1 \cdot c'_1 \cdot s^2 = d_0 + d_1 \cdot s + d_2 \cdot s^2 Decrypt(c,s)Decrypt(c,s)=(c0+c1s)(c0+c1s)=c0c0+(c0c1+c0c1)s+c1c1s2=d0+d1s+d2s2
其中 d 0 = c 0 ⋅ c 0 ′ d_0 = c_0 \cdot c'_0 d0=c0c0 d 1 = c 0 ⋅ c 1 ′ + c 0 ′ ⋅ c 1 d_1 = c_0 \cdot c'_1 + c'_0 \cdot c_1 d1=c0c1+c0c1 d 2 = c 1 ⋅ c 1 ′ d_2 = c_1 \cdot c'_1 d2=c1c1

有趣!如果我们思考一下,将 Decrypt ( c , s ) = c 0 + c 1 ⋅ s \text{Decrypt}(c,s) = c_0 + c_1 \cdot s Decrypt(c,s)=c0+c1s 视为在秘密密钥 s s s 上进行多项式求值,那么它可以被看作是一个一次多项式,形式为 c 0 + c 1 ⋅ S c_0 + c_1 \cdot S c0+c1S,其中 S S S 是多项式变量。

因此,如果我们将对两个密文乘积的解密操作视为在秘密密钥 s s s 上对二次多项式 d 0 + d 1 ⋅ S + d 2 ⋅ S 2 d_0 + d_1 \cdot S + d_2 \cdot S^2 d0+d1S+d2S2 进行求值。

因此,我们可以使用以下操作来进行密文-密文乘法:

CMult ( c , c ′ ) = c m u l t = ( d 0 , d 1 , d 2 ) = ( c 0 ⋅ c 0 ′ , c 0 ⋅ c 1 ′ + c 0 ′ ⋅ c 1 , c 1 ⋅ c 1 ′ ) \text{CMult}(c,c') = c_{mult} = (d_0, d_1, d_2) = (c_0 \cdot c'_0, c_0 \cdot c'_1 + c'_0 \cdot c_1, c_1 \cdot c'_1) CMult(c,c)=cmult=(d0,d1,d2)=(c0c0,c0c1+c0c1,c1c1)

DecryptMult ( c m u l t , s ) = d 0 + d 1 ⋅ s + d 2 ⋅ s 2 \text{DecryptMult}(c_{mult},s) = d_0 + d_1 \cdot s + d_2 \cdot s^2 DecryptMult(cmult,s)=d0+d1s+d2s2

使用这样的操作可能有效,但是存在一个问题:密文的大小增加了!实际上,虽然密文通常只包含几个多项式,但在这里,我们的密文有3个多项式。根据之前的推理,如果我们不采取任何措施,在正确解密下一个乘积时,我们将需要5个多项式,然后是9个多项式,以此类推。因此,密文的大小将呈指数级增长,并且如果我们采用这种方式来定义密文-密文乘法,它在实践中将无法使用。

我们需要找到一种方法,在每一步中进行乘法而不增加密文的大小。这就是重线性化的作用!

Relinearization

我们注意到,可以将密文之间的乘法定义为操作 C M u l t ( c , c ′ ) = ( d 0 , d 1 , d 2 ) CMult(c, c')=(d_0, d_1, d_2) CMult(c,c)=(d0,d1,d2)。然而,问题在于现在输出是一个维度为3的密文,如果在每次计算后继续增加密文的大小,实际使用将变得不可行。

那么问题是什么?问题在于我们需要第三个项,即用于多项式解密的 d 2 d_2 d2项,即 D e c r y p t M u l t ( c m u l t , s ) = d 0 + d 1 ⋅ s + d 2 ⋅ s 2 DecryptMult(cmult, s) = d_0 + d_1 \cdot s + d_2 \cdot s^2 DecryptMult(cmult,s)=d0+d1s+d2s2。但是,如果我们能够找到一种方法,只使用一个一次多项式作为常规解密,就可以计算出 d 2 ⋅ s 2 d_2 \cdot s^2 d2s2,会怎么样呢?在这种情况下,密文的大小将保持不变,它们只是一对多项式!

这就是重线性化的核心:找到一对多项式 ( d 0 ′ , d 1 ′ ) = R e l i n ( c m u l t ) (d'_0, d'_1) = Relin(cmult) (d0,d1)=Relin(cmult),使得: D e c r y p t ( ( d 0 ′ , d 1 ′ ) , s ) = d 0 ′ + d 1 ′ ⋅ s = d 0 + d 1 ⋅ s + d 2 ⋅ s 2 = D e c r y p t ( c , s ) ⋅ D e c r y p t ( c ′ , s ) Decrypt((d'_0, d'_1), s) = d'_0 + d'_1 \cdot s = d_0 + d_1 \cdot s + d_2 \cdot s^2 = Decrypt(c, s) \cdot Decrypt(c', s) Decrypt((d0,d1),s)=d0+d1s=d0+d1s+d2s2=Decrypt(c,s)Decrypt(c,s)

换句话说,重线性化允许我们拥有一对多项式,而不是三对多项式,一旦使用只需要秘密密钥而不需要其平方的常规解密电路解密它们,我们就能得到两个底层明文的乘积。

因此,如果我们在每个密文-密文乘法之后执行重线性化,我们将始终拥有相同大小的密文,并使用相同的解密电路!

现在你可能想知道我们如何定义Relin才能获得这样的结果。思路很简单,我们知道我们需要一对多项式,使得 d 0 ′ + d 1 ′ ⋅ s = d 0 + d 1 ⋅ s + d 2 ⋅ s 2 d'_0 + d'_1 \cdot s = d_0 + d_1 \cdot s + d_2 \cdot s^2 d0+d1s=d0+d1s+d2s2。想法是,我们将定义 ( d 0 ′ , d 1 ′ ) = ( d 0 , d 1 ) + P (d'_0, d'_1) = (d_0, d_1) + P (d0,d1)=(d0,d1)+P,其中 P P P表示一对多项式,使得 D e c r y p t ( P , s ) = d 2 ⋅ s 2 Decrypt(P, s) = d_2 \cdot s^2 Decrypt(P,s)=d2s2

这样,当我们对 ( d 0 ′ , d 1 ′ ) (d'_0, d'_1) (d0,d1)进行解密电路评估时,我们得到:
D e c r y p t ( ( d 0 ′ , d 1 ′ ) , s ) = D e c r y p t ( ( d 0 , d 1 ) , s ) + D e c r y p t ( P , s ) = d 0 + d 1 ⋅ s + d 2 ⋅ s 2 Decrypt((d'_0, d'_1), s) = Decrypt((d_0, d_1), s) + Decrypt(P, s) = d_0 + d_1 \cdot s + d_2 \cdot s^2 Decrypt((d0,d1),s)=Decrypt((d0,d1),s)+Decrypt(P,s)=d0+d1s+d2s2

一个方法是提供一个评估密钥,用于计算 P P P。设 e v k = ( − a 0 ⋅ s + e 0 + s 2 , a 0 ) evk = (-a_0 \cdot s + e_0 + s^2, a_0) evk=(a0s+e0+s2,a0),其中 e 0 e_0 e0是一个小的随机多项式, a 0 a_0 a0是在 R q \mathcal{R}_q Rq上均匀采样的多项式。然后,如果我们应用 D e c r y p t ( e v k , s ) = e 0 + s 2 ≈ s 2 Decrypt(evk, s) = e_0 + s^2 \approx s^2 Decrypt(evk,s)=e0+s2s2。很好!我们看到我们可以公开分享评估密钥给执行计算的一方,因为根据RLWE问题,很难提取出密钥,它可以用于找到平方项。

因此, P P P的一个可能的候选,即解密为 d 2 ⋅ s 2 d_2 \cdot s^2 d2s2的密文,可以简单地定义为 P = d 2 ⋅ e v k = ( d 2 ⋅ ( − a 0 + e 0 + s 2 ) , d 2 ⋅ a 0 ) P = d_2 \cdot evk = (d_2 \cdot (-a_0 + e_0 + s^2), d_2 \cdot a_0) P=d2evk=(d2(a0+e0+s2),d2a0)。确实,正如我们所见,我们有 D e c r y p t ( P , s ) = d 2 ⋅ s 2 + d 2 ⋅ e 0 Decrypt(P, s) = d_2 \cdot s^2 + d_2 \cdot e_0 Decrypt(P,s)=d2s2+d2e0。那么我们可以像通常一样做,将 d 2 ⋅ s 2 + d 2 ⋅ e 0 d_2 \cdot s^2 + d_2 \cdot e_0 d2s2+d2e0近似为 d 2 ⋅ s 2 d_2 \cdot s^2 d2s2吗?

不幸的是在实践中,我们无法直接处理该问题,因为 $ d_2 \cdot e_0$项远大于我们通常处理的噪声。如果您之前有注意到,我们允许对结果进行近似,是因为错误多项式很小,例如一系列小的多项式之和,这样不会对结果产生太大的影响。但是,这里的问题是 d 2 d_2 d2 会很大,因为 d 2 = c 1 ⋅ c 1 ′ d_2=c_1\cdot c'_1 d2=c1c1,其中每个 c 1 c_1 c1 包含在 R q \mathcal{R}_q Rq上均匀采样的多项式 a a a,因此它要比我们通常处理的小错误多项式大得多。

那么在实践中我们如何解决这个问题呢?方法是对评估密钥(evaluation key)进行一些修改,定义为 evk = ( − a 0 ⋅ s + e 0 + p ⋅ s 2 , a 0 ) m o d    ( p ⋅ q ) \text{evk} = (-a_0 \cdot s + e_0 + p \cdot s^2, a_0) \mod (p \cdot q) evk=(a0s+e0+ps2,a0)mod(pq),其中 p p p 是一个大整数, a 0 a_0 a0 是从 R p ⋅ q \mathcal{R}_{p \cdot q} Rpq 上均匀采样的值。这里的思想是我们将通过除以 p p p 来减小与 d 2 d_2 d2 相乘引入的噪声,因此最终我们有:
P = ⌊ p − 1 . d 2 . e v k ⌉ ( m o d   q ) P=\lfloor p^{-1}.d_2.evk\rceil(\mathrm{mod~}q) P=p1.d2.evk(mod q),这意味着我们将除以 p p p 并将结果四舍五入为最接近的整数,并使用模 q q q 进行处理(而不是 p ⋅ q p \cdot q pq)。

好了,最终我们终于有了候选解决方案!对于重线性化(relinearization)的定义,我们需要一个评估密钥(可以公开使用而不会带来风险),定义为:
R e l i n ( ( d 0 , d 1 , d 2 ) , e v k ) = ( d 0 , d 1 ) + ⌊ p − 1 . d 2 . e v k ⌉ \mathtt{Relin}((d_0,d_1,d_2),evk)=(d_0,d_1)+\lfloor p^{-1}.d_2.evk\rceil Relin((d0,d1,d2),evk)=(d0,d1)+p1.d2.evk
所以,如果我们有两个密文 c c c c ′ c' c,并且我们想要将它们相乘(可能多次),然后解密结果,工作流程如下:

将它们相乘: cmult = CMult ( c , c ′ ) = ( d 0 , d 1 , d 2 ) \text{cmult} = \text{CMult}(c,c') = (d_0,d_1,d_2) cmult=CMult(c,c)=(d0,d1,d2)

进行重线性化: crelin = Relin ( ( d 0 , d 1 , d 2 ) , evk ) \text{crelin} = \text{Relin}((d_0,d_1,d_2),\text{evk}) crelin=Relin((d0,d1,d2),evk)

解密输出: μ mult = Decrypt ( crelin , s ) ≈ μ ⋅ μ ′ \mu_{\text{mult}} = \text{Decrypt}(\text{crelin},s) \approx \mu \cdot \mu' μmult=Decrypt(crelin,s)μμ

我在这里给出了整体的思路,但如果您对细节感兴趣,我建议阅读论文《Somewhat Practical Fully Homomorphic Encryption》中的解释。

现在,我们知道了如何将两个密文相乘并保持它们的大小不变。太棒了!虽然您可能认为这已经结束了,但在实现同态加密方案之前,我们还需要进行最后一步:重缩放(rescaling)。在下一篇文章中,我们将了解什么是重新缩放以及如何进行操作,然后再着手编写我们自己的代码!

  • 6
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值