cheating-proof-transcripts/TrapdoorCommitmentCheatingP...
Sarah Jamie Lewis a8fd818dd7 Adding Cheating Proof Examples 2019-10-25 21:07:16 -07:00
..
proofs Adding Cheating Proof Examples 2019-10-25 21:07:16 -07:00
proofs-2 Adding Cheating Proof Examples 2019-10-25 21:07:16 -07:00
proofs-2-zero Adding Cheating Proof Examples 2019-10-25 21:07:16 -07:00
proofs-zero Adding Cheating Proof Examples 2019-10-25 21:07:16 -07:00
BgIntegrationTestUpdate.java Adding Cheating Proof Examples 2019-10-25 21:07:16 -07:00
README Adding Cheating Proof Examples 2019-10-25 21:07:16 -07:00

README

This folder contains proof transcripts that demonstrate a trapdoor in the 
SwissVote-Scytl mixnet.  It was generated by Sarah Jamie Lewis, Olivier
Pereira and Vanessa Teague, using techniques described in our report,
"Ceci n'est pas une preuve."

In order to verify the proof transcripts, you will need to have a running
copy of the Swisspost-Scytl voting system, which was made available to 
researchers through the Swiss public intrusion test at
https://onlinevote-pit.ch/details/

Folders proof/ and proof-zero/ each contain a manipulated proof transcript, each for 
the sequence of votes (2,2,3,7).  In each case, the mixnet manipulates the outcome 
and produces ciphertexts (2,3,3,7) as output, along with a correctness proof 
that passes verification.  

The transcript in proof/ is a typical run of a real election system, in which the votes 
are properly encrypted with random values.  The transcript in proof-zero is an atypical 
run for demonstration purposes, in which zero randomness is used - thus the
manipulation is immediately obvious to a human reader.

Folders proof-2/ and proof-2-zero/ each contain a manipulated proof transcript
that implements the second kind of cheating described in our paper, in section 2.2.2.
In this cheat, every ciphertext is multiplied by 2.  Again proof-2/ contains
a typical run with real randomness, while proof-2-zero/ contains a run in which
zero randomness is used.  Hence the cheating is immediately obvious.


Instructions:
1. Unzip the files and store the proof transcripts.
2. In your copy of the Swisspost-Scytl code, replace the contents of online-voting-mixing/mixnet-engine/src/test/java/com/scytl/products/ov/mixnet/BaseBGMixnetIOVerifierITest.java with BgIntegrationTestUpdate.java
3. Update the proofsPath in BgIntegrationTestUpdate.java to wherever you stored the proofs.
4. Run givenSmallConfigWhenShuffleThenOK() 
5. You should see that the proof passes verification.

*************
The test in proof/ is run with the following inputs:

private static boolean CHEATING = true;
private static boolean CHEATING2 = false;

 BigInteger p = new BigInteger("15294034768093677312256663166625633354362303");
        q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2));
        BigInteger g = new BigInteger("2");

        zp = new ZpSubgroup(g, p, q);

        //Note
        //pow(2, 2972987297297297296356982562, p)
        //5943523178887533241241798626972220822590095
        ZpGroupElement[] publicKeyArray = new ZpGroupElement[1];
        publicKeyArray[0] = new ZpGroupElement(new BigInteger("5943523178887533241241798626972220822590095"), zp.getP(), zp.getQ());
        ElGamalPublicKey publicKey = new ElGamalPublicKey(Arrays.asList(publicKeyArray), zp);

        final GjosteenElGamal elgamal = new GjosteenElGamal(zp, publicKey);

        ZpGroupElement[] elements3 = getAsGroupElementArray(3, zp);
        ZpGroupElement[] elements2 = getAsGroupElementArray(2, zp);
        ZpGroupElement[] elements9 = getAsGroupElementArray(7, zp);

        final GjosteenElGamalRandomness rhoPrime11 = new GjosteenElGamalRandomness(234522456, q);
        final GjosteenElGamalRandomness rhoPrime12 = new GjosteenElGamalRandomness(788749345, q);
        final GjosteenElGamalRandomness rhoPrime21 = new GjosteenElGamalRandomness(543783459, q);
        final GjosteenElGamalRandomness rhoPrime22 = new GjosteenElGamalRandomness(741325490, q);

        final GjosteenElGamalRandomness[] rhoPrime = {rhoPrime11, rhoPrime12, rhoPrime21, rhoPrime22};

        final Ciphertext C11 = elgamal.encrypt(elements2, rhoPrime11);
        final Ciphertext C12 = elgamal.encrypt(elements2, rhoPrime12);
        final Ciphertext C21 = elgamal.encrypt(elements3, rhoPrime21);
        final Ciphertext C22 = elgamal.encrypt(elements9, rhoPrime22);

        final GjosteenElGamalRandomness rho11 = new GjosteenElGamalRandomness(345167524, q);
        final GjosteenElGamalRandomness rho12 = new GjosteenElGamalRandomness(435732453, q);
        final GjosteenElGamalRandomness rho21 = new GjosteenElGamalRandomness(892468901, q);
        final GjosteenElGamalRandomness rho22 = new GjosteenElGamalRandomness(252437823, q);

	and then the third element (C21) is copied over the second (C12).

