last version - main problem was found in RerandomizeTest
parent
8a07f86c0f
commit
9bb2f47b50
|
@ -0,0 +1,91 @@
|
||||||
|
package main;
|
||||||
|
|
||||||
|
import com.google.protobuf.ByteString;
|
||||||
|
import meerkat.protobuf.BulletinBoardAPI;
|
||||||
|
import meerkat.protobuf.Crypto;
|
||||||
|
import meerkat.protobuf.Mixing;
|
||||||
|
import qilin.util.Pair;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Tzlil on 12/17/2015.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class BatchConverter {
|
||||||
|
|
||||||
|
private final int n,layers;
|
||||||
|
public BatchConverter(int n,int layers){
|
||||||
|
this.n = n;
|
||||||
|
this.layers = layers;
|
||||||
|
}
|
||||||
|
private ByteString IntegerToByteString(int a){
|
||||||
|
return ByteString.copyFrom(BigInteger.valueOf(a).toByteArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
private int ByteString2Integer(ByteString bs) {
|
||||||
|
return Integer.valueOf(bs.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<BulletinBoardAPI.BatchData> mixerOutput2BatchData
|
||||||
|
(Pair<Mixing.ZeroKnowledgeProof[][], Crypto.RerandomizableEncryptedMessage[][]> mixerOutput) {
|
||||||
|
|
||||||
|
List<BulletinBoardAPI.BatchData> result = new ArrayList<BulletinBoardAPI.BatchData>();
|
||||||
|
|
||||||
|
result.add(BulletinBoardAPI.BatchData.newBuilder()
|
||||||
|
.setData(IntegerToByteString(n))
|
||||||
|
.build());
|
||||||
|
|
||||||
|
for (Mixing.ZeroKnowledgeProof[] zkpLayer : mixerOutput.a) {
|
||||||
|
for (Mixing.ZeroKnowledgeProof zkp : zkpLayer) {
|
||||||
|
result.add(BulletinBoardAPI.BatchData.newBuilder()
|
||||||
|
.setData(zkp.toByteString())
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Crypto.RerandomizableEncryptedMessage[] encryptionLayer : mixerOutput.b) {
|
||||||
|
for (Crypto.RerandomizableEncryptedMessage encryption : encryptionLayer) {
|
||||||
|
result.add(BulletinBoardAPI.BatchData.newBuilder()
|
||||||
|
.setData(encryption.toByteString())
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pair<Mixing.ZeroKnowledgeProof[][], Crypto.RerandomizableEncryptedMessage[][]> batchDataList2MixerOutput
|
||||||
|
(List<BulletinBoardAPI.BatchData> batchDataList) throws Exception {
|
||||||
|
|
||||||
|
if (n != ByteString2Integer(batchDataList.remove(0).getData())){
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
int nDiv2 = n >>1;
|
||||||
|
Mixing.ZeroKnowledgeProof[][] proofs = new Mixing.ZeroKnowledgeProof[layers][nDiv2];
|
||||||
|
for (int layer = 0; layer <layers; layer++)
|
||||||
|
{
|
||||||
|
for (int proofIndex = 0 ; proofIndex < nDiv2 ; proofIndex ++)
|
||||||
|
{
|
||||||
|
proofs[layer][proofIndex] = Mixing.ZeroKnowledgeProof.parseFrom(batchDataList.remove(0).getData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Crypto.RerandomizableEncryptedMessage[][] encryptions
|
||||||
|
= new Crypto.RerandomizableEncryptedMessage[layers + 1][n];
|
||||||
|
for (int layer = 0; layer <layers + 1; layer++)
|
||||||
|
{
|
||||||
|
for (int encryptionIndex = 0 ; encryptionIndex < n ; encryptionIndex ++)
|
||||||
|
{
|
||||||
|
encryptions[layer][encryptionIndex] = Crypto.RerandomizableEncryptedMessage
|
||||||
|
.parseFrom(batchDataList.remove(0).getData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Pair<Mixing.ZeroKnowledgeProof[][], Crypto.RerandomizableEncryptedMessage[][]>(proofs,encryptions);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
package main;
|
||||||
|
|
||||||
|
import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier;
|
||||||
|
import meerkat.protobuf.Crypto;
|
||||||
|
import meerkat.protobuf.Mixing;
|
||||||
|
import necessary.AsyncBulletinBoardClient;
|
||||||
|
import necessary.BulletinBoardClient;
|
||||||
|
import necessary.CompleteBatch;
|
||||||
|
import qilin.util.Pair;
|
||||||
|
import verifier.VerifyTable;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Tzlil on 12/17/2015.
|
||||||
|
*/
|
||||||
|
public class BatchHandler implements AsyncBulletinBoardClient.ClientCallback<CompleteBatch> {
|
||||||
|
|
||||||
|
private Pair<Mixing.ZeroKnowledgeProof[][], Crypto.RerandomizableEncryptedMessage[][]> mixerOutput;
|
||||||
|
private boolean msgReceived;
|
||||||
|
private Throwable t;
|
||||||
|
private CompleteBatch msg;
|
||||||
|
|
||||||
|
private final int n, layers;
|
||||||
|
private final Mix2ZeroKnowledgeVerifier verifier;
|
||||||
|
|
||||||
|
public BatchHandler(int n, int layers, Mix2ZeroKnowledgeVerifier verifier) {
|
||||||
|
this.mixerOutput = null;
|
||||||
|
this.n = n;
|
||||||
|
this.layers = layers;
|
||||||
|
this.msgReceived = false;
|
||||||
|
this.t = null;
|
||||||
|
this.verifier = verifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleCallback(CompleteBatch msg) {
|
||||||
|
this.msg = msg;
|
||||||
|
this.msgReceived = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleFailure(Throwable t) {
|
||||||
|
this.t = t;
|
||||||
|
this.msgReceived = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isMsgReceived() {
|
||||||
|
return msgReceived;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void convertMessage() throws Exception {
|
||||||
|
BatchConverter batchConverter = new BatchConverter(n,layers);
|
||||||
|
mixerOutput = batchConverter.batchDataList2MixerOutput(msg.getBatchDataList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean verifyTable() throws Exception {
|
||||||
|
if (mixerOutput == null) {
|
||||||
|
convertMessage();
|
||||||
|
}
|
||||||
|
return VerifyTable.verifyTable(verifier, n, mixerOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Crypto.RerandomizableEncryptedMessage> getInputForMixer() throws Throwable {
|
||||||
|
if (t != null) {
|
||||||
|
throw t;
|
||||||
|
}
|
||||||
|
if (mixerOutput == null) {
|
||||||
|
convertMessage();
|
||||||
|
if (!VerifyTable.verifyTable(verifier, n, mixerOutput)) {
|
||||||
|
throw new Exception("in valid table");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Arrays.asList(mixerOutput.b[mixerOutput.b.length - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package main;
|
package main;
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
|
||||||
import com.google.protobuf.InvalidProtocolBufferException;
|
|
||||||
import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier;
|
import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier;
|
||||||
import meerkat.crypto.mixnet.Mixer;
|
import meerkat.crypto.mixnet.Mixer;
|
||||||
import meerkat.protobuf.BulletinBoardAPI;
|
import meerkat.protobuf.BulletinBoardAPI;
|
||||||
|
@ -9,13 +7,10 @@ import meerkat.protobuf.Crypto;
|
||||||
import meerkat.protobuf.Mixing;
|
import meerkat.protobuf.Mixing;
|
||||||
import necessary.AsyncBulletinBoardClient;
|
import necessary.AsyncBulletinBoardClient;
|
||||||
import necessary.BulletinBoardClient;
|
import necessary.BulletinBoardClient;
|
||||||
import necessary.SignedBatch;
|
|
||||||
import qilin.util.Pair;
|
import qilin.util.Pair;
|
||||||
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,10 +19,10 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public class MainMixing {
|
public class MainMixing {
|
||||||
|
|
||||||
private Mixer mixer;
|
private final Mixer mixer;
|
||||||
private Mix2ZeroKnowledgeVerifier verifier;
|
private final Mix2ZeroKnowledgeVerifier verifier;
|
||||||
private int n, layers;
|
private final int n, layers;
|
||||||
private AsyncBulletinBoardClient asyncBulletinBoardClient;
|
private final AsyncBulletinBoardClient asyncBulletinBoardClient;
|
||||||
private final byte[] id;
|
private final byte[] id;
|
||||||
private final int mixerOrder;
|
private final int mixerOrder;
|
||||||
|
|
||||||
|
@ -43,7 +38,7 @@ public class MainMixing {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void main(List<Integer> prevBatchIds, int batchId, BulletinBoardClient.ClientCallback<?> callback) throws Exception {
|
public void main(List<Integer> prevBatchIds, int batchId, AsyncBulletinBoardClient.ClientCallback<?> callback) throws Throwable {
|
||||||
|
|
||||||
List<Crypto.RerandomizableEncryptedMessage> mixerInput;
|
List<Crypto.RerandomizableEncryptedMessage> mixerInput;
|
||||||
|
|
||||||
|
@ -52,11 +47,14 @@ public class MainMixing {
|
||||||
List<BatchHandler> batchHandlers = new ArrayList<BatchHandler>(prevBatchIds.size());
|
List<BatchHandler> batchHandlers = new ArrayList<BatchHandler>(prevBatchIds.size());
|
||||||
BatchHandler currentBatchHandler;
|
BatchHandler currentBatchHandler;
|
||||||
for (Integer prevBatchId : prevBatchIds) {
|
for (Integer prevBatchId : prevBatchIds) {
|
||||||
currentBatchHandler = new BatchHandler(n, layers);
|
currentBatchHandler = new BatchHandler(n, layers,verifier);
|
||||||
asyncBulletinBoardClient.readBatch(id, prevBatchId, currentBatchHandler);
|
asyncBulletinBoardClient.readBatch(id, prevBatchId,currentBatchHandler);
|
||||||
batchHandlers.add(currentBatchHandler);
|
batchHandlers.add(currentBatchHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToDo : assert table continues
|
||||||
|
// ToDo : assert signature validity
|
||||||
|
|
||||||
boolean allDone = false;
|
boolean allDone = false;
|
||||||
while (!allDone) {
|
while (!allDone) {
|
||||||
try {
|
try {
|
||||||
|
@ -64,17 +62,18 @@ public class MainMixing {
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
// check all handlers done
|
// check all handlers messages were received
|
||||||
allDone = true;
|
allDone = true;
|
||||||
for (BatchHandler batchHandler : batchHandlers) {
|
for (BatchHandler batchHandler : batchHandlers) {
|
||||||
allDone &= batchHandler.done;
|
allDone &= batchHandler.isMsgReceived();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// assert all handlers succeeded
|
// assert all handlers succeeded
|
||||||
for (BatchHandler batchHandler : batchHandlers) {
|
for (BatchHandler batchHandler : batchHandlers) {
|
||||||
if(batchHandler.e != null)
|
if(!batchHandler.verifyTable()){
|
||||||
throw batchHandler.e;
|
throw new Exception("invalid input");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BatchHandler lastBatchHandler = batchHandlers.get(batchHandlers.size() - 1);
|
BatchHandler lastBatchHandler = batchHandlers.get(batchHandlers.size() - 1);
|
||||||
|
@ -93,177 +92,14 @@ public class MainMixing {
|
||||||
|
|
||||||
|
|
||||||
private void updateBB(Pair<Mixing.ZeroKnowledgeProof[][], Crypto.RerandomizableEncryptedMessage[][]> mixerOutput
|
private void updateBB(Pair<Mixing.ZeroKnowledgeProof[][], Crypto.RerandomizableEncryptedMessage[][]> mixerOutput
|
||||||
, int batchId, BulletinBoardClient.ClientCallback<?> callback) {
|
, int batchId, AsyncBulletinBoardClient.ClientCallback<?> callback) {
|
||||||
|
|
||||||
BatchConverter batchConverter = new BatchConverter();
|
BatchConverter batchConverter = new BatchConverter(n,layers);
|
||||||
List<BulletinBoardAPI.BatchData> batchDataList = batchConverter.mixerOutput2BatchData(mixerOutput);
|
List<BulletinBoardAPI.BatchData> batchDataList = batchConverter.mixerOutput2BatchData(mixerOutput);
|
||||||
asyncBulletinBoardClient.postBatch(id, batchId, batchDataList, callback);
|
asyncBulletinBoardClient.postBatch(id, batchId, batchDataList, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class BatchConverter {
|
|
||||||
|
|
||||||
ByteString IntegerToByteString(int a){
|
|
||||||
return ByteString.copyFrom(BigInteger.valueOf(a).toByteArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
int ByteString2Integer(ByteString bs) {
|
|
||||||
return Integer.valueOf(bs.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
List<BulletinBoardAPI.BatchData> mixerOutput2BatchData
|
|
||||||
(Pair<Mixing.ZeroKnowledgeProof[][], Crypto.RerandomizableEncryptedMessage[][]> mixerOutput) {
|
|
||||||
|
|
||||||
List<BulletinBoardAPI.BatchData> result = new ArrayList<BulletinBoardAPI.BatchData>();
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
result.add(BulletinBoardAPI.BatchData.newBuilder()
|
|
||||||
.setData(IntegerToByteString(n))
|
|
||||||
.build());
|
|
||||||
|
|
||||||
for (Mixing.ZeroKnowledgeProof[] zkpLayer : mixerOutput.a) {
|
|
||||||
for (Mixing.ZeroKnowledgeProof zkp : zkpLayer) {
|
|
||||||
result.add(BulletinBoardAPI.BatchData.newBuilder()
|
|
||||||
.setData(zkp.toByteString())
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (Crypto.RerandomizableEncryptedMessage[] encryptionLayer : mixerOutput.b) {
|
|
||||||
for (Crypto.RerandomizableEncryptedMessage encryption : encryptionLayer) {
|
|
||||||
result.add(BulletinBoardAPI.BatchData.newBuilder()
|
|
||||||
.setData(encryption.toByteString())
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
Pair<Mixing.ZeroKnowledgeProof[][], Crypto.RerandomizableEncryptedMessage[][]> batchDataList2MixerOutput
|
|
||||||
(List<BulletinBoardAPI.BatchData> batchDataList) throws Exception {
|
|
||||||
|
|
||||||
if (n != ByteString2Integer(batchDataList.remove(0).getData())){
|
|
||||||
throw new Exception();
|
|
||||||
}
|
|
||||||
|
|
||||||
int nDiv2 = n >>1;
|
|
||||||
Mixing.ZeroKnowledgeProof[][] proofs = new Mixing.ZeroKnowledgeProof[layers][nDiv2];
|
|
||||||
for (int layer = 0; layer <layers; layer++)
|
|
||||||
{
|
|
||||||
for (int proofIndex = 0 ; proofIndex < nDiv2 ; proofIndex ++)
|
|
||||||
{
|
|
||||||
proofs[layer][proofIndex] = Mixing.ZeroKnowledgeProof.parseFrom(batchDataList.remove(0).getData());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Crypto.RerandomizableEncryptedMessage[][] encryptions
|
|
||||||
= new Crypto.RerandomizableEncryptedMessage[layers + 1][n];
|
|
||||||
for (int layer = 0; layer <layers + 1; layer++)
|
|
||||||
{
|
|
||||||
for (int encryptionIndex = 0 ; encryptionIndex < n ; encryptionIndex ++)
|
|
||||||
{
|
|
||||||
encryptions[layer][encryptionIndex] = Crypto.RerandomizableEncryptedMessage
|
|
||||||
.parseFrom(batchDataList.remove(0).getData());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Pair<Mixing.ZeroKnowledgeProof[][], Crypto.RerandomizableEncryptedMessage[][]>(proofs,encryptions);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private class BatchHandler implements BulletinBoardClient.ClientCallback<SignedBatch> {
|
|
||||||
|
|
||||||
public Pair<Mixing.ZeroKnowledgeProof[][],Crypto.RerandomizableEncryptedMessage[][]> mixerOutput;
|
|
||||||
public boolean done;
|
|
||||||
private int n,layers;
|
|
||||||
private Exception e;
|
|
||||||
|
|
||||||
public BatchHandler(int n, int layers) {
|
|
||||||
this.n = n;
|
|
||||||
this.layers = layers;
|
|
||||||
done = false;
|
|
||||||
e = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert batch message to MixerInput
|
|
||||||
// and verify it
|
|
||||||
@Override
|
|
||||||
public void handleCallback(SignedBatch msg) {
|
|
||||||
BatchConverter batchConverter = new BatchConverter();
|
|
||||||
try {
|
|
||||||
mixerOutput = batchConverter.batchDataList2MixerOutput(msg.getBatchDataList());
|
|
||||||
done = verifyTable();
|
|
||||||
} catch (Exception e) {
|
|
||||||
this.e = e;
|
|
||||||
done = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleFailure(Throwable t) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean verifyTable() throws InvalidProtocolBufferException {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
Mixing.ZeroKnowledgeProof[][] zeroKnowledgeProofs = mixerOutput.a;
|
|
||||||
Crypto.RerandomizableEncryptedMessage[][] rerandomizableEncryptedMessages = mixerOutput.b;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Crypto.RerandomizableEncryptedMessage> getInputForMixer()
|
|
||||||
{
|
|
||||||
return Arrays.asList(mixerOutput.b[mixerOutput.b.length - 1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,30 @@
|
||||||
package necessary;
|
package necessary;
|
||||||
|
|
||||||
import meerkat.protobuf.BulletinBoardAPI.*;
|
import meerkat.protobuf.BulletinBoardAPI.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Arbel Deutsch Peled on 14-Dec-15.
|
* Created by Arbel Deutsch Peled on 14-Dec-15.
|
||||||
*/
|
*/
|
||||||
public interface AsyncBulletinBoardClient extends BulletinBoardClient {
|
public interface AsyncBulletinBoardClient extends BulletinBoardClient {
|
||||||
|
|
||||||
|
public interface ClientCallback<T> {
|
||||||
|
void handleCallback(T msg);
|
||||||
|
void handleFailure(Throwable t);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface MessageHandler {
|
||||||
|
void handleNewMessages(List<BulletinBoardMessage> messageList);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Post a message to the bulletin board in an asynchronous manner
|
* Post a message to the bulletin board in an asynchronous manner
|
||||||
* @param msg is the message to be posted
|
* @param msg is the message to be posted
|
||||||
* @param callback is a class containing methods to handle the result of the operation
|
* @param callback is a class containing methods to handle the result of the operation
|
||||||
* @return a unique message ID for the message, that can be later used to retrieve the batch
|
* @return a unique message ID for the message, that can be later used to retrieve the batch
|
||||||
*/
|
*/
|
||||||
MessageID postMessage(BulletinBoardMessage msg, ClientCallback<?> callback);
|
public MessageID postMessage(BulletinBoardMessage msg, ClientCallback<?> callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method allows for sending large messages as a batch to the bulletin board
|
* This method allows for sending large messages as a batch to the bulletin board
|
||||||
|
@ -26,12 +35,12 @@ public interface AsyncBulletinBoardClient extends BulletinBoardClient {
|
||||||
* @param callback is a callback function class for handling results of the operation
|
* @param callback is a callback function class for handling results of the operation
|
||||||
* @return a unique message ID for the entire message, that can be later used to retrieve the batch
|
* @return a unique message ID for the entire message, that can be later used to retrieve the batch
|
||||||
*/
|
*/
|
||||||
MessageID postBatch(byte[] signerId, int batchId, List<BatchData> batchDataList, int startPosition, ClientCallback<?> callback);
|
public MessageID postBatch(byte[] signerId, int batchId, List<BatchData> batchDataList, int startPosition, ClientCallback<?> callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overloading of the postBatch method in which startPosition is set to the default value 0
|
* Overloading of the postBatch method in which startPosition is set to the default value 0
|
||||||
*/
|
*/
|
||||||
MessageID postBatch(byte[] signerId, int batchId, List<BatchData> batchDataList, ClientCallback<?> callback);
|
public MessageID postBatch(byte[] signerId, int batchId, List<BatchData> batchDataList, ClientCallback<?> callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check how "safe" a given message is in an asynchronous manner
|
* Check how "safe" a given message is in an asynchronous manner
|
||||||
|
@ -39,7 +48,7 @@ public interface AsyncBulletinBoardClient extends BulletinBoardClient {
|
||||||
* @param id is the unique message identifier for retrieval
|
* @param id is the unique message identifier for retrieval
|
||||||
* @param callback is a callback function class for handling results of the operation
|
* @param callback is a callback function class for handling results of the operation
|
||||||
*/
|
*/
|
||||||
void getRedundancy(MessageID id, ClientCallback<Float> callback);
|
public void getRedundancy(MessageID id, ClientCallback<Float> callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read all messages posted matching the given filter in an asynchronous manner
|
* Read all messages posted matching the given filter in an asynchronous manner
|
||||||
|
@ -49,7 +58,7 @@ public interface AsyncBulletinBoardClient extends BulletinBoardClient {
|
||||||
* @param filterList return only messages that match the filters (null means no filtering).
|
* @param filterList return only messages that match the filters (null means no filtering).
|
||||||
* @param callback is a callback function class for handling results of the operation
|
* @param callback is a callback function class for handling results of the operation
|
||||||
*/
|
*/
|
||||||
void readMessages(MessageFilterList filterList, ClientCallback<List<BulletinBoardMessage>> callback);
|
public void readMessages(MessageFilterList filterList, ClientCallback<List<BulletinBoardMessage>> callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a given batch message from the bulletin board
|
* Read a given batch message from the bulletin board
|
||||||
|
@ -57,6 +66,13 @@ public interface AsyncBulletinBoardClient extends BulletinBoardClient {
|
||||||
* @param batchId is the unique (per signer) ID of the batch
|
* @param batchId is the unique (per signer) ID of the batch
|
||||||
* @param callback is a callback class for handling the result of the operation
|
* @param callback is a callback class for handling the result of the operation
|
||||||
*/
|
*/
|
||||||
void readBatch(byte[] signerId, int batchId, ClientCallback<SignedBatch> callback);
|
public void readBatch(byte[] signerId, int batchId, ClientCallback<CompleteBatch> callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscribes to a notifier that will return any new messages on the server that match the given filters
|
||||||
|
* @param filterList defines the set of filters for message retrieval
|
||||||
|
* @param messageHandler defines the handler for new messages received
|
||||||
|
*/
|
||||||
|
public void subscribe(MessageFilterList filterList, MessageHandler messageHandler);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ public interface BulletinBoardClient {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes all connections, if any.
|
* Closes all connections, if any.
|
||||||
* This is done in a synchronous (blocking) way.
|
* This is msgRecived in a synchronous (blocking) way.
|
||||||
*/
|
*/
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
package necessary;
|
||||||
|
|
||||||
|
|
||||||
|
import meerkat.protobuf.BulletinBoardAPI.*;
|
||||||
|
import meerkat.protobuf.Crypto.*;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Arbel Deutsch Peled on 14-Dec-15.
|
||||||
|
*
|
||||||
|
* A data structure for holding a complete batch message along with its signature
|
||||||
|
*/
|
||||||
|
public class CompleteBatch {
|
||||||
|
|
||||||
|
private BeginBatchMessage beginBatchMessage;
|
||||||
|
private List<BatchData> batchDataList;
|
||||||
|
private Signature signature;
|
||||||
|
|
||||||
|
public CompleteBatch() {
|
||||||
|
batchDataList = new LinkedList<BatchData>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompleteBatch(BeginBatchMessage newBeginBatchMessage) {
|
||||||
|
this();
|
||||||
|
beginBatchMessage = newBeginBatchMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompleteBatch(BeginBatchMessage newBeginBatchMessage, List<BatchData> newDataList) {
|
||||||
|
this(newBeginBatchMessage);
|
||||||
|
appendBatchData(newDataList);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompleteBatch(BeginBatchMessage newBeginBatchMessage, List<BatchData> newDataList, Signature newSignature) {
|
||||||
|
this(newBeginBatchMessage, newDataList);
|
||||||
|
signature = newSignature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BeginBatchMessage getBeginBatchMessage() {
|
||||||
|
return beginBatchMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<BatchData> getBatchDataList() {
|
||||||
|
return batchDataList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Signature getSignature() {
|
||||||
|
return signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBeginBatchMessage(BeginBatchMessage beginBatchMessage) {
|
||||||
|
this.beginBatchMessage = beginBatchMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void appendBatchData(BatchData newBatchData) {
|
||||||
|
batchDataList.add(newBatchData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void appendBatchData(List<BatchData> newBatchDataList) {
|
||||||
|
batchDataList.addAll(newBatchDataList);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSignature(Signature newSignature) {
|
||||||
|
signature = newSignature;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,54 +0,0 @@
|
||||||
package necessary;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Tzlil on 12/27/2015.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import meerkat.protobuf.BulletinBoardAPI.*;
|
|
||||||
import meerkat.protobuf.Crypto.*;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Arbel Deutsch Peled on 14-Dec-15.
|
|
||||||
*
|
|
||||||
* A data structure for holding both a batch message and its signature
|
|
||||||
*/
|
|
||||||
public class SignedBatch {
|
|
||||||
|
|
||||||
private List<BatchData> batchDataList;
|
|
||||||
private Signature signature;
|
|
||||||
|
|
||||||
public SignedBatch() {
|
|
||||||
batchDataList = new LinkedList<BatchData>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public SignedBatch(List<BatchData> newDataList) {
|
|
||||||
this();
|
|
||||||
appendBatchData(newDataList);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SignedBatch(List<BatchData> newDataList, Signature newSignature) {
|
|
||||||
this(newDataList);
|
|
||||||
signature = newSignature;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<BatchData> getBatchDataList() {
|
|
||||||
return batchDataList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Signature getSignature() {
|
|
||||||
return signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void appendBatchData(BatchData newBatchData) {
|
|
||||||
batchDataList.add(newBatchData);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void appendBatchData(List<BatchData> newBatchDataList) {
|
|
||||||
batchDataList.addAll(newBatchDataList);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -7,70 +7,79 @@ import meerkat.protobuf.Crypto;
|
||||||
*/
|
*/
|
||||||
public class ProofOrganizer {
|
public class ProofOrganizer {
|
||||||
|
|
||||||
private final Crypto.RerandomizableEncryptedMessage e1;
|
private final OrProofInput first;
|
||||||
private final Crypto.RerandomizableEncryptedMessage e2;
|
private final OrProofInput second;
|
||||||
private final Crypto.RerandomizableEncryptedMessage e1New;
|
private final OrProofInput third;
|
||||||
private final Crypto.RerandomizableEncryptedMessage e2New;
|
private final OrProofInput fourth;
|
||||||
|
|
||||||
|
protected ProofOrganizer(Crypto.RerandomizableEncryptedMessage e1,Crypto.RerandomizableEncryptedMessage e2
|
||||||
|
,Crypto.RerandomizableEncryptedMessage e1New,Crypto.RerandomizableEncryptedMessage e2New
|
||||||
|
,Crypto.EncryptionRandomness r1,Crypto.EncryptionRandomness r2,boolean switched) {
|
||||||
|
if(!switched) {
|
||||||
|
this.first = new OrProofInput(e1, e1New, e2, e1New, r1,TrueCouple.left);
|
||||||
|
this.second = new OrProofInput(e1, e1New, e1, e2New,r1,TrueCouple.left);
|
||||||
|
this.third = new OrProofInput(e2, e1New, e2, e2New,r2,TrueCouple.right);
|
||||||
|
this.fourth = new OrProofInput(e1, e2New, e2, e2New,r2,TrueCouple.right);
|
||||||
|
}else{
|
||||||
|
this.first = new OrProofInput(e1, e1New, e2, e1New, r2,TrueCouple.right);
|
||||||
|
this.second = new OrProofInput(e1, e1New, e1, e2New,r1,TrueCouple.right);
|
||||||
|
this.third = new OrProofInput(e2, e1New, e2, e2New,r2,TrueCouple.left);
|
||||||
|
this.fourth = new OrProofInput(e1, e2New, e2, e2New,r1,TrueCouple.left);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//in1, out1, in2, out1,
|
|
||||||
//in1, out1, in1, out2
|
|
||||||
//in2, out1, in2, out2,
|
|
||||||
//in1, out2, in2, out2
|
|
||||||
public ProofOrganizer(Crypto.RerandomizableEncryptedMessage e1,Crypto.RerandomizableEncryptedMessage e2
|
public ProofOrganizer(Crypto.RerandomizableEncryptedMessage e1,Crypto.RerandomizableEncryptedMessage e2
|
||||||
,Crypto.RerandomizableEncryptedMessage e1New,Crypto.RerandomizableEncryptedMessage e2New)
|
,Crypto.RerandomizableEncryptedMessage e1New,Crypto.RerandomizableEncryptedMessage e2New) {
|
||||||
{
|
this.first = new OrProofInput(e1, e1New, e2, e1New, null,TrueCouple.unknown);
|
||||||
this.e1 = e1;
|
this.second = new OrProofInput(e1, e1New, e1, e2New,null,TrueCouple.unknown);
|
||||||
this.e2 = e2;
|
this.third = new OrProofInput(e2, e1New, e2, e2New,null,TrueCouple.unknown);
|
||||||
this.e1New = e1New;
|
this.fourth = new OrProofInput(e1, e2New, e2, e2New,null,TrueCouple.unknown);
|
||||||
this.e2New = e2New;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum OrProofOrder{
|
public enum OrProofOrder{
|
||||||
first,second,third,fourth
|
first,second,third,fourth
|
||||||
}
|
}
|
||||||
|
|
||||||
public Crypto.RerandomizableEncryptedMessage getE1(OrProofOrder orProofOrder)
|
public enum TrueCouple{
|
||||||
{
|
left,right,unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public OrProofInput getOrProofInput(OrProofOrder orProofOrder){
|
||||||
switch (orProofOrder){
|
switch (orProofOrder){
|
||||||
case third:
|
|
||||||
return e2;
|
|
||||||
default:
|
|
||||||
return e1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Crypto.RerandomizableEncryptedMessage getE1New(OrProofOrder orProofOrder)
|
|
||||||
{
|
|
||||||
switch (orProofOrder){
|
|
||||||
case fourth:
|
|
||||||
return e2New;
|
|
||||||
default:
|
|
||||||
return e1New;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Crypto.RerandomizableEncryptedMessage getE2(OrProofOrder orProofOrder)
|
|
||||||
{
|
|
||||||
switch (orProofOrder){
|
|
||||||
case second:
|
|
||||||
return e1;
|
|
||||||
default:
|
|
||||||
return e2;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Crypto.RerandomizableEncryptedMessage getE2New(OrProofOrder orProofOrder)
|
|
||||||
{
|
|
||||||
switch (orProofOrder){
|
|
||||||
case first:
|
case first:
|
||||||
return e1New;
|
return this.first;
|
||||||
default:
|
case second:
|
||||||
return e2New;
|
return this.second;
|
||||||
|
case third:
|
||||||
|
return this.third;
|
||||||
|
case fourth:
|
||||||
|
return this.fourth;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class OrProofInput{
|
||||||
|
|
||||||
|
|
||||||
|
public final Crypto.RerandomizableEncryptedMessage e1;
|
||||||
|
public final Crypto.RerandomizableEncryptedMessage e1New;
|
||||||
|
public final Crypto.RerandomizableEncryptedMessage e2;
|
||||||
|
public final Crypto.RerandomizableEncryptedMessage e2New;
|
||||||
|
protected final Crypto.EncryptionRandomness x;
|
||||||
|
protected final TrueCouple flag;
|
||||||
|
|
||||||
|
private OrProofInput(Crypto.RerandomizableEncryptedMessage e1, Crypto.RerandomizableEncryptedMessage e1New,
|
||||||
|
Crypto.RerandomizableEncryptedMessage e2, Crypto.RerandomizableEncryptedMessage e2New,
|
||||||
|
Crypto.EncryptionRandomness x, TrueCouple flag) {
|
||||||
|
this.e1 = e1;
|
||||||
|
this.e1New = e1New;
|
||||||
|
this.e2 = e2;
|
||||||
|
this.e2New = e2New;
|
||||||
|
this.x = x;
|
||||||
|
this.flag = flag;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
import meerkat.crypto.concrete.ECElGamalEncryption;
|
import meerkat.crypto.concrete.ECElGamalEncryption;
|
||||||
import meerkat.crypto.mixnet.Mix2ZeroKnowledgeProver;
|
import meerkat.crypto.mixnet.Mix2ZeroKnowledgeProver;
|
||||||
import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier;
|
import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier;
|
||||||
|
import meerkat.protobuf.ConcreteCrypto;
|
||||||
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;
|
||||||
|
@ -13,6 +14,7 @@ import qilin.primitives.RandomOracle;
|
||||||
import qilin.primitives.concrete.ECGroup;
|
import qilin.primitives.concrete.ECGroup;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
public class Prover implements Mix2ZeroKnowledgeProver {
|
public class Prover implements Mix2ZeroKnowledgeProver {
|
||||||
|
@ -23,8 +25,6 @@ public class Prover implements Mix2ZeroKnowledgeProver {
|
||||||
ECElGamalEncryption ecElGamalEncryption;
|
ECElGamalEncryption ecElGamalEncryption;
|
||||||
ECPoint g,h;
|
ECPoint g,h;
|
||||||
|
|
||||||
Mix2ZeroKnowledgeVerifier verifier;
|
|
||||||
|
|
||||||
public Prover(Random rand,ECElGamalEncryption encryptor,RandomOracle randomOracle) {
|
public Prover(Random rand,ECElGamalEncryption encryptor,RandomOracle randomOracle) {
|
||||||
|
|
||||||
this.rand = rand;
|
this.rand = rand;
|
||||||
|
@ -33,20 +33,6 @@ public class Prover implements Mix2ZeroKnowledgeProver {
|
||||||
this.group = ecElGamalEncryption.getGroup();
|
this.group = ecElGamalEncryption.getGroup();
|
||||||
this.g = group.getGenerator();
|
this.g = group.getGenerator();
|
||||||
this.h = ecElGamalEncryption.getElGamalPK().getPK();
|
this.h = ecElGamalEncryption.getElGamalPK().getPK();
|
||||||
|
|
||||||
verifier = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -60,58 +46,23 @@ public class Prover implements Mix2ZeroKnowledgeProver {
|
||||||
Crypto.EncryptionRandomness r2) throws InvalidProtocolBufferException {
|
Crypto.EncryptionRandomness r2) throws InvalidProtocolBufferException {
|
||||||
|
|
||||||
Mixing.ZeroKnowledgeProof.OrProof first,second,third,fourth;
|
Mixing.ZeroKnowledgeProof.OrProof first,second,third,fourth;
|
||||||
ProofOrganizer organizer = new ProofOrganizer(in1,in2,out1,out2);
|
ProofOrganizer organizer = new ProofOrganizer(in1,in2,out1,out2,r1,r2,sw);
|
||||||
if (!sw)
|
|
||||||
{
|
System.out.println("first");
|
||||||
first = createOrProof(organizer.getE1(ProofOrganizer.OrProofOrder.first),
|
first = createOrProof(organizer.getOrProofInput(ProofOrganizer.OrProofOrder.first));
|
||||||
organizer.getE2(ProofOrganizer.OrProofOrder.first),
|
System.out.println("second");
|
||||||
organizer.getE1New(ProofOrganizer.OrProofOrder.first),
|
second = createOrProof(organizer.getOrProofInput(ProofOrganizer.OrProofOrder.second));
|
||||||
organizer.getE2New(ProofOrganizer.OrProofOrder.first),
|
System.out.println("third");
|
||||||
r1, true);
|
third = createOrProof(organizer.getOrProofInput(ProofOrganizer.OrProofOrder.third));
|
||||||
second = createOrProof(organizer.getE1(ProofOrganizer.OrProofOrder.second),
|
System.out.println("fourth");
|
||||||
organizer.getE2(ProofOrganizer.OrProofOrder.second),
|
fourth = createOrProof(organizer.getOrProofInput(ProofOrganizer.OrProofOrder.fourth));
|
||||||
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);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
Mixing.ZeroKnowledgeProof.Location location = Mixing.ZeroKnowledgeProof.Location.newBuilder()
|
Mixing.ZeroKnowledgeProof.Location location = Mixing.ZeroKnowledgeProof.Location.newBuilder()
|
||||||
.setI(i)
|
.setI(i)
|
||||||
.setJ(j)
|
.setJ(j)
|
||||||
.setLayer(layer)
|
.setLayer(layer)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Mixing.ZeroKnowledgeProof result = Mixing.ZeroKnowledgeProof.newBuilder()
|
Mixing.ZeroKnowledgeProof result = Mixing.ZeroKnowledgeProof.newBuilder()
|
||||||
.setFirst(first)
|
.setFirst(first)
|
||||||
.setSecond(second)
|
.setSecond(second)
|
||||||
|
@ -120,31 +71,18 @@ public class Prover implements Mix2ZeroKnowledgeProver {
|
||||||
.setLocation(location)
|
.setLocation(location)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
//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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Mixing.ZeroKnowledgeProof.OrProof createOrProof(Crypto.RerandomizableEncryptedMessage e1,
|
private Mixing.ZeroKnowledgeProof.OrProof createOrProof(ProofOrganizer.OrProofInput orProofInput)
|
||||||
Crypto.RerandomizableEncryptedMessage e2,
|
throws InvalidProtocolBufferException {
|
||||||
Crypto.RerandomizableEncryptedMessage e1New,
|
|
||||||
Crypto.RerandomizableEncryptedMessage e2New,
|
|
||||||
Crypto.EncryptionRandomness x,
|
|
||||||
boolean flag) throws InvalidProtocolBufferException {
|
|
||||||
|
|
||||||
ElGamalCiphertext e1ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e1);
|
ElGamalCiphertext e1ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(orProofInput.e1);
|
||||||
ElGamalCiphertext e2ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e2);
|
ElGamalCiphertext e2ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(orProofInput.e2);
|
||||||
ElGamalCiphertext e1TagElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e1New);
|
ElGamalCiphertext e1TagElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(orProofInput.e1New);
|
||||||
ElGamalCiphertext e2TagElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e2New);
|
ElGamalCiphertext e2TagElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(orProofInput.e2New);
|
||||||
|
|
||||||
return createOrProofElGamal(e1ElGamal,e2ElGamal,e1TagElGamal,e2TagElGamal,x,flag);
|
return createOrProofElGamal(e1ElGamal,e2ElGamal,e1TagElGamal,e2TagElGamal,orProofInput.x,orProofInput.flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -163,7 +101,7 @@ public class Prover implements Mix2ZeroKnowledgeProver {
|
||||||
ElGamalCiphertext e1New,
|
ElGamalCiphertext e1New,
|
||||||
ElGamalCiphertext e2New,
|
ElGamalCiphertext e2New,
|
||||||
Crypto.EncryptionRandomness x,
|
Crypto.EncryptionRandomness x,
|
||||||
boolean flag) {
|
ProofOrganizer.TrueCouple flag) {
|
||||||
|
|
||||||
ECPoint g1 = g;
|
ECPoint g1 = g;
|
||||||
ECPoint h1 = group.add(convert2ECPoint(e1New.getC1()),group.negate(convert2ECPoint(e1.getC1())));
|
ECPoint h1 = group.add(convert2ECPoint(e1New.getC1()),group.negate(convert2ECPoint(e1.getC1())));
|
||||||
|
@ -178,8 +116,9 @@ public class Prover implements Mix2ZeroKnowledgeProver {
|
||||||
BigInteger r = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound());
|
BigInteger r = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound());
|
||||||
BigInteger c1,c2,z,zTag;
|
BigInteger c1,c2,z,zTag;
|
||||||
ECPoint u,v,uTag,vTag;
|
ECPoint u,v,uTag,vTag;
|
||||||
if (flag)
|
Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle forRandomOracle;
|
||||||
{
|
switch (flag) {
|
||||||
|
case left:
|
||||||
c2 = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound());
|
c2 = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound());
|
||||||
zTag = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound());
|
zTag = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound());
|
||||||
//step 1
|
//step 1
|
||||||
|
@ -189,7 +128,7 @@ public class Prover implements Mix2ZeroKnowledgeProver {
|
||||||
vTag = group.add(group.multiply(g2Tag, zTag), group.negate(group.multiply(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 =
|
forRandomOracle =
|
||||||
Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle.newBuilder()
|
Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle.newBuilder()
|
||||||
.setG1(ByteString.copyFrom(group.encode(g1)))
|
.setG1(ByteString.copyFrom(group.encode(g1)))
|
||||||
.setH1(ByteString.copyFrom(group.encode(h1)))
|
.setH1(ByteString.copyFrom(group.encode(h1)))
|
||||||
|
@ -208,9 +147,8 @@ public class Prover implements Mix2ZeroKnowledgeProver {
|
||||||
//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.orderUpperBound());
|
z = r.add(c1.multiply(new BigInteger(x.getData().toByteArray()))).mod(group.orderUpperBound());
|
||||||
}
|
break;
|
||||||
else
|
case right:
|
||||||
{
|
|
||||||
c1 = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound());
|
c1 = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound());
|
||||||
z = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound());
|
z = new BigInteger(ecElGamalEncryption.generateRandomness(rand).getData().toByteArray()).mod(group.orderUpperBound());
|
||||||
//step 1
|
//step 1
|
||||||
|
@ -220,7 +158,7 @@ public class Prover implements Mix2ZeroKnowledgeProver {
|
||||||
v = group.add(group.multiply(g2, z), group.negate(group.multiply(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 =
|
forRandomOracle =
|
||||||
Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle.newBuilder()
|
Mixing.ZeroKnowledgeProof.OrProof.ForRandomOracle.newBuilder()
|
||||||
.setG1(ByteString.copyFrom(group.encode(g1)))
|
.setG1(ByteString.copyFrom(group.encode(g1)))
|
||||||
.setH1(ByteString.copyFrom(group.encode(h1)))
|
.setH1(ByteString.copyFrom(group.encode(h1)))
|
||||||
|
@ -239,7 +177,18 @@ public class Prover implements Mix2ZeroKnowledgeProver {
|
||||||
//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.orderUpperBound());
|
zTag = r.add(c2.multiply(new BigInteger(x.getData().toByteArray()))).mod(group.orderUpperBound());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//debugging
|
||||||
|
assert (group.multiply(g1, z).equals(group.add(u, group.multiply(h1,c1))));
|
||||||
|
assert (group.multiply(g2, z).equals(group.add(v, group.multiply(h2,c1))));
|
||||||
|
assert (group.multiply(g1Tag, zTag).equals(group.add(uTag, group.multiply(h1Tag,c2))));
|
||||||
|
assert (group.multiply(g2Tag, zTag).equals(group.add(vTag, group.multiply(h2Tag,c2))));
|
||||||
|
|
||||||
|
|
||||||
return Mixing.ZeroKnowledgeProof.OrProof.newBuilder()
|
return Mixing.ZeroKnowledgeProof.OrProof.newBuilder()
|
||||||
.setG1(ByteString.copyFrom(group.encode(g1)))
|
.setG1(ByteString.copyFrom(group.encode(g1)))
|
||||||
.setH1(ByteString.copyFrom(group.encode(h1)))
|
.setH1(ByteString.copyFrom(group.encode(h1)))
|
||||||
|
|
|
@ -59,41 +59,20 @@ public class Verifier implements Mix2ZeroKnowledgeVerifier {
|
||||||
Mixing.ZeroKnowledgeProof proof) throws InvalidProtocolBufferException {
|
Mixing.ZeroKnowledgeProof proof) throws InvalidProtocolBufferException {
|
||||||
|
|
||||||
ProofOrganizer organizer = new ProofOrganizer(in1,in2,out1,out2);
|
ProofOrganizer organizer = new ProofOrganizer(in1,in2,out1,out2);
|
||||||
return verifyOrProof(organizer.getE1(ProofOrganizer.OrProofOrder.first),
|
return verifyOrProof(organizer.getOrProofInput(ProofOrganizer.OrProofOrder.first), proof.getFirst())&&
|
||||||
organizer.getE2(ProofOrganizer.OrProofOrder.first),
|
verifyOrProof(organizer.getOrProofInput(ProofOrganizer.OrProofOrder.second), proof.getSecond())&&
|
||||||
organizer.getE1New(ProofOrganizer.OrProofOrder.first),
|
verifyOrProof(organizer.getOrProofInput(ProofOrganizer.OrProofOrder.third), proof.getThird())&&
|
||||||
organizer.getE2New(ProofOrganizer.OrProofOrder.first),
|
verifyOrProof(organizer.getOrProofInput(ProofOrganizer.OrProofOrder.fourth), proof.getFourth());
|
||||||
proof.getFirst(),ProofOrganizer.OrProofOrder.first)&&
|
|
||||||
verifyOrProof(organizer.getE1(ProofOrganizer.OrProofOrder.second),
|
|
||||||
organizer.getE2(ProofOrganizer.OrProofOrder.second),
|
|
||||||
organizer.getE1New(ProofOrganizer.OrProofOrder.second),
|
|
||||||
organizer.getE2New(ProofOrganizer.OrProofOrder.second),
|
|
||||||
proof.getSecond(),ProofOrganizer.OrProofOrder.second)&&
|
|
||||||
verifyOrProof(organizer.getE1(ProofOrganizer.OrProofOrder.third),
|
|
||||||
organizer.getE2(ProofOrganizer.OrProofOrder.third),
|
|
||||||
organizer.getE1New(ProofOrganizer.OrProofOrder.third),
|
|
||||||
organizer.getE2New(ProofOrganizer.OrProofOrder.third),
|
|
||||||
proof.getThird(),ProofOrganizer.OrProofOrder.third)&&
|
|
||||||
verifyOrProof(organizer.getE1(ProofOrganizer.OrProofOrder.fourth),
|
|
||||||
organizer.getE2(ProofOrganizer.OrProofOrder.fourth),
|
|
||||||
organizer.getE1New(ProofOrganizer.OrProofOrder.fourth),
|
|
||||||
organizer.getE2New(ProofOrganizer.OrProofOrder.fourth),
|
|
||||||
proof.getFourth(),ProofOrganizer.OrProofOrder.fourth);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean verifyOrProof(ProofOrganizer.OrProofInput orProofInput, Mixing.ZeroKnowledgeProof.OrProof orProof)
|
||||||
|
throws InvalidProtocolBufferException {
|
||||||
public boolean verifyOrProof(Crypto.RerandomizableEncryptedMessage e1,
|
ElGamalCiphertext e1ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(orProofInput.e1);
|
||||||
Crypto.RerandomizableEncryptedMessage e2,
|
ElGamalCiphertext e2ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(orProofInput.e2);
|
||||||
Crypto.RerandomizableEncryptedMessage e1Tag,
|
ElGamalCiphertext e1TagElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(orProofInput.e1New);
|
||||||
Crypto.RerandomizableEncryptedMessage e2Tag,
|
ElGamalCiphertext e2TagElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(orProofInput.e2New);
|
||||||
Mixing.ZeroKnowledgeProof.OrProof orProof, ProofOrganizer.OrProofOrder orProofOrder) throws InvalidProtocolBufferException {
|
return verifyElGamaOrProof(e1ElGamal,e2ElGamal,e1TagElGamal,e2TagElGamal,orProof);
|
||||||
|
|
||||||
ElGamalCiphertext e1ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e1);
|
|
||||||
ElGamalCiphertext e2ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e2);
|
|
||||||
ElGamalCiphertext e1TagElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e1Tag);
|
|
||||||
ElGamalCiphertext e2TagElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e2Tag);
|
|
||||||
return verifyElGamaOrProof(e1ElGamal,e2ElGamal,e1TagElGamal,e2TagElGamal,orProof,orProofOrder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -173,7 +152,7 @@ public class Verifier implements Mix2ZeroKnowledgeVerifier {
|
||||||
ElGamalCiphertext e2,
|
ElGamalCiphertext e2,
|
||||||
ElGamalCiphertext e1New,
|
ElGamalCiphertext e1New,
|
||||||
ElGamalCiphertext e2New,
|
ElGamalCiphertext e2New,
|
||||||
Mixing.ZeroKnowledgeProof.OrProof orProof, ProofOrganizer.OrProofOrder orProofOrder)
|
Mixing.ZeroKnowledgeProof.OrProof orProof)
|
||||||
{
|
{
|
||||||
parseOrProof(orProof);
|
parseOrProof(orProof);
|
||||||
List<Condition> conditions = createConditionsList(e1,e2,e1New,e2New);
|
List<Condition> conditions = createConditionsList(e1,e2,e1New,e2New);
|
||||||
|
@ -184,7 +163,6 @@ public class Verifier implements Mix2ZeroKnowledgeVerifier {
|
||||||
if (result){
|
if (result){
|
||||||
result = false;
|
result = false;
|
||||||
System.out.print("\n\n\n");
|
System.out.print("\n\n\n");
|
||||||
System.out.println(orProofOrder.toString());
|
|
||||||
}
|
}
|
||||||
System.out.println(condition.errorDescripton);
|
System.out.println(condition.errorDescripton);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class MixingText {
|
||||||
randomProver = new Random();
|
randomProver = new Random();
|
||||||
randomOracle = new DigestOracle();
|
randomOracle = new DigestOracle();
|
||||||
verifier = new Verifier(encryptor,randomOracle);
|
verifier = new Verifier(encryptor,randomOracle);
|
||||||
prover = new Prover(randomProver,encryptor,randomOracle,verifier);
|
prover = new Prover(randomProver,encryptor,randomOracle);
|
||||||
mixer = new Mixer(randomMixer,prover,encryptor);
|
mixer = new Mixer(randomMixer,prover,encryptor);
|
||||||
|
|
||||||
// generate n
|
// generate n
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
package mixer;
|
||||||
|
|
||||||
|
import com.google.protobuf.ByteString;
|
||||||
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
|
import meerkat.crypto.concrete.ECElGamalEncryption;
|
||||||
|
import meerkat.crypto.mixnet.Mix2ZeroKnowledgeProver;
|
||||||
|
import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier;
|
||||||
|
import meerkat.protobuf.ConcreteCrypto;
|
||||||
|
import meerkat.protobuf.Crypto;
|
||||||
|
import meerkat.protobuf.Voting;
|
||||||
|
import org.bouncycastle.math.ec.ECPoint;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import prover.Prover;
|
||||||
|
import qilin.primitives.RandomOracle;
|
||||||
|
import qilin.primitives.concrete.DigestOracle;
|
||||||
|
import qilin.primitives.concrete.ECElGamal;
|
||||||
|
import qilin.primitives.concrete.ECGroup;
|
||||||
|
import verifier.Verifier;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Tzlil on 1/17/2016.
|
||||||
|
*/
|
||||||
|
public class RerandomizeTest {
|
||||||
|
|
||||||
|
Random rand;
|
||||||
|
ECElGamal.SK key;
|
||||||
|
ECGroup group;
|
||||||
|
ECElGamalEncryption enc;
|
||||||
|
ConcreteCrypto.ElGamalPublicKey serializedPk;
|
||||||
|
ECPoint g ;
|
||||||
|
ECPoint h ;
|
||||||
|
@Before
|
||||||
|
public void setup() throws Exception {
|
||||||
|
rand = new Random();
|
||||||
|
group = new ECGroup("secp256k1");
|
||||||
|
BigInteger sk = ECElGamal.generateSecretKey(group, rand);
|
||||||
|
key = new ECElGamal.SK(group, sk);
|
||||||
|
serializedPk = Utiles.serializePk(group, key);
|
||||||
|
enc = new ECElGamalEncryption();
|
||||||
|
enc.init(serializedPk);
|
||||||
|
RandomOracle randomOracle = new DigestOracle();
|
||||||
|
g = group.getGenerator();
|
||||||
|
h = enc.getElGamalPK().getPK();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ECPoint convert2ECPoint(ByteString bs){
|
||||||
|
return group.decode(bs.toByteArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void oneRerandomizeTest() throws InvalidProtocolBufferException {
|
||||||
|
Voting.PlaintextBallot msg = Utiles.genRandomBallot(2,3,16); // 2 questions with 3 answers each, in range 0-15.
|
||||||
|
|
||||||
|
Crypto.EncryptionRandomness r = enc.generateRandomness(rand);
|
||||||
|
|
||||||
|
|
||||||
|
Crypto.RerandomizableEncryptedMessage e = enc.encrypt(msg, enc.generateRandomness(rand));
|
||||||
|
Crypto.RerandomizableEncryptedMessage eNew = enc.rerandomize(e, r);
|
||||||
|
|
||||||
|
assert (Utiles.decrypt(Voting.PlaintextBallot.class, key, group, e).equals(msg));
|
||||||
|
assert (Utiles.decrypt(Voting.PlaintextBallot.class, key, group, eNew).equals(msg));
|
||||||
|
|
||||||
|
ConcreteCrypto.ElGamalCiphertext eElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e);
|
||||||
|
ConcreteCrypto.ElGamalCiphertext eNewElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(eNew);
|
||||||
|
|
||||||
|
assert (g.multiply(new BigInteger(r.getData().toByteArray())).equals(
|
||||||
|
group.add(convert2ECPoint(eNewElGamal.getC1()),group.negate(convert2ECPoint(eElGamal.getC1())))));
|
||||||
|
assert (h.multiply(new BigInteger(r.getData().toByteArray())).equals(
|
||||||
|
group.add(convert2ECPoint(eNewElGamal.getC2()), group.negate(convert2ECPoint(eElGamal.getC2())))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void rerandomizeTest() throws InvalidProtocolBufferException {
|
||||||
|
|
||||||
|
int tests = 1000;
|
||||||
|
|
||||||
|
for (int i = 0; i < tests; i ++){
|
||||||
|
System.out.println("rerandomiz test #" + i);
|
||||||
|
oneRerandomizeTest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package mixer;
|
package mixer;
|
||||||
|
|
||||||
|
import com.google.protobuf.ByteString;
|
||||||
import com.google.protobuf.InvalidProtocolBufferException;
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
import meerkat.crypto.concrete.ECElGamalEncryption;
|
import meerkat.crypto.concrete.ECElGamalEncryption;
|
||||||
import meerkat.crypto.mixnet.Mix2ZeroKnowledgeProver;
|
import meerkat.crypto.mixnet.Mix2ZeroKnowledgeProver;
|
||||||
|
@ -7,6 +8,7 @@ import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier;
|
||||||
import meerkat.protobuf.ConcreteCrypto;
|
import meerkat.protobuf.ConcreteCrypto;
|
||||||
import meerkat.protobuf.Crypto;
|
import meerkat.protobuf.Crypto;
|
||||||
import meerkat.protobuf.Voting;
|
import meerkat.protobuf.Voting;
|
||||||
|
import org.bouncycastle.math.ec.ECPoint;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import prover.Prover;
|
import prover.Prover;
|
||||||
|
@ -45,12 +47,11 @@ public class ZeroKnowledgeProofTest {
|
||||||
prover = new Prover(new Random(),enc,randomOracle);
|
prover = new Prover(new Random(),enc,randomOracle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ECPoint convert2ECPoint(ByteString bs){
|
||||||
|
return group.decode(bs.toByteArray());
|
||||||
|
}
|
||||||
|
|
||||||
public void oneZKPTest() throws InvalidProtocolBufferException {
|
public void oneZKPTest() throws InvalidProtocolBufferException {
|
||||||
|
|
||||||
Voting.PlaintextBallot msg1 = Utiles.genRandomBallot(2,3,16); // 2 questions with 3 answers each, in range 0-15.
|
Voting.PlaintextBallot msg1 = Utiles.genRandomBallot(2,3,16); // 2 questions with 3 answers each, in range 0-15.
|
||||||
Voting.PlaintextBallot msg2 = Utiles.genRandomBallot(2,3,16);
|
Voting.PlaintextBallot msg2 = Utiles.genRandomBallot(2,3,16);
|
||||||
Crypto.EncryptionRandomness r1 = enc.generateRandomness(rand);
|
Crypto.EncryptionRandomness r1 = enc.generateRandomness(rand);
|
||||||
|
@ -58,13 +59,33 @@ public class ZeroKnowledgeProofTest {
|
||||||
|
|
||||||
Crypto.RerandomizableEncryptedMessage e1 = enc.encrypt(msg1, enc.generateRandomness(rand));
|
Crypto.RerandomizableEncryptedMessage e1 = enc.encrypt(msg1, enc.generateRandomness(rand));
|
||||||
Crypto.RerandomizableEncryptedMessage e2 = enc.encrypt(msg2, enc.generateRandomness(rand));
|
Crypto.RerandomizableEncryptedMessage e2 = enc.encrypt(msg2, enc.generateRandomness(rand));
|
||||||
Crypto.RerandomizableEncryptedMessage e1Tag = enc.rerandomize(e1, r1);
|
Crypto.RerandomizableEncryptedMessage e1New = enc.rerandomize(e1, r1);
|
||||||
Crypto.RerandomizableEncryptedMessage e2Tag = enc.rerandomize(e2, r2);
|
Crypto.RerandomizableEncryptedMessage e2New = enc.rerandomize(e2, r2);
|
||||||
|
|
||||||
assert (Utiles.decrypt(Voting.PlaintextBallot.class, key, group, e1).equals(msg1));
|
assert (Utiles.decrypt(Voting.PlaintextBallot.class, key, group, e1).equals(msg1));
|
||||||
assert (Utiles.decrypt(Voting.PlaintextBallot.class, key, group, e1Tag).equals(msg1));
|
assert (Utiles.decrypt(Voting.PlaintextBallot.class, key, group, e1New).equals(msg1));
|
||||||
assert (Utiles.decrypt(Voting.PlaintextBallot.class, key, group, e2).equals(msg2));
|
assert (Utiles.decrypt(Voting.PlaintextBallot.class, key, group, e2).equals(msg2));
|
||||||
assert (Utiles.decrypt(Voting.PlaintextBallot.class, key, group, e2Tag).equals(msg2));
|
assert (Utiles.decrypt(Voting.PlaintextBallot.class, key, group, e2New).equals(msg2));
|
||||||
assert (verifier.verify(e1,e2,e1Tag,e2Tag,prover.prove(e1,e2,e1Tag,e2Tag,false,0,0,0,r1,r2)));
|
|
||||||
|
ECPoint g = group.getGenerator();
|
||||||
|
ECPoint h = enc.getElGamalPK().getPK();
|
||||||
|
|
||||||
|
ConcreteCrypto.ElGamalCiphertext e1ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e1);
|
||||||
|
ConcreteCrypto.ElGamalCiphertext e2ElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e2);
|
||||||
|
ConcreteCrypto.ElGamalCiphertext e1TagElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e1New);
|
||||||
|
ConcreteCrypto.ElGamalCiphertext e2TagElGamal = ECElGamalEncryption.rerandomizableEncryptedMessage2ElGamalCiphertext(e2New);
|
||||||
|
|
||||||
|
|
||||||
|
assert (g.multiply(new BigInteger(r1.getData().toByteArray())).equals(
|
||||||
|
group.add(convert2ECPoint(e1TagElGamal.getC1()),group.negate(convert2ECPoint(e1ElGamal.getC1())))));
|
||||||
|
assert (h.multiply(new BigInteger(r1.getData().toByteArray())).equals(
|
||||||
|
group.add(convert2ECPoint(e1TagElGamal.getC2()),group.negate(convert2ECPoint(e1ElGamal.getC2())))));
|
||||||
|
assert (g.multiply(new BigInteger(r2.getData().toByteArray())).equals(
|
||||||
|
group.add(convert2ECPoint(e2TagElGamal.getC1()),group.negate(convert2ECPoint(e2ElGamal.getC1())))));
|
||||||
|
assert (h.multiply(new BigInteger(r2.getData().toByteArray())).equals(
|
||||||
|
group.add(convert2ECPoint(e2TagElGamal.getC2()),group.negate(convert2ECPoint(e2ElGamal.getC2())))));
|
||||||
|
|
||||||
|
assert (verifier.verify(e1,e2,e1New,e2New,prover.prove(e1,e2,e1New,e2New,false,0,0,0,r1,r2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -73,7 +94,7 @@ public class ZeroKnowledgeProofTest {
|
||||||
int tests = 1000;
|
int tests = 1000;
|
||||||
|
|
||||||
for (int i = 0; i < tests; i ++){
|
for (int i = 0; i < tests; i ++){
|
||||||
System.out.println("test " + i);
|
System.out.println("ZKP test #" + i);
|
||||||
oneZKPTest();
|
oneZKPTest();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue