public MultiplyLeftHelper(MascotResourcePool resourcePool, Network network, int otherId) { this.resourcePool = resourcePool; this.fieldElementUtils = new FieldElementUtils(resourcePool.getFieldDefinition()); this.rot = resourcePool.createRot(otherId, network); }
/** * Creates random authenticated elements. * * @param numElements number of elements to create * @return random authenticated elements */ public List<AuthenticatedElement> getRandomElements(int numElements) { List<List<AuthenticatedElement>> perPartyElements = new ArrayList<>( resourcePool.getNoOfParties()); for (int partyId = 1; partyId <= resourcePool.getNoOfParties(); partyId++) { if (partyId == resourcePool.getMyId()) { List<FieldElement> randomElements = resourcePool.getLocalSampler().getNext(numElements); perPartyElements.add(elementGeneration.input(randomElements)); } else { perPartyElements.add(elementGeneration.input(partyId, numElements)); } } return Addable.sumRows(perPartyElements); }
/** * Computes digest of messages and resets md. */ private byte[] computeDigest(List<byte[]> messages) { for (byte[] message : messages) { resourcePool.getMessageDigest().update(message); } byte[] digest = resourcePool.getMessageDigest().digest(); resourcePool.getMessageDigest().reset(); return digest; }
/** * Computes additive (unauthenticated) shares of values and distributes the shares across * parties. */ private List<FieldElement> secretShare(List<FieldElement> values, int numShares) { List<List<FieldElement>> allShares = values.stream().map(value -> sharer.share(value, numShares)).collect(Collectors.toList()); List<List<FieldElement>> byParty = TransposeUtils.transpose(allShares); for (int partyId = 1; partyId <= resourcePool.getNoOfParties(); partyId++) { // send shares to everyone but self if (partyId != resourcePool.getMyId()) { List<FieldElement> shares = byParty.get(partyId - 1); network.send(partyId, resourcePool.getFieldDefinition().serialize(shares)); } } // return own shares return byParty.get(resourcePool.getMyId() - 1); }
/** * Constructs new mac checker. */ public MacCheck(MascotResourcePool resourcePool, Network network) { super(resourcePool, network, resourcePool.getFieldDefinition()); }
.stretch(rightFactors, resourcePool.getNumCandidatesPerTriple()); for (int partyId = 1; partyId <= resourcePool.getNoOfParties(); partyId++) { if (partyId != resourcePool.getMyId()) { MultiplyLeft leftMult = leftMultipliers.get(partyId); MultiplyRight rightMult = rightMultipliers.get(partyId); if (resourcePool.getMyId() < partyId) { subFactors.add(rightMult.multiply(stretched)); subFactors.add(leftMult.multiply(leftFactorGroups));
private void initializeMultipliers(MascotResourcePool resourcePool, Network network) { for (int partyId = 1; partyId <= resourcePool.getNoOfParties(); partyId++) { if (partyId != resourcePool.getMyId()) { if (resourcePool.getMyId() < partyId) { rightMultipliers.put(partyId, new MultiplyRight(resourcePool, network, partyId)); leftMultipliers.put(partyId, new MultiplyLeft(resourcePool, network, partyId)); } else { leftMultipliers.put(partyId, new MultiplyLeft(resourcePool, network, partyId)); rightMultipliers.put(partyId, new MultiplyRight(resourcePool, network, partyId)); } } } }
List<FieldElement> feSeeds, List<FieldElement> diffs) { final FieldElement zeroElement = resourcePool.getFieldDefinition().createElement(BigInteger.ZERO); List<FieldElement> result = new ArrayList<>(leftFactors.size()); int diffIdx = 0; for (FieldElement leftFactor : leftFactors) { StrictBitVector currentBits = resourcePool.getFieldDefinition() .convertToBitVector(leftFactor); List<FieldElement> summands = new ArrayList<>(resourcePool.getModBitLength()); for (int b = 0; b < resourcePool.getModBitLength(); b++) { FieldElement feSeed = feSeeds.get(diffIdx); FieldElement diff = diffs.get(diffIdx);
.add(resourcePool.getFieldDefinition(), epsilonDeltaProd, resourcePool.getMyId(), macKeyShare); products.add(product);
/** * Generates random input masks. * * @param maskerId the party that knows the plain mask * @param numMasks number of masks to generate * @return input masks */ public List<InputMask> getInputMasks(Integer maskerId, int numMasks) { if (maskerId.equals(resourcePool.getMyId())) { List<FieldElement> randomMasks = resourcePool.getLocalSampler().getNext(numMasks); List<AuthenticatedElement> authenticated = input(randomMasks); return IntStream.range(0, numMasks) .mapToObj(idx -> new InputMask(randomMasks.get(idx), authenticated.get(idx))) .collect(Collectors.toList()); } else { return input(maskerId, numMasks).stream().map(InputMask::new) .collect(Collectors.toList()); } }
/** * Creates new {@link ElementGeneration}. */ public ElementGeneration(MascotResourcePool resourcePool, Network network, FieldElement macKeyShare, FieldElementPrg jointSampler) { this.resourcePool = resourcePool; this.network = network; this.fieldElementUtils = new FieldElementUtils(resourcePool.getFieldDefinition()); this.macChecker = new MacCheck(resourcePool, network); this.macKeyShare = macKeyShare; this.localSampler = resourcePool.getLocalSampler(); this.jointSampler = jointSampler; this.sharer = new AdditiveSecretSharer(localSampler); this.copeSigners = new HashMap<>(); this.copeInputters = new HashMap<>(); initializeCope(resourcePool, network); }
/** * Generates numTriples multiplication triples in a batch. <p>Implements Protocol 4 (all steps). * Note that while the paper describes a protocol for generating a single triple, this * implementation produces a batch of multiplication triples.</p> * * @param numTriples number of triples to generate * @return valid multiplication triples */ public List<MultiplicationTriple> triple(int numTriples) { // generate random left factor groups List<FieldElement> leftFactorGroups = resourcePool.getLocalSampler() .getNext(numTriples * resourcePool.getNumCandidatesPerTriple()); // generate random right factors List<FieldElement> rightFactors = resourcePool.getLocalSampler().getNext(numTriples); // compute product groups List<FieldElement> productGroups = multiply(leftFactorGroups, rightFactors); // combine into unauthenticated triples List<UnauthenticatedTriple> unauthTriples = toUnauthenticatedTriple(leftFactorGroups, rightFactors, productGroups); // combine unauthenticated triples into unauthenticated triple candidates List<UnauthenticatedCandidate> candidates = combine(unauthTriples); // use el-gen to input candidates and combine them to the authenticated candidates List<AuthenticatedCandidate> authenticated = authenticate(candidates); // for each candidate, run sacrifice and get valid triple return sacrifice(authenticated); }
/** * Creates new {@link Mascot}. */ public Mascot(MascotResourcePool resourcePool, Network network, FieldElement macKeyShare) { this.resourcePool = resourcePool; // agree on joint seed StrictBitVector jointSeed = new CoinTossingMpc(resourcePool, network) .generateJointSeed(resourcePool.getPrgSeedLength()); FieldElementPrg jointSampler = new FieldElementPrgImpl(jointSeed, resourcePool.getFieldDefinition()); this.elementGeneration = new ElementGeneration(resourcePool, network, macKeyShare, jointSampler); this.tripleGeneration = new TripleGeneration(resourcePool, network, elementGeneration, jointSampler); this.bitConverter = new BitConverter(resourcePool, new OnlinePhase(resourcePool, tripleGeneration, elementGeneration, macKeyShare), macKeyShare); }
/** * Computes this party's shares of the final products. <br> For each seed pair (q0, q1) this party * holds, uses q0 to recombine into field elements representing the product shares. * * @param feZeroSeeds the zero choice seeds * @param numRightFactors number of total right factors * @return shares of products */ public List<FieldElement> computeProductShares(List<FieldElement> feZeroSeeds, int numRightFactors) { List<FieldElement> productShares = new ArrayList<>(numRightFactors); for (int rightFactIdx = 0; rightFactIdx < numRightFactors; rightFactIdx++) { int from = rightFactIdx * resourcePool.getModBitLength(); int to = (rightFactIdx + 1) * resourcePool.getModBitLength(); List<FieldElement> subFactors = feZeroSeeds.subList(from, to); FieldElement recombined = fieldElementUtils.recombine(subFactors); productShares.add(recombined.negate()); } return productShares; }
private List<UnauthenticatedTriple> toUnauthenticatedTriple(List<FieldElement> left, List<FieldElement> right, List<FieldElement> products) { Stream<UnauthenticatedTriple> stream = IntStream.range(0, right.size()).mapToObj(idx -> { int groupStart = idx * resourcePool.getNumCandidatesPerTriple(); int groupEnd = (idx + 1) * resourcePool.getNumCandidatesPerTriple(); return new UnauthenticatedTriple(left.subList(groupStart, groupEnd), right.get(idx), products.subList(groupStart, groupEnd)); }); return stream.collect(Collectors.toList()); }
/** * Creates a new {@link CopeInputter} and initializes the COPE protocol. * * <p>This will run the initialization sub-protocol of COPE using an OT protocol to set up the PRG * seeds used in the <i>Extend</i> sub-protocol.</p> */ public CopeInputter(MascotResourcePool resourcePool, Network network, int otherId) { this.otherId = otherId; this.resourcePool = resourcePool; this.network = network; this.leftPrgs = new ArrayList<>(); this.rightPrgs = new ArrayList<>(); this.helper = new MultiplyRightHelper(resourcePool, network, otherId); seedPrgs(helper.generateSeeds(1, resourcePool.getLambdaSecurityParam())); }
/** * Sends own commitment to others and receives others' commitments. * * @param comm own commitment */ private List<HashBasedCommitment> distributeCommitments(HashBasedCommitment comm) { // broadcast own commitment broadcaster.sendToAll(getResourcePool().getCommitmentSerializer().serialize(comm)); // receive other parties' commitments from broadcast List<byte[]> rawComms = broadcaster.receiveFromAll(); // parse return rawComms.stream() .map(getResourcePool().getCommitmentSerializer()::deserialize) .collect(Collectors.toList()); }
/** * Creates new {@link CommitmentBasedInput}. */ public CommitmentBasedInput(MascotResourcePool resourcePool, Network network, ByteSerializer<T> serializer) { this.resourcePool = resourcePool; this.network = network; this.serializer = serializer; // for more than two parties, we need to use broadcast if (resourcePool.getNoOfParties() > 2) { this.broadcaster = new BroadcastingNetworkProxy(network, new BroadcastValidation(resourcePool, network)); } else { // if we have two parties or less we can just use the regular network this.broadcaster = this.network; } }
List<FieldElement> shares = secretShare(values, resourcePool.getNoOfParties()); network.sendToAll(resourcePool.getFieldDefinition().serialize(maskedValue)); network.receive(resourcePool.getMyId());
private void seedPrgs(List<StrictBitVector> seeds) { for (StrictBitVector seed : seeds) { prgs.add(new FieldElementPrgImpl(seed, resourcePool.getFieldDefinition())); } } }