QKD Protocols

This section provides comprehensive documentation of the three QKD protocols implemented in the platform: DPS-QKD, COW-QKD, and BB84-QKD.

DPS-QKD (Differential Phase Shift)

Overview

Differential Phase Shift Quantum Key Distribution (DPS-QKD) is a protocol that encodes information in the phase difference between consecutive optical pulses. It was developed to provide a simple and robust implementation of QKD using standard optical components.

Theory

Principle: Information is encoded in the phase difference between consecutive pulses rather than the absolute phase of individual pulses.

Encoding Scheme: - Bit 0: Phase difference \(\Delta\phi = 0\) - Bit 1: Phase difference \(\Delta\phi = \pi\)

Detection Method: Mach-Zehnder interferometer with two detectors (DM1 and DM2)

Key Features: - Simple phase encoding - Robust against phase drift - Uses standard telecom components - High key rate potential

Mathematical Model

Phase Encoding: For pulse pair \((n-1, n)\): - Random bit \(b \in \{0,1\}\) - Phase difference \(\Delta\phi_n = b \cdot \pi\) - Absolute phase \(\phi_n = \phi_{n-1} + \Delta\phi_n\)

Interference Measurement: The Mach-Zehnder interferometer measures the phase difference: - Detector 1 (DM1) click probability: \(P_1 = \cos^2(\Delta\phi/2)\) - Detector 2 (DM2) click probability: \(P_2 = \sin^2(\Delta\phi/2)\)

Bit Inference: - DM1 click only: \(b_{inferred} = 0\) - DM2 click only: \(b_{inferred} = 1\) - Both or neither click: inconclusive measurement

Implementation

The DPS-QKD implementation is split between sender and receiver classes:

Sender Implementation (simulation.Sender.SenderDPS):

class SenderDPS:
    def __init__(self, avg_photon_number=0.2):
        self.light_source = LightSource(avg_photon_number)
        self.phase_modulator = PhaseModulator()
        self.raw_key_bits = []
        self.sent_pulses_info = []
        self.last_sent_phase = None

    def prepare_and_send_pulse(self, time_slot):
        photon_count = self.light_source.generate_single_pulse_photon_count()

        if self.last_sent_phase is None:
            # First pulse - random phase
            modulated_phase = random.choice([0.0, math.pi])
            current_secret_bit = None
        else:
            # Encode bit in phase difference
            current_secret_bit = random.randint(0, 1)
            self.raw_key_bits.append(current_secret_bit)
            desired_phase_difference = 0.0 if current_secret_bit == 0 else math.pi
            modulated_phase = self.phase_modulator.modulate_phase(
                self.last_sent_phase, desired_phase_difference
            )

        self.last_sent_phase = modulated_phase
        return modulated_phase, photon_count

```

Receiver Implementation (simulation.Receiver.ReceiverDPS):

class ReceiverDPS:
    def __init__(self, detector_efficiency=0.9, dark_count_rate=1e-7):
        self.mzi = MachZehnderInterferometer()
        self.detector_dm1 = SinglePhotonDetector(detector_efficiency, dark_count_rate)
        self.detector_dm2 = SinglePhotonDetector(detector_efficiency, dark_count_rate)

    def receive_and_measure(self, time_slot, current_pulse_photons,
                          current_pulse_phase, previous_pulse_photons,
                          previous_pulse_phase):
        # Calculate interference probabilities
        prob_dm1, prob_dm2 = self.mzi.interfere_pulses(
            previous_pulse_phase, current_pulse_phase
        )

        # Simulate detection
        click_dm1 = self.detector_dm1.detect(1 if random.random() < prob_dm1 else 0)
        click_dm2 = self.detector_dm2.detect(1 if random.random() < prob_dm2 else 0)

        # Infer bit
        if click_dm1 and not click_dm2:
            bob_bit = 0
        elif click_dm2 and not click_dm1:
            bob_bit = 1
        else:
            bob_bit = None  # Inconclusive

        return click_dm1, click_dm2, measured_phase_diff, bob_bit

```

Key Generation Process:

def generate_and_share_key(self, target_node, num_pulses,
                         pulse_repetition_rate_ns, phase_flip_prob=0.0):
    # Generate pulse train
    for i in range(num_pulses):
        time_slot = i * pulse_repetition_rate_ns
        modulated_phase, photon_count = self.prepare_and_send_pulse(time_slot)

    # Transmit through channel
    channel_processed_pulses = []
    for pulse in alice_pulses_sent_info:
        received_photons = channel.transmit_pulse(pulse['photon_count'])

        # Apply phase flip noise
        modulated_phase = pulse['modulated_phase']
        if random.random() < phase_flip_prob:
            modulated_phase = (modulated_phase + math.pi) % (2 * math.pi)

        channel_processed_pulses.append({
            'time_slot': pulse['time_slot'],
            'received_photon_count': received_photons,
            'modulated_phase': modulated_phase
        })

    # Bob's measurements
    bob_clicks_and_inferred_bits = []
    for i, current_pulse in enumerate(channel_processed_pulses):
        previous_pulse = channel_processed_pulses[i-1] if i > 0 else dummy_pulse

        click_dm1, click_dm2, measured_phase_diff, bob_bit = \
            target_node.receive_and_measure(
                current_pulse['time_slot'],
                current_pulse['received_photon_count'],
                current_pulse['modulated_phase'],
                previous_pulse['received_photon_count'],
                previous_pulse['modulated_phase']
            )

        bob_clicks_and_inferred_bits.append({
            'time_slot': current_pulse['time_slot'],
            'click_dm1': click_dm1,
            'click_dm2': click_dm2,
            'measured_phase_diff': measured_phase_diff,
            'bob_inferred_bit': bob_bit
        })

    # Sifting process
    alice_sifted_key = []
    bob_sifted_key = []

    for i in range(1, len(alice_pulses_sent_info)):
        alice_pn_minus_1 = alice_pulses_sent_info[i-1]
        alice_pn = alice_pulses_sent_info[i]

        bob_measurement = bob_clicks_and_inferred_bits[i]

        if bob_measurement['bob_inferred_bit'] is not None:
            # Calculate Alice's intended bit
            alice_intended_delta_phi = (alice_pn['modulated_phase'] -
                                      alice_pn_minus_1['modulated_phase']) % (2 * math.pi)

            if alice_intended_delta_phi > math.pi:
                alice_intended_delta_phi -= 2 * math.pi

            alice_intended_bit = 0 if math.isclose(alice_intended_delta_phi, 0.0) else 1

            alice_sifted_key.append(alice_intended_bit)
            bob_sifted_key.append(bob_measurement['bob_inferred_bit'])

    return alice_sifted_key, bob_sifted_key

```

Usage Example

from simulation.Network import Network
from main import calculate_qber, postprocessing

# Create network
network = Network()
alice = network.add_node('Alice', avg_photon_number=0.2)
bob = network.add_node('Bob', detector_efficiency=0.9, dark_count_rate=1e-7)
network.connect_nodes('Alice', 'Bob', distance_km=20)

# Generate key
alice_key, bob_key = alice.generate_and_share_key(
    bob, num_pulses=10000, pulse_repetition_rate_ns=1, phase_flip_prob=0.05
)

# Analyze results
qber, num_errors = calculate_qber(alice_key, bob_key)
final_key_len, postproc = postprocessing(len(alice_key), qber)

print(f"QBER: {qber:.4f}")
print(f"Sifted key length: {len(alice_key)}")
print(f"Final key length: {final_key_len}")

```

Performance Characteristics

  • Sifting Efficiency: ~25% of raw bits

  • QBER Range: 3-11% for practical systems

  • Key Rate: High potential due to simple encoding

  • Security: Based on quantum interference

  • Hardware Requirements: Standard telecom components

COW-QKD (Coherent One-Way)

Overview

Coherent One-Way Quantum Key Distribution (COW-QKD) is a protocol that uses intensity modulation to encode information and includes monitoring pulses for eavesdropping detection. It was designed to be simple, robust, and secure against various attacks.

Theory

Principle: Information is encoded in the intensity of optical pulses, with monitoring pulses used to detect eavesdropping attempts.

Encoding Scheme: - Bit 0: Vacuum pulse followed by coherent pulse (intensity \(I_0\) then \(I_1\)) - Bit 1: Coherent pulse followed by vacuum pulse (intensity \(I_1\) then \(I_0\)) - Monitoring: Pairs of coherent pulses for eavesdropping detection

Detection Method: Single photon detector with intensity monitoring

Key Features: - Simple intensity modulation - Built-in eavesdropping detection - Robust against various attacks - High key rate potential

Mathematical Model

Pulse Types: - Data Pulse 0: \(I_0 = \mu_{off}\), \(I_1 = \mu_{on}\) - Data Pulse 1: \(I_0 = \mu_{on}\), \(I_1 = \mu_{off}\) - Monitoring Pulse: \(I_0 = \mu_{on}\), \(I_1 = \mu_{on}\)

Detection Model: - Click probability: \(P_{click} = 1 - e^{-\eta I}\) - Where \(\eta\) is detector efficiency and \(I\) is intensity

Sifting Process: - Keep bit if both Alice and Bob identify pulse as data - Discard if either identifies as monitoring - Check monitoring pulses for eavesdropping detection

Implementation

Sender Implementation (simulation.Sender.SenderCOW):

class SenderCOW:
    def __init__(self, avg_photon_number=0.2, monitor_pulse_ratio=0.1,
                 extinction_ratio_db=20.0):
        self.light_source = LightSource(avg_photon_number)
        self.intensity_modulator = IntensityModulator(extinction_ratio_db)
        self.mu = avg_photon_number
        self.monitor_pulse_ratio = monitor_pulse_ratio

    def prepare_pulse_train(self, num_total_pulses):
        self.raw_key_bits = []
        self.sent_pulses_info = []

        num_pairs = num_total_pulses // 2
        time_slot = 0

        mu_on = self.intensity_modulator.modulate(self.mu, 'on')
        mu_off = self.intensity_modulator.modulate(self.mu, 'off')

        for _ in range(num_pairs):
            r = random.random()

            if r < self.monitor_pulse_ratio:
                # Monitoring pulse pair
                self.sent_pulses_info.extend([
                    {
                        'time_slot': time_slot,
                        'photon_count': self.light_source.generate_single_pulse_photon_count(mu_on),
                        'phase': 0.0,
                        'intended_bit': None,
                        'pulse_type': 'monitor_first'
                    },
                    {
                        'time_slot': time_slot + 1,
                        'photon_count': self.light_source.generate_single_pulse_photon_count(mu_on),
                        'phase': 0.0,
                        'intended_bit': None,
                        'pulse_type': 'monitor_second'
                    }
                ])
                time_slot += 2
            else:
                # Data pulse pair
                bit = random.randint(0, 1)
                self.raw_key_bits.append(bit)

                if bit == 0:
                    # Vacuum then coherent
                    self.sent_pulses_info.extend([
                        {
                            'time_slot': time_slot,
                            'photon_count': self.light_source.generate_single_pulse_photon_count(mu_off),
                            'phase': 0.0,
                            'intended_bit': bit,
                            'pulse_type': 'data_first'
                        },
                        {
                            'time_slot': time_slot + 1,
                            'photon_count': self.light_source.generate_single_pulse_photon_count(mu_on),
                            'phase': 0.0,
                            'intended_bit': bit,
                            'pulse_type': 'data_second'
                        }
                    ])
                else:
                    # Coherent then vacuum
                    self.sent_pulses_info.extend([
                        {
                            'time_slot': time_slot,
                            'photon_count': self.light_source.generate_single_pulse_photon_count(mu_on),
                            'phase': 0.0,
                            'intended_bit': bit,
                            'pulse_type': 'data_first'
                        },
                        {
                            'time_slot': time_slot + 1,
                            'photon_count': self.light_source.generate_single_pulse_photon_count(mu_off),
                            'phase': 0.0,
                            'intended_bit': bit,
                            'pulse_type': 'data_second'
                        }
                    ])
                time_slot += 2

        return self.sent_pulses_info

```

Receiver Implementation (simulation.Receiver.ReceiverCOW):

class ReceiverCOW:
    def __init__(self, detector_efficiency=0.9, dark_count_rate=1e-7,
                 detection_threshold_photons=0):
        self.data_detector = SinglePhotonDetector(detector_efficiency, dark_count_rate)
        self.detection_threshold_photons = detection_threshold_photons
        self.received_pulses_info = []

    def measure_pulse(self, time_slot, incident_photons, pulse_type):
        click = self.data_detector.detect(incident_photons)
        bob_inferred_bit = None
        is_monitoring_click = False

        if pulse_type.startswith('data'):
            # Data pulse - infer bit based on click
            if click:
                bob_inferred_bit = 1
            else:
                bob_inferred_bit = 0
        elif pulse_type.startswith('monitor'):
            # Monitoring pulse - check for eavesdropping
            if click:
                is_monitoring_click = True

        self.received_pulses_info.append({
            'time_slot': time_slot,
            'incident_photons': incident_photons,
            'click': click,
            'bob_inferred_bit': bob_inferred_bit,
            'is_monitoring_click': is_monitoring_click,
            'pulse_type': pulse_type
        })

        return click, bob_inferred_bit, is_monitoring_click

```

Key Generation Process:

def generate_and_share_key_cow(self, target_node, num_pulses,
                             pulse_repetition_rate_ns, monitor_pulse_ratio=0.1,
                             detection_threshold_photons=0, phase_flip_prob=0.0,
                             bit_flip_error_prob=0.0):
    # Prepare pulse train
    alice_sent_pulses_info = self.cow_sender.prepare_pulse_train(num_pulses)

    # Transmit through channel
    bob_received_signals = []
    for i, sent_pulse in enumerate(alice_sent_pulses_info):
        received_photons = channel.transmit_pulse(sent_pulse['photon_count'])

        # Apply noise
        final_phase = sent_pulse['phase']
        if random.random() < phase_flip_prob:
            final_phase = (final_phase + math.pi) % (2 * math.pi)

        bob_received_signals.append({
            'time_slot': sent_pulse['time_slot'],
            'received_photons': received_photons,
            'pulse_type': sent_pulse['pulse_type'],
            'final_phase': final_phase
        })

    # Bob's measurements
    bob_measurements = []
    for received_signal in bob_received_signals:
        click, bob_inferred_bit, is_monitoring_click = \
            target_node.cow_receiver.measure_pulse(
                received_signal['time_slot'],
                received_signal['received_photons'],
                received_signal['pulse_type']
            )

        bob_measurements.append({
            'time_slot': received_signal['time_slot'],
            'click': click,
            'bob_inferred_bit': bob_inferred_bit,
            'is_monitoring_click': is_monitoring_click,
            'pulse_type': received_signal['pulse_type']
        })

    # Sifting process
    alice_sifted_key = []
    bob_sifted_key = []

    for i in range(0, len(alice_sent_pulses_info), 2):
        if i + 1 >= len(alice_sent_pulses_info):
            break

        pulse1 = alice_sent_pulses_info[i]
        pulse2 = alice_sent_pulses_info[i + 1]

        bob_measurement1 = bob_measurements[i]
        bob_measurement2 = bob_measurements[i + 1]

        # Check if both pulses are data pulses
        if (pulse1['pulse_type'].startswith('data') and
            pulse2['pulse_type'].startswith('data')):

            # Check if Bob agrees on data pulses
            if (bob_measurement1['bob_inferred_bit'] is not None and
                bob_measurement2['bob_inferred_bit'] is not None):

                # Apply bit flip error
                alice_bit = pulse1['intended_bit']
                bob_bit = bob_measurement1['bob_inferred_bit']

                if random.random() < bit_flip_error_prob:
                    bob_bit = 1 - bob_bit

                alice_sifted_key.append(alice_bit)
                bob_sifted_key.append(bob_bit)

    return alice_sifted_key, bob_sifted_key

```

Usage Example

# Create network
network = Network()
alice = network.add_node('Alice', avg_photon_number=0.1)
bob = network.add_node('Bob', detector_efficiency=0.9, dark_count_rate=1e-7)
network.connect_nodes('Alice', 'Bob', distance_km=20)

# Generate key with COW protocol
alice_key, bob_key = alice.generate_and_share_key_cow(
    bob, num_pulses=10000, pulse_repetition_rate_ns=1,
    monitor_pulse_ratio=0.1, detection_threshold_photons=0,
    phase_flip_prob=0.05, bit_flip_error_prob=0.05
)

# Analyze results
qber, num_errors = calculate_qber(alice_key, bob_key)
final_key_len, postproc = postprocessing(len(alice_key), qber)

print(f"COW-QKD Results:")
print(f"QBER: {qber:.4f}")
print(f"Sifted key length: {len(alice_key)}")
print(f"Final key length: {final_key_len}")

```

Performance Characteristics

  • Sifting Efficiency: ~40% of raw bits

  • QBER Range: 3-10% for practical systems

  • Key Rate: High due to simple intensity modulation

  • Security: Built-in eavesdropping detection

  • Hardware Requirements: Standard optical components

BB84-QKD (Bennett-Brassard 1984)

Overview

BB84 is the original quantum key distribution protocol, proposed by Bennett and Brassard in 1984. It uses four quantum states in two conjugate bases to achieve secure key distribution based on the principles of quantum mechanics.

Theory

Principle: Information is encoded in quantum states using two conjugate bases, with security based on the quantum uncertainty principle.

Encoding Scheme: - Rectilinear Basis (R): \(|0\rangle\) (horizontal), \(|1\rangle\) (vertical) - Diagonal Basis (D): \(|+\rangle = \frac{1}{\sqrt{2}}(|0\rangle + |1\rangle)\), \(|-\rangle = \frac{1}{\sqrt{2}}(|0\rangle - |1\rangle)\)

Detection Method: Single photon detector with basis switching

Key Features: - Original QKD protocol - Information-theoretic security - Basis reconciliation - Proven security against various attacks

Mathematical Model

State Preparation: - Random bit \(b \in \{0,1\}\) - Random basis \(B \in \{R,D\}\) - State: \(|\psi\rangle = |b\rangle_B\)

Measurement: - Random basis choice \(B' \in \{R,D\}\) - Measurement outcome: \(b' \in \{0,1\}\) or no detection

Sifting Process: - Keep bit if \(B = B'\) and detection occurred - Discard if \(B \neq B'\) or no detection

Security: Based on quantum uncertainty principle - measuring in wrong basis disturbs the state

Implementation

Sender Implementation (simulation.Sender.SenderBB84):

class SenderBB84:
    def __init__(self, avg_photon_number=0.2):
        self.light_source = LightSource(avg_photon_number)
        self.raw_key_bits = []
        self.chosen_bases = []
        self.sent_pulses_info = []

    def prepare_and_send_pulse(self, time_slot):
        chosen_bit = random.randint(0, 1)
        self.raw_key_bits.append(chosen_bit)

        chosen_basis = random.choice(['R', 'D'])
        self.chosen_bases.append(chosen_basis)

        if chosen_basis == 'R':
            encoded_state = '|0⟩' if chosen_bit == 0 else '|1⟩'
        else:
            encoded_state = '|+⟩' if chosen_bit == 0 else '|-⟩'

        photon_count = self.light_source.generate_single_pulse_photon_count()

        pulse_info = {
            'time_slot': time_slot,
            'photon_count': photon_count,
            'encoded_state': encoded_state,
            'chosen_bit': chosen_bit,
            'chosen_basis': chosen_basis
        }
        self.sent_pulses_info.append(pulse_info)

        return encoded_state, photon_count, chosen_bit, chosen_basis

```

Receiver Implementation (simulation.Receiver.ReceiverBB84):

class ReceiverBB84:
    def __init__(self, detector_efficiency=0.9, dark_count_rate=1e-7):
        self.detector = SinglePhotonDetector(detector_efficiency, dark_count_rate)
        self.raw_measurements = []
        self.chosen_bases = []
        self.received_pulses_info = []

    def receive_and_measure(self, time_slot, incident_photons, encoded_state):
        chosen_basis = random.choice(['R', 'D'])
        self.chosen_bases.append(chosen_basis)

        click_occurred = self.detector.detect(incident_photons)
        measured_bit = None

        if click_occurred:
            if chosen_basis == 'R':
                # Measure in rectilinear basis
                if encoded_state == '|0⟩':
                    measured_bit = 0 if random.random() > 0.02 else 1
                elif encoded_state == '|1⟩':
                    measured_bit = 1 if random.random() > 0.02 else 0
                else:
                    measured_bit = random.randint(0, 1)
            else:
                # Measure in diagonal basis
                if encoded_state == '|+⟩':
                    measured_bit = 0 if random.random() > 0.02 else 1
                elif encoded_state == '|-⟩':
                    measured_bit = 1 if random.random() > 0.02 else 0
                else:
                    measured_bit = random.randint(0, 1)

        self.raw_measurements.append(measured_bit)

        measurement_info = {
            'time_slot': time_slot,
            'incident_photons': incident_photons,
            'encoded_state': encoded_state,
            'chosen_basis': chosen_basis,
            'click_occurred': click_occurred,
            'measured_bit': measured_bit
        }
        self.received_pulses_info.append(measurement_info)

        return measured_bit, chosen_basis, click_occurred

```

Key Generation Process:

