Working on mixing code rewrite

mixer
Tal Moran 2017-01-11 22:09:01 +02:00
parent b7ef2c10e1
commit 723d348443
4 changed files with 282 additions and 10 deletions

View File

@ -3,6 +3,8 @@ package meerkat.mixer.proofs;
import com.google.protobuf.Message;
import meerkat.crypto.concrete.ECElGamalEncryption;
import meerkat.crypto.concrete.Util;
import meerkat.protobuf.ConcreteCrypto;
import meerkat.protobuf.ConcreteCrypto.GroupElement;
import meerkat.protobuf.Crypto;
import meerkat.protobuf.Mixing;
import org.bouncycastle.math.ec.ECPoint;
@ -32,6 +34,7 @@ public class ECElGamalMixProtocols {
h = params.h;
}
public class DlogStatementSchnorrProver implements SigmaProtocol.Prover {
ECElGamalMixParams.DlogStatement statement;
ECElGamalMixParams.DlogStatementWitness witness;
@ -62,4 +65,232 @@ public class ECElGamalMixProtocols {
return Util.encodeBigInteger(challenge.multiply(witness.x).add(r).mod(group.orderUpperBound()));
}
}
public class DlogStatementSchnorrVerifier implements SigmaProtocol.Verifier {
final ECElGamalMixParams.DlogStatement statement;
public DlogStatementSchnorrVerifier(ECElGamalMixParams.DlogStatement statement) {
this.statement = statement;
}
@Override
public boolean verify(Message firstMessage, BigInteger challenge, Message finalMessage) {
assert(firstMessage instanceof Mixing.Mix2Proof.DlogProof.FirstMessage &&
finalMessage instanceof Mixing.Mix2Proof.DlogProof.FinalMessage);
return verify((Mixing.Mix2Proof.DlogProof.FirstMessage) firstMessage, challenge,
(Mixing.Mix2Proof.DlogProof.FinalMessage) finalMessage);
}
public boolean verify(Mixing.Mix2Proof.DlogProof.FirstMessage firstMessage, BigInteger challenge,
Mixing.Mix2Proof.DlogProof.FinalMessage finalMessage) {
GroupElement grEncoded = firstMessage.getGr();
ECPoint gr = group.decode(grEncoded.toByteArray());
GroupElement hrEncoded = firstMessage.getHr();
ECPoint hr = group.decode(hrEncoded.toByteArray());
BigInteger xcr = Util.decodeBigInteger(finalMessage.getXcr());
boolean gGood = group.add(gr, group.multiply(statement.a,challenge)).equals(group.multiply(statement.g,xcr));
boolean hGood = group.add(hr, group.multiply(statement.b,challenge)).equals(group.multiply(statement.h,xcr));
return gGood && hGood;
}
}
public class DlogStatementSchnorrSimulator implements SigmaProtocol.Simulator {
ECElGamalMixParams.DlogStatement statement;
BigInteger response = null;
public DlogStatementSchnorrSimulator(ECElGamalMixParams.DlogStatement statement) {
this.statement = statement;
}
@Override
public Mixing.Mix2Proof.DlogProof.FirstMessage getFirstMessage(BigInteger challenge) {
response = encryptor.generateRandomExponent(rand);
ECPoint u = group.multiply(statement.g, response).subtract(group.multiply(statement.a,challenge));
ECPoint v = group.multiply(statement.h, response).subtract(group.multiply(statement.b,challenge));
return Mixing.Mix2Proof.DlogProof.FirstMessage.newBuilder()
.setGr(encryptor.encodeElement(u))
.setHr(encryptor.encodeElement(v))
.build();
}
@Override
public Crypto.BigInteger getFinalMessage() {
return Util.encodeBigInteger(response);
}
}
/**
* Prover for plaintext equivalence of a pair of ciphertexts.
*/
public class CiphertextPairEquivalenceProver extends SigmaProtocolAnd.Prover {
public CiphertextPairEquivalenceProver(ECElGamalMixParams.AndStatement statement,
ECElGamalMixParams.AndStatementWitness witness) {
super(new DlogStatementSchnorrProver(statement.clauses[0], witness.witnesses[0]),
new DlogStatementSchnorrProver(statement.clauses[1], witness.witnesses[1]));
}
@Override
protected Mixing.Mix2Proof.AndProof.FirstMessage buildConcatenatedFirstMessage(Message... firstMessages) {
assert (firstMessages.length == 2);
assert (firstMessages[0] instanceof Mixing.Mix2Proof.DlogProof.FirstMessage &&
firstMessages[1] instanceof Mixing.Mix2Proof.DlogProof.FirstMessage);
return Mixing.Mix2Proof.AndProof.FirstMessage.newBuilder()
.setClause0((Mixing.Mix2Proof.DlogProof.FirstMessage)firstMessages[0])
.setClause1((Mixing.Mix2Proof.DlogProof.FirstMessage)firstMessages[1])
.build();
}
@Override
protected Mixing.Mix2Proof.AndProof.FinalMessage buildConcatenatedFinalMessage(Message... finalMessages) {
assert(finalMessages.length == 2);
assert (finalMessages[0] instanceof Mixing.Mix2Proof.DlogProof.FinalMessage &&
finalMessages[1] instanceof Mixing.Mix2Proof.DlogProof.FinalMessage);
return Mixing.Mix2Proof.AndProof.FinalMessage.newBuilder()
.setClause0((Mixing.Mix2Proof.DlogProof.FinalMessage)finalMessages[0])
.setClause1((Mixing.Mix2Proof.DlogProof.FinalMessage)finalMessages[1])
.build();
}
}
public class CiphertextPairEquivalenceVerifier extends SigmaProtocolAnd.Verifier {
public CiphertextPairEquivalenceVerifier(ECElGamalMixParams.AndStatement statement) {
super(new DlogStatementSchnorrVerifier(statement.clauses[0]), new DlogStatementSchnorrVerifier(statement.clauses[1]));
}
@Override
protected Mixing.Mix2Proof.DlogProof.FirstMessage getFirstMessage(Message concatenated, int verifier) {
assert(concatenated instanceof Mixing.Mix2Proof.AndProof.FirstMessage);
Mixing.Mix2Proof.AndProof.FirstMessage msg = (Mixing.Mix2Proof.AndProof.FirstMessage) concatenated;
if (verifier == 0)
return msg.getClause0();
else
return msg.getClause1();
}
@Override
protected Mixing.Mix2Proof.DlogProof.FinalMessage getFinalMessage(Message concatenated, int verifier) {
assert(concatenated instanceof Mixing.Mix2Proof.AndProof.FinalMessage);
Mixing.Mix2Proof.AndProof.FinalMessage msg = (Mixing.Mix2Proof.AndProof.FinalMessage) concatenated;
if (verifier == 0)
return msg.getClause0();
else
return msg.getClause1();
}
}
public class CiphertextPairEquivalenceSimulator extends SigmaProtocolAnd.Simulator {
public CiphertextPairEquivalenceSimulator(ECElGamalMixParams.AndStatement statement) {
super(new DlogStatementSchnorrSimulator(statement.clauses[0]), new DlogStatementSchnorrSimulator(statement.clauses[1]));
}
@Override
protected Mixing.Mix2Proof.AndProof.FirstMessage buildConcatenatedFirstMessage(Message... firstMessages) {
assert (firstMessages.length == 2);
assert (firstMessages[0] instanceof Mixing.Mix2Proof.DlogProof.FirstMessage &&
firstMessages[1] instanceof Mixing.Mix2Proof.DlogProof.FirstMessage);
return Mixing.Mix2Proof.AndProof.FirstMessage.newBuilder()
.setClause0((Mixing.Mix2Proof.DlogProof.FirstMessage)firstMessages[0])
.setClause1((Mixing.Mix2Proof.DlogProof.FirstMessage)firstMessages[1])
.build();
}
@Override
protected Mixing.Mix2Proof.AndProof.FinalMessage buildConcatenatedFinalMessage(Message... finalMessages) {
assert(finalMessages.length == 2);
assert (finalMessages[0] instanceof Mixing.Mix2Proof.DlogProof.FinalMessage &&
finalMessages[1] instanceof Mixing.Mix2Proof.DlogProof.FinalMessage);
return Mixing.Mix2Proof.AndProof.FinalMessage.newBuilder()
.setClause0((Mixing.Mix2Proof.DlogProof.FinalMessage)finalMessages[0])
.setClause1((Mixing.Mix2Proof.DlogProof.FinalMessage)finalMessages[1])
.build();
}
}
public class Mix2Prover extends SigmaProtocolOr2.Prover {
public Mix2Prover(ECElGamalMixParams.Mix2Statement statement, ECElGamalMixParams.Mix2StatementWitness witness) {
super(new CiphertextPairEquivalenceProver(statement.clauses[witness.trueClauseIndex], witness.witness),
new CiphertextPairEquivalenceSimulator(statement.clauses[1 - witness.trueClauseIndex]),
witness.trueClauseIndex);
}
@Override
protected Mixing.Mix2Proof.FirstMessage buildConcatenatedFirstMessage(Message... firstMessages) {
assert(firstMessages.length == 2);
assert (firstMessages[0] instanceof Mixing.Mix2Proof.AndProof.FirstMessage &&
firstMessages[1] instanceof Mixing.Mix2Proof.AndProof.FirstMessage);
return Mixing.Mix2Proof.FirstMessage.newBuilder()
.setClause0((Mixing.Mix2Proof.AndProof.FirstMessage)firstMessages[0])
.setClause1((Mixing.Mix2Proof.AndProof.FirstMessage)firstMessages[1])
.build();
}
@Override
protected Mixing.Mix2Proof.FinalMessage buildConcatenatedFinalMessage(BigInteger firstChallenge,
Message... finalMessages) {
assert(finalMessages.length == 2);
assert (finalMessages[0] instanceof Mixing.Mix2Proof.AndProof.FinalMessage &&
finalMessages[1] instanceof Mixing.Mix2Proof.AndProof.FinalMessage);
return Mixing.Mix2Proof.FinalMessage.newBuilder()
.setClause0((Mixing.Mix2Proof.AndProof.FinalMessage)finalMessages[0])
.setClause1((Mixing.Mix2Proof.AndProof.FinalMessage)finalMessages[1])
.setC0(Util.encodeBigInteger(firstChallenge))
.build();
}
@Override
protected BigInteger generateChallenge() {
return encryptor.generateRandomExponent(rand);
}
@Override
protected BigInteger subtractChallenge(BigInteger c1, BigInteger c2) {
return c1.subtract(c2).mod(group.orderUpperBound());
}
}
public class Mix2Verifier extends SigmaProtocolOr2.Verifier {
public Mix2Verifier(ECElGamalMixParams.Mix2Statement statement) {
super(new CiphertextPairEquivalenceVerifier(statement.clauses[0]), new CiphertextPairEquivalenceVerifier(statement.clauses[1]));
}
@Override
protected Mixing.Mix2Proof.AndProof.FirstMessage getFirstMessage(Message concatenated, int verifier) {
assert(concatenated instanceof Mixing.Mix2Proof.FirstMessage);
Mixing.Mix2Proof.FirstMessage msg = (Mixing.Mix2Proof.FirstMessage) concatenated;
if (verifier == 0)
return msg.getClause0();
else
return msg.getClause1();
}
@Override
protected BigInteger getFirstChallenge(Message concatenated) {
assert(concatenated instanceof Mixing.Mix2Proof.FinalMessage);
Mixing.Mix2Proof.FinalMessage msg = (Mixing.Mix2Proof.FinalMessage) concatenated;
return Util.decodeBigInteger(msg.getC0());
}
@Override
protected Mixing.Mix2Proof.AndProof.FinalMessage getFinalMessage(Message concatenated, int verifier) {
assert(concatenated instanceof Mixing.Mix2Proof.FinalMessage);
Mixing.Mix2Proof.FinalMessage msg = (Mixing.Mix2Proof.FinalMessage) concatenated;
if (verifier == 0)
return msg.getClause0();
else
return msg.getClause1();
}
}
}

