Browse Source

backup: has bug in SSCOT

Boyoung- 9 years ago
parent
commit
84117817b0

+ 23 - 0
src/communication/Communication.java

@@ -4,6 +4,7 @@ import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.io.StreamCorruptedException;
+import java.math.BigInteger;
 import java.net.InetSocketAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
@@ -325,6 +326,16 @@ public class Communication {
 		write("" + out.length);
 		write(out);
 	}
+	
+	public void write(int out) {
+		write(Util.intToBytes(out));
+	}
+	
+	public void write(byte[][] out) {
+		write(out.length);
+		for (int i=0; i<out.length; i++)
+			write(out[i]);
+	}
 
 	public static final Charset defaultCharset = Charset.forName("ASCII");
 
@@ -405,6 +416,18 @@ public class Communication {
 
 		return total;
 	}
+	
+	public int readInt() {
+		return new BigInteger(read()).intValue();
+	}
+	
+	public byte[][] readDoubleByteArray() {
+		int len = readInt();
+		byte[][] data = new byte[len][];
+		for (int i=0; i<len; i++)
+			data[i] = read();
+		return data;
+	}
 
 	/**
 	 * This thread runs while listening for incoming connections. It behaves

+ 2 - 0
src/crypto/Crypto.java

@@ -6,6 +6,7 @@ import java.security.SecureRandom;
 public class Crypto {
 	public static SecureRandom sr;
 	public static int secParam;
+	public static int secParamBytes;
 
 	static {
 		try {
@@ -14,5 +15,6 @@ public class Crypto {
 			e.printStackTrace();
 		}
 		secParam = 80;
+		secParamBytes = (secParam + 7) / 8;
 	}
 }

+ 7 - 0
src/crypto/PRF.java

@@ -2,6 +2,7 @@ package crypto;
 
 import java.security.InvalidKeyException;
 import java.security.NoSuchAlgorithmException;
+import java.util.Random;
 
 import javax.crypto.BadPaddingException;
 import javax.crypto.Cipher;
@@ -95,4 +96,10 @@ public class PRF {
 		System.arraycopy(last, 0, output, outBytes - last.length, last.length);
 		return output;
 	}
+
+	public static byte[] generateKey(Random rand) {
+		byte[] key = new byte[16];
+		rand.nextBytes(key);
+		return key;
+	}
 }

+ 16 - 0
src/exceptions/SSCOTException.java

@@ -0,0 +1,16 @@
+package exceptions;
+
+public class SSCOTException extends RuntimeException {
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+
+	public SSCOTException() {
+		super();
+	}
+
+	public SSCOTException(String message) {
+		super(message);
+	}
+}

+ 11 - 0
src/protocols/OutSSCOT.java

@@ -0,0 +1,11 @@
+package protocols;
+
+public class OutSSCOT {
+	public int t;
+	public byte[] m_t;
+	
+	public OutSSCOT(int t, byte[] m_t) {
+		this.t = t;
+		this.m_t = m_t;
+	}
+}

+ 7 - 0
src/protocols/PreData.java

@@ -0,0 +1,7 @@
+package protocols;
+
+public class PreData {
+	public byte[] sscot_k;
+	public byte[] sscot_kprime;
+	public byte[][] sscot_r;
+}

+ 16 - 98
src/protocols/PreSSCOT.java

@@ -1,12 +1,8 @@
 package protocols;
 
-import java.math.BigInteger;
-
-import org.apache.commons.lang3.tuple.Pair;
-
 import communication.Communication;
+import crypto.Crypto;
 import crypto.PRF;
-import crypto.PRG;
 import oram.Forest;
 import oram.Metadata;
 
@@ -15,107 +11,29 @@ public class PreSSCOT extends Protocol {
 		super(con1, con2);
 	}
 
-	public Pair<Integer, BigInteger> executeCharlie(Communication D,
-			Communication E, int i, int N, int l, int l_p) {
-		// protocol
-		// step 1
-		byte[] msg_ev = E.read();
-
-		// step 2
-		byte[] msg_pw = D.read();
-
-		// step 3
-		byte[][] e = new byte[N][];
-		byte[][] v = new byte[N][];
-		byte[][] p = new byte[N][];
-		byte[][] w = new byte[N][];
-		PRG G = new PRG(l);
-		int gBytes = (l + 7) / 8;
-
-		for (int t = 0; t < N; t++) {
-			e[t] = Arrays.copyOfRange(msg_ev, t * gBytes, (t + 1) * gBytes);
-			v[t] = Arrays.copyOfRange(msg_ev, N * gBytes + t * SR.kBytes, N
-					* gBytes + (t + 1) * SR.kBytes);
-			p[t] = Arrays.copyOfRange(msg_pw, t * SR.kBytes, (t + 1)
-					* SR.kBytes);
-			w[t] = Arrays.copyOfRange(msg_pw, (N + t) * SR.kBytes, (N + t + 1)
-					* SR.kBytes);
-
-			if (new BigInteger(1, v[t]).compareTo(new BigInteger(1, w[t])) == 0) {
-				//BigInteger m_t = new BigInteger(1, e[t]).xor(new BigInteger(1, G.compute(p[t])));
-				byte[] tmp = G.compute(p[t]);
-				BigInteger m_t = new BigInteger(1, e[t]).xor(new BigInteger(1, tmp));
-				return Pair.of(t, m_t);
-			}
+	public void runE(PreData predata, int n) {
+		predata.sscot_k = PRF.generateKey(Crypto.sr);
+		predata.sscot_kprime = PRF.generateKey(Crypto.sr);
+		predata.sscot_r = new byte[n][];
+		for (int i = 0; i < n; i++) {
+			predata.sscot_r[i] = new byte[Crypto.secParamBytes];
+			Crypto.sr.nextBytes(predata.sscot_r[i]);
 		}
-
-		// error
-		return null;
+		con1.write(predata.sscot_k);
+		con1.write(predata.sscot_kprime);
+		con1.write(predata.sscot_r);
 	}
 
-	public void executeDebbie(Communication C, Communication E, int i, int N,
-			int l, int l_p, BigInteger[] b) {
-		// protocol
-		// step 2
-		int diffBits = SR.kBits - l_p;
-		BigInteger[] y = new BigInteger[N];
-		byte[][][] pw = new byte[2][N][];
-		byte[] msg_pw = new byte[SR.kBytes * N * 2];
-		PRF F_k = new PRF(SR.kBits);
-		PRF F_k_p = new PRF(SR.kBits);
-		F_k.init(PreData.sscot_k[i]);
-		F_k_p.init(PreData.sscot_k_p[i]);
-
-		for (int t = 0; t < N; t++) {
-			y[t] = PreData.sscot_r[i][t].xor(b[t].shiftLeft(diffBits));
-			pw[0][t] = F_k.compute(y[t].toByteArray());
-			pw[1][t] = F_k_p.compute(y[t].toByteArray());
-			System.arraycopy(pw[0][t], 0, msg_pw, t * SR.kBytes, SR.kBytes);
-			System.arraycopy(pw[1][t], 0, msg_pw, (N + t) * SR.kBytes,
-					SR.kBytes);
-		}
-
-		C.write(msg_pw, PID.sscot);
+	public void runD(PreData predata) {
+		predata.sscot_k = con1.read();
+		predata.sscot_kprime = con1.read();
+		predata.sscot_r = con1.readDoubleByteArray();
 	}
 
-	public void executeEddie(Communication C, Communication D, int i, int N,
-			int l, int l_p, BigInteger[] m, BigInteger[] a) {
-		// protocol
-		// step 1
-		int gBytes = (l + 7) / 8;
-		int diffBits = SR.kBits - l_p;
-		BigInteger[] x = new BigInteger[N];
-		byte[][][] ev = new byte[2][N][];
-		byte[] msg_ev = new byte[(SR.kBytes + gBytes) * N];
-		PRF F_k = new PRF(SR.kBits);
-		PRF F_k_p = new PRF(SR.kBits);
-		PRG G = new PRG(l);
-		F_k.init(PreData.sscot_k[i]);
-		F_k_p.init(PreData.sscot_k_p[i]);
-
-		for (int t = 0; t < N; t++) {
-			x[t] = PreData.sscot_r[i][t].xor(a[t].shiftLeft(diffBits));
-			//ev[0][t] = new BigInteger(1, G.compute(F_k.compute(x[t].toByteArray()))).xor(m[t]).toByteArray();
-			ev[1][t] = F_k_p.compute(x[t].toByteArray());
-			byte[] tmp = F_k.compute(x[t].toByteArray());
-			tmp = G.compute(tmp);
-			ev[0][t] = new BigInteger(1, tmp).xor(m[t]).toByteArray();
-			if (ev[0][t].length < gBytes)
-				System.arraycopy(ev[0][t], 0, msg_ev, (t + 1) * gBytes
-						- ev[0][t].length, ev[0][t].length);
-			else
-				System.arraycopy(ev[0][t], ev[0][t].length - gBytes, msg_ev, t
-						* gBytes, gBytes);
-			System.arraycopy(ev[1][t], 0, msg_ev, N * gBytes + t * SR.kBytes,
-					SR.kBytes);
-		}
-
-		C.write(msg_ev, PID.sscot);
+	public void runC() {
 	}
 
 	@Override
 	public void run(Party party, Metadata md, Forest forest) {
-		// TODO Auto-generated method stub
-		
 	}
 }

+ 97 - 86
src/protocols/SSCOT.java

@@ -1,121 +1,132 @@
 package protocols;
 
-import java.math.BigInteger;
-
-import org.apache.commons.lang3.tuple.Pair;
-
 import communication.Communication;
+import crypto.Crypto;
 import crypto.PRF;
 import crypto.PRG;
+import exceptions.NoSuchPartyException;
+import exceptions.SSCOTException;
 import oram.Forest;
 import oram.Metadata;
+import util.Util;
 
 public class SSCOT extends Protocol {
 	public SSCOT(Communication con1, Communication con2) {
 		super(con1, con2);
 	}
 
-	public Pair<Integer, BigInteger> executeCharlie(Communication D,
-			Communication E, int i, int N, int l, int l_p) {
-		// protocol
+	public void runE(PreData predata, byte[][] m, byte[][] a) {
 		// step 1
-		byte[] msg_ev = E.read();
+		int n = m.length;
+		int l = m[0].length * 8;
+		byte[][] x = predata.sscot_r;
+		byte[][] e = new byte[n][];
+		byte[][] v = new byte[n][];
+		PRF F_k = new PRF(Crypto.secParam);
+		F_k.init(predata.sscot_k);
+		PRF F_kprime = new PRF(Crypto.secParam);
+		F_kprime.init(predata.sscot_kprime);
+		PRG G = new PRG(l);
 
-		// step 2
-		byte[] msg_pw = D.read();
+		for (int i = 0; i < n; i++) {
+			for (int j = 0; j < a[i].length; j++)
+				x[i][j] = (byte) (predata.sscot_r[i][j] ^ a[i][j]);
 
-		// step 3
-		byte[][] e = new byte[N][];
-		byte[][] v = new byte[N][];
-		byte[][] p = new byte[N][];
-		byte[][] w = new byte[N][];
-		PRG G = new PRG(l);
-		int gBytes = (l + 7) / 8;
-
-		for (int t = 0; t < N; t++) {
-			e[t] = Arrays.copyOfRange(msg_ev, t * gBytes, (t + 1) * gBytes);
-			v[t] = Arrays.copyOfRange(msg_ev, N * gBytes + t * SR.kBytes, N
-					* gBytes + (t + 1) * SR.kBytes);
-			p[t] = Arrays.copyOfRange(msg_pw, t * SR.kBytes, (t + 1)
-					* SR.kBytes);
-			w[t] = Arrays.copyOfRange(msg_pw, (N + t) * SR.kBytes, (N + t + 1)
-					* SR.kBytes);
-
-			if (new BigInteger(1, v[t]).compareTo(new BigInteger(1, w[t])) == 0) {
-				//BigInteger m_t = new BigInteger(1, e[t]).xor(new BigInteger(1, G.compute(p[t])));
-				byte[] tmp = G.compute(p[t]);
-				BigInteger m_t = new BigInteger(1, e[t]).xor(new BigInteger(1, tmp));
-				return Pair.of(t, m_t);
-			}
+			e[i] = Util.xor(G.compute(F_k.compute(x[i])), m[i]);
+			v[i] = F_kprime.compute(x[i]);
 		}
 
-		// error
-		return null;
+		con2.write(e);
+		con2.write(v);
 	}
 
-	public void executeDebbie(Communication C, Communication E, int i, int N,
-			int l, int l_p, BigInteger[] b) {
-		// protocol
+	public void runD(PreData predata, byte[][] b) {
 		// step 2
-		int diffBits = SR.kBits - l_p;
-		BigInteger[] y = new BigInteger[N];
-		byte[][][] pw = new byte[2][N][];
-		byte[] msg_pw = new byte[SR.kBytes * N * 2];
-		PRF F_k = new PRF(SR.kBits);
-		PRF F_k_p = new PRF(SR.kBits);
-		F_k.init(PreData.sscot_k[i]);
-		F_k_p.init(PreData.sscot_k_p[i]);
-
-		for (int t = 0; t < N; t++) {
-			y[t] = PreData.sscot_r[i][t].xor(b[t].shiftLeft(diffBits));
-			pw[0][t] = F_k.compute(y[t].toByteArray());
-			pw[1][t] = F_k_p.compute(y[t].toByteArray());
-			System.arraycopy(pw[0][t], 0, msg_pw, t * SR.kBytes, SR.kBytes);
-			System.arraycopy(pw[1][t], 0, msg_pw, (N + t) * SR.kBytes,
-					SR.kBytes);
+		int n = b.length;
+		byte[][] y = predata.sscot_r;
+		byte[][] p = new byte[n][];
+		byte[][] w = new byte[n][];
+		PRF F_k = new PRF(Crypto.secParam);
+		F_k.init(predata.sscot_k);
+		PRF F_kprime = new PRF(Crypto.secParam);
+		F_kprime.init(predata.sscot_kprime);
+
+		for (int i = 0; i < n; i++) {
+			for (int j = 0; j < b[i].length; j++)
+				y[i][j] = (byte) (predata.sscot_r[i][j] ^ b[i][j]);
+
+			p[i] = F_k.compute(y[i]);
+			w[i] = F_kprime.compute(y[i]);
 		}
 
-		C.write(msg_pw, PID.sscot);
+		con2.write(p);
+		con2.write(w);
 	}
 
-	public void executeEddie(Communication C, Communication D, int i, int N,
-			int l, int l_p, BigInteger[] m, BigInteger[] a) {
-		// protocol
+	public OutSSCOT runC() {
 		// step 1
-		int gBytes = (l + 7) / 8;
-		int diffBits = SR.kBits - l_p;
-		BigInteger[] x = new BigInteger[N];
-		byte[][][] ev = new byte[2][N][];
-		byte[] msg_ev = new byte[(SR.kBytes + gBytes) * N];
-		PRF F_k = new PRF(SR.kBits);
-		PRF F_k_p = new PRF(SR.kBits);
+		byte[][] e = con1.readDoubleByteArray();
+		byte[][] v = con1.readDoubleByteArray();
+
+		// step 2
+		byte[][] p = con2.readDoubleByteArray();
+		byte[][] w = con2.readDoubleByteArray();
+
+		// step 3
+		int n = e.length;
+		int l = e[0].length * 8;
 		PRG G = new PRG(l);
-		F_k.init(PreData.sscot_k[i]);
-		F_k_p.init(PreData.sscot_k_p[i]);
-
-		for (int t = 0; t < N; t++) {
-			x[t] = PreData.sscot_r[i][t].xor(a[t].shiftLeft(diffBits));
-			//ev[0][t] = new BigInteger(1, G.compute(F_k.compute(x[t].toByteArray()))).xor(m[t]).toByteArray();
-			ev[1][t] = F_k_p.compute(x[t].toByteArray());
-			byte[] tmp = F_k.compute(x[t].toByteArray());
-			tmp = G.compute(tmp);
-			ev[0][t] = new BigInteger(1, tmp).xor(m[t]).toByteArray();
-			if (ev[0][t].length < gBytes)
-				System.arraycopy(ev[0][t], 0, msg_ev, (t + 1) * gBytes
-						- ev[0][t].length, ev[0][t].length);
-			else
-				System.arraycopy(ev[0][t], ev[0][t].length - gBytes, msg_ev, t
-						* gBytes, gBytes);
-			System.arraycopy(ev[1][t], 0, msg_ev, N * gBytes + t * SR.kBytes,
-					SR.kBytes);
+		OutSSCOT output = null;
+		int invariant = 0;
+
+		for (int i = 0; i < n; i++) {
+			if (Util.equal(v[i],  w[i])) {
+				byte[] m = Util.xor(e[i], G.compute(p[i]));
+				output = new OutSSCOT(i, m);
+				invariant++;
+			}
 		}
 
-		C.write(msg_ev, PID.sscot);
+		if (invariant != 1)
+			throw new SSCOTException("Invariant error: " + invariant);
+		return output;
 	}
 
 	@Override
 	public void run(Party party, Metadata md, Forest forest) {
-		// TODO Auto-generated method stub
-		
+		int n = 100;
+		int A = 32;
+		int FN = 5;
+		byte[][] m = new byte[n][A];
+		byte[][] a = new byte[n][FN];
+		byte[][] b = new byte[n][FN];
+		for (int i=0; i<n; i++) {
+			Crypto.sr.nextBytes(m[i]);
+			Crypto.sr.nextBytes(a[i]);
+			Crypto.sr.nextBytes(b[i]);			
+			while (Util.equal(a[i], b[i]))
+				Crypto.sr.nextBytes(b[i]);				
+		}
+		int index = Crypto.sr.nextInt(n);
+		b[index] = a[index].clone();
+
+		PreData predata = new PreData();
+		PreSSCOT presscot = new PreSSCOT(con1, con2);
+		if (party == Party.Eddie) {
+			presscot.runE(predata, n);
+			runE(predata, m, a);
+		} else if (party == Party.Debbie) {
+			presscot.runD(predata);
+			runD(predata, b);
+		} else if (party == Party.Charlie) {
+			presscot.runC();
+			OutSSCOT output = runC();
+			if (output.t == index && Util.equal(output.m_t, m[index]))
+				System.out.println("SSCOT test passed");
+			else 
+				System.err.println("SSCOT test failed");
+		} else {
+			throw new NoSuchPartyException(party+"");
+		}
 	}
 }

+ 10 - 0
src/util/Util.java

@@ -8,6 +8,12 @@ import java.util.Random;
 import exceptions.LengthNotMatchException;
 
 public class Util {
+	public static boolean equal(byte[] a, byte[] b) {
+		if (a.length != b.length)
+			return false;
+		return new BigInteger(a).compareTo(new BigInteger(b)) == 0;
+	}
+
 	public static long nextLong(Random r, long range) {
 		long bits, val;
 		do {
@@ -78,6 +84,10 @@ public class Util {
 		return bb.array();
 	}
 
+	public static int bytesToInt(byte[] b) {
+		return new BigInteger(b).intValue();
+	}
+
 	public static void debug(String s) {
 		// only to make Communication.java compile
 	}

+ 5 - 0
test/misc/HelloWorld.java

@@ -2,6 +2,8 @@ package misc;
 
 import java.math.BigInteger;
 
+import util.Util;
+
 public class HelloWorld {
 
 	public static void main(String[] args) {
@@ -22,6 +24,9 @@ public class HelloWorld {
 		// throw new ArrayIndexOutOfBoundsException("" + 11);
 
 		System.out.println((new long[3])[0]);
+		
+		byte[] negInt = Util.intToBytes(-3);
+		System.out.println(new BigInteger(negInt).intValue());
 	}
 
 }

+ 52 - 44
test/ui/TestCLI.java

@@ -14,6 +14,7 @@ import communication.Communication;
 import exceptions.NoSuchPartyException;
 import protocols.Party;
 import protocols.Protocol;
+import protocols.SSCOT;
 
 public class TestCLI {
 	public static final int DEFAULT_PORT = 8000;
@@ -38,6 +39,7 @@ public class TestCLI {
 		}
 
 		String configFile = cmd.getOptionValue("config", "config.yaml");
+		String forestFile = cmd.getOptionValue("forest", null);
 
 		String party = null;
 		String[] positionalArgs = cmd.getArgs();
@@ -48,6 +50,7 @@ public class TestCLI {
 				throw new ParseException("No party specified");
 			} catch (ParseException e) {
 				e.printStackTrace();
+				System.exit(-1);
 			}
 		}
 
@@ -59,26 +62,22 @@ public class TestCLI {
 		String eddieIp = cmd.getOptionValue("eddie_ip", DEFAULT_IP);
 		String debbieIp = cmd.getOptionValue("debbie_ip", DEFAULT_IP);
 
-		//
-		// Class<? extends Protocol> operation = null;
-		// String protocol = cmd.getOptionValue("protocol",
-		// "retrieve").toLowerCase();
-		//
-		// if (protocol.equals("access")) {
-		// operation = Access.class;
-		// } else {
-		// System.out.println("Method " + protocol + " not supported");
-		// System.exit(-1);
-		// }
-		//
-		// Constructor<? extends Protocol> operationCtor = null;
-		// try {
-		// operationCtor = operation.getDeclaredConstructor(Communication.class,
-		// Communication.class);
-		// } catch (NoSuchMethodException | SecurityException e1) {
-		// e1.printStackTrace();
-		// }
-		//
+		Class<? extends Protocol> operation = null;
+		String protocol = cmd.getOptionValue("protocol", "retrieve").toLowerCase();
+
+		if (protocol.equals("sscot")) {
+			operation = SSCOT.class;
+		} else {
+			System.out.println("Protocol " + protocol + " not supported");
+			System.exit(-1);
+		}
+
+		Constructor<? extends Protocol> operationCtor = null;
+		try {
+			operationCtor = operation.getDeclaredConstructor(Communication.class, Communication.class);
+		} catch (NoSuchMethodException | SecurityException e1) {
+			e1.printStackTrace();
+		}
 
 		// For now all logic happens here. Eventually this will get wrapped
 		// up in party specific classes.
@@ -103,20 +102,23 @@ public class TestCLI {
 			debbieCon.readString();
 			charlieCon.readString();
 
-			// try {
-			// operationCtor.newInstance(debbieCon, charlieCon).run(Party.Eddie,
-			// configFile, null);
-			// } catch (InstantiationException | IllegalAccessException |
-			// IllegalArgumentException
-			// | InvocationTargetException e1) {
-			// e1.printStackTrace();
-			// }
+			try {
+				operationCtor.newInstance(debbieCon, charlieCon).run(Party.Eddie, configFile, 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();
 
@@ -140,20 +142,23 @@ public class TestCLI {
 			eddieCon.readString();
 			charlieCon.readString();
 
-			// try {
-			// operationCtor.newInstance(eddieCon, charlieCon).run(Party.Debbie,
-			// configFile, null);
-			// } catch (InstantiationException | IllegalAccessException |
-			// IllegalArgumentException
-			// | InvocationTargetException e1) {
-			// e1.printStackTrace();
-			// }
+			try {
+				operationCtor.newInstance(eddieCon, charlieCon).run(Party.Debbie, configFile, 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();
+			}
 			eddieCon.stop();
 			charlieCon.stop();
 
@@ -177,20 +182,23 @@ public class TestCLI {
 			eddieCon.readString();
 			debbieCon.readString();
 
-			// try {
-			// operationCtor.newInstance(eddieCon, debbieCon).run(Party.Charlie,
-			// configFile, null);
-			// } catch (InstantiationException | IllegalAccessException |
-			// IllegalArgumentException
-			// | InvocationTargetException e1) {
-			// e1.printStackTrace();
-			// }
+			try {
+				operationCtor.newInstance(eddieCon, debbieCon).run(Party.Charlie, configFile, 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();