Eviction.java 8.4 KB

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