View File

@ -15,8 +15,7 @@ public interface SigmaProtocol {
}
public interface Simulator {
public Message getFirstMessage();
public BigInteger getChallenge();
public Message getFirstMessage(BigInteger challenge);
public Message getFinalMessage();
}

View File

@ -8,7 +8,7 @@ import java.math.BigInteger;
* Generic conjuction of sigma protocols
*/
public class SigmaProtocolAnd {
abstract public class Prover implements SigmaProtocol.Prover {
static abstract public class Prover implements SigmaProtocol.Prover {
final SigmaProtocol.Prover[] provers;
abstract protected Message buildConcatenatedFirstMessage(Message... firstMessages);
@ -37,7 +37,7 @@ public class SigmaProtocolAnd {
}
}
abstract public class Verifier implements SigmaProtocol.Verifier {
static abstract public class Verifier implements SigmaProtocol.Verifier {
final SigmaProtocol.Verifier[] verifiers;
abstract protected Message getFirstMessage(Message concatenated, int verifier);
@ -56,4 +56,36 @@ public class SigmaProtocolAnd {
return ok;
}
}
static abstract public class Simulator implements SigmaProtocol.Simulator {
final SigmaProtocol.Simulator[] simulators;
abstract protected Message buildConcatenatedFirstMessage(Message... firstMessages);
abstract protected Message buildConcatenatedFinalMessage(Message... finalMessages);
public Simulator(SigmaProtocol.Simulator... simulators) {
this.simulators = simulators;
}
@Override
public Message getFirstMessage(BigInteger challenge) {
Message[] firstMessages = new Message[simulators.length];
for (int i = 0; i < firstMessages.length; ++i) {
firstMessages[i] = simulators[i].getFirstMessage(challenge);
}
return buildConcatenatedFirstMessage(firstMessages);
}
@Override
public Message getFinalMessage() {
Message[] finalMessages = new Message[simulators.length];
for (int i = 0; i < finalMessages.length; ++i) {
finalMessages[i] = simulators[i].getFinalMessage();
}
return buildConcatenatedFinalMessage(finalMessages);
}
}
}

View File

@ -8,7 +8,7 @@ import java.math.BigInteger;
* Disjunction of 2 Sigma protocol statements
*/
public class SigmaProtocolOr2 {
abstract public class Prover implements SigmaProtocol.Prover {
static abstract public class Prover implements SigmaProtocol.Prover {
final SigmaProtocol.Prover prover;
final SigmaProtocol.Simulator simulator;
final int proverIdx;
@ -16,6 +16,15 @@ public class SigmaProtocolOr2 {
abstract protected Message buildConcatenatedFirstMessage(Message... firstMessages);
abstract protected Message buildConcatenatedFinalMessage(BigInteger firstChallenge, Message... finalMessages);
BigInteger simChallenge;
/**
* Generate a random challenge in an appropriate way (e.g., mod group order)
* @return
*/
abstract protected BigInteger generateChallenge();
/**
* Subtract two challenges in an appropriate way (e.g., mod group order)
* @param c1
@ -39,26 +48,27 @@ public class SigmaProtocolOr2 {
@Override
public Message getFirstMessage() {
simChallenge = generateChallenge();
if (proverIdx == 0) {
return buildConcatenatedFirstMessage(prover.getFirstMessage(), simulator.getFirstMessage());
return buildConcatenatedFirstMessage(prover.getFirstMessage(), simulator.getFirstMessage(simChallenge));
} else {
return buildConcatenatedFirstMessage(simulator.getFirstMessage(), prover.getFirstMessage());
return buildConcatenatedFirstMessage(simulator.getFirstMessage(simChallenge), prover.getFirstMessage());
}
}
@Override
public Message getFinalMessage(BigInteger challenge) {
BigInteger realchallenge = subtractChallenge(challenge, simulator.getChallenge());
BigInteger realchallenge = subtractChallenge(challenge, simChallenge);
if (proverIdx == 0) {
return buildConcatenatedFinalMessage(realchallenge, prover.getFinalMessage(realchallenge), simulator.getFinalMessage());
} else {
return buildConcatenatedFinalMessage(simulator.getChallenge(), simulator.getFinalMessage(), prover.getFinalMessage(realchallenge));
return buildConcatenatedFinalMessage(simChallenge, simulator.getFinalMessage(), prover.getFinalMessage(realchallenge));
}
}
}
abstract public class Verifier implements SigmaProtocol.Verifier {
static abstract public class Verifier implements SigmaProtocol.Verifier {
final SigmaProtocol.Verifier[] verifiers;
abstract protected Message getFirstMessage(Message concatenated, int verifier);