CKKS Part4: CKKS的乘法和重线性化

本文翻译于CKKS EXPLAINED, PART 4: MULTIPLICATION AND RELINEARIZATION,主要介绍CKKS方案中的密文乘法和重线性化技术

介绍#

在上一篇 CKKS Part3: CKKS的加密和解密 ,我们看到了如何基于RLWE问题创建同态加密方案,实现同态加法和密文明文乘法。

虽然执行密文-明文乘法很容易,但正如我们将看到的,密文-密文要复杂得多。事实上,我们需要处理很多事情才能正确地完成它,比如找到正确的操作,这样一旦解密,我们就可以得到两个密文的乘积,以及管理密文的大小。

因此,本文将介绍密文乘法和重新线性化的概念,以减少生成的密文的大小。

基本概念#

为了了解我们将如何在CKKS中执行密文-密文乘法,让我们回顾一下我们在前一篇文章中看到的内容。

首先,记住我们研究的是多项式空间Rq=\Zetaq[X]/(XN+1)。我们将s作为我们的私钥,然后我们可以安全地输出一个公钥p=(b,a)=(−a. s+e,a),其中a均匀取样Rq、 e是一个小的随机多项式。

然后我们有Encrypt(u,s)=c=(c0,c1)=(u,0)+p=(b+u,a)Rq2是明文u\Zetaq[X]/(XN+1)使用公钥p的加密操作。要使用私钥s解密密文c,我们执行以下操作:Decrypt(c,s)=c0+c1.s=u+e

然后我们发现定义一个在密文上的加法运算𝙲𝙰𝚍𝚍cc很容易,所以一旦我们解密𝙲𝙰𝚍𝚍 我们将大致得到两个基本明文的加法。

实现这一点的方法是定义𝙲𝙰𝚍𝚍 具体如下:$$\mbox{C}{Add}\left( c,c' \right)=\left( c+c_{0}',c_{1}+c_{1}' \right)=c+c'=c_{add}$$

事实上,如果我们对其应用解密操作,我们会得到:Decrypt(cadd,s)=c0+c0+(c1+c1).s=c0+c1.s+c0+c1.s=Decrypt(c,s)+Decrypt(c,s)u+u

这里我们看到,对密文做加法非常简单,我们只需要将两个密文相加,我们可以使用常规的解密操作来解密结果,以获得两个对应明文的相加。

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

密文-密文乘法#

现在我们看到了这一点,我们看到我们的目标是找到操作𝙲𝙼𝚞𝚕𝚝,𝙳𝚎𝚌𝚛𝚢𝚙𝚝𝙼𝚞𝚕𝚝, 对于两个密文c,c′我们有:DecryptMult(CMult(c,c),s)=Decrypt(c,s).Decrypt(c,s),切记Decrypt(c,s)=c0+c1.s,我们展开上面的式子得到:

Decrypt(c,s).Decrypt(c,s)=(c0+c1.s).(c0+c1.s)=c0.c0+(c0.c1+c0.c1).s+c1.c1.s2=d0+d1.s+d2.s2

其中d0=c0.c0,d1=(c0.c1+c0c1),d2=c1.c1

有趣的如果我们仔细想想,计算Decrypt(c,s)=c0+c1.s,可以看作是关于私钥s的多项式求值,它是形式为c0+c1.S的一次多项式。S是多项式中的变量。

因此,如果我们看到两个密文乘积上的解密运算,它可以被看作是多项式$d_0+d_1.S+d_2.S^2,关于S的二次多项式

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

CMult(c,c)=cmult=(d0,d1,d2)=(c0.c0,c0.c1+c0.c1,c1.c1)

DecryptMult(cmult,s)=d0+d1.s+d2.s2

使用这样的操作可能会有效,但有一个问题:密文的大小增加了!事实上,虽然密文通常只是几个多项式,但这里有3个多项式用于密文。通过使用与之前相同的推理,如果我们什么都不做,要正确解密下一个乘积,我们需要5个多项式,然后是9个,依此类推。因此,密文的大小将呈指数增长,如果我们这样定义密文-密文乘法,它在实践中将不可用。

我们需要找到一种不增加每一步密文大小的乘法方法。这就是重线性化的用武之地!

重线性化#

我们可以把密文之间的乘法定义为运算:CMult(c,c)=(d0,d1,d2),问题是,现在的输出是一个维数为3的密文,如果我们在每次计算后继续增加密文的大小,那么在实践中使用它将变得不可行。

让我们想想,问题是什么?问题是我们需要第三个项d2,用于多项式解密DecryptMult(cmult,s)=d0+d1.s+d2.s2,但如果我们能找到只有一个1次多项式作为解密去计算d2.s2的方法呢?那么在这种情况下,密文的大小将是恒定的,它们都将只是用到了两个多项式!

这就是重新线性化的本质:找到一对多项式(d0,d1)=Relin(cmμlt),例如:Decrypt((d0,d1),s)=d0+d1.s=d0+d1.s+d2.s2=Decrypt(c,s).Decrypt(c,s)
具体来说,重线性化允许有一对多项式(s的一次方),而不是三对多项式(s的二次方),这样,解密时就只需要用到s,而不用s的平方,我们就可以得到两个明文的乘法。

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

现在你可能想知道我们到底需要如何定义𝚁𝚎𝚕𝚒𝚗 。这个想法很简单,我们知道我们需要一对多项式,例如:d0+d1.s=d0+d1.s+d2.s2,我们的想法是定义(d0,d1)=(d0,d1)+P,其中P表示一对多项式,例如Decrypt(P,s)=d2.s2

这样,当我们用$(d′_0,d′_1)计算解密电路时,我们得到:

Decrypt((d0,d1),s)=Decrypt((d0,d1,s))+Decrypt(P,s)=d0+d1.s+d2.s2

一种方法是提供一个计算密钥,用于计算P。使得evk=(a0.s+e0+s2,a0),其中e0是一个小的随机多项式,a0是一个在Rq上均匀采样的多项式,然后我们计算Decrypt(evk,s)=e0+s2s2,太好了!我们可以看到,我们可以公开计算密钥,因为基于RLWE问题很难提取私钥,可以用来求s的平方项。

所以为了解密出d2.s2, P可能是P=d2.evk=(d2..(a0+e0+s2),d2.a0),的确正如我们所看到的那样Decrypt(P,s)=d2.s2+d2.e0,这时我们可能会考虑d2.s2+d2.e0d2.s2

不幸的是,我们不能这样做,因为d2.e0项比我们通常得到的噪声要大得多。如果你之前注意到了,我们允许对结果进行近似,因为误差多项式很小,比如加入一个小多项,它不会对结果产生太大的影响。但问题是d2很大,因为d2=c1.c1,其中,每个c1包括一个从Rq中采样的多项式a,因此,它比我们通常处理的小误差多项式要大得多。

那么,我们在实践中如何处理这个问题呢?诀窍是稍微修改计算密钥,并将其定义为evk=(a0.s+e0+p.s2,a0)(modp.q),其中p是一个大整数,a0Rq.p中随机采样。这里的想法是,我们将除以p,以去除与d2相乘时产生的噪声,即

Decrypt(evk,s)p=e0+p.s2ps2

,因此最后我们使得:P=p1.d2.evk(mod q),这意味着我们将除以p并将其四舍五入到最接近的整数,然后使用模q(而不是p.q)。

Decrypt(P,s)=p1.d2.e0+d2.s2d2.s2

,因为p1.d2.e0很小,可以约去!
我们终于有了合适的方法了!因此,为了定义重线性化,我们需要一个计算密钥(可以在没有风险的情况下公开),我们将其定义为:Relin((d0,d1,d2,evk))=(d0,d1)+p1.d2.evk。可以看到,重线性化后的密文由三维变二维。

因此,如果我们有两个密文c,c′,并且我们想要将它们相乘(可能几次),然后解密结果,那么工作流程将是:
1、相乘:cmμlt=CMult(c,c)=(d0,d1,d2)
2、重线性化:crelin=Relin((d0,d1,d2),evk)
3、解密输出:umμlt=Decrypt(crelin,s)u.u

我在这里只给出了总体思路,但如果您有兴趣了解细节,我建议您阅读"Somewhat Practical Fully Homomorphic Encryption".一文中的解释。

现在我们知道了如何将两个密文相乘,并保持它们的大小不变。太好了!虽然你可能认为这一切都结束了,但我们会看到,要实现同态加密方案,还有最后一步要做:rescaling,重新缩放。在我们自己编写代码之前,我们将在下一篇文章中看到什么是重缩放,以及如何进行重缩放!

作者:Hang Shao

出处:https://www.cnblogs.com/pam-sh/p/15865445.html

版权:本作品采用「知识共享」许可协议进行许可。

声明:欢迎交流! 原文链接 ,如有问题,可邮件(mir_soh@163.com)咨询.

posted @   PamShao  阅读(4110)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu