diff --git a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mixer.java b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mixer.java index dc2f819..5a0834f 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mixer.java +++ b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mixer.java @@ -11,6 +11,6 @@ import java.util.List; * Created by talm on 25/10/15. */ public interface Mixer { - public Pair - mix(List ciphertexts) throws InvalidProtocolBufferException; + public MixerOutput mix(List ciphertexts) + throws InvalidProtocolBufferException; } diff --git a/meerkat-common/src/main/java/meerkat/crypto/mixnet/MixerOutput.java b/meerkat-common/src/main/java/meerkat/crypto/mixnet/MixerOutput.java new file mode 100644 index 0000000..9ae1432 --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/crypto/mixnet/MixerOutput.java @@ -0,0 +1,13 @@ +package meerkat.crypto.mixnet; + +import meerkat.protobuf.Crypto; +import meerkat.protobuf.Mixing; + +/** + * Created by Tzlil on 1/18/2016. + */ +public interface MixerOutput { + public Mixing.ZeroKnowledgeProof[][] gerProofs(); + public Crypto.RerandomizableEncryptedMessage[][] getEncryptedMessages(); + public int getN(); +} diff --git a/mixer/src/main/java/main/BatchConverter.java b/mixer/src/main/java/main/BatchConverter.java index 0ac2e93..008c868 100644 --- a/mixer/src/main/java/main/BatchConverter.java +++ b/mixer/src/main/java/main/BatchConverter.java @@ -1,6 +1,7 @@ package main; import com.google.protobuf.ByteString; +import meerkat.crypto.mixnet.MixerOutput; import meerkat.protobuf.BulletinBoardAPI; import meerkat.protobuf.Crypto; import meerkat.protobuf.Mixing; @@ -29,8 +30,7 @@ public class BatchConverter { return Integer.valueOf(bs.toString()); } - public List mixerOutput2BatchData - (Pair mixerOutput) { + public List mixerOutput2BatchData(MixerOutput mixerOutput) { List result = new ArrayList(); @@ -38,14 +38,14 @@ public class BatchConverter { .setData(IntegerToByteString(n)) .build()); - for (Mixing.ZeroKnowledgeProof[] zkpLayer : mixerOutput.a) { + for (Mixing.ZeroKnowledgeProof[] zkpLayer : mixerOutput.gerProofs()) { for (Mixing.ZeroKnowledgeProof zkp : zkpLayer) { result.add(BulletinBoardAPI.BatchData.newBuilder() .setData(zkp.toByteString()) .build()); } } - for (Crypto.RerandomizableEncryptedMessage[] encryptionLayer : mixerOutput.b) { + for (Crypto.RerandomizableEncryptedMessage[] encryptionLayer : mixerOutput.getEncryptedMessages()) { for (Crypto.RerandomizableEncryptedMessage encryption : encryptionLayer) { result.add(BulletinBoardAPI.BatchData.newBuilder() .setData(encryption.toByteString()) @@ -55,7 +55,7 @@ public class BatchConverter { return result; } - public Pair batchDataList2MixerOutput + public MixerOutput batchDataList2MixerOutput (List batchDataList) throws Exception { if (n != ByteString2Integer(batchDataList.remove(0).getData())){ @@ -83,7 +83,7 @@ public class BatchConverter { } } - return new Pair(proofs,encryptions); + return new mixer.MixerOutput(n,layers,proofs,encryptions); } diff --git a/mixer/src/main/java/main/BatchHandler.java b/mixer/src/main/java/main/BatchHandler.java index 7e49e6b..d20d369 100644 --- a/mixer/src/main/java/main/BatchHandler.java +++ b/mixer/src/main/java/main/BatchHandler.java @@ -1,6 +1,7 @@ package main; import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier; +import meerkat.crypto.mixnet.MixerOutput; import meerkat.protobuf.Crypto; import meerkat.protobuf.Mixing; import necessary.AsyncBulletinBoardClient; @@ -17,7 +18,7 @@ import java.util.List; */ public class BatchHandler implements AsyncBulletinBoardClient.ClientCallback { - private Pair mixerOutput; + private MixerOutput mixerOutput; private boolean msgReceived; private Throwable t; private CompleteBatch msg; @@ -73,7 +74,7 @@ public class BatchHandler implements AsyncBulletinBoardClient.ClientCallback mixerOutput - = mixer.mix(mixerInput); + MixerOutput mixerOutput = mixer.mix(mixerInput); updateBB(mixerOutput, batchId, callback); } - private void updateBB(Pair mixerOutput + private void updateBB(MixerOutput mixerOutput , int batchId, AsyncBulletinBoardClient.ClientCallback callback) { BatchConverter batchConverter = new BatchConverter(n,layers); diff --git a/mixer/src/main/java/mixer/Mixer.java b/mixer/src/main/java/mixer/Mixer.java index 1de3a91..51a7950 100644 --- a/mixer/src/main/java/mixer/Mixer.java +++ b/mixer/src/main/java/mixer/Mixer.java @@ -1,9 +1,13 @@ package mixer; +import java.math.*; +import java.math.BigInteger; import java.util.ArrayList; import java.util.List; import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier; +import meerkat.crypto.mixnet.MixerOutput; +import qilin.primitives.concrete.ECGroup; import qilin.util.Pair; import java.util.Random; @@ -30,8 +34,14 @@ public class Mixer implements meerkat.crypto.mixnet.Mixer { this.verifier = null; } + public Mixer(Random rand, Mix2ZeroKnowledgeProver prov, Encryption enc,Mix2ZeroKnowledgeVerifier verifier) { + this.random = rand; + this.prover = prov; + this.encryptor = enc; + this.verifier = verifier; + } - public Pair mix(List ciphertexts) throws InvalidProtocolBufferException { + public MixerOutput mix(List ciphertexts) throws InvalidProtocolBufferException { int n = ciphertexts.size(); int nDiv2 = n >> 1; @@ -42,7 +52,7 @@ public class Mixer implements meerkat.crypto.mixnet.Mixer { //initialization int layers = (int) (2 * Math.log(n) / Math.log(2)) - 1; // layers = 2logn -1 RerandomizableEncryptedMessage[][] encryptionTable = new RerandomizableEncryptedMessage[layers + 1][n]; - ZeroKnowledgeProof[][] proofsTable = new ZeroKnowledgeProof[layers][nDiv2]; + ZeroKnowledgeProof[][] proofsTable = new ZeroKnowledgeProof[layers][n]; int index1, index2, switchIndex = 0; EncryptionRandomness r1, r2; RerandomizableEncryptedMessage e1, e2; @@ -50,12 +60,14 @@ public class Mixer implements meerkat.crypto.mixnet.Mixer { MixNetwork mixNetwork = new MixNetwork(new RandomPermutation(n,random)); Switch[] switchesLayer; - // set first level of encryption + EncryptionRandomness[][] randomnesses = new EncryptionRandomness[layers][n]; + // set first level of encryption for (int j = 0; j < n; j++) { encryptionTable[0][j] = ciphertexts.get(j); } + BigInteger time = BigInteger.valueOf(System.currentTimeMillis()); // main loop for (int layer = 0; layer < layers; layer++) { @@ -65,25 +77,45 @@ public class Mixer implements meerkat.crypto.mixnet.Mixer { index2 = sw.j; e1 = encryptionTable[layer][index1]; e2 = encryptionTable[layer][index2]; - r1 = encryptor.generateRandomness(random); - r2 = encryptor.generateRandomness(random); - if (!sw.value) { - encryptionTable[layer + 1][index1] = encryptor.rerandomize(e1, r1); - encryptionTable[layer + 1][index2] = encryptor.rerandomize(e2, r2); - } else { - encryptionTable[layer + 1][index1] = encryptor.rerandomize(e2, r2); - encryptionTable[layer + 1][index2] = encryptor.rerandomize(e1, r1); - } - proofsTable[layer][switchIndex] = - prover.prove(e1, e2, encryptionTable[layer + 1][index1], - encryptionTable[layer + 1][index2], - sw.value, sw.i,sw.j,sw.layer, r1, r2); + r1 = encryptor.generateRandomness(random); + r2 = encryptor.generateRandomness(random); + if (!sw.value) { + encryptionTable[layer + 1][index1] = encryptor.rerandomize(e1, r1); + encryptionTable[layer + 1][index2] = encryptor.rerandomize(e2, r2); - switchIndex = (switchIndex + 1) % nDiv2; + } else { + encryptionTable[layer + 1][index1] = encryptor.rerandomize(e2, r2); + encryptionTable[layer + 1][index2] = encryptor.rerandomize(e1, r1); + } + randomnesses[layer][index1] = r1; + randomnesses[layer][index2] = r2; } } - return new Pair(proofsTable, encryptionTable); + System.out.println("re enc time : " + BigInteger.valueOf(System.currentTimeMillis()).subtract(time)); + time = BigInteger.valueOf(System.currentTimeMillis()); + // main loop + for (int layer = 0; layer < layers; layer++) + { + switchesLayer = mixNetwork.getSwitchesByLayer(layer); + for (Switch sw : switchesLayer) { + index1 = sw.i; + index2 = sw.j; + e1 = encryptionTable[layer][index1]; + e2 = encryptionTable[layer][index2]; + r1 = randomnesses[layer][index1]; + r2 = randomnesses[layer][index2]; + + proofsTable[layer][switchIndex] = + prover.prove(e1, e2, encryptionTable[layer + 1][index1], + encryptionTable[layer + 1][index2], + sw.value, sw.i, sw.j, sw.layer, r1, r2); + + switchIndex = (switchIndex + 1) % nDiv2; + } + } + System.out.println("zkp time : " + BigInteger.valueOf(System.currentTimeMillis()).subtract(time)); + return new mixer.MixerOutput(n,layers,proofsTable, encryptionTable); } } \ No newline at end of file diff --git a/mixer/src/main/java/mixer/MixerOutput.java b/mixer/src/main/java/mixer/MixerOutput.java new file mode 100644 index 0000000..38ad3c8 --- /dev/null +++ b/mixer/src/main/java/mixer/MixerOutput.java @@ -0,0 +1,109 @@ +package mixer; + +import meerkat.protobuf.Crypto; +import meerkat.protobuf.Mixing; + +import java.awt.*; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Files; + + +/** + * Created by Tzlil on 1/18/2016. + */ +public class MixerOutput implements meerkat.crypto.mixnet.MixerOutput{ + private final Mixing.ZeroKnowledgeProof[][] proofs; + private final Crypto.RerandomizableEncryptedMessage[][] encryptedMessages; + private final int n; + private final int layers; + + public MixerOutput(int n,int layers,Mixing.ZeroKnowledgeProof[][] proofs, Crypto.RerandomizableEncryptedMessage[][] encryptedMessages) { + this.proofs = proofs; + this.encryptedMessages = encryptedMessages; + this.n = n; + this.layers = layers; + } + + public MixerOutput(meerkat.crypto.mixnet.MixerOutput mixerOutput) { + this.proofs = mixerOutput.gerProofs(); + this.encryptedMessages = mixerOutput.getEncryptedMessages(); + this.n = mixerOutput.getN(); + this.layers = (int) (2 * Math.log(n) / Math.log(2)) - 1; // layers = 2logn -1; + } + + + @Override + public Mixing.ZeroKnowledgeProof[][] gerProofs() { + return proofs; + } + + @Override + public Crypto.RerandomizableEncryptedMessage[][] getEncryptedMessages() { + return encryptedMessages; + } + + @Override + public int getN() { + return n; + } + + public void outToFile(String dir) throws IOException { + + (new File(dir)).mkdirs(); + //create files + String proofsDir = dir + "/Proofs"; + String encDir = dir + "/EncryptedMessages"; + (new File(proofsDir)).mkdir(); + (new File(encDir)).mkdir(); + for (int layer = 0; layer < layers; layer++){ + (new File(proofsDir +"/layer" + layer )).mkdir(); + (new File(encDir +"/layer" + layer )).mkdir(); + } + (new File(encDir +"/input")).mkdir(); + + + for (int layer = 0; layer < layers; layer++){ + for(int i = 0; i < proofs[layer].length; i ++){ + writeProofToFile(proofsDir,proofs[layer][i]); + } + } + + for (int layer = 0; layer <= layers; layer++){ + for(int i = 0; i < encryptedMessages[layer].length; i ++){ + writeEncToFile(encDir,layer - 1, i,encryptedMessages[layer][i]); + } + } + } + + private void writeProofToFile(String proofsDir, Mixing.ZeroKnowledgeProof proof) throws IOException { + Mixing.ZeroKnowledgeProof.Location location = proof.getLocation(); + int layer = location.getLayer(); + int i = location.getI(); + int j = location.getJ(); + String fileName = proofsDir+"/layer" + layer +"/" + i +"_" + j; + + File file = new File(fileName); + file.createNewFile(); + FileOutputStream fos = new FileOutputStream(file); + fos.write(proof.toByteArray()); + fos.close(); + } + + private void writeEncToFile(String encDir,int layer,int i, Crypto.RerandomizableEncryptedMessage enc) throws IOException { + + String fileName; + if(layer >= 0) + fileName = encDir+"/layer" + layer +"/" + i; + else + fileName = encDir+"/input/" + i; + + File file = new File(fileName); + file.createNewFile(); + FileOutputStream fos = new FileOutputStream(file); + fos.write(enc.toByteArray()); + fos.close(); + } +} diff --git a/mixer/src/main/java/prover/ElGamalProofOrganizer.java b/mixer/src/main/java/prover/ElGamalProofOrganizer.java new file mode 100644 index 0000000..cec8256 --- /dev/null +++ b/mixer/src/main/java/prover/ElGamalProofOrganizer.java @@ -0,0 +1,239 @@ +package prover; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.crypto.concrete.ECElGamalEncryption; +import meerkat.protobuf.ConcreteCrypto; +import meerkat.protobuf.Crypto; +import org.bouncycastle.math.ec.ECPoint; +import qilin.primitives.concrete.ECGroup; + +/** + * Created by Tzlil on 12/30/2015. + */ +public class ElGamalProofOrganizer { + + private final ECGroup group; + private final ECPoint g; + private final ECPoint h; + private final byte[] gEncoded; + private final byte[] hEncoded; + + public ElGamalProofOrganizer(ECGroup group, ECPoint g, ECPoint h){ + this.group = group; + this.g = g; + this.h = h; + this.gEncoded = group.encode(g); + this.hEncoded = group.encode(h); + } + + public enum OrProofOrder { + first, second, third, fourth + } + + public enum TrueCouple { + left, right, unknown + } + + //used by prover only + protected ElGamalProofInput createProofInput(Crypto.RerandomizableEncryptedMessage e1, Crypto.RerandomizableEncryptedMessage e2 + , Crypto.RerandomizableEncryptedMessage e1New, Crypto.RerandomizableEncryptedMessage e2New + , Crypto.EncryptionRandomness r1, Crypto.EncryptionRandomness r2, boolean switched) throws InvalidProtocolBufferException { + + //convert RerandomizableEncryptedMessage to ElGamalCiphertext + ConcreteCrypto.ElGamalCiphertext e1ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e1); + ConcreteCrypto.ElGamalCiphertext e2ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e2); + ConcreteCrypto.ElGamalCiphertext e1NewElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e1New); + ConcreteCrypto.ElGamalCiphertext e2NewElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e2New); + + return new ElGamalProofInput(e1ElGamal,e2ElGamal,e1NewElGamal,e2NewElGamal,r1,r2,switched); + } + + // can be used by anyone, e.g Verifier + public ElGamalProofInput createProofInput(Crypto.RerandomizableEncryptedMessage e1, Crypto.RerandomizableEncryptedMessage e2 + , Crypto.RerandomizableEncryptedMessage e1New, Crypto.RerandomizableEncryptedMessage e2New) throws InvalidProtocolBufferException { + + //convert RerandomizableEncryptedMessage to ElGamalCiphertext + ConcreteCrypto.ElGamalCiphertext e1ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e1); + ConcreteCrypto.ElGamalCiphertext e2ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e2); + ConcreteCrypto.ElGamalCiphertext e1NewElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e1New); + ConcreteCrypto.ElGamalCiphertext e2NewElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e2New); + + return new ElGamalProofInput(e1ElGamal,e2ElGamal,e1NewElGamal,e2NewElGamal); + } + + + public class ElGamalProofInput { + + + private final OrProofInput first; + private final OrProofInput second; + private final OrProofInput third; + private final OrProofInput fourth; + + private ECPoint convert2ECPoint(ByteString bs){ + return group.decode(bs.toByteArray()); + } + + private ElGamalProofInput(ConcreteCrypto.ElGamalCiphertext e1, ConcreteCrypto.ElGamalCiphertext e2 + , ConcreteCrypto.ElGamalCiphertext e1New, ConcreteCrypto.ElGamalCiphertext e2New + , Crypto.EncryptionRandomness r1, Crypto.EncryptionRandomness r2, boolean switched){ + + ECPoint e1c1 = convert2ECPoint(e1.getC1()); + ECPoint e1c2 = convert2ECPoint(e1.getC2()); + ECPoint e2c1 = convert2ECPoint(e2.getC1()); + ECPoint e2c2 = convert2ECPoint(e2.getC2()); + ECPoint e1Nc1 = convert2ECPoint(e1New.getC1()); + ECPoint e1Nc2 = convert2ECPoint(e1New.getC2()); + ECPoint e2Nc1 = convert2ECPoint(e2New.getC1()); + ECPoint e2Nc2 = convert2ECPoint(e2New.getC2()); + + ECPoint c1_e1NDive1 = group.add(e1Nc1, group.negate(e1c1)); + ECPoint c1_e2NDive1 = group.add(e2Nc1, group.negate(e1c1)); + ECPoint c1_e1NDive2 = group.add(e1Nc1, group.negate(e2c1)); + ECPoint c1_e2NDive2 = group.add(e2Nc1, group.negate(e2c1)); + + ECPoint c2_e1NDive1 = group.add(e1Nc2, group.negate(e1c2)); + ECPoint c2_e2NDive1 = group.add(e2Nc2, group.negate(e1c2)); + ECPoint c2_e1NDive2 = group.add(e1Nc2, group.negate(e2c2)); + ECPoint c2_e2NDive2 = group.add(e2Nc2, group.negate(e2c2)); + + byte[] c1_e1NDive1Encoded = group.encode(c1_e1NDive1); + byte[] c1_e2NDive1Encoded = group.encode(c1_e2NDive1); + byte[] c1_e1NDive2Encoded = group.encode(c1_e1NDive2); + byte[] c1_e2NDive2Encoded = group.encode(c1_e2NDive2); + byte[] c2_e1NDive1Encoded = group.encode(c2_e1NDive1); + byte[] c2_e2NDive1Encoded = group.encode(c2_e2NDive1); + byte[] c2_e1NDive2Encoded = group.encode(c2_e1NDive2); + byte[] c2_e2NDive2Encoded = group.encode(c2_e2NDive2); + + + if (!switched) { + this.first = new OrProofInput(c1_e1NDive1,c2_e1NDive1,c1_e1NDive2,c2_e1NDive2 + ,c1_e1NDive1Encoded,c2_e1NDive1Encoded,c1_e1NDive2Encoded,c2_e1NDive2Encoded + ,r1,TrueCouple.left); + this.second = new OrProofInput(c1_e1NDive1,c2_e1NDive1,c1_e2NDive1,c2_e2NDive1 + ,c1_e1NDive1Encoded,c2_e1NDive1Encoded,c1_e2NDive1Encoded,c2_e2NDive1Encoded + ,r1,TrueCouple.left); + this.third = new OrProofInput(c1_e1NDive2,c2_e1NDive2,c1_e2NDive2,c2_e2NDive2 + ,c1_e1NDive2Encoded,c2_e1NDive2Encoded,c1_e2NDive2Encoded,c2_e2NDive2Encoded + ,r2,TrueCouple.right); + this.fourth = new OrProofInput(c1_e2NDive1,c2_e2NDive1,c1_e2NDive2,c2_e2NDive2 + ,c1_e2NDive1Encoded,c2_e2NDive1Encoded,c1_e2NDive2Encoded,c2_e2NDive2Encoded + ,r2,TrueCouple.right); + } else { + this.first = new OrProofInput(c1_e1NDive1,c2_e1NDive1,c1_e1NDive2,c2_e1NDive2 + ,c1_e1NDive1Encoded,c2_e1NDive1Encoded,c1_e1NDive2Encoded,c2_e1NDive2Encoded + ,r2,TrueCouple.right); + this.second = new OrProofInput(c1_e1NDive1,c2_e1NDive1,c1_e2NDive1,c2_e2NDive1 + ,c1_e1NDive1Encoded,c2_e1NDive1Encoded,c1_e2NDive1Encoded,c2_e2NDive1Encoded + ,r1,TrueCouple.right); + this.third = new OrProofInput(c1_e1NDive2,c2_e1NDive2,c1_e2NDive2,c2_e2NDive2 + ,c1_e1NDive2Encoded,c2_e1NDive2Encoded,c1_e2NDive2Encoded,c2_e2NDive2Encoded + ,r2,TrueCouple.left); + this.fourth = new OrProofInput(c1_e2NDive1,c2_e2NDive1,c1_e2NDive2,c2_e2NDive2 + ,c1_e2NDive1Encoded,c2_e2NDive1Encoded,c1_e2NDive2Encoded,c2_e2NDive2Encoded + ,r1,TrueCouple.left); + } + + } + + + private ElGamalProofInput(ConcreteCrypto.ElGamalCiphertext e1, ConcreteCrypto.ElGamalCiphertext e2 + , ConcreteCrypto.ElGamalCiphertext e1New, ConcreteCrypto.ElGamalCiphertext e2New){ + + ECPoint e1c1 = convert2ECPoint(e1.getC1()); + ECPoint e1c2 = convert2ECPoint(e1.getC2()); + ECPoint e2c1 = convert2ECPoint(e2.getC1()); + ECPoint e2c2 = convert2ECPoint(e2.getC2()); + ECPoint e1Nc1 = convert2ECPoint(e1New.getC1()); + ECPoint e1Nc2 = convert2ECPoint(e1New.getC2()); + ECPoint e2Nc1 = convert2ECPoint(e2New.getC1()); + ECPoint e2Nc2 = convert2ECPoint(e2New.getC2()); + + ECPoint c1_e1NDive1 = group.add(e1Nc1, group.negate(e1c1)); + ECPoint c1_e2NDive1 = group.add(e2Nc1, group.negate(e1c1)); + ECPoint c1_e1NDive2 = group.add(e1Nc1, group.negate(e2c1)); + ECPoint c1_e2NDive2 = group.add(e2Nc1, group.negate(e2c1)); + + ECPoint c2_e1NDive1 = group.add(e1Nc2, group.negate(e1c2)); + ECPoint c2_e2NDive1 = group.add(e2Nc2, group.negate(e1c2)); + ECPoint c2_e1NDive2 = group.add(e1Nc2, group.negate(e2c2)); + ECPoint c2_e2NDive2 = group.add(e2Nc2, group.negate(e2c2)); + + this.first = new OrProofInput(c1_e1NDive1,c2_e1NDive1,c1_e1NDive2,c2_e1NDive2); + this.second = new OrProofInput(c1_e1NDive1,c2_e1NDive1,c1_e2NDive1,c2_e2NDive1); + this.third = new OrProofInput(c1_e1NDive2,c2_e1NDive2,c1_e2NDive2,c2_e2NDive2); + this.fourth = new OrProofInput(c1_e2NDive1,c2_e2NDive1,c1_e2NDive2,c2_e2NDive2); + } + + + + public OrProofInput getOrProofInput(OrProofOrder orProofOrder) { + switch (orProofOrder) { + + case first: + return this.first; + case second: + return this.second; + case third: + return this.third; + case fourth: + return this.fourth; + } + return null; + } + } + public class OrProofInput{ + + public final ECPoint g1; + public final ECPoint h1; + public final ECPoint g2; + public final ECPoint h2; + public final ECPoint g1Tag; + public final ECPoint h1Tag; + public final ECPoint g2Tag; + public final ECPoint h2Tag; + + protected final byte[] g1Encoded; + protected final byte[] h1Encoded; + protected final byte[] g2Encoded; + protected final byte[] h2Encoded; + protected final byte[] g1TagEncoded; + protected final byte[] h1TagEncoded; + protected final byte[] g2TagEncoded; + protected final byte[] h2TagEncoded; + + protected final Crypto.EncryptionRandomness x; + protected final TrueCouple flag; + + private OrProofInput(ECPoint h1, ECPoint h2, ECPoint h1Tag, ECPoint h2Tag + ,byte[] h1Encoded, byte[] h2Encoded, byte[] h1TagEncoded, byte[] h2TagEncoded + , Crypto.EncryptionRandomness x, TrueCouple flag) { + this.g1 = g; + this.h1 = h1; + this.g2 = h; + this.h2 = h2; + this.g1Tag = g; + this.h1Tag = h1Tag; + this.g2Tag = h; + this.h2Tag = h2Tag; + + this.g1Encoded = gEncoded; + this.h1Encoded = h1Encoded; + this.g2Encoded = hEncoded; + this.h2Encoded = h2Encoded; + this.g1TagEncoded = gEncoded; + this.h1TagEncoded = h1TagEncoded; + this.g2TagEncoded = hEncoded; + this.h2TagEncoded = h2TagEncoded; + + this.x = x; + this.flag = flag; + + } + private OrProofInput(ECPoint h1, ECPoint h2, ECPoint h1Tag, ECPoint h2Tag) { + this(h1,h2,h1Tag,h2Tag,null,null,null,null,null,TrueCouple.unknown); + } + } +} diff --git a/mixer/src/main/java/prover/ProofOrganizer.java b/mixer/src/main/java/prover/ProofOrganizer.java deleted file mode 100644 index 16b032b..0000000 --- a/mixer/src/main/java/prover/ProofOrganizer.java +++ /dev/null @@ -1,85 +0,0 @@ -package prover; - -import meerkat.protobuf.Crypto; - -/** - * Created by Tzlil on 12/30/2015. - */ -public class ProofOrganizer { - - private final OrProofInput first; - private final OrProofInput second; - private final OrProofInput third; - private final OrProofInput fourth; - - protected ProofOrganizer(Crypto.RerandomizableEncryptedMessage e1,Crypto.RerandomizableEncryptedMessage e2 - ,Crypto.RerandomizableEncryptedMessage e1New,Crypto.RerandomizableEncryptedMessage e2New - ,Crypto.EncryptionRandomness r1,Crypto.EncryptionRandomness r2,boolean switched) { - if(!switched) { - this.first = new OrProofInput(e1, e1New, e2, e1New, r1,TrueCouple.left); - this.second = new OrProofInput(e1, e1New, e1, e2New,r1,TrueCouple.left); - this.third = new OrProofInput(e2, e1New, e2, e2New,r2,TrueCouple.right); - this.fourth = new OrProofInput(e1, e2New, e2, e2New,r2,TrueCouple.right); - }else{ - this.first = new OrProofInput(e1, e1New, e2, e1New, r2,TrueCouple.right); - this.second = new OrProofInput(e1, e1New, e1, e2New,r1,TrueCouple.right); - this.third = new OrProofInput(e2, e1New, e2, e2New,r2,TrueCouple.left); - this.fourth = new OrProofInput(e1, e2New, e2, e2New,r1,TrueCouple.left); - } - - } - - public ProofOrganizer(Crypto.RerandomizableEncryptedMessage e1,Crypto.RerandomizableEncryptedMessage e2 - ,Crypto.RerandomizableEncryptedMessage e1New,Crypto.RerandomizableEncryptedMessage e2New) { - this.first = new OrProofInput(e1, e1New, e2, e1New, null,TrueCouple.unknown); - this.second = new OrProofInput(e1, e1New, e1, e2New,null,TrueCouple.unknown); - this.third = new OrProofInput(e2, e1New, e2, e2New,null,TrueCouple.unknown); - this.fourth = new OrProofInput(e1, e2New, e2, e2New,null,TrueCouple.unknown); - } - - public enum OrProofOrder{ - first,second,third,fourth - } - - public enum TrueCouple{ - left,right,unknown - } - - - public OrProofInput getOrProofInput(OrProofOrder orProofOrder){ - switch (orProofOrder){ - - case first: - return this.first; - case second: - return this.second; - case third: - return this.third; - case fourth: - return this.fourth; - } - return null; - } - - public class OrProofInput{ - - - public final Crypto.RerandomizableEncryptedMessage e1; - public final Crypto.RerandomizableEncryptedMessage e1New; - public final Crypto.RerandomizableEncryptedMessage e2; - public final Crypto.RerandomizableEncryptedMessage e2New; - protected final Crypto.EncryptionRandomness x; - protected final TrueCouple flag; - - private OrProofInput(Crypto.RerandomizableEncryptedMessage e1, Crypto.RerandomizableEncryptedMessage e1New, - Crypto.RerandomizableEncryptedMessage e2, Crypto.RerandomizableEncryptedMessage e2New, - Crypto.EncryptionRandomness x, TrueCouple flag) { - this.e1 = e1; - this.e1New = e1New; - this.e2 = e2; - this.e2New = e2New; - this.x = x; - this.flag = flag; - } - } -} diff --git a/mixer/src/main/java/prover/Prover.java b/mixer/src/main/java/prover/Prover.java index 5cbd2c0..93c2536 100644 --- a/mixer/src/main/java/prover/Prover.java +++ b/mixer/src/main/java/prover/Prover.java @@ -4,8 +4,6 @@ import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; import meerkat.crypto.concrete.ECElGamalEncryption; import meerkat.crypto.mixnet.Mix2ZeroKnowledgeProver; -import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier; -import meerkat.protobuf.ConcreteCrypto; import meerkat.protobuf.ConcreteCrypto.ElGamalCiphertext; import meerkat.protobuf.Crypto; import meerkat.protobuf.Mixing; @@ -14,7 +12,6 @@ import qilin.primitives.RandomOracle; import qilin.primitives.concrete.ECGroup; import java.math.BigInteger; -import java.util.List; import java.util.Random; public class Prover implements Mix2ZeroKnowledgeProver { @@ -24,6 +21,7 @@ public class Prover implements Mix2ZeroKnowledgeProver { Random rand; ECElGamalEncryption ecElGamalEncryption; ECPoint g,h; + ElGamalProofOrganizer organizer; public Prover(Random rand,ECElGamalEncryption encryptor,RandomOracle randomOracle) { @@ -33,10 +31,9 @@ public class Prover implements Mix2ZeroKnowledgeProver { this.group = ecElGamalEncryption.getGroup(); this.g = group.getGenerator(); this.h = ecElGamalEncryption.getElGamalPK().getPK(); + this.organizer = new ElGamalProofOrganizer(group,g,h); } - - public Mixing.ZeroKnowledgeProof prove(Crypto.RerandomizableEncryptedMessage in1, Crypto.RerandomizableEncryptedMessage in2, Crypto.RerandomizableEncryptedMessage out1, @@ -44,18 +41,14 @@ public class Prover implements Mix2ZeroKnowledgeProver { boolean sw,int i,int j, int layer, Crypto.EncryptionRandomness r1, Crypto.EncryptionRandomness r2) throws InvalidProtocolBufferException { - Mixing.ZeroKnowledgeProof.OrProof first,second,third,fourth; - ProofOrganizer organizer = new ProofOrganizer(in1,in2,out1,out2,r1,r2,sw); - System.out.println("first"); - first = createOrProof(organizer.getOrProofInput(ProofOrganizer.OrProofOrder.first)); - System.out.println("second"); - second = createOrProof(organizer.getOrProofInput(ProofOrganizer.OrProofOrder.second)); - System.out.println("third"); - third = createOrProof(organizer.getOrProofInput(ProofOrganizer.OrProofOrder.third)); - System.out.println("fourth"); - fourth = createOrProof(organizer.getOrProofInput(ProofOrganizer.OrProofOrder.fourth)); + ElGamalProofOrganizer.ElGamalProofInput input = organizer.createProofInput(in1,in2,out1,out2,r1,r2,sw); + + first = createOrProofElGamal(input.getOrProofInput(ElGamalProofOrganizer.OrProofOrder.first)); + second = createOrProofElGamal(input.getOrProofInput(ElGamalProofOrganizer.OrProofOrder.second)); + third = createOrProofElGamal(input.getOrProofInput(ElGamalProofOrganizer.OrProofOrder.third)); + fourth = createOrProofElGamal(input.getOrProofInput(ElGamalProofOrganizer.OrProofOrder.fourth)); Mixing.ZeroKnowledgeProof.Location location = Mixing.ZeroKnowledgeProof.Location.newBuilder() .setI(i) @@ -70,25 +63,9 @@ public class Prover implements Mix2ZeroKnowledgeProver { .setFourth(fourth) .setLocation(location) .build(); - return result; } - private Mixing.ZeroKnowledgeProof.OrProof createOrProof(ProofOrganizer.OrProofInput orProofInput) - throws InvalidProtocolBufferException { - - ElGamalCiphertext e1ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(orProofInput.e1); - ElGamalCiphertext e2ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(orProofInput.e2); - ElGamalCiphertext e1TagElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(orProofInput.e1New); - ElGamalCiphertext e2TagElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(orProofInput.e2New); - - return createOrProofElGamal(e1ElGamal,e2ElGamal,e1TagElGamal,e2TagElGamal,orProofInput.x,orProofInput.flag); - } - - - private ECPoint convert2ECPoint(ByteString bs){ - return group.decode(bs.toByteArray()); - } public BigInteger hash(Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle input) { byte[] arr = input.toByteArray(); @@ -96,28 +73,25 @@ public class Prover implements Mix2ZeroKnowledgeProver { } - private Mixing.ZeroKnowledgeProof.OrProof createOrProofElGamal(ElGamalCiphertext e1, - ElGamalCiphertext e2, - ElGamalCiphertext e1New, - ElGamalCiphertext e2New, - Crypto.EncryptionRandomness x, - ProofOrganizer.TrueCouple flag) { + private Mixing.ZeroKnowledgeProof.OrProof createOrProofElGamal(ElGamalProofOrganizer.OrProofInput orProofInput) { - ECPoint g1 = g; - ECPoint h1 = group.add(convert2ECPoint(e1New.getC1()),group.negate(convert2ECPoint(e1.getC1()))); - ECPoint g2 = h; - ECPoint h2 = group.add(convert2ECPoint(e1New.getC2()),group.negate(convert2ECPoint(e1.getC2()))); + ECPoint g1 = orProofInput.g1; + ECPoint h1 = orProofInput.h1; + ECPoint g2 = orProofInput.g2; + ECPoint h2 = orProofInput.h2; - ECPoint g1Tag = g; - ECPoint h1Tag = group.add(convert2ECPoint(e2New.getC1()),group.negate(convert2ECPoint(e2.getC1()))); - ECPoint g2Tag = h; - ECPoint h2Tag = group.add(convert2ECPoint(e2New.getC2()),group.negate(convert2ECPoint(e2.getC2()))); + ECPoint g1Tag = orProofInput.g1Tag; + ECPoint h1Tag = orProofInput.h1Tag; + ECPoint g2Tag = orProofInput.g2Tag; + ECPoint h2Tag = orProofInput.h2Tag; BigInteger r = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound()); BigInteger c1,c2,z,zTag; ECPoint u,v,uTag,vTag; Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle forRandomOracle; - switch (flag) { + + + switch (orProofInput.flag) { case left: c2 = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound()); zTag = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound()); @@ -130,14 +104,14 @@ public class Prover implements Mix2ZeroKnowledgeProver { // c1 = (hash(input + step1) + group size - c2)% group size forRandomOracle = Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle.newBuilder() - .setG1(ByteString.copyFrom(group.encode(g1))) - .setH1(ByteString.copyFrom(group.encode(h1))) - .setG2(ByteString.copyFrom(group.encode(g2))) - .setH2(ByteString.copyFrom(group.encode(h2))) - .setG1Tag(ByteString.copyFrom(group.encode(g1Tag))) - .setH1Tag(ByteString.copyFrom(group.encode(h1Tag))) - .setG2Tag(ByteString.copyFrom(group.encode(g2Tag))) - .setH2Tag(ByteString.copyFrom(group.encode(h2Tag))) + .setG1(ByteString.copyFrom(orProofInput.g1Encoded)) + .setH1(ByteString.copyFrom(orProofInput.h1Encoded)) + .setG2(ByteString.copyFrom(orProofInput.g2Encoded)) + .setH2(ByteString.copyFrom(orProofInput.h2Encoded)) + .setG1Tag(ByteString.copyFrom(orProofInput.g1TagEncoded)) + .setH1Tag(ByteString.copyFrom(orProofInput.g1TagEncoded)) + .setG2Tag(ByteString.copyFrom(orProofInput.g1TagEncoded)) + .setH2Tag(ByteString.copyFrom(orProofInput.g1TagEncoded)) .setU(ByteString.copyFrom(group.encode(u))) .setV(ByteString.copyFrom(group.encode(v))) .setUTag(ByteString.copyFrom(group.encode(uTag))) @@ -146,7 +120,7 @@ public class Prover implements Mix2ZeroKnowledgeProver { c1 = hash(forRandomOracle).add(group.orderUpperBound().subtract(c2)).mod(group.orderUpperBound()); //step 3 //z = (r + c1 * x) % group size; - z = r.add(c1.multiply(new BigInteger(x.getData().toByteArray()))).mod(group.orderUpperBound()); + z = r.add(c1.multiply(new BigInteger(orProofInput.x.getData().toByteArray()))).mod(group.orderUpperBound()); break; case right: c1 = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound()); @@ -160,14 +134,14 @@ public class Prover implements Mix2ZeroKnowledgeProver { // c1 = (hash(input + step1) + group size - c1)% group size forRandomOracle = Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle.newBuilder() - .setG1(ByteString.copyFrom(group.encode(g1))) - .setH1(ByteString.copyFrom(group.encode(h1))) - .setG2(ByteString.copyFrom(group.encode(g2))) - .setH2(ByteString.copyFrom(group.encode(h2))) - .setG1Tag(ByteString.copyFrom(group.encode(g1Tag))) - .setH1Tag(ByteString.copyFrom(group.encode(h1Tag))) - .setG2Tag(ByteString.copyFrom(group.encode(g2Tag))) - .setH2Tag(ByteString.copyFrom(group.encode(h2Tag))) + .setG1(ByteString.copyFrom(orProofInput.g1Encoded)) + .setH1(ByteString.copyFrom(orProofInput.h1Encoded)) + .setG2(ByteString.copyFrom(orProofInput.g2Encoded)) + .setH2(ByteString.copyFrom(orProofInput.h2Encoded)) + .setG1Tag(ByteString.copyFrom(orProofInput.g1TagEncoded)) + .setH1Tag(ByteString.copyFrom(orProofInput.g1TagEncoded)) + .setG2Tag(ByteString.copyFrom(orProofInput.g1TagEncoded)) + .setH2Tag(ByteString.copyFrom(orProofInput.g1TagEncoded)) .setU(ByteString.copyFrom(group.encode(u))) .setV(ByteString.copyFrom(group.encode(v))) .setUTag(ByteString.copyFrom(group.encode(uTag))) @@ -176,39 +150,37 @@ public class Prover implements Mix2ZeroKnowledgeProver { c2 = hash(forRandomOracle).add(group.orderUpperBound().subtract(c1)).mod(group.orderUpperBound()); //step 3 //zTag = (r + c2 * x) % group size; - zTag = r.add(c2.multiply(new BigInteger(x.getData().toByteArray()))).mod(group.orderUpperBound()); + zTag = r.add(c2.multiply(new BigInteger(orProofInput.x.getData().toByteArray()))).mod(group.orderUpperBound()); break; default: return null; } //debugging - assert (group.multiply(g1, z).equals(group.add(u, group.multiply(h1,c1)))); - assert (group.multiply(g2, z).equals(group.add(v, group.multiply(h2,c1)))); - assert (group.multiply(g1Tag, zTag).equals(group.add(uTag, group.multiply(h1Tag,c2)))); - assert (group.multiply(g2Tag, zTag).equals(group.add(vTag, group.multiply(h2Tag,c2)))); + //assert (group.multiply(g1, z).equals(group.add(u, group.multiply(h1,c1)))); + //assert (group.multiply(g2, z).equals(group.add(v, group.multiply(h2,c1)))); + //assert (group.multiply(g1Tag, zTag).equals(group.add(uTag, group.multiply(h1Tag,c2)))); + //assert (group.multiply(g2Tag, zTag).equals(group.add(vTag, group.multiply(h2Tag,c2)))); return Mixing.ZeroKnowledgeProof.OrProof.newBuilder() - .setG1(ByteString.copyFrom(group.encode(g1))) - .setH1(ByteString.copyFrom(group.encode(h1))) - .setG2(ByteString.copyFrom(group.encode(g2))) - .setH2(ByteString.copyFrom(group.encode(h2))) - .setG1Tag(ByteString.copyFrom(group.encode(g1Tag))) - .setH1Tag(ByteString.copyFrom(group.encode(h1Tag))) - .setG2Tag(ByteString.copyFrom(group.encode(g2Tag))) - .setH2Tag(ByteString.copyFrom(group.encode(h2Tag))) - .setU(ByteString.copyFrom(group.encode(u))) - .setV(ByteString.copyFrom(group.encode(v))) - .setUTag(ByteString.copyFrom(group.encode(uTag))) - .setVTag(ByteString.copyFrom(group.encode(vTag))) + .setG1(forRandomOracle.getG1()) + .setH1(forRandomOracle.getH1()) + .setG2(forRandomOracle.getG2()) + .setH2(forRandomOracle.getH2()) + .setG1Tag(forRandomOracle.getG1()) + .setH1Tag(forRandomOracle.getH1Tag()) + .setG2Tag(forRandomOracle.getG2Tag()) + .setH2Tag(forRandomOracle.getH2Tag()) + .setU(forRandomOracle.getU()) + .setV(forRandomOracle.getV()) + .setUTag(forRandomOracle.getUTag()) + .setVTag(forRandomOracle.getVTag()) .setC1(ByteString.copyFrom(c1.toByteArray())) .setC2(ByteString.copyFrom(c2.toByteArray())) .setZ(ByteString.copyFrom(z.toByteArray())) .setZTag(ByteString.copyFrom(zTag.toByteArray())) .build(); } - - } diff --git a/mixer/src/main/java/verifier/Verifier.java b/mixer/src/main/java/verifier/Verifier.java index 977abfc..efe77aa 100644 --- a/mixer/src/main/java/verifier/Verifier.java +++ b/mixer/src/main/java/verifier/Verifier.java @@ -8,7 +8,7 @@ import meerkat.protobuf.ConcreteCrypto.ElGamalCiphertext; import meerkat.protobuf.Crypto; import meerkat.protobuf.Mixing; import org.bouncycastle.math.ec.ECPoint; -import prover.ProofOrganizer; +import prover.ElGamalProofOrganizer; import qilin.primitives.RandomOracle; import qilin.primitives.concrete.ECGroup; @@ -33,6 +33,7 @@ public class Verifier implements Mix2ZeroKnowledgeVerifier { RandomOracle randomOracle; ECElGamalEncryption encryptor; ECPoint g,h; + ElGamalProofOrganizer organizer; public Verifier(ECElGamalEncryption encryptor, RandomOracle randomOracle) { this.encryptor = encryptor; @@ -40,6 +41,7 @@ public class Verifier implements Mix2ZeroKnowledgeVerifier { this.g = group.getGenerator(); this.h = encryptor.getElGamalPK().getPK(); this.randomOracle = randomOracle; + this.organizer = new ElGamalProofOrganizer(group,g,h); } public BigInteger hash(Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle input) { @@ -57,26 +59,14 @@ public class Verifier implements Mix2ZeroKnowledgeVerifier { Crypto.RerandomizableEncryptedMessage out1, Crypto.RerandomizableEncryptedMessage out2, Mixing.ZeroKnowledgeProof proof) throws InvalidProtocolBufferException { - - ProofOrganizer organizer = new ProofOrganizer(in1,in2,out1,out2); - return verifyOrProof(organizer.getOrProofInput(ProofOrganizer.OrProofOrder.first), proof.getFirst())&& - verifyOrProof(organizer.getOrProofInput(ProofOrganizer.OrProofOrder.second), proof.getSecond())&& - verifyOrProof(organizer.getOrProofInput(ProofOrganizer.OrProofOrder.third), proof.getThird())&& - verifyOrProof(organizer.getOrProofInput(ProofOrganizer.OrProofOrder.fourth), proof.getFourth()); + ElGamalProofOrganizer.ElGamalProofInput input = organizer.createProofInput(in1,in2,out1,out2); + return verifyElGamaOrProof(input.getOrProofInput(ElGamalProofOrganizer.OrProofOrder.first), proof.getFirst())&& + verifyElGamaOrProof(input.getOrProofInput(ElGamalProofOrganizer.OrProofOrder.second), proof.getSecond())&& + verifyElGamaOrProof(input.getOrProofInput(ElGamalProofOrganizer.OrProofOrder.third), proof.getThird())&& + verifyElGamaOrProof(input.getOrProofInput(ElGamalProofOrganizer.OrProofOrder.fourth), proof.getFourth()); } - public boolean verifyOrProof(ProofOrganizer.OrProofInput orProofInput, Mixing.ZeroKnowledgeProof.OrProof orProof) - throws InvalidProtocolBufferException { - ElGamalCiphertext e1ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(orProofInput.e1); - ElGamalCiphertext e2ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(orProofInput.e2); - ElGamalCiphertext e1TagElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(orProofInput.e1New); - ElGamalCiphertext e2TagElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(orProofInput.e2New); - return verifyElGamaOrProof(e1ElGamal,e2ElGamal,e1TagElGamal,e2TagElGamal,orProof); - } - - - private ECPoint g1,g2,h1,h2; private ECPoint g1Tag,g2Tag,h1Tag,h2Tag; private ECPoint u,v,uTag,vTag; @@ -117,23 +107,16 @@ public class Verifier implements Mix2ZeroKnowledgeVerifier { zTag = new BigInteger(orProof.getZTag().toByteArray()); } - private List createConditionsList(ElGamalCiphertext e1, - ElGamalCiphertext e2, - ElGamalCiphertext e1New, - ElGamalCiphertext e2New){ + private List createConditionsList(ElGamalProofOrganizer.OrProofInput orProofInput){ 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( g1,orProofInput.g1,"g1 != g")); + conditions.add(new Condition( h1,orProofInput.h1,"h1 != e1New.c1/e1.c1")); + conditions.add(new Condition( g2,orProofInput.g2,"g2 != h")); + conditions.add(new Condition( h2,orProofInput.h2,"h2 != e1New.c2/e1.c2")); + conditions.add(new Condition( g1Tag,orProofInput.g1Tag,"g1Tag != g")); + conditions.add(new Condition( h1Tag,orProofInput.h1Tag,"h1Tag != e2New.c1/e2.c1")); + conditions.add(new Condition( g2Tag,orProofInput.g2,"g2Tag != h")); + conditions.add(new Condition( h2Tag,orProofInput.h2,"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")); @@ -148,14 +131,11 @@ public class Verifier implements Mix2ZeroKnowledgeVerifier { return conditions; } - public boolean verifyElGamaOrProof(ElGamalCiphertext e1, - ElGamalCiphertext e2, - ElGamalCiphertext e1New, - ElGamalCiphertext e2New, - Mixing.ZeroKnowledgeProof.OrProof orProof) + public boolean verifyElGamaOrProof(ElGamalProofOrganizer.OrProofInput orProofInput, Mixing.ZeroKnowledgeProof.OrProof orProof) + { parseOrProof(orProof); - List conditions = createConditionsList(e1,e2,e1New,e2New); + List conditions = createConditionsList(orProofInput); boolean result = true; for (Condition condition: conditions) { diff --git a/mixer/src/main/java/verifier/VerifyTable.java b/mixer/src/main/java/verifier/VerifyTable.java index a0075c0..37fdedb 100644 --- a/mixer/src/main/java/verifier/VerifyTable.java +++ b/mixer/src/main/java/verifier/VerifyTable.java @@ -2,6 +2,7 @@ package verifier; import com.google.protobuf.InvalidProtocolBufferException; import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier; +import meerkat.crypto.mixnet.MixerOutput; import meerkat.protobuf.Crypto; import meerkat.protobuf.Mixing; import qilin.util.Pair; @@ -13,8 +14,8 @@ import java.util.Arrays; */ public final class VerifyTable { - public static boolean verifyTable(Mix2ZeroKnowledgeVerifier verifier,int n,Pair mixerOutput) throws InvalidProtocolBufferException { + public static boolean verifyTable(Mix2ZeroKnowledgeVerifier verifier,int n,MixerOutput mixerOutput) + throws InvalidProtocolBufferException { int index1,index2,layer; //assert n = 2^k @@ -29,8 +30,8 @@ public final class VerifyTable { Arrays.fill(locationChecksumLayer,false); } - Mixing.ZeroKnowledgeProof[][] zeroKnowledgeProofs = mixerOutput.a; - Crypto.RerandomizableEncryptedMessage[][] rerandomizableEncryptedMessages = mixerOutput.b; + Mixing.ZeroKnowledgeProof[][] zeroKnowledgeProofs = mixerOutput.gerProofs(); + Crypto.RerandomizableEncryptedMessage[][] rerandomizableEncryptedMessages = mixerOutput.getEncryptedMessages(); for (Mixing.ZeroKnowledgeProof[] zkpLayer: zeroKnowledgeProofs) { for (Mixing.ZeroKnowledgeProof zkp: zkpLayer) { diff --git a/mixer/src/test/java/mixer/CreateTestVector.java b/mixer/src/test/java/mixer/CreateTestVector.java new file mode 100644 index 0000000..fcb273b --- /dev/null +++ b/mixer/src/test/java/mixer/CreateTestVector.java @@ -0,0 +1,100 @@ +package mixer; + +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.crypto.concrete.ECElGamalEncryption; +import meerkat.crypto.mixnet.Mix2ZeroKnowledgeProver; +import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier; +import meerkat.protobuf.Crypto; +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 verifier.Verifier; +import verifier.VerifyTable; + +import java.io.IOException; +import java.security.spec.InvalidKeySpecException; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +/** + * Created by Tzlil on 1/19/2016. + */ +public class CreateTestVector { + + + ECElGamalEncryption encryptor; + ECGroup group; + Random random,randomMixer,randomProver; + RandomOracle randomOracle; + Mix2ZeroKnowledgeVerifier verifier; + Mix2ZeroKnowledgeProver prover; + meerkat.crypto.mixnet.Mixer mixer; + private int layers; + private int n; + + + @Before + public void setup() throws InvalidKeySpecException { + // initialization + random = new Random(); + group = new ECGroup("secp256k1"); + encryptor = new ECElGamalEncryption(); + 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); + mixer = new Mixer(randomMixer,prover,encryptor,verifier); + + // generate n + int logN = 10; // + random.nextInt(8) + layers = 2*logN - 1; + n = 1 << logN; + } + + public List generateMixerInput(){ + List result = new ArrayList(); + Voting.PlaintextBallot msg; + for (int i = 0; i < n ; i++){ + msg = Utiles.genRandomBallot(2,3,16); + result.add(encryptor.encrypt(msg, encryptor.generateRandomness(random))); + } + return result; + } + //@Test + public void createValidTest() throws IOException { + + List mixerInput = generateMixerInput(); + System.out.println("start mixing"); + MixerOutput mixerOutput = new MixerOutput(mixer.mix(mixerInput)); + System.out.println("mixing ended, start verification"); + assert (VerifyTable.verifyTable(verifier,n,mixerOutput)); + System.out.println("verification ended, start printing"); + mixerOutput.outToFile("C:\\Users\\Tzlil\\Desktop\\TestVector\\Test3"); + System.out.println("all done"); + } + + //@Test + public void createInvalidTest() throws IOException { + + //Mix2ZeroKnowledgeVerifier corruptedVerifier = new Verifier(encryptor,randomOracle,true); + //Mix2ZeroKnowledgeProver corruptedProver = new Prover(randomProver,encryptor,randomOracle,true); + //mixer = new Mixer(randomMixer,corruptedProver,encryptor,corruptedVerifier); + + List mixerInput = generateMixerInput(); + System.out.println("start mixing"); + MixerOutput mixerOutput = new MixerOutput(mixer.mix(mixerInput)); + System.out.println("mixing ended, start negative verification"); + assert (!VerifyTable.verifyTable(verifier,n,mixerOutput)); + System.out.println("verification ended, start printing"); + mixerOutput.outToFile("C:\\Users\\Tzlil\\Desktop\\TestVector\\Test5"); + System.out.println("all done"); + } +} diff --git a/mixer/src/test/java/mixer/MixingText.java b/mixer/src/test/java/mixer/MixingText.java index ac05513..23645ed 100644 --- a/mixer/src/test/java/mixer/MixingText.java +++ b/mixer/src/test/java/mixer/MixingText.java @@ -6,8 +6,7 @@ package mixer; import com.google.protobuf.InvalidProtocolBufferException; import meerkat.crypto.concrete.ECElGamalEncryption; -import meerkat.crypto.mixnet.Mix2ZeroKnowledgeProver; -import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier; +import meerkat.crypto.mixnet.*; import meerkat.protobuf.Crypto; import meerkat.protobuf.Mixing; import meerkat.protobuf.Voting; @@ -33,7 +32,7 @@ public class MixingText { Random random,randomMixer,randomProver; RandomOracle randomOracle; Mix2ZeroKnowledgeVerifier verifier; - Mix2ZeroKnowledgeProver prover; + Prover prover; meerkat.crypto.mixnet.Mixer mixer; private int layers; private int n; @@ -54,7 +53,7 @@ public class MixingText { mixer = new Mixer(randomMixer,prover,encryptor); // generate n - int logN = 8; // + random.nextInt(8) + int logN = 10; // + random.nextInt(8) layers = 2*logN - 1; n = 1 << logN; } @@ -71,7 +70,23 @@ public class MixingText { @Test public void mixingTest() throws InvalidProtocolBufferException { - Pair mixerOutput = mixer.mix(generateMixerInput()); + System.out.println("n is : " + n); + System.out.println(" generating input"); + List mixerInput = generateMixerInput(); + System.out.println(" start mixing"); + long startTime = System.currentTimeMillis(); + + meerkat.crypto.mixnet.MixerOutput mixerOutput = mixer.mix(mixerInput); + + long finishTime = System.currentTimeMillis(); + System.out.println(" that took: "+(finishTime-startTime)+ " ms"); + + System.out.println("start verification"); + startTime = System.currentTimeMillis(); + assert (VerifyTable.verifyTable(verifier,n,mixerOutput)); + + finishTime = System.currentTimeMillis(); + System.out.println(" that took: "+(finishTime-startTime)+ " ms"); } } diff --git a/mixer/src/test/java/mixer/RerandomizeTest.java b/mixer/src/test/java/mixer/RerandomizeTest.java index 6e29bb5..f98bc1e 100644 --- a/mixer/src/test/java/mixer/RerandomizeTest.java +++ b/mixer/src/test/java/mixer/RerandomizeTest.java @@ -67,8 +67,8 @@ public class RerandomizeTest { ConcreteCrypto.ElGamalCiphertext eNewElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(eNew); assert (g.multiply(new BigInteger(r.getData().toByteArray())).equals( - group.add(convert2ECPoint(eNewElGamal.getC1()),group.negate(convert2ECPoint(eElGamal.getC1()))))); - assert (h.multiply(new BigInteger(r.getData().toByteArray())).equals( + group.add(convert2ECPoint(eNewElGamal.getC1()),group.negate(convert2ECPoint(eElGamal.getC1()))))); + assert(h.multiply(new BigInteger(r.getData().toByteArray())).equals( group.add(convert2ECPoint(eNewElGamal.getC2()), group.negate(convert2ECPoint(eElGamal.getC2()))))); } diff --git a/mixer/src/test/java/profiling/ECGroupProfiling/AddProfiling.java b/mixer/src/test/java/profiling/ECGroupProfiling/AddProfiling.java new file mode 100644 index 0000000..3c9880f --- /dev/null +++ b/mixer/src/test/java/profiling/ECGroupProfiling/AddProfiling.java @@ -0,0 +1,65 @@ +package profiling.ECGroupProfiling; + +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.crypto.concrete.ECElGamalEncryption; +import mixer.Utiles; +import org.bouncycastle.math.ec.ECPoint; +import org.junit.Before; +import org.junit.Test; +import qilin.primitives.concrete.ECElGamal; +import qilin.primitives.concrete.ECGroup; + +import java.security.spec.InvalidKeySpecException; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +/** + * Created by Tzlil on 1/20/2016. + */ +public class AddProfiling { + + ECElGamalEncryption encryptor; + ECGroup group; + Random random; + private int n; + List members1; + List members2; + + @Before + public void setup() throws InvalidKeySpecException { + // initialization + random = new Random(); + group = new ECGroup("secp256k1"); + encryptor = new ECElGamalEncryption(); + encryptor.init(Utiles.serializePk(group, new ECElGamal.SK(group, ECElGamal.generateSecretKey(group, random)))); + // generate n; + int sqrtn = 128; + n = sqrtn*sqrtn; + + members1 = new ArrayList(sqrtn); + members2 = new ArrayList(sqrtn); + + for (int i = 0 ; i < sqrtn; i ++){ + members1.add(group.sample(random)); + members2.add(group.sample(random)); + } + } + + @Test + public void addProfiling() throws InvalidProtocolBufferException { + System.out.println("Add"); + System.out.println("n is : " + n); + System.out.println("start n operations"); + long startTime = System.currentTimeMillis(); + for (ECPoint member1: members1) { + for (ECPoint member2: members2) { + group.add(member1,member2); + } + } + + long finishTime = System.currentTimeMillis(); + System.out.println(" that took: "+(finishTime-startTime)+ " ms"); + System.out.println(" avg of"+((double)(finishTime-startTime))/(n * n)+ " ms"); + } +} diff --git a/mixer/src/test/java/profiling/ECGroupProfiling/EncodeProfiling.java b/mixer/src/test/java/profiling/ECGroupProfiling/EncodeProfiling.java new file mode 100644 index 0000000..af03f70 --- /dev/null +++ b/mixer/src/test/java/profiling/ECGroupProfiling/EncodeProfiling.java @@ -0,0 +1,59 @@ +package profiling.ECGroupProfiling; + +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.crypto.concrete.ECElGamalEncryption; +import mixer.Utiles; +import org.bouncycastle.math.ec.ECPoint; +import org.junit.Before; +import org.junit.Test; +import qilin.primitives.concrete.ECElGamal; +import qilin.primitives.concrete.ECGroup; + +import java.security.spec.InvalidKeySpecException; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +/** + * Created by Tzlil on 1/20/2016. + */ +public class EncodeProfiling { + + ECElGamalEncryption encryptor; + ECGroup group; + Random random; + private int n; + List members; + + @Before + public void setup() throws InvalidKeySpecException { + // initialization + random = new Random(); + group = new ECGroup("secp256k1"); + encryptor = new ECElGamalEncryption(); + encryptor.init(Utiles.serializePk(group, new ECElGamal.SK(group, ECElGamal.generateSecretKey(group, random)))); + // generate n; + int sqrtn = 128; + n = sqrtn*sqrtn; + + members = new ArrayList(n); + for (int i = 0 ; i < n; i ++){ + members.add(group.sample(random)); + } + } + @Test + public void encodeProfiling() throws InvalidProtocolBufferException { + System.out.println("Encode"); + System.out.println("n is : " + n); + + System.out.println("start n operations"); + long startTime = System.currentTimeMillis(); + for (ECPoint member: members) { + group.encode(member); + } + + long finishTime = System.currentTimeMillis(); + System.out.println(" that took: "+(finishTime-startTime)+ " ms"); + System.out.println(" avg of"+((double)(finishTime-startTime))/(n * n)+ " ms"); + } +} diff --git a/mixer/src/test/java/profiling/ECGroupProfiling/MulProfiling.java b/mixer/src/test/java/profiling/ECGroupProfiling/MulProfiling.java new file mode 100644 index 0000000..bb7c7cb --- /dev/null +++ b/mixer/src/test/java/profiling/ECGroupProfiling/MulProfiling.java @@ -0,0 +1,81 @@ +package profiling.ECGroupProfiling; + +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.crypto.concrete.ECElGamalEncryption; +import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier; +import meerkat.protobuf.Crypto; +import meerkat.protobuf.Voting; +import mixer.Mixer; +import mixer.Utiles; +import org.bouncycastle.math.ec.ECPoint; +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 verifier.Verifier; +import verifier.VerifyTable; + +import java.math.BigInteger; +import java.security.spec.InvalidKeySpecException; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +/** + * Created by Tzlil on 1/19/2016. + */ +public class MulProfiling { + + ECElGamalEncryption encryptor; + ECGroup group; + Random random; + private int n; + List members; + List randomnesses; + @Before + public void setup() throws InvalidKeySpecException { + // initialization + random = new Random(); + group = new ECGroup("secp256k1"); + encryptor = new ECElGamalEncryption(); + encryptor.init(Utiles.serializePk(group, new ECElGamal.SK(group, ECElGamal.generateSecretKey(group, random)))); + // generate n + int sqrtn = 128; + n = sqrtn*sqrtn; + + members = new ArrayList(sqrtn); + randomnesses = new ArrayList(sqrtn); + + byte[] arr = new byte[256]; + for (int i = 0 ; i < sqrtn; i ++){ + members.add(group.sample(random)); + random.nextBytes(arr); + randomnesses.add(new BigInteger(arr)); + } + } + + @Test + public void mulProfiling() throws InvalidProtocolBufferException { + System.out.println("Multiply"); + System.out.println("n is : " + n); + + System.out.println("start n operations"); + long startTime = System.currentTimeMillis(); + for(ECPoint member:members) { + for (BigInteger rand : randomnesses) { + group.multiply(member, rand); + + } + } + + long finishTime = System.currentTimeMillis(); + System.out.println(" that took: "+(finishTime-startTime)+ " ms"); + System.out.println(" avg of"+((double)(finishTime-startTime))/(n*n)+ " ms"); + } + + + +} diff --git a/mixer/src/test/java/profiling/ECGroupProfiling/NegateProfiling.java b/mixer/src/test/java/profiling/ECGroupProfiling/NegateProfiling.java new file mode 100644 index 0000000..344a813 --- /dev/null +++ b/mixer/src/test/java/profiling/ECGroupProfiling/NegateProfiling.java @@ -0,0 +1,59 @@ +package profiling.ECGroupProfiling; + +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.crypto.concrete.ECElGamalEncryption; +import mixer.Utiles; +import org.bouncycastle.math.ec.ECPoint; +import org.junit.Before; +import org.junit.Test; +import qilin.primitives.concrete.ECElGamal; +import qilin.primitives.concrete.ECGroup; + +import java.security.spec.InvalidKeySpecException; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +/** + * Created by Tzlil on 1/20/2016. + */ +public class NegateProfiling { + + ECElGamalEncryption encryptor; + ECGroup group; + Random random; + private int n; + List members; + + @Before + public void setup() throws InvalidKeySpecException { + // initialization + random = new Random(); + group = new ECGroup("secp256k1"); + encryptor = new ECElGamalEncryption(); + encryptor.init(Utiles.serializePk(group, new ECElGamal.SK(group, ECElGamal.generateSecretKey(group, random)))); + // generate n; + int sqrtn = 128; + n = sqrtn*sqrtn; + + members = new ArrayList(n); + for (int i = 0 ; i < n; i ++){ + members.add(group.sample(random)); + } + } + @Test + public void negProfiling() throws InvalidProtocolBufferException { + System.out.println("Neg"); + System.out.println("n is : " + n); + + System.out.println("start n operations"); + long startTime = System.currentTimeMillis(); + for (ECPoint member: members) { + group.negate(member); + } + + long finishTime = System.currentTimeMillis(); + System.out.println(" that took: "+(finishTime-startTime)+ " ms"); + System.out.println(" avg of"+((double)(finishTime-startTime))/(n * n)+ " ms"); + } +} diff --git a/mixer/src/test/java/profiling/RerandomizeProfiling.java b/mixer/src/test/java/profiling/RerandomizeProfiling.java new file mode 100644 index 0000000..01148ec --- /dev/null +++ b/mixer/src/test/java/profiling/RerandomizeProfiling.java @@ -0,0 +1,79 @@ +package profiling; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.crypto.concrete.ECElGamalEncryption; +import meerkat.crypto.mixnet.Mix2ZeroKnowledgeProver; +import meerkat.protobuf.ConcreteCrypto; +import meerkat.protobuf.Crypto; +import meerkat.protobuf.Voting; +import mixer.Utiles; +import org.bouncycastle.math.ec.ECPoint; +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 java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/20/2016. + */ +public class RerandomizeProfiling { + + Random rand; + ECElGamal.SK key; + ECGroup group; + ECElGamalEncryption enc; + ConcreteCrypto.ElGamalPublicKey serializedPk; + int n; + Crypto.EncryptionRandomness[] randomnesses; + Crypto.RerandomizableEncryptedMessage[] encryptedMessage; + + @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 = Utiles.serializePk(group, key); + enc = new ECElGamalEncryption(); + enc.init(serializedPk); + n = 1024 * 18; + randomnesses = new Crypto.EncryptionRandomness[n]; + encryptedMessage = new Crypto.RerandomizableEncryptedMessage[n]; + + Voting.PlaintextBallot msg; + + for (int i = 0; i < n ; i ++){ + msg = Utiles.genRandomBallot(2,3,16); + randomnesses[i] = enc.generateRandomness(rand); + encryptedMessage[i] = enc.encrypt(msg, enc.generateRandomness(rand)); + } + } + + private ECPoint convert2ECPoint(ByteString bs){ + return group.decode(bs.toByteArray()); + } + + @Test + public void RerandomizeProfiling() throws InvalidProtocolBufferException { + + System.out.println("Rerandomiz"); + System.out.println("n is : " + n); + System.out.println("start n operations"); + long startTime = System.currentTimeMillis(); + + for (int i = 0; i < n ; i ++){ + enc.rerandomize(encryptedMessage[i],randomnesses[i]); + } + + long finishTime = System.currentTimeMillis(); + System.out.println(" that took: "+(finishTime-startTime)+ " ms"); + System.out.println(" avg of"+((double)(finishTime-startTime))/n + " ms"); + } +} diff --git a/mixer/src/test/java/profiling/ZeroKnowledgeProofProfiling.java b/mixer/src/test/java/profiling/ZeroKnowledgeProofProfiling.java new file mode 100644 index 0000000..ec91ddb --- /dev/null +++ b/mixer/src/test/java/profiling/ZeroKnowledgeProofProfiling.java @@ -0,0 +1,87 @@ +package profiling; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.crypto.concrete.ECElGamalEncryption; +import meerkat.crypto.mixnet.Mix2ZeroKnowledgeProver; +import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier; +import meerkat.protobuf.ConcreteCrypto; +import meerkat.protobuf.Crypto; +import meerkat.protobuf.Voting; +import mixer.Utiles; +import org.bouncycastle.math.ec.ECPoint; +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 java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/20/2016. + */ +public class ZeroKnowledgeProofProfiling { + + Random rand; + ECElGamal.SK key; + ECGroup group; + ECElGamalEncryption enc; + ConcreteCrypto.ElGamalPublicKey serializedPk; + Mix2ZeroKnowledgeProver prover ; + int n; + Crypto.EncryptionRandomness[] randomnesses; + Crypto.RerandomizableEncryptedMessage[] encryptedMessage; + Crypto.RerandomizableEncryptedMessage[] reencryptedMessage; + @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 = Utiles.serializePk(group, key); + enc = new ECElGamalEncryption(); + enc.init(serializedPk); + RandomOracle randomOracle = new DigestOracle(); + prover = new Prover(new Random(),enc,randomOracle); + n = 512 * 18; + randomnesses = new Crypto.EncryptionRandomness[n*2]; + encryptedMessage = new Crypto.RerandomizableEncryptedMessage[n*2]; + reencryptedMessage = new Crypto.RerandomizableEncryptedMessage[n*2]; + + Voting.PlaintextBallot msg; + + for (int i = 0; i < n*2 ; i ++){ + msg = Utiles.genRandomBallot(2,3,16); + randomnesses[i] = enc.generateRandomness(rand); + encryptedMessage[i] = enc.encrypt(msg, enc.generateRandomness(rand)); + reencryptedMessage[i] = enc.rerandomize(encryptedMessage[i], randomnesses[i]); + } + } + + private ECPoint convert2ECPoint(ByteString bs){ + return group.decode(bs.toByteArray()); + } + + @Test + public void zeroKnowledgeProofTest() throws InvalidProtocolBufferException { + + System.out.println("Prove"); + System.out.println("n is : " + n); + System.out.println("start n proves"); + long startTime = System.currentTimeMillis(); + + for (int i = 0; i < n*2 ; i +=2){ + prover.prove(encryptedMessage[i],encryptedMessage[i+1],reencryptedMessage[i],reencryptedMessage[i+1], + false,0,0,0,randomnesses[i],randomnesses[i+1]); + } + + long finishTime = System.currentTimeMillis(); + System.out.println(" that took: "+(finishTime-startTime)+ " ms"); + System.out.println(" avg of"+((double)(finishTime-startTime))/n + " ms"); + } +}