1. BB84 单光子源与偏振编码的密钥生成流程实现
任务拆解:一次 BB84 密钥协商要跑通哪些环节
本例的目标不是讲清 BB84 的全部物理背景,而是用一段可运行的 Python 代码,把“单光子偏振态制备 → 量子信道传输 → 单光子测量 → 基矢比对 → 筛选后密钥一致性校验”这条链路完整走一遍,并输出误码率。为了让结果可复现,我们固定随机种子,用理想信道(无窃听、无损耗)作为基线,此时筛选后误码率应为 0;随后再人为翻转少量比特,观察误码率如何变化,从而验证“误码率统计”这一环节确实在工作。
BB84 的核心约定如下:Alice 随机选择两种基矢之一——直角基(Z 基,用比特 0/1 表示)或对角基(X 基,用比特 +/− 表示);在每个基矢下随机选择比特值,制备对应的单光子偏振态。Bob 独立随机选择测量基矢进行测量。只有当双方基矢一致时,测量结果才具有确定性,这些比特构成筛选后密钥(sifted key)。
关键实现:偏振态制备与测量的编码方式
代码中用一个整数同时编码“基矢”和“比特值”,避免物理态与逻辑比特混淆。约定:0 表示 Z 基比特 0(|H⟩),1 表示 Z 基比特 1(|V⟩),2 表示 X 基比特 0(|+⟩),3 表示 X 基比特 1(|−⟩)。基矢由 state // 2 得到(0 为 Z,1 为 X),比特值由 state % 2 得到。Bob 的测量规则是:若测量基与制备基一致,则结果等于原比特;若不一致,则结果在 0/1 上等概率随机——这正是 BB84 中“非正交基测量引入不确定性”的最小化模拟。
import random
def prepare_state(rng):
"""Alice 制备:返回 0..3,编码 (基矢, 比特)。"""
basis = rng.randint(0, 1) # 0=Z, 1=X
bit = rng.randint(0, 1)
return basis * 2 + bit
def measure(state, bob_basis, rng):
"""Bob 测量:返回测量比特。"""
alice_basis = state // 2
alice_bit = state % 2
if bob_basis == alice_basis:
return alice_bit # 基矢一致,结果确定
return rng.randint(0, 1) # 基矢不同,结果随机
def run_bb84(n_bits=1000, seed=2024, flip_positions=None):
rng = random.Random(seed)
alice_states = [prepare_state(rng) for _ in range(n_bits)]
bob_bases = [rng.randint(0, 1) for _ in range(n_bits)]
bob_results = [measure(s, b, rng) for s, b in zip(alice_states, bob_bases)]
# 基矢比对与筛选
sifted_alice, sifted_bob = [], []
for s, bb, br in zip(alice_states, bob_bases, bob_results):
if s // 2 == bb:
sifted_alice.append(s % 2)
sifted_bob.append(br)
# 人为注入错误(用于验证误码率统计)
if flip_positions:
for p in flip_positions:
if p < len(sifted_bob):
sifted_bob[p] ^= 1
errors = sum(a != b for a, b in zip(sifted_alice, sifted_bob))
qber = errors / len(sifted_alice) if sifted_alice else 0.0
return len(sifted_alice), errors, qber
if __name__ == "__main__":
n, err, qber = run_bb84()
print(f"筛选后密钥长度: {n}, 错误比特数: {err}, QBER: {qber:.4f}")
n2, err2, qber2 = run_bb84(flip_positions=[0, 5, 10, 20, 50])
print(f"注入5处翻转后: 长度 {n2}, 错误 {err2}, QBER: {qber2:.4f}")
运行结果与判读
在理想信道、固定种子 2024、n_bits=1000 的设定下,筛选后密钥长度约为 500(因为双方基矢一致的概率为 1/2),错误比特数为 0,QBER 为 0.0000。第二次运行人为翻转了筛选后密钥中 5 个位置的比特,错误数变为 5,QBER 约为 0.01。这两组结果说明:基矢比对逻辑正确(只保留一致基矢的比特),且误码率统计能如实反映密钥差异。
可复现的验证清单
| 检查项 | 预期现象 | 说明 |
|---|---|---|
| 筛选后长度 | 约等于 n_bits/2 | 基矢一致概率 1/2,允许统计波动 |
| 理想信道 QBER | 0.0000 | 无窃听、无噪声时筛选比特完全一致 |
| 注入 5 处翻转 | 错误数 = 5,QBER ≈ 5/筛选长度 | 验证误码统计链路有效 |
| 更换随机种子 | 长度与 QBER 小幅波动 | 理想信道下 QBER 仍应为 0 |
把 flip_positions 改为空列表并更换种子,可反复确认“理想信道下筛选后密钥始终一致”;把翻转位置数量逐步增大,可观察 QBER 线性上升,为下一例的窃听检测阈值判定建立直观基线。