如何在Qiskit中优化适用于Kyber/NTRU的(𝑎+𝑏+1)mod(2ⁿ+1)可逆模加法器?
实现(𝑎+𝑏+1)mod(2ⁿ+1)高效可逆加法器(Qiskit)
核心原理
模2ⁿ+1的关键特性是2ⁿ ≡ -1 mod(2ⁿ+1),这意味着n位加法溢出时(总和≥2ⁿ),等价于将溢出位取反后反馈到最低位做修正,无需额外大数值减法操作。
分步实现方案
1. 基础可逆加法链(带进位)
用QuantumRegister存储输入,1个辅助比特处理进位(初始置1对应加1操作),仅用CNOT和Toffoli门构建可逆全加器链:
from qiskit import QuantumCircuit, QuantumRegister, AncillaRegister n = 4 # 可替换为目标位宽 a = QuantumRegister(n, 'a') b = QuantumRegister(n, 'b') # 最终结果存在b中 carry = AncillaRegister(1, 'carry') qc = QuantumCircuit(a, b, carry) # 初始化carry为1,对应加1操作 qc.x(carry[0]) # 可逆全加器链(从最低位到最高位) for i in range(n): # 计算第i位和与进位更新,保证操作可逆 qc.ccx(a[i], b[i], carry[0]) qc.cx(a[i], b[i]) qc.cx(carry[0], b[i])
此时carry[0]为溢出标志(1表示总和≥2ⁿ),b存储无模和。
2. 可逆模修正
基于溢出标志执行模2ⁿ+1修正:若溢出,将无模和减1(因为2ⁿ ≡ -1,总和2ⁿ + t等价于t-1 mod(2ⁿ+1))。用溢出位作为控制位,实现可逆减1:
# 溢出时对b执行可逆减1 for i in range(n): # 从最低位开始,翻转直到遇到第一个1(可逆减1逻辑) qc.ccx(carry[0], b[i], carry[0]) qc.cx(carry[0], b[i]) # 恢复carry到初始状态(可复用) qc.x(carry[0])
修正后b寄存器存储的就是(a+b+1)mod(2ⁿ+1)的结果。
3. 辅助比特复用优化
解决之前反计算混乱的问题:加法完成后,反向执行加法链的逆操作,恢复a和carry到初始状态,实现辅助比特零开销复用:
# 反计算加法链,恢复a和carry(保留b的结果) for i in range(n-1, -1, -1): qc.cx(carry[0], b[i]) qc.cx(a[i], b[i]) qc.ccx(a[i], b[i], carry[0])
4. 与QFT/先行进位集成
- 先行进位集成:用可逆先行进位逻辑替换逐位加法链,将电路深度从O(n)降至O(log n)。通过多层Toffoli门提前计算高位进位,避免逐位传播延迟,完全兼容现有可逆门约束。
- QFT集成:QFT加法器适合大位宽场景,模
2ⁿ+1可通过QFT域的相位调整实现——将加法转换为相位偏移后,对溢出对应的相位执行反转,再逆QFT得到结果。结合反计算可大幅减少QFT所需的辅助比特开销。
关键优化总结
- 仅用1个辅助比特,通过反计算完全复用,无额外开销;
- 纯CNOT/Toffoli门实现,符合可逆逻辑要求;
- 先行进位优化后电路深度降至对数级;
- 模修正逻辑直接利用
2ⁿ+1的数学特性,避免冗余操作。
内容的提问来源于stack exchange,提问作者Supercell Burner
相关产品推荐
相关产品推荐

