Ver código fonte

Pipeline after Access working.

Boyoung- 8 anos atrás
pai
commit
e9a9b7e584

+ 1 - 1
ObliVMGC/com/oblivm/backend/gc/halfANDs/Garbler.java

@@ -19,7 +19,7 @@ final class Garbler {
 
 	ByteBuffer buffer = ByteBuffer.allocate(GCSignal.len + 9);
 
-	public GCSignal hash(GCSignal lb, long k, boolean b) {
+	public synchronized GCSignal hash(GCSignal lb, long k, boolean b) {
 		buffer.clear();
 		sha1.update(buffer.put(lb.bytes).putLong(k).put(b ? (byte) 1 : (byte) 0));
 		return GCSignal.newInstance(sha1.digest());

+ 1 - 1
ObliVMGC/com/oblivm/backend/gc/offline/Garbler.java

@@ -27,7 +27,7 @@ final class Garbler {
 
 	ByteBuffer buffer = ByteBuffer.allocate(GCSignal.len * 2 + 8);
 
-	private GCSignal getPadding(GCSignal lb0, GCSignal lb1, long k) {
+	private synchronized GCSignal getPadding(GCSignal lb0, GCSignal lb1, long k) {
 		buffer.clear();
 		sha1.update((buffer.put(lb0.bytes).put(lb1.bytes).putLong(k)));
 		GCSignal ret = GCSignal.newInstance(sha1.digest());

+ 1 - 1
ObliVMGC/com/oblivm/backend/gc/regular/Garbler.java

@@ -29,7 +29,7 @@ final class Garbler {
 
 	ByteBuffer buffer = ByteBuffer.allocate(GCSignal.len * 2 + 8);
 
-	private void getPadding(GCSignal lb0, GCSignal lb1, long k, GCSignal ret) {
+	private synchronized void getPadding(GCSignal lb0, GCSignal lb1, long k, GCSignal ret) {
 		buffer.clear();
 		sha1.update((buffer.put(lb0.bytes).put(lb1.bytes).putLong(k)));
 		System.arraycopy(sha1.digest(), 0, ret.bytes, 0, GCSignal.len);

+ 3 - 3
ObliVMGC/com/oblivm/backend/ot/Cipher.java

@@ -38,7 +38,7 @@ public final class Cipher {
 		return cph.xor(getPaddingOfLength(key, cphLength));
 	}
 
-	private BigInteger getPaddingOfLength(byte[] key, int padLength) {
+	private synchronized BigInteger getPaddingOfLength(byte[] key, int padLength) {
 
 		byte[] pad = new byte[(padLength - 1) / 8 + 1];
 		byte[] tmp;
@@ -62,7 +62,7 @@ public final class Cipher {
 		return cph.xor(getPaddingOfLength(j, key, cphLength));
 	}
 
-	private BigInteger getPaddingOfLength(int j, byte[] key, int padLength) {
+	private synchronized BigInteger getPaddingOfLength(int j, byte[] key, int padLength) {
 		sha1.update(ByteBuffer.allocate(4).putInt(j).array());
 		sha1.update(key);
 
@@ -88,7 +88,7 @@ public final class Cipher {
 		return getPadding(key, k).xor(c);
 	}
 
-	private GCSignal getPadding(GCSignal key, int k) {
+	private synchronized GCSignal getPadding(GCSignal key, int k) {
 		sha1.update(key.bytes);
 		sha1.update(ByteBuffer.allocate(4).putInt(k).array());
 		GCSignal ret = GCSignal.newInstance(sha1.digest());

+ 5 - 3
src/communication/Communication.java

@@ -196,9 +196,10 @@ public class Communication {
 			Util.disp("connect to: " + address);
 
 		// Don't throw out connections if we are already connected
-		if (mState == STATE_CONNECTING || mConnectedThread != null) {
-			return;
-		}
+		/*
+		 * if (mState == STATE_CONNECTING || mConnectedThread != null) { return;
+		 * }
+		 */
 
 		mNumTries++;
 		mAddress = address;
@@ -813,6 +814,7 @@ public class Communication {
 
 			mmInStream = tmpIn;
 			mmOutStream = tmpOut;
+
 		}
 
 		public void setTcpNoDelay(boolean on) {

+ 1 - 1
src/crypto/PRF.java

@@ -44,7 +44,7 @@ public class PRF {
 		}
 	}
 
-	public byte[] compute(byte[] input) {
+	public synchronized byte[] compute(byte[] input) {
 		if (input.length > maxInputBytes)
 			throw new IllegalInputException(input.length + " > " + maxInputBytes);
 

+ 1 - 1
src/crypto/PRG.java

@@ -34,7 +34,7 @@ public class PRG {
 		this.l = l;
 	}
 
-	public byte[] compute(byte[] seed) {
+	public synchronized byte[] compute(byte[] seed) {
 		byte[] input;
 		if (seed.length > 16) {
 			throw new IllegalInputException(seed.length + " > 16");

+ 2 - 2
src/gc/GCUtil.java

@@ -67,7 +67,7 @@ public class GCUtil {
 		return out;
 	}
 
-	public static byte[][] genOutKeyHashes(GCSignal[] outZeroKeys) {
+	public static synchronized byte[][] genOutKeyHashes(GCSignal[] outZeroKeys) {
 		byte[][] hashes = new byte[outZeroKeys.length][];
 		for (int i = 0; i < outZeroKeys.length; i++) {
 			hashes[i] = Crypto.sha1.digest(outZeroKeys[i].bytes);
@@ -100,7 +100,7 @@ public class GCUtil {
 		return pairs;
 	}
 
-	public static byte[] hashAll(GCSignal[] keys) {
+	public static synchronized byte[] hashAll(GCSignal[] keys) {
 		for (int i = 0; i < keys.length; i++)
 			Crypto.sha1.update(keys[i].bytes);
 		return Crypto.sha1.digest();

+ 7 - 0
src/oram/Global.java

@@ -0,0 +1,7 @@
+package oram;
+
+public class Global {
+
+	public static boolean cheat = true;
+	public static boolean pipeline = false;
+}

+ 0 - 2
src/oram/Metadata.java

@@ -49,8 +49,6 @@ public class Metadata {
 
 	private long forestBytes;
 
-	public static boolean cheat = false;
-
 	public Metadata() {
 		setup(configFileName);
 	}

+ 3 - 3
src/oram/Tree.java

@@ -58,7 +58,7 @@ public class Tree implements Serializable {
 
 		int fBytes = treeIndex == 0 ? 0 : 1;
 		int[] tupleParams = new int[] { fBytes, nBytes, lBytes, aBytes };
-		if (!Metadata.cheat) {
+		if (!Global.cheat) {
 			buckets = new Array64<Bucket>(numBuckets);
 			buckets.set(0, new Bucket(stashSize, tupleParams, rand));
 			for (int i = 1; i < numBuckets; i++)
@@ -143,7 +143,7 @@ public class Tree implements Serializable {
 	}
 
 	public Bucket[] getBucketsOnPath(BigInteger L) {
-		if (Metadata.cheat)
+		if (Global.cheat)
 			return pathBuckets;
 
 		long[] indices = getBucketIndicesOnPath(L);
@@ -162,7 +162,7 @@ public class Tree implements Serializable {
 	}
 
 	public void setBucketsOnPath(BigInteger L, Bucket[] buckets) {
-		if (Metadata.cheat) {
+		if (Global.cheat) {
 			pathBuckets = buckets;
 			return;
 		}

+ 2 - 1
src/protocols/Access.java

@@ -11,6 +11,7 @@ import exceptions.AccessException;
 import exceptions.NoSuchPartyException;
 import oram.Bucket;
 import oram.Forest;
+import oram.Global;
 import oram.Metadata;
 import oram.Tree;
 import oram.Tuple;
@@ -309,7 +310,7 @@ public class Access extends Protocol {
 		System.out.println();
 
 		for (int i = 0; i < records; i++) {
-			long N = Metadata.cheat ? 0 : Util.nextLong(numInsert, Crypto.sr);
+			long N = Global.cheat ? 0 : Util.nextLong(numInsert, Crypto.sr);
 
 			for (int j = 0; j < repeat; j++) {
 				System.out.println("Test: " + i + " " + j);

+ 137 - 0
src/protocols/Pipeline.java

@@ -0,0 +1,137 @@
+package protocols;
+
+import java.util.Arrays;
+
+import communication.Communication;
+import crypto.Crypto;
+import exceptions.NoSuchPartyException;
+import oram.Metadata;
+import oram.Tree;
+import oram.Tuple;
+import protocols.struct.OutAccess;
+import protocols.struct.Party;
+import protocols.struct.PreData;
+import util.Timer;
+import util.Util;
+
+public class Pipeline extends Thread {
+
+	private Communication con1;
+	private Communication con2;
+	private Party party;
+	private PreData[] predata;
+	private Tree OTi;
+	private int h;
+	private Timer timer;
+	private Metadata md;
+	private int treeIndex;
+	private byte[] Li;
+	private OutAccess outaccess;
+
+	public Pipeline(Communication con1, Communication con2, Party party, PreData[] predata, Tree OTi, int h,
+			Timer timer, Metadata md, int treeIndex, byte[] Li, OutAccess outaccess) {
+		this.con1 = con1;
+		this.con2 = con2;
+		this.party = party;
+		this.predata = predata;
+		this.OTi = OTi;
+		this.h = h;
+		this.timer = timer;
+		this.md = md;
+		this.treeIndex = treeIndex;
+		this.Li = Li;
+		this.outaccess = outaccess;
+	}
+
+	public void runE(PreData[] predata, Tree OTi, int h, Timer timer) {
+		// 1st eviction
+		Access access = new Access(con1, con2);
+		Reshuffle reshuffle = new Reshuffle(con1, con2);
+		PostProcessT postprocesst = new PostProcessT(con1, con2);
+		UpdateRoot updateroot = new UpdateRoot(con1, con2);
+		Eviction eviction = new Eviction(con1, con2);
+
+		Tuple[] path = reshuffle.runE(predata[0], outaccess.E_P, OTi.getTreeIndex() == 0, timer);
+		Tuple Ti = postprocesst.runE(predata[0], outaccess.E_Ti, OTi.getTreeIndex() == h - 1, timer);
+		Tuple[] root = Arrays.copyOfRange(path, 0, OTi.getStashSize());
+		root = updateroot.runE(predata[0], OTi.getTreeIndex() == 0, outaccess.Li, root, Ti, timer);
+		System.arraycopy(root, 0, path, 0, root.length);
+		eviction.runE(predata[0], OTi.getTreeIndex() == 0, outaccess.Li,
+				OTi.getTreeIndex() == 0 ? new Tuple[] { Ti } : path, OTi, timer);
+
+		// 2nd eviction
+		OutAccess outaccess2 = access.runE2(OTi, timer);
+		Tuple[] path2 = outaccess2.E_P;
+		Tuple Ti2 = outaccess2.E_Ti;
+		Tuple[] root2 = Arrays.copyOfRange(path2, 0, OTi.getStashSize());
+		root2 = updateroot.runE(predata[1], OTi.getTreeIndex() == 0, outaccess2.Li, root2, Ti2, timer);
+		System.arraycopy(root2, 0, path2, 0, root2.length);
+		eviction.runE(predata[1], OTi.getTreeIndex() == 0, outaccess2.Li,
+				OTi.getTreeIndex() == 0 ? new Tuple[] { Ti2 } : path2, OTi, timer);
+	}
+
+	public void runD(PreData predata[], Tree OTi, Timer timer) {
+		// 1st eviction
+		Access access = new Access(con1, con2);
+		Reshuffle reshuffle = new Reshuffle(con1, con2);
+		PostProcessT postprocesst = new PostProcessT(con1, con2);
+		UpdateRoot updateroot = new UpdateRoot(con1, con2);
+		Eviction eviction = new Eviction(con1, con2);
+
+		reshuffle.runD();
+		postprocesst.runD();
+		updateroot.runD(predata[0], OTi.getTreeIndex() == 0, Li, OTi.getW(), timer);
+		eviction.runD(predata[0], OTi.getTreeIndex() == 0, Li, OTi, timer);
+
+		// 2nd eviction
+		byte[] Li2 = access.runD2(OTi, timer);
+		updateroot.runD(predata[1], OTi.getTreeIndex() == 0, Li2, OTi.getW(), timer);
+		eviction.runD(predata[1], OTi.getTreeIndex() == 0, Li2, OTi, timer);
+	}
+
+	public OutAccess runC(PreData[] predata, Metadata md, int ti, byte[] Li, Timer timer) {
+		// 1st eviction
+		Access access = new Access(con1, con2);
+		Reshuffle reshuffle = new Reshuffle(con1, con2);
+		PostProcessT postprocesst = new PostProcessT(con1, con2);
+		UpdateRoot updateroot = new UpdateRoot(con1, con2);
+		Eviction eviction = new Eviction(con1, con2);
+
+		Tuple[] path = reshuffle.runC(predata[0], outaccess.C_P, ti == 0, timer);
+		Tuple Ti = postprocesst.runC(predata[0], outaccess.C_Ti, Li, outaccess.C_Lip1, outaccess.C_j2,
+				ti == md.getNumTrees() - 1, timer);
+		Tuple[] root = Arrays.copyOfRange(path, 0, md.getStashSizeOfTree(ti));
+		root = updateroot.runC(predata[0], ti == 0, root, Ti, timer);
+		System.arraycopy(root, 0, path, 0, root.length);
+		eviction.runC(predata[0], ti == 0, ti == 0 ? new Tuple[] { Ti } : path, md.getLBitsOfTree(ti) + 1,
+				md.getStashSizeOfTree(ti), md.getW(), timer);
+
+		// 2nd eviction
+		byte[] Li2 = Util.nextBytes(md.getLBytesOfTree(ti), Crypto.sr);
+		OutAccess outaccess2 = access.runC2(md, ti, Li2, timer);
+		Tuple[] path2 = outaccess2.C_P;
+		Tuple Ti2 = outaccess2.C_Ti;
+		Tuple[] root2 = Arrays.copyOfRange(path2, 0, md.getStashSizeOfTree(ti));
+		root2 = updateroot.runC(predata[1], ti == 0, root2, Ti2, timer);
+		System.arraycopy(root2, 0, path2, 0, root2.length);
+		eviction.runC(predata[1], ti == 0, ti == 0 ? new Tuple[] { Ti2 } : path2, md.getLBitsOfTree(ti) + 1,
+				md.getStashSizeOfTree(ti), md.getW(), timer);
+
+		return outaccess;
+	}
+
+	public void run() {
+		if (party == Party.Eddie) {
+			runE(predata, OTi, h, timer);
+
+		} else if (party == Party.Debbie) {
+			runD(predata, OTi, timer);
+
+		} else if (party == Party.Charlie) {
+			runC(predata, md, treeIndex, Li, timer);
+
+		} else {
+			throw new NoSuchPartyException(party + "");
+		}
+	}
+}

+ 2 - 1
src/protocols/PostProcessT.java

@@ -7,6 +7,7 @@ import crypto.Crypto;
 import exceptions.AccessException;
 import exceptions.NoSuchPartyException;
 import oram.Forest;
+import oram.Global;
 import oram.Metadata;
 import oram.Tree;
 import oram.Tuple;
@@ -118,7 +119,7 @@ public class PostProcessT extends Protocol {
 		System.out.println();
 
 		for (int i = 0; i < records; i++) {
-			long N = Metadata.cheat ? 0 : Util.nextLong(numInsert, Crypto.sr);
+			long N = Global.cheat ? 0 : Util.nextLong(numInsert, Crypto.sr);
 
 			for (int j = 0; j < repeat; j++) {
 				System.out.println("Test: " + i + " " + j);

+ 5 - 7
src/protocols/Protocol.java

@@ -4,6 +4,7 @@ import communication.Communication;
 import crypto.Crypto;
 import exceptions.NoSuchPartyException;
 import oram.Forest;
+import oram.Global;
 import oram.Metadata;
 import protocols.struct.Party;
 
@@ -48,21 +49,18 @@ public abstract class Protocol {
 		}
 	}
 
-	public void run(Party party, String configFile, String forestFile) {
-		Metadata md = new Metadata(configFile);
+	public void run(Party party, Metadata md, String forestFile) {
 		Forest forest = null;
-
-		Metadata.cheat = true;
-
 		if (party == Party.Eddie) {
-			if (Metadata.cheat)
+			if (Global.cheat)
 				forest = new Forest(md, Crypto.sr);
 			else if (forestFile == null)
 				forest = Forest.readFromFile(md.getDefaultSharesName1());
 			else
 				forest = Forest.readFromFile(forestFile);
+
 		} else if (party == Party.Debbie) {
-			if (Metadata.cheat)
+			if (Global.cheat)
 				forest = new Forest(md, null);
 			else if (forestFile == null)
 				forest = Forest.readFromFile(md.getDefaultSharesName2());

+ 2 - 1
src/protocols/Reshuffle.java

@@ -7,6 +7,7 @@ import crypto.Crypto;
 import exceptions.AccessException;
 import exceptions.NoSuchPartyException;
 import oram.Forest;
+import oram.Global;
 import oram.Metadata;
 import oram.Tree;
 import oram.Tuple;
@@ -89,7 +90,7 @@ public class Reshuffle extends Protocol {
 		System.out.println();
 
 		for (int i = 0; i < records; i++) {
-			long N = Metadata.cheat ? 0 : Util.nextLong(numInsert, Crypto.sr);
+			long N = Global.cheat ? 0 : Util.nextLong(numInsert, Crypto.sr);
 
 			for (int j = 0; j < repeat; j++) {
 				System.out.println("Test: " + i + " " + j);

+ 105 - 23
src/protocols/Retrieve.java

@@ -8,11 +8,13 @@ import crypto.Crypto;
 import exceptions.AccessException;
 import exceptions.NoSuchPartyException;
 import oram.Forest;
+import oram.Global;
 import oram.Metadata;
 import oram.Tree;
 import oram.Tuple;
 import protocols.precomputation.PreRetrieve;
 import protocols.struct.OutAccess;
+import protocols.struct.OutRetrieve;
 import protocols.struct.Party;
 import protocols.struct.PreData;
 import util.Bandwidth;
@@ -23,11 +25,19 @@ import util.Util;
 
 public class Retrieve extends Protocol {
 
+	Communication[] cons1;
+	Communication[] cons2;
+
 	public Retrieve(Communication con1, Communication con2) {
 		super(con1, con2);
 	}
 
-	public OutAccess runE(PreData[] predata, Tree OTi, byte[] Ni, byte[] Nip1_pr, int h, Timer timer) {
+	public void setCons(Communication[] a, Communication[] b) {
+		cons1 = a;
+		cons2 = b;
+	}
+
+	public void runE(PreData[] predata, Tree OTi, byte[] Ni, byte[] Nip1_pr, int h, Timer timer) {
 		// 1st eviction
 		Access access = new Access(con1, con2);
 		Reshuffle reshuffle = new Reshuffle(con1, con2);
@@ -53,8 +63,6 @@ public class Retrieve extends Protocol {
 		System.arraycopy(root2, 0, path2, 0, root2.length);
 		eviction.runE(predata[1], OTi.getTreeIndex() == 0, outaccess2.Li,
 				OTi.getTreeIndex() == 0 ? new Tuple[] { Ti2 } : path2, OTi, timer);
-
-		return outaccess;
 	}
 
 	public void runD(PreData predata[], Tree OTi, byte[] Ni, byte[] Nip1_pr, Timer timer) {
@@ -77,7 +85,7 @@ public class Retrieve extends Protocol {
 		eviction.runD(predata[1], OTi.getTreeIndex() == 0, Li2, OTi, timer);
 	}
 
-	public OutAccess runC(PreData[] predata, Metadata md, int ti, byte[] Li, int h, Timer timer) {
+	public OutAccess runC(PreData[] predata, Metadata md, int ti, byte[] Li, Timer timer) {
 		// 1st eviction
 		Access access = new Access(con1, con2);
 		Reshuffle reshuffle = new Reshuffle(con1, con2);
@@ -87,8 +95,8 @@ public class Retrieve extends Protocol {
 
 		OutAccess outaccess = access.runC(md, ti, Li, timer);
 		Tuple[] path = reshuffle.runC(predata[0], outaccess.C_P, ti == 0, timer);
-		Tuple Ti = postprocesst.runC(predata[0], outaccess.C_Ti, Li, outaccess.C_Lip1, outaccess.C_j2, ti == h - 1,
-				timer);
+		Tuple Ti = postprocesst.runC(predata[0], outaccess.C_Ti, Li, outaccess.C_Lip1, outaccess.C_j2,
+				ti == md.getNumTrees() - 1, timer);
 		Tuple[] root = Arrays.copyOfRange(path, 0, md.getStashSizeOfTree(ti));
 		root = updateroot.runC(predata[0], ti == 0, root, Ti, timer);
 		System.arraycopy(root, 0, path, 0, root.length);
@@ -109,10 +117,47 @@ public class Retrieve extends Protocol {
 		return outaccess;
 	}
 
+	public Pipeline pipelineE(PreData[] predata, Tree OTi, byte[] Ni, byte[] Nip1_pr, int h, Timer[] timer) {
+		Access access = new Access(con1, con2);
+		OutAccess outaccess = access.runE(predata[0], OTi, Ni, Nip1_pr, timer[0]);
+
+		int ti = OTi.getTreeIndex();
+		Pipeline pipeline = new Pipeline(cons1[ti + 1], cons2[ti + 1], Party.Eddie, predata, OTi, h, timer[ti + 1],
+				null, ti, outaccess.Li, outaccess);
+		pipeline.start();
+
+		return pipeline;
+	}
+
+	public Pipeline pipelineD(PreData predata[], Tree OTi, byte[] Ni, byte[] Nip1_pr, Timer[] timer) {
+		Access access = new Access(con1, con2);
+		byte[] Li = access.runD(predata[0], OTi, Ni, Nip1_pr, timer[0]);
+
+		int ti = OTi.getTreeIndex();
+		Pipeline pipeline = new Pipeline(cons1[ti + 1], cons2[ti + 1], Party.Debbie, predata, OTi, 0, timer[ti + 1],
+				null, ti, Li, null);
+		pipeline.start();
+
+		return pipeline;
+	}
+
+	public OutRetrieve pipelineC(PreData[] predata, Metadata md, int ti, byte[] Li, Timer[] timer) {
+		Access access = new Access(con1, con2);
+		OutAccess outaccess = access.runC(md, ti, Li, timer[0]);
+
+		Pipeline pipeline = new Pipeline(cons1[ti + 1], cons2[ti + 1], Party.Charlie, predata, null, 0, timer[ti + 1],
+				md, ti, Li, outaccess);
+		pipeline.start();
+
+		return new OutRetrieve(outaccess, pipeline);
+	}
+
 	// for testing correctness
 	@Override
 	public void run(Party party, Metadata md, Forest forest) {
-		if (Metadata.cheat)
+		if (Global.pipeline)
+			System.out.println("Pipeline Mode is On");
+		if (Global.cheat)
 			System.out.println("Cheat Mode is On");
 
 		int records = 7;
@@ -124,28 +169,37 @@ public class Retrieve extends Protocol {
 		long numInsert = md.getNumInsertRecords();
 		int addrBits = md.getAddrBits();
 
-		Timer timer = new Timer();
+		int numTimer = Global.pipeline ? numTrees + 1 : 1;
+		Timer[] timer = new Timer[numTimer];
+		for (int i = 0; i < numTimer; i++)
+			timer[i] = new Timer();
+
 		StopWatch ete_off = new StopWatch("ETE_offline");
 		StopWatch ete_on = new StopWatch("ETE_online");
 
 		long[] gates = new long[2];
 
+		Pipeline[] threads = new Pipeline[numTrees];
+
 		sanityCheck();
 		System.out.println();
 
 		for (int i = 0; i < records; i++) {
-			long N = Metadata.cheat ? 0 : Util.nextLong(numInsert, Crypto.sr);
+			long N = Global.cheat ? 0 : Util.nextLong(numInsert, Crypto.sr);
 
 			for (int j = 0; j < repeat; j++) {
 				int cycleIndex = i * repeat + j;
 				if (cycleIndex == reset * repeat) {
-					timer.reset();
+					for (int k = 0; k < timer.length; k++)
+						timer[k].reset();
 					ete_on.reset();
 					ete_off.reset();
 				}
 				if (cycleIndex == 1) {
-					con1.bandSwitch = false;
-					con2.bandSwitch = false;
+					for (int k = 0; k < cons1.length; k++) {
+						cons1[k].bandSwitch = false;
+						cons2[k].bandSwitch = false;
+					}
 				}
 
 				System.out.println("Test: " + i + " " + j);
@@ -160,12 +214,13 @@ public class Retrieve extends Protocol {
 
 					if (party == Party.Eddie) {
 						ete_off.start();
-						preretrieve.runE(predata[ti], md, ti, timer);
+						preretrieve.runE(predata[ti], md, ti, timer[0]);
 						ete_off.stop();
 
 					} else if (party == Party.Debbie) {
 						ete_off.start();
-						long[] cnt = preretrieve.runD(predata[ti], md, ti, ti == 0 ? null : predata[ti - 1][0], timer);
+						long[] cnt = preretrieve.runD(predata[ti], md, ti, ti == 0 ? null : predata[ti - 1][0],
+								timer[0]);
 						ete_off.stop();
 
 						if (cycleIndex == 0) {
@@ -175,17 +230,16 @@ public class Retrieve extends Protocol {
 
 					} else if (party == Party.Charlie) {
 						ete_off.start();
-						preretrieve.runC(predata[ti], md, ti, ti == 0 ? null : predata[ti - 1][0], timer);
+						preretrieve.runC(predata[ti], md, ti, ti == 0 ? null : predata[ti - 1][0], timer[0]);
 						ete_off.stop();
 
 					} else {
 						throw new NoSuchPartyException(party + "");
 					}
 				}
-				
+
 				sanityCheck();
 				System.out.println("done!");
-				
 
 				byte[] Li = new byte[0];
 				for (int ti = 0; ti < numTrees; ti++) {
@@ -207,7 +261,10 @@ public class Retrieve extends Protocol {
 						con1.write(sD_Nip1_pr);
 
 						ete_on.start();
-						runE(predata[ti], OTi, sE_Ni, sE_Nip1_pr, numTrees, timer);
+						if (!Global.pipeline)
+							runE(predata[ti], OTi, sE_Ni, sE_Nip1_pr, numTrees, timer[0]);
+						else
+							threads[ti] = pipelineE(predata[ti], OTi, sE_Ni, sE_Nip1_pr, numTrees, timer);
 						ete_on.stop();
 
 						if (ti == numTrees - 1)
@@ -220,7 +277,10 @@ public class Retrieve extends Protocol {
 						byte[] sD_Nip1_pr = con1.read();
 
 						ete_on.start();
-						runD(predata[ti], OTi, sD_Ni, sD_Nip1_pr, timer);
+						if (!Global.pipeline)
+							runD(predata[ti], OTi, sD_Ni, sD_Nip1_pr, timer[0]);
+						else
+							threads[ti] = pipelineD(predata[ti], OTi, sD_Ni, sD_Nip1_pr, timer);
 						ete_on.stop();
 
 					} else if (party == Party.Charlie) {
@@ -228,8 +288,15 @@ public class Retrieve extends Protocol {
 						System.out.println("L" + ti + "="
 								+ Util.addZeros(Util.getSubBits(new BigInteger(1, Li), lBits, 0).toString(2), lBits));
 
+						OutAccess outaccess = null;
 						ete_on.start();
-						OutAccess outaccess = runC(predata[ti], md, ti, Li, numTrees, timer);
+						if (!Global.pipeline)
+							outaccess = runC(predata[ti], md, ti, Li, timer[0]);
+						else {
+							OutRetrieve outretrieve = pipelineC(predata[ti], md, ti, Li, timer);
+							outaccess = outretrieve.outaccess;
+							threads[ti] = outretrieve.pipeline;
+						}
 						ete_on.stop();
 
 						Li = outaccess.C_Lip1;
@@ -249,12 +316,23 @@ public class Retrieve extends Protocol {
 						throw new NoSuchPartyException(party + "");
 					}
 				}
+
+				if (Global.pipeline)
+					for (int ti = 0; ti < numTrees; ti++) {
+						try {
+							threads[ti].join();
+						} catch (InterruptedException e) {
+							e.printStackTrace();
+						}
+					}
 			}
 		}
 		System.out.println();
 
-		timer.noPrePrint();
-		// timer.divideBy((records-reset)*repeat).print();
+		Timer sum = new Timer();
+		for (int i = 0; i < timer.length; i++)
+			sum = sum.add(timer[i]);
+		sum.noPrePrint();
 		System.out.println();
 
 		System.out.println(ete_on.noPreToMS());
@@ -263,7 +341,9 @@ public class Retrieve extends Protocol {
 
 		Bandwidth[] bandwidth = new Bandwidth[P.size];
 		for (int i = 0; i < P.size; i++) {
-			bandwidth[i] = con1.bandwidth[i].add(con2.bandwidth[i]);
+			bandwidth[i] = new Bandwidth(P.names[i]);
+			for (int j = 0; j < cons1.length; j++)
+				bandwidth[i] = bandwidth[i].add(cons1[j].bandwidth[i].add(cons2[j].bandwidth[i]));
 			System.out.println(bandwidth[i].noPreToString());
 		}
 		System.out.println();
@@ -271,5 +351,7 @@ public class Retrieve extends Protocol {
 		System.out.println(gates[0]);
 		System.out.println(gates[1]);
 		System.out.println();
+
+		sanityCheck();
 	}
 }

+ 13 - 0
src/protocols/struct/OutRetrieve.java

@@ -0,0 +1,13 @@
+package protocols.struct;
+
+import protocols.Pipeline;
+
+public class OutRetrieve {
+	public OutAccess outaccess;
+	public Pipeline pipeline;
+
+	public OutRetrieve(OutAccess outaccess, Pipeline pipeline) {
+		this.outaccess = outaccess;
+		this.pipeline = pipeline;
+	}
+}

+ 105 - 101
src/ui/CLI.java

@@ -12,6 +12,8 @@ import org.apache.commons.cli.ParseException;
 
 import communication.Communication;
 import exceptions.NoSuchPartyException;
+import oram.Global;
+import oram.Metadata;
 import protocols.*;
 import protocols.struct.Party;
 
@@ -27,6 +29,7 @@ public class CLI {
 		options.addOption("eddie_ip", true, "IP to look for eddie");
 		options.addOption("debbie_ip", true, "IP to look for debbie");
 		options.addOption("protocol", true, "Algorithim to test");
+		options.addOption("pipeline", false, "Whether to do pipelined eviction");
 
 		// Parse the command line arguments
 		CommandLineParser cmdParser = new GnuParser();
@@ -37,6 +40,8 @@ public class CLI {
 			e1.printStackTrace();
 		}
 
+		Global.pipeline = cmd.hasOption("pipeline");
+
 		String configFile = cmd.getOptionValue("config", "config.yaml");
 		String forestFile = cmd.getOptionValue("forest", null);
 
@@ -102,138 +107,137 @@ public class CLI {
 		// up in party specific classes.
 		System.out.println("Starting " + party + "...");
 
-		if (party.equals("eddie")) {
-			Communication debbieCon = new Communication();
-			debbieCon.start(eddiePort1);
-
-			Communication charlieCon = new Communication();
-			charlieCon.start(eddiePort2);
+		Metadata md = new Metadata(configFile);
+		int numComs = Global.pipeline ? md.getNumTrees() + 1 : 1;
+		Communication[] con1 = new Communication[numComs];
+		Communication[] con2 = new Communication[numComs];
 
-			System.out.println("Waiting to establish connections...");
-			while (debbieCon.getState() != Communication.STATE_CONNECTED)
-				;
-			while (charlieCon.getState() != Communication.STATE_CONNECTED)
-				;
-			System.out.println("Connection established.");
-
-			debbieCon.setTcpNoDelay(true);
-			charlieCon.setTcpNoDelay(true);
+		if (party.equals("eddie")) {
+			System.out.print("Waiting to establish debbie connections...");
+			for (int i = 0; i < numComs; i++) {
+				con1[i] = new Communication();
+				con1[i].start(eddiePort1);
+				eddiePort1 += 3;
+				while (con1[i].getState() != Communication.STATE_CONNECTED)
+					;
+			}
+			System.out.println(" done!");
+
+			System.out.print("Waiting to establish charlie connections...");
+			for (int i = 0; i < numComs; i++) {
+				con2[i] = new Communication();
+				con2[i].start(eddiePort2);
+				eddiePort2 += 3;
+				while (con2[i].getState() != Communication.STATE_CONNECTED)
+					;
+			}
+			System.out.println(" done!");
 
-			debbieCon.write("start");
-			charlieCon.write("start");
-			debbieCon.readString();
-			charlieCon.readString();
+			for (int i = 0; i < numComs; i++) {
+				con1[i].setTcpNoDelay(true);
+				con2[i].setTcpNoDelay(true);
+			}
 
 			try {
-				operationCtor.newInstance(debbieCon, charlieCon).run(Party.Eddie, configFile, forestFile);
+				Protocol p = operationCtor.newInstance(con1[0], con2[0]);
+				if (protocol.equals("rtv"))
+					((Retrieve) p).setCons(con1, con2);
+				p.run(Party.Eddie, md, forestFile);
 			} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
 					| InvocationTargetException e) {
 				e.printStackTrace();
 			}
 
-			debbieCon.write("end");
-			charlieCon.write("end");
-			debbieCon.readString();
-			charlieCon.readString();
-
-			try {
-				Thread.sleep(1000);
-			} catch (InterruptedException e) {
-				e.printStackTrace();
-			}
-			debbieCon.stop();
-			charlieCon.stop();
-
 		} else if (party.equals("debbie")) {
-			Communication eddieCon = new Communication();
-			InetSocketAddress eddieAddr = new InetSocketAddress(eddieIp, eddiePort1);
-			eddieCon.connect(eddieAddr);
-
-			Communication charlieCon = new Communication();
-			charlieCon.start(debbiePort);
-
-			System.out.println("Waiting to establish connections...");
-			while (eddieCon.getState() != Communication.STATE_CONNECTED)
-				;
-			while (charlieCon.getState() != Communication.STATE_CONNECTED)
-				;
-			System.out.println("Connection established");
-
-			eddieCon.setTcpNoDelay(true);
-			charlieCon.setTcpNoDelay(true);
+			System.out.print("Waiting to establish eddie connections...");
+			for (int i = 0; i < numComs; i++) {
+				con1[i] = new Communication();
+				InetSocketAddress addr = new InetSocketAddress(eddieIp, eddiePort1);
+				con1[i].connect(addr);
+				eddiePort1 += 3;
+				while (con1[i].getState() != Communication.STATE_CONNECTED)
+					;
+			}
+			System.out.println(" done!");
+
+			System.out.print("Waiting to establish charlie connections...");
+			for (int i = 0; i < numComs; i++) {
+				con2[i] = new Communication();
+				con2[i].start(debbiePort);
+				debbiePort += 3;
+				while (con2[i].getState() != Communication.STATE_CONNECTED)
+					;
+			}
+			System.out.println(" done!");
 
-			eddieCon.write("start");
-			charlieCon.write("start");
-			eddieCon.readString();
-			charlieCon.readString();
+			for (int i = 0; i < numComs; i++) {
+				con1[i].setTcpNoDelay(true);
+				con2[i].setTcpNoDelay(true);
+			}
 
 			try {
-				operationCtor.newInstance(eddieCon, charlieCon).run(Party.Debbie, configFile, forestFile);
+				Protocol p = operationCtor.newInstance(con1[0], con2[0]);
+				if (protocol.equals("rtv"))
+					((Retrieve) p).setCons(con1, con2);
+				p.run(Party.Debbie, md, forestFile);
 			} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
 					| InvocationTargetException e) {
 				e.printStackTrace();
 			}
 
-			eddieCon.write("end");
-			charlieCon.write("end");
-			eddieCon.readString();
-			charlieCon.readString();
-
-			try {
-				Thread.sleep(1000);
-			} catch (InterruptedException e) {
-				e.printStackTrace();
+		} else if (party.equals("charlie")) {
+			System.out.print("Waiting to establish eddie connections...");
+			for (int i = 0; i < numComs; i++) {
+				con1[i] = new Communication();
+				InetSocketAddress addr = new InetSocketAddress(eddieIp, eddiePort2);
+				con1[i].connect(addr);
+				eddiePort2 += 3;
+				while (con1[i].getState() != Communication.STATE_CONNECTED)
+					;
 			}
-			eddieCon.stop();
-			charlieCon.stop();
+			System.out.println(" done!");
+
+			System.out.print("Waiting to establish debbie connections...");
+			for (int i = 0; i < numComs; i++) {
+				con2[i] = new Communication();
+				InetSocketAddress addr = new InetSocketAddress(debbieIp, debbiePort);
+				con2[i].connect(addr);
+				debbiePort += 3;
+				while (con2[i].getState() != Communication.STATE_CONNECTED)
+					;
+			}
+			System.out.println(" done!");
 
-		} else if (party.equals("charlie")) {
-			Communication debbieCon = new Communication();
-			Communication eddieCon = new Communication();
-			InetSocketAddress eddieAddr = new InetSocketAddress(eddieIp, eddiePort2);
-			eddieCon.connect(eddieAddr);
-			InetSocketAddress debbieAddr = new InetSocketAddress(debbieIp, debbiePort);
-			debbieCon.connect(debbieAddr);
-
-			System.out.println("Waiting to establish connections...");
-			while (eddieCon.getState() != Communication.STATE_CONNECTED)
-				;
-			while (debbieCon.getState() != Communication.STATE_CONNECTED)
-				;
-			System.out.println("Connection established");
-
-			eddieCon.setTcpNoDelay(true);
-			debbieCon.setTcpNoDelay(true);
-
-			eddieCon.write("start");
-			debbieCon.write("start");
-			eddieCon.readString();
-			debbieCon.readString();
+			for (int i = 0; i < numComs; i++) {
+				con1[i].setTcpNoDelay(true);
+				con2[i].setTcpNoDelay(true);
+			}
 
 			try {
-				operationCtor.newInstance(eddieCon, debbieCon).run(Party.Charlie, configFile, forestFile);
+				Protocol p = operationCtor.newInstance(con1[0], con2[0]);
+				if (protocol.equals("rtv"))
+					((Retrieve) p).setCons(con1, con2);
+				p.run(Party.Charlie, md, forestFile);
 			} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
 					| InvocationTargetException e) {
 				e.printStackTrace();
 			}
 
-			eddieCon.write("end");
-			debbieCon.write("end");
-			eddieCon.readString();
-			debbieCon.readString();
-
-			try {
-				Thread.sleep(1000);
-			} catch (InterruptedException e) {
-				e.printStackTrace();
-			}
-			eddieCon.stop();
-			debbieCon.stop();
-
 		} else {
 			throw new NoSuchPartyException(party);
 		}
 
+		try {
+			Thread.sleep(1000);
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+
+		for (int i = 0; i < numComs; i++) {
+			con1[i].stop();
+			con2[i].stop();
+		}
+
 		System.out.println(party + " exiting...");
 	}
 }

+ 23 - 0
src/util/StopWatch.java

@@ -107,4 +107,27 @@ public class StopWatch {
 		sw.elapsedCPU = elapsedCPU / n;
 		return sw;
 	}
+
+	public StopWatch add(StopWatch s) {
+		if (isOn || s.isOn) {
+			try {
+				throw new StopWatchException("StopWatch is still running");
+			} catch (StopWatchException e) {
+				e.printStackTrace();
+			}
+		}
+
+		if (!task.equals(s.task)) {
+			try {
+				throw new StopWatchException("Tasks don't match: " + task + " != " + s.task);
+			} catch (StopWatchException e) {
+				e.printStackTrace();
+			}
+		}
+
+		StopWatch sw = new StopWatch(task);
+		sw.elapsedWC = elapsedWC + s.elapsedWC;
+		sw.elapsedCPU = elapsedCPU + s.elapsedCPU;
+		return sw;
+	}
 }

+ 13 - 0
src/util/Timer.java

@@ -28,6 +28,7 @@ public class Timer {
 			stack.peek().stop();
 		}
 		stack.push(watches[p][m]).start();
+
 	}
 
 	public void stop(int p, int m) {
@@ -36,6 +37,7 @@ public class Timer {
 		stack.pop().stop();
 		if (!stack.empty())
 			stack.peek().start();
+
 	}
 
 	public void reset() {
@@ -71,4 +73,15 @@ public class Timer {
 				sws[i][j] = watches[i][j].divideBy(n);
 		return new Timer(sws);
 	}
+
+	public Timer add(Timer t) {
+		if (!stack.empty() || !t.stack.empty())
+			throw new TimerException("Stack not empty");
+
+		StopWatch[][] sws = new StopWatch[P.size][M.size];
+		for (int i = 0; i < watches.length; i++)
+			for (int j = 0; j < watches[i].length; j++)
+				sws[i][j] = watches[i][j].add(t.watches[i][j]);
+		return new Timer(sws);
+	}
 }