SEAL全同态加密CKKS方案入门详解

1 核心原理

1.1 编码与嵌入原理

CKKS的核心创新是规范嵌入(Canonical Embedding),将环R上的多项式与复数空间CN/2双向映射:

(1)多项式f(x)∈R可通过分圆多项式的根映射为N/2维复数向量

(2)复数向量可反向映射为环上多项式,实现向量数据与多项式的无损转换

(3)结合缩放因子Δ=2k,将浮点数放大为整数,适配有限域运算

槽位数量=N/2,例如N=8192时,单密文可打包4096个浮点数并行运算。R是分圆多项式环:

环中的元素是系数是整数(严格来说是实数)的N次多项式。

CN/2是N/2维复数向量构成的环,它里面的元素是N/2维复数向量。规范嵌入是环同构(保持环加法与乘法的双向一一映射):

设ζj = ei(2j+1)π/N,j = 0,1,...,N-1是xN + 1 = 0,即xN = -1 = eiπ的N个元根,则σ从左到右表示为:

σ有以下关键性质:

(1)加法映射为向量加法,即σ(f+g) = σ(f) + σ(g)

(2)乘法映射为向量逐元素乘法(Hadamard积)σ(f•g) = σ(f) • σ(g)

(3)双射(可逆)

可以从向量还原多项式(逆映射),接下来以N=8为例,从正反两个方面进行分析。

1 正向映射(canomical embedding R->C4)

当N=8时,环表示为:

环中的元素为多项式:f(x)=a0+a1x+a2x2+...+a7x7,x8+1=0的元根为:x=ei(2k+1)π/8,k=0,1,...,7,由元根的共轭可知:

则正向映射将多项式映射为复数向量,表示为:

以上只取前4个根,因为由于共轭有:

以多项式f(x) = 1 + 2x + 3x2为例,计算第一个槽:

同理可得4维向量的其他分量,从而完成多项式向复向量的映射,σ(f) = (z0,z1,z2,z3)∈C4。这一步本质上就是FFT的前半部分,𝑓(𝑥)有8个实自由度,而复向量看起来只有4个自由度,但是因为𝑧i是复数,它本身有2个实自由度,所以总体上来说复向量有4x2=8个实自由度。

2 逆向映射(C4->R)

逆向映射将复数向量映射为多项式,由(z0,z1,z2,z3)∈C4恢复一个多项式,构造长度为8的"频域向量":

唯一多项式f(x)满足:f(ζk) = zk,k = 0,1,2,...,7,利用Lagrange插值(工程上对应inverse FFT)即可得到:

其中所有ai∈R。这里的双向映射正是CKKS Encode/Decode在做的事:

1.2 缩放因子(Scale)及近似计算

CKKS不追求绝对精确,解密结果与原始明文存在极小精度误差,误差可控且远低于机器学习/数值分析的容忍阈值,这是效率与实用性的平衡设计,为了实现该目标引入了缩放因子,缩放因子在"把实/复数嵌入整数多项式环"时,由"缩放+舍入"不可避免引入了精度误差:

仍以N=8为例说明相应流程,原本映射

是一对零误差的严格双射,但是CKKS要做一件"非法的事",逆向映射由实/复数转换成整系数多项式,就是:

操作本身就不可能精确完成,原因很简单,左边是连续域,右边是离散格,CKKS的解决方案是进行"缩放+舍入(误差源头)",首先引入一个scale Δ,在映射前对复向量进行缩放:

这一步只是放大并没有引入误差,接下来进行逆embedding(IFFT)得到实系数多项式:

理论上这一步仍然是精确的,但是在进行随后一步舍入到整系数时会产生误差:

令:

其中e(x)的每个系数都满足|ei|≤1/2,当映射回slot空间时,会对m(x)再做canonical embedding:

而:

所以:

其中εk = e(ζk),最后会除于scale Δ:

这就是CKKS的"近似",对比BFV中的"舍入",他们的含义完全不同:

BFV的舍入是:

在模t意义下,向整数添加噪声,再把"整数+小噪声"映射回同一个整数,只要噪声受控该过程就是之前操作的精确逆操作。

CKKS的舍入是:

把"连续实数"映射到最近的整数,再把整数映射回实数,该过程并不是之前操作的精确逆操作,所以产生"近似"。

