Bucket.java 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. package oram;
  2. import java.io.Serializable;
  3. import java.util.Arrays;
  4. import java.util.Random;
  5. import org.apache.commons.lang3.ArrayUtils;
  6. import crypto.Crypto;
  7. import exceptions.LengthNotMatchException;
  8. import util.Util;
  9. public class Bucket implements Serializable {
  10. /**
  11. *
  12. */
  13. private static final long serialVersionUID = 1L;
  14. private Tuple[] tuples;
  15. public Bucket(int numTuples, int[] tupleParams, Random rand) {
  16. if (tupleParams.length != 4)
  17. throw new LengthNotMatchException(tupleParams.length + " != 4");
  18. tuples = new Tuple[numTuples];
  19. for (int i = 0; i < numTuples; i++)
  20. tuples[i] = new Tuple(tupleParams[0], tupleParams[1], tupleParams[2], tupleParams[3], rand);
  21. }
  22. public Bucket(Tuple[] tuples) {
  23. this.tuples = tuples;
  24. }
  25. // deep copy
  26. public Bucket(Bucket b) {
  27. tuples = new Tuple[b.getNumTuples()];
  28. for (int i = 0; i < tuples.length; i++)
  29. tuples[i] = new Tuple(b.getTuple(i));
  30. }
  31. public int getNumBytes() {
  32. return tuples.length * tuples[0].getNumBytes();
  33. }
  34. public int getNumTuples() {
  35. return tuples.length;
  36. }
  37. public Tuple[] getTuples() {
  38. return tuples;
  39. }
  40. public Tuple getTuple(int i) {
  41. return tuples[i];
  42. }
  43. public void setTuple(int i, Tuple tuple) {
  44. if (!tuples[i].sameLength(tuple))
  45. throw new LengthNotMatchException(tuples[i].getNumBytes() + " != " + tuple.getNumBytes());
  46. tuples[i] = tuple;
  47. }
  48. public void permute(int[] p) {
  49. tuples = Util.permute(tuples, p);
  50. }
  51. public Bucket xor(Bucket b) {
  52. if (!this.sameLength(b))
  53. throw new LengthNotMatchException(getNumBytes() + " != " + b.getNumBytes());
  54. Tuple[] newTuples = new Tuple[tuples.length];
  55. for (int i = 0; i < tuples.length; i++)
  56. newTuples[i] = tuples[i].xor(b.getTuple(i));
  57. return new Bucket(newTuples);
  58. }
  59. public void setXor(Bucket b) {
  60. if (!this.sameLength(b))
  61. throw new LengthNotMatchException(getNumBytes() + " != " + b.getNumBytes());
  62. for (int i = 0; i < tuples.length; i++)
  63. tuples[i].setXor(b.getTuple(i));
  64. }
  65. public boolean sameLength(Bucket b) {
  66. return getNumBytes() == b.getNumBytes();
  67. }
  68. public static Tuple[] bucketsToTuples(Bucket[] buckets) {
  69. int numTuples = 0;
  70. for (int i = 0; i < buckets.length; i++)
  71. numTuples += buckets[i].getNumTuples();
  72. Tuple[] tuples = new Tuple[numTuples];
  73. int tupleCnt = 0;
  74. for (int i = 0; i < buckets.length; i++)
  75. for (int j = 0; j < buckets[i].getNumTuples(); j++) {
  76. tuples[tupleCnt] = buckets[i].getTuple(j);
  77. tupleCnt++;
  78. }
  79. return tuples;
  80. }
  81. public static Bucket[] tuplesToBuckets(Tuple[] tuples, int d, int sw, int w) {
  82. if (tuples.length != sw + (d - 1) * w)
  83. throw new LengthNotMatchException(tuples.length + " != " + (sw + (d - 1) * w));
  84. Bucket[] buckets = new Bucket[d];
  85. for (int i = 0; i < d; i++) {
  86. int start = i == 0 ? 0 : sw + (i - 1) * w;
  87. int end = i == 0 ? sw : start + w;
  88. buckets[i] = new Bucket(Arrays.copyOfRange(tuples, start, end));
  89. }
  90. return buckets;
  91. }
  92. public void expand(Tuple[] ts) {
  93. if (!tuples[0].sameLength(ts[0]))
  94. throw new LengthNotMatchException(tuples[0].getNumBytes() + " != " + ts[0].getNumBytes());
  95. tuples = ArrayUtils.addAll(tuples, ts);
  96. }
  97. // append empty random content tuples
  98. public void expand(int numTuples) {
  99. if (tuples.length >= numTuples)
  100. return;
  101. int f = tuples[0].getF().length;
  102. int n = tuples[0].getN().length;
  103. int l = tuples[0].getL().length;
  104. int a = tuples[0].getA().length;
  105. Tuple[] newTuples = new Tuple[numTuples];
  106. System.arraycopy(tuples, 0, newTuples, 0, tuples.length);
  107. for (int i = tuples.length; i < numTuples; i++) {
  108. newTuples[i] = new Tuple(f, n, l, a, Crypto.sr);
  109. newTuples[i].setF(new byte[f]);
  110. }
  111. tuples = newTuples;
  112. }
  113. public void shrink(int numTuples) {
  114. if (numTuples >= tuples.length)
  115. return;
  116. tuples = Arrays.copyOfRange(tuples, 0, numTuples);
  117. }
  118. public byte[] toByteArray() {
  119. int tupleBytes = tuples[0].getNumBytes();
  120. byte[] bucket = new byte[getNumBytes()];
  121. for (int i = 0; i < tuples.length; i++) {
  122. byte[] tuple = tuples[i].toByteArray();
  123. System.arraycopy(tuple, 0, bucket, i * tupleBytes, tupleBytes);
  124. }
  125. return bucket;
  126. }
  127. @Override
  128. public String toString() {
  129. String str = "Bucket:";
  130. for (int i = 0; i < tuples.length; i++)
  131. str += ("\n " + tuples[i]);
  132. return str;
  133. }
  134. }