浏览代码

alg1 deepestAndEmpty tested correctly

Boyoung- 9 年之前
父节点
当前提交
9af9fc5a98
共有 4 个文件被更改,包括 222 次插入17 次删除
  1. 6 4
      ObliVMGC/com/oblivm/backend/circuits/arithmetic/IntegerLib.java
  2. 14 13
      src/gc/GCLib.java
  3. 199 0
      src/protocols/DeepestAndEmpty.java
  4. 3 0
      src/ui/CLI.java

+ 6 - 4
ObliVMGC/com/oblivm/backend/circuits/arithmetic/IntegerLib.java

@@ -373,12 +373,14 @@ public class IntegerLib<T> extends CircuitLib<T> implements ArithmeticLib<T> {
 
 	public T[] numberOfOnes(T[] t) {
 		if (t.length == 0) {
-			T[] res = env.newTArray(1);
-			res[0] = SIGNAL_ZERO;
-			return res;
+			// T[] res = env.newTArray(1);
+			// res[0] = SIGNAL_ZERO;
+			// return res;
+			return zeros(2);
 		}
 		if (t.length == 1) {
-			return t;
+			// return t;
+			return padSignal(t, 2);
 		} else {
 			int length = 1;
 			int w = 1;

+ 14 - 13
src/gc/GarbledCircuitLib.java → src/gc/GCLib.java

@@ -6,17 +6,14 @@ import java.util.Arrays;
 import com.oblivm.backend.circuits.arithmetic.IntegerLib;
 import com.oblivm.backend.flexsc.CompEnv;
 
-import crypto.Crypto;
-import util.Util;
-
-public class GarbledCircuitLib<T> extends IntegerLib<T> {
+public class GCLib<T> extends IntegerLib<T> {
 
 	private int d;
 	private int w;
 	private int logD;
 	private int logW;
 
-	public GarbledCircuitLib(CompEnv<T> e, int d, int w) {
+	public GCLib(CompEnv<T> e, int d, int w) {
 		super(e);
 		this.d = d;
 		this.w = w;
@@ -40,26 +37,30 @@ public class GarbledCircuitLib<T> extends IntegerLib<T> {
 		for (int j = 0; j < tupleLabels.length; j++)
 			tupleLabels[j] = xor(E_tupleLabels[j], C_tupleLabels[j]);
 
-		T[] l = padSignal(ones(d - 1 - i), d); // has sign bit 0
-		T[] j1 = toSignals(Util.nextLong(w, Crypto.sr), logW); // no sign bit
-		T[] j2 = toSignals(Util.nextLong(w, Crypto.sr), logW);
-		T[] et = zeros(1); // no sign bit
+		T[] l = padSignal(ones(d - 1 - i), d); // has sign bit
+		T[] j1 = zeros(logW); // no sign bit
+		T[] j2 = zeros(logW);
+		T[] et = zeros(1);
+
 		for (int j = 0; j < w; j++) {
 			T[] tupleIndex = toSignals(j, logW);
-			T[] lz = xor(pathLabel, tupleLabels[j]); // no sign bit
+			T[] lz = xor(pathLabel, tupleLabels[j]);
 			zerosFollowedByOnes(lz);
-			lz = padSignal(lz, d); // has sign bit
+			lz = padSignal(lz, d); // add sign bit
 			T firstIf = and(feBits[j], less(lz, l));
 			l = mux(l, lz, firstIf);
 			j1 = mux(j1, tupleIndex, firstIf);
 			et = mux(ones(1), et, feBits[j]);
 			j2 = mux(tupleIndex, j2, feBits[j]);
 		}
-		T[] l_p = numberOfOnes(not(Arrays.copyOf(l, d - 1))); // has sign bit
+
+		T[] l_p = numberOfOnes(not(Arrays.copyOfRange(l, 0, d - 1))); // has
+																		// sign
+																		// bit
 
 		T[][] output = env.newTArray(4, 0);
 		output[0] = l_p;
-		output[1] = padSignal(j1, logW + 1);
+		output[1] = padSignal(j1, logW + 1); // add sign bit
 		output[2] = padSignal(j2, logW + 1);
 		output[3] = et;
 		return output;

+ 199 - 0
src/protocols/DeepestAndEmpty.java

@@ -0,0 +1,199 @@
+package protocols;
+
+import java.math.BigInteger;
+
+import com.oblivm.backend.flexsc.CompEnv;
+import com.oblivm.backend.gc.GCGenComp;
+import com.oblivm.backend.gc.GCSignal;
+import com.oblivm.backend.gc.regular.GCEva;
+import com.oblivm.backend.gc.regular.GCGen;
+import com.oblivm.backend.network.Network;
+
+import communication.Communication;
+import crypto.Crypto;
+import exceptions.NoSuchPartyException;
+import gc.GCLib;
+import oram.Forest;
+import oram.Metadata;
+import util.Util;
+
+public class DeepestAndEmpty extends Protocol {
+
+	private int d = 10;
+	private int w = 8;
+
+	public DeepestAndEmpty(Communication con1, Communication con2) {
+		super(con1, con2);
+	}
+
+	private GCSignal[] revSelectKeys(GCSignal[][] pairs, byte[] input) {
+		BigInteger in = new BigInteger(1, input);
+		GCSignal[] out = new GCSignal[pairs.length];
+		for (int i = 0; i < pairs.length; i++)
+			out[i] = pairs[i][in.testBit(i) ? 1 : 0];
+		return out;
+	}
+
+	private GCSignal[] selectKeys(GCSignal[][] pairs, byte[] input) {
+		BigInteger in = new BigInteger(1, input);
+		GCSignal[] out = new GCSignal[pairs.length];
+		for (int i = 0; i < pairs.length; i++)
+			out[i] = pairs[i][in.testBit(pairs.length - 1 - i) ? 1 : 0];
+		return out;
+	}
+
+	private GCSignal[][] genKeyPairs(int n) {
+		GCSignal[][] pairs = new GCSignal[n][];
+		for (int i = 0; i < n; i++)
+			pairs[i] = GCGenComp.genPair();
+		return pairs;
+	}
+
+	private GCSignal[] getZeroKeys(GCSignal[][] pairs) {
+		GCSignal[] keys = new GCSignal[pairs.length];
+		for (int i = 0; i < keys.length; i++)
+			keys[i] = pairs[i][0];
+		return keys;
+	}
+
+	private BigInteger decodeOutput(GCSignal[] out1, GCSignal[] out2) {
+		BigInteger output = BigInteger.ZERO;
+		for (int i = 0; i < out1.length; i++) {
+			if (out2[i].isPublic()) {
+				if (out2[i].v)
+					output = output.setBit(i);
+			} else if (out1[i].equals(out2[i])) {
+				;
+			} else if (out1[i].equals(GCGenComp.R.xor(out2[i]))) {
+				output = output.setBit(i);
+			} else {
+				System.err.println("ERROR on GC output!");
+				return null;
+			}
+		}
+		return output;
+	}
+
+	private String addZeros(String a, int n) {
+		String out = a;
+		for (int i = 0; i < n - a.length(); i++)
+			out = "0" + out;
+		return out;
+	}
+
+	public void runE() {
+		int i = Crypto.sr.nextInt(d);
+		byte[] Li = Util.nextBytes((d - 1 + 7) / 8, Crypto.sr);
+		byte[] feBits = Util.nextBytes((w + 7) / 8, Crypto.sr);
+		byte[][] tupleLabels = new byte[w][];
+		for (int j = 0; j < w; j++)
+			tupleLabels[j] = Util.nextBytes((d - 1 + 7) / 8, Crypto.sr);
+
+		GCSignal[][] E_feKeyPairs = genKeyPairs(w);
+		GCSignal[][] C_feKeyPairs = genKeyPairs(w);
+		GCSignal[] E_feZeroKeys = getZeroKeys(E_feKeyPairs);
+		GCSignal[] C_feZeroKeys = getZeroKeys(C_feKeyPairs);
+		GCSignal[] E_feKeyInput = selectKeys(E_feKeyPairs, feBits);
+
+		GCSignal[][][] E_labelKeyPairs = new GCSignal[w][][];
+		GCSignal[][][] C_labelKeyPairs = new GCSignal[w][][];
+		GCSignal[][] E_labelZeroKeys = new GCSignal[w][];
+		GCSignal[][] C_labelZeroKeys = new GCSignal[w][];
+		GCSignal[][] E_labelKeyInput = new GCSignal[w][];
+		for (int j = 0; j < w; j++) {
+			E_labelKeyPairs[j] = genKeyPairs(d - 1);
+			C_labelKeyPairs[j] = genKeyPairs(d - 1);
+			E_labelZeroKeys[j] = getZeroKeys(E_labelKeyPairs[j]);
+			C_labelZeroKeys[j] = getZeroKeys(C_labelKeyPairs[j]);
+			E_labelKeyInput[j] = revSelectKeys(E_labelKeyPairs[j], tupleLabels[j]);
+		}
+
+		con1.write(i);
+		con1.write(Li);
+		con1.write(E_feKeyInput);
+		con1.write(C_feZeroKeys);
+		con1.write(E_labelKeyInput);
+		con1.write(C_labelZeroKeys);
+
+		Network channel = new Network(null, con1);
+		CompEnv<GCSignal> gen = new GCGen(channel);
+		GCSignal[][] E_out = new GCLib<GCSignal>(gen, d, w).deepestAndEmptyTuples(i, Li, E_feZeroKeys, C_feZeroKeys,
+				E_labelZeroKeys, C_labelZeroKeys);
+
+		GCSignal[][] D_out = con1.readObject();
+
+		int l = decodeOutput(E_out[0], D_out[0]).intValue();
+		int j1 = decodeOutput(E_out[1], D_out[1]).intValue();
+		int j2 = decodeOutput(E_out[2], D_out[2]).intValue();
+		int et = decodeOutput(E_out[3], D_out[3]).intValue();
+
+		System.out.println("i=" + i);
+
+		System.out.print("full tuples: ");
+		BigInteger fe = new BigInteger(1, feBits);
+		for (int j = 0; j < w; j++)
+			if (fe.testBit(w - 1 - j))
+				System.out.print(j + " ");
+		System.out.println();
+		System.out.print("empty tuples: ");
+		for (int j = 0; j < w; j++)
+			if (!fe.testBit(w - 1 - j))
+				System.out.print(j + " ");
+		System.out.println();
+
+		System.out.println("tuple labels xor path label:");
+		BigInteger pathLabel = new BigInteger(1, Li);
+		for (int j = 0; j < w; j++) {
+			BigInteger xor = Util.getSubBits(new BigInteger(1, tupleLabels[j]).xor(pathLabel), d - 1, 0);
+			System.out.println(j + ": " + addZeros(xor.toString(2), d - 1));
+		}
+
+		System.out.println();
+		System.out.println("deepest level: " + l);
+		System.out.println("deepest tuple index: " + j1);
+		System.out.println("empty tuple index: " + j2);
+		System.out.println("empty tuple exists: " + et);
+	}
+
+	public void runD() {
+		int i = con1.readObject();
+		byte[] Li = con1.read();
+		GCSignal[] E_feKeyInput = con1.readObject();
+		GCSignal[] C_feZeroKeys = con1.readObject();
+		GCSignal[][] E_labelKeyInput = con1.readObject();
+		GCSignal[][] C_labelZeroKeys = con1.readObject();
+
+		Network channel = new Network(con1, null);
+		CompEnv<GCSignal> gen = new GCEva(channel);
+		GCLib<GCSignal> dae = new GCLib<GCSignal>(gen, d, w);
+		dae.deepestAndEmptyTuples(i, Li, E_feKeyInput, C_feZeroKeys, E_labelKeyInput, C_labelZeroKeys);
+
+		gen.setEvaluate();
+		GCSignal[][] D_out = dae.deepestAndEmptyTuples(i, Li, E_feKeyInput, C_feZeroKeys, E_labelKeyInput,
+				C_labelZeroKeys);
+
+		con1.write(D_out);
+	}
+
+	public void runC() {
+
+	}
+
+	// for testing correctness
+	@Override
+	public void run(Party party, Metadata md, Forest forest) {
+
+		if (party == Party.Eddie) {
+			runE();
+
+		} else if (party == Party.Debbie) {
+			runD();
+
+		} else if (party == Party.Charlie) {
+			runC();
+
+		} else {
+			throw new NoSuchPartyException(party + "");
+		}
+	}
+}

+ 3 - 0
src/ui/CLI.java

@@ -22,6 +22,7 @@ import protocols.SSXOT;
 import protocols.Access;
 import protocols.GarbledCircuit;
 import protocols.GarbledCircuitTest;
+import protocols.DeepestAndEmpty;
 
 public class CLI {
 	public static final int DEFAULT_PORT = 8000;
@@ -88,6 +89,8 @@ public class CLI {
 			operation = GarbledCircuit.class;
 		} else if (protocol.equals("gctest")) {
 			operation = GarbledCircuitTest.class;
+		} else if (protocol.equals("dae")) {
+			operation = DeepestAndEmpty.class;
 		} else {
 			System.out.println("Protocol " + protocol + " not supported");
 			System.exit(-1);