More refactoring for mixer

mixer
Tal Moran 2016-11-02 00:31:49 +02:00
parent 1baa567d8e
commit 5b268cd779
4 changed files with 352 additions and 317 deletions

View File

@ -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;
}
}
}

View File

@ -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);
}
}
}

View File

@ -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;

View File

@ -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) &&