3. 同态加密算法概览:BGV、BFV、CKKS、TFHE 的原理对比与适用场景
咱们做日志聚合查询,说白了就是在密文上做计算。但同态加密不是一门统一的法术,它分好几条路。每条路的设计哲学、数学基础、适用场景都不太一样。如果你选错了方案,性能会差一个数量级,甚至功能都跑不通。
我个人习惯,在决定用哪个方案之前,先搞清楚这几件事:你要算整数还是实数?电路深度大不大?容忍多少性能损耗?想清楚这些,再选算法。
这一章,咱们把目前最主流的四个方案——BGV、BFV、CKKS、TFHE,挨个拆解一遍。我会结合我在日志系统中的踩坑经验,给你讲清楚:它们各自长什么样,有什么短板,以及什么时候该用谁。
3.1 BGV 方案
BGV 是 Brakerski-Gentry-Vaikuntanathan 的缩写,2011年提出。它是最早进入实用化阶段的层次型全同态方案之一。
BGV 的核心思路是模数切换(Modulus Switching)。你可以理解为:每次乘法都会让噪声膨胀,BGV 通过减小密文模数把噪声压下来。代价是模数会一步步变小,最终算到极限就停了。所以 BGV 天然适合已知深度的电路。
我在项目中遇到过一个问题:如果用 BGV 做日志平均值的聚合,需要预先知道日志记录的总条数,否则模数链长度定不下来。你想想看,如果日志流是无限的,BGV 就有点尴尬。
3.2 BFV 方案
BFV(Brakerski-Fan-Vercauteren)与 BGV 几乎同时期。它俩解决的是同一个问题,但路子不一样。
BFV 用的是缩放因子(Scaling Factor)。它把明文放大后再塞进密文,计算完再缩放回来。噪声控制靠的是“relinearization”和“rescaling”的组合拳。
| 对比维度 | BGV | BFV |
|---|---|---|
| 噪声管理方式 | 模数切换(变小) | 缩放因子(动态调整) |
| 密文膨胀 | 较低 | 中等 |
| 乘法性能 | 稍快 | 加解密稍慢 |
| 整数精度 | 精确 | 精确 |
3.3 CKKS 方案
CKKS(Cheon-Kim-Kim-Song)2017年才提出。它一出世,咱们工程师的眼睛就亮了——因为它支持近似计算。
日志聚合里,平均值、方差、百分位数……这些统计量通常都涉及实数运算。BGV 和 BFV 做实数要自己编码,很麻烦。CKKS 直接把实数放进去,允许计算过程中有一个可控的误差。这个误差一般在 \(10^{-5}\) 级别,对统计查询来说完全够用。
你想想看,日志分析里,99%的查询都不要求数学上的精确值。你要的是“今天平均延迟是 120.3ms 还是 120.5ms”?这个误差完全能接受。
我个人偏好,在日志聚合场景里,CKKS 是最实用的选项。性能好,精度够,代码写起来也省心。
3.4 TFHE 方案
TFHE(Fast Fully Homomorphic Encryption over the Torus)2016年由 Chillotti 等人提出。它有个独门绝技:单次运算速度快,支持任意次数的自举(Bootstrapping)。
什么叫自举?就是清空噪声,让密文回到初始状态。BGV 和 BFV 也能做,但慢。TFHE 的自举只需毫秒级别。这意味着你可以做任意深度的电路,不用提前规划。
但代价是:TFHE 的单次乘法或比较操作比 BGV 慢。它适合做“控制流密集”的任务,比如密文比较、条件选择、分支判断。
- 优势:支持任意深度计算,自举速度快,适合做查找表(LUT)。
- 劣势:单次操作开销大,对批量向量处理不友好。
- 适合场景:需要在密文上做条件判断(比如“如果值大于阈值则触发告警”)。
3.5 四种方案核心对比
我把它们的核心参数放在一张表里,方便你对照。
| 方案 | 设计目标 | 数据类型 | 适用场景 | 性能特点 | 缺点 |
|---|---|---|---|---|---|
| BGV | 层次全同态 | 整数(精确) | 固定深度批处理 | SIMD 快,乘法低延迟 | 深度受限 |
| BFV | 层次全同态 | 整数(精确) | 通用整数计算 | 编程模型直观 | 解密开销大 |
| CKKS | 层次全同态 | 实数(近似) | 统计、ML、日志聚合 | 近似计算,性能好 | 有误差 |
| TFHE | 自举全同态 | 二进制/小整数 | 条件判断、控制流 | 任意深度,自举快 | 单次操作慢 |
3.6 怎么选?我的经验法则
搞清楚区别以后,选型就不难了。我一般按这个流程走:
- 看数据类型:是整数还是实数?整数走 BGV 或 BFV,实数直接上 CKKS。
- 看电路深度:如果计算步骤超过 10-20 层,而且不能提前规划,TFHE 更合适。
- 看批量程度:如果一次要处理百万级记录,BGV 的 SIMD 是最优解。
- 看精度要求:需要精确到位的匹配,不要用 CKKS。
嗯,这里要注意:写代码的时候,不要为了“通用”去封装一个万能库。同态加密跟传统加密不一样,参数配错了直接跑不动。我见过有人用 BGV 的参数去跑 CKKS 的电路,结果噪声炸了,解密全错。
3.7 知识体系图
下面这张图概括了四种方案在日志聚合场景中的定位。你可以用它来做选型参考。
这张图你多看几眼。实际写代码时,先定位你的数据在哪个节点,再往下走,基本不会选错。
好,这一章就到这里。算法选型是基础,基础打牢了,后面写聚合查询逻辑才能顺手。