Mixing + Mixer test
parent
767d73c143
commit
c8646712c0
|
@ -1,4 +1,4 @@
|
||||||
#Mon Dec 14 14:35:37 IST 2015
|
#Thu Dec 17 12:20:25 IST 2015
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|
|
@ -11,7 +11,7 @@ public interface Mix2ZeroKnowledgeProver {
|
||||||
Crypto.RerandomizableEncryptedMessage in2,
|
Crypto.RerandomizableEncryptedMessage in2,
|
||||||
Crypto.RerandomizableEncryptedMessage out1,
|
Crypto.RerandomizableEncryptedMessage out1,
|
||||||
Crypto.RerandomizableEncryptedMessage out2,
|
Crypto.RerandomizableEncryptedMessage out2,
|
||||||
boolean switched,
|
boolean switched,int i,int j, int layer, // switch info
|
||||||
Crypto.EncryptionRandomness r1,
|
Crypto.EncryptionRandomness r1,
|
||||||
Crypto.EncryptionRandomness r2);
|
Crypto.EncryptionRandomness r2);
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,15 @@ message ZeroKnowledgeProof {
|
||||||
bytes z = 15;
|
bytes z = 15;
|
||||||
bytes zTag = 16;
|
bytes zTag = 16;
|
||||||
}
|
}
|
||||||
|
message Location{
|
||||||
|
int32 i = 1;
|
||||||
|
int32 j = 2;
|
||||||
|
int32 layer = 3;
|
||||||
|
}
|
||||||
|
|
||||||
OrProof first = 1;
|
OrProof first = 1;
|
||||||
OrProof second = 2;
|
OrProof second = 2;
|
||||||
OrProof third = 3;
|
OrProof third = 3;
|
||||||
OrProof fourth = 4;
|
OrProof fourth = 4;
|
||||||
|
Location location = 5;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
package main;
|
||||||
|
|
||||||
|
import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier;
|
||||||
|
import meerkat.crypto.mixnet.Mixer;
|
||||||
|
import meerkat.protobuf.Crypto;
|
||||||
|
import meerkat.protobuf.Mixing;
|
||||||
|
import qilin.util.Pair;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Tzlil on 12/17/2015.
|
||||||
|
*/
|
||||||
|
public class MainMixing {
|
||||||
|
|
||||||
|
Mixer mixer;
|
||||||
|
Mix2ZeroKnowledgeVerifier verifier;
|
||||||
|
int n,layers;
|
||||||
|
|
||||||
|
public MainMixing(Mixer mixer, Mix2ZeroKnowledgeVerifier verifier, int n) {
|
||||||
|
this.mixer = mixer;
|
||||||
|
this.verifier = verifier;
|
||||||
|
this.n = n;
|
||||||
|
this.layers = (int) (2 * Math.log(n) / Math.log(2)) - 1; // layers = 2logn -1
|
||||||
|
}
|
||||||
|
|
||||||
|
private void firstMixing( ) throws Exception
|
||||||
|
{
|
||||||
|
updateBB(mixer.mix(getInputForFirstMixer()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void otherMixing() throws Exception
|
||||||
|
{
|
||||||
|
List<Mixing.ZeroKnowledgeProof[][]> zeroKnowledgeProofsLists = downloadProofs();
|
||||||
|
List<Crypto.RerandomizableEncryptedMessage[][]> rerandomizableEncryptedMessageLists = downloadEncryptionTable();
|
||||||
|
|
||||||
|
for (int i = 0; i < zeroKnowledgeProofsLists.size(); i++)
|
||||||
|
{
|
||||||
|
if(!verifyTable(n,layers,zeroKnowledgeProofsLists.get(i),rerandomizableEncryptedMessageLists.get(i)))
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
Crypto.RerandomizableEncryptedMessage[] lastLayerInCurrent,firstLineInNext;
|
||||||
|
for (int i = 0; i < rerandomizableEncryptedMessageLists.size() - 1 ; i++)
|
||||||
|
{
|
||||||
|
lastLayerInCurrent = rerandomizableEncryptedMessageLists.get(i)[layers - 1];
|
||||||
|
firstLineInNext = rerandomizableEncryptedMessageLists.get(i + 1)[0];
|
||||||
|
if(!Arrays.equals(lastLayerInCurrent,firstLineInNext))
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Crypto.RerandomizableEncryptedMessage> inputForMixer =
|
||||||
|
Arrays.asList(rerandomizableEncryptedMessageLists
|
||||||
|
.get(rerandomizableEncryptedMessageLists.size() - 1)[layers - 1]);
|
||||||
|
|
||||||
|
updateBB(mixer.mix(inputForMixer));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Mixing.ZeroKnowledgeProof[][]> downloadProofs()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Crypto.RerandomizableEncryptedMessage[][]> downloadEncryptionTable()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Crypto.RerandomizableEncryptedMessage> getInputForFirstMixer()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateBB(Pair<Mixing.ZeroKnowledgeProof[][],Crypto.RerandomizableEncryptedMessage[][]> mixerOutput){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean verifyTable(int n,int layers, Mixing.ZeroKnowledgeProof[][] zeroKnowledgeProofs,
|
||||||
|
Crypto.RerandomizableEncryptedMessage[][] rerandomizableEncryptedMessages)
|
||||||
|
{
|
||||||
|
int index1,index2,layer;
|
||||||
|
|
||||||
|
//initialize locationChecksum table
|
||||||
|
// use for check BeneshNet validity
|
||||||
|
boolean[][] locationChecksum = new boolean[layers][n];
|
||||||
|
for (boolean[] locationChecksumLayer: locationChecksum) {
|
||||||
|
Arrays.fill(locationChecksumLayer,false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (Mixing.ZeroKnowledgeProof[] zkpLayer: zeroKnowledgeProofs) {
|
||||||
|
for (Mixing.ZeroKnowledgeProof zkp: zkpLayer) {
|
||||||
|
Mixing.ZeroKnowledgeProof.Location location = zkp.getLocation();
|
||||||
|
index1 = location.getI();
|
||||||
|
index2 = location.getJ();
|
||||||
|
layer = location.getLayer();
|
||||||
|
|
||||||
|
// check location validity
|
||||||
|
if (layer > layers >> 1) {
|
||||||
|
if (index2 - index1 != n >> (layers - layer))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if (index2 - index1 != n >> (layer + 1))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mark location in table
|
||||||
|
locationChecksum[layer][index1] = true;
|
||||||
|
locationChecksum[layer][index2] = true;
|
||||||
|
|
||||||
|
// verify proof
|
||||||
|
if(!verifier.verify(rerandomizableEncryptedMessages[index1][layer],
|
||||||
|
rerandomizableEncryptedMessages[index2][layer],
|
||||||
|
rerandomizableEncryptedMessages[index1][layer + 1],
|
||||||
|
rerandomizableEncryptedMessages[index2][layer + 1],
|
||||||
|
zkp))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify all necessary locations for BeneshNet were proved
|
||||||
|
for (boolean[] checksumLayer: locationChecksum) {
|
||||||
|
for (boolean locationBoolean: checksumLayer) {
|
||||||
|
if (!locationBoolean)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,5 @@
|
||||||
package mixer;
|
package mixer;
|
||||||
|
|
||||||
import com.google.protobuf.Enum;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
|
@ -14,12 +12,14 @@ import java.util.Random;
|
||||||
public class MixNetwork {
|
public class MixNetwork {
|
||||||
|
|
||||||
private final Switch[][] switches;
|
private final Switch[][] switches;
|
||||||
private final Random random;
|
|
||||||
|
|
||||||
public MixNetwork(int n,int layers,Random random)
|
public MixNetwork(RandomPermutation randomPermutation)
|
||||||
{
|
{
|
||||||
this.random = random;
|
int[] permutation = randomPermutation.permutation;
|
||||||
int[] permutation = randomPermutation(n);
|
int n = permutation.length;
|
||||||
|
assert ((n & n-1) == 0); //n == 2^k
|
||||||
|
int layers = (int)(2*Math.log(n)/Math.log(2));
|
||||||
|
|
||||||
int[] pi, piL, piR;
|
int[] pi, piL, piR;
|
||||||
Queue<int[]> permutationsQueue = new ArrayBlockingQueue<int[]>(n);
|
Queue<int[]> permutationsQueue = new ArrayBlockingQueue<int[]>(n);
|
||||||
Graph graph;
|
Graph graph;
|
||||||
|
@ -64,26 +64,6 @@ public class MixNetwork {
|
||||||
return switches[layer];
|
return switches[layer];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private int[] randomPermutation(int n){
|
|
||||||
List<Integer> numbers= new ArrayList<Integer>(n);
|
|
||||||
for (int i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
numbers.add(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
int[] result = new int[n];
|
|
||||||
int index;
|
|
||||||
for (int i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
index = random.nextInt(n - i);
|
|
||||||
result[i] = numbers.get(index);
|
|
||||||
numbers.remove(index);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Graph {
|
private class Graph {
|
||||||
private int n;
|
private int n;
|
||||||
private int nDiv2;
|
private int nDiv2;
|
||||||
|
|
|
@ -42,7 +42,7 @@ public class Mixer implements meerkat.crypto.mixnet.Mixer {
|
||||||
EncryptionRandomness r1, r2;
|
EncryptionRandomness r1, r2;
|
||||||
RerandomizableEncryptedMessage e1, e2;
|
RerandomizableEncryptedMessage e1, e2;
|
||||||
boolean half = true;
|
boolean half = true;
|
||||||
MixNetwork mixNetwork = new MixNetwork(n,layers,random);
|
MixNetwork mixNetwork = new MixNetwork(new RandomPermutation(n,random));
|
||||||
Switch[] switchesLayer;
|
Switch[] switchesLayer;
|
||||||
|
|
||||||
// set first level of encryption
|
// set first level of encryption
|
||||||
|
@ -72,7 +72,7 @@ public class Mixer implements meerkat.crypto.mixnet.Mixer {
|
||||||
proofsTable[layer][switchIndex] =
|
proofsTable[layer][switchIndex] =
|
||||||
prover.prove(e1, e2, encryptionTable[layer + 1][index1],
|
prover.prove(e1, e2, encryptionTable[layer + 1][index1],
|
||||||
encryptionTable[layer + 1][index2],
|
encryptionTable[layer + 1][index2],
|
||||||
sw.value, r1, r2);
|
sw.value, sw.i,sw.j,sw.layer, r1, r2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new Pair<ZeroKnowledgeProof[][], RerandomizableEncryptedMessage[][]>(proofsTable, encryptionTable);
|
return new Pair<ZeroKnowledgeProof[][], RerandomizableEncryptedMessage[][]>(proofsTable, encryptionTable);
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package mixer;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Tzlil on 12/17/2015.
|
||||||
|
*/
|
||||||
|
class RandomPermutation {
|
||||||
|
|
||||||
|
protected final int[] permutation;
|
||||||
|
|
||||||
|
protected RandomPermutation(int n,Random random)
|
||||||
|
{
|
||||||
|
List<Integer> numbers= new ArrayList<Integer>(n);
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
numbers.add(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] result = new int[n];
|
||||||
|
int index;
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
index = random.nextInt(n - i);
|
||||||
|
result[i] = numbers.get(index);
|
||||||
|
numbers.remove(index);
|
||||||
|
}
|
||||||
|
permutation = result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +0,0 @@
|
||||||
package necessary;
|
|
||||||
|
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
public interface Group {
|
|
||||||
|
|
||||||
ByteString div(ByteString dividend, ByteString divisor);
|
|
||||||
ByteString mul(ByteString a, ByteString b);
|
|
||||||
ByteString pow(ByteString bas, BigInteger exp);
|
|
||||||
BigInteger groupSize();
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
package necessary;
|
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
|
||||||
import meerkat.protobuf.Crypto;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Tzlil on 12/14/2015.
|
|
||||||
*/
|
|
||||||
public class GroupImpl implements Group {
|
|
||||||
|
|
||||||
qilin.primitives.Group<ByteString> qilinInstance;
|
|
||||||
public GroupImpl(qilin.primitives.Group qilinInstance) {
|
|
||||||
this.qilinInstance = qilinInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteString div(ByteString dividend, ByteString divisor) {
|
|
||||||
return mul(dividend,qilinInstance.negate(divisor));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteString mul(ByteString a, ByteString b) {
|
|
||||||
return qilinInstance.add(a,b);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteString pow(ByteString bas, BigInteger exp) {
|
|
||||||
return qilinInstance.multiply(bas,exp);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BigInteger groupSize() {
|
|
||||||
return qilinInstance.orderUpperBound();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,20 +7,19 @@ import meerkat.protobuf.ConcreteCrypto.ElGamalCiphertext;
|
||||||
import meerkat.protobuf.Crypto;
|
import meerkat.protobuf.Crypto;
|
||||||
import meerkat.protobuf.Mixing;
|
import meerkat.protobuf.Mixing;
|
||||||
import necessary.General;
|
import necessary.General;
|
||||||
import necessary.Group;
|
import qilin.primitives.Group;
|
||||||
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
public class Prover implements Mix2ZeroKnowledgeProver {
|
public class Prover implements Mix2ZeroKnowledgeProver {
|
||||||
|
|
||||||
Group group;
|
Group<ByteString> group;
|
||||||
General general;
|
General general;
|
||||||
Random rand;
|
Random rand;
|
||||||
Encryption encryptor;
|
Encryption encryptor;
|
||||||
|
|
||||||
public Prover(Group group,Random rand,Encryption encryptor,General general) {
|
public Prover(Group<ByteString> group,Random rand,Encryption encryptor,General general) {
|
||||||
this.group = group;
|
this.group = group;
|
||||||
this.rand = rand;
|
this.rand = rand;
|
||||||
this.encryptor = encryptor;
|
this.encryptor = encryptor;
|
||||||
|
@ -31,7 +30,7 @@ public class Prover implements Mix2ZeroKnowledgeProver {
|
||||||
Crypto.RerandomizableEncryptedMessage in2,
|
Crypto.RerandomizableEncryptedMessage in2,
|
||||||
Crypto.RerandomizableEncryptedMessage out1,
|
Crypto.RerandomizableEncryptedMessage out1,
|
||||||
Crypto.RerandomizableEncryptedMessage out2,
|
Crypto.RerandomizableEncryptedMessage out2,
|
||||||
boolean sw,
|
boolean sw,int i,int j, int layer,
|
||||||
Crypto.EncryptionRandomness r1,
|
Crypto.EncryptionRandomness r1,
|
||||||
Crypto.EncryptionRandomness r2) {
|
Crypto.EncryptionRandomness r2) {
|
||||||
|
|
||||||
|
@ -50,11 +49,17 @@ public class Prover implements Mix2ZeroKnowledgeProver {
|
||||||
third = createOrProof(in2, out1, in2, out2, r2, true);
|
third = createOrProof(in2, out1, in2, out2, r2, true);
|
||||||
fourth = createOrProof(in1, out2, in2, out2, r1, true);
|
fourth = createOrProof(in1, out2, in2, out2, r1, true);
|
||||||
}
|
}
|
||||||
|
Mixing.ZeroKnowledgeProof.Location location = Mixing.ZeroKnowledgeProof.Location.newBuilder()
|
||||||
|
.setI(i)
|
||||||
|
.setJ(j)
|
||||||
|
.setLayer(layer)
|
||||||
|
.build();
|
||||||
return Mixing.ZeroKnowledgeProof.newBuilder()
|
return Mixing.ZeroKnowledgeProof.newBuilder()
|
||||||
.setFirst(first)
|
.setFirst(first)
|
||||||
.setSecond(second)
|
.setSecond(second)
|
||||||
.setThird(third)
|
.setThird(third)
|
||||||
.setFourth(fourth)
|
.setFourth(fourth)
|
||||||
|
.setLocation(location)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +79,8 @@ public class Prover implements Mix2ZeroKnowledgeProver {
|
||||||
return createOrProofElGamal(e1ElGamal,e2ElGamal,e1TagElGamal,e2TagElGamal,x,flag);
|
return createOrProofElGamal(e1ElGamal,e2ElGamal,e1TagElGamal,e2TagElGamal,x,flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private Mixing.ZeroKnowledgeProof.OrProof createOrProofElGamal(ElGamalCiphertext e1,
|
private Mixing.ZeroKnowledgeProof.OrProof createOrProofElGamal(ElGamalCiphertext e1,
|
||||||
ElGamalCiphertext e2,
|
ElGamalCiphertext e2,
|
||||||
ElGamalCiphertext e1New,
|
ElGamalCiphertext e1New,
|
||||||
|
@ -81,27 +88,27 @@ public class Prover implements Mix2ZeroKnowledgeProver {
|
||||||
Crypto.EncryptionRandomness x,
|
Crypto.EncryptionRandomness x,
|
||||||
boolean flag) {
|
boolean flag) {
|
||||||
ByteString g1 = general.getG();
|
ByteString g1 = general.getG();
|
||||||
ByteString h1 = group.div(e1New.getC1(),e1.getC1());
|
ByteString h1 = group.add(e1New.getC1(),group.negate(e1.getC1()));
|
||||||
ByteString g2 = general.getH();
|
ByteString g2 = general.getH();
|
||||||
ByteString h2 = group.div(e1New.getC2(),e1.getC2());
|
ByteString h2 = group.add(e1New.getC2(),group.negate(e1.getC2()));
|
||||||
|
|
||||||
ByteString g1Tag = general.getG();
|
ByteString g1Tag = general.getG();
|
||||||
ByteString h1Tag = group.div(e2New.getC1(),e2.getC1());
|
ByteString h1Tag = group.add(e2New.getC1(),group.negate(e2.getC1()));
|
||||||
ByteString g2Tag = general.getH();
|
ByteString g2Tag = general.getH();
|
||||||
ByteString h2Tag = group.div(e2New.getC2(),e2.getC2());
|
ByteString h2Tag = group.add(e2New.getC2(),group.negate(e2.getC2()));
|
||||||
|
|
||||||
BigInteger r = new BigInteger(encryptor.generateRandomness(rand).getData().toByteArray()).mod(group.groupSize());
|
BigInteger r = new BigInteger(encryptor.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound());
|
||||||
BigInteger c1,c2,z,zTag;
|
BigInteger c1,c2,z,zTag;
|
||||||
ByteString u,v,uTag,vTag;
|
ByteString u,v,uTag,vTag;
|
||||||
if (flag)
|
if (flag)
|
||||||
{
|
{
|
||||||
c2 = new BigInteger(encryptor.generateRandomness(rand).getData().toByteArray()).mod(group.groupSize());
|
c2 = new BigInteger(encryptor.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound());
|
||||||
zTag = new BigInteger(encryptor.generateRandomness(rand).getData().toByteArray()).mod(group.groupSize());
|
zTag = new BigInteger(encryptor.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound());
|
||||||
//step 1
|
//step 1
|
||||||
u = group.pow(g1, r);
|
u = group.multiply(g1, r);
|
||||||
v = group.pow(g2, r);
|
v = group.multiply(g2, r);
|
||||||
uTag = group.div(group.pow(g1Tag, zTag), group.pow(h1Tag, c2));
|
uTag = group.add(group.multiply(g1Tag, zTag), group.negate(group.multiply(h1Tag, c2)));
|
||||||
vTag = group.div(group.pow(g2Tag, zTag), group.pow(h2Tag, c2));
|
vTag = group.add(group.multiply(g2Tag, zTag), group.negate(group.multiply(h2Tag, c2)));
|
||||||
//step 2
|
//step 2
|
||||||
// c1 = (hash(input + step1) + group size - c2)% group size
|
// c1 = (hash(input + step1) + group size - c2)% group size
|
||||||
Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle forRandomOracle =
|
Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle forRandomOracle =
|
||||||
|
@ -119,20 +126,20 @@ public class Prover implements Mix2ZeroKnowledgeProver {
|
||||||
.setUTag(uTag)
|
.setUTag(uTag)
|
||||||
.setVTag(vTag)
|
.setVTag(vTag)
|
||||||
.build();
|
.build();
|
||||||
c1 = general.hash(forRandomOracle).add(group.groupSize().subtract(c2)).mod(group.groupSize());
|
c1 = general.hash(forRandomOracle).add(group.orderUpperBound().subtract(c2)).mod(group.orderUpperBound());
|
||||||
//step 3
|
//step 3
|
||||||
//z = (r + c1 * x) % group size;
|
//z = (r + c1 * x) % group size;
|
||||||
z = r.add(c1.multiply(new BigInteger(x.getData().toByteArray()))).mod(group.groupSize());
|
z = r.add(c1.multiply(new BigInteger(x.getData().toByteArray()))).mod(group.orderUpperBound());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
c1 = new BigInteger(encryptor.generateRandomness(rand).getData().toByteArray()).mod(group.groupSize());
|
c1 = new BigInteger(encryptor.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound());
|
||||||
z = new BigInteger(encryptor.generateRandomness(rand).getData().toByteArray()).mod(group.groupSize());
|
z = new BigInteger(encryptor.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound());
|
||||||
//step 1
|
//step 1
|
||||||
uTag = group.pow(g1Tag, r);
|
uTag = group.multiply(g1Tag, r);
|
||||||
vTag = group.pow(g2Tag, r);
|
vTag = group.multiply(g2Tag, r);
|
||||||
u = group.div(group.pow(g1, z), group.pow(h1, c1));
|
u = group.add(group.multiply(g1, z), group.negate(group.multiply(h1, c1)));
|
||||||
v = group.div(group.pow(g2, z), group.pow(h2, c1));
|
v = group.add(group.multiply(g2, z), group.negate(group.multiply(h2, c1)));
|
||||||
//step 2
|
//step 2
|
||||||
// c1 = (hash(input + step1) + group size - c1)% group size
|
// c1 = (hash(input + step1) + group size - c1)% group size
|
||||||
Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle forRandomOracle =
|
Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle forRandomOracle =
|
||||||
|
@ -150,10 +157,10 @@ public class Prover implements Mix2ZeroKnowledgeProver {
|
||||||
.setUTag(uTag)
|
.setUTag(uTag)
|
||||||
.setVTag(vTag)
|
.setVTag(vTag)
|
||||||
.build();
|
.build();
|
||||||
c2 = general.hash(forRandomOracle).add(group.groupSize().subtract(c1)).mod(group.groupSize());
|
c2 = general.hash(forRandomOracle).add(group.orderUpperBound().subtract(c1)).mod(group.orderUpperBound());
|
||||||
//step 3
|
//step 3
|
||||||
//zTag = (r + c2 * x) % group size;
|
//zTag = (r + c2 * x) % group size;
|
||||||
zTag = r.add(c2.multiply(new BigInteger(x.getData().toByteArray()))).mod(group.groupSize());
|
zTag = r.add(c2.multiply(new BigInteger(x.getData().toByteArray()))).mod(group.orderUpperBound());
|
||||||
}
|
}
|
||||||
return Mixing.ZeroKnowledgeProof.OrProof.newBuilder()
|
return Mixing.ZeroKnowledgeProof.OrProof.newBuilder()
|
||||||
.setG1(g1)
|
.setG1(g1)
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
package verifier;
|
package verifier;
|
||||||
|
|
||||||
import meerkat.crypto.Encryption;
|
|
||||||
import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier;
|
import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier;
|
||||||
import meerkat.protobuf.ConcreteCrypto.ElGamalCiphertext;
|
import meerkat.protobuf.ConcreteCrypto.ElGamalCiphertext;
|
||||||
import meerkat.protobuf.Crypto;
|
import meerkat.protobuf.Crypto;
|
||||||
import meerkat.protobuf.Mixing;
|
import meerkat.protobuf.Mixing;
|
||||||
import necessary.General;
|
import necessary.General;
|
||||||
import necessary.Group;
|
import qilin.primitives.Group;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
@ -42,6 +41,7 @@ public class Verifier implements Mix2ZeroKnowledgeVerifier {
|
||||||
ElGamalCiphertext e1TagElGamal = general.calcRerandomizable2ElGamal(out1);
|
ElGamalCiphertext e1TagElGamal = general.calcRerandomizable2ElGamal(out1);
|
||||||
ElGamalCiphertext e2TagElGamal = general.calcRerandomizable2ElGamal(out2);
|
ElGamalCiphertext e2TagElGamal = general.calcRerandomizable2ElGamal(out2);
|
||||||
|
|
||||||
|
|
||||||
return verifyElGamaOrProof(e1ElGamal,e2ElGamal,e1TagElGamal,e2TagElGamal,proof.getFirst()) &&
|
return verifyElGamaOrProof(e1ElGamal,e2ElGamal,e1TagElGamal,e2TagElGamal,proof.getFirst()) &&
|
||||||
verifyElGamaOrProof(e1ElGamal,e2ElGamal,e1TagElGamal,e2TagElGamal,proof.getSecond()) &&
|
verifyElGamaOrProof(e1ElGamal,e2ElGamal,e1TagElGamal,e2TagElGamal,proof.getSecond()) &&
|
||||||
verifyElGamaOrProof(e1ElGamal,e2ElGamal,e1TagElGamal,e2TagElGamal,proof.getThird()) &&
|
verifyElGamaOrProof(e1ElGamal,e2ElGamal,e1TagElGamal,e2TagElGamal,proof.getThird()) &&
|
||||||
|
@ -73,28 +73,28 @@ public class Verifier implements Mix2ZeroKnowledgeVerifier {
|
||||||
|
|
||||||
return //input
|
return //input
|
||||||
orProof.getG1().equals(general.getG())&&
|
orProof.getG1().equals(general.getG())&&
|
||||||
orProof.getH1().equals(group.div(e1New.getC1(), e1.getC1()))&&
|
orProof.getH1().equals(group.add(e1New.getC1(), group.negate(e1.getC1())))&&
|
||||||
orProof.getG2().equals(general.getH())&&
|
orProof.getG2().equals(general.getH())&&
|
||||||
orProof.getH2().equals(group.div(e1New.getC2(), e1.getC2()))&&
|
orProof.getH2().equals(group.add(e1New.getC2(), group.negate(e1.getC2())))&&
|
||||||
// input'
|
// input'
|
||||||
orProof.getG1Tag().equals(general.getG())&&
|
orProof.getG1Tag().equals(general.getG())&&
|
||||||
orProof.getH1Tag().equals(group.div(e2New.getC1(), e2.getC1()))&&
|
orProof.getH1Tag().equals(group.add(e2New.getC1(), group.negate(e2.getC1())))&&
|
||||||
orProof.getG2Tag().equals(general.getH())&&
|
orProof.getG2Tag().equals(general.getH())&&
|
||||||
orProof.getH2Tag().equals(group.div(e2New.getC2(), e2.getC2())) &&
|
orProof.getH2Tag().equals(group.add(e2New.getC2(), group.negate(e2.getC2()))) &&
|
||||||
// hash
|
// hash
|
||||||
// assert (c1 + c2 ) % group size == hash (imput + step1) % group size
|
// assert (c1 + c2 ) % group size == hash (imput + step1) % group size
|
||||||
new BigInteger(orProof.getC1().toByteArray()).add(new BigInteger(orProof.getC2().toByteArray())).mod(group.groupSize())
|
new BigInteger(orProof.getC1().toByteArray()).add(new BigInteger(orProof.getC2().toByteArray())).mod(group.orderUpperBound())
|
||||||
.equals(general.hash(forRandomOracle).mod(group.groupSize()).mod(group.groupSize()))&&
|
.equals(general.hash(forRandomOracle).mod(group.orderUpperBound()).mod(group.orderUpperBound()))&&
|
||||||
// proof
|
// proof
|
||||||
// g1 ^ z == u * ( h1 ^ c1 ) && g2 ^ z == v * ( h2 ^ c1 ) && the same for tag case
|
// g1 ^ z == u * ( h1 ^ c1 ) && g2 ^ z == v * ( h2 ^ c1 ) && the same for tag case
|
||||||
group.pow(orProof.getG1(), new BigInteger(orProof.getZ().toByteArray()))
|
group.multiply(orProof.getG1(), new BigInteger(orProof.getZ().toByteArray()))
|
||||||
.equals(group.mul(orProof.getU(), group.pow(orProof.getH1(),new BigInteger(orProof.getC1().toByteArray())))) &&
|
.equals(group.add(orProof.getU(), group.multiply(orProof.getH1(),new BigInteger(orProof.getC1().toByteArray())))) &&
|
||||||
group.pow(orProof.getG2(), new BigInteger(orProof.getZ().toByteArray()))
|
group.multiply(orProof.getG2(), new BigInteger(orProof.getZ().toByteArray()))
|
||||||
.equals(group.mul(orProof.getV(), group.pow(orProof.getH2(),new BigInteger(orProof.getC1().toByteArray())))) &&
|
.equals(group.add(orProof.getV(), group.multiply(orProof.getH2(),new BigInteger(orProof.getC1().toByteArray())))) &&
|
||||||
group.pow(orProof.getG1Tag(), new BigInteger(orProof.getZTag().toByteArray()))
|
group.multiply(orProof.getG1Tag(), new BigInteger(orProof.getZTag().toByteArray()))
|
||||||
.equals(group.mul(orProof.getUTag(), group.pow(orProof.getH1Tag(),new BigInteger(orProof.getC2().toByteArray())))) &&
|
.equals(group.add(orProof.getUTag(), group.multiply(orProof.getH1Tag(),new BigInteger(orProof.getC2().toByteArray())))) &&
|
||||||
group.pow(orProof.getG2Tag(), new BigInteger(orProof.getZTag().toByteArray()))
|
group.multiply(orProof.getG2Tag(), new BigInteger(orProof.getZTag().toByteArray()))
|
||||||
.equals(group.mul(orProof.getVTag(), group.pow(orProof.getH2Tag(),new BigInteger(orProof.getC2().toByteArray()))));
|
.equals(group.add(orProof.getVTag(), group.multiply(orProof.getH2Tag(),new BigInteger(orProof.getC2().toByteArray()))));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
package mixer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Tzlil on 12/17/2015.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class MixNetworkTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMixNetwork() throws Exception{
|
||||||
|
|
||||||
|
Random random = new Random();
|
||||||
|
int logn = random.nextInt()%10 + 5;
|
||||||
|
|
||||||
|
int n = 1 << logn;
|
||||||
|
int layers = 2*logn - 1;
|
||||||
|
RandomPermutation randomPermutation = new RandomPermutation(n,random);
|
||||||
|
MixNetwork mixNetwork = new MixNetwork(randomPermutation);
|
||||||
|
|
||||||
|
//initialize arr s.t arr[i] = i
|
||||||
|
int[] arr = new int[n];
|
||||||
|
for (int i = 0; i < n ;i ++)
|
||||||
|
arr[i] = i;
|
||||||
|
|
||||||
|
// layer by layer swap between values
|
||||||
|
for (int layer = 0 ; layer< layers ; layer ++) {
|
||||||
|
for (Switch sw : mixNetwork.getSwitchesByLayer(layer)) {
|
||||||
|
if(sw.value) {
|
||||||
|
arr[sw.i] += arr[sw.j];
|
||||||
|
arr[sw.j] = arr[sw.i] - arr[sw.j];
|
||||||
|
arr[sw.i] -= arr[sw.j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(Arrays.equals(arr,randomPermutation.permutation));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue