Eavesdropping to QKD Example

We will rerun the same example as before. But in this example, we have an listener who tries to attack QKD protocol:

import QDNS
import logging

We need to program Alice to initiate qkd protocol with Bob:

class Alice(QDNS.Node):
    def __init__(self, *user_args):
        super().__init__("Alice")
        self.create_new_application(self.default_app, *user_args)

    @staticmethod
    def default_app(app: QDNS.Application, *user_args):
        # Lets use 512 lenght, E91 method.
        protocol = app.run_qkd_protocol("Bob", 512, QDNS.E91_METHOD)

        if protocol is None:
            print("{}: Protocol is failed to establish.".format(app.host_label))
        else:
            print("{}: QKD Key generated!".format(app.host_label))

For Bob, we need to make him wait for protocol:

class Bob(QDNS.Node):
    def __init__(self, *user_args):
        super().__init__("Bob")
        self.create_new_application(self.default_app, *user_args)

    @staticmethod
    def default_app(app: QDNS.Application, *user_args):
        protocol = app.wait_qkd()

        if protocol is None:
            print("{}: Protocol is failed to establish.".format(app.host_label))
        else:
            print("{}: QKD Key generated!".format(app.host_label))

Now we got eavesdropper Eve. He will measure every qubit he got:

class Eve(QDNS.Observer):
    def __init__(self):
        super().__init__("Eve")
        # Static flag is not essantial.
        self.create_new_application(self.eve_app, delayed_start_time=0, static=True)

    @staticmethod
    def eve_app(app: QDNS.Application, *user_args):
        # Listens the traffic on Eve node in loop.
        app.listener.set_interrupt(True)

        while True:
            communication = app.listener.get_communication_item()

            # Break if no traffic come.
            if communication is None:
                break

            # Ignore classic packages.
            if isinstance(communication, QDNS.Package):
                pass
            else:
                # Eve secretly measures qubits.
                app.measure_qubits(communication.qubits)

            # Release packets or qubits we got. We measured qubits.
            app.listener.release_item()

        print("Eve listening is over.")

Here is the main function for this example:

def main():
    logging.basicConfig(level=logging.WARNING)

    alice, bob, eve = Alice(), Bob(), Eve()
    net = QDNS.Network(alice, bob, eve)
    net.add_channels(alice, eve, length=1.0) # km
    net.add_channels(eve, bob, length=1.0)

    conf = QDNS.BackendConfiguration(QDNS.STIM_BACKEND, 1, {2: 2048})

    # Before simulation we can change the qkd protocol default paramters.
    # 0.75 to good match threshold, 16 to sample divisor.
    # Since channel lengths are 2.0km total, this value to except from protocol.

    QDNS.change_e91_values(0.75, 16)

    # Let's ignore state_preapir, measure error, gate errors.
    # Set probabilty to 0, or set channel to QDNS.no_noise_channel.
    QDNS.change_default_noise_pattern(
        QDNS.NoisePattern(
            0.0, 0.0, 0.0,
            sp_channel=QDNS.bit_flip_channel,
            measure_channel=QDNS.bit_and_phase_flip_channel,
            gate_channel=QDNS.phase_flip_channel,
            scramble_channel=QDNS.depolarisation_channel,
        )
    )

    # Also noise pattern can be given to simulate() as paramater or
    # can be setted to default as shown as below.

    sim = QDNS.Simulator()
    results = sim.simulate(net, conf)

if __name__ == "__main__":
    main()

This results are expected. If you set logging level to debug, you’ll see that the match rate is around ~40%.

WARNING:QDNS::Kernel::Backend:STIM backend is prepaired for simulation. Prepairation time: ~0.0001 sec

Alice: Protocol is failed to establish.
Bob: Protocol is failed to establish.

WARNING:QDNS::Alice:Device simulation is idled after 1.0018 seconds.
WARNING:QDNS::Bob:Device simulation is idled after 1.0018 seconds.
WARNING:QDNS::Eve:Device simulation is idled after 1.0017 seconds.
WARNING:QDNS::Kernel:Simulation is ended in 1.5046 seconds. Real raw time: 0.0717