Eviction.java 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. package protocols;
  2. import java.math.BigInteger;
  3. import java.util.Arrays;
  4. import com.oblivm.backend.gc.GCSignal;
  5. import communication.Communication;
  6. import gc.GCUtil;
  7. import oram.Bucket;
  8. import oram.Forest;
  9. import oram.Metadata;
  10. import oram.Tree;
  11. import oram.Tuple;
  12. import protocols.struct.Party;
  13. import protocols.struct.PreData;
  14. import util.M;
  15. import util.P;
  16. import util.Timer;
  17. import util.Util;
  18. public class Eviction extends Protocol {
  19. private int pid = P.EVI;
  20. public Eviction(Communication con1, Communication con2) {
  21. super(con1, con2);
  22. }
  23. private int[] prepareEviction(int target[], int[] ti, int W) {
  24. int d = ti.length;
  25. int[] evict = new int[W * d];
  26. for (int r = 0; r < d; r++) {
  27. int tupleIndex = r * W + ti[r];
  28. for (int c = 0; c < W; c++) {
  29. int currIndex = r * W + c;
  30. if (currIndex == tupleIndex) {
  31. int targetIndex = target[r] * W + ti[target[r]];
  32. evict[targetIndex] = currIndex;
  33. } else
  34. evict[currIndex] = currIndex;
  35. }
  36. }
  37. return evict;
  38. }
  39. public void runE(PreData predata, boolean firstTree, byte[] Li, Tuple[] originalPath, Tree OTi, Timer timer) {
  40. timer.start(pid, M.online_comp);
  41. if (firstTree) {
  42. OTi.setBucketsOnPath(new BigInteger(1, Li).longValue(), new Bucket[] { new Bucket(originalPath) });
  43. timer.stop(pid, M.online_comp);
  44. return;
  45. }
  46. int d = OTi.getD();
  47. int sw = OTi.getStashSize();
  48. int w = OTi.getW();
  49. Tuple[] pathTuples = new Tuple[d * w];
  50. System.arraycopy(originalPath, 0, pathTuples, 0, w);
  51. System.arraycopy(originalPath, sw, pathTuples, w, (d - 1) * w);
  52. Bucket[] pathBuckets = Bucket.tuplesToBuckets(pathTuples, d, w, w);
  53. GCSignal[] LiInputKeys = GCUtil.revSelectKeys(predata.evict_LiKeyPairs, Li);
  54. GCSignal[][] E_feInputKeys = new GCSignal[d][];
  55. GCSignal[][][] E_labelInputKeys = new GCSignal[d][][];
  56. GCSignal[][] deltaInputKeys = new GCSignal[d][];
  57. for (int i = 0; i < d; i++) {
  58. E_feInputKeys[i] = GCUtil.selectFeKeys(predata.evict_E_feKeyPairs[i], pathBuckets[i].getTuples());
  59. E_labelInputKeys[i] = GCUtil.selectLabelKeys(predata.evict_E_labelKeyPairs[i], pathBuckets[i].getTuples());
  60. deltaInputKeys[i] = GCUtil.revSelectKeys(predata.evict_deltaKeyPairs[i], predata.evict_delta[i]);
  61. }
  62. timer.start(pid, M.online_write);
  63. con1.write(pid, LiInputKeys);
  64. con1.write(pid, E_feInputKeys);
  65. con1.write(pid, E_labelInputKeys);
  66. con1.write(pid, deltaInputKeys);
  67. timer.stop(pid, M.online_write);
  68. PermuteTarget permutetarget = new PermuteTarget(con1, con2);
  69. permutetarget.runE();
  70. PermuteIndex permuteindex = new PermuteIndex(con1, con2);
  71. permuteindex.runE();
  72. int logW = (int) Math.ceil(Math.log(w + 1) / Math.log(2));
  73. int W = (int) Math.pow(2, logW);
  74. for (int i = 0; i < d; i++) {
  75. pathBuckets[i].expand(W);
  76. pathBuckets[i].permute(predata.evict_delta_p[i]);
  77. }
  78. pathBuckets = Util.permute(pathBuckets, predata.evict_pi);
  79. for (int i = 0; i < d; i++) {
  80. pathBuckets[i].permute(predata.evict_rho_p[i]);
  81. }
  82. pathTuples = Bucket.bucketsToTuples(pathBuckets);
  83. SSXOT ssxot = new SSXOT(con1, con2, 1);
  84. pathTuples = ssxot.runE(predata, pathTuples, timer);
  85. pathBuckets = Bucket.tuplesToBuckets(pathTuples, d, W, W);
  86. for (int i = 0; i < d; i++) {
  87. int[] rho_ivs = Util.inversePermutation(predata.evict_rho_p[i]);
  88. pathBuckets[i].permute(rho_ivs);
  89. }
  90. int[] pi_ivs = Util.inversePermutation(predata.evict_pi);
  91. pathBuckets = Util.permute(pathBuckets, pi_ivs);
  92. for (int i = 0; i < d; i++) {
  93. int[] delta_ivs = Util.inversePermutation(predata.evict_delta_p[i]);
  94. pathBuckets[i].permute(delta_ivs);
  95. pathBuckets[i].shrink(w);
  96. }
  97. pathBuckets[0].expand(Arrays.copyOfRange(originalPath, w, sw));
  98. OTi.setBucketsOnPath(new BigInteger(1, Li).longValue(), pathBuckets);
  99. timer.stop(pid, M.online_comp);
  100. }
  101. public void runD(PreData predata, boolean firstTree, byte[] Li, Tree OTi, Timer timer) {
  102. timer.start(pid, M.online_comp);
  103. if (firstTree) {
  104. timer.start(pid, M.online_read);
  105. Tuple[] originalPath = con2.readTupleArray(pid);
  106. timer.stop(pid, M.online_read);
  107. OTi.setBucketsOnPath(new BigInteger(1, Li).longValue(), new Bucket[] { new Bucket(originalPath) });
  108. timer.stop(pid, M.online_comp);
  109. return;
  110. }
  111. timer.start(pid, M.online_read);
  112. GCSignal[] LiInputKeys = con1.readGCSignalArray(pid);
  113. GCSignal[][] E_feInputKeys = con1.readDoubleGCSignalArray(pid);
  114. GCSignal[][][] E_labelInputKeys = con1.readTripleGCSignalArray(pid);
  115. GCSignal[][] deltaInputKeys = con1.readDoubleGCSignalArray(pid);
  116. GCSignal[][] C_feInputKeys = con2.readDoubleGCSignalArray(pid);
  117. GCSignal[][][] C_labelInputKeys = con2.readTripleGCSignalArray(pid);
  118. timer.stop(pid, M.online_read);
  119. int w = OTi.getW();
  120. int logW = (int) Math.ceil(Math.log(w + 1) / Math.log(2));
  121. GCSignal[][][] outKeys = predata.evict_gcroute.routing(LiInputKeys, E_feInputKeys, C_feInputKeys,
  122. E_labelInputKeys, C_labelInputKeys, deltaInputKeys);
  123. byte[][] ti_p = new byte[deltaInputKeys.length][];
  124. for (int i = 0; i < ti_p.length; i++) {
  125. ti_p[i] = Util.padArray(GCUtil.evaOutKeys(outKeys[1][i], predata.evict_tiOutKeyHashes[i]).toByteArray(),
  126. (logW + 7) / 8);
  127. }
  128. PermuteTarget permutetarget = new PermuteTarget(con1, con2);
  129. int[] target_pp = permutetarget.runD(predata, firstTree, outKeys[0], timer);
  130. PermuteIndex permuteindex = new PermuteIndex(con1, con2);
  131. int[] ti_pp = permuteindex.runD(predata, firstTree, ti_p, w, timer);
  132. int W = (int) Math.pow(2, logW);
  133. int[] evict = prepareEviction(target_pp, ti_pp, W);
  134. SSXOT ssxot = new SSXOT(con1, con2, 1);
  135. ssxot.runD(predata, evict, timer);
  136. timer.start(pid, M.online_read);
  137. Bucket[] pathBuckets = con2.readBucketArray(pid);
  138. timer.stop(pid, M.online_read);
  139. OTi.setBucketsOnPath(new BigInteger(1, Li).longValue(), pathBuckets);
  140. timer.stop(pid, M.online_comp);
  141. }
  142. public void runC(PreData predata, boolean firstTree, Tuple[] originalPath, int d, int sw, int w, Timer timer) {
  143. if (firstTree) {
  144. timer.start(pid, M.online_write);
  145. con2.write(pid, originalPath);
  146. timer.stop(pid, M.online_write);
  147. return;
  148. }
  149. timer.start(pid, M.online_comp);
  150. Tuple[] pathTuples = new Tuple[d * w];
  151. System.arraycopy(originalPath, 0, pathTuples, 0, w);
  152. System.arraycopy(originalPath, sw, pathTuples, w, (d - 1) * w);
  153. Bucket[] pathBuckets = Bucket.tuplesToBuckets(pathTuples, d, w, w);
  154. GCSignal[][] C_feInputKeys = new GCSignal[d][];
  155. GCSignal[][][] C_labelInputKeys = new GCSignal[d][][];
  156. for (int i = 0; i < d; i++) {
  157. C_feInputKeys[i] = GCUtil.selectFeKeys(predata.evict_C_feKeyPairs[i], pathBuckets[i].getTuples());
  158. C_labelInputKeys[i] = GCUtil.selectLabelKeys(predata.evict_C_labelKeyPairs[i], pathBuckets[i].getTuples());
  159. }
  160. timer.start(pid, M.online_write);
  161. con2.write(pid, C_feInputKeys);
  162. con2.write(pid, C_labelInputKeys);
  163. timer.stop(pid, M.online_write);
  164. PermuteTarget permutetarget = new PermuteTarget(con1, con2);
  165. permutetarget.runC(predata, firstTree, timer);
  166. PermuteIndex permuteindex = new PermuteIndex(con1, con2);
  167. permuteindex.runC(predata, firstTree, timer);
  168. int logW = (int) Math.ceil(Math.log(w + 1) / Math.log(2));
  169. int W = (int) Math.pow(2, logW);
  170. for (int i = 0; i < d; i++) {
  171. pathBuckets[i].expand(W);
  172. pathBuckets[i].permute(predata.evict_delta_p[i]);
  173. }
  174. pathBuckets = Util.permute(pathBuckets, predata.evict_pi);
  175. for (int i = 0; i < d; i++) {
  176. pathBuckets[i].permute(predata.evict_rho_p[i]);
  177. }
  178. pathTuples = Bucket.bucketsToTuples(pathBuckets);
  179. SSXOT ssxot = new SSXOT(con1, con2, 1);
  180. pathTuples = ssxot.runC(predata, pathTuples, timer);
  181. pathBuckets = Bucket.tuplesToBuckets(pathTuples, d, W, W);
  182. for (int i = 0; i < d; i++) {
  183. int[] rho_ivs = Util.inversePermutation(predata.evict_rho_p[i]);
  184. pathBuckets[i].permute(rho_ivs);
  185. }
  186. int[] pi_ivs = Util.inversePermutation(predata.evict_pi);
  187. pathBuckets = Util.permute(pathBuckets, pi_ivs);
  188. for (int i = 0; i < d; i++) {
  189. int[] delta_ivs = Util.inversePermutation(predata.evict_delta_p[i]);
  190. pathBuckets[i].permute(delta_ivs);
  191. pathBuckets[i].shrink(w);
  192. }
  193. pathBuckets[0].expand(Arrays.copyOfRange(originalPath, w, sw));
  194. timer.start(pid, M.online_write);
  195. con2.write(pid, pathBuckets);
  196. timer.stop(pid, M.online_write);
  197. timer.stop(pid, M.online_comp);
  198. }
  199. // for testing correctness
  200. @Override
  201. public void run(Party party, Metadata md, Forest forest) {
  202. System.out.println("Use Retrieve to test Eviction");
  203. }
  204. }