Tree.java 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. package oram;
  2. import java.io.Serializable;
  3. import java.math.BigInteger;
  4. import java.util.Random;
  5. import exceptions.LengthNotMatchException;
  6. import util.Array64;
  7. import util.Util;
  8. public class Tree implements Serializable {
  9. /**
  10. *
  11. */
  12. private static final long serialVersionUID = 1L;
  13. private int tau;
  14. private int twoTauPow;
  15. private int treeIndex;
  16. private int w;
  17. private int stashSize;
  18. private int nBits;
  19. private int lBits;
  20. private int alBits;
  21. private int nBytes;
  22. private int lBytes;
  23. private int alBytes;
  24. private int aBytes;
  25. private int tupleBytes;
  26. private long numBuckets;
  27. private long numBytes;
  28. private int d;
  29. private int h;
  30. private Array64<Bucket> buckets;
  31. // only for cheat
  32. private Bucket[] pathBuckets;
  33. public Tree(int index, Metadata md, Random rand) {
  34. tau = md.getTau();
  35. twoTauPow = md.getTwoTauPow();
  36. treeIndex = index;
  37. w = md.getW();
  38. stashSize = md.getStashSizeOfTree(treeIndex);
  39. nBits = md.getNBitsOfTree(treeIndex);
  40. lBits = md.getLBitsOfTree(treeIndex);
  41. alBits = md.getAlBitsOfTree(treeIndex);
  42. nBytes = md.getNBytesOfTree(treeIndex);
  43. lBytes = md.getLBytesOfTree(treeIndex);
  44. alBytes = md.getAlBytesOfTree(treeIndex);
  45. aBytes = md.getABytesOfTree(treeIndex);
  46. tupleBytes = md.getTupleBytesOfTree(treeIndex);
  47. numBuckets = md.getNumBucketsOfTree(treeIndex);
  48. numBytes = md.getTreeBytesOfTree(treeIndex);
  49. d = lBits + 1;
  50. h = md.getNumTrees();
  51. int fBytes = treeIndex == 0 ? 0 : 1;
  52. int[] tupleParams = new int[] { fBytes, nBytes, lBytes, aBytes };
  53. if (!Global.cheat) {
  54. buckets = new Array64<Bucket>(numBuckets);
  55. buckets.set(0, new Bucket(stashSize, tupleParams, rand));
  56. for (int i = 1; i < numBuckets; i++)
  57. buckets.set(i, new Bucket(w, tupleParams, rand));
  58. } else {
  59. pathBuckets = new Bucket[d];
  60. pathBuckets[0] = new Bucket(stashSize, tupleParams, null);
  61. for (int i = 1; i < d; i++)
  62. pathBuckets[i] = new Bucket(w, tupleParams, null);
  63. if (rand != null && treeIndex > 0)
  64. pathBuckets[0].getTuple(0).setF(new byte[] { 1 });
  65. }
  66. }
  67. // only used for xor operation
  68. // does not shallow/deep copy buckets
  69. private Tree(Tree t) {
  70. tau = t.getTau();
  71. twoTauPow = t.getTwoTauPow();
  72. treeIndex = t.getTreeIndex();
  73. w = t.getW();
  74. stashSize = t.getStashSize();
  75. nBits = t.getNBits();
  76. lBits = t.getLBits();
  77. alBits = t.getAlBits();
  78. nBytes = t.getNBytes();
  79. lBytes = t.getLBytes();
  80. alBytes = t.getAlBytes();
  81. aBytes = t.getABytes();
  82. tupleBytes = t.getTupleBytes();
  83. numBuckets = t.getNumBuckets();
  84. numBytes = t.getNumBytes();
  85. d = t.getD();
  86. h = t.getH();
  87. buckets = new Array64<Bucket>(numBuckets);
  88. }
  89. public Bucket getBucket(long i) {
  90. return buckets.get(i);
  91. }
  92. public void setBucket(long i, Bucket bucket) {
  93. if (!buckets.get(i).sameLength(bucket))
  94. throw new LengthNotMatchException(buckets.get(i).getNumBytes() + " != " + bucket.getNumBytes());
  95. buckets.set(i, bucket);
  96. }
  97. public Tree xor(Tree t) {
  98. if (!this.sameLength(t))
  99. throw new LengthNotMatchException(numBytes + " != " + t.getNumBytes());
  100. Tree newTree = new Tree(t);
  101. for (long i = 0; i < numBuckets; i++)
  102. // cannot use newTree.setBucket() here
  103. newTree.buckets.set(i, buckets.get(i).xor(t.getBucket(i)));
  104. return newTree;
  105. }
  106. public void setXor(Tree t) {
  107. if (!this.sameLength(t))
  108. throw new LengthNotMatchException(numBytes + " != " + t.getNumBytes());
  109. for (long i = 0; i < numBuckets; i++)
  110. buckets.get(i).setXor(t.getBucket(i));
  111. }
  112. public boolean sameLength(Tree t) {
  113. return numBytes == t.getNumBytes();
  114. }
  115. private long[] getBucketIndicesOnPath(BigInteger L) {
  116. if (treeIndex == 0)
  117. return new long[] { 0 };
  118. L = Util.getSubBits(L, lBits, 0);
  119. long[] indices = new long[d];
  120. for (int i = 1; i < d; i++) {
  121. if (L.testBit(d - i - 1))
  122. indices[i] = indices[i - 1] * 2 + 2;
  123. else
  124. indices[i] = indices[i - 1] * 2 + 1;
  125. }
  126. return indices;
  127. }
  128. public Bucket[] getBucketsOnPath(BigInteger L) {
  129. if (Global.cheat)
  130. return pathBuckets;
  131. long[] indices = getBucketIndicesOnPath(L);
  132. Bucket[] buckets = new Bucket[indices.length];
  133. for (int i = 0; i < indices.length; i++)
  134. buckets[i] = getBucket(indices[i]);
  135. return buckets;
  136. }
  137. public Bucket[] getBucketsOnPath(byte[] L) {
  138. return getBucketsOnPath(new BigInteger(1, L));
  139. }
  140. public Bucket[] getBucketsOnPath(long L) {
  141. return getBucketsOnPath(BigInteger.valueOf(L));
  142. }
  143. public void setBucketsOnPath(BigInteger L, Bucket[] buckets) {
  144. if (Global.cheat) {
  145. pathBuckets = buckets;
  146. return;
  147. }
  148. long[] indices = getBucketIndicesOnPath(L);
  149. if (indices.length != buckets.length)
  150. throw new LengthNotMatchException(indices.length + " != " + buckets.length);
  151. for (int i = 0; i < indices.length; i++)
  152. setBucket(indices[i], buckets[i]);
  153. }
  154. public void setBucketsOnPath(byte[] L, Bucket[] buckets) {
  155. setBucketsOnPath(new BigInteger(1, L), buckets);
  156. }
  157. public void setBucketsOnPath(long L, Bucket[] buckets) {
  158. setBucketsOnPath(BigInteger.valueOf(L), buckets);
  159. }
  160. public int getTau() {
  161. return tau;
  162. }
  163. public int getTwoTauPow() {
  164. return twoTauPow;
  165. }
  166. public int getTreeIndex() {
  167. return treeIndex;
  168. }
  169. public int getW() {
  170. return w;
  171. }
  172. public int getStashSize() {
  173. return stashSize;
  174. }
  175. public int getFBytes() {
  176. return treeIndex == 0 ? 0 : 1;
  177. }
  178. public int getNBits() {
  179. return nBits;
  180. }
  181. public int getLBits() {
  182. return lBits;
  183. }
  184. public int getAlBits() {
  185. return alBits;
  186. }
  187. public int getNBytes() {
  188. return nBytes;
  189. }
  190. public int getLBytes() {
  191. return lBytes;
  192. }
  193. public int getAlBytes() {
  194. return alBytes;
  195. }
  196. public int getABytes() {
  197. return aBytes;
  198. }
  199. public int getTupleBytes() {
  200. return tupleBytes;
  201. }
  202. public long getNumBuckets() {
  203. return numBuckets;
  204. }
  205. public long getNumBytes() {
  206. return numBytes;
  207. }
  208. public int getD() {
  209. return d;
  210. }
  211. public int getH() {
  212. return h;
  213. }
  214. }