aicis / fresco

A FRamework for Efficient Secure COmputation
Other
133 stars 59 forks source link

Different return values to players in AES demo #336

Closed KyleKotowick closed 5 years ago

KyleKotowick commented 5 years ago

The AES demo is great, but is it possible to not return the ciphertext to the player that sent the key?

Since the entire purpose of MPC is to prevent one party from finding out the input of the other, the way the AES demo is coded now is unrealistic. It returns the ciphertext to both players, and since one player has the key that was used to encrypt the plaintext the other player sent, he can just use that key to decrypt the ciphertext and retrieve the plaintext. It would be ideal if the ciphertext was only returned to the player who contributed the plaintext, and the player who contributed the key just got a True/False return value of whether it succeeded.

Is this possible to do securely with Fresco (i.e. a malicious player who sent the key can't edit their code to get the ciphertext as well)?

GuutBoy commented 5 years ago

Sure, that is possible. Just change the line outs.add(seq.binary().open(toOpen)); to outs.add(seq.binary().open(toOpen, 2)); in https://github.com/aicis/fresco/blob/master/demos/aes/src/main/java/dk/alexandra/fresco/demo/AesDemo.java

This should open the values to a specific party, rather than all parties (in this case party two). You may need to some of the remaining demo code accordingly to handle the new output.

KyleKotowick commented 5 years ago

Thank you for the quick response. Unfortunately, this doesn't seem to be a secure solution. If we edit the code as you suggest, and both Player 1 (key) and Player 2 (plaintext) run the code:

outs.add(seq.binary().open(toOpen, 2));

Then this works as intended, and only Player 2 receives the ciphertext. If we assume that Player 1 is malicious, however, and changes their local code, then now the following code is being run:

Player 1: outs.add(seq.binary().open(toOpen));

Player 2: outs.add(seq.binary().open(toOpen, 2));

And now, even though Player 2 didn't consent to it, Player 1 still receives the ciphertext. At least, that's what's happening in the tests I'm running.

EDIT: it should also be noted that this strategy wouldn't work when trying to run this securly anyways, because when I try it with the TinyTables protcol suite, it throws the error: java.lang.UnsupportedOperationException: The opening towards party id is not implemented for TinyTables

EDIT 2: I tried using SPDZ instead, and the following command:

java -jar target\fresco-demo-aes.jar -e SEQUENTIAL_BATCHED -i 1 -p 1:localhost:8081 -p 2:localhost:8082 -s spdz -Dspdz.preprocessingStrategy=DUMMY -in 000102030405060708090a0b0c0d0e0f

Throws an error:

Error while parsing arguments / instantiating protocol suite: Name is null
Exception in thread "main" java.lang.IllegalArgumentException: Error while parsing arguments: Name is null
        at dk.alexandra.fresco.demo.cli.CmdLineUtil.parse(CmdLineUtil.java:273)
        at dk.alexandra.fresco.demo.AesDemo.main(AesDemo.java:81)
Caused by: java.lang.NullPointerException: Name is null
        at java.lang.Enum.valueOf(Unknown Source)
        at dk.alexandra.fresco.suite.spdz.configuration.PreprocessingStrategy.valueOf(PreprocessingStrategy.java:6)
        at dk.alexandra.fresco.demo.cli.CmdLineProtocolSuite.createSpdzResourcePool(CmdLineProtocolSuite.java:124)
        at dk.alexandra.fresco.demo.cli.CmdLineProtocolSuite.<init>(CmdLineProtocolSuite.java:72)
        at dk.alexandra.fresco.demo.cli.CmdLineUtil.parse(CmdLineUtil.java:249)

EDIT 3: After editing the code in CmdLineUtil.java:273 to force it to use PreprocessingStrategy.DUMMY (for some reason it was failing to read this setting from the command line argument), I now get the error:

java.lang.ClassCastException: dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric cannot be cast to dk.alexandra.fresco.framework.builder.binary.ProtocolBuilderBinary
        at dk.alexandra.fresco.demo.AesDemo.buildComputation(AesDemo.java:52)

So, since DummyBool isn't secure, TinyTables doesn't support outputting to a specific player ID, and SPDZ isn't compatible with the AES computations (Arithmetic vs. Bool), is there no way to do this securely?

n1v0lg commented 5 years ago

This is happening is because you are running with the dummy suite which is inherently insecure. And you're right, TinyTables does not currently support opening to a single party (that suite was more of an experimental implementation and we're planning to drop support for it in a coming release). The reason SPDZ doesn't work here is that it's an arithmetic suite which does not support boolean protocols. SPDZ does support MiMC (https://eprint.iacr.org/2016/492.pdf) a different symmetric enc. scheme however--I would recommend giving that a shot if you just need symmetric encryption but not necessarily AES.

KyleKotowick commented 5 years ago

Unfortunately, AES is required for my implementation. Is there no way to do this then?

Is it possible to convert the AES demo to be an arithmetic protocol instead of boolean?

n1v0lg commented 5 years ago

There is no out-of-the-box way to run AES in arithmetic mode unfortunately. You would have to implement it as a computation based on arithmetic operations in FRESCO (certainly doable but would require a fair amount of work).

Regarding tiny tables: our tiny tables implementation only protects against passive adversaries (i.e., parties are required to faithfully execute the protocol). In that sense, the attack you describe is out of scope for our adversary model since an attacker is assumed to follow the protocol.

If you are okay with passive security then adding an output-to-single-party protocol should be pretty straight-forward.

However, if you need full malicious security, tiny tables does not currently provide that even if you were to implement the single-party output protocol.

In that sense, implementing AES in arithmetic mode is probably your best bet.

Edit Actually, sorry, come to think of it, here's a workaround for the output-single-party issue: you could have the party that is to receive the ciphertext input a random binary string, under MPC xor that with the ciphertext, and output to both parties. The intended ciphertext recipient can then reconstruct the real ciphertext (by xoring again), but the key holder will not be able to because the output is one-time padded. Note that this does not address the fact that our tiny tables implementation only supports semi-honest security though.