Working on mixing code rewrite
parent
b7ef2c10e1
commit
723d348443
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,8 +15,7 @@ public interface SigmaProtocol {
|
|||
}
|
||||
|
||||
public interface Simulator {
|
||||
public Message getFirstMessage();
|
||||
public BigInteger getChallenge();
|
||||
public Message getFirstMessage(BigInteger challenge);
|
||||
public Message getFinalMessage();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue