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 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
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()