PIRAccess.java 9.1 KB

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