Exemplo n.º 1
0
def qubit_send_w_retransmission(host, q_size, receiver_id,
                                checksum_size_per_qubit):
    """
    Sends the data qubits along with checksum qubits , with the possibility of retransmission.

    :param host: Sender of qubits
    :param q_size: Number of qubits to be sent
    :param receiver_id: ID of the receiver
    :param checksum_size_per_qubit: Checksum qubit per data qubit size
    :return:
    """
    bit_arr = np.random.randint(2, size=q_size)
    print('Bit array to be sent: ' + str(bit_arr))
    qubits = []
    for i in range(q_size):
        q_tmp = Qubit(host)
        if bit_arr[i] == 1:
            q_tmp.X()
        qubits.append(q_tmp)

    check_qubits = host.add_checksum(qubits, checksum_size_per_qubit)
    checksum_size = int(q_size / checksum_size_per_qubit)
    qubits.append(check_qubits)
    checksum_cnt = 0
    for i in range(q_size + checksum_size):
        if i < q_size:
            q = qubits[i]
        else:
            q = qubits[q_size][checksum_cnt]
            checksum_cnt = checksum_cnt + 1

        q_success = False
        got_ack = False
        number_of_retransmissions = 0

        while not got_ack and number_of_retransmissions < MAX_NUM_OF_TRANSMISSIONS:
            print('Alice prepares qubit')
            err_1 = Qubit(host)
            # encode logical qubit
            q.cnot(err_1)

            _, ack_received = host.send_qubit(receiver_id, q, await_ack=True)
            if ack_received:
                err_1.release()
                got_ack = True
                q_success = True

            if not q_success:
                print('Alice: Bob did not receive the qubit')
                # re-introduce a qubit to the system and correct the error
                q = Qubit(host)
                err_1.cnot(q)

            number_of_retransmissions += 1

        if number_of_retransmissions == 10:
            print("Alice: too many attempts made")
            return False
    return True
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()