PIRAccess.java 9.0 KB

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