Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mascot preprocessing #214

Merged
merged 527 commits into from Jan 25, 2018
Merged

Mascot preprocessing #214

merged 527 commits into from Jan 25, 2018

Conversation

n1v0lg
Copy link
Contributor

@n1v0lg n1v0lg commented Dec 21, 2017

Introduces MASCOT (https://eprint.iacr.org/2016/505.pdf) protocol for the SPDZ offline phase and an OT-extension protocol (https://eprint.iacr.org/2015/546). Also implements several useful sub-protocols, including base OT (www.pinkas.net/PAPERS/effot.ps), actively-secure broadcast, coin-tossing, and commitments.

Copy link
Collaborator

@pffrandsen pffrandsen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just the first run, I have fixed a few comments myself.

I have not gone through all files yet.

<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>fresco-tools-mascot</finalName>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we package mascot - why?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops that was a copy and paste. Gone now.

//import java.util.List;
//import java.util.stream.Stream;
//
//// TODO this class is sad
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code?

*/
@Override
public void send(int partyId, byte[] data) {
throw new UnsupportedOperationException("Broadcast network can only send to all");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks more like a proxy than a decorator

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just rename the class

// for each value we will have two sub-factors for each other party
List<List<FieldElement>> subFactors = new ArrayList<>();

// TODO parallelize
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still a TODO or irellevant now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a performance improvement for the > 2 party case. I will remove the TODO and make an improve performance issue instead where this can go as a subtask.

Copy link
Collaborator

@KasperDamgaard KasperDamgaard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general: really cool!!! :D
I would like to see mascot removed from spdz though, as it is really just a different data supplier. Also, it would be awesome if mascot could store the preprocessed data on file. If we only have the option of generating new data on the fly, then we kinda loose the whole idea of the preprocessing concept. So creating an option/class for serializing to disk and either use the same format as the current static approach (SpdzStorageDataSupplier) or change that supplier to accomodate a faster/better way (optimal solution - since we currently are using crappy IO and inefficient ObjectStreams - we want NIO instead I think).

* digest serves as the commitment itself and the opening is the randomness and
* the message committed to.
*
* @author jot2re
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We decided at some point that all author tags be removed. Some are still remaining, but I guess we should be consistent on new files

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed all author tags from the OT package.

import java.math.BigInteger;
import java.security.MessageDigest;

public interface NumericResourcePool extends ResourcePool {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interface missing javadoc. Which might help for me in understanding exactly what it is. In my world, resource pools are specific to protocol suites, and I don't think all numeric protocol suites needs access to e.g. a hash algorithm?

STATIC; // Use data already present on the machine it's running on.
DUMMY, // Use a dummy approach (e.g. always the same data)
MASCOT, // Use the Mascot preprocessing
STATIC // Use data already present on the machine it's running on.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not have Mascot as a possibility here. It belongs within the mascot project only.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

@@ -111,7 +112,7 @@ public SpdzMacCheckProtocol(SecureRandom rand, MessageDigest digest, SpdzStorage
}
deltaSum = deltaSum.mod(modulus);
if (!deltaSum.equals(BigInteger.ZERO)) {
throw new MPCException(
throw new MaliciousException(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! - while I remember: The other runtime exceptions in this class should also be malicious. This requires a few tests to be altered from what they expect.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, the other exceptions I'm talking about are not present until the spdz-test-coverage PR is merged in. Whichever PR get's merged last, should correct that then :)

private int maxBitLength;
private int batchSize;

public static SpdzMascotDataSupplier createTestSupplier(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want this in the "production" code?

List<Integer> ports = new ArrayList<>(noOfParties);
for (int i = 1; i <= noOfParties; i++) {
ports.add(9000 + i * (noOfParties - 1));
}

int maxBitLength;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 150 doesn't matter for other preprocessing types. Just make it 128 if this is required by MASCOT

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bitlength has relation to the size of modulus but also needs to be aligned to 8.

Let us fix the mim test and then see


@Test
public void testMimcWithMascot() {
// TODO This fails (most likely because
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this todo still valid?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

* @param macShare this party's share of the mac
* @throws MaliciousException if mac-check fails
*/
public void check(FieldElement opened, FieldElement macKeyShare, FieldElement macShare) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly out of curiosity: do we do MAC checks for just a single field element? Seems like it should be possible to pool multiple together and do the check on a sum.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, but the batching happens outside of this class (in ElementGeneration.check for instance).


<dependency>
<groupId>dk.alexandra.fresco</groupId>
<artifactId>mascot</artifactId>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not agree that the online spdz should depend on mascot. Cause it doesn't :) - mascot effectively just provides a different SpdzDataSupplier, and all tests on that should be done within mascot. The same was done with the (now removed) fuelstation where a REST data supplier was created and used only within that project. So I suggest moving the mascot supplier to mascot.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are three options:

  1. Mascot depending on spdz
  2. Spdz depending on mascot
  3. new spdz offline maven project

1 is your suggestion, and implies that mascot should be seen as a subprotocol of spdz
2 is the current solution
3 is the correct, but cumbersome solution

The plan is to keep mascot pure, therefore we went with 2. Which also eliminates the potential jar hell at the end of that choice.

@@ -0,0 +1,161 @@
package dk.alexandra.fresco.suite.spdz.storage;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned in the spdz POM file comment, this class should be located within the mascot project.

@pffrandsen
Copy link
Collaborator

@Rhaea I definitely think we should aim for MVP, and not extend this PR to include offline storage possibilities. And I fail to see the reason to put implementations of offline storage into the framework. There are serialization strategies available so anyone can do their own storage.

// Retrieve the random preprocessed message
byte[] randomMessage = randomMessages.get(offset).toByteArray();
// Use the random message as the seed to a PRG
Drbg currentPrg = new AesCtrDrbg(randomMessage);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment on optimization on the Sender side.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment on Sender side.

* @param choiceBit
* The actual choice bit of the receiver
*/
private void sendSwitchBit(Boolean choiceBit) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason choiceBit should not be a primitive type boolean instead of an object Boolean?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in c901c59

* Choice-bit. False for message 0, true for message 1.
* @return The serialized message from the OT
*/
public byte[] receive(Boolean choiceBit) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason choiceBit should not be a primitive type boolean instead of an object Boolean?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in 6bd02da

private final int batchSize;

/**
* Constructs a new OT protocol and constructs the internal sender and receiver
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not right, these objects are created in the send and receive methods. Possibly the java doc is updated?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in 6bd02da

// the value itself.
// Size of an int is always 4 bytes in java
ByteBuffer indexBuffer = ByteBuffer
.allocate(4 + input.get(0).getSize() * 8);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be .allocate(4 + input.get(0).getSize() / 8);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... possibly even .allocate((Integer.SIZE + input.get(0).getSize()) / 8); to make the code more readable (and make the comment above redundant).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit 0515efa

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I think you missed some parenthesis. Nevermind, I will fix it before merge.

* @return A random messages generated using a PRG
*/
private StrictBitVector computeRandomMessage(StrictBitVector seed, int sizeOfMessage) {
Drbg rand = new AesCtrDrbg(seed.toByteArray());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned other places this should just be taken directly from the seed if the length allows it. And otherwise should be the result of applying a hash function not a freshly seeded DRBG.

*/
public void send(Ot ot) {
if (sent == true) {
throw new IllegalStateException("Seed OTs have already been sent.");
Copy link
Contributor

@GuutBoy GuutBoy Jan 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible/reasonable to just hand the ot object to the constructor and do the sending/receiving at construction? This way there would be no reason to handle these exceptions.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe. The problem is that OT is asymmetric and thus one party must call send when the other calls receive and vice versa. Thus the constructor would also need the IDs from the OT functionality to do this properly. Furthermore this also requires the RotList to ALWAYS do OT in both directions. Something we might not want to do in general (MASCOT does it, but if we make 2PC protocols, we don't need it).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I am not too keen on doing too much network interaction in constructors, both in regards to testing, but also in regards to usage.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I guess you know better than I what problems it would cause :). However, at least then we should add to the documentation of these methods that they should only be called once/only called after send/recieve. Also, it would be nice to have getter methods for the sent/receive flags so you can test if the methods are safe to call.

Btw, we do network stuff in many constructors in, e.g., MASCOT, I do not see that as a problem.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added documentation in commit 0515efa
I have not added gettter and setter methods since they are currently not needed and thus adding these would mean that we also had to test methods. In general I don't think it is a good idea to add dead code.
Regarding the network stuff: I personally prefer light constructors, in particular when we are at the primitive level (which I consider OT to be). The reason being that otherwise we must ensure that both parties are at the same place in the protocol at the same time, at the specific place where an object is constructed, not when it is necessary used.

Copy link
Contributor

@GuutBoy GuutBoy Jan 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just the docs changed is fine by me.

About the constructor, I think in this case this implementation does make sense to me. As you say, you may not always both send and receive. So you cant just do both at construction (unless you pass extra parameters to the constructor or something, which would probably just be a mess anyway).

* vectors.
*/
public class Transpose {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For a utility class like this that is only intended to have static methods it is a good idea to add an empty private contructor so it is not instantiated by mistake. Like so:

private Tranpose() {
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in commit faa7e12

* Superclass containing the common methods for the sender and
* receiver parties of correlated OT with errors.
*/
public class CoteShared {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not a huge fan of these *Shared super classes. It seems to me they are mainly used to hold common parameters and utility methods which could just as well be held in a separate helper class (basically the resourcepool).

At least, I think they should be made abstract as only their subclasses are intended to be instantiated.
(This comment goes for essentially all the classes with the Shared suffix).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have already removed the getter methods so that they now only contain common methods in order to avoid code-copy between the sender and receiver, while still keeping an object oriented approach.
I have now also made them abstract in commit faa7e12

@GuutBoy
Copy link
Contributor

GuutBoy commented Jan 24, 2018

I think I have been through everything, and will not be adding more comments. I think I am pretty much ready to merge once the last few bits are done. Good job guys 👍

@GuutBoy
Copy link
Contributor

GuutBoy commented Jan 24, 2018

Btw. Note to self: let's try not to do a PR this huge ever again.

@GuutBoy GuutBoy merged commit 328b893 into develop Jan 25, 2018
@GuutBoy GuutBoy deleted the mascot-preprocessing branch January 25, 2018 12:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants