Exemple #1
0
    def preparation_and_distribution():
        for serial in range(NO_OF_SERIALS):
            for bit_no in range(QUBITS_PER_MONEY):
                random_bit = randint(0, 1)
                random_base = randint(0, 1)

                bank_bits[serial].append(random_bit)
                bank_basis[serial].append(random_base)
                q = Qubit(host)
                if random_bit == 1:
                    q.X()
                if random_base == 1:
                    q.H()
                host.send_qubit(customer, q, await_ack=False)
Exemple #2
0
def _send_key(packet):
    receiver = network.get_host(packet.receiver)
    sender = network.get_host(packet.sender)
    key_size = packet.payload['keysize']

    packet.protocol = REC_KEY
    network.send(packet)

    secret_key = np.random.randint(2, size=key_size)
    msg_buff = []
    sender.qkd_keys[receiver.host_id] = secret_key.tolist()
    sequence_nr = 0
    # iterate over all bits in the secret key.
    for bit in secret_key:
        ack = False
        while not ack:
            # get a random base. 0 for Z base and 1 for X base.
            base = random.randint(0, 1)

            # create qubit
            q_bit = Qubit(sender)
            # Set qubit to the bit from the secret key.
            if bit == 1:
                q_bit.X()

            # Apply basis change to the bit if necessary.
            if base == 1:
                q_bit.H()

            # Send Qubit to Receiver
            sender.send_qubit(receiver.host_id, q_bit, await_ack=True)
            # Get measured basis of Receiver
            message = sender.get_next_classical_message(
                receiver.host_id, msg_buff, sequence_nr)
            # Compare to send basis, if same, answer with 0 and set ack True and go to next bit,
            # otherwise, send 1 and repeat.
            if message == ("%d:%d") % (sequence_nr, base):
                ack = True
                sender.send_classical(receiver.host_id, ("%d:0" % sequence_nr),
                                      await_ack=True)
            else:
                ack = False
                sender.send_classical(receiver.host_id, ("%d:1" % sequence_nr),
                                      await_ack=True)

            sequence_nr += 1
Exemple #3
0
def Alice_qkd(alice, msg_buff):
    sequence_nr = 0
    # iterate over all bits in the secret key.
    for bit in secret_key:
        ack = False
        while not ack:
            print("Alice sequence nr is %d." % sequence_nr)
            # get a random base. 0 for Z base and 1 for X base.
            base = random.randint(0, 1)

            # create qubit
            q_bit = Qubit(alice)

            # Set qubit to the bit from the secret key.
            if bit == 1:
                q_bit.X()

            # Apply basis change to the bit if necessary.
            if base == 1:
                q_bit.H()

            # Send Qubit to Bob
            alice.send_qubit(hosts['Eve'].host_id, q_bit, await_ack=True)

            # Get measured basis of Bob
            message = get_next_classical_message(alice, hosts['Eve'].host_id,
                                                 msg_buff, sequence_nr)

            # Compare to send basis, if same, answer with 0 and set ack True and go to next bit,
            # otherwise, send 1 and repeat.
            if message == ("%d:%d") % (sequence_nr, base):
                ack = True
                alice.send_classical(hosts['Eve'].host_id,
                                     ("%d:0" % sequence_nr),
                                     await_ack=True)
            else:
                ack = False
                alice.send_classical(hosts['Eve'].host_id,
                                     ("%d:1" % sequence_nr),
                                     await_ack=True)

            sequence_nr += 1
Exemple #4
0
    def _establish_epr(self, sender, receiver, q_id, o_seq_num, blocked):
        """
        Instead doing an entanglement swap, for efficiency we establish EPR pairs
        directly for simulation, if an entanglement swap would have been possible.

        Args:
            sender (Host): Sender of the EPR pair
            receiver (Host): Receiver of the EPR pair
            q_id (str): Qubit ID of the sent EPR pair
            o_seq_num (int): The original sequence number
            blocked (bool): If the pair being distributed is blocked or not
        """
        host_sender = self.get_host(sender)
        host_receiver = self.get_host(receiver)
        q1 = Qubit(host_sender)
        q2 = Qubit(host_sender)
        q1.H()
        q1.cnot(q2)
        host_sender.add_epr(receiver, q1, q_id, blocked)
        host_receiver.add_epr(sender, q2, q_id, blocked)
        host_receiver.send_ack(sender, o_seq_num)
Exemple #5
0
def handshake_receiver(host, sender_id):
    """
    Establishes a classical TCP-like handshake with the sender .
    If successful starts to receive the qubits , otherwise terminated the connection.

    :param host: Receiver host
    :param sender_id: ID of the sender
    :return: If successful returns True, otherwise False
    """
    latest_seq_num = host.get_sequence_number(sender_id)

    # Receive the EPR half of Alice and the SYN message
    qb_2 = host.get_data_qubit(sender_id, wait=WAIT_TIME)
    if qb_2 is None:
        Logger.get_instance().log('qb_2 is None')
        return False
    qb_2 = qb_2['q']

    message_recv = host.get_message_w_seq_num(sender_id, (latest_seq_num + 1),
                                              wait=WAIT_TIME)
    if not message_recv:
        Logger.get_instance().log('No message has arrived')
        return False

    message_recv = message_recv[0]['message']

    if message_recv == '10':
        Logger.get_instance().log("SYN is received by Bob")
    else:
        return False

    # Create an EPR pair.
    qb_3 = Qubit(host)
    qb_4 = Qubit(host)
    qb_3.H()
    qb_3.cnot(qb_4)

    # Send half of the EPR pair created (qubit 3) and send back the qubit 2 that Alice has sent first.
    _, ack_received = host.send_qubit(sender_id, qb_2, await_ack=True)

    if ack_received is False:
        Logger.get_instance().log('ACK is not received')
        return False

    _, ack_received = host.send_qubit(sender_id, qb_3, await_ack=True)
    if ack_received is False:
        Logger.get_instance().log('ACK is not received')
        return False

    # Send SYN-ACK message.
    host.send_classical(sender_id, SYN_ACK, True)
    latest_seq_num = host.get_sequence_number(sender_id)

    # Receive the ACK message.
    message = host.get_message_w_seq_num(sender_id,
                                         latest_seq_num,
                                         wait=WAIT_TIME)
    if message is None:
        Logger.get_instance().log('ACK was not received by Bob')
        return False

    if message.content == '01':
        Logger.get_instance().log('ACK was received by Bob')

    # Receive the qubit 3.
    qa_3 = host.get_data_qubit(sender_id, wait=WAIT_TIME)
    if qa_3 is None:
        return False

    # Make a Bell State measurement in qubit 3 and qubit 4.
    qa_3.cnot(qb_4)
    qa_3.H()

    qa_3_check = qa_3.measure()
    qb_4_check = qb_4.measure()

    # If measurement results are as expected , establish the TCP connection.
    # Else report that there is something wrong.
    if qa_3_check == 0 and qb_4_check == 0:
        Logger.get_instance().log("TCP connection established.")
        return True
    else:
        Logger.get_instance().log("Something is wrong.")
        return False
Exemple #6
0
def handshake_sender(host, receiver_id):
    """
    Establishes a classical TCP-like handshake with the receiver .
    If successful starts the transmission of qubits , otherwise terminated the connection.

    :param host: Sender of qubits
    :param receiver_id: ID of the receiver
    :return: If successful returns True, otherwise False
    """

    # Create an EPR pair.
    qa_1 = Qubit(host)
    qa_2 = Qubit(host)

    qa_1.H()
    qa_1.cnot(qa_2)

    # Send a half of EPR pair and the SYN message to Bob.
    _, ack_received = host.send_qubit(receiver_id, qa_2, await_ack=True)
    if ack_received is False:
        Logger.get_instance().log('ACK is not received')
        return False
    ack_received = host.send_classical(receiver_id, SYN, await_ack=True)
    if ack_received is False:
        Logger.get_instance().log('ACK is not received')
        return False

    syn_seq_num = host.get_sequence_number(receiver_id)

    # Receive the qubits Bob has sent (qubit 2 and qubit 3) for SYN-ACK.
    qb_2 = host.get_data_qubit(receiver_id, wait=WAIT_TIME)
    if qb_2 is None:
        return False

    qb_3 = host.get_data_qubit(receiver_id, wait=WAIT_TIME)
    if qb_3 is None:
        return False

    # Receive the classical message Bob has sent for SYN-ACK.
    message_recv = host.get_message_w_seq_num(receiver_id,
                                              syn_seq_num + 2,
                                              wait=WAIT_TIME)
    if message_recv is None:
        return False

    if message_recv.content == '11':
        Logger.get_instance().log("SYN-ACK is received by Alice")
    else:
        Logger.get_instance().log('Connection terminated - 1 ')
        return False

    # Make a Bell State measurement on qubit 1 and qubit 2.
    qa_1.cnot(qb_2)
    qa_1.H()
    qa_1_check = qa_1.measure()
    qb_2_check = qb_2.measure()

    # If measurement results are as expected, send Bob a ACK message and the qubit 3 that he has sent previously.
    # Else report that there is something wrong.
    if qa_1_check == 0 and qb_2_check == 0:
        latest_seq_num = host.get_sequence_number(receiver_id)
        ack_received = host.send_classical(receiver_id, ACK, await_ack=True)
        if ack_received is False:
            Logger.get_instance().log('ACK is not received')
            return False
        _, ack_received = host.send_qubit(receiver_id, qb_3, await_ack=True)
        if ack_received is False:
            Logger.get_instance().log('ACK is not received')
            return False
        message = host.get_message_w_seq_num(receiver_id,
                                             latest_seq_num + 2,
                                             wait=WAIT_TIME)
        return message.content == 'ACK'
    else:
        Logger.get_instance().log("Something is wrong.")
        return False
