cheating-proof-transcripts/TrapdoorCommitmentCheatingP.../BgIntegrationTestUpdate.java

161 lines
6.4 KiB
Java

/*
* This file is produced by Sarah Jamie Lewis, Olivier Pereira and Vanessa Teague to demonstrate a trapdoor in
* the SwissVote-Scytl implementation of Bayer-Groth proofs.
*
* It is intended to be applied to our four demonstration proof transcripts, made available along with
* this file. The transcripts pass verification but change the outcome of the election.
*
* March 1st, 2019.
*
*/
package com.scytl.products.ov.mixnet;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import com.scytl.products.ov.mixnet.commons.io.*;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.elgamal.bean.ElGamalPublicKey;
import com.scytl.cryptolib.elgamal.cryptoapi.Ciphertext;
import com.scytl.cryptolib.mathematical.groups.impl.ZpSubgroup;
import com.scytl.products.ov.mixnet.commons.ballots.ElGamalEncryptedBallots;
import com.scytl.products.ov.mixnet.commons.beans.proofs.ShuffleProof;
import com.scytl.products.ov.mixnet.commons.homomorphic.impl.GjosteenElGamal;
import com.scytl.products.ov.mixnet.commons.proofs.bg.commitments.CommitmentParams;
import com.scytl.products.ov.mixnet.commons.tools.CiphertextTools;
import com.scytl.products.ov.mixnet.commons.tools.MatrixArranger;
import com.scytl.products.ov.mixnet.commons.tools.MultiExponentiation;
import com.scytl.products.ov.mixnet.commons.tools.MultiExponentiationImpl;
import com.scytl.products.ov.mixnet.commons.validation.EncryptedBallotsDuplicationValidator;
import com.scytl.products.ov.mixnet.commons.validation.EncryptedBallotsValidator;
import com.scytl.products.ov.mixnet.commons.validation.EncryptedBallotsValidatorManager;
import com.scytl.products.ov.mixnet.proofs.bg.shuffle.ShuffleProofVerifier;
import static com.scytl.products.ov.mixnet.commons.io.CommitmentParamsReader.readCommitmentParamsFromStream;
public class BaseBGMixnetIOVerifierITest {
private static ZpSubgroup zp;
private static int m;
private static int n;
private static int numiterations;
private static CommitmentParams commitmentParams;
private static GjosteenElGamal elgamal;
private static JSONProofsReader proofsReader;
private static ElGamalEncryptedBallotsLoader elgamalEncryptedBallotsLoader;
private static MultiExponentiation limMultiExpo;
private static CiphertextTools ciphertextTools;
// Comment out as appropriate depending on whether you're running the full test or the zero test
private static boolean CHEATING2 = true;
private static String zeroFlag = "";
//private static String zeroFlag = "-zero";
static String twoFlag = CHEATING2 ? "-2" : "";
private static String proofsPath="/tmp/SwissVoteTest/proofs"+twoFlag+zeroFlag+"/";
@BeforeClass
public static void setUp() throws IOException, GeneralCryptoLibException {
BigInteger p = new BigInteger("15294034768093677312256663166625633354362303");
BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2));
BigInteger g = new BigInteger("2");
zp = new ZpSubgroup(g, p, q);
ElGamalPublicKey pubKey = ElgamalPublicKeyReader.readPublicKeyFromStream(new FileInputStream(proofsPath+"publicKey"+twoFlag+zeroFlag+".out"));
elgamal = new GjosteenElGamal(zp,pubKey);
m = 2;
n = 2;
proofsReader = new JSONProofsReader();
final List<EncryptedBallotsValidator> listValidators = new ArrayList<>();
listValidators.add(new EncryptedBallotsDuplicationValidator());
EncryptedBallotsValidatorManager validator = new EncryptedBallotsValidatorManager(listValidators);
elgamalEncryptedBallotsLoader = new ElGamalEncryptedBallotsLoader(validator);
limMultiExpo = MultiExponentiationImpl.getInstance();
ciphertextTools = new CiphertextTools(limMultiExpo);
}
private static CommitmentParams readCommitmentParamsFromFile() throws IOException {
final Path pathCommitmentParamsFile =
Paths.get(proofsPath+"commitmentParams"+twoFlag+zeroFlag+".out");
FileInputStream fis = new FileInputStream(pathCommitmentParamsFile.toFile());
return readCommitmentParamsFromStream(zp, fis);
}
@Test
public void givenSmallConfigWhenShuffleThenOK()
throws IOException, GeneralCryptoLibException {
// /////////////////////////////////////////////////
//
// Verify the proofs
//
// /////////////////////////////////////////////////
final ElGamalEncryptedBallots encryptedBallots_VerifierCopy =
elgamalEncryptedBallotsLoader.loadCSV(zp, new FileInputStream(proofsPath+"input"+twoFlag+zeroFlag+".csv"));
final Ciphertext[][] originalCiphertexts_VerifierCopy =
MatrixArranger.arrangeInCiphertextMatrix(encryptedBallots_VerifierCopy, m, n);
final ElGamalEncryptedBallots reencryptedBallots;
reencryptedBallots = elgamalEncryptedBallotsLoader.loadCSV(zp, new FileInputStream(
Paths.get(proofsPath+"output"+twoFlag+zeroFlag+".csv").toFile()));
final Ciphertext[][] reencryptedCiphertexts_VerifierCopy =
MatrixArranger.arrangeInCiphertextMatrix(reencryptedBallots, m, n);
commitmentParams = readCommitmentParamsFromFile();
System.out.println(commitmentParams.getG()[0]);
final ShuffleProofVerifier verifier = new ShuffleProofVerifier(zp, elgamal, commitmentParams,
originalCiphertexts_VerifierCopy, reencryptedCiphertexts_VerifierCopy, m, n, 0, numiterations,
ciphertextTools, limMultiExpo);
final ShuffleProof shuffleProof_VerifierCopy = proofsReader.read(
new FileInputStream(Paths.get(proofsPath+"complete-proof"+twoFlag+zeroFlag+".json").toFile()));
System.out.println("Shuffle Proof: "+ shuffleProof_VerifierCopy.getSecondAnswer().toString());
final boolean testResult = verifier.verifyProof(shuffleProof_VerifierCopy.getInitialMessage(),
shuffleProof_VerifierCopy.getFirstAnswer(), shuffleProof_VerifierCopy.getSecondAnswer());
final String errorMsg = "proofs failed to validate";
Assert.assertTrue(errorMsg, testResult);
}
}