Prechádzať zdrojové kódy

convert message to single byte array myself...

Boyoung- 8 rokov pred
rodič
commit
c179e83744

+ 234 - 0
src/communication/ComUtil.java

@@ -0,0 +1,234 @@
+package communication;
+
+import java.util.Arrays;
+
+import com.oblivm.backend.gc.GCSignal;
+
+import oram.Tuple;
+import util.Util;
+
+public class ComUtil {
+	public static byte[] toByteArray(byte[][] in) {
+		int len1 = in.length;
+		int len2 = in[0].length;
+		byte[] out = new byte[len1 * len2];
+		for (int i = 0; i < len1; i++)
+			System.arraycopy(in[i], 0, out, i * len2, len2);
+		return out;
+	}
+
+	public static byte[][] toDoubleByteArray(byte[] in, int len1) {
+		int len2 = in.length / len1;
+		byte[][] out = new byte[len1][];
+		for (int i = 0; i < len1; i++) {
+			out[i] = Arrays.copyOfRange(in, i * len2, (i + 1) * len2);
+		}
+		return out;
+	}
+
+	public static byte[] toByteArray(byte[][][] in) {
+		int len1 = in.length;
+		int len2 = in[0].length;
+		int len3 = in[0][0].length;
+		byte[] out = new byte[len1 * len2 * len3];
+		for (int i = 0; i < len1; i++)
+			for (int j = 0; j < len2; j++)
+				System.arraycopy(in[i][j], 0, out, i * len2 * len3 + j * len3, len3);
+		return out;
+	}
+
+	public static byte[][][] toTripleByteArray(byte[] in, int len1, int len2) {
+		int len3 = in.length / len1 / len2;
+		byte[][][] out = new byte[len1][len2][];
+		for (int i = 0; i < len1; i++) {
+			for (int j = 0; j < len2; j++) {
+				out[i][j] = Arrays.copyOfRange(in, i * len2 * len3 + j * len3, i * len2 * len3 + j * len3 + len3);
+			}
+		}
+		return out;
+	}
+
+	public static byte[] toByteArray(int[] in) {
+		byte[] out = new byte[in.length * 4];
+		for (int i = 0; i < in.length; i++) {
+			byte[] n = Util.intToBytes(in[i]);
+			System.arraycopy(n, 0, out, i * 4, 4);
+		}
+		return out;
+	}
+
+	public static int[] toIntArray(byte[] in) {
+		int len1 = in.length / 4;
+		int[] out = new int[len1];
+		for (int i = 0; i < len1; i++) {
+			byte[] b = Arrays.copyOfRange(in, i * 4, (i + 1) * 4);
+			out[i] = Util.bytesToInt(b);
+		}
+		return out;
+	}
+
+	public static byte[] toByteArray(int[][] in) {
+		int len1 = in.length;
+		int len2 = in[0].length;
+		byte[] out = new byte[len1 * len2 * 4];
+		for (int i = 0; i < len1; i++) {
+			for (int j = 0; j < len2; j++) {
+				byte[] n = Util.intToBytes(in[i][j]);
+				System.arraycopy(n, 0, out, (i * len2 + j) * 4, 4);
+			}
+		}
+		return out;
+	}
+
+	public static int[][] toDoubleIntArray(byte[] in, int len1) {
+		int len2 = in.length / len1 / 4;
+		int[][] out = new int[len1][len2];
+		for (int i = 0; i < len1; i++) {
+			for (int j = 0; j < len2; j++) {
+				byte[] b = Arrays.copyOfRange(in, (i * len2 + j) * 4, (i * len2 + j + 1) * 4);
+				out[i][j] = Util.bytesToInt(b);
+			}
+		}
+		return out;
+	}
+
+	public static byte[] toByteArray(Tuple[] in) {
+		int len1 = in.length;
+		int f = in[0].getF().length;
+		int n = in[0].getN().length;
+		int l = in[0].getL().length;
+		int a = in[0].getA().length;
+		int len2 = f + n + l + a;
+		byte[] out = new byte[len1 * len2];
+		for (int i = 0; i < len1; i++) {
+			System.arraycopy(in[i].getF(), 0, out, i * len2, f);
+			System.arraycopy(in[i].getN(), 0, out, i * len2 + f, n);
+			System.arraycopy(in[i].getL(), 0, out, i * len2 + f + n, l);
+			System.arraycopy(in[i].getA(), 0, out, i * len2 + f + n + l, a);
+		}
+		return out;
+	}
+
+	public static Tuple[] toTupleArray(byte[] in, int len1, int f, int n, int l) {
+		int len2 = in.length / len1;
+		Tuple[] out = new Tuple[len1];
+		for (int i = 0; i < len1; i++) {
+			byte[] F = Arrays.copyOfRange(in, i * len2, i * len2 + f);
+			byte[] N = Arrays.copyOfRange(in, i * len2 + f, i * len2 + f + n);
+			byte[] L = Arrays.copyOfRange(in, i * len2 + f + n, i * len2 + f + n + l);
+			byte[] A = Arrays.copyOfRange(in, i * len2 + f + n + l, (i + 1) * len2);
+			out[i] = new Tuple(F, N, L, A);
+		}
+		return out;
+	}
+
+	public static byte[] toByteArray(GCSignal[] in) {
+		byte[] out = new byte[in.length * GCSignal.len];
+		for (int i = 0; i < in.length; i++) {
+			System.arraycopy(in[i].bytes, 0, out, i * GCSignal.len, GCSignal.len);
+		}
+		return out;
+	}
+
+	public static GCSignal[] toGCSignalArray(byte[] in) {
+		int len1 = in.length / GCSignal.len;
+		GCSignal[] out = new GCSignal[len1];
+		for (int i = 0; i < len1; i++) {
+			byte[] b = Arrays.copyOfRange(in, i * GCSignal.len, (i + 1) * GCSignal.len);
+			out[i] = new GCSignal(b);
+		}
+		return out;
+	}
+
+	public static byte[] toByteArray(GCSignal[][] in) {
+		int len1 = in.length;
+		int len2 = in[0].length;
+		byte[] out = new byte[len1 * len2 * GCSignal.len];
+		for (int i = 0; i < len1; i++) {
+			for (int j = 0; j < len2; j++) {
+				System.arraycopy(in[i][j].bytes, 0, out, (i * len2 + j) * GCSignal.len, GCSignal.len);
+			}
+		}
+		return out;
+	}
+
+	public static GCSignal[][] toDoubleGCSignalArray(byte[] in, int len1) {
+		int len2 = in.length / len1 / GCSignal.len;
+		GCSignal[][] out = new GCSignal[len1][len2];
+		for (int i = 0; i < len1; i++) {
+			for (int j = 0; j < len2; j++) {
+				byte[] b = Arrays.copyOfRange(in, (i * len2 + j) * GCSignal.len, (i * len2 + j + 1) * GCSignal.len);
+				out[i][j] = new GCSignal(b);
+			}
+		}
+		return out;
+	}
+
+	public static byte[] toByteArray(GCSignal[][][] in) {
+		int len1 = in.length;
+		int len2 = in[0].length;
+		int len3 = in[0][0].length;
+		byte[] out = new byte[len1 * len2 * len3 * GCSignal.len];
+		for (int i = 0; i < len1; i++) {
+			for (int j = 0; j < len2; j++) {
+				for (int k = 0; k < len3; k++) {
+					System.arraycopy(in[i][j][k].bytes, 0, out, (i * len2 * len3 + j * len3 + k) * GCSignal.len,
+							GCSignal.len);
+				}
+			}
+		}
+		return out;
+	}
+
+	public static GCSignal[][][] toTripleGCSignalArray(byte[] in, int len1, int len2) {
+		int len3 = in.length / len1 / len2 / GCSignal.len;
+		GCSignal[][][] out = new GCSignal[len1][len2][len3];
+		for (int i = 0; i < len1; i++) {
+			for (int j = 0; j < len2; j++) {
+				for (int k = 0; k < len3; k++) {
+					byte[] b = Arrays.copyOfRange(in, (i * len2 * len3 + j * len3 + k) * GCSignal.len,
+							(i * len2 * len3 + j * len3 + k + 1) * GCSignal.len);
+					out[i][j][k] = new GCSignal(b);
+				}
+			}
+		}
+		return out;
+	}
+
+	public static byte[] toByteArray(GCSignal[][][][] in) {
+		int len1 = in.length;
+		int len2 = in[0].length;
+		int len3 = in[0][0].length;
+		int len4 = in[0][0][0].length;
+		byte[] out = new byte[len1 * len2 * len3 * len4 * GCSignal.len];
+		for (int i = 0; i < len1; i++) {
+			for (int j = 0; j < len2; j++) {
+				for (int k = 0; k < len3; k++) {
+					for (int l = 0; l < len4; l++) {
+						System.arraycopy(in[i][j][k][l].bytes, 0, out,
+								(i * len2 * len3 * len4 + j * len3 * len4 + k * len4 + l) * GCSignal.len, GCSignal.len);
+					}
+				}
+			}
+		}
+		return out;
+	}
+
+	public static GCSignal[][][][] toQuadGCSignalArray(byte[] in, int len1, int len2, int len3) {
+		int len4 = in.length / len1 / len2 / len3 / GCSignal.len;
+		GCSignal[][][][] out = new GCSignal[len1][len2][len3][len4];
+		for (int i = 0; i < len1; i++) {
+			for (int j = 0; j < len2; j++) {
+				for (int k = 0; k < len3; k++) {
+					for (int l = 0; l < len4; l++) {
+						byte[] b = Arrays.copyOfRange(in,
+								(i * len2 * len3 * len4 + j * len3 * len4 + k * len4 + l) * GCSignal.len,
+								(i * len2 * len3 * len4 + j * len3 * len4 + k * len4 + l + 1) * GCSignal.len);
+						out[i][j][k][l] = new GCSignal(b);
+					}
+				}
+			}
+		}
+		return out;
+	}
+}

