@Override public DRes<RowPairD<SInt, SInt>> buildComputation(ProtocolBuilderNumeric builder) { DRes<List<DRes<SInt>>> updatedLeft = builder.collections().condSelect(condition, right, left); DRes<List<DRes<SInt>>> updatedRight = builder.collections().condSelect(condition, left, right); return () -> new RowPairD<>(updatedLeft, updatedRight); } }
@Override public DRes<Matrix<DRes<BigInteger>>> buildComputation(ProtocolBuilderNumeric builder) { Collections collections = builder.collections(); List<DRes<List<DRes<BigInteger>>>> closedRows = new ArrayList<>(); for (List<? extends DRes<SInt>> row : closedMatrix.out().getRows()) { // still sort of hacky: need to artificially wrap row in computation DRes<List<DRes<BigInteger>>> closedRow = collections.openList(() -> row); closedRows.add(closedRow); } return () -> new MatrixUtils().unwrapRows(closedRows); } }
@Override public DRes<Matrix<DRes<SInt>>> buildComputation(ProtocolBuilderNumeric builder) { Collections collections = builder.collections(); List<DRes<List<DRes<SInt>>>> closed = isInputProvider ? buildAsProvider(collections) : buildAsReceiver(collections); return () -> new MatrixUtils().unwrapRows(closed); } }
/** * Executes application. * * @param sce the execution environment * @param rp resource pool */ public void runApplication(SecureComputationEngine<ResourcePoolT, ProtocolBuilderNumeric> sce, ResourcePoolT rp, Network network) { int groupByIdx = 0; int aggIdx = 1; // Create application we are going run Application<Matrix<BigInteger>, ProtocolBuilderNumeric> aggApp = root -> { DRes<Matrix<DRes<SInt>>> closed; // player 1 provides input if (rp.getMyId() == 1) { closed = root.collections().closeMatrix(readInputs(), 1); } else { // if we aren't player 1 we need to provide the expected size of the input closed = root.collections().closeMatrix(8, 2, 1); } DRes<Matrix<DRes<SInt>>> aggregated = root.collections().leakyAggregateSum(closed, groupByIdx, aggIdx); DRes<Matrix<DRes<BigInteger>>> opened = root.collections().openMatrix(aggregated); return () -> new MatrixUtils().unwrapMatrix(opened); }; // Run application and get result Matrix<BigInteger> result = sce.runApplication(aggApp, rp, network); writeOutputs(result); sce.shutdownSCE(); }
@Override public void test() throws Exception { // define input and output List<BigInteger> input = new ArrayList<>(); // define functionality to be tested Application<List<SInt>, ProtocolBuilderNumeric> testApplication = root -> { DRes<List<DRes<SInt>>> closed = root.collections().closeList(input, 1); return () -> closed.out().stream().map(DRes::out).collect(Collectors.toList()); }; List<SInt> output = runApplication(testApplication); assertTrue(output.isEmpty()); } };
@Override public DRes<Matrix<DRes<SInt>>> buildComputation(ProtocolBuilderNumeric builder) { Collections collections = builder.collections(); List<T> swappersOut = conditions.out(); Matrix<T> rowsOut = rows.out(); List<DRes<RowPairD<SInt, SInt>>> pairs = new ArrayList<>(); int swapperIdx = 0; for (int i = 0; i < rowsOut.getHeight() - 1; i += 2) { List<T> tempLeft = rowsOut.getRow(i); List<T> tempRight = rowsOut.getRow(i + 1); DRes<RowPairD<SInt, SInt>> pair = collections.swapIf(swappersOut.get(swapperIdx), () -> tempLeft, () -> tempRight); swapperIdx++; pairs.add(pair); } return () -> { ArrayList<ArrayList<DRes<SInt>>> temp = new ArrayList<>(); for (DRes<RowPairD<SInt, SInt>> pair : pairs) { temp.add(new ArrayList<>(pair.out().getFirst().out())); temp.add(new ArrayList<>(pair.out().getSecond().out())); } return new Matrix<>(rowsOut.getHeight(), rowsOut.getWidth(), temp); }; } }
@Override public DRes<RowPairD<BigInteger, BigInteger>> buildComputation(ProtocolBuilderNumeric builder) { RowPairD<SInt, SInt> closedPairOut = closedPair.out(); Collections collections = builder.collections(); RowPairD<BigInteger, BigInteger> openPair = new RowPairD<>(collections.openList(closedPairOut.getFirst()), collections.openList(closedPairOut.getSecond())); return () -> openPair; }
@Override public void test() throws Exception { // define input and output ArrayList<BigInteger> rowOne = new ArrayList<>(); rowOne.add(BigInteger.valueOf(1)); rowOne.add(BigInteger.valueOf(2)); rowOne.add(BigInteger.valueOf(3)); ArrayList<BigInteger> rowTwo = new ArrayList<>(); rowTwo.add(BigInteger.valueOf(4)); rowTwo.add(BigInteger.valueOf(5)); rowTwo.add(BigInteger.valueOf(6)); ArrayList<ArrayList<BigInteger>> mat = new ArrayList<>(); mat.add(rowOne); mat.add(rowTwo); Matrix<BigInteger> input = new Matrix<>(2, 3, mat); // define functionality to be tested Application<Matrix<BigInteger>, ProtocolBuilderNumeric> testApplication = root -> { Collections collections = root.collections(); DRes<Matrix<DRes<SInt>>> closed = collections.closeMatrix(input, 1); DRes<Matrix<DRes<BigInteger>>> opened = collections.openMatrix(closed); return () -> new MatrixUtils().unwrapMatrix(opened); }; Matrix<BigInteger> output = runApplication(testApplication); assertThat(output.getRows(), is(input.getRows())); } };
@Override public void test() { Application<List<BigInteger>, ProtocolBuilderNumeric> app = producer -> { Numeric numeric = producer.numeric(); Collections collections = producer.collections(); int numBits = 10; List<DRes<SInt>> bits = new ArrayList<>(numBits); for (int i = 0; i < numBits; i++) { bits.add(numeric.randomBit()); } DRes<List<DRes<BigInteger>>> opened = collections.openList(() -> bits); return () -> opened.out().stream().map(DRes::out) .collect(Collectors.toList()); }; List<BigInteger> bits = runApplication(app); for (BigInteger bit : bits) { Assert.assertTrue("Expected bit but was " + bit, bit.equals(BigInteger.ZERO) || bit.equals(BigInteger.ONE)); } } };
@Override public void test() { Application<List<BigInteger>, ProtocolBuilderNumeric> app = producer -> { Numeric numeric = producer.numeric(); Collections collections = producer.collections(); int numElements = 10; List<DRes<SInt>> elements = new ArrayList<>(numElements); for (int i = 0; i < numElements; i++) { elements.add(numeric.randomElement()); } DRes<List<DRes<BigInteger>>> opened = collections.openList(() -> elements); return () -> opened.out().stream().map(DRes::out) .collect(Collectors.toList()); }; List<BigInteger> elements = runApplication(app); assertAllDifferent(elements); Assert.assertEquals(10, elements.size()); } };
@Override public void test() throws Exception { // define functionality to be tested Application<Matrix<BigInteger>, ProtocolBuilderNumeric> testApplication = root -> { DRes<Matrix<DRes<SInt>>> closed = root.collections().closeMatrix(input, 1); DRes<Matrix<DRes<SInt>>> aggregated = root.collections().leakyAggregateSum(closed, 0, 1); DRes<Matrix<DRes<BigInteger>>> opened = root.collections().openMatrix(aggregated); return () -> new MatrixUtils().unwrapMatrix(opened); }; Matrix<BigInteger> actual = runApplication(testApplication); // sort by key to undo shuffling // (keys are guaranteed to be unique) Collections.sort(actual.getRows(), (r1, r2) -> r1.get(0).compareTo(r2.get(0))); assertThat(actual.getRows(), is(expected.getRows())); } };
@Override public void test() throws Exception { // define input List<BigInteger> input = new ArrayList<>(); int numInputs = 100; for (int i = 0; i < numInputs; i++) { input.add(BigInteger.valueOf(i)); } // define functionality to be tested Application<List<BigInteger>, ProtocolBuilderNumeric> testApplication = root -> { Collections collections = root.collections(); DRes<List<DRes<SInt>>> closed; if (root.getBasicNumericContext().getMyId() == 1) { // party 1 provides input closed = collections.closeList(input, 1); } else { // other parties receive it closed = collections.closeList(numInputs, 1); } DRes<List<DRes<BigInteger>>> opened = collections.openList(closed); return () -> opened.out().stream().map(DRes::out).collect(Collectors.toList()); }; // run test application List<BigInteger> output = runApplication(testApplication); assertThat(output, is(input)); } };
@Override public void test() throws Exception { // input Matrix<BigInteger> input = new Matrix<>(0, 0, new ArrayList<>()); // functionality to be tested Application<Matrix<SInt>, ProtocolBuilderNumeric> testApplication = root -> { // close inputs Collections collections = root.collections(); DRes<Matrix<DRes<SInt>>> mat = collections.closeMatrix(input, 1); // unwrap and return result return () -> new MatrixUtils().unwrapMatrix(mat); }; Matrix<SInt> output = runApplication(testApplication); assertTrue(output.getRows().isEmpty()); } };
@Override public void test() throws Exception { Application<Matrix<BigInteger>, ProtocolBuilderNumeric> testApplication = root -> { DRes<Matrix<DRes<SInt>>> closed = root.collections().closeMatrix(input, 1); // use package-private constructor to fix randomness DRes<Matrix<DRes<SInt>>> shuffled = root.seq( new ShuffleRows(closed, new Random(42 + root.getBasicNumericContext().getMyId()))); DRes<Matrix<DRes<BigInteger>>> opened = root.collections().openMatrix(shuffled); return () -> new MatrixUtils().unwrapMatrix(opened); }; Matrix<BigInteger> actual = runApplication(testApplication); assertThat(actual.getRows(), is(expected.getRows())); } };
@Override public DRes<Matrix<DRes<SInt>>> buildComputation(ProtocolBuilderNumeric builder) { /* * There is a round for each party in pids. Each party chooses a random permutation (of indexes) * and applies it to values using PermuteRows. */ Matrix<DRes<SInt>> valuesOut = values.out(); final int height = valuesOut.getHeight(); if (height < 2) { return values; } final int pid = builder.getBasicNumericContext().getMyId(); final int numPids = builder.getBasicNumericContext().getNoOfParties(); return builder.seq( (seq) -> new IterationState(0, values) ).whileLoop((state) -> state.round < numPids, (seq, state) -> { int thisRoundPid = state.round + 1; // parties start from 1 DRes<Matrix<DRes<SInt>>> permuted; if (pid == thisRoundPid) { permuted = seq.collections().permute(state.intermediate, getIdxPerm(height)); } else { permuted = seq.collections().permute(state.intermediate, thisRoundPid); } return new IterationState(state.round + 1, permuted); }).seq((seq, state) -> state.intermediate); }
@Override public void test() throws Exception { // define functionality to be tested Application<Pair<List<BigInteger>, List<BigInteger>>, ProtocolBuilderNumeric> testApplication = root -> { Collections collections = root.collections(); DRes<List<DRes<SInt>>> closedLeft = collections.closeList(input.getFirst(), 1); DRes<List<DRes<SInt>>> closedRight = collections.closeList(input.getSecond(), 1); DRes<SInt> swapper = root.numeric().input(swapperOpen, 1); DRes<RowPairD<SInt, SInt>> swapped = collections.swapIf(swapper, closedLeft, closedRight); DRes<RowPairD<BigInteger, BigInteger>> openSwapped = collections.openRowPair(swapped); return () -> { RowPairD<BigInteger, BigInteger> openSwappedOut = openSwapped.out(); List<BigInteger> leftRes = openSwappedOut.getFirst().out().stream().map(DRes::out) .collect(Collectors.toList()); List<BigInteger> rightRes = openSwappedOut.getSecond().out().stream() .map(DRes::out).collect(Collectors.toList()); return new Pair<>(leftRes, rightRes); }; }; Pair<List<BigInteger>, List<BigInteger>> output = runApplication(testApplication); assertThat(output, is(expected)); } };
@Override public void test() { Application<Pair<Integer, List<DRes<BigInteger>>>, ProtocolBuilderNumeric> app = producer -> { Numeric numeric = producer.numeric(); int noOfParties = producer.getBasicNumericContext().getNoOfParties(); List<DRes<SInt>> inputs = new ArrayList<>(noOfParties); for (int i = 1; i <= noOfParties; i++) { inputs.add(numeric.input(BigInteger.valueOf(i), i)); } DRes<List<DRes<BigInteger>>> opened = producer.collections().openList(() -> inputs); return () -> new Pair<>(noOfParties, opened.out()); }; Pair<Integer, List<DRes<BigInteger>>> output = runApplication(app); int noOfParties = output.getFirst(); List<DRes<BigInteger>> inputs = output.getSecond(); Assert.assertEquals(noOfParties, inputs.size()); for (int i = 0; i < noOfParties; i++) { Assert.assertEquals(i + 1, inputs.get(i).out().intValue()); } } };
@Override public void test() throws Exception { // define functionality to be tested Application<Matrix<BigInteger>, ProtocolBuilderNumeric> testApplication = root -> { Collections collections = root.collections(); DRes<List<DRes<SInt>>> swappers = collections.closeList(openSwappers, 1); DRes<Matrix<DRes<SInt>>> closed = collections.closeMatrix(input, 1); DRes<Matrix<DRes<SInt>>> swapped = collections.swapNeighborsIf(swappers, closed); DRes<Matrix<DRes<BigInteger>>> opened = collections.openMatrix(swapped); return () -> new MatrixUtils().unwrapMatrix(opened); }; Matrix<BigInteger> output = runApplication(testApplication); assertThat(output.getRows(), is(expected.getRows())); } };
@Override public void test() throws Exception { // define functionality to be tested Application<Matrix<BigInteger>, ProtocolBuilderNumeric> testApplication = root -> { Collections collections = root.collections(); DRes<Matrix<DRes<SInt>>> closed = collections.closeMatrix(input, 1); DRes<Matrix<DRes<SInt>>> permuted = null; if (root.getBasicNumericContext().getMyId() == 1) { permuted = collections.permute(closed, idxPerm); } else { permuted = collections.permute(closed, 1); } DRes<Matrix<DRes<BigInteger>>> opened = collections.openMatrix(permuted); return () -> new MatrixUtils().unwrapMatrix(opened); }; Matrix<BigInteger> actual = runApplication(testApplication); assertThat(actual.getRows(), is(expected.getRows())); } };
@Override public void test() throws Exception { // define functionality to be tested Application<Pair<DRes<BigInteger>, DRes<BigInteger>>, ProtocolBuilderNumeric> testApplication = root -> { Numeric nb = root.numeric(); AdvancedNumeric advancedNumeric = root.advancedNumeric(); Collections collections = root.collections(); DRes<SInt> left = nb.input(leftOpen, 1); DRes<SInt> right = nb.input(rightOpen, 1); DRes<SInt> selector = nb.input(swapperOpen, 1); DRes<Pair<DRes<SInt>, DRes<SInt>>> swapped = advancedNumeric.swapIf(selector, left, right); return collections.openPair(swapped); }; Pair<DRes<BigInteger>, DRes<BigInteger>> output = runApplication(testApplication); Pair<BigInteger, BigInteger> actual = new Pair<>(output.getFirst().out(), output.getSecond().out()); Assert.assertEquals(expected, actual); } };