2021SC@SDUSC PALISADE开源库(二)CKKS讲解系列(三)加密和解密

2021SC@SDUSC

目录

介绍

错误学习

环形学习错误

同态操作

大致思路(重要)

加法

大致思路(重要)

 乘法

大致思路(重要)


介绍

在上一篇文章 PALISADE开源库(二)CKKS讲解系列(二)完整编码和解码 中,我们看到了如何实现CKKS的编码器和解码器,这使得我们能够将向量转化为多项式,反之亦然。这一步是必然的,因为我们将看到使用多项式要比直接使用向量更有效地构建同态加密方法。

我们将在本文中看到如何使用困难问题(例如LWERLWE)来构建近似同态加密方案。CKKS 使用近似算术而不是精确算术,从某种意义上说,一旦我们完成计算,我们可能会得到与直接进行计算的结果略有不同的结果。这意味着,如果您加密 2 和 3,添加它们的密文,然后解密,您可能会得到类似 4.99 或 5.01 而不是 5 的结果。 BFV 等其他方案是精确的,这意味着它们将产生恰好 5。

那么为什么要使用 CKKS 呢?CKKS 更适合实数算术,我们可以得到近似但接近的结果,而 BFV 更适合整数算术。

我们将在本文中看到如何使用 LWE 和 RLWE 实现近似算术同态加密方案的加密和解密。

错误学习

CKKS 是一种公钥加密方案,其中生成密钥和公钥。公钥用于加密,可以共享,私钥用于解密,必须保密。

CKKS和其他许多同态加密方案的基础是错误学习(LWE)问题,LWE问题是为了区分

这个问题会变得容易得多,因为我们可以用高斯消去法来解线性方程组。

我们都知道,LWE问题的难度不亚于量子计算机的最坏情况格点问题。因此,我们可以利用发现秘密s(ai, < ai, s > +ei)这一事实。

假设我们生成一个秘钥:

 事实上,我们将使用 p = (-A.s + e, A) - A.s A.s

然后使用公钥和秘钥对一条μ∈Znq的消息进行加密和解密,可以采用以下方案:

  • 使用p加密μ:输出

        c = (μ, 0) + p = (μ − A.s + e, A) = (c0, c1).

  • 使用s解密c:输出

        μ' = c0 + c1.s = μ − A.s + e + A.s = μ+e ≈ μ

在加密阶段,我们使用公钥,用它来掩盖信息μ。因此,消息被隐藏在带有掩码−A.s的密文的第一个坐标中。记住A是均匀采样的,所以它确实有效地掩盖了μ。为了去掉它,我们可以使用c的第二个坐标,它只存储A,并与秘钥s结合,得到的解密结果是μ+e。注意这里,我们并没有精确地得到原始信息μ,而是μ加上一些噪声e,这就是为什么我们说我们有一个近似的算术方案。如果e足够小,则解密将接近于原始的μ。

因此,我们已经在这里看到了如何使用LWE问题来构建一个可以安全抵御量子攻击的公开加密方案。上述实现的问题是,虽然秘钥的大小是O(n),但由于矩阵A,公钥的大小是O(n^2),计算也需要O(n^2)操作。因为n将决定我们方案的安全性,如果我们使用LWE来构造我们的方案,在实践中它将非常低效,因为O(n^2)密钥大小和复杂性将使它太不切实际。

环形学习错误

环形学习错误是LWE的一个变体,但在环上。Znq不是使用向量,我们将工作在多项式Zq [X] / (X^N + 1)(我们假设这里N是2的幂)。现在我们画一个圆和e来自Zq [X] / (X^N + 1),仍然是均匀采样的,圆是一个小秘密多项式和e是一个小噪声多项式。切换到RLWE有两个主要优点:

  • 密钥的大小不再是二次的而是线性的,因为我们现在输出公钥p = (−a.s + e, a),其中a.s表示a与s的多项式乘积。因为所有的操作都是在多项式之间完成的,所以私钥和公钥的大小都是O(n)。
  • 乘法是在多项式上做的,因此它可以用离散傅里叶变换来完成复杂度为O(nlog(n))的多项式乘法,而不是O(n^2)因为我们必须做矩阵向量乘法。

