A comprehensive Python simulation of the BB84 protocol using Qiskit, demonstrating secure key exchange, eavesdropper detection, and the impact of quantum noise.
This project was developed for the Qiskit Hackathon. It provides an end-to-end simulation of the BB84 Quantum Key Distribution protocol, a foundational method for establishing information-theoretically secure communication channels.
The simulation demonstrates:
- The complete process of generating a secure cryptographic key between two parties (Alice and Bob).
- How the presence of an eavesdropper (Eve) can be reliably detected.
- The practical impact of real-world hardware noise on the protocol's performance.
- End-to-End Simulation: Implements the full BB84 protocol including qubit encoding, transmission, measurement, and key sifting.
- Eavesdropper Detection: Simulates an intercept-resend attack by an eavesdropper (Eve) and demonstrates how this attack is detected by measuring the Quantum Bit Error Rate (QBER).
- Noise Analysis: Includes simulations on both an ideal (noise-free) and a custom noisy quantum backend to show the effect of real-world hardware errors on the QBER.
- Advanced Analysis: Provides a plot showing the relationship between increasing gate noise and the resulting QBER, demonstrating the protocol's sensitivity to hardware imperfections.
- Clear Visualization: Generates intuitive plots for each scenario, visually comparing Alice's and Bob's sifted keys to highlight errors and mismatches.
The project contains the following files:
- bb84_notebook_complete.ipynb: The main Jupyter Notebook file containing all the Python code for the protocol logic, simulations, and visualizations.
- README.md: This file, providing an overview and instructions for the project.
- requirements.txt: A list of all the necessary Python packages required to run the project.
- [Your_Presentation_File.pdf]: (To be added by you) The final presentation slides explaining the project.
To run this project, first clone the repository (or download the files) into a local directory. Then, install the necessary Python packages using the requirements.txt file.
It is recommended to use a virtual environment.
# Create and activate a virtual environment (optional but recommended)
python -m venv qiskit_env
source qiskit_env/bin/activate # On Windows, use `qiskit_env\Scripts\activate`
# Install the required packages
pip install -r requirements.txt
All the code and simulations are contained within the single Jupyter Notebook file.
-
Make sure you have Jupyter Notebook or JupyterLab installed (pip install jupyterlab).
-
Launch JupyterLab from your terminal:
jupyter-lab -
Open the bb84_notebook_complete.ipynb file within the Jupyter interface.
-
Run all the cells in the notebook from top to bottom by clicking Run > Run All Cells.
The notebook will automatically execute all simulation scenarios, print the results, and display the corresponding plots inline.
The notebook runs several key scenarios:
- Ideal Case (No Eve): Simulates the protocol on a perfect, noise-free simulator.
- Expected QBER: ~0%. The final keys should match perfectly.
- Ideal Case (With Eve): Simulates an eavesdropper attack on a perfect simulator.
- Expected QBER: ~25%. Eve's interference introduces a high error rate, making her presence detectable.
- Noise Impact Analysis: Simulates the protocol with varying levels of depolarizing noise (without Eve).
- Expected Result: The QBER increases as the hardware noise level increases, showing the challenge of implementing QKD on real devices.
- Qiskit: The core framework for creating and running quantum circuits.
- Qiskit Aer: Used for high-performance, realistic simulations of quantum circuits, including noise models.
- NumPy: For efficient numerical operations and random data generation.
- Matplotlib: For creating all the plots and visualizations.
The primary goal of this project was to create a fully functional and educational simulation of the BB84 Quantum Key Distribution protocol. My approach was centered around clarity, reproducibility, and fulfilling all requirements of the hackathon prompt.
- Encapsulated Logic: The core protocol logic was encapsulated within a BB84_Protocol Python class. This object-oriented approach cleanly separates the roles of Alice, Bob, and the eavesdropper (Eve), making the code modular and easy to understand.
- Jupyter Notebook Environment: To ensure ease of use and provide a clear, step-by-step demonstration, the entire project—from the class definition to simulation runs and visualizations—is contained within a single Jupyter Notebook (bb84_notebook_complete.ipynb).
- Comprehensive Scenarios: The simulation covers three critical scenarios to provide a complete picture of the protocol's performance:
- An ideal, noise-free environment to establish a baseline.
- An intercept-resend attack by Eve to demonstrate how the protocol detects eavesdropping.
- A realistic, noisy environment to show how real-world quantum hardware imperfections affect the key exchange.
- Advanced Noise Analysis: To go beyond the basic requirements, an additional analysis was performed to plot the Quantum Bit Error Rate (QBER) as a function of increasing hardware noise, providing deeper insight into the protocol's practical limitations.
The complete, commented implementation can be found in the bb84_notebook_complete.ipynb file.
A key part of the logic is the simulation of the qubit exchange, which handles the presence of an eavesdropper:
def simulate_exchange(self, eavesdropper_present=False):
"""Simulates the qubit exchange between Alice and Bob."""
self.bob_results = []
for i in range(self.key_length):
qc = QuantumCircuit(1, 1)
encode_qubit(qc, self.alice_bits[i], self.alice_bases[i])
if eavesdropper\_present:
\# Eve intercepts, measures, and resends a new qubit
eve\_measured\_bit \= self.\_measure\_and\_resend(qc, self.eve\_bases\[i\])
qc\_bob \= QuantumCircuit(1, 1\)
encode\_qubit(qc\_bob, eve\_measured\_bit, self.eve\_bases\[i\])
measure\_qubit(qc\_bob, self.bob\_bases\[i\])
self.bob\_results.append(self.\_run\_circuit(qc\_bob))
else:
\# Direct transmission from Alice to Bob
measure\_qubit(qc, self.bob\_bases\[i\])
self.bob\_results.append(self.\_run\_circuit(qc))
The simulations successfully demonstrated the principles of the BB84 protocol. The key results are summarized below:
| Scenario | Eavesdropper | Backend | Expected QBER | Observed QBER | Outcome |
|---|---|---|---|---|---|
| 1 | No | Ideal | ~0% | 0.00% | Secure key established |
| 2 | Yes | Ideal | ~25% | ~25% | Eavesdropper detected; key discarded |
The notebook generates several plots, including:
- Key Comparison Plots: These plots visually show the perfect match between Alice's and Bob's sifted keys in the secure scenario and the significant mismatches introduced by Eve.
- Noise Impact Plot: This graph clearly shows a near-linear relationship between the gate error probability and the resulting QBER, confirming the protocol's sensitivity to noise.
The main challenge encountered during development was related to Qiskit's evolving package structure.
- Challenge: Initial attempts to use a noisy backend via qiskit.providers.fake_provider resulted in ImportError exceptions, as the location of these modules has changed across different Qiskit versions. This made the code unreliable.
- Solution: To create a robust and version-agnostic solution, I abandoned the FakeProvider. Instead, I implemented a custom noise model directly using qiskit_aer.noise. By creating a NoiseModel and adding a depolarizing_error to the gates, I could reliably simulate a noisy backend without depending on modules with shifting import paths. This approach is more stable and provides finer control over the noise parameters.