From efde36d869f901df457546b64e49e0a351a8e0f6 Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Mon, 25 Jan 2016 16:48:36 +0200 Subject: [PATCH] profiling --- .../crypto/concrete/ECDSASignature.java | 2 +- .../crypto/concrete/ECElGamalEncryption.java | 2 +- mixer/src/main/java/main/BatchConverter.java | 14 +- mixer/src/main/java/main/BatchHandler.java | 5 +- mixer/src/main/java/main/MainMixing.java | 78 +++-- mixer/src/main/java/mixer/Mixer.java | 127 +++++--- .../java/prover/ElGamalProofOrganizer.java | 278 +++++++++++------- mixer/src/main/java/prover/Prover.java | 93 ++++-- mixer/src/main/java/verifier/Verifier.java | 141 +++------ .../verifier/ZeroKnowledgeOrProofParser.java | 69 +++++ .../src/test/java/mixer/RerandomizeTest.java | 8 +- .../java/mixer/ZeroKnowledgeProofTest.java | 8 +- .../java/profiling/BigInteger/AddSub.java | 69 +++++ .../BigInteger/GenerateRandomness.java | 49 +++ .../java/profiling/BigInteger/Modulo.java | 57 ++++ .../test/java/profiling/BigInteger/Mul.java | 63 ++++ .../java/profiling/BigInteger/SHA256.java | 57 ++++ .../profiling/Convert/ByteString2ECPoint.java | 73 +++++ ...bleEncryptedMessage2ElGamalCiphertext.java | 67 +++++ .../AddProfiling.java => ECGroup/Add.java} | 8 +- .../Encode.java} | 6 +- .../MulProfiling.java => ECGroup/Mul.java} | 15 +- .../Negate.java} | 6 +- ...ndomizeProfiling.java => Rerandomize.java} | 10 +- ...Profiling.java => ZeroKnowledgeProof.java} | 7 +- 25 files changed, 936 insertions(+), 376 deletions(-) create mode 100644 mixer/src/main/java/verifier/ZeroKnowledgeOrProofParser.java create mode 100644 mixer/src/test/java/profiling/BigInteger/AddSub.java create mode 100644 mixer/src/test/java/profiling/BigInteger/GenerateRandomness.java create mode 100644 mixer/src/test/java/profiling/BigInteger/Modulo.java create mode 100644 mixer/src/test/java/profiling/BigInteger/Mul.java create mode 100644 mixer/src/test/java/profiling/BigInteger/SHA256.java create mode 100644 mixer/src/test/java/profiling/Convert/ByteString2ECPoint.java create mode 100644 mixer/src/test/java/profiling/Convert/RerandomizableEncryptedMessage2ElGamalCiphertext.java rename mixer/src/test/java/profiling/{ECGroupProfiling/AddProfiling.java => ECGroup/Add.java} (93%) rename mixer/src/test/java/profiling/{ECGroupProfiling/EncodeProfiling.java => ECGroup/Encode.java} (94%) rename mixer/src/test/java/profiling/{ECGroupProfiling/MulProfiling.java => ECGroup/Mul.java} (83%) rename mixer/src/test/java/profiling/{ECGroupProfiling/NegateProfiling.java => ECGroup/Negate.java} (94%) rename mixer/src/test/java/profiling/{RerandomizeProfiling.java => Rerandomize.java} (93%) rename mixer/src/test/java/profiling/{ZeroKnowledgeProofProfiling.java => ZeroKnowledgeProof.java} (95%) diff --git a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java index 6cbcf8d..b0a79f2 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java @@ -44,7 +44,7 @@ public class ECDSASignature extends GlobalCryptoSetup implements DigitalSignatur ByteBuffer lenBuf = ByteBuffer.allocate(4); - Map loadedCertificates = new HashMap<>(); + Map loadedCertificates = new HashMap(); /** * Signature currently loaded (will be used in calls to {@link #verify()}). diff --git a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java index 910a1aa..5dae4b7 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java @@ -109,7 +109,7 @@ public class ECElGamalEncryption extends GlobalCryptoSetup implements Encryption .build(); } - public static ConcreteCrypto.ElGamalCiphertext rerandomizableEncryptedMessage2ElGamalCiphertext(Crypto.RerandomizableEncryptedMessage msg) throws InvalidProtocolBufferException { + public static ConcreteCrypto.ElGamalCiphertext RerandomizableEncryptedMessage2ElGamalCiphertext(Crypto.RerandomizableEncryptedMessage msg) throws InvalidProtocolBufferException { return ConcreteCrypto.ElGamalCiphertext.parseFrom(msg.getData()); } diff --git a/mixer/src/main/java/main/BatchConverter.java b/mixer/src/main/java/main/BatchConverter.java index 008c868..919f406 100644 --- a/mixer/src/main/java/main/BatchConverter.java +++ b/mixer/src/main/java/main/BatchConverter.java @@ -5,7 +5,6 @@ import meerkat.crypto.mixnet.MixerOutput; import meerkat.protobuf.BulletinBoardAPI; import meerkat.protobuf.Crypto; import meerkat.protobuf.Mixing; -import qilin.util.Pair; import java.math.BigInteger; import java.util.ArrayList; @@ -22,7 +21,8 @@ public class BatchConverter { this.n = n; this.layers = layers; } - private ByteString IntegerToByteString(int a){ + + private ByteString Integer2ByteString(int a){ return ByteString.copyFrom(BigInteger.valueOf(a).toByteArray()); } @@ -30,12 +30,12 @@ public class BatchConverter { return Integer.valueOf(bs.toString()); } - public List mixerOutput2BatchData(MixerOutput mixerOutput) { + public List MixerOutput2BatchData(MixerOutput mixerOutput) { List result = new ArrayList(); result.add(BulletinBoardAPI.BatchData.newBuilder() - .setData(IntegerToByteString(n)) + .setData(Integer2ByteString(n)) .build()); for (Mixing.ZeroKnowledgeProof[] zkpLayer : mixerOutput.gerProofs()) { @@ -55,7 +55,7 @@ public class BatchConverter { return result; } - public MixerOutput batchDataList2MixerOutput + public MixerOutput BatchDataList2MixerOutput (List batchDataList) throws Exception { if (n != ByteString2Integer(batchDataList.remove(0).getData())){ @@ -64,7 +64,7 @@ public class BatchConverter { int nDiv2 = n >>1; Mixing.ZeroKnowledgeProof[][] proofs = new Mixing.ZeroKnowledgeProof[layers][nDiv2]; - for (int layer = 0; layer mixerInput; - - if (mixerOrder > 0) { - List batchHandlers = new ArrayList(prevBatchIds.size()); - BatchHandler currentBatchHandler; - for (Integer prevBatchId : prevBatchIds) { - currentBatchHandler = new BatchHandler(n, layers,verifier); - asyncBulletinBoardClient.readBatch(id, prevBatchId,currentBatchHandler); - batchHandlers.add(currentBatchHandler); - } - - // ToDo : assert table continues - // ToDo : assert signature validity - - boolean allDone = false; - while (!allDone) { - try { - Thread.sleep(30); - } catch (InterruptedException e) { - // do nothing - } - // check all handlers messages were received - allDone = true; - for (BatchHandler batchHandler : batchHandlers) { - allDone &= batchHandler.isMsgReceived(); - } - } - - // assert all handlers succeeded - for (BatchHandler batchHandler : batchHandlers) { - if(!batchHandler.verifyTable()){ - throw new Exception("invalid input"); - } - } - - BatchHandler lastBatchHandler = batchHandlers.get(batchHandlers.size() - 1); - mixerInput = lastBatchHandler.getInputForMixer(); - - } else { - // ToDo : handle first mixer case - mixerInput = null; + List batchHandlers = new ArrayList(prevBatchIds.size()); + BatchHandler currentBatchHandler; + for (Integer prevBatchId : prevBatchIds) { + currentBatchHandler = new BatchHandler(n, layers,verifier); + asyncBulletinBoardClient.readBatch(id, prevBatchId,currentBatchHandler); + batchHandlers.add(currentBatchHandler); } + // ToDo : assert table continues + // ToDo : assert signature validity + + boolean allDone = false; + while (!allDone) { + try { + Thread.sleep(30); + } catch (InterruptedException e) { + // do nothing + } + // check all handlers messages were received + allDone = true; + for (BatchHandler batchHandler : batchHandlers) { + allDone &= batchHandler.isMsgReceived(); + } + } + + // assert all handlers succeeded + for (BatchHandler batchHandler : batchHandlers) { + if(!batchHandler.verifyTable()){ + throw new Exception("invalid input"); + } + } + + BatchHandler lastBatchHandler = batchHandlers.get(batchHandlers.size() - 1); + mixerInput = lastBatchHandler.getInputForMixer(); + MixerOutput mixerOutput = mixer.mix(mixerInput); updateBB(mixerOutput, batchId, callback); @@ -95,7 +85,7 @@ public class MainMixing { , int batchId, AsyncBulletinBoardClient.ClientCallback callback) { BatchConverter batchConverter = new BatchConverter(n,layers); - List batchDataList = batchConverter.mixerOutput2BatchData(mixerOutput); + List batchDataList = batchConverter.MixerOutput2BatchData(mixerOutput); asyncBulletinBoardClient.postBatch(id, batchId, batchDataList, callback); } diff --git a/mixer/src/main/java/mixer/Mixer.java b/mixer/src/main/java/mixer/Mixer.java index 51a7950..477e740 100644 --- a/mixer/src/main/java/mixer/Mixer.java +++ b/mixer/src/main/java/mixer/Mixer.java @@ -22,10 +22,10 @@ import verifier.Verifier; public class Mixer implements meerkat.crypto.mixnet.Mixer { - private Random random; - private Mix2ZeroKnowledgeProver prover; - private Encryption encryptor; - private Mix2ZeroKnowledgeVerifier verifier; + protected final Random random; + protected final Mix2ZeroKnowledgeProver prover; + protected final Encryption encryptor; + protected final Mix2ZeroKnowledgeVerifier verifier; public Mixer(Random rand, Mix2ZeroKnowledgeProver prov, Encryption enc) { this.random = rand; @@ -41,45 +41,51 @@ public class Mixer implements meerkat.crypto.mixnet.Mixer { this.verifier = verifier; } - public MixerOutput mix(List ciphertexts) throws InvalidProtocolBufferException { - - int n = ciphertexts.size(); - int nDiv2 = n >> 1; - // assert n = 2^k and n > 1 - if (n <= 1 || ((n & (n - 1)) != 0)) - return null; - - //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][n]; - int index1, index2, switchIndex = 0; - EncryptionRandomness r1, r2; - RerandomizableEncryptedMessage e1, e2; - boolean half = true; - MixNetwork mixNetwork = new MixNetwork(new RandomPermutation(n,random)); - Switch[] switchesLayer; - - EncryptionRandomness[][] randomnesses = new EncryptionRandomness[layers][n]; + // assert n = 2^k and n > 1 + protected boolean inputBasicCheckSum(int n){ + return n > 1 && ((n & (n - 1)) == 0); + } + protected RerandomizableEncryptedMessage[][] initializeEncryptionTable(int n,int layers,List ciphertexts){ // set first level of encryption - for (int j = 0; j < n; j++) { - encryptionTable[0][j] = ciphertexts.get(j); - } + RerandomizableEncryptedMessage[][] encryptionTable = new RerandomizableEncryptedMessage[layers + 1][n]; + for (int j = 0; j < n; j++) { + encryptionTable[0][j] = ciphertexts.get(j); + } + return encryptionTable; + } + protected EncryptionRandomness[][] generateRandomnessesForRerandomize(int n,int layers){ + EncryptionRandomness[][] randomnesses = new EncryptionRandomness[layers][n]; + for (int layer = 0; layer < layers; layer++) + { + for (int i = 0; i < n; i++) { + randomnesses[layer][i] = encryptor.generateRandomness(random);; + } + } + return randomnesses; + } - BigInteger 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]; + protected MixNetwork createMixNetwork(int n){ + return new MixNetwork(new RandomPermutation(n,random)); + } - r1 = encryptor.generateRandomness(random); - r2 = encryptor.generateRandomness(random); + protected void rerandomize(int layers,MixNetwork mixNetwork, RerandomizableEncryptedMessage[][] encryptionTable + ,EncryptionRandomness[][] randomnesses) throws InvalidProtocolBufferException { + Switch[] switchesLayer; + int index1,index2; + RerandomizableEncryptedMessage e1,e2; + EncryptionRandomness r1,r2; + 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]; if (!sw.value) { encryptionTable[layer + 1][index1] = encryptor.rerandomize(e1, r1); encryptionTable[layer + 1][index2] = encryptor.rerandomize(e2, r2); @@ -88,13 +94,19 @@ public class Mixer implements meerkat.crypto.mixnet.Mixer { encryptionTable[layer + 1][index1] = encryptor.rerandomize(e2, r2); encryptionTable[layer + 1][index2] = encryptor.rerandomize(e1, r1); } - randomnesses[layer][index1] = r1; - randomnesses[layer][index2] = r2; - } - } - System.out.println("re enc time : " + BigInteger.valueOf(System.currentTimeMillis()).subtract(time)); - time = BigInteger.valueOf(System.currentTimeMillis()); - // main loop + } + } + } + + protected ZeroKnowledgeProof[][] createZKPTable(int n,int layers,MixNetwork mixNetwork, RerandomizableEncryptedMessage[][] encryptionTable + ,EncryptionRandomness[][] randomnesses) throws InvalidProtocolBufferException { + ZeroKnowledgeProof[][] proofsTable = new ZeroKnowledgeProof[layers][n]; + Switch[] switchesLayer; + int index1,index2; + int switchIndex = 0; + int nDiv2 = n >> 1; + RerandomizableEncryptedMessage e1,e2; + EncryptionRandomness r1,r2; for (int layer = 0; layer < layers; layer++) { switchesLayer = mixNetwork.getSwitchesByLayer(layer); @@ -114,7 +126,30 @@ public class Mixer implements meerkat.crypto.mixnet.Mixer { switchIndex = (switchIndex + 1) % nDiv2; } } + return proofsTable; + } + + public MixerOutput mix(List ciphertexts) throws InvalidProtocolBufferException { + + int n = ciphertexts.size(); + int nDiv2 = n >> 1; + + if (!inputBasicCheckSum(n)) + return null; + + int layers = (int) (2 * Math.log(n) / Math.log(2)) - 1; // layers = 2logn -1 + RerandomizableEncryptedMessage[][] encryptionTable = initializeEncryptionTable(n,layers,ciphertexts); + EncryptionRandomness[][] randomnesses = generateRandomnessesForRerandomize(n,layers); + MixNetwork mixNetwork = createMixNetwork(n); + + BigInteger time = BigInteger.valueOf(System.currentTimeMillis()); + rerandomize(layers,mixNetwork,encryptionTable,randomnesses); + System.out.println("re enc time : " + BigInteger.valueOf(System.currentTimeMillis()).subtract(time)); + + time = BigInteger.valueOf(System.currentTimeMillis()); + ZeroKnowledgeProof[][] proofsTable = createZKPTable(n,layers,mixNetwork,encryptionTable,randomnesses); System.out.println("zkp time : " + BigInteger.valueOf(System.currentTimeMillis()).subtract(time)); + return new mixer.MixerOutput(n,layers,proofsTable, encryptionTable); } diff --git a/mixer/src/main/java/prover/ElGamalProofOrganizer.java b/mixer/src/main/java/prover/ElGamalProofOrganizer.java index cec8256..540e944 100644 --- a/mixer/src/main/java/prover/ElGamalProofOrganizer.java +++ b/mixer/src/main/java/prover/ElGamalProofOrganizer.java @@ -9,7 +9,9 @@ import org.bouncycastle.math.ec.ECPoint; import qilin.primitives.concrete.ECGroup; /** - * Created by Tzlil on 12/30/2015. + * use for organize the input for each ZKP + * + * both prover and verifier implantation are using it */ public class ElGamalProofOrganizer { @@ -19,6 +21,11 @@ public class ElGamalProofOrganizer { private final byte[] gEncoded; private final byte[] hEncoded; + /** + * @param group + * @param g - generator of group + * @param h - h = g ^ SecretKey + */ public ElGamalProofOrganizer(ECGroup group, ECPoint g, ECPoint h){ this.group = group; this.g = g; @@ -35,37 +42,68 @@ public class ElGamalProofOrganizer { left, right, unknown } - //used by prover only - protected ElGamalProofInput createProofInput(Crypto.RerandomizableEncryptedMessage e1, Crypto.RerandomizableEncryptedMessage e2 - , Crypto.RerandomizableEncryptedMessage e1New, Crypto.RerandomizableEncryptedMessage e2New + /** + * can be used by prover only + * + * call to the main overload with flag = true + */ + protected ElGamalProofInput createProofInput(Crypto.RerandomizableEncryptedMessage in1, Crypto.RerandomizableEncryptedMessage in2 + , Crypto.RerandomizableEncryptedMessage out1, Crypto.RerandomizableEncryptedMessage out2 , 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); + //boolean flag = true; + return createProofInput(in1,in2,out1,out2,r1,r2,switched,true); } - // 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 { + /** + * can be used by anyone, e.g verifier + * + * call to the main overload with flag = false + */ + public ElGamalProofInput createProofInput(Crypto.RerandomizableEncryptedMessage in1, Crypto.RerandomizableEncryptedMessage in2 + , Crypto.RerandomizableEncryptedMessage out1, Crypto.RerandomizableEncryptedMessage out2) throws InvalidProtocolBufferException { + + // flag = false; + return createProofInput(in1,in2,out1,out2,null,null,false,false); + } + + /** + * inner method + * convert each encrypted message to ElGamalCiphertext + * + * @param flag - true if called by prover ( r1,r2,switched are known) + * @return ElGamalProofInput + * @throws InvalidProtocolBufferException - in case that at least one of the encrypted messages isn't + * ElGamalCiphertext + */ + private ElGamalProofInput createProofInput(Crypto.RerandomizableEncryptedMessage in1, Crypto.RerandomizableEncryptedMessage in2 + , Crypto.RerandomizableEncryptedMessage out1, Crypto.RerandomizableEncryptedMessage out2 + , Crypto.EncryptionRandomness r1, Crypto.EncryptionRandomness r2, boolean switched,boolean flag) + 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); + ConcreteCrypto.ElGamalCiphertext in1ElGamal = ECElGamalEncryption.RerandomizableEncryptedMessage2ElGamalCiphertext(in1); + ConcreteCrypto.ElGamalCiphertext in2ElGamal = ECElGamalEncryption.RerandomizableEncryptedMessage2ElGamalCiphertext(in2); + ConcreteCrypto.ElGamalCiphertext out1ElGamal = ECElGamalEncryption.RerandomizableEncryptedMessage2ElGamalCiphertext(out1); + ConcreteCrypto.ElGamalCiphertext out2ElGamal = ECElGamalEncryption.RerandomizableEncryptedMessage2ElGamalCiphertext(out2); - return new ElGamalProofInput(e1ElGamal,e2ElGamal,e1NewElGamal,e2NewElGamal); + if(flag) { + return new ElGamalProofInput(in1ElGamal, in2ElGamal, out1ElGamal, out2ElGamal, r1, r2, switched); + }else { + return new ElGamalProofInput(in1ElGamal, in2ElGamal, out1ElGamal, out2ElGamal); + } } + /** + * can be construct by instance of organizer only by calling createProofInput method (all constructors are private) + * + * in construction it use for preparing the input for prove, while avoiding double converting or calculations + * + * use as a container for 4 OrProofInput. + */ public class ElGamalProofInput { - private final OrProofInput first; private final OrProofInput second; private final OrProofInput third; @@ -75,100 +113,111 @@ public class ElGamalProofOrganizer { return group.decode(bs.toByteArray()); } + + /** + * @param flag - true if called by prover ( r1,r2,switched are known) + */ + private ElGamalProofInput(ConcreteCrypto.ElGamalCiphertext e1, ConcreteCrypto.ElGamalCiphertext e2 + , ConcreteCrypto.ElGamalCiphertext e1New, ConcreteCrypto.ElGamalCiphertext e2New + , Crypto.EncryptionRandomness r1, Crypto.EncryptionRandomness r2, boolean switched,boolean flag){ + + 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)); + + + if(!flag){ + + 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); + + }else { + + 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); + } + } + } + + + /** + * used by the prover + * call to the main constructor with flag = true + */ 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); - } - + //flag = true; + this(e1,e2,e1New,e2New,r1,r2,switched,true); } - + /** + * used by prover + * call to the main constructor with flag = true + */ 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); + //flag = false; + this(e1,e2,e1New,e2New,null,null,false,false); } - - + /** + * getter for all 4 OrProofInputs + * + * @param orProofOrder + * @return the required OrProof + */ public OrProofInput getOrProofInput(OrProofOrder orProofOrder) { switch (orProofOrder) { @@ -184,8 +233,16 @@ public class ElGamalProofOrganizer { return null; } } - public class OrProofInput{ + + /** + * can't be constructed (all constructors are private) + * + * 4 instances will be constructed for each new ElGamalProofInput + * + * container for all necessary inputs for single OrProof + */ + public class OrProofInput{ public final ECPoint g1; public final ECPoint h1; public final ECPoint g2; @@ -195,6 +252,7 @@ public class ElGamalProofOrganizer { public final ECPoint g2Tag; public final ECPoint h2Tag; + // can be access by prover only protected final byte[] g1Encoded; protected final byte[] h1Encoded; protected final byte[] g2Encoded; @@ -203,10 +261,12 @@ public class ElGamalProofOrganizer { protected final byte[] h1TagEncoded; protected final byte[] g2TagEncoded; protected final byte[] h2TagEncoded; - protected final Crypto.EncryptionRandomness x; protected final TrueCouple flag; + /** + * used by prover only + */ private OrProofInput(ECPoint h1, ECPoint h2, ECPoint h1Tag, ECPoint h2Tag ,byte[] h1Encoded, byte[] h2Encoded, byte[] h1TagEncoded, byte[] h2TagEncoded , Crypto.EncryptionRandomness x, TrueCouple flag) { @@ -232,6 +292,10 @@ public class ElGamalProofOrganizer { this.flag = flag; } + + /** + * use by verifier + */ 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/Prover.java b/mixer/src/main/java/prover/Prover.java index 93c2536..93fba71 100644 --- a/mixer/src/main/java/prover/Prover.java +++ b/mixer/src/main/java/prover/Prover.java @@ -4,7 +4,6 @@ import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; import meerkat.crypto.concrete.ECElGamalEncryption; import meerkat.crypto.mixnet.Mix2ZeroKnowledgeProver; -import meerkat.protobuf.ConcreteCrypto.ElGamalCiphertext; import meerkat.protobuf.Crypto; import meerkat.protobuf.Mixing; import org.bouncycastle.math.ec.ECPoint; @@ -14,26 +13,52 @@ import qilin.primitives.concrete.ECGroup; import java.math.BigInteger; import java.util.Random; + +/** + * implements of Mix2ZeroKnowledgeProver interface + * this implantation assumes that each RerandomizableEncryptedMessage is ElGamalCiphertext + */ public class Prover implements Mix2ZeroKnowledgeProver { - ECGroup group; - RandomOracle randomOracle; - Random rand; - ECElGamalEncryption ecElGamalEncryption; - ECPoint g,h; - ElGamalProofOrganizer organizer; + private final ECGroup group; + private final RandomOracle randomOracle; + private final Random rand; + private final ECElGamalEncryption encryptor; + private final ECPoint g,h; + private final BigInteger groupOrderUpperBound; + private final ElGamalProofOrganizer organizer; + /** + * @param rand + * @param encryptor + * @param randomOracle - use for Fiat–Shamir heuristic + */ public Prover(Random rand,ECElGamalEncryption encryptor,RandomOracle randomOracle) { this.rand = rand; - this.ecElGamalEncryption = encryptor; + this.encryptor = encryptor; this.randomOracle = randomOracle; - this.group = ecElGamalEncryption.getGroup(); + this.group = this.encryptor.getGroup(); this.g = group.getGenerator(); - this.h = ecElGamalEncryption.getElGamalPK().getPK(); + this.h = this.encryptor.getElGamalPK().getPK(); this.organizer = new ElGamalProofOrganizer(group,g,h); + this.groupOrderUpperBound = group.orderUpperBound(); } + /** + * @param in1 + * @param in2 + * @param out1 - if sw then out1 = rerandomize(in2,r2) else out1 = rerandomize(in1,r1) + * @param out2 - if sw then out2 = rerandomize(in1,r1) else out1 = rerandomize(in2,r2) + * @param sw - flag + * @param i - column of in1 and out1 in encryption table + * @param j - column of in2 and out2 in encryption table + * @param layer - row of in1,in2 in encryption table + * @param r1 + * @param r2 + * @return - a valid ZKP that indeed out1,out2 calculated as required + * @throws InvalidProtocolBufferException + */ public Mixing.ZeroKnowledgeProof prove(Crypto.RerandomizableEncryptedMessage in1, Crypto.RerandomizableEncryptedMessage in2, Crypto.RerandomizableEncryptedMessage out1, @@ -67,12 +92,22 @@ public class Prover implements Mix2ZeroKnowledgeProver { } - public BigInteger hash(Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle input) { + /** + * Fiat–Shamir heuristic + * @param input - protobuf contains all parameters from the first step of the current prove + * @return randomOracle.hash(input) + */ + private BigInteger hash(Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle input) { byte[] arr = input.toByteArray(); return new BigInteger(this.randomOracle.hash(arr,arr.length)); } + /** + * @param orProofInput + * @return ZKP OrProof: there exists x s.t (g1 ^ x == h1 and g2 ^ x == h2) or (g1' ^ x == h1 and g2' ^ x == h2) + * assuming DLog is hard in this.group then that proves x is known for the prover + */ private Mixing.ZeroKnowledgeProof.OrProof createOrProofElGamal(ElGamalProofOrganizer.OrProofInput orProofInput) { ECPoint g1 = orProofInput.g1; @@ -85,7 +120,7 @@ public class Prover implements Mix2ZeroKnowledgeProver { ECPoint g2Tag = orProofInput.g2Tag; ECPoint h2Tag = orProofInput.h2Tag; - BigInteger r = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound()); + BigInteger r = new BigInteger(encryptor.generateRandomness(rand).getData().toByteArray()).mod(groupOrderUpperBound); BigInteger c1,c2,z,zTag; ECPoint u,v,uTag,vTag; Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle forRandomOracle; @@ -93,8 +128,8 @@ public class Prover implements Mix2ZeroKnowledgeProver { 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()); + c2 = new BigInteger(encryptor.generateRandomness(rand).getData().toByteArray()).mod(groupOrderUpperBound); + zTag = new BigInteger(encryptor.generateRandomness(rand).getData().toByteArray()).mod(groupOrderUpperBound); //step 1 u = group.multiply(g1, r); v = group.multiply(g2, r); @@ -109,22 +144,22 @@ public class Prover implements Mix2ZeroKnowledgeProver { .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)) + .setH1Tag(ByteString.copyFrom(orProofInput.h1TagEncoded)) + .setG2Tag(ByteString.copyFrom(orProofInput.g2TagEncoded)) + .setH2Tag(ByteString.copyFrom(orProofInput.h2TagEncoded)) .setU(ByteString.copyFrom(group.encode(u))) .setV(ByteString.copyFrom(group.encode(v))) .setUTag(ByteString.copyFrom(group.encode(uTag))) .setVTag(ByteString.copyFrom(group.encode(vTag))) .build(); - c1 = hash(forRandomOracle).add(group.orderUpperBound().subtract(c2)).mod(group.orderUpperBound()); + c1 = hash(forRandomOracle).add(group.orderUpperBound().subtract(c2)).mod(groupOrderUpperBound); //step 3 //z = (r + c1 * x) % group size; - z = r.add(c1.multiply(new BigInteger(orProofInput.x.getData().toByteArray()))).mod(group.orderUpperBound()); + z = r.add(c1.multiply(new BigInteger(orProofInput.x.getData().toByteArray()))).mod(groupOrderUpperBound); break; case right: - c1 = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound()); - z = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound()); + c1 = new BigInteger(encryptor.generateRandomness(rand).getData().toByteArray()).mod(groupOrderUpperBound); + z = new BigInteger(encryptor.generateRandomness(rand).getData().toByteArray()).mod(groupOrderUpperBound); //step 1 uTag = group.multiply(g1Tag, r); vTag = group.multiply(g2Tag, r); @@ -139,29 +174,23 @@ public class Prover implements Mix2ZeroKnowledgeProver { .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)) + .setH1Tag(ByteString.copyFrom(orProofInput.h1TagEncoded)) + .setG2Tag(ByteString.copyFrom(orProofInput.g2TagEncoded)) + .setH2Tag(ByteString.copyFrom(orProofInput.h2TagEncoded)) .setU(ByteString.copyFrom(group.encode(u))) .setV(ByteString.copyFrom(group.encode(v))) .setUTag(ByteString.copyFrom(group.encode(uTag))) .setVTag(ByteString.copyFrom(group.encode(vTag))) .build(); - c2 = hash(forRandomOracle).add(group.orderUpperBound().subtract(c1)).mod(group.orderUpperBound()); + c2 = hash(forRandomOracle).add(group.orderUpperBound().subtract(c1)).mod(groupOrderUpperBound); //step 3 //zTag = (r + c2 * x) % group size; - zTag = r.add(c2.multiply(new BigInteger(orProofInput.x.getData().toByteArray()))).mod(group.orderUpperBound()); + zTag = r.add(c2.multiply(new BigInteger(orProofInput.x.getData().toByteArray()))).mod(groupOrderUpperBound); 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)))); - return Mixing.ZeroKnowledgeProof.OrProof.newBuilder() .setG1(forRandomOracle.getG1()) diff --git a/mixer/src/main/java/verifier/Verifier.java b/mixer/src/main/java/verifier/Verifier.java index efe77aa..94c6084 100644 --- a/mixer/src/main/java/verifier/Verifier.java +++ b/mixer/src/main/java/verifier/Verifier.java @@ -1,10 +1,8 @@ package verifier; -import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; import meerkat.crypto.concrete.ECElGamalEncryption; import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier; -import meerkat.protobuf.ConcreteCrypto.ElGamalCiphertext; import meerkat.protobuf.Crypto; import meerkat.protobuf.Mixing; import org.bouncycastle.math.ec.ECPoint; @@ -20,20 +18,12 @@ import java.util.List; public class Verifier implements Mix2ZeroKnowledgeVerifier { - /** - * Return true iff the proof is valid. - * @param in1 - * @param in2 - * @param out1 - * @param out2 - * @return - */ - - ECGroup group; - RandomOracle randomOracle; - ECElGamalEncryption encryptor; - ECPoint g,h; - ElGamalProofOrganizer organizer; + private final ECGroup group; + private final RandomOracle randomOracle; + private final ECElGamalEncryption encryptor; + private final ECPoint g,h; + private final ElGamalProofOrganizer organizer; + private final ZeroKnowledgeOrProofParser parser; public Verifier(ECElGamalEncryption encryptor, RandomOracle randomOracle) { this.encryptor = encryptor; @@ -42,18 +32,16 @@ public class Verifier implements Mix2ZeroKnowledgeVerifier { this.h = encryptor.getElGamalPK().getPK(); this.randomOracle = randomOracle; this.organizer = new ElGamalProofOrganizer(group,g,h); + this.parser = new ZeroKnowledgeOrProofParser(group); } public BigInteger hash(Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle input) { byte[] arr = input.toByteArray(); return new BigInteger(this.randomOracle.hash(arr,arr.length)); } - - private ECPoint convert2ECPoint(ByteString bs){ - return group.decode(bs.toByteArray()); - } - - + /** + * @return true iff the proof is valid + */ public boolean verify(Crypto.RerandomizableEncryptedMessage in1, Crypto.RerandomizableEncryptedMessage in2, Crypto.RerandomizableEncryptedMessage out1, @@ -67,97 +55,62 @@ public class Verifier implements Mix2ZeroKnowledgeVerifier { } - 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()) - .setG2(orProof.getG2()) - .setH2(orProof.getH2()) - .setG1Tag(orProof.getG1Tag()) - .setH1Tag(orProof.getH1Tag()) - .setG2Tag(orProof.getG2Tag()) - .setH2Tag(orProof.getH2Tag()) - .setU(orProof.getU()) - .setV(orProof.getV()) - .setUTag(orProof.getUTag()) - .setVTag(orProof.getVTag()) - .build(); - g1 = convert2ECPoint(orProof.getG1()); - g2 = convert2ECPoint(orProof.getG2()); - h1 = convert2ECPoint(orProof.getH1()); - h2 = convert2ECPoint(orProof.getH2()); - g1Tag = convert2ECPoint(orProof.getG1Tag()); - g2Tag = convert2ECPoint(orProof.getG2Tag()); - h1Tag = convert2ECPoint(orProof.getH1Tag()); - h2Tag = convert2ECPoint(orProof.getH2Tag()); - u = convert2ECPoint(orProof.getU()); - v = convert2ECPoint(orProof.getV()); - uTag = convert2ECPoint(orProof.getUTag()); - vTag = convert2ECPoint(orProof.getVTag()); - c1 = new BigInteger(orProof.getC1().toByteArray()); - c2 = new BigInteger(orProof.getC2().toByteArray()); - z = new BigInteger(orProof.getZ().toByteArray()); - zTag = new BigInteger(orProof.getZTag().toByteArray()); - } - private List createConditionsList(ElGamalProofOrganizer.OrProofInput orProofInput){ - List conditions = new ArrayList(); - 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")); - 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(ElGamalProofOrganizer.OrProofInput orProofInput, Mixing.ZeroKnowledgeProof.OrProof orProof) - - { - parseOrProof(orProof); - List conditions = createConditionsList(orProofInput); + public boolean verifyElGamaOrProof(ElGamalProofOrganizer.OrProofInput orProofInput, + Mixing.ZeroKnowledgeProof.OrProof orProof) { + ZeroKnowledgeOrProofParser.ZeroKnowledgeOrProofContainer container = parser.parseOrProof(orProof); + List conditions = createConditionsList(orProofInput,container); boolean result = true; - for (Condition condition: conditions) { + for (Condition condition: conditions) { //temporary if(!condition.test()){ if (result){ result = false; System.out.print("\n\n\n"); } - System.out.println(condition.errorDescripton); + System.out.println(condition.errorDescription); } } return result; } + + private List createConditionsList(ElGamalProofOrganizer.OrProofInput orProofInput + ,ZeroKnowledgeOrProofParser.ZeroKnowledgeOrProofContainer container){ + List conditions = new ArrayList(); + conditions.add(new Condition( container.g1,orProofInput.g1,"g1 != g")); + conditions.add(new Condition( container.h1,orProofInput.h1,"h1 != e1New.c1/e1.c1")); + conditions.add(new Condition( container.g2,orProofInput.g2,"g2 != h")); + conditions.add(new Condition( container.h2,orProofInput.h2,"h2 != e1New.c2/e1.c2")); + conditions.add(new Condition( container.g1Tag,orProofInput.g1Tag,"g1Tag != g")); + conditions.add(new Condition( container.h1Tag,orProofInput.h1Tag,"h1Tag != e2New.c1/e2.c1")); + conditions.add(new Condition( container.g2Tag,orProofInput.g2Tag,"g2Tag != h")); + conditions.add(new Condition( container.h2Tag,orProofInput.h2Tag,"h2Tag != e2New.c2/e2.c2")); + conditions.add(new Condition(container.c1.add(container.c2).mod(group.orderUpperBound()), + hash(container.forRandomOracle).mod(group.orderUpperBound()).mod(group.orderUpperBound()), + "(c1 + c2 ) % group size == hash (imput + step1) % group size")); + conditions.add(new Condition( group.multiply(container.g1, container.z), + group.add(container.u, group.multiply(container.h1,container.c1)),"g1 ^ z != u * ( h1 ^ c1 )")); + conditions.add(new Condition( group.multiply(container.g2, container.z), + group.add(container.v, group.multiply(container.h2,container.c1)),"g2 ^ z != v * ( h2 ^ c1 )")); + conditions.add(new Condition( group.multiply(container.g1Tag, container.zTag), + group.add(container.uTag, group.multiply(container.h1Tag,container.c2)) + ,"g1Tag ^ zTag != uTag * ( h1Tag ^ c2 )")); + conditions.add(new Condition( group.multiply(container.g2Tag, container.zTag), + group.add(container.vTag, group.multiply(container.h2Tag,container.c2)) + ,"g2Tag ^ zTag != vTag * ( h2Tag ^ c2 )")); + return conditions; + } + private class Condition{ T given, expected; - String errorDescripton; + String errorDescription; - Condition(T given,T expected,String descripton){ + Condition(T given,T expected,String description){ this.given = given; - this.errorDescripton = descripton; + this.errorDescription = description; this.expected = expected; } diff --git a/mixer/src/main/java/verifier/ZeroKnowledgeOrProofParser.java b/mixer/src/main/java/verifier/ZeroKnowledgeOrProofParser.java new file mode 100644 index 0000000..d3f82a5 --- /dev/null +++ b/mixer/src/main/java/verifier/ZeroKnowledgeOrProofParser.java @@ -0,0 +1,69 @@ +package verifier; + +import com.google.protobuf.ByteString; +import meerkat.protobuf.Mixing; +import org.bouncycastle.math.ec.ECPoint; +import qilin.primitives.concrete.ECGroup; + +import java.math.BigInteger; + +/** + * Created by Tzlil on 1/25/2016. + */ +public class ZeroKnowledgeOrProofParser { + + private final ECGroup group; + public ZeroKnowledgeOrProofParser(ECGroup group) { + this.group = group; + } + + public ECPoint convert2ECPoint(ByteString bs){ + return group.decode(bs.toByteArray()); + } + + public ZeroKnowledgeOrProofContainer parseOrProof(Mixing.ZeroKnowledgeProof.OrProof orProof){ + return new ZeroKnowledgeOrProofContainer(orProof); + } + + public class ZeroKnowledgeOrProofContainer{ + public final ECPoint g1,g2,h1,h2; + public final ECPoint g1Tag,g2Tag,h1Tag,h2Tag; + public final ECPoint u,v,uTag,vTag; + public final BigInteger c1,c2,z,zTag; + public final Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle forRandomOracle; + + private ZeroKnowledgeOrProofContainer(Mixing.ZeroKnowledgeProof.OrProof orProof){ + this.forRandomOracle = + Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle.newBuilder() + .setG1(orProof.getG1()) + .setH1(orProof.getH1()) + .setG2(orProof.getG2()) + .setH2(orProof.getH2()) + .setG1Tag(orProof.getG1Tag()) + .setH1Tag(orProof.getH1Tag()) + .setG2Tag(orProof.getG2Tag()) + .setH2Tag(orProof.getH2Tag()) + .setU(orProof.getU()) + .setV(orProof.getV()) + .setUTag(orProof.getUTag()) + .setVTag(orProof.getVTag()) + .build(); + this.g1 = convert2ECPoint(orProof.getG1()); + this.g2 = convert2ECPoint(orProof.getG2()); + this.h1 = convert2ECPoint(orProof.getH1()); + this.h2 = convert2ECPoint(orProof.getH2()); + this.g1Tag = convert2ECPoint(orProof.getG1Tag()); + this.g2Tag = convert2ECPoint(orProof.getG2Tag()); + this.h1Tag = convert2ECPoint(orProof.getH1Tag()); + this.h2Tag = convert2ECPoint(orProof.getH2Tag()); + this.u = convert2ECPoint(orProof.getU()); + this.v = convert2ECPoint(orProof.getV()); + this.uTag = convert2ECPoint(orProof.getUTag()); + this.vTag = convert2ECPoint(orProof.getVTag()); + this.c1 = new BigInteger(orProof.getC1().toByteArray()); + this.c2 = new BigInteger(orProof.getC2().toByteArray()); + this.z = new BigInteger(orProof.getZ().toByteArray()); + this.zTag = new BigInteger(orProof.getZTag().toByteArray()); + } + } +} diff --git a/mixer/src/test/java/mixer/RerandomizeTest.java b/mixer/src/test/java/mixer/RerandomizeTest.java index f98bc1e..c607f61 100644 --- a/mixer/src/test/java/mixer/RerandomizeTest.java +++ b/mixer/src/test/java/mixer/RerandomizeTest.java @@ -3,20 +3,16 @@ package mixer; 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 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 java.math.BigInteger; import java.util.Random; @@ -63,8 +59,8 @@ public class RerandomizeTest { assert (Utiles.decrypt(Voting.PlaintextBallot.class, key, group, e).equals(msg)); assert (Utiles.decrypt(Voting.PlaintextBallot.class, key, group, eNew).equals(msg)); - ConcreteCrypto.ElGamalCiphertext eElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e); - ConcreteCrypto.ElGamalCiphertext eNewElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(eNew); + ConcreteCrypto.ElGamalCiphertext eElGamal = ECElGamalEncryption.RerandomizableEncryptedMessage2ElGamalCiphertext(e); + 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()))))); diff --git a/mixer/src/test/java/mixer/ZeroKnowledgeProofTest.java b/mixer/src/test/java/mixer/ZeroKnowledgeProofTest.java index a0952e2..5bfedc8 100644 --- a/mixer/src/test/java/mixer/ZeroKnowledgeProofTest.java +++ b/mixer/src/test/java/mixer/ZeroKnowledgeProofTest.java @@ -70,10 +70,10 @@ public class ZeroKnowledgeProofTest { ECPoint g = group.getGenerator(); ECPoint h = enc.getElGamalPK().getPK(); - ConcreteCrypto.ElGamalCiphertext e1ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e1); - ConcreteCrypto.ElGamalCiphertext e2ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e2); - ConcreteCrypto.ElGamalCiphertext e1TagElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e1New); - ConcreteCrypto.ElGamalCiphertext e2TagElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e2New); + ConcreteCrypto.ElGamalCiphertext e1ElGamal = ECElGamalEncryption.RerandomizableEncryptedMessage2ElGamalCiphertext(e1); + ConcreteCrypto.ElGamalCiphertext e2ElGamal = ECElGamalEncryption.RerandomizableEncryptedMessage2ElGamalCiphertext(e2); + ConcreteCrypto.ElGamalCiphertext e1TagElGamal = ECElGamalEncryption.RerandomizableEncryptedMessage2ElGamalCiphertext(e1New); + ConcreteCrypto.ElGamalCiphertext e2TagElGamal = ECElGamalEncryption.RerandomizableEncryptedMessage2ElGamalCiphertext(e2New); assert (g.multiply(new BigInteger(r1.getData().toByteArray())).equals( diff --git a/mixer/src/test/java/profiling/BigInteger/AddSub.java b/mixer/src/test/java/profiling/BigInteger/AddSub.java new file mode 100644 index 0000000..1505aca --- /dev/null +++ b/mixer/src/test/java/profiling/BigInteger/AddSub.java @@ -0,0 +1,69 @@ +package profiling.BigInteger; + +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.crypto.concrete.ECElGamalEncryption; +import meerkat.protobuf.ConcreteCrypto; +import meerkat.protobuf.Voting; +import mixer.Utiles; +import org.junit.Before; +import org.junit.Test; +import qilin.primitives.RandomOracle; +import qilin.primitives.concrete.ECElGamal; +import qilin.primitives.concrete.ECGroup; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/21/2016. + */ +public class AddSub { + + int tests; + BigInteger[] randoms; + BigInteger[] randoms2; + + @Before + public void setup() throws Exception { + Random rand = new Random(); + tests = 1 << 17; + randoms = new BigInteger[tests]; + rand = new Random(); + + ECGroup group = new ECGroup("secp256k1"); + BigInteger sk = ECElGamal.generateSecretKey(group, rand); + ECElGamal.SK key = new ECElGamal.SK(group, sk); + ConcreteCrypto.ElGamalPublicKey serializedPk = Utiles.serializePk(group, key); + ECElGamalEncryption enc = new ECElGamalEncryption(); + enc.init(serializedPk); + + for (int i =0 ; i < tests ; i++){ + randoms[i] = new BigInteger(enc.generateRandomness(rand).getData().toByteArray()); + } + randoms2 = new BigInteger[tests]; + for (int i =0 ; i < tests ; i++){ + randoms2[i] = new BigInteger(enc.generateRandomness(rand).getData().toByteArray()); + } + + } + + @Test + public void AddSubProfiling() throws InvalidProtocolBufferException { + + System.out.println("AddSub"); + System.out.println("#" + tests + " tests"); + long startTime = System.currentTimeMillis(); + int i = 0; + while (i < randoms.length / 2) { + randoms[i].add(randoms2[i]); + i++; + } + while (i < randoms.length) { + randoms[i].subtract(randoms2[i]); + i++; + } + long finishTime = System.currentTimeMillis(); + System.out.println(" that took: "+(finishTime-startTime)+ " ms"); + System.out.println(" avg of "+((double)(finishTime-startTime))/tests + " ms"); + } +} diff --git a/mixer/src/test/java/profiling/BigInteger/GenerateRandomness.java b/mixer/src/test/java/profiling/BigInteger/GenerateRandomness.java new file mode 100644 index 0000000..837fcc5 --- /dev/null +++ b/mixer/src/test/java/profiling/BigInteger/GenerateRandomness.java @@ -0,0 +1,49 @@ +package profiling.BigInteger; + +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.crypto.concrete.ECElGamalEncryption; +import meerkat.protobuf.ConcreteCrypto; +import mixer.Utiles; +import org.junit.Before; +import org.junit.Test; +import qilin.primitives.concrete.ECElGamal; +import qilin.primitives.concrete.ECGroup; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/25/2016. + */ +public class GenerateRandomness { + int tests; + ECElGamalEncryption enc; + Random rand; + @Before + public void setup() throws Exception { + rand = new Random(); + ECGroup group = new ECGroup("secp256k1"); + tests = 1<<18; + + BigInteger sk = ECElGamal.generateSecretKey(group, rand); + ECElGamal.SK key = new ECElGamal.SK(group, sk); + ConcreteCrypto.ElGamalPublicKey serializedPk = Utiles.serializePk(group, key); + enc = new ECElGamalEncryption(); + enc.init(serializedPk); + + } + + @Test + public void GenerateRandomnessProfiling() throws InvalidProtocolBufferException { + + System.out.println("GenerateRandomnessProfiling"); + System.out.println("#" + tests + " tests"); + long startTime = System.currentTimeMillis(); + for (int i =0 ; i < tests ; i++){ + enc.generateRandomness(rand).getData().toByteArray(); + } + long finishTime = System.currentTimeMillis(); + System.out.println(" that took: "+(finishTime-startTime)+ " ms"); + System.out.println(" avg of "+((double)(finishTime-startTime))/tests + " ms"); + } +} diff --git a/mixer/src/test/java/profiling/BigInteger/Modulo.java b/mixer/src/test/java/profiling/BigInteger/Modulo.java new file mode 100644 index 0000000..a1757ee --- /dev/null +++ b/mixer/src/test/java/profiling/BigInteger/Modulo.java @@ -0,0 +1,57 @@ +package profiling.BigInteger; + +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.crypto.concrete.ECElGamalEncryption; +import meerkat.protobuf.ConcreteCrypto; +import meerkat.protobuf.Voting; +import mixer.Utiles; +import org.junit.Before; +import org.junit.Test; +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/21/2016. + */ +public class Modulo { + int tests; + BigInteger[] randoms; + BigInteger orderUpperBound; + + @Before + public void setup() throws Exception { + Random rand = new Random(); + ECGroup group = new ECGroup("secp256k1"); + orderUpperBound = group.orderUpperBound(); + tests = 1<<17; + randoms = new BigInteger[tests]; + + BigInteger sk = ECElGamal.generateSecretKey(group, rand); + ECElGamal.SK key = new ECElGamal.SK(group, sk); + ConcreteCrypto.ElGamalPublicKey serializedPk = Utiles.serializePk(group, key); + ECElGamalEncryption enc = new ECElGamalEncryption(); + enc.init(serializedPk); + for (int i =0 ; i < tests ; i++){ + randoms[i] = new BigInteger(enc.generateRandomness(rand).getData().toByteArray()); + } + } + + @Test + public void ModuloProfiling() throws InvalidProtocolBufferException { + + System.out.println("ModuloProfiling"); + System.out.println("#" + tests + " tests"); + long startTime = System.currentTimeMillis(); + for (int i = 0 ; i < randoms.length;i++) { + randoms[i].mod(orderUpperBound); + } + long finishTime = System.currentTimeMillis(); + System.out.println(" that took: "+(finishTime-startTime)+ " ms"); + System.out.println(" avg of "+((double)(finishTime-startTime))/tests + " ms"); + } +} diff --git a/mixer/src/test/java/profiling/BigInteger/Mul.java b/mixer/src/test/java/profiling/BigInteger/Mul.java new file mode 100644 index 0000000..9656255 --- /dev/null +++ b/mixer/src/test/java/profiling/BigInteger/Mul.java @@ -0,0 +1,63 @@ +package profiling.BigInteger; + +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.crypto.concrete.ECElGamalEncryption; +import meerkat.protobuf.ConcreteCrypto; +import mixer.Utiles; +import org.junit.Before; +import org.junit.Test; +import qilin.primitives.concrete.ECElGamal; +import qilin.primitives.concrete.ECGroup; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/25/2016. + */ +public class Mul { + + int tests; + BigInteger[] randoms; + BigInteger[] randoms2; + + @Before + public void setup() throws Exception { + Random rand = new Random(); + tests = 1 << 17; + randoms = new BigInteger[tests]; + rand = new Random(); + + ECGroup group = new ECGroup("secp256k1"); + BigInteger sk = ECElGamal.generateSecretKey(group, rand); + ECElGamal.SK key = new ECElGamal.SK(group, sk); + ConcreteCrypto.ElGamalPublicKey serializedPk = Utiles.serializePk(group, key); + ECElGamalEncryption enc = new ECElGamalEncryption(); + enc.init(serializedPk); + + for (int i =0 ; i < tests ; i++){ + randoms[i] = new BigInteger(enc.generateRandomness(rand).getData().toByteArray()); + } + randoms2 = new BigInteger[tests]; + for (int i =0 ; i < tests ; i++){ + randoms2[i] = new BigInteger(enc.generateRandomness(rand).getData().toByteArray()); + } + + } + + @Test + public void MulProfiling() throws InvalidProtocolBufferException { + + System.out.println("Mul"); + System.out.println("#" + tests + " tests"); + long startTime = System.currentTimeMillis(); + int i = 0; + while (i < randoms.length) { + randoms[i].multiply(randoms2[i]); + i++; + } + long finishTime = System.currentTimeMillis(); + System.out.println(" that took: "+(finishTime-startTime)+ " ms"); + System.out.println(" avg of "+((double)(finishTime-startTime))/tests + " ms"); + } +} diff --git a/mixer/src/test/java/profiling/BigInteger/SHA256.java b/mixer/src/test/java/profiling/BigInteger/SHA256.java new file mode 100644 index 0000000..7e086a4 --- /dev/null +++ b/mixer/src/test/java/profiling/BigInteger/SHA256.java @@ -0,0 +1,57 @@ +package profiling.BigInteger; + +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.crypto.concrete.ECElGamalEncryption; +import meerkat.protobuf.ConcreteCrypto; +import meerkat.protobuf.Crypto; +import meerkat.protobuf.Mixing; +import meerkat.protobuf.Voting; +import mixer.Utiles; +import org.junit.Before; +import org.junit.Test; +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/25/2016. + */ +public class SHA256 { + final int LENGTH = 420; + int tests; + BigInteger[] randoms; + RandomOracle randomOracle; + + @Before + public void setup() throws Exception { + Random rand = new Random(); + randomOracle = new DigestOracle(); + tests = 1<<15; + Voting.PlaintextBallot msg; + randoms = new BigInteger[tests]; + byte[] arr = new byte[LENGTH]; + for (int i =0 ; i < tests ; i++){ + rand.nextBytes(arr); + randoms[i] = new BigInteger(arr); + } + } + + @Test + public void SHA256Profiling() throws InvalidProtocolBufferException { + + System.out.println("SHA256Profiling"); + System.out.println("#" + tests + " tests"); + long startTime = System.currentTimeMillis(); + for (int i = 0 ; i < randoms.length;i++) { + byte[] arr = randoms[i].toByteArray(); + new BigInteger(this.randomOracle.hash(arr, arr.length)); + } + long finishTime = System.currentTimeMillis(); + System.out.println(" that took: "+(finishTime-startTime)+ " ms"); + System.out.println(" avg of "+((double)(finishTime-startTime))/tests + " ms"); + } +} diff --git a/mixer/src/test/java/profiling/Convert/ByteString2ECPoint.java b/mixer/src/test/java/profiling/Convert/ByteString2ECPoint.java new file mode 100644 index 0000000..77d1a68 --- /dev/null +++ b/mixer/src/test/java/profiling/Convert/ByteString2ECPoint.java @@ -0,0 +1,73 @@ +package profiling.Convert; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.crypto.concrete.ECElGamalEncryption; +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 qilin.primitives.concrete.ECElGamal; +import qilin.primitives.concrete.ECGroup; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/25/2016. + */ +public class ByteString2ECPoint { + Random rand; + ECElGamal.SK key; + ECGroup group; + ECElGamalEncryption enc; + ConcreteCrypto.ElGamalPublicKey serializedPk; + int tests; + ConcreteCrypto.ElGamalCiphertext[] 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); + tests = 1024 * 19; + encryptedMessage = new ConcreteCrypto.ElGamalCiphertext[tests]; + + Voting.PlaintextBallot msg; + + for (int i = 0; i < tests; i ++){ + msg = Utiles.genRandomBallot(2,3,16); + + encryptedMessage[i] = ECElGamalEncryption.RerandomizableEncryptedMessage2ElGamalCiphertext + (enc.encrypt(msg, enc.generateRandomness(rand))); + } + } + private ECPoint convert2ECPoint(ByteString bs){ + return group.decode(bs.toByteArray()); + } + + @Test + public void ByteString2ECPointProfiling() throws InvalidProtocolBufferException { + + System.out.println("ByteString2ECPointProfiling"); + System.out.println("#"+ tests + " tests"); + System.out.println("start tests operations"); + long startTime = System.currentTimeMillis(); + + for (int i = 0; i < tests; i ++){ + convert2ECPoint(encryptedMessage[i].getC1()); + convert2ECPoint(encryptedMessage[i].getC2()); + } + + long finishTime = System.currentTimeMillis(); + System.out.println(" that took: "+(finishTime-startTime)+ " ms"); + System.out.println(" avg of "+((double)(finishTime-startTime))/ (2 * tests) + " ms"); + } +} diff --git a/mixer/src/test/java/profiling/Convert/RerandomizableEncryptedMessage2ElGamalCiphertext.java b/mixer/src/test/java/profiling/Convert/RerandomizableEncryptedMessage2ElGamalCiphertext.java new file mode 100644 index 0000000..8639911 --- /dev/null +++ b/mixer/src/test/java/profiling/Convert/RerandomizableEncryptedMessage2ElGamalCiphertext.java @@ -0,0 +1,67 @@ +package profiling.Convert; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.crypto.concrete.ECElGamalEncryption; +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 qilin.primitives.concrete.ECElGamal; +import qilin.primitives.concrete.ECGroup; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/25/2016. + */ +public class RerandomizableEncryptedMessage2ElGamalCiphertext { + Random rand; + ECElGamal.SK key; + ECGroup group; + ECElGamalEncryption enc; + ConcreteCrypto.ElGamalPublicKey serializedPk; + int tests; + 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); + tests = 1024 * 18; + encryptedMessage = new Crypto.RerandomizableEncryptedMessage[tests]; + + Voting.PlaintextBallot msg; + + for (int i = 0; i < tests; i ++){ + msg = Utiles.genRandomBallot(2,3,16); + + encryptedMessage[i] = enc.encrypt(msg, enc.generateRandomness(rand)); + } + } + @Test + public void RerandomizableEncryptedMessage2ElGamalCiphertext() throws InvalidProtocolBufferException { + + System.out.println("RerandomizableEncryptedMessage2ElGamalCiphertext"); + System.out.println("#"+ tests + " tests"); + System.out.println("start tests operations"); + long startTime = System.currentTimeMillis(); + + for (int i = 0; i < tests; i ++){ + ECElGamalEncryption.RerandomizableEncryptedMessage2ElGamalCiphertext(encryptedMessage[i]); + } + + long finishTime = System.currentTimeMillis(); + System.out.println(" that took: "+(finishTime-startTime)+ " ms"); + System.out.println(" avg of "+((double)(finishTime-startTime))/ tests + " ms"); + } +} diff --git a/mixer/src/test/java/profiling/ECGroupProfiling/AddProfiling.java b/mixer/src/test/java/profiling/ECGroup/Add.java similarity index 93% rename from mixer/src/test/java/profiling/ECGroupProfiling/AddProfiling.java rename to mixer/src/test/java/profiling/ECGroup/Add.java index 3c9880f..31865b9 100644 --- a/mixer/src/test/java/profiling/ECGroupProfiling/AddProfiling.java +++ b/mixer/src/test/java/profiling/ECGroup/Add.java @@ -1,4 +1,4 @@ -package profiling.ECGroupProfiling; +package profiling.ECGroup; import com.google.protobuf.InvalidProtocolBufferException; import meerkat.crypto.concrete.ECElGamalEncryption; @@ -17,7 +17,7 @@ import java.util.Random; /** * Created by Tzlil on 1/20/2016. */ -public class AddProfiling { +public class Add { ECElGamalEncryption encryptor; ECGroup group; @@ -48,7 +48,7 @@ public class AddProfiling { @Test public void addProfiling() throws InvalidProtocolBufferException { - System.out.println("Add"); + System.out.println("AddSub"); System.out.println("n is : " + n); System.out.println("start n operations"); long startTime = System.currentTimeMillis(); @@ -60,6 +60,6 @@ public class AddProfiling { long finishTime = System.currentTimeMillis(); System.out.println(" that took: "+(finishTime-startTime)+ " ms"); - System.out.println(" avg of"+((double)(finishTime-startTime))/(n * n)+ " ms"); + System.out.println(" avg of"+((double)(finishTime-startTime))/(n)+ " ms"); } } diff --git a/mixer/src/test/java/profiling/ECGroupProfiling/EncodeProfiling.java b/mixer/src/test/java/profiling/ECGroup/Encode.java similarity index 94% rename from mixer/src/test/java/profiling/ECGroupProfiling/EncodeProfiling.java rename to mixer/src/test/java/profiling/ECGroup/Encode.java index af03f70..a7a731f 100644 --- a/mixer/src/test/java/profiling/ECGroupProfiling/EncodeProfiling.java +++ b/mixer/src/test/java/profiling/ECGroup/Encode.java @@ -1,4 +1,4 @@ -package profiling.ECGroupProfiling; +package profiling.ECGroup; import com.google.protobuf.InvalidProtocolBufferException; import meerkat.crypto.concrete.ECElGamalEncryption; @@ -17,7 +17,7 @@ import java.util.Random; /** * Created by Tzlil on 1/20/2016. */ -public class EncodeProfiling { +public class Encode { ECElGamalEncryption encryptor; ECGroup group; @@ -54,6 +54,6 @@ public class EncodeProfiling { long finishTime = System.currentTimeMillis(); System.out.println(" that took: "+(finishTime-startTime)+ " ms"); - System.out.println(" avg of"+((double)(finishTime-startTime))/(n * n)+ " ms"); + System.out.println(" avg of"+((double)(finishTime-startTime))/(n)+ " ms"); } } diff --git a/mixer/src/test/java/profiling/ECGroupProfiling/MulProfiling.java b/mixer/src/test/java/profiling/ECGroup/Mul.java similarity index 83% rename from mixer/src/test/java/profiling/ECGroupProfiling/MulProfiling.java rename to mixer/src/test/java/profiling/ECGroup/Mul.java index bb7c7cb..b0c0c7e 100644 --- a/mixer/src/test/java/profiling/ECGroupProfiling/MulProfiling.java +++ b/mixer/src/test/java/profiling/ECGroup/Mul.java @@ -1,22 +1,13 @@ -package profiling.ECGroupProfiling; +package profiling.ECGroup; 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; @@ -27,7 +18,7 @@ import java.util.Random; /** * Created by Tzlil on 1/19/2016. */ -public class MulProfiling { +public class Mul { ECElGamalEncryption encryptor; ECGroup group; @@ -73,7 +64,7 @@ public class MulProfiling { long finishTime = System.currentTimeMillis(); System.out.println(" that took: "+(finishTime-startTime)+ " ms"); - System.out.println(" avg of"+((double)(finishTime-startTime))/(n*n)+ " ms"); + System.out.println(" avg of"+((double)(finishTime-startTime))/(n)+ " ms"); } diff --git a/mixer/src/test/java/profiling/ECGroupProfiling/NegateProfiling.java b/mixer/src/test/java/profiling/ECGroup/Negate.java similarity index 94% rename from mixer/src/test/java/profiling/ECGroupProfiling/NegateProfiling.java rename to mixer/src/test/java/profiling/ECGroup/Negate.java index 344a813..75030fa 100644 --- a/mixer/src/test/java/profiling/ECGroupProfiling/NegateProfiling.java +++ b/mixer/src/test/java/profiling/ECGroup/Negate.java @@ -1,4 +1,4 @@ -package profiling.ECGroupProfiling; +package profiling.ECGroup; import com.google.protobuf.InvalidProtocolBufferException; import meerkat.crypto.concrete.ECElGamalEncryption; @@ -17,7 +17,7 @@ import java.util.Random; /** * Created by Tzlil on 1/20/2016. */ -public class NegateProfiling { +public class Negate { ECElGamalEncryption encryptor; ECGroup group; @@ -54,6 +54,6 @@ public class NegateProfiling { long finishTime = System.currentTimeMillis(); System.out.println(" that took: "+(finishTime-startTime)+ " ms"); - System.out.println(" avg of"+((double)(finishTime-startTime))/(n * n)+ " ms"); + System.out.println(" avg of"+((double)(finishTime-startTime))/(n)+ " ms"); } } diff --git a/mixer/src/test/java/profiling/RerandomizeProfiling.java b/mixer/src/test/java/profiling/Rerandomize.java similarity index 93% rename from mixer/src/test/java/profiling/RerandomizeProfiling.java rename to mixer/src/test/java/profiling/Rerandomize.java index 01148ec..ed018f3 100644 --- a/mixer/src/test/java/profiling/RerandomizeProfiling.java +++ b/mixer/src/test/java/profiling/Rerandomize.java @@ -23,7 +23,7 @@ import java.util.Random; /** * Created by Tzlil on 1/20/2016. */ -public class RerandomizeProfiling { +public class Rerandomize { Random rand; ECElGamal.SK key; @@ -43,7 +43,9 @@ public class RerandomizeProfiling { serializedPk = Utiles.serializePk(group, key); enc = new ECElGamalEncryption(); enc.init(serializedPk); - n = 1024 * 18; + int LogVotes = 10; + int layers = 2*LogVotes - 1; + n = layers * (1<