diff --git a/core/src/main/java/dk/alexandra/fresco/framework/builder/BuildStep.java b/core/src/main/java/dk/alexandra/fresco/framework/builder/BuildStep.java index 2cbba9bdb..24b6edd78 100644 --- a/core/src/main/java/dk/alexandra/fresco/framework/builder/BuildStep.java +++ b/core/src/main/java/dk/alexandra/fresco/framework/builder/BuildStep.java @@ -8,7 +8,7 @@ /** * A single step in the chained list of lambda that creates protocols to evaluate. The root step is - * defined in the ProbtocolBuilderImpl. + * defined in the ProtocolBuilderImpl. * * @param the type of input for this binary step (the previous step's output). * @param the type iof builder, currently either numeric or binary diff --git a/core/src/main/java/dk/alexandra/fresco/framework/builder/ProtocolBuilderImpl.java b/core/src/main/java/dk/alexandra/fresco/framework/builder/ProtocolBuilderImpl.java index e54012916..e16148d62 100644 --- a/core/src/main/java/dk/alexandra/fresco/framework/builder/ProtocolBuilderImpl.java +++ b/core/src/main/java/dk/alexandra/fresco/framework/builder/ProtocolBuilderImpl.java @@ -26,7 +26,7 @@ protected ProtocolBuilderImpl( this.factory = factory; } - private void createAndAppend(ProtocolProducer producer) { + protected void createAndAppend(ProtocolProducer producer) { if (protocols == null) { throw new IllegalStateException("Cannot build this twice, it has all ready been constructed"); } @@ -93,4 +93,8 @@ public BuildStep par(ComputationParallel f) createAndAppend(new LazyProtocolProducerDecorator(() -> builder.createProducer(null, factory))); return builder; } + + public boolean isParallel() { + return parallel; + } } diff --git a/core/src/main/java/dk/alexandra/fresco/framework/builder/numeric/ProtocolBuilderNumeric.java b/core/src/main/java/dk/alexandra/fresco/framework/builder/numeric/ProtocolBuilderNumeric.java index db4c5aa8f..a4a2bebf1 100644 --- a/core/src/main/java/dk/alexandra/fresco/framework/builder/numeric/ProtocolBuilderNumeric.java +++ b/core/src/main/java/dk/alexandra/fresco/framework/builder/numeric/ProtocolBuilderNumeric.java @@ -14,7 +14,7 @@ public class ProtocolBuilderNumeric extends ProtocolBuilderImpl connectNetwork(final NetworkConfiguration conf, connectionService.submit(() -> connectServer(conf)); Duration remainingTime = timeout; try { + Future> completed; + Instant start = Instant.now(); for (int i = 0; i < connectionThreads; i++) { remainingTime = remainingTime.minus(Duration.between(start, Instant.now())); - Future> completed = - connectionService.poll(remainingTime.toMillis(), TimeUnit.MILLISECONDS); + completed = connectionService.poll(remainingTime.toMillis(), TimeUnit.MILLISECONDS); if (completed == null) { throw new TimeoutException("Timed out waiting for client connections"); } else { @@ -134,7 +129,7 @@ private Map connectClient(final NetworkConfiguration conf) } catch (ConnectException e) { // A connect exception is expected if the opposing side is not listening for our // connection attempt yet. We ignore this and try again. - Thread.sleep(1 << ++attempts); + Thread.sleep(1L << ++attempts); } } } diff --git a/core/src/main/java/dk/alexandra/fresco/framework/sce/evaluator/NetworkBatchDecorator.java b/core/src/main/java/dk/alexandra/fresco/framework/sce/evaluator/NetworkBatchDecorator.java index cb8317810..80f80cd2f 100644 --- a/core/src/main/java/dk/alexandra/fresco/framework/sce/evaluator/NetworkBatchDecorator.java +++ b/core/src/main/java/dk/alexandra/fresco/framework/sce/evaluator/NetworkBatchDecorator.java @@ -52,10 +52,24 @@ public int getNoOfParties() { public void send(int id, byte[] data) { ByteArrayOutputStream buffer = this.output .computeIfAbsent(id, (i) -> new ByteArrayOutputStream()); - if (data.length > Byte.MAX_VALUE) { - throw new IllegalStateException( - "Current implementation only supports small packages, data.length=" + data.length); - } +// if (data.length > Byte.MAX_VALUE) { +// byte[] buf = new byte[Byte.MAX_VALUE]; +// int offset = 0; +// do { +// System.arraycopy(data, offset, buf, 0, Byte.MAX_VALUE); +// send(id, buf); +// offset += Byte.MAX_VALUE; +// } while (offset + Byte.MAX_VALUE <= data.length); +// if (data.length % Byte.MAX_VALUE != 0) { +// // we need to send a last block +// int length = data.length - offset; +// buf = new byte[length]; +// System.arraycopy(data, offset, buf, 0, length); +// send(id, buf); +// } +// throw new IllegalStateException( +// "Current implementation only supports small packages, data.length=" + data.length); +// } buffer.write(data.length); buffer.write(data, 0, data.length); } diff --git a/core/src/main/java/dk/alexandra/fresco/framework/sce/evaluator/ProtocolCollectionList.java b/core/src/main/java/dk/alexandra/fresco/framework/sce/evaluator/ProtocolCollectionList.java index 79d4c4632..2b2afe5a3 100644 --- a/core/src/main/java/dk/alexandra/fresco/framework/sce/evaluator/ProtocolCollectionList.java +++ b/core/src/main/java/dk/alexandra/fresco/framework/sce/evaluator/ProtocolCollectionList.java @@ -6,6 +6,8 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; public class ProtocolCollectionList implements ProtocolCollection { diff --git a/core/src/main/java/dk/alexandra/fresco/lib/helper/SingleProtocolProducer.java b/core/src/main/java/dk/alexandra/fresco/lib/helper/SingleProtocolProducer.java index 34b542ca6..cb180a179 100644 --- a/core/src/main/java/dk/alexandra/fresco/lib/helper/SingleProtocolProducer.java +++ b/core/src/main/java/dk/alexandra/fresco/lib/helper/SingleProtocolProducer.java @@ -48,4 +48,9 @@ public T out() { } return result; } + + public NativeProtocol getProtocol() { + return protocol; + } + } diff --git a/demos/sum/src/main/java/dk/alexandra/fresco/demo/InputSumExample.java b/demos/sum/src/main/java/dk/alexandra/fresco/demo/InputSumExample.java index e026b9122..548d485c9 100644 --- a/demos/sum/src/main/java/dk/alexandra/fresco/demo/InputSumExample.java +++ b/demos/sum/src/main/java/dk/alexandra/fresco/demo/InputSumExample.java @@ -43,7 +43,11 @@ public void runApplication( network.sendToAll(ByteBuffer.allocate(4).putInt(myArraySize).array()); List received = network.receiveFromAll(); - int[] allInputSizes = received.stream().mapToInt(binary -> ByteBuffer.allocate(4).put(binary).rewind().getInt()).toArray(); + int[] allInputSizes = received.stream().mapToInt(binary -> binary[3] + | binary[2] << 8 + | binary[1] << 16 + | binary[0] << 24 + ).toArray(); if (myId == 1) { // party input diff --git a/lib/common/src/main/java/dk/alexandra/fresco/lib/common/compare/RandomAdditiveMask.java b/lib/common/src/main/java/dk/alexandra/fresco/lib/common/compare/RandomAdditiveMask.java index 1f7479dd0..1a031ebaf 100644 --- a/lib/common/src/main/java/dk/alexandra/fresco/lib/common/compare/RandomAdditiveMask.java +++ b/lib/common/src/main/java/dk/alexandra/fresco/lib/common/compare/RandomAdditiveMask.java @@ -2,6 +2,7 @@ import dk.alexandra.fresco.framework.DRes; import dk.alexandra.fresco.framework.builder.Computation; +import dk.alexandra.fresco.framework.util.Pair; import dk.alexandra.fresco.lib.common.math.AdvancedNumeric; import dk.alexandra.fresco.framework.builder.numeric.Numeric; import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric; @@ -14,30 +15,25 @@ public class RandomAdditiveMask implements Computation { private final int noOfBits; - - private List> bits; - private DRes value; - public RandomAdditiveMask(int noOfBits) { this.noOfBits = noOfBits; } @Override public DRes buildComputation( - ProtocolBuilderNumeric builder) { - Numeric numericBuilder = builder.numeric(); - bits = new ArrayList<>(); - for (int i = 0; i < noOfBits; i++) { - DRes randomBit = numericBuilder.randomBit(); - bits.add(randomBit); - } - - MiscBigIntegerGenerators oIntGenerators = new MiscBigIntegerGenerators(builder.getBasicNumericContext().getModulus()); - AdvancedNumeric advancedNumeric = AdvancedNumeric.using(builder); - List twoPows = oIntGenerators.getTwoPowersList(noOfBits); - value = advancedNumeric.innerProductWithPublicPart(twoPows, bits); - return () -> new AdvancedNumeric.RandomAdditiveMask( - bits, - value.out()); + ProtocolBuilderNumeric builder) { + return builder.par(par -> { + Numeric numericBuilder = par.numeric(); + List> bits = new ArrayList<>(); + for (int i = 0; i < noOfBits; i++) { + DRes randomBit = numericBuilder.randomBit(); + bits.add(randomBit); + } + return DRes.of(bits); + }).par((par, bits) -> { + MiscBigIntegerGenerators oIntGenerators = new MiscBigIntegerGenerators(par.getBasicNumericContext().getModulus()); + List twoPows = oIntGenerators.getTwoPowersList(noOfBits); + return Pair.lazy(bits, AdvancedNumeric.using(par).innerProductWithPublicPart(twoPows, bits)); + }).par((par, bitsAndValue) -> DRes.of(new AdvancedNumeric.RandomAdditiveMask(bitsAndValue.getFirst(), bitsAndValue.getSecond()))); } -} +} \ No newline at end of file diff --git a/lib/common/src/main/java/dk/alexandra/fresco/lib/common/math/DefaultAdvancedNumeric.java b/lib/common/src/main/java/dk/alexandra/fresco/lib/common/math/DefaultAdvancedNumeric.java index 00cc0e023..e09cedbe0 100644 --- a/lib/common/src/main/java/dk/alexandra/fresco/lib/common/math/DefaultAdvancedNumeric.java +++ b/lib/common/src/main/java/dk/alexandra/fresco/lib/common/math/DefaultAdvancedNumeric.java @@ -7,6 +7,7 @@ import dk.alexandra.fresco.framework.value.SInt; import dk.alexandra.fresco.lib.common.collections.sort.KeyedCompareAndSwap; import dk.alexandra.fresco.lib.common.compare.MiscBigIntegerGenerators; +import dk.alexandra.fresco.lib.common.compare.RandomAdditiveMask; import dk.alexandra.fresco.lib.common.math.integer.conditional.ConditionalSelect; import dk.alexandra.fresco.lib.common.math.integer.conditional.SwapIf; import dk.alexandra.fresco.lib.common.math.integer.binary.IntegerToBitsLogRounds; @@ -178,7 +179,7 @@ public DRes, List>>>> keyedCompareAndSwap( public DRes bitsToInteger(List> bits) { MiscBigIntegerGenerators oIntGenerators = new MiscBigIntegerGenerators( builder.getBasicNumericContext().getModulus()); - return builder.seq(seq -> AdvancedNumeric.using(seq) + return builder.par(par -> AdvancedNumeric.using(par) .innerProductWithPublicPart(oIntGenerators.getTwoPowersList(bits.size()), bits)); } } diff --git a/lib/common/src/main/java/dk/alexandra/fresco/lib/common/math/integer/binary/Truncate.java b/lib/common/src/main/java/dk/alexandra/fresco/lib/common/math/integer/binary/Truncate.java index f0efeb0c4..66da05beb 100644 --- a/lib/common/src/main/java/dk/alexandra/fresco/lib/common/math/integer/binary/Truncate.java +++ b/lib/common/src/main/java/dk/alexandra/fresco/lib/common/math/integer/binary/Truncate.java @@ -2,12 +2,16 @@ 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.Pair; import dk.alexandra.fresco.framework.value.SInt; +import dk.alexandra.fresco.lib.common.compare.MiscBigIntegerGenerators; import dk.alexandra.fresco.lib.common.math.AdvancedNumeric; import dk.alexandra.fresco.lib.common.math.AdvancedNumeric.RandomAdditiveMask; import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; /** * Returns a number which is approximately the input shifted a number of positions to the right. The @@ -37,20 +41,18 @@ public DRes buildComputation(ProtocolBuilderNumeric builder) { if (shifts >= maxBitLength) { return builder.numeric().known(0); } - - return builder.seq(seq -> { - + return builder.par(par -> { /* * Generate random additive mask of the same length as the input + some extra to avoid * leakage. */ - return AdvancedNumeric.using(seq) - .additiveMask(maxBitLength + builder.getBasicNumericContext().getStatisticalSecurityParam()); + return AdvancedNumeric.using(par) + .additiveMask(maxBitLength + builder.getBasicNumericContext().getStatisticalSecurityParam()); - }).seq((seq, randomAdditiveMask) -> { + }).par((par, randomAdditiveMask) -> { - DRes result = seq.numeric().add(input, randomAdditiveMask.value); - DRes open = seq.numeric().open(result); + DRes result = par.numeric().add(input, randomAdditiveMask.value); + DRes open = par.numeric().open(result); return Pair.lazy(open, randomAdditiveMask); }).seq((seq, maskedInput) -> { @@ -62,10 +64,10 @@ public DRes buildComputation(ProtocolBuilderNumeric builder) { * rBottom = r (mod 2^shifts). */ final DRes rBottom = AdvancedNumeric.using(seq) - .bitsToInteger(mask.bits.subList(0, shifts)); + .bitsToInteger(mask.bits.subList(0, shifts)); BigInteger inverse = - BigInteger.ONE.shiftLeft(shifts).modInverse(seq.getBasicNumericContext().getModulus()); + BigInteger.ONE.shiftLeft(shifts).modInverse(seq.getBasicNumericContext().getModulus()); DRes rTop = seq.numeric().sub(mask.value, rBottom); /* diff --git a/lib/common/src/main/java/dk/alexandra/fresco/lib/common/math/integer/linalg/InnerProductOpen.java b/lib/common/src/main/java/dk/alexandra/fresco/lib/common/math/integer/linalg/InnerProductOpen.java index 96fed8b16..76368429d 100644 --- a/lib/common/src/main/java/dk/alexandra/fresco/lib/common/math/integer/linalg/InnerProductOpen.java +++ b/lib/common/src/main/java/dk/alexandra/fresco/lib/common/math/integer/linalg/InnerProductOpen.java @@ -36,6 +36,6 @@ public DRes buildComputation(ProtocolBuilderNumeric builder) { result.add(numericBuilder.mult(nextA, nextB)); } return () -> result; - }).seq((seq, list) -> AdvancedNumeric.using(seq).sum(list)); + }).par((par, list) -> AdvancedNumeric.using(par).sum(list)); } } diff --git a/lib/fixed/src/main/java/dk/alexandra/fresco/lib/fixed/DefaultAdvancedFixedNumeric.java b/lib/fixed/src/main/java/dk/alexandra/fresco/lib/fixed/DefaultAdvancedFixedNumeric.java index 4bedc3462..fc574d98e 100644 --- a/lib/fixed/src/main/java/dk/alexandra/fresco/lib/fixed/DefaultAdvancedFixedNumeric.java +++ b/lib/fixed/src/main/java/dk/alexandra/fresco/lib/fixed/DefaultAdvancedFixedNumeric.java @@ -31,9 +31,9 @@ public DefaultAdvancedFixedNumeric(ProtocolBuilderNumeric builder) { @Override public DRes random() { - return builder.seq(seq -> { + return builder.par(par -> { DRes random = - AdvancedNumeric.using(seq).additiveMask(seq.getBasicNumericContext().getDefaultFixedPointPrecision()); + AdvancedNumeric.using(par).additiveMask(par.getBasicNumericContext().getDefaultFixedPointPrecision()); return random; }).seq((seq, random) -> { return () -> new SFixed(random.value); diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTAdd.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTAdd.java new file mode 100644 index 000000000..e59330d8e --- /dev/null +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTAdd.java @@ -0,0 +1,57 @@ +package dk.alexandra.fresco.suite.crt; + +import dk.alexandra.fresco.framework.DRes; +import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; +import dk.alexandra.fresco.framework.network.Network; +import dk.alexandra.fresco.framework.value.SInt; +import dk.alexandra.fresco.suite.crt.datatypes.CRTSInt; +import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTResourcePool; +import dk.alexandra.fresco.suite.crt.protocols.framework.CRTNativeProtocol; +import dk.alexandra.fresco.suite.spdz.SpdzResourcePool; +import dk.alexandra.fresco.suite.spdz.gates.SpdzAddProtocol; +import dk.alexandra.fresco.suite.spdz.gates.SpdzMultProtocol; + +public class CRTAdd extends CRTNativeProtocol { + + private final DRes a; + private final DRes b; + private CRTSInt out; + private EvaluationStatus status = EvaluationStatus.HAS_MORE_ROUNDS; + private SpdzAddProtocol spdzAddProtocolLeft; + private SpdzAddProtocol spdzAddProtocolRight; + + public CRTAdd(DRes a, DRes b) { + this.a = a; + this.b = b; + } + + @Override + public CRTSInt out() { + return out; + } + + @Override + public EvaluationStatus evaluate(int round, CRTResourcePool CRTResourcePool, + Network network) { + if (round == 0) { + CRTSInt aOut = (CRTSInt) a.out(); + DRes aLeft = aOut.getLeft(); + DRes aRight = aOut.getRight(); + + CRTSInt bOut = (CRTSInt) b.out(); + DRes bLeft = bOut.getLeft(); + DRes bRight = bOut.getRight(); + + spdzAddProtocolLeft = new SpdzAddProtocol(aLeft, bLeft); + spdzAddProtocolRight = new SpdzAddProtocol(aRight, bRight); + } + spdzAddProtocolLeft.evaluate(round, (SpdzResourcePool) CRTResourcePool.getSubResourcePools().getFirst(), network); + status = spdzAddProtocolRight.evaluate(round, (SpdzResourcePool) CRTResourcePool.getSubResourcePools().getSecond(), network); + if (status == EvaluationStatus.IS_DONE) { + this.out = new CRTSInt(spdzAddProtocolLeft.out(), spdzAddProtocolRight.out()); + return EvaluationStatus.IS_DONE; + } else { + return EvaluationStatus.HAS_MORE_ROUNDS; + } + } +} \ No newline at end of file diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTBuilderFactory.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTBuilderFactory.java index 8865e8611..ced76fa05 100644 --- a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTBuilderFactory.java +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTBuilderFactory.java @@ -7,40 +7,50 @@ import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric; import dk.alexandra.fresco.framework.util.Pair; import dk.alexandra.fresco.framework.value.SInt; -import dk.alexandra.fresco.lib.common.math.AdvancedNumeric; import dk.alexandra.fresco.lib.field.integer.BasicNumericContext; import dk.alexandra.fresco.suite.crt.datatypes.CRTSInt; -import dk.alexandra.fresco.suite.crt.protocols.CRTSIntProtocol; -import dk.alexandra.fresco.suite.crt.protocols.framework.CRTBigIntegerProtocol; -import dk.alexandra.fresco.suite.crt.suites.ProtocolSuiteProtocolSupplier; +import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTDataSupplier; +import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTResourcePool; +import dk.alexandra.fresco.suite.crt.protocols.framework.ProtocolBuilderNumericWrapper; +import dk.alexandra.fresco.suite.spdz.gates.SpdzMultProtocol; + import java.math.BigInteger; public class CRTBuilderFactory implements BuilderFactoryNumeric { - private final BasicNumericContext context; - private final ProtocolSuiteProtocolSupplier left; - private final ProtocolSuiteProtocolSupplier right; + private final CRTNumericContext context; + private final BuilderFactoryNumeric left; + private final BuilderFactoryNumeric right; private final BigInteger p, q; + private final ResourcePoolA resourcePoolLeft; + private final ResourcePoolB resourcePoolRight; - public CRTBuilderFactory(ResourcePoolA resourcePoolLeft, - ProtocolSuiteProtocolSupplier leftPspp, - ResourcePoolB resourcePoolRight, - ProtocolSuiteProtocolSupplier rightPspp) { + public CRTBuilderFactory(CRTResourcePool resourcePool, + BuilderFactoryNumeric left, + BuilderFactoryNumeric right) { + this(resourcePool, left, right, CRTDataSupplier.DEFAULT_STATSECURITY); + } + public CRTBuilderFactory(CRTResourcePool resourcePool, + BuilderFactoryNumeric left, + BuilderFactoryNumeric right, + int statisticalSec) { - if (resourcePoolLeft.getMyId() != resourcePoolRight.getMyId() - || resourcePoolLeft.getNoOfParties() != resourcePoolRight.getNoOfParties()) { + if (resourcePool.getSubResourcePools().getFirst().getMyId() != resourcePool.getSubResourcePools().getSecond().getMyId() + || resourcePool.getSubResourcePools().getFirst().getNoOfParties() != resourcePool.getSubResourcePools().getSecond().getNoOfParties()) { throw new IllegalArgumentException( "The protocol suites used must be configured with the same ID and number of players"); } - this.left = leftPspp; - this.right = rightPspp; + this.left = left; + this.resourcePoolLeft = resourcePool.getSubResourcePools().getFirst(); + this.right = right; + this.resourcePoolRight = resourcePool.getSubResourcePools().getSecond(); this.p = resourcePoolLeft.getModulus(); this.q = resourcePoolRight.getModulus(); - this.context = new CRTNumericContext( - p.bitLength() + q.bitLength() - 40, //TODO - resourcePoolLeft.getMyId(), resourcePoolLeft.getNoOfParties(), left, right, p, q); + this.context = new CRTNumericContext<>( + p.bitLength() + q.bitLength() - statisticalSec, //TODO update based on new detail + resourcePoolLeft.getMyId(), resourcePoolLeft.getNoOfParties(), left, right, p, q, resourcePool); } @Override @@ -48,13 +58,15 @@ public BasicNumericContext getBasicNumericContext() { return context; } + @Override public Numeric createNumeric(ProtocolBuilderNumeric builder) { return new Numeric() { @Override public DRes add(DRes a, DRes b) { - +// CRTAdd crtAdd = new CRTAdd(a, b); +// return builder.append(crtAdd); return builder.par(par -> { CRTSInt aOut = (CRTSInt) a.out(); @@ -65,9 +77,12 @@ public DRes add(DRes a, DRes b) { DRes bLeft = bOut.getLeft(); DRes bRight = bOut.getRight(); - return par.append(new CRTSIntProtocol<>( - left.add(aLeft, bLeft), - right.add(aRight, bRight))); + Numeric l = context.leftNumeric(par); + Numeric r = context.rightNumeric(par); + + return new CRTSInt( + l.add(aLeft, bLeft), + r.add(aRight, bRight)); }); } @@ -92,8 +107,12 @@ public DRes sub(DRes a, DRes b) { DRes bLeft = bOut.getLeft(); DRes bRight = bOut.getRight(); - return par.append(new CRTSIntProtocol<>( - left.sub(aLeft, bLeft), right.sub(aRight, bRight))); + Numeric l = context.leftNumeric(par); + Numeric r = context.rightNumeric(par); + + return new CRTSInt( + l.sub(aLeft, bLeft), + r.sub(aRight, bRight)); }); } @@ -117,6 +136,8 @@ public DRes sub(DRes a, BigInteger b) { @Override public DRes mult(DRes a, DRes b) { +// CRTMult crtMult = new CRTMult(a, b); +// return builder.append(crtMult); return builder.par(par -> { CRTSInt aOut = (CRTSInt) a.out(); DRes aLeft = aOut.getLeft(); @@ -126,75 +147,105 @@ public DRes mult(DRes a, DRes b) { DRes bLeft = bOut.getLeft(); DRes bRight = bOut.getRight(); - return par.append(new CRTSIntProtocol<>( - left.mult(aLeft, bLeft), right.mult(aRight, bRight))); + Numeric l = context.leftNumeric(par); + Numeric r = context.rightNumeric(par); + + return new CRTSInt( + l.mult(aLeft, bLeft), + r.mult(aRight, bRight)); }); } @Override public DRes mult(BigInteger a, DRes b) { - return builder.seq(seq -> { - Numeric numeric = createNumeric(seq); - DRes aSecret = numeric.known(a); - return numeric.mult(aSecret, b); + return builder.par(par -> { + Pair aRNS = Util.mapToCRT(a, p, q); + + CRTSInt bOut = (CRTSInt) b.out(); + DRes bLeft = bOut.getLeft(); + DRes bRight = bOut.getRight(); + + Numeric l = context.leftNumeric(par); + Numeric r = context.rightNumeric(par); + + return new CRTSInt( + l.mult(aRNS.getFirst(), bLeft), + r.mult(aRNS.getSecond(), bRight)); }); } @Override public DRes randomBit() { - return builder.seq(seq -> builder.numeric().known(0)); // TODO + return builder.seq(seq -> seq.numeric().known(0)); // TODO } @Override public DRes randomElement() { - return builder.par(par -> par.append(new CRTSIntProtocol<>( - left.randomElement(), right.randomElement()))); + return builder.par(par -> { + Numeric l = context.leftNumeric(par); + Numeric r = context.rightNumeric(par); + return new CRTSInt(l.randomElement(), + r.randomElement()); + }); } @Override public DRes known(BigInteger value) { + Pair crt = Util.mapToCRT(value, p, q); +// CRTKnown crtMult = new CRTKnown(crt); +// return builder.append(crtMult); return builder.par(par -> { - Pair crt = mapToCRT(value); - return par.append(new CRTSIntProtocol<>( - left.known(crt.getFirst()), right.known(crt.getSecond()))); + Numeric l = context.leftNumeric(par); + Numeric r = context.rightNumeric(par); + return new CRTSInt(l.known(crt.getFirst()), r.known(crt.getSecond())); }); } @Override public DRes input(BigInteger value, int inputParty) { + Pair crt; + if (value != null) { + crt = Util.mapToCRT(value, p, q); + } else { + crt = new Pair<>(null, null); + } + return builder.par(par -> { - Pair crt = mapToCRT(value); - return par.append(new CRTSIntProtocol<>( - left.input(crt.getFirst(), inputParty), right.input(crt.getSecond(), inputParty))); + Numeric l = context.leftNumeric(par); + Numeric r = context.rightNumeric(par); + + return new CRTSInt(l.input(crt.getFirst(), inputParty), + r.input(crt.getSecond(), inputParty)); }); } @Override public DRes open(DRes secretShare) { +// CRTOpen crtOpen = new CRTOpen(secretShare); +// return builder.append(crtOpen); return builder.par(par -> { CRTSInt crtsInt = (CRTSInt) secretShare.out(); - return par.append(new CRTBigIntegerProtocol<>( - left.open(crtsInt.getLeft()), - right.open(crtsInt.getRight()), - p, q)); - }); + + Numeric l = context.leftNumeric(par); + Numeric r = context.rightNumeric(par); + + return Pair.lazy(l.open(crtsInt.getLeft()), r.open(crtsInt.getRight())); + }).seq((seq, opened) -> DRes.of(Util.mapToBigInteger(opened.getFirst().out(), opened.getSecond().out(), p, q))); } @Override public DRes open(DRes secretShare, int outputParty) { return builder.par(par -> { CRTSInt crtsInt = (CRTSInt) secretShare.out(); - return par.append(new CRTBigIntegerProtocol<>( - left.open(crtsInt.getLeft(), outputParty), - right.open(crtsInt.getRight(), outputParty), - p, q)); - }); + + Numeric l = left.createNumeric(new ProtocolBuilderNumericWrapper<>(par, left, resourcePoolLeft)); + Numeric r = right.createNumeric(new ProtocolBuilderNumericWrapper<>(par, right, resourcePoolRight)); + + return Pair.lazy(l.open(crtsInt.getLeft(), outputParty), r.open(crtsInt.getRight(), outputParty)); + }).seq((seq, opened) -> DRes.of(opened.getFirst() == null ? null : Util.mapToBigInteger(opened.getFirst().out(), opened.getSecond().out(), p, q))); + } }; } - public Pair mapToCRT(BigInteger x) { - return Util.mapToCRT(x, p, q); - } - } diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTKnown.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTKnown.java new file mode 100644 index 000000000..ab690abf7 --- /dev/null +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTKnown.java @@ -0,0 +1,53 @@ +package dk.alexandra.fresco.suite.crt; + +import dk.alexandra.fresco.framework.DRes; +import dk.alexandra.fresco.framework.Party; +import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; +import dk.alexandra.fresco.framework.network.Network; +import dk.alexandra.fresco.framework.util.Pair; +import dk.alexandra.fresco.framework.value.SInt; +import dk.alexandra.fresco.suite.crt.datatypes.CRTSInt; +import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTResourcePool; +import dk.alexandra.fresco.suite.crt.protocols.framework.CRTNativeProtocol; +import dk.alexandra.fresco.suite.spdz.SpdzResourcePool; +import dk.alexandra.fresco.suite.spdz.gates.SpdzKnownSIntProtocol; +import dk.alexandra.fresco.suite.spdz.gates.SpdzMultProtocol; + +import java.math.BigInteger; + +public class CRTKnown extends CRTNativeProtocol { + + private final BigInteger left; + private final BigInteger right; + private CRTSInt out; + private EvaluationStatus status = EvaluationStatus.HAS_MORE_ROUNDS; + private SpdzKnownSIntProtocol spdzLeft; + private SpdzKnownSIntProtocol spdzRight; + + public CRTKnown(Pair input) { + this.left = input.getFirst(); + this.right = input.getSecond(); + } + + @Override + public CRTSInt out() { + return out; + } + + @Override + public EvaluationStatus evaluate(int round, CRTResourcePool CRTResourcePool, + Network network) { + if (round == 0) { + spdzLeft = new SpdzKnownSIntProtocol(left); + spdzRight = new SpdzKnownSIntProtocol(right); + } + spdzLeft.evaluate(round, (SpdzResourcePool) CRTResourcePool.getSubResourcePools().getFirst(), network); + status = spdzRight.evaluate(round, (SpdzResourcePool) CRTResourcePool.getSubResourcePools().getSecond(), network); + if (status == EvaluationStatus.IS_DONE) { + this.out = new CRTSInt(spdzLeft.out(), spdzRight.out()); + return EvaluationStatus.IS_DONE; + } else { + return EvaluationStatus.HAS_MORE_ROUNDS; + } + } +} diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTMult.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTMult.java new file mode 100644 index 000000000..3408609b2 --- /dev/null +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTMult.java @@ -0,0 +1,63 @@ +package dk.alexandra.fresco.suite.crt; + +import dk.alexandra.fresco.framework.DRes; +import dk.alexandra.fresco.framework.builder.numeric.Numeric; +import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; +import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric; +import dk.alexandra.fresco.framework.network.Network; +import dk.alexandra.fresco.framework.value.SInt; +import dk.alexandra.fresco.suite.crt.datatypes.CRTSInt; +import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTResourcePool; +import dk.alexandra.fresco.suite.crt.protocols.framework.CRTNativeProtocol; +import dk.alexandra.fresco.suite.spdz.SpdzResourcePool; +import dk.alexandra.fresco.suite.spdz.datatypes.SpdzSInt; +import dk.alexandra.fresco.suite.spdz.gates.SpdzKnownSIntProtocol; +import dk.alexandra.fresco.suite.spdz.gates.SpdzMultProtocol; +import dk.alexandra.fresco.suite.spdz.gates.SpdzNativeProtocol; + +import java.math.BigInteger; + +public class CRTMult extends CRTNativeProtocol { + + private final DRes a; + private final DRes b; + private CRTSInt out; + private EvaluationStatus status = EvaluationStatus.HAS_MORE_ROUNDS; + private SpdzMultProtocol spdzMultProtocolLeft; + private SpdzMultProtocol spdzMultProtocolRight; + + public CRTMult(DRes a, DRes b) { + this.a = a; + this.b = b; + } + + @Override + public CRTSInt out() { + return out; + } + + @Override + public EvaluationStatus evaluate(int round, CRTResourcePool CRTResourcePool, + Network network) { + if (round == 0) { + CRTSInt aOut = (CRTSInt) a.out(); + DRes aLeft = aOut.getLeft(); + DRes aRight = aOut.getRight(); + + CRTSInt bOut = (CRTSInt) b.out(); + DRes bLeft = bOut.getLeft(); + DRes bRight = bOut.getRight(); + + spdzMultProtocolLeft = new SpdzMultProtocol(aLeft, bLeft); + spdzMultProtocolRight = new SpdzMultProtocol(aRight, bRight); + } + spdzMultProtocolLeft.evaluate(round, (SpdzResourcePool) CRTResourcePool.getSubResourcePools().getFirst(), network); + status = spdzMultProtocolRight.evaluate(round, (SpdzResourcePool) CRTResourcePool.getSubResourcePools().getSecond(), network); + if (status == EvaluationStatus.IS_DONE) { + this.out = new CRTSInt(spdzMultProtocolLeft.out(), spdzMultProtocolRight.out()); + return EvaluationStatus.IS_DONE; + } else { + return EvaluationStatus.HAS_MORE_ROUNDS; + } + } +} diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTNumericContext.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTNumericContext.java index ef25dbe4a..56e607c51 100644 --- a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTNumericContext.java +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTNumericContext.java @@ -1,16 +1,26 @@ package dk.alexandra.fresco.suite.crt; +import dk.alexandra.fresco.framework.DRes; +import dk.alexandra.fresco.framework.builder.numeric.BuilderFactoryNumeric; +import dk.alexandra.fresco.framework.builder.numeric.Numeric; import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; -import dk.alexandra.fresco.framework.util.Pair; +import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric; +import dk.alexandra.fresco.framework.sce.resources.ResourcePool; +import dk.alexandra.fresco.framework.value.SInt; import dk.alexandra.fresco.lib.field.integer.BasicNumericContext; -import dk.alexandra.fresco.suite.crt.suites.ProtocolSuiteProtocolSupplier; +import dk.alexandra.fresco.suite.crt.datatypes.CRTSInt; +import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTResourcePool; +import dk.alexandra.fresco.suite.crt.protocols.framework.ProtocolBuilderNumericWrapper; + import java.math.BigInteger; public class CRTNumericContext extends BasicNumericContext { private final BigInteger p, q; - private final ProtocolSuiteProtocolSupplier leftProtocolSupplier; - private final ProtocolSuiteProtocolSupplier rightProtocolSupplier; + private final BuilderFactoryNumeric left; + private final BuilderFactoryNumeric right; + + private final CRTResourcePool resourcePool; /** * Construct a new BasicNumericContext. @@ -20,13 +30,14 @@ public class CRTNumericContext left, ProtocolSuiteProtocolSupplier right, - BigInteger p, BigInteger q) { + BuilderFactoryNumeric left, BuilderFactoryNumeric right, + BigInteger p, BigInteger q, CRTResourcePool resourcePool) { super(maxBitLength, myId, noOfParties, new CRTRingDefinition(p, q), p.bitLength()); this.p = p; this.q = q; - this.leftProtocolSupplier = left; - this.rightProtocolSupplier = right; + this.left = left; + this.right = right; + this.resourcePool = resourcePool; } /** Get the modulus of the left ring in the RNS representation. */ @@ -39,15 +50,59 @@ public BigInteger getRightModulus() { return q; } - /** Get a {@link ProtocolSuiteProtocolSupplier} for the MPC system on the left ring. */ - public ProtocolSuiteProtocolSupplier getLeftProtocolSupplier() { - return leftProtocolSupplier; + /** + * Get a {@link BuilderFactoryNumeric} for the MPC system on the left ring. + */ + public BuilderFactoryNumeric getLeft() { + return left; + } + + /** + * Get a {@link BuilderFactoryNumeric} for the MPC system on the right ring. + */ + public BuilderFactoryNumeric getRight() { + return right; + } + + + public ResourcePoolA getResourcePoolLeft() { + return resourcePool.getSubResourcePools().getFirst(); + } + + public ResourcePoolB getResourcePoolRight() { + return resourcePool.getSubResourcePools().getSecond(); + } + + public CRTResourcePool getResourcePool() { + return resourcePool; + } + + /** + * Get an instance of Numeric for the left scheme using the given builder. + */ + public Numeric leftNumeric(ProtocolBuilderNumeric builder) { + return left.createNumeric(new ProtocolBuilderNumericWrapper<>(builder, left, resourcePool.getSubResourcePools().getFirst())); + } + + /** + * Get an instance of Numeric for the right scheme using the given builder. + */ + public Numeric rightNumeric(ProtocolBuilderNumeric builder) { + return right.createNumeric(new ProtocolBuilderNumericWrapper<>(builder, right, resourcePool.getSubResourcePools().getSecond())); } - /** Get a {@link ProtocolSuiteProtocolSupplier} for the MPC system on the right ring. */ - public ProtocolSuiteProtocolSupplier getRightProtocolSupplier() { - return rightProtocolSupplier; + public DRes getLeft(DRes crtInteger) { + if (crtInteger.out() == null || !(crtInteger.out() instanceof CRTSInt)) { + throw new IllegalArgumentException("Input must be a non-null CRTSInt"); + } + return ((CRTSInt) crtInteger).getLeft(); } + public DRes getRight(DRes crtInteger) { + if (crtInteger.out() == null || !(crtInteger.out() instanceof CRTSInt)) { + throw new IllegalArgumentException("Input must be a non-null CRTSInt"); + } + return ((CRTSInt) crtInteger.out()).getRight(); + } } diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTOpen.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTOpen.java new file mode 100644 index 000000000..4374a7459 --- /dev/null +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTOpen.java @@ -0,0 +1,61 @@ +package dk.alexandra.fresco.suite.crt; + +import dk.alexandra.fresco.framework.DRes; +import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; +import dk.alexandra.fresco.framework.builder.numeric.field.FieldDefinition; +import dk.alexandra.fresco.framework.network.Network; +import dk.alexandra.fresco.framework.util.AesCtrDrbg; +import dk.alexandra.fresco.framework.util.OpenedValueStore; +import dk.alexandra.fresco.framework.util.OpenedValueStoreImpl; +import dk.alexandra.fresco.framework.util.Pair; +import dk.alexandra.fresco.framework.value.SInt; +import dk.alexandra.fresco.suite.crt.datatypes.CRTSInt; +import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTResourcePool; +import dk.alexandra.fresco.suite.crt.protocols.framework.CRTNativeProtocol; +import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticResourcePool; +import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticResourcePoolImpl; +import dk.alexandra.fresco.suite.spdz.SpdzResourcePool; +import dk.alexandra.fresco.suite.spdz.SpdzResourcePoolImpl; +import dk.alexandra.fresco.suite.spdz.gates.SpdzKnownSIntProtocol; +import dk.alexandra.fresco.suite.spdz.gates.SpdzOutputToAllProtocol; +import dk.alexandra.fresco.suite.spdz.storage.SpdzDataSupplier; +import dk.alexandra.fresco.suite.spdz.storage.SpdzDummyDataSupplier; + +import java.math.BigInteger; + +public class CRTOpen extends CRTNativeProtocol { + + private final DRes input; + private BigInteger out; + private EvaluationStatus status = EvaluationStatus.HAS_MORE_ROUNDS; + private SpdzOutputToAllProtocol spdzLeft; + private SpdzOutputToAllProtocol spdzRight; + + public CRTOpen(DRes input) { + this.input = input; + } + + @Override + public BigInteger out() { + return out; + } + + @Override + public EvaluationStatus evaluate(int round, CRTResourcePool CRTResourcePool, + Network network) { + if (round == 0) { + spdzLeft = new SpdzOutputToAllProtocol(((CRTSInt) input.out()).getLeft()); + spdzRight = new SpdzOutputToAllProtocol(((CRTSInt) input.out()).getRight()); + } + spdzLeft.evaluate(round, (SpdzResourcePool) CRTResourcePool.getSubResourcePools().getFirst(), network); + status = spdzRight.evaluate(round, (SpdzResourcePool) CRTResourcePool.getSubResourcePools().getSecond(), network); + if (status == EvaluationStatus.IS_DONE) { + Pair fieldDefs = CRTResourcePool.getFieldDefinitions(); + this.out = Util.mapToBigInteger(spdzLeft.out(), spdzRight.out(), fieldDefs.getFirst().getModulus(), fieldDefs.getSecond().getModulus()); + return EvaluationStatus.IS_DONE; + } else { + return EvaluationStatus.HAS_MORE_ROUNDS; + } + } +} + diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTProtocolSuite.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTProtocolSuite.java index 159f8c24d..31c2a6e89 100644 --- a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTProtocolSuite.java +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/CRTProtocolSuite.java @@ -7,25 +7,31 @@ import dk.alexandra.fresco.framework.util.Pair; import dk.alexandra.fresco.suite.ProtocolSuiteNumeric; import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTResourcePool; -import dk.alexandra.fresco.suite.crt.suites.ProtocolSuiteProtocolSupplier; public class CRTProtocolSuite implements ProtocolSuiteNumeric> { - private final ProtocolSuiteProtocolSupplier left; - private final ProtocolSuiteProtocolSupplier right; + private final BuilderFactoryNumeric left; + private final BuilderFactoryNumeric right; - public CRTProtocolSuite(ProtocolSuiteProtocolSupplier left, - ProtocolSuiteProtocolSupplier right) { + public CRTProtocolSuite(BuilderFactoryNumeric left, + BuilderFactoryNumeric right) { this.left = left; this.right = right; } + public BuilderFactoryNumeric getLeft() { + return left; + } + + public BuilderFactoryNumeric getRight() { + return right; + } + @Override public BuilderFactoryNumeric init(CRTResourcePool resourcePool) { Pair resourcePools = resourcePool.getSubResourcePools(); - return new CRTBuilderFactory<>(resourcePools.getFirst(), left, resourcePools.getSecond(), - right); + return new CRTBuilderFactory<>(resourcePool, left, right); } @Override @@ -34,18 +40,15 @@ public RoundSynchronization> createRoundSynchronization() @Override public void beforeBatch(ProtocolCollection> nativeProtocols, CRTResourcePool resourcePool, Network network) { - } @Override public void finishedBatch(int gatesEvaluated, CRTResourcePool resourcePool, Network network) { - } @Override public void finishedEval(CRTResourcePool resourcePool, Network network) { - } }; } diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/Util.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/Util.java index 004ab54c9..32a36e184 100644 --- a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/Util.java +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/Util.java @@ -1,5 +1,6 @@ package dk.alexandra.fresco.suite.crt; +import dk.alexandra.fresco.framework.util.Drbg; import dk.alexandra.fresco.framework.util.Pair; import java.math.BigInteger; import java.util.Objects; diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/CRTCombinedPad.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/CRTCombinedPad.java new file mode 100644 index 000000000..a11a1075c --- /dev/null +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/CRTCombinedPad.java @@ -0,0 +1,30 @@ +package dk.alexandra.fresco.suite.crt.datatypes; + +import dk.alexandra.fresco.framework.DRes; +import dk.alexandra.fresco.framework.value.SInt; + +import java.util.List; + +public class CRTCombinedPad { + private final CRTSInt noisePair; + private final DRes rho; + private final DRes psi; + + public CRTCombinedPad(CRTSInt noisePair, DRes rho, DRes psi) { + this.noisePair = noisePair; + this.rho = rho; + this.psi = psi; + } + + public CRTSInt getNoisePair() { + return noisePair; + } + + public DRes getRho() { + return rho; + } + + public DRes getPsi() { + return psi; + } +} diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/CRTCovertDataSupplier.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/CRTCovertDataSupplier.java new file mode 100644 index 000000000..093064ebd --- /dev/null +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/CRTCovertDataSupplier.java @@ -0,0 +1,15 @@ +package dk.alexandra.fresco.suite.crt.datatypes.resource; + +import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; + +public class CRTCovertDataSupplier + extends CRTDataSupplier { + + public CRTCovertDataSupplier() { + this(DEFAULT_BATCH_SIZE, DEFAULT_DETERRENCE_FACTOR, DEFAULT_STATSECURITY); + } + + public CRTCovertDataSupplier(int batchSize, int deterrenceFactor, int securityParam) { + super(new CovertNoiseGenerator<>(batchSize, deterrenceFactor, securityParam)); + } +} diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/CRTDataSupplier.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/CRTDataSupplier.java index e02d9396f..3bcef2e3b 100644 --- a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/CRTDataSupplier.java +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/CRTDataSupplier.java @@ -1,24 +1,54 @@ package dk.alexandra.fresco.suite.crt.datatypes.resource; +import dk.alexandra.fresco.framework.DRes; +import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; +import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric; import dk.alexandra.fresco.framework.builder.numeric.field.FieldDefinition; import dk.alexandra.fresco.framework.util.Pair; +import dk.alexandra.fresco.suite.crt.datatypes.CRTCombinedPad; import dk.alexandra.fresco.suite.crt.datatypes.CRTSInt; -public interface CRTDataSupplier { +import java.util.ArrayDeque; + +public abstract class CRTDataSupplier { + public static final int DEFAULT_BATCH_SIZE = 8; + public static final int DEFAULT_DETERRENCE_FACTOR = 2; + public static final int DEFAULT_STATSECURITY = 60; + + private final ArrayDeque noisePairs = new ArrayDeque<>(); + private final NoiseGenerator noiseGenerator; + + + protected CRTDataSupplier(NoiseGenerator noiseGenerator) { + this.noiseGenerator = noiseGenerator; + } /** * Supplies the next correlated noise * * @return r */ - CRTSInt getCorrelatedNoise(); - + public DRes getCorrelatedNoise(ProtocolBuilderNumeric builder) { + if (noisePairs.isEmpty()) { + return builder.seq(noiseGenerator).seq((seq, noise) -> { + noisePairs.addAll(noise); + CRTCombinedPad out = noisePairs.pop(); + return DRes.of(out); + }); + } else { + return DRes.of(noisePairs.pop()); + } + } /** * Supply the next random bit - * + * todo * @return b */ - CRTSInt getRandomBit(); + public CRTSInt getRandomBit() { + throw new IllegalArgumentException("Not implemented yet"); + } - Pair getFieldDefinitions(); + public Pair getFieldDefinitions() { + throw new IllegalArgumentException("Not implemented yet"); + } } diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/CRTDummyDataSupplier.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/CRTDummyDataSupplier.java index 4c8da904b..5e592d107 100644 --- a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/CRTDummyDataSupplier.java +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/CRTDummyDataSupplier.java @@ -1,27 +1,33 @@ package dk.alexandra.fresco.suite.crt.datatypes.resource; +import dk.alexandra.fresco.framework.DRes; +import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; +import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric; import dk.alexandra.fresco.framework.builder.numeric.field.FieldDefinition; import dk.alexandra.fresco.framework.util.Pair; import dk.alexandra.fresco.framework.value.SInt; import dk.alexandra.fresco.suite.crt.Util; +import dk.alexandra.fresco.suite.crt.datatypes.CRTCombinedPad; import dk.alexandra.fresco.suite.crt.datatypes.CRTSInt; import java.math.BigInteger; import java.util.Random; import java.util.function.Function; -public class CRTDummyDataSupplier implements CRTDataSupplier { +public class CRTDummyDataSupplier extends CRTDataSupplier { private final FieldDefinition fp, fq; - private final int myId; private final int players; + private final int statisticalSecurity; private final Random random; private final Function wrapperLeft, wrapperRight; - public CRTDummyDataSupplier(int myId, int players, FieldDefinition leftField, - FieldDefinition rightField, Function wrapperLeft, - Function wrapperRight) { - this.myId = myId; + // todo could aggregate the semihonest Dummy data supplier to avoid code-copy + public CRTDummyDataSupplier(int myId, int players, int statisticalSecurity, FieldDefinition leftField, + FieldDefinition rightField, Function wrapperLeft, + Function wrapperRight) { + super(null); this.players = players; + this.statisticalSecurity = statisticalSecurity; this.fp = leftField; this.fq = rightField; this.wrapperLeft = wrapperLeft; @@ -32,13 +38,17 @@ public CRTDummyDataSupplier(int myId, int players, FieldDefinition leftField, } @Override - public CRTSInt getCorrelatedNoise() { + public DRes getCorrelatedNoise(ProtocolBuilderNumeric builder) { BigInteger r = Util.randomBigInteger(random, fp.getModulus()); BigInteger l = Util - .randomBigInteger(random, BigInteger.valueOf(players).add(BigInteger.ONE)); - - return new CRTSInt(wrapperLeft.apply(r), - wrapperRight.apply(r.add(l.multiply(fp.getModulus())))); + .randomBigInteger(random, BigInteger.valueOf(players)); + BigInteger rho = new BigInteger(statisticalSecurity, random); + BigInteger psi = new BigInteger(statisticalSecurity, random); + return DRes.of( + new CRTCombinedPad( + new CRTSInt(wrapperLeft.apply(r), + wrapperRight.apply(r.add(l.multiply(fp.getModulus())))), + wrapperRight.apply(rho), wrapperRight.apply(psi))); } @Override diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/CRTResourcePoolImpl.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/CRTResourcePoolImpl.java index 7e3262f2b..6dc41c1df 100644 --- a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/CRTResourcePoolImpl.java +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/CRTResourcePoolImpl.java @@ -19,8 +19,8 @@ public CRTResourcePoolImpl(int myId, int noOfPlayers, CRTDataSupplier dataSuppli super(myId, noOfPlayers); this.dataSupplier = dataSupplier; this.definition = new CRTRingDefinition( - dataSupplier.getFieldDefinitions().getFirst().getModulus(), - dataSupplier.getFieldDefinitions().getSecond().getModulus()); + resourcePoolLeft.getFieldDefinition().getModulus(), + resourcePoolRight.getFieldDefinition().getModulus()); this.resourcePools = new Pair<>(resourcePoolLeft, resourcePoolRight); } @@ -31,7 +31,7 @@ public Pair getSubResourcePools() { @Override public Pair getFieldDefinitions() { - return dataSupplier.getFieldDefinitions(); + return new Pair<>(resourcePools.getFirst().getFieldDefinition(), resourcePools.getSecond().getFieldDefinition()); } @Override diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/CRTSemiHonestDataSupplier.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/CRTSemiHonestDataSupplier.java new file mode 100644 index 000000000..709ca7319 --- /dev/null +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/CRTSemiHonestDataSupplier.java @@ -0,0 +1,16 @@ +package dk.alexandra.fresco.suite.crt.datatypes.resource; + +import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; + +public class CRTSemiHonestDataSupplier + extends CRTDataSupplier { + + public CRTSemiHonestDataSupplier() { + super(new SemiHonestNoiseGenerator<>(DEFAULT_BATCH_SIZE, DEFAULT_STATSECURITY)); + } + + public CRTSemiHonestDataSupplier(int batchSize, int statSec) { + super(new SemiHonestNoiseGenerator<>(batchSize, statSec)); + } +} diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/CovertNoiseGenerator.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/CovertNoiseGenerator.java new file mode 100644 index 000000000..1cf9df139 --- /dev/null +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/CovertNoiseGenerator.java @@ -0,0 +1,150 @@ +package dk.alexandra.fresco.suite.crt.datatypes.resource; + +import dk.alexandra.fresco.framework.DRes; +import dk.alexandra.fresco.framework.MaliciousException; +import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; +import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric; +import dk.alexandra.fresco.framework.util.*; +import dk.alexandra.fresco.framework.value.SInt; +import dk.alexandra.fresco.suite.crt.CRTNumericContext; +import dk.alexandra.fresco.suite.crt.datatypes.CRTCombinedPad; +import dk.alexandra.fresco.suite.crt.datatypes.CRTSInt; +import dk.alexandra.fresco.tools.commitment.CoinTossingComputation; +import dk.alexandra.fresco.tools.commitment.HashBasedCommitmentSerializer; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +public class CovertNoiseGenerator + extends NoiseGenerator { + + private final int batchSize; + private final int deterrenceFactor; + private final int securityParam; + + private final PairShareGenerator pairShareGenerator; + private final PaddingGenerator padGenerator; + private final CoinTossingComputation coinToss; + private AesCtrDrbg jointDrbg; + private final Drng localDrng; + + + public CovertNoiseGenerator(int batchSize, int deterrenceFactor, int securityParam) { + this(batchSize, deterrenceFactor, securityParam, new AesCtrDrbg()); + } + + public CovertNoiseGenerator(int batchSize, int deterrenceFactor, int securityParam, Drbg localDrbg) { + this.batchSize = batchSize; + this.deterrenceFactor = deterrenceFactor; + this.securityParam = securityParam; + + this.localDrng = new DrngImpl(localDrbg); + HashBasedCommitmentSerializer commitmentSerializer = new HashBasedCommitmentSerializer(); + this.pairShareGenerator = new PairShareGenerator<>(this.deterrenceFactor * batchSize, securityParam, localDrng); + this.padGenerator = new PaddingGenerator(this.deterrenceFactor * batchSize, securityParam, localDrng); + this.coinToss = new CoinTossingComputation(32, commitmentSerializer, localDrbg); + } + + @Override + public DRes> buildComputation(ProtocolBuilderNumeric builder, + CRTNumericContext context) { + return builder.par(par -> { + DRes> pairShares = pairShareGenerator.buildComputation(par, context); + DRes> rhoPad = padGenerator.buildComputation(par, context); + DRes> psiPad = padGenerator.buildComputation(par, context); + // Sample batchsize random noise pairs to keep, mark all other to be checked/selected + DRes seed; + if (this.jointDrbg == null) { + seed = coinToss.buildComputation(par); + } // reuse seed if already computed. + else { + seed = null; + } + return () -> new Object[] { + pairShares, rhoPad, psiPad, seed, + }; + }).par((par, data) -> { + List combinedPads = new ArrayList<>(this.deterrenceFactor * batchSize); + for (int i = 0; i < deterrenceFactor * batchSize; i++) { + combinedPads.add(new CRTCombinedPad( + ((DRes>) data[0]).out().get(i), + ((DRes>) data[1]).out().get(i).getRight(), + ((DRes>) data[2]).out().get(i).getRight())); + } + return Pair.lazy((DRes) data[3], combinedPads); + }).par((par, pair) -> { // Open selected pairs + // prepare pairs indices to keep + if (this.jointDrbg == null) { + byte[] seed = pair.getFirst().out(); + jointDrbg = new AesCtrDrbg(seed); + } + + // Sample indexes of elements to keep + int[] toKeep = new int[batchSize]; + for (int i = 0; i < batchSize; i++) { + // We need securityParam + log(deterrenceFactor) bits to ensure uniform randomness + byte[] sample = new byte[1+((securityParam + Integer.numberOfLeadingZeros(deterrenceFactor))/8)]; + jointDrbg.nextBytes(sample); + toKeep[i] = new BigInteger(1, sample).mod(BigInteger.valueOf(deterrenceFactor)).intValue(); + } + + // check all other pairs + List combinedPad = pair.getSecond(); + int i = 0; + List> padTestSet = new ArrayList<>(); + List, DRes>> noisePairTestSet = new ArrayList<>(); + List noisePairsToKeep = new ArrayList<>(batchSize); + List> rhoToKeep = new ArrayList<>(batchSize); + List> psiToKeep = new ArrayList<>(batchSize); + for (int j = 0; j < batchSize*deterrenceFactor; j++) { + i = j / deterrenceFactor; // current batch no. + if (j == toKeep[i] + i * deterrenceFactor) {// skip the once marked to keep. + // scale them back up, so they correspond to a batch. + noisePairsToKeep.add(combinedPad.get(j).getNoisePair()); + rhoToKeep.add(combinedPad.get(j).getRho()); + psiToKeep.add(combinedPad.get(j).getPsi()); + } else { + DRes leftClosed = combinedPad.get(j).getNoisePair().getLeft(); + DRes rightClosed = combinedPad.get(j).getNoisePair().getRight(); + DRes leftOpened = context.leftNumeric(par).open(leftClosed); + DRes rightOpened = context.rightNumeric(par).open(rightClosed); + noisePairTestSet.add(new Pair<>(leftOpened, rightOpened)); + DRes rhoToTest = context.rightNumeric(par).open(combinedPad.get(j).getRho()); + DRes psiToTest = context.rightNumeric(par).open(combinedPad.get(j).getPsi()); + padTestSet.add(rhoToTest); + padTestSet.add(psiToTest); + } + } + Object[] data = new Object[] { + noisePairsToKeep, noisePairTestSet, rhoToKeep, psiToKeep, padTestSet + }; + return () -> data; + }).par((par, data) -> { // Check selected pairs + List, DRes>> noiseTestSet = (List, DRes>>) data[1]; + List> padTestSet = (List>) data[4]; + BigInteger modulo = BigInteger.valueOf(2).pow(securityParam); + for (int i = 0; i < batchSize*(deterrenceFactor-1); i++) { + BigInteger rp = noiseTestSet.get(i).getFirst().out(); + BigInteger rq = noiseTestSet.get(i).getSecond().out(); + if (rp.compareTo(rq) != 0) { + throw new MaliciousException("Cheating in the noise pair"); + } + } + // TODO identify which party is malicious + for (int i = 0; i < 2*batchSize*(deterrenceFactor-1); i++) { + if (padTestSet.get(i).out().compareTo(modulo) >= 0) { + throw new MaliciousException("Cheating in the size of psi or rho"); + } + } + List noisePairs = (List) data[0]; + List rhoToKeep = (List) data[2]; + List psiToKeep = (List) data[3]; + List padsToUse = new ArrayList<>(batchSize); + for (int i = 0; i < batchSize; i++) { + padsToUse.add(new CRTCombinedPad(noisePairs.get(i), rhoToKeep.get(i), psiToKeep.get(i))); + } + return () -> padsToUse; + }); + } +} \ No newline at end of file diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/NoiseGenerator.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/NoiseGenerator.java new file mode 100644 index 000000000..945539e8d --- /dev/null +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/NoiseGenerator.java @@ -0,0 +1,18 @@ +package dk.alexandra.fresco.suite.crt.datatypes.resource; + +import dk.alexandra.fresco.framework.DRes; +import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; +import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric; +import dk.alexandra.fresco.suite.crt.CRTNumericContext; +import dk.alexandra.fresco.suite.crt.datatypes.CRTCombinedPad; +import dk.alexandra.fresco.suite.crt.protocols.framework.CRTComputation; + +import java.util.List; + +public abstract class NoiseGenerator + extends CRTComputation, ResourcePoolL, ResourcePoolR> { + + @Override + abstract public DRes> buildComputation(ProtocolBuilderNumeric builder, + CRTNumericContext context); +} diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/PaddingGenerator.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/PaddingGenerator.java new file mode 100644 index 000000000..51825121d --- /dev/null +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/PaddingGenerator.java @@ -0,0 +1,58 @@ +package dk.alexandra.fresco.suite.crt.datatypes.resource; + +import dk.alexandra.fresco.framework.DRes; +import dk.alexandra.fresco.framework.builder.numeric.Numeric; +import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; +import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric; +import dk.alexandra.fresco.framework.util.AesCtrDrbg; +import dk.alexandra.fresco.framework.util.Drbg; +import dk.alexandra.fresco.framework.util.Drng; +import dk.alexandra.fresco.framework.util.DrngImpl; +import dk.alexandra.fresco.framework.value.SInt; +import dk.alexandra.fresco.suite.crt.CRTNumericContext; +import dk.alexandra.fresco.suite.crt.datatypes.CRTSInt; +import dk.alexandra.fresco.suite.crt.protocols.framework.CRTComputation; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +public class PaddingGenerator + extends CRTComputation, ResourcePoolL, ResourcePoolR> { + + private final int batchSize; + private final int securityParam; + private final Drng localDrng; + + public PaddingGenerator(int batchSize, int securityParam) { + this(batchSize, securityParam, new DrngImpl(new AesCtrDrbg())); + } + + public PaddingGenerator(int batchSize, int securityParam, Drng localDrng) { + this.batchSize = batchSize; + this.securityParam = securityParam; + this.localDrng = localDrng; + } + + @Override + public DRes> buildComputation(ProtocolBuilderNumeric builder, CRTNumericContext context) { + return builder.par(par -> { + Numeric right = context.rightNumeric(par); + List res = new ArrayList<>(batchSize); + for (int i = 0; i < batchSize; i++) { + for (int j = 1; j <= par.getBasicNumericContext().getNoOfParties(); j++) { + DRes curPad; + if (j == par.getBasicNumericContext().getMyId()) { + BigInteger modulo = BigInteger.valueOf(2).pow(securityParam); + BigInteger myRhoShare = localDrng.nextBigInteger(modulo); + curPad = right.input(myRhoShare, par.getBasicNumericContext().getMyId()); + } else { + curPad = right.input(null, j); + } + res.add(new CRTSInt(null, curPad)); + } + } + return () -> res; + }); + } +} \ No newline at end of file diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/PairShareGenerator.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/PairShareGenerator.java new file mode 100644 index 000000000..e73f36561 --- /dev/null +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/PairShareGenerator.java @@ -0,0 +1,61 @@ +package dk.alexandra.fresco.suite.crt.datatypes.resource; + +import dk.alexandra.fresco.framework.DRes; +import dk.alexandra.fresco.framework.builder.numeric.Numeric; +import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; +import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric; +import dk.alexandra.fresco.framework.util.AesCtrDrbg; +import dk.alexandra.fresco.framework.util.Drbg; +import dk.alexandra.fresco.framework.util.Drng; +import dk.alexandra.fresco.framework.util.DrngImpl; +import dk.alexandra.fresco.framework.value.SInt; +import dk.alexandra.fresco.suite.crt.CRTNumericContext; +import dk.alexandra.fresco.suite.crt.Util; +import dk.alexandra.fresco.suite.crt.datatypes.CRTSInt; +import dk.alexandra.fresco.suite.crt.protocols.framework.CRTComputation; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +public class PairShareGenerator + + extends CRTComputation, ResourcePoolL, ResourcePoolR> { + private final int batchSize; + private final int securityParam; + private final Drng localDrng; + + public PairShareGenerator(int batchSize, int securityParam) { + this(batchSize, securityParam, new DrngImpl(new AesCtrDrbg())); + } + + public PairShareGenerator(int batchSize, int securityParam, Drng localDrng) { + this.batchSize = batchSize; + this.securityParam = securityParam; + this.localDrng = localDrng; + } + + @Override + public DRes> buildComputation(ProtocolBuilderNumeric builder, CRTNumericContext context) { + return builder.par(par -> { + Numeric left = context.leftNumeric(par); + Numeric right = context.rightNumeric(par); + List res = new ArrayList<>(batchSize); + for (int i = 0; i < batchSize; i++) { + for (int j = 1; j <= context.getNoOfParties(); j++) { + DRes curLeft, curRight; + if (j == context.getMyId()) { + BigInteger r = localDrng.nextBigInteger(context.getLeftModulus()); + curLeft = left.input(r, context.getMyId()); + curRight = right.input(r, context.getMyId()); + } else { + curLeft = left.input(null, j); + curRight = right.input(null, j); + } + res.add(new CRTSInt(curLeft, curRight)); + } + } + return () -> res; + }); + } +} diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/SemiHonestNoiseGenerator.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/SemiHonestNoiseGenerator.java new file mode 100644 index 000000000..709abaaf5 --- /dev/null +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/datatypes/resource/SemiHonestNoiseGenerator.java @@ -0,0 +1,61 @@ +package dk.alexandra.fresco.suite.crt.datatypes.resource; + +import dk.alexandra.fresco.framework.DRes; +import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; +import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric; +import dk.alexandra.fresco.framework.util.*; +import dk.alexandra.fresco.suite.crt.CRTNumericContext; +import dk.alexandra.fresco.suite.crt.datatypes.CRTCombinedPad; +import dk.alexandra.fresco.suite.crt.datatypes.CRTSInt; +import dk.alexandra.fresco.tools.commitment.CoinTossingComputation; +import dk.alexandra.fresco.tools.commitment.HashBasedCommitmentSerializer; + +import java.util.ArrayList; +import java.util.List; + +public class SemiHonestNoiseGenerator + extends NoiseGenerator { + + private final int batchSize; + private final int securityParam; + private final Drng localDrng; + private final PairShareGenerator pairShareGenerator; + private final PaddingGenerator padGenerator; + private final CoinTossingComputation coinToss; + + public SemiHonestNoiseGenerator(int batchSize, int securityParam) { + this(batchSize, securityParam, new AesCtrDrbg()); + } + + public SemiHonestNoiseGenerator(int batchSize, int securityParam, Drbg localDrbg) { + this.batchSize = batchSize; + this.securityParam = securityParam; + this.localDrng = new DrngImpl(localDrbg); + HashBasedCommitmentSerializer commitmentSerializer = new HashBasedCommitmentSerializer(); + this.pairShareGenerator = new PairShareGenerator<>( batchSize, securityParam, new DrngImpl(localDrbg)); + this.padGenerator = new PaddingGenerator(batchSize, securityParam, new DrngImpl(localDrbg)); + this.coinToss = new CoinTossingComputation(32, commitmentSerializer, localDrbg); + } + + @Override + public DRes> buildComputation(ProtocolBuilderNumeric builder, + CRTNumericContext context) { + return builder.par(par -> { + DRes> pairShares = pairShareGenerator.buildComputation(par, context); + DRes> rhoPad = padGenerator.buildComputation(par, context); + DRes> psiPad = padGenerator.buildComputation(par, context); + return () -> new Object[] { + pairShares, rhoPad, psiPad + }; + }).par((par, data) -> { + List combinedPads = new ArrayList<>(batchSize); + for (int i = 0; i < batchSize; i++) { + combinedPads.add(new CRTCombinedPad( + ((DRes>) data[0]).out().get(i), + ((DRes>) data[1]).out().get(i).getRight(), + ((DRes>) data[2]).out().get(i).getRight())); + } + return ()->combinedPads; + }); + } +} diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/fixed/CRTFixedNumeric.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/fixed/CRTFixedNumeric.java index 46943c04d..965d7fc07 100644 --- a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/fixed/CRTFixedNumeric.java +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/fixed/CRTFixedNumeric.java @@ -6,6 +6,7 @@ import dk.alexandra.fresco.lib.fixed.DefaultFixedNumeric; import dk.alexandra.fresco.lib.fixed.truncations.Truncation; import dk.alexandra.fresco.suite.crt.CRTNumericContext; +import dk.alexandra.fresco.suite.crt.protocols.TruncOne; import dk.alexandra.fresco.suite.crt.protocols.Truncp; import java.math.BigInteger; @@ -21,10 +22,20 @@ public BigInteger getDivisor() { return ((CRTNumericContext) builder.getBasicNumericContext()).getLeftModulus(); } + /** + * Truncation with error bound in the amount of parties + */ @Override public DRes truncate(DRes value, ProtocolBuilderNumeric scope) { return new Truncp(value).buildComputation(scope); } + + /** + * Truncation with at most a single bit error + */ + public DRes truncateOne(DRes value, ProtocolBuilderNumeric scope) { + return new TruncOne(value).buildComputation(scope); + } }); this.p = ((CRTNumericContext) builder.getBasicNumericContext()).getLeftModulus(); } diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/CorrelatedNoiseProtocol.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/CorrelatedNoiseProtocol.java index 06d1e37f9..8d0435a49 100644 --- a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/CorrelatedNoiseProtocol.java +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/CorrelatedNoiseProtocol.java @@ -1,28 +1,18 @@ package dk.alexandra.fresco.suite.crt.protocols; +import dk.alexandra.fresco.framework.DRes; import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; -import dk.alexandra.fresco.framework.network.Network; -import dk.alexandra.fresco.framework.value.SInt; -import dk.alexandra.fresco.suite.crt.datatypes.CRTSInt; -import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTResourcePool; -import dk.alexandra.fresco.suite.crt.protocols.framework.CRTNativeProtocol; +import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric; +import dk.alexandra.fresco.suite.crt.CRTNumericContext; +import dk.alexandra.fresco.suite.crt.datatypes.CRTCombinedPad; +import dk.alexandra.fresco.suite.crt.protocols.framework.CRTComputation; /** Generate a pair of correlated noise, eg (r, r + ep) for some 0 ≤ e ≤ n. */ public class CorrelatedNoiseProtocol extends - CRTNativeProtocol { - - private CRTSInt r; - - @Override - public EvaluationStatus evaluate(int round, - CRTResourcePool resourcePool, Network network) { - - this.r = resourcePool.getDataSupplier().getCorrelatedNoise(); - return EvaluationStatus.IS_DONE; - } + CRTComputation { @Override - public SInt out() { - return r; + public DRes buildComputation(ProtocolBuilderNumeric builder, CRTNumericContext context) { + return context.getResourcePool().getDataSupplier().getCorrelatedNoise(builder); } } diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/LiftPQProtocol.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/LiftPQProtocol.java index 953335437..bbcc6560a 100644 --- a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/LiftPQProtocol.java +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/LiftPQProtocol.java @@ -1,45 +1,43 @@ package dk.alexandra.fresco.suite.crt.protocols; import dk.alexandra.fresco.framework.DRes; +import dk.alexandra.fresco.framework.builder.numeric.Numeric; import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric; import dk.alexandra.fresco.framework.value.SInt; import dk.alexandra.fresco.suite.crt.CRTNumericContext; +import dk.alexandra.fresco.suite.crt.Util; import dk.alexandra.fresco.suite.crt.datatypes.CRTSInt; import dk.alexandra.fresco.suite.crt.protocols.framework.CRTComputation; /** - * Given a secret shared [x]p in p, output [x - ep]q for some 0 ≤ e ≤ n in q. + * Given a secret shared ([x]p, [_]q) in p, output ([x]p, [x - ep]q) for some 0 ≤ e ≤ n in q. */ public class LiftPQProtocol extends - CRTComputation { - - private final DRes value; - private CRTSInt r; - - public LiftPQProtocol(DRes value) { - this.value = value; - } - - @Override - public DRes buildComputation(ProtocolBuilderNumeric builder, - CRTNumericContext context) { - return builder.seq(seq -> seq.append(new CorrelatedNoiseProtocol<>())).seq((seq, noise) -> { - this.r = (CRTSInt) noise.out(); - - DRes xBar; - if (value.out() instanceof CRTSInt) { - xBar = seq.append(context.getLeftProtocolSupplier().add(((CRTSInt) value.out()).getLeft(), r.getLeft())); - } else { - xBar = seq.append(context.getLeftProtocolSupplier().add(value, r.getLeft())); - } - return seq.append(context.getLeftProtocolSupplier().open(xBar)); - - }).seq((seq, xBarOpen) -> { - DRes xBarRight = context.getRightProtocolSupplier().known(xBarOpen); - DRes xRight = context.getRightProtocolSupplier().sub(xBarRight, r.getRight()); - return new CRTSInt(null, xRight); - }); - } - + CRTComputation { + + private final DRes value; + private CRTSInt r; + + // The right value is ignored in the input + public LiftPQProtocol(DRes value) { + this.value = value; + } + + @Override + public DRes buildComputation(ProtocolBuilderNumeric builder, + CRTNumericContext context) { + return builder.seq(new CorrelatedNoiseProtocol<>()).seq((seq, noise) -> { + this.r = noise.getNoisePair(); + + // Add noise to the left value. The right is ignored. + DRes xBar = context.leftNumeric(seq).add(((CRTSInt) value.out()).getLeft(), r.getLeft()); + return context.leftNumeric(seq).open(xBar); + }).seq((seq, xBarOpen) -> { + Numeric right = context.rightNumeric(seq); + // Remove the noise and return + DRes adjusted = right.sub(xBarOpen, r.getRight()); + return new CRTSInt(((CRTSInt) value.out()).getLeft(), adjusted); + }); + } } diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/LiftQPProtocol.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/LiftQPProtocol.java index b597e0b44..3f797e1a0 100644 --- a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/LiftQPProtocol.java +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/LiftQPProtocol.java @@ -1,37 +1,57 @@ package dk.alexandra.fresco.suite.crt.protocols; import dk.alexandra.fresco.framework.DRes; +import dk.alexandra.fresco.framework.builder.numeric.Numeric; import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric; import dk.alexandra.fresco.framework.value.SInt; import dk.alexandra.fresco.suite.crt.CRTNumericContext; +import dk.alexandra.fresco.suite.crt.Util; import dk.alexandra.fresco.suite.crt.datatypes.CRTSInt; import dk.alexandra.fresco.suite.crt.protocols.framework.CRTComputation; +import java.math.BigInteger; + /** - * Given a secret shared [x]q in q with x < q - np, output [x]p in p. + * Given a secret shared ([_]p, [x]q) in p, output ([x]p, [x]q). */ public class LiftQPProtocol extends - CRTComputation { - - private final DRes value; - private CRTSInt r; - - public LiftQPProtocol(DRes value) { - this.value = value; - } - - @Override - public DRes buildComputation(ProtocolBuilderNumeric builder, - CRTNumericContext context) { - return builder.seq(seq -> new CorrelatedNoiseProtocol<>()).seq((seq, noise) -> { - this.r = (CRTSInt) noise.out(); - DRes xBar = seq.append(context.getRightProtocolSupplier().add(value, r.getRight())); - return seq.append(context.getRightProtocolSupplier().open(xBar)); - }).seq((seq, xBarOpen) -> { - DRes xBarRight = context.getLeftProtocolSupplier().known(xBarOpen); - return context.getLeftProtocolSupplier().sub(xBarRight, r.getLeft()); - }); - } + CRTComputation { + + private final DRes value; + private CRTSInt r; + private DRes rho; + private DRes psi; + + public LiftQPProtocol(DRes value) { + this.value = value; + } + + @Override + public DRes buildComputation(ProtocolBuilderNumeric builder, + CRTNumericContext context) { + //q' = q / 2 is divisible by p, so adding it to the input only affects the output by q mod p = 1 if there's an overflow. + BigInteger qPrime = context.getRightModulus().subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); + + return builder.seq(new CorrelatedNoiseProtocol<>()).seq((seq, noise) -> { + this.r = (CRTSInt) noise.getNoisePair().out(); + this.rho = noise.getRho(); + this.psi = noise.getPsi(); + return seq.numeric().add(qPrime, value); + }).seq((seq, value) -> { + + // Add noise to the right value. The left is ignored. + DRes temp = context.rightNumeric(seq).add(((CRTSInt) value.out()).getRight(), r.getRight()); + // Add statistical noise drowning + DRes xBar = context.rightNumeric(seq).add(temp, + context.rightNumeric(seq).mult(context.getLeftModulus(), rho)); + return context.rightNumeric(seq).open(xBar); + }).seq((seq, xBarOpen) -> { + Numeric left = context.leftNumeric(seq); + // Remove the noise and return + DRes adjusted = left.sub(xBarOpen, r.getLeft()); + return new CRTSInt(adjusted, ((CRTSInt) value.out()).getRight()); + }); + } } diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/Projection.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/Projection.java index 5baf6e773..0d20d8709 100644 --- a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/Projection.java +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/Projection.java @@ -23,7 +23,7 @@ public Projection(DRes crt, Coordinate coordinate) { @Override public DRes buildComputation(ProtocolBuilderNumeric builder, - CRTNumericContext context) { + CRTNumericContext context) { BigInteger coefficient; if (coordinate == Coordinate.LEFT) { coefficient = context.getRightModulus().multiply(context.getRightModulus().modInverse(context.getLeftModulus())); diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/RandomModP.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/RandomModP.java index 5ad095bf1..f021c8085 100644 --- a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/RandomModP.java +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/RandomModP.java @@ -5,7 +5,6 @@ import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric; import dk.alexandra.fresco.framework.value.SInt; import dk.alexandra.fresco.suite.crt.CRTNumericContext; -import dk.alexandra.fresco.suite.crt.CRTRingDefinition; import dk.alexandra.fresco.suite.crt.protocols.Projection.Coordinate; import dk.alexandra.fresco.suite.crt.protocols.framework.CRTComputation; @@ -15,10 +14,7 @@ public class RandomModP buildComputation(ProtocolBuilderNumeric builder, CRTNumericContext context) { - return builder.seq(seq -> seq.numeric().randomElement()) - .pairInPar( - (seq, r) -> seq.seq(new Projection<>(r, Coordinate.LEFT)), - (seq, r) -> seq.seq(new LiftPQProtocol<>(r))) - .seq((seq, rPair) -> seq.numeric().add(rPair.getFirst(), rPair.getSecond())); + //TODO + return builder.numeric().known(7); } } diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/TruncOne.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/TruncOne.java new file mode 100644 index 000000000..7d27e05b4 --- /dev/null +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/TruncOne.java @@ -0,0 +1,57 @@ +package dk.alexandra.fresco.suite.crt.protocols; + +import dk.alexandra.fresco.framework.DRes; +import dk.alexandra.fresco.framework.builder.numeric.Numeric; +import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; +import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric; +import dk.alexandra.fresco.framework.util.Pair; +import dk.alexandra.fresco.framework.value.SInt; +import dk.alexandra.fresco.suite.crt.CRTNumericContext; +import dk.alexandra.fresco.suite.crt.datatypes.CRTSInt; +import dk.alexandra.fresco.suite.crt.protocols.framework.CRTComputation; + +import java.math.BigInteger; + +public class TruncOne extends CRTComputation { + + private final DRes value; + + public TruncOne(DRes value) { + this.value = value; + } + + @Override + public DRes buildComputation(ProtocolBuilderNumeric builder, + CRTNumericContext context) { + + // The multiplicative inverse of p mod q + BigInteger n2 = context.getLeftModulus().modInverse(context.getRightModulus()); + + return builder.seq(seq -> { + BigInteger U = BigInteger.valueOf(context.getNoOfParties()); // TODO is it right that it is exactly number of parties? + DRes y = new Truncp<>(value).buildComputation(seq); + // (U + 1)([x] - p[y] + pU) + DRes temp = seq.numeric().sub(value, + seq.numeric().mult(context.getLeftModulus(), y)); + temp = seq.numeric().add(context.getLeftModulus().multiply(U), temp); + DRes xPrime = seq.numeric().mult(U.add(BigInteger.ONE), temp); + DRes w = new Truncp<>(xPrime).buildComputation(seq); + temp = seq.numeric().sub(y, U); + return seq.numeric().sub(temp, poly(seq.numeric(), context.getModulus(), U, w)); + }); + } + + private DRes poly(Numeric seq, BigInteger m, BigInteger U, DRes w) { + long L = U.longValueExact()+1; + long M = L+1; + long iterations = M+M*L+L-1; + for (int i = 0; i < iterations; i++) { +//todo!! + } + return null; + } + + private DRes lagrange(Numeric seq, BigInteger m, DRes x, int i, int j) { + return seq.mult(BigInteger.valueOf(i-j).modInverse(m), seq.sub(x, i)); + } +} diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/Truncp.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/Truncp.java index 8bd38d7ff..aa190db14 100644 --- a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/Truncp.java +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/Truncp.java @@ -1,17 +1,18 @@ package dk.alexandra.fresco.suite.crt.protocols; import dk.alexandra.fresco.framework.DRes; +import dk.alexandra.fresco.framework.builder.numeric.Numeric; import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric; import dk.alexandra.fresco.framework.util.Pair; import dk.alexandra.fresco.framework.value.SInt; import dk.alexandra.fresco.suite.crt.CRTNumericContext; -import dk.alexandra.fresco.suite.crt.CRTRingDefinition; +import dk.alexandra.fresco.suite.crt.datatypes.CRTSInt; import dk.alexandra.fresco.suite.crt.protocols.Projection.Coordinate; import dk.alexandra.fresco.suite.crt.protocols.framework.CRTComputation; import java.math.BigInteger; -/** Compute x / p as integer division (rounded down) */ +/** Compute x / p as integer division (rounded down) with a potential error */ public class Truncp extends CRTComputation { private final DRes value; @@ -27,14 +28,13 @@ public DRes buildComputation(ProtocolBuilderNumeric builder, // The multiplicative inverse of p mod q BigInteger n2 = context.getLeftModulus().modInverse(context.getRightModulus()); - return builder.par(par -> { - DRes liftedX1 = new LiftPQProtocol<>(value).buildComputation(par); - DRes x2 = new Projection<>(value, Coordinate.RIGHT).buildComputation(par); - return Pair.lazy(liftedX1, x2); - }).seq((seq, x) -> { - DRes y2 = seq.numeric().mult(n2, seq.numeric().sub(x.getSecond(), x.getFirst())); + return builder.seq(seq -> new LiftPQProtocol<>(value).buildComputation(seq)).seq((seq, liftedX1) -> { + Numeric rightNumeric = context.rightNumeric(seq); + DRes y2Right = rightNumeric.sub(context.getRight(value), context.getRight(liftedX1)); + y2Right = rightNumeric.mult(n2, y2Right); + CRTSInt y2 = new CRTSInt(context.leftNumeric(seq).known(0), y2Right); DRes y1 = new LiftQPProtocol<>(y2).buildComputation(seq); - return seq.numeric().add(y1, y2); - }); + return Pair.lazy(y1, y2Right); + }).seq((seq, y) -> new CRTSInt(context.getLeft(y.getFirst().out()), y.getSecond())); } } diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/framework/CRTAbstractProtocol.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/framework/CRTAbstractProtocol.java index bbbbae0a2..9784b200a 100644 --- a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/framework/CRTAbstractProtocol.java +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/framework/CRTAbstractProtocol.java @@ -3,6 +3,7 @@ import dk.alexandra.fresco.framework.NativeProtocol; import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; import dk.alexandra.fresco.framework.network.Network; +import dk.alexandra.fresco.framework.util.Pair; import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTResourcePool; import java.util.function.BiFunction; diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/framework/CRTBatchedStrategy.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/framework/CRTBatchedStrategy.java new file mode 100644 index 000000000..605d57802 --- /dev/null +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/framework/CRTBatchedStrategy.java @@ -0,0 +1,39 @@ +package dk.alexandra.fresco.suite.crt.protocols.framework; + +import dk.alexandra.fresco.framework.NativeProtocol; +import dk.alexandra.fresco.framework.ProtocolCollection; +import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; +import dk.alexandra.fresco.framework.network.Network; +import dk.alexandra.fresco.framework.sce.evaluator.BatchEvaluationStrategy; +import dk.alexandra.fresco.framework.sce.evaluator.NetworkBatchDecorator; +import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTResourcePool; + +import java.util.Iterator; + +public class CRTBatchedStrategy implements + BatchEvaluationStrategy> { + + @Override + public void processBatch(ProtocolCollection> nativeProtocols, CRTResourcePool resourcePool, NetworkBatchDecorator network) { + int round = 0; + while (nativeProtocols.size() > 0) { + evaluateCurrentRound(nativeProtocols, network, resourcePool, round); + network.flush(); + round++; + } + } + + private void evaluateCurrentRound( + ProtocolCollection> protocols, Network sceNetwork, + CRTResourcePool rp, int round) { + Iterator>> iterator = protocols.iterator(); + while (iterator.hasNext()) { + NativeProtocol> protocol = iterator.next(); + NativeProtocol.EvaluationStatus status = protocol.evaluate(round, rp, sceNetwork); + if (status.equals(NativeProtocol.EvaluationStatus.IS_DONE)) { + iterator.remove(); + } + } + } +} + diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/framework/CRTComputation.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/framework/CRTComputation.java index ea495d61c..0e4f39abc 100644 --- a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/framework/CRTComputation.java +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/framework/CRTComputation.java @@ -5,7 +5,6 @@ import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric; import dk.alexandra.fresco.suite.crt.CRTNumericContext; -import dk.alexandra.fresco.suite.crt.CRTRingDefinition; public abstract class CRTComputation implements + BatchEvaluationStrategy> { + + @Override + public void processBatch(ProtocolCollection> protocols, + CRTResourcePool resourcePool, + NetworkBatchDecorator network) { + for (NativeProtocol> protocol : protocols) { + int round = 0; + NativeProtocol.EvaluationStatus status; + do { + status = protocol.evaluate(round, resourcePool, network); + // send phase + network.flush(); + round++; + } while (status.equals(NativeProtocol.EvaluationStatus.HAS_MORE_ROUNDS)); + } + } +} \ No newline at end of file diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/framework/NativeProtocolWrapper.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/framework/NativeProtocolWrapper.java new file mode 100644 index 000000000..3b91363d3 --- /dev/null +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/framework/NativeProtocolWrapper.java @@ -0,0 +1,32 @@ +package dk.alexandra.fresco.suite.crt.protocols.framework; + +import dk.alexandra.fresco.framework.NativeProtocol; +import dk.alexandra.fresco.framework.network.Network; +import dk.alexandra.fresco.framework.sce.resources.ResourcePool; + +// When native protocols are actually evaluated in an evaluation strategy, it's unknown which of the resource pools, each protocol will use. To fix this, +// we create this wrapper which gives a reference to the relevant resource pool for each single protocol in the {@link ProtocolBuilderNumericWrapper}. +public class NativeProtocolWrapper implements NativeProtocol { + + private final NativeProtocol protocol; + private final ResourcePoolT resourcePool; + + public NativeProtocolWrapper(NativeProtocol protocol, ResourcePoolT resourcePool) { + this.protocol = protocol; + this.resourcePool = resourcePool; + } + + public ResourcePoolT getResourcePool() { + return resourcePool; + } + + @Override + public OutputT out() { + return protocol.out(); + } + + @Override + public EvaluationStatus evaluate(int round, ResourcePoolT resourcePool, Network network) { + return protocol.evaluate(round, this.resourcePool, network); + } +} diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/framework/ProtocolBuilderNumericWrapper.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/framework/ProtocolBuilderNumericWrapper.java new file mode 100644 index 000000000..5485a6835 --- /dev/null +++ b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/protocols/framework/ProtocolBuilderNumericWrapper.java @@ -0,0 +1,28 @@ +package dk.alexandra.fresco.suite.crt.protocols.framework; + +import dk.alexandra.fresco.framework.DRes; +import dk.alexandra.fresco.framework.NativeProtocol; +import dk.alexandra.fresco.framework.builder.numeric.BuilderFactoryNumeric; +import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric; +import dk.alexandra.fresco.framework.sce.resources.ResourcePool; + +// When native protocols are actually evaluated in an evaluation strategy, it's unknown which of the resource pools, each protocol will use. To fix this, +// we create a wrapper around NativeProcol's which gives each of them reference to the relevant resource pool. +public class ProtocolBuilderNumericWrapper extends ProtocolBuilderNumeric { + + private final ResourcePoolT resourcePool; + private final ProtocolBuilderNumeric builder; + + public ProtocolBuilderNumericWrapper(ProtocolBuilderNumeric builder, BuilderFactoryNumeric factory, ResourcePoolT resourcePool) { + super(factory, builder.isParallel()); + this.builder = builder; + this.resourcePool = resourcePool; + } + + @Override + public DRes append(NativeProtocol nativeProtocol) { + return builder.append(new NativeProtocolWrapper<>((NativeProtocol) nativeProtocol, resourcePool)); + } + + +} diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/suites/DummyProtocolSupplier.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/suites/DummyProtocolSupplier.java deleted file mode 100644 index 65157b898..000000000 --- a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/suites/DummyProtocolSupplier.java +++ /dev/null @@ -1,98 +0,0 @@ -package dk.alexandra.fresco.suite.crt.suites; - -import dk.alexandra.fresco.framework.DRes; -import dk.alexandra.fresco.framework.NativeProtocol; -import dk.alexandra.fresco.framework.builder.numeric.field.FieldDefinition; -import dk.alexandra.fresco.framework.value.SInt; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticAddProtocol; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticCloseProtocol; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticKnownProtocol; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticMultProtocol; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticOpenProtocol; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticOpenToAllProtocol; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticRandomBitProtocol; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticRandomElementProtocol; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticResourcePool; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticSInt; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticSubtractProtocol; -import java.math.BigInteger; -import java.util.Random; - -public class DummyProtocolSupplier implements - ProtocolSuiteProtocolSupplier { - - private final Random random; - private final FieldDefinition field; - - public DummyProtocolSupplier(Random random, FieldDefinition field) { - this.random = random; - this.field = field; - } - - @Override - public NativeProtocol known(BigInteger value) { - return new DummyArithmeticKnownProtocol(value); - } - - @Override - public NativeProtocol input(BigInteger value, int playerId) { - return new DummyArithmeticCloseProtocol(value, playerId); - } - - @Override - public NativeProtocol open(DRes value, - int playerId) { - return new DummyArithmeticOpenProtocol(value, playerId); - } - - @Override - public NativeProtocol open(DRes value) { - return new DummyArithmeticOpenToAllProtocol(value); - } - - @Override - public NativeProtocol add(DRes a, DRes b) { - return new DummyArithmeticAddProtocol(a, b); - } - - @Override - public NativeProtocol add(BigInteger a, DRes b) { - return new DummyArithmeticAddProtocol(new DummyArithmeticSInt(field.createElement(a)), b); - } - - @Override - public NativeProtocol sub(DRes a, DRes b) { - return new DummyArithmeticSubtractProtocol(a, b); - } - - @Override - public NativeProtocol sub(DRes a, BigInteger b) { - return new DummyArithmeticSubtractProtocol(a, new DummyArithmeticSInt(field.createElement(b))); - } - - @Override - public NativeProtocol sub(BigInteger a, DRes b) { - return new DummyArithmeticMultProtocol(new DummyArithmeticSInt(field.createElement(a)), b); - } - - @Override - public NativeProtocol mult(DRes a, DRes b) { - return new DummyArithmeticMultProtocol(a, b); - } - - @Override - public NativeProtocol mult(BigInteger a, DRes b) { - return new DummyArithmeticMultProtocol(new DummyArithmeticSInt(field.createElement(a)), b); - } - - @Override - public NativeProtocol randomElement() { - return new DummyArithmeticRandomElementProtocol(random); - } - - @Override - public NativeProtocol randomBit() { - return new DummyArithmeticRandomBitProtocol(random); - } - -} diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/suites/ProtocolSuiteProtocolSupplier.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/suites/ProtocolSuiteProtocolSupplier.java deleted file mode 100644 index 29eebbedb..000000000 --- a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/suites/ProtocolSuiteProtocolSupplier.java +++ /dev/null @@ -1,38 +0,0 @@ -package dk.alexandra.fresco.suite.crt.suites; - -import dk.alexandra.fresco.framework.DRes; -import dk.alexandra.fresco.framework.NativeProtocol; -import dk.alexandra.fresco.framework.builder.numeric.NumericResourcePool; -import dk.alexandra.fresco.framework.builder.numeric.field.FieldDefinition; -import dk.alexandra.fresco.framework.value.SInt; -import java.math.BigInteger; - -public interface ProtocolSuiteProtocolSupplier { - - NativeProtocol known(BigInteger value); - - NativeProtocol input(BigInteger value, int playerId); - - NativeProtocol open(DRes value, int playerId); - - NativeProtocol open(DRes value); - - NativeProtocol add(DRes a, DRes b); - - NativeProtocol add(BigInteger a, DRes b); - - NativeProtocol sub(DRes a, DRes b); - - NativeProtocol sub(DRes a, BigInteger b); - - NativeProtocol sub(BigInteger a, DRes b); - - NativeProtocol mult(DRes a, DRes b); - - NativeProtocol mult(BigInteger a, DRes b); - - NativeProtocol randomElement(); - - NativeProtocol randomBit(); - -} diff --git a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/suites/SpdzProtocolSupplier.java b/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/suites/SpdzProtocolSupplier.java deleted file mode 100644 index 5f578c8fa..000000000 --- a/suite/crt/src/main/java/dk/alexandra/fresco/suite/crt/suites/SpdzProtocolSupplier.java +++ /dev/null @@ -1,102 +0,0 @@ -package dk.alexandra.fresco.suite.crt.suites; - -import dk.alexandra.fresco.framework.DRes; -import dk.alexandra.fresco.framework.NativeProtocol; -import dk.alexandra.fresco.framework.builder.numeric.field.FieldDefinition; -import dk.alexandra.fresco.framework.value.SInt; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticAddProtocol; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticCloseProtocol; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticKnownProtocol; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticMultProtocol; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticOpenProtocol; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticOpenToAllProtocol; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticRandomBitProtocol; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticRandomElementProtocol; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticResourcePool; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticSInt; -import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticSubtractProtocol; -import dk.alexandra.fresco.suite.spdz.SpdzRandomBitProtocol; -import dk.alexandra.fresco.suite.spdz.SpdzResourcePool; -import dk.alexandra.fresco.suite.spdz.gates.SpdzAddProtocol; -import dk.alexandra.fresco.suite.spdz.gates.SpdzAddProtocolKnownLeft; -import dk.alexandra.fresco.suite.spdz.gates.SpdzInputProtocol; -import dk.alexandra.fresco.suite.spdz.gates.SpdzKnownSIntProtocol; -import dk.alexandra.fresco.suite.spdz.gates.SpdzMultProtocol; -import dk.alexandra.fresco.suite.spdz.gates.SpdzMultProtocolKnownLeft; -import dk.alexandra.fresco.suite.spdz.gates.SpdzOutputSingleProtocol; -import dk.alexandra.fresco.suite.spdz.gates.SpdzOutputToAllProtocol; -import dk.alexandra.fresco.suite.spdz.gates.SpdzRandomProtocol; -import dk.alexandra.fresco.suite.spdz.gates.SpdzSubtractProtocol; -import dk.alexandra.fresco.suite.spdz.gates.SpdzSubtractProtocolKnownLeft; -import dk.alexandra.fresco.suite.spdz.gates.SpdzSubtractProtocolKnownRight; -import java.math.BigInteger; -import java.util.Random; - -public class SpdzProtocolSupplier implements - ProtocolSuiteProtocolSupplier { - - @Override - public NativeProtocol known(BigInteger value) { - return new SpdzKnownSIntProtocol(value); - } - - @Override - public NativeProtocol input(BigInteger value, int playerId) { - return new SpdzInputProtocol(value, playerId); - } - - @Override - public NativeProtocol open(DRes value, int playerId) { - return new SpdzOutputSingleProtocol(value, playerId); - } - - @Override - public NativeProtocol open(DRes value) { - return new SpdzOutputToAllProtocol(value); - } - - @Override - public NativeProtocol add(DRes a, DRes b) { - return new SpdzAddProtocol(a, b); - } - - @Override - public NativeProtocol add(BigInteger a, DRes b) { - return new SpdzAddProtocolKnownLeft(a, b); - } - - @Override - public NativeProtocol sub(DRes a, DRes b) { - return new SpdzSubtractProtocol(a, b); - } - - @Override - public NativeProtocol sub(DRes a, BigInteger b) { - return new SpdzSubtractProtocolKnownRight(a, b); - } - - @Override - public NativeProtocol sub(BigInteger a, DRes b) { - return new SpdzSubtractProtocolKnownLeft(a, b); - } - - @Override - public NativeProtocol mult(DRes a, DRes b) { - return new SpdzMultProtocol(a, b); - } - - @Override - public NativeProtocol mult(BigInteger a, DRes b) { - return new SpdzMultProtocolKnownLeft(a, b); - } - - @Override - public NativeProtocol randomElement() { - return new SpdzRandomProtocol(); - } - - @Override - public NativeProtocol randomBit() { - return new SpdzRandomBitProtocol(); - } -} diff --git a/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/AbstractCovertDummyCRTTest.java b/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/AbstractCovertDummyCRTTest.java new file mode 100644 index 000000000..6871043d0 --- /dev/null +++ b/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/AbstractCovertDummyCRTTest.java @@ -0,0 +1,106 @@ +package dk.alexandra.fresco.suite.crt; + +import dk.alexandra.fresco.framework.ProtocolEvaluator; +import dk.alexandra.fresco.framework.TestThreadRunner; +import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric; +import dk.alexandra.fresco.framework.builder.numeric.field.BigIntegerFieldDefinition; +import dk.alexandra.fresco.framework.builder.numeric.field.FieldDefinition; +import dk.alexandra.fresco.framework.builder.numeric.field.MersennePrimeFieldDefinition; +import dk.alexandra.fresco.framework.configuration.NetworkConfiguration; +import dk.alexandra.fresco.framework.configuration.NetworkUtil; +import dk.alexandra.fresco.framework.network.Network; +import dk.alexandra.fresco.framework.network.socket.SocketNetwork; +import dk.alexandra.fresco.framework.sce.SecureComputationEngine; +import dk.alexandra.fresco.framework.sce.SecureComputationEngineImpl; +import dk.alexandra.fresco.framework.sce.evaluator.BatchEvaluationStrategy; +import dk.alexandra.fresco.framework.sce.evaluator.BatchedProtocolEvaluator; +import dk.alexandra.fresco.framework.sce.evaluator.EvaluationStrategy; +import dk.alexandra.fresco.lib.field.integer.BasicNumericContext; +import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTCovertDataSupplier; +import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTDataSupplier; +import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTResourcePool; +import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTResourcePoolImpl; +import dk.alexandra.fresco.suite.crt.protocols.framework.CRTBatchedStrategy; +import dk.alexandra.fresco.suite.crt.protocols.framework.CRTSequentialStrategy; +import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticBuilderFactory; +import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticResourcePool; +import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticResourcePoolImpl; + +import java.math.BigInteger; +import java.util.*; +import java.util.function.Supplier; + +/** + * Abstract class which handles a lot of boiler plate testing code. This makes running a single test + * using different parameters quite easy. + */ +public class AbstractCovertDummyCRTTest { + + // Note that the modulus on the right should have twice the bit length of that to the left in order for RandomModP to + // work correctly. + protected static final FieldDefinition DEFAULT_FIELD_LEFT = + MersennePrimeFieldDefinition.find(64); + protected static final FieldDefinition DEFAULT_FIELD_RIGHT = new BigIntegerFieldDefinition( + new BigInteger(152 + 40, new Random(1234)).nextProbablePrime()); + + public void runTest( + TestThreadRunner.TestThreadFactory, ProtocolBuilderNumeric> f, + EvaluationStrategy evalStrategy, int noOfParties) { + + List ports = new ArrayList<>(noOfParties); + for (int i = 1; i <= noOfParties; i++) { + ports.add(9000 + i * (noOfParties - 1)); + } + + Map netConf = + NetworkUtil.getNetworkConfigurations(ports); + Map, + ProtocolBuilderNumeric> + > conf = new HashMap<>(); + + for (int playerId : netConf.keySet()) { + + BatchEvaluationStrategy> batchEvaluationStrategy = + new CRTBatchedStrategy<>(); + DummyArithmeticResourcePool rpLeft = new DummyArithmeticResourcePoolImpl(playerId, + noOfParties, DEFAULT_FIELD_LEFT); + DummyArithmeticResourcePool rpRight = new DummyArithmeticResourcePoolImpl(playerId, + noOfParties, DEFAULT_FIELD_RIGHT); + CRTResourcePool rp = + new CRTResourcePoolImpl<>(playerId, noOfParties, null, rpLeft, rpRight); + + CRTProtocolSuite ps = + new CRTProtocolSuite<>( + new DummyArithmeticBuilderFactory(new BasicNumericContext(DEFAULT_FIELD_LEFT.getBitLength() - 24, + playerId, noOfParties, DEFAULT_FIELD_LEFT, 16, 40)), + new DummyArithmeticBuilderFactory(new BasicNumericContext(DEFAULT_FIELD_RIGHT.getBitLength()- 40, + playerId, noOfParties, DEFAULT_FIELD_RIGHT, 16, 40))); + ProtocolEvaluator> evaluator = + new BatchedProtocolEvaluator<>(batchEvaluationStrategy, ps); + + NetworkConfiguration partyNetConf = netConf.get(playerId); + SecureComputationEngine, ProtocolBuilderNumeric> sce = + new SecureComputationEngineImpl<>(ps, evaluator); + + Supplier networkSupplier = () -> new SocketNetwork(partyNetConf); + CRTDataSupplier dataSupplier = new CRTCovertDataSupplier( + ); + + TestThreadRunner.TestThreadConfiguration< + CRTResourcePool, + ProtocolBuilderNumeric> ttc = + new TestThreadRunner.TestThreadConfiguration<>(sce, + () -> new CRTResourcePoolImpl<>(playerId, noOfParties, dataSupplier, rpLeft, rpRight), + networkSupplier); + conf.put(playerId, ttc); + } + + TestThreadRunner.run(f, conf); + } + +} diff --git a/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/AbstractDummyCRTTest.java b/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/AbstractDummyCRTTest.java index 64a06bf20..00492ee9f 100644 --- a/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/AbstractDummyCRTTest.java +++ b/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/AbstractDummyCRTTest.java @@ -14,25 +14,20 @@ import dk.alexandra.fresco.framework.sce.evaluator.BatchEvaluationStrategy; import dk.alexandra.fresco.framework.sce.evaluator.BatchedProtocolEvaluator; import dk.alexandra.fresco.framework.sce.evaluator.EvaluationStrategy; -import dk.alexandra.fresco.logging.DefaultPerformancePrinter; -import dk.alexandra.fresco.logging.PerformanceLogger; -import dk.alexandra.fresco.logging.PerformanceLoggerCountingAggregate; -import dk.alexandra.fresco.logging.PerformancePrinter; +import dk.alexandra.fresco.lib.field.integer.BasicNumericContext; import dk.alexandra.fresco.suite.ProtocolSuiteNumeric; import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTDataSupplier; import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTDummyDataSupplier; import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTResourcePool; import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTResourcePoolImpl; -import dk.alexandra.fresco.suite.crt.suites.DummyProtocolSupplier; +import dk.alexandra.fresco.suite.crt.protocols.framework.CRTSequentialStrategy; +import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticBuilderFactory; import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticResourcePool; import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticResourcePoolImpl; import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticSInt; + import java.math.BigInteger; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; +import java.util.*; /** * Abstract class which handles a lot of boiler plate testing code. This makes running a single test @@ -40,10 +35,13 @@ */ public class AbstractDummyCRTTest { + // Note that the modulus on the right should have twice the bit length of that to the left in order for RandomModP to + // work correctly. protected static final FieldDefinition DEFAULT_FIELD_LEFT = MersennePrimeFieldDefinition.find(64); protected static final FieldDefinition DEFAULT_FIELD_RIGHT = new BigIntegerFieldDefinition( - new BigInteger(128 + 40, new Random(1234)).nextProbablePrime()); + new BigInteger(152 + 40, new Random(1234)).nextProbablePrime()); + protected static final int STATISTICAL_SEC = 40; public void runTest( TestThreadRunner.TestThreadFactory, ProtocolBuilderNumeric> f, @@ -65,7 +63,7 @@ public void runTest( for (int playerId : netConf.keySet()) { BatchEvaluationStrategy> batchEvaluationStrategy = - evalStrategy.getStrategy(); + new CRTSequentialStrategy<>(); DummyArithmeticResourcePool rpLeft = new DummyArithmeticResourcePoolImpl(playerId, noOfParties, DEFAULT_FIELD_LEFT); DummyArithmeticResourcePool rpRight = new DummyArithmeticResourcePoolImpl(playerId, @@ -73,8 +71,10 @@ public void runTest( ProtocolSuiteNumeric> ps = new CRTProtocolSuite<>( - new DummyProtocolSupplier(new Random(0), DEFAULT_FIELD_LEFT), - new DummyProtocolSupplier(new Random(1), DEFAULT_FIELD_RIGHT)); + new DummyArithmeticBuilderFactory(new BasicNumericContext(DEFAULT_FIELD_LEFT.getBitLength() - 24, + playerId, noOfParties, DEFAULT_FIELD_LEFT, 16, STATISTICAL_SEC)), + new DummyArithmeticBuilderFactory(new BasicNumericContext(DEFAULT_FIELD_RIGHT.getBitLength()- 40, + playerId, noOfParties, DEFAULT_FIELD_RIGHT, 16, STATISTICAL_SEC))); ProtocolEvaluator> evaluator = new BatchedProtocolEvaluator<>(batchEvaluationStrategy, ps); @@ -82,8 +82,8 @@ public void runTest( SecureComputationEngine, ProtocolBuilderNumeric> sce = new SecureComputationEngineImpl<>(ps, evaluator); - CRTDataSupplier dataSupplier = new CRTDummyDataSupplier(playerId, noOfParties, - DEFAULT_FIELD_LEFT, DEFAULT_FIELD_RIGHT, + CRTDataSupplier dataSupplier = new CRTDummyDataSupplier<>(playerId, noOfParties, STATISTICAL_SEC + , DEFAULT_FIELD_LEFT, DEFAULT_FIELD_RIGHT, x -> new DummyArithmeticSInt(DEFAULT_FIELD_LEFT.createElement(x)), y -> new DummyArithmeticSInt(DEFAULT_FIELD_RIGHT.createElement(y))); diff --git a/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/AbstractSemiHonestDummyCRTTest.java b/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/AbstractSemiHonestDummyCRTTest.java new file mode 100644 index 000000000..f8f0276f6 --- /dev/null +++ b/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/AbstractSemiHonestDummyCRTTest.java @@ -0,0 +1,103 @@ +package dk.alexandra.fresco.suite.crt; + +import dk.alexandra.fresco.framework.ProtocolEvaluator; +import dk.alexandra.fresco.framework.TestThreadRunner; +import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric; +import dk.alexandra.fresco.framework.builder.numeric.field.BigIntegerFieldDefinition; +import dk.alexandra.fresco.framework.builder.numeric.field.FieldDefinition; +import dk.alexandra.fresco.framework.builder.numeric.field.MersennePrimeFieldDefinition; +import dk.alexandra.fresco.framework.configuration.NetworkConfiguration; +import dk.alexandra.fresco.framework.configuration.NetworkUtil; +import dk.alexandra.fresco.framework.network.Network; +import dk.alexandra.fresco.framework.network.socket.SocketNetwork; +import dk.alexandra.fresco.framework.sce.SecureComputationEngine; +import dk.alexandra.fresco.framework.sce.SecureComputationEngineImpl; +import dk.alexandra.fresco.framework.sce.evaluator.BatchEvaluationStrategy; +import dk.alexandra.fresco.framework.sce.evaluator.BatchedProtocolEvaluator; +import dk.alexandra.fresco.framework.sce.evaluator.EvaluationStrategy; +import dk.alexandra.fresco.lib.field.integer.BasicNumericContext; +import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTDataSupplier; +import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTResourcePool; +import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTResourcePoolImpl; +import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTSemiHonestDataSupplier; +import dk.alexandra.fresco.suite.crt.protocols.framework.CRTSequentialStrategy; +import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticBuilderFactory; +import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticResourcePool; +import dk.alexandra.fresco.suite.dummy.arithmetic.DummyArithmeticResourcePoolImpl; + +import java.math.BigInteger; +import java.util.*; +import java.util.function.Supplier; + +/** + * Abstract class which handles a lot of boiler plate testing code. This makes running a single test + * using different parameters quite easy. + */ +public class AbstractSemiHonestDummyCRTTest { + + // Note that the modulus on the right should have twice the bit length of that to the left in order for RandomModP to + // work correctly. + protected static final FieldDefinition DEFAULT_FIELD_LEFT = + MersennePrimeFieldDefinition.find(64); + protected static final FieldDefinition DEFAULT_FIELD_RIGHT = new BigIntegerFieldDefinition( + new BigInteger(152 + 40, new Random(1234)).nextProbablePrime()); + + public void runTest( + TestThreadRunner.TestThreadFactory, ProtocolBuilderNumeric> f, + EvaluationStrategy evalStrategy, int noOfParties) { + + List ports = new ArrayList<>(noOfParties); + for (int i = 1; i <= noOfParties; i++) { + ports.add(9000 + i * (noOfParties - 1)); + } + + Map netConf = + NetworkUtil.getNetworkConfigurations(ports); + Map, + ProtocolBuilderNumeric> + > conf = new HashMap<>(); + + for (int playerId : netConf.keySet()) { + + BatchEvaluationStrategy> batchEvaluationStrategy = + new CRTSequentialStrategy<>(); + DummyArithmeticResourcePool rpLeft = new DummyArithmeticResourcePoolImpl(playerId, + noOfParties, DEFAULT_FIELD_LEFT); + DummyArithmeticResourcePool rpRight = new DummyArithmeticResourcePoolImpl(playerId, + noOfParties, DEFAULT_FIELD_RIGHT); + CRTResourcePool rp = + new CRTResourcePoolImpl<>(playerId, noOfParties, null, rpLeft, rpRight); + + CRTProtocolSuite ps = + new CRTProtocolSuite<>( + new DummyArithmeticBuilderFactory(new BasicNumericContext(DEFAULT_FIELD_LEFT.getBitLength() - 24, + playerId, noOfParties, DEFAULT_FIELD_LEFT, 16, 40)), + new DummyArithmeticBuilderFactory(new BasicNumericContext(DEFAULT_FIELD_RIGHT.getBitLength()- 40, + playerId, noOfParties, DEFAULT_FIELD_RIGHT, 16, 40))); + ProtocolEvaluator> evaluator = + new BatchedProtocolEvaluator<>(batchEvaluationStrategy, ps); + + NetworkConfiguration partyNetConf = netConf.get(playerId); + SecureComputationEngine, ProtocolBuilderNumeric> sce = + new SecureComputationEngineImpl<>(ps, evaluator); + + Supplier networkSupplier = () -> new SocketNetwork(partyNetConf); + CRTDataSupplier dataSupplier = new CRTSemiHonestDataSupplier<>(); + + TestThreadRunner.TestThreadConfiguration< + CRTResourcePool, + ProtocolBuilderNumeric> ttc = + new TestThreadRunner.TestThreadConfiguration<>(sce, + () -> new CRTResourcePoolImpl<>(playerId, noOfParties, dataSupplier, rpLeft, rpRight), + networkSupplier); + conf.put(playerId, ttc); + } + + TestThreadRunner.run(f, conf); + } + +} diff --git a/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/AbstractSpdzCRTTest.java b/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/AbstractSpdzCRTTest.java index d0e4405e0..f3c4a8fc1 100644 --- a/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/AbstractSpdzCRTTest.java +++ b/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/AbstractSpdzCRTTest.java @@ -1,8 +1,5 @@ package dk.alexandra.fresco.suite.crt; -import static dk.alexandra.fresco.suite.spdz.configuration.PreprocessingStrategy.DUMMY; -import static dk.alexandra.fresco.suite.spdz.configuration.PreprocessingStrategy.MASCOT; - import dk.alexandra.fresco.framework.DRes; import dk.alexandra.fresco.framework.ProtocolEvaluator; import dk.alexandra.fresco.framework.TestThreadRunner; @@ -25,23 +22,15 @@ import dk.alexandra.fresco.framework.sce.evaluator.EvaluationStrategy; import dk.alexandra.fresco.framework.sce.resources.storage.FilebasedStreamedStorageImpl; import dk.alexandra.fresco.framework.sce.resources.storage.InMemoryStorage; -import dk.alexandra.fresco.framework.util.AesCtrDrbg; -import dk.alexandra.fresco.framework.util.AesCtrDrbgFactory; -import dk.alexandra.fresco.framework.util.Drbg; -import dk.alexandra.fresco.framework.util.OpenedValueStoreImpl; -import dk.alexandra.fresco.framework.util.Pair; +import dk.alexandra.fresco.framework.util.*; import dk.alexandra.fresco.framework.value.SInt; import dk.alexandra.fresco.lib.field.integer.BasicNumericContext; import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTDataSupplier; import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTDummyDataSupplier; import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTResourcePool; import dk.alexandra.fresco.suite.crt.datatypes.resource.CRTResourcePoolImpl; -import dk.alexandra.fresco.suite.crt.suites.SpdzProtocolSupplier; -import dk.alexandra.fresco.suite.spdz.NetManager; -import dk.alexandra.fresco.suite.spdz.SpdzBuilder; -import dk.alexandra.fresco.suite.spdz.SpdzProtocolSuite; -import dk.alexandra.fresco.suite.spdz.SpdzResourcePool; -import dk.alexandra.fresco.suite.spdz.SpdzResourcePoolImpl; +import dk.alexandra.fresco.suite.crt.protocols.framework.CRTSequentialStrategy; +import dk.alexandra.fresco.suite.spdz.*; import dk.alexandra.fresco.suite.spdz.configuration.PreprocessingStrategy; import dk.alexandra.fresco.suite.spdz.datatypes.SpdzSInt; import dk.alexandra.fresco.suite.spdz.storage.SpdzDataSupplier; @@ -51,16 +40,16 @@ import dk.alexandra.fresco.tools.ot.base.DummyOt; import dk.alexandra.fresco.tools.ot.base.Ot; import dk.alexandra.fresco.tools.ot.otextension.RotList; + import java.math.BigInteger; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; +import static dk.alexandra.fresco.suite.spdz.configuration.PreprocessingStrategy.DUMMY; +import static dk.alexandra.fresco.suite.spdz.configuration.PreprocessingStrategy.MASCOT; + /** * Abstract class which handles a lot of boiler plate testing code. This makes running a single test * using different parameters quite easy. @@ -69,8 +58,10 @@ public class AbstractSpdzCRTTest { protected static final FieldDefinition DEFAULT_FIELD_LEFT = MersennePrimeFieldDefinition.find(64); + protected static final int STATISTICAL_SEC = 40; + // q = p^3 + 139p + 1 where q = DEFAULT_FIELD_RIGHT and p = DEFAULT_FIELD_LEFT. protected static final FieldDefinition DEFAULT_FIELD_RIGHT = new BigIntegerFieldDefinition( - new BigInteger(128 + 40, new Random(1234)).nextProbablePrime()); + new BigInteger("6277101735386680703605810478201558570393289253487848005721")); //152 + 40, new Random(1234)).nextProbablePrime()); private static final int PRG_SEED_LENGTH = 256; private static Drbg getDrbg(int myId) { @@ -117,20 +108,23 @@ public void runTest( for (int playerId : netConf.keySet()) { - BatchEvaluationStrategy> strategy = evalStrategy - .getStrategy(); + BatchEvaluationStrategy> strategy = new CRTSequentialStrategy<>(); - CRTProtocolSuite ps = new CRTProtocolSuite<>( - new SpdzProtocolSupplier(), new SpdzProtocolSupplier()); + CRTProtocolSuite ps = + new CRTProtocolSuite<>( + new SpdzBuilder(new BasicNumericContext(DEFAULT_FIELD_LEFT.getBitLength() - 24, + playerId, noOfParties, DEFAULT_FIELD_LEFT, 16, STATISTICAL_SEC)), + new SpdzBuilder(new BasicNumericContext(DEFAULT_FIELD_RIGHT.getBitLength() - 40, + playerId, noOfParties, DEFAULT_FIELD_RIGHT, 16, STATISTICAL_SEC))); ProtocolEvaluator> evaluator = - new BatchedProtocolEvaluator<>(strategy, ps); + new BatchedProtocolEvaluator>(strategy, ps); SecureComputationEngine, ProtocolBuilderNumeric> sce = new SecureComputationEngineImpl<>(ps, evaluator); - CRTDataSupplier dataSupplier = new CRTDummyDataSupplier(playerId, noOfParties, - DEFAULT_FIELD_LEFT, DEFAULT_FIELD_RIGHT, + CRTDataSupplier dataSupplier = new CRTDummyDataSupplier<>(playerId, noOfParties, STATISTICAL_SEC + , DEFAULT_FIELD_LEFT, DEFAULT_FIELD_RIGHT, x -> toSpdzSInt(x, playerId, noOfParties, DEFAULT_FIELD_LEFT, new Random(1234), new BigInteger(DEFAULT_FIELD_LEFT.getModulus().bitLength(), new Random(0)) .mod(DEFAULT_FIELD_LEFT.getModulus())), diff --git a/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/BasicCRTTests.java b/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/BasicCRTTests.java index 406041067..ee56fbc97 100644 --- a/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/BasicCRTTests.java +++ b/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/BasicCRTTests.java @@ -12,334 +12,327 @@ import dk.alexandra.fresco.lib.fixed.FixedNumeric; import dk.alexandra.fresco.lib.fixed.SFixed; import dk.alexandra.fresco.suite.crt.fixed.CRTFixedNumeric; -import dk.alexandra.fresco.suite.crt.protocols.CorrelatedNoiseProtocol; -import dk.alexandra.fresco.suite.crt.protocols.LiftPQProtocol; -import dk.alexandra.fresco.suite.crt.protocols.LiftQPProtocol; -import dk.alexandra.fresco.suite.crt.protocols.Projection; +import dk.alexandra.fresco.suite.crt.protocols.*; import dk.alexandra.fresco.suite.crt.protocols.Projection.Coordinate; -import dk.alexandra.fresco.suite.crt.protocols.RandomModP; -import dk.alexandra.fresco.suite.crt.protocols.Truncp; +import org.junit.Assert; + import java.math.BigDecimal; import java.math.BigInteger; import java.util.List; import java.util.Random; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.junit.Assert; public class BasicCRTTests { - public static class TestInput - extends TestThreadFactory { + public static class TestInput + extends TestThreadFactory { - @Override - public TestThread next() { - BigInteger value = BigInteger.valueOf(10); - return new TestThread() { @Override - public void test() { - Application app = producer -> { - Numeric numeric = producer.numeric(); - DRes input = numeric.input(value, 1); - return numeric.open(input); - }; - BigInteger output = runApplication(app); - - Assert.assertEquals(value, output); + public TestThread next() { + BigInteger value = BigInteger.valueOf(10); + return new TestThread() { + @Override + public void test() { + Application app = producer -> { + Numeric numeric = producer.numeric(); + DRes input = numeric.input(value, 1); + return numeric.open(input); + }; + BigInteger output = runApplication(app); + + Assert.assertEquals(value, output); + } + }; } - }; } - } - - public static class TestCorrelatedNoise - extends TestThreadFactory { - @Override - public TestThread next() { - return new TestThread() { + public static class TestCorrelatedNoise + extends TestThreadFactory { @Override - public void test() { - Application app = producer -> producer - .seq(seq -> seq.append( - new CorrelatedNoiseProtocol<>())).seq((seq, r) -> seq.numeric().open(r)); - BigInteger output = runApplication(app); + public TestThread next() { + return new TestThread() { - CRTRingDefinition ring = (CRTRingDefinition) this.getFieldDefinition(); - Pair crt = ring.integerToRNS(output); + @Override + public void test() { + Application app = producer -> producer + .seq(new CorrelatedNoiseProtocol<>()).seq((seq, r) -> seq.numeric().open(r.getNoisePair())); + BigInteger output = runApplication(app); - Assert.assertEquals(crt.getFirst(), crt.getSecond().mod(ring.getLeftModulus())); + CRTRingDefinition ring = (CRTRingDefinition) this.getFieldDefinition(); + Pair crt = ring.integerToRNS(output); + + System.out.println(crt.getFirst() + ", " + crt.getSecond()); + + Assert.assertEquals(crt.getFirst(), crt.getSecond().mod(ring.getLeftModulus())); + } + }; } - }; } - } - - public static class TestProjectionLeft - extends TestThreadFactory { - @Override - public TestThread next() { - return new TestThread() { + public static class TestProjectionLeft + extends TestThreadFactory { @Override - public void test() { - BigInteger x = BigInteger.valueOf(7); - BigInteger y = BigInteger.valueOf(11); - Application app = producer -> producer.seq(seq -> { - CRTRingDefinition ring = (CRTRingDefinition) this.getFieldDefinition(); - BigInteger toConvert = ring.RNStoBigInteger(x, y); - return new Projection<>(seq.numeric().known(toConvert), Coordinate.LEFT) - .buildComputation(seq); - }).seq((seq, r) -> seq.numeric().open(r)); - BigInteger output = runApplication(app); - - CRTRingDefinition ring = (CRTRingDefinition) this.getFieldDefinition(); - Pair crt = Util.mapToCRT(output, ring.getLeftModulus(), ring.getRightModulus()); - - Assert.assertEquals(x, crt.getFirst()); - Assert.assertEquals(BigInteger.ZERO, crt.getSecond()); + public TestThread next() { + return new TestThread() { + + @Override + public void test() { + BigInteger x = BigInteger.valueOf(7); + BigInteger y = BigInteger.valueOf(11); + Application app = producer -> producer.seq(seq -> { + CRTRingDefinition ring = (CRTRingDefinition) this.getFieldDefinition(); + BigInteger toConvert = ring.RNStoBigInteger(x, y); + return new Projection<>(seq.numeric().known(toConvert), Coordinate.LEFT) + .buildComputation(seq); + }).seq((seq, r) -> seq.numeric().open(r)); + BigInteger output = runApplication(app); + + CRTRingDefinition ring = (CRTRingDefinition) this.getFieldDefinition(); + Pair crt = Util.mapToCRT(output, ring.getLeftModulus(), ring.getRightModulus()); + + Assert.assertEquals(x, crt.getFirst()); + Assert.assertEquals(BigInteger.ZERO, crt.getSecond()); + } + }; } - }; } - } - public static class TestProjectionRight - extends TestThreadFactory { - - @Override - public TestThread next() { - return new TestThread() { + public static class TestProjectionRight + extends TestThreadFactory { @Override - public void test() { - BigInteger x = BigInteger.valueOf(7); - BigInteger y = BigInteger.valueOf(11); - Application app = producer -> producer.seq(seq -> { - CRTRingDefinition ring = (CRTRingDefinition) this.getFieldDefinition(); - BigInteger toConvert = ring.RNStoBigInteger(x, y); - return new Projection<>(seq.numeric().known(toConvert), Coordinate.RIGHT) - .buildComputation(seq); - }).seq((seq, r) -> seq.numeric().open(r)); - BigInteger output = runApplication(app); - - CRTRingDefinition ring = (CRTRingDefinition) this.getFieldDefinition(); - Pair crt = Util.mapToCRT(output, ring.getLeftModulus(), ring.getRightModulus()); - - Assert.assertEquals(BigInteger.ZERO, crt.getFirst()); - Assert.assertEquals(y, crt.getSecond()); + public TestThread next() { + return new TestThread() { + + @Override + public void test() { + BigInteger x = BigInteger.valueOf(7); + BigInteger y = BigInteger.valueOf(11); + Application app = producer -> producer.seq(seq -> { + CRTRingDefinition ring = (CRTRingDefinition) this.getFieldDefinition(); + BigInteger toConvert = ring.RNStoBigInteger(x, y); + return new Projection<>(seq.numeric().known(toConvert), Coordinate.RIGHT) + .buildComputation(seq); + }).seq((seq, r) -> seq.numeric().open(r)); + BigInteger output = runApplication(app); + + CRTRingDefinition ring = (CRTRingDefinition) this.getFieldDefinition(); + Pair crt = Util.mapToCRT(output, ring.getLeftModulus(), ring.getRightModulus()); + + Assert.assertEquals(BigInteger.ZERO, crt.getFirst()); + Assert.assertEquals(y, crt.getSecond()); + } + }; } - }; } - } - - public static class TestLiftPQ - extends TestThreadFactory { - @Override - public TestThread next() { - return new TestThread() { + public static class TestLiftPQ + extends TestThreadFactory { @Override - public void test() { - CRTRingDefinition ring = (CRTRingDefinition) this.getFieldDefinition(); - BigInteger value = ring.getLeftModulus().subtract(BigInteger.TEN); - Application app = producer -> producer.seq(seq -> { - BigInteger toConvert = ring.RNStoBigInteger(value, BigInteger.ZERO); - - return new LiftPQProtocol<>(seq.numeric().known(toConvert)).buildComputation(seq); - }).seq((seq, r) -> seq.numeric().open(r)); - BigInteger output = runApplication(app); - - Pair crt = ring.integerToRNS(output); - - Assert.assertEquals(value, crt.getSecond()); + public TestThread next() { + return new TestThread() { + + @Override + public void test() { + CRTRingDefinition ring = (CRTRingDefinition) this.getFieldDefinition(); + BigInteger value = new BigInteger("12345"); + Application app = producer -> producer.seq(seq -> { + BigInteger toConvert = ring.RNStoBigInteger(value, BigInteger.ZERO); + return new LiftPQProtocol<>(seq.numeric().known(toConvert)).buildComputation(seq); + }).seq((seq, r) -> seq.numeric().open(r)); + BigInteger output = runApplication(app); + Assert.assertEquals(value, output.mod(ring.getLeftModulus())); + } + }; } - }; } - } - - public static class TestLiftQP - extends TestThreadFactory { - @Override - public TestThread next() { - return new TestThread() { + public static class TestLiftQP + extends TestThreadFactory { @Override - public void test() { - BigInteger value = BigInteger.valueOf(1234); - Application app = producer -> producer.seq(seq -> { - CRTRingDefinition ring = (CRTRingDefinition) this.getFieldDefinition(); - BigInteger toConvert = ring.RNStoBigInteger(BigInteger.ZERO, value); - return new LiftQPProtocol<>(seq.numeric().known(toConvert)).buildComputation(seq); - - }).seq((seq, r) -> seq.numeric().open(r)); - BigInteger output = runApplication(app); - - CRTRingDefinition ring = (CRTRingDefinition) this.getFieldDefinition(); - Pair crt = Util.mapToCRT(output, ring.getLeftModulus(), ring.getRightModulus()); - - Assert.assertEquals(value, crt.getFirst()); + public TestThread next() { + return new TestThread() { + + @Override + public void test() { + BigInteger value = BigInteger.valueOf(1234); + Application app = producer -> producer.seq(seq -> { + CRTRingDefinition ring = (CRTRingDefinition) this.getFieldDefinition(); + BigInteger toConvert = ring.RNStoBigInteger(BigInteger.ZERO, value); + return new LiftQPProtocol<>(seq.numeric().known(toConvert)).buildComputation(seq); + + }).seq((seq, r) -> seq.numeric().open(r)); + BigInteger output = runApplication(app); + + CRTRingDefinition ring = (CRTRingDefinition) this.getFieldDefinition(); + Pair crt = Util.mapToCRT(output, ring.getLeftModulus(), ring.getRightModulus()); + + Assert.assertEquals(value, crt.getFirst()); + } + }; } - }; } - } - public static class TestTruncp - extends TestThreadFactory { - - @Override - public TestThread next() { - return new TestThread() { + public static class TestTruncp + extends TestThreadFactory { @Override - public void test() { - BigInteger value = new BigInteger(84, new Random(1234)); - Application app = producer -> producer.seq(seq -> { - DRes x = seq.numeric().known(value); - DRes y = new Truncp<>(x).buildComputation(seq); - return seq.numeric().open(y); - }); - BigInteger output = runApplication(app); - CRTRingDefinition ring = (CRTRingDefinition) this.getFieldDefinition(); - Assert.assertEquals(value.divide(ring.getLeftModulus()), output); + public TestThread next() { + return new TestThread() { + + @Override + public void test() { + BigInteger value = new BigInteger(84, new Random(1234)); + Application app = producer -> producer.seq(seq -> { + DRes x = seq.numeric().known(value); + DRes y = new Truncp<>(x).buildComputation(seq); + return seq.numeric().open(y); + }); + BigInteger output = runApplication(app); + CRTRingDefinition ring = (CRTRingDefinition) this.getFieldDefinition(); + Assert.assertTrue(output.subtract(value.divide(ring.getLeftModulus())).compareTo(BigInteger.valueOf(this.conf.getResourcePool().getNoOfParties())) <= 0); + } + }; } - }; } - } - - public static class TestFixedPointInput - extends TestThreadFactory { - @Override - public TestThread next() { - return new TestThread() { + public static class TestFixedPointInput + extends TestThreadFactory { @Override - public void test() { + public TestThread next() { + return new TestThread() { - double input = Math.PI; + @Override + public void test() { - Application app = producer -> producer.seq(seq -> { - FixedNumeric numeric = new CRTFixedNumeric(seq); - DRes x = numeric.input(input, 1); - return numeric.open(x); - }); - BigDecimal output = runApplication(app); - Assert.assertEquals(input, output.doubleValue(), 0.001); + double input = Math.PI; + Application app = producer -> producer.seq(seq -> { + FixedNumeric numeric = new CRTFixedNumeric(seq); + DRes x = numeric.input(input, 1); + return numeric.open(x); + }); + BigDecimal output = runApplication(app); + Assert.assertEquals(input, output.doubleValue(), 0.001); + + } + }; } - }; } - } - - public static class TestFixedPointMultiplication - extends TestThreadFactory { - @Override - public TestThread next() { - return new TestThread() { + public static class TestFixedPointMultiplication + extends TestThreadFactory { @Override - public void test() { - - double a = Math.PI; - double b = 7.001; - - Application app = producer -> producer.seq(seq -> { - FixedNumeric numeric = new CRTFixedNumeric(seq); - DRes x = numeric.input(a, 1); - DRes y = numeric.input(b, 2); - return numeric.open(numeric.mult(x, y)); - }); - BigDecimal output = runApplication(app); - Assert.assertEquals(a*b, output.doubleValue(), 0.001); - + public TestThread next() { + return new TestThread() { + + @Override + public void test() { + + double a = Math.PI; + double b = 7.001; + + Application app = producer -> producer.seq(seq -> { + FixedNumeric numeric = new CRTFixedNumeric(seq); + DRes x = numeric.input(a, 1); + DRes y = numeric.input(b, 2); + return numeric.open(numeric.mult(x, y)); + }); + BigDecimal output = runApplication(app); + Assert.assertEquals(a * b, output.doubleValue(), 0.001); + + } + }; } - }; } - } - - public static class TestFixedPointDivision - extends TestThreadFactory { - @Override - public TestThread next() { - return new TestThread() { + public static class TestFixedPointDivision + extends TestThreadFactory { @Override - public void test() { + public TestThread next() { + return new TestThread() { - double a = 7.001; - double b = Math.PI; + @Override + public void test() { - Application app = producer -> producer.seq(seq -> { - FixedNumeric numeric = new CRTFixedNumeric(seq); - DRes y = numeric.input(a, 2); - return numeric.open(numeric.div(y, b)); - }); - BigDecimal output = runApplication(app); - Assert.assertEquals(a/b, output.doubleValue(), 0.001); + double a = 7.001; + double b = Math.PI; + Application app = producer -> producer.seq(seq -> { + FixedNumeric numeric = new CRTFixedNumeric(seq); + DRes y = numeric.input(a, 2); + return numeric.open(numeric.div(y, b)); + }); + BigDecimal output = runApplication(app); + Assert.assertEquals(a / b, output.doubleValue(), 0.001); + + } + }; } - }; } - } - - public static class TestFixedPointSecretDivision - extends TestThreadFactory { - @Override - public TestThread next() { - return new TestThread() { + public static class TestFixedPointSecretDivision + extends TestThreadFactory { @Override - public void test() { - - double a = 17.90 + Math.PI; - double b = 0.2; - - Application app = producer -> producer.seq(seq -> { - FixedNumeric numeric = new CRTFixedNumeric(seq); - DRes x = numeric.input(a, 1); - DRes y = numeric.input(b, 2); - return numeric.open(numeric.div(x, y)); - }); - BigDecimal output = runApplication(app); - Assert.assertEquals(a/b, output.doubleValue(), 0.01); + public TestThread next() { + return new TestThread() { + + @Override + public void test() { + + double a = 17.90 + Math.PI; + double b = 0.2; + + Application app = producer -> producer.seq(seq -> { + FixedNumeric numeric = new CRTFixedNumeric(seq); + DRes x = numeric.input(a, 1); + DRes y = numeric.input(b, 2); + return numeric.open(numeric.div(x, y)); + }); + BigDecimal output = runApplication(app); + Assert.assertEquals(a / b, output.doubleValue(), 0.01); + } + }; } - }; } - } - - public static class TestRandomModP - extends TestThreadFactory { - @Override - public TestThread next() { - return new TestThread() { + public static class TestRandomModP + extends TestThreadFactory { @Override - public void test() { - - int n = 100; - - Application, ProtocolBuilderNumeric> app = producer -> producer.seq(seq -> { - List> output = Stream.generate(() -> seq.seq(new RandomModP<>())).limit(n).map(seq.numeric()::open).collect( - Collectors.toList()); - return DRes.of(output); - }).seq((seq, output) -> DRes.of(output.stream().map(DRes::out).collect(Collectors.toList()))); - List output = runApplication(app); - - CRTRingDefinition ring = (CRTRingDefinition) this.getFieldDefinition(); - for (BigInteger r : output) { - if (r.compareTo(ring.getLeftModulus()) >= 0) { - Assert.fail(); - } - } + public TestThread next() { + return new TestThread() { + + @Override + public void test() { + + int n = 100; + + Application, ProtocolBuilderNumeric> app = producer -> producer.seq(seq -> { + List> output = Stream.generate(() -> seq.seq(new RandomModP<>())).limit(n).map(seq.numeric()::open).collect( + Collectors.toList()); + return DRes.of(output); + }).seq((seq, output) -> DRes.of(output.stream().map(DRes::out).collect(Collectors.toList()))); + List output = runApplication(app); + + CRTRingDefinition ring = (CRTRingDefinition) this.getFieldDefinition(); + for (BigInteger r : output) { + if (r.compareTo(ring.getLeftModulus()) >= 0) { + Assert.fail(); + } + } + } + }; } - }; } - } } diff --git a/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/TestCRT.java b/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/TestCRT.java index 7dbe9c39f..9d92a2151 100644 --- a/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/TestCRT.java +++ b/suite/crt/src/test/java/dk/alexandra/fresco/suite/crt/TestCRT.java @@ -6,6 +6,7 @@ import dk.alexandra.fresco.lib.common.math.integer.TestProductAndSum.TestSum; import dk.alexandra.fresco.lib.common.math.integer.binary.BinaryOperationsTests.TestGenerateRandomBitMask; import dk.alexandra.fresco.lib.common.math.integer.binary.BinaryOperationsTests.TestRightShift; +import dk.alexandra.fresco.lib.common.math.integer.division.DivisionTests; import dk.alexandra.fresco.lib.common.math.integer.linalg.LinAlgTests.TestInnerProductClosed; import dk.alexandra.fresco.lib.common.math.integer.linalg.LinAlgTests.TestInnerProductOpen; import dk.alexandra.fresco.lib.common.math.integer.mod.Mod2mTests.TestMod2m; @@ -31,12 +32,14 @@ import dk.alexandra.fresco.suite.crt.BasicCRTTests.TestTruncp; import dk.alexandra.fresco.suite.crt.fixed.CRTAdvancedFixedNumeric; import dk.alexandra.fresco.suite.crt.fixed.CRTFixedNumeric; +import dk.alexandra.fresco.suite.dummy.arithmetic.BasicArithmeticTests; import dk.alexandra.fresco.suite.dummy.arithmetic.BasicArithmeticTests.TestLotsMult; import dk.alexandra.fresco.suite.dummy.arithmetic.BasicArithmeticTests.TestOutputToSingleParty; import dk.alexandra.fresco.suite.dummy.arithmetic.BasicArithmeticTests.TestRandomBit; import dk.alexandra.fresco.suite.dummy.arithmetic.BasicArithmeticTests.TestSumAndMult; import dk.alexandra.fresco.suite.spdz.configuration.PreprocessingStrategy; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; public class TestCRT { @@ -52,6 +55,11 @@ public void testInput() { new AbstractSpdzCRTTest().runTest(new TestInput<>(), EvaluationStrategy.SEQUENTIAL, PreprocessingStrategy.DUMMY, 2); } + @Test + public void testKnown() { + new AbstractSpdzCRTTest().runTest(new BasicArithmeticTests.TestKnownSInt<>(), EvaluationStrategy.SEQUENTIAL, PreprocessingStrategy.DUMMY, 2); + } + @Test public void testSum() { new AbstractSpdzCRTTest().runTest(new TestSum<>(), EvaluationStrategy.SEQUENTIAL, PreprocessingStrategy.DUMMY, 2); @@ -77,6 +85,16 @@ public void testMultAndAdd() { new AbstractSpdzCRTTest().runTest(new TestSumAndMult<>(), EvaluationStrategy.SEQUENTIAL, PreprocessingStrategy.MASCOT, 2); } + @Test + public void testDivision() { + new AbstractSpdzCRTTest().runTest(new DivisionTests.TestDivision<>(), EvaluationStrategy.SEQUENTIAL, PreprocessingStrategy.DUMMY, 2); + } + + @Test + public void testDivisionKnownDivisor() { + new AbstractSpdzCRTTest().runTest(new DivisionTests.TestKnownDivisorDivision<>(), EvaluationStrategy.SEQUENTIAL, PreprocessingStrategy.DUMMY, 2); + } + @Test public void testRightShift() { new AbstractSpdzCRTTest().runTest(new TestRightShift<>(), EvaluationStrategy.SEQUENTIAL, PreprocessingStrategy.DUMMY, 2); @@ -94,43 +112,82 @@ public void testMults() { @Test public void testCorrelatedNoise() { - new AbstractDummyCRTTest() + new AbstractSemiHonestDummyCRTTest() .runTest(new TestCorrelatedNoise<>(), EvaluationStrategy.SEQUENTIAL, 2); } @Test public void testGenerateRandomBitMask() { - new AbstractDummyCRTTest().runTest(new TestGenerateRandomBitMask<>(), EvaluationStrategy.SEQUENTIAL, 2); + new AbstractSemiHonestDummyCRTTest().runTest(new TestGenerateRandomBitMask<>(), EvaluationStrategy.SEQUENTIAL, 2); } @Test public void testRandomBit() { - new AbstractDummyCRTTest().runTest(new TestRandomBit<>(), EvaluationStrategy.SEQUENTIAL, 2); + new AbstractSemiHonestDummyCRTTest().runTest(new TestRandomBit<>(), EvaluationStrategy.SEQUENTIAL, 2); } @Test public void testLiftPQ() { - new AbstractDummyCRTTest().runTest(new TestLiftPQ<>(), EvaluationStrategy.SEQUENTIAL, 2); + new AbstractSemiHonestDummyCRTTest().runTest(new TestLiftPQ<>(), EvaluationStrategy.SEQUENTIAL, 2); } @Test public void testLiftQP() { - new AbstractDummyCRTTest().runTest(new TestLiftQP<>(), EvaluationStrategy.SEQUENTIAL, 2); + new AbstractSemiHonestDummyCRTTest().runTest(new TestLiftQP<>(), EvaluationStrategy.SEQUENTIAL, 2); } @Test public void testProjectionLeft() { - new AbstractDummyCRTTest() + new AbstractSemiHonestDummyCRTTest() .runTest(new TestProjectionLeft<>(), EvaluationStrategy.SEQUENTIAL, 2); } @Test public void testProjectionRight() { - new AbstractDummyCRTTest() + new AbstractSemiHonestDummyCRTTest() .runTest(new TestProjectionRight<>(), EvaluationStrategy.SEQUENTIAL, 2); } + @Test + public void testCovertCorrelatedNoise() { + new AbstractCovertDummyCRTTest() + .runTest(new TestCorrelatedNoise<>(), EvaluationStrategy.SEQUENTIAL, 2); + } + + @Test + public void testCovertGenerateRandomBitMask() { + new AbstractCovertDummyCRTTest().runTest(new TestGenerateRandomBitMask<>(), EvaluationStrategy.SEQUENTIAL, 2); + } + + @Test + public void testCovertRandomBit() { + new AbstractCovertDummyCRTTest().runTest(new TestRandomBit<>(), EvaluationStrategy.SEQUENTIAL, 2); + } + + @Test + public void testCovertLiftPQ() { + new AbstractCovertDummyCRTTest().runTest(new TestLiftPQ<>(), EvaluationStrategy.SEQUENTIAL, 2); + } + + @Test + public void testCovertLiftQP() { + new AbstractCovertDummyCRTTest().runTest(new TestLiftQP<>(), EvaluationStrategy.SEQUENTIAL, 2); + } + + @Test + public void testCovertProjectionLeft() { + new AbstractCovertDummyCRTTest() + .runTest(new TestProjectionLeft<>(), EvaluationStrategy.SEQUENTIAL, 2); + } + + @Test + public void testCovertProjectionRight() { + new AbstractCovertDummyCRTTest() + .runTest(new TestProjectionRight<>(), EvaluationStrategy.SEQUENTIAL, 2); + } + + @Test public void testTruncp() { new AbstractSpdzCRTTest() @@ -155,6 +212,8 @@ public void testFixedPointDivision() { .runTest(new TestFixedPointDivision<>(), EvaluationStrategy.SEQUENTIAL, PreprocessingStrategy.DUMMY, 2); } + // TODO needs random bit and other framework things implemented + @Ignore @Test public void testFixedPointSecretDivision() { new AbstractSpdzCRTTest() @@ -168,6 +227,8 @@ public void testSort() { PreprocessingStrategy.DUMMY, 2); } + // TODO needs random bit and other framework things implemented + @Ignore @Test public void testSortDifferentValueLength() { new AbstractSpdzCRTTest() @@ -175,6 +236,8 @@ public void testSortDifferentValueLength() { PreprocessingStrategy.DUMMY, 2); } + // TODO needs random bit and other framework things implemented + @Ignore @Test public void testExp() { new AbstractSpdzCRTTest() diff --git a/suite/spdz/src/test/java/dk/alexandra/fresco/suite/spdz/maccheck/TestSpdzMacCheckTamperWithValues.java b/suite/spdz/src/test/java/dk/alexandra/fresco/suite/spdz/maccheck/TestSpdzMacCheckTamperWithValues.java index afea133d3..29f3b9343 100644 --- a/suite/spdz/src/test/java/dk/alexandra/fresco/suite/spdz/maccheck/TestSpdzMacCheckTamperWithValues.java +++ b/suite/spdz/src/test/java/dk/alexandra/fresco/suite/spdz/maccheck/TestSpdzMacCheckTamperWithValues.java @@ -1,7 +1,5 @@ package dk.alexandra.fresco.suite.spdz.maccheck; -import static org.junit.Assert.assertThat; - import dk.alexandra.fresco.framework.Application; import dk.alexandra.fresco.framework.DRes; import dk.alexandra.fresco.framework.MaliciousException; @@ -9,18 +7,19 @@ 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.builder.numeric.field.BigIntegerFieldDefinition; import dk.alexandra.fresco.framework.builder.numeric.field.MersennePrimeFieldDefinition; -import dk.alexandra.fresco.framework.util.ModulusFinder; import dk.alexandra.fresco.framework.value.SInt; import dk.alexandra.fresco.suite.spdz.AbstractSpdzTest; import dk.alexandra.fresco.suite.spdz.SpdzResourcePool; import dk.alexandra.fresco.suite.spdz.configuration.PreprocessingStrategy; import dk.alexandra.fresco.suite.spdz.datatypes.SpdzSInt; -import java.math.BigInteger; import org.hamcrest.core.IsInstanceOf; import org.junit.Test; +import java.math.BigInteger; + +import static org.junit.Assert.assertEquals; + public class TestSpdzMacCheckTamperWithValues extends AbstractSpdzTest { private static MersennePrimeFieldDefinition definition = MersennePrimeFieldDefinition.find(8); @@ -72,7 +71,7 @@ public void test() { try { runApplication(app); } catch (Exception e) { - assertThat(e.getCause(), IsInstanceOf.instanceOf(MaliciousException.class)); + assertEquals(e.getCause(), IsInstanceOf.instanceOf(MaliciousException.class)); } } };