55int main(
int argc,
char** argv) {
56 std::cout <<
"[DEMO] Repeater-centric entanglement swap starting\n";
58 RngSeedManager::SetSeed(1);
59 RngSeedManager::SetRun(1);
62 cmd.Parse(argc, argv);
65 Trace(
"Repeater-Centric Entanglement Swap");
67 Time::SetResolution(Time::NS);
85 const Time kSingleGate = NanoSeconds(100);
86 const Time kTwoQGate = NanoSeconds(300);
87 const Time kQDelay = NanoSeconds(10);
88 const Time kClassical = kQDelay;
95 chS1A->SetAttribute(
"Delay", TimeValue(kQDelay));
96 chS1R->SetAttribute(
"Delay", TimeValue(kQDelay));
97 chS2R->SetAttribute(
"Delay", TimeValue(kQDelay));
98 chS2B->SetAttribute(
"Delay", TimeValue(kQDelay));
106 InternetStackHelper internet;
107 internet.Install(alice);
108 internet.Install(repeater);
109 internet.Install(bob);
111 PointToPointHelper p2p;
112 p2p.SetDeviceAttribute(
"DataRate", StringValue(
"100Mbps"));
113 p2p.SetChannelAttribute(
"Delay", StringValue(
"10ns"));
115 Ipv4AddressHelper ipv4;
116 ipv4.SetBase(
"10.1.1.0",
"255.255.255.0");
117 auto ifsAR = ipv4.Assign(p2p.Install(alice, repeater));
118 ipv4.SetBase(
"10.1.2.0",
"255.255.255.0");
119 auto ifsRB = ipv4.Assign(p2p.Install(repeater, bob));
120 Ipv4GlobalRoutingHelper::PopulateRoutingTables();
122 const Ipv4Address kRepeaterAddr = ifsAR.GetAddress(1);
123 const Ipv4Address kBobAddr = ifsRB.GetAddress(1);
130 auto repeaterAckRx = Socket::CreateSocket(repeater, UdpSocketFactory::GetTypeId());
131 repeaterAckRx->Bind(InetSocketAddress(Ipv4Address::GetAny(),
kAckPort));
133 auto aliceTx = Socket::CreateSocket(alice, UdpSocketFactory::GetTypeId());
134 aliceTx->Connect(InetSocketAddress(kRepeaterAddr,
kAckPort));
136 auto bobAckTx = Socket::CreateSocket(bob, UdpSocketFactory::GetTypeId());
137 bobAckTx->Connect(InetSocketAddress(kRepeaterAddr,
kAckPort));
139 auto repeaterTx = Socket::CreateSocket(repeater, UdpSocketFactory::GetTypeId());
140 repeaterTx->Connect(InetSocketAddress(kBobAddr,
kCtrlPort));
142 auto bobCtrlRx = Socket::CreateSocket(bob, UdpSocketFactory::GetTypeId());
143 bobCtrlRx->Bind(InetSocketAddress(Ipv4Address::GetAny(),
kCtrlPort));
146 int acksReceived = 0;
147 bool bsmDone =
false;
150 std::shared_ptr<Qubit> repMem1;
151 std::shared_ptr<Qubit> repMem2;
152 int repQubitsRxd = 0;
155 repeater->SetRecvCallback([&](std::shared_ptr<Qubit> q) {
157 if (repQubitsRxd == 1) {
160 std::cout <<
"[REPEATER][quantum] " << q->GetLabel() <<
" arrived (1/2)\n";
164 std::cout <<
"[REPEATER][quantum] " << q->GetLabel() <<
" arrived (2/2)\n";
169 std::shared_ptr<Qubit> qFlyB;
170 bool qubitArrived =
false;
171 bool bitsArrived =
false;
177 auto tryBobCorrections = [&]() {
178 if (!bobCtx.qubitArrived || !bobCtx.bitsArrived)
180 Trace(
"Bob applies Pauli corrections X^m2=", bobCtx.m2,
" Z^m1=", bobCtx.m1);
182 bob->Apply(
gates::X(), {bobCtx.qFlyB});
188 bob->Apply(
gates::Z(), {bobCtx.qFlyB});
195 Trace(
"End-to-end entanglement established between Alice and Bob");
196 std::cout <<
"[DONE] End-to-end entanglement established\n";
201 alice->SetRecvCallback([&](std::shared_ptr<Qubit> q) {
203 std::cout <<
"[ALICE][quantum] " << q->GetLabel() <<
" arrived at t="
204 << Simulator::Now().GetNanoSeconds() <<
" ns\n";
205 aliceTx->Send(Create<Packet>(1));
206 const auto tNow = Simulator::Now();
207 TraceSendPacket(
"Alice",
"Repeater", tNow, tNow + kClassical,
"ACK: fly_a received",
"udp");
211 bob->SetRecvCallback([&](std::shared_ptr<Qubit> q) {
213 bobCtx.qubitArrived =
true;
215 std::cout <<
"[BOB][quantum] " << q->GetLabel() <<
" arrived at t="
216 << Simulator::Now().GetNanoSeconds() <<
" ns\n";
217 bobAckTx->Send(Create<Packet>(1));
218 const auto tNow = Simulator::Now();
219 TraceSendPacket(
"Bob",
"Repeater", tNow, tNow + kClassical,
"ACK: fly_b received",
"udp");
224 bobCtrlRx->SetRecvCallback([&](Ptr<Socket> sock) {
226 while (Ptr<Packet> p = sock->RecvFrom(from)) {
227 uint8_t bits[2] = {0, 0};
228 p->CopyData(bits, 2);
229 bobCtx.m1 = bits[0] & 1;
230 bobCtx.m2 = bits[1] & 1;
231 bobCtx.bitsArrived =
true;
232 Trace(
"Bob receives corrections m1=", bobCtx.m1,
" m2=", bobCtx.m2);
234 std::cout <<
"[BOB][CTRL] corrections m1=" << bobCtx.m1 <<
" m2=" << bobCtx.m2 <<
"\n";
240 repeaterAckRx->SetRecvCallback([&](Ptr<Socket> sock) {
242 while (sock->RecvFrom(from)) {
245 std::cout <<
"[REPEATER] ACK " << acksReceived <<
"/2 received\n";
247 if (acksReceived == 2 && !bsmDone) {
250 if (!repMem1 || !repMem2) {
251 std::cerr <<
"[REPEATER] ERROR: memory qubits not ready for BSM!\n";
255 Trace(
"Repeater performs BSM on rep_a and rep_b");
257 auto [
m1,
m2] = repeater->MeasureBell(repMem1, repMem2);
258 std::cout <<
"[REPEATER][BSM] m1=" <<
m1 <<
" m2=" <<
m2 <<
"\n";
266 const auto tNow = Simulator::Now();
267 uint8_t bits[2] = {(uint8_t)(
m1 & 1), (uint8_t)(
m2 & 1)};
268 repeaterTx->Send(Create<Packet>(bits, 2));
272 TraceSendCbit(
"m1",
"Repeater",
"Bob", tNow, tNow + kClassical);
273 TraceSendCbit(
"m2",
"Repeater",
"Bob", tNow, tNow + kClassical);
275 StrCat(
"BSM corrections: m1=",
m1,
" m2=",
m2),
"udp");
282 Simulator::Schedule(MicroSeconds(1), [&]() {
283 Trace(
"Phase 1: Src1 and Src2 generate Bell pairs");
284 TraceNodeText(
"Src1",
"Generating Bell pair (fly_a, rep_a)");
285 TraceNodeText(
"Src2",
"Generating Bell pair (rep_b, fly_b)");
287 auto [flyA, memA] = src1->CreateBellPair();
288 flyA->SetLabel(
"fly_a");
289 memA->SetLabel(
"rep_a");
293 auto [memB, flyB] = src2->CreateBellPair();
294 memB->SetLabel(
"rep_b");
295 flyB->SetLabel(
"fly_b");
299 Simulator::Schedule(kTwoQGate, [&, flyA, memA, memB, flyB]() {
304 std::cout <<
"[SRC1] Bell pair ready\n";
305 std::cout <<
"[SRC2] Bell pair ready\n";
308 Simulator::Schedule(kSingleGate, [&, flyA, memA, memB, flyB]() {
309 Trace(
"Phase 2: distributing qubits to endpoints and repeater");
310 const auto tSend = Simulator::Now();
312 src1->Send(flyA, alice->GetId());
315 src1->Send(memA, repeater->GetId());
316 TraceSendQubit(
"rep_a",
"Src1",
"Repeater", tSend, tSend + kQDelay);
318 src2->Send(memB, repeater->GetId());
319 TraceSendQubit(
"rep_b",
"Src2",
"Repeater", tSend, tSend + kQDelay);
321 src2->Send(flyB, bob->GetId());
326 std::cout <<
"[SRC1] fly_a sent to Alice, rep_a sent to Repeater\n";
327 std::cout <<
"[SRC2] rep_b sent to Repeater, fly_b sent to Bob\n";
332 Simulator::Stop(MilliSeconds(1));
334 Simulator::Destroy();
337 std::cout <<
"[DONE] Repeater swap finished\n";