GCRoute.java 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. package gc;
  2. import java.util.Arrays;
  3. import com.oblivm.backend.circuits.arithmetic.IntegerLib;
  4. import com.oblivm.backend.flexsc.CompEnv;
  5. public class GCRoute<T> extends IntegerLib<T> {
  6. private int d;
  7. private int w;
  8. private int logD;
  9. private int logW;
  10. // d: tree depth
  11. // w: non-root bucket width
  12. public GCRoute(CompEnv<T> e, int d, int w) {
  13. super(e);
  14. this.d = d;
  15. this.w = w;
  16. logD = (int) Math.ceil(Math.log(d) / Math.log(2));
  17. logW = (int) Math.ceil(Math.log(w + 1) / Math.log(2)); // includes fake
  18. // empty tuple
  19. }
  20. public T[][][] routing(T[] Li, T[][] E_feBits, T[][] C_feBits, T[][][] E_tupleLabels, T[][][] C_tupleLabels,
  21. T[][] delta) {
  22. T[][] feBits = env.newTArray(d, 0);
  23. T[][][] tupleLabels = env.newTArray(d, w, 0);
  24. for (int i = 0; i < d; i++) {
  25. feBits[i] = xor(E_feBits[i], C_feBits[i]);
  26. for (int j = 0; j < w; j++) {
  27. tupleLabels[i][j] = xor(E_tupleLabels[i][j], C_tupleLabels[i][j]);
  28. }
  29. }
  30. T[][][] pd = prepareDeepest(Li, feBits, tupleLabels);
  31. T[][][] ptai = prepareTargetAndIndex(pd[0], pd[1], pd[2], pd[3], delta);
  32. T[][] target = makeCycle(ptai[0], ptai[2][0], ptai[2][1], ptai[2][2], ptai[2][3]);
  33. T[][][] output = env.newTArray(2, 0, 0);
  34. output[0] = target;
  35. output[1] = ptai[1];
  36. // rm sign bit
  37. for (int i = 0; i < output[0].length; i++) {
  38. output[0][i] = Arrays.copyOfRange(output[0][i], 0, logD);
  39. output[1][i] = Arrays.copyOfRange(output[1][i], 0, logW);
  40. }
  41. return output;
  42. }
  43. private void zerosFollowedByOnes(T[] input) {
  44. for (int i = input.length - 2; i >= 0; i--) {
  45. input[i] = or(input[i], input[i + 1]);
  46. }
  47. }
  48. public T[][] findDeepestAndEmpty(int i, T[] pathLabel, T[] feBits, T[][] tupleLabels) {
  49. T[] l = padSignal(ones(d - 1 - i), d); // has sign bit
  50. T[] j1 = zeros(logW); // no sign bit
  51. T[] j2 = zeros(logW);
  52. T[] et = zeros(1);
  53. for (int j = 0; j < w; j++) {
  54. T[] tupleIndex = toSignals(j, logW);
  55. T[] lz = xor(pathLabel, tupleLabels[j]);
  56. zerosFollowedByOnes(lz);
  57. lz = padSignal(lz, d); // add sign bit
  58. T firstIf = and(feBits[j], less(lz, l));
  59. l = mux(l, lz, firstIf);
  60. j1 = mux(j1, tupleIndex, firstIf);
  61. et = mux(ones(1), et, feBits[j]);
  62. j2 = mux(tupleIndex, j2, feBits[j]);
  63. }
  64. T[] l_p = numberOfOnes(not(Arrays.copyOfRange(l, 0, d - 1))); // has
  65. // sign
  66. // bit
  67. T[][] output = env.newTArray(4, 0);
  68. output[0] = l_p;
  69. output[1] = padSignal(j1, logW + 1); // add sign bit
  70. output[2] = padSignal(j2, logW + 1);
  71. output[3] = et;
  72. return output;
  73. }
  74. public T[][][] prepareDeepest(T[] Li, T[][] feBits, T[][][] tupleLabels) {
  75. T[] perpD = ones(logD + 1);
  76. T[][][] output = env.newTArray(4, d, 0);
  77. T[][] deepest = env.newTArray(d, 0);
  78. for (int j = 0; j < d; j++)
  79. deepest[j] = perpD;
  80. T[] src = perpD;
  81. T[] goal = perpD; // \perp = -1 in 2's complement form
  82. for (int i = 0; i < d; i++) {
  83. T[] index = toSignals(i, logD + 1);
  84. deepest[i] = mux(deepest[i], src, geq(goal, index));
  85. T[][] dae = findDeepestAndEmpty(i, Li, feBits[i], tupleLabels[i]);
  86. T[] l = dae[0];
  87. output[1][i] = dae[1];
  88. output[2][i] = dae[2];
  89. output[3][i] = dae[3];
  90. T lGreaterGoal = greater(l, goal);
  91. goal = mux(goal, l, lGreaterGoal);
  92. src = mux(src, index, lGreaterGoal);
  93. }
  94. output[0] = deepest;
  95. return output;
  96. }
  97. public T[][][] prepareTargetAndIndex(T[][] deepest, T[][] j1, T[][] j2, T[][] et, T[][] delta) {
  98. T[] ft = toSignals(w, logW + 1);
  99. T[] perpD = ones(logD + 1);
  100. T[] perpW = ones(logW + 1);
  101. T[][][] output = env.newTArray(3, 4, 0);
  102. T[] nTop = perpD;
  103. T[] nBot = perpD;
  104. T[] eTop = perpD;
  105. T[] eBot = perpD;
  106. T[] src = perpD;
  107. T[] dest = perpD;
  108. T[][] target = env.newTArray(d, 0);
  109. T[][] f = env.newTArray(d, 0);
  110. for (int i = 0; i < d; i++) {
  111. target[i] = perpD;
  112. f[i] = perpW;
  113. }
  114. for (int i = d - 1; i >= 0; i--) {
  115. T[] index = toSignals(i, logD + 1);
  116. T iEqSrc = eq(index, src);
  117. target[i] = mux(target[i], dest, iEqSrc);
  118. f[i] = mux(f[i], j1[i], iEqSrc);
  119. src = mux(src, perpD, iEqSrc);
  120. T deepestEqPerp = eq(deepest[i], perpD);
  121. dest = mux(dest, index, and(iEqSrc, deepestEqPerp));
  122. dest = mux(dest, perpD, and(iEqSrc, not(deepestEqPerp)));
  123. T destEqPerp = eq(dest, perpD);
  124. T srcEqPerp = eq(src, perpD);
  125. T fourthIf = and(not(deepestEqPerp), and(not(destEqPerp), srcEqPerp));
  126. target[i] = mux(target[i], dest, fourthIf);
  127. f[i] = mux(f[i], j2[i], fourthIf);
  128. T targetEqPerp = eq(target[i], perpD);
  129. T fifthIf = and(not(deepestEqPerp), or(and(destEqPerp, et[i][0]), not(targetEqPerp)));
  130. src = mux(src, deepest[i], fifthIf);
  131. dest = mux(dest, index, fifthIf);
  132. eTop = mux(eTop, src, fifthIf);
  133. T eBotEqPerp = eq(eBot, perpD);
  134. T sixthIf = and(fifthIf, eBotEqPerp);
  135. eBot = mux(eBot, dest, sixthIf);
  136. f[i] = mux(f[i], j2[i], sixthIf);
  137. T fEqPerp = eq(f[i], perpW);
  138. f[i] = mux(f[i], ft, fEqPerp);
  139. nTop = mux(nTop, index, fEqPerp);
  140. T nBotEqPerp = eq(nBot, perpD);
  141. nBot = mux(nBot, index, and(fEqPerp, nBotEqPerp));
  142. f[i] = xor(f[i], padSignal(delta[i], logW + 1));
  143. }
  144. output[0] = target;
  145. output[1] = f;
  146. output[2][0] = nTop;
  147. output[2][1] = nBot;
  148. output[2][2] = eTop;
  149. output[2][3] = eBot;
  150. return output;
  151. }
  152. public T[][] makeCycle(T[][] target, T[] nTop, T[] nBot, T[] eTop, T[] eBot) {
  153. T[] perpD = ones(logD + 1);
  154. T[] nPrev = perpD;
  155. for (int i = 0; i < d; i++) {
  156. T[] index = toSignals(i, logD + 1);
  157. T nTopEqPerp = eq(nTop, perpD);
  158. T iEqEBot = eq(index, eBot);
  159. target[i] = mux(target[i], eTop, and(nTopEqPerp, iEqEBot));
  160. T thirdIf = and(not(nTopEqPerp), iEqEBot);
  161. target[i] = mux(target[i], nBot, thirdIf);
  162. T fourthIf = and(not(or(nTopEqPerp, iEqEBot)), eq(target[i], perpD));
  163. T iEqNTop = eq(index, nTop);
  164. T fifthIf = and(fourthIf, iEqNTop);
  165. T eTopEqPerp = eq(eTop, perpD);
  166. target[i] = mux(target[i], nBot, and(fifthIf, eTopEqPerp));
  167. target[i] = mux(target[i], eTop, and(fifthIf, not(eTopEqPerp)));
  168. target[i] = mux(target[i], nPrev, and(fourthIf, not(iEqNTop)));
  169. nPrev = mux(nPrev, index, fourthIf);
  170. }
  171. return target;
  172. }
  173. }