+ 106 - 130
src/communication/Communication.java

@@ -3,7 +3,6 @@ package communication;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
-import java.io.Serializable;
 import java.io.StreamCorruptedException;
 import java.math.BigInteger;
 import java.net.InetSocketAddress;
@@ -15,7 +14,7 @@ import java.util.ArrayList;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 
-import org.apache.commons.lang3.SerializationUtils;
+import org.bouncycastle.util.Arrays;
 
 import com.oblivm.backend.gc.GCSignal;
 
@@ -359,98 +358,88 @@ public class Communication {
 
 	public void write(byte[][] arr) {
 		write(arr.length);
-		for (int i = 0; i < arr.length; i++)
-			write(arr[i]);
+		write(ComUtil.toByteArray(arr));
 	}
 
 	public void write(int pid, byte[][] arr) {
 		write(pid, arr.length);
-		for (int i = 0; i < arr.length; i++)
-			write(pid, arr[i]);
+		write(pid, ComUtil.toByteArray(arr));
 	}
 
-	public void write(BigInteger b) {
-		write(b.toByteArray());
-	}
-
-	public void write(int pid, BigInteger b) {
-		write(pid, b.toByteArray());
-	}
-
-	public void write(BigInteger[] arr) {
+	public void write(byte[][][] arr) {
 		write(arr.length);
-		for (int i = 0; i < arr.length; i++)
-			write(arr[i]);
+		write(arr[0].length);
+		write(ComUtil.toByteArray(arr));
 	}
 
-	public void write(int pid, BigInteger[] arr) {
+	public void write(int pid, byte[][][] arr) {
 		write(pid, arr.length);
-		for (int i = 0; i < arr.length; i++)
-			write(pid, arr[i]);
+		write(pid, arr[0].length);
+		write(pid, ComUtil.toByteArray(arr));
 	}
 
-	public void write(BigInteger[][] arr) {
-		write(arr.length);
-		for (int i = 0; i < arr.length; i++)
-			write(arr[i]);
+	public void write(BigInteger b) {
+		write(b.toByteArray());
 	}
 
-	public void write(int pid, BigInteger[][] arr) {
-		write(pid, arr.length);
-		for (int i = 0; i < arr.length; i++)
-			write(pid, arr[i]);
+	public void write(int pid, BigInteger b) {
+		write(pid, b.toByteArray());
 	}
 
 	public void write(int n) {
-		write(BigInteger.valueOf(n).toByteArray());
+		write(BigInteger.valueOf(n));
 	}
 
 	public void write(int pid, int n) {
-		write(pid, BigInteger.valueOf(n).toByteArray());
+		write(pid, BigInteger.valueOf(n));
 	}
 
 	public void write(int[] arr) {
-		write(arr.length);
-		for (int i = 0; i < arr.length; i++)
-			write(arr[i]);
+		write(ComUtil.toByteArray(arr));
 	}
 
 	public void write(int pid, int[] arr) {
-		write(pid, arr.length);
-		for (int i = 0; i < arr.length; i++)
-			write(pid, arr[i]);
+		write(pid, ComUtil.toByteArray(arr));
 	}
 
 	public void write(int[][] arr) {
 		write(arr.length);
-		for (int i = 0; i < arr.length; i++)
-			write(arr[i]);
+		write(ComUtil.toByteArray(arr));
 	}
 
 	public void write(int pid, int[][] arr) {
 		write(pid, arr.length);
-		for (int i = 0; i < arr.length; i++)
-			write(pid, arr[i]);
+		write(pid, ComUtil.toByteArray(arr));
 	}
 
 	public void write(Tuple t) {
-		write(SerializationUtils.serialize(t));
+		write(t.getF().length);
+		write(t.getN().length);
+		write(t.getL().length);
+		write(t.toByteArray());
 	}
 
 	public void write(int pid, Tuple t) {
-		write(pid, SerializationUtils.serialize(t));
+		write(pid, t.getF().length);
+		write(pid, t.getN().length);
+		write(pid, t.getL().length);
+		write(pid, t.toByteArray());
 	}
 
 	public void write(Tuple[] arr) {
 		write(arr.length);
-		for (int i = 0; i < arr.length; i++)
-			write(arr[i]);
+		write(arr[0].getF().length);
+		write(arr[0].getN().length);
+		write(arr[0].getL().length);
+		write(ComUtil.toByteArray(arr));
 	}
 
-	public void write(int pid, Tuple[] tuples) {
-		write(pid, tuples.length);
-		for (int i = 0; i < tuples.length; i++)
-			write(pid, tuples[i]);
+	public void write(int pid, Tuple[] arr) {
+		write(pid, arr.length);
+		write(pid, arr[0].getF().length);
+		write(pid, arr[0].getN().length);
+		write(pid, arr[0].getL().length);
+		write(pid, ComUtil.toByteArray(arr));
 	}
 
 	public void write(Bucket b) {
@@ -463,14 +452,14 @@ public class Communication {
 
 	public void write(Bucket[] arr) {
 		write(arr.length);
-		for (int i = 0; i < arr.length; i++)
-			write(arr[i]);
+		write(arr[0].getNumTuples());
+		write(Bucket.bucketsToTuples(arr));
 	}
 
 	public void write(int pid, Bucket[] arr) {
 		write(pid, arr.length);
-		for (int i = 0; i < arr.length; i++)
-			write(pid, arr[i]);
+		write(pid, arr[0].getNumTuples());
+		write(pid, Bucket.bucketsToTuples(arr));
 	}
 
 	public void write(GCSignal key) {
@@ -482,51 +471,47 @@ public class Communication {
 	}
 
 	public void write(GCSignal[] arr) {
-		write(arr.length);
-		for (int i = 0; i < arr.length; i++)
-			write(arr[i]);
+		write(ComUtil.toByteArray(arr));
 	}
 
 	public void write(int pid, GCSignal[] arr) {
-		write(pid, arr.length);
-		for (int i = 0; i < arr.length; i++)
-			write(pid, arr[i]);
+		write(pid, ComUtil.toByteArray(arr));
 	}
 
 	public void write(GCSignal[][] arr) {
 		write(arr.length);
-		for (int i = 0; i < arr.length; i++)
-			write(arr[i]);
+		write(ComUtil.toByteArray(arr));
 	}
 
 	public void write(int pid, GCSignal[][] arr) {
 		write(pid, arr.length);
-		for (int i = 0; i < arr.length; i++)
-			write(pid, arr[i]);
+		write(pid, ComUtil.toByteArray(arr));
 	}
 
 	public void write(GCSignal[][][] arr) {
 		write(arr.length);
-		for (int i = 0; i < arr.length; i++)
-			write(arr[i]);
+		write(arr[0].length);
+		write(ComUtil.toByteArray(arr));
 	}
 
 	public void write(int pid, GCSignal[][][] arr) {
 		write(pid, arr.length);
-		for (int i = 0; i < arr.length; i++)
-			write(pid, arr[i]);
+		write(pid, arr[0].length);
+		write(pid, ComUtil.toByteArray(arr));
 	}
 
 	public void write(GCSignal[][][][] arr) {
 		write(arr.length);
-		for (int i = 0; i < arr.length; i++)
-			write(arr[i]);
+		write(arr[0].length);
+		write(arr[0][0].length);
+		write(ComUtil.toByteArray(arr));
 	}
 
 	public void write(int pid, GCSignal[][][][] arr) {
 		write(pid, arr.length);
-		for (int i = 0; i < arr.length; i++)
-			write(pid, arr[i]);
+		write(pid, arr[0].length);
+		write(pid, arr[0][0].length);
+		write(pid, ComUtil.toByteArray(arr));
 	}
 
 	public static final Charset defaultCharset = Charset.forName("ASCII");
@@ -616,62 +601,63 @@ public class Communication {
 
 	public byte[][] readDoubleByteArray() {
 		int len = readInt();
-		byte[][] arr = new byte[len][];
-		for (int i = 0; i < len; i++)
-			arr[i] = read();
-		return arr;
-	}
-
-	public BigInteger readBigInteger() {
-		return new BigInteger(read());
+		return ComUtil.toDoubleByteArray(read(), len);
 	}
 
-	public BigInteger[] readBigIntegerArray() {
-		int len = readInt();
-		BigInteger[] arr = new BigInteger[len];
-		for (int i = 0; i < len; i++)
-			arr[i] = readBigInteger();
-		return arr;
+	public byte[][][] readTripleByteArray() {
+		int len1 = readInt();
+		int len2 = readInt();
+		return ComUtil.toTripleByteArray(read(), len1, len2);
 	}
 
-	public BigInteger[][] readDoubleBigIntegerArray() {
-		int len = readInt();
-		BigInteger[][] arr = new BigInteger[len][];
-		for (int i = 0; i < len; i++)
-			arr[i] = readBigIntegerArray();
-		return arr;
+	public BigInteger readBigInteger() {
+		return new BigInteger(read());
 	}
 
 	public int readInt() {
-		return new BigInteger(read()).intValue();
+		return readBigInteger().intValue();
 	}
 
 	public int[] readIntArray() {
-		int len = readInt();
-		int[] arr = new int[len];
-		for (int i = 0; i < len; i++)
-			arr[i] = readInt();
-		return arr;
+		return ComUtil.toIntArray(read());
 	}
 
 	public int[][] readDoubleIntArray() {
 		int len = readInt();
-		int[][] arr = new int[len][];
-		for (int i = 0; i < len; i++)
-			arr[i] = readIntArray();
-		return arr;
+		return ComUtil.toDoubleIntArray(read(), len);
 	}
 
 	public Tuple readTuple() {
-		Tuple t = SerializationUtils.deserialize(read());
-		return t;
+		int f = readInt();
+		int n = readInt();
+		int l = readInt();
+		int endN = f + n;
+		int endL = endN + l;
+		byte[] b = read();
+		byte[] F = Arrays.copyOfRange(b, 0, f);
+		byte[] N = Arrays.copyOfRange(b, f, endN);
+		byte[] L = Arrays.copyOfRange(b, endN, endL);
+		byte[] A = Arrays.copyOfRange(b, endL, b.length);
+		return new Tuple(F, N, L, A);
 	}
 
 	public Tuple[] readTupleArray() {
-		int len = readInt();
-		Tuple[] arr = new Tuple[len];
-		for (int i = 0; i < len; i++)
-			arr[i] = readTuple();
+		int len1 = readInt();
+		int f = readInt();
+		int n = readInt();
+		int l = readInt();
+		byte[] b = read();
+		int len2 = b.length / len1;
+		int endN = f + n;
+		int endL = endN + l;
+		Tuple[] arr = new Tuple[len1];
+		for (int i = 0; i < len1; i++) {
+			byte[] F = Arrays.copyOfRange(b, i * len2, i * len2 + f);
+			byte[] N = Arrays.copyOfRange(b, i * len2 + f, i * len2 + endN);
+			byte[] L = Arrays.copyOfRange(b, i * len2 + endN, i * len2 + endL);
+			byte[] A = Arrays.copyOfRange(b, i * len2 + endL, (i + 1) * len2);
+			arr[i] = new Tuple(F, N, L, A);
+		}
 		return arr;
 	}
 
@@ -680,11 +666,11 @@ public class Communication {
 	}
 
 	public Bucket[] readBucketArray() {
-		int len = readInt();
-		Bucket[] arr = new Bucket[len];
-		for (int i = 0; i < len; i++)
-			arr[i] = readBucket();
-		return arr;
+		int d = readInt();
+		int sw = readInt();
+		Tuple[] arr = readTupleArray();
+		int w = (arr.length - sw) / (d - 1);
+		return Bucket.tuplesToBuckets(arr, d, sw, w);
 	}
 
 	public GCSignal readGCSignal() {
@@ -692,35 +678,25 @@ public class Communication {
 	}
 
 	public GCSignal[] readGCSignalArray() {
-		int len = readInt();
-		GCSignal[] arr = new GCSignal[len];
-		for (int i = 0; i < len; i++)
-			arr[i] = readGCSignal();
-		return arr;
+		return ComUtil.toGCSignalArray(read());
 	}
 
 	public GCSignal[][] readDoubleGCSignalArray() {
 		int len = readInt();
-		GCSignal[][] arr = new GCSignal[len][];
-		for (int i = 0; i < len; i++)
-			arr[i] = readGCSignalArray();
-		return arr;
+		return ComUtil.toDoubleGCSignalArray(read(), len);
 	}
 
 	public GCSignal[][][] readTripleGCSignalArray() {
-		int len = readInt();
-		GCSignal[][][] arr = new GCSignal[len][][];
-		for (int i = 0; i < len; i++)
-			arr[i] = readDoubleGCSignalArray();
-		return arr;
+		int len1 = readInt();
+		int len2 = readInt();
+		return ComUtil.toTripleGCSignalArray(read(), len1, len2);
 	}
 
 	public GCSignal[][][][] readQuadGCSignalArray() {
-		int len = readInt();
-		GCSignal[][][][] arr = new GCSignal[len][][][];
-		for (int i = 0; i < len; i++)
-			arr[i] = readTripleGCSignalArray();
-		return arr;
+		int len1 = readInt();
+		int len2 = readInt();
+		int len3 = readInt();
+		return ComUtil.toQuadGCSignalArray(read(), len1, len2, len3);
 	}
 
 	/**

+ 7 - 0
src/gc/GCRoute.java

@@ -41,6 +41,13 @@ public class GCRoute<T> extends IntegerLib<T> {
 		T[][][] output = env.newTArray(2, 0, 0);
 		output[0] = target;
 		output[1] = ptai[1];
+
+		// rm sign bit
+		for (int i = 0; i < output[0].length; i++) {
+			output[0][i] = Arrays.copyOfRange(output[0][i], 0, logD);
+			output[1][i] = Arrays.copyOfRange(output[1][i], 0, logW);
+		}
+
 		return output;
 	}
 

+ 7 - 6
src/gc/GCUtil.java

@@ -8,6 +8,7 @@ import com.oblivm.backend.gc.GCSignal;
 import crypto.Crypto;
 import exceptions.LengthNotMatchException;
 import oram.Tuple;
+import util.Util;
 
 public class GCUtil {
 
@@ -66,24 +67,24 @@ public class GCUtil {
 		return out;
 	}
 
-	public static BigInteger[] genOutKeyHashes(GCSignal[] outZeroKeys) {
-		BigInteger[] hashes = new BigInteger[outZeroKeys.length];
+	public static byte[][] genOutKeyHashes(GCSignal[] outZeroKeys) {
+		byte[][] hashes = new byte[outZeroKeys.length][];
 		for (int i = 0; i < outZeroKeys.length; i++) {
-			hashes[i] = new BigInteger(Crypto.sha1.digest(outZeroKeys[i].bytes));
+			hashes[i] = Crypto.sha1.digest(outZeroKeys[i].bytes);
 		}
 		return hashes;
 	}
 
-	public static BigInteger evaOutKeys(GCSignal[] outKeys, BigInteger[] genHashes) {
+	public static BigInteger evaOutKeys(GCSignal[] outKeys, byte[][] genHashes) {
 		if (outKeys.length != genHashes.length)
 			throw new LengthNotMatchException(outKeys.length + " != " + genHashes.length);
-		BigInteger[] evaHashes = genOutKeyHashes(outKeys);
+		byte[][] evaHashes = genOutKeyHashes(outKeys);
 		BigInteger output = BigInteger.ZERO;
 		for (int i = 0; i < outKeys.length; i++) {
 			if (outKeys[i].isPublic()) {
 				if (outKeys[i].v)
 					output = output.setBit(i);
-			} else if (genHashes[i].compareTo(evaHashes[i]) != 0) {
+			} else if (!Util.equal(genHashes[i], evaHashes[i])) {
 				output = output.setBit(i);
 			}
 		}

+ 0 - 1
src/protocols/Access.java

@@ -4,7 +4,6 @@ import java.math.BigInteger;
 import java.util.Arrays;
 
 import org.apache.commons.lang3.ArrayUtils;
-import org.apache.commons.lang3.SerializationUtils;
 
 import communication.Communication;
 import crypto.Crypto;

+ 8 - 7
src/protocols/Eviction.java

@@ -69,8 +69,7 @@ public class Eviction extends Protocol {
 		for (int i = 0; i < d; i++) {
 			E_feInputKeys[i] = GCUtil.selectFeKeys(predata.evict_E_feKeyPairs[i], pathBuckets[i].getTuples());
 			E_labelInputKeys[i] = GCUtil.selectLabelKeys(predata.evict_E_labelKeyPairs[i], pathBuckets[i].getTuples());
-			deltaInputKeys[i] = GCUtil.revSelectKeys(predata.evict_deltaKeyPairs[i],
-					predata.evict_delta[i].toByteArray());
+			deltaInputKeys[i] = GCUtil.revSelectKeys(predata.evict_deltaKeyPairs[i], predata.evict_delta[i]);
 		}
 
 		timer.start(pid, M.online_write);
@@ -144,22 +143,24 @@ public class Eviction extends Protocol {
 		GCSignal[][][] C_labelInputKeys = con2.readTripleGCSignalArray();
 		timer.stop(pid, M.online_read);
 
+		int w = OTi.getW();
+		int logW = (int) Math.ceil(Math.log(w + 1) / Math.log(2));
+
 		GCSignal[][][] outKeys = predata.evict_gcroute.routing(LiInputKeys, E_feInputKeys, C_feInputKeys,
 				E_labelInputKeys, C_labelInputKeys, deltaInputKeys);
 
-		int[] ti_p = new int[deltaInputKeys.length];
+		byte[][] ti_p = new byte[deltaInputKeys.length][];
 		for (int i = 0; i < ti_p.length; i++) {
-			ti_p[i] = GCUtil.evaOutKeys(outKeys[1][i], predata.evict_tiOutKeyHashes[i]).intValue();
+			ti_p[i] = Util.padArray(GCUtil.evaOutKeys(outKeys[1][i], predata.evict_tiOutKeyHashes[i]).toByteArray(),
+					(logW + 7) / 8);
 		}
 
 		PermuteTarget permutetarget = new PermuteTarget(con1, con2);
 		int[] target_pp = permutetarget.runD(predata, firstTree, outKeys[0], timer);
 
 		PermuteIndex permuteindex = new PermuteIndex(con1, con2);
-		int[] ti_pp = permuteindex.runD(predata, firstTree, ti_p, timer);
+		int[] ti_pp = permuteindex.runD(predata, firstTree, ti_p, w, timer);
 
-		int w = OTi.getW();
-		int logW = (int) Math.ceil(Math.log(w + 1) / Math.log(2));
 		int W = (int) Math.pow(2, logW);
 		int[] evict = prepareEviction(target_pp, ti_pp, W);
 

+ 22 - 22
src/protocols/PermuteIndex.java

@@ -26,31 +26,28 @@ public class PermuteIndex extends Protocol {
 	public void runE() {
 	}
 
-	public int[] runD(PreData predata, boolean firstTree, int[] ti, Timer timer) {
+	public int[] runD(PreData predata, boolean firstTree, byte[][] ti, int w, Timer timer) {
 		if (firstTree)
 			return null;
 
 		timer.start(pid, M.online_comp);
 
-		BigInteger[] ti_p = new BigInteger[ti.length];
-		for (int i = 0; i < ti.length; i++)
-			ti_p[i] = BigInteger.valueOf(ti[i]);
-
-		BigInteger[] z = Util.xor(ti_p, predata.pi_p);
+		byte[][] z = Util.xor(ti, predata.pi_p);
 
 		timer.start(pid, M.online_write);
 		con2.write(pid, z);
 		timer.stop(pid, M.online_write);
 
 		timer.start(pid, M.online_read);
-		BigInteger[] g = con2.readBigIntegerArray();
+		byte[][] g = con2.readDoubleByteArray();
 		timer.stop(pid, M.online_read);
 
-		ti_p = Util.xor(predata.pi_a, g);
+		ti = Util.xor(predata.pi_a, g);
 
+		int logW = (int) Math.ceil(Math.log(w + 1) / Math.log(2));
 		int[] ti_pp = new int[ti.length];
 		for (int i = 0; i < ti.length; i++)
-			ti_pp[i] = ti_p[i].intValue();
+			ti_pp[i] = Util.getSubBits(new BigInteger(ti[i]), logW, 0).intValue();
 
 		timer.stop(pid, M.online_comp);
 		return ti_pp;
@@ -63,12 +60,12 @@ public class PermuteIndex extends Protocol {
 		timer.start(pid, M.online_comp);
 
 		timer.start(pid, M.online_read);
-		BigInteger[] z = con2.readBigIntegerArray();
+		byte[][] z = con2.readDoubleByteArray();
 		timer.stop(pid, M.online_read);
 
 		z = Util.xor(z, predata.pi_r);
 		z = Util.permute(z, predata.evict_pi);
-		BigInteger[] g = Util.xor(predata.evict_rho, z);
+		byte[][] g = Util.xor(predata.evict_rho, z);
 
 		timer.start(pid, M.online_write);
 		con2.write(pid, g);
@@ -82,7 +79,7 @@ public class PermuteIndex extends Protocol {
 	public void run(Party party, Metadata md, Forest forest) {
 		Timer timer = new Timer();
 
-		for (int i = 0; i < 50; i++) {
+		for (int i = 0; i < 100; i++) {
 
 			System.out.println("i=" + i);
 
@@ -94,17 +91,18 @@ public class PermuteIndex extends Protocol {
 				int w = Crypto.sr.nextInt(15) + 5;
 				int logW = (int) Math.ceil(Math.log(w + 1) / Math.log(2));
 
-				int[] ti = new int[d];
+				byte[][] ti = new byte[d][];
 				predata.evict_pi = Util.randomPermutation(d, Crypto.sr);
-				predata.evict_rho = new BigInteger[d];
+				predata.evict_rho = new byte[d][];
 				for (int j = 0; j < d; j++) {
-					ti[j] = Crypto.sr.nextInt(w + 1);
-					predata.evict_rho[j] = new BigInteger(logW, Crypto.sr);
+					ti[j] = Util.nextBytes((logW + 7) / 8, Crypto.sr);
+					predata.evict_rho[j] = Util.nextBytes((logW + 7) / 8, Crypto.sr);
 				}
 
 				con1.write(predata.evict_pi);
 				con1.write(predata.evict_rho);
 				con1.write(ti);
+				con1.write(w);
 
 				con2.write(predata.evict_pi);
 				con2.write(predata.evict_rho);
@@ -117,8 +115,9 @@ public class PermuteIndex extends Protocol {
 				ti = Util.permute(ti, predata.evict_pi);
 				int j = 0;
 				for (; j < d; j++) {
-					ti[j] = predata.evict_rho[j].intValue() ^ ti[j];
-					if (ti[j] != ti_pp[j]) {
+					int tmp = Util.getSubBits(new BigInteger(Util.xor(predata.evict_rho[j], ti[j])), logW, 0)
+							.intValue();
+					if (tmp != ti_pp[j]) {
 						System.err.println("PermuteIndex test failed");
 						break;
 					}
@@ -128,17 +127,18 @@ public class PermuteIndex extends Protocol {
 
 			} else if (party == Party.Debbie) {
 				predata.evict_pi = con1.readIntArray();
-				predata.evict_rho = con1.readBigIntegerArray();
-				int[] ti = con1.readIntArray();
+				predata.evict_rho = con1.readDoubleByteArray();
+				byte[][] ti = con1.readDoubleByteArray();
+				int w = con1.readInt();
 
 				prepermuteindex.runD(predata, timer);
 
-				int[] ti_pp = runD(predata, false, ti, timer);
+				int[] ti_pp = runD(predata, false, ti, w, timer);
 				con1.write(ti_pp);
 
 			} else if (party == Party.Charlie) {
 				predata.evict_pi = con1.readIntArray();
-				predata.evict_rho = con1.readBigIntegerArray();
+				predata.evict_rho = con1.readDoubleByteArray();
 
 				prepermuteindex.runC(predata, timer);
 

+ 13 - 12
src/protocols/PermuteTarget.java

@@ -37,13 +37,14 @@ public class PermuteTarget extends Protocol {
 
 		// PermuteTargetI
 		int d = targetOutKeys.length;
+		int logD = (int) Math.ceil(Math.log(d) / Math.log(2));
 		int I[] = new int[d];
-		BigInteger[] target = new BigInteger[d];
+		byte[][] target = new byte[d][];
 
 		for (int i = 0; i < d; i++) {
-			BigInteger hashKeys = new BigInteger(GCUtil.hashAll(targetOutKeys[i]));
+			byte[] hashKeys = GCUtil.hashAll(targetOutKeys[i]);
 			for (int j = 0; j < d; j++) {
-				if (hashKeys.compareTo(predata.pt_keyT[i][j]) == 0) {
+				if (Util.equal(hashKeys, predata.pt_keyT[i][j])) {
 					I[i] = j;
 					target[i] = predata.pt_targetT[i][j];
 					break;
@@ -52,7 +53,7 @@ public class PermuteTarget extends Protocol {
 		}
 
 		// PermuteTargetII
-		BigInteger[] z = Util.xor(target, predata.pt_p);
+		byte[][] z = Util.xor(target, predata.pt_p);
 
 		timer.start(pid, M.online_write);
 		con2.write(pid, z);
@@ -60,14 +61,14 @@ public class PermuteTarget extends Protocol {
 		timer.stop(pid, M.online_write);
 
 		timer.start(pid, M.online_read);
-		BigInteger[] g = con2.readBigIntegerArray();
+		byte[][] g = con2.readDoubleByteArray();
 		timer.stop(pid, M.online_read);
 
 		target = Util.xor(predata.pt_a, g);
 
 		int[] target_pp = new int[d];
 		for (int i = 0; i < d; i++)
-			target_pp[i] = target[i].intValue();
+			target_pp[i] = Util.getSubBits(new BigInteger(target[i]), logD, 0).intValue();
 
 		timer.stop(pid, M.online_comp);
 		return target_pp;
@@ -81,16 +82,16 @@ public class PermuteTarget extends Protocol {
 
 		// PermuteTargetII
 		timer.start(pid, M.online_read);
-		BigInteger[] z = con2.readBigIntegerArray();
+		byte[][] z = con2.readDoubleByteArray();
 		int[] I = con2.readIntArray();
 		timer.stop(pid, M.online_read);
 
-		BigInteger[] mk = new BigInteger[z.length];
+		byte[][] mk = new byte[z.length][];
 		for (int i = 0; i < mk.length; i++) {
-			mk[i] = predata.pt_maskT[i][I[i]].xor(z[i]);
-			mk[i] = predata.pt_r[i].xor(mk[i]);
+			mk[i] = Util.xor(predata.pt_maskT[i][I[i]], z[i]);
+			mk[i] = Util.xor(predata.pt_r[i], mk[i]);
 		}
-		BigInteger[] g = Util.permute(mk, predata.evict_pi);
+		byte[][] g = Util.permute(mk, predata.evict_pi);
 
 		timer.start(pid, M.online_write);
 		con2.write(pid, g);
@@ -104,7 +105,7 @@ public class PermuteTarget extends Protocol {
 	public void run(Party party, Metadata md, Forest forest) {
 		Timer timer = new Timer();
 
-		for (int i = 0; i < 50; i++) {
+		for (int i = 0; i < 100; i++) {
 
 			System.out.println("i=" + i);
 

+ 3 - 3
src/protocols/UpdateRoot.java

@@ -148,7 +148,7 @@ public class UpdateRoot extends Protocol {
 				con2.write(sw);
 				con2.write(lBits);
 
-				preupdateroot.runE(predata, sw, lBits, timer);
+				preupdateroot.runE(predata, false, sw, lBits, timer);
 				Tuple[] newR = runE(predata, false, Li, R, Ti, timer);
 
 				Tuple[] R_C = con2.readTupleArray();
@@ -230,7 +230,7 @@ public class UpdateRoot extends Protocol {
 				byte[] Li = con1.read();
 				int[] tupleParam = new int[] { 1, 2, (lBits + 7) / 8, 3 };
 
-				preupdateroot.runD(predata, sw, lBits, tupleParam, timer);
+				preupdateroot.runD(predata, false, sw, lBits, tupleParam, timer);
 				runD(predata, false, Li, md.getW(), timer);
 
 			} else if (party == Party.Charlie) {
@@ -241,7 +241,7 @@ public class UpdateRoot extends Protocol {
 					R[j] = new Tuple(1, 2, (lBits + 7) / 8, 3, null);
 				Tuple Ti = new Tuple(1, 2, (lBits + 7) / 8, 3, null);
 
-				preupdateroot.runC(predata, timer);
+				preupdateroot.runC(predata, false, timer);
 				R = runC(predata, false, R, Ti, timer);
 
 				con1.write(R);

+ 8 - 10
src/protocols/precomputation/PreEviction.java

@@ -1,7 +1,5 @@
 package protocols.precomputation;
 
-import java.math.BigInteger;
-
 import com.oblivm.backend.flexsc.CompEnv;
 import com.oblivm.backend.gc.GCSignal;
 import com.oblivm.backend.gc.regular.GCEva;
@@ -77,7 +75,7 @@ public class PreEviction extends Protocol {
 		GCSignal[][][] outZeroKeys = new GCRoute<GCSignal>(gen, d, w).routing(LiZeroKeys, E_feZeroKeys, C_feZeroKeys,
 				E_labelZeroKeys, C_labelZeroKeys, deltaZeroKeys);
 
-		predata.evict_tiOutKeyHashes = new BigInteger[d][];
+		predata.evict_tiOutKeyHashes = new byte[d][][];
 		predata.evict_targetOutKeyPairs = new GCSignal[d][][];
 		for (int i = 0; i < d; i++) {
 			predata.evict_tiOutKeyHashes[i] = GCUtil.genOutKeyHashes(outZeroKeys[1][i]);
@@ -94,14 +92,14 @@ public class PreEviction extends Protocol {
 
 		// Permutation
 		predata.evict_pi = Util.randomPermutation(d, Crypto.sr);
-		predata.evict_delta = new BigInteger[d];
-		predata.evict_rho = new BigInteger[d];
+		predata.evict_delta = new byte[d][];
+		predata.evict_rho = new byte[d][];
 		predata.evict_delta_p = new int[d][];
 		predata.evict_rho_p = new int[d][];
 
 		for (int i = 0; i < d; i++) {
-			predata.evict_delta[i] = new BigInteger(logW, Crypto.sr);
-			predata.evict_rho[i] = new BigInteger(logW, Crypto.sr);
+			predata.evict_delta[i] = Util.nextBytes((logW + 7) / 8, Crypto.sr);
+			predata.evict_rho[i] = Util.nextBytes((logW + 7) / 8, Crypto.sr);
 			predata.evict_delta_p[i] = Util.getXorPermutation(predata.evict_delta[i], logW);
 			predata.evict_rho_p[i] = Util.getXorPermutation(predata.evict_rho[i], logW);
 		}
@@ -164,7 +162,7 @@ public class PreEviction extends Protocol {
 		eva.setEvaluate();
 
 		timer.start(pid, M.offline_read);
-		predata.evict_tiOutKeyHashes = con1.readDoubleBigIntegerArray();
+		predata.evict_tiOutKeyHashes = con1.readTripleByteArray();
 		predata.evict_targetOutKeyPairs = con1.readTripleGCSignalArray();
 		timer.stop(pid, M.offline_read);
 
@@ -197,8 +195,8 @@ public class PreEviction extends Protocol {
 
 		// Permutation
 		predata.evict_pi = con1.readIntArray();
-		predata.evict_delta = con1.readBigIntegerArray();
-		predata.evict_rho = con1.readBigIntegerArray();
+		predata.evict_delta = con1.readDoubleByteArray();
+		predata.evict_rho = con1.readDoubleByteArray();
 		predata.evict_delta_p = con1.readDoubleIntArray();
 		predata.evict_rho_p = con1.readDoubleIntArray();
 		timer.stop(pid, M.offline_read);

+ 9 - 11
src/protocols/precomputation/PrePermuteIndex.java

@@ -1,7 +1,5 @@
 package protocols.precomputation;
 
-import java.math.BigInteger;
-
 import communication.Communication;
 import crypto.Crypto;
 import oram.Forest;
@@ -27,13 +25,13 @@ public class PrePermuteIndex extends Protocol {
 
 		int logW = (int) Math.ceil(Math.log(w + 1) / Math.log(2));
 
-		predata.pi_p = new BigInteger[d];
-		predata.pi_r = new BigInteger[d];
-		predata.pi_a = new BigInteger[d];
+		predata.pi_p = new byte[d][];
+		predata.pi_r = new byte[d][];
+		predata.pi_a = new byte[d][];
 		for (int i = 0; i < d; i++) {
-			predata.pi_p[i] = new BigInteger(logW, Crypto.sr);
-			predata.pi_r[i] = new BigInteger(logW, Crypto.sr);
-			predata.pi_a[i] = predata.pi_p[i].xor(predata.pi_r[i]);
+			predata.pi_p[i] = Util.nextBytes((logW + 7) / 8, Crypto.sr);
+			predata.pi_r[i] = Util.nextBytes((logW + 7) / 8, Crypto.sr);
+			predata.pi_a[i] = Util.xor(predata.pi_p[i], predata.pi_r[i]);
 		}
 		predata.pi_a = Util.permute(predata.pi_a, predata.evict_pi);
 
@@ -48,14 +46,14 @@ public class PrePermuteIndex extends Protocol {
 
 	public void runD(PreData predata, Timer timer) {
 		timer.start(pid, M.offline_read);
-		predata.pi_p = con1.readBigIntegerArray();
-		predata.pi_a = con1.readBigIntegerArray();
+		predata.pi_p = con1.readDoubleByteArray();
+		predata.pi_a = con1.readDoubleByteArray();
 		timer.stop(pid, M.offline_read);
 	}
 
 	public void runC(PreData predata, Timer timer) {
 		timer.start(pid, M.offline_read);
-		predata.pi_r = con1.readBigIntegerArray();
+		predata.pi_r = con1.readDoubleByteArray();
 		timer.stop(pid, M.offline_read);
 	}
 

+ 20 - 18
src/protocols/precomputation/PrePermuteTarget.java

@@ -31,19 +31,21 @@ public class PrePermuteTarget extends Protocol {
 		// PermuteTargetI
 		int logD = (int) Math.ceil(Math.log(d) / Math.log(2));
 
-		predata.pt_keyT = new BigInteger[d][d];
-		predata.pt_targetT = new BigInteger[d][d];
-		predata.pt_maskT = new BigInteger[d][d];
+		predata.pt_keyT = new byte[d][d][];
+		predata.pt_targetT = new byte[d][d][];
+		predata.pt_maskT = new byte[d][d][];
 
 		for (int i = 0; i < d; i++) {
 			for (int j = 0; j < d; j++) {
 				GCSignal[] keys = GCUtil.revSelectKeys(predata.evict_targetOutKeyPairs[i],
 						BigInteger.valueOf(j).toByteArray());
-				predata.pt_keyT[i][j] = new BigInteger(GCUtil.hashAll(keys));
+				predata.pt_keyT[i][j] = GCUtil.hashAll(keys);
 
-				predata.pt_maskT[i][j] = new BigInteger(logD, Crypto.sr);
+				predata.pt_maskT[i][j] = Util.nextBytes((logD + 7) / 8, Crypto.sr);
 
-				predata.pt_targetT[i][j] = BigInteger.valueOf(predata.evict_pi[j]).xor(predata.pt_maskT[i][j]);
+				predata.pt_targetT[i][j] = Util.xor(
+						Util.padArray(BigInteger.valueOf(predata.evict_pi[j]).toByteArray(), (logD + 7) / 8),
+						predata.pt_maskT[i][j]);
 			}
 
 			int[] randPerm = Util.randomPermutation(d, Crypto.sr);
@@ -59,13 +61,13 @@ public class PrePermuteTarget extends Protocol {
 		timer.stop(pid, M.offline_write);
 
 		// PermuteTargetII
-		predata.pt_p = new BigInteger[d];
-		predata.pt_r = new BigInteger[d];
-		predata.pt_a = new BigInteger[d];
+		predata.pt_p = new byte[d][];
+		predata.pt_r = new byte[d][];
+		predata.pt_a = new byte[d][];
 		for (int i = 0; i < d; i++) {
-			predata.pt_p[i] = new BigInteger(logD, Crypto.sr);
-			predata.pt_r[i] = new BigInteger(logD, Crypto.sr);
-			predata.pt_a[i] = predata.pt_p[i].xor(predata.pt_r[i]);
+			predata.pt_p[i] = Util.nextBytes((logD + 7) / 8, Crypto.sr);
+			predata.pt_r[i] = Util.nextBytes((logD + 7) / 8, Crypto.sr);
+			predata.pt_a[i] = Util.xor(predata.pt_p[i], predata.pt_r[i]);
 		}
 		predata.pt_a = Util.permute(predata.pt_a, predata.evict_pi);
 
@@ -81,22 +83,22 @@ public class PrePermuteTarget extends Protocol {
 	public void runD(PreData predata, int d, Timer timer) {
 		timer.start(pid, M.offline_read);
 		// PermuteTargetI
-		predata.pt_keyT = con1.readDoubleBigIntegerArray();
-		predata.pt_targetT = con1.readDoubleBigIntegerArray();
+		predata.pt_keyT = con1.readTripleByteArray();
+		predata.pt_targetT = con1.readTripleByteArray();
 
 		// PermuteTargetII
-		predata.pt_p = con1.readBigIntegerArray();
-		predata.pt_a = con1.readBigIntegerArray();
+		predata.pt_p = con1.readDoubleByteArray();
+		predata.pt_a = con1.readDoubleByteArray();
 		timer.stop(pid, M.offline_read);
 	}
 
 	public void runC(PreData predata, Timer timer) {
 		timer.start(pid, M.offline_read);
 		// PermuteTargetI
-		predata.pt_maskT = con1.readDoubleBigIntegerArray();
+		predata.pt_maskT = con1.readTripleByteArray();
 
 		// PermuteTargetII
-		predata.pt_r = con1.readBigIntegerArray();
+		predata.pt_r = con1.readDoubleByteArray();
 		timer.stop(pid, M.offline_read);
 	}
 

+ 6 - 6
src/protocols/precomputation/PreRetrieve.java

@@ -30,11 +30,11 @@ public class PreRetrieve extends Protocol {
 		preaccess.runE(predata[0], md.getTwoTauPow(), numTuples, tupleParam, timer);
 		prereshuffle.runE(predata[0], timer);
 		prepostprocesst.runE(predata[0], timer);
-		preupdateroot.runE(predata[0], md.getStashSizeOfTree(ti), md.getLBitsOfTree(ti), timer);
+		preupdateroot.runE(predata[0], ti == 0, md.getStashSizeOfTree(ti), md.getLBitsOfTree(ti), timer);
 		preeviction.runE(predata[0], ti == 0, md.getLBitsOfTree(ti) + 1, md.getW(), timer);
 
 		// 2nd eviction
-		preupdateroot.runE(predata[1], md.getStashSizeOfTree(ti), md.getLBitsOfTree(ti), timer);
+		preupdateroot.runE(predata[1], ti == 0, md.getStashSizeOfTree(ti), md.getLBitsOfTree(ti), timer);
 		preeviction.runE(predata[1], ti == 0, md.getLBitsOfTree(ti) + 1, md.getW(), timer);
 	}
 
@@ -52,11 +52,11 @@ public class PreRetrieve extends Protocol {
 		preaccess.runD(predata[0], timer);
 		prereshuffle.runD(predata[0], tupleParam, timer);
 		prepostprocesst.runD(predata[0], prev, md.getLBytesOfTree(ti), md.getAlBytesOfTree(ti), md.getTau(), timer);
-		preupdateroot.runD(predata[0], md.getStashSizeOfTree(ti), md.getLBitsOfTree(ti), tupleParam, timer);
+		preupdateroot.runD(predata[0], ti == 0, md.getStashSizeOfTree(ti), md.getLBitsOfTree(ti), tupleParam, timer);
 		preeviction.runD(predata[0], ti == 0, md.getLBitsOfTree(ti) + 1, md.getW(), tupleParam, timer);
 
 		// 2nd eviction
-		preupdateroot.runD(predata[1], md.getStashSizeOfTree(ti), md.getLBitsOfTree(ti), tupleParam, timer);
+		preupdateroot.runD(predata[1], ti == 0, md.getStashSizeOfTree(ti), md.getLBitsOfTree(ti), tupleParam, timer);
 		preeviction.runD(predata[1], ti == 0, md.getLBitsOfTree(ti) + 1, md.getW(), tupleParam, timer);
 	}
 
@@ -71,11 +71,11 @@ public class PreRetrieve extends Protocol {
 		preaccess.runC(timer);
 		prereshuffle.runC(predata[0], timer);
 		prepostprocesst.runC(predata[0], prev, md.getLBytesOfTree(ti), md.getAlBytesOfTree(ti), timer);
-		preupdateroot.runC(predata[0], timer);
+		preupdateroot.runC(predata[0], ti == 0, timer);
 		preeviction.runC(predata[0], ti == 0, timer);
 
 		// 2nd eviction
-		preupdateroot.runC(predata[1], timer);
+		preupdateroot.runC(predata[1], ti == 0, timer);
 		preeviction.runC(predata[1], ti == 0, timer);
 	}
 

+ 14 - 7
src/protocols/precomputation/PreUpdateRoot.java

@@ -1,7 +1,5 @@
 package protocols.precomputation;
 
-import java.math.BigInteger;
-
 import com.oblivm.backend.flexsc.CompEnv;
 import com.oblivm.backend.gc.GCSignal;
 import com.oblivm.backend.gc.regular.GCEva;
@@ -28,7 +26,10 @@ public class PreUpdateRoot extends Protocol {
 		super(con1, con2);
 	}
 
-	public void runE(PreData predata, int sw, int lBits, Timer timer) {
+	public void runE(PreData predata, boolean firstTree, int sw, int lBits, Timer timer) {
+		if (firstTree)
+			return;
+
 		timer.start(pid, M.offline_comp);
 
 		int sLogW = (int) Math.ceil(Math.log(sw) / Math.log(2));
@@ -56,7 +57,7 @@ public class PreUpdateRoot extends Protocol {
 		GCSignal[][] outZeroKeys = new GCUpdateRoot<GCSignal>(gen, lBits + 1, sw).rootFindDeepestAndEmpty(j1ZeroKeys,
 				LiZeroKeys, E_feZeroKeys, C_feZeroKeys, E_labelZeroKeys, C_labelZeroKeys);
 
-		predata.ur_outKeyHashes = new BigInteger[outZeroKeys.length][];
+		predata.ur_outKeyHashes = new byte[outZeroKeys.length][][];
 		for (int i = 0; i < outZeroKeys.length; i++)
 			predata.ur_outKeyHashes[i] = GCUtil.genOutKeyHashes(outZeroKeys[i]);
 
@@ -72,7 +73,10 @@ public class PreUpdateRoot extends Protocol {
 		timer.stop(pid, M.offline_comp);
 	}
 
-	public void runD(PreData predata, int sw, int lBits, int[] tupleParam, Timer timer) {
+	public void runD(PreData predata, boolean firstTree, int sw, int lBits, int[] tupleParam, Timer timer) {
+		if (firstTree)
+			return;
+
 		timer.start(pid, M.offline_comp);
 
 		int logSW = (int) Math.ceil(Math.log(sw) / Math.log(2));
@@ -95,7 +99,7 @@ public class PreUpdateRoot extends Protocol {
 		eva.setEvaluate();
 
 		timer.start(pid, M.offline_read);
-		predata.ur_outKeyHashes = con1.readDoubleBigIntegerArray();
+		predata.ur_outKeyHashes = con1.readTripleByteArray();
 		timer.stop(pid, M.offline_read);
 
 		PreSSXOT pressxot = new PreSSXOT(con1, con2, 0);
@@ -104,7 +108,10 @@ public class PreUpdateRoot extends Protocol {
 		timer.stop(pid, M.offline_comp);
 	}
 
-	public void runC(PreData predata, Timer timer) {
+	public void runC(PreData predata, boolean firstTree, Timer timer) {
+		if (firstTree)
+			return;
+
 		timer.start(pid, M.offline_comp);
 
 		timer.start(pid, M.offline_read);

+ 13 - 15
src/protocols/struct/PreData.java

@@ -1,7 +1,5 @@
 package protocols.struct;
 
-import java.math.BigInteger;
-
 import com.oblivm.backend.gc.GCSignal;
 
 import crypto.PRF;
@@ -50,7 +48,7 @@ public class PreData {
 	public GCSignal[][] ur_C_feKeyPairs;
 	public GCSignal[][][] ur_E_labelKeyPairs;
 	public GCSignal[][][] ur_C_labelKeyPairs;
-	public BigInteger[][] ur_outKeyHashes;
+	public byte[][][] ur_outKeyHashes;
 	public GCUpdateRoot<GCSignal> ur_gcur;
 
 	public GCSignal[][] evict_LiKeyPairs;
@@ -59,26 +57,26 @@ public class PreData {
 	public GCSignal[][][][] evict_E_labelKeyPairs;
 	public GCSignal[][][][] evict_C_labelKeyPairs;
 	public GCSignal[][][] evict_deltaKeyPairs;
-	public BigInteger[][] evict_tiOutKeyHashes;
+	public byte[][][] evict_tiOutKeyHashes;
 	public GCSignal[][][] evict_targetOutKeyPairs;
 	public GCRoute<GCSignal> evict_gcroute;
 	public int[] evict_pi;
-	public BigInteger[] evict_delta;
-	public BigInteger[] evict_rho;
+	public byte[][] evict_delta;
+	public byte[][] evict_rho;
 	public int[][] evict_delta_p;
 	public int[][] evict_rho_p;
 
 	// PermuteTargetI
-	public BigInteger[][] pt_maskT;
-	public BigInteger[][] pt_keyT;
-	public BigInteger[][] pt_targetT;
+	public byte[][][] pt_maskT;
+	public byte[][][] pt_keyT;
+	public byte[][][] pt_targetT;
 	// PermuteTargetII
-	public BigInteger[] pt_p;
-	public BigInteger[] pt_r;
-	public BigInteger[] pt_a;
+	public byte[][] pt_p;
+	public byte[][] pt_r;
+	public byte[][] pt_a;
 
 	// PermuteIndex
-	public BigInteger[] pi_p;
-	public BigInteger[] pi_r;
-	public BigInteger[] pi_a;
+	public byte[][] pi_p;
+	public byte[][] pi_r;
+	public byte[][] pi_a;
 }

+ 24 - 2
src/util/Util.java

@@ -71,6 +71,15 @@ public class Util {
 		return arr;
 	}
 
+	public static byte[][] xor(byte[][] a, byte[][] b) {
+		if (a.length != b.length)
+			throw new LengthNotMatchException(a.length + " != " + b.length);
+		byte[][] c = new byte[a.length][];
+		for (int i = 0; i < a.length; i++)
+			c[i] = xor(a[i], b[i]);
+		return c;
+	}
+
 	// c = a ^ b
 	public static byte[] xor(byte[] a, byte[] b) {
 		if (a.length != b.length)
@@ -161,11 +170,12 @@ public class Util {
 		}
 	}
 
-	public static int[] getXorPermutation(BigInteger b, int bits) {
+	public static int[] getXorPermutation(byte[] b, int bits) {
+		BigInteger bi = Util.getSubBits(new BigInteger(b), bits, 0);
 		int len = (int) Math.pow(2, bits);
 		int[] p = new int[len];
 		for (int i = 0; i < len; i++) {
-			p[i] = BigInteger.valueOf(i).xor(b).intValue();
+			p[i] = BigInteger.valueOf(i).xor(bi).intValue();
 		}
 		return p;
 	}
@@ -177,6 +187,18 @@ public class Util {
 		return out;
 	}
 
+	public static byte[] padArray(byte[] in, int len) {
+		if (in.length == len)
+			return in;
+		else if (in.length < len) {
+			byte[] out = new byte[len];
+			System.arraycopy(in, 0, out, len - in.length, in.length);
+			return out;
+		} else {
+			return Arrays.copyOfRange(in, in.length - len, in.length);
+		}
+	}
+
 	public static void debug(String s) {
 		// only to make Communication.java compile
 	}