├── .gitignore
├── Config.conf
├── LICENSE.md
├── README.md
├── compile.sh
├── lib
├── commons-cli-1.2.jar
├── commons-io-2.4.jar
├── commons-lang-2.6.jar
├── commons-lang3-3.3.2.jar
├── junit.jar
└── org.hamcrest.core_1.3.0.v201303031735.jar
├── runAdd.sh
├── runArbit.sh
├── runHam.sh
├── runMill.sh
├── runMult.sh
├── runSort.sh
├── src
├── circuits
│ ├── BitonicSortLib.java
│ ├── CircuitLib.java
│ └── arithmetic
│ │ ├── ArithmeticLib.java
│ │ ├── DenseMatrixLib.java
│ │ ├── FixedPointLib.java
│ │ ├── FloatLib.java
│ │ ├── IntegerLib.java
│ │ └── VectorLib.java
├── example
│ ├── Add.java
│ ├── ArbitCircuit.java
│ ├── HammingDistance.java
│ ├── Millionaire.java
│ ├── Mult.java
│ └── Sort.java
├── flexsc
│ ├── BooleanCompEnv.java
│ ├── CVCompEnv.java
│ ├── CircuitWire.java
│ ├── ClearCircuitCompEnv.java
│ ├── CompEnv.java
│ ├── Comparator.java
│ ├── Flag.java
│ ├── IWritable.java
│ ├── Mode.java
│ ├── PMCompEnv.java
│ └── Party.java
├── gc
│ ├── BadLabelException.java
│ ├── DbgUtils.java
│ ├── GCCompEnv.java
│ ├── GCEvaComp.java
│ ├── GCGenComp.java
│ ├── GCSignal.java
│ ├── halfANDs
│ │ ├── GCEva.java
│ │ ├── GCGen.java
│ │ ├── Garbler.java
│ │ └── TestGarbler.java
│ ├── offline
│ │ ├── FileReader.java
│ │ ├── GCEva.java
│ │ ├── GCGen.java
│ │ ├── Garbler.java
│ │ └── TestGarbler.java
│ └── regular
│ │ ├── GCEva.java
│ │ ├── GCGen.java
│ │ ├── Garbler.java
│ │ └── TestGarbler.java
├── network
│ ├── Client.java
│ ├── Network.java
│ └── Server.java
├── oram
│ ├── Block.java
│ ├── BucketLib.java
│ ├── CircuitOram.java
│ ├── CircuitOramLib.java
│ ├── LinearScanOram.java
│ ├── OramParty.java
│ ├── PlainBlock.java
│ ├── RecursiveCircuitOram.java
│ ├── SecureArray.java
│ ├── TreeBasedOramParty.java
│ └── TrivialPrivateOram.java
├── ot
│ ├── BitMatrix.java
│ ├── Cipher.java
│ ├── FakeOTReceiver.java
│ ├── FakeOTSender.java
│ ├── NPOTReceiver.java
│ ├── NPOTSender.java
│ ├── OTExtReceiver.java
│ ├── OTExtSender.java
│ ├── OTPreprocessReceiver.java
│ ├── OTPreprocessSender.java
│ ├── OTReceiver.java
│ └── OTSender.java
├── rand
│ ├── ISAACAlgorithm.java
│ ├── ISAACEngine.java
│ └── ISAACProvider.java
└── util
│ ├── ConfigParser.java
│ ├── Constants.java
│ ├── EvaRunnable.java
│ ├── GenRunnable.java
│ ├── StopWatch.java
│ └── Utils.java
├── test
├── component
│ └── TestISAACRandom.java
├── harness
│ ├── TestBigInteger.java
│ ├── TestFixedPoint.java
│ ├── TestFloat.java
│ ├── TestHarness.java
│ ├── TestMatrix.java
│ ├── TestSend.java
│ ├── TestSortHarness.java
│ ├── TestSpeed.java
│ └── Test_2Input1Output.java
├── matrix
│ ├── TestMatrixAdd.java
│ ├── TestMatrixEigenValue.java
│ ├── TestMatrixMultiplication.java
│ ├── TestMatrixQRDecomposition.java
│ └── TestMatrixRowReducedEchelonForm.java
├── oram
│ ├── CountCircuitOramBasic.java
│ ├── CountCircuitOramRec.java
│ ├── CountTrivialOram.java
│ ├── TestCircuitOramBasic.java
│ ├── TestCircuitOramRec.java
│ ├── TestCircuitOramRecClient.java
│ ├── TestCircuitOramRecServer.java
│ └── TestTrivialOram.java
├── ot
│ ├── TestCipher.java
│ ├── TestNPOT.java
│ ├── TestNPOTMany.java
│ ├── TestOTExt.java
│ ├── TestOTExtMany.java
│ └── TestOTPreMany.java
└── testlibs
│ ├── TestBitonicSortLib.java
│ ├── TestCircuitLib.java
│ ├── TestFixedPointLib.java
│ ├── TestFloatLib.java
│ └── TestIntegerLib.java
└── throttle.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 | .DS_Store
3 | # Mobile Tools for Java (J2ME)
4 | .mtj.tmp/
5 |
6 | # Package Files #
7 | *.war
8 | *.ear
9 |
10 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
11 | hs_err_pid*
12 | /bin/
13 |
14 | .DS_Store
15 | .classpath
16 | .project
17 | NPOTKey
18 | source.txt
19 |
--------------------------------------------------------------------------------
/Config.conf:
--------------------------------------------------------------------------------
1 | #Host: 192.168.1.102
2 | Host: localhost
3 | Port: 54321
4 | #Mode can be OPT, VERIFY, COUNT and REAL
5 | #Mode: CIRCUIT
6 | #Mode: VERIFY
7 | Mode:OPT
8 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (C) 2014 - 2015 Xiao Wang
2 |
3 | This program is free software: you can redistribute it and/or modify
4 | it under the terms of the Creative Commons Attribution-NonCommercial
5 | license.
6 |
7 | This program is distributed in the hope that it will be useful,
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | Creative Commons Attribution-NonCommercial license for more details.
11 |
12 | You should have received a copy of the Creative Commons
13 | Attribution-NonCommercial license. If not, see
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | FlexSC
2 | ======
3 |
4 | A Flexible Efficient Secure Computation Backend.
5 |
6 | JAVA-8 required
7 |
8 | **Looking for more efficient FlexSC? [emp-toolkit](https://github.com/emp-toolkit) is written in C/C++ and supports both malicious and semi-honest 2(M)PC**
9 |
10 | version 0.2
11 |
12 | 1. Runnable backend.
13 | 2. Modes(REAL, VERIFY, COUNT, OPT, OFFLINE) that can run the real protocol, verify the correctness of circuit and count the statitics
14 | of the circuits, halfgate protocols and offline garblging.
15 | 3. Basic integer arithmetic circuit library with test case.
16 | 4. Fixed point and Floating point arithmetic circuit library with test case.
17 | 5. Sorting circuit library with test case.
18 | 6. Libs for Matrix and vectors.
19 | 7. RAM support
20 |
21 | version 0.3(TODO)
22 |
23 | 1. optimize some circuit size for Integers, redesign floating point numbers.
24 | 2. optimize roundtrip problem
25 | 3. develop better tutorial
26 |
27 | This document is in developemnt.
28 |
--------------------------------------------------------------------------------
/compile.sh:
--------------------------------------------------------------------------------
1 | mkdir -p bin
2 | find . -name "*.java" > source.txt;
3 | javac -cp bin:lib/* -d bin @source.txt;
4 |
--------------------------------------------------------------------------------
/lib/commons-cli-1.2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxiao1254/FlexSC/1350b6e6cc0354753f8b0e7e92e77cd7c08313a8/lib/commons-cli-1.2.jar
--------------------------------------------------------------------------------
/lib/commons-io-2.4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxiao1254/FlexSC/1350b6e6cc0354753f8b0e7e92e77cd7c08313a8/lib/commons-io-2.4.jar
--------------------------------------------------------------------------------
/lib/commons-lang-2.6.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxiao1254/FlexSC/1350b6e6cc0354753f8b0e7e92e77cd7c08313a8/lib/commons-lang-2.6.jar
--------------------------------------------------------------------------------
/lib/commons-lang3-3.3.2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxiao1254/FlexSC/1350b6e6cc0354753f8b0e7e92e77cd7c08313a8/lib/commons-lang3-3.3.2.jar
--------------------------------------------------------------------------------
/lib/junit.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxiao1254/FlexSC/1350b6e6cc0354753f8b0e7e92e77cd7c08313a8/lib/junit.jar
--------------------------------------------------------------------------------
/lib/org.hamcrest.core_1.3.0.v201303031735.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangxiao1254/FlexSC/1350b6e6cc0354753f8b0e7e92e77cd7c08313a8/lib/org.hamcrest.core_1.3.0.v201303031735.jar
--------------------------------------------------------------------------------
/runAdd.sh:
--------------------------------------------------------------------------------
1 | java -cp bin:lib/* util.GenRunnable example.Add 2 &
2 |
3 | java -cp bin:lib/* util.EvaRunnable example.Add 13
4 |
--------------------------------------------------------------------------------
/runArbit.sh:
--------------------------------------------------------------------------------
1 | java -cp bin:lib/* util.GenRunnable example.ArbitCircuit true &
2 |
3 | java -cp bin:lib/* util.EvaRunnable example.ArbitCircuit false
4 |
--------------------------------------------------------------------------------
/runHam.sh:
--------------------------------------------------------------------------------
1 | java -cp bin:lib/* util.GenRunnable example.HammingDistance &
2 |
3 | java -cp bin:lib/* util.EvaRunnable example.HammingDistance
4 |
--------------------------------------------------------------------------------
/runMill.sh:
--------------------------------------------------------------------------------
1 | java -cp bin:lib/* util.GenRunnable example.Millionaire 1 &
2 |
3 | java -cp bin:lib/* util.EvaRunnable example.Millionaire 8
4 |
--------------------------------------------------------------------------------
/runMult.sh:
--------------------------------------------------------------------------------
1 | java -cp bin:lib/* util.GenRunnable example.Mult 2 &
2 |
3 | java -cp bin:lib/* util.EvaRunnable example.Mult 5
4 |
--------------------------------------------------------------------------------
/runSort.sh:
--------------------------------------------------------------------------------
1 | java -cp bin:lib/* util.GenRunnable example.Sort &
2 |
3 | java -cp bin:lib/* util.EvaRunnable example.Sort
4 |
--------------------------------------------------------------------------------
/src/circuits/BitonicSortLib.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2014 by Xiao Shaun Wang
2 | package circuits;
3 |
4 | import circuits.arithmetic.IntegerLib;
5 | import flexsc.CompEnv;
6 |
7 | public class BitonicSortLib extends IntegerLib {
8 | public BitonicSortLib(CompEnv e) {
9 | super(e);
10 | }
11 |
12 | public void sortWithPayload(T[][] a, T[][] data, T isAscending) {
13 | bitonicSortWithPayload(a, data, 0, a.length, isAscending);
14 | }
15 |
16 | private void bitonicSortWithPayload(T[][] key, T[][] data, int lo, int n,
17 | T dir) {
18 | if (n > 1) {
19 | int m = n / 2;
20 | bitonicSortWithPayload(key, data, lo, m, not(dir));
21 | bitonicSortWithPayload(key, data, lo + m, n - m, dir);
22 | bitonicMergeWithPayload(key, data, lo, n, dir);
23 | }
24 | }
25 |
26 | protected void bitonicMergeWithPayload(T[][] key, T[][] data, int lo, int n,
27 | T dir) {
28 | if (n > 1) {
29 | int m = greatestPowerOfTwoLessThan(n);
30 | for (int i = lo; i < lo + n - m; i++)
31 | compareWithPayload(key, data, i, i + m, dir);
32 | bitonicMergeWithPayload(key, data, lo, m, dir);
33 | bitonicMergeWithPayload(key, data, lo + m, n - m, dir);
34 | }
35 | }
36 |
37 | private void compareWithPayload(T[][] key, T[][] data, int i, int j, T dir) {
38 | T greater = not(leq(key[i], key[j]));
39 | T swap = eq(greater, dir);
40 | T[] s = mux(key[j], key[i], swap);
41 | s = xor(s, key[i]);
42 | T[] ki = xor(key[j], s);
43 | T[] kj = xor(key[i], s);
44 | key[i] = ki;
45 | key[j] = kj;
46 |
47 | T[] s2 = mux(data[j], data[i], swap);
48 | s2 = xor(s2, data[i]);
49 | T[] di = xor(data[j], s2);
50 | T[] dj = xor(data[i], s2);
51 | data[i] = di;
52 | data[j] = dj;
53 | }
54 |
55 | public void sort(T[][] a, T isAscending) {
56 | bitonicSort(a, 0, a.length, isAscending);
57 | }
58 |
59 | private void bitonicSort(T[][] key, int lo, int n, T dir) {
60 | if (n > 1) {
61 | int m = n / 2;
62 | bitonicSort(key, lo, m, not(dir));
63 | bitonicSort(key, lo + m, n - m, dir);
64 | bitonicMerge(key, lo, n, dir);
65 | }
66 | }
67 |
68 | protected void bitonicMerge(T[][] key, int lo, int n, T dir) {
69 | if (n > 1) {
70 | int m = greatestPowerOfTwoLessThan(n);
71 | for (int i = lo; i < lo + n - m; i++)
72 | compare(key, i, i + m, dir);
73 | bitonicMerge(key, lo, m, dir);
74 | bitonicMerge(key, lo + m, n - m, dir);
75 | }
76 | }
77 |
78 | private void compare(T[][] key, int i, int j, T dir) {
79 | T swap = eq(not(leq(key[i], key[j])), dir);
80 | T[] s = mux(key[j], key[i], swap);
81 | s = xor(s, key[i]);
82 | T[] ki = xor(key[j], s);
83 | T[] kj = xor(key[i], s);
84 | key[i] = ki;
85 | key[j] = kj;
86 | }
87 |
88 | private int greatestPowerOfTwoLessThan(int n) {
89 | int k = 1;
90 | while (k < n)
91 | k = k << 1;
92 | return k >> 1;
93 | }
94 |
95 | public void sortWithPayload(T[] a, T[][] data, T isAscending) {
96 | bitonicSortWithPayload(a, data, 0, a.length, isAscending);
97 | }
98 |
99 | private void bitonicSortWithPayload(T[] key, T[][] data, int lo, int n,
100 | T dir) {
101 | if (n > 1) {
102 | int m = n / 2;
103 | bitonicSortWithPayload(key, data, lo, m, not(dir));
104 | bitonicSortWithPayload(key, data, lo + m, n - m, dir);
105 | bitonicMergeWithPayload(key, data, lo, n, dir);
106 | }
107 | }
108 |
109 | private void bitonicMergeWithPayload(T[] key, T[][] data, int lo, int n,
110 | T dir) {
111 | if (n > 1) {
112 | int m = greatestPowerOfTwoLessThan(n);
113 | for (int i = lo; i < lo + n - m; i++)
114 | compareWithPayload(key, data, i, i + m, dir);
115 | bitonicMergeWithPayload(key, data, lo, m, dir);
116 | bitonicMergeWithPayload(key, data, lo + m, n - m, dir);
117 | }
118 | }
119 |
120 | private void compareWithPayload(T[] key, T[][] data, int i, int j, T dir) {
121 | T greater = and(key[i], not(key[j]));
122 | T swap = eq(greater, dir);
123 | T s = mux(key[j], key[i], swap);
124 | s = xor(s, key[i]);
125 | T ki = xor(key[j], s);
126 | T kj = xor(key[i], s);
127 | key[i] = ki;
128 | key[j] = kj;
129 |
130 | T[] s2 = mux(data[j], data[i], swap);
131 | s2 = xor(s2, data[i]);
132 | T[] di = xor(data[j], s2);
133 | T[] dj = xor(data[i], s2);
134 | data[i] = di;
135 | data[j] = dj;
136 | }
137 |
138 | public void sortWithPayload(T[][] a, T[] data, T isAscending) {
139 | bitonicSortWithPayload(a, data, 0, a.length, isAscending);
140 | }
141 |
142 | private void bitonicSortWithPayload(T[][] key, T[] data, int lo, int n,
143 | T dir) {
144 | if (n > 1) {
145 | int m = n / 2;
146 | bitonicSortWithPayload(key, data, lo, m, not(dir));
147 | bitonicSortWithPayload(key, data, lo + m, n - m, dir);
148 | bitonicMergeWithPayload(key, data, lo, n, dir);
149 | }
150 | }
151 |
152 | private void bitonicMergeWithPayload(T[][] key, T[] data, int lo, int n,
153 | T dir) {
154 | if (n > 1) {
155 | int m = greatestPowerOfTwoLessThan(n);
156 | for (int i = lo; i < lo + n - m; i++)
157 | compareWithPayload(key, data, i, i + m, dir);
158 | bitonicMergeWithPayload(key, data, lo, m, dir);
159 | bitonicMergeWithPayload(key, data, lo + m, n - m, dir);
160 | }
161 | }
162 |
163 | private void compareWithPayload(T[][] key, T[] data, int i, int j, T dir) {
164 | T greater = not(leq(key[i], key[j]));
165 | T swap = eq(greater, dir);
166 | T[] s = mux(key[j], key[i], swap);
167 | s = xor(s, key[i]);
168 | T[] ki = xor(key[j], s);
169 | T[] kj = xor(key[i], s);
170 | key[i] = ki;
171 | key[j] = kj;
172 |
173 | T s2 = mux(data[j], data[i], swap);
174 | s2 = xor(s2, data[i]);
175 | T di = xor(data[j], s2);
176 | T dj = xor(data[i], s2);
177 | data[i] = di;
178 | data[j] = dj;
179 | }
180 |
181 |
182 | }
--------------------------------------------------------------------------------
/src/circuits/arithmetic/ArithmeticLib.java:
--------------------------------------------------------------------------------
1 | package circuits.arithmetic;
2 |
3 | import flexsc.CompEnv;
4 |
5 | public interface ArithmeticLib {
6 | CompEnv getEnv();
7 | T[] inputOfAlice(double d);
8 |
9 | T[] inputOfBob(double d);
10 |
11 | double outputToAlice(T[] a);
12 |
13 | T[] add(T[] x, T[] y);
14 |
15 | T[] multiply(T[] x, T[] y);
16 |
17 | T[] div(T[] x, T[] y);
18 |
19 | T[] sub(T[] x, T[] y);
20 |
21 | T[] publicValue(double v);
22 |
23 | T leq(T[] a, T[] b);
24 |
25 | T eq(T[] a, T[] b);
26 |
27 | T[] sqrt(T[] a);
28 |
29 | T[] toSecureInt(T[] a, IntegerLib lib);
30 | T[] toSecureFloat(T[] a, FloatLib lib);
31 | T[] toSecureFixPoint(T[] a, FixedPointLib lib);
32 | int numBits();
33 | }
--------------------------------------------------------------------------------
/src/circuits/arithmetic/FixedPointLib.java:
--------------------------------------------------------------------------------
1 | package circuits.arithmetic;
2 |
3 | import java.util.Arrays;
4 |
5 | import util.Utils;
6 | import flexsc.CompEnv;
7 |
8 | //http://x86asm.net/articles/fixed-point-arithmetic-and-tricks/
9 | public class FixedPointLib implements ArithmeticLib {
10 |
11 | CompEnv env;
12 | IntegerLib lib;
13 | int offset;
14 | int width;
15 |
16 | public FixedPointLib(CompEnv e, int width, int offset) {
17 | assert(offset%2 == 0);
18 | this.env = e;
19 | lib = new IntegerLib<>(e);
20 | this.offset = offset;
21 | this.width = width;
22 | }
23 |
24 | public T[] inputOfAlice(double d) {
25 | return env.inputOfAlice(Utils.fromFixPoint(d, width, offset));
26 | }
27 |
28 | public T[] inputOfBob(double d) {
29 | return env.inputOfBob(Utils.fromFixPoint(d, width, offset));
30 | }
31 |
32 | public T[] add(T[] x, T[] y) {
33 | return lib.add(x, y);
34 | }
35 |
36 | public T[] sub(T[] x, T[] y) {
37 | return lib.sub(x, y);
38 | }
39 |
40 | //http://dsp.stackexchange.com/questions/7906/fixed-point-multiplication-with-negative-numbers
41 | public T[] multiply(T[] x, T[] y) {
42 | T[] res = lib.karatsubaMultiply(lib.absolute(x), lib.absolute(y));
43 | res = Arrays.copyOfRange(res, offset,offset+ width);
44 | return lib.addSign(res, lib.xor(x[x.length-1], y[y.length-1]));
45 | }
46 |
47 | public T[] div(T[] x, T[] y) {
48 | T[] padX = lib.padSignedSignal(x, x.length + offset);
49 | return Arrays.copyOf(lib.div(lib.leftPublicShift(padX, offset), y), width);
50 | }
51 |
52 | public T[] publicValue(double d) {
53 | boolean[] a = Utils.fromFixPoint(d, width, offset);
54 | T[] res = env.newTArray(width);
55 | for (int i = 0; i < width; ++i)
56 | res[i] = a[i] ? lib.SIGNAL_ONE : lib.SIGNAL_ZERO;
57 | return res;
58 | }
59 |
60 | @Override
61 | public T leq(T[] a, T[] b) {
62 | return lib.leq(a, b);
63 | }
64 |
65 | @Override
66 | public T eq(T[] a, T[] b) {
67 | return lib.eq(a, b);
68 | }
69 |
70 | @Override
71 | public T[] sqrt(T[] a) {
72 | T[] res = lib.sqrt(a);
73 | return lib.leftPublicShift(res, offset/2);
74 | }
75 |
76 | @Override
77 | public CompEnv getEnv() {
78 | return env;
79 | }
80 |
81 | @Override
82 | public T[] toSecureInt(T[] a, IntegerLib lib) {
83 | T[] res = lib.env.newTArray(lib.width);
84 | T[] intPart = Arrays.copyOfRange(a, offset, a.length);
85 | if(res.length >= intPart.length)
86 | System.arraycopy(intPart, 0, res, 0, intPart.length);
87 | else
88 | res = Arrays.copyOf(intPart, res.length);
89 | return res;
90 | }
91 |
92 | @Override
93 | public T[] toSecureFloat(T[] a, FloatLib lib) {
94 | return null;
95 | }
96 |
97 | @Override
98 | public T[] toSecureFixPoint(T[] a, FixedPointLib lib) {
99 | //later may support case between different libs;
100 | return a;
101 | }
102 |
103 | @Override
104 | public double outputToAlice(T[] a) {
105 | return Utils.toFixPoint(env.outputToAlice(a), offset);
106 | }
107 |
108 | @Override
109 | public int numBits() {
110 | return width;
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/src/circuits/arithmetic/VectorLib.java:
--------------------------------------------------------------------------------
1 | package circuits.arithmetic;
2 |
3 | import flexsc.CompEnv;
4 |
5 | public class VectorLib {
6 | ArithmeticLib lib;
7 | CompEnv env;
8 |
9 | public VectorLib(CompEnv e, ArithmeticLib lib) {
10 | env = e;
11 | this.lib = lib;
12 | }
13 |
14 | public T[][] xor(T[][] a, T[][] b) {
15 | IntegerLib ilib = new IntegerLib(lib.getEnv());
16 | T[][] res = env.newTArray(a.length, 1);
17 | for (int i = 0; i < a.length; ++i)
18 | res[i] = ilib.xor(a[i], b[i]);
19 | return res;
20 | }
21 |
22 | public T[][] add(T[][] a, T[][] b) {
23 | T[][] res = env.newTArray(a.length, 1);
24 | for (int i = 0; i < a.length; ++i)
25 | res[i] = lib.add(a[i], b[i]);
26 | return res;
27 | }
28 |
29 | public T[][] sub(T[][] a, T[][] b) {
30 | T[][] res = env.newTArray(a.length, 1);
31 | for (int i = 0; i < a.length; ++i)
32 | res[i] = lib.sub(a[i], b[i]);
33 | return res;
34 | }
35 |
36 | public T[] innerProduct(T[][] a, T[][] b) {
37 | T[] res = lib.publicValue(0);
38 | for (int i = 0; i < a.length; ++i)
39 | res = lib.add(res, lib.multiply(a[i], b[i]));
40 | return res;
41 | }
42 |
43 | public T[][] scalarProduct(T[] scalar, T[][] v) {
44 | T[][] res = env.newTArray(v.length, 1);
45 | for (int i = 0; i < v.length; ++i)
46 | res[i] = lib.multiply(scalar, v[i]);
47 | return res;
48 | }
49 |
50 | public T[][] projection(T[][] a, T[][] e) {
51 | T[] ea = innerProduct(e, a);
52 | T[] ee = innerProduct(e, e);
53 | T[] scalar = lib.div(ea, ee);
54 | return scalarProduct(scalar, e);
55 | }
56 |
57 | public T[][] normalize(T[][] vec) {
58 | T[] scalar = innerProduct(vec, vec);
59 | scalar = lib.sqrt(scalar);
60 | scalar = lib.div(lib.publicValue(1), scalar);
61 | return scalarProduct(scalar, vec);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/example/Add.java:
--------------------------------------------------------------------------------
1 | package example;
2 |
3 | import util.EvaRunnable;
4 | import util.GenRunnable;
5 | import util.Utils;
6 | import circuits.arithmetic.IntegerLib;
7 | import flexsc.CompEnv;
8 | import gc.BadLabelException;
9 |
10 | public class Add {
11 |
12 | static public T[] compute(CompEnv gen, T[] inputA, T[] inputB){
13 | return new IntegerLib(gen).addFull(inputA, inputB, false);
14 | }
15 |
16 | public static class Generator extends GenRunnable {
17 |
18 | T[] inputA;
19 | T[] inputB;
20 | T[] scResult;
21 |
22 | @Override
23 | public void prepareInput(CompEnv gen) {
24 | inputA = gen.inputOfAlice(Utils.fromInt(new Integer(args[0]), 32));
25 | gen.flush();
26 | inputB = gen.inputOfBob(new boolean[32]);
27 | }
28 |
29 | @Override
30 | public void secureCompute(CompEnv gen) {
31 | scResult = compute(gen, inputA, inputB);
32 | }
33 |
34 | @Override
35 | public void prepareOutput(CompEnv gen) throws BadLabelException {
36 | System.out.println(Utils.toInt(gen.outputToAlice(scResult)));
37 | System.out.println("out length = " + scResult.length);
38 | }
39 | }
40 |
41 | public static class Evaluator extends EvaRunnable {
42 | T[] inputA;
43 | T[] inputB;
44 | T[] scResult;
45 |
46 | @Override
47 | public void prepareInput(CompEnv gen) {
48 | inputA = gen.inputOfAlice(new boolean[32]);
49 | gen.flush();
50 | inputB = gen.inputOfBob(Utils.fromInt(new Integer(args[0]), 32));
51 | }
52 |
53 | @Override
54 | public void secureCompute(CompEnv gen) {
55 | scResult = compute(gen, inputA, inputB);
56 | }
57 |
58 | @Override
59 | public void prepareOutput(CompEnv gen) throws BadLabelException {
60 | //gen.outputToAlice(scResult);
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/example/ArbitCircuit.java:
--------------------------------------------------------------------------------
1 | package example;
2 |
3 | import util.EvaRunnable;
4 | import util.GenRunnable;
5 | import flexsc.CompEnv;
6 | import gc.BadLabelException;
7 |
8 | public class ArbitCircuit {
9 |
10 |
11 | static public T compute(CompEnv gen, T inputA, T inputB){
12 | T c = gen.and(inputA, inputB);
13 | T d = gen.xor(inputA, c);
14 | T e = gen.xor(c, d);
15 | return gen.and(gen.and(c, d), gen.not(e));
16 | }
17 |
18 | public static class Generator extends GenRunnable {
19 |
20 | T inputA;
21 | T inputB;
22 | T scResult;
23 |
24 | @Override
25 | public void prepareInput(CompEnv gen) {
26 | inputA = gen.inputOfAlice(Boolean.parseBoolean(args[0])); // real input
27 | gen.flush();
28 | inputB = gen.inputOfBob(false); // fake input
29 | }
30 |
31 | @Override
32 | public void secureCompute(CompEnv gen) {
33 | scResult = compute(gen, inputA, inputB);
34 | }
35 |
36 | @Override
37 | public void prepareOutput(CompEnv gen) throws BadLabelException {
38 | System.out.println(gen.outputToAlice(scResult));
39 | }
40 | }
41 |
42 | public static class Evaluator extends EvaRunnable {
43 | T inputA;
44 | T inputB;
45 | T scResult;
46 |
47 | @Override
48 | public void prepareInput(CompEnv gen) {
49 | inputA = gen.inputOfAlice(false);
50 | gen.flush();
51 | inputB = gen.inputOfBob(Boolean.parseBoolean(args[0]));
52 | }
53 |
54 | @Override
55 | public void secureCompute(CompEnv gen) {
56 | scResult = compute(gen, inputA, inputB);
57 | }
58 |
59 | @Override
60 | public void prepareOutput(CompEnv gen) throws BadLabelException {
61 | gen.outputToAlice(scResult);
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/example/HammingDistance.java:
--------------------------------------------------------------------------------
1 | package example;
2 |
3 | import util.EvaRunnable;
4 | import util.GenRunnable;
5 | import util.Utils;
6 |
7 | import java.util.Arrays;
8 |
9 | import circuits.arithmetic.IntegerLib;
10 | import flexsc.CompEnv;
11 | import gc.BadLabelException;
12 |
13 | public class HammingDistance {
14 |
15 | static int LEN = 32;
16 | static public T[] compute(CompEnv gen, T[] inputA, T[] inputB){
17 | return new IntegerLib(gen).hammingDistance(inputA, inputB);
18 | }
19 |
20 |
21 | public static class Generator extends GenRunnable {
22 |
23 | T[] inputA;
24 | T[] inputB;
25 | T[] scResult;
26 |
27 | @Override
28 | public void prepareInput(CompEnv gen) {
29 | boolean[] in = new boolean[LEN];
30 | for(int i = 0; i < in.length; ++i)
31 | in[i] = CompEnv.rnd.nextBoolean();
32 | inputA = gen.inputOfAlice(in);
33 | gen.flush();
34 | inputB = gen.inputOfBob(new boolean[LEN]);
35 | System.out.println("Input from Gen:"+Arrays.toString(in));
36 | }
37 |
38 | @Override
39 | public void secureCompute(CompEnv gen) {
40 | scResult = compute(gen, inputA, inputB);
41 | }
42 | @Override
43 | public void prepareOutput(CompEnv gen) throws BadLabelException {
44 | System.out.println(Utils.toInt(gen.outputToAlice(scResult)));
45 | System.out.println("out len = " + scResult.length);
46 | }
47 |
48 | }
49 |
50 | public static class Evaluator extends EvaRunnable {
51 | T[] inputA;
52 | T[] inputB;
53 | T[] scResult;
54 |
55 | @Override
56 | public void prepareInput(CompEnv gen) {
57 | boolean[] in = new boolean[LEN];
58 | for(int i = 0; i < in.length; ++i)
59 | in[i] = CompEnv.rnd.nextBoolean();
60 | inputA = gen.inputOfAlice(new boolean[LEN]);
61 | gen.flush();
62 | inputB = gen.inputOfBob(in);
63 | System.out.println("Input from Eva:"+Arrays.toString(in));
64 | }
65 |
66 | @Override
67 | public void secureCompute(CompEnv gen) {
68 | scResult = compute(gen, inputA, inputB);
69 | }
70 |
71 | @Override
72 | public void prepareOutput(CompEnv gen) throws BadLabelException {
73 | // gen.outputToAlice(scResult);
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/example/Millionaire.java:
--------------------------------------------------------------------------------
1 | package example;
2 |
3 | import util.EvaRunnable;
4 | import util.GenRunnable;
5 | import util.Utils;
6 | import circuits.arithmetic.IntegerLib;
7 | import flexsc.CompEnv;
8 | import gc.BadLabelException;
9 |
10 | public class Millionaire {
11 |
12 |
13 | static public T compute(CompEnv gen, T[] inputA, T[] inputB){
14 | return new IntegerLib(gen).geq(inputA, inputB);
15 | }
16 |
17 | public static class Generator extends GenRunnable {
18 |
19 | T[] inputA;
20 | T[] inputB;
21 | T scResult;
22 |
23 | @Override
24 | public void prepareInput(CompEnv gen) {
25 | inputA = gen.inputOfAlice(Utils.fromInt(new Integer(args[0]), 32));
26 | gen.flush();
27 | inputB = gen.inputOfBob(new boolean[32]);
28 | }
29 |
30 | @Override
31 | public void secureCompute(CompEnv gen) {
32 | scResult = compute(gen, inputA, inputB);
33 | }
34 |
35 | @Override
36 | public void prepareOutput(CompEnv gen) throws BadLabelException {
37 | System.out.println(gen.outputToAlice(scResult));
38 | }
39 | }
40 |
41 | public static class Evaluator extends EvaRunnable {
42 | T[] inputA;
43 | T[] inputB;
44 | T scResult;
45 |
46 | @Override
47 | public void prepareInput(CompEnv gen) {
48 | inputA = gen.inputOfAlice(new boolean[32]);
49 | gen.flush();
50 | inputB = gen.inputOfBob(Utils.fromInt(new Integer(args[0]), 32));
51 | }
52 |
53 | @Override
54 | public void secureCompute(CompEnv gen) {
55 | scResult = compute(gen, inputA, inputB);
56 | }
57 |
58 | @Override
59 | public void prepareOutput(CompEnv gen) throws BadLabelException {
60 | gen.outputToAlice(scResult);
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/example/Mult.java:
--------------------------------------------------------------------------------
1 | package example;
2 |
3 | import util.EvaRunnable;
4 | import util.GenRunnable;
5 | import util.Utils;
6 | import circuits.arithmetic.IntegerLib;
7 | import flexsc.CompEnv;
8 | import gc.BadLabelException;
9 |
10 | public class Mult {
11 |
12 | static public T[] compute(CompEnv gen, T[] inputA, T[] inputB){
13 | return new IntegerLib(gen).multiplyFull(inputA, inputB);
14 | }
15 |
16 | public static class Generator extends GenRunnable {
17 |
18 | T[] inputA;
19 | T[] inputB;
20 | T[] scResult;
21 |
22 | @Override
23 | public void prepareInput(CompEnv gen) {
24 | inputA = gen.inputOfAlice(Utils.fromInt(new Integer(args[0]), 32));
25 | gen.flush();
26 | inputB = gen.inputOfBob(new boolean[32]);
27 | }
28 |
29 | @Override
30 | public void secureCompute(CompEnv gen) {
31 | scResult = compute(gen, inputA, inputB);
32 | }
33 |
34 | @Override
35 | public void prepareOutput(CompEnv gen) throws BadLabelException {
36 | System.out.println(Utils.toInt(gen.outputToAlice(scResult)));
37 | System.out.println(scResult.length);
38 | }
39 | }
40 |
41 | public static class Evaluator extends EvaRunnable {
42 | T[] inputA;
43 | T[] inputB;
44 | T[] scResult;
45 |
46 | @Override
47 | public void prepareInput(CompEnv gen) {
48 | inputA = gen.inputOfAlice(new boolean[32]);
49 | gen.flush();
50 | inputB = gen.inputOfBob(Utils.fromInt(new Integer(args[0]), 32));
51 | }
52 |
53 | @Override
54 | public void secureCompute(CompEnv gen) {
55 | scResult = compute(gen, inputA, inputB);
56 | }
57 |
58 | @Override
59 | public void prepareOutput(CompEnv gen) throws BadLabelException {
60 | //gen.outputToAlice(scResult);
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/example/Sort.java:
--------------------------------------------------------------------------------
1 | package example;
2 |
3 | import util.EvaRunnable;
4 | import util.GenRunnable;
5 | import util.Utils;
6 | import circuits.BitonicSortLib;
7 | import flexsc.CompEnv;
8 |
9 | public class Sort {
10 | static public T[][] compute(CompEnv gen, T[][] inputA, T[][] inputB){
11 | T[][] in = gen.newTArray(inputA.length+inputB.length, 0);
12 | System.arraycopy(inputA, 0, in, 0, inputA.length);
13 | System.arraycopy(inputB, 0, in,inputA.length, inputB.length);
14 | BitonicSortLib lib = new BitonicSortLib(gen);
15 | lib.sort(in, lib.SIGNAL_ONE);
16 | return in;
17 | }
18 |
19 | public static class Generator extends GenRunnable {
20 | T[][] inputB;
21 | T[][] inputA;
22 | T[][] in;
23 |
24 | @Override
25 | public void prepareInput(CompEnv gen) {
26 | inputB = gen.newTArray(10, 0);
27 | for(int i = 0; i < 10; ++i)
28 | inputB[i] = gen.inputOfBob(new boolean[32]);
29 | inputA = gen.newTArray(10, 0);
30 | for(int i = 0; i < 10; ++i)
31 | inputA[i] = gen.inputOfAlice(Utils.fromInt(i, 32));
32 | }
33 |
34 | @Override
35 | public void secureCompute(CompEnv gen) {
36 | in = compute(gen, inputA, inputB);
37 | }
38 | @Override
39 | public void prepareOutput(CompEnv gen) {
40 | for(int i = 0; i < 20; ++i)
41 | System.out.println(Utils.toInt(gen.outputToAlice(in[i])));
42 | }
43 | }
44 |
45 | public static class Evaluator extends EvaRunnable {
46 | T[][] inputB;
47 | T[] scResult;
48 | T[][] inputA;
49 | T[][] in;
50 |
51 | @Override
52 | public void prepareInput(CompEnv gen) {
53 | inputB = gen.newTArray(10, 0);
54 | for(int i = 0; i < 10; ++i)
55 | inputB[i] = gen.inputOfBob(Utils.fromInt(i, 32));
56 |
57 | inputA = gen.newTArray(10, 0);
58 | inputA = gen.inputOfAlice(new boolean[10][32]);
59 | }
60 |
61 | @Override
62 | public void secureCompute(CompEnv gen) {
63 | in = compute(gen, inputA, inputB);
64 | }
65 |
66 | @Override
67 | public void prepareOutput(CompEnv gen) {
68 | for(int i = 0; i < 20; ++i)
69 | gen.outputToAlice(in[i]);
70 | }
71 |
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/flexsc/BooleanCompEnv.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2014 by Xiao Shaun Wang
2 | package flexsc;
3 |
4 | import network.Network;
5 |
6 | public abstract class BooleanCompEnv extends CompEnv {
7 | Boolean t = true;
8 | Boolean f = false;
9 | public BooleanCompEnv(Network cha, Party p, Mode m) {
10 | super(cha, p, m);
11 | }
12 |
13 | @Override
14 | public Boolean[] newTArray(int len) {
15 | Boolean[] res = new Boolean[len];
16 | return res;
17 | }
18 |
19 | @Override
20 | public Boolean newT(boolean v) {
21 | return v;
22 | }
23 |
24 | @Override
25 | public Boolean[][] newTArray(int d1, int d2) {
26 | return new Boolean[d1][d2];
27 | }
28 |
29 | @Override
30 | public Boolean[][][] newTArray(int d1, int d2, int d3) {
31 | return new Boolean[d1][d2][d3];
32 | }
33 |
34 | @Override
35 | public Boolean ONE() {
36 | return t;
37 | }
38 |
39 | @Override
40 | public Boolean ZERO() {
41 | return f;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/flexsc/CVCompEnv.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2014 by Xiao Shaun Wang
2 | package flexsc;
3 |
4 | import network.Network;
5 | import util.Utils;
6 |
7 | public class CVCompEnv extends BooleanCompEnv {
8 | public CVCompEnv(Network channel, Party p) {
9 | super(channel, p, Mode.VERIFY);
10 | this.party = p;
11 | }
12 |
13 | @Override
14 | public Boolean inputOfAlice(boolean in) {
15 | Boolean res = null;
16 | res = in;
17 | if (party == Party.Alice)
18 | channel.writeInt(in ? 1 : 0);
19 | else {
20 | int re = channel.readInt();
21 | res = re == 1;
22 | }
23 | channel.flush();
24 | return res;
25 | }
26 |
27 | @Override
28 | public Boolean inputOfBob(boolean in) {
29 | Boolean res = null;
30 | channel.flush();
31 | res = in;
32 | if (party == Party.Bob)
33 | channel.writeInt(in ? 1 : 0);
34 | else {
35 | int re = channel.readInt();
36 | res = re == 1;
37 | }
38 | channel.flush();
39 | return res;
40 | }
41 |
42 | @Override
43 | public boolean outputToAlice(Boolean out) {
44 | return out;
45 | }
46 |
47 | public boolean outputToBob(Boolean out) {
48 | return out;
49 | }
50 |
51 | @Override
52 | public Boolean and(Boolean a, Boolean b) {
53 | ++Flag.sw.ands;++numOfAnds;
54 | return a && b;
55 | }
56 |
57 | @Override
58 | public Boolean xor(Boolean a, Boolean b) {
59 | return a ^ b;
60 | }
61 |
62 | @Override
63 | public Boolean not(Boolean a) {
64 | return !a;
65 | }
66 |
67 | public Boolean[] inputOfAlice(boolean[] in) {
68 | Boolean[] res = new Boolean[in.length];
69 | for (int i = 0; i < res.length; ++i)
70 | res[i] = inputOfAlice(in[i]);
71 | return res;
72 | }
73 |
74 | @Override
75 | public Boolean[] inputOfBob(boolean[] in) {
76 | Boolean[] res = new Boolean[in.length];
77 | for (int i = 0; i < res.length; ++i)
78 | res[i] = inputOfBob(in[i]);
79 | return res;
80 | }
81 |
82 | @Override
83 | public boolean[] outputToAlice(Boolean[] out) {
84 | return Utils.tobooleanArray(out);
85 | }
86 |
87 | @Override
88 | public boolean[] outputToBob(Boolean[] out) {
89 | return Utils.tobooleanArray(out);
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/flexsc/CircuitWire.java:
--------------------------------------------------------------------------------
1 | package flexsc;
2 |
3 | public class CircuitWire {
4 |
5 | public static int wid = 0;
6 | public boolean v;
7 | public int wireId;
8 |
9 | public CircuitWire(boolean b, int wireId) {
10 | this.v = b;
11 | this.wireId = wireId;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/flexsc/ClearCircuitCompEnv.java:
--------------------------------------------------------------------------------
1 | package flexsc;
2 |
3 | import network.Network;
4 |
5 | public class ClearCircuitCompEnv extends CompEnv {
6 |
7 | public ClearCircuitCompEnv(Network w, Party p) {
8 | super(w, p, Mode.CIRCUIT);
9 | }
10 |
11 | @Override
12 | public CircuitWire inputOfAlice(boolean in) {
13 | Boolean res = in;
14 | if (party == Party.Alice)
15 | channel.writeInt(in ? 1 : 0);
16 | else {
17 | int re = channel.readInt();
18 | res = re == 1;
19 | }
20 | channel.flush();
21 | return new CircuitWire(res, CircuitWire.wid++);
22 | }
23 |
24 | @Override
25 | public CircuitWire inputOfBob(boolean in) {
26 | Boolean res = null;
27 | channel.flush();
28 | res = in;
29 | if (party == Party.Bob)
30 | channel.writeInt(in ? 1 : 0);
31 | else {
32 | int re = channel.readInt();
33 | res = re == 1;
34 | }
35 | channel.flush();
36 | return new CircuitWire(res, CircuitWire.wid++);
37 | }
38 |
39 | @Override
40 | public boolean outputToAlice(CircuitWire out) {
41 | if (party == Party.Alice)
42 | System.out.println("OUT = " + out.wireId + " VALUE = " + out.v);
43 | return false;
44 | }
45 |
46 | @Override
47 | public boolean outputToBob(CircuitWire out) {
48 | if (party == Party.Alice)
49 | System.out.println("OUT = " + out.wireId + " VALUE = " + out.v);
50 | return false;
51 | }
52 |
53 | @Override
54 | public CircuitWire[] inputOfAlice(boolean[] in) {
55 | CircuitWire[] signal = new CircuitWire[in.length];
56 | for (int i = 0; i < in.length; i++)
57 | signal[i] = inputOfAlice(in[i]);
58 | return signal;
59 | }
60 |
61 | @Override
62 | public CircuitWire[] inputOfBob(boolean[] in) {
63 | CircuitWire[] signal = new CircuitWire[in.length];
64 | for (int i = 0; i < in.length; i++)
65 | signal[i] = inputOfBob(in[i]);
66 | return signal;
67 | }
68 |
69 | @Override
70 | public boolean[] outputToAlice(CircuitWire[] out) {
71 | for (int i = 0; i < out.length; i++)
72 | System.out.println("OUT = " + out[i].wireId + " VALUE = " + out[i].v);
73 | return null;
74 | }
75 |
76 | @Override
77 | public boolean[] outputToBob(CircuitWire[] out) {
78 | for (int i = 0; i < out.length; i++)
79 | System.out.println("OUT = " + out[i].wireId + " VALUE = " + out[i].v);
80 | return null;
81 | }
82 |
83 | @Override
84 | public CircuitWire and(CircuitWire a, CircuitWire b) {
85 | int id = CircuitWire.wid++;
86 | if (party == Party.Alice)
87 | System.out.println(a.wireId + " AND " + b.wireId + " = " + id);
88 | return new CircuitWire(a.v & b.v, id);
89 | }
90 |
91 | @Override
92 | public CircuitWire xor(CircuitWire a, CircuitWire b) {
93 | int id = CircuitWire.wid++;
94 | if (party == Party.Alice)
95 | System.out.println(a.wireId + " XOR " + b.wireId + " = " + id);
96 | return new CircuitWire(a.v ^ b.v, id);
97 | }
98 |
99 | @Override
100 | public CircuitWire not(CircuitWire a) {
101 | int id = CircuitWire.wid++;
102 | if (party == Party.Alice)
103 | System.out.println("NOT " + a.wireId + " = " + id);
104 | return new CircuitWire(!a.v, id);
105 | }
106 |
107 | @Override
108 | public CircuitWire ONE() {
109 | return new CircuitWire(true, CircuitWire.wid++);
110 | }
111 |
112 | @Override
113 | public CircuitWire ZERO() {
114 | return new CircuitWire(false, CircuitWire.wid++);
115 | }
116 |
117 | @Override
118 | public CircuitWire[] newTArray(int len) {
119 | return new CircuitWire[len];
120 | }
121 |
122 | @Override
123 | public CircuitWire[][] newTArray(int d1, int d2) {
124 | return new CircuitWire[d1][d2];
125 | }
126 |
127 | @Override
128 | public CircuitWire[][][] newTArray(int d1, int d2, int d3) {
129 | return new CircuitWire[d1][d2][d3];
130 | }
131 |
132 | @Override
133 | public CircuitWire newT(boolean v) {
134 | return new CircuitWire(v, CircuitWire.wid++);
135 | }
136 |
137 | }
138 |
--------------------------------------------------------------------------------
/src/flexsc/CompEnv.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2014 by Xiao Shaun Wang
2 | package flexsc;
3 |
4 | import java.security.NoSuchAlgorithmException;
5 | import java.security.SecureRandom;
6 | import java.security.Security;
7 |
8 | import network.Network;
9 | import rand.ISAACProvider;
10 | import util.Utils;
11 |
12 | public abstract class CompEnv {
13 | public long numOfAnds = 0;
14 | public static SecureRandom rnd;
15 | static{
16 | Security.addProvider(new ISAACProvider());
17 | try {
18 | rnd = SecureRandom.getInstance("ISAACRandom");
19 |
20 | } catch (NoSuchAlgorithmException e) {
21 | e.printStackTrace();
22 | }
23 | }
24 |
25 | @SuppressWarnings("rawtypes")
26 | public static CompEnv getEnv(Mode mode, Party p, Network w) {
27 | if (mode == Mode.REAL)
28 | if (p == Party.Bob)
29 | return new gc.regular.GCEva(w);
30 | else
31 | return new gc.regular.GCGen(w);
32 | else if (mode == Mode.OPT)
33 | if (p == Party.Bob)
34 | return new gc.halfANDs.GCEva(w);
35 | else
36 | return new gc.halfANDs.GCGen(w);
37 | else if (mode == Mode.VERIFY)
38 | return new CVCompEnv(w, p);
39 | else if (mode == Mode.COUNT)
40 | return new PMCompEnv(w, p);
41 | else if (mode == Mode.OFFLINE) {
42 | if (p == Party.Bob)
43 | return new gc.offline.GCEva(w);
44 | else
45 | return new gc.offline.GCGen(w);
46 | } else if (mode == Mode.CIRCUIT) {
47 | return new ClearCircuitCompEnv(w, p);
48 | } else {
49 | try {
50 | throw new Exception("not a supported Mode!");
51 | } catch (Exception e) {
52 | // TODO Auto-generated catch block
53 | e.printStackTrace();
54 | }
55 | return null;
56 | }
57 | }
58 |
59 | public Network channel;
60 | public Party party;
61 | public Mode mode;
62 |
63 | public CompEnv(Network w, Party p, Mode m) {
64 | this.channel = w;
65 | this.mode = m;
66 | this.party = p;
67 | }
68 |
69 | public abstract T inputOfAlice(boolean in);
70 |
71 | public abstract T inputOfBob(boolean in);
72 |
73 | public abstract boolean outputToAlice(T out);
74 |
75 | public abstract boolean outputToBob(T out);
76 |
77 | public abstract T[] inputOfAlice(boolean[] in);
78 |
79 | public abstract T[] inputOfBob(boolean[] in);
80 |
81 | public T[][] inputOfAlice(boolean[][] in) {
82 | boolean[] flattened = Utils.flatten(in);
83 | T[] res = inputOfAlice(flattened);
84 | T[][] unflattened = newTArray(in.length, in[0].length);
85 | Utils.unflatten(res, unflattened);
86 | return unflattened;
87 | }
88 |
89 | public T[][] inputOfBob(boolean[][] in) {
90 | boolean[] flattened = Utils.flatten(in);
91 | T[] res = inputOfBob(flattened);
92 | T[][] unflattened = newTArray(in.length, in[0].length);
93 | Utils.unflatten(res, unflattened);
94 | return unflattened;
95 | }
96 |
97 | public T[][][] inputOfAlice(boolean[][][] in) {
98 | boolean[] flattened = Utils.flatten(in);
99 | T[] res = inputOfAlice(flattened);
100 | T[][][] unflattened = newTArray(in.length, in[0].length, in[0][0].length);
101 | Utils.unflatten(res, unflattened);
102 | return unflattened;
103 | }
104 |
105 | public T[][][] inputOfBob(boolean[][][] in) {
106 | boolean[] flattened = Utils.flatten(in);
107 | T[] res = inputOfBob(flattened);
108 | T[][][] unflattened = newTArray(in.length, in[0].length, in[0][0].length);
109 | Utils.unflatten(res, unflattened);
110 | return unflattened;
111 | }
112 |
113 |
114 | public abstract boolean[] outputToAlice(T[] out);
115 |
116 | public abstract boolean[] outputToBob(T[] out);
117 |
118 | public abstract T and(T a, T b);
119 |
120 | public abstract T xor(T a, T b);
121 |
122 | public abstract T not(T a);
123 |
124 | public abstract T ONE();
125 |
126 | public abstract T ZERO();
127 |
128 | public abstract T[] newTArray(int len);
129 |
130 | public abstract T[][] newTArray(int d1, int d2);
131 |
132 | public abstract T[][][] newTArray(int d1, int d2, int d3);
133 |
134 | public abstract T newT(boolean v);
135 |
136 | public Party getParty() {
137 | return party;
138 | }
139 |
140 | public void flush() {
141 | channel.flush();
142 | }
143 |
144 | public Mode getMode() {
145 | return mode;
146 | }
147 | }
--------------------------------------------------------------------------------
/src/flexsc/Comparator.java:
--------------------------------------------------------------------------------
1 | package flexsc;
2 |
3 |
4 | public interface Comparator {
5 | public abstract T compare(T[] a, T[] b) throws Exception;
6 | }
7 |
--------------------------------------------------------------------------------
/src/flexsc/Flag.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2013 by Yan Huang
2 | // and Xiao Shaun Wang
3 |
4 | package flexsc;
5 |
6 | import util.StopWatch;
7 |
8 | public class Flag {
9 | public static boolean CountTime = false;
10 | public static StopWatch sw = new StopWatch(CountTime);
11 | public static boolean countIO = false;
12 | public static boolean FakeOT = false;
13 | public static boolean ProprocessOT = false;
14 | public static int OTBlockSize = 1024*64;
15 | public static boolean offline = true;
16 | public static String tableName = "table";
17 | }
--------------------------------------------------------------------------------
/src/flexsc/IWritable.java:
--------------------------------------------------------------------------------
1 | package flexsc;
2 |
3 | // for compiler generated code
4 | public interface IWritable, T2> {
5 | public int numBits();
6 |
7 | public T2[] getBits();
8 |
9 | public T1 newObj(T2[] data) throws Exception;
10 |
11 | default T1 fake() throws Exception {
12 | return newObj(getBits());
13 | };
14 |
15 | default T1 muxFake(T2 dummy) throws Exception {
16 | return fake();
17 | }
18 |
19 | }
--------------------------------------------------------------------------------
/src/flexsc/Mode.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2013 by Yan Huang
2 | // and Xiao Shaun Wang
3 |
4 | package flexsc;
5 |
6 | public enum Mode {
7 | // verify the correctness of the circuit without running the protocol
8 | VERIFY,
9 | //GRR3 + Free XOR
10 | REAL,
11 | //Simulating the protocol and count number of gates/encs
12 | COUNT,
13 | //Half Gates
14 | OPT,
15 | //Offline
16 | OFFLINE,
17 | // Generate Clear Circuit
18 | CIRCUIT;
19 |
20 | public static Mode getMode(String optionValue) {
21 | if(optionValue.equals("VERIFY")) {
22 | return VERIFY;
23 | } else if(optionValue.equals("REAL")) {
24 | return REAL;
25 | } else if(optionValue.equals("COUNT")) {
26 | return COUNT;
27 | } else if(optionValue.equals("OPT")) {
28 | return OPT;
29 | } else if(optionValue.equals("OFFLINE")) {
30 | return OPT;
31 | } else if (optionValue.equals("CIRCUIT")) {
32 | return CIRCUIT;
33 | } else return null;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/flexsc/PMCompEnv.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2014 by Xiao Shaun Wang
2 | package flexsc;
3 |
4 | import network.Network;
5 | import util.Utils;
6 |
7 | /*
8 | * The computational environment for performance measurement.
9 | */
10 | public class PMCompEnv extends BooleanCompEnv {
11 | public static class Statistics {
12 | public long andGate = 0;
13 | public long xorGate = 0;
14 | public long notGate = 0;
15 | public long OTs = 0;
16 | public long NumEncAlice = 0;
17 | public long NumEncBob = 0;
18 | public long bandwidth = 0;
19 |
20 | public void flush() {
21 | bandwidth = 0;
22 | andGate = 0;
23 | xorGate = 0;
24 | notGate = 0;
25 | OTs = 0;
26 | NumEncAlice = 0;
27 | NumEncBob = 0;
28 | }
29 |
30 | public void add(Statistics s2) {
31 | andGate += s2.andGate;
32 | xorGate += s2.xorGate;
33 | notGate += s2.notGate;
34 | OTs += s2.OTs;
35 | NumEncAlice += s2.NumEncAlice;
36 | NumEncBob += s2.NumEncBob;
37 | bandwidth += s2.bandwidth;
38 | }
39 |
40 | public void finalize() {
41 | NumEncAlice = andGate * 4 + OTs * 2;
42 | NumEncBob = andGate * 1 + OTs * 1;
43 | }
44 |
45 | public Statistics newInstance() {
46 | Statistics s = new Statistics();
47 | s.andGate = andGate;
48 | s.xorGate = xorGate;
49 | s.notGate = notGate;
50 | s.OTs = OTs;
51 | s.NumEncAlice = NumEncAlice;
52 | s.NumEncBob = NumEncBob;
53 | s.bandwidth = bandwidth;
54 | return s;
55 | }
56 | }
57 |
58 | public Statistics statistic;
59 |
60 |
61 | public PMCompEnv(Network channel, Party p) {
62 | super(channel, p, Mode.COUNT);
63 | this.party = p;
64 | t = true;
65 | f = false;
66 | statistic = new Statistics();
67 | }
68 |
69 | @Override
70 | public Boolean inputOfAlice(boolean in) {
71 | return f;
72 | }
73 |
74 | @Override
75 | public Boolean inputOfBob(boolean in) {
76 | ++statistic.OTs;
77 | statistic.bandwidth += 10;
78 | return f;
79 | }
80 |
81 | @Override
82 | public boolean outputToAlice(Boolean out) {
83 | statistic.bandwidth += 10;
84 | return false;
85 | }
86 |
87 | @Override
88 | public boolean outputToBob(Boolean out) {
89 | statistic.bandwidth += 10;
90 | return false;
91 | }
92 |
93 | @Override
94 | public Boolean and(Boolean a, Boolean b) {
95 | ++statistic.andGate;
96 | statistic.bandwidth += 3 * 10;
97 | return f;
98 | }
99 |
100 | @Override
101 | public Boolean xor(Boolean a, Boolean b) {
102 | ++statistic.xorGate;
103 | return f;
104 | }
105 |
106 | @Override
107 | public Boolean not(Boolean a) {
108 | ++statistic.notGate;
109 | return f;
110 | }
111 |
112 | @Override
113 | public boolean[] outputToAlice(Boolean[] out) {
114 | statistic.bandwidth += 10 * out.length;
115 | return Utils.tobooleanArray(out);
116 | }
117 |
118 | @Override
119 | public boolean[] outputToBob(Boolean[] out) {
120 | statistic.bandwidth += 10 * out.length;
121 | return Utils.tobooleanArray(out);
122 | }
123 |
124 | @Override
125 | public Boolean[] inputOfAlice(boolean[] in) {
126 | statistic.bandwidth += 10*in.length;
127 | return Utils.toBooleanArray(in);
128 | }
129 |
130 | @Override
131 | public Boolean[] inputOfBob(boolean[] in) {
132 | statistic.OTs += in.length;
133 | statistic.bandwidth += 10 * 2 * (80 + in.length);
134 | return Utils.toBooleanArray(in);
135 | }
136 | }
--------------------------------------------------------------------------------
/src/flexsc/Party.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2013 by Yan Huang
2 | // and Xiao Shaun Wang
3 |
4 | package flexsc;
5 |
6 | public enum Party {
7 | Alice, Bob;
8 | }
9 |
--------------------------------------------------------------------------------
/src/gc/BadLabelException.java:
--------------------------------------------------------------------------------
1 | package gc;
2 |
3 | public class BadLabelException extends Exception {
4 |
5 | private static final long serialVersionUID = 1L;
6 |
7 | public BadLabelException(String message) {
8 | super(message);
9 | }
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/src/gc/DbgUtils.java:
--------------------------------------------------------------------------------
1 | package gc;
2 |
3 | import flexsc.CompEnv;
4 | import gc.regular.GCEva;
5 | import gc.regular.GCGen;
6 |
7 | public class DbgUtils {
8 |
9 | static void debugMsg(CompEnv env, String msg) {
10 | if (env instanceof GCEva)
11 | System.err.println(msg);
12 | }
13 |
14 | static void debugVal(CompEnv env, GCSignal bs, String msg)
15 | throws Exception {
16 | if (env instanceof GCGen) {
17 | bs.send(((GCGen) env).channel);
18 | GCGen.R.send(((GCGen) env).channel);
19 | } else {
20 | int x;
21 | GCSignal glb = GCSignal.receive(((GCEva) env).channel);
22 | GCSignal R = GCSignal.receive(((GCEva) env).channel);
23 | if (bs.equals(glb))
24 | x = 0;
25 | else if (bs.equals(R.xor(glb)))
26 | x = 1;
27 | else
28 | throw new Exception(String.format("bad label: %s",
29 | bs.toHexStr()));
30 | System.out.println(String.format("%s = %d", msg, x));
31 |
32 | }
33 | }
34 |
35 | static void debugLabel(CompEnv env, GCSignal bs, String msg) {
36 | if (env instanceof GCGen) {
37 | System.err.println(String.format("[%s] %s, %s", msg, bs.toHexStr(), GCGen.R.xor(bs).toHexStr()));
38 | } else
39 | System.out.println(String.format("[%s] %s", msg, bs.toHexStr()));
40 | }
41 | }
--------------------------------------------------------------------------------
/src/gc/GCCompEnv.java:
--------------------------------------------------------------------------------
1 | package gc;
2 |
3 | import network.Network;
4 | import flexsc.CompEnv;
5 | import flexsc.Mode;
6 | import flexsc.Party;
7 |
8 | public abstract class GCCompEnv extends CompEnv {
9 | public GCCompEnv(Network channel, Party p, Mode mode) {
10 | super(channel, p, mode);
11 | }
12 |
13 | public GCSignal ONE() {
14 | return new GCSignal(true);
15 | }
16 |
17 | public GCSignal ZERO() {
18 | return new GCSignal(false);
19 | }
20 |
21 | public GCSignal[] newTArray(int len) {
22 | return new GCSignal[len];
23 | }
24 |
25 | public GCSignal[][] newTArray(int d1, int d2) {
26 | return new GCSignal[d1][d2];
27 | }
28 |
29 | public GCSignal[][][] newTArray(int d1, int d2, int d3) {
30 | return new GCSignal[d1][d2][d3];
31 | }
32 |
33 | public GCSignal newT(boolean v) {
34 | return new GCSignal(v);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/gc/GCEvaComp.java:
--------------------------------------------------------------------------------
1 | package gc;
2 |
3 | import java.io.IOException;
4 | import java.util.Arrays;
5 |
6 | import network.Network;
7 | import ot.FakeOTReceiver;
8 | import ot.OTExtReceiver;
9 | import ot.OTPreprocessReceiver;
10 | import ot.OTReceiver;
11 | import flexsc.Flag;
12 | import flexsc.Mode;
13 | import flexsc.Party;
14 |
15 | public abstract class GCEvaComp extends GCCompEnv{
16 |
17 | OTReceiver rcv;
18 |
19 | protected long gid = 0;
20 |
21 | public GCEvaComp(Network channel, Mode mode) {
22 | super(channel, Party.Bob, mode);
23 |
24 | if (Flag.FakeOT)
25 | rcv = new FakeOTReceiver(channel);
26 | else if (Flag.ProprocessOT)
27 | rcv = new OTPreprocessReceiver(channel);
28 | else
29 | rcv = new OTExtReceiver(channel);
30 |
31 | }
32 |
33 | public GCSignal inputOfAlice(boolean in) {
34 | Flag.sw.startOT();
35 | GCSignal signal = GCSignal.receive(channel);
36 | Flag.sw.stopOT();
37 | return signal;
38 | }
39 |
40 | public GCSignal inputOfBob(boolean in) {
41 | Flag.sw.startOT();
42 | GCSignal signal = null;
43 | try {
44 | signal = rcv.receive(in);
45 | } catch (IOException e) {
46 | e.printStackTrace();
47 | }
48 | Flag.sw.stopOT();
49 | return signal;
50 | }
51 |
52 | public GCSignal[] inputOfBob(boolean[] x) {
53 | GCSignal[] ret = new GCSignal[x.length];
54 | for(int i = 0; i < x.length; i+=Flag.OTBlockSize) {
55 | GCSignal[] tmp = inputOfBobInter(Arrays.copyOfRange(x, i, Math.min(i+Flag.OTBlockSize, x.length)));
56 | System.arraycopy(tmp, 0, ret, i, tmp.length);
57 | }
58 | return ret;
59 | }
60 |
61 | public GCSignal[] inputOfBobInter(boolean[] x) {
62 | Flag.sw.startOT();
63 | GCSignal[] signal = null;
64 | try {
65 | signal = rcv.receive(x);
66 | } catch (IOException e) {
67 | e.printStackTrace();
68 | }
69 | Flag.sw.stopOT();
70 | return signal;
71 | }
72 |
73 | public GCSignal[] inputOfAlice(boolean[] x) {
74 | Flag.sw.startOT();
75 | GCSignal[] result = new GCSignal[x.length];
76 | for (int i = 0; i < x.length; ++i)
77 | result[i] = GCSignal.receive(channel);
78 | Flag.sw.stopOT();
79 | return result;
80 | }
81 |
82 | public boolean outputToAlice(GCSignal out) {
83 | if (!out.isPublic())
84 | out.send(channel);
85 | return false;
86 | }
87 |
88 | public boolean outputToBob(GCSignal out) {
89 | if (out.isPublic())
90 | return out.v;
91 |
92 | GCSignal lb = GCSignal.receive(channel);
93 | if (lb.equals(out))
94 | return false;
95 | else
96 | return true;
97 | }
98 |
99 | public boolean[] outputToAlice(GCSignal[] out) {
100 | boolean[] result = new boolean[out.length];
101 | for (int i = 0; i < result.length; ++i) {
102 | if (!out[i].isPublic())
103 | out[i].send(channel);
104 | }
105 |
106 | channel.flush();
107 |
108 | for (int i = 0; i < result.length; ++i)
109 | result[i] = false;
110 | return result;
111 | }
112 |
113 | public boolean[] outputToBob(GCSignal[] out) {
114 | boolean[] result = new boolean[out.length];
115 | for (int i = 0; i < result.length; ++i) {
116 | result[i] = outputToBob(out[i]);
117 | }
118 | return result;
119 | }
120 |
121 | public GCSignal xor(GCSignal a, GCSignal b) {
122 | if (a.isPublic() && b.isPublic())
123 | return ((a.v ^ b.v) ? new GCSignal(true):new GCSignal(false));
124 | else if (a.isPublic())
125 | return a.v ? not(b) : b;
126 | else if (b.isPublic())
127 | return b.v ? not(a) : a;
128 | else
129 | return a.xor(b);
130 | }
131 |
132 | public GCSignal not(GCSignal a) {
133 | if (a.isPublic())
134 | return ((!a.v) ?new GCSignal(true):new GCSignal(false));
135 | else {
136 | return a;
137 | }
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/src/gc/GCGenComp.java:
--------------------------------------------------------------------------------
1 | package gc;
2 |
3 | import java.io.IOException;
4 | import java.util.Arrays;
5 |
6 | import network.Network;
7 | import ot.FakeOTSender;
8 | import ot.OTExtSender;
9 | import ot.OTPreprocessSender;
10 | import ot.OTSender;
11 | import flexsc.CompEnv;
12 | import flexsc.Flag;
13 | import flexsc.Mode;
14 | import flexsc.Party;
15 |
16 | public abstract class GCGenComp extends GCCompEnv {
17 |
18 | static public GCSignal R = null;
19 | static {
20 | R = GCSignal.freshLabel(CompEnv.rnd);
21 | R.setLSB();
22 | }
23 |
24 | OTSender snd;
25 | protected long gid = 0;
26 |
27 | public GCGenComp(Network channel, Mode mode) {
28 | super(channel, Party.Alice, mode);
29 |
30 | if (Flag.FakeOT)
31 | snd = new FakeOTSender(80, channel);
32 | else if(Flag.ProprocessOT)
33 | snd = new OTPreprocessSender(80, channel);
34 | else
35 | snd = new OTExtSender(80, channel);
36 | }
37 |
38 | public static GCSignal[] genPairForLabel(Mode mode) {
39 | GCSignal[] label = new GCSignal[2];
40 | if(mode != Mode.OFFLINE || !Flag.offline)
41 | label[0] = GCSignal.freshLabel(rnd);
42 | if(mode == Mode.OFFLINE) {
43 | if(Flag.offline) {
44 | label[0] = new GCSignal(gc.offline.GCGen.fread.read(10));
45 | }
46 | else
47 | label[0].send(gc.offline.GCGen.fout);
48 | }
49 | label[1] = R.xor(label[0]);
50 | return label;
51 | }
52 |
53 | public static GCSignal[] genPair() {
54 | GCSignal[] label = new GCSignal[2];
55 | label[0] = GCSignal.freshLabel(rnd);
56 | label[1] = R.xor(label[0]);
57 | return label;
58 | }
59 |
60 | public GCSignal inputOfAlice(boolean in) {
61 | Flag.sw.startOT();
62 | GCSignal[] label = genPairForLabel(mode);
63 | Flag.sw.startOTIO();
64 | label[in ? 1 : 0].send(channel);
65 | flush();
66 | Flag.sw.stopOTIO();
67 | Flag.sw.stopOT();
68 | return label[0];
69 | }
70 |
71 | public GCSignal inputOfBob(boolean in) {
72 | Flag.sw.startOT();
73 | GCSignal[] label = genPairForLabel(mode);
74 | try {
75 | snd.send(label);
76 | } catch (IOException e) {
77 | e.printStackTrace();
78 | }
79 | Flag.sw.stopOT();
80 | return label[0];
81 | }
82 |
83 | public GCSignal[] inputOfAlice(boolean[] x) {
84 | Flag.sw.startOT();
85 | GCSignal[][] pairs = new GCSignal[x.length][2];
86 | GCSignal[] result = new GCSignal[x.length];
87 | for (int i = 0; i < x.length; ++i) {
88 | pairs[i] = genPairForLabel(mode);
89 | result[i] = pairs[i][0];
90 | }
91 | Flag.sw.startOTIO();
92 | for (int i = 0; i < x.length; ++i)
93 | pairs[i][x[i] ? 1 : 0].send(channel);
94 | flush();
95 | Flag.sw.stopOTIO();
96 | Flag.sw.stopOT();
97 | return result;
98 | }
99 |
100 | public GCSignal[] inputOfBob(boolean[] x) {
101 | GCSignal[] ret = new GCSignal[x.length];
102 | for(int i = 0; i < x.length; i+=Flag.OTBlockSize) {
103 | GCSignal[] tmp = inputOfBobInter(Arrays.copyOfRange(x, i, Math.min(i+Flag.OTBlockSize, x.length)));
104 | System.arraycopy(tmp, 0, ret, i, tmp.length);
105 | }
106 | return ret;
107 | }
108 | public GCSignal[] inputOfBobInter(boolean[] x) {
109 | Flag.sw.startOT();
110 | GCSignal[][] pair = new GCSignal[x.length][2];
111 | for (int i = 0; i < x.length; ++i)
112 | pair[i] = genPairForLabel(mode);
113 | try {
114 | snd.send(pair);
115 | } catch (IOException e) {
116 | // TODO Auto-generated catch block
117 | e.printStackTrace();
118 | }
119 | GCSignal[] result = new GCSignal[x.length];
120 | for (int i = 0; i < x.length; ++i)
121 | result[i] = pair[i][0];
122 | Flag.sw.stopOT();
123 | return result;
124 | }
125 |
126 | protected boolean gatesRemain = false;
127 |
128 | public boolean outputToAlice(GCSignal out) {
129 |
130 | if (gatesRemain) {
131 | gatesRemain = false;
132 | flush();
133 | }
134 |
135 | if (out.isPublic())
136 | return out.v;
137 |
138 | GCSignal lb = GCSignal.receive(channel);
139 |
140 | if (lb.equals(out))
141 | return false;
142 | else if (lb.equals(R.xor(out)))
143 | return true;
144 |
145 | try {
146 | throw new Exception("bad label at final output.");
147 | } catch (Exception e) {
148 | // TODO Auto-generated catch block
149 | e.printStackTrace();
150 | }
151 | return false;
152 | }
153 |
154 | public boolean outputToBob(GCSignal out) {
155 | if (!out.isPublic())
156 | out.send(channel);
157 | return false;
158 | }
159 |
160 | public boolean[] outputToBob(GCSignal[] out) {
161 | boolean[] result = new boolean[out.length];
162 |
163 | for (int i = 0; i < result.length; ++i) {
164 | if (!out[i].isPublic())
165 | out[i].send(channel);
166 | }
167 | flush();
168 |
169 | for (int i = 0; i < result.length; ++i)
170 | result[i] = false;
171 | return result;
172 | }
173 |
174 | public boolean[] outputToAlice(GCSignal[] out) {
175 | boolean[] result = new boolean[out.length];
176 | for (int i = 0; i < result.length; ++i) {
177 | result[i] = outputToAlice(out[i]);
178 | }
179 | return result;
180 | }
181 |
182 |
183 | public GCSignal xor(GCSignal a, GCSignal b) {
184 | if (a.isPublic() && b.isPublic())
185 | return new GCSignal(a.v ^ b.v);
186 | else if (a.isPublic())
187 | return a.v ? not(b) : new GCSignal(b);
188 | else if (b.isPublic())
189 | return b.v ? not(a) : new GCSignal(a);
190 | else {
191 | return a.xor(b);
192 | }
193 | }
194 |
195 | public GCSignal not(GCSignal a) {
196 | if (a.isPublic())
197 | return new GCSignal(!a.v);
198 | else
199 | return R.xor(a);
200 | }
201 | }
--------------------------------------------------------------------------------
/src/gc/GCSignal.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2013 by Yan Huang
2 | // Improved by Xiao Shaun Wang and Kartik Nayak
3 |
4 | package gc;
5 |
6 | import java.io.IOException;
7 | import java.io.OutputStream;
8 | import java.security.SecureRandom;
9 | import java.util.Arrays;
10 |
11 | import network.Network;
12 |
13 | public class GCSignal {
14 | public static final int len = 10;
15 | public byte[] bytes;
16 | public boolean v;
17 |
18 | public static final GCSignal ZERO = new GCSignal(new byte[len]);
19 |
20 | public GCSignal(byte[] b) {
21 | bytes = b;
22 | }
23 |
24 | public GCSignal(boolean b) {
25 | v = b;
26 | }
27 |
28 | public static GCSignal freshLabel(SecureRandom rnd) {
29 | byte[] b = new byte[len];
30 | rnd.nextBytes(b);
31 | return new GCSignal(b);
32 | }
33 |
34 | public static GCSignal newInstance(byte[] bs) {
35 | assert (bs.length <= len) : "Losing entropy when constructing signals.";
36 | byte[] b = new byte[len];
37 | Arrays.fill(b, (byte) ((bs[0] < 0) ? 0xff : 0));
38 | int newlen = len < bs.length ? len : bs.length;
39 | System.arraycopy(bs, 0, b, len - newlen, newlen);
40 | return new GCSignal(b);
41 | }
42 |
43 | public GCSignal(GCSignal lb) {
44 | v = lb.v;
45 | bytes = (lb.bytes == null) ? null : Arrays.copyOf(lb.bytes, len);
46 | }
47 |
48 | public boolean isPublic() {
49 | return bytes == null;
50 | }
51 |
52 | public GCSignal xor(GCSignal lb) {
53 | byte[] nb = new byte[len];
54 | for (int i = 0; i < len; i++)
55 | nb[i] = (byte) (bytes[i] ^ lb.bytes[i]);
56 | return new GCSignal(nb);
57 | }
58 |
59 | public static void xor(GCSignal l, GCSignal r, GCSignal ret) {
60 | for (int i = 0; i < len; i++)
61 | ret.bytes[i] = (byte) (l.bytes[i] ^ r.bytes[i]);
62 | }
63 |
64 |
65 | public void setLSB() {
66 | bytes[0] |= 1;
67 | }
68 |
69 | public int getLSB() {
70 | return (bytes[0] & 1);
71 | }
72 |
73 | // 'send' and 'receive' are supposed to be used only for secret signals
74 | public void send(Network channel) {
75 | channel.writeByte(bytes, len);
76 | }
77 |
78 | // 'send' and 'receive' are supposed to be used only for secret signals
79 | public void send(OutputStream os) {
80 | try {
81 | os.write(bytes);
82 | } catch (IOException e) {
83 | // TODO Auto-generated catch block
84 | e.printStackTrace();
85 | }
86 | }
87 |
88 | // 'send' and 'receive' are supposed to be used only for secret signals
89 | public static GCSignal receive(Network channel) {
90 | byte[] b = channel.readBytes(len);
91 | return new GCSignal(b);
92 | }
93 |
94 | public static void receive(Network channel, GCSignal s) {
95 | if(s.bytes == null)
96 | s.bytes = new byte[len];
97 | channel.readBytes(s.bytes);
98 | }
99 |
100 |
101 | @Override
102 | public boolean equals(Object lb) {
103 | if (this == lb)
104 | return true;
105 | else if (lb instanceof GCSignal)
106 | return Arrays.equals(bytes, ((GCSignal) lb).bytes);
107 | else
108 | return false;
109 | }
110 |
111 | public String toHexStr() {
112 | StringBuilder str = new StringBuilder();
113 | for (byte b : bytes)
114 | str.append(Integer.toHexString(b & 0xff));
115 | return str.toString();
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/src/gc/halfANDs/GCEva.java:
--------------------------------------------------------------------------------
1 | package gc.halfANDs;
2 |
3 | import flexsc.Flag;
4 | import flexsc.Mode;
5 | import gc.GCEvaComp;
6 | import gc.GCSignal;
7 | import network.Network;
8 |
9 | public class GCEva extends GCEvaComp {
10 | Garbler gb;
11 |
12 | public GCEva(Network channel) {
13 | super(channel, Mode.OPT);
14 | gb = new Garbler();
15 | }
16 |
17 | public GCSignal and(GCSignal a, GCSignal b) {
18 | Flag.sw.startGC();
19 | GCSignal res;
20 | if (a.isPublic() && b.isPublic())
21 | res = ((a.v && b.v)? new GCSignal(true): new GCSignal(false));
22 | else if (a.isPublic())
23 | res = a.v ? b : new GCSignal(false);
24 | else if (b.isPublic())
25 | res = b.v ? a : new GCSignal(false);
26 | else {
27 | ++numOfAnds;
28 | int i0 = a.getLSB();
29 | int i1 = b.getLSB();
30 |
31 | GCSignal TG = GCSignal.ZERO, WG, TE = GCSignal.ZERO, WE;
32 | try {
33 | Flag.sw.startGCIO();
34 | TG = GCSignal.receive(channel);
35 | TE = GCSignal.receive(channel);
36 | Flag.sw.stopGCIO();
37 | } catch (Exception e) {
38 | e.printStackTrace();
39 | System.exit(1);
40 | }
41 |
42 | WG = gb.hash(a, gid, false).xor((i0 == 1) ? TG : GCSignal.ZERO);
43 | WE = gb.hash(b, gid, true).xor((i1 == 1) ? (TE.xor(a)) : GCSignal.ZERO);
44 |
45 | res = WG.xor(WE);
46 |
47 | gid++;
48 | }
49 | Flag.sw.stopGC();
50 | return res;
51 | }
52 | }
--------------------------------------------------------------------------------
/src/gc/halfANDs/GCGen.java:
--------------------------------------------------------------------------------
1 | package gc.halfANDs;
2 |
3 | import flexsc.Flag;
4 | import flexsc.Mode;
5 | import gc.GCGenComp;
6 | import gc.GCSignal;
7 | import network.Network;
8 |
9 | public class GCGen extends GCGenComp {
10 | Garbler gb;
11 |
12 | public GCGen(Network channel){
13 | super(channel, Mode.OPT);
14 | gb = new Garbler();
15 | labelL[0] = new GCSignal(new byte[10]);
16 | labelL[1] = new GCSignal(new byte[10]);
17 | labelR[0] = new GCSignal(new byte[10]);
18 | labelR[1] = new GCSignal(new byte[10]);
19 | TG = new GCSignal(new byte[10]);
20 | WG = new GCSignal(new byte[10]);
21 | TE = new GCSignal(new byte[10]);
22 | WE = new GCSignal(new byte[10]);
23 | G1 = new GCSignal(new byte[10]);
24 | TMP = new GCSignal(new byte[10]);
25 | }
26 |
27 | private GCSignal labelL[] = new GCSignal[2];
28 | private GCSignal labelR[] = new GCSignal[2];
29 |
30 | private GCSignal TG, WG, TE, WE, G1, TMP;
31 |
32 | private GCSignal garble(GCSignal a, GCSignal b) {
33 | labelL[0] = a;
34 | GCSignal.xor(R, labelL[0], labelL[1]);
35 | // labelL[1] = R.xor(labelL[0]);
36 | labelR[0] = b;
37 | GCSignal.xor(R, labelR[0], labelR[1]);
38 | // labelR[1] = R.xor(labelR[0]);
39 |
40 | int cL = a.getLSB();
41 | int cR = b.getLSB();
42 |
43 | // first half gate
44 | // GCSignal G1 = gb.hash(labelL[0], gid, false);
45 | gb.hash(labelL[0], gid, false, G1);
46 | gb.hash(labelL[1], gid, false, TMP);
47 | // TG = G1.xor(TMP).xor((cR == 1) ? R : GCSignal.ZERO);
48 | GCSignal.xor(G1, TMP, TMP);
49 | GCSignal.xor(TMP, (cR == 1) ? R : GCSignal.ZERO, TG);
50 | // WG = G1.xor((cL == 1) ? TG : GCSignal.ZERO);
51 | GCSignal.xor(G1, (cL == 1) ? TG : GCSignal.ZERO, WG);
52 |
53 | // second half gate
54 | // G1 = gb.hash(labelR[0], gid, true);
55 | gb.hash(labelR[0], gid, true, G1);
56 | gb.hash(labelR[1], gid, true, TMP);
57 | // TE = G1.xor(TMP).xor(labelL[0]);
58 | GCSignal.xor(G1, TMP, TMP);
59 | GCSignal.xor(TMP, labelL[0], TE);
60 | // WE = G1.xor((cR == 1) ? (TE.xor(labelL[0])) : GCSignal.ZERO);
61 | GCSignal.xor(G1, (cR == 1) ? (TE.xor(labelL[0])) : GCSignal.ZERO, WE);
62 |
63 | // send the encrypted gate
64 | try {
65 | Flag.sw.startGCIO();
66 | TG.send(channel);
67 | TE.send(channel);
68 | Flag.sw.stopGCIO();
69 | } catch (Exception e) {
70 | e.printStackTrace();
71 | System.exit(1);
72 | }
73 |
74 | // combine halves
75 | return WG.xor(WE);
76 | }
77 |
78 | public GCSignal and(GCSignal a, GCSignal b) {
79 |
80 | Flag.sw.startGC();
81 | GCSignal res;
82 | if (a.isPublic() && b.isPublic())
83 | res = ((a.v && b.v)? new GCSignal(true): new GCSignal(false));
84 | else if (a.isPublic())
85 | res = a.v ? b : new GCSignal(false);
86 | else if (b.isPublic())
87 | res = b.v ? a : new GCSignal(false);
88 | else {
89 | ++numOfAnds;
90 | GCSignal ret = garble(a, b);
91 | gid++;
92 | res = ret;
93 | gatesRemain = true;
94 | }
95 | Flag.sw.stopGC();
96 | return res;
97 | }
98 | }
--------------------------------------------------------------------------------
/src/gc/halfANDs/Garbler.java:
--------------------------------------------------------------------------------
1 | package gc.halfANDs;
2 |
3 | import gc.GCSignal;
4 |
5 | import java.nio.ByteBuffer;
6 | import java.security.MessageDigest;
7 |
8 | final class Garbler {
9 | private MessageDigest sha1 = null;
10 | Garbler() {
11 | try {
12 | sha1 = MessageDigest.getInstance("SHA-1");
13 | }
14 | catch (Exception e) {
15 | e.printStackTrace();
16 | System.exit(1);
17 | }
18 | }
19 |
20 | ByteBuffer buffer = ByteBuffer.allocate(GCSignal.len+9);
21 | public GCSignal hash(GCSignal lb, long k, boolean b) {
22 | buffer.clear();
23 | sha1.update(buffer.put(lb.bytes).putLong(k).put(b?(byte)1:(byte)0).array());
24 | return GCSignal.newInstance(sha1.digest());
25 | }
26 |
27 | public void hash(GCSignal lb, long k, boolean b, GCSignal ret) {
28 | buffer.clear();
29 | sha1.update(buffer.put(lb.bytes).putLong(k).put(b?(byte)1:(byte)0).array());
30 | System.arraycopy(sha1.digest(), 0, ret.bytes, 0, 10);
31 | }
32 | }
--------------------------------------------------------------------------------
/src/gc/halfANDs/TestGarbler.java:
--------------------------------------------------------------------------------
1 | package gc.halfANDs;
2 |
3 | import gc.GCSignal;
4 |
5 | import java.security.SecureRandom;
6 |
7 | public class TestGarbler {
8 | SecureRandom rnd = new SecureRandom();
9 | GCSignal a = GCSignal.freshLabel(rnd);
10 | GCSignal b = GCSignal.freshLabel(rnd);
11 | GCSignal m = GCSignal.freshLabel(rnd);
12 | Garbler gb = new Garbler();
13 |
14 | // public void test() {
15 | // gb.enc(a, b, 0, m);
16 | //
17 | //// Assert.assertTrue(m.equals(gb.dec(a, b, 0L, gb.enc(a, b, 0L, m))));
18 | // }
19 | //
20 | // @Test
21 | // public void test1000() {
22 | // for(int i = 0; i<10000; i++)
23 | // test();
24 | // }
25 | }
26 |
--------------------------------------------------------------------------------
/src/gc/offline/FileReader.java:
--------------------------------------------------------------------------------
1 | package gc.offline;
2 |
3 | import java.io.File;
4 | import java.io.FileInputStream;
5 | import java.io.IOException;
6 | import java.util.Arrays;
7 |
8 | public class FileReader {
9 | byte[] data;
10 | int pos = 0;
11 | public FileReader(String name) {
12 | try {
13 | File file = new File(name);
14 | FileInputStream fis;
15 | fis = new FileInputStream(file);
16 | data = new byte[(int) file.length()];
17 | fis.read(data);
18 | fis.close();
19 | } catch ( IOException e) {
20 | // TODO Auto-generated catch block
21 | e.printStackTrace();
22 | }
23 | }
24 |
25 |
26 | public void read(byte[] a) {
27 | System.arraycopy(data, pos, a, 0, a.length);
28 | pos += a.length;
29 | }
30 |
31 | public byte[] read(int len){
32 | byte[] res = Arrays.copyOfRange(data, pos, pos+len);
33 | pos += len;
34 | return res;
35 | }
36 |
37 | static public void main(String[] args) {
38 | double t1 = System.nanoTime();
39 | FileReader a = new FileReader("table");
40 | double t2 = System.nanoTime();
41 | System.out.println(t2-t1);
42 | System.out.println(a.data.length);
43 | byte[] b = new byte[10];
44 | a.read(b);
45 | }
46 | }
--------------------------------------------------------------------------------
/src/gc/offline/GCEva.java:
--------------------------------------------------------------------------------
1 | package gc.offline;
2 |
3 | import flexsc.Flag;
4 | import flexsc.Mode;
5 | import gc.GCEvaComp;
6 | import gc.GCSignal;
7 | import network.Network;
8 |
9 | public class GCEva extends GCEvaComp {
10 | Garbler gb;
11 | GCSignal[][] gtt = new GCSignal[2][2];
12 |
13 | public GCEva(Network channel) {
14 | super(channel, Mode.OFFLINE);
15 | gb = new Garbler();
16 | gtt[0][0] = GCSignal.ZERO;
17 | }
18 |
19 | private void receiveGTT() {
20 | try {
21 | Flag.sw.startGCIO();
22 | gtt[0][1] = GCSignal.receive(channel);
23 | gtt[1][0] = GCSignal.receive(channel);
24 | gtt[1][1] = GCSignal.receive(channel);
25 | Flag.sw.stopGCIO();
26 | } catch (Exception e) {
27 | e.printStackTrace();
28 | System.exit(1);
29 | }
30 | }
31 |
32 | public GCSignal and(GCSignal a, GCSignal b) {
33 | Flag.sw.startGC();
34 |
35 | GCSignal res;
36 | if (a.isPublic() && b.isPublic())
37 | res = ( (a.v && b.v) ? new GCSignal(true) :new GCSignal(false));
38 | else if (a.isPublic())
39 | res = a.v ? b :new GCSignal(false);
40 | else if (b.isPublic())
41 | res = b.v ? a :new GCSignal(false);
42 | else {
43 | ++numOfAnds;
44 | receiveGTT();
45 |
46 | int i0 = a.getLSB();
47 | int i1 = b.getLSB();
48 |
49 | res = gb.dec(a, b, gid, gtt[i0][i1]);
50 | gid++;
51 | }
52 | Flag.sw.stopGC();
53 | return res;
54 | }
55 | }
--------------------------------------------------------------------------------
/src/gc/offline/GCGen.java:
--------------------------------------------------------------------------------
1 | package gc.offline;
2 |
3 | import flexsc.CompEnv;
4 | import flexsc.Flag;
5 | import flexsc.Mode;
6 | import gc.GCGenComp;
7 | import gc.GCSignal;
8 |
9 | import java.io.BufferedOutputStream;
10 | import java.io.IOException;
11 |
12 | import network.Network;
13 |
14 | public class GCGen extends GCGenComp {
15 | Garbler gb;
16 |
17 | public static BufferedOutputStream fout = null;
18 | public static FileReader fread = null;
19 |
20 | public GCGen(Network channel) {
21 | super(channel, Mode.OFFLINE);
22 | gtt[0][1] = GCSignal.freshLabel(CompEnv.rnd);
23 | gtt[1][0] = GCSignal.freshLabel(CompEnv.rnd);
24 | gtt[1][1] = GCSignal.freshLabel(CompEnv.rnd);
25 | gb = new Garbler();
26 | }
27 |
28 | private GCSignal[][] gtt = new GCSignal[2][2];
29 |
30 | private GCSignal labelL[] = new GCSignal[2];
31 | private GCSignal labelR[] = new GCSignal[2];
32 | GCSignal[] lb = new GCSignal[2];;
33 | private GCSignal garble(GCSignal a, GCSignal b) {
34 | labelL[0] = a;
35 | labelL[1] = R.xor(labelL[0]);
36 | labelR[0] = b;
37 | labelR[1] = R.xor(labelR[0]);
38 |
39 | int cL = a.getLSB();
40 | int cR = b.getLSB();
41 |
42 | lb[cL & cR] = gb.enc(labelL[cL], labelR[cR], gid, GCSignal.ZERO);
43 | lb[1 - (cL & cR)] = R.xor(lb[cL & cR]);
44 |
45 | gtt[0 ^ cL][0 ^ cR] = lb[0];
46 | gtt[0 ^ cL][1 ^ cR] = lb[0];
47 | gtt[1 ^ cL][0 ^ cR] = lb[0];
48 | gtt[1 ^ cL][1 ^ cR] = lb[1];
49 |
50 | if (cL != 0 || cR != 0)
51 | gtt[0 ^ cL][0 ^ cR] = gb.enc(labelL[0], labelR[0], gid,
52 | gtt[0 ^ cL][0 ^ cR]);
53 | if (cL != 0 || cR != 1)
54 | gtt[0 ^ cL][1 ^ cR] = gb.enc(labelL[0], labelR[1], gid,
55 | gtt[0 ^ cL][1 ^ cR]);
56 | if (cL != 1 || cR != 0)
57 | gtt[1 ^ cL][0 ^ cR] = gb.enc(labelL[1], labelR[0], gid,
58 | gtt[1 ^ cL][0 ^ cR]);
59 | if (cL != 1 || cR != 1)
60 | gtt[1 ^ cL][1 ^ cR] = gb.enc(labelL[1], labelR[1], gid,
61 | gtt[1 ^ cL][1 ^ cR]);
62 | return lb[0];
63 | }
64 |
65 | public double t;
66 | private GCSignal readGateFromFile() {
67 | fread.read(gtt[0][1].bytes);
68 | fread.read(gtt[1][0].bytes);
69 | fread.read(gtt[1][1].bytes);
70 | GCSignal a = new GCSignal(fread.read(10));
71 | return a;
72 | }
73 |
74 | private void writeGateToFile(GCSignal a){
75 | gtt[0][1].send(fout);
76 | gtt[1][0].send(fout);
77 | gtt[1][1].send(fout);
78 | a.send(fout);
79 | try {
80 | fout.flush();
81 | } catch (IOException e) {
82 | e.printStackTrace();
83 | }
84 | }
85 |
86 | private void sendGTT() {
87 | try {
88 | Flag.sw.startGCIO();
89 | gtt[0][1].send(channel);
90 | gtt[1][0].send(channel);
91 | gtt[1][1].send(channel);
92 | Flag.sw.stopGCIO();
93 | } catch (Exception e) {
94 | e.printStackTrace();
95 | System.exit(1);
96 | }
97 | }
98 |
99 | public GCSignal and(GCSignal a, GCSignal b) {
100 |
101 | Flag.sw.startGC();
102 | GCSignal res = null;
103 | if (a.isPublic() && b.isPublic())
104 | res = ( (a.v && b.v) ? new GCSignal(true):new GCSignal(false));
105 | else if (a.isPublic())
106 | res = a.v ? b : new GCSignal(false);
107 | else if (b.isPublic())
108 | res = b.v ? a : new GCSignal(false);
109 | else {
110 | ++numOfAnds;
111 | if(Flag.offline) {
112 | res = readGateFromFile();
113 | } else {
114 | res = garble(a, b);
115 | writeGateToFile(res);
116 | if (gid % 100000 == 0) {
117 | System.out.println(gid);
118 | }
119 | }
120 | sendGTT();
121 | gid++;
122 | gatesRemain = true;
123 | }
124 | Flag.sw.stopGC();
125 | return res;
126 | }
127 |
128 | }
--------------------------------------------------------------------------------
/src/gc/offline/Garbler.java:
--------------------------------------------------------------------------------
1 | package gc.offline;
2 |
3 | import gc.GCSignal;
4 |
5 | import java.nio.ByteBuffer;
6 | import java.security.MessageDigest;
7 |
8 | final class Garbler {
9 | private MessageDigest sha1 = null;
10 | Garbler() {
11 | try {
12 | sha1 = MessageDigest.getInstance("SHA-1");
13 | }
14 | catch (Exception e) {
15 | e.printStackTrace();
16 | System.exit(1);
17 | }
18 | }
19 |
20 |
21 | public GCSignal enc(GCSignal lb0, GCSignal lb1, long k, GCSignal m) {
22 | return getPadding(lb0, lb1, k).xor(m);
23 | }
24 |
25 | public GCSignal dec(GCSignal lb0, GCSignal lb1, long k, GCSignal c) {
26 | return getPadding(lb0, lb1, k).xor(c);
27 | }
28 |
29 | ByteBuffer buffer = ByteBuffer.allocate(GCSignal.len*2+8);
30 | private GCSignal getPadding(GCSignal lb0, GCSignal lb1, long k) {
31 | buffer.clear();
32 | sha1.update((buffer.put(lb0.bytes).put(lb1.bytes).putLong(k)));
33 | GCSignal ret = GCSignal.newInstance(sha1.digest());
34 | return ret;
35 | }
36 | }
--------------------------------------------------------------------------------
/src/gc/offline/TestGarbler.java:
--------------------------------------------------------------------------------
1 | package gc.offline;
2 |
3 | import gc.GCSignal;
4 |
5 | import java.security.SecureRandom;
6 |
7 | import org.junit.Test;
8 |
9 | public class TestGarbler {
10 | SecureRandom rnd = new SecureRandom();
11 | GCSignal a = GCSignal.freshLabel(rnd);
12 | GCSignal b = GCSignal.freshLabel(rnd);
13 | GCSignal m = GCSignal.freshLabel(rnd);
14 | Garbler gb = new Garbler();
15 |
16 | public void test() {
17 | gb.enc(a, b, 0, m);
18 | }
19 |
20 | @Test
21 | public void test1000() {
22 | double t1 = System.nanoTime();
23 | int len = 1000000;
24 | for(int i = 0; i void send(T[][][] data, CompEnv env) {
150 | for (int i = 0; i < data.length; i++) {
151 | send(data[i], env);
152 | }
153 | }
154 |
155 | public void send(T[][] data, CompEnv env) {
156 | for (int i = 0; i < data.length; i++) {
157 | send(data[i], env);
158 | }
159 | }
160 |
161 | public T[][] read(int length1, int length2, CompEnv env) {
162 | T[][] ret = env.newTArray(length1, 1);
163 | for (int i = 0; i < length1; i++) {
164 | ret[i] = read(length2, env);
165 | }
166 | return ret;
167 | }
168 |
169 | public T[][][] read(int length1, int length2, int length3, CompEnv env) {
170 | T[][][] ret = env.newTArray(length1, 1, 1);
171 | for (int i = 0; i < length1; i++) {
172 | ret[i] = read(length2, length3, env);
173 | }
174 | return ret;
175 | }
176 |
177 | public void send(T[] data, CompEnv env) {
178 | for (int i = 0; i < data.length; i++) {
179 | send(data[i], env);
180 | }
181 | }
182 |
183 | public void send(T data, CompEnv env) {
184 | Mode mode = env.getMode();
185 | if (mode == Mode.REAL) {
186 | GCSignal gcData = (GCSignal) data;
187 | gcData.send(this);
188 | } else if(mode == Mode.VERIFY) {
189 | writeBoolean((Boolean) data);
190 | } else if (mode == Mode.COUNT) {
191 |
192 | }
193 | }
194 |
195 | public T[] read(int length, CompEnv env) {
196 | T[] ret = env.newTArray(length);
197 | for (int i = 0; i < length; i++) {
198 | ret[i] = read(env);
199 | }
200 | return ret;
201 | }
202 |
203 | @SuppressWarnings("unchecked")
204 | public T read(CompEnv env) {
205 | Mode mode = env.getMode();
206 | if (mode == Mode.REAL || mode == Mode.OPT || mode == Mode.OFFLINE) {
207 | GCSignal signal = GCSignal.receive(this);
208 | return (T) signal;
209 | } else if(mode == Mode.VERIFY) {
210 | Boolean vData = readBoolean();
211 | return (T) vData;
212 | } else if (mode == Mode.COUNT) {
213 | return env.ZERO();
214 | }
215 | // shouldn't happen;
216 | return null;
217 | }
218 |
219 | public boolean readBoolean() {
220 | int read = readInt();
221 | return read == 1;
222 | }
223 |
224 | public void writeBoolean(boolean data) {
225 | int sen = data ? 1 : 0;
226 | writeInt(sen);
227 | }
228 | }
229 |
--------------------------------------------------------------------------------
/src/network/Server.java:
--------------------------------------------------------------------------------
1 | package network;
2 |
3 | import java.io.BufferedInputStream;
4 | import java.io.BufferedOutputStream;
5 | import java.io.IOException;
6 | import java.net.ServerSocket;
7 |
8 | public class Server extends Network {
9 |
10 | public void listen(int port) {
11 | try {
12 | serverSock = new ServerSocket(port);
13 | sock = serverSock.accept(); // wait for client to connect
14 |
15 | os = new BufferedOutputStream(sock.getOutputStream());
16 | is = new BufferedInputStream(sock.getInputStream());
17 | } catch (IOException e) {
18 | // TODO Auto-generated catch block
19 | e.printStackTrace();
20 | } // create socket and bind to port
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/oram/Block.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2014 by Xiao Shaun Wang
2 | package oram;
3 |
4 | import java.util.Arrays;
5 |
6 | public class Block {
7 |
8 | public T[] iden;
9 | public T[] pos;
10 | public T[] data;
11 | public T isDummy;
12 |
13 | public Block(T[] iden, T[] pos, T[] data, T isDummy) {
14 | this.iden = iden;
15 | this.pos = pos;
16 | this.data = data;
17 | this.isDummy = isDummy;
18 | }
19 |
20 | public Block(T[] Tarray, int lengthOfIden, int lengthOfPos, int lengthOfData) {
21 | iden = Arrays.copyOfRange(Tarray, 0, lengthOfIden);
22 | pos = Arrays.copyOfRange(Tarray, lengthOfIden, lengthOfIden
23 | + lengthOfPos);
24 | data = Arrays.copyOfRange(Tarray, lengthOfIden + lengthOfPos,
25 | lengthOfIden + lengthOfPos + lengthOfData);
26 | isDummy = Tarray[Tarray.length - 1];
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/oram/CircuitOram.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2014 by Xiao Shaun Wang
2 | package oram;
3 |
4 | import java.util.Arrays;
5 |
6 | import flexsc.CompEnv;
7 | import flexsc.Party;
8 |
9 | public class CircuitOram extends TreeBasedOramParty {
10 | public CircuitOramLib lib;
11 | Block[] scQueue;
12 | int cnt = 0;
13 | public PlainBlock[] queue;
14 | public int queueCapacity;
15 |
16 | boolean[] nextPath() {
17 | boolean[] res = new boolean[logN];
18 | int temp = cnt;
19 | for (int i = res.length - 1; i >= 0; --i) {
20 | res[i] = (temp & 1) == 1;
21 | temp >>= 1;
22 | }
23 | cnt = (cnt + 1) % N;
24 | return res;
25 | }
26 |
27 | public CircuitOram(CompEnv env, int N, int dataSize, int cap, int sp) {
28 | super(env, N, dataSize, cap);
29 | lib = new CircuitOramLib(lengthOfIden, lengthOfPos, lengthOfData,
30 | logN, capacity, env);
31 | queueCapacity = 30;
32 | queue = new PlainBlock[queueCapacity];
33 |
34 | for (int i = 0; i < queue.length; ++i)
35 | queue[i] = getDummyBlock(p == Party.Alice);
36 |
37 | scQueue = prepareBlocks(queue, queue);
38 | }
39 |
40 | public CircuitOram(CompEnv env, int N, int dataSize) {
41 | super(env, N, dataSize, 3);
42 | lib = new CircuitOramLib(lengthOfIden, lengthOfPos, lengthOfData,
43 | logN, capacity, env);
44 | queueCapacity = 30;
45 | queue = new PlainBlock[queueCapacity];
46 |
47 | for (int i = 0; i < queue.length; ++i)
48 | queue[i] = getDummyBlock(p == Party.Alice);
49 |
50 | scQueue = prepareBlocks(queue, queue);
51 |
52 | }
53 |
54 | protected void ControlEviction() {
55 | flushOneTime(nextPath());
56 | flushOneTime(nextPath());
57 | }
58 |
59 | public void flushOneTime(boolean[] pos) {
60 | PlainBlock[][] blocks = getPath(pos);
61 | Block[][] scPath = preparePath(blocks, blocks);
62 |
63 | lib.flush(scPath, pos, scQueue);
64 |
65 | blocks = preparePlainPath(scPath);
66 | putPath(blocks, pos);
67 | }
68 |
69 | int initalValue = 0;
70 | public void setInitialValue(int intial) {
71 | initalValue = intial;
72 | }
73 | public T[] readAndRemove(T[] scIden, boolean[] pos,
74 | boolean RandomWhenNotFound) {
75 | PlainBlock[][] blocks = getPath(pos);
76 | Block[][] scPath = preparePath(blocks, blocks);
77 |
78 | Block res = lib.readAndRemove(scPath, scIden);
79 | Block res2 = lib.readAndRemove(scQueue, scIden);
80 | res = lib.mux(res, res2, res.isDummy);
81 |
82 | blocks = preparePlainPath(scPath);
83 | putPath(blocks, pos);
84 |
85 | if (RandomWhenNotFound) {
86 | PlainBlock b = randomBlock();
87 | Block scb = inputBlockOfClient(b);
88 | Block finalRes = lib.mux(res, scb, res.isDummy);
89 |
90 | return finalRes.data;
91 | } else {
92 | return lib.mux(res.data, lib.toSignals(initalValue, res.data.length), res.isDummy);
93 | }
94 | }
95 |
96 | public void putBack(T[] scIden, T[] scNewPos, T[] scData) {
97 | Block b = new Block(scIden, scNewPos, scData, lib.SIGNAL_ZERO);
98 | lib.add(scQueue, b);
99 |
100 | env.flush();
101 | ControlEviction();
102 | }
103 |
104 | public T[] read(T[] scIden, boolean[] pos, T[] scNewPos) {
105 | scIden = Arrays.copyOf(scIden, lengthOfIden);
106 | T[] r = readAndRemove(scIden, pos, false);
107 | putBack(scIden, scNewPos, r);
108 | return r;
109 | }
110 |
111 | public void write(T[] scIden, boolean[] pos, T[] scNewPos, T[] scData) {
112 | scIden = Arrays.copyOf(scIden, lengthOfIden);
113 | readAndRemove(scIden, pos, false);
114 | putBack(scIden, scNewPos, scData);
115 | }
116 |
117 | public void write(T[] scIden, T[] pos, T[] scNewPos, T[] scData, T dummy) {
118 | scIden = Arrays.copyOf(scIden, lengthOfIden);
119 | conditionalReadAndRemove(scIden, pos, dummy);
120 | conditionalPutBack(scIden, scNewPos, scData, dummy);
121 | }
122 |
123 | public T[] access(T[] scIden, boolean[] pos, T[] scNewPos, T[] scData, T op) {
124 | scIden = Arrays.copyOf(scIden, lengthOfIden);
125 | T[] r = readAndRemove(scIden, pos, false);
126 | T[] toWrite = lib.mux(r, scData, op);
127 | putBack(scIden, scNewPos, toWrite);
128 | return toWrite;
129 | }
130 |
131 | public T[] conditionalReadAndRemove(T[] scIden, T[] pos, T condition) {
132 | // Utils.print(env, "rar: iden:", scIden, pos, condition);
133 | scIden = Arrays.copyOf(scIden, lengthOfIden);
134 | T[] scPos = Arrays.copyOf(pos, lengthOfPos);
135 | T[] randbools = lib.randBools(scPos.length);
136 | T[] posToUse = lib.mux(randbools, scPos, condition);
137 |
138 | boolean[] path = lib.declassifyToBoth(posToUse);
139 |
140 | PlainBlock[][] blocks = getPath(path);
141 | Block[][] scPath = preparePath(blocks, blocks);
142 |
143 | Block res = lib.conditionalReadAndRemove(scPath, scIden, condition);
144 | Block res2 = lib
145 | .conditionalReadAndRemove(scQueue, scIden, condition);
146 | res = lib.mux(res, res2, res.isDummy);
147 |
148 | blocks = preparePlainPath(scPath);
149 | putPath(blocks, path);
150 | env.flush();
151 | return lib.mux(res.data, lib.toSignals(initalValue, res.data.length), res.isDummy);
152 | }
153 |
154 | public void conditionalPutBack(T[] scIden, T[] scNewPos, T[] scData,
155 | T condition) {
156 | env.flush();
157 | scIden = Arrays.copyOf(scIden, lengthOfIden);
158 |
159 | Block b = new Block(scIden, scNewPos, scData, lib.SIGNAL_ZERO);
160 | lib.conditionalAdd(scQueue, b, condition);
161 | env.flush();
162 | ControlEviction();
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/src/oram/LinearScanOram.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2014 by Xiao Shaun Wang
2 | package oram;
3 |
4 | import circuits.arithmetic.IntegerLib;
5 | import flexsc.CompEnv;
6 |
7 | public class LinearScanOram {
8 | public T[][] content;
9 | public CompEnv env;
10 | public int lengthOfIden;
11 | public IntegerLib lib;
12 | public int dataSize;
13 | public LinearScanOram(CompEnv env, int N, int dataSize) {
14 | this.env = env;
15 | this.dataSize = dataSize;
16 | lib = new IntegerLib(env);
17 | content = env.newTArray(N, 0);
18 | long a = 1;
19 | lengthOfIden = 1;
20 | while (a < N) {
21 | a *= 2;
22 | ++lengthOfIden;
23 | }
24 |
25 | --lengthOfIden;
26 | for(int i = 0; i < N; ++i)
27 | content[i] = lib.zeros(dataSize);
28 | }
29 |
30 | public void add(T[] iden, T[] data, T dummy) {
31 | T[] iden1 = lib.padSignal(iden, lengthOfIden);
32 | for(int i = 0; i < content.length; ++i) {
33 | T eq = lib.eq(iden1, lib.toSignals(i, lengthOfIden));
34 | eq = lib.and(eq, dummy);
35 | content[i] = lib.mux(content[i], data, eq);
36 | }
37 | }
38 |
39 | public void add(T[] iden, T[] data) {
40 | T[] iden1 = lib.padSignal(iden, lengthOfIden);
41 | for(int i = 0; i < content.length; ++i) {
42 | T eq = lib.eq(iden1, lib.toSignals(i, lengthOfIden));
43 | content[i] = lib.mux(content[i], data, eq);
44 | }
45 | }
46 |
47 | public T[] readAndRemove(T[] iden) {
48 | return readAndRemove(iden, false);
49 | }
50 |
51 | public T[] readAndRemove(T[] iden, boolean randomWhennotFound) {
52 | T[] iden1 = lib.padSignal(iden, lengthOfIden);
53 | T[] res = lib.zeros(content[0].length);
54 | for(int i = 0; i < content.length; ++i) {
55 | T eq = lib.eq(iden1, lib.toSignals(i, lengthOfIden));
56 | res = lib.mux(res, content[i], eq);
57 | }
58 | return res;
59 | }
60 |
61 | public T[] read(T[] iden) {
62 | return readAndRemove(iden, false);
63 | }
64 |
65 | public void write(T[] iden, T[] data) {
66 | add(iden, data);
67 | }
68 |
69 | public void write(T[] iden, T[] data, T dummy) {
70 | add(iden, data, dummy);
71 | }
72 |
73 | public void putBack(T[] scIden, T[] scData) {
74 | add(scIden, scData);
75 | }
76 | public T[] read(int index) {
77 | return content[index];
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/oram/PlainBlock.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2014 by Xiao Shaun Wang
2 | package oram;
3 |
4 | import util.Utils;
5 |
6 | public class PlainBlock {
7 | public long iden;
8 | public long pos;
9 | public boolean[] data;
10 | public boolean isDummy;
11 |
12 | public PlainBlock(long iden, long pos, boolean[] data, boolean isDummy) {
13 | this.iden = iden;
14 | this.pos = pos;
15 | this.data = data;
16 | this.isDummy = isDummy;
17 | }
18 |
19 | public boolean[] toBooleanArray(int lengthOfIden, int lengthOfPos) {
20 | boolean[] result = new boolean[lengthOfIden + lengthOfPos + data.length
21 | + 1];
22 | System.arraycopy(Utils.fromLong(iden, lengthOfIden), 0, result, 0, lengthOfIden);
23 | System.arraycopy(Utils.fromLong(pos, lengthOfIden), 0, result, lengthOfIden, lengthOfPos);
24 | System.arraycopy(data, 0, result, lengthOfPos + lengthOfIden, data.length);
25 | result[result.length - 1] = isDummy;
26 | return result;
27 | }
28 |
29 | static public boolean[] toBooleanArray(PlainBlock[] blocks, int lengthOfIden, int lengthOfPos) {
30 | int blockSize = (lengthOfIden + lengthOfPos
31 | + blocks[0].data.length + 1);
32 | boolean[] result = new boolean[blockSize * blocks.length];
33 | for (int i = 0; i < blocks.length; ++i) {
34 | boolean[] tmp = blocks[i].toBooleanArray(lengthOfIden, lengthOfPos);
35 | System.arraycopy(tmp, 0, result, i * blockSize, blockSize);
36 | }
37 | return result;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/oram/SecureArray.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2014 by Xiao Shaun Wang
2 | package oram;
3 |
4 | import java.util.Arrays;
5 |
6 | import flexsc.CompEnv;
7 | import gc.BadLabelException;
8 |
9 | public class SecureArray {
10 | static final int threshold = 256;
11 | boolean useTrivialOram = false;
12 | public LinearScanOram trivialOram = null;
13 | public RecursiveCircuitOram circuitOram = null;
14 | public int lengthOfIden;
15 |
16 | public SecureArray(CompEnv env, int N, int dataSize) throws Exception {
17 | useTrivialOram = N <= threshold;
18 | if (useTrivialOram) {
19 | trivialOram = new LinearScanOram(env, N, dataSize);
20 | lengthOfIden = trivialOram.lengthOfIden;
21 | } else {
22 | circuitOram = new RecursiveCircuitOram(env, N, dataSize);
23 | lengthOfIden = circuitOram.lengthOfIden;
24 | }
25 | }
26 |
27 | public T[] readAndRemove(T[] iden) throws BadLabelException {
28 | return circuitOram.clients.get(0).readAndRemove(iden,
29 | Arrays.copyOfRange(circuitOram.clients.get(0).lib.declassifyToBoth(iden), 0, circuitOram.clients.get(0).lengthOfPos), false);
30 | }
31 |
32 | public T[] read(T[] iden) throws BadLabelException {
33 | if (useTrivialOram)
34 | return trivialOram.read(iden);
35 | else
36 | return circuitOram.read(iden);
37 | }
38 |
39 | public void write(T[] iden, T[] data) throws Exception {
40 | if (useTrivialOram)
41 | trivialOram.write(iden, data);
42 | else
43 | circuitOram.write(iden, data);
44 | }
45 |
46 | public void conditionalWrite(T[] iden, T[]data, T condition) throws BadLabelException {
47 | if(useTrivialOram) {
48 | T[] readData = trivialOram.readAndRemove(iden);
49 | T[] toAdd = trivialOram.lib.mux(readData, data, condition);
50 | trivialOram.putBack(iden, toAdd);
51 | }
52 | else {
53 | //op == 1 means write, 0 means read
54 | circuitOram.access(iden, data, condition);
55 | }
56 | }
57 | }
--------------------------------------------------------------------------------
/src/oram/TreeBasedOramParty.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2014 by Xiao Shaun Wang
2 | package oram;
3 |
4 | import flexsc.CompEnv;
5 | import flexsc.Mode;
6 | import flexsc.Party;
7 |
8 | public abstract class TreeBasedOramParty extends OramParty {
9 | public PlainBlock[][] tree;
10 | protected int capacity;
11 |
12 | public TreeBasedOramParty(CompEnv env, int N, int dataSize, int capacity) {
13 | super(env, N, dataSize);
14 | this.capacity = capacity;
15 |
16 | if (env.mode != Mode.COUNT) {
17 | tree = new PlainBlock[this.N][capacity];
18 |
19 | PlainBlock b = getDummyBlock(p == Party.Alice);
20 |
21 | for (int i = 0; i < this.N; ++i)
22 | for (int j = 0; j < capacity; ++j)
23 | tree[i][j] = b;
24 | }
25 | }
26 |
27 | protected PlainBlock[][] getPath(boolean[] path) {
28 | PlainBlock[][] result = new PlainBlock[logN][];
29 | if (env.mode == Mode.COUNT) {
30 | for (int i = 0; i < logN; ++i) {
31 | result[i] = new PlainBlock[capacity];
32 | for (int j = 0; j < capacity; ++j)
33 | result[i][j] = getDummyBlock(true);
34 | }
35 | return result;
36 | }
37 | int index = 1;
38 | result[0] = tree[index];
39 | for (int i = 1; i < logN; ++i) {
40 | index *= 2;
41 | if (path[lengthOfPos - i])
42 | ++index;
43 | result[i] = tree[index];
44 | }
45 | return result;
46 | }
47 |
48 | protected void putPath(PlainBlock[][] blocks, boolean[] path) {
49 | if (env.mode == Mode.COUNT)
50 | return;
51 | int index = 1;
52 | tree[index] = blocks[0];
53 | for (int i = 1; i < logN; ++i) {
54 | index *= 2;
55 | if (path[lengthOfPos - i])
56 | ++index;
57 | tree[index] = blocks[i];
58 | }
59 | }
60 |
61 | public Block[][] preparePath(PlainBlock[][] clientBlock,
62 | PlainBlock[][] serverBlock) {
63 | Block[][] s = inputPathOfServer(serverBlock);
64 | Block[][] c = inputPathOfClient(clientBlock);
65 | return lib.xor(s, c);
66 | }
67 |
68 | public Block[][] inputPathOfClient(PlainBlock[][] b) {
69 | int length = 0;
70 | for (int i = 0; i < b.length; ++i)
71 | length += b[i].length;
72 |
73 | PlainBlock[] tmp = new PlainBlock[length];
74 | int cnt = 0;
75 | for (int i = 0; i < b.length; ++i)
76 | for (int j = 0; j < b[i].length; ++j)
77 | tmp[cnt++] = b[i][j];
78 |
79 | Block[] tmpResult = inputBucketOfClient(tmp);
80 | cnt = 0;
81 | Block[][] result = lib.newBlockMatrix(b.length);
82 | for (int i = 0; i < b.length; ++i) {
83 | result[i] = lib.newBlockArray(b[i].length);
84 | for (int j = 0; j < b[i].length; ++j)
85 | result[i][j] = tmpResult[cnt++];
86 | }
87 | return result;
88 | }
89 |
90 | public Block[][] inputPathOfServer(PlainBlock[][] b) {
91 | int length = 0;
92 | for (int i = 0; i < b.length; ++i)
93 | length += b[i].length;
94 |
95 | PlainBlock[] tmp = new PlainBlock[length];
96 | int cnt = 0;
97 | for (int i = 0; i < b.length; ++i)
98 | for (int j = 0; j < b[i].length; ++j)
99 | tmp[cnt++] = b[i][j];
100 | Block[] tmpResult = inputBucketOfServer(tmp);
101 |
102 | cnt = 0;
103 | Block[][] result = lib.newBlockMatrix(b.length);
104 | for (int i = 0; i < b.length; ++i) {
105 | result[i] = lib.newBlockArray(b[i].length);
106 | for (int j = 0; j < b[i].length; ++j)
107 | result[i][j] = tmpResult[cnt++];
108 | }
109 | return result;
110 | }
111 |
112 | public PlainBlock[][] preparePlainPath(Block[][] blocks) {
113 | Block[][] randomSCPath = lib.newBlockMatrix(blocks.length);
114 |
115 | PlainBlock[][] randomPath = new PlainBlock[blocks.length][];
116 | for (int i = 0; i < randomPath.length; ++i) {
117 | randomPath[i] = randomBucket(blocks[i].length);
118 | }
119 | env.flush();
120 |
121 | randomSCPath = inputPathOfServer(randomPath);
122 |
123 | PlainBlock[][] result = outputBuckets(lib.xor(blocks, randomSCPath));
124 |
125 | if (p == Party.Alice)
126 | return result;
127 | else
128 | return randomPath;
129 | }
130 |
131 | public PlainBlock[][] randomPath(PlainBlock[][] path) {
132 | PlainBlock[][] result = new PlainBlock[path.length][];
133 | for (int i = 0; i < path.length; ++i)
134 | result[i] = randomBucket(path[i].length);
135 | return result;
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/src/oram/TrivialPrivateOram.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2014 by Xiao Shaun Wang
2 | package oram;
3 |
4 | import java.util.Arrays;
5 |
6 | import flexsc.CompEnv;
7 | import flexsc.Party;
8 |
9 | public class TrivialPrivateOram extends OramParty {
10 | public PlainBlock[] bucket;
11 | Block[] result;
12 | int capacity;
13 |
14 | public TrivialPrivateOram(CompEnv env, int N, int dataSize) {
15 | super(env, N, dataSize, 1);
16 | this.capacity = N;
17 | bucket = new PlainBlock[capacity];
18 |
19 | for (int i = 0; i < bucket.length; ++i) {
20 | bucket[i] = getDummyBlock(p == Party.Alice);
21 | }
22 | result = prepareBlocks(bucket, bucket);
23 | }
24 |
25 | int InitialValue = 0;
26 | public void setInitialValue(int initial) {
27 | InitialValue = initial;
28 | }
29 | public void add(T[] iden, T[] data) {
30 | T[] pos = env.newTArray(1);
31 | pos[0] = lib.SIGNAL_ONE;
32 | Block scNewBlock = new Block(iden, pos, data, lib.SIGNAL_ZERO);
33 | lib.add(result, scNewBlock);
34 | }
35 |
36 | public T[] readAndRemove(T[] scIden) {
37 | return readAndRemove(scIden, true);
38 | }
39 |
40 | public T[] readAndRemove(T[] scIden, boolean randomWhennotFound) {
41 | scIden = lib.padSignal(scIden, lengthOfIden);
42 | Block res = lib.readAndRemove(result, scIden);
43 | T[] finalRes;
44 | if (randomWhennotFound) {
45 | PlainBlock b1 = randomBlock();
46 | Block scb1 = inputBlockOfClient(b1);
47 | finalRes = lib.mux(res.data, scb1.data, res.isDummy);
48 | } else {
49 | finalRes = lib.mux(res.data, lib.toSignals(InitialValue, res.data.length),
50 | res.isDummy);
51 | }
52 |
53 | return finalRes;
54 | }
55 |
56 | public T[] read(int index) {
57 | return result[index].data;
58 | }
59 |
60 | public void write(int index, T[] d) {
61 | result[index].data = d;
62 | }
63 |
64 | public T[] read(T[] scIden) {
65 | scIden = Arrays.copyOf(scIden, lengthOfIden);
66 | T[] r = readAndRemove(scIden, false);
67 | putBack(scIden, r);
68 |
69 | return r;
70 | }
71 |
72 | public void write(T[] scIden, T[] b) {
73 | scIden = Arrays.copyOf(scIden, lengthOfIden);
74 | readAndRemove(scIden);
75 | putBack(scIden, b);
76 | }
77 |
78 | public void putBack(T[] scIden, T[] scData) {
79 | scIden = Arrays.copyOf(scIden, lengthOfIden);
80 | add(scIden, scData);
81 | }
82 |
83 | public T[] conditionalReadAndRemove(T[] iden, T condition) {
84 | return lib.conditionalReadAndRemove(result, iden, condition).data;
85 | }
86 | public void conditionalPutBack(T[] iden, T[] data, T condition) {
87 | T[] pos = env.newTArray(1);
88 | pos[0] = lib.SIGNAL_ONE;
89 | Block scNewBlock = new Block(iden, pos, data, lib.SIGNAL_ZERO);
90 | lib.conditionalAdd(result, scNewBlock, condition);
91 | }
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/src/ot/BitMatrix.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2013 by Yan Huang
2 | // Improved by Xiao Shaun Wang
3 |
4 | package ot;
5 |
6 | import java.math.BigInteger;
7 | import java.security.SecureRandom;
8 |
9 | class BitMatrix {
10 | private int nRows;
11 | private int nCols;
12 | BigInteger[] data; // column vectors of the matrix
13 |
14 | public BitMatrix(int rows, int cols) {
15 | nRows = rows;
16 | nCols = cols;
17 | data = new BigInteger[nCols];
18 | }
19 |
20 | public void initialize(SecureRandom rnd) {
21 | for (int i = 0; i < nCols; i++)
22 | data[i] = new BigInteger(nRows, rnd);
23 | }
24 |
25 | public BitMatrix transpose() {
26 | return NaiveTranspose(this);
27 | }
28 |
29 | static public BitMatrix NaiveTranspose(BitMatrix a) {
30 | BitMatrix b = new BitMatrix(a.nCols, a.nRows);
31 |
32 | for (int i = 0; i < a.nRows; i++)
33 | b.data[i] = BigInteger.ZERO;
34 |
35 | for (int j = 0; j < a.nCols; j++)
36 | for (int i = 0; i < a.nRows; i++)
37 | if (a.data[j].testBit(i))
38 | b.data[i] = b.data[i].setBit(j);
39 | return b;
40 | }
41 |
42 | static public BitMatrix COtranspose(BitMatrix a) {
43 | BitMatrix b = new BitMatrix(a.nCols, a.nRows);
44 | for (int i = 0; i < a.nRows; i++)
45 | b.data[i] = BigInteger.ZERO;
46 | COtranspose(a, b, 0, 0, a.nRows, a.nCols);
47 | return b;
48 | }
49 |
50 | static public void COtranspose(BitMatrix a, BitMatrix b, int startx,
51 | int starty, int endx, int endy) {
52 |
53 | if (endy - starty == 1 && endx - startx == 1) {
54 | if (a.data[starty].testBit(startx))
55 | b.data[startx] = b.data[startx].setBit(starty);
56 | return;
57 | } else if (endy - starty < endx - startx) {
58 |
59 | int midx = (startx + endx) / 2;
60 | COtranspose(a, b, startx, starty, midx, endy);
61 | COtranspose(a, b, midx, starty, endx, endy);
62 | } else {
63 | int midy = (starty + endy) / 2;
64 | COtranspose(a, b, startx, starty, endx, midy);
65 | COtranspose(a, b, startx, midy, endx, endy);
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/src/ot/Cipher.java:
--------------------------------------------------------------------------------
1 | //Copyright (C) 2014 by Yan Huang
2 |
3 | package ot;
4 |
5 | import gc.GCSignal;
6 |
7 | import java.math.BigInteger;
8 | import java.nio.ByteBuffer;
9 | import java.security.MessageDigest;
10 |
11 | public final class Cipher {
12 | private static final int unitLength = 160; // SHA-1 has 160-bit output.
13 | private static final int bytesPerUnit = (unitLength-1)/8+1; // SHA-1 has 20 bytes.
14 |
15 | private MessageDigest sha1;
16 |
17 | public Cipher() {
18 | try {
19 | sha1 = MessageDigest.getInstance("SHA-1");
20 | } catch (Exception e) {
21 | e.printStackTrace();
22 | System.exit(1);
23 | }
24 | }
25 |
26 | BigInteger a = BigInteger.ONE;
27 | public BigInteger encrypt(byte[] key, BigInteger msg, int msgLength) {
28 | assert (msgLength <= unitLength) : "Message longer than hash block width.";
29 | return msg.xor(getPaddingOfLength(key, msgLength));
30 | }
31 |
32 | public BigInteger decrypt(byte[] key, BigInteger cph, int cphLength) {
33 | assert (cphLength > unitLength) : "Ciphertext longer than hash block width.";
34 | return cph.xor(getPaddingOfLength(key, cphLength));
35 | }
36 |
37 | private BigInteger getPaddingOfLength(byte[] key, int padLength) {
38 |
39 | byte[] pad = new byte[(padLength-1)/8+1];
40 | byte[] tmp;
41 | int i;
42 | for (i = 0; i < (pad.length-1)/bytesPerUnit; i++) {
43 | assert (i < 128) : "Padding is unexpectedly long.";
44 | sha1.update(key);
45 | sha1.update((byte)i);
46 | tmp = sha1.digest();
47 | System.arraycopy(tmp, 0, pad, i*bytesPerUnit, bytesPerUnit);
48 | }
49 |
50 | return new BigInteger(1, pad);
51 | }
52 |
53 | public BigInteger encrypt(int j, byte[] key, BigInteger msg,
54 | int msgLength) {
55 | return msg.xor(getPaddingOfLength(j, key, msgLength));
56 | }
57 |
58 | public BigInteger decrypt(int j, byte[] key, BigInteger cph,
59 | int cphLength) {
60 | return cph.xor(getPaddingOfLength(j, key, cphLength));
61 | }
62 |
63 | private BigInteger getPaddingOfLength(int j, byte[] key, int padLength) {
64 | sha1.update(ByteBuffer.allocate(4).putInt(j).array());
65 | sha1.update(key);
66 |
67 | byte[] pad = new byte[(padLength-1)/8+1];
68 | byte[] tmp;
69 | tmp = sha1.digest();
70 | int i;
71 | for (i = 0; i < (pad.length-1)/bytesPerUnit; i++) {
72 | System.arraycopy(tmp, 0, pad, i*bytesPerUnit, bytesPerUnit);
73 | sha1.update(tmp);
74 | tmp = sha1.digest();
75 | }
76 | System.arraycopy(tmp, 0, pad, i*bytesPerUnit, pad.length-i*bytesPerUnit);
77 |
78 | return new BigInteger(1, pad);
79 | }
80 |
81 | public GCSignal enc(GCSignal key, GCSignal m, int k) {
82 | return getPadding(key, k).xor(m);
83 | }
84 |
85 | public GCSignal dec(GCSignal key, GCSignal c, int k) {
86 | return getPadding(key, k).xor(c);
87 | }
88 |
89 | private GCSignal getPadding(GCSignal key, int k) {
90 | sha1.update(key.bytes);
91 | sha1.update(ByteBuffer.allocate(4).putInt(k).array());
92 | GCSignal ret = GCSignal.newInstance(sha1.digest());
93 | return ret;
94 | }
95 | }
--------------------------------------------------------------------------------
/src/ot/FakeOTReceiver.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2013 by Yan Huang
2 | // Improved by Xiao Shaun Wang
3 |
4 | package ot;
5 |
6 | import gc.GCSignal;
7 | import network.Network;
8 |
9 | public class FakeOTReceiver extends OTReceiver {
10 | public FakeOTReceiver(Network channel) {
11 | super(channel);
12 | }
13 |
14 | @Override
15 | public GCSignal receive(boolean c) {
16 | GCSignal[] m = new GCSignal[2];
17 | m[0] = GCSignal.receive(channel);
18 | m[1] = GCSignal.receive(channel);
19 | return m[c ? 1 : 0];
20 | }
21 |
22 | @Override
23 | public GCSignal[] receive(boolean[] c) {
24 | GCSignal[] res = new GCSignal[c.length];
25 | for (int i = 0; i < c.length; i++) {
26 | GCSignal[] m = new GCSignal[2];
27 | m[0] = GCSignal.receive(channel);
28 | m[1] = GCSignal.receive(channel);
29 | res[i] = m[c[i] ? 1 : 0];
30 | }
31 | return res;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/ot/FakeOTSender.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2013 by Yan Huang
2 | // Improved by Xiao Shaun Wang
3 |
4 | package ot;
5 |
6 | import gc.GCSignal;
7 |
8 | import java.io.IOException;
9 |
10 | import network.Network;
11 |
12 | public class FakeOTSender extends OTSender {
13 | public FakeOTSender(int bitLen, Network channel) {
14 | super(bitLen, channel);
15 | }
16 |
17 | @Override
18 | public void send(GCSignal[] m) {
19 | m[0].send(channel);
20 | m[1].send(channel);
21 | }
22 |
23 | @Override
24 | public void send(GCSignal[][] m) throws IOException {
25 | for (int i = 0; i < m.length; i++) {
26 | m[i][0].send(channel);
27 | m[i][1].send(channel);
28 | }
29 | channel.flush();
30 | }
31 | }
--------------------------------------------------------------------------------
/src/ot/NPOTReceiver.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2013 by Yan Huang
2 |
3 | package ot;
4 |
5 | import flexsc.Flag;
6 | import gc.GCSignal;
7 |
8 | import java.io.IOException;
9 | import java.math.BigInteger;
10 | import java.security.NoSuchAlgorithmException;
11 | import java.security.SecureRandom;
12 | import java.security.Security;
13 |
14 | import network.Network;
15 | import rand.ISAACProvider;
16 |
17 | public class NPOTReceiver extends OTReceiver {
18 | static SecureRandom rnd;
19 | static {
20 | Security.addProvider(new ISAACProvider());
21 | try {
22 | rnd = SecureRandom.getInstance("ISAACRandom");
23 | } catch (NoSuchAlgorithmException e) {
24 | e.printStackTrace();
25 | }
26 | }
27 |
28 | private BigInteger p, q, g, C;
29 | private BigInteger gr;
30 |
31 | private BigInteger[][] pk;
32 |
33 | private BigInteger[] keys;
34 |
35 | Cipher cipher;
36 |
37 | public NPOTReceiver(Network channel) throws Exception {
38 | super(channel);
39 |
40 | cipher = new Cipher();
41 |
42 | initialize();
43 | }
44 |
45 | @Override
46 | public GCSignal receive(boolean c) throws IOException {
47 | return receive(new boolean[] { c })[0];
48 | }
49 |
50 | public GCSignal[] receive(boolean[] choices) throws IOException {
51 | step1(choices);
52 | return step2(choices);
53 | }
54 |
55 | private void initialize() throws Exception {
56 | Flag.sw.startOTIO();
57 | C = channel.readBI();
58 | p = channel.readBI();
59 | q = channel.readBI();
60 | g = channel.readBI();
61 | gr = channel.readBI();
62 | msgBitLength = channel.readInt();
63 | Flag.sw.stopOTIO();
64 | }
65 |
66 | private void step1(boolean[] choices) throws IOException {
67 | keys = new BigInteger[choices.length];
68 | pk = new BigInteger[choices.length][2];
69 | BigInteger[] pk0 = new BigInteger[choices.length];
70 | for (int i = 0; i < choices.length; i++) {
71 | BigInteger k = (new BigInteger(q.bitLength(), rnd)).mod(q);
72 | BigInteger gk = g.modPow(k, p);
73 | BigInteger C_over_gk = C.multiply(gk.modInverse(p)).mod(p);
74 | keys[i] = gr.modPow(k, p);
75 |
76 | int sigma = choices[i] ? 1 : 0;
77 | pk[i][sigma] = gk;
78 | pk[i][1 - sigma] = C_over_gk;
79 |
80 | pk0[i] = pk[i][0];
81 | }
82 |
83 | Flag.sw.startOTIO();
84 | for (int i = 0; i < choices.length; i++)
85 | channel.writeBI(pk0[i]);
86 | channel.flush();
87 | Flag.sw.stopOTIO();
88 |
89 | }
90 |
91 | private GCSignal[] step2(boolean[] choices) {
92 | BigInteger[][] msg = new BigInteger[choices.length][2];
93 | Flag.sw.startOTIO();
94 | for (int i = 0; i < choices.length; i++) {
95 | msg[i][0] = channel.readBI();
96 | msg[i][1] = channel.readBI();
97 | }
98 | Flag.sw.stopOTIO();
99 |
100 | GCSignal[] data = new GCSignal[choices.length];
101 | for (int i = 0; i < choices.length; i++) {
102 | int sigma = choices[i] ? 1 : 0;
103 | data[i] = GCSignal.newInstance(cipher.decrypt(
104 | keys[i].toByteArray(), msg[i][sigma], msgBitLength)
105 | .toByteArray());
106 | }
107 | return data;
108 | }
109 | }
--------------------------------------------------------------------------------
/src/ot/NPOTSender.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2013 by Yan Huang
2 |
3 | package ot;
4 |
5 | import flexsc.Flag;
6 | import gc.GCSignal;
7 |
8 | import java.io.File;
9 | import java.io.FileInputStream;
10 | import java.io.FileOutputStream;
11 | import java.io.IOException;
12 | import java.io.ObjectInputStream;
13 | import java.io.ObjectOutputStream;
14 | import java.math.BigInteger;
15 | import java.security.NoSuchAlgorithmException;
16 | import java.security.SecureRandom;
17 | import java.security.Security;
18 |
19 | import network.Network;
20 | import rand.ISAACProvider;
21 |
22 | public class NPOTSender extends OTSender {
23 |
24 | static SecureRandom rnd;
25 | static {
26 | Security.addProvider(new ISAACProvider());
27 | try {
28 | rnd = SecureRandom.getInstance("ISAACRandom");
29 | } catch (NoSuchAlgorithmException e) {
30 | e.printStackTrace();
31 | }
32 | }
33 | private static final int certainty = 80;
34 |
35 | private final static int qLength = 160; // 512;
36 | private final static int pLength = 1024; // 15360;
37 |
38 | private BigInteger p, q, g, C, r;
39 | private BigInteger Cr, gr;
40 |
41 | Cipher cipher;
42 |
43 | public NPOTSender(int msgBitLength, Network channel)
44 | throws Exception {
45 | super(msgBitLength, channel);
46 | cipher = new Cipher();
47 |
48 | initialize();
49 | }
50 |
51 | public void send(GCSignal[][] msgPairs) throws IOException {
52 | step1(msgPairs);
53 | }
54 |
55 | private void initialize() throws Exception {
56 | File keyfile = new File("NPOTKey");
57 | if (keyfile.exists()) {
58 | FileInputStream fin = new FileInputStream(keyfile);
59 | ObjectInputStream fois = new ObjectInputStream(fin);
60 |
61 | C = (BigInteger) fois.readObject();
62 | p = (BigInteger) fois.readObject();
63 | q = (BigInteger) fois.readObject();
64 | g = (BigInteger) fois.readObject();
65 | gr = (BigInteger) fois.readObject();
66 | r = (BigInteger) fois.readObject();
67 | fois.close();
68 |
69 | Flag.sw.startOTIO();
70 | channel.writeBI(C);
71 | channel.writeBI(p);
72 | channel.writeBI(q);
73 | channel.writeBI(g);
74 | channel.writeBI(gr);
75 | channel.writeInt(msgBitLength);
76 | channel.flush();
77 | Flag.sw.stopOTIO();
78 |
79 | Cr = C.modPow(r, p);
80 | } else {
81 | BigInteger pdq;
82 | q = new BigInteger(qLength, certainty, rnd);
83 |
84 | do {
85 | pdq = new BigInteger(pLength - qLength, rnd);
86 | pdq = pdq.clearBit(0);
87 | p = q.multiply(pdq).add(BigInteger.ONE);
88 | } while (!p.isProbablePrime(certainty));
89 |
90 | do {
91 | g = new BigInteger(pLength - 1, rnd);
92 | } while ((g.modPow(pdq, p)).equals(BigInteger.ONE)
93 | || (g.modPow(q, p)).equals(BigInteger.ONE));
94 |
95 | r = (new BigInteger(qLength, rnd)).mod(q);
96 | gr = g.modPow(r, p);
97 | C = (new BigInteger(qLength, rnd)).mod(q);
98 |
99 | Flag.sw.startOTIO();
100 | channel.writeBI(C);
101 | channel.writeBI(p);
102 | channel.writeBI(q);
103 | channel.writeBI(g);
104 | channel.writeBI(gr);
105 | channel.writeInt(msgBitLength);
106 | channel.flush();
107 | Flag.sw.stopOTIO();
108 |
109 | Cr = C.modPow(r, p);
110 |
111 | FileOutputStream fout = new FileOutputStream(keyfile);
112 | ObjectOutputStream foos = new ObjectOutputStream(fout);
113 |
114 | foos.writeObject(C);
115 | foos.writeObject(p);
116 | foos.writeObject(q);
117 | foos.writeObject(g);
118 | foos.writeObject(gr);
119 | foos.writeObject(r);
120 |
121 | foos.flush();
122 | foos.close();
123 | }
124 | }
125 |
126 | GCSignal[][] m = new GCSignal[1][2];
127 |
128 | @Override
129 | public void send(GCSignal[] msgPair) throws IOException {
130 | m[0][0] = msgPair[0];
131 | m[0][1] = msgPair[1];
132 | send(m);
133 | }
134 |
135 | private void step1(GCSignal[][] msgPairs) throws IOException {
136 | BigInteger[] pk0 = new BigInteger[msgPairs.length];
137 | Flag.sw.startOTIO();
138 | for (int i = 0; i < pk0.length; i++)
139 | pk0[i] = channel.readBI();
140 | Flag.sw.stopOTIO();
141 |
142 | BigInteger[] pk1 = new BigInteger[msgPairs.length];
143 | BigInteger[][] msg = new BigInteger[msgPairs.length][2];
144 |
145 | for (int i = 0; i < msgPairs.length; i++) {
146 | pk0[i] = pk0[i].modPow(r, p);
147 | pk1[i] = Cr.multiply(pk0[i].modInverse(p)).mod(p);
148 |
149 | msg[i][0] = cipher.encrypt(pk0[i].toByteArray(), new BigInteger(
150 | msgPairs[i][0].bytes), msgBitLength);
151 | msg[i][1] = cipher.encrypt(pk1[i].toByteArray(), new BigInteger(
152 | msgPairs[i][1].bytes), msgBitLength);
153 | }
154 | Flag.sw.startOTIO();
155 | for (int i = 0; i < msg.length; i++) {
156 | channel.writeBI(msg[i][0]);
157 | channel.writeBI(msg[i][1]);
158 | }
159 | channel.flush();
160 | Flag.sw.stopOTIO();
161 |
162 | }
163 | }
--------------------------------------------------------------------------------
/src/ot/OTExtReceiver.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2013 by Yan Huang
2 | // Improved by Xiao Shaun Wang
3 |
4 | package ot;
5 |
6 | import flexsc.Flag;
7 | import gc.GCSignal;
8 |
9 | import java.io.IOException;
10 | import java.math.BigInteger;
11 | import java.security.NoSuchAlgorithmException;
12 | import java.security.SecureRandom;
13 | import java.security.Security;
14 | import java.util.Arrays;
15 |
16 | import network.Network;
17 | import ot.OTExtSender.SecurityParameter;
18 | import rand.ISAACProvider;
19 |
20 | public class OTExtReceiver extends OTReceiver {
21 | static SecureRandom rnd;
22 | static {
23 | Security.addProvider(new ISAACProvider());
24 | try {
25 | rnd = SecureRandom.getInstance("ISAACRandom");
26 | } catch (NoSuchAlgorithmException e) {
27 | e.printStackTrace();
28 | }
29 | }
30 |
31 | private int msgBitLength;
32 |
33 | private OTSender snder;
34 | private GCSignal[][] keyPairs;
35 |
36 | Cipher cipher;
37 |
38 | public OTExtReceiver(Network channel) {
39 | super(channel);
40 |
41 | cipher = new Cipher();
42 |
43 | try {
44 | initialize();
45 | } catch (Exception e) {
46 | e.printStackTrace();
47 | }
48 | }
49 |
50 | boolean[] s = new boolean[SecurityParameter.k1];
51 |
52 | public GCSignal[] receive(boolean[] choices) throws IOException {
53 | GCSignal[] keys = new GCSignal[SecurityParameter.k1];
54 |
55 | boolean[] c = new boolean[SecurityParameter.k1 + choices.length];
56 | for (int i = 0; i < SecurityParameter.k1; i++)
57 | c[i] = rnd.nextBoolean();
58 | for (int i = SecurityParameter.k1; i < c.length; i++)
59 | c[i] = choices[i - SecurityParameter.k1];
60 |
61 | GCSignal[] received = reverseAndExtend(keyPairs, c, msgBitLength, channel, cipher);
62 |
63 | for (int i = 0; i < OTExtSender.SecurityParameter.k1; i++) {
64 | keys[i] = received[i];
65 | s[i] = c[i];
66 | }
67 | for (int i = 0; i < OTExtSender.SecurityParameter.k1; i++) {
68 | keyPairs[i][0] = GCSignal.freshLabel(rnd);
69 | keyPairs[i][1] = GCSignal.freshLabel(rnd);
70 | }
71 | OTExtSender.reverseAndExtend(s, keys, msgBitLength, keyPairs, channel,
72 | cipher);
73 |
74 | return Arrays.copyOfRange(received, SecurityParameter.k1,
75 | received.length);
76 | }
77 |
78 | static GCSignal[] reverseAndExtend(GCSignal[][] keyPairs,
79 | boolean[] choices, int msgBitLength, Network channel, Cipher cipher) throws IOException {
80 | BigInteger[][] msgPairs = new BigInteger[SecurityParameter.k1][2];
81 | BigInteger[][] cphPairs = new BigInteger[SecurityParameter.k1][2];
82 |
83 | BitMatrix T = new BitMatrix(choices.length, SecurityParameter.k1);
84 | T.initialize(rnd);
85 |
86 | BigInteger biChoices = OTExtSender.fromBoolArray(choices);
87 | for (int i = 0; i < SecurityParameter.k1; i++) {
88 | msgPairs[i][0] = T.data[i];
89 | msgPairs[i][1] = T.data[i].xor(biChoices);
90 |
91 | cphPairs[i][0] = cipher.encrypt(keyPairs[i][0].bytes,
92 | msgPairs[i][0], choices.length);
93 | cphPairs[i][1] = cipher.encrypt(keyPairs[i][1].bytes,
94 | msgPairs[i][1], choices.length);
95 | channel.writeBI(cphPairs[i][0]);
96 | channel.writeBI(cphPairs[i][1]);
97 | }
98 |
99 | Flag.sw.startOTIO();
100 | channel.flush();
101 | Flag.sw.stopOTIO();
102 |
103 | BitMatrix tT = T.transpose();
104 | GCSignal[] res = new GCSignal[choices.length];
105 |
106 | GCSignal[][] y = new GCSignal[choices.length][2];
107 |
108 | for (int i = 0; i < choices.length; i++) {
109 | y[i][0] = GCSignal.receive(channel);
110 | y[i][1] = GCSignal.receive(channel);
111 | int sigma = choices[i] ? 1 : 0;
112 | res[i] = cipher.dec(GCSignal.newInstance(tT.data[i].toByteArray()),
113 | y[i][sigma], i);
114 | }
115 |
116 | return res;
117 | }
118 |
119 | private void initialize() throws Exception {
120 | Flag.sw.startOTIO();
121 | msgBitLength = channel.readInt();
122 | Flag.sw.stopOTIO();
123 |
124 | snder = new NPOTSender(OTExtSender.SecurityParameter.k1, channel);
125 |
126 | keyPairs = new GCSignal[OTExtSender.SecurityParameter.k1][2];
127 | for (int i = 0; i < OTExtSender.SecurityParameter.k1; i++) {
128 | keyPairs[i][0] = GCSignal.freshLabel(rnd);
129 | keyPairs[i][1] = GCSignal.freshLabel(rnd);
130 | }
131 |
132 | snder.send(keyPairs);
133 | channel.flush();
134 | }
135 |
136 | GCSignal[] pool;
137 | int poolIndex = 0;
138 |
139 | @Override
140 | public GCSignal receive(boolean c) {
141 | try {
142 | throw new Exception(
143 | "It doesn't make sense to do single OT with OT extension!");
144 | } catch (Exception e) {
145 | e.printStackTrace();
146 | }
147 | return null;
148 | }
149 | }
--------------------------------------------------------------------------------
/src/ot/OTExtSender.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2013 by Yan Huang
2 | // Improved by Xiao Shaun Wang
3 |
4 | package ot;
5 |
6 | import flexsc.Flag;
7 | import gc.GCSignal;
8 |
9 | import java.io.IOException;
10 | import java.math.BigInteger;
11 | import java.security.NoSuchAlgorithmException;
12 | import java.security.SecureRandom;
13 | import java.security.Security;
14 |
15 | import network.Network;
16 | import rand.ISAACProvider;
17 |
18 | public class OTExtSender extends OTSender {
19 | static class SecurityParameter {
20 | public static final int k1 = 80; // number of columns in T
21 | }
22 |
23 | private static SecureRandom rnd;
24 | static {
25 | Security.addProvider(new ISAACProvider());
26 | try {
27 | rnd = SecureRandom.getInstance("ISAACRandom");
28 | } catch (NoSuchAlgorithmException e) {
29 | e.printStackTrace();
30 | }
31 | }
32 | private OTReceiver rcver;
33 | private boolean[] s;
34 | private GCSignal[] keys;
35 |
36 | Cipher cipher;
37 |
38 | public OTExtSender(int msgBitLength, Network channel) {
39 | super(msgBitLength, channel);
40 |
41 | cipher = new Cipher();
42 |
43 | try {
44 | initialize();
45 | } catch (Exception e) {
46 | e.printStackTrace();
47 | }
48 | }
49 |
50 | int poolIndex = 0;
51 |
52 | @Override
53 | public void send(GCSignal[] m) {
54 | try {
55 | throw new Exception(
56 | "It doesn't make sense to do single OT with OT extension!");
57 | } catch (Exception e) {
58 | e.printStackTrace();
59 | }
60 | }
61 |
62 | /*
63 | * Everything in msgPairs are effective Sender's messages.
64 | */
65 | GCSignal[][] keyPairs = new GCSignal[SecurityParameter.k1][2];
66 |
67 | public void send(GCSignal[][] msgPairs) throws IOException {
68 | GCSignal[][] pairs = new GCSignal[SecurityParameter.k1
69 | + msgPairs.length][2];
70 | for (int i = 0; i < SecurityParameter.k1; i++) {
71 | pairs[i][0] = GCSignal.freshLabel(rnd);
72 | pairs[i][1] = GCSignal.freshLabel(rnd);
73 | }
74 |
75 | for (int i = SecurityParameter.k1; i < pairs.length; i++) {
76 | pairs[i][0] = msgPairs[i - SecurityParameter.k1][0];
77 | pairs[i][1] = msgPairs[i - SecurityParameter.k1][1];
78 | }
79 |
80 | reverseAndExtend(s, keys, msgBitLength, pairs, channel, cipher);
81 |
82 | for (int i = 0; i < SecurityParameter.k1; i++) {
83 | keyPairs[i][0] = pairs[i][0];
84 | keyPairs[i][1] = pairs[i][1];
85 | }
86 | for (int i = 0; i < s.length; i++)
87 | s[i] = rnd.nextBoolean();
88 | keys = OTExtReceiver.reverseAndExtend(keyPairs, s,
89 | SecurityParameter.k1, channel, cipher);
90 | }
91 |
92 | // Given s and keys, obliviously sends msgPairs which contains 'numOfPairs'
93 | // pairs of strings, each of length 'msgBitLength' bits.
94 |
95 | static void reverseAndExtend(boolean[] s, GCSignal[] keys,
96 | int msgBitLength, GCSignal[][] msgPairs, Network channel,
97 | Cipher cipher) throws IOException {
98 | BigInteger[][] cphPairs = new BigInteger[SecurityParameter.k1][2];
99 |
100 | Flag.sw.startOTIO();
101 | for (int i = 0; i < SecurityParameter.k1; i++) {
102 | cphPairs[i][0] = channel.readBI();
103 | cphPairs[i][1] = channel.readBI();
104 | }
105 | Flag.sw.stopOTIO();
106 |
107 | int numOfPairs = msgPairs.length;
108 |
109 | BitMatrix Q = new BitMatrix(numOfPairs, SecurityParameter.k1);
110 |
111 | for (int i = 0; i < SecurityParameter.k1; i++) {
112 | if (s[i])
113 | Q.data[i] = cipher.decrypt(keys[i].bytes, cphPairs[i][1],
114 | numOfPairs);
115 | else
116 | Q.data[i] = cipher.decrypt(keys[i].bytes, cphPairs[i][0],
117 | numOfPairs);
118 | }
119 |
120 | BitMatrix tQ = Q.transpose();
121 |
122 | BigInteger biS = fromBoolArray(s);
123 |
124 | GCSignal[][] y = new GCSignal[numOfPairs][2];
125 | for (int i = 0; i < numOfPairs; i++) {
126 | y[i][0] = cipher.enc(
127 | GCSignal.newInstance(tQ.data[i].toByteArray()),
128 | msgPairs[i][0], i);
129 | y[i][1] = cipher.enc(
130 | GCSignal.newInstance(tQ.data[i].xor(biS).toByteArray()),
131 | msgPairs[i][1], i);
132 | y[i][0].send(channel);
133 | y[i][1].send(channel);
134 | }
135 |
136 | Flag.sw.startOTIO();
137 | channel.flush();
138 | Flag.sw.stopOTIO();
139 |
140 | }
141 |
142 | private void initialize() throws Exception {
143 | Flag.sw.startOTIO();
144 | channel.writeInt(msgBitLength);
145 | channel.flush();
146 | Flag.sw.stopOTIO();
147 |
148 | rcver = new NPOTReceiver(channel);
149 |
150 | s = new boolean[SecurityParameter.k1];
151 | for (int i = 0; i < s.length; i++)
152 | s[i] = rnd.nextBoolean();
153 |
154 | keys = rcver.receive(s);
155 | }
156 |
157 | public static BigInteger fromBoolArray(boolean[] a) {
158 | BigInteger res = BigInteger.ZERO;
159 | for (int i = 0; i < a.length; i++)
160 | if (a[i])
161 | res = res.setBit(i);
162 | return res;
163 | }
164 | }
--------------------------------------------------------------------------------
/src/ot/OTPreprocessReceiver.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) by Xiao Shaun Wang
2 |
3 | package ot;
4 |
5 | import flexsc.CompEnv;
6 | import flexsc.Flag;
7 | import gc.GCSignal;
8 |
9 | import java.io.IOException;
10 | import java.util.Arrays;
11 |
12 | import network.Network;
13 |
14 | public class OTPreprocessReceiver extends OTReceiver {
15 | GCSignal[] buffer = new GCSignal[OTPreprocessSender.bufferSize];
16 | boolean[] choose = new boolean[OTPreprocessSender.bufferSize];
17 | int bufferusage = 0;
18 |
19 | public void fillup() {
20 | channel.flush();
21 |
22 | while(bufferusage < OTPreprocessSender.bufferSize) {
23 | int l = Math.min(OTPreprocessSender.fillLength, OTPreprocessSender.bufferSize-bufferusage);
24 |
25 | for(int i = bufferusage; i < bufferusage+l; ++i)
26 | choose[i] = CompEnv.rnd.nextBoolean();
27 | GCSignal[] kc = null;
28 | try {
29 | kc = reciever.receive(Arrays.copyOfRange(choose, bufferusage, bufferusage+l));
30 | } catch (IOException e) {
31 | e.printStackTrace();
32 | }
33 | System.arraycopy(kc, 0, buffer, bufferusage, kc.length);
34 | bufferusage += l;
35 | }
36 |
37 | channel.flush();
38 |
39 | }
40 |
41 | OTExtReceiver reciever;
42 | public OTPreprocessReceiver(Network channel) {
43 | super(channel);
44 | reciever = new OTExtReceiver(channel);
45 | fillup();
46 | }
47 |
48 |
49 | public GCSignal receive(boolean b) throws IOException {
50 | bufferusage--;
51 | byte z = (b^choose[bufferusage]) ? (byte)1 : (byte)0;
52 | Flag.sw.startOTIO();
53 | channel.writeByte(z);
54 | channel.flush();
55 | GCSignal[] y = new GCSignal[]{GCSignal.receive(channel), GCSignal.receive(channel)};
56 | Flag.sw.stopOTIO();
57 | if(bufferusage == 0)
58 | fillup();
59 | return y[b?1:0].xor(buffer[bufferusage]);
60 | }
61 |
62 | public GCSignal[] receive(boolean[] b) throws IOException {
63 | if(bufferusage < b.length)
64 | fillup();
65 | byte[] z = new byte[b.length];
66 | int tmp = bufferusage;
67 | for(int i = 0; i < b.length; ++i) {
68 | --tmp;
69 | z[i] = (b[i]^choose[tmp]) ? (byte)1 : (byte)0;
70 | }
71 | Flag.sw.startOTIO();
72 | channel.writeByte(z, z.length);
73 | channel.flush();
74 | Flag.sw.stopOTIO();
75 | GCSignal[] ret = new GCSignal[b.length];
76 | for(int i = 0; i < b.length; ++i) {
77 | bufferusage--;
78 | Flag.sw.startOTIO();
79 | GCSignal[] y = new GCSignal[]{GCSignal.receive(channel), GCSignal.receive(channel)};
80 | Flag.sw.stopOTIO();
81 | ret[i] = y[b[i]?1:0].xor(buffer[bufferusage]);
82 | }
83 | return ret;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/ot/OTPreprocessSender.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) by Xiao Shaun Wang
2 |
3 | package ot;
4 |
5 | import flexsc.Flag;
6 | import gc.GCGenComp;
7 | import gc.GCSignal;
8 |
9 | import java.io.IOException;
10 | import java.util.Arrays;
11 |
12 | import network.Network;
13 |
14 | public class OTPreprocessSender extends OTSender {
15 | OTExtSender sender;
16 | public OTPreprocessSender(int msgBitLength, Network channel) {
17 | super(msgBitLength, channel);
18 | sender = new OTExtSender(msgBitLength, channel);
19 | fillup();
20 | }
21 |
22 | final static public int bufferSize = 1024*1024*1;
23 | final static public int fillLength = 300000;
24 | GCSignal[][] buffer = new GCSignal[bufferSize][2];
25 | int bufferusage = 0;
26 |
27 | public void fillup () {
28 |
29 | channel.flush();
30 |
31 | while(bufferusage < bufferSize) {
32 | int l = Math.min(fillLength, bufferSize-bufferusage);
33 | for(int i = bufferusage; i < bufferusage+l; ++i)
34 | buffer[i] = GCGenComp.genPair();
35 | try {
36 | sender.send(Arrays.copyOfRange(buffer, bufferusage, bufferusage+l));
37 | } catch (IOException e) {
38 | e.printStackTrace();
39 | }
40 | bufferusage +=l;
41 | System.out.println("preprocessing OT"+bufferusage/(double)bufferSize);
42 | }
43 | channel.flush();
44 | }
45 |
46 |
47 | public void send(GCSignal[] m) throws IOException {
48 | Flag.sw.startOTIO();
49 | byte z = channel.readBytes(1)[0];
50 | Flag.sw.stopOTIO();
51 | bufferusage--;
52 | if(z == 0) {
53 | m[0].xor(buffer[bufferusage][0]).send(channel);
54 | m[1].xor(buffer[bufferusage][1]).send(channel);
55 | }
56 | else {
57 | m[0].xor(buffer[bufferusage][1]).send(channel);
58 | m[1].xor(buffer[bufferusage][0]).send(channel);
59 | }
60 | if(bufferusage == 0)
61 | fillup();
62 | }
63 |
64 | public void send(GCSignal[][] m) throws IOException {
65 | if(bufferusage < m.length)
66 | fillup();
67 | Flag.sw.startOTIO();
68 | byte[] z = channel.readBytes(m.length);
69 | Flag.sw.stopOTIO();
70 | for(int i = 0; i < m.length; ++i) {
71 | bufferusage--;
72 | if(z[i] == 0) {
73 | m[i][0].xor(buffer[bufferusage][0]).send(channel);
74 | m[i][1].xor(buffer[bufferusage][1]).send(channel);
75 | }
76 | else {
77 | m[i][0].xor(buffer[bufferusage][1]).send(channel);
78 | m[i][1].xor(buffer[bufferusage][0]).send(channel);
79 | }
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/ot/OTReceiver.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2013 by Yan Huang
2 | // Improved by Xiao Shaun Wang
3 |
4 | package ot;
5 |
6 | import gc.GCSignal;
7 |
8 | import java.io.IOException;
9 |
10 | import network.Network;
11 |
12 | public abstract class OTReceiver {
13 | Network channel;
14 | int msgBitLength;
15 |
16 | public OTReceiver(Network channel) {
17 | this.channel = channel;
18 | }
19 |
20 | public abstract GCSignal receive(boolean c) throws IOException;
21 |
22 | public abstract GCSignal[] receive(boolean[] c) throws IOException;
23 | }
24 |
--------------------------------------------------------------------------------
/src/ot/OTSender.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2013 by Yan Huang
2 | // Improved by Xiao Shaun Wang
3 |
4 | package ot;
5 |
6 | import gc.GCSignal;
7 |
8 | import java.io.IOException;
9 |
10 | import network.Network;
11 |
12 | public abstract class OTSender {
13 | Network channel;
14 | int msgBitLength;
15 |
16 | public OTSender(int bitLen, Network channel) {
17 | this.channel = channel;
18 | msgBitLength = bitLen;
19 | }
20 |
21 | public abstract void send(GCSignal[] m) throws IOException;
22 |
23 | public abstract void send(GCSignal[][] m) throws IOException;
24 | }
--------------------------------------------------------------------------------
/src/rand/ISAACProvider.java:
--------------------------------------------------------------------------------
1 | package rand;
2 |
3 | /**
4 | * @author Daniel Berlin
5 | */
6 | public final class ISAACProvider extends java.security.Provider {
7 | /**
8 | *
9 | */
10 | private static final long serialVersionUID = 1L;
11 | public static final String NAME = "ISAACProvider";
12 | public static final double VERSION = 0.3;
13 | public static final String INFO = "Provider for the ISAAC PRNG";
14 |
15 | @SuppressWarnings({ "unchecked", "rawtypes" })
16 | public ISAACProvider() {
17 | super(NAME, VERSION, INFO);
18 |
19 | java.security.AccessController
20 | .doPrivileged(new java.security.PrivilegedAction() {
21 | public Object run() {
22 | put("SecureRandom.ISAACRandom", "rand.ISAACEngine");
23 | return (null);
24 | }
25 | });
26 | }
27 | }
--------------------------------------------------------------------------------
/src/util/ConfigParser.java:
--------------------------------------------------------------------------------
1 | package util;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 | import java.util.HashMap;
6 | import java.util.Scanner;
7 |
8 | public class ConfigParser {
9 | HashMap config;
10 | public ConfigParser (String filename) {
11 | File file = new File(filename);
12 | Scanner scanner = null;
13 | config = new HashMap();
14 | try {
15 | scanner = new Scanner(file);
16 | while(scanner.hasNextLine()) {
17 | String a = scanner.nextLine();
18 | String[] content = a.split(":");
19 | if(!a.startsWith("#") && content.length == 2) {
20 | config.put(content[0].trim(), content[1].trim());
21 | }
22 | }
23 | } catch (FileNotFoundException e) {
24 | // TODO Auto-generated catch block
25 | e.printStackTrace();
26 | }
27 | scanner.close();
28 | }
29 |
30 | public String getString(String string){
31 | return config.get(string);
32 | }
33 |
34 | public long getLong(String string){
35 | return new Long(config.get(string));
36 | }
37 |
38 | public int getInt(String string){
39 | return new Integer(config.get(string));
40 | }
41 | public boolean getBool(String string){
42 | return config.get(string).contains("T")||config.get(string).contains("True")
43 | ||config.get(string).contains("true")||config.get(string).contains("Yes")
44 | ||config.get(string).contains("yes");
45 | }
46 | }
--------------------------------------------------------------------------------
/src/util/Constants.java:
--------------------------------------------------------------------------------
1 | package util;
2 |
3 | public class Constants {
4 | public static final String MACHINE_SPEC = "machine_spec/";
5 | public static final String INPUT_DIR = "in/";
6 | public static final int OFFLINE_FILE_BUFFER_SIZE = 1024 * 1024 * 1024;
7 | }
--------------------------------------------------------------------------------
/src/util/EvaRunnable.java:
--------------------------------------------------------------------------------
1 | package util;
2 |
3 | import java.util.Arrays;
4 |
5 | import org.apache.commons.cli.ParseException;
6 |
7 | import flexsc.CompEnv;
8 | import flexsc.Flag;
9 | import flexsc.Mode;
10 | import flexsc.Party;
11 |
12 | public abstract class EvaRunnable extends network.Client implements Runnable {
13 | public abstract void prepareInput(CompEnv gen) throws Exception;
14 | public abstract void secureCompute(CompEnv gen) throws Exception;
15 | public abstract void prepareOutput(CompEnv gen) throws Exception;
16 | Mode m;
17 | int port;
18 | String host;
19 | protected String[] args;
20 | public boolean verbose = true;
21 | public ConfigParser config;
22 | public void setParameter(ConfigParser config, String[] args) {
23 | this.m = Mode.getMode(config.getString("Mode"));
24 | this.port = config.getInt("Port");
25 | host = config.getString("Host");
26 | this.args = args;
27 | this.config = config;
28 | }
29 |
30 | public void setParameter(Mode m, String host, int port){
31 | this.m = m;
32 | this.port = port;
33 | this.host = host;
34 | }
35 |
36 | public void run() {
37 | try {
38 | if(verbose)
39 | System.out.println("connecting");
40 | connect(host, port);
41 | if(verbose)
42 | System.out.println("connected");
43 |
44 | @SuppressWarnings("unchecked")
45 | CompEnv env = CompEnv.getEnv(m, Party.Bob, this);
46 |
47 | double s = System.nanoTime();
48 | Flag.sw.startTotal();
49 | prepareInput(env);
50 | os.flush();
51 | secureCompute(env);
52 | os.flush();
53 | prepareOutput(env);
54 | os.flush();
55 | Flag.sw.stopTotal();
56 | double e = System.nanoTime();
57 | disconnect();
58 | if(verbose){
59 | System.out.println("Eva running time:"+(e-s)/1e9);
60 | System.out.println("Number Of AND Gates:"+env.numOfAnds);
61 | }
62 | } catch (Exception e) {
63 | e.printStackTrace();
64 | System.exit(1);
65 | }
66 | }
67 |
68 | @SuppressWarnings("rawtypes")
69 | public static void main(String[] args) throws InstantiationException, IllegalAccessException, ParseException, ClassNotFoundException {
70 | ConfigParser config = new ConfigParser("Config.conf");
71 |
72 | Class> clazz = Class.forName(args[0]+"$Evaluator");
73 | EvaRunnable run = (EvaRunnable) clazz.newInstance();
74 | run.setParameter(config, Arrays.copyOfRange(args, 1, args.length));
75 | run.run();
76 | if(Flag.CountTime)
77 | Flag.sw.print();
78 | if(Flag.countIO)
79 | run.printStatistic();
80 | }
81 | }
--------------------------------------------------------------------------------
/src/util/GenRunnable.java:
--------------------------------------------------------------------------------
1 | package util;
2 |
3 | import java.util.Arrays;
4 |
5 | import org.apache.commons.cli.ParseException;
6 |
7 | import flexsc.CompEnv;
8 | import flexsc.Flag;
9 | import flexsc.Mode;
10 | import flexsc.Party;
11 |
12 | public abstract class GenRunnable extends network.Server implements Runnable {
13 |
14 | Mode m;
15 | int port;
16 | protected String[] args;
17 | public boolean verbose = true;
18 | public ConfigParser config;
19 | public void setParameter(ConfigParser config, String[] args) {
20 | this.m = Mode.getMode(config.getString("Mode"));
21 | this.port = config.getInt("Port");
22 | this.args = args;
23 | this.config = config;
24 | }
25 |
26 | public void setParameter(Mode m, int port) {
27 | this.m = m;
28 | this.port = port;
29 | }
30 |
31 | public abstract void prepareInput(CompEnv gen) throws Exception;
32 | public abstract void secureCompute(CompEnv gen) throws Exception;
33 | public abstract void prepareOutput(CompEnv gen) throws Exception;
34 |
35 | public void run() {
36 | try {
37 | if(verbose)
38 | System.out.println("connecting");
39 | listen(port);
40 | if(verbose)
41 | System.out.println("connected");
42 |
43 | @SuppressWarnings("unchecked")
44 | CompEnv env = CompEnv.getEnv(m, Party.Alice, this);
45 |
46 | double s = System.nanoTime();
47 | Flag.sw.startTotal();
48 | prepareInput(env);
49 | os.flush();
50 | secureCompute(env);
51 | os.flush();
52 | prepareOutput(env);
53 | os.flush();
54 | Flag.sw.stopTotal();
55 | double e = System.nanoTime();
56 | disconnect();
57 | if(verbose) {
58 | System.out.println("Gen running time:"+(e-s)/1e9);
59 | System.out.println(env.numOfAnds);
60 | }
61 | } catch (Exception e) {
62 | e.printStackTrace();
63 | System.exit(1);
64 | }
65 | }
66 |
67 |
68 | @SuppressWarnings("rawtypes")
69 | public static void main(String[] args) throws ParseException, ClassNotFoundException, InstantiationException, IllegalAccessException {
70 | ConfigParser config = new ConfigParser("Config.conf");
71 |
72 | Class> clazz = Class.forName(args[0]+"$Generator");
73 | GenRunnable run = (GenRunnable) clazz.newInstance();
74 | run.setParameter(config, Arrays.copyOfRange(args, 1, args.length));
75 | run.run();
76 | if(Flag.CountTime)
77 | Flag.sw.print();
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/util/StopWatch.java:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2014 by Xiao Shaun Wang
2 | package util;
3 |
4 | public class StopWatch {
5 | public long ands = 0;
6 | double startTimeOT = 0;
7 | double stopTimeOT = 0;
8 | public double elapsedTimeOT = 0;
9 |
10 | double startTimeGC = 0;
11 | double stopTimeGC = 0;
12 | public double elapsedTimeGC = 0;
13 |
14 | double startTimeTotal = 0;
15 | double stopTimeTotal = 0;
16 | public double elapsedTimeTotal = 0;
17 |
18 | double startTimeOTIO = 0;
19 | double stopTimeOTIO = 0;
20 | public double elapsedTimeOTIO = 0;
21 |
22 | double startTimeGCIO = 0;
23 | double stopTimeGCIO = 0;
24 | public double elapsedTimeGCIO = 0;
25 | boolean countTime;
26 | long counter = 1;
27 |
28 | public StopWatch(boolean countTime) {
29 | this.countTime = countTime;
30 | }
31 |
32 | public void startOT() {
33 | if (countTime)
34 | startTimeOT = System.nanoTime();
35 | }
36 |
37 | public void stopOT() {
38 | if (countTime) {
39 | stopTimeOT = System.nanoTime();
40 | elapsedTimeOT += stopTimeOT - startTimeOT;
41 | }
42 | }
43 |
44 | public void startOTIO() {
45 | if (countTime)
46 | startTimeOTIO = System.nanoTime();
47 | }
48 |
49 | public void stopOTIO() {
50 | if (countTime) {
51 | stopTimeOTIO = System.nanoTime();
52 | elapsedTimeOTIO += stopTimeOTIO - startTimeOTIO;
53 | }
54 | }
55 |
56 | public void startGC() {
57 | if (countTime)
58 | startTimeGC = System.nanoTime();
59 | }
60 |
61 | public void stopGC() {
62 | if (countTime) {
63 | stopTimeGC = System.nanoTime();
64 | elapsedTimeGC += stopTimeGC - startTimeGC;
65 | }
66 | }
67 |
68 | public void startGCIO() {
69 | if (countTime)
70 | startTimeGCIO = System.nanoTime();
71 | }
72 |
73 | public void stopGCIO() {
74 | if (countTime) {
75 | stopTimeGCIO = System.nanoTime();
76 | elapsedTimeGCIO += stopTimeGCIO - startTimeGCIO;
77 | }
78 | }
79 |
80 | public void startTotal() {
81 | startTimeTotal = System.nanoTime();
82 | }
83 |
84 | public double stopTotal() {
85 | stopTimeTotal = System.nanoTime();
86 | elapsedTimeTotal += stopTimeTotal - startTimeTotal;
87 | return stopTimeTotal - startTimeTotal;
88 | }
89 |
90 | public void addCounter() {
91 | ++counter;
92 | }
93 |
94 | public void flush() {
95 | ands = 0;
96 | startTimeOT = 0;
97 | stopTimeOT = 0;
98 | elapsedTimeOT = 0;
99 |
100 | startTimeGC = 0;
101 | stopTimeGC = 0;
102 | elapsedTimeGC = 0;
103 |
104 | startTimeTotal = 0;
105 | stopTimeTotal = 0;
106 | elapsedTimeTotal = 0;
107 |
108 | startTimeOTIO = 0;
109 | stopTimeOTIO = 0;
110 | elapsedTimeOTIO = 0;
111 |
112 | startTimeGCIO = 0;
113 | stopTimeGCIO = 0;
114 | elapsedTimeGCIO = 0;
115 | counter = 1;
116 |
117 | }
118 |
119 | public void print() {
120 | System.out
121 | .println("Total Time \t GC CPU Time\t GCIO Time\t OTCPU Time\t OTIO Time\n");
122 | System.out.println(elapsedTimeTotal / 1000000000.0 / counter + "\t"
123 | + (elapsedTimeGC - elapsedTimeGCIO) / 1000000000.0 / counter
124 | + "\t" + elapsedTimeGCIO / 1000000000.0 / counter + " "
125 | + (elapsedTimeOT - elapsedTimeOTIO) / 1000000000.0 / counter
126 | + "\t" + elapsedTimeOTIO / 1000000000.0 / counter + "\n");
127 | System.out.println("Number of Gate:"+ands);
128 | }
129 |
130 | public void print(int i) {
131 | System.out.println("timer:\t"+i+" \t"+elapsedTimeTotal / 1000000000.0 / counter + "\t"
132 | + (elapsedTimeGC - elapsedTimeGCIO) / 1000000000.0 / counter
133 | + "\t" + elapsedTimeGCIO / 1000000000.0 / counter + " "
134 | + (elapsedTimeOT - elapsedTimeOTIO) / 1000000000.0 / counter
135 | + "\t" + elapsedTimeOTIO / 1000000000.0 / counter + "\n");
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/test/component/TestISAACRandom.java:
--------------------------------------------------------------------------------
1 | package component;
2 |
3 | import java.math.BigInteger;
4 | import java.security.NoSuchAlgorithmException;
5 | import java.security.SecureRandom;
6 | import java.security.Security;
7 |
8 | import rand.ISAACProvider;
9 |
10 | public class TestISAACRandom {
11 | public static void main(String[] args) throws NoSuchAlgorithmException {
12 | // Add the provider to make Java aware of ISAAC
13 | Security.addProvider(new ISAACProvider());
14 |
15 | // Instanciate ISAAC
16 | SecureRandom isaac = SecureRandom.getInstance("ISAACRandom");
17 |
18 | // The engine's constructor (which handles all calls to the algorithm)
19 | // auto-seeds
20 | // the new instance. Setting the seed is optional. See ISAACEngine.
21 | // Two instances will never (unless SecureRandom's getSeed method
22 | // returns the same data)
23 | // return the same random data. Try running this demo twice and compare
24 | // the output...
25 | //
26 | // isaac.setSeed (new byte[] {1, 2, 3, 4, 5});
27 |
28 | // Fetch some random data
29 | for (int i = 0; i < 10; i++) {
30 | for (int j = 0; j < 10; j++) {
31 | // Get 4 fresh random bytes...
32 | byte[] random = new byte[4];
33 | isaac.nextBytes(random);
34 |
35 | // ... and make an integer from these bytes ...
36 | int randomInt = new BigInteger(random).intValue();
37 |
38 | // "Prettyfy" the integer
39 | String output = Integer.toHexString(randomInt);
40 | while (output.length() < 8)
41 | output = "0" + output;
42 |
43 | // Print it
44 | System.out.print(output + " ");
45 | }
46 | System.out.println("");
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/test/harness/TestBigInteger.java:
--------------------------------------------------------------------------------
1 | package harness;
2 |
3 | import java.math.BigInteger;
4 |
5 | import org.junit.Assert;
6 |
7 | import util.EvaRunnable;
8 | import util.GenRunnable;
9 | import util.Utils;
10 | import flexsc.CompEnv;
11 | import flexsc.Mode;
12 | import flexsc.PMCompEnv;
13 | import gc.BadLabelException;
14 |
15 |
16 |
17 | public class TestBigInteger extends TestHarness{
18 | public static final int LENGTH = 799;
19 | final static int RANGE = LENGTH;
20 | public static abstract class Helper {
21 | BigInteger intA, intB;
22 | boolean[] a;
23 | boolean[] b;
24 | public Helper(BigInteger aa, BigInteger bb) {
25 | intA = aa;
26 | intB = bb;
27 |
28 | a = Utils.fromBigInteger(aa, RANGE);
29 | b = Utils.fromBigInteger(bb, RANGE);
30 | }
31 | public abstract T[] secureCompute(T[] Signala, T[] Signalb, CompEnv e);
32 | public abstract BigInteger plainCompute(BigInteger x, BigInteger y);
33 | }
34 |
35 | public static class GenRunnableTestBigInteger extends GenRunnable {
36 | public double andgates;
37 | public double encs;
38 |
39 | boolean[] z;
40 | Helper h;
41 | public GenRunnableTestBigInteger(Helper h) {
42 | this.h = h;
43 | verbose = false;
44 | }
45 |
46 | T[] a;
47 | T[] b;
48 | T[] d;
49 | @Override
50 | public void prepareInput(CompEnv gen) {
51 | a = gen.inputOfAlice(h.a);
52 | b = gen.inputOfBob(new boolean[LENGTH]);
53 | }
54 |
55 | @Override
56 | public void secureCompute(CompEnv gen) {
57 | d = h.secureCompute(a, b, gen);
58 | }
59 |
60 | @Override
61 | public void prepareOutput(CompEnv gen) throws BadLabelException {
62 | z = gen.outputToAlice(d);
63 | if (m == Mode.COUNT) {
64 | ((PMCompEnv) gen).statistic.finalize();
65 | andgates = ((PMCompEnv) gen).statistic.andGate;
66 | encs = ((PMCompEnv) gen).statistic.NumEncAlice;
67 | System.out.println(andgates + " " + encs);
68 | } else {
69 |
70 | // System.out.println(Arrays.toString( Utils.fromBigInteger(h.plainCompute(h.intA, h.intB), z.length)));
71 | // System.out.println(Arrays.toString(Utils.fromBigInteger(Utils.toBigInteger(z), z.length)));
72 |
73 | Assert.assertEquals(h.plainCompute(h.intA, h.intB), Utils.toBigInteger(z));
74 | }
75 | }
76 | }
77 |
78 | public static class EvaRunnableTestBigInteger extends EvaRunnable {
79 | EvaRunnableTestBigInteger(Helper h) {
80 | this.h = h;
81 | verbose = false;
82 | }
83 |
84 | Helper h;
85 | T[] a;
86 | T[] b;
87 | T[] d;
88 |
89 | @Override
90 | public void prepareInput(CompEnv env) {
91 | a = env.inputOfAlice(new boolean[LENGTH]);
92 | b = env.inputOfBob(h.b);
93 | }
94 |
95 | @Override
96 | public void secureCompute(CompEnv env) {
97 | d = h.secureCompute(a, b, env);
98 | }
99 |
100 | @Override
101 | public void prepareOutput(CompEnv env) throws BadLabelException {
102 | env.outputToAlice(d);
103 | }
104 | }
105 | static public void runThreads(Helper h) throws Exception {
106 | GenRunnable gen = new GenRunnableTestBigInteger(h);
107 | gen.setParameter(m, 54321);
108 | EvaRunnable env = new EvaRunnableTestBigInteger(h);
109 | env.setParameter(m, "localhost", 54321);
110 | Thread tGen = new Thread(gen);
111 | Thread tEva = new Thread(env);
112 | tGen.start();
113 | Thread.sleep(5);
114 | tEva.start();
115 | tGen.join();
116 | tEva.join();
117 | }
118 | }
--------------------------------------------------------------------------------
/test/harness/TestFixedPoint.java:
--------------------------------------------------------------------------------
1 | package harness;
2 |
3 | import org.junit.Assert;
4 |
5 | import util.EvaRunnable;
6 | import util.GenRunnable;
7 | import util.Utils;
8 | import flexsc.CompEnv;
9 | import flexsc.Mode;
10 | import flexsc.PMCompEnv;
11 | import gc.BadLabelException;
12 |
13 | public class TestFixedPoint extends TestHarness {
14 | public static final int width = 40, offset = 20;
15 |
16 | public static abstract class Helper {
17 | double a, b;
18 |
19 | public Helper(double a, double b) {
20 | this.b = b;
21 | this.a = a;
22 | }
23 |
24 | public abstract