# Quantum Teleportation in ProjectQ

(01/08/2021)

## Protocol

Alice and Bob are best friends, back from their student days, when they had been both immersed in studying classical information theory. Now, as the years have passed, they have found themselves in the middle of pandemic, in their respective self-isolated labs at the different ends of the world -- just when Alice started enjoying quantum theory and its possibilities.

Alice has a qubit Q in the state $|\psi\rangle$ she wants to share with Bob. Unfortunately, she cannot send him the state directly, as the quantum communication channels are severed (thankfully, the classical ones are still intact!). However, she has an advantage: Alice and Bob each have a spare qubit (which we will call A and B, respectively) which are entangled in a Bell state, and thus form a Bell pair:

$|\Phi\rangle_{AB} = \frac{1}{\sqrt{2}}(|00\rangle_{AB}+|11\rangle_{AB})$

Luckily, they have created a Bell pair a while ago, before the pandemic hit their lands, using a simple circuit which applies a Hadamard gate to the first qubit, and then flips the second qubit conditional on the first qubit being in the state $|1\rangle$:

Now, the entanglement Alice and Bob share, can be used to ''teleport'' the state $|\psi\rangle$ to Bob's side. First, Alice entangles the qubit Q with her share of the Bell pair A. Then, she measures both of her qubits: one in the Z-basis (the usual computational basis), and one in Hadamard basis. Alice send her measurement outcomes to Bob via a classical communication channel.

On his side, Bob has to apply operations depending on information he receives from Alice: he applies an X and/or a Z gate:

Voilá -- Bob recovers the state $|\psi\rangle$​ on his side, as Alice wanted!

## Code

We can translate the teleportation protocol to ProjectQ. The complete example is attached to this post -- feel free to click and play around!

First, we have to allocate and create a Bell pair Alice and Bob share:

def create_bell_pair(eng):

b1 = eng.allocate_qubit()
b2 = eng.allocate_qubit()

H | b1
CNOT | (b1, b2)

return b1, b2

b1, b2 = create_bell_pair(eng)


We also need to allocate and initialise (in the state $|0\rangle$ as is the default with ProjectQ) the qubit Q Alice wants to share with Bob:

psi = eng.allocate_qubit()


We entangle it with Alice's share of the Bell pair, measure the two qubits Alice has access to as explained above, and send results to Bob:

​CNOT | (psi,b1)
H | psi
Measure | psi
Measure | b1
msg_to_bob = [int(psi), int(b1)]


Finally, Bob applies operations depending on the message from Alice:

with Control(eng, b1):
X | b2

with Control(eng, psi):
Z | b2

## Challenge

Now Alice can share the state of a single qubit with Bob. What if she wants to share the state of two qubits instead? Think how the protocol should be modified for this case.