/** * Completes the receiver's part of the Naor-Pinkas OT in order to receive a random message of the * length of hash digest. * * @return The random message received */ private byte[] receiveRandomOt(boolean choiceBit) { BigInteger c = new BigInteger(network.receive(otherId)); BigInteger privateKey = randNum.nextBigInteger(dhModulus); BigInteger publicKeySigma = dhGenerator.modPow(privateKey, dhModulus); BigInteger publicKeyNotSigma = publicKeySigma.modInverse(dhModulus).multiply(c); if (choiceBit == false) { network.send(otherId, publicKeySigma.toByteArray()); } else { network.send(otherId, publicKeyNotSigma.toByteArray()); } BigInteger encZero = new BigInteger(network.receive(otherId)); BigInteger encOne = new BigInteger(network.receive(otherId)); byte[] message; if (choiceBit == false) { message = decryptRandomMessage(encZero, privateKey); } else { message = decryptRandomMessage(encOne, privateKey); } return message; }
/** * Sends own opening info to others and receives others' opening info. * * @param opening own opening info */ private List<byte[]> distributeOpenings(byte[] opening) { // send (over regular network) own opening info network.sendToAll(opening); // receive opening info from others return network.receiveFromAll(); }
/** * Retrieves input from all players (including yourself) * * @return A list of byte buffers where the data from party 1 resides at * index 0 and so forth. */ default List<byte[]> receiveFromAll() { List<byte[]> res = new ArrayList<>(); for (int i = 1; i <= getNoOfParties(); i++) { res.add(receive(i)); } return res; }
/** * Queues up a value to be send to all parties (yourself included). * * @param data The value to send to all parties */ default void sendToAll(byte[] data) { for (int i = 1; i <= getNoOfParties(); i++) { send(i, data); } }
@Override public EvaluationStatus evaluate(int round, ResourcePool resourcePool, Network network) { if (round == 0) { if (resourcePool.getMyId() == sender) { network.sendToAll(new byte[]{BooleanSerializer.toBytes(input.out())}); } return EvaluationStatus.HAS_MORE_ROUNDS; } else { boolean r = BooleanSerializer.fromBytes(network.receive(sender)[0]); this.output = new DummyBooleanSBool(r); return EvaluationStatus.IS_DONE; } }
@Override public byte[] receive(int id) { ByteArrayInputStream byteInputStream = input.get(id); if (byteInputStream == null) { byte[] partyData = network.receive(id); byteInputStream = new ByteArrayInputStream(partyData); input.put(id, byteInputStream); } int count = byteInputStream.read(); byte[] bytes = new byte[count]; byteInputStream.read(bytes, 0, count); return bytes; }
@Override public void sendToAll(byte[] data) { network.sendToAll(data); }
@Override public void send(int partyId, byte[] data) { this.delegate.send(partyId, data); }
boolean receiveBroadcastValidation(Network network, byte[] digest) { //TODO: should we check that we get messages from all players? boolean validated = true; List<byte[]> digests = network.receiveFromAll(); for (byte[] d : digests) { boolean equals = Arrays.equals(d, digest); validated = validated && equals; } return validated; } }
@Override public int getNoOfParties() { return delegate.getNoOfParties(); }
@Override public EvaluationStatus evaluate(int round, DummyArithmeticResourcePool rp, Network network) { if (round == 0) { if (targetId == rp.getMyId()) { network.sendToAll(rp.getFieldDefinition().serialize(open)); } return EvaluationStatus.HAS_MORE_ROUNDS; } else { //if (round == 1) { byte[] bin = network.receive(targetId); closed = new DummyArithmeticSInt(rp.getFieldDefinition().deserialize(bin)); return EvaluationStatus.IS_DONE; } }
@Override public StrictBitVector receive(boolean choiceBit) { byte[] seed = receiveRandomOt(choiceBit); byte[] encryptedZeroMessage = network.receive(otherId); byte[] encryptedOneMessage = network.receive(otherId); return recoverTrueMessage(encryptedZeroMessage, encryptedOneMessage, seed, choiceBit); }
private byte[] sendAndReset(MessageDigest dig, Network network) { byte[] digest = dig.digest(); dig.reset(); network.sendToAll(digest); return digest; }
/** * Flushes the internal buffers and sends the (remaining) pieces over the wire. */ public void flush() { for (int i = 1; i <= noOfParties; i++) { if (output.containsKey(i)) { ByteArrayOutputStream byteArrayOutputStream = output.get(i); byte[] data = byteArrayOutputStream.toByteArray(); network.send(i, data); } output.remove(i); } input.clear(); } }
/** * Receives digests from other parties and checks that these are consistent with own digest. */ public void receiveAndValidateDigests(byte[] ownDigest) { List<byte[]> received = network.receiveFromAll(); validateDigests(ownDigest, received); }
@Override public int getNoOfParties() { return network.getNoOfParties(); }
@Override public EvaluationStatus evaluate(int round, ResourcePoolT resourcePool, Network network) { if (round == 0) { network.sendToAll(input.clone()); return EvaluationStatus.HAS_MORE_ROUNDS; } else { result = network.receiveFromAll(); return EvaluationStatus.IS_DONE; } } }
/** * Exchange the seed with the other party using a commitment protocol. * * @param seed * The current party's seed * @param network * The network instance * @return The other party's seed */ private byte[] exchangeSeeds(byte[] seed, Network network) { // Let the party with the smallest id be the party receiving a commitment if (myId < otherId) { byte[] serializedComm = network.receive(otherId); HashBasedCommitment comm = serializer.deserialize(serializedComm); network.send(otherId, seed.clone()); byte[] opening = network.receive(otherId); return comm.open(opening); } else { HashBasedCommitment comm = new HashBasedCommitment(); byte[] openInfo = comm.commit(rand, seed); network.send(otherId, serializer.serialize(comm)); byte[] otherSeed = network.receive(otherId); network.send(otherId, openInfo); return otherSeed; } } }
/** * Runs broadcast validation upon receiving messages to ensure consistency. */ @Override public byte[] receive(int partyId) { byte[] received = network.receive(partyId); validator.validate(Arrays.asList(received)); return received; }