From 387283b0b36ee030d09f28796de2ec0eba65414f Mon Sep 17 00:00:00 2001
From: Nikolaj Volgushev
Date: Mon, 16 Apr 2018 23:14:31 +0200
Subject: [PATCH 001/231] Arithmetic AND and XOR
---
.../fresco/lib/compare/gt/CarryBits.java | 27 +++++++++
.../binary/ArithmeticAndKnownRight.java | 51 +++++++++++++++++
.../binary/ArithmeticXorKnownRight.java | 55 +++++++++++++++++++
3 files changed, 133 insertions(+)
create mode 100644 core/src/main/java/dk/alexandra/fresco/lib/compare/gt/CarryBits.java
create mode 100644 core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticAndKnownRight.java
create mode 100644 core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticXorKnownRight.java
diff --git a/core/src/main/java/dk/alexandra/fresco/lib/compare/gt/CarryBits.java b/core/src/main/java/dk/alexandra/fresco/lib/compare/gt/CarryBits.java
new file mode 100644
index 000000000..1df89d76d
--- /dev/null
+++ b/core/src/main/java/dk/alexandra/fresco/lib/compare/gt/CarryBits.java
@@ -0,0 +1,27 @@
+package dk.alexandra.fresco.lib.compare.gt;
+
+import dk.alexandra.fresco.framework.DRes;
+import dk.alexandra.fresco.framework.builder.Computation;
+import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric;
+import dk.alexandra.fresco.framework.value.SInt;
+import java.math.BigInteger;
+import java.util.List;
+
+public class CarryBits implements Computation>, ProtocolBuilderNumeric> {
+
+ private final List> valuesA;
+ private final List> valuesB;
+ private final int k;
+
+ public CarryBits(List> valuesA, List> valuesB) {
+ this.valuesA = valuesA;
+ this.valuesB = valuesB;
+ this.k = valuesA.size();
+ }
+
+ @Override
+ public DRes>> buildComputation(ProtocolBuilderNumeric builder) {
+ return null;
+ }
+
+}
diff --git a/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticAndKnownRight.java b/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticAndKnownRight.java
new file mode 100644
index 000000000..7c97be1ed
--- /dev/null
+++ b/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticAndKnownRight.java
@@ -0,0 +1,51 @@
+package dk.alexandra.fresco.lib.math.integer.binary;
+
+import dk.alexandra.fresco.framework.DRes;
+import dk.alexandra.fresco.framework.builder.Computation;
+import dk.alexandra.fresco.framework.builder.numeric.Numeric;
+import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric;
+import dk.alexandra.fresco.framework.value.SInt;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Computes logical AND for each bit in the two lists. Bits are represented as arithmetic
+ * elements. The AND operation is expressed via an arithmetic gate.
+ */
+public class ArithmeticAndKnownRight implements
+ Computation>, ProtocolBuilderNumeric> {
+
+ private final DRes>> leftBits;
+ private final DRes>> rightBits;
+
+ /**
+ * Constructs new {@link ArithmeticXorKnownRight}.
+ *
+ * @param leftBits secret bits represented as arithmetic elements
+ * @param rightBits open bits represented as arithmetic elements
+ */
+ public ArithmeticAndKnownRight(
+ DRes>> leftBits,
+ DRes>> rightBits) {
+ this.leftBits = leftBits;
+ this.rightBits = rightBits;
+ }
+
+ @Override
+ public DRes>> buildComputation(ProtocolBuilderNumeric builder) {
+ List> leftOut = leftBits.out();
+ List> rightOut = rightBits.out();
+ List> andedBits = new ArrayList<>(leftOut.size());
+ Numeric nb = builder.numeric();
+ for (int i = 0; i < leftOut.size(); i++) {
+ DRes leftBit = leftOut.get(i);
+ BigInteger rightBit = rightOut.get(i).out();
+ // logical and of two bits can be computed as product
+ DRes andedBit = nb.mult(rightBit, leftBit);
+ andedBits.add(andedBit);
+ }
+ return () -> andedBits;
+ }
+
+}
diff --git a/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticXorKnownRight.java b/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticXorKnownRight.java
new file mode 100644
index 000000000..4d14822b3
--- /dev/null
+++ b/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticXorKnownRight.java
@@ -0,0 +1,55 @@
+package dk.alexandra.fresco.lib.math.integer.binary;
+
+import dk.alexandra.fresco.framework.DRes;
+import dk.alexandra.fresco.framework.builder.Computation;
+import dk.alexandra.fresco.framework.builder.numeric.Numeric;
+import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric;
+import dk.alexandra.fresco.framework.value.SInt;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Computes logical XOR for each bit in the two lists. Bits are represented as represented as
+ * arithmetic elements. The XOR operation is expressed via an arithmetic gate.
+ */
+public class ArithmeticXorKnownRight implements
+ Computation>, ProtocolBuilderNumeric> {
+
+ private static final BigInteger TWO = BigInteger.valueOf(2);
+ private final DRes>> leftBits;
+ private final DRes>> rightBits;
+
+ /**
+ * Constructs new {@link ArithmeticXorKnownRight}.
+ *
+ * @param leftBits secret bits represented as arithmetic elements
+ * @param rightBits open bits represented as arithmetic elements
+ */
+ public ArithmeticXorKnownRight(
+ DRes>> leftBits,
+ DRes>> rightBits) {
+ this.leftBits = leftBits;
+ this.rightBits = rightBits;
+ }
+
+ @Override
+ public DRes>> buildComputation(ProtocolBuilderNumeric builder) {
+ List> leftOut = leftBits.out();
+ List> rightOut = rightBits.out();
+ List> xoredBits = new ArrayList<>(leftOut.size());
+ Numeric nb = builder.numeric();
+ for (int i = 0; i < leftOut.size(); i++) {
+ DRes leftBit = leftOut.get(i);
+ BigInteger rightBit = rightOut.get(i).out();
+ // logical xor of two bits can be computed as leftBit + rightBit - 2 * leftBit * rightBit
+ DRes xoredBit = nb.sub(
+ nb.add(rightBit, leftBit),
+ nb.mult(TWO, nb.mult(rightBit, leftBit))
+ );
+ xoredBits.add(xoredBit);
+ }
+ return () -> xoredBits;
+ }
+
+}
From 9831b4162e93a9b4831bae1d8d79fb9d25a2edf6 Mon Sep 17 00:00:00 2001
From: Nikolaj Volgushev
Date: Tue, 17 Apr 2018 09:24:51 +0200
Subject: [PATCH 002/231] Make comps parallel
---
.../integer/binary/ArithmeticAndKnownRight.java | 8 +++-----
.../integer/binary/ArithmeticXorKnownRight.java | 16 +++++++++-------
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticAndKnownRight.java b/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticAndKnownRight.java
index 7c97be1ed..9ebebea8a 100644
--- a/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticAndKnownRight.java
+++ b/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticAndKnownRight.java
@@ -1,8 +1,7 @@
package dk.alexandra.fresco.lib.math.integer.binary;
import dk.alexandra.fresco.framework.DRes;
-import dk.alexandra.fresco.framework.builder.Computation;
-import dk.alexandra.fresco.framework.builder.numeric.Numeric;
+import dk.alexandra.fresco.framework.builder.ComputationParallel;
import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric;
import dk.alexandra.fresco.framework.value.SInt;
import java.math.BigInteger;
@@ -14,7 +13,7 @@
* elements. The AND operation is expressed via an arithmetic gate.
*/
public class ArithmeticAndKnownRight implements
- Computation>, ProtocolBuilderNumeric> {
+ ComputationParallel>, ProtocolBuilderNumeric> {
private final DRes>> leftBits;
private final DRes>> rightBits;
@@ -37,12 +36,11 @@ public DRes>> buildComputation(ProtocolBuilderNumeric builder) {
List> leftOut = leftBits.out();
List> rightOut = rightBits.out();
List> andedBits = new ArrayList<>(leftOut.size());
- Numeric nb = builder.numeric();
for (int i = 0; i < leftOut.size(); i++) {
DRes leftBit = leftOut.get(i);
BigInteger rightBit = rightOut.get(i).out();
// logical and of two bits can be computed as product
- DRes andedBit = nb.mult(rightBit, leftBit);
+ DRes andedBit = builder.seq(seq -> builder.numeric().mult(rightBit, leftBit));
andedBits.add(andedBit);
}
return () -> andedBits;
diff --git a/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticXorKnownRight.java b/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticXorKnownRight.java
index 4d14822b3..f0c7e38c3 100644
--- a/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticXorKnownRight.java
+++ b/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticXorKnownRight.java
@@ -1,7 +1,7 @@
package dk.alexandra.fresco.lib.math.integer.binary;
import dk.alexandra.fresco.framework.DRes;
-import dk.alexandra.fresco.framework.builder.Computation;
+import dk.alexandra.fresco.framework.builder.ComputationParallel;
import dk.alexandra.fresco.framework.builder.numeric.Numeric;
import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric;
import dk.alexandra.fresco.framework.value.SInt;
@@ -14,7 +14,7 @@
* arithmetic elements. The XOR operation is expressed via an arithmetic gate.
*/
public class ArithmeticXorKnownRight implements
- Computation>, ProtocolBuilderNumeric> {
+ ComputationParallel>, ProtocolBuilderNumeric> {
private static final BigInteger TWO = BigInteger.valueOf(2);
private final DRes>> leftBits;
@@ -38,15 +38,17 @@ public DRes>> buildComputation(ProtocolBuilderNumeric builder) {
List> leftOut = leftBits.out();
List> rightOut = rightBits.out();
List> xoredBits = new ArrayList<>(leftOut.size());
- Numeric nb = builder.numeric();
for (int i = 0; i < leftOut.size(); i++) {
DRes leftBit = leftOut.get(i);
BigInteger rightBit = rightOut.get(i).out();
// logical xor of two bits can be computed as leftBit + rightBit - 2 * leftBit * rightBit
- DRes xoredBit = nb.sub(
- nb.add(rightBit, leftBit),
- nb.mult(TWO, nb.mult(rightBit, leftBit))
- );
+ DRes xoredBit = builder.seq(seq -> {
+ Numeric nb = builder.numeric();
+ return nb.sub(
+ nb.add(rightBit, leftBit),
+ nb.mult(TWO, nb.mult(rightBit, leftBit))
+ );
+ });
xoredBits.add(xoredBit);
}
return () -> xoredBits;
From 724aa64dadab0b9f5fd4e2c1ba898d98180cc6ee Mon Sep 17 00:00:00 2001
From: Nikolaj Volgushev
Date: Tue, 17 Apr 2018 09:53:38 +0200
Subject: [PATCH 003/231] Logical and and xor tests
---
.../builder/numeric/Collections.java | 30 ++---
.../binary/ArithmeticAndKnownRight.java | 2 +-
.../binary/ArithmeticXorKnownRight.java | 2 +-
.../integer/binary/BinaryOperationsTests.java | 105 ++++++++++++++++--
.../TestDummyArithmeticProtocolSuite.java | 12 ++
5 files changed, 125 insertions(+), 26 deletions(-)
diff --git a/core/src/main/java/dk/alexandra/fresco/framework/builder/numeric/Collections.java b/core/src/main/java/dk/alexandra/fresco/framework/builder/numeric/Collections.java
index 171abb4b9..9a58dbdbe 100644
--- a/core/src/main/java/dk/alexandra/fresco/framework/builder/numeric/Collections.java
+++ b/core/src/main/java/dk/alexandra/fresco/framework/builder/numeric/Collections.java
@@ -22,7 +22,7 @@ public interface Collections extends ComputationDirectory {
* @param closedPair secret values
* @return opened values
*/
- public DRes, DRes>> openPair(
+ DRes, DRes>> openPair(
DRes, DRes>> closedPair);
/**
@@ -31,7 +31,7 @@ public DRes, DRes>> openPair(
* @param closedPair secret values
* @return openened rows
*/
- public DRes> openRowPair(DRes> closedPair);
+ DRes> openRowPair(DRes> closedPair);
/**
* Closes list of input values.
@@ -41,7 +41,7 @@ public DRes, DRes>> openPair(
* @param inputParty party providing input
* @return closed list
*/
- public DRes>> closeList(List openList, int inputParty);
+ DRes>> closeList(List openList, int inputParty);
/**
* Closes list of input values.
@@ -51,7 +51,7 @@ public DRes, DRes>> openPair(
* @param inputParty party providing input
* @return closed list
*/
- public DRes>> closeList(int numberOfInputs, int inputParty);
+ DRes>> closeList(int numberOfInputs, int inputParty);
/**
* Opens list of secret values.
@@ -59,7 +59,7 @@ public DRes, DRes>> openPair(
* @param closedList secret values
* @return closed values
*/
- public DRes>> openList(DRes>> closedList);
+ DRes>> openList(DRes>> closedList);
/**
* Closes matrix of input values.
@@ -69,7 +69,7 @@ public DRes, DRes>> openPair(
* @param inputParty party providing input
* @return closed matrix
*/
- public DRes>> closeMatrix(Matrix openMatrix, int inputParty);
+ DRes>> closeMatrix(Matrix openMatrix, int inputParty);
/**
* Closes matrix of input values.
@@ -80,7 +80,7 @@ public DRes, DRes>> openPair(
* @param inputParty party providing input
* @return closed matrix
*/
- public DRes>> closeMatrix(int h, int w, int inputParty);
+ DRes>> closeMatrix(int h, int w, int inputParty);
/**
* Opens matrix of secret values.
@@ -88,7 +88,7 @@ public DRes, DRes>> openPair(
* @param closedMatrix input matrix
* @return open matrix
*/
- public DRes>> openMatrix(DRes>> closedMatrix);
+ DRes>> openMatrix(DRes>> closedMatrix);
// Conditional
@@ -100,7 +100,7 @@ public DRes, DRes>> openPair(
* @param right right row
* @return left if condition right otherwise
*/
- public DRes>> condSelect(DRes condition, DRes>> left,
+ DRes>> condSelect(DRes condition, DRes>> left,
DRes>> right);
/**
@@ -112,7 +112,7 @@ public DRes>> condSelect(DRes condition, DRes> swapIf(DRes condition, DRes>> left,
+ DRes> swapIf(DRes condition, DRes>> left,
DRes>> right);
/**
@@ -122,7 +122,7 @@ public DRes> swapIf(DRes condition, DRes>> swapNeighborsIf(DRes>> conditions,
+ DRes>> swapNeighborsIf(DRes>> conditions,
DRes>> mat);
// Permutations
@@ -135,7 +135,7 @@ public DRes>> swapNeighborsIf(DRes>> condition
* @param idxPerm encodes the desired permutation by supplying for each index a new index
* @return permuted rows
*/
- public DRes>> permute(DRes>> values, int[] idxPerm);
+ DRes>> permute(DRes>> values, int[] idxPerm);
/**
* Permutes the rows of values according to idxPerm.
@@ -145,7 +145,7 @@ public DRes>> swapNeighborsIf(DRes>> condition
* @param permProviderPid the ID of the party choosing permutation
* @return permuted rows
*/
- public DRes>> permute(DRes>> values, int permProviderPid);
+ DRes>> permute(DRes>> values, int permProviderPid);
/**
* Randomly permutes (shuffles) rows of values. Uses secure source of randomness.
@@ -153,7 +153,7 @@ public DRes>> swapNeighborsIf(DRes>> condition
* @param values rows to shuffle
* @return shuffled rows
*/
- public DRes>> shuffle(DRes>> values);
+ DRes>> shuffle(DRes>> values);
// Relational (SQL-like) operators
@@ -168,7 +168,7 @@ public DRes>> swapNeighborsIf(DRes>> condition
* @param aggColIdx column to aggregate
* @return aggregated result
*/
- public DRes>> leakyAggregateSum(DRes>> values,
+ DRes>> leakyAggregateSum(DRes>> values,
int groupColIdx, int aggColIdx);
}
diff --git a/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticAndKnownRight.java b/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticAndKnownRight.java
index 9ebebea8a..3ce36918c 100644
--- a/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticAndKnownRight.java
+++ b/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticAndKnownRight.java
@@ -40,7 +40,7 @@ public DRes>> buildComputation(ProtocolBuilderNumeric builder) {
DRes leftBit = leftOut.get(i);
BigInteger rightBit = rightOut.get(i).out();
// logical and of two bits can be computed as product
- DRes andedBit = builder.seq(seq -> builder.numeric().mult(rightBit, leftBit));
+ DRes andedBit = builder.seq(seq -> seq.numeric().mult(rightBit, leftBit));
andedBits.add(andedBit);
}
return () -> andedBits;
diff --git a/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticXorKnownRight.java b/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticXorKnownRight.java
index f0c7e38c3..148188bd9 100644
--- a/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticXorKnownRight.java
+++ b/core/src/main/java/dk/alexandra/fresco/lib/math/integer/binary/ArithmeticXorKnownRight.java
@@ -43,7 +43,7 @@ public DRes>> buildComputation(ProtocolBuilderNumeric builder) {
BigInteger rightBit = rightOut.get(i).out();
// logical xor of two bits can be computed as leftBit + rightBit - 2 * leftBit * rightBit
DRes xoredBit = builder.seq(seq -> {
- Numeric nb = builder.numeric();
+ Numeric nb = seq.numeric();
return nb.sub(
nb.add(rightBit, leftBit),
nb.mult(TWO, nb.mult(rightBit, leftBit))
diff --git a/core/src/test/java/dk/alexandra/fresco/lib/math/integer/binary/BinaryOperationsTests.java b/core/src/test/java/dk/alexandra/fresco/lib/math/integer/binary/BinaryOperationsTests.java
index 2fc9e1e80..5eecad1c9 100644
--- a/core/src/test/java/dk/alexandra/fresco/lib/math/integer/binary/BinaryOperationsTests.java
+++ b/core/src/test/java/dk/alexandra/fresco/lib/math/integer/binary/BinaryOperationsTests.java
@@ -17,11 +17,8 @@
/**
- * Generic test cases for basic finite field operations.
- *
- * Can be reused by a test case for any protocol suite that implements the basic field protocol
- * factory.
- *
+ * Generic test cases for basic finite field operations. Can be reused by a test case for any
+ * protocol suite that implements the basic field protocol factory.
*/
public class BinaryOperationsTests {
@@ -39,7 +36,7 @@ public TestThread next() {
private final int shifts = 3;
@Override
- public void test() throws Exception {
+ public void test() {
Application, ProtocolBuilderNumeric> app =
(ProtocolBuilderNumeric builder) -> {
AdvancedNumeric rightShift = builder.advancedNumeric();
@@ -52,7 +49,7 @@ public void test() throws Exception {
builder.numeric().open(() -> shiftedRight.out().getRemainder());
return () -> Arrays.asList(openResult.out(), openRemainder.out());
};
- List output = runApplication(app);
+ List output = runApplication(app);
Assert.assertEquals(input.shiftRight(shifts), output.get(0));
Assert.assertEquals(input.mod(BigInteger.ONE.shiftLeft(shifts)), output.get(1));
@@ -75,7 +72,7 @@ public TestThread next() {
private final BigInteger input = BigInteger.valueOf(5);
@Override
- public void test() throws Exception {
+ public void test() {
Application app = builder -> {
DRes sharedInput = builder.numeric().known(input);
AdvancedNumeric bitLengthBuilder = builder.advancedNumeric();
@@ -104,7 +101,7 @@ public TestThread next() {
private final int max = 16;
@Override
- public void test() throws Exception {
+ public void test() {
Application, ProtocolBuilderNumeric> app =
producer -> producer.seq(builder -> {
DRes sharedInput = builder.numeric().known(input);
@@ -123,4 +120,94 @@ public void test() throws Exception {
};
}
}
+
+ public static class TestArithmeticAndKnownRight
+ extends TestThreadFactory {
+
+ @Override
+ public TestThread next() {
+
+ return new TestThread() {
+ private final List left = Arrays.asList(
+ BigInteger.ONE,
+ BigInteger.ZERO,
+ BigInteger.ONE,
+ BigInteger.ZERO);
+ private final List> right = Arrays.asList(
+ () -> BigInteger.ONE,
+ () -> BigInteger.ONE,
+ () -> BigInteger.ZERO,
+ () -> BigInteger.ZERO);
+
+ @Override
+ public void test() {
+ Application>, ProtocolBuilderNumeric> app =
+ root -> {
+ int myId = root.getBasicNumericContext().getMyId();
+ DRes>> leftClosed =
+ (myId == 1) ?
+ root.collections().closeList(left, 1)
+ : root.collections().closeList(left.size(), 1);
+ DRes>> anded = root
+ .par(new ArithmeticAndKnownRight(leftClosed, () -> right));
+ return root.collections().openList(anded);
+ };
+ List actual = runApplication(app).stream().map(DRes::out)
+ .collect(Collectors.toList());
+ List expected = Arrays.asList(
+ BigInteger.ONE,
+ BigInteger.ZERO,
+ BigInteger.ZERO,
+ BigInteger.ZERO
+ );
+ Assert.assertEquals(expected, actual);
+ }
+ };
+ }
+ }
+
+ public static class TestArithmeticXorKnownRight
+ extends TestThreadFactory {
+
+ @Override
+ public TestThread next() {
+
+ return new TestThread() {
+ private final List left = Arrays.asList(
+ BigInteger.ONE,
+ BigInteger.ZERO,
+ BigInteger.ONE,
+ BigInteger.ZERO);
+ private final List> right = Arrays.asList(
+ () -> BigInteger.ONE,
+ () -> BigInteger.ONE,
+ () -> BigInteger.ZERO,
+ () -> BigInteger.ZERO);
+
+ @Override
+ public void test() {
+ Application>, ProtocolBuilderNumeric> app =
+ root -> {
+ int myId = root.getBasicNumericContext().getMyId();
+ DRes>> leftClosed =
+ (myId == 1) ?
+ root.collections().closeList(left, 1)
+ : root.collections().closeList(left.size(), 1);
+ DRes>> anded = root
+ .par(new ArithmeticXorKnownRight(leftClosed, () -> right));
+ return root.collections().openList(anded);
+ };
+ List actual = runApplication(app).stream().map(DRes::out)
+ .collect(Collectors.toList());
+ List expected = Arrays.asList(
+ BigInteger.ZERO,
+ BigInteger.ONE,
+ BigInteger.ONE,
+ BigInteger.ZERO
+ );
+ Assert.assertEquals(expected, actual);
+ }
+ };
+ }
+ }
}
diff --git a/core/src/test/java/dk/alexandra/fresco/suite/dummy/arithmetic/TestDummyArithmeticProtocolSuite.java b/core/src/test/java/dk/alexandra/fresco/suite/dummy/arithmetic/TestDummyArithmeticProtocolSuite.java
index 7973e9688..a7780fbff 100644
--- a/core/src/test/java/dk/alexandra/fresco/suite/dummy/arithmetic/TestDummyArithmeticProtocolSuite.java
+++ b/core/src/test/java/dk/alexandra/fresco/suite/dummy/arithmetic/TestDummyArithmeticProtocolSuite.java
@@ -31,6 +31,8 @@
import dk.alexandra.fresco.lib.lp.LPSolver;
import dk.alexandra.fresco.lib.lp.LpBuildingBlockTests;
import dk.alexandra.fresco.lib.math.integer.binary.BinaryOperationsTests;
+import dk.alexandra.fresco.lib.math.integer.binary.BinaryOperationsTests.TestArithmeticAndKnownRight;
+import dk.alexandra.fresco.lib.math.integer.binary.BinaryOperationsTests.TestArithmeticXorKnownRight;
import dk.alexandra.fresco.lib.math.integer.division.DivisionTests;
import dk.alexandra.fresco.lib.math.integer.exp.ExponentiationTests;
import dk.alexandra.fresco.lib.math.integer.linalg.LinAlgTests;
@@ -769,4 +771,14 @@ public void test_trunctation() throws Exception {
runTest(new TruncationTests.TestTruncation<>(), new TestParameters().numParties(2));
}
+ @Test
+ public void testArithmeticAndKnownRight() {
+ runTest(new TestArithmeticAndKnownRight<>(), new TestParameters());
+ }
+
+ @Test
+ public void testArithmeticXorKnownRight() {
+ runTest(new TestArithmeticXorKnownRight<>(), new TestParameters());
+ }
+
}
From 80b8b5ffa0c83252f3d731ef637ca1cd9e62a0a5 Mon Sep 17 00:00:00 2001
From: Nikolaj Volgushev
Date: Tue, 17 Apr 2018 14:15:22 +0200
Subject: [PATCH 004/231] Stub for mod2m
---
.../fresco/lib/math/integer/mod/Mod2m.java | 33 +++++++++++++++++++
1 file changed, 33 insertions(+)
create mode 100644 core/src/main/java/dk/alexandra/fresco/lib/math/integer/mod/Mod2m.java
diff --git a/core/src/main/java/dk/alexandra/fresco/lib/math/integer/mod/Mod2m.java b/core/src/main/java/dk/alexandra/fresco/lib/math/integer/mod/Mod2m.java
new file mode 100644
index 000000000..49d7a133f
--- /dev/null
+++ b/core/src/main/java/dk/alexandra/fresco/lib/math/integer/mod/Mod2m.java
@@ -0,0 +1,33 @@
+package dk.alexandra.fresco.lib.math.integer.mod;
+
+import dk.alexandra.fresco.framework.DRes;
+import dk.alexandra.fresco.framework.builder.Computation;
+import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric;
+import dk.alexandra.fresco.framework.value.SInt;
+
+/**
+ * Computes modular reduction of value mod 2^m.
+ */
+public class Mod2m implements Computation {
+
+ private final DRes value;
+ private final int m;
+
+ /**
+ * Constructs new {@link Mod2m}.
+ *
+ * @param value value to reduce
+ * @param m exponent (2^{m})
+ */
+ public Mod2m(DRes value, int m) {
+ this.value = value;
+ this.m = m;
+ }
+
+ @Override
+ public DRes buildComputation(ProtocolBuilderNumeric builder) {
+ // TODO implement
+ return null;
+ }
+
+}
From a9976e319da3fbf0262df2a3d27ca82ac9bee46c Mon Sep 17 00:00:00 2001
From: Nikolaj Volgushev
Date: Tue, 17 Apr 2018 14:36:29 +0200
Subject: [PATCH 005/231] Mod2m test skeleton
---
.../lib/math/integer/mod/Mod2mTests.java | 36 +++++++++++++++++++
.../TestDummyArithmeticProtocolSuite.java | 5 +++
2 files changed, 41 insertions(+)
create mode 100644 core/src/test/java/dk/alexandra/fresco/lib/math/integer/mod/Mod2mTests.java
diff --git a/core/src/test/java/dk/alexandra/fresco/lib/math/integer/mod/Mod2mTests.java b/core/src/test/java/dk/alexandra/fresco/lib/math/integer/mod/Mod2mTests.java
new file mode 100644
index 000000000..f03a926f5
--- /dev/null
+++ b/core/src/test/java/dk/alexandra/fresco/lib/math/integer/mod/Mod2mTests.java
@@ -0,0 +1,36 @@
+package dk.alexandra.fresco.lib.math.integer.mod;
+
+import dk.alexandra.fresco.framework.Application;
+import dk.alexandra.fresco.framework.DRes;
+import dk.alexandra.fresco.framework.TestThreadRunner.TestThread;
+import dk.alexandra.fresco.framework.TestThreadRunner.TestThreadFactory;
+import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric;
+import dk.alexandra.fresco.framework.sce.resources.ResourcePool;
+import dk.alexandra.fresco.framework.value.SInt;
+import java.math.BigInteger;
+
+public class Mod2mTests {
+
+ public static class TestMod2mBaseCase
+ extends TestThreadFactory {
+
+ @Override
+ public TestThread next() {
+
+ return new TestThread() {
+
+ @Override
+ public void test() {
+ Application app = builder -> {
+ // TODO implement
+ DRes value = builder.numeric().known(BigInteger.ONE);
+ int m = 64;
+ return builder.seq(new Mod2m(value, m));
+ };
+ DRes result = runApplication(app);
+ }
+ };
+ }
+ }
+
+}
diff --git a/core/src/test/java/dk/alexandra/fresco/suite/dummy/arithmetic/TestDummyArithmeticProtocolSuite.java b/core/src/test/java/dk/alexandra/fresco/suite/dummy/arithmetic/TestDummyArithmeticProtocolSuite.java
index a7780fbff..b4dd5b171 100644
--- a/core/src/test/java/dk/alexandra/fresco/suite/dummy/arithmetic/TestDummyArithmeticProtocolSuite.java
+++ b/core/src/test/java/dk/alexandra/fresco/suite/dummy/arithmetic/TestDummyArithmeticProtocolSuite.java
@@ -38,6 +38,7 @@
import dk.alexandra.fresco.lib.math.integer.linalg.LinAlgTests;
import dk.alexandra.fresco.lib.math.integer.log.LogTests;
import dk.alexandra.fresco.lib.math.integer.min.MinTests;
+import dk.alexandra.fresco.lib.math.integer.mod.Mod2mTests.TestMod2mBaseCase;
import dk.alexandra.fresco.lib.math.integer.sqrt.SqrtTests;
import dk.alexandra.fresco.lib.math.integer.stat.StatisticsTests;
import dk.alexandra.fresco.lib.math.polynomial.PolynomialTests;
@@ -781,4 +782,8 @@ public void testArithmeticXorKnownRight() {
runTest(new TestArithmeticXorKnownRight<>(), new TestParameters());
}
+ @Test
+ public void testMod2mBaseCase() {
+ runTest(new TestMod2mBaseCase<>(), new TestParameters());
+ }
}
From ae2f8558595d67e137fca2c04083207195a22a14 Mon Sep 17 00:00:00 2001
From: Nikolaj Volgushev
Date: Tue, 17 Apr 2018 17:12:07 +0200
Subject: [PATCH 006/231] WIP precarry
---
.../fresco/framework/util/SIntPair.java | 13 +++
.../fresco/lib/compare/gt/CarryBits.java | 27 ++++--
.../fresco/lib/compare/gt/CarryHelper.java | 43 +++++++++
.../fresco/lib/compare/gt/PreCarryBits.java | 44 ++++++++++
.../fresco/lib/compare/gt/TestPreCarry.java | 88 +++++++++++++++++++
.../TestDummyArithmeticProtocolSuite.java | 13 +++
6 files changed, 221 insertions(+), 7 deletions(-)
create mode 100644 core/src/main/java/dk/alexandra/fresco/framework/util/SIntPair.java
create mode 100644 core/src/main/java/dk/alexandra/fresco/lib/compare/gt/CarryHelper.java
create mode 100644 core/src/main/java/dk/alexandra/fresco/lib/compare/gt/PreCarryBits.java
create mode 100644 core/src/test/java/dk/alexandra/fresco/lib/compare/gt/TestPreCarry.java
diff --git a/core/src/main/java/dk/alexandra/fresco/framework/util/SIntPair.java b/core/src/main/java/dk/alexandra/fresco/framework/util/SIntPair.java
new file mode 100644
index 000000000..d09f56161
--- /dev/null
+++ b/core/src/main/java/dk/alexandra/fresco/framework/util/SIntPair.java
@@ -0,0 +1,13 @@
+package dk.alexandra.fresco.framework.util;
+
+import dk.alexandra.fresco.framework.DRes;
+import dk.alexandra.fresco.framework.value.SInt;
+
+public class SIntPair extends Pair, DRes> {
+
+ public SIntPair(DRes first,
+ DRes second) {
+ super(first, second);
+ }
+
+}
diff --git a/core/src/main/java/dk/alexandra/fresco/lib/compare/gt/CarryBits.java b/core/src/main/java/dk/alexandra/fresco/lib/compare/gt/CarryBits.java
index 1df89d76d..640590b6b 100644
--- a/core/src/main/java/dk/alexandra/fresco/lib/compare/gt/CarryBits.java
+++ b/core/src/main/java/dk/alexandra/fresco/lib/compare/gt/CarryBits.java
@@ -3,24 +3,37 @@
import dk.alexandra.fresco.framework.DRes;
import dk.alexandra.fresco.framework.builder.Computation;
import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric;
+import dk.alexandra.fresco.framework.util.SIntPair;
import dk.alexandra.fresco.framework.value.SInt;
+import dk.alexandra.fresco.lib.math.integer.binary.ArithmeticXorKnownRight;
import java.math.BigInteger;
+import java.util.ArrayList;
import java.util.List;
public class CarryBits implements Computation>, ProtocolBuilderNumeric> {
- private final List> valuesA;
- private final List> valuesB;
- private final int k;
+ private final DRes>> bitsA;
+ private final DRes>> bitsB;
- public CarryBits(List> valuesA, List> valuesB) {
- this.valuesA = valuesA;
- this.valuesB = valuesB;
- this.k = valuesA.size();
+ public CarryBits(DRes>> bitsA, DRes>> bitsB) {
+ this.bitsA = bitsA;
+ this.bitsB = bitsB;
}
@Override
public DRes>> buildComputation(ProtocolBuilderNumeric builder) {
+ // these could also be done in parallel
+ DRes>> xoredDef = builder.par(new ArithmeticXorKnownRight(bitsA, bitsB));
+ DRes>> andedDef = builder.par(new ArithmeticXorKnownRight(bitsA, bitsB));
+ DRes> pairs = () -> {
+ List> xored = xoredDef.out();
+ List> anded = andedDef.out();
+ List innerPairs = new ArrayList<>(xored.size());
+ for (int i = 0; i < xored.size(); i++) {
+ innerPairs.add(new SIntPair(xored.get(i), anded.get(i)));
+ }
+ return innerPairs;
+ };
return null;
}
diff --git a/core/src/main/java/dk/alexandra/fresco/lib/compare/gt/CarryHelper.java b/core/src/main/java/dk/alexandra/fresco/lib/compare/gt/CarryHelper.java
new file mode 100644
index 000000000..c3f7a47db
--- /dev/null
+++ b/core/src/main/java/dk/alexandra/fresco/lib/compare/gt/CarryHelper.java
@@ -0,0 +1,43 @@
+package dk.alexandra.fresco.lib.compare.gt;
+
+import dk.alexandra.fresco.framework.DRes;
+import dk.alexandra.fresco.framework.builder.Computation;
+import dk.alexandra.fresco.framework.builder.numeric.Numeric;
+import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric;
+import dk.alexandra.fresco.framework.util.SIntPair;
+import dk.alexandra.fresco.framework.value.SInt;
+
+/**
+ * Corresponds to circle operator in paper. Given (p_{2}, g_{2}) and (p_{1}, g_{1}) computes (p,
+ * g) where p = p_{2} * p_{1} and g = g_{2} + (p_{1} * g_{1}).
+ */
+public class CarryHelper implements Computation {
+
+ private final DRes leftBitPair;
+ private final DRes rightBitPair;
+
+ public CarryHelper(DRes leftBitPair, DRes rightBitPair) {
+ this.leftBitPair = leftBitPair;
+ this.rightBitPair = rightBitPair;
+ }
+
+ @Override
+ public DRes buildComputation(ProtocolBuilderNumeric builder) {
+ SIntPair left = leftBitPair.out();
+ SIntPair right = rightBitPair.out();
+ DRes p1 = left.getFirst();
+ DRes g1 = left.getSecond();
+ DRes p2 = right.getFirst();
+ DRes g2 = right.getSecond();
+ return builder.par(par -> {
+ Numeric numeric = par.numeric();
+ DRes p = numeric.mult(p1, p2);
+ DRes q = par.seq(seq -> {
+ DRes temp = seq.numeric().mult(p2, g1);
+ return seq.numeric().add(temp, g2);
+ });
+ return () -> new SIntPair(p, q);
+ });
+ }
+
+}
diff --git a/core/src/main/java/dk/alexandra/fresco/lib/compare/gt/PreCarryBits.java b/core/src/main/java/dk/alexandra/fresco/lib/compare/gt/PreCarryBits.java
new file mode 100644
index 000000000..9af54ee7d
--- /dev/null
+++ b/core/src/main/java/dk/alexandra/fresco/lib/compare/gt/PreCarryBits.java
@@ -0,0 +1,44 @@
+package dk.alexandra.fresco.lib.compare.gt;
+
+import dk.alexandra.fresco.framework.DRes;
+import dk.alexandra.fresco.framework.builder.Computation;
+import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric;
+import dk.alexandra.fresco.framework.util.SIntPair;
+import dk.alexandra.fresco.framework.value.SInt;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class PreCarryBits implements Computation {
+
+ private final DRes>> pairsDef;
+
+ public PreCarryBits(DRes>> pairs) {
+ this.pairsDef = pairs;
+ }
+
+ @Override
+ public DRes buildComputation(ProtocolBuilderNumeric builder) {
+ List> pairs = pairsDef.out();
+ Collections.reverse(pairs);
+ int k = pairs.size();
+ if (k == 1) {
+ return pairs.get(0).out().getSecond();
+ } else {
+ DRes>> bitsU = builder.par(par -> {
+ List> bitsUInner = new ArrayList<>(k / 2);
+ for (int i = 0; i < k / 2; i++) {
+ DRes left = pairs.get(2 * i + 1);
+ DRes right = pairs.get(2 * i);
+ bitsUInner.add(par.seq(new CarryHelper(left, right)));
+ }
+ List> nextRound = bitsUInner.subList(0, k / 2);
+ Collections.reverse(nextRound);
+ return () -> nextRound;
+ });
+ return builder.seq(new PreCarryBits(bitsU));
+ }
+ }
+
+
+}
diff --git a/core/src/test/java/dk/alexandra/fresco/lib/compare/gt/TestPreCarry.java b/core/src/test/java/dk/alexandra/fresco/lib/compare/gt/TestPreCarry.java
new file mode 100644
index 000000000..6fd71d593
--- /dev/null
+++ b/core/src/test/java/dk/alexandra/fresco/lib/compare/gt/TestPreCarry.java
@@ -0,0 +1,88 @@
+package dk.alexandra.fresco.lib.compare.gt;
+
+import dk.alexandra.fresco.framework.Application;
+import dk.alexandra.fresco.framework.DRes;
+import dk.alexandra.fresco.framework.TestThreadRunner.TestThread;
+import dk.alexandra.fresco.framework.TestThreadRunner.TestThreadFactory;
+import dk.alexandra.fresco.framework.builder.numeric.Numeric;
+import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric;
+import dk.alexandra.fresco.framework.sce.resources.ResourcePool;
+import dk.alexandra.fresco.framework.util.Pair;
+import dk.alexandra.fresco.framework.util.SIntPair;
+import dk.alexandra.fresco.framework.value.SInt;
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.List;
+import org.junit.Assert;
+
+public class TestPreCarry {
+
+ public static class TestCarryHelper
+ extends TestThreadFactory {
+
+ @Override
+ public TestThread next() {
+ return new TestThread() {
+
+ @Override
+ public void test() {
+ Application, ProtocolBuilderNumeric> app = builder -> {
+ Numeric numeric = builder.numeric();
+ DRes p1 = numeric.known(BigInteger.ONE);
+ DRes g1 = numeric.known(BigInteger.ZERO);
+ DRes p2 = numeric.known(BigInteger.ONE);
+ DRes g2 = numeric.known(BigInteger.ONE);
+ SIntPair pairOne = new SIntPair(p1, g1);
+ SIntPair pairTwo = new SIntPair(p2, g2);
+ DRes carried = builder
+ .seq(new CarryHelper(() -> pairTwo, () -> pairOne));
+ return builder.seq(seq -> {
+ SIntPair carriedOut = carried.out();
+ DRes p = seq.numeric().open(carriedOut.getFirst());
+ DRes q = seq.numeric().open(carriedOut.getSecond());
+ return () -> new Pair<>(p.out(), q.out());
+ });
+ };
+ Pair expected = new Pair<>(
+ BigInteger.ONE, // p1 & p2
+ BigInteger.ONE // g2 | (p1 & g1)
+ );
+ Pair actual = runApplication(app);
+ Assert.assertEquals(expected, actual);
+ }
+ };
+ }
+ }
+
+ public static class TestPreCarryBits
+ extends TestThreadFactory {
+
+ @Override
+ public TestThread next() {
+ return new TestThread() {
+
+ @Override
+ public void test() {
+ Application app = builder -> {
+ Numeric numeric = builder.numeric();
+ DRes p1 = numeric.known(BigInteger.ONE);
+ DRes g1 = numeric.known(BigInteger.ZERO);
+ DRes p2 = numeric.known(BigInteger.ONE);
+ DRes g2 = numeric.known(BigInteger.ONE);
+ SIntPair pairOne = new SIntPair(p1, g1);
+ SIntPair pairTwo = new SIntPair(p2, g2);
+ List> pairs = Arrays.asList(
+ () -> pairOne,
+ () -> pairTwo
+ );
+ DRes carried = builder.seq(new PreCarryBits(() -> pairs));
+ return builder.numeric().open(carried);
+ };
+ BigInteger actual = runApplication(app);
+ Assert.assertEquals(BigInteger.ZERO, actual);
+ }
+ };
+ }
+ }
+
+}
diff --git a/core/src/test/java/dk/alexandra/fresco/suite/dummy/arithmetic/TestDummyArithmeticProtocolSuite.java b/core/src/test/java/dk/alexandra/fresco/suite/dummy/arithmetic/TestDummyArithmeticProtocolSuite.java
index b4dd5b171..1eb0f44c5 100644
--- a/core/src/test/java/dk/alexandra/fresco/suite/dummy/arithmetic/TestDummyArithmeticProtocolSuite.java
+++ b/core/src/test/java/dk/alexandra/fresco/suite/dummy/arithmetic/TestDummyArithmeticProtocolSuite.java
@@ -22,6 +22,8 @@
import dk.alexandra.fresco.lib.collections.relational.LeakyAggregationTests;
import dk.alexandra.fresco.lib.collections.shuffle.ShuffleRowsTests;
import dk.alexandra.fresco.lib.compare.CompareTests;
+import dk.alexandra.fresco.lib.compare.gt.TestPreCarry.TestCarryHelper;
+import dk.alexandra.fresco.lib.compare.gt.TestPreCarry.TestPreCarryBits;
import dk.alexandra.fresco.lib.conditional.ConditionalSelectTests;
import dk.alexandra.fresco.lib.conditional.ConditionalSwapNeighborsTests;
import dk.alexandra.fresco.lib.conditional.ConditionalSwapRowsTests;
@@ -786,4 +788,15 @@ public void testArithmeticXorKnownRight() {
public void testMod2mBaseCase() {
runTest(new TestMod2mBaseCase<>(), new TestParameters());
}
+
+ @Test
+ public void testCarryHelper() {
+ runTest(new TestCarryHelper<>(), new TestParameters());
+ }
+
+ @Test
+ public void testPreCarryBits() {
+ runTest(new TestPreCarryBits<>(), new TestParameters());
+ }
+
}
From c2205c7c208298165500e8ec9944f21df7be1261 Mon Sep 17 00:00:00 2001
From: Nikolaj Volgushev
Date: Tue, 17 Apr 2018 18:05:52 +0200
Subject: [PATCH 007/231] Carry out tests
---
.../gt/{CarryBits.java => CarryOut.java} | 20 +-
.../fresco/lib/compare/gt/PreCarryBits.java | 1 +
.../fresco/lib/compare/gt/CarryOutTests.java | 61 ++++
.../{TestPreCarry.java => PreCarryTests.java} | 9 +-
.../TestDummyArithmeticProtocolSuite.java | 267 +++++++++---------
5 files changed, 218 insertions(+), 140 deletions(-)
rename core/src/main/java/dk/alexandra/fresco/lib/compare/gt/{CarryBits.java => CarryOut.java} (60%)
create mode 100644 core/src/test/java/dk/alexandra/fresco/lib/compare/gt/CarryOutTests.java
rename core/src/test/java/dk/alexandra/fresco/lib/compare/gt/{TestPreCarry.java => PreCarryTests.java} (94%)
diff --git a/core/src/main/java/dk/alexandra/fresco/lib/compare/gt/CarryBits.java b/core/src/main/java/dk/alexandra/fresco/lib/compare/gt/CarryOut.java
similarity index 60%
rename from core/src/main/java/dk/alexandra/fresco/lib/compare/gt/CarryBits.java
rename to core/src/main/java/dk/alexandra/fresco/lib/compare/gt/CarryOut.java
index 640590b6b..750ab6468 100644
--- a/core/src/main/java/dk/alexandra/fresco/lib/compare/gt/CarryBits.java
+++ b/core/src/main/java/dk/alexandra/fresco/lib/compare/gt/CarryOut.java
@@ -5,36 +5,38 @@
import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric;
import dk.alexandra.fresco.framework.util.SIntPair;
import dk.alexandra.fresco.framework.value.SInt;
+import dk.alexandra.fresco.lib.math.integer.binary.ArithmeticAndKnownRight;
import dk.alexandra.fresco.lib.math.integer.binary.ArithmeticXorKnownRight;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
-public class CarryBits implements Computation>, ProtocolBuilderNumeric> {
+public class CarryOut implements Computation {
private final DRes>> bitsA;
private final DRes>> bitsB;
- public CarryBits(DRes>> bitsA, DRes>> bitsB) {
+ public CarryOut(DRes>> bitsA, DRes>> bitsB) {
this.bitsA = bitsA;
this.bitsB = bitsB;
}
@Override
- public DRes>> buildComputation(ProtocolBuilderNumeric builder) {
- // these could also be done in parallel
+ public DRes buildComputation(ProtocolBuilderNumeric builder) {
+ // TODO both calls should be in parallel
DRes>> xoredDef = builder.par(new ArithmeticXorKnownRight(bitsA, bitsB));
- DRes>> andedDef = builder.par(new ArithmeticXorKnownRight(bitsA, bitsB));
- DRes> pairs = () -> {
+ DRes>> andedDef = builder.par(new ArithmeticAndKnownRight(bitsA, bitsB));
+ DRes>> pairs = () -> {
List> xored = xoredDef.out();
List> anded = andedDef.out();
- List