PIRRetrieve.java 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. package pir;
  2. import java.math.BigInteger;
  3. import java.util.Arrays;
  4. import communication.Communication;
  5. import crypto.Crypto;
  6. import exceptions.AccessException;
  7. import exceptions.NoSuchPartyException;
  8. import oram.Forest;
  9. import oram.Global;
  10. import oram.Metadata;
  11. import oram.Tree;
  12. import oram.Tuple;
  13. import pir.precomputation.PrePIRRetrieve;
  14. import protocols.Pipeline;
  15. import protocols.PostProcessT;
  16. import protocols.Protocol;
  17. import protocols.UpdateRoot;
  18. import protocols.struct.OutAccess;
  19. import protocols.struct.OutRetrieve;
  20. import protocols.struct.Party;
  21. import protocols.struct.PreData;
  22. import util.Bandwidth;
  23. import util.P;
  24. import util.StopWatch;
  25. import util.Timer;
  26. import util.Util;
  27. public class PIRRetrieve extends Protocol {
  28. Communication[] cons1;
  29. Communication[] cons2;
  30. public PIRRetrieve(Communication con1, Communication con2) {
  31. super(con1, con2);
  32. }
  33. public void setCons(Communication[] a, Communication[] b) {
  34. cons1 = a;
  35. cons2 = b;
  36. }
  37. public byte[] runE(PreData[] predata, Tree OTi, byte[] Ni, byte[] Nip1_pr, int h, Timer timer) {
  38. // 1st eviction
  39. PIRAccess access = new PIRAccess(con1, con2);
  40. PIRReshuffle reshuffle = new PIRReshuffle(con1, con2);
  41. PostProcessT postprocesst = new PostProcessT(con1, con2);
  42. UpdateRoot updateroot = new UpdateRoot(con1, con2);
  43. PIREviction eviction = new PIREviction(con1, con2);
  44. OutAccess outaccess = access.runE(predata[0], OTi, Ni, Nip1_pr, timer);
  45. // Tuple[] path = reshuffle.runE(predata[0], outaccess.E_P,
  46. // OTi.getTreeIndex() == 0, timer);
  47. Tuple[] path = outaccess.E_P;
  48. byte[][] fbArray = new byte[outaccess.E_P.length][];
  49. for (int i = 0; i < fbArray.length; i++)
  50. fbArray[i] = outaccess.E_P[i].getF();
  51. reshuffle.runE(predata[0], fbArray, OTi.getTreeIndex() == 0, timer);
  52. Tuple Ti = postprocesst.runE(predata[0], outaccess.E_Ti, OTi.getTreeIndex() == h - 1, timer);
  53. Tuple[] root = Arrays.copyOfRange(path, 0, OTi.getStashSize());
  54. root = updateroot.runE(predata[0], OTi.getTreeIndex() == 0, outaccess.Li, root, Ti, timer);
  55. System.arraycopy(root, 0, path, 0, root.length);
  56. eviction.runE(predata[0], OTi.getTreeIndex() == 0, outaccess.Li,
  57. OTi.getTreeIndex() == 0 ? new Tuple[] { Ti } : path, OTi, timer);
  58. // 2nd eviction
  59. OutAccess outaccess2 = access.runE2(OTi, timer);
  60. Tuple[] path2 = outaccess2.E_P;
  61. Tuple Ti2 = outaccess2.E_Ti;
  62. Tuple[] root2 = Arrays.copyOfRange(path2, 0, OTi.getStashSize());
  63. root2 = updateroot.runE(predata[1], OTi.getTreeIndex() == 0, outaccess2.Li, root2, Ti2, timer);
  64. System.arraycopy(root2, 0, path2, 0, root2.length);
  65. eviction.runE(predata[1], OTi.getTreeIndex() == 0, outaccess2.Li,
  66. OTi.getTreeIndex() == 0 ? new Tuple[] { Ti2 } : path2, OTi, timer);
  67. return Ti.getA();
  68. }
  69. public void runD(PreData predata[], Tree OTi, byte[] Ni, byte[] Nip1_pr, Timer timer) {
  70. // 1st eviction
  71. PIRAccess access = new PIRAccess(con1, con2);
  72. PIRReshuffle reshuffle = new PIRReshuffle(con1, con2);
  73. PostProcessT postprocesst = new PostProcessT(con1, con2);
  74. UpdateRoot updateroot = new UpdateRoot(con1, con2);
  75. PIREviction eviction = new PIREviction(con1, con2);
  76. byte[] Li = access.runD(predata[0], OTi, Ni, Nip1_pr, timer);
  77. reshuffle.runD();
  78. postprocesst.runD();
  79. updateroot.runD(predata[0], OTi.getTreeIndex() == 0, Li, OTi.getW(), timer);
  80. eviction.runD(predata[0], OTi.getTreeIndex() == 0, Li, OTi, timer);
  81. // 2nd eviction
  82. byte[] Li2 = access.runD2(OTi, timer);
  83. updateroot.runD(predata[1], OTi.getTreeIndex() == 0, Li2, OTi.getW(), timer);
  84. eviction.runD(predata[1], OTi.getTreeIndex() == 0, Li2, OTi, timer);
  85. }
  86. public OutAccess runC(PreData[] predata, Metadata md, Tree OTi, int ti, byte[] Li, Timer timer) {
  87. // 1st eviction
  88. PIRAccess access = new PIRAccess(con1, con2);
  89. PIRReshuffle reshuffle = new PIRReshuffle(con1, con2);
  90. PostProcessT postprocesst = new PostProcessT(con1, con2);
  91. UpdateRoot updateroot = new UpdateRoot(con1, con2);
  92. PIREviction eviction = new PIREviction(con1, con2);
  93. OutAccess outaccess = access.runC(md, OTi, ti, Li, timer);
  94. // Tuple[] path = reshuffle.runC(predata[0], outaccess.C_P, ti == 0,
  95. // timer);
  96. Tuple[] path = outaccess.C_P;
  97. byte[][] fbArray = new byte[outaccess.C_P.length][];
  98. for (int i = 0; i < fbArray.length; i++)
  99. fbArray[i] = outaccess.C_P[i].getF();
  100. reshuffle.runC(predata[0], fbArray, ti == 0, timer);
  101. Tuple Ti = postprocesst.runC(predata[0], outaccess.C_Ti, Li, outaccess.C_Lip1, outaccess.C_j2,
  102. ti == md.getNumTrees() - 1, timer);
  103. Tuple[] root = Arrays.copyOfRange(path, 0, md.getStashSizeOfTree(ti));
  104. root = updateroot.runC(predata[0], ti == 0, root, Ti, timer);
  105. System.arraycopy(root, 0, path, 0, root.length);
  106. eviction.runC(predata[0], ti == 0, ti == 0 ? new Tuple[] { Ti } : path, md.getLBitsOfTree(ti) + 1,
  107. md.getStashSizeOfTree(ti), md.getW(), timer);
  108. // 2nd eviction
  109. byte[] Li2 = Util.nextBytes(md.getLBytesOfTree(ti), Crypto.sr);
  110. OutAccess outaccess2 = access.runC2(md, OTi, ti, Li2, timer);
  111. Tuple[] path2 = outaccess2.C_P;
  112. Tuple Ti2 = outaccess2.C_Ti;
  113. Tuple[] root2 = Arrays.copyOfRange(path2, 0, md.getStashSizeOfTree(ti));
  114. root2 = updateroot.runC(predata[1], ti == 0, root2, Ti2, timer);
  115. System.arraycopy(root2, 0, path2, 0, root2.length);
  116. eviction.runC(predata[1], ti == 0, ti == 0 ? new Tuple[] { Ti2 } : path2, md.getLBitsOfTree(ti) + 1,
  117. md.getStashSizeOfTree(ti), md.getW(), timer);
  118. return outaccess;
  119. }
  120. public Pipeline pipelineE(PreData[] predata, Tree OTi, byte[] Ni, byte[] Nip1_pr, int h, Timer[] timer) {
  121. PIRAccess access = new PIRAccess(con1, con2);
  122. OutAccess outaccess = access.runE(predata[0], OTi, Ni, Nip1_pr, timer[0]);
  123. int ti = OTi.getTreeIndex();
  124. Pipeline pipeline = new Pipeline(cons1[ti + 1], cons2[ti + 1], Party.Eddie, predata, OTi, h, timer[ti + 1],
  125. null, ti, outaccess.Li, outaccess);
  126. pipeline.start();
  127. return pipeline;
  128. }
  129. public Pipeline pipelineD(PreData predata[], Tree OTi, byte[] Ni, byte[] Nip1_pr, Timer[] timer) {
  130. PIRAccess access = new PIRAccess(con1, con2);
  131. byte[] Li = access.runD(predata[0], OTi, Ni, Nip1_pr, timer[0]);
  132. int ti = OTi.getTreeIndex();
  133. Pipeline pipeline = new Pipeline(cons1[ti + 1], cons2[ti + 1], Party.Debbie, predata, OTi, 0, timer[ti + 1],
  134. null, ti, Li, null);
  135. pipeline.start();
  136. return pipeline;
  137. }
  138. public OutRetrieve pipelineC(PreData[] predata, Metadata md, Tree OTi, int ti, byte[] Li, Timer[] timer) {
  139. PIRAccess access = new PIRAccess(con1, con2);
  140. OutAccess outaccess = access.runC(md, OTi, ti, Li, timer[0]);
  141. Pipeline pipeline = new Pipeline(cons1[ti + 1], cons2[ti + 1], Party.Charlie, predata, null, 0, timer[ti + 1],
  142. md, ti, Li, outaccess);
  143. pipeline.start();
  144. return new OutRetrieve(outaccess, pipeline);
  145. }
  146. // for testing correctness
  147. @Override
  148. public void run(Party party, Metadata md, Forest forest) {
  149. if (Global.pipeline)
  150. System.out.println("Pipeline Mode is On");
  151. if (Global.cheat)
  152. System.out.println("Cheat Mode is On");
  153. int records = 10;
  154. int reset = 5;
  155. int repeat = 1;
  156. int tau = md.getTau();
  157. int numTrees = md.getNumTrees();
  158. long numInsert = md.getNumInsertRecords();
  159. int addrBits = md.getAddrBits();
  160. int numTimer = Global.pipeline ? numTrees + 1 : 1;
  161. Timer[] timer = new Timer[numTimer];
  162. for (int i = 0; i < numTimer; i++)
  163. timer[i] = new Timer();
  164. StopWatch ete_off = new StopWatch("ETE_offline");
  165. StopWatch ete_on = new StopWatch("ETE_online");
  166. long[] gates = new long[2];
  167. Pipeline[] threads = new Pipeline[numTrees];
  168. sanityCheck();
  169. System.out.println();
  170. for (int i = 0; i < records; i++) {
  171. long N = Global.cheat ? 0 : Util.nextLong(numInsert, Crypto.sr);
  172. for (int j = 0; j < repeat; j++) {
  173. int cycleIndex = i * repeat + j;
  174. if (cycleIndex == reset * repeat) {
  175. for (int k = 0; k < timer.length; k++)
  176. timer[k].reset();
  177. ete_on.reset();
  178. ete_off.reset();
  179. }
  180. if (cycleIndex == 1) {
  181. for (int k = 0; k < cons1.length; k++) {
  182. cons1[k].bandSwitch = false;
  183. cons2[k].bandSwitch = false;
  184. }
  185. }
  186. System.out.println("Test: " + i + " " + j);
  187. System.out.println("N=" + BigInteger.valueOf(N).toString(2));
  188. System.out.print("Precomputation... ");
  189. PreData[][] predata = new PreData[numTrees][2];
  190. PrePIRRetrieve preretrieve = new PrePIRRetrieve(con1, con2);
  191. for (int ti = 0; ti < numTrees; ti++) {
  192. predata[ti][0] = new PreData();
  193. predata[ti][1] = new PreData();
  194. if (party == Party.Eddie) {
  195. ete_off.start();
  196. preretrieve.runE(predata[ti], md, ti, timer[0]);
  197. ete_off.stop();
  198. } else if (party == Party.Debbie) {
  199. ete_off.start();
  200. long[] cnt = preretrieve.runD(predata[ti], md, ti, ti == 0 ? null : predata[ti - 1][0],
  201. timer[0]);
  202. ete_off.stop();
  203. if (cycleIndex == 0) {
  204. gates[0] += cnt[0];
  205. gates[1] += cnt[1];
  206. }
  207. } else if (party == Party.Charlie) {
  208. ete_off.start();
  209. preretrieve.runC(predata[ti], md, ti, ti == 0 ? null : predata[ti - 1][0], timer[0]);
  210. ete_off.stop();
  211. } else {
  212. throw new NoSuchPartyException(party + "");
  213. }
  214. }
  215. sanityCheck();
  216. System.out.println("done!");
  217. byte[] Li = new byte[0];
  218. for (int ti = 0; ti < numTrees; ti++) {
  219. long Ni_value = Util.getSubBits(N, addrBits, addrBits - md.getNBitsOfTree(ti));
  220. long Nip1_pr_value = Util.getSubBits(N, addrBits - md.getNBitsOfTree(ti),
  221. Math.max(addrBits - md.getNBitsOfTree(ti) - tau, 0));
  222. byte[] Ni = Util.longToBytes(Ni_value, md.getNBytesOfTree(ti));
  223. byte[] Nip1_pr = Util.longToBytes(Nip1_pr_value, (tau + 7) / 8);
  224. if (party == Party.Eddie) {
  225. Tree OTi = forest.getTree(ti);
  226. byte[] sE_Ni = Util.nextBytes(Ni.length, Crypto.sr);
  227. byte[] sD_Ni = Util.xor(Ni, sE_Ni);
  228. con1.write(sD_Ni);
  229. byte[] sE_Nip1_pr = Util.nextBytes(Nip1_pr.length, Crypto.sr);
  230. byte[] sD_Nip1_pr = Util.xor(Nip1_pr, sE_Nip1_pr);
  231. con1.write(sD_Nip1_pr);
  232. byte[] E_A = null;
  233. if (!Global.pipeline) {
  234. ete_on.start();
  235. E_A = runE(predata[ti], OTi, sE_Ni, sE_Nip1_pr, numTrees, timer[0]);
  236. ete_on.stop();
  237. } else {
  238. if (ti == 0)
  239. ete_on.start();
  240. threads[ti] = pipelineE(predata[ti], OTi, sE_Ni, sE_Nip1_pr, numTrees, timer);
  241. }
  242. if (ti == numTrees - 1) {
  243. con2.write(N);
  244. con2.write(E_A);
  245. }
  246. } else if (party == Party.Debbie) {
  247. Tree OTi = forest.getTree(ti);
  248. byte[] sD_Ni = con1.read();
  249. byte[] sD_Nip1_pr = con1.read();
  250. if (!Global.pipeline) {
  251. ete_on.start();
  252. runD(predata[ti], OTi, sD_Ni, sD_Nip1_pr, timer[0]);
  253. ete_on.stop();
  254. } else {
  255. if (ti == 0)
  256. ete_on.start();
  257. threads[ti] = pipelineD(predata[ti], OTi, sD_Ni, sD_Nip1_pr, timer);
  258. }
  259. } else if (party == Party.Charlie) {
  260. Tree OTi = forest.getTree(ti);
  261. int lBits = md.getLBitsOfTree(ti);
  262. System.out.println("L" + ti + "="
  263. + Util.addZeros(Util.getSubBits(new BigInteger(1, Li), lBits, 0).toString(2), lBits));
  264. OutAccess outaccess = null;
  265. if (!Global.pipeline) {
  266. ete_on.start();
  267. outaccess = runC(predata[ti], md, OTi, ti, Li, timer[0]);
  268. ete_on.stop();
  269. } else {
  270. if (ti == 0)
  271. ete_on.start();
  272. OutRetrieve outretrieve = pipelineC(predata[ti], md, OTi, ti, Li, timer);
  273. outaccess = outretrieve.outaccess;
  274. threads[ti] = outretrieve.pipeline;
  275. }
  276. Li = outaccess.C_Lip1;
  277. if (ti == numTrees - 1) {
  278. N = con1.readLong();
  279. byte[] E_A = con1.read();
  280. long data = new BigInteger(1, Util.xor(outaccess.C_Ti.getA(), E_A)).longValue();
  281. if (N == data) {
  282. System.out.println("PIR Retrieval passed");
  283. System.out.println();
  284. } else {
  285. throw new AccessException("PIR Retrieval failed");
  286. }
  287. }
  288. } else {
  289. throw new NoSuchPartyException(party + "");
  290. }
  291. }
  292. if (Global.pipeline) {
  293. for (int ti = 0; ti < numTrees; ti++) {
  294. try {
  295. threads[ti].join();
  296. } catch (InterruptedException e) {
  297. e.printStackTrace();
  298. }
  299. }
  300. ete_on.stop();
  301. }
  302. }
  303. }
  304. System.out.println();
  305. Timer sum = new Timer();
  306. for (int i = 0; i < timer.length; i++)
  307. sum = sum.add(timer[i]);
  308. sum.noPrePrint();
  309. System.out.println();
  310. StopWatch comEnc = new StopWatch("CE_online_comp");
  311. for (int i = 0; i < cons1.length; i++)
  312. comEnc = comEnc.add(cons1[i].comEnc.add(cons2[i].comEnc));
  313. System.out.println(comEnc.noPreToMS());
  314. System.out.println();
  315. if (Global.pipeline)
  316. ete_on.elapsedCPU = 0;
  317. System.out.println(ete_on.noPreToMS());
  318. System.out.println(ete_off.noPreToMS());
  319. System.out.println();
  320. Bandwidth[] bandwidth = new Bandwidth[P.size];
  321. for (int i = 0; i < P.size; i++) {
  322. bandwidth[i] = new Bandwidth(P.names[i]);
  323. for (int j = 0; j < cons1.length; j++)
  324. bandwidth[i] = bandwidth[i].add(cons1[j].bandwidth[i].add(cons2[j].bandwidth[i]));
  325. System.out.println(bandwidth[i].noPreToString());
  326. }
  327. System.out.println();
  328. System.out.println(gates[0]);
  329. System.out.println(gates[1]);
  330. System.out.println();
  331. sanityCheck();
  332. }
  333. @Override
  334. public void run(Party party, Metadata md, Forest[] forests) {
  335. System.err.println("Check2");
  336. if (Global.pipeline)
  337. System.out.println("Pipeline Mode is On");
  338. if (Global.cheat)
  339. System.out.println("Cheat Mode is On");
  340. int records = 10;
  341. int reset = 5;
  342. int repeat = 1;
  343. int tau = md.getTau();
  344. int numTrees = md.getNumTrees();
  345. long numInsert = md.getNumInsertRecords();
  346. int addrBits = md.getAddrBits();
  347. int numTimer = Global.pipeline ? numTrees + 1 : 1;
  348. Timer[] timer = new Timer[numTimer];
  349. for (int i = 0; i < numTimer; i++)
  350. timer[i] = new Timer();
  351. StopWatch ete_off = new StopWatch("ETE_offline");
  352. StopWatch ete_on = new StopWatch("ETE_online");
  353. long[] gates = new long[2];
  354. Pipeline[] threads = new Pipeline[numTrees];
  355. sanityCheck();
  356. System.out.println();
  357. for (int i = 0; i < records; i++) {
  358. long N = Global.cheat ? 0 : Util.nextLong(numInsert, Crypto.sr);
  359. for (int j = 0; j < repeat; j++) {
  360. int cycleIndex = i * repeat + j;
  361. if (cycleIndex == reset * repeat) {
  362. for (int k = 0; k < timer.length; k++)
  363. timer[k].reset();
  364. ete_on.reset();
  365. ete_off.reset();
  366. }
  367. if (cycleIndex == 1) {
  368. for (int k = 0; k < cons1.length; k++) {
  369. cons1[k].bandSwitch = false;
  370. cons2[k].bandSwitch = false;
  371. }
  372. }
  373. System.out.println("Test: " + i + " " + j);
  374. System.out.println("N=" + BigInteger.valueOf(N).toString(2));
  375. System.out.print("Precomputation... ");
  376. PreData[][] predata = new PreData[numTrees][2];
  377. PrePIRRetrieve preretrieve = new PrePIRRetrieve(con1, con2);
  378. for (int ti = 0; ti < numTrees; ti++) {
  379. predata[ti][0] = new PreData();
  380. predata[ti][1] = new PreData();
  381. if (party == Party.Eddie) {
  382. ete_off.start();
  383. preretrieve.runE(predata[ti], md, ti, timer[0]);
  384. ete_off.stop();
  385. } else if (party == Party.Debbie) {
  386. ete_off.start();
  387. long[] cnt = preretrieve.runD(predata[ti], md, ti, ti == 0 ? null : predata[ti - 1][0],
  388. timer[0]);
  389. ete_off.stop();
  390. if (cycleIndex == 0) {
  391. gates[0] += cnt[0];
  392. gates[1] += cnt[1];
  393. }
  394. } else if (party == Party.Charlie) {
  395. ete_off.start();
  396. preretrieve.runC(predata[ti], md, ti, ti == 0 ? null : predata[ti - 1][0], timer[0]);
  397. ete_off.stop();
  398. } else {
  399. throw new NoSuchPartyException(party + "");
  400. }
  401. }
  402. sanityCheck();
  403. System.out.println("done!");
  404. byte[] Li = new byte[0];
  405. for (int ti = 0; ti < numTrees; ti++) {
  406. long Ni_value = Util.getSubBits(N, addrBits, addrBits - md.getNBitsOfTree(ti));
  407. long Nip1_pr_value = Util.getSubBits(N, addrBits - md.getNBitsOfTree(ti),
  408. Math.max(addrBits - md.getNBitsOfTree(ti) - tau, 0));
  409. byte[] Ni = Util.longToBytes(Ni_value, md.getNBytesOfTree(ti));
  410. byte[] Nip1_pr = Util.longToBytes(Nip1_pr_value, (tau + 7) / 8);
  411. if (party == Party.Eddie) {
  412. Tree OTi = forests[0].getTree(ti);
  413. byte[] sE_Ni = Util.nextBytes(Ni.length, Crypto.sr);
  414. byte[] sD_Ni = Util.xor(Ni, sE_Ni);
  415. con1.write(sD_Ni);
  416. byte[] sE_Nip1_pr = Util.nextBytes(Nip1_pr.length, Crypto.sr);
  417. byte[] sD_Nip1_pr = Util.xor(Nip1_pr, sE_Nip1_pr);
  418. con1.write(sD_Nip1_pr);
  419. byte[] E_A = null;
  420. if (!Global.pipeline) {
  421. ete_on.start();
  422. E_A = runE(predata[ti], OTi, sE_Ni, sE_Nip1_pr, numTrees, timer[0]);
  423. ete_on.stop();
  424. } else {
  425. if (ti == 0)
  426. ete_on.start();
  427. threads[ti] = pipelineE(predata[ti], OTi, sE_Ni, sE_Nip1_pr, numTrees, timer);
  428. }
  429. if (ti == numTrees - 1) {
  430. con2.write(N);
  431. con2.write(E_A);
  432. }
  433. } else if (party == Party.Debbie) {
  434. Tree OTi = forests[1].getTree(ti);
  435. byte[] sD_Ni = con1.read();
  436. byte[] sD_Nip1_pr = con1.read();
  437. if (!Global.pipeline) {
  438. ete_on.start();
  439. runD(predata[ti], OTi, sD_Ni, sD_Nip1_pr, timer[0]);
  440. ete_on.stop();
  441. } else {
  442. if (ti == 0)
  443. ete_on.start();
  444. threads[ti] = pipelineD(predata[ti], OTi, sD_Ni, sD_Nip1_pr, timer);
  445. }
  446. } else if (party == Party.Charlie) {
  447. Tree OTi = forests[1].getTree(ti);
  448. int lBits = md.getLBitsOfTree(ti);
  449. System.out.println("L" + ti + "="
  450. + Util.addZeros(Util.getSubBits(new BigInteger(1, Li), lBits, 0).toString(2), lBits));
  451. OutAccess outaccess = null;
  452. if (!Global.pipeline) {
  453. ete_on.start();
  454. outaccess = runC(predata[ti], md, OTi, ti, Li, timer[0]);
  455. ete_on.stop();
  456. } else {
  457. if (ti == 0)
  458. ete_on.start();
  459. OutRetrieve outretrieve = pipelineC(predata[ti], md, OTi, ti, Li, timer);
  460. outaccess = outretrieve.outaccess;
  461. threads[ti] = outretrieve.pipeline;
  462. }
  463. Li = outaccess.C_Lip1;
  464. if (ti == numTrees - 1) {
  465. N = con1.readLong();
  466. byte[] E_A = con1.read();
  467. long data = new BigInteger(1, Util.xor(outaccess.C_Ti.getA(), E_A)).longValue();
  468. if (N == data) {
  469. System.out.println("PIR Retrieval passed");
  470. System.out.println();
  471. } else {
  472. throw new AccessException("PIR Retrieval failed");
  473. }
  474. }
  475. } else {
  476. throw new NoSuchPartyException(party + "");
  477. }
  478. }
  479. if (Global.pipeline) {
  480. for (int ti = 0; ti < numTrees; ti++) {
  481. try {
  482. threads[ti].join();
  483. } catch (InterruptedException e) {
  484. e.printStackTrace();
  485. }
  486. }
  487. ete_on.stop();
  488. }
  489. }
  490. }
  491. System.out.println();
  492. Timer sum = new Timer();
  493. for (int i = 0; i < timer.length; i++)
  494. sum = sum.add(timer[i]);
  495. sum.noPrePrint();
  496. System.out.println();
  497. StopWatch comEnc = new StopWatch("CE_online_comp");
  498. for (int i = 0; i < cons1.length; i++)
  499. comEnc = comEnc.add(cons1[i].comEnc.add(cons2[i].comEnc));
  500. System.out.println(comEnc.noPreToMS());
  501. System.out.println();
  502. if (Global.pipeline)
  503. ete_on.elapsedCPU = 0;
  504. System.out.println(ete_on.noPreToMS());
  505. System.out.println(ete_off.noPreToMS());
  506. System.out.println();
  507. Bandwidth[] bandwidth = new Bandwidth[P.size];
  508. for (int i = 0; i < P.size; i++) {
  509. bandwidth[i] = new Bandwidth(P.names[i]);
  510. for (int j = 0; j < cons1.length; j++)
  511. bandwidth[i] = bandwidth[i].add(cons1[j].bandwidth[i].add(cons2[j].bandwidth[i]));
  512. System.out.println(bandwidth[i].noPreToString());
  513. }
  514. System.out.println();
  515. System.out.println(gates[0]);
  516. System.out.println(gates[1]);
  517. System.out.println();
  518. sanityCheck();
  519. }
  520. }