PIRAccess.java 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. package protocols;
  2. import java.math.BigInteger;
  3. import org.apache.commons.lang3.ArrayUtils;
  4. import communication.Communication;
  5. import crypto.Crypto;
  6. import exceptions.NoSuchPartyException;
  7. import oram.Bucket;
  8. import oram.Forest;
  9. import oram.Metadata;
  10. import oram.Tree;
  11. import oram.Tuple;
  12. import struct.OutPIRAccess;
  13. import struct.OutPIRCOT;
  14. import struct.Party;
  15. import struct.TwoOneXor;
  16. import struct.TwoThreeXorByte;
  17. import struct.TwoThreeXorInt;
  18. import subprotocols.PIRCOT;
  19. import subprotocols.ThreeShiftPIR;
  20. import subprotocols.ThreeShiftXorPIR;
  21. import util.M;
  22. import util.P;
  23. import util.Util;
  24. public class PIRAccess extends Protocol {
  25. int pid = P.ACC;
  26. public PIRAccess(Communication con1, Communication con2) {
  27. super(con1, con2);
  28. online_band = all.online_band[pid];
  29. offline_band = all.offline_band[pid];
  30. timer = all.timer[pid];
  31. }
  32. public OutPIRAccess runE(Metadata md, Tree tree_DE, Tree tree_CE, byte[] Li, TwoThreeXorByte L, TwoThreeXorByte N,
  33. TwoThreeXorInt dN) {
  34. timer.start(M.online_comp);
  35. Bucket[] pathBuckets_DE = tree_DE.getBucketsOnPath(Li);
  36. Tuple[] pathTuples_DE = Bucket.bucketsToTuples(pathBuckets_DE);
  37. Bucket[] pathBuckets_CE = tree_CE.getBucketsOnPath(Li);
  38. Tuple[] pathTuples_CE = Bucket.bucketsToTuples(pathBuckets_CE);
  39. int pathTuples = pathTuples_CE.length;
  40. int ttp = md.getTwoTauPow();
  41. int treeIndex = tree_DE.getTreeIndex();
  42. boolean isLastTree = treeIndex == md.getNumTrees() - 1;
  43. boolean isFirstTree = treeIndex == 0;
  44. byte[][] x_DE = new byte[pathTuples][];
  45. byte[][] x_CE = new byte[pathTuples][];
  46. for (int i = 0; i < pathTuples; i++) {
  47. x_DE[i] = pathTuples_DE[i].getA();
  48. x_CE[i] = pathTuples_CE[i].getA();
  49. }
  50. OutPIRCOT j = new OutPIRCOT();
  51. TwoOneXor dN21 = new TwoOneXor();
  52. TwoThreeXorByte X = new TwoThreeXorByte();
  53. if (isFirstTree) {
  54. X.DE = x_DE[0];
  55. X.CE = x_CE[0];
  56. } else {
  57. byte[][] u = new byte[pathTuples][];
  58. for (int i = 0; i < pathTuples; i++) {
  59. u[i] = ArrayUtils.addAll(pathTuples_CE[i].getF(), pathTuples_CE[i].getN());
  60. }
  61. byte[] v = ArrayUtils.addAll(new byte[] { 1 }, N.CE);
  62. PIRCOT ksearch = new PIRCOT(con1, con2);
  63. j = ksearch.runE(u, v);
  64. ThreeShiftPIR threeshiftpir = new ThreeShiftPIR(con1, con2, Crypto.sr_DE, Crypto.sr_CE);
  65. X = threeshiftpir.runE(x_DE, x_CE, j);
  66. dN21.t_E = dN.CE ^ dN.DE;
  67. dN21.s_CE = dN.CE;
  68. dN21.s_DE = dN.DE;
  69. }
  70. TwoThreeXorByte nextL = null;
  71. byte[] Lip1 = null;
  72. if (!isLastTree) {
  73. ThreeShiftXorPIR threeshiftxorpir = new ThreeShiftXorPIR(con1, con2, Crypto.sr_DE, Crypto.sr_CE);
  74. nextL = threeshiftxorpir.runE(x_DE, x_CE, j, dN21, ttp);
  75. Lip1 = Util.xor(Util.xor(nextL.DE, nextL.CE), nextL.CD);
  76. }
  77. OutPIRAccess out = new OutPIRAccess(null, pathTuples_CE, pathTuples_DE, j, X, nextL, Lip1);
  78. timer.stop(M.online_comp);
  79. return out;
  80. }
  81. public OutPIRAccess runD(Metadata md, Tree tree_DE, Tree tree_CD, byte[] Li, TwoThreeXorByte L, TwoThreeXorByte N,
  82. TwoThreeXorInt dN) {
  83. timer.start(M.online_comp);
  84. Bucket[] pathBuckets_DE = tree_DE.getBucketsOnPath(Li);
  85. Tuple[] pathTuples_DE = Bucket.bucketsToTuples(pathBuckets_DE);
  86. Bucket[] pathBuckets_CD = tree_CD.getBucketsOnPath(Li);
  87. Tuple[] pathTuples_CD = Bucket.bucketsToTuples(pathBuckets_CD);
  88. int pathTuples = pathTuples_CD.length;
  89. int ttp = md.getTwoTauPow();
  90. int treeIndex = tree_DE.getTreeIndex();
  91. boolean isLastTree = treeIndex == md.getNumTrees() - 1;
  92. boolean isFirstTree = treeIndex == 0;
  93. byte[][] x_DE = new byte[pathTuples][];
  94. byte[][] x_CD = new byte[pathTuples][];
  95. for (int i = 0; i < pathTuples; i++) {
  96. x_DE[i] = pathTuples_DE[i].getA();
  97. x_CD[i] = pathTuples_CD[i].getA();
  98. }
  99. OutPIRCOT j = new OutPIRCOT();
  100. TwoOneXor dN21 = new TwoOneXor();
  101. TwoThreeXorByte X = new TwoThreeXorByte();
  102. if (isFirstTree) {
  103. X.DE = x_DE[0];
  104. X.CD = x_CD[0];
  105. } else {
  106. byte[][] u = new byte[pathTuples][];
  107. for (int i = 0; i < pathTuples; i++) {
  108. u[i] = ArrayUtils.addAll(pathTuples_DE[i].getF(), pathTuples_DE[i].getN());
  109. Util.setXor(u[i], ArrayUtils.addAll(pathTuples_CD[i].getF(), pathTuples_CD[i].getN()));
  110. }
  111. byte[] v = ArrayUtils.addAll(new byte[] { 1 }, N.CE);
  112. Util.setXor(v, ArrayUtils.addAll(new byte[] { 1 }, N.CD));
  113. PIRCOT ksearch = new PIRCOT(con1, con2);
  114. j = ksearch.runD(u, v);
  115. ThreeShiftPIR threeshiftpir = new ThreeShiftPIR(con1, con2, Crypto.sr_DE, Crypto.sr_CD);
  116. X = threeshiftpir.runD(x_DE, x_CD, j);
  117. dN21.t_D = dN.CD ^ dN.DE;
  118. dN21.s_CD = dN.CD;
  119. dN21.s_DE = dN.DE;
  120. }
  121. TwoThreeXorByte nextL = null;
  122. byte[] Lip1 = null;
  123. if (!isLastTree) {
  124. ThreeShiftXorPIR threeshiftxorpir = new ThreeShiftXorPIR(con1, con2, Crypto.sr_DE, Crypto.sr_CD);
  125. nextL = threeshiftxorpir.runD(x_DE, x_CD, j, dN21, ttp);
  126. Lip1 = Util.xor(Util.xor(nextL.DE, nextL.CE), nextL.CD);
  127. }
  128. OutPIRAccess out = new OutPIRAccess(pathTuples_CD, null, pathTuples_DE, j, X, nextL, Lip1);
  129. timer.stop(M.online_comp);
  130. return out;
  131. }
  132. public OutPIRAccess runC(Metadata md, Tree tree_CD, Tree tree_CE, byte[] Li, TwoThreeXorByte L, TwoThreeXorByte N,
  133. TwoThreeXorInt dN) {
  134. timer.start(M.online_comp);
  135. Bucket[] pathBuckets_CD = tree_CD.getBucketsOnPath(Li);
  136. Tuple[] pathTuples_CD = Bucket.bucketsToTuples(pathBuckets_CD);
  137. Bucket[] pathBuckets_CE = tree_CE.getBucketsOnPath(Li);
  138. Tuple[] pathTuples_CE = Bucket.bucketsToTuples(pathBuckets_CE);
  139. int pathTuples = pathTuples_CE.length;
  140. int ttp = md.getTwoTauPow();
  141. int treeIndex = tree_CE.getTreeIndex();
  142. boolean isLastTree = treeIndex == md.getNumTrees() - 1;
  143. boolean isFirstTree = treeIndex == 0;
  144. byte[][] x_CE = new byte[pathTuples][];
  145. byte[][] x_CD = new byte[pathTuples][];
  146. for (int i = 0; i < pathTuples; i++) {
  147. x_CE[i] = pathTuples_CE[i].getA();
  148. x_CD[i] = pathTuples_CD[i].getA();
  149. }
  150. OutPIRCOT j = new OutPIRCOT();
  151. TwoOneXor dN21 = new TwoOneXor();
  152. TwoThreeXorByte X = new TwoThreeXorByte();
  153. if (isFirstTree) {
  154. X.CE = x_CE[0];
  155. X.CD = x_CD[0];
  156. } else {
  157. PIRCOT ksearch = new PIRCOT(con1, con2);
  158. j = ksearch.runC(pathTuples);
  159. ThreeShiftPIR threeshiftpir = new ThreeShiftPIR(con1, con2, Crypto.sr_CE, Crypto.sr_CD);
  160. X = threeshiftpir.runC(x_CD, x_CE, j);
  161. dN21.t_C = dN.CD ^ dN.CE;
  162. dN21.s_CD = dN.CD;
  163. dN21.s_CE = dN.CE;
  164. }
  165. TwoThreeXorByte nextL = null;
  166. byte[] Lip1 = null;
  167. if (!isLastTree) {
  168. ThreeShiftXorPIR threeshiftxorpir = new ThreeShiftXorPIR(con1, con2, Crypto.sr_CE, Crypto.sr_CD);
  169. nextL = threeshiftxorpir.runC(x_CD, x_CE, j, dN21, ttp);
  170. Lip1 = Util.xor(Util.xor(nextL.DE, nextL.CE), nextL.CD);
  171. }
  172. OutPIRAccess out = new OutPIRAccess(pathTuples_CD, pathTuples_CE, null, j, X, nextL, Lip1);
  173. timer.stop(M.online_comp);
  174. return out;
  175. }
  176. @Override
  177. public void run(Party party, Metadata md, Forest[] forest) {
  178. Tree tree_CD = null;
  179. Tree tree_DE = null;
  180. Tree tree_CE = null;
  181. for (int test = 0; test < 100; test++) {
  182. for (int treeIndex = 0; treeIndex < md.getNumTrees(); treeIndex++) {
  183. if (party == Party.Eddie) {
  184. tree_DE = forest[0].getTree(treeIndex);
  185. tree_CE = forest[1].getTree(treeIndex);
  186. } else if (party == Party.Debbie) {
  187. tree_DE = forest[0].getTree(treeIndex);
  188. tree_CD = forest[1].getTree(treeIndex);
  189. } else if (party == Party.Charlie) {
  190. tree_CE = forest[0].getTree(treeIndex);
  191. tree_CD = forest[1].getTree(treeIndex);
  192. } else {
  193. throw new NoSuchPartyException(party + "");
  194. }
  195. int Llen = md.getLBytesOfTree(treeIndex);
  196. int Nlen = md.getNBytesOfTree(treeIndex);
  197. TwoThreeXorInt dN = new TwoThreeXorInt();
  198. TwoThreeXorByte N = new TwoThreeXorByte();
  199. N.CD = new byte[Nlen];
  200. N.DE = new byte[Nlen];
  201. N.CE = new byte[Nlen];
  202. TwoThreeXorByte L = new TwoThreeXorByte();
  203. L.CD = new byte[Llen];
  204. L.DE = new byte[Llen];
  205. L.CE = new byte[Llen];
  206. byte[] Li = new byte[Llen];
  207. if (party == Party.Eddie) {
  208. OutPIRAccess out = this.runE(md, tree_DE, tree_CE, Li, L, N, dN);
  209. out.j.t_D = con1.readInt();
  210. out.j.t_C = con2.readInt();
  211. out.X.CD = con1.read();
  212. int pathTuples = out.pathTuples_CE.length;
  213. int index = (out.j.t_D + out.j.s_CE) % pathTuples;
  214. byte[] X = Util.xor(Util.xor(out.X.DE, out.X.CE), out.X.CD);
  215. boolean fail = false;
  216. if (index != 0) {
  217. System.err.println(test + " " + treeIndex + ": PIRAcc test failed on KSearch index");
  218. fail = true;
  219. }
  220. if (new BigInteger(1, X).intValue() != 0) {
  221. System.err.println(test + " " + treeIndex + ": PIRAcc test failed on 3ShiftPIR X");
  222. fail = true;
  223. }
  224. if (treeIndex < md.getNumTrees() - 1 && new BigInteger(1, out.Lip1).intValue() != 0) {
  225. System.err.println(test + " " + treeIndex + ": PIRAcc test failed on 3ShiftXorPIR Lip1");
  226. fail = true;
  227. }
  228. if (!fail)
  229. System.out.println(test + " " + treeIndex + ": PIRAcc test passed");
  230. } else if (party == Party.Debbie) {
  231. OutPIRAccess out = this.runD(md, tree_DE, tree_CD, Li, L, N, dN);
  232. con1.write(out.j.t_D);
  233. con1.write(out.X.CD);
  234. } else if (party == Party.Charlie) {
  235. OutPIRAccess out = this.runC(md, tree_CD, tree_CE, Li, L, N, dN);
  236. con1.write(out.j.t_C);
  237. } else {
  238. throw new NoSuchPartyException(party + "");
  239. }
  240. }
  241. }
  242. }
  243. // TODO: add Access on second path
  244. @Override
  245. public void run(Party party, Metadata md, Forest forest) {
  246. }
  247. }