PIRAccess.java 9.0 KB

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