所以用RLWE代替LWE,我们的key会小很多,运算会更快,所以前面的方案就更实用了。而且,RLWE 仍然是一个难题,并提供了强大的安全保证,因此使用 RLWE 仍然提供了一个安全方案。

同态操作

现在我们已经知道了为什么我们要研究Zq[X]/(X^N+1)的多项式,以及我们如何得到一个基于它的加密方案,让我们看看如何定义密文上的加法和乘法来得到一个同态加密方案。

我们有一个秘密为s,一个公钥p = (b, a)=(- a.s + e, a),要加密消息μ,我们只需输出c = (μ+b, a),而要用s解密它,我们计算c0+c1.s,它将近似地给出原始信息。

大致思路(重要)

加法

现在假设我们有两个信息:μ和μ',然后我们把它们加密成c = (c0, c1)和c' =(c'0, c'1)。那么c'' = c + c' = (c0 + c'0, c1+c'1)就是 μ + μ'的正确加密,即当我们用s解密时,我们(近似地)得到μ+μ '。

实际上,c''的解密机制是c'',0+c'',1.s = c0 + c'0 + (c1 + c'1).s = c0 + c1.s + c'0 + c'1.s = μ+μ ' +2e≈μ+μ'。因为我们说过e是可以忽略的。

这意味着如果您添加密文,然后解密它们,您将获得添加的明文!这意味着通过这个简单的方案,您可以允许某人对加密数据执行添加操作,而用户仍然可以对其进行解密并获得正确的结果。这是我们迈向同态加密方案的第一步。

大致思路(重要)

 乘法

尽管如此,我们仍然需要定义密文上的乘法,这更复杂。实际上,我们的目标是找到一个密文堆积体c'',这样当我们用密钥s解密它时,我们就能得到明文的乘积。

因为两个密文的乘法比较复杂,所以我们现在先重点讲一个密文和一个明文的乘法,后面的文章看看密文之间的乘法怎么做。

假设我们有一个明文μ,加密成密文 c = (c0, c1)和明文μ'。然后,只需输出c'' = (μ'.c0,μ'.c1),即可得到乘法的密文。

然后我们解密c'',我们得到:

μ′.c0 + μ′.c1.s=μ′.(c0 + c1.s)=μ′.(μ + e)=μ′.μ + μ′.e ≈ μ′.μ

因此,通过这些加法和乘法的实现,我们已经看到可以加密一些数据,对其执行操作,这样一旦我们解密它,我们就会得到与对明文数据执行计算相同的结果。

因为我们还有一些概念需要解决,比如密文-密文乘法、重新线性化和重新缩放,我们暂时不会介绍代码实现。一旦我们拥有了所有的构建块,我们将把所有东西放在一起,形成一个类似于 CKKS 的端到端近似同态加密方案!

大致思路(重要)

