CKKS 同态加密方案深度解析:近似计算的格密码实现
概述
全同态加密(FHE)自 2009 年 Gentry 提出首个可行方案以来,经历了三代演进:BFV/BGV 支持整数精确计算,TFHE 支持布尔电路,而 CKKS(Cheon-Kim-Kim-Song, 2016)则开辟了实数/复数近似计算的新赛道。
CKKS 的核心创新在于复数编码:将明文向量映射到多项式环 ℤₚ[x]/(xⁿ+1) 的复数域中,使得同态加法与乘法天然对应 SIMD 向量运算。配合重缩放(Rescaling)技术,CKKS 能够在每次乘法后控制噪声增长,从而实现大规模近似计算。
| 特性 | BFV/BGV | CKKS | TFHE |
|---|---|---|---|
| 明文类型 | 整数 ℤ_q | 复数 ℂⁿ/² | 布尔值 |
| 计算精度 | 精确 | 近似(可调节) | 精确 |
| SIMD 批处理 | 是(整数编码) | 是(自然复数向量) | 否 |
| 引导速度 | 秒级 | 秒级 | 毫秒级 |
| 典型应用场景 | 精确统计、投票 | ML 推理、信号处理 | 布尔电路、比较操作 |
数学基础:从 RLWE 到复数编码
RLWE 问题回顾
CKKS 的安全性基于 Ring-LWE(Ring Learning With Errors)问题。给定多项式环 R_q = ℤ_q[x]/(xⁿ+1),问题定义为:
输入:(a, b = a·s + e mod q)
求解:秘密多项式 s ∈ R_q其中 a ← R_q 均匀随机,s ← χ_s 从误差分布采样,e ← χ_e 从更窄的误差分布采样。当 n = 2^k 时,R_q 具有好的代数结构,支持 NTT 加速。
CKKS 复数编码
CKKS 的核心创新是将明文向量 m = (m₀, m₁, ..., m_{n/2-1}) ∈ ℂ^{n/2} 编码为多项式 m(x) ∈ R_q:
m(x) = Σ_{i=0}^{n/2-1} m_i · (x^n - 1)/(x - ζ^{2i+1}) mod Φ_n(x)其中 ζ = e^{πi/n} 是 2n 次本原单位根,Φ_n(x) = xⁿ+1 是第 2n 个分圆多项式。
解码过程(NTT 逆变换):对多项式系数进行逆数论变换(INTT),得到评估点值:
m_i ≈ Δ^{-1} · Poly(ζ^{2i+1}) mod q其中 Δ = ⌊q/t⌋ 是缩放因子,t 是明文模数(通常 t = 2^δ,δ ≈ 30-60)。
编码与解码公式
编码(Encode):将复数向量编码为多项式系数。
# ⚠️ 伪代码:实际编码需使用专业 FHE 库
# CKKS 编码涉及复数域上的拉格朗日插值,无法用纯 Python 简单实现
# 编码原理简述:
# 1. 将复数向量 m 乘以缩放因子 Δ,转换为整数表示
# 2. 在 2n 次单位根的奇数幂处评估多项式
# 3. 通过逆 NTT 得到多项式系数,模 q 约化
# 4. 最终返回长度为 n 的整数列表(模 q)解码(Decode):多项式系数 -> 复数向量。
# ⚠️ 伪代码:实际解码需使用专业 FHE 库
# CKKS 解码涉及 NTT 评估和复数域插值
# 解码原理简述:
# 1. 对多项式系数进行 NTT 评估(在单位根处采样)
# 2. 提取奇数位置的评估点 {Poly(ζ^(2i+1))}
# 3. 乘以 Δ⁻¹ 恢复原始复数
# 4. 最终返回长度为 n/2 的复数列表核心运算原语
同态加法
CKKS 的加法是逐分量多项式加法:
Enc(m₁) + Enc(m₂) = Enc(m₁ + m₂)噪声增长:Δ_new ≈ Δ₁ + Δ₂,线性叠加。
同态乘法与重缩放
乘法是 CKKS 的关键操作,涉及重缩放(Rescaling):
Enc(m₁) · Enc(m₂) = Enc(Δ · m₁ · m₂) (模 q)乘法后密文尺度变为 q·Δ,需要通过重缩放将其恢复到 Δ:
rescale(ct, p) = ct · p^{-1} mod q其中 p 是预选择的素数(通常取 q 的大因子),使得 p | q。
重缩放后:
Rescale(Enc(Δ·m₁·m₂), p) = Enc(m₁·m₂) (模 q/p)新模数 q' = q/p,噪声增长:
Δ_new ≈ (Δ₁ · Δ₂) / p + e_rescale自同构(Rotation)
CKKS 支持循环旋转操作,用于 SIMD 向量的移位:
Rotl(Enc(m₀, m₁, ..., m_{n/2-1})) = Enc(m_{n/2-1}, m₀, ..., m_{n/2-2})实现方式:利用多项式环的自同构 σ: x ↦ x^{2^k} mod (xⁿ+1)。
关键优化:旋转操作需要辅助密钥(galois keys),这些密钥由密钥生成器预先计算并存储。
噪声增长模型
CKKS 的安全性依赖于噪声(错误)的增长可控。
噪声预算
定义噪声预算:
budget = log₂(q) - log₂(Δ) - log₂(||e||)每次加法消耗约 log₂(2) 的预算,每次乘法消耗约 log₂(Δ) 的预算。
深度限制
给定初始参数 (n, q, Δ),最大同态深度:
max_depth ≈ budget / log₂(Δ)工程建议:
- 简单加法网络:n = 2¹⁴-2¹⁶, q 约 60-80 位
- ML 推理(多乘法):n = 2¹⁶-2¹⁸, q 约 1200-2400 位
- 引导操作可将深度恢复,但增加开销 60-80%
参数选择指南
安全级别
CKKS 的参数选择需平衡安全性、性能与精度:
| 安全级别 | n | q 位数 | Δ 位数 | 预估安全性 |
|---|---|---|---|---|
| 128-bit | 2¹⁴ | 600-800 | 30-40 | AES-128 等价 |
| 192-bit | 2¹⁵ | 900-1200 | 30-40 | AES-192 等价 |
| 256-bit | 2¹⁶ | 1200-2400 | 30-40 | AES-256 等价 |
精度与噪声平衡
缩放因子 Δ 的选择影响精度与噪声:
精度 ≈ log₂(Δ) 位
噪声增长 ∝ Δ(乘法时)经验法则:
- 浮点单精度(23 位尾数):Δ = 2³²
- 浮点双精度(52 位尾数):Δ = 2⁶⁴(需更大 q)
- 机器学习(8 位量化):Δ = 2¹⁶ 足够
工程实现要点
主流库介绍与使用示例
目前生产级 CKKS 实现主要有三个库:
- Microsoft SEAL(C++,Python 绑定)— 最成熟的开源实现,支持 BFV/CKKS/BGV
- OpenFHE — 多方案支持,社区活跃
- PALISADE — 学术导向,支持多种 FHE 方案
# ⚠️ 以下示例需要安装 Microsoft SEAL Python 绑定
# pip install microsoft-seal 或从源码编译安装
# 示例流程(非可运行代码):
from seal import CKKSEncoder, SEALContext, KeyGenerator
# 1. 设置参数
parms = SealParams(SEAL_POLICY_NTT_AVAILABLE)
context = SEALContext(parms)
scale = 2.0 ** 40 # 精度控制
# 2. 初始化编码器和密钥
encoder = CKKSEncoder(context)
keygen = KeyGenerator(context)
sk, pk, rk = keygen.keypair()
# 3. 编码复数向量并加密
plain_vec = [complex(i, 0) for i in range(8192 // 2)]
plain = Plaintext()
encoder.encode(plain_vec, scale, plain)
cipher = Ciphertext()
encryptor.encrypt(pk, plain, cipher)
# 4. 同态运算
evaluator = Evaluator(context)
evaluator.multiply_inplace(cipher, cipher) # 平方
evaluator.rescale_to_inplace(cipher, scale) # 重缩放
# 5. 解密
decryptor = Decryptor(context, sk)
result_plain = Plaintext()
decryptor.decrypt(cipher, result_plain)
decoded = encoder.decode(result_plain)性能特征
基于 Intel Xeon Gold 6248R @ 3.0GHz,Microsoft SEAL 4.1,n = 2¹⁴:
| 操作 | 延迟 | 吞吐量 |
|---|---|---|
| 加密(向量 8192) | 2-5 ms | 200-500 ops/sec |
| 解密(向量 8192) | 1-3 ms | 300-1000 ops/sec |
| 同态加法 | 0.5-1 ms | 1000-2000 ops/sec |
| 同态乘法(含重缩放) | 5-15 ms | 70-200 ops/sec |
| 旋转操作 | 1-3 ms | 300-1000 ops/sec |
| 引导(bootstrapping) | 2-10 秒 | 0.1-0.5 ops/sec |
应用场景
隐私保护机器学习
CKKS 在 NN-inference(神经网络推理)中表现突出:
输入:加密的患者特征向量(1024 维)
模型:加密的神经网络权重(128 层)
输出:加密的预测结果(疾病风险评分)关键技术:
- 固定点编码:将浮点数转换为定点数,减少精度损失
- 分段线性近似:用折线近似激活函数(ReLU、Sigmoid)
- batching 优化:利用 SIMD 并行处理多个样本
安全多方统计分析
场景:多家医院联合计算患者平均年龄
方案:每家医院加密自己的数据,汇总后解密均值
优势:数据不出院,隐私不泄露信号处理
CKKS 天然支持复数运算,适用于:
- 加密的 FFT 计算
- 安全频谱分析
- 加密滤波器设计
与 BFV/BGV 的关键差异
| 对比项 | BFV/BGV | CKKS |
|---|---|---|
| 编码方式 | 整数编码 | 复数编码 |
| 缩放因子 | 无(精确计算) | 有(近似计算) |
| 重缩放操作 | 不需要 | 必须(每次乘法后) |
| 旋转操作 | 需特殊编码 | 原生支持 |
| 适用场景 | 精确算术 | 近似计算 |
已知局限与研究方向
当前局限
- 密文膨胀:CKKS 密文尺寸约为明文的 2n 倍(n = 8192 时约 128KB)
- 乘法开销:每次乘法需重缩放,比加法慢 10-100 倍
- 引导成本高:单次引导操作需 2-10 秒,限制了极深电路
- 精度损失累积:多次乘法后近似误差可能累积到不可接受
研究方向
- 模块化密码学:结合 BFV 与 CKKS,实现混合精度计算
- 硬件加速:FPGA/ASIC 专用 NTT 引擎,提升吞吐量
- 参数自动选择:根据电路深度自动优化参数
- 国密适配:探索 CKKS 与 SM2/SM9 标识密码的结合
参考资源
- CKKS 原始论文 (ASIACRYPT 2016)
- Microsoft SEAL 库 — 支持 BFV/CKKS 的生产级实现
- OpenFHE 库 — 支持多种 FHE 方案的开源库
- HElib 库 — 早期 CKKS 实现参考
相关实践文章:
- 同态加密基础 — FHE 整体架构概览
- Paillier 加法同态加密 — 部分同态方案
- RLWE 格密码基础 — CKKS 的安全基石