smal changes after code review
parent
c37d30baf6
commit
767d73c143
|
@ -15,4 +15,5 @@ public interface Mix2ZeroKnowledgeProver {
|
||||||
Crypto.EncryptionRandomness r1,
|
Crypto.EncryptionRandomness r1,
|
||||||
Crypto.EncryptionRandomness r2);
|
Crypto.EncryptionRandomness r2);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,118 +0,0 @@
|
||||||
package mixer;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
class Graph
|
|
||||||
{
|
|
||||||
private int n;
|
|
||||||
private int nDiv2;
|
|
||||||
private Node[] nodes;
|
|
||||||
protected Graph(int[] permutation){
|
|
||||||
n = permutation.length; // n = 2^k
|
|
||||||
nDiv2 = n >> 1;
|
|
||||||
createNodes();
|
|
||||||
createEdges(permutation);
|
|
||||||
setSwitches();
|
|
||||||
}
|
|
||||||
|
|
||||||
// provide an access to graph to algorithm result
|
|
||||||
// index must be less then n/2
|
|
||||||
protected boolean getSwitchValue(int index,boolean up)
|
|
||||||
{
|
|
||||||
return up ? nodes[index].on : nodes[index + n / 2].on;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create two lines of nodes size n/2 each
|
|
||||||
// the value of the i th node is (i,i+n/2) if i < n /2 (first line)
|
|
||||||
// otherwise its value is (i - n/2 , i) (second line)
|
|
||||||
private void createNodes()
|
|
||||||
{
|
|
||||||
nodes = new Node[n];
|
|
||||||
for (int i = 0; i < n / 2; i++)
|
|
||||||
{
|
|
||||||
nodes[i] = new Node(true);
|
|
||||||
nodes[i + nDiv2] = new Node(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// create an edge between each pair of nodes i,j from different lines (i index of the first line)
|
|
||||||
// if exists k in i th node's value and t in j th node's value
|
|
||||||
// s.t permutation[k] == t
|
|
||||||
// the edge is broken if (k < n/2 and t >= n/2) or (k >= n/2 and t < n/2)
|
|
||||||
// Note: in purpose to avoid edge cases, each node has exactly two edges
|
|
||||||
private void createEdges(int[] permutation)
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
for (int i = 0; i < nDiv2; i++)
|
|
||||||
{
|
|
||||||
j = (permutation[i] % nDiv2) + nDiv2;
|
|
||||||
nodes[i].edges.add(new Edge(nodes[j], (permutation[i] >= nDiv2)));
|
|
||||||
nodes[j].edges.add(new Edge(nodes[i], (permutation[i] >= nDiv2)));
|
|
||||||
|
|
||||||
j = (permutation[i + nDiv2] % nDiv2) + nDiv2;
|
|
||||||
nodes[i].edges.add(new Edge(nodes[j], (permutation[i + nDiv2] < nDiv2)));
|
|
||||||
nodes[j].edges.add(new Edge(nodes[i], (permutation[i + nDiv2] < nDiv2)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set switch's value (on/off) for each switch (node)
|
|
||||||
// s.t if nodes i,j connected by edge e, i th switch's value
|
|
||||||
// must be equal to j's if e is broken or not equal if e is not broken
|
|
||||||
private void setSwitches()
|
|
||||||
{
|
|
||||||
Node node;
|
|
||||||
boolean v;
|
|
||||||
Edge e0,e1;
|
|
||||||
// iterate over first line of nodes
|
|
||||||
for (int i = 0; i < nDiv2; i++)
|
|
||||||
{
|
|
||||||
node = nodes[i];
|
|
||||||
if (node.set)
|
|
||||||
continue;
|
|
||||||
//select default value for first node in connected component
|
|
||||||
v = false;
|
|
||||||
// set value to all reachable nodes from node
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
node.set = true;
|
|
||||||
node.on = v;
|
|
||||||
e0 = node.edges.get(0); e1 = node.edges.get(1);
|
|
||||||
if (e0.neighbor.set && e1.neighbor.set)
|
|
||||||
break;
|
|
||||||
v ^= (!e0.neighbor.set) ? e0.broken : e1.broken;
|
|
||||||
node = (!e0.neighbor.set) ? e0.neighbor : e1.neighbor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//inner classes
|
|
||||||
|
|
||||||
private class Node
|
|
||||||
{
|
|
||||||
public boolean up;
|
|
||||||
public List<Edge> edges;
|
|
||||||
public boolean on;
|
|
||||||
public boolean set;
|
|
||||||
public Node(boolean up)
|
|
||||||
{
|
|
||||||
this.up = up;
|
|
||||||
edges = new ArrayList<Edge>();
|
|
||||||
set = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Edge
|
|
||||||
{
|
|
||||||
public Node neighbor;
|
|
||||||
public boolean broken;
|
|
||||||
public Edge(Node neighbor, boolean broken)
|
|
||||||
{
|
|
||||||
this.neighbor = neighbor;
|
|
||||||
this.broken = broken;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,195 @@
|
||||||
|
package mixer;
|
||||||
|
|
||||||
|
import com.google.protobuf.Enum;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Tzlil on 12/15/2015.
|
||||||
|
*/
|
||||||
|
public class MixNetwork {
|
||||||
|
|
||||||
|
private final Switch[][] switches;
|
||||||
|
private final Random random;
|
||||||
|
|
||||||
|
public MixNetwork(int n,int layers,Random random)
|
||||||
|
{
|
||||||
|
this.random = random;
|
||||||
|
int[] permutation = randomPermutation(n);
|
||||||
|
int[] pi, piL, piR;
|
||||||
|
Queue<int[]> permutationsQueue = new ArrayBlockingQueue<int[]>(n);
|
||||||
|
Graph graph;
|
||||||
|
int iDiv2;
|
||||||
|
int nDiv2 = n >> 1;
|
||||||
|
switches = new Switch[layers][nDiv2];
|
||||||
|
int index1,index2;
|
||||||
|
|
||||||
|
permutationsQueue.add(permutation);
|
||||||
|
for (int i = n, layer = 0; i > 1; i >>= 1, layer++) // i == permutation size
|
||||||
|
{
|
||||||
|
iDiv2 = i >> 1;
|
||||||
|
for (int j = 0; j < nDiv2; j += iDiv2) // j == permutation start index
|
||||||
|
{
|
||||||
|
pi = permutationsQueue.remove();
|
||||||
|
graph = new Graph(pi);
|
||||||
|
piL = new int[iDiv2];
|
||||||
|
piR = new int[iDiv2];
|
||||||
|
for (int k = 0; k < iDiv2; k++) // k == switch index in permutation j
|
||||||
|
{
|
||||||
|
index1 = k + j;
|
||||||
|
index2 = k + j + iDiv2;
|
||||||
|
switches[layers - layer - 1][k + j] = new Switch(index1,index2,layers - layer - 1,graph.getSwitchValue(k, true));
|
||||||
|
switches[layer][k + j] = new Switch(index1,index2,layer,graph.getSwitchValue(k, false));
|
||||||
|
|
||||||
|
if (!switches[layers - layer - 1][k + j].value) {
|
||||||
|
piL[k] = pi[k] % iDiv2;
|
||||||
|
piR[k] = pi[k + iDiv2] % iDiv2;
|
||||||
|
} else {
|
||||||
|
piL[k] = pi[k + iDiv2] % iDiv2;
|
||||||
|
piR[k] = pi[k] % iDiv2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
permutationsQueue.add(piL);
|
||||||
|
permutationsQueue.add(piR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Switch[] getSwitchesByLayer(int 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 int n;
|
||||||
|
private int nDiv2;
|
||||||
|
private Node[][] nodes;
|
||||||
|
protected Graph(int[] permutation){
|
||||||
|
n = permutation.length; // n = 2^k
|
||||||
|
nDiv2 = n >> 1;
|
||||||
|
createNodes();
|
||||||
|
createEdges(permutation);
|
||||||
|
setSwitches();
|
||||||
|
}
|
||||||
|
|
||||||
|
// provide an access to algorithm result
|
||||||
|
// index must be less then n/2
|
||||||
|
protected boolean getSwitchValue(int index,boolean up)
|
||||||
|
{
|
||||||
|
return up ? nodes[0][index].value : nodes[1][index].value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create two lines of nodes size n/2 each
|
||||||
|
// the value of the i th node is (i,i+n/2) if i < n /2 (first line)
|
||||||
|
// otherwise its value is (i - n/2 , i) (second line)
|
||||||
|
private void createNodes()
|
||||||
|
{
|
||||||
|
nodes = new Node[2][nDiv2];
|
||||||
|
for (int i = 0; i < nDiv2; i++)
|
||||||
|
{
|
||||||
|
nodes[0][i] = new Node();
|
||||||
|
nodes[1][i] = new Node();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create an edge between each pair of nodes i,j from different lines (i index of the first line)
|
||||||
|
// if exists k in i th node's value and t in j th node's value
|
||||||
|
// s.t permutation[k] == t
|
||||||
|
// the edge is broken if (k < n/2 and t >= n/2) or (k >= n/2 and t < n/2)
|
||||||
|
// Note: in purpose to avoid edge cases, each node has exactly two edges
|
||||||
|
private void createEdges(int[] permutation)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
for (int i = 0; i < nDiv2; i++)
|
||||||
|
{
|
||||||
|
j = permutation[i] % nDiv2;
|
||||||
|
nodes[0][i].edges.add(new Edge(nodes[1][j], (permutation[i] >= nDiv2)));
|
||||||
|
nodes[1][j].edges.add(new Edge(nodes[0][i], (permutation[i] >= nDiv2)));
|
||||||
|
|
||||||
|
j = permutation[i + nDiv2] % nDiv2;
|
||||||
|
nodes[0][i].edges.add(new Edge(nodes[1][j], (permutation[i + nDiv2] < nDiv2)));
|
||||||
|
nodes[1][j].edges.add(new Edge(nodes[0][i], (permutation[i + nDiv2] < nDiv2)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set switch's value (on/off) for each switch (node)
|
||||||
|
// s.t if nodes i,j connected by edge e, i th switch's value
|
||||||
|
// must be equal to j's if e is broken or not equal if e is not broken
|
||||||
|
private void setSwitches()
|
||||||
|
{
|
||||||
|
Node node;
|
||||||
|
boolean v;
|
||||||
|
Edge e0,e1;
|
||||||
|
// iterate over first line of nodes
|
||||||
|
for (int i = 0; i < nDiv2; i++)
|
||||||
|
{
|
||||||
|
node = nodes[0][i];
|
||||||
|
if (node.set)
|
||||||
|
continue;
|
||||||
|
//select default value for first node in connected component
|
||||||
|
v = false;
|
||||||
|
// set value to all reachable nodes from node
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
node.set = true;
|
||||||
|
node.value = v;
|
||||||
|
e0 = node.edges.get(0); e1 = node.edges.get(1);
|
||||||
|
if (e0.neighbor.set && e1.neighbor.set)
|
||||||
|
break;
|
||||||
|
v ^= (!e0.neighbor.set) ? e0.broken : e1.broken;
|
||||||
|
node = (!e0.neighbor.set) ? e0.neighbor : e1.neighbor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//inner classes
|
||||||
|
private class Node
|
||||||
|
{
|
||||||
|
public List<Edge> edges;
|
||||||
|
private boolean value;
|
||||||
|
private boolean set;
|
||||||
|
public Node()
|
||||||
|
{
|
||||||
|
edges = new ArrayList<Edge>(2);
|
||||||
|
set = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Edge
|
||||||
|
{
|
||||||
|
public Node neighbor;
|
||||||
|
public boolean broken;
|
||||||
|
public Edge(Node neighbor, boolean broken)
|
||||||
|
{
|
||||||
|
this.neighbor = neighbor;
|
||||||
|
this.broken = broken;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -2,8 +2,6 @@ package mixer;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Queue;
|
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
|
||||||
import qilin.util.Pair;
|
import qilin.util.Pair;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
@ -15,151 +13,69 @@ import meerkat.protobuf.Mixing.*;
|
||||||
import meerkat.crypto.Encryption;
|
import meerkat.crypto.Encryption;
|
||||||
import meerkat.crypto.mixnet.Mix2ZeroKnowledgeProver;
|
import meerkat.crypto.mixnet.Mix2ZeroKnowledgeProver;
|
||||||
|
|
||||||
public class Mixer implements meerkat.crypto.mixnet.Mixer{
|
public class Mixer implements meerkat.crypto.mixnet.Mixer {
|
||||||
|
|
||||||
private Random random;
|
private Random random;
|
||||||
private Mix2ZeroKnowledgeProver prover;
|
private Mix2ZeroKnowledgeProver prover;
|
||||||
private Encryption encryptor;
|
private Encryption encryptor;
|
||||||
|
|
||||||
public Mixer(Random rand,Mix2ZeroKnowledgeProver prov,Encryption enc) {
|
public Mixer(Random rand, Mix2ZeroKnowledgeProver prov, Encryption enc) {
|
||||||
this.random = rand;
|
this.random = rand;
|
||||||
this.prover = prov;
|
this.prover = prov;
|
||||||
this.encryptor = enc;
|
this.encryptor = enc;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<ZeroKnowledgeProof[][],RerandomizableEncryptedMessage[][]> mix(List<RerandomizableEncryptedMessage> ciphertexts) throws InvalidProtocolBufferException{
|
public Pair<ZeroKnowledgeProof[][], RerandomizableEncryptedMessage[][]> mix(List<RerandomizableEncryptedMessage> ciphertexts) throws InvalidProtocolBufferException {
|
||||||
|
|
||||||
int n = ciphertexts.size();
|
int n = ciphertexts.size();
|
||||||
int nDiv2 = n >> 1;
|
int nDiv2 = n >> 1;
|
||||||
// assert n = 2^k and n > 1
|
// assert n = 2^k and n > 1
|
||||||
if( n <= 1 || ((n & (n-1)) != 0))
|
if (n <= 1 || ((n & (n - 1)) != 0))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
//initialization
|
//initialization
|
||||||
int layers = (int)(2 * Math.log(n)/Math.log(2)) - 1; // layers = 2logn -1
|
int layers = (int) (2 * Math.log(n) / Math.log(2)) - 1; // layers = 2logn -1
|
||||||
RerandomizableEncryptedMessage[][] encryptionTable = new RerandomizableEncryptedMessage[layers][n];
|
RerandomizableEncryptedMessage[][] encryptionTable = new RerandomizableEncryptedMessage[layers + 1][n];
|
||||||
ZeroKnowledgeProof[][] proofsTable= new ZeroKnowledgeProof[layers][nDiv2];
|
ZeroKnowledgeProof[][] proofsTable = new ZeroKnowledgeProof[layers][nDiv2];
|
||||||
boolean[][] mixnet = createMixNet(n,layers);
|
int index1, index2, switchIndex = 0;
|
||||||
int index1, index2, switchIndex = 0;
|
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);
|
||||||
|
Switch[] switchesLayer;
|
||||||
|
|
||||||
// set first level of encryption
|
// set first level of encryption
|
||||||
for (int j = 0; j < n; j++)
|
for (int j = 0; j < n; j++) {
|
||||||
{
|
encryptionTable[0][j] = ciphertexts.get(j);
|
||||||
encryptionTable[0][j] = ciphertexts.get(j);
|
|
||||||
}
|
|
||||||
|
|
||||||
// main loop
|
|
||||||
int i = n,iDiv2;
|
|
||||||
for (int layer = 0; layer < layers; layer++) // i == permutation size
|
|
||||||
{
|
|
||||||
iDiv2 = i >> 1;
|
|
||||||
for (int j = 0; j < n; j += i) // j == permutation index
|
|
||||||
{
|
|
||||||
for (int k = 0; k < iDiv2; k++) // k == elements index in permutation j
|
|
||||||
{
|
|
||||||
index1 = k + j;
|
|
||||||
index2 = k + j + iDiv2;
|
|
||||||
e1 = encryptionTable[layer][index1];
|
|
||||||
e2 = encryptionTable[layer][index2];
|
|
||||||
r1 = encryptor.generateRandomness(random);
|
|
||||||
r2 = encryptor.generateRandomness(random);
|
|
||||||
if (!mixnet[layer][switchIndex])
|
|
||||||
{
|
|
||||||
encryptionTable[layer+1][index1] = encryptor.rerandomize(e1, r1);
|
|
||||||
encryptionTable[layer+1][index2] = encryptor.rerandomize(e2,r2);
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
encryptionTable[layer+1][index1] = encryptor.rerandomize(e2,r2);
|
|
||||||
encryptionTable[layer+1][index2] = encryptor.rerandomize(e1,r1);
|
|
||||||
}
|
|
||||||
proofsTable[layer][switchIndex] =
|
|
||||||
prover.prove(e1, e2, encryptionTable[layer + 1][index1],
|
|
||||||
encryptionTable[layer + 1][index2],
|
|
||||||
mixnet[layer][switchIndex], r1,r2);
|
|
||||||
|
|
||||||
switchIndex = (switchIndex + 1) % nDiv2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (half)
|
|
||||||
{
|
|
||||||
i = iDiv2;
|
|
||||||
if (i == 1)
|
|
||||||
{
|
|
||||||
half = false;
|
|
||||||
i = 4; // avoid duplicate layer in the middle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
i <<= 1;
|
|
||||||
}
|
|
||||||
return new Pair<ZeroKnowledgeProof[][],RerandomizableEncryptedMessage[][]>(proofsTable, encryptionTable);
|
|
||||||
}
|
|
||||||
|
|
||||||
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];
|
// main loop
|
||||||
int index;
|
for (int layer = 0; layer < layers; layer++)
|
||||||
for (int i = 0; i < n; i++)
|
|
||||||
{
|
{
|
||||||
index = random.nextInt(n - i);
|
switchesLayer = mixNetwork.getSwitchesByLayer(layer);
|
||||||
result[i] = numbers.get(index);
|
for (Switch sw : switchesLayer) {
|
||||||
numbers.remove(index);
|
index1 = sw.i;
|
||||||
}
|
index2 = sw.j;
|
||||||
return result;
|
e1 = encryptionTable[layer][index1];
|
||||||
}
|
e2 = encryptionTable[layer][index2];
|
||||||
|
r1 = encryptor.generateRandomness(random);
|
||||||
|
r2 = encryptor.generateRandomness(random);
|
||||||
|
if (!sw.value) {
|
||||||
|
encryptionTable[layer + 1][index1] = encryptor.rerandomize(e1, r1);
|
||||||
|
encryptionTable[layer + 1][index2] = encryptor.rerandomize(e2, r2);
|
||||||
|
|
||||||
private boolean[][] createMixNet(int n,int layers)
|
} else {
|
||||||
{
|
encryptionTable[layer + 1][index1] = encryptor.rerandomize(e2, r2);
|
||||||
int[] permutation = randomPermutation(n);
|
encryptionTable[layer + 1][index2] = encryptor.rerandomize(e1, r1);
|
||||||
int[] pi, piL, piR;
|
|
||||||
Queue<int[]> permutationsQueue = new ArrayBlockingQueue<int[]>(n);
|
|
||||||
Graph graph;
|
|
||||||
int iDiv2;
|
|
||||||
int nDiv2 = n >> 1;
|
|
||||||
boolean[][] mixnet = new boolean[layers][nDiv2];
|
|
||||||
|
|
||||||
permutationsQueue.add(permutation);
|
|
||||||
for (int i = n, layer = 0; i > 1; i >>= 1, layer++) // i == permutation size
|
|
||||||
{
|
|
||||||
iDiv2 = i >> 1;
|
|
||||||
for (int j = 0; j < nDiv2; j += iDiv2) // j == permutation index
|
|
||||||
{
|
|
||||||
pi = permutationsQueue.remove();
|
|
||||||
graph = new Graph(pi);
|
|
||||||
piL = new int[iDiv2];
|
|
||||||
piR = new int[iDiv2];
|
|
||||||
for (int k = 0; k < iDiv2; k++) // k == switch index in permutation j
|
|
||||||
{
|
|
||||||
mixnet[layers - layer - 1][k + j] = graph.getSwitchValue(k, true);
|
|
||||||
mixnet[layer][k + j] = graph.getSwitchValue(k, false);
|
|
||||||
|
|
||||||
if (!mixnet[layers - layer - 1][k + j])
|
|
||||||
{
|
|
||||||
piL[k] = pi[k] % iDiv2;
|
|
||||||
piR[k] = pi[k + iDiv2] % iDiv2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
piL[k] = pi[k + iDiv2] % iDiv2;
|
|
||||||
piR[k] = pi[k] % iDiv2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
permutationsQueue.add(piL);
|
proofsTable[layer][switchIndex] =
|
||||||
permutationsQueue.add(piR);
|
prover.prove(e1, e2, encryptionTable[layer + 1][index1],
|
||||||
|
encryptionTable[layer + 1][index2],
|
||||||
|
sw.value, r1, r2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mixnet;
|
return new Pair<ZeroKnowledgeProof[][], RerandomizableEncryptedMessage[][]>(proofsTable, encryptionTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package mixer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Tzlil on 12/15/2015.
|
||||||
|
*/
|
||||||
|
public class Switch{
|
||||||
|
|
||||||
|
public final int i, j, layer;
|
||||||
|
public final boolean value;
|
||||||
|
|
||||||
|
public Switch(int i, int j, int layer, boolean value) {
|
||||||
|
this.i = i;
|
||||||
|
this.j = j;
|
||||||
|
this.layer = layer;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,12 +31,12 @@ public class Prover implements Mix2ZeroKnowledgeProver {
|
||||||
Crypto.RerandomizableEncryptedMessage in2,
|
Crypto.RerandomizableEncryptedMessage in2,
|
||||||
Crypto.RerandomizableEncryptedMessage out1,
|
Crypto.RerandomizableEncryptedMessage out1,
|
||||||
Crypto.RerandomizableEncryptedMessage out2,
|
Crypto.RerandomizableEncryptedMessage out2,
|
||||||
boolean switched,
|
boolean sw,
|
||||||
Crypto.EncryptionRandomness r1,
|
Crypto.EncryptionRandomness r1,
|
||||||
Crypto.EncryptionRandomness r2) {
|
Crypto.EncryptionRandomness r2) {
|
||||||
|
|
||||||
Mixing.ZeroKnowledgeProof.OrProof first,second,third,fourth;
|
Mixing.ZeroKnowledgeProof.OrProof first,second,third,fourth;
|
||||||
if (!switched)
|
if (!sw)
|
||||||
{
|
{
|
||||||
first = createOrProof(in1, out1, in2, out1, r1, true);
|
first = createOrProof(in1, out1, in2, out1, r1, true);
|
||||||
second = createOrProof(in1, out1, in1, out2, r1, true);
|
second = createOrProof(in1, out1, in1, out2, r1, true);
|
||||||
|
|
Loading…
Reference in New Issue