-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrun_bb84_eve_demo.py
More file actions
115 lines (88 loc) · 4.05 KB
/
run_bb84_eve_demo.py
File metadata and controls
115 lines (88 loc) · 4.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import numpy as np
from braket.devices import LocalSimulator
from braket.circuits import noises
from utils.bb84 import initialize_protocol, encode_qubits, measure_qubits, filter_qubits
# -------------------------
# Eve attack demo settings
# -------------------------
NUMBER_OF_QUBITS_PER_ROUND = 12
ROUNDS = 400 # increase for a smoother QBER estimate
BIT_FLIP_PROBABILITY = 0.0 # set to 0.1 to combine channel noise + Eve
SEED = None # set an int for reproducible runs
def run_round(bitflip_p: float, eve_intercept_resend: bool):
"""Run one BB84 exchange round and return (sifted_bits_count, error_bits_count)."""
n = NUMBER_OF_QUBITS_PER_ROUND
# Alice bits/bases; Bob bases
encoding_basis_A, states_A, _ = initialize_protocol(n)
_, _, measurement_basis_B = initialize_protocol(n)
# Alice prepares qubits
alice_circuit = encode_qubits(n, states_A, encoding_basis_A)
# Optional channel noise between Alice->(Eve/Bob)
if bitflip_p and bitflip_p > 0:
noise = noises.BitFlip(probability=bitflip_p)
alice_circuit.apply_gate_noise(noise)
device = LocalSimulator("braket_dm")
else:
device = LocalSimulator("default")
if not eve_intercept_resend:
# Bob measures directly
c = measure_qubits(alice_circuit, measurement_basis_B)
c.measure(list(range(n)))
result = device.run(c, shots=1).result()
measured_bits = np.array(result.measurements[0], dtype=np.uint8)
else:
# Eve chooses random bases, measures, and resends
_, _, eve_basis = initialize_protocol(n)
# Eve measurement
eve_circuit = measure_qubits(alice_circuit, eve_basis)
eve_circuit.measure(list(range(n)))
eve_result = device.run(eve_circuit, shots=1).result()
eve_bits = np.array(eve_result.measurements[0], dtype=np.uint8)
# Eve resends: prepare fresh qubits consistent with her measurement outcome and basis
resend_circuit = encode_qubits(n, eve_bits, eve_basis)
# Optional channel noise between Eve->Bob
if bitflip_p and bitflip_p > 0:
noise = noises.BitFlip(probability=bitflip_p)
resend_circuit.apply_gate_noise(noise)
# Bob measures
c = measure_qubits(resend_circuit, measurement_basis_B)
c.measure(list(range(n)))
bob_result = device.run(c, shots=1).result()
measured_bits = np.array(bob_result.measurements[0], dtype=np.uint8)
# Sifting: keep only positions where Alice and Bob used the same basis
alice_sifted = filter_qubits(states_A, encoding_basis_A, measurement_basis_B)
bob_sifted = filter_qubits(measured_bits, encoding_basis_A, measurement_basis_B)
# Count errors in sifted bits
errors = int(np.sum(alice_sifted != bob_sifted))
return int(alice_sifted.size), errors
def simulate(eve_intercept_resend: bool):
total_sifted = 0
total_errors = 0
for _ in range(ROUNDS):
s, e = run_round(BIT_FLIP_PROBABILITY, eve_intercept_resend)
total_sifted += s
total_errors += e
qber = (total_errors / total_sifted) if total_sifted else 0.0
return total_sifted, total_errors, qber
def main():
if SEED is not None:
np.random.seed(SEED)
print("=== BB84 Eve Demo (Intercept-Resend) ===\n")
print(f"Qubits per round: {NUMBER_OF_QUBITS_PER_ROUND}")
print(f"Rounds: {ROUNDS}")
print(f"Bit-flip p: {BIT_FLIP_PROBABILITY}\n")
s0, e0, q0 = simulate(eve_intercept_resend=False)
print("--- No Eve ---")
print(f"Sifted bits: {s0}")
print(f"Errors: {e0}")
print(f"QBER: {q0:.3f}\n")
s1, e1, q1 = simulate(eve_intercept_resend=True)
print("--- Eve: intercept-resend ---")
print(f"Sifted bits: {s1}")
print(f"Errors: {e1}")
print(f"QBER: {q1:.3f}\n")
if BIT_FLIP_PROBABILITY == 0.0:
print("Reference: In ideal BB84, intercept-resend produces about 25% QBER on the sifted key.")
print("(Your estimate will approach 0.25 as you increase ROUNDS.)")
if __name__ == "__main__":
main()