本节摘要:噪声预算是同态工程的"燃料表":它定义为一个密文从当前噪声到危险线的比特余量,每种操作按固定速率消耗它。本节给出预算的定义与测量方式、完整消耗表、耗尽的典型症状与排错流程,然后讲清 SIMD 打包如何把单密文成本摊到数千槽上、跨槽运算为何需要旋转密钥与对角线技术。这是全册工程计量的基础一节。
把解密条件翻译成工程语言:密文里藏着一个噪声量,它必须小于某个危险线,解密才能正确。所谓噪声预算,就是"危险线的对数减去当前噪声的对数",单位是比特——预算还剩多少比特,就还能扛住多少增长。一个刚加密的密文,预算大约等于系数模数与明文模数之比的对数减去初始噪声:以一百零九比特系数模数、二十比特明文模数的常用档为例,新密文预算约几十比特(典型报告值在五六十比特量级)。预算归零,解密开始输出随机垃圾,而且没有任何报错——这是同态系统最阴险的故障形态。
测量预算的标准方法叫"解密失败测试":把密文解密、与正确明文比对、二分定位失败点,反推预算。主流库把预算查询做成了内省接口,工程上应当把它嵌入单元测试——每个电路模板跑完一遍后断言预算余量大于安全阈值(一般留五到十比特余量),余量不足就在持续集成里直接失败。这套纪律成本低廉,却能把"上线后偶发解密乱码"这类最难排查的问题消灭在提交阶段。

把消耗速率列成表,预算管理就从玄学变成算术。下表是整数线方案的典型量级(近似线把"乘法"换成"乘法加重缩放",速率略低):
| 操作类型 | 预算消耗(量级) | 附注 |
|---|---|---|
| 新鲜加密 | 起点约五十五比特(常用档) | 依参数浮动 |
| 密文加法 | 约一比特 | 取较大噪声加常数 |
| 明文乘法(乘常数) | 与常数比特数相关 | 便宜得多,能省则省 |
| 密文乘法(含重线性化) | 约二十到二十五比特 | 大头,深度规划的锚点 |
| 旋转 | 约十比特上下 | 跨槽运算的固定税 |
| 自举 | 重置回起点附近 | 消耗时间而非预算 |
预算分配的实践像项目排期:先数电路的乘法深度(把激活函数的逼近多项式次数也算进去),乘上单次消耗,加上末尾安全余量,得到需要的模数链长度;再去安全参数表里找能容纳这条链的维度档。一个高频失误是漏算"隐式乘法"——比如把除法实现为求逆级数、把比较实现为符号函数多项式,这些电路的真实深度往往比直觉深两三倍。预算排错的排查顺序也固定:先确认参数档与电路深度匹配、再检查是否有密文意外跨层相乘(把高层密文与低层密文混算会瞬间烧穿预算)、最后怀疑实现层的精度错配。
第三章提过打包的原理(中国剩余定理对齐),这里补全它的工程面。一个维度八千一百九十二的密文有四千零九十六个槽,加法与乘法天然槽内独立进行;单密文一百多千字节的尺寸没变,但"每次运算服务的明文数"从一变成四千零九十六——摊销后每槽成本骤降三个数量级以上。这就是"负载必须向量化"的硬理由:把一个循环里逐条处理的记录重排成定长向量批量加密,是同态工程收益最大的一次重构,没有之一。
跨槽运算是打包的税种。槽与槽在中国剩余结构里互相独立,想让第一槽的值去到第三槽,必须做"旋转"——用伽罗瓦密钥执行一次自同构。旋转贵(预算与时间都高出普通乘法一截),于是向量级的模式匹配与矩阵乘法都围绕"少旋转"设计:矩阵乘向量的标准做法是对角线法,把矩阵按循环对角线拆开,每条对角线乘上旋转后的向量再累加,旋转次数等于维度的一半。深度学习卷积层的旋转优化(把卷积重排成矩阵乘、复用旋转结果)是隐私推理性能的关键手筋,第五章算例里会看到它的实战数字。
# 预算检查的单元测试骨架(接口形态参考主流库) def test_circuit_noise_budget(ctx, circuit_template, inputs): ct = encrypt_inputs(ctx, inputs) for step in circuit_template: ct = step.apply(ct) # 逐步执行同态运算 if step.is_multiplication: budget = ctx.remaining_budget(ct) assert budget >= SAFETY_MARGIN, ( f"预算余量 {budget} 比特低于安全线," f"当前步骤 {step.name},建议提升维度档或插入自举") assert decrypt_and_check(ct, inputs) # 端到端正确性对拍
这段骨架值得直接抄进项目:预算断言放在每次乘法之后而不是电路末尾,能把"哪一步烧穿预算"的定位成本从小时级降到分钟级。再配合持续集成里的定期跑批,参数档升级(比如社区标准更新)引起的预算滑坡会在第一时间暴露。
💡 关键直觉:噪声预算像旧式机械手表的发条——上满弦(新密文)后走时(运算)稳定消耗,发条将尽时不是停摆而是先乱走(解密输出随机值)。工程上必须装"余量表"(预算查询)并在跌到安全线前主动回店上弦(自举或重新加密)。
把噪声预算从概念落到日常工程操作。操作一,预算表的建立:每个业务管线开工前,列一张乘法深度表(每个算子消耗几层),层数加安全余量定参数档位——这张表就是同态工程的施工图,改一层参数意味着全链重测,改前必须过评审。操作二,噪声的可观测化:多数库能导出当前噪声水位(invariant noise ratio 之类),把它的日志接进观测面板,跑批量任务时盯着曲线与预算线的距离——距离收窄到警戒线就报警,能防住九成的密文失聪事故。操作三,打包策略与噪声的联动:SIMD 槽里塞的明文振幅越大,运算后的噪声吃越深,所以打包不只是把数据摆满,还要按数据的动态范围分层摆——大数单独一槽或先缩放,这是 CKKS 精度事故的头号来源。操作四,失败演练:故意用浅参数跑超深度任务,看密文失聪时的报错形态与诊断路径——团队见过一次失聪,比读十遍噪声章节都管用。四条操作的共同底色:把不可见的噪声变成看得见的指标与流程,这是同态工程从能跑到可靠的分水岭。