2. 量子比特与测量基础

BB84 协议的全部安全性都建立在量子力学最基本的几条规则之上。在动手写仿真代码之前,必须先把“量子比特长什么样、怎么编码、怎么测量、测量后会发生什么”这四件事讲清楚。本节不涉及协议流程,只聚焦于仿真中真正要用到的物理模型:偏振编码、两组测量基、测量坍缩,以及单光子源与探测器的理想化假设。

一、偏振编码:把比特写进光子的偏振方向

在光纤或自由空间量子通信中,最常用的物理载体是单光子的偏振态。一个偏振态可以用二维复向量表示,即量子比特 |ψ⟩ = α|0⟩ + β|1⟩,其中 |α|² + |β|² = 1。BB84 只使用四个特定的偏振态,它们分成两组正交基:

  • 计算基(Z 基,直线基):|0⟩ 对应水平偏振 ↔,|1⟩ 对应垂直偏振 ↕。二者互相正交,可完美区分。
  • 对角基(X 基,斜线基):|+⟩ = (|0⟩+|1⟩)/√2 对应 +45° 偏振 ↗,|−⟩ = (|0⟩−|1⟩)/√2 对应 −45° 偏振 ↘。

注意一个关键事实:|+⟩ 和 |−⟩ 都不是 |0⟩ 或 |1⟩ 本身,而是它们的等权叠加。这意味着,如果发送方用 X 基编码,接收方却用 Z 基测量,结果将完全随机——这正是 BB84 窃听检测的物理根源。在仿真中,我们通常用两个比特来记录一个光子:一个比特表示“选了哪个基”(0=Z,1=X),另一个比特表示“在该基下编码的比特值”。

二、测量:投影与坍缩

量子测量不是“看一眼”,而是一次不可逆的投影操作。对态 |ψ⟩ 在基 {|e₀⟩, |e₁⟩} 下测量,得到结果 0 的概率为 |⟨e₀|ψ⟩|²,得到结果 1 的概率为 |⟨e₁|ψ⟩|²。测量一旦发生,态就坍缩到与结果对应的基向量上,原来的叠加信息被破坏。

把这条规则套到 BB84 的四种情形上,可以得到一张完整的概率表(见下方 SVG 中的矩阵)。例如发送 |+⟩、用 Z 基测量:|⟨0|+⟩|² = 1/2,|⟨1|+⟩|² = 1/2,结果各半,且测量后态变成 |0⟩ 或 |1⟩,不再是 |+⟩。而发送 |+⟩、用 X 基测量:|⟨+|+⟩|² = 1,结果确定为 0。这就是“基匹配则确定、基不匹配则随机”的完整来源。

仿真实现要点:不要用浮点随机数去“模拟”概率,而应直接按规则判定——基匹配时结果等于编码比特,基不匹配时以 0.5 概率随机取 0 或 1。这样既准确又便于复现(固定随机种子即可)。

三、单光子源与探测器的理想化模型

真实设备存在多光子、暗计数、探测效率不足、偏振漂移等问题。BB84 仿真入门阶段通常先采用理想化模型,把非理想因素留到后续章节单独引入。理想模型包含以下约定:

  • 单光子源:每次发射严格一个光子,无多光子成分,偏振态制备无误差,四个态等概率选取。
  • 量子信道:无损耗、无噪声、无窃听时偏振态保持不变;引入窃听时按截获—重发策略改变态。
  • 单光子探测器:探测效率 100%,暗计数为 0,测量基可完美切换,测量结果无翻转错误。

在这些假设下,仿真中“基不匹配”是唯一的随机性来源,误码率(QBER)在无窃听时应严格为 0。一旦引入窃听者,QBER 会上升到约 25%,这个数值正是由上面的概率表推导出来的:窃听者用错误基测量时,有 1/2 概率把态投到错误方向,接收方再测时又有一半概率出错,综合约 1/4。理解这一点,后续的窃听仿真才有据可依。

BB84 偏振编码与测量坍缩关系图 发送态(偏振编码) 计算基 Z |0⟩ ↔ 水平 |1⟩ ↕ 垂直 比特 0 / 1 对角基 X |+⟩ ↗ +45° |−⟩ ↘ −45° 比特 0 / 1 接收方测量(投影 + 坍缩) 发送态 Z 基测量 X 基测量 |0⟩ 确定 0 随机 0/1 |1⟩ 确定 1 随机 0/1 |+⟩ 随机 0/1 确定 0 |−⟩ 随机 0/1 确定 1 坍缩规则 • 基匹配:结果 = 编码比特 • 基不匹配:结果各 1/2 • 测量后态坍缩到结果基 • 原叠加信息不可恢复 → 窃听必留 25% 误码 理想化模型假设 单光子源 • 每次严格 1 光子 • 四态等概率 • 制备无误差 量子信道 • 无损耗、无噪声 • 偏振态保持 • 窃听按截获重发 单光子探测器 • 效率 100% • 暗计数 0 • 基切换无误差 • 结果无翻转 光子 约束

四、仿真中如何落地这四个概念

把上述内容映射到代码,通常只需要几个字段和一次判定。下面给出一个最小可用的 Python 片段,演示“制备—测量”一步的完整逻辑,可直接作为后续协议仿真的基础函数:

import random

# 基:0 = Z 基,1 = X 基
# 比特:0 或 1
def prepare(bit, basis):
    # 返回偏振态标识,便于调试观察
    if basis == 0:
        return "H" if bit == 0 else "V"      # |0⟩ / |1⟩
    else:
        return "D" if bit == 0 else "A"      # |+⟩ / |−⟩

def measure(state, basis):
    # 理想模型:基匹配则确定,不匹配则各 1/2
    if basis == 0:                # 用 Z 基测
        if state in ("H", "V"):
            return 0 if state == "H" else 1
        return random.randint(0, 1)   # D/A 坍缩为随机
    else:                         # 用 X 基测
        if state in ("D", "A"):
            return 0 if state == "D" else 1
        return random.randint(0, 1)   # H/V 坍缩为随机

# 示例:发送 |+⟩,接收方用 Z 基测量
s = prepare(0, 1)      # "D"
r = measure(s, 0)      # 约 50% 得 0,50% 得 1
print(s, r)

这段代码刻意把“态”和“基”分开表示,而不是直接存成比特,原因是:如果只存比特,就无法区分“发送方用 X 基编码的 0”和“发送方用 Z 基编码的 0”,而这两者在接收方用错基测量时行为完全不同。仿真中保留基信息,是保证物理正确性的前提。

五、常见理解偏差

初学者最容易犯的错误有三个。第一,把“基不匹配时结果随机”误解为“结果一定错误”——实际上随机意味着约一半碰巧正确,这正是后续筛选(sifting)后仍能保留一半数据的原因。第二,认为测量可以“事后补救”——坍缩是不可逆的,接收方测完后再想还原发送方的原始叠加态是不可能的,这也是窃听者无法完美复制未知量子态(不可克隆定理)的直观体现。第三,把理想模型当成真实设备——真实系统中探测效率、暗计数和偏振漂移都会引入额外误码,仿真时应把“理想误码”和“设备误码”分开统计,否则无法判断误码究竟来自窃听还是来自器件。

掌握以上四点后,BB84 的协议流程就只剩下“随机选基、公开比对基、筛后估计误码”这些经典操作,量子部分的难点已经在编码与测量这一层被消化掉了。