****************
The test in proof-zero/ is run with the following inputs:

private static boolean CHEATING = true;
private static boolean CHEATING2 = false;

 BigInteger p = new BigInteger("15294034768093677312256663166625633354362303");
        q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2));
        BigInteger g = new BigInteger("2");

        zp = new ZpSubgroup(g, p, q);

        //Note
        //pow(2, 2972987297297297296356982562, p)
        //5943523178887533241241798626972220822590095
        ZpGroupElement[] publicKeyArray = new ZpGroupElement[1];
        publicKeyArray[0] = new ZpGroupElement(new BigInteger("5943523178887533241241798626972220822590095"), zp.getP(), zp.getQ());
        ElGamalPublicKey publicKey = new ElGamalPublicKey(Arrays.asList(publicKeyArray), zp);

        final GjosteenElGamal elgamal = new GjosteenElGamal(zp, publicKey);

        ZpGroupElement[] elements3 = getAsGroupElementArray(3, zp);
        ZpGroupElement[] elements2 = getAsGroupElementArray(2, zp);
        ZpGroupElement[] elements9 = getAsGroupElementArray(7, zp);

        final GjosteenElGamalRandomness rhoPrime11 = new GjosteenElGamalRandomness(0, q);
        final GjosteenElGamalRandomness rhoPrime12 = new GjosteenElGamalRandomness(0, q);
        final GjosteenElGamalRandomness rhoPrime21 = new GjosteenElGamalRandomness(0, q);
        final GjosteenElGamalRandomness rhoPrime22 = new GjosteenElGamalRandomness(0, q);

        final GjosteenElGamalRandomness[] rhoPrime = {rhoPrime11, rhoPrime12, rhoPrime21, rhoPrime22};

        final Ciphertext C11 = elgamal.encrypt(elements2, rhoPrime11);
        final Ciphertext C12 = elgamal.encrypt(elements2, rhoPrime12);
        final Ciphertext C21 = elgamal.encrypt(elements3, rhoPrime21);
        final Ciphertext C22 = elgamal.encrypt(elements9, rhoPrime22);

        final GjosteenElGamalRandomness rho11 = new GjosteenElGamalRandomness(0, q);
        final GjosteenElGamalRandomness rho12 = new GjosteenElGamalRandomness(0, q);
        final GjosteenElGamalRandomness rho21 = new GjosteenElGamalRandomness(0, q);
        final GjosteenElGamalRandomness rho22 = new GjosteenElGamalRandomness(0, q);

	and then the third element (C21) is copied over the second (C12).


***********
The test in proof-2-zero/ is run with the following inputs:

private static boolean CHEATING = false;
private static boolean CHEATING2 = true;

BigInteger p = new BigInteger("15294034768093677312256663166625633354362303");
        q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2));
        BigInteger g = new BigInteger("2");