def generate_and_share_key_bb84(self, target_node, num_pulses,
                              pulse_repetition_rate_ns, phase_flip_prob=0.0):
    # Generate pulse train
    for i in range(num_pulses):
        time_slot = i * pulse_repetition_rate_ns
        encoded_state, photon_count, chosen_bit, chosen_basis = \
            self.bb84_sender.prepare_and_send_pulse(time_slot)

    # Transmit through channel
    channel_processed_pulses = []
    for pulse in alice_pulses_sent_info:
        received_photons = channel.transmit_pulse(pulse['photon_count'])

        channel_processed_pulses.append({
            'time_slot': pulse['time_slot'],
            'received_photon_count': received_photons,
            'encoded_state': pulse['encoded_state']
        })

    # Bob's measurements
    bob_measurements = []
    for pulse in channel_processed_pulses:
        measured_bit, chosen_basis, click_occurred = \
            target_node.bb84_receiver.receive_and_measure(
                pulse['time_slot'],
                pulse['received_photon_count'],
                pulse['encoded_state']
            )

        bob_measurements.append({
            'time_slot': pulse['time_slot'],
            'measured_bit': measured_bit,
            'chosen_basis': chosen_basis,
            'click_occurred': click_occurred
        })

    # Sifting process
    alice_sifted_key = []
    bob_sifted_key = []

    for i, alice_pulse in enumerate(alice_pulses_sent_info):
        bob_measurement = bob_measurements[i]

        # Check if bases match and detection occurred
        if (alice_pulse['chosen_basis'] == bob_measurement['chosen_basis'] and
            bob_measurement['click_occurred']):

            alice_sifted_key.append(alice_pulse['chosen_bit'])
            bob_sifted_key.append(bob_measurement['measured_bit'])

    return alice_sifted_key, bob_sifted_key

```

Usage Example

# Create network
network = Network()
alice = network.add_node('Alice', avg_photon_number=0.2)
bob = network.add_node('Bob', detector_efficiency=0.9, dark_count_rate=1e-7)
network.connect_nodes('Alice', 'Bob', distance_km=20)

# Generate key with BB84 protocol
alice_key, bob_key = alice.generate_and_share_key_bb84(
    bob, num_pulses=10000, pulse_repetition_rate_ns=1, phase_flip_prob=0.05
)

# Analyze results
qber, num_errors = calculate_qber(alice_key, bob_key)
final_key_len, postproc = postprocessing(len(alice_key), qber)

print(f"BB84-QKD Results:")
print(f"QBER: {qber:.4f}")
print(f"Sifted key length: {len(alice_key)}")
print(f"Final key length: {final_key_len}")

```

Performance Characteristics

  • Sifting Efficiency: ~50% of raw bits

  • QBER Range: 3-11% for practical systems

  • Key Rate: Moderate due to basis reconciliation

  • Security: Information-theoretic security

  • Hardware Requirements: Polarization or phase encoding

Protocol Comparison

Performance Metrics

Protocol | Sifting Efficiency | QBER Range | Key Rate | Security Level | Hardware Complexity |

|----------|——————-|------------|———-|----------------|——————-| | DPS-QKD | ~25% | 3-11% | High | High | Low | | COW-QKD | ~40% | 3-10% | High | High | Low | | BB84-QKD | ~50% | 3-11% | Moderate | Highest | Medium |

Use Case Recommendations

DPS-QKD: - High-speed applications - Simple hardware requirements - Phase-stable environments - Cost-sensitive deployments

COW-QKD: - Security-critical applications - Eavesdropping detection required - Robust performance needed - Monitoring capabilities desired

BB84-QKD: - Maximum security requirements - Research and development - Educational purposes - Standard QKD implementations

Implementation Considerations

DPS-QKD: - Requires phase stability - Sensitive to phase noise - Simple implementation - High key rate potential

COW-QKD: - Requires intensity control - Monitoring pulse overhead - Robust against attacks - Built-in security features

BB84-QKD: - Requires basis switching - Basis reconciliation overhead - Proven security - Standard protocol

Future Protocol Extensions

The platform is designed to easily accommodate new QKD protocols:

  1. Protocol Interface: Standard interface for new protocols

  2. Modular Design: Separate sender/receiver implementations

  3. Parameter Configuration: Flexible parameter system

  4. Analysis Integration: Automatic QBER and key rate analysis

Adding a new protocol involves:

  1. Implementing sender and receiver classes

  2. Adding protocol-specific parameters

  3. Integrating with the network model

  4. Adding frontend support

  5. Updating documentation