From 5b268cd7797a3823a282a0b468747aac8d305ba4 Mon Sep 17 00:00:00 2001 From: Tal Moran Date: Wed, 2 Nov 2016 00:31:49 +0200 Subject: [PATCH] More refactoring for mixer --- .../mixer/proofs/ECElGamalMixParams.java | 336 ++++++++++++++++++ .../mixer/proofs/ECElGamalMixProof.java | 301 ---------------- .../java/meerkat/mixer/proofs/Prover.java | 16 +- .../java/meerkat/mixer/proofs/Verifier.java | 16 +- 4 files changed, 352 insertions(+), 317 deletions(-) create mode 100644 mixer/src/main/java/meerkat/mixer/proofs/ECElGamalMixParams.java delete mode 100644 mixer/src/main/java/meerkat/mixer/proofs/ECElGamalMixProof.java diff --git a/mixer/src/main/java/meerkat/mixer/proofs/ECElGamalMixParams.java b/mixer/src/main/java/meerkat/mixer/proofs/ECElGamalMixParams.java new file mode 100644 index 0000000..d601d1a --- /dev/null +++ b/mixer/src/main/java/meerkat/mixer/proofs/ECElGamalMixParams.java @@ -0,0 +1,336 @@ +package meerkat.mixer.proofs; + +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 org.factcenter.qilin.primitives.concrete.ECGroup; + +/** + * use for organize the input for each ZKP + * + * both meerkat.mixer.proofs and meerkat.mixer.verifier implementation use it + */ +public class ECElGamalMixParams { + + private final ECGroup group; + private final ECPoint g; + private final ECPoint h; + private final byte[] gEncoded; + private final byte[] hEncoded; + + + /** + * Decode from the serialized representation to an {@link ECPoint} object. + * @param bs + * @return + */ + private ECPoint decodeECPoint(ByteString bs){ + return group.decode(bs.toByteArray()); + } + + /** + * @param group + * @param g - generator of group + * @param h - h = g ^ SecretKey + */ + public ECElGamalMixParams(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 TrueCouple { + left, right, unknown + } + + + /** + * can be used by anyone, e.g meerkat.mixer.verifier + * + * call to the meerkat.mixer.main overload with flag = false + */ + public Statement createStatement(Crypto.RerandomizableEncryptedMessage in1, Crypto.RerandomizableEncryptedMessage in2 + , Crypto.RerandomizableEncryptedMessage out1, Crypto.RerandomizableEncryptedMessage out2) throws InvalidProtocolBufferException { + + 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 Statement(in1ElGamal, in2ElGamal, out1ElGamal, out2ElGamal); + } + + /** + + * convert each encrypted message to ElGamalCiphertext + * + * @throws InvalidProtocolBufferException - in case that at least one of the encrypted messages isn't + * ElGamalCiphertext + */ + protected ProverStatement createProverStatement(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 in1ElGamal = ECElGamalEncryption.RerandomizableEncryptedMessage2ElGamalCiphertext(in1); + ConcreteCrypto.ElGamalCiphertext in2ElGamal = ECElGamalEncryption.RerandomizableEncryptedMessage2ElGamalCiphertext(in2); + ConcreteCrypto.ElGamalCiphertext out1ElGamal = ECElGamalEncryption.RerandomizableEncryptedMessage2ElGamalCiphertext(out1); + ConcreteCrypto.ElGamalCiphertext out2ElGamal = ECElGamalEncryption.RerandomizableEncryptedMessage2ElGamalCiphertext(out2); + + return new ProverStatement(in1ElGamal, in2ElGamal, out1ElGamal, out2ElGamal, r1, r2, switched); + } + + + /** + * Statement to be proved. + * + * The actual stored data is a cached representation for use in proofs and verification. This consists of the four substatements that are ORs of the DLOG equality. + * + * A Statement can be constructed only by calling the {@link #createStatement} factory method on an instance of ECElGamalMixParams (all constructors are private) + * + */ + public class Statement { + + /** + * Denote the first ciphertext pair e1=(e1c1,e1c2), e2=(e2c1,e2c2) and the second + * e1N=(e1Nc1, e1Nc2) and e2N=(e2Nc1,e2Nc2). + * Then ci_ejNDivek = ejNci/ekci + */ + ECPoint c1_e1NDive1; + /** + * See {@link #c1_e1NDive1} + */ + ECPoint c1_e2NDive1; + + /** + * See {@link #c1_e1NDive1} + */ + ECPoint c1_e1NDive2; + + /** + * See {@link #c1_e1NDive1} + */ + ECPoint c1_e2NDive2; + + /** + * See {@link #c1_e1NDive1} + */ + ECPoint c2_e1NDive1; + + /** + * See {@link #c1_e1NDive1} + */ + ECPoint c2_e2NDive1; + + /** + * See {@link #c1_e1NDive1} + */ + ECPoint c2_e1NDive2; + + /** + * See {@link #c1_e1NDive1} + */ + ECPoint c2_e2NDive2; + + + private final OrStatement orStatements[] = new OrStatement[4]; + + + public OrStatement getOrStatement(int num) { + if (orStatements[0] == null) + generateOrStatements(); + + return orStatements[num]; + } + + public void setOrStatement(int num, OrStatement orStatement) { + orStatements[num] = orStatement; + } + + + + /** + * Generate and set the four substatements. + */ + protected void generateOrStatements() { + setOrStatement(0, new OrStatement(c1_e1NDive1,c2_e1NDive1,c1_e1NDive2,c2_e1NDive2)); + setOrStatement(1, new OrStatement(c1_e1NDive1,c2_e1NDive1,c1_e2NDive1,c2_e2NDive1)); + setOrStatement(2, new OrStatement(c1_e1NDive2,c2_e1NDive2,c1_e2NDive2,c2_e2NDive2)); + setOrStatement(3, new OrStatement(c1_e2NDive1,c2_e2NDive1,c1_e2NDive2,c2_e2NDive2)); + } + + + private Statement(ConcreteCrypto.ElGamalCiphertext e1, ConcreteCrypto.ElGamalCiphertext e2 + , ConcreteCrypto.ElGamalCiphertext e1New, ConcreteCrypto.ElGamalCiphertext e2New){ + + ECPoint e1c1 = decodeECPoint(e1.getC1()); + ECPoint e1c2 = decodeECPoint(e1.getC2()); + ECPoint e2c1 = decodeECPoint(e2.getC1()); + ECPoint e2c2 = decodeECPoint(e2.getC2()); + ECPoint e1Nc1 = decodeECPoint(e1New.getC1()); + ECPoint e1Nc2 = decodeECPoint(e1New.getC2()); + ECPoint e2Nc1 = decodeECPoint(e2New.getC1()); + ECPoint e2Nc2 = decodeECPoint(e2New.getC2()); + + c1_e1NDive1 = group.add(e1Nc1, group.negate(e1c1)); + c1_e2NDive1 = group.add(e2Nc1, group.negate(e1c1)); + c1_e1NDive2 = group.add(e1Nc1, group.negate(e2c1)); + c1_e2NDive2 = group.add(e2Nc1, group.negate(e2c1)); + c2_e1NDive1 = group.add(e1Nc2, group.negate(e1c2)); + c2_e2NDive1 = group.add(e2Nc2, group.negate(e1c2)); + c2_e1NDive2 = group.add(e1Nc2, group.negate(e2c2)); + c2_e2NDive2 = group.add(e2Nc2, group.negate(e2c2)); + } + } + + public class ProverStatement extends Statement { + /** + * True iff the ciphertexts were switched (i.e., decrypt(e1N) == decrypt(e2) and decrypt(e2N) == decrypt(e1) + */ + boolean switched; + + /** + * Encryption randomness for e1 rerandomization + */ + Crypto.EncryptionRandomness r1; + + /** + * Encryption randomnesss for e2 rerandomization + */ + Crypto.EncryptionRandomness r2; + + @Override + protected void generateOrStatements() { + 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) { + setOrStatement(0, new OrProverStatement(c1_e1NDive1, c2_e1NDive1, c1_e1NDive2, c2_e1NDive2 + , c1_e1NDive1Encoded, c2_e1NDive1Encoded, c1_e1NDive2Encoded, c2_e1NDive2Encoded + , r1, TrueCouple.left)); + setOrStatement(1, new OrProverStatement(c1_e1NDive1, c2_e1NDive1, c1_e2NDive1, c2_e2NDive1 + , c1_e1NDive1Encoded, c2_e1NDive1Encoded, c1_e2NDive1Encoded, c2_e2NDive1Encoded + , r1, TrueCouple.left)); + setOrStatement(2, new OrProverStatement(c1_e1NDive2, c2_e1NDive2, c1_e2NDive2, c2_e2NDive2 + , c1_e1NDive2Encoded, c2_e1NDive2Encoded, c1_e2NDive2Encoded, c2_e2NDive2Encoded + , r2, TrueCouple.right)); + setOrStatement(3, new OrProverStatement(c1_e2NDive1, c2_e2NDive1, c1_e2NDive2, c2_e2NDive2 + , c1_e2NDive1Encoded, c2_e2NDive1Encoded, c1_e2NDive2Encoded, c2_e2NDive2Encoded + , r2, TrueCouple.right)); + } else { + setOrStatement(0, new OrProverStatement(c1_e1NDive1, c2_e1NDive1, c1_e1NDive2, c2_e1NDive2 + , c1_e1NDive1Encoded, c2_e1NDive1Encoded, c1_e1NDive2Encoded, c2_e1NDive2Encoded + , r2, TrueCouple.right)); + setOrStatement(1, new OrProverStatement(c1_e1NDive1, c2_e1NDive1, c1_e2NDive1, c2_e2NDive1 + , c1_e1NDive1Encoded, c2_e1NDive1Encoded, c1_e2NDive1Encoded, c2_e2NDive1Encoded + , r1, TrueCouple.right)); + setOrStatement(2, new OrProverStatement(c1_e1NDive2, c2_e1NDive2, c1_e2NDive2, c2_e2NDive2 + , c1_e1NDive2Encoded, c2_e1NDive2Encoded, c1_e2NDive2Encoded, c2_e2NDive2Encoded + , r2, TrueCouple.left)); + setOrStatement(3, new OrProverStatement(c1_e2NDive1, c2_e2NDive1, c1_e2NDive2, c2_e2NDive2 + , c1_e2NDive1Encoded, c2_e2NDive1Encoded, c1_e2NDive2Encoded, c2_e2NDive2Encoded + , r1, TrueCouple.left)); + } + } + + + @Override + public OrProverStatement getOrStatement(int num) { + OrStatement orStatement = super.getOrStatement(num); + if (!(orStatement instanceof OrProverStatement)) + throw new RuntimeException("ProverStatement should always have OrProverStatement substatements!!"); + + return (OrProverStatement) orStatement; + } + + private ProverStatement(ConcreteCrypto.ElGamalCiphertext e1, ConcreteCrypto.ElGamalCiphertext e2, + ConcreteCrypto.ElGamalCiphertext e1New, ConcreteCrypto.ElGamalCiphertext e2New, + Crypto.EncryptionRandomness r1, Crypto.EncryptionRandomness r2, boolean switched) { + super(e1, e2, e1New, e2New); + this.r1 = r1; + this.r2 = r2; + this.switched = switched; + } + + } + + /** + * The statement of a single disjunction to be proved: + * Either there exists x s.t (g1 ^ x == h1 and g2 ^ x == h2) or there exists x s.t. (g1' ^ x == h1 and g2' ^ x == h2) + * + * The statement can't be constructed externally (all constructors are private) + * + * 4 instances will be constructed for each new {@link ECElGamalMixParams.Statement} + * + */ + public class OrStatement { + 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; + + + /** + * used by meerkat.mixer.proofs only + */ + private OrStatement(ECPoint h1, ECPoint h2, ECPoint h1Tag, ECPoint h2Tag) { + this.g1 = g; + this.h1 = h1; + this.g2 = h; + this.h2 = h2; + this.g1Tag = g; + this.h1Tag = h1Tag; + this.g2Tag = h; + this.h2Tag = h2Tag; + + + + } + } + + public class OrProverStatement extends OrStatement { + 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 OrProverStatement(ECPoint h1, ECPoint h2, ECPoint h1Tag, ECPoint h2Tag, + byte[] h1Encoded, byte[] h2Encoded, byte[] h1TagEncoded, byte[] h2TagEncoded, + Crypto.EncryptionRandomness x, TrueCouple flag) { + super(h1, h2, h1Tag, 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; + } + } +} diff --git a/mixer/src/main/java/meerkat/mixer/proofs/ECElGamalMixProof.java b/mixer/src/main/java/meerkat/mixer/proofs/ECElGamalMixProof.java deleted file mode 100644 index bb41856..0000000 --- a/mixer/src/main/java/meerkat/mixer/proofs/ECElGamalMixProof.java +++ /dev/null @@ -1,301 +0,0 @@ -package meerkat.mixer.proofs; - -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 org.factcenter.qilin.primitives.concrete.ECGroup; - -/** - * use for organize the input for each ZKP - * - * both meerkat.mixer.proofs and meerkat.mixer.verifier implementation use it - */ -public class ECElGamalMixProof { - - private final ECGroup group; - private final ECPoint g; - private final ECPoint h; - private final byte[] gEncoded; - private final byte[] hEncoded; - - /** - * @param group - * @param g - generator of group - * @param h - h = g ^ SecretKey - */ - public ECElGamalMixProof(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 TrueCouple { - left, right, unknown - } - - /** - * can be used by meerkat.mixer.proofs only - * - * call to the meerkat.mixer.main overload with flag = true - */ - protected Statement createProofInput(Crypto.RerandomizableEncryptedMessage in1, Crypto.RerandomizableEncryptedMessage in2 - , Crypto.RerandomizableEncryptedMessage out1, Crypto.RerandomizableEncryptedMessage out2 - , Crypto.EncryptionRandomness r1, Crypto.EncryptionRandomness r2, boolean switched) throws InvalidProtocolBufferException { - - //boolean flag = true; - return createProofInput(in1,in2,out1,out2,r1,r2,switched,true); - } - - /** - * can be used by anyone, e.g meerkat.mixer.verifier - * - * call to the meerkat.mixer.main overload with flag = false - */ - public Statement 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 meerkat.mixer.proofs ( r1,r2,switched are known) - * @return ElGamalProofInput - * @throws InvalidProtocolBufferException - in case that at least one of the encrypted messages isn't - * ElGamalCiphertext - */ - private Statement 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 in1ElGamal = ECElGamalEncryption.RerandomizableEncryptedMessage2ElGamalCiphertext(in1); - ConcreteCrypto.ElGamalCiphertext in2ElGamal = ECElGamalEncryption.RerandomizableEncryptedMessage2ElGamalCiphertext(in2); - ConcreteCrypto.ElGamalCiphertext out1ElGamal = ECElGamalEncryption.RerandomizableEncryptedMessage2ElGamalCiphertext(out1); - ConcreteCrypto.ElGamalCiphertext out2ElGamal = ECElGamalEncryption.RerandomizableEncryptedMessage2ElGamalCiphertext(out2); - - if(flag) { - return new Statement(in1ElGamal, in2ElGamal, out1ElGamal, out2ElGamal, r1, r2, switched); - }else { - return new Statement(in1ElGamal, in2ElGamal, out1ElGamal, out2ElGamal); - } - } - - - /** - * Statement to be proved. The statement consists of the four substatements that are ORs of the DLOG equality. - * - * This can be constructed only by calling createProofInput method on an instance of ECElGamalMixProof (all constructors are private) - * - * in construction it is used for preparing the input for proving, while avoiding double converting or calculations - * - * use as a container for 4 OrProofInput. - */ - public class Statement { - private final OrStatement first; - private final OrStatement second; - private final OrStatement third; - private final OrStatement fourth; - - - public OrStatement getFirst() { - return first; - } - - public OrStatement getSecond() { - return second; - } - - public OrStatement getThird() { - return third; - } - - public OrStatement getFourth() { - return fourth; - } - - /** - * Decode from the serialized representation to an {@link ECPoint} object. - * @param bs - * @return - */ - private ECPoint decodeECPoint(ByteString bs){ - return group.decode(bs.toByteArray()); - } - - - /** - * @param proving - true if called by meerkat.mixer.proofs ( r1,r2,switched are known) - */ - private Statement(ConcreteCrypto.ElGamalCiphertext e1, ConcreteCrypto.ElGamalCiphertext e2 - , ConcreteCrypto.ElGamalCiphertext e1New, ConcreteCrypto.ElGamalCiphertext e2New - , Crypto.EncryptionRandomness r1, Crypto.EncryptionRandomness r2, boolean switched, boolean proving){ - - ECPoint e1c1 = decodeECPoint(e1.getC1()); - ECPoint e1c2 = decodeECPoint(e1.getC2()); - ECPoint e2c1 = decodeECPoint(e2.getC1()); - ECPoint e2c2 = decodeECPoint(e2.getC2()); - ECPoint e1Nc1 = decodeECPoint(e1New.getC1()); - ECPoint e1Nc2 = decodeECPoint(e1New.getC2()); - ECPoint e2Nc1 = decodeECPoint(e2New.getC1()); - ECPoint e2Nc2 = decodeECPoint(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(!proving) { - this.first = new OrStatement(c1_e1NDive1,c2_e1NDive1,c1_e1NDive2,c2_e1NDive2); - this.second = new OrStatement(c1_e1NDive1,c2_e1NDive1,c1_e2NDive1,c2_e2NDive1); - this.third = new OrStatement(c1_e1NDive2,c2_e1NDive2,c1_e2NDive2,c2_e2NDive2); - this.fourth = new OrStatement(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 OrStatement(c1_e1NDive1, c2_e1NDive1, c1_e1NDive2, c2_e1NDive2 - , c1_e1NDive1Encoded, c2_e1NDive1Encoded, c1_e1NDive2Encoded, c2_e1NDive2Encoded - , r1, TrueCouple.left); - this.second = new OrStatement(c1_e1NDive1, c2_e1NDive1, c1_e2NDive1, c2_e2NDive1 - , c1_e1NDive1Encoded, c2_e1NDive1Encoded, c1_e2NDive1Encoded, c2_e2NDive1Encoded - , r1, TrueCouple.left); - this.third = new OrStatement(c1_e1NDive2, c2_e1NDive2, c1_e2NDive2, c2_e2NDive2 - , c1_e1NDive2Encoded, c2_e1NDive2Encoded, c1_e2NDive2Encoded, c2_e2NDive2Encoded - , r2, TrueCouple.right); - this.fourth = new OrStatement(c1_e2NDive1, c2_e2NDive1, c1_e2NDive2, c2_e2NDive2 - , c1_e2NDive1Encoded, c2_e2NDive1Encoded, c1_e2NDive2Encoded, c2_e2NDive2Encoded - , r2, TrueCouple.right); - } else { - this.first = new OrStatement(c1_e1NDive1, c2_e1NDive1, c1_e1NDive2, c2_e1NDive2 - , c1_e1NDive1Encoded, c2_e1NDive1Encoded, c1_e1NDive2Encoded, c2_e1NDive2Encoded - , r2, TrueCouple.right); - this.second = new OrStatement(c1_e1NDive1, c2_e1NDive1, c1_e2NDive1, c2_e2NDive1 - , c1_e1NDive1Encoded, c2_e1NDive1Encoded, c1_e2NDive1Encoded, c2_e2NDive1Encoded - , r1, TrueCouple.right); - this.third = new OrStatement(c1_e1NDive2, c2_e1NDive2, c1_e2NDive2, c2_e2NDive2 - , c1_e1NDive2Encoded, c2_e1NDive2Encoded, c1_e2NDive2Encoded, c2_e2NDive2Encoded - , r2, TrueCouple.left); - this.fourth = new OrStatement(c1_e2NDive1, c2_e2NDive1, c1_e2NDive2, c2_e2NDive2 - , c1_e2NDive1Encoded, c2_e2NDive1Encoded, c1_e2NDive2Encoded, c2_e2NDive2Encoded - , r1, TrueCouple.left); - } - } - } - - - /** - * used by the meerkat.mixer.proofs - * call to the meerkat.mixer.main constructor with proving = true - */ - private Statement(ConcreteCrypto.ElGamalCiphertext e1, ConcreteCrypto.ElGamalCiphertext e2 - , ConcreteCrypto.ElGamalCiphertext e1New, ConcreteCrypto.ElGamalCiphertext e2New - , Crypto.EncryptionRandomness r1, Crypto.EncryptionRandomness r2, boolean switched){ - //proving = true; - this(e1,e2,e1New,e2New,r1,r2,switched,true); - } - - /** - * used by meerkat.mixer.proofs - * call to the meerkat.mixer.main constructor with proving = false - */ - private Statement(ConcreteCrypto.ElGamalCiphertext e1, ConcreteCrypto.ElGamalCiphertext e2 - , ConcreteCrypto.ElGamalCiphertext e1New, ConcreteCrypto.ElGamalCiphertext e2New){ - //proving = false; - this(e1,e2,e1New,e2New,null,null,false,false); - } - } - - - /** - * The statement of a single disjunction to be proved: - * Either there exists x s.t (g1 ^ x == h1 and g2 ^ x == h2) or there exists x s.t. (g1' ^ x == h1 and g2' ^ x == h2) - * - * The statement can't be constructed externally (all constructors are private) - * - * 4 instances will be constructed for each new {@link ECElGamalMixProof.Statement} - * - */ - public class OrStatement { - 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; - - // can be access by meerkat.mixer.proofs only - 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; - - /** - * used by meerkat.mixer.proofs only - */ - private OrStatement(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; - - } - - /** - * used by meerkat.mixer.verifier - */ - private OrStatement(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/meerkat/mixer/proofs/Prover.java b/mixer/src/main/java/meerkat/mixer/proofs/Prover.java index 5465c9c..cc8e46b 100644 --- a/mixer/src/main/java/meerkat/mixer/proofs/Prover.java +++ b/mixer/src/main/java/meerkat/mixer/proofs/Prover.java @@ -26,7 +26,7 @@ public class Prover implements Mix2ZeroKnowledgeProver { private final ECElGamalEncryption encryptor; private final ECPoint g,h; private final BigInteger groupOrderUpperBound; - private final ECElGamalMixProof organizer; + private final ECElGamalMixParams organizer; /** * @param rand @@ -41,7 +41,7 @@ public class Prover implements Mix2ZeroKnowledgeProver { this.group = this.encryptor.getGroup(); this.g = group.getGenerator(); this.h = this.encryptor.getElGamalPK().getPK(); - this.organizer = new ECElGamalMixProof(group,g,h); + this.organizer = new ECElGamalMixParams(group,g,h); this.groupOrderUpperBound = group.orderUpperBound(); } @@ -68,12 +68,12 @@ public class Prover implements Mix2ZeroKnowledgeProver { Crypto.EncryptionRandomness r2) throws InvalidProtocolBufferException { Mixing.ZeroKnowledgeProof.OrProof first,second,third,fourth; - ECElGamalMixProof.Statement statement = organizer.createProofInput(in1,in2,out1,out2,r1,r2,sw); + ECElGamalMixParams.ProverStatement statement = organizer.createProverStatement(in1,in2,out1,out2,r1,r2,sw); - first = createOrProofElGamal(statement.getFirst()); - second = createOrProofElGamal(statement.getSecond()); - third = createOrProofElGamal(statement.getThird()); - fourth = createOrProofElGamal(statement.getFourth()); + first = createOrProofElGamal(statement.getOrStatement(0)); + second = createOrProofElGamal(statement.getOrStatement(1)); + third = createOrProofElGamal(statement.getOrStatement(2)); + fourth = createOrProofElGamal(statement.getOrStatement(3)); Mixing.ZeroKnowledgeProof.Location location = Mixing.ZeroKnowledgeProof.Location.newBuilder() .setI(i) @@ -109,7 +109,7 @@ public class Prover implements Mix2ZeroKnowledgeProver { * @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 meerkat.mixer.proofs */ - private Mixing.ZeroKnowledgeProof.OrProof createOrProofElGamal(ECElGamalMixProof.OrStatement orStatement) { + private Mixing.ZeroKnowledgeProof.OrProof createOrProofElGamal(ECElGamalMixParams.OrProverStatement orStatement) { ECPoint g1 = orStatement.g1; ECPoint h1 = orStatement.h1; diff --git a/mixer/src/main/java/meerkat/mixer/proofs/Verifier.java b/mixer/src/main/java/meerkat/mixer/proofs/Verifier.java index d1bd4e3..2dc9254 100644 --- a/mixer/src/main/java/meerkat/mixer/proofs/Verifier.java +++ b/mixer/src/main/java/meerkat/mixer/proofs/Verifier.java @@ -18,7 +18,7 @@ public class Verifier implements Mix2ZeroKnowledgeVerifier { private final ECGroup group; private final RandomOracle randomOracle; private final ECPoint g,h; - private final ECElGamalMixProof organizer; + private final ECElGamalMixParams organizer; private final ZeroKnowledgeOrProofParser parser; /** @@ -31,7 +31,7 @@ public class Verifier implements Mix2ZeroKnowledgeVerifier { this.g = group.getGenerator(); this.h = encryptor.getElGamalPK().getPK(); this.randomOracle = randomOracle; - this.organizer = new ECElGamalMixProof(group,g,h); + this.organizer = new ECElGamalMixParams(group,g,h); this.parser = new ZeroKnowledgeOrProofParser(group); } @@ -52,11 +52,11 @@ public class Verifier implements Mix2ZeroKnowledgeVerifier { Crypto.RerandomizableEncryptedMessage out1, Crypto.RerandomizableEncryptedMessage out2, Mixing.ZeroKnowledgeProof proof) throws InvalidProtocolBufferException { - ECElGamalMixProof.Statement statement = organizer.createProofInput(in1,in2,out1,out2); - return verifyElGamaOrProof(statement.getFirst(), proof.getFirst())&& - verifyElGamaOrProof(statement.getSecond(), proof.getSecond())&& - verifyElGamaOrProof(statement.getThird(), proof.getThird())&& - verifyElGamaOrProof(statement.getFourth(), proof.getFourth()); + ECElGamalMixParams.Statement statement = organizer.createStatement(in1,in2,out1,out2); + return verifyElGamaOrProof(statement.getOrStatement(0), proof.getFirst())&& + verifyElGamaOrProof(statement.getOrStatement(1), proof.getSecond())&& + verifyElGamaOrProof(statement.getOrStatement(2), proof.getThird())&& + verifyElGamaOrProof(statement.getOrStatement(3), proof.getFourth()); } @@ -67,7 +67,7 @@ public class Verifier implements Mix2ZeroKnowledgeVerifier { * @param orProof * @return verify single or proof */ - private boolean verifyElGamaOrProof(ECElGamalMixProof.OrStatement orStatement, + private boolean verifyElGamaOrProof(ECElGamalMixParams.OrStatement orStatement, Mixing.ZeroKnowledgeProof.OrProof orProof) { ZeroKnowledgeOrProofParser.ZeroKnowledgeOrProofContainer container = parser.parseOrProof(orProof); return container.g1.equals(orStatement.g1) &&