2015-12-11 07:41:26 -05:00
|
|
|
package prover;
|
|
|
|
|
|
|
|
import com.google.protobuf.ByteString;
|
2015-12-31 11:58:25 -05:00
|
|
|
import com.google.protobuf.InvalidProtocolBufferException;
|
|
|
|
import meerkat.crypto.concrete.ECElGamalEncryption;
|
2015-12-11 07:41:26 -05:00
|
|
|
import meerkat.crypto.mixnet.Mix2ZeroKnowledgeProver;
|
2015-12-31 11:58:25 -05:00
|
|
|
import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier;
|
2015-12-11 07:41:26 -05:00
|
|
|
import meerkat.protobuf.ConcreteCrypto.ElGamalCiphertext;
|
|
|
|
import meerkat.protobuf.Crypto;
|
|
|
|
import meerkat.protobuf.Mixing;
|
2015-12-31 11:58:25 -05:00
|
|
|
import org.bouncycastle.math.ec.ECPoint;
|
|
|
|
import qilin.primitives.RandomOracle;
|
|
|
|
import qilin.primitives.concrete.ECGroup;
|
2015-12-14 10:54:44 -05:00
|
|
|
|
|
|
|
import java.math.BigInteger;
|
2015-12-11 07:41:26 -05:00
|
|
|
import java.util.Random;
|
|
|
|
|
|
|
|
public class Prover implements Mix2ZeroKnowledgeProver {
|
|
|
|
|
2015-12-31 11:58:25 -05:00
|
|
|
ECGroup group;
|
|
|
|
RandomOracle randomOracle;
|
2015-12-11 07:41:26 -05:00
|
|
|
Random rand;
|
2015-12-31 11:58:25 -05:00
|
|
|
ECElGamalEncryption ecElGamalEncryption;
|
|
|
|
ECPoint g,h;
|
|
|
|
|
|
|
|
Mix2ZeroKnowledgeVerifier verifier;
|
|
|
|
|
|
|
|
public Prover(Random rand,ECElGamalEncryption encryptor,RandomOracle randomOracle) {
|
2015-12-11 07:41:26 -05:00
|
|
|
|
|
|
|
this.rand = rand;
|
2015-12-31 11:58:25 -05:00
|
|
|
this.ecElGamalEncryption = encryptor;
|
|
|
|
this.randomOracle = randomOracle;
|
|
|
|
this.group = ecElGamalEncryption.getGroup();
|
|
|
|
this.g = group.getGenerator();
|
|
|
|
this.h = ecElGamalEncryption.getElGamalPK().getPK();
|
|
|
|
|
|
|
|
verifier = null;
|
2015-12-11 07:41:26 -05:00
|
|
|
}
|
|
|
|
|
2015-12-31 11:58:25 -05:00
|
|
|
public Prover(Random rand,ECElGamalEncryption encryptor,RandomOracle randomOracle,Mix2ZeroKnowledgeVerifier verifier) {
|
|
|
|
|
|
|
|
this.rand = rand;
|
|
|
|
this.ecElGamalEncryption = encryptor;
|
|
|
|
this.randomOracle = randomOracle;
|
|
|
|
this.group = ecElGamalEncryption.getGroup();
|
|
|
|
this.g = group.getGenerator();
|
|
|
|
this.h = ecElGamalEncryption.getElGamalPK().getPK();
|
|
|
|
|
|
|
|
this.verifier = verifier;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-12-11 07:41:26 -05:00
|
|
|
public Mixing.ZeroKnowledgeProof prove(Crypto.RerandomizableEncryptedMessage in1,
|
|
|
|
Crypto.RerandomizableEncryptedMessage in2,
|
|
|
|
Crypto.RerandomizableEncryptedMessage out1,
|
|
|
|
Crypto.RerandomizableEncryptedMessage out2,
|
2015-12-17 12:15:48 -05:00
|
|
|
boolean sw,int i,int j, int layer,
|
2015-12-11 07:41:26 -05:00
|
|
|
Crypto.EncryptionRandomness r1,
|
2015-12-31 11:58:25 -05:00
|
|
|
Crypto.EncryptionRandomness r2) throws InvalidProtocolBufferException {
|
2015-12-11 07:41:26 -05:00
|
|
|
|
|
|
|
Mixing.ZeroKnowledgeProof.OrProof first,second,third,fourth;
|
2015-12-31 11:58:25 -05:00
|
|
|
ProofOrganizer organizer = new ProofOrganizer(in1,in2,out1,out2);
|
2015-12-15 09:44:50 -05:00
|
|
|
if (!sw)
|
2015-12-11 07:41:26 -05:00
|
|
|
{
|
2015-12-31 11:58:25 -05:00
|
|
|
first = createOrProof(organizer.getE1(ProofOrganizer.OrProofOrder.first),
|
|
|
|
organizer.getE2(ProofOrganizer.OrProofOrder.first),
|
|
|
|
organizer.getE1New(ProofOrganizer.OrProofOrder.first),
|
|
|
|
organizer.getE2New(ProofOrganizer.OrProofOrder.first),
|
|
|
|
r1, true);
|
|
|
|
second = createOrProof(organizer.getE1(ProofOrganizer.OrProofOrder.second),
|
|
|
|
organizer.getE2(ProofOrganizer.OrProofOrder.second),
|
|
|
|
organizer.getE1New(ProofOrganizer.OrProofOrder.second),
|
|
|
|
organizer.getE2New(ProofOrganizer.OrProofOrder.second), r1, true);
|
|
|
|
third = createOrProof(organizer.getE1(ProofOrganizer.OrProofOrder.third),
|
|
|
|
organizer.getE2(ProofOrganizer.OrProofOrder.third),
|
|
|
|
organizer.getE1New(ProofOrganizer.OrProofOrder.third),
|
|
|
|
organizer.getE2New(ProofOrganizer.OrProofOrder.third), r2, false);
|
|
|
|
fourth = createOrProof(organizer.getE1(ProofOrganizer.OrProofOrder.fourth),
|
|
|
|
organizer.getE2(ProofOrganizer.OrProofOrder.fourth),
|
|
|
|
organizer.getE1New(ProofOrganizer.OrProofOrder.fourth),
|
|
|
|
organizer.getE2New(ProofOrganizer.OrProofOrder.fourth), r2, false);
|
2015-12-11 07:41:26 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-12-31 11:58:25 -05:00
|
|
|
first = createOrProof(organizer.getE1(ProofOrganizer.OrProofOrder.first),
|
|
|
|
organizer.getE2(ProofOrganizer.OrProofOrder.first),
|
|
|
|
organizer.getE1New(ProofOrganizer.OrProofOrder.first),
|
|
|
|
organizer.getE2New(ProofOrganizer.OrProofOrder.first),
|
|
|
|
r2, false);
|
|
|
|
second = createOrProof(organizer.getE1(ProofOrganizer.OrProofOrder.second),
|
|
|
|
organizer.getE2(ProofOrganizer.OrProofOrder.second),
|
|
|
|
organizer.getE1New(ProofOrganizer.OrProofOrder.second),
|
|
|
|
organizer.getE2New(ProofOrganizer.OrProofOrder.second),
|
|
|
|
r1, false);
|
|
|
|
third = createOrProof(organizer.getE1(ProofOrganizer.OrProofOrder.third),
|
|
|
|
organizer.getE2(ProofOrganizer.OrProofOrder.third),
|
|
|
|
organizer.getE1New(ProofOrganizer.OrProofOrder.third),
|
|
|
|
organizer.getE2New(ProofOrganizer.OrProofOrder.third),
|
|
|
|
r2, true);
|
|
|
|
fourth = createOrProof(organizer.getE1(ProofOrganizer.OrProofOrder.fourth),
|
|
|
|
organizer.getE2(ProofOrganizer.OrProofOrder.fourth),
|
|
|
|
organizer.getE1New(ProofOrganizer.OrProofOrder.fourth),
|
|
|
|
organizer.getE2New(ProofOrganizer.OrProofOrder.fourth),
|
|
|
|
r1, true);
|
2015-12-11 07:41:26 -05:00
|
|
|
}
|
2015-12-17 12:15:48 -05:00
|
|
|
Mixing.ZeroKnowledgeProof.Location location = Mixing.ZeroKnowledgeProof.Location.newBuilder()
|
|
|
|
.setI(i)
|
|
|
|
.setJ(j)
|
|
|
|
.setLayer(layer)
|
|
|
|
.build();
|
2015-12-31 11:58:25 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mixing.ZeroKnowledgeProof result = Mixing.ZeroKnowledgeProof.newBuilder()
|
2015-12-11 07:41:26 -05:00
|
|
|
.setFirst(first)
|
|
|
|
.setSecond(second)
|
|
|
|
.setThird(third)
|
|
|
|
.setFourth(fourth)
|
2015-12-17 12:15:48 -05:00
|
|
|
.setLocation(location)
|
2015-12-11 07:41:26 -05:00
|
|
|
.build();
|
2015-12-31 11:58:25 -05:00
|
|
|
|
|
|
|
//debuging
|
|
|
|
if (verifier != null){
|
|
|
|
if (!verifier.verify(in1,in2,out1,out2,result)){
|
|
|
|
|
|
|
|
System.out.print(location.toString());
|
|
|
|
System.out.println("switch value : " + sw);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
2015-12-11 07:41:26 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
private Mixing.ZeroKnowledgeProof.OrProof createOrProof(Crypto.RerandomizableEncryptedMessage e1,
|
|
|
|
Crypto.RerandomizableEncryptedMessage e2,
|
|
|
|
Crypto.RerandomizableEncryptedMessage e1New,
|
|
|
|
Crypto.RerandomizableEncryptedMessage e2New,
|
|
|
|
Crypto.EncryptionRandomness x,
|
2015-12-31 11:58:25 -05:00
|
|
|
boolean flag) throws InvalidProtocolBufferException {
|
2015-12-11 07:41:26 -05:00
|
|
|
|
2015-12-31 11:58:25 -05:00
|
|
|
ElGamalCiphertext e1ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e1);
|
|
|
|
ElGamalCiphertext e2ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e2);
|
|
|
|
ElGamalCiphertext e1TagElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e1New);
|
|
|
|
ElGamalCiphertext e2TagElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e2New);
|
2015-12-11 07:41:26 -05:00
|
|
|
|
|
|
|
return createOrProofElGamal(e1ElGamal,e2ElGamal,e1TagElGamal,e2TagElGamal,x,flag);
|
|
|
|
}
|
|
|
|
|
2015-12-17 12:15:48 -05:00
|
|
|
|
2015-12-31 11:58:25 -05:00
|
|
|
private ECPoint convert2ECPoint(ByteString bs){
|
|
|
|
return group.decode(bs.toByteArray());
|
|
|
|
}
|
|
|
|
|
|
|
|
public BigInteger hash(Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle input) {
|
|
|
|
byte[] arr = input.toByteArray();
|
|
|
|
return new BigInteger(this.randomOracle.hash(arr,arr.length));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-12-11 07:41:26 -05:00
|
|
|
private Mixing.ZeroKnowledgeProof.OrProof createOrProofElGamal(ElGamalCiphertext e1,
|
|
|
|
ElGamalCiphertext e2,
|
|
|
|
ElGamalCiphertext e1New,
|
|
|
|
ElGamalCiphertext e2New,
|
|
|
|
Crypto.EncryptionRandomness x,
|
|
|
|
boolean flag) {
|
|
|
|
|
2015-12-31 11:58:25 -05:00
|
|
|
ECPoint g1 = g;
|
|
|
|
ECPoint h1 = group.add(convert2ECPoint(e1New.getC1()),group.negate(convert2ECPoint(e1.getC1())));
|
|
|
|
ECPoint g2 = h;
|
|
|
|
ECPoint h2 = group.add(convert2ECPoint(e1New.getC2()),group.negate(convert2ECPoint(e1.getC2())));
|
|
|
|
|
|
|
|
ECPoint g1Tag = g;
|
|
|
|
ECPoint h1Tag = group.add(convert2ECPoint(e2New.getC1()),group.negate(convert2ECPoint(e2.getC1())));
|
|
|
|
ECPoint g2Tag = h;
|
|
|
|
ECPoint h2Tag = group.add(convert2ECPoint(e2New.getC2()),group.negate(convert2ECPoint(e2.getC2())));
|
2015-12-11 07:41:26 -05:00
|
|
|
|
2015-12-31 11:58:25 -05:00
|
|
|
BigInteger r = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound());
|
2015-12-14 10:54:44 -05:00
|
|
|
BigInteger c1,c2,z,zTag;
|
2015-12-31 11:58:25 -05:00
|
|
|
ECPoint u,v,uTag,vTag;
|
2015-12-11 07:41:26 -05:00
|
|
|
if (flag)
|
|
|
|
{
|
2015-12-31 11:58:25 -05:00
|
|
|
c2 = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound());
|
|
|
|
zTag = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound());
|
2015-12-11 07:41:26 -05:00
|
|
|
//step 1
|
2015-12-17 12:15:48 -05:00
|
|
|
u = group.multiply(g1, r);
|
|
|
|
v = group.multiply(g2, r);
|
|
|
|
uTag = group.add(group.multiply(g1Tag, zTag), group.negate(group.multiply(h1Tag, c2)));
|
|
|
|
vTag = group.add(group.multiply(g2Tag, zTag), group.negate(group.multiply(h2Tag, c2)));
|
2015-12-11 07:41:26 -05:00
|
|
|
//step 2
|
|
|
|
// c1 = (hash(input + step1) + group size - c2)% group size
|
2015-12-14 10:54:44 -05:00
|
|
|
Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle forRandomOracle =
|
|
|
|
Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle.newBuilder()
|
2015-12-31 11:58:25 -05:00
|
|
|
.setG1(ByteString.copyFrom(group.encode(g1)))
|
|
|
|
.setH1(ByteString.copyFrom(group.encode(h1)))
|
|
|
|
.setG2(ByteString.copyFrom(group.encode(g2)))
|
|
|
|
.setH2(ByteString.copyFrom(group.encode(h2)))
|
|
|
|
.setG1Tag(ByteString.copyFrom(group.encode(g1Tag)))
|
|
|
|
.setH1Tag(ByteString.copyFrom(group.encode(h1Tag)))
|
|
|
|
.setG2Tag(ByteString.copyFrom(group.encode(g2Tag)))
|
|
|
|
.setH2Tag(ByteString.copyFrom(group.encode(h2Tag)))
|
|
|
|
.setU(ByteString.copyFrom(group.encode(u)))
|
|
|
|
.setV(ByteString.copyFrom(group.encode(v)))
|
|
|
|
.setUTag(ByteString.copyFrom(group.encode(uTag)))
|
|
|
|
.setVTag(ByteString.copyFrom(group.encode(vTag)))
|
2015-12-14 10:54:44 -05:00
|
|
|
.build();
|
2015-12-31 11:58:25 -05:00
|
|
|
c1 = hash(forRandomOracle).add(group.orderUpperBound().subtract(c2)).mod(group.orderUpperBound());
|
2015-12-11 07:41:26 -05:00
|
|
|
//step 3
|
|
|
|
//z = (r + c1 * x) % group size;
|
2015-12-17 12:15:48 -05:00
|
|
|
z = r.add(c1.multiply(new BigInteger(x.getData().toByteArray()))).mod(group.orderUpperBound());
|
2015-12-11 07:41:26 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-12-31 11:58:25 -05:00
|
|
|
c1 = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound());
|
|
|
|
z = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound());
|
2015-12-11 07:41:26 -05:00
|
|
|
//step 1
|
2015-12-17 12:15:48 -05:00
|
|
|
uTag = group.multiply(g1Tag, r);
|
|
|
|
vTag = group.multiply(g2Tag, r);
|
|
|
|
u = group.add(group.multiply(g1, z), group.negate(group.multiply(h1, c1)));
|
|
|
|
v = group.add(group.multiply(g2, z), group.negate(group.multiply(h2, c1)));
|
2015-12-11 07:41:26 -05:00
|
|
|
//step 2
|
|
|
|
// c1 = (hash(input + step1) + group size - c1)% group size
|
2015-12-14 10:54:44 -05:00
|
|
|
Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle forRandomOracle =
|
|
|
|
Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle.newBuilder()
|
2015-12-31 11:58:25 -05:00
|
|
|
.setG1(ByteString.copyFrom(group.encode(g1)))
|
|
|
|
.setH1(ByteString.copyFrom(group.encode(h1)))
|
|
|
|
.setG2(ByteString.copyFrom(group.encode(g2)))
|
|
|
|
.setH2(ByteString.copyFrom(group.encode(h2)))
|
|
|
|
.setG1Tag(ByteString.copyFrom(group.encode(g1Tag)))
|
|
|
|
.setH1Tag(ByteString.copyFrom(group.encode(h1Tag)))
|
|
|
|
.setG2Tag(ByteString.copyFrom(group.encode(g2Tag)))
|
|
|
|
.setH2Tag(ByteString.copyFrom(group.encode(h2Tag)))
|
|
|
|
.setU(ByteString.copyFrom(group.encode(u)))
|
|
|
|
.setV(ByteString.copyFrom(group.encode(v)))
|
|
|
|
.setUTag(ByteString.copyFrom(group.encode(uTag)))
|
|
|
|
.setVTag(ByteString.copyFrom(group.encode(vTag)))
|
2015-12-14 10:54:44 -05:00
|
|
|
.build();
|
2015-12-31 11:58:25 -05:00
|
|
|
c2 = hash(forRandomOracle).add(group.orderUpperBound().subtract(c1)).mod(group.orderUpperBound());
|
2015-12-11 07:41:26 -05:00
|
|
|
//step 3
|
|
|
|
//zTag = (r + c2 * x) % group size;
|
2015-12-17 12:15:48 -05:00
|
|
|
zTag = r.add(c2.multiply(new BigInteger(x.getData().toByteArray()))).mod(group.orderUpperBound());
|
2015-12-11 07:41:26 -05:00
|
|
|
}
|
|
|
|
return Mixing.ZeroKnowledgeProof.OrProof.newBuilder()
|
2015-12-31 11:58:25 -05:00
|
|
|
.setG1(ByteString.copyFrom(group.encode(g1)))
|
|
|
|
.setH1(ByteString.copyFrom(group.encode(h1)))
|
|
|
|
.setG2(ByteString.copyFrom(group.encode(g2)))
|
|
|
|
.setH2(ByteString.copyFrom(group.encode(h2)))
|
|
|
|
.setG1Tag(ByteString.copyFrom(group.encode(g1Tag)))
|
|
|
|
.setH1Tag(ByteString.copyFrom(group.encode(h1Tag)))
|
|
|
|
.setG2Tag(ByteString.copyFrom(group.encode(g2Tag)))
|
|
|
|
.setH2Tag(ByteString.copyFrom(group.encode(h2Tag)))
|
|
|
|
.setU(ByteString.copyFrom(group.encode(u)))
|
|
|
|
.setV(ByteString.copyFrom(group.encode(v)))
|
|
|
|
.setUTag(ByteString.copyFrom(group.encode(uTag)))
|
|
|
|
.setVTag(ByteString.copyFrom(group.encode(vTag)))
|
2015-12-14 10:54:44 -05:00
|
|
|
.setC1(ByteString.copyFrom(c1.toByteArray()))
|
|
|
|
.setC2(ByteString.copyFrom(c2.toByteArray()))
|
|
|
|
.setZ(ByteString.copyFrom(z.toByteArray()))
|
|
|
|
.setZTag(ByteString.copyFrom(zTag.toByteArray()))
|
2015-12-11 07:41:26 -05:00
|
|
|
.build();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|