def test_BB84_time_bin(): tl = Timeline(1e12) # stop time is 1 s alice = QKDNode("alice", tl, encoding=time_bin, stack_size=1) bob = QKDNode("bob", tl, encoding=time_bin, stack_size=1) pair_bb84_protocols(alice.protocol_stack[0], bob.protocol_stack[0]) qc = QuantumChannel("qc", tl, distance=10e3, polarization_fidelity=0.99, attenuation=0.00002) qc.set_ends(alice, bob) cc = ClassicalChannel("cc", tl, distance=10e3) cc.set_ends(alice, bob) # Parent pa = Parent(alice, 128, "alice") pb = Parent(bob, 128, "bob") alice.protocol_stack[0].upper_protocols.append(pa) pa.lower_protocols.append(alice.protocol_stack[0]) bob.protocol_stack[0].upper_protocols.append(pb) pb.lower_protocols.append(bob.protocol_stack[0]) process = Process(pa, "push", []) event = Event(0, process) tl.schedule(event) tl.init() tl.run() assert pa.counter == pb.counter == 10
def test_cascade_run(): KEYSIZE = 512 KEYNUM = 10 tl = Timeline(1e11) alice = QKDNode("alice", tl) bob = QKDNode("bob", tl) pair_bb84_protocols(alice.protocol_stack[0], bob.protocol_stack[0]) pair_cascade_protocols(alice.protocol_stack[1], bob.protocol_stack[1]) qc = QuantumChannel("qc", tl, distance=1e3, attenuation=2e-5, polarization_fidelity=0.97) qc.set_ends(alice, bob) cc = ClassicalChannel("cc", tl, distance=1e3) cc.set_ends(alice, bob) # Parent pa = Parent(alice, KEYSIZE, KEYNUM) pb = Parent(bob, KEYSIZE, KEYNUM) alice.protocol_stack[1].upper_protocols.append(pa) pa.lower_protocols.append(alice.protocol_stack[1]) bob.protocol_stack[1].upper_protocols.append(pb) pb.lower_protocols.append(bob.protocol_stack[1]) process = Process(pa, "push", []) event = Event(0, process) tl.schedule(event) tl.init() tl.run() assert pa.counter == pb.counter == KEYNUM for k1, k2 in zip(pa.keys, pb.keys): assert k1 == k2 assert k1 < 2**KEYSIZE # check that key is not too large assert alice.protocol_stack[1].error_bit_rate == 0
def test_Node_send_qubit(): from sequence.components.photon import Photon from numpy import random random.seed(0) class FakeNode(Node): def __init__(self, name, tl): Node.__init__(self, name, tl) self.log = [] def receive_qubit(self, src, qubit): self.log.append((self.timeline.now(), src, qubit.name)) tl = Timeline() node1 = FakeNode("node1", tl) node2 = FakeNode("node2", tl) qc = QuantumChannel("qc", tl, 2e-4, 2e4) qc.set_ends(node1, node2) tl.init() for i in range(1000): photon = Photon(str(i)) node1.send_qubit("node2", photon) tl.time += 1 for i in range(1000): photon = Photon(str(i)) node2.send_qubit("node1", photon) tl.time += 1 assert len(node1.log) == len(node2.log) == 0 tl.run() expect_rate = 1 - qc.loss assert abs(len(node1.log) / 1000 - expect_rate) < 0.1 assert abs(len(node2.log) / 1000 - expect_rate) < 0.1
def test_light_source(): class Receiver(Node): def __init__(self, name, tl): Node.__init__(self, name, tl) self.log = [] def receive_qubit(self, src: str, qubit) -> None: self.log.append((self.timeline.now(), src, qubit)) tl = Timeline() FREQ, MEAN = 1e8, 0.1 ls = LightSource("ls", tl, frequency=FREQ, mean_photon_num=MEAN) sender = FakeNode("sender", tl, ls) assert sender.lightsource.frequency == FREQ and sender.lightsource.mean_photon_num == MEAN receiver = Receiver("receiver", tl) qc = QuantumChannel("qc", tl, distance=1e5, attenuation=0) qc.set_ends(sender, receiver) state_list = [] STATE_LEN = 1000 for _ in range(STATE_LEN): basis = random.randint(2) bit = random.randint(2) state_list.append(polarization["bases"][basis][bit]) tl.init() ls.emit(state_list, "receiver") tl.run() assert (len(receiver.log) / STATE_LEN) - MEAN < 0.1 for time, src, qubit in receiver.log: index = int(qubit.name) assert state_list[index] == qubit.quantum_state.state assert time == index * (1e12 / FREQ) + qc.delay assert src == "sender"
def test_QuantumRouter_init(): tl = Timeline() node1 = QuantumRouter("node1", tl) for i in range(2, 50): node = QuantumRouter("node%d" % i, tl) mid = BSMNode("mid%d" % i, tl, [node1.name, node.name]) qc = QuantumChannel("qc_l_%d" % i, tl, 0, 1000) qc.set_ends(node1, mid) qc = QuantumChannel("qc_r_%d" % i, tl, 0, 1000) qc.set_ends(node, mid) node1.init() assert len(node1.map_to_middle_node) == 48 for i in range(2, 50): node_name = "node%d" % i assert node1.map_to_middle_node[node_name] == "mid%d" % i
KEYSIZE = 256 KEYNUM = 10 errors = [] # store error rates throughputs = [] # store throughputs # open file to store experiment results # Path("results/timebin").mkdir(parents=True, exist_ok=True) # filename = "results/timebin/distance_cascade.log" # fh = open(filename, 'w') for distance in distances: tl = Timeline(runtime) tl.seed(1) tl.show_progress = True qc = QuantumChannel("qc", tl, distance=distance * 1e3, attenuation=0.0002) cc = ClassicalChannel("cc", tl, distance=distance * 1e3) # Alice ls_params = {"frequency": 2e6, "mean_photon_num": 0.1} alice = QKDNode("alice", tl, encoding=time_bin) for name, param in ls_params.items(): alice.update_lightsource_params(name, param) # Bob detector_params = [{"efficiency": 0.072, "dark_count": dark_count, "time_resolution": 10}, {"efficiency": 0.072, "dark_count": dark_count, "time_resolution": 10}, {"efficiency": 0.072, "dark_count": dark_count, "time_resolution": 10}] bob = QKDNode("bob", tl, encoding=time_bin)
def test_NetworkManager(): tl = Timeline(1e10) n1 = FakeNode("n1", tl, 50) n2 = FakeNode("n2", tl, 50) n3 = FakeNode("n3", tl, 20) m1 = BSMNode("m1", tl, ["n1", "n2"]) m2 = BSMNode("m2", tl, ["n2", "n3"]) cc = ClassicalChannel("cc_n1_n2", tl, 10, delay=1e5) cc.set_ends(n1, n2) cc = ClassicalChannel("cc_n1_m1", tl, 10, delay=1e5) cc.set_ends(n1, m1) cc = ClassicalChannel("cc_n2_m1", tl, 10, delay=1e5) cc.set_ends(n2, m1) cc = ClassicalChannel("cc_n2_n3", tl, 10, delay=1e5) cc.set_ends(n2, n3) cc = ClassicalChannel("cc_n2_m2", tl, 10, delay=1e5) cc.set_ends(n2, m2) cc = ClassicalChannel("cc_n3_m2", tl, 10, delay=1e5) cc.set_ends(n3, m2) qc = QuantumChannel("qc_n1_m1", tl, 0, 10) qc.set_ends(n1, m1) qc = QuantumChannel("qc_n2_m1", tl, 0, 10) qc.set_ends(n2, m1) qc = QuantumChannel("qc_n2_m2", tl, 0, 10) qc.set_ends(n2, m2) qc = QuantumChannel("qc_n3_m2", tl, 0, 10) qc.set_ends(n3, m2) n1.network_manager.protocol_stack[0].add_forwarding_rule("n2", "n2") n1.network_manager.protocol_stack[0].add_forwarding_rule("n3", "n2") n2.network_manager.protocol_stack[0].add_forwarding_rule("n1", "n1") n2.network_manager.protocol_stack[0].add_forwarding_rule("n3", "n3") n3.network_manager.protocol_stack[0].add_forwarding_rule("n1", "n2") n3.network_manager.protocol_stack[0].add_forwarding_rule("n2", "n2") tl.init() # approved request n1.network_manager.request("n3", 1e12, 2e12, 20, 0.9) tl.run() assert len(n1.send_log) == len(n1.receive_log) == 1 assert n1.send_log[0][0] == "n2" and n1.receive_log[0][0] == "n2" assert n1.send_log[0][1].payload.payload.msg_type == RSVPMsgType.REQUEST assert n1.receive_log[0][1].payload.payload.msg_type == RSVPMsgType.APPROVE assert len(n2.send_log) == len(n2.receive_log) == 2 assert n2.send_log[0][0] == "n3" and n2.receive_log[0][0] == "n1" assert n2.send_log[1][0] == "n1" and n2.receive_log[1][0] == "n3" assert len(n3.send_log) == len(n3.receive_log) == 1 assert n3.send_log[0][0] == "n2" and n3.receive_log[0][0] == "n2" n1.reset() n2.reset() n3.reset() # rejected request n1.network_manager.request("n3", 3e12, 4e12, 50, 0.9) tl.run() assert len(n1.send_log) == len(n1.receive_log) == 1 assert n1.send_log[0][0] == "n2" and n1.receive_log[0][0] == "n2" assert n1.send_log[0][1].payload.payload.msg_type == RSVPMsgType.REQUEST assert n1.receive_log[0][1].payload.payload.msg_type == RSVPMsgType.REJECT assert len(n2.send_log) == len(n2.receive_log) == 1 assert n2.send_log[0][0] == "n1" and n2.receive_log[0][0] == "n1" n1.reset() n2.reset() n3.reset() n1.network_manager.request("n3", 5e12, 6e12, 25, 0.9) tl.run() assert len(n1.send_log) == len(n1.receive_log) == 1 assert n1.send_log[0][0] == "n2" and n1.receive_log[0][0] == "n2" assert n1.send_log[0][1].payload.payload.msg_type == RSVPMsgType.REQUEST assert n1.receive_log[0][1].payload.payload.msg_type == RSVPMsgType.REJECT assert len(n2.send_log) == len(n2.receive_log) == 2 assert n2.send_log[0][0] == "n3" and n2.receive_log[0][0] == "n1" assert n2.send_log[1][0] == "n1" and n2.receive_log[1][0] == "n3" assert len(n3.send_log) == len(n3.receive_log) == 1 assert n3.send_log[0][0] == "n2" and n3.receive_log[0][0] == "n2"
pass if __name__ == "__main__": runtime = 1e12 keysize = 256 distances = [1, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100] # distances in km errors = [] # store error rates throughputs = [] # store throughputs for distance in distances: tl = Timeline(runtime) tl.seed(1) qc = QuantumChannel("qc", tl, distance=distance * 1e3, polarization_fidelity=0.97, attenuation=0.0002) cc = ClassicalChannel("cc", tl, distance=distance * 1e3) # Alice ls_params = {"frequency": 80e6, "mean_photon_num": 0.1} alice = QKDNode("alice", tl, encoding=time_bin, stack_size=1) for name, param in ls_params.items(): alice.update_lightsource_params(name, param) # Bob detector_params = [{ "efficiency": 0.8, "dark_count": 1,
# create all-to-all classical connections cc_delay = 1e9 node_list = [r1, r2, r3, m12, m23] for node1 in node_list: for node2 in node_list: cc = ClassicalChannel("cc_%s_%s" % (node1.name, node2.name), tl, 1e3, delay=cc_delay) cc.set_ends(node1, node2) # create quantum channels linking r1 and r2 to m1 qc_atten = 0 qc_dist = 1e3 qc1 = QuantumChannel("qc_r1_m12", tl, qc_atten, qc_dist) qc1.set_ends(r1, m12) qc2 = QuantumChannel("qc_r2_m12", tl, qc_atten, qc_dist) qc2.set_ends(r2, m12) # create quantum channels linking r2 and r3 to m2 qc3 = QuantumChannel("qc_r2_m23", tl, qc_atten, qc_dist) qc3.set_ends(r2, m23) qc4 = QuantumChannel("qc_r3_m23", tl, qc_atten, qc_dist) qc4.set_ends(r3, m23) tl.init() # load rules rule1 = Rule(10, eg_rule_action_f1_1, eg_rule_condition_f1) r1.resource_manager.load(rule1) rule2 = Rule(10, eg_rule_action_f1_2, eg_rule_condition_f1)
KEYSIZE = 256 KEYNUM = 10 errors = [] # store error rates throughputs = [] # store throughputs # open file to store experiment results # Path("results/timebin").mkdir(parents=True, exist_ok=True) # filename = "results/timebin/distance_cascade.log" # fh = open(filename, 'w') for distance in distances: tl = Timeline(runtime) tl.seed(1) tl.show_progress = True qc0 = QuantumChannel("qc0", tl, distance=distance * 1e3, attenuation=0.0002) qc1 = QuantumChannel("qc1", tl, distance=distance * 1e3, attenuation=0.0002) cc0 = ClassicalChannel("cc0", tl, distance=distance * 1e3) cc1 = ClassicalChannel("cc1", tl, distance=distance * 1e3) # Alice ls_params = {"frequency": 2e6, "mean_photon_num": 0.1} alice = QKDNode("alice", tl, encoding=time_bin) for name, param in ls_params.items(): alice.update_lightsource_params(name, param) # Bob detector_params = [{"efficiency": 0.072, "dark_count": dark_count, "time_resolution": 10}, {"efficiency": 0.072, "dark_count": dark_count, "time_resolution": 10}, {"efficiency": 0.072, "dark_count": dark_count, "time_resolution": 10}]
def test_ResourceReservationProtocol_create_rules(): tl = Timeline() routers = [] mids = [] for i in range(5): router = FakeNode("r%d" % i, tl, memo_size=20) routers.append(router) for i in range(4): mid = BSMNode("mid%d" % i, tl, [routers[i].name, routers[i + 1].name]) mids.append(mid) for i in range(4): qc = QuantumChannel("qc_l_%d" % i, tl, 0, 100) qc.set_ends(routers[i], mids[i]) qc = QuantumChannel("qc_r_%d" % i, tl, 0, 100) qc.set_ends(routers[i + 1], mids[i]) for i, n1 in enumerate(routers + mids): for j, n2 in enumerate(routers + mids): if i >= j: continue cc = ClassicalChannel("cc_%s_%s" % (n1.name, n2.name), tl, 10, delay=100000) cc.set_ends(n1, n2) tl.init() path = [r.name for r in routers] reservation = Reservation("r0", "r4", 1, 1000000000, 10, 0.9) for node in [routers[0], routers[-1]]: for i, card in enumerate(node.rsvp.timecards): if i >= 10: break card.add(reservation) rules = node.rsvp.create_rules(path, reservation) assert len(rules) == 3 node.rsvp.load_rules(rules, reservation) for node in routers[1:-1]: for i, card in enumerate(node.rsvp.timecards): card.add(reservation) rules = node.rsvp.create_rules(path, reservation) assert len(rules) == 6 node.rsvp.load_rules(rules, reservation) tl.run() for node in routers: assert len(node.resource_manager.rule_manager) == 0 counter = 0 for memory in routers[0].memory_array: if memory.entangled_memory[ "node_id"] == "r4" and memory.fidelity >= 0.9: counter += 1 assert counter >= 0 for info in routers[0].resource_manager.memory_manager: if info.state == "ENTANGLED" and info.remote_node == "r4" and info.fidelity >= 0.9: counter -= 1 assert counter == 0
self.detector.owner = self def receive_qubit(self, src, qubit): if not qubit.is_null: self.detector.get() if __name__ == "__main__": runtime = 10e12 tl = Timeline(runtime) # nodes and hardware node1 = SenderNode("node1", tl) node2 = ReceiverNode("node2", tl) qc = QuantumChannel("qc", tl, attenuation=0, distance=1e3) qc.set_ends(node1, node2) # counter counter = Counter() node2.detector.attach(counter) # schedule events time_bin = int(1e12 / FREQUENCY) process1 = Process(node1.memory, "update_state", [[complex(math.sqrt(1 / 2)), complex(math.sqrt(1 / 2))]]) process2 = Process(node1.memory, "excite", ["node2"]) for i in range(NUM_TRIALS): event1 = Event(i * time_bin, process1)
def test_Node_assign_qchannel(): tl = Timeline() node = Node("node1", tl) qc = QuantumChannel("qc", tl, 2e-4, 1e3) node.assign_qchannel(qc, "node2") assert "node2" in node.qchannels and node.qchannels["node2"] == qc
def pair_protocol(p1: EntanglementProtocol, p2: EntanglementProtocol): p1.set_others(p2) p2.set_others(p1) tl = Timeline() node1 = EntangleGenNode('node1', tl) node2 = EntangleGenNode('node2', tl) bsm_node = BSMNode('bsm_node', tl, ['node1', 'node2']) bsm_node.bsm.update_detectors_params('efficiency', 1) qc1 = QuantumChannel('qc1', tl, attenuation=0, distance=1000) qc2 = QuantumChannel('qc2', tl, attenuation=0, distance=1000) qc1.set_ends(node1, bsm_node) qc2.set_ends(node2, bsm_node) nodes = [node1, node2, bsm_node] for i in range(3): for j in range(3): cc= ClassicalChannel('cc_%s_%s'%(nodes[i].name, nodes[j].name), tl, 1000, 1e8) cc.set_ends(nodes[i], nodes[j]) for i in range(1000): tl.time = tl.now() + 1e11 node1.create_protocol('bsm_node', 'node2') node2.create_protocol('bsm_node', 'node1')
def test_ResourceManager2(): from sequence.kernel.process import Process from sequence.kernel.event import Event from sequence.components.optical_channel import ClassicalChannel, QuantumChannel from sequence.topology.node import BSMNode from sequence.entanglement_management.generation import EntanglementGenerationA class TestNode(Node): def __init__(self, name, tl): Node.__init__(self, name, tl) self.memory_array = MemoryArray(name + ".MemoryArray", tl, num_memories=50) self.memory_array.owner = self self.resource_manager = ResourceManager(self) def receive_message(self, src: str, msg: "Message") -> None: if msg.receiver == "resource_manager": self.resource_manager.received_message(src, msg) else: if msg.receiver is None: matching = [ p for p in self.protocols if type(p) == msg.protocol_type ] for p in matching: p.received_message(src, msg) else: for protocol in self.protocols: if protocol.name == msg.receiver: protocol.received_message(src, msg) break def get_idle_memory(self, info): pass def eg_rule_condition(memory_info, manager): if memory_info.state == "RAW": return [memory_info] else: return [] def eg_rule_action1(memories_info): def eg_req_func(protocols): for protocol in protocols: if isinstance(protocol, EntanglementGenerationA): return protocol memories = [info.memory for info in memories_info] memory = memories[0] protocol = EntanglementGenerationA(None, "EGA." + memory.name, "mid_node", "node2", memory) protocol.primary = True return [protocol, ["node2"], [eg_req_func]] def eg_rule_action2(memories_info): memories = [info.memory for info in memories_info] memory = memories[0] protocol = EntanglementGenerationA(None, "EGA." + memory.name, "mid_node", "node1", memory) return [protocol, [None], [None]] tl = Timeline() node1, node2 = TestNode("node1", tl), TestNode("node2", tl) mid_node = BSMNode("mid_node", tl, [node1.name, node2.name]) mid_node.bsm.detectors[0].efficiency = 1 mid_node.bsm.detectors[1].efficiency = 1 cc0 = ClassicalChannel("cc_n1_n2", tl, 0, 1e3) cc1 = ClassicalChannel("cc_n2_n1", tl, 0, 1e3) cc2 = ClassicalChannel("cc_n1_m", tl, 0, 1e3) cc3 = ClassicalChannel("cc_m_n1", tl, 0, 1e3) cc4 = ClassicalChannel("cc_n2_m", tl, 0, 1e3) cc5 = ClassicalChannel("cc_m_n2", tl, 0, 1e3) cc0.set_ends(node1, node2) cc1.set_ends(node2, node1) cc2.set_ends(node1, mid_node) cc3.set_ends(mid_node, node1) cc4.set_ends(node2, mid_node) cc5.set_ends(mid_node, node2) qc0 = QuantumChannel("qc_n1_m", tl, 0, 1e3, frequency=8e7) qc1 = QuantumChannel("qc_n2_m", tl, 0, 1e3, frequency=8e7) qc0.set_ends(node1, mid_node) qc1.set_ends(node2, mid_node) tl.init() rule1 = Rule(10, eg_rule_action1, eg_rule_condition) node1.resource_manager.load(rule1) rule2 = Rule(10, eg_rule_action2, eg_rule_condition) node2.resource_manager.load(rule2) process = Process(node1.resource_manager, "expire", [rule1]) event = Event(10, process) tl.schedule(event) process = Process(node2.resource_manager, "expire", [rule2]) event = Event(10, process) tl.schedule(event) tl.run() # for info in node1.resource_manager.memory_manager: # print(info.memory.name, info.state, info.remote_memo) # # for info in node2.resource_manager.memory_manager: # print(info.memory.name, info.state, info.remote_memo) for info in node1.resource_manager.memory_manager: assert info.state == "RAW" for info in node2.resource_manager.memory_manager: assert info.state == "RAW" assert len(node1.protocols) == len(node2.protocols) == 0 assert len(node1.resource_manager.pending_protocols) == len( node2.resource_manager.pending_protocols) == 0 assert len(node1.resource_manager.waiting_protocols) == len( node2.resource_manager.waiting_protocols) == 0
key_error_list = [] latency_list = [] setup_time_list = [] start_time_list = [] bb84_latency_list = [] for id in range(NUM_EXPERIMENTS): distance = max(1000, 10000 * int(id)) tl = Timeline(runtime) tl.seed(2) tl.show_progress = True qc0 = QuantumChannel("qc0", tl, distance=distance, polarization_fidelity=0.97, attenuation=0.0002) qc1 = QuantumChannel("qc1", tl, distance=distance, polarization_fidelity=0.97, attenuation=0.0002) cc0 = ClassicalChannel("cc0", tl, distance=distance) cc1 = ClassicalChannel("cc1", tl, distance=distance) cc0.delay += 10e9 cc1.delay += 10e9 # Alice ls_params = {"frequency": 80e6, "mean_photon_num": 0.1} alice = QKDNode("alice", tl)
def test_ResourceReservationProtocol_set_es_params(): class TestNode(FakeNode): def __init__(self, name, tl): super().__init__(name, tl, memo_size=20) self.counter = 0 def receive_message(self, src: str, msg: "Message") -> None: for protocol in self.resource_manager.pending_protocols: if isinstance(protocol, EntanglementSwappingA): assert protocol.success_prob == 0.8 and protocol.degradation == 0.7 self.counter += 1 super().receive_message(src, msg) tl = Timeline() routers = [] mids = [] for i in range(5): router = TestNode("r%d" % i, tl) router.rsvp.set_swapping_success_rate(0.8) router.rsvp.set_swapping_degradation(0.7) routers.append(router) for i in range(4): mid = BSMNode("mid%d" % i, tl, [routers[i].name, routers[i + 1].name]) mids.append(mid) for i in range(4): qc = QuantumChannel("qc_l_%d" % i, tl, 0, 100) qc.set_ends(routers[i], mids[i]) qc = QuantumChannel("qc_r_%d" % i, tl, 0, 100) qc.set_ends(routers[i + 1], mids[i]) for i, n1 in enumerate(routers + mids): for j, n2 in enumerate(routers + mids): if i >= j: continue cc = ClassicalChannel("cc_%s_%s" % (n1.name, n2.name), tl, 10, delay=100000) cc.set_ends(n1, n2) tl.init() path = [r.name for r in routers] reservation = Reservation("r0", "r4", 1, 9000000, 10, 0.9) for node in [routers[0], routers[-1]]: for i, card in enumerate(node.rsvp.timecards): if i >= 10: break card.add(reservation) rules = node.rsvp.create_rules(path, reservation) assert len(rules) == 3 node.rsvp.load_rules(rules, reservation) for node in routers[1:-1]: for i, card in enumerate(node.rsvp.timecards): card.add(reservation) rules = node.rsvp.create_rules(path, reservation) assert len(rules) == 6 node.rsvp.load_rules(rules, reservation) tl.run() counter = 0 for node in routers: counter += node.counter assert counter > 0