|
@@ -0,0 +1,137 @@
|
|
|
+package protocols;
|
|
|
+
|
|
|
+import java.math.BigInteger;
|
|
|
+
|
|
|
+import com.oblivm.backend.circuits.arithmetic.IntegerLib;
|
|
|
+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.AccessException;
|
|
|
+import exceptions.NoSuchPartyException;
|
|
|
+import oram.Forest;
|
|
|
+import oram.Metadata;
|
|
|
+import oram.Tree;
|
|
|
+import util.Util;
|
|
|
+
|
|
|
+public class GarbledCircuit extends Protocol {
|
|
|
+
|
|
|
+ private int totalLength = 1000;
|
|
|
+
|
|
|
+ public GarbledCircuit(Communication con1, Communication con2) {
|
|
|
+ super(con1, con2);
|
|
|
+ }
|
|
|
+
|
|
|
+ private int countOnes(boolean[] in) {
|
|
|
+ int cnt = 0;
|
|
|
+ for (int i = 0; i < in.length; i++)
|
|
|
+ if (in[i])
|
|
|
+ cnt++;
|
|
|
+ return cnt;
|
|
|
+ }
|
|
|
+
|
|
|
+ private int booleansToInt(boolean[] arr) {
|
|
|
+ int n = 0;
|
|
|
+ for (int i = arr.length - 1; i >= 0; i--)
|
|
|
+ n = (n << 1) | (arr[i] ? 1 : 0);
|
|
|
+ return n;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void runE() {
|
|
|
+ Network w = new Network(null, con1);
|
|
|
+ CompEnv<GCSignal> gen = new GCGen(w);
|
|
|
+
|
|
|
+ boolean[] input1 = new boolean[totalLength];
|
|
|
+ boolean[] input2 = new boolean[totalLength];
|
|
|
+ boolean[] input = new boolean[totalLength];
|
|
|
+ for (int i = 0; i < input1.length; ++i) {
|
|
|
+ input1[i] = CompEnv.rnd.nextBoolean();
|
|
|
+ input2[i] = CompEnv.rnd.nextBoolean();
|
|
|
+ input[i] = input1[i] ^ input2[i];
|
|
|
+ }
|
|
|
+
|
|
|
+ GCSignal[][] inputKeyPairs1 = new GCSignal[input1.length][];
|
|
|
+ GCSignal[] localInputKeys1 = new GCSignal[input1.length];
|
|
|
+ GCSignal[][] inputKeyPairs2 = new GCSignal[input1.length][];
|
|
|
+ GCSignal[] localInputKeys2 = new GCSignal[input1.length];
|
|
|
+ GCSignal[] inputE = new GCSignal[input1.length];
|
|
|
+ GCSignal[] inputD = new GCSignal[input1.length];
|
|
|
+ for (int i = 0; i < input1.length; i++) {
|
|
|
+ inputKeyPairs1[i] = GCGenComp.genPair();
|
|
|
+ localInputKeys1[i] = inputKeyPairs1[i][0];
|
|
|
+ inputKeyPairs2[i] = GCGenComp.genPair();
|
|
|
+ localInputKeys2[i] = inputKeyPairs2[i][0];
|
|
|
+
|
|
|
+ inputE[i] = input1[i] ? inputKeyPairs1[i][1] : inputKeyPairs1[i][0];
|
|
|
+ inputD[i] = input2[i] ? inputKeyPairs2[i][1] : inputKeyPairs2[i][0];
|
|
|
+ }
|
|
|
+
|
|
|
+ GCSignal[] outputE = new IntegerLib<GCSignal>(gen).hammingDistance(localInputKeys1, localInputKeys2);
|
|
|
+
|
|
|
+ con1.write(inputE);
|
|
|
+ con1.write(inputD);
|
|
|
+
|
|
|
+ GCSignal[] outputD = con1.readObject();
|
|
|
+
|
|
|
+ boolean[] output = new boolean[totalLength];
|
|
|
+ for (int i = 0; i < outputE.length; i++) {
|
|
|
+ if (outputE[i].isPublic())
|
|
|
+ output[i] = outputE[i].v;
|
|
|
+ else if (outputE[i].equals(outputD[i]))
|
|
|
+ output[i] = false;
|
|
|
+ else if (outputD[i].equals(GCGenComp.R.xor(outputE[i])))
|
|
|
+ output[i] = true;
|
|
|
+ else
|
|
|
+ System.err.println("ERROR on GC output!");
|
|
|
+ }
|
|
|
+
|
|
|
+ int inCnt = countOnes(input);
|
|
|
+ int outCnt = booleansToInt(output);
|
|
|
+ System.out.println((inCnt == outCnt) + " " + inCnt + " " + outCnt);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void runD() {
|
|
|
+ Network w = new Network(con1, null);
|
|
|
+ CompEnv<GCSignal> gen = new GCEva(w);
|
|
|
+
|
|
|
+ GCSignal[] randomInput = new GCSignal[totalLength];
|
|
|
+ for (int i = 0; i < randomInput.length; i++)
|
|
|
+ randomInput[i] = GCSignal.freshLabel(Crypto.sr);
|
|
|
+ IntegerLib<GCSignal> il = new IntegerLib<GCSignal>(gen);
|
|
|
+ il.hammingDistance(randomInput, randomInput);
|
|
|
+
|
|
|
+ GCSignal[] inputE = con1.readObject();
|
|
|
+ GCSignal[] inputD = con1.readObject();
|
|
|
+
|
|
|
+ gen.setEvaluate();
|
|
|
+ GCSignal[] outputD = il.hammingDistance(inputE, inputD);
|
|
|
+
|
|
|
+ con1.write(outputD);
|
|
|
+ }
|
|
|
+
|
|
|
+ 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 + "");
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|