from qiskit import *
from qiskit.compiler import transpile, assemble
from qiskit.tools.jupyter import *
from qiskit.visualization import *
import matplotlib.pyplot as plotter
import numpy as np
from IPython.display import display, Math, Latex
import math as m
%matplotlib inline
from qiskit import *
from qiskit.visualization import plot_histogram
%config InlineBackend.figure_format = 'svg'
qc_ab = QuantumCircuit(6,6) #Create a quantum circuit with 6 qubits and 6 classical bits
##ENCODE BIT STRING
#The random bit sequence Alice needs to encode is: 100100, so the first and fourth qubits are flipped from |0> -> |1>
qc_ab.x(0) #The first qubit is indexed at 0, following Python being zero-indexed. From now on it'll be referred to as qubit 0 and so on.
qc_ab.x(3)
qc_ab.barrier()
##ALICE CHOOSES
#Alice randomly chooses to apply an X or an H.
#Note that since the state is already either a |0> or |1>, a Z essentially leaves the qubit state unchanged. But let's write it anyway, shall we?
qc_ab.h(0) # or qc.z(0) # switch these based on your own choice
qc_ab.z(1) # or qc.h(1)
qc_ab.z(2) # or qc.h(2)
qc_ab.h(3) # or qc.z(3)
qc_ab.z(4) # or qc.h(4)
qc_ab.h(5) # or qc.z(5)
qc_ab.barrier()
##BOB CHOOSES
#Alice sends the qubit sequence to Bob, and Bob randomly chooses measurements
qc_ab.h(0) # or qc.z(0) # switch these based on your own choice
qc_ab.z(1) # or qc.h(1)
qc_ab.h(2) # or qc.z(2)
qc_ab.h(3) # or qc.z(3)
qc_ab.z(4) # or qc.h(4)
qc_ab.z(5) # or qc.h(5)
qc_ab.barrier()
##PUBLICIZE CHOICES
#Alice and Bob publicize their choices and only retain those for which their choices match. In this case: qubits 0,1,3,4.
#Note: technically Bob performs the measurement BEFORE publicizing, but we're combining the two here since no one is actually communicating.
qc_ab.measure(0,0)
qc_ab.measure(1,1)
qc_ab.measure(3,3)
qc_ab.measure(4,4)
#qc_ab.measure(2,2) #come back to uncomment these to see what happens to the results after you've run this once
#qc_ab.measure(5,5)
qc_ab.draw(output='mpl') #let's see what this circuit looks like!
##EXECUTE
result = execute(qc_ab, Aer.get_backend('qasm_simulator')).result().get_counts() #We're only making use of the simulator. Refer to [2] to see how you can run this on a real quantum computer.
plot_histogram(result)
#Same situation but now with an eavesdropper (Eve)
qc_aeb = QuantumCircuit(6,6) #Create a quantum circuit with 6 qubits and 6 classical bits
##ENCODE BIT STRING
qc_aeb.x(0)
qc_aeb.x(3)
qc_aeb.barrier()
##ALICE CHOOSES
qc_aeb.h(0)
qc_aeb.z(1)
qc_aeb.z(2)
qc_aeb.h(3)
qc_aeb.z(4)
qc_aeb.h(5)
qc_aeb.barrier()
##EVE CHOOSES
qc_aeb.h(0) #play around with these to see how many states with non-zero probabilities show up at the end for a fixed set of Alice's and Bob's choices
qc_aeb.z(1)
qc_aeb.h(2)
qc_aeb.h(3)
qc_aeb.z(4)
qc_aeb.z(5)
qc_aeb.barrier()
##BOB CHOOSES
qc_aeb.h(0)
qc_aeb.z(1)
qc_aeb.h(2)
qc_aeb.h(3)
qc_aeb.z(4)
qc_aeb.z(5)
qc_aeb.barrier()
##PUBLICIZE CHOICES
qc_aeb.measure(0,0)
qc_aeb.measure(1,1)
qc_aeb.measure(3,3)
qc_aeb.measure(4,4)
#qc_aeb.measure(2,2) #come back to uncomment these to see what happens to the results after you've run this once
#qc_aeb.measure(5,5)
qc_aeb.draw(output='mpl') #let's see what this circuit looks like!
##EXECUTE
result = execute(qc_aeb, Aer.get_backend('qasm_simulator')).result().get_counts()
plot_histogram(result)
|