/** * Constructs new mac checker. */ public MacCheck(MascotResourcePool resourcePool, Network network) { super(resourcePool, network, resourcePool.getFieldDefinition()); }
private void seedPrgs(List<StrictBitVector> seeds) { for (StrictBitVector seed : seeds) { prgs.add(new FieldElementPrgImpl(seed, resourcePool.getFieldDefinition())); } } }
/** * Creates new triple generation protocol. */ public TripleGeneration(MascotResourcePool resourcePool, Network network, ElementGeneration elementGeneration, FieldElementPrg jointSampler) { this.resourcePool = resourcePool; this.fieldElementUtils = new FieldElementUtils(resourcePool.getFieldDefinition()); this.leftMultipliers = new HashMap<>(); this.rightMultipliers = new HashMap<>(); initializeMultipliers(resourcePool, network); this.elementGeneration = elementGeneration; this.jointSampler = jointSampler; }
private FieldElement fromBits(StrictBitVector vector) { // safe since the modulus is guaranteed to be close enough to 2^modBitLength return resourcePool.getFieldDefinition().deserialize(vector.toByteArray()); } }
public MultiplyLeftHelper(MascotResourcePool resourcePool, Network network, int otherId) { this.resourcePool = resourcePool; this.fieldElementUtils = new FieldElementUtils(resourcePool.getFieldDefinition()); this.rot = resourcePool.createRot(otherId, network); }
public MultiplyRightHelper(MascotResourcePool resourcePool, Network network, int otherId) { this.resourcePool = resourcePool; this.fieldElementUtils = new FieldElementUtils(resourcePool.getFieldDefinition()); this.rot = resourcePool.createRot(otherId, network); }
/** * Opens secret elements (distributes shares among all parties and recombines). Implements Open * sub-protocol of Protocol 3. * * @param closed authenticated elements to open * @return opened value */ public List<FieldElement> open(List<AuthenticatedElement> closed) { // get shares from authenticated elements (step 1) List<FieldElement> ownShares = closed.stream().map(AuthenticatedElement::getShare).collect(Collectors.toList()); // send own shares to others network.sendToAll(resourcePool.getFieldDefinition().serialize(ownShares)); // receive others' shares List<byte[]> rawShares = network.receiveFromAll(); // parse List<List<FieldElement>> shares = rawShares.stream() .map(resourcePool.getFieldDefinition()::deserializeList) .collect(Collectors.toList()); // recombine (step 2) return Addable.sumRows(shares); }
private FieldElement fromBits(StrictBitVector vector) { // safe since the modulus is guaranteed to be close enough to 2^modBitLength return resourcePool.getFieldDefinition().deserialize(vector.toByteArray()); }
private void seedPrgs(List<Pair<StrictBitVector, StrictBitVector>> seeds) { for (Pair<StrictBitVector, StrictBitVector> seedPair : seeds) { FieldDefinition definition = resourcePool.getFieldDefinition(); this.leftPrgs.add(new FieldElementPrgImpl(seedPair.getFirst(), definition)); this.rightPrgs.add(new FieldElementPrgImpl(seedPair.getSecond(), definition)); } } }
/** * Computes shares of product of this party's mac key share and other party's inputs. * * @param numInputs number of other party's inputs * @return shares of product */ public List<FieldElement> extend(int numInputs) { // compute chosen masks List<FieldElement> chosenMasks = generateMasks(numInputs); // use mac share for each input List<FieldElement> macKeyShares = IntStream.range(0, numInputs).mapToObj(idx -> macKeyShare).collect(Collectors.toList()); // receive diffs from other party List<FieldElement> diffs = resourcePool.getFieldDefinition().deserializeList(network.receive(otherId)); // compute product shares return multiplier.computeProductShares(macKeyShares, chosenMasks, diffs); }
/** * Computes shares of products of this party's input elements and other party's mac key share. * * @param inputElements input field elements * @return shares of products of mac key share and input elements */ public List<FieldElement> extend(List<FieldElement> inputElements) { // use seeds to generate mask pairs List<Pair<FieldElement, FieldElement>> maskPairs = generateMaskPairs(inputElements.size()); // compute t0 - t1 + x for each input x for each mask pair List<FieldElement> diffs = helper.computeDiffs(maskPairs, inputElements); // send diffs network.send(otherId, resourcePool.getFieldDefinition().serialize(diffs)); // get zero index masks List<FieldElement> feZeroSeeds = maskPairs.parallelStream().map(Pair::getFirst).collect(Collectors.toList()); // compute product shares return helper.computeProductShares(feZeroSeeds, inputElements.size()); }
/** * 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); }
/** * Uses left factors as choice bits to receive seeds to prgs. * * @param leftFactors the left side of the multiplication * @param seedLength the length of the seeds that the ROT produces * @return list of seeds to prgs */ public List<StrictBitVector> generateSeeds(List<FieldElement> leftFactors, int seedLength) { FieldDefinition fieldDefinition = resourcePool.getFieldDefinition(); StrictBitVector packedFactors = new StrictBitVector(fieldDefinition.serialize(reversed(leftFactors))); // use rot to get choice seeds List<StrictBitVector> seeds = rot.receive(packedFactors, seedLength); Collections.reverse(seeds); return seeds; }
/** * 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); }
/** * Runs a batch of the entry wise product protocol with a given of right hand vector. * * <p> * For right vector <i><b>b</b>= b<sub>0</sub>, b<sub>1</sub>, ...)</i> and left vector of the * other party <i><b>a</b> = (a<sub>0</sub>, a<sub>1</sub>, ...)</i>, the protocol computes secret * shares of entry wise product <i>(a<sub>0</sub>b<sub>0</sub>, a<sub>1</sub>b<sub>1</sub>, ... * </i>). * </p> * * @param rightFactors this party's vector <i>b<sub>0</sub>, b<sub>1</sub> ...</i> * @return shares of the products <i>a<sub>0</sub>b<sub>0</sub>, a<sub>1</sub>b<sub>1</sub> ... * </i> */ public List<FieldElement> multiply(List<FieldElement> rightFactors) { List<Pair<StrictBitVector, StrictBitVector>> seedPairs = multiplyRightHelper.generateSeeds(rightFactors.size(), resourcePool.getModBitLength()); // convert seeds pairs to field elements so we can compute on them List<Pair<FieldElement, FieldElement>> feSeedPairs = seedsToFieldElements(seedPairs); // compute q0 - q1 + b for each seed pair List<FieldElement> diffs = multiplyRightHelper.computeDiffs(feSeedPairs, rightFactors); // send diffs over to other party network.send(otherId, resourcePool.getFieldDefinition().serialize(diffs)); // get zero index seeds List<FieldElement> feZeroSeeds = feSeedPairs.parallelStream().map(Pair::getFirst).collect(Collectors.toList()); // compute product shares return multiplyRightHelper.computeProductShares(feZeroSeeds, rightFactors.size()); }
/** * Computes this party's authenticated shares of inputter party's inputs. Implements a non-input * party's side of the Input sub-protocol of Protocol 3. * * @param inputterId id of inputter * @param numInputs number of inputs * @return authenticated shares of inputs */ public List<AuthenticatedElement> input(Integer inputterId, int numInputs) { // receive shares from inputter (step 2) List<FieldElement> shares = resourcePool.getFieldDefinition().deserializeList(network.receive(inputterId)); // receive per-element mac shares (steps 3 through 5) CopeSigner copeSigner = copeSigners.get(inputterId); List<FieldElement> macs = copeSigner.extend(numInputs + 1); // generate coefficients for macs (step 6) List<FieldElement> coefficients = jointSampler.getNext(numInputs + 1); // receive masked value we will use in mac-check (step 7) FieldElement maskedValue = resourcePool.getFieldDefinition().deserialize(network.receive(inputterId)); // perform mac-check on opened value (steps 8 through 9) runMacCheck(maskedValue, coefficients, macs); // combine shares and mac shares to authenticated elements // (exclude mac and share of extra element) (step 10) List<FieldElement> inputElementMacs = macs.subList(0, numInputs); return toAuthenticatedElements(shares.subList(0, numInputs), inputElementMacs); }
/** * Implements batched version of Sacrifice sub-protocol of Protocol 4. */ private List<MultiplicationTriple> sacrifice(List<AuthenticatedCandidate> candidates) { // step 1 or protocol List<FieldElement> randomCoefficients = jointSampler.getNext(candidates.size()); // step 2 // compute masked values we will open and use in mac-check List<AuthenticatedElement> rhos = computeRhos(candidates, randomCoefficients); // step 3 // open masked values List<FieldElement> openRhos = elementGeneration.open(rhos); // step 4 // compute macs List<AuthenticatedElement> sigmas = computeSigmas(candidates, randomCoefficients, openRhos); // step 5 // put rhos and sigmas together rhos.addAll(sigmas); // pad open rhos with zeroes, one for each sigma List<FieldElement> paddedRhos = fieldElementUtils .padWith(openRhos, resourcePool.getFieldDefinition().createElement(0), sigmas.size()); // run mac-check elementGeneration.check(rhos, paddedRhos); // convert candidates to valid triples and return return toMultTriples(candidates); }
/** * Runs mac-check on open value. <br> * Conceptually, checks (macShare0 + ... + macShareN) = (open) * (keyShare0 + ... + keyShareN) * * @param opened the opened element to validate * @param macKeyShare this party's share of the mac key * @param macShare this party's share of the mac * @throws MaliciousException if mac-check fails */ public void check( FieldElement opened, FieldElement macKeyShare, FieldElement macShare) { // we will check that all sigmas together add up to 0 FieldElement sigma = macShare.subtract(opened.multiply(macKeyShare)); // commit to own value List<FieldElement> sigmas = allCommit(sigma); // add up all sigmas FieldElement sigmaSum = Addable.sum(sigmas); BigInteger outputSum = getResourcePool().getFieldDefinition().convertToUnsigned(sigmaSum); // sum of sigmas must be 0 if (outputSum.signum() != 0) { throw new MaliciousException("Malicious mac forging detected"); } }
/** * Runs a batch of the entry wise product protocol with a given of left hand vector. * * <p> For right vector <i><b>b</b>= b<sub>0</sub>, b<sub>1</sub>, ...)</i> and left vector * <i><b>a</b> = (a<sub>0</sub>, a<sub>1</sub>, ...)</i>, the protocol computes secret shares of * entry wise product <i>(a<sub>0</sub>b<sub>0</sub>, a<sub>1</sub>b<sub>1</sub>, ... </i>). </p> * * @param leftFactors this party's vector <i>a<sub>0</sub>, a<sub>1</sub> ...</i> * @return shares of the products <i>a<sub>0</sub>b<sub>0</sub>, a<sub>1</sub>b<sub>1</sub> * ...</i> */ public List<FieldElement> multiply(List<FieldElement> leftFactors) { List<StrictBitVector> seeds = multiplyLeftHelper.generateSeeds(leftFactors, resourcePool.getModBitLength()); List<FieldElement> feSeeds = seedsToFieldElements(seeds); // receive diffs from other party List<FieldElement> diffs = resourcePool.getFieldDefinition().deserializeList(network.receive(otherId)); return multiplyLeftHelper.computeProductShares(leftFactors, feSeeds, diffs); }
/** * 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); }