← Quantum Store · Guides · Lessons · Glossary · Packages · About · Türkçe

Quantum Store editors

BB84 quantum key distribution

ProtocolCryptographyLicence: MITVersion: 1.0.04.3 KB
Download ZIP (free)

A Qiskit simulation of the Bennett–Brassard 1984 QKD protocol: with no eavesdropper the error rate is 0%; when an eavesdropper steps in, the attack is detected through about 25% errors.

How does BB84 work?

  1. Alice picks random bits and encodes each one into a single photon or qubit in a random basis (Z: |0⟩/|1⟩ or X: |+⟩/|−⟩).
  2. Bob measures each qubit in a random basis of his own choosing.
  3. Over a public channel they compare only their bases; the bits where the bases match form the shared key (about half of them).
  4. They reveal part of the key and look at the error rate (QBER). An eavesdropper (Eve) has to measure, so she disturbs the states and the QBER rises to about 25%.

Test result

With 400 qubits:

Limits

This is an educational simulation. Real QKD systems also need channel loss handling, error correction (information reconciliation) and privacy amplification.

Next steps

  1. Add 5% random bit-flip noise to the channel and watch the QBER.
  2. Try a case where Eve measures only some of the qubits.

Installation and running

pip install qiskit numpy
python bb84.py

Tested with: qiskit 2.5.2, Python 3.12.

Links

Package contents

Licence

This package was prepared by the Quantum Store editors and is distributed under the MIT licence.


Quantum Store — https://hakanerdogan.com/en

Example code

The example shipped in the package, run and checked. Comments and printed messages are in Turkish; the code is the same in any language. Everything is in the ZIP.

bb84.py

"""BB84 kuantum anahtar dağıtımı (QKD) protokolü — Qiskit simülasyonu.

Alice rastgele bitleri rastgele bazlarda (Z veya X) kodlar, Bob rastgele
bazlarda ölçer. Bazların eşleştiği bitler ortak anahtarı oluşturur
("sifting"). Araya bir dinleyici (Eve) girerse, kendi rastgele ölçümleri
anahtarda yaklaşık %25 hata oranı (QBER) üretir ve fark edilir.

Çalıştırma:
    pip install qiskit numpy
    python bb84.py
"""

import numpy as np
from qiskit import QuantumCircuit
from qiskit.primitives import StatevectorSampler

N = 400
rng = np.random.default_rng(2026)
sampler = StatevectorSampler(seed=2026)


def prepare(bit: int, basis: int) -> QuantumCircuit:
    qc = QuantumCircuit(1, 1)
    if bit:
        qc.x(0)
    if basis:  # 1 = X bazı
        qc.h(0)
    return qc


def measure_in(qc: QuantumCircuit, basis: int) -> QuantumCircuit:
    qc = qc.copy()
    if basis:
        qc.h(0)
    qc.measure(0, 0)
    return qc


def run_single_shot(circuits: list[QuantumCircuit]) -> np.ndarray:
    results = sampler.run(circuits, shots=1).result()
    return np.array([int(next(iter(r.data.c.get_counts()))) for r in results])


def bb84(with_eve: bool) -> tuple[int, float]:
    alice_bits = rng.integers(0, 2, N)
    alice_bases = rng.integers(0, 2, N)
    bob_bases = rng.integers(0, 2, N)

    channel = [prepare(b, a) for b, a in zip(alice_bits, alice_bases)]

    if with_eve:
        eve_bases = rng.integers(0, 2, N)
        eve_bits = run_single_shot([measure_in(q, e) for q, e in zip(channel, eve_bases)])
        channel = [prepare(b, e) for b, e in zip(eve_bits, eve_bases)]

    bob_bits = run_single_shot([measure_in(q, b) for q, b in zip(channel, bob_bases)])

    keep = alice_bases == bob_bases
    key_len = int(keep.sum())
    qber = float(np.mean(alice_bits[keep] != bob_bits[keep]))
    return key_len, qber


for label, eve in (("Dinleyici yok", False), ("Eve araya girdi", True)):
    key_len, qber = bb84(eve)
    print(f"{label:16s}: anahtar uzunluğu = {key_len}, QBER = {qber:.1%}")
    if eve:
        assert 0.15 < qber < 0.35, qber
    else:
        assert qber == 0.0, qber

print("Tamam: dinleyici yokken hata 0, dinleyici varken ~%25 hata.")

Related concepts

← All packages

Share: X · LinkedIn