diff --git a/mixer/src/main/java/verifier/Verifier.java b/mixer/src/main/java/verifier/Verifier.java index 19549ce..c8c9914 100644 --- a/mixer/src/main/java/verifier/Verifier.java +++ b/mixer/src/main/java/verifier/Verifier.java @@ -13,6 +13,7 @@ import qilin.primitives.RandomOracle; import qilin.primitives.concrete.ECGroup; import java.math.BigInteger; +import java.util.ArrayList; import java.util.List; @@ -95,14 +96,16 @@ public class Verifier implements Mix2ZeroKnowledgeVerifier { return verifyElGamaOrProof(e1ElGamal,e2ElGamal,e1TagElGamal,e2TagElGamal,orProof,orProofOrder); } - public boolean verifyElGamaOrProof(ElGamalCiphertext e1, - ElGamalCiphertext e2, - ElGamalCiphertext e1New, - ElGamalCiphertext e2New, - Mixing.ZeroKnowledgeProof.OrProof orProof, ProofOrganizer.OrProofOrder orProofOrder) - { - Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle forRandomOracle = + + private ECPoint g1,g2,h1,h2; + private ECPoint g1Tag,g2Tag,h1Tag,h2Tag; + private ECPoint u,v,uTag,vTag; + private BigInteger c1,c2,z,zTag; + private Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle forRandomOracle; + + private void parseOrProof(Mixing.ZeroKnowledgeProof.OrProof orProof){ + forRandomOracle = Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle.newBuilder() .setG1(orProof.getG1()) .setH1(orProof.getH1()) @@ -117,9 +120,6 @@ public class Verifier implements Mix2ZeroKnowledgeVerifier { .setUTag(orProof.getUTag()) .setVTag(orProof.getVTag()) .build(); - - ECPoint g1,g2,h1,h2; - ECPoint g1Tag,g2Tag,h1Tag,h2Tag; g1 = convert2ECPoint(orProof.getG1()); g2 = convert2ECPoint(orProof.getG2()); h1 = convert2ECPoint(orProof.getH1()); @@ -128,97 +128,83 @@ public class Verifier implements Mix2ZeroKnowledgeVerifier { g2Tag = convert2ECPoint(orProof.getG2Tag()); h1Tag = convert2ECPoint(orProof.getH1Tag()); h2Tag = convert2ECPoint(orProof.getH2Tag()); - - ECPoint u,v,uTag,vTag; u = convert2ECPoint(orProof.getU()); v = convert2ECPoint(orProof.getV()); uTag = convert2ECPoint(orProof.getUTag()); vTag = convert2ECPoint(orProof.getVTag()); - - BigInteger c1,c2,z,zTag; c1 = new BigInteger(orProof.getC1().toByteArray()); c2 = new BigInteger(orProof.getC2().toByteArray()); z = new BigInteger(orProof.getZ().toByteArray()); zTag = new BigInteger(orProof.getZTag().toByteArray()); + } - ECPoint[] given = new ECPoint[12]; - ECPoint[] expected = new ECPoint[12]; - String[] description = new String[12]; - int i = 0; - given[i++] = g1; - given[i++] = h1; - given[i++] = g2; - given[i++] = h2; - given[i++] = g1Tag; - given[i++] = h1Tag; - given[i++] = g2Tag; - given[i++] = h2Tag; - given[i++] = group.multiply(g1, z); - given[i++] = group.multiply(g2, z); - given[i++] = group.multiply(g1Tag, zTag); - given[i] = group.multiply(g2Tag, zTag); - i = 0; - expected[i++] = g; - expected[i++] = group.add(convert2ECPoint(e1New.getC1()), group.negate(convert2ECPoint(e1.getC1()))); - expected[i++] = h; - expected[i++] = group.add(convert2ECPoint(e1New.getC2()), group.negate(convert2ECPoint(e1.getC2()))); - expected[i++] = g; - expected[i++] = group.add(convert2ECPoint(e2New.getC1()), group.negate(convert2ECPoint(e2.getC1()))); - expected[i++] = h; - expected[i++] = group.add(convert2ECPoint(e2New.getC2()), group.negate(convert2ECPoint(e2.getC2()))); - expected[i++] = group.add(u, group.multiply(h1,c1)); - expected[i++] = group.add(v, group.multiply(h2,c1)); - expected[i++] = group.add(uTag, group.multiply(h1Tag,c2)); - expected[i] = group.add(vTag, group.multiply(h2Tag,c2)); - i = 0; - description[i++] = "g1 != g"; - description[i++] = "h1 != e1New.c1/e1.c1"; - description[i++] = "g2 != h"; - description[i++] = "h2 != e1New.c2/e1.c2"; - description[i++] = "g1Tag != g"; - description[i++] = "h1Tag != e2New.c1/e2.c1"; - description[i++] = "g2Tag != h"; - description[i++] = "h2Tag != e2New.c2/e2.c2"; - description[i++] = "g1 ^ z != u * ( h1 ^ c1 )"; - description[i++] = "g2 ^ z != v * ( h2 ^ c1 )"; - description[i++] = "g1Tag ^ zTag != uTag * ( h1Tag ^ c2 )"; - description[i] = "g2Tag ^ zTag != vTag * ( h2Tag ^ c2 )"; - boolean first = true; - for (int j = 0; j < given.length ; j++){ - if(!given[j].equals(expected[j])){ - if (first){ - first = false; + private List createConditionsList(ElGamalCiphertext e1, + ElGamalCiphertext e2, + ElGamalCiphertext e1New, + ElGamalCiphertext e2New){ + List conditions = new ArrayList(); + conditions.add(new Condition( g1,g,"g1 != g")); + conditions.add(new Condition( h1,group.add(convert2ECPoint(e1New.getC1()), + group.negate(convert2ECPoint(e1.getC1()))),"h1 != e1New.c1/e1.c1")); + conditions.add(new Condition( g2,h,"g2 != h")); + conditions.add(new Condition( h2,group.add(convert2ECPoint(e1New.getC2()), + group.negate(convert2ECPoint(e1.getC2()))),"h2 != e1New.c2/e1.c2")); + conditions.add(new Condition( g1Tag,g,"g1Tag != g")); + conditions.add(new Condition( h1Tag,group.add(convert2ECPoint(e2New.getC1()), + group.negate(convert2ECPoint(e2.getC1()))),"h1Tag != e2New.c1/e2.c1")); + conditions.add(new Condition( g2Tag,h,"g2Tag != h")); + conditions.add(new Condition( h2Tag,group.add(convert2ECPoint(e2New.getC2()), + group.negate(convert2ECPoint(e2.getC2()))),"h2Tag != e2New.c2/e2.c2")); + conditions.add(new Condition(c1.add(c2).mod(group.orderUpperBound()), + hash(forRandomOracle).mod(group.orderUpperBound()).mod(group.orderUpperBound()), + "(c1 + c2 ) % group size == hash (imput + step1) % group size")); + conditions.add(new Condition( group.multiply(g1, z), + group.add(u, group.multiply(h1,c1)),"g1 ^ z != u * ( h1 ^ c1 )")); + conditions.add(new Condition( group.multiply(g2, z), + group.add(v, group.multiply(h2,c1)),"g2 ^ z != v * ( h2 ^ c1 )")); + conditions.add(new Condition( group.multiply(g1Tag, zTag), + group.add(uTag, group.multiply(h1Tag,c2)),"g1Tag ^ zTag != uTag * ( h1Tag ^ c2 )")); + conditions.add(new Condition( group.multiply(g2Tag, zTag), + group.add(vTag, group.multiply(h2Tag,c2)),"g2Tag ^ zTag != vTag * ( h2Tag ^ c2 )")); + return conditions; + } + + public boolean verifyElGamaOrProof(ElGamalCiphertext e1, + ElGamalCiphertext e2, + ElGamalCiphertext e1New, + ElGamalCiphertext e2New, + Mixing.ZeroKnowledgeProof.OrProof orProof, ProofOrganizer.OrProofOrder orProofOrder) + { + parseOrProof(orProof); + List conditions = createConditionsList(e1,e2,e1New,e2New); + + boolean result = true; + for (Condition condition: conditions) { + if(!condition.test()){ + if (result){ + result = false; System.out.print("\n\n\n"); System.out.println(orProofOrder.toString()); } - System.out.println(description[j]); + System.out.println(condition.errorDescripton); } } + return result; + } - return //input - g1.equals(g)&& - h1.equals(group.add(convert2ECPoint(e1New.getC1()) - , group.negate(convert2ECPoint(e1.getC1()))))&& - g2.equals(h)&& - h2.equals(group.add(convert2ECPoint(e1New.getC2()) - , group.negate(convert2ECPoint(e1.getC2()))))&& - // input' - g1Tag.equals(g)&& - h1Tag.equals(group.add(convert2ECPoint(e2New.getC1()) - , group.negate(convert2ECPoint(e2.getC1()))))&& - g2Tag.equals(h)&& - h2Tag.equals(group.add(convert2ECPoint(e2New.getC2()) - , group.negate(convert2ECPoint(e2.getC2())))) && - // hash - // assert (c1 + c2 ) % group size == hash (imput + step1) % group size - new BigInteger(orProof.getC1().toByteArray()).add(new BigInteger(orProof.getC2().toByteArray())).mod(group.orderUpperBound()) - .equals(hash(forRandomOracle).mod(group.orderUpperBound()).mod(group.orderUpperBound()))&& - // proof - // g1 ^ z == u * ( h1 ^ c1 ) && g2 ^ z == v * ( h2 ^ c1 ) && the same for tag case - group.multiply(g1, z).equals(group.add(u, group.multiply(h1,c1))) && - group.multiply(g2, z).equals(group.add(v, group.multiply(h2,c1))) && - group.multiply(g1Tag, zTag).equals(group.add(uTag, group.multiply(h1Tag,c2))) && - group.multiply(g2Tag, zTag).equals(group.add(vTag, group.multiply(h2Tag,c2))); + private class Condition{ + T given, expected; + String errorDescripton; + + Condition(T given,T expected,String descripton){ + this.given = given; + this.errorDescripton = descripton; + this.expected = expected; + } + + boolean test(){ + return given.equals(expected); + } } } diff --git a/mixer/src/test/java/mixer/MixNetworkTest.java b/mixer/src/test/java/mixer/MixNetworkTest.java index 4652460..d5faed5 100644 --- a/mixer/src/test/java/mixer/MixNetworkTest.java +++ b/mixer/src/test/java/mixer/MixNetworkTest.java @@ -5,7 +5,6 @@ package mixer; */ import org.junit.Test; - import java.util.Arrays; import java.util.Random; @@ -16,7 +15,6 @@ public class MixNetworkTest { Random random = new Random(); int logn = 10; - int n = 1 << logn; int layers = 2*logn - 1; RandomPermutation randomPermutation = new RandomPermutation(n,random); diff --git a/mixer/src/test/java/mixer/MixingText.java b/mixer/src/test/java/mixer/MixingText.java index c5f8f33..a4b9c81 100644 --- a/mixer/src/test/java/mixer/MixingText.java +++ b/mixer/src/test/java/mixer/MixingText.java @@ -3,33 +3,24 @@ package mixer; /** * Created by Tzlil on 12/30/2015. */ -import com.google.protobuf.ByteString; + import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Message; import meerkat.crypto.concrete.ECElGamalEncryption; -import meerkat.crypto.concrete.GlobalCryptoSetup; import meerkat.crypto.mixnet.Mix2ZeroKnowledgeProver; import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier; -import meerkat.protobuf.ConcreteCrypto; import meerkat.protobuf.Crypto; import meerkat.protobuf.Mixing; -import org.bouncycastle.jce.spec.ECParameterSpec; -import org.bouncycastle.jce.spec.ECPublicKeySpec; -import org.bouncycastle.math.ec.ECPoint; +import meerkat.protobuf.Voting; +import org.junit.Before; import org.junit.Test; import prover.Prover; import qilin.primitives.RandomOracle; import qilin.primitives.concrete.DigestOracle; import qilin.primitives.concrete.ECElGamal; import qilin.primitives.concrete.ECGroup; -import qilin.primitives.generic.ElGamal; import qilin.util.Pair; import verifier.Verifier; import verifier.VerifyTable; - -import java.math.BigInteger; -import java.security.KeyFactory; -import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.util.ArrayList; import java.util.List; @@ -39,74 +30,48 @@ public class MixingText { ECElGamalEncryption encryptor; ECGroup group; - Random random ; - private BigInteger sk; - private ECElGamal.SK key; - private ConcreteCrypto.ElGamalPublicKey serializedPk; + Random random,randomMixer,randomProver; + RandomOracle randomOracle; + Mix2ZeroKnowledgeVerifier verifier; + Mix2ZeroKnowledgeProver prover; + meerkat.crypto.mixnet.Mixer mixer; + private int layers; + private int n; - public final static String ENCRYPTION_KEY_ALGORITHM = "ECDH"; - /** - * Serialize an El-Gamal public key into a form acceptable by {@link ECElGamalEncryption} - * @param pk - * @return - */ - public static ConcreteCrypto.ElGamalPublicKey serializePk(ECGroup group, ElGamal.PK pk) { - ECPoint pkPoint = pk.getPK(); - ECParameterSpec params = group.getCurveParams(); - ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(pkPoint, params); - - try { - KeyFactory fact = KeyFactory.getInstance(ENCRYPTION_KEY_ALGORITHM, - GlobalCryptoSetup.getBouncyCastleProvider()); - PublicKey javaPk = fact.generatePublic(pubKeySpec); - ConcreteCrypto.ElGamalPublicKey serializedPk = ConcreteCrypto.ElGamalPublicKey.newBuilder() - .setSubjectPublicKeyInfo(ByteString.copyFrom(javaPk.getEncoded())).build(); - - return serializedPk; - } catch (Exception e) { - throw new RuntimeException("Error converting public key!", e); - } - } - - public void mixingTest() throws InvalidProtocolBufferException, InvalidKeySpecException { + @Before + public void setup() throws InvalidKeySpecException { // initialization random = new Random(); group = new ECGroup("secp256k1"); - sk = ECElGamal.generateSecretKey(group, random); - key = new ECElGamal.SK(group, sk); - serializedPk = serializePk(group, key); encryptor = new ECElGamalEncryption(); - encryptor.init(serializedPk); - - - Random randomMixer = new Random(); - Random randomProver = new Random(); - RandomOracle randomOracle = new DigestOracle(); - - Mix2ZeroKnowledgeVerifier verifier = new Verifier(encryptor,randomOracle); - Mix2ZeroKnowledgeProver prover = new Prover(randomProver,encryptor,randomOracle,verifier); - meerkat.crypto.mixnet.Mixer mixer = new Mixer(randomMixer,prover,encryptor); - ECGroup group = encryptor.getGroup(); - + encryptor.init(Utiles.serializePk(group, new ECElGamal.SK(group, ECElGamal.generateSecretKey(group, random)))); + randomMixer = new Random(); + randomProver = new Random(); + randomOracle = new DigestOracle(); + verifier = new Verifier(encryptor,randomOracle); + prover = new Prover(randomProver,encryptor,randomOracle,verifier); + mixer = new Mixer(randomMixer,prover,encryptor); // generate n - int logN = 7; // + random.nextInt(8) - int layers = 2*logN - 1; - int n = 1 << logN; + int logN = 8; // + random.nextInt(8) + layers = 2*logN - 1; + n = 1 << logN; + } - // generate MixerInput - List mixerInput = new ArrayList(); - Message message; + public List generateMixerInput(){ + List result = new ArrayList(); + Voting.PlaintextBallot msg; for (int i = 0; i < n ; i++){ - message = Mixing.Plaintext.newBuilder() - .setData(ByteString.copyFrom(group.encode(group.sample(random)))) - .build(); - mixerInput.add(encryptor.encrypt(message, encryptor.generateRandomness(random))); + msg = Utiles.genRandomBallot(2,3,16); + result.add(encryptor.encrypt(msg, encryptor.generateRandomness(random))); } + return result; + } - Pair mixerOutput = mixer.mix(mixerInput); - -// assert (VerifyTable.verifyTable(verifier,n,mixerOutput)); + @Test + public void mixingTest() throws InvalidProtocolBufferException { + Pair mixerOutput = mixer.mix(generateMixerInput()); + assert (VerifyTable.verifyTable(verifier,n,mixerOutput)); } } diff --git a/mixer/src/test/java/mixer/Utiles.java b/mixer/src/test/java/mixer/Utiles.java new file mode 100644 index 0000000..2be2a1c --- /dev/null +++ b/mixer/src/test/java/mixer/Utiles.java @@ -0,0 +1,102 @@ +package mixer; + +import com.google.protobuf.ByteString; +import com.google.protobuf.GeneratedMessage; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; +import meerkat.crypto.concrete.ECElGamalEncryption; +import meerkat.crypto.concrete.GlobalCryptoSetup; +import meerkat.protobuf.ConcreteCrypto; +import meerkat.protobuf.Crypto; +import meerkat.protobuf.Voting; +import org.bouncycastle.jce.spec.ECParameterSpec; +import org.bouncycastle.jce.spec.ECPublicKeySpec; +import org.bouncycastle.math.ec.ECPoint; +import qilin.primitives.concrete.ECElGamal; +import qilin.primitives.concrete.ECGroup; +import qilin.primitives.generic.ElGamal; +import qilin.util.Pair; + +import java.io.ByteArrayInputStream; +import java.security.KeyFactory; +import java.security.PublicKey; +import java.util.Random; + +/** + * Created by Tzlil on 1/1/2016. + */ +public class Utiles { + + + public final static String ENCRYPTION_KEY_ALGORITHM = "ECDH"; + /** + * Serialize an El-Gamal public key into a form acceptable by {@link ECElGamalEncryption} + * @param pk + * @return + */ + public static ConcreteCrypto.ElGamalPublicKey serializePk(ECGroup group, ElGamal.PK pk) { + ECPoint pkPoint = pk.getPK(); + ECParameterSpec params = group.getCurveParams(); + + ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(pkPoint, params); + + try { + KeyFactory fact = KeyFactory.getInstance(ENCRYPTION_KEY_ALGORITHM, + GlobalCryptoSetup.getBouncyCastleProvider()); + PublicKey javaPk = fact.generatePublic(pubKeySpec); + ConcreteCrypto.ElGamalPublicKey serializedPk = ConcreteCrypto.ElGamalPublicKey.newBuilder() + .setSubjectPublicKeyInfo(ByteString.copyFrom(javaPk.getEncoded())).build(); + + return serializedPk; + } catch (Exception e) { + throw new RuntimeException("Error converting public key!", e); + } + } + + /** + * Standard (non-threshold) decryption for testing purposes. + * @param secretKey + * @return + */ + public static T decrypt(Class plaintextMessageType, ECElGamal.SK secretKey, ECGroup group, Crypto.RerandomizableEncryptedMessage opaqueCipher) + throws InvalidProtocolBufferException { + ConcreteCrypto.ElGamalCiphertext cipherText = ConcreteCrypto.ElGamalCiphertext.parseFrom(opaqueCipher.getData()); + ByteString c1encoded = cipherText.getC1(); + ByteString c2encoded = cipherText.getC2(); + + ECPoint c1 = group.decode(c1encoded.toByteArray()); + ECPoint c2 = group.decode(c2encoded.toByteArray()); + + assert (group.contains(c1)); + assert (group.contains(c2)); + + ECPoint plaintextEncoded = secretKey.decrypt(new Pair(c1, c2)); + + byte[] plaintext = group.injectiveDecode(plaintextEncoded); + + ByteArrayInputStream in = new ByteArrayInputStream(plaintext); + + try { + java.lang.reflect.Method newBuilder = plaintextMessageType.getMethod("newBuilder"); + GeneratedMessage.Builder builder = (GeneratedMessage.Builder) newBuilder.invoke(plaintextMessageType); + builder.mergeDelimitedFrom(in); + return plaintextMessageType.cast(builder.build()); + } catch (Exception e) { + throw new InvalidProtocolBufferException("Plaintext protobuf error"); + } + } + + static Random random = new Random(); + + public static Voting.PlaintextBallot genRandomBallot(int numQuestions, int numAnswers, int maxAnswer) { + Voting.PlaintextBallot.Builder ballot = Voting.PlaintextBallot.newBuilder(); + ballot.setSerialNumber(random.nextInt(1000000)); + for (int i = 0; i < numQuestions; ++i) { + Voting.BallotAnswer.Builder answers = ballot.addAnswersBuilder(); + for (int j = 0; j < numAnswers; ++j) { + answers.addAnswer(random.nextInt(maxAnswer)); + } + } + return ballot.build(); + } +} diff --git a/mixer/src/test/java/mixer/ZeroKnowledgeProofTest.java b/mixer/src/test/java/mixer/ZeroKnowledgeProofTest.java index e75ce19..9c50f74 100644 --- a/mixer/src/test/java/mixer/ZeroKnowledgeProofTest.java +++ b/mixer/src/test/java/mixer/ZeroKnowledgeProofTest.java @@ -1,20 +1,12 @@ package mixer; -import com.google.protobuf.ByteString; -import com.google.protobuf.GeneratedMessage; import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Message; import meerkat.crypto.concrete.ECElGamalEncryption; -import meerkat.crypto.concrete.GlobalCryptoSetup; import meerkat.crypto.mixnet.Mix2ZeroKnowledgeProver; import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier; import meerkat.protobuf.ConcreteCrypto; import meerkat.protobuf.Crypto; -import meerkat.protobuf.Mixing; import meerkat.protobuf.Voting; -import org.bouncycastle.jce.spec.ECParameterSpec; -import org.bouncycastle.jce.spec.ECPublicKeySpec; -import org.bouncycastle.math.ec.ECPoint; import org.junit.Before; import org.junit.Test; import prover.Prover; @@ -22,87 +14,16 @@ import qilin.primitives.RandomOracle; import qilin.primitives.concrete.DigestOracle; import qilin.primitives.concrete.ECElGamal; import qilin.primitives.concrete.ECGroup; -import qilin.primitives.generic.ElGamal; -import qilin.util.Pair; import verifier.Verifier; - -import java.io.ByteArrayInputStream; import java.math.BigInteger; -import java.security.KeyFactory; -import java.security.PublicKey; -import java.security.spec.InvalidKeySpecException; -import java.util.Arrays; import java.util.Random; -import static org.junit.Assert.assertEquals; - /** * Created by Tzlil on 12/31/2015. */ public class ZeroKnowledgeProofTest { - - public final static String ENCRYPTION_KEY_ALGORITHM = "ECDH"; - /** - * Serialize an El-Gamal public key into a form acceptable by {@link ECElGamalEncryption} - * @param pk - * @return - */ - public static ConcreteCrypto.ElGamalPublicKey serializePk(ECGroup group, ElGamal.PK pk) { - ECPoint pkPoint = pk.getPK(); - ECParameterSpec params = group.getCurveParams(); - - ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(pkPoint, params); - - try { - KeyFactory fact = KeyFactory.getInstance(ENCRYPTION_KEY_ALGORITHM, - GlobalCryptoSetup.getBouncyCastleProvider()); - PublicKey javaPk = fact.generatePublic(pubKeySpec); - ConcreteCrypto.ElGamalPublicKey serializedPk = ConcreteCrypto.ElGamalPublicKey.newBuilder() - .setSubjectPublicKeyInfo(ByteString.copyFrom(javaPk.getEncoded())).build(); - - return serializedPk; - } catch (Exception e) { - throw new RuntimeException("Error converting public key!", e); - } - } - - /** - * Standard (non-threshold) decryption for testing purposes. - * @param secretKey - * @return - */ - public static T decrypt(Class plaintextMessageType, ECElGamal.SK secretKey, ECGroup group, Crypto.RerandomizableEncryptedMessage opaqueCipher) - throws InvalidProtocolBufferException { - ConcreteCrypto.ElGamalCiphertext cipherText = ConcreteCrypto.ElGamalCiphertext.parseFrom(opaqueCipher.getData()); - ByteString c1encoded = cipherText.getC1(); - ByteString c2encoded = cipherText.getC2(); - - ECPoint c1 = group.decode(c1encoded.toByteArray()); - ECPoint c2 = group.decode(c2encoded.toByteArray()); - - assert (group.contains(c1)); - assert (group.contains(c2)); - - ECPoint plaintextEncoded = secretKey.decrypt(new Pair(c1, c2)); - - byte[] plaintext = group.injectiveDecode(plaintextEncoded); - - ByteArrayInputStream in = new ByteArrayInputStream(plaintext); - - try { - java.lang.reflect.Method newBuilder = plaintextMessageType.getMethod("newBuilder"); - GeneratedMessage.Builder builder = (GeneratedMessage.Builder) newBuilder.invoke(plaintextMessageType); - builder.mergeDelimitedFrom(in); - return plaintextMessageType.cast(builder.build()); - } catch (Exception e) { - throw new InvalidProtocolBufferException("Plaintext protobuf error"); - } - } - - - Random rand = new Random(0); // Insecure deterministic random for testing. - + Random rand; ECElGamal.SK key; ECGroup group; ECElGamalEncryption enc; @@ -112,14 +33,12 @@ public class ZeroKnowledgeProofTest { @Before public void setup() throws Exception { + rand = new Random(); group = new ECGroup("secp256k1"); BigInteger sk = ECElGamal.generateSecretKey(group, rand); key = new ECElGamal.SK(group, sk); - serializedPk = serializePk(group, key); - - + serializedPk = Utiles.serializePk(group, key); enc = new ECElGamalEncryption(); - enc.init(serializedPk); RandomOracle randomOracle = new DigestOracle(); verifier = new Verifier(enc,randomOracle); @@ -127,23 +46,13 @@ public class ZeroKnowledgeProofTest { } - Voting.PlaintextBallot genRandomBallot(int numQuestions, int numAnswers, int maxAnswer) { - Voting.PlaintextBallot.Builder ballot = Voting.PlaintextBallot.newBuilder(); - ballot.setSerialNumber(rand.nextInt(1000000)); - for (int i = 0; i < numQuestions; ++i) { - Voting.BallotAnswer.Builder answers = ballot.addAnswersBuilder(); - for (int j = 0; j < numAnswers; ++j) { - answers.addAnswer(rand.nextInt(maxAnswer)); - } - } - return ballot.build(); - } + public void oneZKPTest() throws InvalidProtocolBufferException { - Voting.PlaintextBallot msg1 = genRandomBallot(2,3,16); // 2 questions with 3 answers each, in range 0-15. - Voting.PlaintextBallot msg2 = genRandomBallot(2,3,16); + Voting.PlaintextBallot msg1 = Utiles.genRandomBallot(2,3,16); // 2 questions with 3 answers each, in range 0-15. + Voting.PlaintextBallot msg2 = Utiles.genRandomBallot(2,3,16); Crypto.EncryptionRandomness r1 = enc.generateRandomness(rand); Crypto.EncryptionRandomness r2 = enc.generateRandomness(rand); @@ -151,10 +60,10 @@ public class ZeroKnowledgeProofTest { Crypto.RerandomizableEncryptedMessage e2 = enc.encrypt(msg2, enc.generateRandomness(rand)); Crypto.RerandomizableEncryptedMessage e1Tag = enc.rerandomize(e1, r1); Crypto.RerandomizableEncryptedMessage e2Tag = enc.rerandomize(e2, r2); - assert (decrypt(Voting.PlaintextBallot.class, key, group, e1).equals(msg1)); - assert (decrypt(Voting.PlaintextBallot.class, key, group, e1Tag).equals(msg1)); - assert (decrypt(Voting.PlaintextBallot.class, key, group, e2).equals(msg2)); - assert (decrypt(Voting.PlaintextBallot.class, key, group, e2Tag).equals(msg2)); + assert (Utiles.decrypt(Voting.PlaintextBallot.class, key, group, e1).equals(msg1)); + assert (Utiles.decrypt(Voting.PlaintextBallot.class, key, group, e1Tag).equals(msg1)); + assert (Utiles.decrypt(Voting.PlaintextBallot.class, key, group, e2).equals(msg2)); + assert (Utiles.decrypt(Voting.PlaintextBallot.class, key, group, e2Tag).equals(msg2)); assert (verifier.verify(e1,e2,e1Tag,e2Tag,prover.prove(e1,e2,e1Tag,e2Tag,false,0,0,0,r1,r2))); }