PIRRetrieve.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. package protocols;
  2. import java.math.BigInteger;
  3. import java.util.Arrays;
  4. import communication.Communication;
  5. import crypto.Crypto;
  6. import exceptions.NoSuchPartyException;
  7. import oram.Forest;
  8. import oram.Global;
  9. import oram.Metadata;
  10. import oram.Tree;
  11. import oram.Tuple;
  12. import struct.OutFF;
  13. import struct.OutPIRAccess;
  14. import struct.OutULiT;
  15. import struct.Party;
  16. import struct.TwoThreeXorByte;
  17. import struct.TwoThreeXorInt;
  18. import util.M;
  19. import util.StopWatch;
  20. import util.Util;
  21. // TODO: really FlipFlag on path, and update path in Eviction
  22. // TODO: fix simulation
  23. public class PIRRetrieve extends Protocol {
  24. Communication[] cons1;
  25. Communication[] cons2;
  26. public PIRRetrieve(Communication con1, Communication con2) {
  27. super(con1, con2);
  28. }
  29. public void setCons(Communication[] a, Communication[] b) {
  30. cons1 = a;
  31. cons2 = b;
  32. }
  33. public OutPIRAccess runE(Metadata md, Tree tree_DE, Tree tree_CE, byte[] Li, TwoThreeXorByte L, TwoThreeXorByte N,
  34. TwoThreeXorInt dN) {
  35. timer.start(M.online_comp);
  36. int treeIndex = tree_DE.getTreeIndex();
  37. boolean isLastTree = treeIndex == md.getNumTrees() - 1;
  38. boolean isFirstTree = treeIndex == 0;
  39. PIRAccess piracc = new PIRAccess(con1, con2);
  40. OutPIRAccess outpiracc = piracc.runE(md, tree_DE, tree_CE, Li, L, N, dN);
  41. OutULiT T = new OutULiT();
  42. if (!isLastTree) {
  43. TwoThreeXorByte Lp = new TwoThreeXorByte(md.getLBytesOfTree(treeIndex));
  44. TwoThreeXorByte Lpi = new TwoThreeXorByte(md.getLBytesOfTree(treeIndex + 1));
  45. ULiT ulit = new ULiT(con1, con2, Crypto.sr_DE, Crypto.sr_CE);
  46. T = ulit.runE(outpiracc.X, N, dN, Lp, Lpi, outpiracc.nextL, md.getTwoTauPow());
  47. } else {
  48. T.DE = outpiracc.pathTuples_DE[0];
  49. T.CE = outpiracc.pathTuples_CE[0];
  50. }
  51. int pathTuples = outpiracc.pathTuples_CE.length;
  52. if (!isFirstTree) {
  53. byte[][] fb_DE = new byte[pathTuples][];
  54. byte[][] fb_CE = new byte[pathTuples][];
  55. for (int i = 0; i < pathTuples; i++) {
  56. fb_DE[i] = outpiracc.pathTuples_DE[i].getF();
  57. fb_CE[i] = outpiracc.pathTuples_CE[i].getF();
  58. }
  59. FlipFlag ff = new FlipFlag(con1, con2);
  60. OutFF outff = ff.runE(fb_DE, fb_CE, outpiracc.j.s_DE);
  61. for (int i = 0; i < pathTuples; i++) {
  62. // outpiracc.pathTuples_DE[i].setF(outff.fb_DE[i]);
  63. // outpiracc.pathTuples_CE[i].setF(outff.fb_CE[i]);
  64. }
  65. }
  66. int stashSize = tree_DE.getStashSize();
  67. int[] tupleParam = new int[] { treeIndex == 0 ? 0 : 1, md.getNBytesOfTree(treeIndex),
  68. md.getLBytesOfTree(treeIndex), md.getABytesOfTree(treeIndex) };
  69. Tuple[] path = new Tuple[pathTuples];
  70. for (int i = 0; i < pathTuples; i++) {
  71. path[i] = outpiracc.pathTuples_DE[i].xor(outpiracc.pathTuples_CE[i]);
  72. }
  73. Tuple[] R = Arrays.copyOfRange(path, 0, stashSize);
  74. UpdateRoot updateroot = new UpdateRoot(con1, con2);
  75. R = updateroot.runE(isFirstTree, stashSize, md.getLBitsOfTree(treeIndex), tupleParam, Li, R, T.DE.xor(T.CE));
  76. System.arraycopy(R, 0, path, 0, R.length);
  77. Eviction eviction = new Eviction(con1, con2);
  78. eviction.runE(isFirstTree, tupleParam, Li, path, tree_DE);
  79. // simulation of Reshare
  80. timer.start(M.online_write);
  81. con2.write(online_band, path);
  82. timer.stop(M.online_write);
  83. timer.start(M.online_read);
  84. con2.readTupleArrayAndDec();
  85. timer.stop(M.online_read);
  86. // second eviction sim
  87. for (int i = 0; i < pathTuples; i++) {
  88. path[i] = outpiracc.pathTuples_DE[i].xor(outpiracc.pathTuples_CE[i]);
  89. }
  90. R = Arrays.copyOfRange(path, 0, stashSize);
  91. R = updateroot.runE(isFirstTree, stashSize, md.getLBitsOfTree(treeIndex), tupleParam, Li, R, T.DE.xor(T.CE));
  92. System.arraycopy(R, 0, path, 0, R.length);
  93. eviction.runE(isFirstTree, tupleParam, Li, path, tree_DE);
  94. // simulation of Reshare
  95. timer.start(M.online_write);
  96. con2.write(online_band, path);
  97. timer.stop(M.online_write);
  98. timer.start(M.online_read);
  99. con2.readTupleArrayAndDec();
  100. timer.stop(M.online_read);
  101. timer.stop(M.online_comp);
  102. return outpiracc;
  103. }
  104. public OutPIRAccess runD(Metadata md, Tree tree_DE, Tree tree_CD, byte[] Li, TwoThreeXorByte L, TwoThreeXorByte N,
  105. TwoThreeXorInt dN) {
  106. timer.start(M.online_comp);
  107. int treeIndex = tree_DE.getTreeIndex();
  108. boolean isLastTree = treeIndex == md.getNumTrees() - 1;
  109. boolean isFirstTree = treeIndex == 0;
  110. PIRAccess piracc = new PIRAccess(con1, con2);
  111. OutPIRAccess outpiracc = piracc.runD(md, tree_DE, tree_CD, Li, L, N, dN);
  112. OutULiT T = new OutULiT();
  113. if (!isLastTree) {
  114. TwoThreeXorByte Lp = new TwoThreeXorByte(md.getLBytesOfTree(treeIndex));
  115. TwoThreeXorByte Lpi = new TwoThreeXorByte(md.getLBytesOfTree(treeIndex + 1));
  116. ULiT ulit = new ULiT(con1, con2, Crypto.sr_DE, Crypto.sr_CD);
  117. T = ulit.runD(outpiracc.X, N, dN, Lp, Lpi, outpiracc.nextL, md.getTwoTauPow());
  118. } else {
  119. T.CD = outpiracc.pathTuples_CD[0];
  120. T.DE = outpiracc.pathTuples_DE[0];
  121. }
  122. int pathTuples = outpiracc.pathTuples_CD.length;
  123. if (!isFirstTree) {
  124. byte[][] fb_DE = new byte[pathTuples][];
  125. byte[][] fb_CD = new byte[pathTuples][];
  126. for (int i = 0; i < pathTuples; i++) {
  127. fb_DE[i] = outpiracc.pathTuples_DE[i].getF();
  128. fb_CD[i] = outpiracc.pathTuples_CD[i].getF();
  129. }
  130. FlipFlag ff = new FlipFlag(con1, con2);
  131. OutFF outff = ff.runD(fb_DE, fb_CD, outpiracc.j.s_DE);
  132. for (int i = 0; i < pathTuples; i++) {
  133. // outpiracc.pathTuples_DE[i].setF(outff.fb_DE[i]);
  134. // outpiracc.pathTuples_CD[i].setF(outff.fb_CD[i]);
  135. }
  136. }
  137. int stashSize = tree_DE.getStashSize();
  138. int[] tupleParam = new int[] { treeIndex == 0 ? 0 : 1, md.getNBytesOfTree(treeIndex),
  139. md.getLBytesOfTree(treeIndex), md.getABytesOfTree(treeIndex) };
  140. UpdateRoot updateroot = new UpdateRoot(con1, con2);
  141. updateroot.runD(isFirstTree, stashSize, md.getLBitsOfTree(treeIndex), tupleParam, Li, tree_DE.getW());
  142. Eviction eviction = new Eviction(con1, con2);
  143. eviction.runD(isFirstTree, tupleParam, Li, tree_DE);
  144. // second eviction sim
  145. updateroot.runD(isFirstTree, stashSize, md.getLBitsOfTree(treeIndex), tupleParam, Li, tree_DE.getW());
  146. eviction.runD(isFirstTree, tupleParam, Li, tree_DE);
  147. timer.stop(M.online_comp);
  148. return outpiracc;
  149. }
  150. public OutPIRAccess runC(Metadata md, Tree tree_CD, Tree tree_CE, byte[] Li, TwoThreeXorByte L, TwoThreeXorByte N,
  151. TwoThreeXorInt dN) {
  152. timer.start(M.online_comp);
  153. int treeIndex = tree_CE.getTreeIndex();
  154. boolean isLastTree = treeIndex == md.getNumTrees() - 1;
  155. boolean isFirstTree = treeIndex == 0;
  156. PIRAccess piracc = new PIRAccess(con1, con2);
  157. OutPIRAccess outpiracc = piracc.runC(md, tree_CD, tree_CE, Li, L, N, dN);
  158. OutULiT T = new OutULiT();
  159. if (!isLastTree) {
  160. TwoThreeXorByte Lp = new TwoThreeXorByte(md.getLBytesOfTree(treeIndex));
  161. TwoThreeXorByte Lpi = new TwoThreeXorByte(md.getLBytesOfTree(treeIndex + 1));
  162. ULiT ulit = new ULiT(con1, con2, Crypto.sr_CE, Crypto.sr_CD);
  163. T = ulit.runC(outpiracc.X, N, dN, Lp, Lpi, outpiracc.nextL, md.getTwoTauPow());
  164. } else {
  165. T.CD = outpiracc.pathTuples_CD[0];
  166. T.CE = outpiracc.pathTuples_CE[0];
  167. }
  168. int pathTuples = outpiracc.pathTuples_CD.length;
  169. if (!isFirstTree) {
  170. byte[][] fb_CE = new byte[pathTuples][];
  171. byte[][] fb_CD = new byte[pathTuples][];
  172. for (int i = 0; i < pathTuples; i++) {
  173. fb_CE[i] = outpiracc.pathTuples_CE[i].getF();
  174. fb_CD[i] = outpiracc.pathTuples_CD[i].getF();
  175. }
  176. FlipFlag ff = new FlipFlag(con1, con2);
  177. OutFF outff = ff.runC(fb_CD, fb_CE, outpiracc.j.t_C);
  178. for (int i = 0; i < pathTuples; i++) {
  179. // outpiracc.pathTuples_CD[i].setF(outff.fb_CD[i]);
  180. // outpiracc.pathTuples_CE[i].setF(outff.fb_CE[i]);
  181. }
  182. }
  183. int stashSize = tree_CE.getStashSize();
  184. int[] tupleParam = new int[] { treeIndex == 0 ? 0 : 1, md.getNBytesOfTree(treeIndex),
  185. md.getLBytesOfTree(treeIndex), md.getABytesOfTree(treeIndex) };
  186. Tuple[] path = outpiracc.pathTuples_CD;
  187. Tuple[] R = Arrays.copyOfRange(path, 0, stashSize);
  188. UpdateRoot updateroot = new UpdateRoot(con1, con2);
  189. R = updateroot.runC(isFirstTree, tupleParam, R, T.CD);
  190. System.arraycopy(R, 0, path, 0, R.length);
  191. Eviction eviction = new Eviction(con1, con2);
  192. eviction.runC(isFirstTree, tupleParam, path, tree_CD.getD(), stashSize, tree_CD.getW());
  193. // simulation of Reshare
  194. timer.start(M.online_write);
  195. con1.write(online_band, path);
  196. timer.stop(M.online_write);
  197. timer.start(M.online_read);
  198. con1.readTupleArrayAndDec();
  199. timer.stop(M.online_read);
  200. // second eviction sim
  201. R = Arrays.copyOfRange(path, 0, stashSize);
  202. R = updateroot.runC(isFirstTree, tupleParam, R, T.CD);
  203. System.arraycopy(R, 0, path, 0, R.length);
  204. eviction.runC(isFirstTree, tupleParam, path, tree_CD.getD(), stashSize, tree_CD.getW());
  205. // simulation of Reshare
  206. timer.start(M.online_write);
  207. con1.write(online_band, path);
  208. timer.stop(M.online_write);
  209. timer.start(M.online_read);
  210. con1.readTupleArrayAndDec();
  211. timer.stop(M.online_read);
  212. timer.stop(M.online_comp);
  213. return outpiracc;
  214. }
  215. @Override
  216. public void run(Party party, Metadata md, Forest[] forest) {
  217. StopWatch ete = new StopWatch("ETE");
  218. Tree tree_CD = null;
  219. Tree tree_DE = null;
  220. Tree tree_CE = null;
  221. int iterations = 100;
  222. int reset = 20;
  223. for (int test = 0; test < iterations; test++) {
  224. if (test == reset) {
  225. timer.reset();
  226. ete.reset();
  227. }
  228. if (test == 1) {
  229. Global.bandSwitch = false;
  230. }
  231. for (int treeIndex = 0; treeIndex < md.getNumTrees(); treeIndex++) {
  232. if (party == Party.Eddie) {
  233. tree_DE = forest[0].getTree(treeIndex);
  234. tree_CE = forest[1].getTree(treeIndex);
  235. } else if (party == Party.Debbie) {
  236. tree_DE = forest[0].getTree(treeIndex);
  237. tree_CD = forest[1].getTree(treeIndex);
  238. } else if (party == Party.Charlie) {
  239. tree_CE = forest[0].getTree(treeIndex);
  240. tree_CD = forest[1].getTree(treeIndex);
  241. } else {
  242. throw new NoSuchPartyException(party + "");
  243. }
  244. int Llen = md.getLBytesOfTree(treeIndex);
  245. int Nlen = md.getNBytesOfTree(treeIndex);
  246. TwoThreeXorInt dN = new TwoThreeXorInt();
  247. TwoThreeXorByte N = new TwoThreeXorByte();
  248. N.CD = new byte[Nlen];
  249. N.DE = new byte[Nlen];
  250. N.CE = new byte[Nlen];
  251. TwoThreeXorByte L = new TwoThreeXorByte();
  252. L.CD = new byte[Llen];
  253. L.DE = new byte[Llen];
  254. L.CE = new byte[Llen];
  255. byte[] Li = new byte[Llen];
  256. if (party == Party.Eddie) {
  257. ete.start();
  258. OutPIRAccess out = this.runE(md, tree_DE, tree_CE, Li, L, N, dN);
  259. ete.stop();
  260. out.j.t_D = con1.readInt();
  261. out.j.t_C = con2.readInt();
  262. out.X.CD = con1.read();
  263. int pathTuples = out.pathTuples_CE.length;
  264. int index = (out.j.t_D + out.j.s_CE) % pathTuples;
  265. byte[] X = Util.xor(Util.xor(out.X.DE, out.X.CE), out.X.CD);
  266. boolean fail = false;
  267. if (index != 0) {
  268. System.err.println(test + " " + treeIndex + ": PIRAcc test failed on KSearch index");
  269. fail = true;
  270. }
  271. if (new BigInteger(1, X).intValue() != 0) {
  272. System.err.println(test + " " + treeIndex + ": PIRAcc test failed on 3ShiftPIR X");
  273. fail = true;
  274. }
  275. if (treeIndex < md.getNumTrees() - 1 && new BigInteger(1, out.Lip1).intValue() != 0) {
  276. System.err.println(test + " " + treeIndex + ": PIRAcc test failed on 3ShiftXorPIR Lip1");
  277. fail = true;
  278. }
  279. if (!fail)
  280. System.out.println(test + " " + treeIndex + ": PIRAcc test passed");
  281. } else if (party == Party.Debbie) {
  282. ete.start();
  283. OutPIRAccess out = this.runD(md, tree_DE, tree_CD, Li, L, N, dN);
  284. ete.stop();
  285. con1.write(out.j.t_D);
  286. con1.write(out.X.CD);
  287. } else if (party == Party.Charlie) {
  288. ete.start();
  289. OutPIRAccess out = this.runC(md, tree_CD, tree_CE, Li, L, N, dN);
  290. ete.stop();
  291. con1.write(out.j.t_C);
  292. } else {
  293. throw new NoSuchPartyException(party + "");
  294. }
  295. }
  296. }
  297. // Bandwidth total = new Bandwidth("Total Online");
  298. // for (int i = 0; i < P.size; i++) {
  299. // for (int j = 0; j < cons1.length; j++)
  300. // total.add(cons1[j].bandwidth[i].add(cons2[j].bandwidth[i]).bandwidth);
  301. // }
  302. // System.out.println(total.toString());
  303. // timer.divideBy(iterations - reset);
  304. // timer.print();
  305. System.out.println(ete.toMS());
  306. sanityCheck();
  307. }
  308. // for testing correctness
  309. @Override
  310. public void run(Party party, Metadata md, Forest forest) {
  311. }
  312. }