184 lines
6.9 KiB
Java
184 lines
6.9 KiB
Java
/*
|
|
* 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());
|
|
|
|
}
|
|
|
|
}
|
|
|