Q2NS dev
ns-3 module
Loading...
Searching...
No Matches
q2ns-3-teleportation-comms-example.cc
Go to the documentation of this file.
1/*-----------------------------------------------------------------------------
2 * Q2NS - Quantum Network Simulator
3 * Copyright (c) 2026 quantuminternet.it
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *---------------------------------------------------------------------------*/
9/**
10 * @file q2ns-3-teleportation-comms-example.cc
11 * @brief Teleportation with classical communication (UDP)
12 *
13 * Demonstrates:
14 * - Quantum link + Bell pair distribution
15 * - Bell-state measurement at Alice
16 * - UDP transmission of the two classical correction bits
17 * - Bob waiting for both the qubit and the classical bits before correcting
18 */
19
20#include "ns3/q2ns-netcontroller.h"
21#include "ns3/q2ns-qnode.h"
22#include "ns3/q2ns-qubit.h"
23
24#include "ns3/core-module.h"
25#include "ns3/internet-module.h"
26#include "ns3/network-module.h"
27#include "ns3/point-to-point-module.h"
28#include "ns3/simulator.h"
29
30#include <iostream>
31
32using namespace ns3;
33using namespace q2ns;
34
35namespace {
36
37
38// Bob's local information about the teleportation as it arrives.
39// He learns the remote qubit through the quantum channel and the
40// Bell-measurement outcomes through the classical channel.
41struct BobInfo {
42 std::shared_ptr<Qubit> qBremote;
43 bool qubitArrived = false;
44 bool bitsArrived = false;
45 int m1 = 0;
46 int m2 = 0;
47};
48
49
50// Bob can complete teleportation only after he has both:
51// 1) the received qubit, and
52// 2) Alice's two classical correction bits.
53void TryCorrections(Ptr<QNode> bob, BobInfo& bobInfo) {
54 if (!bobInfo.qubitArrived || !bobInfo.bitsArrived) {
55 return;
56 }
57
58 std::cout << "[B] Applying corrections: Z^" << bobInfo.m1 << " X^" << bobInfo.m2 << "|state>\n";
59
60 if (bobInfo.m2) {
61 bob->Apply(gates::X(), {bobInfo.qBremote});
62 }
63 if (bobInfo.m1) {
64 bob->Apply(gates::Z(), {bobInfo.qBremote});
65 }
66
67 int mx = bob->Measure(bobInfo.qBremote, Basis::X);
68 std::cout << "[B][VERIFY] Final state is correct: " << ((mx == 0) ? "yes" : "no") << "\n";
69}
70
71
72} // namespace
73
74int main() {
75 std::cout << "[DEMO] Teleportation (A->B) with classical communication starting\n";
76
77 ns3::RngSeedManager::SetSeed(1);
78 ns3::RngSeedManager::SetRun(1);
79
80 NetController net;
81 net.SetQStateBackend(QStateBackend::Ket);
82
83 auto A = net.CreateNode();
84 auto B = net.CreateNode();
85
86
87
88 // Networking setup
89 // Create the quantum channel used to distribute Bob's half of the Bell pair.
90 auto ch = net.InstallQuantumLink(A, B);
91 ch->SetAttribute("Delay", TimeValue(NanoSeconds(10)));
92
93 // Install a simple IP/UDP network between Alice and Bob for the two
94 // correction bits that complete the teleportation protocol.
95 InternetStackHelper internet;
96 internet.Install(A);
97 internet.Install(B);
98
99 PointToPointHelper p2p;
100 p2p.SetDeviceAttribute("DataRate", StringValue("100Mbps"));
101 p2p.SetChannelAttribute("Delay", StringValue("1ms"));
102 NetDeviceContainer devices = p2p.Install(A, B);
103
104 Ipv4AddressHelper ip;
105 ip.SetBase("10.1.1.0", "255.255.255.0");
106 Ipv4InterfaceContainer interfaces = ip.Assign(devices);
107
108 const uint16_t port = 9000;
109
110 Ptr<Socket> bobSocket = Socket::CreateSocket(B, UdpSocketFactory::GetTypeId());
111 bobSocket->Bind(InetSocketAddress(Ipv4Address::GetAny(), port));
112
113 Ptr<Socket> aliceSocket = Socket::CreateSocket(A, UdpSocketFactory::GetTypeId());
114 aliceSocket->Connect(InetSocketAddress(interfaces.GetAddress(1), port));
115
116
117 // Bob's classical and quantum receive callbacks
118 // Create a BobInfo instance to track Bob's local information updates
119 BobInfo bobInfo;
120
121 // When Bob receives the remote Bell-pair half, he records that the quantum
122 // part has arrived. He then tries to finish teleportation, which succeeds
123 // only if the classical correction packet has already arrived too.
124 B->SetRecvCallback([B, &bobInfo](std::shared_ptr<Qubit> q) {
125 std::cout << "[RECV][quantum][B]: yes\n";
126 bobInfo.qubitArrived = true;
127 bobInfo.qBremote = q;
128
129 TryCorrections(B, bobInfo);
130 });
131
132
133 // When the classical correction packet arrives at Bob, decode the two bits
134 // and check whether Bob now has everything needed to finish teleportation.
135 bobSocket->SetRecvCallback([B, &bobInfo](Ptr<Socket> socket) {
136 while (Ptr<Packet> packet = socket->Recv()) {
137 bobInfo.bitsArrived = true;
138
139 uint8_t bytes[2] = {0, 0};
140 packet->CopyData(bytes, 2);
141
142 bobInfo.m1 = bytes[0] & 1;
143 bobInfo.m2 = bytes[1] & 1;
144
145 std::cout << "[RECV][classical][B] m1=" << bobInfo.m1 << ", m2=" << bobInfo.m2 << "\n";
146
147 TryCorrections(B, bobInfo);
148 }
149 });
150
151
152
153 // Scheduling the protocol
154 // Alice first sends Bob's Bell-pair half over the quantum channel.
155 // She then prepares |+>, performs the Bell-state measurement locally,
156 // and sends the two resulting correction bits to Bob over UDP.
157 Simulator::Schedule(NanoSeconds(1), [&]() {
158 auto [qA, qBremote] = A->CreateBellPair();
159 bool ok = A->Send(qBremote, B->GetId());
160 std::cout << "[SEND][quantum] A->B: " << (ok ? "ok" : "failed") << "\n";
161
162 auto qAToTeleport = A->CreateQubit();
163 A->Apply(gates::H(), {qAToTeleport});
164 auto [m1, m2] = A->MeasureBell(qAToTeleport, qA);
165 std::cout << "[A] BSM results: " << m1 << ", " << m2 << "\n";
166
167 uint8_t bytes[2] = {static_cast<uint8_t>(m1), static_cast<uint8_t>(m2)};
168 aliceSocket->Send(Create<Packet>(bytes, 2));
169 std::cout << "[SEND][classical] A->B: m1=" << m1 << ", m2=" << m2 << "\n";
170 });
171
172
173
174 Simulator::Stop(Seconds(10));
175 Simulator::Run();
176
177 std::cout << "[DONE] Teleportation (A->B) with classical communication finished\n";
178
179 Simulator::Destroy();
180 return 0;
181}
Main user-facing facade for creating and configuring a quantum network.
ns3::Ptr< QNode > CreateNode(const std::string &label="")
Create a QNode with an optional human-readable label.
ns3::Ptr< QChannel > InstallQuantumLink(ns3::Ptr< QNode > a, ns3::Ptr< QNode > b)
Install a duplex quantum link between two nodes.
void SetQStateBackend(QStateBackend b)
Set the default backend used for newly created quantum states.
QGate X(ns3::Time d=ns3::Seconds(0))
Return the Pauli-X gate descriptor.
Definition q2ns-qgate.h:356
QGate H(ns3::Time d=ns3::Seconds(0))
Return the Hadamard gate descriptor.
Definition q2ns-qgate.h:383
QGate Z(ns3::Time d=ns3::Seconds(0))
Return the Pauli-Z gate descriptor.
Definition q2ns-qgate.h:374
uint8_t m2
uint8_t m1