31 min read

Entanglement is not just a curiosity of quantum mechanics — it is a resource that enables communication tasks impossible in the classical world. This chapter explores two landmark protocols that exploit entanglement for communication:

Chapter 10: Superdense Coding, Quantum Key Distribution, and the Communication Applications of Entanglement

Learning Objectives

By the end of this chapter, you will be able to:

  • Implement the superdense coding protocol and explain how 2 classical bits are transmitted using 1 qubit
  • Derive the mathematics of superdense coding from first principles
  • Describe the BB84 and E91 quantum key distribution protocols and their security guarantees
  • Simulate QKD with an eavesdropper and quantify the information leakage
  • Understand the conceptual basis of QKD security proofs and practical attack vectors
  • Articulate the vision of a quantum internet and the role of entanglement as a communication resource
  • Compute the secret key rate as a function of quantum bit error rate
  • Implement error correction and privacy amplification in QKD
  • Compare prepare-and-measure vs. entanglement-based QKD protocols

10.1 Introduction: Entanglement as a Communication Resource

Entanglement is not just a curiosity of quantum mechanics — it is a resource that enables communication tasks impossible in the classical world. This chapter explores two landmark protocols that exploit entanglement for communication:

  1. Superdense coding: Sending 2 classical bits by transmitting only 1 qubit, using pre-shared entanglement
  2. Quantum Key Distribution (QKD): Generating a provably secure shared secret key, with security guaranteed by the laws of physics rather than computational assumptions

These protocols are not just theoretical curiosities. QKD systems are commercially available today, and superdense coding has been demonstrated in laboratories worldwide. Together with teleportation (Chapter 9), they form the foundation of the emerging quantum internet.

Recurring Theme: Entanglement is a resource, not magic. It must be created, distributed, and consumed. Like any physical resource, it is subject to noise, loss, and degradation. The engineering challenge is managing these imperfections.

Historical Context. Superdense coding was discovered by Charles Bennett and Stephen Wiesner in 1992, building on Wiesner's earlier idea of "conjugate coding" from 1970 (which also laid the groundwork for QKD). Bennett and Brassard independently developed BB84 in 1984, creating the first QKD protocol. Artur Ekert proposed the entanglement-based E91 protocol in 1991, connecting QKD to Bell's theorem. These protocols represent the first practical applications of quantum information theory.


10.2 Superdense Coding

10.2.1 The Puzzle

Classically, sending 2 bits requires 2 physical bits (or 1 bit sent twice). Quantum mechanically, pre-shared entanglement allows us to send 2 classical bits by transmitting only 1 qubit. This is the superdense coding protocol, discovered by Bennett and Wiesner in 1992.

Why is this surprising? The Holevo bound states that 1 qubit can carry at most 1 classical bit of information. So how can we transmit 2 bits with 1 qubit? The answer is that the entanglement carries the other bit — it's a pre-existing resource. The total resource consumption is 1 ebit (entanglement) + 1 qubit (transmission) = 2 bits of capacity, which is consistent with the Holevo bound.

10.2.2 The Protocol

Prerequisite: Alice and Bob share a Bell state $|\Phi^+\rangle = \frac{|00\rangle + |11\rangle}{\sqrt{2}}$. Alice holds qubit A; Bob holds qubit B.

Goal: Alice wants to send 2 classical bits $(x, y)$ to Bob.

Alice's Side                              Bob's Side
────────────                              ──────────

                Pre-shared Bell pair
|0⟩_A ──H──●───────────────────────────●── H ──╱╲── x
            |                           |         (classical bit 1)
|0⟩_B ─────⊕── ? ──? ──? ──? ──? ──? ──⊕─────────
                                              ╱╲── y
                                              (classical bit 0)

Step 1 — Encoding: Depending on the 2-bit message $(x, y)$, Alice applies one of four operations to her qubit:

Bits $(x, y)$ Alice's Operation Resulting Bell State
00 $I$ (do nothing) $|\Phi^+\rangle = \frac{|00\rangle + |11\rangle}{\sqrt{2}}$
01 $X$ (bit flip) $|\Psi^+\rangle = \frac{|01\rangle + |10\rangle}{\sqrt{2}}$
10 $Z$ (phase flip) $|\Phi^-\rangle = \frac{|00\rangle - |11\rangle}{\sqrt{2}}$
11 $ZX$ (both) $|\Psi^-\rangle = \frac{|01\rangle - |10\rangle}{\sqrt{2}}$

The four resulting states are the four Bell states — mutually orthogonal and perfectly distinguishable.

Step 2 — Transmission: Alice sends her qubit to Bob (1 qubit transmitted).

Step 3 — Bell Measurement: Bob now holds both qubits. He performs a Bell measurement (CNOT + Hadamard + computational basis measurement) to determine which of the four Bell states he has, thereby recovering the 2-bit message $(x, y)$.

10.2.3 Mathematical Derivation

Starting from $|\Phi^+\rangle_{AB} = \frac{|00\rangle + |11\rangle}{\sqrt{2}}$:

Encoding 00 (identity): $$(I \otimes I)|\Phi^+\rangle = |\Phi^+\rangle = \frac{|00\rangle + |11\rangle}{\sqrt{2}}$$

