Implementing The Eckert Protocol Simulation

Learning Lab
My Journey Through Books, Discoveries, and Ideas

Implementing the Eckert protocol simulation

In the previous post here, I described the quantum mechanical elements for simulating the Ekert protocol: entangled pairs and local measurements. Now, I detail how these are used within the full protocol simulation, covering the measurement sequence, eavesdropping detection via the CHSH inequality, and key reconciliation.

The E91Protocol class manages the simulation. A source generates KEY_LENGTH entangled pairs (E91QubitPair instances), distributing one qubit from each pair to Alice and the other to Bob. For each pair i, Alice randomly selects a measurement angle \theta_{A,i} from her configured set (BASIS_A, e.g., \{0^\circ, 22.5^\circ, 45^\circ\}), and Bob independently selects \theta_{B,i} from his set (BASIS_B, e.g., \{0^\circ, 22.5^\circ, 67.5^\circ\}).


# In E91Protocol.generateKey:
L = self._cfg.KEY_LENGTH
# Alice's and Bob's randomly chosen angle sequences
self._anglesA = np.random.choice(self._cfg.BASIS_A, L)
self._anglesB = np.random.choice(self._cfg.BASIS_B, L)
# Create the entangled pairs
self._pairs = [E91QubitPair() for _ in range(L)]

Alice then measures her qubit using \theta_{A,i}, yielding outcome a_i. Bob measures his using \theta_{B,i}, yielding b_i. This sequential measurement process is handled by the localMeasure function, which accounts for state collapse after Alice’s measurement influences Bob’s subsequent measurement.

Simulating eavesdropping

When eavesdropping is simulated, Eve intercepts Bob’s qubit after Alice has measured hers but before Bob does. Alice’s measurement collapses the state. Eve measures the qubit intended for Bob using an angle \theta_{E,i} chosen from her set (BASIS_E, e.g., {0°, 22.5°, 45°, 67.5°}), obtaining outcome e_i. This action irretrievably destroys the quantum correlations between Alice and the qubit Bob eventually receives. Eve sends Bob a new qubit prepared according to her result e_i. Bob measures this fake qubit with his angle \theta_{B,i}. His results will now be correlated with Eve’s actions, not Alice’s original qubit, in a way detectable by the CHSH test.


# In E91Protocol.sendKey (simplified eavesdropping case):
if eavesdropping:
    thetaE = np.random.choice(self._cfg.BASIS_E) # Eve chooses basis
    # Alice measures her qubit; gets result a_result, Bob qubit state changes
    a_result, b_state_after_A_measure = localMeasure(state, thetaA, 'A')
    # Eve intercepts b_state and measures it
    e_result, _ = localMeasure(b_state_after_A_measure, thetaE, 'B') # Eve acts on B side
    # Bob receives a qubit based on Eve result (e_result).
    self._resultsA.append(a_result)
    self._resultsE.append(e_result) # Store Eve result
    self._resultsB.append(e_result) # Bob gets compromised result
else:
    # No Eve: Standard sequence
    a_result, b_state_after_A_measure = localMeasure(state, thetaA, 'A')
    b_result, _ = localMeasure(tensor(ket0(), b_state_after_A_measure), thetaB, 'B')
    self._resultsA.append(a_result)
    self._resultsB.append(b_result)

Reconciliation and security check via CHSH

After all measurements, Alice and Bob communicate classically. They publicly announce the angles (\theta_{A,i}, \theta_{B,i}) used for each measurement i.

The process then diverges based on the angle pairs. Measurements where both Alice and Bob used the 0^\circ basis (as specified by KEY_BASIS in the configuration concept) are singled out for potential key generation. Alice collects her measurement outcomes (a_i) from these specific instances to form the raw key bits.


# In E91Protocol.reconcileKey:
key_indices = [i for i in range(len(self._anglesA))
               if self._anglesA[i] == 0 and self._anglesB[i] == 0]
