Skip to content

Note

Click here to download the full example code

Superdense Coding

In classical communication, sending two bits of information requires transmitting two physical bits. But with the help of quantum entanglement, we can bend this rule.

Superdense coding proposed by Bennet and Wiesner in 1992 1 lets Alice send two classical bits to Bob by transmitting just one qubit. The catch here is that they must share an entangled pair of qubits beforehand. We will explain this protocol in detail below:

Superdense coding protocol

1. Before any communication begins, a third party prepares two qubits in Bell state:

\[ \ket{\psi} = \frac{\ket{00} + \ket{11}}{\sqrt{2}} \]

Alice takes the first qubit, Bob takes the second, and they both separate. This entangled pair is responsible for linking the qubits non-locally, allowing Alice's local operations to affect the global state.

import numpy as np

from toqito.matrices import cnot, hadamard, pauli
from toqito.states import bell

np.set_printoptions(precision=8, suppress=True)

bell_state = bell(0)
print(f"Initial Bell state (|Φ⁺⟩): \n {bell_state}")

Out:

Initial Bell state (|Φ⁺⟩): 
 [[0.70710678]
 [0.        ]
 [0.        ]
 [0.70710678]]

2. Alice holds two classical bits (\(a\) and \(b\)) that she wants to send. For the tutorial, she is choosing to send \(11\). Depending on the values of her classical bits, she applies one of the four Pauli Gates to her qubit for encoding:

\(a\) \(b\) message Gate applied Final output (Bell state)
\(0\) \(0\) \(\ket{00}\) \(I\) \(\frac{\ket{00} + \ket{11}}{\sqrt{2}}\)
\(0\) \(1\) \(\ket{01}\) \(X\) \(\frac{\ket{10} + \ket{01}}{\sqrt{2}}\)
\(1\) \(0\) \(\ket{10}\) \(Z\) \(\frac{\ket{00} - \ket{11}}{\sqrt{2}}\)
\(1\) \(1\) \(\ket{11}\) \(XZ = iY\) \(\frac{\ket{10} - \ket{01}}{\sqrt{2}}\)
pauli_gate_operations = {
    # Identity gate.
    "00": pauli("I"),
    # Pauli-X gate.
    "01": pauli("X"),
    # Pauli-Z gate.
    "10": pauli("Z"),
    # X followed by Z (equivalent to iY).
    "11": 1j * pauli("Y"),
}

message_to_encode = "11"

# Alice sends her encoded entangled state after this step.
entangled_state_encoded = np.kron(pauli_gate_operations[message_to_encode], pauli("I")) @ bell_state
print(f"Entangled state is: {entangled_state_encoded}")

Out:

Entangled state is: [[ 0.        +0.j]
 [ 0.70710678+0.j]
 [-0.70710678+0.j]
 [ 0.        +0.j]]

3. Bob performs operations to reverse the entanglement on encoded state sent by Alice and extract the bits. First, he applies a Controlled-NOT or \(CX\) (CNOT) Gate with the qubit received from Alice as the control qubit and Bob's original qubit as the target qubit. After this, Bob moves ahead and applies a Hadamard or \(H\) gate to Alice's qubit.

state_after_cnot = cnot() @ entangled_state_encoded
decoded_state = np.kron(hadamard(1), pauli("I")) @ state_after_cnot
print(f"Decoded state:\n {decoded_state}")

Out:

Decoded state:
 [[0.+0.j]
 [0.+0.j]
 [0.+0.j]
 [1.+0.j]]

4. Finally, Bob measures both qubits in the computational basis (\(\ket{0}, \ket{1}\)). The result is guaranteed to be \(11\); the two bits that Alice sent.

measurement_probabilities = np.abs(decoded_state.flatten()) ** 2
print(f"Measurement probabilities for basis states |00>, |01>, |10>, |11>: \n {measurement_probabilities}")
# mkdocs_gallery_thumbnail_path = 'figures/logo.png'

Out:

Measurement probabilities for basis states |00>, |01>, |10>, |11>: 
 [0. 0. 0. 1.]

Total running time of the script: ( 0 minutes 3.983 seconds)

Download Python source code: superdense_coding.py

Download Jupyter notebook: superdense_coding.ipynb

Gallery generated by mkdocs-gallery


  1. Charles H. Bennett and Stephen J. Wiesner. Communication via one- and two-particle operators on Einstein-P odolsky-Rosen states. Phys. Rev. Lett., 69:2881–2884, Nov 1992. URL: https://link.aps.org/doi/10.1103/PhysRevLett.69.2881, doi:10.1103/PhysRevLett.69.2881