一句话:BFV里round用于"纠错",CKKS里round用于"近似"。在SEAL中常用2^40,精度与噪声达到平衡。

1.3 噪声管理

在CKKS中,噪声管理主要依靠Rescaling(重缩放)机制,它配合RNS链,实现了对噪声的"阶梯式"精准控制。

1 CKKS噪声的组成部分

CKKS的噪声e并不是单一来源,它是由三部分叠加而成的:

**初始噪声(erlwe):**加密时引入的离散高斯噪声,用于保障安全性。

**编码误差(eenc):**将浮点数缩放并舍入到整数多项式时参数的损失。

**计算误差(ecomp):**同态乘法和重线性化引入的噪声。

在CKKS中,我们不区分"噪声"和"误差"。缩放因子Δ决定了明文的精度,而噪声只要不侵蚀到Δ定义的有效位,计算就是可靠的。

2 核心机制:Rescaling(重缩放)

当我们做一次同态乘法:

如果不处理,连续乘法会导致数值迅速爆炸,超出模数q的范围。此时将密文除于一个RNS素数ql(通常设ql≈Δ),并进行舍入:

结果:

(1)缩放因子回归:Δ2/ql ≈ Δ,有效位回到了正确的位置。

(2)噪声同步缩减:原本的噪声e也被除于了ql,新噪声为:e/ql+舍入误差

可见Rescaling不仅把膨胀的数值拉回来,同时顺手把增长的噪声也按比例缩小了。

3 RNS链与层(Levels)的噪声控制

在实际实现中,模数Q是L个小模数之积Q=q0·q1·...·qL-1,每一层计算都对应链中的一个素数,以L=4为例给出流程:

以上每一层Rescaling都会吃掉总模数Q的约p比特(假设Δ=2p),当RNS链只剩下最后一个素数q0时,无法再进行Rescaling,此时再做乘法,噪声将无法被缩小,会迅速覆盖掉有效明文位。假设Q为600bit,Δ为40bit,Q能支撑约600/40=15层乘法,算到第15层时,模数只剩40bit左右,此时噪声和明文混在一起,无法再分。与BFV的区别:BFV的噪声管理是为了保住"整数的绝对准确";CKKS的噪声管理是为了保住"浮点数的有效精度"。

2 CKKS标准流程划分

以SEAL库为例,完整流程分为5个阶段。

2.1 系统初始化与参数生成

输入参数:

多项式模次数N(2的整数幂)

模数链系数{q1,q2,...,qL}(递减序列,决定运算深度)

缩放因子Δ=2k(控制计算精度)

高斯噪声分布χ(RLWE基础噪声)

输出参数:

合法的SEAL上下文

2.2 密钥生成

基于RLWE问题生成密钥组,私钥绝对保密,公钥/辅助密钥可公开分发。

(1)私钥sk

随机采样小范数多项式:sk∈R(系数仅为-1/0/1)

(2)公钥pk=(b,a)

a:环上随机多项式

b:b=-(a·sk + epk),其中epk是高斯噪声多项式

(3)重线性化密钥rlk

用于密文乘法后的维度压缩,由私钥加密派生,服务器执行重线性化时使用。

(4)旋转密钥rot_k(可选)

用于密文槽位旋转,实现向量数据重排、求和等高阶运算。

2.3 编码与加密

步骤1 明文编码(浮点数/复数->多项式)

该步会将实数/复数向量z∈CN/2转换为明文多项式。

(1)构造对称向量(Symmetry Construction)

在进行变换前,首先构造一个长度为N的向量Z:

向量的后部部分是前半部分的共轭,这种对称性保证了下一步IFFT出来的多项式系数全部是实浮点数。

(2)正则嵌入逆变换(IFFT)

将长度为N的对称向量Z进行逆变换,得到一个多项式p(x),其系数ai理论上应该是实数(由于浮点数计算精度问题,可能会有极小的虚部,通常直接舍弃)。

(3)缩放与舍入(Scaling & Rounding)

对实浮点数系数进行操作:

由此得到了系数为实整数的多项式pt。