bitsA_key = np.array([self._resultsA[i] for i in key_indices])

The security validation uses data from different measurement settings, specifically those angle combinations designated for the CHSH test (e.g., Alice uses angles from CHSH_A (\{22.5^\circ, 45^\circ\}) and Bob from CHSH_B (\{22.5^\circ, 67.5^\circ\}). They calculate the correlation coefficient E(a, b) for each required pair of angles (a, b) using the recorded measurement outcomes.

E(a, b) = \mathcal P(+,+|a,b) + \mathcal P(-,-|a,b) - \mathcal P(+,-|a,b) - \mathcal P(-,+|a,b)

This is estimated in the simulation by averaging the product of Alice’s and Bob’s outcomes (mapped to \{+1, -1\}) for all instances where angles a and b were used.


    def _expectation(self, a_deg, b_deg):
        # Calculate E(a, b) from stored results
        vals = []
        for angleA, angleB, rA, rB in zip(self._anglesA, self._anglesB,
                                          self._resultsA, self._resultsB):
            if angleA == a_deg and angleB == b_deg:
                # Map outcomes {0, 1} to {+1, -1}
                A = 1 if rA == 0 else -1
                B = 1 if rB == 0 else -1
                vals.append(A * B)
        # Return mean if data exists, else 0
        return np.mean(vals) if vals else 0.0

They compute the CHSH parameter S using the four required expectation values corresponding to the angles (a_0, a_1) from CHSH_A and (b_0, b_1) from CHSH_B.

S = |E(a_0, b_0) - E(a_0, b_1) + E(a_1, b_0) + E(a_1, b_1)|


# In E91Protocol.reconcileKey (continued):
a0, a1 = self._cfg.CHSH_A
b0, b1 = self._cfg.CHSH_B
E00 = self._expectation(a0, b0)
E01 = self._expectation(a0, b1)
E10 = self._expectation(a1, b0)
E11 = self._expectation(a1, b1)
chsh = abs(E00 - E01 + E10 + E11)

The security decision relies solely on this value. If S > 2, it violates the Bell-CHSH inequality, which cannot be achieved by classical systems or by Eve performing intercept-resend attacks without altering the statistics in a detectable way. This violation confirms the presence of strong quantum correlations and implies the communication channel was secure during the transmission of the qubits used for the CHSH test angles.

By extension, the key bits derived from the 0^\circ/0^\circ basis measurements are also considered secure under the assumption that Eve’s interaction would affect all pairs similarly. If S \le 2, the correlations are compatible with classical physics or eavesdropping, and the protocol is aborted.


# In E91Protocol.reconcileKey (continued):
# Security check: CHSH violation is the only criterion
self._isKeyCompromised = chsh <= 2

if self._isKeyCompromised:
    self._key = None # Abort, key is insecure
    self._isKeyValid = False
else:
    # Secure: pack the key bits generated from 0/0 basis
    key_array = np.array(bitsA_key, dtype=np.uint8)
    self._key = np.packbits(key_array).tobytes()
    self._isKeyValid = True

# Return True if the key is valid (not compromised)
return not self._isKeyCompromised

Key generation

If the CHSH test confirms security (S > 2), the raw key bits extracted from the 0^\circ/0^\circ measurements (bitsA_key) are packed into a byte string, forming the final shared secret key.

Testing

I include unit tests to verify the simulation’s behavior under different conditions:

  • a valid key is successfully generated, and the CHSH value exceeds 2,
  • the presence of Eve leads to CHSH value \le 2, causing the protocol to correctly identify the key as compromised and abort generation,
  • if a valid key is generated, it can be successfully used for encrypting and decrypting messages using the base class methods.

This completes the simulation of the Ekert protocol, demonstrating how entanglement and the violation of Bell inequalities can be used not only to share a key but also to simultaneously verify its security.

For access to the complete simulation code, please visit the GitHub repository here.