Explorar o código

Retrieve with all protocols running correctly! Yeah!!

Boyoung- %!s(int64=8) %!d(string=hai) anos
pai
achega
fff8a672a2

+ 46 - 0
src/oram/Bucket.java

@@ -4,7 +4,11 @@ import java.io.Serializable;
 import java.util.Arrays;
 import java.util.Random;
 
+import org.apache.commons.lang3.ArrayUtils;
+
+import crypto.Crypto;
 import exceptions.LengthNotMatchException;
+import util.Util;
 
 public class Bucket implements Serializable {
 	/**
@@ -48,6 +52,11 @@ public class Bucket implements Serializable {
 	public Tuple[] getTuples() {
 		return tuples;
 	}
+	
+	public void setTuples(Tuple[] tuples) {
+		// TODO: add checks
+		this.tuples = tuples;
+	}
 
 	public Tuple getTuple(int i) {
 		return tuples[i];
@@ -58,6 +67,10 @@ public class Bucket implements Serializable {
 			throw new LengthNotMatchException(tuples[i].getNumBytes() + " != " + tuple.getNumBytes());
 		tuples[i] = tuple;
 	}
+	
+	public void permute(int[] p) {
+		tuples = Util.permute(tuples, p);
+	}
 
 	public Bucket xor(Bucket b) {
 		if (!this.sameLength(b))
@@ -125,4 +138,37 @@ public class Bucket implements Serializable {
 		}
 		return buckets;
 	}
+	
+	public void expand(Tuple[] ts) {
+		// TODO: add check
+		tuples = ArrayUtils.addAll(tuples, ts);
+		numBytes = tuples.length * tuples[0].getNumBytes();
+	}
+	
+	public void expand(int numTuples) {
+		if (tuples.length >= numTuples)
+			return;
+		
+		int f = tuples[0].getF().length;
+		int n = tuples[0].getN().length;
+		int l = tuples[0].getL().length;
+		int a = tuples[0].getA().length;
+		
+		Tuple[] newTuples = new Tuple[numTuples];
+		System.arraycopy(tuples, 0, newTuples, 0, tuples.length);
+		for (int i=tuples.length; i<numTuples; i++) {
+			newTuples[i] = new Tuple(f, n, l, a, Crypto.sr);
+			newTuples[i].setF(new byte[f]);
+		}
+		
+		tuples = newTuples;
+		numBytes = tuples.length * tuples[0].getNumBytes();
+	}
+	
+	public void shrink(int numTuples) {
+		if (numTuples >= tuples.length)
+			return;
+		tuples = Arrays.copyOfRange(tuples, 0, numTuples);
+		numBytes = tuples.length * tuples[0].getNumBytes();
+	}
 }

+ 6 - 3
src/oram/Tree.java

@@ -4,9 +4,9 @@ import java.io.Serializable;
 import java.math.BigInteger;
 import java.util.Random;
 
-import exceptions.InvalidPathLabelException;
 import exceptions.LengthNotMatchException;
 import util.Array64;
+import util.Util;
 
 public class Tree implements Serializable {
 	/**
@@ -118,8 +118,11 @@ public class Tree implements Serializable {
 	private long[] getBucketIndicesOnPath(long L) {
 		if (treeIndex == 0)
 			return new long[] { 0 };
-		if (L < 0 || L > numBuckets / 2)
-			throw new InvalidPathLabelException(BigInteger.valueOf(L).toString(2));
+		
+		//if (L < 0 || L > numBuckets / 2)
+		//	throw new InvalidPathLabelException(BigInteger.valueOf(L).toString(2));
+		L = Util.getSubBits(L, lBits, 0);
+		
 		BigInteger biL = BigInteger.valueOf(L);
 		long[] indices = new long[d];
 		for (int i = 1; i < d; i++) {

+ 169 - 26
src/protocols/Eviction.java

@@ -1,6 +1,7 @@
 package protocols;
 
 import java.math.BigInteger;
+import java.util.Arrays;
 
 import com.oblivm.backend.gc.GCSignal;
 
@@ -12,6 +13,7 @@ import measure.Timer;
 import oram.Bucket;
 import oram.Forest;
 import oram.Metadata;
+import oram.Tree;
 import oram.Tuple;
 import util.Util;
 
@@ -19,10 +21,35 @@ public class Eviction extends Protocol {
 	public Eviction(Communication con1, Communication con2) {
 		super(con1, con2);
 	}
+	
+	private int[] prepareEviction(int target[], int[] ti, int W) {
+		int d = ti.length;
+		int[] evict = new int[W*d];
+		for (int r=0; r<d; r++) {
+			int tupleIndex = r*W + ti[r];
+			for (int c=0; c<W; c++) {
+				int currIndex = r*W + c;
+				if (currIndex == tupleIndex) {
+					int targetIndex = target[r]*W + ti[target[r]];
+					evict[targetIndex] = currIndex;
+				}
+				else
+					evict[currIndex] = currIndex;
+			}
+		}
+		return evict;
+	}
 
-	public Tuple[] runE(PreData predata, boolean firstTree, byte[] Li, Tuple[] pathTuples, int d, int w, Timer timer) {
-		if (firstTree)
-			return pathTuples;
+	public void runE(PreData predata, boolean firstTree, byte[] Li, Tuple[] originalPath, int d, int w, Tree OTi, Timer timer) {
+		if (firstTree) {
+			OTi.setBucketsOnPath(new BigInteger(1, Li).longValue(), new Bucket[]{new Bucket(originalPath)});
+			return;
+		}
+		
+		int sw = OTi.getStashSize();
+		Tuple[] pathTuples = new Tuple[d*w];
+		System.arraycopy(originalPath, 0, pathTuples, 0, w);
+		System.arraycopy(originalPath, sw, pathTuples, w, (d-1)*w);
 
 		Bucket[] pathBuckets = Bucket.tuplesToBuckets(pathTuples, d, w, w);
 
@@ -41,13 +68,51 @@ public class Eviction extends Protocol {
 		con1.write(E_feInputKeys);
 		con1.write(E_labelInputKeys);
 		con1.write(deltaInputKeys);
-
-		return pathTuples;
+		
+		PermuteTarget permutetarget = new PermuteTarget(con1, con2);
+		permutetarget.runE();
+		
+		PermuteIndex permuteindex = new PermuteIndex(con1, con2);
+		permuteindex.runE();
+		
+		int logW = (int) Math.ceil(Math.log(w + 1) / Math.log(2));
+		int W = (int) Math.pow(2, logW);
+		for (int i=0; i<d; i++) {
+			pathBuckets[i].expand(W);
+			pathBuckets[i].permute(predata.evict_delta_p[i]);
+		}
+		pathBuckets = Util.permute(pathBuckets, predata.evict_pi);
+		for (int i=0; i<d; i++) {
+			pathBuckets[i].permute(predata.evict_rho_p[i]);
+		}
+		pathTuples = Bucket.bucketsToTuples(pathBuckets);
+		
+		SSXOT ssxot = new SSXOT(con1, con2, 1);
+		pathTuples = ssxot.runE(predata, pathTuples, timer);
+		
+		pathBuckets = Bucket.tuplesToBuckets(pathTuples, d, W, W);
+		for (int i=0; i<d; i++) {
+			int[] rho_ivs = Util.inversePermutation(predata.evict_rho_p[i]);
+			pathBuckets[i].permute(rho_ivs);
+		}
+		int[] pi_ivs = Util.inversePermutation(predata.evict_pi);
+		pathBuckets = Util.permute(pathBuckets, pi_ivs);
+		for (int i=0; i<d; i++) {
+			int[] delta_ivs = Util.inversePermutation(predata.evict_delta_p[i]);
+			pathBuckets[i].permute(delta_ivs);
+			pathBuckets[i].shrink(w);
+		}
+		
+		pathBuckets[0].expand(Arrays.copyOfRange(originalPath, w, sw));
+		OTi.setBucketsOnPath(new BigInteger(1, Li).longValue(), pathBuckets);
 	}
 
-	public void runD(PreData predata, boolean firstTree, byte[] Li, int w, Timer timer) {
-		if (firstTree)
+	public void runD(PreData predata, boolean firstTree, byte[] Li, int w, Tree OTi, Timer timer) {
+		if (firstTree) {
+			Tuple[] originalPath = con2.readObject();
+			OTi.setBucketsOnPath(new BigInteger(1, Li).longValue(), new Bucket[]{new Bucket(originalPath)});
 			return;
+		}
 
 		GCSignal[] LiInputKeys = con1.readObject();
 		GCSignal[][] E_feInputKeys = con1.readObject();
@@ -61,26 +126,54 @@ public class Eviction extends Protocol {
 				C_labelInputKeys, deltaInputKeys);
 
 		int[] ti_p = new int[deltaInputKeys.length];
-		// int[] target = new int[deltaInputKeys.length];
 		for (int i = 0; i < ti_p.length; i++) {
 			ti_p[i] = GCUtil.evaOutKeys(outKeys[1][i], predata.evict_tiOutKeyHashes[i]).intValue();
-			// target[i] = GCUtil.evaOutKeys(outKeys[0][i],
-			// predata.tmpKeyHashes[i]).intValue();
 		}
 
-		System.out.println("ti:");
+		/*System.out.println("ti:");
 		for (int i = 0; i < ti_p.length; i++)
 			System.out.print(ti_p[i] + " ");
+		System.out.println();*/
+		
+		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);
+		
+		/*System.out.println("ti_pp:");
+		for (int i = 0; i < ti_p.length; i++)
+			System.out.print(ti_pp[i] + " ");
 		System.out.println();
-		// System.out.println("target:");
-		// for (int i=0; i<ti_p.length; i++)
-		// System.out.print(target[i] + " ");
-		// System.out.println();
+		
+		System.out.println("target_pp:");
+		for (int i = 0; i < ti_p.length; i++)
+			System.out.print(target_pp[i] + " ");
+		System.out.println();*/
+		
+		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);
+		/*for (int i = 0; i < evict.length; i++)
+			System.out.print(evict[i] + " ");
+		System.out.println();*/
+		
+		SSXOT ssxot = new SSXOT(con1, con2, 1);
+		ssxot.runD(predata, evict, timer);
+		
+		Bucket[] pathBuckets = con2.readObject();
+		OTi.setBucketsOnPath(new BigInteger(1, Li).longValue(), pathBuckets);
 	}
 
