Add Break in OR Proof Demonstration
This commit is contained in:
parent
fdcc205cfa
commit
60b8a0173c
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* Copyright 2018 Scytl Secure Electronic Voting SA
|
||||
*
|
||||
* All rights reserved
|
||||
*
|
||||
* See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
|
||||
*/
|
||||
package com.scytl.cryptolib.proofs.maurer.factory;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
|
||||
import com.scytl.cryptolib.elgamal.bean.CiphertextImpl;
|
||||
import com.scytl.cryptolib.elgamal.bean.ElGamalPublicKey;
|
||||
import com.scytl.cryptolib.elgamal.bean.WitnessImpl;
|
||||
import com.scytl.cryptolib.elgamal.cryptoapi.Ciphertext;
|
||||
import com.scytl.cryptolib.elgamal.cryptoapi.Witness;
|
||||
import com.scytl.cryptolib.mathematical.groups.impl.Exponent;
|
||||
import com.scytl.cryptolib.mathematical.groups.impl.ZpGroupElement;
|
||||
import com.scytl.cryptolib.mathematical.groups.impl.ZpSubgroup;
|
||||
import com.scytl.cryptolib.mathematical.groups.utils.MathematicalTestDataGenerator;
|
||||
import com.scytl.cryptolib.primitives.messagedigest.configuration.ConfigMessageDigestAlgorithmAndProvider;
|
||||
import com.scytl.cryptolib.primitives.service.PrimitivesService;
|
||||
import com.scytl.cryptolib.proofs.bean.ProofPreComputedValues;
|
||||
import com.scytl.cryptolib.proofs.maurer.configuration.ConfigProofHashCharset;
|
||||
import com.scytl.cryptolib.proofs.proof.Proof;
|
||||
import com.scytl.cryptolib.securerandom.cryptoapi.CryptoAPIRandomInteger;
|
||||
|
||||
/**
|
||||
* Tests of {@link ORProofVerifier}.
|
||||
*/
|
||||
public class ORProofVerifierTest {
|
||||
private static final String DATA = "data";
|
||||
|
||||
private static final int INDEX = 1;
|
||||
|
||||
private ZpSubgroup group;
|
||||
|
||||
private ElGamalPublicKey publicKey;
|
||||
|
||||
private List<ZpGroupElement> elements;
|
||||
|
||||
private Ciphertext ciphertext;
|
||||
|
||||
private Witness witness;
|
||||
|
||||
private Proof proof;
|
||||
|
||||
@Before
|
||||
public void setUp() throws GeneralCryptoLibException {
|
||||
group = MathematicalTestDataGenerator.getZpSubgroup();
|
||||
|
||||
Exponent privateKey =
|
||||
new Exponent(group.getQ(), BigInteger.valueOf(2));
|
||||
List<ZpGroupElement> keys =
|
||||
singletonList(group.getGenerator().exponentiate(privateKey));
|
||||
publicKey = new ElGamalPublicKey(keys, group);
|
||||
|
||||
elements = asList( group.getGenerator().multiply(group.getGenerator()),
|
||||
group.getGenerator().multiply(group.getGenerator()).multiply(group.getGenerator()),
|
||||
group.getGenerator().multiply(group.getGenerator())
|
||||
.multiply(group.getGenerator()).multiply(group.getGenerator()));
|
||||
|
||||
Exponent a = new Exponent(group.getQ(), BigInteger.valueOf(3));
|
||||
|
||||
|
||||
// Y * GGG
|
||||
ciphertext = new CiphertextImpl(
|
||||
group.getGenerator().exponentiate(a), publicKey.getKeys()
|
||||
.get(0).exponentiate(a).multiply(elements.get(INDEX)));
|
||||
|
||||
witness = new WitnessImpl(a);
|
||||
|
||||
CryptoAPIRandomInteger random =
|
||||
new PrimitivesService().getCryptoRandomInteger();
|
||||
|
||||
ORProofPreComputer preComputer =
|
||||
new ORProofPreComputer(publicKey, elements.size());
|
||||
|
||||
ProofPreComputedValues preComputedValues =
|
||||
preComputer.preCompute(random);
|
||||
|
||||
ORProofGenerator generator = new ORProofGenerator(ciphertext,
|
||||
publicKey, witness, INDEX, elements, DATA, random,
|
||||
ConfigMessageDigestAlgorithmAndProvider.SHA256_SUN,
|
||||
ConfigProofHashCharset.UTF8, preComputedValues);
|
||||
|
||||
proof = generator.generate();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVerifyCorrect() throws GeneralCryptoLibException {
|
||||
ORProofVerifier verifier = new ORProofVerifier(ciphertext,
|
||||
publicKey, elements, DATA, proof, group,
|
||||
ConfigMessageDigestAlgorithmAndProvider.SHA256_SUN,
|
||||
ConfigProofHashCharset.UTF8);
|
||||
assertTrue(verifier.verify());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVerifyIncorrectData()
|
||||
throws GeneralCryptoLibException {
|
||||
ORProofVerifier verifier = new ORProofVerifier(ciphertext,
|
||||
publicKey, elements, DATA + "something else", proof, group,
|
||||
ConfigMessageDigestAlgorithmAndProvider.SHA256_SUN,
|
||||
ConfigProofHashCharset.UTF8);
|
||||
assertFalse(verifier.verify());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVerifyIncorrectElement()
|
||||
throws GeneralCryptoLibException {
|
||||
Exponent a = new Exponent(group.getQ(), BigInteger.valueOf(3));
|
||||
|
||||
ciphertext = new CiphertextImpl(
|
||||
group.getGenerator().exponentiate(a), publicKey.getKeys()
|
||||
.get(0).exponentiate(a).multiply(elements.get(INDEX+1)));
|
||||
|
||||
ORProofVerifier verifier = new ORProofVerifier(ciphertext,
|
||||
publicKey, elements, DATA, proof, group,
|
||||
ConfigMessageDigestAlgorithmAndProvider.SHA256_SUN,
|
||||
ConfigProofHashCharset.UTF8);
|
||||
assertFalse(verifier.verify());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testBreakingTheProof()
|
||||
throws GeneralCryptoLibException {
|
||||
|
||||
// Create a bad ciphertext
|
||||
Exponent a = new Exponent(group.getQ(), BigInteger.valueOf(3));
|
||||
// We set out element to the Identity.
|
||||
ZpGroupElement hacked = group.getIdentity();
|
||||
|
||||
// Create a ciphertext using the public key and our random exponent a
|
||||
Ciphertext not_a_good_ciphertext = new CiphertextImpl(
|
||||
hacked.exponentiate(a), publicKey.getKeys()
|
||||
.get(0).exponentiate(a).multiply(hacked));
|
||||
|
||||
|
||||
// Next 3 lines are the same as in the test setup, we just need them for constructing the
|
||||
// proof generator
|
||||
CryptoAPIRandomInteger random =
|
||||
new PrimitivesService().getCryptoRandomInteger();
|
||||
ORProofPreComputer preComputer =
|
||||
new ORProofPreComputer(publicKey, elements.size());
|
||||
ProofPreComputedValues preComputedValues =
|
||||
preComputer.preCompute(random);
|
||||
|
||||
// Make the Bad Proof
|
||||
// Setting the Index to -1
|
||||
// this causes the proof code to generate random exponents for every entry
|
||||
ORProofGenerator generator = new ORProofGenerator(not_a_good_ciphertext,
|
||||
publicKey, witness, -1, elements, DATA, random,
|
||||
ConfigMessageDigestAlgorithmAndProvider.SHA256_SUN,
|
||||
ConfigProofHashCharset.UTF8, preComputedValues);
|
||||
|
||||
// This uses generate2, which was already defined, I just removed the "correctExponents(hash, exponents);" line
|
||||
// All of the exponents are therefore random.
|
||||
// (Not that if the verifier was not broken, removing correctExponents should alone cause this to fail)
|
||||
Proof proof2 = generator.generate2();
|
||||
|
||||
// Verifier passes with the ciphertext that does not encode one of the elements.
|
||||
ORProofVerifier verifier = new ORProofVerifier(not_a_good_ciphertext,
|
||||
publicKey, elements, DATA, proof2, group,
|
||||
ConfigMessageDigestAlgorithmAndProvider.SHA256_SUN,
|
||||
ConfigProofHashCharset.UTF8);
|
||||
assertTrue(verifier.verify());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue