from dataclasses import dataclass, field import typing from random import choice, uniform @dataclass class EveBS: hijack_probability: float = 0.45 my_bases: typing.List[bool] = field(default_factory=list) obtained_data: typing.List[typing.Optional[bool]] = field(default_factory=list) def process_photons(self, photons: typing.List[typing.Tuple[bool, bool]]) -> typing.List[typing.Tuple[bool, bool]]: basis = choice([False, True]) self.my_bases.append(basis) clicks = [0, 0] passed = [] for photon in photons: if uniform(0, 1) <= self.hijack_probability: photon_bit, photon_basis = photon if photon_basis == basis: clicks[photon_bit] += 1 else: clicks[choice([0, 1])] += 1 else: passed.append(photon) if any(clicks) and not all(clicks): self.obtained_data.append(bool(clicks[1])) else: self.obtained_data.append(None) return passed @dataclass class EvePNS: k: int = 1 my_bases: typing.List[bool] = field(default_factory=list) obtained_data: typing.List[typing.Optional[bool]] = field(default_factory=list) def process_photons(self, photons: typing.List[typing.Tuple[bool, bool]]) -> typing.List[typing.Tuple[bool, bool]]: basis = choice([False, True]) self.my_bases.append(basis) clicks = [0, 0] passed = [] captured = 0 for photon in photons: if captured < self.k: captured += 1 photon_bit, photon_basis = photon if photon_basis == basis: clicks[photon_bit] += 1 else: clicks[choice([0, 1])] += 1 else: passed.append(photon) if any(clicks) and not all(clicks): self.obtained_data.append(bool(clicks[1])) else: self.obtained_data.append(None) return passed