@Override public DRes<SInt> add(DRes<SInt> a, DRes<SInt> b) { addCount++; return this.delegate.add(a, b); }
@Override public DRes<SInt> add(BigInteger a, DRes<SInt> b) { return this.delegate.add(a, b); }
/** * Convenience implementation of {@link #add(BigInteger, DRes)} */ default DRes<SInt> add(long a, DRes<SInt> b) { return add(BigInteger.valueOf(a), b); }
private DRes<SInt> or(ProtocolBuilderNumeric builder, DRes<SInt> a, DRes<SInt> b) { Numeric numeric = builder.numeric(); DRes<SInt> product = numeric.mult(a, b); DRes<SInt> add = numeric.add(a, b); return numeric.sub(add, product); }
@Override public DRes<SInt> buildComputation(ProtocolBuilderNumeric builder) { Numeric numeric = builder.numeric(); DRes<SInt> sub = numeric.sub(left, right); DRes<SInt> mult = numeric.mult(condition, sub); return numeric.add(mult, right); } }
@Override public DRes<SInt> buildComputation(ProtocolBuilderNumeric iterationBuilder) { return iterationBuilder.seq(seq -> () -> input ).whileLoop( (inputs) -> inputs.size() > 1, (seq, inputs) -> seq.par(parallel -> { List<DRes<SInt>> out = new ArrayList<>(); Numeric numericBuilder = parallel.numeric(); DRes<SInt> left = null; for (DRes<SInt> input1 : inputs) { if (left == null) { left = input1; } else { out.add(numericBuilder.add(left, input1)); left = null; } } if (left != null) { out.add(left); } return () -> out; }) ).seq((builder, currentInput) -> { return currentInput.get(0); }); } }
public void compareAndSwap(ProtocolBuilderNumeric builder, int a, int b, List<DRes<SInt>> values) { //Non splitting version Numeric numeric = builder.numeric(); DRes<SInt> valueA = values.get(a); DRes<SInt> valueB = values.get(b); DRes<SInt> comparison = builder.comparison().compareLEQ(valueA, valueB); DRes<SInt> sub = numeric.sub(valueA, valueB); DRes<SInt> c = numeric.mult(comparison, sub); DRes<SInt> d = numeric.mult(minusOne, c); //a = comparison*a+(1-comparison)*b ==> comparison*(a-b)+b //b = comparison*b+(1-comparison)*a ==> -comparison*(a-b)+a builder.par(par -> { values.set(a, par.numeric().add(c, valueB)); values.set(b, par.numeric().add(d, valueA)); return null; }); }
@Override public DRes<SInt> buildComputation(ProtocolBuilderNumeric builder) { return builder.seq((seq) -> { //Find the bit representation of the input return seq.advancedNumeric().toBits(input, maxBitLength); }).seq((seq, bits) -> { DRes<SInt> mostSignificantBitIndex = null; Numeric numeric = seq.numeric(); for (int n = 0; n < maxBitLength; n++) { // If bits[n] == 1 we let mostSignificantIndex be current index. // Otherwise we leave it be. SInt remainderResult = bits.get(n); if (mostSignificantBitIndex == null) { mostSignificantBitIndex = numeric.mult(BigInteger.valueOf(n), () -> remainderResult); } else { DRes<SInt> sub = numeric.sub(BigInteger.valueOf(n), mostSignificantBitIndex); DRes<SInt> mult = numeric.mult(() -> remainderResult, sub); mostSignificantBitIndex = numeric.add(mult, mostSignificantBitIndex); } } // We are interested in the bit length of the input, so we add one to // the index of the most significant bit since the indices are counte from 0 return numeric.add(BigInteger.ONE, mostSignificantBitIndex); }); }
@Override public DRes<SReal> add(BigDecimal a, DRes<SReal> b) { return builder.seq(seq -> { SFixed floatB = (SFixed) b.out(); int precision = Math.max(defaultPrecision, floatB.getPrecision()); BigInteger intA = unscaled(a, precision); DRes<SInt> unscaledB = unscaled(seq, (SFixed) b.out(), precision); return new SFixed(seq.numeric().add(intA, unscaledB), precision); }); }
@Override public DRes<BigInteger> buildComputation(ProtocolBuilderNumeric producer) { return producer.seq(inputApp).seq((seq, inputs) -> { DRes<SInt> sum = null; for (SInt input : inputs) { if (sum == null) { sum = input; } else { sum = seq.numeric().add(sum, input); } } return seq.numeric().open(sum); }); } }
@Override public DRes<SInt> buildComputation(ProtocolBuilderNumeric builder) { BigInteger modulus = builder.getBasicNumericContext().getModulus(); final int requiredRounds = getRequiredRounds(modulus, requestedRounds); /* * In the first round we compute c = (p + K)^{3} where p is the plaintext */ return builder.seq(seq -> { DRes<SInt> add = seq.numeric().add(plainText, encryptionKey); return new IterationState(1, seq.advancedNumeric().exp(add, THREE)); }).whileLoop((state) -> state.round < requiredRounds, (seq, state) -> { /* * We're in an intermediate round where we compute c_{i} = (c_{i - 1} + K + r_{i})^{3} where K * is the symmetric key i is the reverse of the current round count r_{i} is the round * constant c_{i - 1} is the cipher text we have computed in the previous round */ BigInteger roundConstantInteger = roundConstants.getConstant(state.round, modulus); Numeric numeric = seq.numeric(); DRes<SInt> masked = numeric.add(roundConstantInteger, numeric.add(state.value, encryptionKey)); DRes<SInt> updatedValue = seq.advancedNumeric().exp(masked, THREE); return new IterationState(state.round + 1, updatedValue); }).seq((seq, state) -> /* * We're in the last round so we just mask the current cipher text with the encryption key */ seq.numeric().add(state.value, encryptionKey)); }
@Override public DRes<SReal> add(DRes<SReal> a, DRes<SReal> b) { return builder.seq(seq -> { SFixed floatA = (SFixed) a.out(); SFixed floatB = (SFixed) b.out(); int precision = Math.max(floatA.getPrecision(), (floatB.getPrecision())); DRes<SInt> unscaledA = unscaled(seq, floatA, precision); DRes<SInt> unscaledB = unscaled(seq, floatB, precision); return new SFixed(seq.numeric().add(unscaledA, unscaledB), precision); }); }
@Override public DRes<SInt> buildComputation(ProtocolBuilderNumeric builder) { int degree = polynomial.getMaxDegree(); /* * We use Horner's method, p(x) = (( ... ((p_{n-1} x + p_{n-2})x + * p_{n-3}) ... )x + a_1)x + a_0 */ DRes<SInt> tmp = polynomial.getCoefficient(degree - 1); for (int i = degree - 2; i >= 0; i--) { tmp = builder.numeric().mult(tmp, valueX); tmp = builder.numeric().add(tmp, polynomial.getCoefficient(i)); } return tmp; }
@Override public void test() { Application<BigInteger, ProtocolBuilderNumeric> app = producer -> { Numeric numeric = producer.numeric(); DRes<SInt> input = numeric.input(value, 1); DRes<SInt> result = numeric.add(add, input); return numeric.open(result); }; BigInteger output = runApplication(app); Assert.assertEquals(BigInteger.valueOf(14), output); } };
@Override public void test() { Application<BigInteger, ProtocolBuilderNumeric> app = producer -> { Numeric numeric = producer.numeric(); DRes<SInt> firstClosed = numeric.known(first); DRes<SInt> secondClosed = numeric.known(second); DRes<SInt> add = numeric.add(firstClosed, secondClosed); DRes<SInt> mult = numeric.mult(firstClosed, add); return numeric.open(mult); }; BigInteger output = runApplication(app); Assert.assertEquals(first.add(second).multiply(first), output); } };
@Override public void test() { BigInteger modulus = conf.getResourcePool().getModulus(); BigInteger leftValue = modulus.subtract(BigInteger.ONE); BigInteger rightValue = BigInteger.valueOf(4); Application<BigInteger, ProtocolBuilderNumeric> app = producer -> { Numeric numeric = producer.numeric(); DRes<SInt> left = numeric.input(leftValue, 1); DRes<SInt> right = numeric.input(rightValue, 1); DRes<SInt> result = numeric.add(left, right); return numeric.open(result); }; BigInteger output = runApplication(app); Assert.assertEquals(BigInteger.valueOf(3), output); } };
@Override public DRes<SInt> buildComputation(ProtocolBuilderNumeric builder) { return builder.seq((seq) -> seq.advancedNumeric() .additiveMask(bitLength + securityParameter) ).seq((seq, mask) -> { DRes<SInt> mS = seq.numeric().add(input, () -> mask.random); DRes<BigInteger> mO = seq.numeric().open(mS); return () -> new Pair<>(mask.bits.subList(0, bitLength), mO.out()); }).seq((seq, pair) -> new HammingDistance(pair.getFirst(), pair.getSecond()).buildComputation(seq) ); } }
@Override public void test() { Application<BigInteger, ProtocolBuilderNumeric> app = producer -> { Numeric numeric = producer.numeric(); DRes<SInt> left = numeric.input(leftValue, 1); DRes<SInt> right = numeric.input(rightValue, 1); DRes<SInt> result = numeric.add(left, right); return numeric.open(result); }; BigInteger output = runApplication(app); Assert.assertEquals(BigInteger.valueOf(14), output); } };
@Test public void testRunApplication() { Application<BigInteger, ProtocolBuilderNumeric> app = builder -> { DRes<SInt> a = builder.numeric().known(BigInteger.valueOf(10)); DRes<SInt> b = builder.numeric().known(BigInteger.valueOf(10)); return builder.numeric().open(builder.numeric().add(a, b)); }; DummyArithmeticResourcePool rp = new DummyArithmeticResourcePoolImpl(0, 1, fieldDefinition); BigInteger b = sce.runApplication(app, rp, null); assertThat(b, is(BigInteger.valueOf(20))); }
@Test public void testRunApplicationLong() { Application<BigInteger, ProtocolBuilderNumeric> app = builder -> { DRes<SInt> a = builder.numeric().known(10L); DRes<SInt> b = builder.numeric().known(10L); return builder.numeric().open(builder.numeric().add(a, b)); }; DummyArithmeticResourcePool rp = new DummyArithmeticResourcePoolImpl(0, 1, fieldDefinition); BigInteger b = sce.runApplication(app, rp, null); assertThat(b, is(BigInteger.valueOf(20))); }