ECF 1.5
main (2).cpp
1#include "Quantum/Quantum.h"
2#include "attack.h"
3
4namespace QKD
5{
6 enum GateType
7 {
8 NOT=0,
9 Rotation,
10 Hadamard,
11
12 Measure
13 };
14
15 struct Gate
16 {
17 Gate()
18 {
19 type = 0;
20 controlMode = false;
21 target = 0;
22 control = 0;
23 p = 0;
24 theta = 0;
25 psi = 0;
26 }
27 int type;
28 bool controlMode;
29 int target, control;
30 double p, theta, psi;
31 };
32}
33
34double SafeLog(double x)
35{
36 if(x < 0.000000001)
37 return 0;
38 return log(x) / log(2.0);
39}
40double entropy(double x)
41{
42 return -x*SafeLog(x) - (1-x)*SafeLog(1-x);
43}
44double entropy(double a, double b, double c, double d)
45{
46 return -a*SafeLog(a) - b*SafeLog(b) - c*SafeLog(c) - d*SafeLog(d);
47}
48
49QKD::Attack* atk;
50std::vector <algebra::mat> EVec;
51bool COMPUTE_ACTUAL_RATE = false;
52
53void setupAttackVectors(QKD::Stats& stats) // run this once at startup!
54{
55 EVec.resize(4);
56 for(int i=0; i<EVec.size(); ++i)
57 EVec[i].create(4,1);
58
59 atk = new QKD::Attack(stats);
60}
61
62double ComputeFitness(std::list <QKD::Gate>& A, std::list <QKD::Gate>& B)
63{
64 const int keyA = 0;
65 const int arA = 1;
66 const int extraA = 2;
67 const int numExtraA = 0;
68
69 const int T = extraA+numExtraA;
70
71 const int keyB = T+1;
72 const int arB = T+2;
73 const int extraB = T+3;
74 const int numExtraB = 0;
75
76 const int E = extraB+numExtraB;
77
78 const int NUM_WIRES = E+1;
79
80 const int ASpace = T; // largest wire (inclusive) A is allowed access to
81
83
84 for(int i=0; i<NUM_WIRES; ++i){
85 if(i != E)
86 dl.dimension.push_back(2);
87 else
88 dl.dimension.push_back(4);
89 }
90
91 quantum::KetBra kb(NUM_WIRES);
92 kb.p = 1;
93 dl.density.push_back(kb);
94
95 // run A:
96 if(!A.empty()){
97 std::list<QKD::Gate>::iterator Iter;
98 for(Iter = A.begin(); Iter != A.end(); ++Iter){
99 int target = Iter->target;
100 int control = Iter->control;
101 if(!Iter->controlMode)
102 control = -1;
103
104 // ensure that gates aren't applied to wires that cannot be accessed:
105 if(target > ASpace || control > ASpace)
106 continue;
107 if(target == E || control == E)
108 continue;
109
110 if(Iter->controlMode && control == target)
111 continue;
112
113 switch(Iter->type){
114 case QKD::Hadamard: dl.applyHadamard(target, control);
115 break;
116
117 case QKD::NOT: dl.applyNOT(target, control);
118 break;
119
120 case QKD::Rotation: dl.applySU2(target, control, Iter->p, Iter->theta, Iter->psi);
121 break;
122
123 case QKD::Measure: dl.measure(target);
124 break;
125 }
126 }
127 }
128
129 dl.applyAttackOp(T, E); // E attacks
130
131 // Run B:
132 if(!B.empty()){
133 std::list<QKD::Gate>::iterator Iter;
134 for(Iter = B.begin(); Iter != B.end(); ++Iter){
135 int target = Iter->target;
136 int control = Iter->control;
137 if(!Iter->controlMode)
138 control = -1;
139
140 // ensure that gates aren't applied to wires that cannot be accessed:
141 if(target < T || (control < T && control >= 0))
142 continue;
143 if(target == E || control == E)
144 continue;
145
146 if(Iter->controlMode && control == target)
147 continue;
148
149 switch(Iter->type){
150 case QKD::Hadamard: dl.applyHadamard(target, control);
151 break;
152
153 case QKD::NOT: dl.applyNOT(target, control);
154 break;
155
156 case QKD::Rotation: dl.applySU2(target, control, Iter->p, Iter->theta, Iter->psi);
157 break;
158
159 case QKD::Measure: dl.measure(target);
160 break;
161 }
162 }
163 }
164
165 // now A measures key
166 dl.measure(keyA);
167
168 // B measures key
169 dl.measure(keyB);
170
171 // project to both users accepting (conditioning):
172 dl.project(arA, 1);
173 dl.project(arB, 1);
174
175 // check that there is something here (always possible to "reject" with probability 1)
176 if(dl.density.empty())
177 return 0; // both parties are always saying 'reject' so no key so key-rate = 0.
178
179 atk->begin();
180
181 quantum::DensityList saveDL = dl;
182 double bestRate = 2;
183
184 while(!atk->getNext(EVec[0], EVec[1], EVec[2], EVec[3])){
185 dl = saveDL;
186 double paccept = dl.trace(EVec, E);
187 // compute H(A|B):
188
189 double p00 = dl.calculatePr(keyA, 0, keyB, 0, EVec, E);
190 double p01 = dl.calculatePr(keyA, 0, keyB, 1, EVec, E);
191 double p10 = dl.calculatePr(keyA, 1, keyB, 0, EVec, E);
192 double p11 = dl.calculatePr(keyA, 1, keyB, 1, EVec, E);
193
194 double HAB = entropy(p00, p01, p10, p11);
195 double HB = entropy(p00 + p10);
196
197 // compute S(A|E):
198 // trace out B's wires:
199 for(int w=keyA+1; w<E; ++w)
200 dl.trace(w);
201
202 // trace out A's extra wires:
203 //for(int w=keyA+1; w<=T; ++w)
204 // dl.trace(w);
205
206 double SAE = dl.entropy(EVec, E);
207 dl.trace(keyA);
208 double SE = dl.entropy(EVec, E);
209 double rate = 100;
210
211 if(COMPUTE_ACTUAL_RATE)
212 rate = (SAE - SE) - (HAB - HB);
213 else
214 rate = paccept * ( (SAE-SE) - (HAB-HB) );
215
216 if(rate < bestRate)
217 bestRate = rate;
218 }
219
220 return bestRate;
221}
222
223
224void testSimple()
225{
226 std::list <QKD::Gate> A, B;
227 QKD::Gate g;
228 g.type = QKD::NOT;
229 g.target = 2;
230 A.push_back(g);
231 ComputeFitness(A,B);
232}
233
234void testBB84()
235{
236 std::list <QKD::Gate> A, B;
237 QKD::Gate g;
238 g.type = QKD::NOT;
239 g.target = 1;
240 g.controlMode = false;
241
242 A.push_back(g); // g1
243
244 g.type = QKD::Hadamard;
245 g.target = 0;
246 g.controlMode = false;
247
248 A.push_back(g); // g2
249
250 g.type = QKD::NOT;
251 g.target = 2;
252 g.controlMode = true;
253 g.control = 0;
254
255 A.push_back(g); // g3
256
257
258 g.type = QKD::NOT;
259 g.target = 3;
260 g.control = 2;
261 g.controlMode = true;
262
263 B.push_back(g); // h1
264
265 g.type = QKD::NOT;
266 g.target = 4;
267 g.controlMode = false;
268
269 B.push_back(g); // h2
270
271
272 std::cout << "Test 1: key-rate (should be 1) = " << ComputeFitness(A,B) << "\n\n";
273
274}
275
276void test()
277{
278 std::list <QKD::Gate> A, B;
279 QKD::Gate g;
280 g.type = 2;
281 g.target = 0;
282 g.control = 1;
283 g.controlMode = false;
284 A.push_back(g); // g1
285
286 g.type = 2;
287 g.target = 0;
288 g.controlMode = true;
289 g.control = 0;
290 A.push_back(g); // g2
291
292 g.type = 1;
293 g.target = 2;
294 g.controlMode = false;
295 g.control = 1;
296 A.push_back(g); // g3
297
298
299 g.type = 1;
300 g.target = 4;
301 g.control = 4;
302 g.controlMode = true;
303 B.push_back(g); // h1
304
305 g.type = 1;
306 g.target = 4;
307 g.controlMode = false;
308 g.control = 3;
309 B.push_back(g); // h2
310
311
312 std::cout << "Test 1: key-rate = " << ComputeFitness(A,B) << "\n\n";
313}
314
315
316int main(int argc, char** argv)
317{
318 QKD::Stats stats;
319
320 stats.symmetric(.01); // Test EA with different values between .01 and .5.
321
322 setupAttackVectors(stats);
323
324 testBB84();
325
326 std::cout << "Above value should be = " << stats.BB84Rate() << "\n";
327
328 delete atk;
329
330 return 0;
331}