-	public Tuple[] runC(PreData predata, boolean firstTree, Tuple[] pathTuples, int d, int w, Timer timer) {
-		if (firstTree)
-			return pathTuples;
+	public void runC(PreData predata, boolean firstTree, Tuple[] originalPath, int d, int w, int sw, Timer timer) {
+		if (firstTree) {
+			con2.write(originalPath);
+			return;
+		}
+		
+		Tuple[] pathTuples = new Tuple[d*w];
+		System.arraycopy(originalPath, 0, pathTuples, 0, w);
+		System.arraycopy(originalPath, sw, pathTuples, w, (d-1)*w);
 
 		Bucket[] pathBuckets = Bucket.tuplesToBuckets(pathTuples, d, w, w);
 
@@ -93,8 +186,43 @@ public class Eviction extends Protocol {
 
 		con2.write(C_feInputKeys);
 		con2.write(C_labelInputKeys);
-
-		return pathTuples;
+		
+		PermuteTarget permutetarget = new PermuteTarget(con1, con2);
+		permutetarget.runC(predata, firstTree, timer);
+		
+		PermuteIndex permuteindex = new PermuteIndex(con1, con2);
+		permuteindex.runC(predata, firstTree, timer);
+		
+		int logW = (int) Math.ceil(Math.log(w + 1) / Math.log(2));
+		int W = (int) Math.pow(2, logW);
+		for (int i=0; i<d; i++) {
+			pathBuckets[i].expand(W);
+			pathBuckets[i].permute(predata.evict_delta_p[i]);
+		}
+		pathBuckets = Util.permute(pathBuckets, predata.evict_pi);
+		for (int i=0; i<d; i++) {
+			pathBuckets[i].permute(predata.evict_rho_p[i]);
+		}
+		pathTuples = Bucket.bucketsToTuples(pathBuckets);
+		
+		SSXOT ssxot = new SSXOT(con1, con2, 1);
+		pathTuples = ssxot.runC(predata, pathTuples, timer);
+		
+		pathBuckets = Bucket.tuplesToBuckets(pathTuples, d, W, W);
+		for (int i=0; i<d; i++) {
+			int[] rho_ivs = Util.inversePermutation(predata.evict_rho_p[i]);
+			pathBuckets[i].permute(rho_ivs);
+		}
+		int[] pi_ivs = Util.inversePermutation(predata.evict_pi);
+		pathBuckets = Util.permute(pathBuckets, pi_ivs);
+		for (int i=0; i<d; i++) {
+			int[] delta_ivs = Util.inversePermutation(predata.evict_delta_p[i]);
+			pathBuckets[i].permute(delta_ivs);
+			pathBuckets[i].shrink(w);
+		}
+		
+		pathBuckets[0].expand(Arrays.copyOfRange(originalPath, w, sw));
+		con2.write(pathBuckets);
 	}
 
 	// for testing correctness
@@ -127,8 +255,8 @@ public class Eviction extends Protocol {
 				con2.write(d);
 				con2.write(w);
 
-				preeviction.runE(predata, d, w, timer);
-				runE(predata, false, Li, path, d, w, timer);
+				preeviction.runE(predata, false, d, w, timer);
+				//runE(predata, false, Li, path, d, w, null, timer);
 
 				int emptyIndex = 0;
 				for (int j = 0; j < d * w; j++) {
@@ -142,6 +270,21 @@ public class Eviction extends Protocol {
 					}
 				}
 				System.out.println("last empty: " + emptyIndex);
+				
+				System.out.println("pi:");
+				for (int j = 0; j < d; j++)
+					System.out.print(predata.evict_pi[j] + " ");
+				System.out.println();
+				
+				System.out.println("delta:");
+				for (int j = 0; j < d; j++)
+					System.out.print(predata.evict_delta[j].intValue() + " ");
+				System.out.println();
+				
+				System.out.println("rho:");
+				for (int j = 0; j < d; j++)
+					System.out.print(predata.evict_rho[j].intValue() + " ");
+				System.out.println();
 
 			} else if (party == Party.Debbie) {
 				int d = con1.readObject();
@@ -149,8 +292,8 @@ public class Eviction extends Protocol {
 				byte[] Li = con1.read();
 				int[] tupleParam = new int[] { 1, 2, (d - 1 + 7) / 8, 3 };
 
-				preeviction.runD(predata, d, w, tupleParam, timer);
-				runD(predata, false, Li, w, timer);
+				preeviction.runD(predata, false, d, w, tupleParam, timer);
+				//runD(predata, false, Li, w, null, timer);
 
 			} else if (party == Party.Charlie) {
 				int d = con1.readObject();
@@ -160,8 +303,8 @@ public class Eviction extends Protocol {
 				for (int j = 0; j < d * w; j++)
 					path[j] = new Tuple(1, 2, lBytes, 3, null);
 
-				preeviction.runC(predata, timer);
-				runC(predata, false, path, d, w, timer);
+				preeviction.runC(predata, false, timer);
+				//runC(predata, false, path, d, w, timer);
 
 			} else {
 				throw new NoSuchPartyException(party + "");

+ 49 - 3
src/protocols/PreEviction.java

@@ -22,7 +22,10 @@ public class PreEviction extends Protocol {
 		super(con1, con2);
 	}
 
-	public void runE(PreData predata, int d, int w, Timer timer) {
+	public void runE(PreData predata, boolean firstTree, int d, int w, Timer timer) {
+		if (firstTree)
+			return;
+		
 		// GC
 		int logW = (int) Math.ceil(Math.log(w + 1) / Math.log(2));
 
@@ -100,9 +103,24 @@ public class PreEviction extends Protocol {
 		con2.write(predata.evict_rho);
 		con2.write(predata.evict_delta_p);
 		con2.write(predata.evict_rho_p);
+		
+		// PermuteTarget
+		PrePermuteTarget prepermutetarget = new PrePermuteTarget(con1, con2);
+		prepermutetarget.runE(predata, d, timer);
+		
+		// PermuteIndex
+		PrePermuteIndex prepermuteindex = new PrePermuteIndex(con1, con2);
+		prepermuteindex.runE(predata, d, w, timer);
+		
+		// SSXOT
+		PreSSXOT pressxot = new PreSSXOT(con1, con2, 1);
+		pressxot.runE(predata, timer);
 	}
 
-	public void runD(PreData predata, int d, int w, int[] tupleParam, Timer timer) {
+	public void runD(PreData predata, boolean firstTree, int d, int w, int[] tupleParam, Timer timer) {
+		if (firstTree)
+			return;
+		
 		// GC
 		int logW = (int) Math.ceil(Math.log(w + 1) / Math.log(2));
 
@@ -134,9 +152,25 @@ public class PreEviction extends Protocol {
 		predata.evict_tiOutKeyHashes = con1.readObject();
 		predata.evict_targetOutKeyPairs = con1.readObject();
 		// predata.tmpKeyHashes = con1.readObject();
+		
+		// PermuteTarget
+		PrePermuteTarget prepermutetarget = new PrePermuteTarget(con1, con2);
+		prepermutetarget.runD(predata, d, timer);
+		
+		// PermuteIndex
+		PrePermuteIndex prepermuteindex = new PrePermuteIndex(con1, con2);
+		prepermuteindex.runD(predata, timer);
+		
+		// SSXOT
+		int W = (int) Math.pow(2, logW);
+		PreSSXOT pressxot = new PreSSXOT(con1, con2, 1);
+		pressxot.runD(predata, d*W, d*W, tupleParam, timer);
 	}
 
-	public void runC(PreData predata, Timer timer) {
+	public void runC(PreData predata, boolean firstTree, Timer timer) {
+		if (firstTree)
+			return;
+		
 		// GC
 		predata.evict_C_feKeyPairs = con1.readObject();
 		predata.evict_C_labelKeyPairs = con1.readObject();
@@ -147,6 +181,18 @@ public class PreEviction extends Protocol {
 		predata.evict_rho = con1.readObject();
 		predata.evict_delta_p = con1.readObject();
 		predata.evict_rho_p = con1.readObject();
+		
+		// PermuteTarget
+		PrePermuteTarget prepermutetarget = new PrePermuteTarget(con1, con2);
+		prepermutetarget.runC(predata, timer);
+		
+		// PermuteIndex
+		PrePermuteIndex prepermuteindex = new PrePermuteIndex(con1, con2);
+		prepermuteindex.runC(predata, timer);
+		
+		// SSXOT
+		PreSSXOT pressxot = new PreSSXOT(con1, con2, 1);
+		pressxot.runC(predata, timer);
 	}
 
 	@Override

+ 6 - 0
src/protocols/PreRetrieve.java

@@ -17,6 +17,7 @@ public class PreRetrieve extends Protocol {
 		PreReshuffle prereshuffle = new PreReshuffle(con1, con2);
 		PrePostProcessT prepostprocesst = new PrePostProcessT(con1, con2);
 		PreUpdateRoot preupdateroot = new PreUpdateRoot(con1, con2);
+		PreEviction preeviction = new PreEviction(con1, con2);
 
 		int numTuples = md.getStashSizeOfTree(ti) + md.getLBitsOfTree(ti) * md.getW();
 		int[] tupleParam = new int[] { ti == 0 ? 0 : 1, md.getNBytesOfTree(ti), md.getLBytesOfTree(ti),
@@ -26,6 +27,7 @@ public class PreRetrieve extends Protocol {
 		prereshuffle.runE(predata, timer);
 		prepostprocesst.runE(predata, timer);
 		preupdateroot.runE(predata, md.getStashSizeOfTree(ti), md.getLBitsOfTree(ti), timer);
+		preeviction.runE(predata, ti==0, md.getLBitsOfTree(ti)+1, md.getW(), timer);
 	}
 
 	public void runD(PreData predata, Metadata md, int ti, PreData prev, Timer timer) {
@@ -33,6 +35,7 @@ public class PreRetrieve extends Protocol {
 		PreReshuffle prereshuffle = new PreReshuffle(con1, con2);
 		PrePostProcessT prepostprocesst = new PrePostProcessT(con1, con2);
 		PreUpdateRoot preupdateroot = new PreUpdateRoot(con1, con2);
+		PreEviction preeviction = new PreEviction(con1, con2);
 
 		int[] tupleParam = new int[] { ti == 0 ? 0 : 1, md.getNBytesOfTree(ti), md.getLBytesOfTree(ti),
 				md.getABytesOfTree(ti) };
@@ -41,6 +44,7 @@ public class PreRetrieve extends Protocol {
 		prereshuffle.runD(predata, tupleParam, timer);
 		prepostprocesst.runD(predata, prev, md.getLBytesOfTree(ti), md.getAlBytesOfTree(ti), md.getTau(), timer);
 		preupdateroot.runD(predata, md.getStashSizeOfTree(ti), md.getLBitsOfTree(ti), tupleParam, timer);
+		preeviction.runD(predata, ti==0, md.getLBitsOfTree(ti)+1, md.getW(), tupleParam, timer);
 	}
 
 	public void runC(PreData predata, Metadata md, int ti, PreData prev, Timer timer) {
@@ -48,11 +52,13 @@ public class PreRetrieve extends Protocol {
 		PreReshuffle prereshuffle = new PreReshuffle(con1, con2);
 		PrePostProcessT prepostprocesst = new PrePostProcessT(con1, con2);
 		PreUpdateRoot preupdateroot = new PreUpdateRoot(con1, con2);
+		PreEviction preeviction = new PreEviction(con1, con2);
 
 		preaccess.runC(timer);
 		prereshuffle.runC(predata, timer);
 		prepostprocesst.runC(predata, prev, md.getLBytesOfTree(ti), md.getAlBytesOfTree(ti), timer);
 		preupdateroot.runC(predata, timer);
+		preeviction.runC(predata, ti==0, timer);
 	}
 
 	@Override

+ 12 - 1
src/protocols/Retrieve.java

@@ -26,12 +26,16 @@ public class Retrieve extends Protocol {
 		Reshuffle reshuffle = new Reshuffle(con1, con2);
 		PostProcessT postprocesst = new PostProcessT(con1, con2);
 		UpdateRoot updateroot = new UpdateRoot(con1, con2);
+		Eviction eviction = new Eviction(con1, con2);
 
 		OutAccess outaccess = access.runE(predata, OTi, Ni, Nip1_pr, timer);
 		Tuple[] path = reshuffle.runE(predata, outaccess.E_P, OTi.getTreeIndex() == 0, timer);
 		Tuple Ti = postprocesst.runE(predata, outaccess.E_Ti, OTi.getTreeIndex() == h - 1, timer);
 		Tuple[] root = Arrays.copyOfRange(path, 0, OTi.getStashSize());
 		root = updateroot.runE(predata, OTi.getTreeIndex() == 0, outaccess.Li, root, Ti, timer);
+		System.arraycopy(root, 0, path, 0, root.length);
+		eviction.runE(predata, OTi.getTreeIndex() == 0, outaccess.Li,
+				OTi.getTreeIndex() == 0 ? new Tuple[] { Ti } : path, OTi.getD(), OTi.getW(), OTi, timer);
 
 		return outaccess;
 	}
@@ -41,11 +45,13 @@ public class Retrieve extends Protocol {
 		Reshuffle reshuffle = new Reshuffle(con1, con2);
 		PostProcessT postprocesst = new PostProcessT(con1, con2);
 		UpdateRoot updateroot = new UpdateRoot(con1, con2);
+		Eviction eviction = new Eviction(con1, con2);
 
 		byte[] Li = access.runD(predata, OTi, Ni, Nip1_pr, timer);
 		reshuffle.runD();
 		postprocesst.runD();
 		updateroot.runD(predata, OTi.getTreeIndex() == 0, Li, OTi.getW(), timer);
+		eviction.runD(predata, OTi.getTreeIndex() == 0, Li, OTi.getW(), OTi, timer);
 	}
 
 	public OutAccess runC(PreData predata, Metadata md, int ti, byte[] Li, int h, Timer timer) {
@@ -53,12 +59,16 @@ public class Retrieve extends Protocol {
 		Reshuffle reshuffle = new Reshuffle(con1, con2);
 		PostProcessT postprocesst = new PostProcessT(con1, con2);
 		UpdateRoot updateroot = new UpdateRoot(con1, con2);
+		Eviction eviction = new Eviction(con1, con2);
 
 		OutAccess outaccess = access.runC(md, ti, Li, timer);
 		Tuple[] path = reshuffle.runC(predata, outaccess.C_P, ti == 0, timer);
 		Tuple Ti = postprocesst.runC(predata, outaccess.C_Ti, Li, outaccess.C_Lip1, outaccess.C_j2, ti == h - 1, timer);
 		Tuple[] root = Arrays.copyOfRange(path, 0, md.getStashSizeOfTree(ti));
 		root = updateroot.runC(predata, ti == 0, root, Ti, timer);
+		System.arraycopy(root, 0, path, 0, root.length);
+		eviction.runC(predata, ti == 0, ti == 0 ? new Tuple[] { Ti } : path, md.getLBitsOfTree(ti) + 1, md.getW(),
+				md.getStashSizeOfTree(ti), timer);
 
 		return outaccess;
 	}
@@ -146,7 +156,8 @@ public class Retrieve extends Protocol {
 						sw.stop();
 
 					} else if (party == Party.Charlie) {
-						System.out.println("L" + ti + "=" + new BigInteger(1, Li).toString(2));
+						int lBits = md.getLBitsOfTree(ti);
+						System.out.println("L" + ti + "=" + Util.addZeros(Util.getSubBits(new BigInteger(1, Li), lBits, 0).toString(2), lBits));
 
 						sw.start();
 						OutAccess outaccess = runC(predata[ti], md, ti, Li, numTrees, timer);

+ 7 - 0
src/util/Util.java

@@ -107,6 +107,13 @@ public class Util {
 	public static int bytesToInt(byte[] b) {
 		return new BigInteger(b).intValue();
 	}
+	
+	public static int[] identityPermutation(int len) {
+		int[] out = new int[len];
+		for (int i=0; i<len; i++)
+			out[i] = i;
+		return out;
+	}
 
 	public static int[] randomPermutation(int len, Random rand) {
 		List<Integer> list = new ArrayList<Integer>(len);

+ 50 - 0
test/protocols/TestEviction_C.java

@@ -0,0 +1,50 @@
+package protocols;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+
+public class TestEviction_C {
+
+	public static void main(String[] args) {
+		Runtime runTime = Runtime.getRuntime();
+		Process process = null;
+		String dir = System.getProperty("user.dir");
+		String binDir = dir + "\\bin";
+		String libs = dir + "\\lib\\*";
+		try {
+			process = runTime.exec("java -classpath " + binDir + ";" + libs + " ui.CLI -protocol evict charlie");
+
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		InputStream inputStream = process.getInputStream();
+		InputStreamReader isr = new InputStreamReader(inputStream);
+		InputStream errorStream = process.getErrorStream();
+		InputStreamReader esr = new InputStreamReader(errorStream);
+
+		System.out.println("STANDARD OUTPUT:");
+		int n1;
+		char[] c1 = new char[1024];
+		try {
+			while ((n1 = isr.read(c1)) > 0) {
+				System.out.print(new String(Arrays.copyOfRange(c1, 0, n1)));
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+		System.out.println("STANDARD ERROR:");
+		int n2;
+		char[] c2 = new char[1024];
+		try {
+			while ((n2 = esr.read(c2)) > 0) {
+				System.err.print(new String(Arrays.copyOfRange(c2, 0, n2)));
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+}

+ 50 - 0
test/protocols/TestEviction_D.java

@@ -0,0 +1,50 @@
+package protocols;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+
+public class TestEviction_D {
+
+	public static void main(String[] args) {
+		Runtime runTime = Runtime.getRuntime();
+		Process process = null;
+		String dir = System.getProperty("user.dir");
+		String binDir = dir + "\\bin";
+		String libs = dir + "\\lib\\*";
+		try {
+			process = runTime.exec("java -classpath " + binDir + ";" + libs + " ui.CLI -protocol evict debbie");
+
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		InputStream inputStream = process.getInputStream();
+		InputStreamReader isr = new InputStreamReader(inputStream);
+		InputStream errorStream = process.getErrorStream();
+		InputStreamReader esr = new InputStreamReader(errorStream);
+
+		System.out.println("STANDARD OUTPUT:");
+		int n1;
+		char[] c1 = new char[1024];
+		try {
+			while ((n1 = isr.read(c1)) > 0) {
+				System.out.print(new String(Arrays.copyOfRange(c1, 0, n1)));
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+		System.out.println("STANDARD ERROR:");
+		int n2;
+		char[] c2 = new char[1024];
+		try {
+			while ((n2 = esr.read(c2)) > 0) {
+				System.err.print(new String(Arrays.copyOfRange(c2, 0, n2)));
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+}

+ 50 - 0
test/protocols/TestEviction_E.java

@@ -0,0 +1,50 @@
+package protocols;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+
+public class TestEviction_E {
+
+	public static void main(String[] args) {
+		Runtime runTime = Runtime.getRuntime();
+		Process process = null;
+		String dir = System.getProperty("user.dir");
+		String binDir = dir + "\\bin";
+		String libs = dir + "\\lib\\*";
+		try {
+			process = runTime.exec("java -classpath " + binDir + ";" + libs + " ui.CLI -protocol evict eddie");
+
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		InputStream inputStream = process.getInputStream();
+		InputStreamReader isr = new InputStreamReader(inputStream);
+		InputStream errorStream = process.getErrorStream();
+		InputStreamReader esr = new InputStreamReader(errorStream);
+
+		System.out.println("STANDARD OUTPUT:");
+		int n1;
+		char[] c1 = new char[1024];
+		try {
+			while ((n1 = isr.read(c1)) > 0) {
+				System.out.print(new String(Arrays.copyOfRange(c1, 0, n1)));
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+		System.out.println("STANDARD ERROR:");
+		int n2;
+		char[] c2 = new char[1024];
+		try {
+			while ((n2 = esr.read(c2)) > 0) {
+				System.err.print(new String(Arrays.copyOfRange(c2, 0, n2)));
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+}