The simulation below runs the core loop of E91. Alice and Bob each pick a random measurement basis for every entangled pair. After measuring, they publicly compare which bases they used (not their outcomes). Pairs where they chose compatible bases produce a shared bit; the rest are discarded. A final Bell test on a subset of pairs checks whether correlations are strong enough to rule out eavesdropping.
<!-- E91 demo: controls at top, results panel below -->
<div class="controls">
<label>Rounds: <input type="number" id="nRounds" min="10" max="200" value="60" /></label>
<label class="spy-wrap">
<input type="checkbox" id="spyOn" />
Enable eavesdropper (Eve)
</label>
<button id="btnRun" type="button">Run protocol</button>
</div>
<div id="results" class="results hidden">
<div class="stat-row">
<span class="stat-label">Key bits extracted</span>
<span class="stat-val" id="valKeyBits">—</span>
</div>
<div class="stat-row">
<span class="stat-label">CHSH Bell score |S|</span>
<span class="stat-val" id="valBell">—</span>
</div>
<div class="stat-row">
<span class="stat-label">Channel verdict</span>
<span class="stat-val verdict" id="valVerdict">—</span>
</div>
<div class="key-display" id="keyDisplay"></div>
<div class="bell-bar-wrap">
<div class="bell-bar-bg">
<div class="bell-bar-fill" id="bellBar"></div>
<span class="bell-mark classical" title="Classical upper bound: |S| = 2">2</span>
<span class="bell-mark quantum" title="Quantum (Tsirelson) bound: |S| = 2√2 ≈ 2.83">2√2</span>
</div>
<div class="bell-labels">
<span>0</span><span>classical bound (2)</span><span>quantum max (2√2)</span>
</div>
</div>
</div>
<p class="footnote" id="footNote"></p>
/* E91 demo styles */
* { box-sizing: border-box; }
body { font-family: system-ui, sans-serif; margin: 0; color: #1d2433; font-size: 14px; }
.controls { display: flex; flex-wrap: wrap; gap: .6rem; align-items: center; margin-bottom: .8rem; }
.controls label { display: flex; align-items: center; gap: .3rem; font-size: .88rem; }
.controls input[type=number] { width: 64px; padding: .25rem .4rem; border: 1px solid #adb5c0; border-radius: 6px; font-size: .88rem; }
.spy-wrap { background: #fff3cd; border-radius: 6px; padding: .25rem .55rem; border: 1px solid #e9c46a; }
button { font: 600 13px system-ui; padding: .4rem .85rem; background: #1d3557; color: #fff; border: none; border-radius: 8px; cursor: pointer; }
button:hover { background: #2a4a75; }
.results { margin-top: .4rem; }
.hidden { display: none; }
.stat-row { display: flex; justify-content: space-between; align-items: baseline; border-bottom: 1px solid #e8eef3; padding: .28rem 0; }
.stat-label { color: #4a5568; }
.stat-val { font-weight: 700; }
.verdict.ok { color: #0a7d33; }
.verdict.warn { color: #c92f3c; }
.key-display { font: 600 12px ui-monospace, monospace; background: #e8eef3; border-radius: 6px; padding: .45rem .6rem; margin: .55rem 0; word-break: break-all; color: #1d3557; min-height: 1.8em; letter-spacing: .05em; }
.bell-bar-wrap { margin-top: .55rem; }
.bell-bar-bg { position: relative; height: 22px; background: #dde3eb; border-radius: 6px; overflow: visible; }
.bell-bar-fill { height: 100%; border-radius: 6px; background: #1d3557; transition: width .5s; }
.bell-mark { position: absolute; top: -18px; font-size: .75rem; font-weight: 700; transform: translateX(-50%); }
.bell-mark.classical { left: 50%; color: #c92f3c; }
.bell-mark.quantum { left: 88.4%; color: #0a7d33; }
.bell-labels { display: flex; justify-content: space-between; font-size: .72rem; color: #666; margin-top: 2px; }
.footnote { font-size: .78rem; color: #666; margin: .5rem 0 0; line-height: 1.45; }
// Ekert E91 protocol simulation.
// Alice and Bob each pick a random measurement basis (angle) per round.
// Matching bases -> sifted key bit. Mismatched bases -> CHSH Bell test.
// Measurement angles (radians)
// Alice uses {0, pi/4} and Bob uses {pi/8, 3pi/8}
// Matched pairs (same-index bases) -> key bits; mismatched -> Bell test.
const ALICE_BASES = [0, Math.PI / 4];
const BOB_BASES = [Math.PI / 8, 3 * Math.PI / 8];
// Tsirelson bound
const QUANTUM_MAX = 2 * Math.sqrt(2); // approx 2.828
// Simulate one entangled pair measurement.
// Outcome is +1 or -1. For an entangled singlet pair the joint probability:
// P(a=b | angle diff θ) = sin²(θ), P(a≠b) = cos²(θ)
function measurePair(aliceAngle, bobAngle, evePresent) {
// Singlet state: outcomes anti-correlate with probability cos^2(theta).
const theta = aliceAngle - bobAngle;
const pSame = Math.sin(theta) * Math.sin(theta);
const rnd = Math.random();
let aliceOut, bobOut;
if (evePresent) {
// Eve breaks entanglement; each particle measured independently (random).
aliceOut = Math.random() < 0.5 ? 1 : -1;
bobOut = Math.random() < 0.5 ? 1 : -1;
} else {
aliceOut = Math.random() < 0.5 ? 1 : -1;
bobOut = (rnd < pSame) ? aliceOut : -aliceOut;
}
return { aliceOut, bobOut };
}
// Compute CHSH parameter S from accumulated correlator sums.
// CHSH correlator E(a,b) = <A_a * B_b> summed over angle pairs.
// S = E(a1,b1) - E(a1,b2) + E(a2,b1) + E(a2,b2)
// Classical bound |S| <= 2; quantum: |S| = 2√2.
function computeCHSH(counts) {
function E(ai, bi) {
const key = ai + ',' + bi;
const c = counts[key] || { sum: 0, n: 0 };
return c.n === 0 ? 0 : c.sum / c.n;
}
return E(0, 0) - E(0, 1) + E(1, 0) + E(1, 1);
}
function run() {
const n = Math.max(10, Math.min(200, parseInt(document.getElementById('nRounds').value) || 60));
const eve = document.getElementById('spyOn').checked;
const keyBits = [];
// Accumulate correlators for all four angle-pair combinations.
const counts = {};
for (let ai = 0; ai < 2; ai++) for (let bi = 0; bi < 2; bi++) counts[ai + ',' + bi] = { sum: 0, n: 0 };
for (let i = 0; i < n; i++) {
const ai = Math.floor(Math.random() * 2);
const bi = Math.floor(Math.random() * 2);
const { aliceOut, bobOut } = measurePair(ALICE_BASES[ai], BOB_BASES[bi], eve);
// ALL pairs feed the CHSH Bell test; matched-index pairs also yield key bits.
// ALL pairs contribute to the CHSH Bell test (needed for all 4 correlator terms).
counts[ai + ',' + bi].sum += aliceOut * bobOut;
counts[ai + ',' + bi].n += 1;
// Matched-index pair: convert outcome to key bit. Alice's +1 -> bit 0; -1 -> bit 1
if (ai === bi) {
// Every pair (matched or not) contributes to the CHSH correlator.
keyBits.push(aliceOut === 1 ? 0 : 1);
}
}
const S = Math.abs(computeCHSH(counts));
// Update UI with results.
document.getElementById('valKeyBits').textContent = keyBits.length;
const bellEl = document.getElementById('valBell');
bellEl.textContent = S.toFixed(3);
const verdictEl = document.getElementById('valVerdict');
const secure = S > 2.0;
verdictEl.textContent = secure ? '✓ Secure — Bell violation confirmed' : '✗ Eavesdropper detected — abort!';
verdictEl.className = 'stat-val verdict ' + (secure ? 'ok' : 'warn');
// Show up to 80 key bits.
const keyStr = keyBits.slice(0, 80).join('');
document.getElementById('keyDisplay').textContent = keyStr || '—';
// Scale bar to Tsirelson bound.
const pct = Math.min(100, (S / (QUANTUM_MAX * 1.05)) * 100);
document.getElementById('bellBar').style.width = pct + '%';
document.getElementById('footNote').textContent =
eve ? 'Eve measures every pair, collapsing entanglement. The CHSH score drops toward 2 (or below), revealing the intrusion.' : 'No eavesdropper. Quantum correlations push |S| above 2, confirming the channel is clean.';
document.getElementById('results').classList.remove('hidden');
console.log('E91 run result:', { rounds: n, keyBits: keyBits.length, S: S.toFixed(3), secure });
}
document.getElementById('btnRun').addEventListener('click', run);
// Run once on load.
run();
<!-- E91 demo: controls at top, results panel below -->
<div class="controls">
<label>Rounds: <input type="number" id="nRounds" min="10" max="200" value="60" /></label>
<label class="spy-wrap">
<input type="checkbox" id="spyOn" />
Enable eavesdropper (Eve)
</label>
<button id="btnRun" type="button">Run protocol</button>
</div>
<div id="results" class="results hidden">
<div class="stat-row">
<span class="stat-label">Key bits extracted</span>
<span class="stat-val" id="valKeyBits">—</span>
</div>
<div class="stat-row">
<span class="stat-label">CHSH Bell score |S|</span>
<span class="stat-val" id="valBell">—</span>
</div>
<div class="stat-row">
<span class="stat-label">Channel verdict</span>
<span class="stat-val verdict" id="valVerdict">—</span>
</div>
<div class="key-display" id="keyDisplay"></div>
<div class="bell-bar-wrap">
<div class="bell-bar-bg">
<div class="bell-bar-fill" id="bellBar"></div>
<span class="bell-mark classical" title="Classical upper bound: |S| = 2">2</span>
<span class="bell-mark quantum" title="Quantum (Tsirelson) bound: |S| = 2√2 ≈ 2.83">2√2</span>
</div>
<div class="bell-labels">
<span>0</span><span>classical bound (2)</span><span>quantum max (2√2)</span>
</div>
</div>
</div>
<p class="footnote" id="footNote"></p>
/* E91 demo styles */
* { box-sizing: border-box; }
body { font-family: system-ui, sans-serif; margin: 0; color: #1d2433; font-size: 14px; }
.controls { display: flex; flex-wrap: wrap; gap: .6rem; align-items: center; margin-bottom: .8rem; }
.controls label { display: flex; align-items: center; gap: .3rem; font-size: .88rem; }
.controls input[type=number] { width: 64px; padding: .25rem .4rem; border: 1px solid #adb5c0; border-radius: 6px; font-size: .88rem; }
.spy-wrap { background: #fff3cd; border-radius: 6px; padding: .25rem .55rem; border: 1px solid #e9c46a; }
button { font: 600 13px system-ui; padding: .4rem .85rem; background: #1d3557; color: #fff; border: none; border-radius: 8px; cursor: pointer; }
button:hover { background: #2a4a75; }
.results { margin-top: .4rem; }
.hidden { display: none; }
.stat-row { display: flex; justify-content: space-between; align-items: baseline; border-bottom: 1px solid #e8eef3; padding: .28rem 0; }
.stat-label { color: #4a5568; }
.stat-val { font-weight: 700; }
.verdict.ok { color: #0a7d33; }
.verdict.warn { color: #c92f3c; }
.key-display { font: 600 12px ui-monospace, monospace; background: #e8eef3; border-radius: 6px; padding: .45rem .6rem; margin: .55rem 0; word-break: break-all; color: #1d3557; min-height: 1.8em; letter-spacing: .05em; }
.bell-bar-wrap { margin-top: .55rem; }
.bell-bar-bg { position: relative; height: 22px; background: #dde3eb; border-radius: 6px; overflow: visible; }
.bell-bar-fill { height: 100%; border-radius: 6px; background: #1d3557; transition: width .5s; }
.bell-mark { position: absolute; top: -18px; font-size: .75rem; font-weight: 700; transform: translateX(-50%); }
.bell-mark.classical { left: 50%; color: #c92f3c; }
.bell-mark.quantum { left: 88.4%; color: #0a7d33; }
.bell-labels { display: flex; justify-content: space-between; font-size: .72rem; color: #666; margin-top: 2px; }
.footnote { font-size: .78rem; color: #666; margin: .5rem 0 0; line-height: 1.45; }
// Ekert E91 protocol simulation.
// Alice and Bob each pick a random measurement basis (angle) per round.
// Matching bases -> sifted key bit. Mismatched bases -> CHSH Bell test.
// Measurement angles (radians)
// Alice uses {0, pi/4} and Bob uses {pi/8, 3pi/8}
// Matched pairs (same-index bases) -> key bits; mismatched -> Bell test.
const ALICE_BASES = [0, Math.PI / 4];
const BOB_BASES = [Math.PI / 8, 3 * Math.PI / 8];
// Tsirelson bound
const QUANTUM_MAX = 2 * Math.sqrt(2); // approx 2.828
// Simulate one entangled pair measurement.
// Outcome is +1 or -1. For an entangled singlet pair the joint probability:
// P(a=b | angle diff θ) = sin²(θ), P(a≠b) = cos²(θ)
function measurePair(aliceAngle, bobAngle, evePresent) {
// Singlet state: outcomes anti-correlate with probability cos^2(theta).
const theta = aliceAngle - bobAngle;
const pSame = Math.sin(theta) * Math.sin(theta);
const rnd = Math.random();
let aliceOut, bobOut;
if (evePresent) {
// Eve breaks entanglement; each particle measured independently (random).
aliceOut = Math.random() < 0.5 ? 1 : -1;
bobOut = Math.random() < 0.5 ? 1 : -1;
} else {
aliceOut = Math.random() < 0.5 ? 1 : -1;
bobOut = (rnd < pSame) ? aliceOut : -aliceOut;
}
return { aliceOut, bobOut };
}
// Compute CHSH parameter S from accumulated correlator sums.
// CHSH correlator E(a,b) = <A_a * B_b> summed over angle pairs.
// S = E(a1,b1) - E(a1,b2) + E(a2,b1) + E(a2,b2)
// Classical bound |S| <= 2; quantum: |S| = 2√2.
function computeCHSH(counts) {
function E(ai, bi) {
const key = ai + ',' + bi;
const c = counts[key] || { sum: 0, n: 0 };
return c.n === 0 ? 0 : c.sum / c.n;
}
return E(0, 0) - E(0, 1) + E(1, 0) + E(1, 1);
}
function run() {
const n = Math.max(10, Math.min(200, parseInt(document.getElementById('nRounds').value) || 60));
const eve = document.getElementById('spyOn').checked;
const keyBits = [];
// Accumulate correlators for all four angle-pair combinations.
const counts = {};
for (let ai = 0; ai < 2; ai++) for (let bi = 0; bi < 2; bi++) counts[ai + ',' + bi] = { sum: 0, n: 0 };
for (let i = 0; i < n; i++) {
const ai = Math.floor(Math.random() * 2);
const bi = Math.floor(Math.random() * 2);
const { aliceOut, bobOut } = measurePair(ALICE_BASES[ai], BOB_BASES[bi], eve);
// ALL pairs feed the CHSH Bell test; matched-index pairs also yield key bits.
// ALL pairs contribute to the CHSH Bell test (needed for all 4 correlator terms).
counts[ai + ',' + bi].sum += aliceOut * bobOut;
counts[ai + ',' + bi].n += 1;
// Matched-index pair: convert outcome to key bit. Alice's +1 -> bit 0; -1 -> bit 1
if (ai === bi) {
// Every pair (matched or not) contributes to the CHSH correlator.
keyBits.push(aliceOut === 1 ? 0 : 1);
}
}
const S = Math.abs(computeCHSH(counts));
// Update UI with results.
document.getElementById('valKeyBits').textContent = keyBits.length;
const bellEl = document.getElementById('valBell');
bellEl.textContent = S.toFixed(3);
const verdictEl = document.getElementById('valVerdict');
const secure = S > 2.0;
verdictEl.textContent = secure ? '✓ Secure — Bell violation confirmed' : '✗ Eavesdropper detected — abort!';
verdictEl.className = 'stat-val verdict ' + (secure ? 'ok' : 'warn');
// Show up to 80 key bits.
const keyStr = keyBits.slice(0, 80).join('');
document.getElementById('keyDisplay').textContent = keyStr || '—';
// Scale bar to Tsirelson bound.
const pct = Math.min(100, (S / (QUANTUM_MAX * 1.05)) * 100);
document.getElementById('bellBar').style.width = pct + '%';
document.getElementById('footNote').textContent =
eve ? 'Eve measures every pair, collapsing entanglement. The CHSH score drops toward 2 (or below), revealing the intrusion.' : 'No eavesdropper. Quantum correlations push |S| above 2, confirming the channel is clean.';
document.getElementById('results').classList.remove('hidden');
console.log('E91 run result:', { rounds: n, keyBits: keyBits.length, S: S.toFixed(3), secure });
}
document.getElementById('btnRun').addEventListener('click', run);
// Run once on load.
run();
Notice: the key bits come only from the rounds where both parties' bases matched. The Bell-test rounds use the mismatched pairs — not to extract key bits but to detect any spy. If you enable the eavesdropper, the Bell score drops below the classical bound and the protocol aborts.
For a purely classical channel the same trick is impossible: there is no classical correlation that simultaneously yields shared random bits and violates Bell inequalities. The security is a direct consequence of quantum physics, not computational complexity.
Comments
Loading comments...