<think>好的,我现在要处理用户关于CKKS同态加密解密原理实现的问题。首先,我需要回忆一下CKKS的基本概念结构。CKKS是一种支持近似数运算的同态加密方案,主要用于实数或复数上的计算,这在机器学习中非常有用。用户之前提到的参考内容提到了噪声问题现有方案的一些特点,这可能与CKKS中的噪声管理有关。 首先,我应该从CKKS的整体流程开始,包括加密解密以及同态操作的过程。需要解释其数学基础,比如环LWE问题、多项式环结构,以及编码解码的部分,因为CKKS的关键在于将浮点数向量编码到多项式环上,然后再加密。这里可能需要提到FFT逆FFT在编码中的作用,以及如何通过缩放因子来保持精度。 接下来是加密的具体步骤,包括公钥的使用,如何生成密文。然后解密过程,用私钥解密出编码后的多项式,再通过解码得到原始向量的近似值。这里需要强调噪声的影响,每次操作后噪声会增加,当超过阈值时解密会失败,所以需要噪声管理技术,比如模切换重线性化。 然后是同态操作,加法乘法的处理方式,特别是乘法后如何用重线性化来减少密文大小,以及模切换控制噪声增长。这部分需要详细说明,因为用户可能对如何实现这些操作感兴趣。 关于实现,可能需要提到常用的库,比如Microsoft SEAL或PALISADE,以及实现中的关键参数选择,比如多项式次数、模数链的设置、缩放因子的大小等。这部分需要结合理论,说明参数如何影响安全性计算能力。 用户的问题还提到了参考中的噪声问题,所以在解释过程中要特别强调噪声管理的策略,比如在乘法加法后如何处理噪声,以及如何通过调整参数来平衡计算深度噪声增长。 最后,生成相关问题需要考虑用户可能的后续疑问,比如与BFV的区别、参数选择、实际应用中的挑战、如何评估安全性等。这些问题应该覆盖理论实践的不同方面,帮助用户进一步探索。 检查是否有遗漏的部分,比如是否涵盖了加密解密的数学表达式,是否正确使用了$$...$$格式,是否引用了提供的参考内容。确保所有数学公式都正确使用LaTeX,行内公式用$...$,独立公式单独成段。同时,回答需要用中文,结构清晰,分步骤解释。</think>### CKKS同态加密原理与实现 #### 1. 基础结构 CKKS方案基于**环LWE问题**构建,核心数学结构为多项式环$R_q = \mathbb{Z}_q[X]/(X^N + 1)$,其中$N=2^k$为多项式次数。加密对象为复数向量$z \in \mathbb{C}^{N/2}$,通过**编码-加密-计算-解密-解码**流程实现近似计算[^1]。 #### 2. 编码/解码过程 **编码**:将向量$z$映射到多项式$m(X) \in R$: $$ \text{Encode}(z) = \Delta \cdot \tau^{-1}(z) $$ 其中$\Delta$为缩放因子(保留小数精度),$\tau$为**规范嵌入映射**,利用FFT实现快速转换。 **解码**:通过逆过程恢复近似值: $$ \text{Decode}(m) = \tau(m/\Delta) $$ #### 3. 加密/解密流程 - **密钥生成**:生成私钥$s \leftarrow R_2$(元多项式),公钥$pk=(b,a)=(-a\cdot s + e \mod q, a)$ - **加密**:对消息$m$生成密文$ct=(c_0,c_1)= (v\cdot b + m + e_0, v\cdot a + e_1) \mod q$ - **解密**:计算$m' = c_0 + c_1 \cdot s \mod q$,再解码得到近似结果 #### 4. 同态操作 - **加法**:直接相加对应位置多项式 $$ ct_{add} = (ct_1[0]+ct_2[0], ct_1[1]+ct_2[1]) $$ - **乘法**:使用张量积后重线性化 $$ ct_{mult} = \text{Relin}(ct_1 \otimes ct_2) $$ 引入**重线性化密钥**$rlk$将次密文降为次 #### 5. 噪声管理 - **模切换**:每次乘法后降低模数$q \rightarrow q'$,按比例缩放噪声 $$ ct' = \lfloor (q'/q) \cdot ct \rceil $$ - **缩放因子调节**:动态调整$\Delta$值保持计算精度 #### 6. 实现示例(伪代码框架) ```python class CKKS: def __init__(self, poly_degree=1024, scale=2**30): self.N = poly_degree # 多项式次数 self.scale = scale # 缩放因子 self.q = 60 # 初始模数 def encode(self, z): # 使用FFT将向量转换为多项式 m = inverse_fft(z) * self.scale return m.round() def encrypt(self, m, pk): v = random_poly() e = error_poly() ct0 = pk.b * v + m + e ct1 = pk.a * v + e return Ciphertext(ct0, ct1) def decrypt(self, ct, sk): m_approx = ct[0] + ct[1] * sk return m_approx / self.scale ``` #### 7. 关键技术点 1. **近似计算特性**:允许有限精度的浮点运算误差 2. **复数支持**:通过编码方案处理实部虚部 3. **打包加密**:单次加密可处理$N/2$个复数 4. **模数链设计**:$q = \prod_{i=0}^L q_i$ 实现多级计算
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值