Encoding 01 ($X$ on Alice's qubit): $$(X \otimes I)|\Phi^+\rangle = \frac{1}{\sqrt{2}}(X|0\rangle \otimes |0\rangle + X|1\rangle \otimes |1\rangle) = \frac{|10\rangle + |01\rangle}{\sqrt{2}} = |\Psi^+\rangle$$

Encoding 10 ($Z$ on Alice's qubit): $$(Z \otimes I)|\Phi^+\rangle = \frac{1}{\sqrt{2}}(Z|0\rangle \otimes |0\rangle + Z|1\rangle \otimes |1\rangle) = \frac{|00\rangle - |11\rangle}{\sqrt{2}} = |\Phi^-\rangle$$

Encoding 11 ($ZX$ on Alice's qubit): $$(ZX \otimes I)|\Phi^+\rangle = \frac{1}{\sqrt{2}}(Z|1\rangle \otimes |0\rangle + Z|0\rangle \otimes |1\rangle) = \frac{|10\rangle - |01\rangle}{\sqrt{2}} = -|\Psi^-\rangle$$

Note: the global phase of $-1$ in the last case is irrelevant — the state is $|\Psi^-\rangle$ up to global phase, which is physically indistinguishable.

The four Bell states are orthonormal: $$\langle \Phi^+ | \Phi^+ \rangle = \langle \Phi^- | \Phi^- \rangle = \langle \Psi^+ | \Psi^+ \rangle = \langle \Psi^- | \Psi^- \rangle = 1$$ $$\langle \Phi^+ | \Phi^- \rangle = \langle \Phi^+ | \Psi^+ \rangle = \cdots = 0$$

Bob's Bell measurement distinguishes them perfectly (in the noiseless case).

Worked Example 10.1: Verifying the Bell measurement

Bob applies CNOT (with Alice's qubit as control) and Hadamard (on Alice's qubit), then measures both qubits:

$$\text{CNOT} \cdot (H \otimes I) |\Phi^+\rangle = |00\rangle \quad \text{(message 00)}$$ $$\text{CNOT} \cdot (H \otimes I) |\Psi^+\rangle = |01\rangle \quad \text{(message 01)}$$ $$\text{CNOT} \cdot (H \otimes I) |\Phi^-\rangle = |10\rangle \quad \text{(message 10)}$$ $$\text{CNOT} \cdot (H \otimes I) |\Psi^-\rangle = |11\rangle \quad \text{(message 11)}$$

Let's verify the first one:

$$(H \otimes I)|\Phi^+\rangle = \frac{1}{\sqrt{2}}\left(\frac{|0\rangle + |1\rangle}{\sqrt{2}} \otimes |0\rangle + \frac{|0\rangle - |1\rangle}{\sqrt{2}} \otimes |1\rangle\right) = \frac{1}{2}(|00\rangle + |10\rangle + |01\rangle - |11\rangle)$$

$$\text{CNOT} \cdot \frac{1}{2}(|00\rangle + |10\rangle + |01\rangle - |11\rangle) = \frac{1}{2}(|00\rangle + |11\rangle + |01\rangle - |10\rangle)$$

Wait, let me be more careful. With Alice's qubit as control:

$$\text{CNOT}_{A \to B}|00\rangle = |00\rangle, \quad \text{CNOT}_{A \to B}|10\rangle = |11\rangle, \quad \text{CNOT}_{A \to B}|01\rangle = |01\rangle, \quad \text{CNOT}_{A \to B}|11\rangle = |10\rangle$$

$$\text{CNOT} \cdot \frac{1}{2}(|00\rangle + |10\rangle + |01\rangle - |11\rangle) = \frac{1}{2}(|00\rangle + |11\rangle + |01\rangle - |10\rangle)$$

This doesn't simplify to $|00\rangle$. Let me recheck... Actually, the standard Bell measurement uses the inverse of the Bell state creation circuit. Since $|\Phi^+\rangle$ is created by $(H \otimes I) \cdot \text{CNOT}$, the measurement circuit is $\text{CNOT} \cdot (H \otimes I)$:

$$\text{CNOT} \cdot (H \otimes I) \cdot (H \otimes I) \cdot \text{CNOT} = \text{CNOT} \cdot (H^2 \otimes I) \cdot \text{CNOT} = \text{CNOT} \cdot (I \otimes I) \cdot \text{CNOT} = \text{CNOT}^2 = I$$

So $\text{CNOT} \cdot (H \otimes I) |\Phi^+\rangle = \text{CNOT} \cdot (H \otimes I) \cdot (H \otimes I) \cdot \text{CNOT} |00\rangle = |00\rangle$. ✓

The other cases follow similarly, confirming that the Bell measurement correctly decodes all four messages.

10.2.4 The Resource Trade-off

Superdense coding reveals a fundamental trade-off in quantum information theory:

  • Without entanglement: 1 qubit can carry at most 1 classical bit of information (Holevo bound)
  • With 1 pre-shared Bell pair: 1 qubit can carry 2 classical bits
  • With $n$ pre-shared Bell pairs: $n$ qubits can carry $2n$ classical bits

The entanglement is "consumed" in the process — after the Bell measurement, the entanglement is gone. This is a one-time resource.

Common Misconception. "Superdense coding lets you send more information than is physically possible." No! The total resource consumption (entanglement + qubit) equals the information sent. It's a trade: you consume entanglement to boost classical channel capacity. The entanglement must be distributed beforehand, which itself costs quantum communication.

10.2.5 Complete Qiskit Implementation

import numpy as np
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit.quantum_info import Statevector, Operator
from qiskit_aer import AerSimulator

simulator = AerSimulator()

# ============================================================
# SUPERDENSE CODING: Complete Implementation
# ============================================================

def create_superdense_coding_circuit(message_bits):
    """
    Build the superdense coding circuit.

    Args:
        message_bits: tuple (x, y) where x,y ∈ {0,1}
            (x, y) = (0,0): I
            (x, y) = (0,1): X
            (x, y) = (1,0): Z
            (x, y) = (1,1): ZX

    Qubit layout:
        q[0] = Alice's qubit (sent to Bob)
        q[1] = Bob's qubit

    Classical bits:
        c[0] = Bob's measurement of q[0] (after CNOT+H)
        c[1] = Bob's measurement of q[1]
    """
    x, y = message_bits

    qr = QuantumRegister(2, 'q')
    cr = ClassicalRegister(2, 'c')
    qc = QuantumCircuit(qr, cr)

    # SETUP: Create Bell pair (Alice has q0, Bob has q1)
    qc.h(qr[0])
    qc.cx(qr[0], qr[1])
    qc.barrier(label='Bell pair created')

    # ALICE'S ENCODING (on her qubit q0 only)
    if x == 1 and y == 0:      # Message 10: Z gate
        qc.z(qr[0])
    elif x == 0 and y == 1:    # Message 01: X gate
        qc.x(qr[0])
    elif x == 1 and y == 1:    # Message 11: ZX (or X then Z)
        qc.z(qr[0])
        qc.x(qr[0])
    # Message 00: do nothing (I)

    qc.barrier(label='Encoded')

    # BOB'S BELL MEASUREMENT
    qc.cx(qr[0], qr[1])
    qc.h(qr[0])
    qc.measure(qr[0], cr[0])  # This gives x (the first bit)
    qc.measure(qr[1], cr[1])  # This gives y (the second bit)

    return qc


# ============================================================
# DEMONSTRATION: Test all 4 messages
# ============================================================

print("=" * 70)
print("SUPERDENSE CODING: Sending 2 classical bits with 1 qubit")
print("=" * 70)

for x, y in [(0,0), (0,1), (1,0), (1,1)]:
    qc = create_superdense_coding_circuit((x, y))
    result = simulator.run(qc, shots=1024).result()
    counts = result.get_counts()

    # Qiskit uses little-endian: cr[1]cr[0] = yx
    expected = f"{y}{x}"
    success_rate = counts.get(expected, 0) / 1024 * 100

    print(f"\nMessage ({x},{y}):")
    print(f"  Alice applies: ", end="")
    if (x, y) == (0, 0): print("I (identity)")
    elif (x, y) == (0, 1): print("X (bit flip)")
    elif (x, y) == (1, 0): print("Z (phase flip)")
    elif (x, y) == (1, 1): print("ZX (bit + phase flip)")
    print(f"  Bob measures: {counts}")
    print(f"  Success rate: {success_rate:.1f}%")

10.2.6 Verifying the Protocol with Statevectors

# ============================================================
# VERIFICATION: Check all four encoding operations
# ============================================================

from qiskit.quantum_info import Statevector

print("\n" + "=" * 70)
print("VERIFICATION: Statevector analysis")
print("=" * 70)

# Bell states
phi_plus = Statevector([1/np.sqrt(2), 0, 0, 1/np.sqrt(2)])    # |Φ+⟩
phi_minus = Statevector([1/np.sqrt(2), 0, 0, -1/np.sqrt(2)])   # |Φ-⟩
psi_plus = Statevector([0, 1/np.sqrt(2), 1/np.sqrt(2), 0])     # |Ψ+⟩
psi_minus = Statevector([0, 1/np.sqrt(2), -1/np.sqrt(2), 0])   # |Ψ-⟩

bell_states = {
    'Φ+': phi_plus,
    'Φ-': phi_minus,
    'Ψ+': psi_plus,
    'Ψ-': psi_minus,
}

# Verify orthonormality
print("\nBell state inner products:")
for name1, state1 in bell_states.items():
    for name2, state2 in bell_states.items():
        inner = np.abs(state1.inner(state2))**2
        print(f"  ⟨{name1}|{name2}⟩ = {inner:.6f}", end="")
    print()

# Verify encoding operations
operations = {
    'I': np.eye(4),
    'X⊗I': np.kron(np.array([[0,1],[1,0]]), np.eye(2)),
    'Z⊗I': np.kron(np.array([[1,0],[0,-1]]), np.eye(2)),
    'ZX⊗I': np.kron(np.array([[0,-1],[1,0]]), np.eye(2)),
}

print("\nEncoding verification:")
for name, op in operations.items():
    result = Statevector(op @ phi_plus.data)
    # Find which Bell state it matches
    for bell_name, bell_state in bell_states.items():
        fidelity = np.abs(np.conj(result.data) @ bell_state.data)**2
        if fidelity > 0.99:
            print(f"  {name} |Φ+⟩ → |{bell_name}⟩ (fidelity = {fidelity:.6f})")
            break

10.2.7 Superdense Coding with Noise

# ============================================================
# NOISE ANALYSIS: Superdense coding with depolarizing noise
# ============================================================

print("\n" + "=" * 70)
print("SUPERDENSE CODING WITH DEPOLARIZING NOISE")
print("=" * 70)

from qiskit_aer.noise import NoiseModel, depolarizing_error

noise_levels = [0.0, 0.005, 0.01, 0.02, 0.05, 0.10]
results_by_noise = {}

for noise_level in noise_levels:
    if noise_level == 0:
        sim = AerSimulator()
    else:
        noise_model = NoiseModel()
        error_1q = depolarizing_error(noise_level, 1)
        error_2q = depolarizing_error(noise_level * 10, 2)
        noise_model.add_all_qubit_quantum_error(error_1q, ['h', 'x', 'z'])
        noise_model.add_all_qubit_quantum_error(error_2q, ['cx'])
        sim = AerSimulator(noise_model=noise_model)

    success_rates = []
    for x, y in [(0,0), (0,1), (1,0), (1,1)]:
        qc = create_superdense_coding_circuit((x, y))
        result = sim.run(qc, shots=2048).result()
        counts = result.get_counts()
        expected = f"{y}{x}"
        success_rate = counts.get(expected, 0) / 2048 * 100
        success_rates.append(success_rate)

    avg_success = np.mean(success_rates)
    results_by_noise[noise_level] = avg_success
    print(f"  Noise {noise_level:.3f}: avg success rate = {avg_success:.1f}%")

print("\nNote: Success rate degrades with noise, but remains above 50%")
print("(the random guessing baseline) even at moderate noise levels.")

10.2.8 The Information-Theoretic Perspective

Superdense coding saturates the Holevo bound for the case of pre-shared entanglement. The Holevo bound states that $n$ qubits can convey at most $n$ classical bits of information:

$$\chi = S(\rho) - \sum_x p_x S(\rho_x) \leq n$$

With $n$ pre-shared Bell pairs, the effective capacity doubles to $2n$ bits — but the total resource consumption (entanglement + qubit transmission) is $2n$ qubit-transmissions' worth. This is the entanglement-assisted classical capacity:

$$C_E = C + \frac{1}{2}E$$

where $C$ is the classical capacity and $E$ is the entanglement rate. For superdense coding, $C = 1$ bit per qubit and $E = 1$ ebit per qubit, giving $C_E = 1 + 1/2 = 3/2$ bits per channel use. But wait — we send 2 bits using 1 qubit and 1 ebit, so the rate is 2 bits per (qubit + ebit), which is consistent with the formula $C_E = C + E = 1 + 1 = 2$ bits per use of the combined (quantum + entanglement) channel.

Common Misconception. "Superdense coding violates the Holevo bound." No! The Holevo bound applies to qubits without pre-shared entanglement. With entanglement, the bound is modified to $C_E = C + E$, and superdense coding saturates this enhanced bound.


10.3 Quantum Key Distribution: BB84

10.3.1 The Key Distribution Problem

Alice and Bob want to establish a shared secret key over a public channel. An eavesdropper (Eve) can intercept all communication. Classical solutions (Diffie-Hellman, RSA) rely on computational assumptions (factoring is hard, discrete log is hard). Quantum Key Distribution (QKD) provides information-theoretic security — security guaranteed by the laws of quantum mechanics, independent of the adversary's computational power.

Why is key distribution important? The one-time pad is perfectly secure: if Alice and Bob share a random key $K$ of the same length as the message $M$, the ciphertext $C = M \oplus K$ reveals nothing about $M$ to an eavesdropper. The challenge is distributing $K$ without anyone else learning it. QKD solves this distribution problem.

10.3.2 The BB84 Protocol (Bennett-Brassard 1984)

BB84 is the original and most widely deployed QKD protocol. It does not require entanglement — it uses single photons in superposition states.

Alice                                          Bob
─────                                          ───

For each bit, Alice randomly chooses:          Bob randomly chooses:
  Bit value: 0 or 1                              Measurement basis: + or ×
  Encoding basis: + (Z) or × (X)

Encoding rules:
  Basis + (Z-basis):  |0⟩ for bit 0, |1⟩ for bit 1
  Basis × (X-basis):  |+⟩ for bit 0, |-⟩ for bit 1

          Quantum Channel (single photons)
Alice ──────────────────────────────────────→ Bob
          (Eve may intercept)

          Classical Authenticated Channel
Alice ←──────────────────────────────────────→ Bob
          (Basis reconciliation, error check, privacy amplification)

Step-by-step:

  1. Transmission: Alice generates $N$ random bits $\{a_i\}$ and $N$ random basis choices $\{b_i^A\}$ ($+$ or $\times$). For each $i$, she prepares and sends the corresponding qubit state to Bob.

  2. Measurement: Bob generates $N$ random basis choices $\{b_i^B\}$ and measures each received qubit in his chosen basis, obtaining bits $\{\hat{b}_i\}$.

  3. Basis Reconciliation (Sifting): Over the public classical channel, Alice and Bob announce their basis choices (but NOT the bit values). They discard all bits where $b_i^A \neq b_i^B$. The remaining bits (approximately $N/2$) form the sifted key.

  4. Error Estimation: Alice and Bob publicly compare a random subset of the sifted key. If the error rate exceeds a threshold (~11% for BB84), they abort — Eve is listening.

  5. Error Correction: They apply classical error correction (e.g., Cascade protocol) to reconcile their keys.

  6. Privacy Amplification: They apply a randomness extractor (e.g., Toeplitz matrix hashing) to shrink the key, eliminating any information Eve may have gained.

Worked Example 10.2: A BB84 exchange

Suppose Alice wants to send the bit string 0110:

Bit $i$ Alice's bit Alice's basis Alice's state Bob's basis Bob's measurement Match? Sifted bit
1 0 + $\|0\rangle$ + 0 Yes 0
2 1 × $\|-\rangle$ + 0 or 1 No
3 1 + $\|1\rangle$ × random No
4 0 × $\|+\rangle$ × 0 Yes 0

Alice and Bob discard bits 2 and 3 (basis mismatch), keeping bits 1 and 4. The sifted key is "00" (from Alice's bits 1 and 4).

10.3.3 Why BB84 Is Secure

The security of BB84 rests on two quantum principles:

  1. The no-cloning theorem: Eve cannot copy the transmitted qubits without disturbing them.

  2. Measurement disturbance: Any measurement by Eve in the wrong basis disturbs the state, introducing errors that Alice and Bob can detect.

Detailed security argument:

If Eve intercepts and measures a qubit, she must guess the basis. When she guesses wrong (50% of the time): - She obtains a random bit (no information about Alice's bit) - She disturbs the state, causing Bob's measurement to disagree with Alice's bit 50% of the time

Overall, Eve's interception introduces a 25% error rate in the sifted key — easily detectable.

Quantitative analysis: If Eve intercepts a fraction $f$ of qubits using an intercept-resend attack:

  • Probability Eve measures in the correct basis: $1/2$
  • Probability Eve measures in the wrong basis: $1/2$
  • When Eve measures in the wrong basis and Bob measures in the correct basis: probability of error = $1/2$

So the total error rate from Eve is:

$$QBER = f \times \frac{1}{2} \times \frac{1}{2} = \frac{f}{4}$$

For full interception ($f = 1$), $QBER = 25\%$, far above the 11% threshold.

Common Misconception. "QKD is unconditionally secure, so it can't be broken." Not exactly. QKD's protocol is information-theoretically secure, but implementations can have side channels. Photon-number splitting, detector blinding, and timing attacks have all been demonstrated. The security of QKD depends on the implementation matching the theoretical model.

10.3.4 Complete BB84 Simulation in Qiskit

import numpy as np
from qiskit import QuantumCircuit
from qiskit_aer import AerSimulator

simulator = AerSimulator()

# ============================================================
# BB84 QKD PROTOCOL SIMULATION
# ============================================================

def bb84_simulate(n_bits=200, eavesdropper=False, noise_prob=0.0):
    """
    Simulate the BB84 QKD protocol.

    Args:
        n_bits: Number of bits to transmit
        eavesdropper: If True, Eve intercepts and measures each qubit
        noise_prob: Probability of channel noise (bit flip)

    Returns:
        Dictionary with protocol statistics
    """

    # Step 1: Alice generates random bits and random bases
    alice_bits = np.random.randint(0, 2, n_bits)
    alice_bases = np.random.randint(0, 2, n_bits)  # 0 = Z-basis (+), 1 = X-basis (×)

    # Step 2: Bob generates random measurement bases
    bob_bases = np.random.randint(0, 2, n_bits)

    # Step 3: Prepare, (optionally intercept), and measure each qubit
    bob_results = np.zeros(n_bits, dtype=int)
    eve_results = np.zeros(n_bits, dtype=int) if eavesdropper else None
    eve_bases = np.random.randint(0, 2, n_bits) if eavesdropper else None

    for i in range(n_bits):
        # Build the circuit for this qubit
        qc = QuantumCircuit(1, 1)

        # Alice's encoding
        if alice_bits[i] == 1:
            qc.x(0)  # |1⟩ in Z-basis
        if alice_bases[i] == 1:
            qc.h(0)  # Convert to X-basis: |0⟩→|+⟩, |1⟩→|-⟩

        # Eve's interception (if active)
        if eavesdropper:
            # Eve measures in her randomly chosen basis
            if eve_bases[i] == 1:
                qc.h(0)  # Measure in X-basis
            qc.measure(0, 0)
            result = simulator.run(qc, shots=1).result()
            eve_results[i] = int(list(result.get_counts().keys())[0])

            # Eve re-prepares and sends to Bob
            qc = QuantumCircuit(1, 1)
            if eve_results[i] == 1:
                qc.x(0)
            if eve_bases[i] == 1:
                qc.h(0)

        # Channel noise (bit-flip)
        if np.random.random() < noise_prob:
            qc.x(0)

        # Bob's measurement
        if bob_bases[i] == 1:
            qc.h(0)  # Measure in X-basis
        qc.measure(0, 0)

        result = simulator.run(qc, shots=1).result()
        bob_results[i] = int(list(result.get_counts().keys())[0])

    # Step 4: Sifting — keep only bits where bases match
    matching_bases = (alice_bases == bob_bases)
    sifted_alice = alice_bits[matching_bases]
    sifted_bob = bob_results[matching_bases]

    # Step 5: Error rate in sifted key
    errors = np.sum(sifted_alice != sifted_bob)
    error_rate = errors / len(sifted_alice) if len(sifted_alice) > 0 else 0

    # Eve's information (if she intercepted)
    if eavesdropper:
        eve_matching = (alice_bases == eve_bases)
        eve_correct = np.sum(alice_bits[eve_matching] == eve_results[eve_matching])
        eve_total = np.sum(eve_matching)
        eve_info_rate = eve_correct / eve_total if eve_total > 0 else 0
    else:
        eve_info_rate = None

    return {
        'n_bits': n_bits,
        'sifted_bits': len(sifted_alice),
        'sift_ratio': len(sifted_alice) / n_bits,
        'errors': errors,
        'error_rate': error_rate,
        'eavesdropper': eavesdropper,
        'eve_info_rate': eve_info_rate,
        'noise_prob': noise_prob,
        'sifted_alice': sifted_alice,
        'sifted_bob': sifted_bob,
    }


# ============================================================
# RUN SIMULATIONS
# ============================================================

print("=" * 70)
print("BB84 QKD PROTOCOL SIMULATION")
print("=" * 70)

# Scenario 1: No eavesdropper, no noise
print("\n--- Scenario 1: Ideal channel (no Eve, no noise) ---")
result1 = bb84_simulate(n_bits=500, eavesdropper=False, noise_prob=0.0)
print(f"  Transmitted: {result1['n_bits']} qubits")
print(f"  Sifted key length: {result1['sifted_bits']} bits ({result1['sift_ratio']*100:.1f}%)")
print(f"  Errors: {result1['errors']}")
print(f"  Error rate: {result1['error_rate']*100:.2f}%")
print(f"  First 20 sifted key bits (Alice): {result1['sifted_alice'][:20]}")
print(f"  First 20 sifted key bits (Bob):   {result1['sifted_bob'][:20]}")

# Scenario 2: Eve intercepts every qubit
print("\n--- Scenario 2: Eve intercepts all qubits ---")
result2 = bb84_simulate(n_bits=500, eavesdropper=True, noise_prob=0.0)
print(f"  Transmitted: {result2['n_bits']} qubits")
print(f"  Sifted key length: {result2['sifted_bits']} bits")
print(f"  Errors: {result2['errors']}")
print(f"  Error rate: {result2['error_rate']*100:.2f}%")
print(f"  Eve's information rate: {result2['eve_info_rate']*100:.2f}%")
print(f"  (Expected: ~25% error rate, ~50% Eve info rate)")

# Scenario 3: Eve intercepts + channel noise
print("\n--- Scenario 3: Eve + 5% channel noise ---")
result3 = bb84_simulate(n_bits=500, eavesdropper=True, noise_prob=0.05)
print(f"  Error rate: {result3['error_rate']*100:.2f}%")
print(f"  Eve's information rate: {result3['eve_info_rate']*100:.2f}%")

10.3.5 Error Correction and Privacy Amplification

After sifting, Alice and Bob have correlated but possibly different bit strings. Error correction reconciles them, and privacy amplification removes Eve's information.

Error Correction (Cascade Protocol):

The Cascade protocol works in multiple passes:

  1. Pass 1: Alice and Bob divide their keys into blocks of size $k$. For each block, they compare parities. If a block has a parity mismatch, they bisect it and compare sub-block parities, recursively finding and correcting errors.

  2. Pass 2: After correcting errors in Pass 1, Alice and Bob shuffle their keys (using a publicly agreed permutation) and repeat with smaller block sizes.

  3. Repeat until the estimated error rate is below the threshold.

def cascade_error_correction(alice_key, bob_key, block_size=8):
    """Simplified Cascade error correction."""
    n = len(alice_key)
    errors_corrected = 0

    # Pass 1: Check parities in blocks
    for start in range(0, n, block_size):
        end = min(start + block_size, n)
        alice_block = alice_key[start:end]
        bob_block = bob_key[start:end]

        if sum(alice_block) % 2 != sum(bob_block) % 2:
            # Binary search for the error
            low, high = start, end
            while high - low > 1:
                mid = (low + high) // 2
                if sum(alice_key[low:mid]) % 2 != sum(bob_key[low:mid]) % 2:
                    high = mid
                else:
                    low = mid
            # Correct the error
            bob_key[low] = 1 - bob_key[low]
            errors_corrected += 1

    remaining_errors = np.sum(alice_key != bob_key)
    return alice_key, bob_key, errors_corrected, remaining_errors

# Test error correction
print("\n--- Error Correction Demo ---")
np.random.seed(42)
alice_key = np.random.randint(0, 2, 64)
bob_key = alice_key.copy()
# Introduce 5% errors
error_positions = np.random.random(64) < 0.05
bob_key[error_positions] = 1 - bob_key[error_positions]
print(f"  Initial errors: {np.sum(alice_key != bob_key)}")

alice_key, bob_key, corrected, remaining = cascade_error_correction(
    alice_key.copy(), bob_key.copy(), block_size=8
)
print(f"  Errors corrected: {corrected}")
print(f"  Remaining errors: {remaining}")

Privacy Amplification:

After error correction, Alice and Bob share identical keys, but Eve may have partial information. Privacy amplification reduces Eve's information to negligible levels by shortening the key.

The standard method uses a universal hash function (e.g., Toeplitz matrix):

def privacy_amplification(key, output_length):
    """Privacy amplification using Toeplitz matrix hashing.

    Shortens the key from len(key) to output_length bits,
    removing approximately len(key) - output_length bits of Eve's information.
    """
    n = len(key)
    m = output_length

    if m >= n:
        return key  # No shortening needed

    # Generate a random Toeplitz matrix
    # A Toeplitz matrix is defined by its first row and first column
    seed = np.random.randint(0, 2, n + m - 1)

    # Compute the hash: output = T * key (mod 2)
    output = np.zeros(m, dtype=int)
    for i in range(m):
        for j in range(n):
            # T[i][j] = seed[m - 1 - i + j]
            output[i] ^= key[j] * seed[m - 1 - i + j]

    return output

# Demo
print("\n--- Privacy Amplification Demo ---")
key = np.random.randint(0, 2, 128)
# Shorten from 128 to 80 bits (removing 48 bits = ~48 bits of Eve's info)
shortened = privacy_amplification(key, 80)
print(f"  Original key length: {len(key)} bits")
print(f"  Shortened key length: {len(shortened)} bits")
print(f"  Information removed: {len(key) - len(shortened)} bits")
print(f"  (This is the amount of Eve's information we assume could be compromised)")

10.3.6 The BB84 Error Threshold

The theoretical security threshold for BB84 against general attacks is a Quantum Bit Error Rate (QBER) of approximately 11%. Above this, no secure key can be distilled. In practice, commercial QKD systems operate at QBERs of 1-5% and abort above 8%.

The secret key rate after error correction and privacy amplification, in the asymptotic limit, is:

$$R = 1 - 2H_2(\text{QBER})$$

where $H_2(p) = -p\log_2 p - (1-p)\log_2(1-p)$ is the binary entropy function. This yields $R > 0$ for QBER $\lesssim 0.11$.

Derivation sketch: The sifted key has length $n/2$ (half the bits are discarded due to basis mismatch). Error correction leaks about $H_2(\text{QBER})$ bits per sifted bit to Eve. Privacy amplification removes another $H_2(\text{QBER})$ bits (Eve's information about the remaining bits). The net key rate per sifted bit is $1 - 2H_2(\text{QBER})$.

# Secret key rate vs QBER
import numpy as np

def binary_entropy(p):
    """Binary entropy function H_2(p)."""
    if p == 0 or p == 1:
        return 0
    return -p * np.log2(p) - (1-p) * np.log2(1-p)

def secret_key_rate(qber):
    """Asymptotic secret key rate for BB84 (simplified)."""
    if qber == 0:
        return 1.0
    if qber >= 0.5:
        return 0.0
    h2 = binary_entropy(qber)
    return max(0, 1 - 2*h2)

print("\n--- Secret Key Rate vs QBER ---")
print(f"  {'QBER':>8s}  {'H2(QBER)':>10s}  {'Key Rate':>10s}")
print(f"  {'-'*8}  {'-'*10}  {'-'*10}")
for qber in [0.0, 0.01, 0.02, 0.05, 0.08, 0.10, 0.11, 0.12, 0.15, 0.20]:
    rate = secret_key_rate(qber)
    h2 = binary_entropy(qber)
    print(f"  {qber*100:7.1f}%  {h2:10.4f}  {rate:10.4f}")

# Plot
try:
    import matplotlib.pyplot as plt
    qbers = np.linspace(0, 0.2, 200)
    rates = [secret_key_rate(q) for q in qbers]
    plt.figure(figsize=(8, 5))
    plt.plot(qbers * 100, rates, 'b-', linewidth=2)
    plt.axhline(y=0, color='r', linestyle='--', alpha=0.5)
    plt.axvline(x=11, color='g', linestyle='--', alpha=0.5, label='QBER = 11%')
    plt.xlabel('Quantum Bit Error Rate (%)')
    plt.ylabel('Secret Key Rate (bits per sifted bit)')
    plt.title('BB84 Secret Key Rate vs QBER')
    plt.legend()
    plt.grid(True, alpha=0.3)
    plt.savefig('bb84_key_rate.png', dpi=150)
    print("\nPlot saved to bb84_key_rate.png")
except ImportError:
    pass

10.3.7 Detecting Eavesdropping

# ============================================================
# DETECTING EVE: Multiple runs to show statistics
# ============================================================

print("\n" + "=" * 70)
print("EAVESDROPPING DETECTION: Statistical Analysis")
print("=" * 70)

n_runs = 50
n_bits_per_run = 300

# No Eve
qber_no_eve = []
for _ in range(n_runs):
    r = bb84_simulate(n_bits=n_bits_per_run, eavesdropper=False, noise_prob=0.0)
    qber_no_eve.append(r['error_rate'])

# Full Eve
qber_full_eve = []
for _ in range(n_runs):
    r = bb84_simulate(n_bits=n_bits_per_run, eavesdropper=True, noise_prob=0.0)
    qber_full_eve.append(r['error_rate'])

# Partial Eve (50% interception)
qber_partial_eve = []
for _ in range(n_runs):
    # Simulate partial interception by running with 50% probability
    if np.random.random() < 0.5:
        r = bb84_simulate(n_bits=n_bits_per_run, eavesdropper=True, noise_prob=0.0)
    else:
        r = bb84_simulate(n_bits=n_bits_per_run, eavesdropper=False, noise_prob=0.0)
    qber_partial_eve.append(r['error_rate'])

print(f"\n  No Eve:          mean QBER = {np.mean(qber_no_eve)*100:.2f}% (std = {np.std(qber_no_eve)*100:.2f}%)")
print(f"  Full Eve:        mean QBER = {np.mean(qber_full_eve)*100:.2f}% (std = {np.std(qber_full_eve)*100:.2f}%)")
print(f"  50% Eve:         mean QBER = {np.mean(qber_partial_eve)*100:.2f}% (std = {np.std(qber_partial_eve)*100:.2f}%)")
print(f"\n  Detection threshold: ~11% QBER")
print(f"  Full Eve is ALWAYS detectable (QBER ≈ 25%)")
print(f"  Even 25% Eve interception is detectable (QBER ≈ 6.25%)")

10.4 The E91 Protocol: Entanglement-Based QKD

10.4.1 Ekert's 1991 Protocol

Artur Ekert proposed an entanglement-based QKD protocol (E91) that uses Bell's inequality to detect eavesdropping. Instead of Alice preparing and sending states, a central source distributes entangled pairs to Alice and Bob.

                    Entanglement Source
                          |
                    ┌─────┴─────┐
                    |  EPR Pair  |
                    └─────┬─────┘
                     ┌────┴────┐
                   Alice      Bob
                     │          │
                   Measure    Measure
                  in random   in random
                    basis      basis

Protocol:

  1. A source emits pairs of qubits in the Bell state $|\Phi^+\rangle$, sending one to Alice and one to Bob.

  2. Alice and Bob each measure their qubit in a randomly chosen basis from a set of three (e.g., angles $0^\circ, 45^\circ, 90^\circ$ for Alice; $45^\circ, 90^\circ, 135^\circ$ for Bob).

  3. After all measurements, they publicly announce their basis choices.

  4. Measurements in matching bases form the sifted key.

  5. Measurements in mismatched bases are used to test the CHSH inequality (a form of Bell's inequality). If the CHSH value exceeds 2 (the classical bound), the correlations are genuinely quantum and no eavesdropper is present.

10.4.2 The CHSH Test

The CHSH inequality states that for any local hidden variable theory:

$$S = |E(a,b) - E(a,b') + E(a',b) + E(a',b')| \leq 2$$

where $E(a,b)$ is the correlation coefficient for measurements at angles $a$ and $b$. Quantum mechanics predicts $S = 2\sqrt{2} \approx 2.828$ for optimal angle choices.

Why does CHSH violation guarantee security?

If Eve intercepts the entangled pairs and measures them, she breaks the entanglement. The resulting correlations become classical, and the CHSH value drops to $\leq 2$. If Alice and Bob observe $S > 2$, they have verified the quantum nature of their correlations and can bound Eve's information.

Derivation of the quantum prediction:

For a Bell state $|\Phi^+\rangle$ measured at angles $a$ (Alice) and $b$ (Bob):

$$E(a, b) = \langle \sigma_a \otimes \sigma_b \rangle = \cos[2(a - b)]$$

For optimal angles $a = 0°, a' = 45°, b = 22.5°, b' = 67.5°$:

$$S = |E(0°, 22.5°) - E(0°, 67.5°) + E(45°, 22.5°) + E(45°, 67.5°)|$$ $$= |\cos(45°) - \cos(135°) + \cos(45°) + \cos(45°)|$$ $$= |\frac{1}{\sqrt{2}} + \frac{1}{\sqrt{2}} + \frac{1}{\sqrt{2}} + \frac{1}{\sqrt{2}}| = 2\sqrt{2} \approx 2.828$$

This exceeds the classical bound of 2, confirming genuine quantum correlations.

# E91 CHSH test simulation
def chsh_test_simulation(n_pairs=2000):
    """Simulate the CHSH test for E91."""
    # Alice's measurement angles (in radians)
    alice_angles = [0, np.pi/4, np.pi/2]       # 0°, 45°, 90°
    # Bob's measurement angles
    bob_angles = [np.pi/4, np.pi/2, 3*np.pi/4]  # 45°, 90°, 135°

    # For each pair, randomly choose measurement angles
    alice_choices = np.random.randint(0, 3, n_pairs)
    bob_choices = np.random.randint(0, 3, n_pairs)

    # Simulate measurement outcomes for |Φ+⟩ state
    alice_results = np.zeros(n_pairs, dtype=int)
    bob_results = np.zeros(n_pairs, dtype=int)

    for i in range(n_pairs):
        a = alice_angles[alice_choices[i]]
        b = bob_angles[bob_choices[i]]

        # For |Φ+⟩: P(same) = cos²(a - b)
        p_same = np.cos(a - b)**2

        alice_results[i] = np.random.binomial(1, 0.5)
        if np.random.random() < p_same:
            bob_results[i] = alice_results[i]
        else:
            bob_results[i] = 1 - alice_results[i]

    # Compute CHSH correlations
    def correlation(a_idx, b_idx):
        mask_a = (alice_choices == a_idx)
        mask_b = (bob_choices == b_idx)
        mask = mask_a & mask_b
        if np.sum(mask) == 0:
            return 0
        same = np.sum(alice_results[mask] == bob_results[mask])
        total = np.sum(mask)
        return 2 * same / total - 1

    E11 = correlation(0, 0)  # a1=0°, b1=45°
    E13 = correlation(0, 2)  # a1=0°, b3=135°
    E31 = correlation(2, 0)  # a3=90°, b1=45°
    E33 = correlation(2, 2)  # a3=90°, b3=135°

    S = np.abs(E11 - E13 + E31 + E33)

    return S, E11, E13, E31, E33

print("\n" + "=" * 70)
print("E91 PROTOCOL: CHSH INEQUALITY TEST")
print("=" * 70)

# Run multiple times to see statistical variation
S_values = []
for _ in range(20):
    S, E11, E13, E31, E33 = chsh_test_simulation(n_pairs=2000)
    S_values.append(S)

print(f"\n  Mean S = {np.mean(S_values):.4f} (std = {np.std(S_values):.4f})")
print(f"  Classical bound: S ≤ 2")
print(f"  Quantum maximum: S = 2√2 ≈ {2*np.sqrt(2):.4f}")
print(f"  CHSH violated: {'Yes' if np.mean(S_values) > 2 else 'No'}")

10.4.3 E91 Security Proof Sketch

The security of E91 rests on the CHSH violation:

  1. No Eve: Alice and Bob observe $S \approx 2\sqrt{2}$, confirming genuine quantum correlations.

  2. Eve present: If Eve intercepts and measures the pairs, she breaks the entanglement. The CHSH value drops to $S \leq 2$, which Alice and Bob detect.

  3. Information bound: The observed CHSH violation $S$ directly bounds Eve's information about the key. Specifically:

$$I_{\text{Eve}} \leq H_2\left(\frac{1 + \sqrt{(S/2)^2 - 1}}{2}\right)$$

where $H_2$ is the binary entropy. For $S = 2\sqrt{2}$, Eve's information is zero (perfect entanglement). For $S = 2$, Eve has full information.

  1. Privacy amplification: After bounding Eve's information, Alice and Bob apply privacy amplification to produce a perfectly secret key.

10.5 Security of QKD: Conceptual Overview

10.5.1 Information-Theoretic Security

Unlike classical public-key cryptography, QKD provides information-theoretic security — the proof does not rely on any computational hardness assumption. Even an adversary with unlimited computational power (a quantum computer capable of breaking RSA) cannot break QKD.

The security proof proceeds in three stages:

  1. Entanglement-based reformulation: BB84 is equivalent to an entanglement-based protocol where Alice measures half of a Bell state. This allows the use of entanglement-based security proofs.

  2. Uncertainty principle: The complementary bases ($Z$ and $X$) impose a fundamental trade-off: the more information Eve gains about the $Z$-basis bits, the more disturbance she causes in the $X$-basis, and vice versa. Formally:

$$H(Z|E) + H(X|E) \geq \log_2 d$$

where $H(Z|E)$ is the conditional entropy of the $Z$-basis bits given Eve's information, and similarly for $X$.

  1. Privacy amplification: Given an upper bound on Eve's information (derived from the observed error rate), Alice and Bob can apply a hash function to distill a shorter, perfectly secret key.

The Shor-Preskill proof (2000):

The landmark security proof by Shor and Preskill shows that BB84 is secure against arbitrary attacks (including collective and coherent attacks). The proof works by:

  1. Showing that BB84 is equivalent to an entanglement-based protocol
  2. Proving security of the entanglement-based protocol using entanglement distillation
  3. Showing that error correction and privacy amplification in the prepare-and-measure version correspond to entanglement distillation in the entanglement-based version

10.5.2 Attack Models

Individual attacks: Eve attacks each qubit independently with the same strategy. The simplest is the intercept-resend attack (measure and re-prepare), which introduces ~25% QBER.

# Demonstrate intercept-resend attack
def intercept_resend_attack(n_bits=500, intercept_fraction=1.0):
    """Simulate intercept-resend attack with varying interception fraction."""
    qber_values = []
    for _ in range(20):
        # Simulate with partial interception
        alice_bits = np.random.randint(0, 2, n_bits)
        alice_bases = np.random.randint(0, 2, n_bits)
        bob_bases = np.random.randint(0, 2, n_bits)

        bob_results = np.zeros(n_bits, dtype=int)

        for i in range(n_bits):
            if np.random.random() < intercept_fraction:
                # Eve intercepts
                eve_basis = np.random.randint(0, 2)
                # Eve measures and re-prepares
                # (simplified: just add noise)
                if eve_basis != alice_bases[i]:
                    bob_results[i] = np.random.randint(0, 2)
                else:
                    # Eve got it right, but Bob might measure in wrong basis
                    if bob_bases[i] == alice_bases[i]:
                        bob_results[i] = alice_bits[i]
                    else:
                        bob_results[i] = np.random.randint(0, 2)
            else:
                # No interception
                if bob_bases[i] == alice_bases[i]:
                    bob_results[i] = alice_bits[i]
                else:
                    bob_results[i] = np.random.randint(0, 2)

        matching = (alice_bases == bob_bases)
        sifted_alice = alice_bits[matching]
        sifted_bob = bob_results[matching]
        qber = np.sum(sifted_alice != sifted_bob) / len(sifted_alice) if len(sifted_alice) > 0 else 0
        qber_values.append(qber)

    return np.mean(qber_values)

print("\n--- Intercept-Resend Attack ---")
for frac in [0.0, 0.25, 0.50, 0.75, 1.0]:
    qber = intercept_resend_attack(intercept_fraction=frac)
    print(f"  Intercept fraction {frac:.2f}: QBER = {qber*100:.1f}%")

Collective attacks: Eve entangles each qubit with an ancilla and performs a collective measurement on all ancillas at the end. More powerful than individual attacks.

Coherent attacks: The most general attack — Eve can perform any operation allowed by quantum mechanics on all qubits jointly. Security against coherent attacks is the gold standard.

BB84 has been proven secure against coherent attacks (Shor-Preskill 2000, Renner 2005).

10.5.3 Practical Attacks: Quantum Hacking

Real QKD systems have been broken not by attacking the protocol but by exploiting implementation imperfections:

Attack Target Description Countermeasure
Photon-number splitting (PNS) Weak coherent pulses If a pulse contains >1 photon, Eve can steal one Decoy state protocol
Trojan horse Alice/Bob's setup Eve injects bright light to probe modulator settings Optical isolation
Detector blinding Bob's detectors Bright light forces detectors to click on demand Detector monitoring
Time-shift attack Timing Eve shifts photon arrival time to exploit detector mismatch Symmetric detectors
Wavelength attack Wavelength filters Eve uses a different wavelength to bypass filters Narrowband filtering
Phase remapping Phase modulators Eve manipulates the phase reference Randomized phases

The detector blinding attack (2010): This was one of the most dramatic quantum hacking demonstrations. By shining a bright light into Bob's detectors, Eve could force them into a linear mode where they only click when she chooses. This completely broke the security of the system without introducing any QBER.

The lesson: A protocol is only as secure as its implementation. Measurement-device-independent QKD (MDI-QKD) and device-independent QKD (DI-QKD) close many of these loopholes by removing the need to trust the measurement devices.

Common Misconception. "QKD is unconditionally secure, so real QKD systems are unconditionally secure." No! The protocol is information-theoretically secure, but implementations can have side channels. The gap between theoretical security and practical security is an active area of research.


10.6 Practical QKD Systems

10.6.1 Commercial QKD

Companies selling QKD systems include: - ID Quantique (Switzerland): Cerberis, Clavis systems — used in banking and government - Toshiba (Japan): Long-distance QKD over fiber, achieving 100+ km with low error rates - QuantumCTek (China): Integrated QKD networks — deployed the Beijing-Shanghai backbone - MagiQ (USA): QPN security system — early commercial QKD product

10.6.2 QKD Networks

Several QKD networks have been deployed: - DARPA QKD Network (USA, 2003): 10 nodes in Boston, first QKD network - SECOQC (Europe, 2008): 6 nodes in Vienna, demonstrated network routing - Tokyo QKD Network (Japan, 2010): Metropolitan network, 3-node deployment - Beijing-Shanghai Backbone (China, 2017): 2000 km trusted-node network connecting Beijing, Jinan, Hefei, and Shanghai - Micius Satellite (China, 2016): Space-based QKD enabling intercontinental key exchange between Beijing and Vienna (7600 km)

10.6.3 Limitations

QKD has fundamental limitations: - Distance: Fiber loss limits direct QKD to ~100-200 km without quantum repeaters - Key rate: Current systems generate keys at kbps to Mbps rates — sufficient for key distribution but not for one-time-pad encryption of bulk data - Authentication: QKD requires an initial shared secret for authentication (the "chicken-and-egg" problem). This is typically a small key (128 bits) that can be expanded. - Cost: Specialized hardware (single-photon detectors, quantum repeaters) is expensive - Trusted nodes: Long-distance QKD networks use trusted nodes, which are potential weak points

Recurring Theme. We're at the beginning. Current QKD systems are like the telegraph — functional but limited. The quantum internet will eventually provide end-to-end quantum connectivity, but building the infrastructure will take decades.


10.7 Comparison of QKD Protocols

Feature BB84 E91 B92 SARG04
Type Prepare-and-measure Entanglement-based Prepare-and-measure Modified BB84
Entanglement No Yes No No
States 4 (Z and X bases) Bell pairs 2 non-orthogonal 4 (same as BB84)
Security basis No-cloning + uncertainty Bell inequality violation No-cloning No-cloning
QBER threshold ~11% ~11% ~7% ~11%
Key rate ~50% of raw bits ~42% of raw bits ~25% of raw bits ~50% of raw bits
PNS resistance With decoy states Inherent Weak Improved over BB84
Implementation Simpler Harder Simplest Moderate

B92 (Bennett 1992): Uses only two non-orthogonal states (e.g., $|0\rangle$ and $|+\rangle$). Simpler than BB84 but has a lower key rate and lower error threshold.

SARG04 (Scarani et al. 2004): A modification of BB84 that uses the same four states but a different sifting protocol, providing better resistance to photon-number splitting attacks.


10.8 The Quantum Internet Vision

The quantum internet is not a replacement for the classical internet — it is a complementary network that delivers quantum bits (qubits) between nodes. Its applications include:

                    ┌──────────────────────────────┐
                    │     QUANTUM INTERNET          │
                    │                               │
                    │  ┌─────────┐    ┌─────────┐  │
                    │  │ QKD     │    │ Blind QC │  │
                    │  └─────────┘    └─────────┘  │
                    │  ┌─────────┐    ┌─────────┐  │
                    │  │ Telepor-│    │ Quantum  │  │
                    │  │ tation  │    │ Sensors  │  │
                    │  └─────────┘    └─────────┘  │
                    │  ┌─────────┐    ┌─────────┐  │
                    │  │ Super-  │    │ Entangle-│  │
                    │  │ dense   │    │ ment Dist│  │
                    │  └─────────┘    └─────────┘  │
                    └──────────────────────────────┘

The protocol stack of a quantum internet includes:

  1. Physical layer: Photonic qubits, quantum memories, transducers
  2. Link layer: Entanglement generation, purification, and swapping
  3. Network layer: Routing of entanglement, path selection
  4. Transport layer: Reliable qubit delivery, retransmission
  5. Application layer: QKD, blind computation, sensor networks

The six stages of quantum internet development (Wehner, Elkouss, Hanson 2018):

Stage Capability Example Application
1 Trusted repeater QKD with trusted nodes
2 Prepare and measure QKD with end-to-end security
3 Entanglement distribution Quantum teleportation
4 Quantum memory Blind quantum computation
5 Few-qubit fault-tolerant Quantum voting, position verification
6 Quantum computing Distributed quantum computation

We are currently between stages 1 and 2.

Recurring Theme. We're at the beginning. The quantum internet today is where the classical internet was in the 1970s — proof-of-concept demonstrations exist, but the engineering challenges are immense. Noise, loss, and decoherence are the enemies at every layer.


10.9 The Relationship Between Superdense Coding, Teleportation, and QKD

These three protocols form a coherent family:

Protocol Quantum Resource Classical Resource Transmitted Consumed
Teleportation 1 ebit 2 cbits 1 qubit Bell pair + cbits
Superdense coding 1 ebit 1 qubit 2 cbits Bell pair + qubit
QKD (BB84) None 1 qubit/bit 1 cbit/key bit Qubits only
QKD (E91) 1 ebit Classical channel 1 cbit/key bit Bell pair

Teleportation and superdense coding are "dual" protocols: - Teleportation: Consume entanglement + classical bits → transmit quantum information - Superdense coding: Consume entanglement + quantum bits → transmit classical information

They are related by a "time reversal" — in teleportation, Alice sends classical bits to Bob; in superdense coding, Alice sends a qubit to Bob. The entanglement is consumed in both cases.

QKD (BB84 variant) uses no entanglement but requires a quantum channel for transmission. QKD (E91 variant) uses entanglement as a resource for security verification.


10.10 Superdense Coding: Deeper Analysis

10.10.1 Why Can't We Send More Than 2 Bits?

The Holevo bound limits the classical capacity of a single qubit to at most 1 bit. Superdense coding appears to violate this, sending 2 bits with 1 qubit. But the Holevo bound applies to qubits without pre-shared entanglement. With 1 ebit of shared entanglement, the capacity doubles.

Can we do better? No. The entanglement-assisted classical capacity of a noiseless qubit channel is exactly 2 bits per channel use. This is the entanglement-assisted Holevo bound:

$$C_E = 1 + S(\rho) \leq 2$$

where $S(\rho)$ is the von Neumann entropy of the shared entangled state. For a maximally entangled state, $S(\rho) = 1$, giving $C_E = 2$.

Worked Example 10.3: Superdense coding with a non-maximally entangled state

If Alice and Bob share a partially entangled state $|\psi\rangle = \sqrt{p}|00\rangle + \sqrt{1-p}|11\rangle$ (with $p \neq 1/2$), the capacity is reduced:

The four states after encoding are: - $(I \otimes I)|\psi\rangle = \sqrt{p}|00\rangle + \sqrt{1-p}|11\rangle$ - $(X \otimes I)|\psi\rangle = \sqrt{p}|10\rangle + \sqrt{1-p}|01\rangle$ - $(Z \otimes I)|\psi\rangle = \sqrt{p}|00\rangle - \sqrt{1-p}|11\rangle$ - $(ZX \otimes I)|\psi\rangle = \sqrt{p}|10\rangle - \sqrt{1-p}|01\rangle$

These are not orthogonal unless $p = 1/2$, so they cannot be perfectly distinguished. The capacity is strictly less than 2 bits.

For $p = 0.9$: the states are nearly orthogonal, and the mutual information approaches 2 bits. For $p = 0.5 + \epsilon$: the states are only barely distinguishable, and the capacity is close to 0.

# Capacity of superdense coding with partial entanglement
import numpy as np

def partial_entanglement_capacity(p, n_shots=10000):
    """Estimate the capacity of superdense coding with partial entanglement."""
    # Prepare the partially entangled state
    psi = np.array([np.sqrt(p), 0, 0, np.sqrt(1-p)])

    # Encoding operations
    I = np.eye(4)
    X_op = np.kron(np.array([[0,1],[1,0]]), np.eye(2))
    Z_op = np.kron(np.array([[1,0],[0,-1]]), np.eye(2))
    ZX_op = Z_op @ X_op

    states = [
        I @ psi,          # Message 00
        X_op @ psi,       # Message 01
        Z_op @ psi,       # Message 10
        ZX_op @ psi,      # Message 11
    ]

    # Compute the Gram matrix (overlaps between states)
    gram = np.zeros((4, 4))
    for i in range(4):
        for j in range(4):
            gram[i, j] = np.abs(np.conj(states[i]) @ states[j])**2

    # The states are perfectly distinguishable iff the Gram matrix is the identity
    # Capacity is reduced when the off-diagonal elements are non-zero
    off_diag = np.sum(np.abs(gram)) - np.trace(np.abs(gram))

    return gram, off_diag

print("\n--- Superdense Coding with Partial Entanglement ---")
print(f"{'p':>8s}  {'Off-diag':>10s}  {'Distinguishability':>20s}")
print("-" * 45)
for p in [0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 0.99]:
    gram, off_diag = partial_entanglement_capacity(p)
    print(f"{p:8.2f}  {off_diag:10.4f}  {'Perfect' if off_diag < 1e-10 else 'Partial'}")

10.10.2 Superdense Coding with Multiple Qubits

If Alice and Bob share $n$ Bell pairs, Alice can send $2n$ classical bits by transmitting $n$ qubits:

$$\text{Capacity} = 2n \text{ bits}$$

This is achieved by applying Pauli operations to each of her $n$ qubits independently, then sending all $n$ qubits to Bob, who performs $n$ Bell measurements.

# Multi-qubit superdense coding (2 Bell pairs = 4 classical bits)
def multi_superdense_coding(n_pairs, message):
    """
    Superdense coding with n_pairs Bell pairs.
    Message is a tuple of n_pairs 2-bit values.
    """
    n_qubits = 2 * n_pairs
    qc = QuantumCircuit(n_qubits, n_qubits)

    # Create n Bell pairs
    for i in range(n_pairs):
        qc.h(2*i)
        qc.cx(2*i, 2*i + 1)

    qc.barrier()

    # Encode message on Alice's qubits
    for i, (x, y) in enumerate(message):
        if x == 1 and y == 0:
            qc.z(2*i)
        elif x == 0 and y == 1:
            qc.x(2*i)
        elif x == 1 and y == 1:
            qc.z(2*i)
            qc.x(2*i)

    qc.barrier()

    # Bell measurement on each pair
    for i in range(n_pairs):
        qc.cx(2*i, 2*i + 1)
        qc.h(2*i)
        qc.measure(2*i, 2*i)
        qc.measure(2*i + 1, 2*i + 1)

    return qc

# Test: send message (1,0), (0,1) using 2 Bell pairs
message = [(1, 0), (0, 1)]
qc = multi_superdense_coding(2, message)
print(f"\n2-pair superdense coding for message {message}:")
print(qc.draw('text', fold=60))

result = simulator.run(qc, shots=1024).result()
counts = result.get_counts()
print(f"Results: {counts}")

10.10.3 Experimental Implementations of Superdense Coding

Superdense coding has been demonstrated experimentally in several physical systems:

Year System Fidelity Group
1996 Nuclear magnetic resonance (NMR) ~85% Chuang (MIT)
2004 Photon polarization ~85% Zeilinger (Vienna)
2015 Superconducting qubits ~80% IBM Research
2017 Trapped ions ~90% Blatt (Innsbruck)
2021 Integrated photonics ~95% Various

The main challenges are: - Bell state preparation: Must be high-fidelity (>95%) - Bell measurement: Must distinguish all 4 Bell states (photonic systems typically distinguish only 2) - Classical communication: Must be low-latency and reliable

In photonic systems, the incomplete Bell measurement (distinguishing only 2 of 4 Bell states) reduces the capacity from 2 bits to at most 1.585 bits per qubit (the "linear optics limit").


10.11 QKD Security Proofs: A Deeper Look

10.11.1 The Shor-Preskill Proof

The Shor-Preskill proof (2000) is the most elegant security proof for BB84. It works by:

  1. Reformulation: Show that BB84 is equivalent to an entanglement-based protocol where Alice prepares EPR pairs and measures one half in a random basis.

  2. Entanglement distillation: Show that error correction and privacy amplification in BB84 are equivalent to entanglement distillation (purifying Bell pairs).

  3. Security: If Alice and Bob can distill near-perfect Bell pairs, then by the monogamy of entanglement, Eve cannot be correlated with the key.

The key insight is that privacy amplification in BB84 corresponds to applying a random unitary to the key bits, which "twirls" any correlation Eve might have into a product state.

The formal security bound: After sifting, error correction, and privacy amplification with a secure key of length $\ell$, the trace distance between the actual key and a perfect key is bounded by:

$$\|\rho_{AE} - \rho_A^{\text{perfect}} \otimes \rho_E\|_1 \leq \epsilon_{\text{sec}}$$

where $\epsilon_{\text{sec}}$ is the security parameter, which can be made arbitrarily small.

10.11.2 Composable Security

A security proof is composable if the key generated by QKD can be safely used in any subsequent protocol (e.g., as a one-time pad key). The Shor-Preskill proof provides composable security.

Non-composable security (which some earlier proofs provided) means the key is secure for a specific use case but might leak information when used in combination with other protocols. Composable security is the gold standard.

10.11.3 Finite-Key Effects

The asymptotic security proofs assume infinitely long keys. In practice, keys are finite, which introduces statistical fluctuations:

  • Statistical fluctuations: The observed QBER may differ from the true QBER by $O(1/\sqrt{n})$
  • Confidence intervals: We need to account for the probability that the true QBER is higher than observed
  • Key length: The final key must be long enough that the security parameter $\epsilon_{\text{sec}}$ is small

For a key of length $n$ with observed QBER $e$, the secure key length $\ell$ is:

$$\ell \leq n \cdot (1 - h(e)) - \text{leak}_{\text{EC}} - \text{safety margin}$$

where $h(e)$ is the binary entropy, $\text{leak}_{\text{EC}}$ is the information revealed during error correction, and the safety margin accounts for finite-key effects.

Typically, for $\epsilon_{\text{sec}} = 10^{-10}$, the safety margin reduces the key rate by a few percent for $n > 10^6$ but significantly for $n < 10^4$.

10.11.4 Measurement-Device-Independent QKD (MDI-QKD)

One of the most important advances in practical QKD is MDI-QKD (Lo, Curty, Qi, 2012), which removes all security assumptions about the measurement devices:

The MDI-QKD protocol:

  1. Alice and Bob each prepare random qubit states and send them to an untrusted relay (Charles)
  2. Charles performs a Bell state measurement on the two received qubits
  3. Charles announces which Bell state he measured
  4. Alice and Bob post-select on the successful events and apply standard sifting and privacy amplification

Why MDI-QKD is secure: Even if Charles is completely controlled by Eve, the security of the key depends only on Alice and Bob's state preparation devices (which they can verify). All detector side-channel attacks are eliminated because the measurement device is untrusted.

def mdi_qkd_simulation(n_bits=200, eavesdropper=False):
    """Simulate MDI-QKD protocol."""
    # Alice and Bob each prepare states
    alice_bits = np.random.randint(0, 2, n_bits)
    alice_bases = np.random.randint(0, 2, n_bits)
    bob_bits = np.random.randint(0, 2, n_bits)
    bob_bases = np.random.randint(0, 2, n_bits)

    # Charles performs Bell measurement
    # (In MDI-QKD, Charles is untrusted)
    key_alice = []
    key_bob = []

    for i in range(n_bits):
        # Both send qubits to Charles
        # Charles performs Bell measurement
        # Successful only when both send in same basis
        if alice_bases[i] == bob_bases[i]:
            # Alice and Bob sent in same basis
            # If both sent |0⟩ or both sent |1⟩, Charles gets |Φ+⟩
            # If one sent |0⟩ and other |1⟩, Charles gets |Ψ+⟩
            if alice_bits[i] == bob_bits[i]:
                # Same bit → Charles reports successful projection
                # Alice keeps her bit, Bob flips his (or not, depending on convention)
                key_alice.append(alice_bits[i])
                key_bob.append(bob_bits[i])  # Should match Alice's
            else:
                # Different bits → also a valid event
                key_alice.append(alice_bits[i])
                key_bob.append(bob_bits[i])

    # Compute QBER
    if len(key_alice) > 0:
        errors = sum(a != b for a, b in zip(key_alice, key_bob))
        qber = errors / len(key_alice)
    else:
        qber = 0

    return {
        'key_length': len(key_alice),
        'qber': qber,
        'sift_ratio': len(key_alice) / n_bits if n_bits > 0 else 0,
    }

print("\n--- MDI-QKD Simulation ---")
for n in [200, 500, 1000]:
    result = mdi_qkd_simulation(n_bits=n)
    print(f"  n={n}: key length={result['key_length']}, QBER={result['qber']*100:.1f}%")

10.12 The Economics of QKD

10.12.1 Cost-Benefit Analysis

QKD is expensive. A single QKD link costs $100K-$500K, including: - Quantum optical equipment (lasers, detectors, beam splitters) - Classical communication infrastructure - Trusted node hardware (for distances >100 km)

But QKD provides something no classical system can: information-theoretic security. This is valuable for: - Government and military communications - Financial transactions and trading - Healthcare data - Long-term data storage (encrypted now, decrypted later with quantum computers)

The "harvest now, decrypt later" threat: An adversary can record encrypted communications today and decrypt them when a quantum computer becomes available. QKD-encrypted data remains secure even against future quantum computers.

10.12.2 Key Rate Comparison

System Distance Key Rate Cost
BB84 (fiber, no repeater) 100 km 10 kbps $100K
BB84 (fiber, trusted nodes) 500 km 1 kbps $500K
BB84 (satellite) 1000+ km 1 bps $100M
Classical (AES-256) Unlimited 10 Gbps $100

QKD is orders of magnitude slower and more expensive than classical encryption, but it provides unconditional security. The question is: when is that worth the cost?


10.13 QKD and Post-Quantum Cryptography

10.13.1 The Cryptographic Landscape

The development of large-scale quantum computers threatens current public-key cryptography:

Algorithm Classical Security Quantum Security Status
RSA-2048 ~112 bits Broken (Shor's algorithm) Vulnerable
ECC P-256 ~128 bits Broken (Shor's algorithm) Vulnerable
AES-256 256 bits ~128 bits (Grover's algorithm) Still secure (with larger keys)
SHA-256 256 bits ~128 bits (Grover's algorithm) Still secure (with larger output)

10.13.2 Three Responses to Quantum Threat

  1. Post-quantum cryptography (PQC): Classical algorithms believed to be secure against quantum attacks (lattice-based, code-based, hash-based). Standardized by NIST in 2022-2024. No new hardware needed, but security relies on computational assumptions.

  2. Quantum key distribution (QKD): Information-theoretically secure key distribution. Requires new hardware (quantum channels), but security is guaranteed by physics.

  3. Hybrid approaches: Combine PQC and QKD for defense-in-depth. Use PQC for the bulk of communication and QKD for the most sensitive keys.

Recurring Theme. Quantum advantage is problem-specific. PQC is better for general-purpose communication; QKD is better for high-security applications. The two are complementary, not competing.


10.14 Quantum Cryptography Beyond QKD

10.14.1 Quantum Digital Signatures

Quantum digital signatures (QDS) allow a sender to sign a message such that any recipient can verify the signature, but no one can forge it. Unlike QKD, which provides confidentiality, QDS provides authentication and non-repudiation.

The Gottesman-Chuang QDS protocol (2001):

  1. The signer creates multiple copies of a quantum one-way function (QOWF) and distributes them to recipients
  2. To sign a message, the signer applies the QOWF and announces the result
  3. Recipients verify by measuring their copies of the QOWF

QDS is computationally demanding (requiring many qubits per signed bit) but provides information-theoretic security.

10.14.2 Quantum Secret Sharing

Quantum secret sharing (QSS) distributes a quantum secret among multiple parties such that only authorized subsets can reconstruct it. This is the quantum analogue of classical Shamir's secret sharing.

The (3,3) threshold scheme: A quantum state $|\psi\rangle$ is encoded into 3 shares such that all 3 shares are required to reconstruct $|\psi\rangle$. Any 2 shares reveal no information.

# Quantum secret sharing: (3,3) threshold scheme
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit.quantum_info import Statevector, partial_trace, DensityMatrix
import numpy as np

def create_secret_sharing_circuit():
    """Create a (3,3) quantum secret sharing circuit.
    Encodes a state |ψ⟩ into 3 shares, each revealing no information alone."""
    qr = QuantumRegister(3, 'q')  # 3 shares
    cr = ClassicalRegister(3, 'c')
    qc = QuantumCircuit(qr, cr)

    # Encode |ψ⟩ = α|0⟩ + β|1⟩ into 3 shares
    # Using the encoding: |ψ⟩ → α|000⟩ + β|111⟩ (GHZ-like)
    # (In practice, this is done via a specific encoding circuit)

    # For simplicity, create a GHZ-like encoding
    qc.h(qr[0])
    qc.cx(qr[0], qr[1])
    qc.cx(qr[0], qr[2])

    return qc

qc = create_secret_sharing_circuit()
sv = Statevector.from_instruction(qc)
print(f"Encoded state: {sv.data}")

# Verify that each share individually reveals no information
for i in range(3):
    rho = DensityMatrix(sv)
    rho_partial = partial_trace(rho, [j for j in range(3) if j != i])
    print(f"Share {i} reduced density matrix:")
    print(f"  {np.round(rho_partial.data, 4)}")
    print(f"  Is maximally mixed? {np.allclose(rho_partial.data, np.eye(2)/2, atol=1e-10)}")

10.14.3 Quantum Coin Flipping

Quantum coin flipping allows two distrustful parties to agree on a random bit over a quantum channel, with the guarantee that neither party can bias the outcome beyond a certain probability.

The Bennett-Blum protocol (1989):

  1. Alice randomly chooses a bit $a$ and a basis $b$, prepares $|a\rangle_b$, and sends it to Bob
  2. Bob randomly chooses a basis $b'$ and measures the qubit, obtaining bit $a'$
  3. Alice announces $a, b$; Bob checks if $b' = b$ and $a' = a$
  4. The coin value is $c = a \oplus a'$ (or some agreed function)

With honest parties, the coin is fair. With a dishonest party, the maximum bias is $1/\sqrt{2} - 1/2 \approx 20.7\%$, compared to the classical limit of 50%.

10.14.4 Quantum Oblivious Transfer

Quantum oblivious transfer (QOT) allows Alice to send one of two messages to Bob, such that: - Bob receives exactly one message (not both) - Alice doesn't know which message Bob received

QOT is a fundamental primitive in secure multi-party computation and is a building block for many cryptographic protocols.


10.15 The Quantum Internet: A Technical Deep Dive

10.15.1 Quantum Repeaters: Architecture and Performance

A quantum repeater extends the range of entanglement distribution by performing entanglement swapping at intermediate nodes. The key performance metric is the entanglement generation rate as a function of distance.

Simple model: Consider a chain of $N$ repeater nodes, each separated by distance $L/N$. The entanglement generation rate between adjacent nodes is:

$$R_{\text{link}} \approx \frac{P_{\text{suc}} \cdot f_{\text{rep}}}{1 + P_{\text{suc}} \cdot t_{\text{classical}}}$$

where: - $P_{\text{suc}}$ is the success probability per attempt - $f_{\text{rep}}$ is the source repetition rate - $t_{\text{classical}}$ is the classical communication time

For fiber with loss coefficient $\alpha$ (dB/km), the success probability over distance $L/N$ is:

$$P_{\text{suc}} \approx 10^{-\alpha \cdot L / (10N)}$$

The end-to-end rate scales as $R \propto P_{\text{suc}}^{N}$ (without purification) or $R \propto P_{\text{suc}}$ (with nested purification).

import numpy as np

def entanglement_rate(distance_km, num_repeaters, loss_db_per_km=0.2,
                      source_rate_mhz=10, detector_efficiency=0.1):
    """Estimate entanglement generation rate with quantum repeaters."""
    # Distance between repeaters
    segment_length = distance_km / (num_repeaters + 1)

    # Success probability per segment
    loss_per_segment = loss_db_per_km * segment_length
    p_success_per_attempt = detector_efficiency * 10**(-loss_per_segment / 10)

    # Classical communication time per segment
    speed_of_light_fiber = 2e5  # km/s (fiber refractive index ~1.5)
    t_classical = 2 * segment_length / speed_of_light_fiber  # round trip

    # Source repetition rate
    f_rep = source_rate_mhz * 1e6  # Hz

    # Per-segment rate (with multiplexing)
    r_segment = f_rep * p_success_per_attempt

    # End-to-end rate (with entanglement swapping)
    # All segments must succeed simultaneously (simplified model)
    r_end_to_end = r_segment * p_success_per_attempt**num_repeaters

    return r_end_to_end

print("Entanglement Generation Rate vs Distance and Repeaters")
print(f"{'Distance (km)':>15s}  {'0 repeaters':>12s}  {'2 repeaters':>12s}  {'4 repeaters':>12s}")
print("-" * 55)
for dist in [50, 100, 200, 500, 1000]:
    r0 = entanglement_rate(dist, 0)
    r2 = entanglement_rate(dist, 2)
    r4 = entanglement_rate(dist, 4)
    print(f"{dist:>15d}  {r0:>12.2e}  {r2:>12.2e}  {r4:>12.2e}")

10.15.2 Quantum Memory Requirements

A crucial component of quantum repeaters is quantum memory — the ability to store qubits for long enough to perform entanglement swapping and purification. Current quantum memories have:

Platform Storage Time Efficiency Fidelity
Atomic ensembles (Rb) ~100 μs ~30% ~90%
NV centers (diamond) ~1 ms ~80% ~99%
Rare-earth ions (Eu) ~1 s ~5% ~95%
Atomic cavities ~1 ms ~90% ~99.9%

The storage time must exceed the classical communication time between adjacent nodes. For 100 km segments, $t_{\text{classical}} \approx 500$ μs, so millisecond-scale memories are sufficient.

10.15.3 Satellite-Based QKD

The Micius satellite (launched 2016) demonstrated several quantum communication milestones:

  1. Satellite-to-ground QKD (2017): Key distribution over 1200 km
  2. Satellite-to-ground entanglement distribution (2017): Bell inequality violation over 1200 km
  3. Satellite-to-ground teleportation (2017): Teleportation over 1400 km
  4. Intercontinental QKD (2018): Key exchange between China and Austria

Key challenges for satellite QKD:

  • Atmospheric loss: Photons scatter in the atmosphere, reducing the key rate
  • Pointing accuracy: The satellite must track the ground station with microradian precision
  • Background light: Sunlight and other light sources introduce errors
  • Limited contact time: A LEO satellite passes overhead for only ~5 minutes per orbit
  • Doppler shift: The satellite's motion shifts the photon frequency

Key rate estimation for satellite QKD:

$$R_{\text{satellite}} \approx \frac{N_{\text{photon}} \cdot \eta_{\text{atm}} \cdot \eta_{\text{det}} \cdot (1 - e_{\text{QBER}})}{t_{\text{pass}}}$$

where $N_{\text{photon}}$ is the number of photons sent per second, $\eta_{\text{atm}}$ is the atmospheric transmission, $\eta_{\text{det}}$ is the detector efficiency, and $t_{\text{pass}}$ is the pass duration.

Typical values for the Micius satellite: - Photon rate: ~5 MHz - Atmospheric transmission: ~1-10% (depending on weather) - Detector efficiency: ~40% - QBER: ~3-8% - Key rate: ~1 kbps during a 5-minute pass