ZpGroupElement[] publicKeyArray = new ZpGroupElement[1];
        publicKeyArray[0] = new ZpGroupElement(new BigInteger("5943523178887533241241798626972220822590095"), zp.getP(), zp.getQ());
        ElGamalPublicKey publicKey = new ElGamalPublicKey(Arrays.asList(publicKeyArray), zp);

        final GjosteenElGamal elgamal = new GjosteenElGamal(zp, publicKey);

        ZpGroupElement[] elements3 = getAsGroupElementArray(3, zp);
        ZpGroupElement[] elements2 = getAsGroupElementArray(2, zp);
        ZpGroupElement[] elements7 = getAsGroupElementArray(7, zp);

        final GjosteenElGamalRandomness rhoPrime11 = new GjosteenElGamalRandomness(0, q);
        final GjosteenElGamalRandomness rhoPrime12 = new GjosteenElGamalRandomness(0, q);
        final GjosteenElGamalRandomness rhoPrime21 = new GjosteenElGamalRandomness(0, q);
        final GjosteenElGamalRandomness rhoPrime22 = new GjosteenElGamalRandomness(0, q);

        final GjosteenElGamalRandomness[] rhoPrime = {rhoPrime11, rhoPrime12, rhoPrime21, rhoPrime22};

        final Ciphertext C11 = elgamal.encrypt(elements3, rhoPrime11);
        final Ciphertext C12 = elgamal.encrypt(elements3, rhoPrime12);
        final Ciphertext C21 = elgamal.encrypt(elements7, rhoPrime21);
        final Ciphertext C22 = elgamal.encrypt(elements7, rhoPrime22);

        final GjosteenElGamalRandomness rho11 = new GjosteenElGamalRandomness(0, q);
        final GjosteenElGamalRandomness rho12 = new GjosteenElGamalRandomness(0, q);
        final GjosteenElGamalRandomness rho21 = new GjosteenElGamalRandomness(0, q);
        final GjosteenElGamalRandomness rho22 = new GjosteenElGamalRandomness(0, q);

        final GjosteenElGamalRandomness[] rho = {rho11, rho12, rho21, rho22};
        final Ciphertext[][] vecC = {{C11, C12 }, {C21, C22 }};

        Ciphertext[][] ciphertexts = {
            {C11.multiply(elgamal.encrypt(elements2, rho11)),
                            C12.multiply(elgamal.encrypt(elements2, rho12))},
                    {C21.multiply(elgamal.encrypt(elements2, rho21)),
                            C22.multiply(elgamal.encrypt(elements2, rho22))}
            };
        
***********

The test in proof-2/ is run with the following inputs:

private static boolean CHEATING = false;
private static boolean CHEATING2 = true;

  ZpGroupElement[] publicKeyArray = new ZpGroupElement[1];
        publicKeyArray[0] = new ZpGroupElement(new BigInteger("5943523178887533241241798626972220822590095"), zp.getP(), zp.getQ());
        ElGamalPublicKey publicKey = new ElGamalPublicKey(Arrays.asList(publicKeyArray), zp);

        final GjosteenElGamal elgamal = new GjosteenElGamal(zp, publicKey);

        ZpGroupElement[] elements3 = getAsGroupElementArray(3, zp);
        ZpGroupElement[] elements2 = getAsGroupElementArray(2, zp);
        ZpGroupElement[] elements7 = getAsGroupElementArray(7, zp);

        final GjosteenElGamalRandomness rhoPrime11 = new GjosteenElGamalRandomness(234522456, q);
        final GjosteenElGamalRandomness rhoPrime12 = new GjosteenElGamalRandomness(788749345, q);
        final GjosteenElGamalRandomness rhoPrime21 = new GjosteenElGamalRandomness(543783459, q);
        final GjosteenElGamalRandomness rhoPrime22 = new GjosteenElGamalRandomness(741325490, q);

        final GjosteenElGamalRandomness[] rhoPrime = {rhoPrime11, rhoPrime12, rhoPrime21, rhoPrime22};

        final Ciphertext C11 = elgamal.encrypt(elements3, rhoPrime11);
        final Ciphertext C12 = elgamal.encrypt(elements3, rhoPrime12);
        final Ciphertext C21 = elgamal.encrypt(elements7, rhoPrime21);
        final Ciphertext C22 = elgamal.encrypt(elements7, rhoPrime22);

        final GjosteenElGamalRandomness rho11 = new GjosteenElGamalRandomness(345167524, q);
        final GjosteenElGamalRandomness rho12 = new GjosteenElGamalRandomness(435732453, q);
        final GjosteenElGamalRandomness rho21 = new GjosteenElGamalRandomness(892468901, q);
        final GjosteenElGamalRandomness rho22 = new GjosteenElGamalRandomness(252437823, q);

        final GjosteenElGamalRandomness[] rho = {rho11, rho12, rho21, rho22};
        final Ciphertext[][] vecC = {{C11, C12 }, {C21, C22 }};

        Ciphertext[][] ciphertexts = {
            {C11.multiply(elgamal.encrypt(elements2, rho11)),
                            C12.multiply(elgamal.encrypt(elements2, rho12))},
                    {C21.multiply(elgamal.encrypt(elements2, rho21)),
                            C22.multiply(elgamal.encrypt(elements2, rho22))}