Retrieve.java 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. package protocols;
  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.Metadata;
  10. import oram.Tree;
  11. import oram.Tuple;
  12. import protocols.precomputation.PreRetrieve;
  13. import protocols.struct.OutAccess;
  14. import protocols.struct.Party;
  15. import protocols.struct.PreData;
  16. import util.Bandwidth;
  17. import util.P;
  18. import util.StopWatch;
  19. import util.Timer;
  20. import util.Util;
  21. public class Retrieve extends Protocol {
  22. public Retrieve(Communication con1, Communication con2) {
  23. super(con1, con2);
  24. }
  25. public OutAccess runE(PreData[] predata, Tree OTi, byte[] Ni, byte[] Nip1_pr, int h, Timer timer) {
  26. // 1st eviction
  27. Access access = new Access(con1, con2);
  28. Reshuffle reshuffle = new Reshuffle(con1, con2);
  29. PostProcessT postprocesst = new PostProcessT(con1, con2);
  30. UpdateRoot updateroot = new UpdateRoot(con1, con2);
  31. Eviction eviction = new Eviction(con1, con2);
  32. OutAccess outaccess = access.runE(predata[0], OTi, Ni, Nip1_pr, timer);
  33. Tuple[] path = reshuffle.runE(predata[0], outaccess.E_P, OTi.getTreeIndex() == 0, timer);
  34. Tuple Ti = postprocesst.runE(predata[0], outaccess.E_Ti, OTi.getTreeIndex() == h - 1, timer);
  35. Tuple[] root = Arrays.copyOfRange(path, 0, OTi.getStashSize());
  36. root = updateroot.runE(predata[0], OTi.getTreeIndex() == 0, outaccess.Li, root, Ti, timer);
  37. System.arraycopy(root, 0, path, 0, root.length);
  38. eviction.runE(predata[0], OTi.getTreeIndex() == 0, outaccess.Li,
  39. OTi.getTreeIndex() == 0 ? new Tuple[] { Ti } : path, OTi, timer);
  40. // 2nd eviction
  41. OutAccess outaccess2 = access.runE2(OTi, timer);
  42. Tuple[] path2 = outaccess2.E_P;
  43. Tuple Ti2 = outaccess2.E_Ti;
  44. Tuple[] root2 = Arrays.copyOfRange(path2, 0, OTi.getStashSize());
  45. root2 = updateroot.runE(predata[1], OTi.getTreeIndex() == 0, outaccess2.Li, root2, Ti2, timer);
  46. System.arraycopy(root2, 0, path2, 0, root2.length);
  47. eviction.runE(predata[1], OTi.getTreeIndex() == 0, outaccess2.Li,
  48. OTi.getTreeIndex() == 0 ? new Tuple[] { Ti2 } : path2, OTi, timer);
  49. return outaccess;
  50. }
  51. public void runD(PreData predata[], Tree OTi, byte[] Ni, byte[] Nip1_pr, Timer timer) {
  52. // 1st eviction
  53. Access access = new Access(con1, con2);
  54. Reshuffle reshuffle = new Reshuffle(con1, con2);
  55. PostProcessT postprocesst = new PostProcessT(con1, con2);
  56. UpdateRoot updateroot = new UpdateRoot(con1, con2);
  57. Eviction eviction = new Eviction(con1, con2);
  58. byte[] Li = access.runD(predata[0], OTi, Ni, Nip1_pr, timer);
  59. reshuffle.runD();
  60. postprocesst.runD();
  61. updateroot.runD(predata[0], OTi.getTreeIndex() == 0, Li, OTi.getW(), timer);
  62. eviction.runD(predata[0], OTi.getTreeIndex() == 0, Li, OTi, timer);
  63. // 2nd eviction
  64. byte[] Li2 = access.runD2(OTi, timer);
  65. updateroot.runD(predata[1], OTi.getTreeIndex() == 0, Li2, OTi.getW(), timer);
  66. eviction.runD(predata[1], OTi.getTreeIndex() == 0, Li2, OTi, timer);
  67. }
  68. public OutAccess runC(PreData[] predata, Metadata md, int ti, byte[] Li, int h, Timer timer) {
  69. // 1st eviction
  70. Access access = new Access(con1, con2);
  71. Reshuffle reshuffle = new Reshuffle(con1, con2);
  72. PostProcessT postprocesst = new PostProcessT(con1, con2);
  73. UpdateRoot updateroot = new UpdateRoot(con1, con2);
  74. Eviction eviction = new Eviction(con1, con2);
  75. OutAccess outaccess = access.runC(md, ti, Li, timer);
  76. Tuple[] path = reshuffle.runC(predata[0], outaccess.C_P, ti == 0, timer);
  77. Tuple Ti = postprocesst.runC(predata[0], outaccess.C_Ti, Li, outaccess.C_Lip1, outaccess.C_j2, ti == h - 1,
  78. timer);
  79. Tuple[] root = Arrays.copyOfRange(path, 0, md.getStashSizeOfTree(ti));
  80. root = updateroot.runC(predata[0], ti == 0, root, Ti, timer);
  81. System.arraycopy(root, 0, path, 0, root.length);
  82. eviction.runC(predata[0], ti == 0, ti == 0 ? new Tuple[] { Ti } : path, md.getLBitsOfTree(ti) + 1,
  83. md.getStashSizeOfTree(ti), md.getW(), timer);
  84. // 2nd eviction
  85. byte[] Li2 = Util.nextBytes(md.getLBytesOfTree(ti), Crypto.sr);
  86. OutAccess outaccess2 = access.runC2(md, ti, Li2, timer);
  87. Tuple[] path2 = outaccess2.C_P;
  88. Tuple Ti2 = outaccess2.C_Ti;
  89. Tuple[] root2 = Arrays.copyOfRange(path2, 0, md.getStashSizeOfTree(ti));
  90. root2 = updateroot.runC(predata[1], ti == 0, root2, Ti2, timer);
  91. System.arraycopy(root2, 0, path2, 0, root2.length);
  92. eviction.runC(predata[1], ti == 0, ti == 0 ? new Tuple[] { Ti2 } : path2, md.getLBitsOfTree(ti) + 1,
  93. md.getStashSizeOfTree(ti), md.getW(), timer);
  94. return outaccess;
  95. }
  96. // for testing correctness
  97. @Override
  98. public void run(Party party, Metadata md, Forest forest) {
  99. if (Metadata.cheat)
  100. System.out.println("Cheat Mode is On");
  101. int records = 6;
  102. int repeat = 5;
  103. int reset = 1;
  104. int tau = md.getTau();
  105. int numTrees = md.getNumTrees();
  106. long numInsert = md.getNumInsertRecords();
  107. int addrBits = md.getAddrBits();
  108. Timer timer = new Timer();
  109. StopWatch ete_off = new StopWatch("ETE_offline");
  110. StopWatch ete_on = new StopWatch("ETE_online");
  111. long[] gates = new long[2];
  112. sanityCheck();
  113. System.out.println();
  114. for (int i = 0; i < records; i++) {
  115. long N = Metadata.cheat ? 0 : Util.nextLong(numInsert, Crypto.sr);
  116. for (int j = 0; j < repeat; j++) {
  117. int cycleIndex = i * repeat + j;
  118. if (cycleIndex == reset * repeat)
  119. timer.reset();
  120. if (cycleIndex == 1) {
  121. con1.bandSwitch = false;
  122. con2.bandSwitch = false;
  123. }
  124. System.out.println("Test: " + i + " " + j);
  125. System.out.println("N=" + BigInteger.valueOf(N).toString(2));
  126. System.out.print("Precomputation... ");
  127. PreData[][] predata = new PreData[numTrees][2];
  128. PreRetrieve preretrieve = new PreRetrieve(con1, con2);
  129. for (int ti = 0; ti < numTrees; ti++) {
  130. predata[ti][0] = new PreData();
  131. predata[ti][1] = new PreData();
  132. if (party == Party.Eddie) {
  133. ete_off.start();
  134. preretrieve.runE(predata[ti], md, ti, timer);
  135. ete_off.stop();
  136. } else if (party == Party.Debbie) {
  137. ete_off.start();
  138. long[] cnt = preretrieve.runD(predata[ti], md, ti, ti == 0 ? null : predata[ti - 1][0], timer);
  139. ete_off.stop();
  140. if (cycleIndex == 0) {
  141. gates[0] += cnt[0];
  142. gates[1] += cnt[1];
  143. }
  144. } else if (party == Party.Charlie) {
  145. ete_off.start();
  146. preretrieve.runC(predata[ti], md, ti, ti == 0 ? null : predata[ti - 1][0], timer);
  147. ete_off.stop();
  148. } else {
  149. throw new NoSuchPartyException(party + "");
  150. }
  151. }
  152. System.out.println("done!");
  153. byte[] Li = new byte[0];
  154. for (int ti = 0; ti < numTrees; ti++) {
  155. long Ni_value = Util.getSubBits(N, addrBits, addrBits - md.getNBitsOfTree(ti));
  156. long Nip1_pr_value = Util.getSubBits(N, addrBits - md.getNBitsOfTree(ti),
  157. Math.max(addrBits - md.getNBitsOfTree(ti) - tau, 0));
  158. byte[] Ni = Util.longToBytes(Ni_value, md.getNBytesOfTree(ti));
  159. byte[] Nip1_pr = Util.longToBytes(Nip1_pr_value, (tau + 7) / 8);
  160. if (party == Party.Eddie) {
  161. Tree OTi = forest.getTree(ti);
  162. byte[] sE_Ni = Util.nextBytes(Ni.length, Crypto.sr);
  163. byte[] sD_Ni = Util.xor(Ni, sE_Ni);
  164. con1.write(sD_Ni);
  165. byte[] sE_Nip1_pr = Util.nextBytes(Nip1_pr.length, Crypto.sr);
  166. byte[] sD_Nip1_pr = Util.xor(Nip1_pr, sE_Nip1_pr);
  167. con1.write(sD_Nip1_pr);
  168. ete_on.start();
  169. runE(predata[ti], OTi, sE_Ni, sE_Nip1_pr, numTrees, timer);
  170. ete_on.stop();
  171. if (ti == numTrees - 1)
  172. con2.write(N);
  173. } else if (party == Party.Debbie) {
  174. Tree OTi = forest.getTree(ti);
  175. byte[] sD_Ni = con1.read();
  176. byte[] sD_Nip1_pr = con1.read();
  177. ete_on.start();
  178. runD(predata[ti], OTi, sD_Ni, sD_Nip1_pr, timer);
  179. ete_on.stop();
  180. } else if (party == Party.Charlie) {
  181. int lBits = md.getLBitsOfTree(ti);
  182. System.out.println("L" + ti + "="
  183. + Util.addZeros(Util.getSubBits(new BigInteger(1, Li), lBits, 0).toString(2), lBits));
  184. ete_on.start();
  185. OutAccess outaccess = runC(predata[ti], md, ti, Li, numTrees, timer);
  186. ete_on.stop();
  187. Li = outaccess.C_Lip1;
  188. if (ti == numTrees - 1) {
  189. N = con1.readLong();
  190. long data = new BigInteger(1, outaccess.C_Ti.getA()).longValue();
  191. if (N == data) {
  192. System.out.println("Access passed");
  193. System.out.println();
  194. } else {
  195. throw new AccessException("Access failed");
  196. }
  197. }
  198. } else {
  199. throw new NoSuchPartyException(party + "");
  200. }
  201. }
  202. }
  203. }
  204. System.out.println();
  205. timer.noPrePrint();
  206. // timer.divideBy((records-reset)*repeat).print();
  207. System.out.println();
  208. System.out.println(ete_on.noPreToMS());
  209. System.out.println(ete_off.noPreToMS());
  210. System.out.println();
  211. Bandwidth[] bandwidth = new Bandwidth[P.size];
  212. for (int i = 0; i < P.size; i++) {
  213. bandwidth[i] = con1.bandwidth[i].add(con2.bandwidth[i]);
  214. System.out.println(bandwidth[i].noPreToString());
  215. }
  216. System.out.println();
  217. System.out.println(gates[0]);
  218. System.out.println(gates[1]);
  219. System.out.println();
  220. }
  221. }