以N=4为例,假设z=(3,4),则首先对z进行扩展Z=(3,4,4,3),因为3和4可以看作是虚部为零的复数,所以Z向量后半部分的共轭和前半部分完全相同。接下来目标是将Z映射为多项式p(x)=a0+a1x+a2x2+a3x3,即需要找到多项式的实系数a0,a1,a2,a3。在CKKS中,使用x4+1=0的单位根,它们是:ζ0 = eiπ/4,ζ1 = ei3π/4,ζ2 = ei5π/4,ζ3 = ei7π/4,ζ2和ζ3是ζ1和ζ0的共轭,则对于多项式p(x)满足:p(ζ0) = y0 = 3,p(ζ1) = y1 = 4,p(ζ2) = y2 = 4,p(ζ3) = y3 = 3,可以利用IFFT逆变换系数公式进行求解:

依次计算各个系数:

计算a0:

计算a1:

由:

可知:

计算a2:

由于ζ0-2 = -i,ζ1-2 = i,ζ2-2 = -i,ζ3-2 = i,可知:

计算a3:

由:

可知:

以上多项式系数的计算过程可以看到,系数中的虚部会因为共轭对称完全抵消,只剩实部,得到多项式是p(x)=3.5-0.3535x+0.3535x3,后续将在此多项式的基础上对齐系数进行放大及舍入完成编码流程。

步骤2 明文加密(明文->密文)

编码后的明文多项式pt被转换为一个包含两个多项式的密文对(c0,c1):

图中a,b是公钥对儿的两部分,u是小范数随机多项式,e0,e1是高斯噪声多项式,Q是密文大模数。

2.4 密文同态运算

支持加法、标量乘、密文乘、旋转、求和等运算,是CKKS的核心能力。

1 密文加法(同态加)

输入:两个同维度密文ct=(ct0,ct1),ct'=(ct0',ct1')

输出:ctadd=(ct0+ct0',ct1+ct1')

特性:无维度膨胀,无需重线性化,噪声线性叠加,运算后缩放因子保持不变。

2 密文乘法(同态乘)

原始乘法:两个二元组密文相乘,输出三元组密文ctmult=(c0,c1,c2),其中c0=ct0•ct0',c1=ct0•ct1'+ct1•ct0',c2=ct1•ct1'。

重线性化:使用重线性化密钥rlk,将三元组压缩回标准二元组,恢复密文结构

重缩放:乘法后,缩放因子变成Δ2,为了防止数值爆炸,会将密文除于Δ并舍入

模切换:降低模数,同步缩放数据,压缩噪声,保证后续运算可行性

特性:噪声指数级增长,必须配合重线性化+模切换使用。

3 高阶运算

标量乘法:密文与公开常数相乘,无需密钥

槽位旋转:移动单个槽位数据,配合旋转密钥使用

槽位求和:批量数据聚合,适用于统计计算

2.5 解密与解码

1 密文解密

输入:密文ct=(ct0,ct1)、私钥sk

输出:解码前明文多项式

解密公式:

最后部分可以看作是总噪声,则有:ptdec = pt + etotal

2 明文解码

(1)去除模数映射,将多项式转换为复数向量

(2)除于缩放因子Δ,还原为原始尺度的浮点数

(3)舍弃虚部(实数场景),得到最终计算结果

3 代码示例

以下是SEAL库CKKS同态加密方案示例代码:

相关推荐
Binary_ey2 小时前
光刻技术第22期 | 贝叶斯压缩感知光源优化的优化技术及对比分析
人工智能·深度学习·机器学习
蚂蚁数据AntData2 小时前
破解AI“机器味“困境:HeartBench评测实践详解
大数据·人工智能·算法·机器学习·语言模型·开源
ZC跨境爬虫2 小时前
Python异步IO详解:原理、应用场景与实战指南(高并发爬虫首选)
爬虫·python·算法·自动化
倦王3 小时前
力扣日刷47-补
python·算法·leetcode
沉鱼.443 小时前
第十三届题目
c语言·c++·算法
ZHOU_WUYI3 小时前
ppo算法简单实现
人工智能·pytorch·算法
无限进步_4 小时前
【C++】巧用静态变量与构造函数:一种非常规的求和实现
开发语言·c++·git·算法·leetcode·github·visual studio
小超超爱学习99374 小时前
大数乘法,超级简单模板
开发语言·c++·算法
Ricardo-Yang4 小时前
SCNP语义分割边缘logits策略
数据结构·人工智能·python·深度学习·算法