def RepeaterProtocol(host, alice, bob):

    timeout = 180
    start = time.time()

    logrepeater = open("logs/repeater.txt", "w")

    bit_count = 0

    while bit_count < 1:

        if time.time() - start > timeout:
            return

        host.empty_classical()
        time.sleep(1)

        # Synchronize with Alice and Bob
        host.send_broadcast(str(bit_count))
        wait = True
        messages = []
        while wait:
            messages = host.classical
            if len(messages) == 2:
                wait = False
                host.empty_classical()
                        
        basis = random.randint(0, 1)
        ack_arrived = host.send_classical(alice, basis, await_ack = True)
        if not ack_arrived:
            logrepeater.write("Repeater: Failed to send basis %d to Alice\n"%bit_count)
            print("Repeater: Failed to send basis %d to Alice"%bit_count)
            continue
        ack_arrived = host.send_classical(bob, basis, await_ack = True)
        if not ack_arrived:
            logrepeater.write("Repeater: Failed to send basis %d to Bob\n"%bit_count)
            print("Repeater: Failed to send basis %d to Bob"%bit_count)
            continue

        # Generate two qubits
        q_alice = Qubit(host)
        q_mem_alice = Qubit(host)

        # Entangle the two qubits to create an entangled pair
        q_alice.H()
        q_alice.cnot(q_mem_alice)

        # Send one of the qubits of the entangled state to Alice
        q_alice_id, ack_arrived = host.send_qubit(alice, q_alice, await_ack=True)

        if not ack_arrived:
            # Alice did not receive qubit
            logrepeater.write("Repeater: Alice did not receive EPR %d\n"%bit_count)
            print("Repeater: Alice did not receive EPR %d"%bit_count)
            #q_alice.measure()
            q_mem_alice.measure()
            continue
        else:
            alice_bit = host.get_next_classical(alice, wait=5)
            if alice_bit is not None:
                logrepeater.write("Repeater: Alice received entangled qubit %d and measured %s\n"%(bit_count, str(alice_bit.content)))
                print("Repeater: Alice received entangled qubit %d and measured %s"%(bit_count, str(alice_bit.content)))
            else:
                continue
        
        # Generate two qubits
        q_bob = Qubit(host)
        q_mem_bob = Qubit(host)

        # Entangle the two qubits to create an entangled pair
        q_bob.H()
        q_bob.cnot(q_mem_bob)

        q_bob_id, ack_arrived = host.send_qubit(bob, q_bob, await_ack=True)

        if not ack_arrived:
            # Bob did not receive qubit
            #print("Repeater: Bob did not receive EPR")
            logrepeater.write("Repeater: Bob did not receive EPR %d\n"%bit_count)
            print("Repeater: Bob did not receive EPR %d"%bit_count)
            #q_bob.measure()
            q_mem_bob.measure()
            q_mem_alice.measure()
            continue
        else:
            bob_bit = host.get_next_classical(bob, wait=5)
            if bob_bit is not None:
                logrepeater.write("Repeater: Bob received entangled qubit %d and measured %s\n"%(bit_count, str(bob_bit.content)))
                print("Repeater: Bob received entangled qubit %d and measured %s"%(bit_count, str(bob_bit.content)))
            else:
                continue

        # Both Alice and Bob have successfully made BB84 measurements
        # Perform Bell state measurement on the two qubits present in the memory

        q_mem_alice.cnot(q_mem_bob)
        q_mem_alice.H()
        alice_bit = q_mem_alice.measure()
        bob_bit = q_mem_bob.measure()

        # Send results of measurement to Bob
        ack_arrived = host.send_classical(bob, "%d:%d"%(alice_bit, bob_bit), await_ack = True)

        if not ack_arrived:
            logrepeater.write("Repeater: Bell State Measurement %d void\n"%bit_count)
            print("Repeater: Bell State Measurement %d void"%bit_count)
            q_mem_alice.release()
            q_mem_bob.release()
            continue
        else:
            # Communicate Bob's success to Alice
            ack_arrived = host.send_classical(alice, str(bit_count), await_ack=True)
            if not ack_arrived:
                print("Repeater: Alice did not acknowledge Bob's success for bit %d"%bit_count)
                logrepeater.write("Repeater: Alice did not acknowledge Bob's success for bit %d\n"%bit_count)
                continue

        bit_count += 1

    logrepeater.close()