More refactoring for tests and protocol -- user class now handles all messages synchronously (in the main thread); concurrency is now simpler)
parent
c798e827dc
commit
1f8df95895
|
@ -49,6 +49,9 @@ dependencies {
|
|||
// Google protobufs
|
||||
compile 'com.google.protobuf:protobuf-java:3.+'
|
||||
|
||||
// Depend on test resources from meerkat-common
|
||||
testCompile project(path: ':meerkat-common', configuration: 'testOutput')
|
||||
|
||||
testCompile 'junit:junit:4.+'
|
||||
|
||||
runtime 'org.codehaus.groovy:groovy:2.4.+'
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
package meerkat.crypto.dkg.comm;
|
||||
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.google.protobuf.Message;
|
||||
import meerkat.crypto.utils.Channel;
|
||||
import meerkat.protobuf.DKG;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Created by Tzlil on 2/14/2016.
|
||||
*
|
||||
* an implementation of ReceiverCallback
|
||||
*/
|
||||
public abstract class MailHandler implements Channel.ReceiverCallback{
|
||||
final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
/**
|
||||
* fixed value for broadcasting
|
||||
*/
|
||||
public static final int BROADCAST = 0;
|
||||
|
||||
/**
|
||||
* message handler
|
||||
*/
|
||||
private MessageHandler messageHandler;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param messageHandler
|
||||
*/
|
||||
public MailHandler(MessageHandler messageHandler){
|
||||
this.messageHandler = messageHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Was this broadcastMessage was received by broadcast channel
|
||||
* @param broadcastMessage
|
||||
* @return broadcastMessage user destination == BROADCAST
|
||||
*/
|
||||
public boolean isBroadcast(DKG.BroadcastMessage broadcastMessage){
|
||||
return broadcastMessage.getDestination() == BROADCAST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveMail(DKG.BroadcastMessage envelope) {
|
||||
try {
|
||||
messageHandler.handleMessage(envelope);
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
logger.warn("Received invalid protocol buffer from channel", e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,50 +1,47 @@
|
|||
package meerkat.crypto.dkg.comm;
|
||||
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.google.protobuf.Message;
|
||||
import meerkat.protobuf.DKG;
|
||||
import meerkat.comm.Channel;
|
||||
import meerkat.protobuf.Comm;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Created by Tzlil on 2/14/2016.
|
||||
* an interface for handling received messages
|
||||
*
|
||||
* an implementation of ReceiverCallback
|
||||
*/
|
||||
public interface MessageHandler {
|
||||
public abstract class MessageHandler implements Channel.ReceiverCallback {
|
||||
final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
/**
|
||||
* fixed value for broadcasting
|
||||
*/
|
||||
public static final int BROADCAST = 0;
|
||||
|
||||
/**
|
||||
* Handle a broadcast (or unicast) message.
|
||||
* If the message is invalid, the handler can throw an {@link InvalidProtocolBufferException}, in which
|
||||
* case the message will simply be ignored.
|
||||
* @param envelope
|
||||
*/
|
||||
void handleMessage(DKG.BroadcastMessage envelope) throws InvalidProtocolBufferException;
|
||||
//
|
||||
// /**
|
||||
// * handle share message
|
||||
// */
|
||||
// void handleShareMessage(int sender, boolean isBroadcast, Message message);
|
||||
//
|
||||
// /**
|
||||
// * handle commitment message
|
||||
// */
|
||||
// void handleCommitmentMessage(int sender, boolean isBroadcast, Message message);
|
||||
//
|
||||
// /**
|
||||
// * handle complaint message
|
||||
// */
|
||||
// void handleComplaintMessage(int sender, boolean isBroadcast, Message message);
|
||||
//
|
||||
// /**
|
||||
// * handle done message
|
||||
// */
|
||||
// void handleDoneMessage(int sender, boolean isBroadcast, Message message);
|
||||
//
|
||||
// /**
|
||||
// * handle answer message
|
||||
// */
|
||||
// void handleAnswerMessage(int sender, boolean isBroadcast, Message message);
|
||||
//
|
||||
// /**
|
||||
// * handle abort message
|
||||
// */
|
||||
// void handleAbortMessage(int sender, boolean isBroadcast, Message message);
|
||||
public abstract void handleMessage(Comm.BroadcastMessage envelope) throws InvalidProtocolBufferException;
|
||||
|
||||
/**
|
||||
* Was this broadcastMessage was received by broadcast channel
|
||||
* @param broadcastMessage
|
||||
* @return broadcastMessage user destination == BROADCAST
|
||||
*/
|
||||
public boolean isBroadcast(Comm.BroadcastMessage broadcastMessage){
|
||||
return broadcastMessage.getDestination() == BROADCAST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveMessage(Comm.BroadcastMessage envelope) {
|
||||
try {
|
||||
handleMessage(envelope);
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
logger.warn("Received invalid protocol buffer from channel", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
package meerkat.crypto.dkg.feldman;
|
||||
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.google.protobuf.Message;
|
||||
import meerkat.crypto.dkg.comm.MessageHandler;
|
||||
import meerkat.protobuf.DKG;
|
||||
|
||||
/**
|
||||
* Created by Tzlil on 2/29/2016.
|
||||
* an extension of MailHandler matching joint feldman protocol
|
||||
*/
|
||||
public class MailHandler extends meerkat.crypto.dkg.comm.MailHandler {
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param messageHandler
|
||||
*/
|
||||
public MailHandler(MessageHandler messageHandler) {
|
||||
super(messageHandler);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package meerkat.crypto.dkg.feldman;
|
||||
|
||||
import meerkat.crypto.utils.Channel;
|
||||
import meerkat.comm.Channel;
|
||||
import meerkat.crypto.secretsharing.feldman.VerifiableSecretSharing;
|
||||
import meerkat.crypto.secretsharing.shamir.Polynomial;
|
||||
import com.google.protobuf.ByteString;
|
||||
|
@ -171,7 +171,9 @@ public class Protocol<T> extends VerifiableSecretSharing<T> {
|
|||
*/
|
||||
public boolean isValidShare(int i){
|
||||
Party<T> party = parties[i - 1];
|
||||
return isValidShare(party.share,party.commitments,id);
|
||||
synchronized (parties[i - 1]) {
|
||||
return isValidShare(party.share, party.commitments, id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -232,7 +234,7 @@ public class Protocol<T> extends VerifiableSecretSharing<T> {
|
|||
*/
|
||||
public void answerAllComplainingPlayers(){
|
||||
ComplaintState[] complaints = parties[id - 1].complaints;
|
||||
for (int i = 1; i <= n ; i++) {
|
||||
for (int i = 1; i <= n; i++) {
|
||||
switch (complaints[i - 1]) {
|
||||
case Waiting:
|
||||
broadcastComplaintAnswer(i);
|
||||
|
@ -241,6 +243,7 @@ public class Protocol<T> extends VerifiableSecretSharing<T> {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -252,26 +255,28 @@ public class Protocol<T> extends VerifiableSecretSharing<T> {
|
|||
Set<Integer> QUAL = new HashSet<Integer>();
|
||||
boolean nonDisqualified;
|
||||
int counter;
|
||||
for (int i = 1; i <= n; i++){
|
||||
ComplaintState[] complaints = parties[i - 1].complaints;
|
||||
nonDisqualified = true;
|
||||
counter = 0;
|
||||
for (int j = 1; j <= n; j++){
|
||||
switch (complaints[j - 1]) {
|
||||
case OK:
|
||||
break;
|
||||
case NonDisqualified:
|
||||
counter++;
|
||||
break;
|
||||
default:
|
||||
nonDisqualified = false;
|
||||
for (int i = 1; i <= n; i++) {
|
||||
synchronized (parties[i - 1]) {
|
||||
ComplaintState[] complaints = parties[i - 1].complaints;
|
||||
nonDisqualified = true;
|
||||
counter = 0;
|
||||
for (int j = 1; j <= n; j++) {
|
||||
switch (complaints[j - 1]) {
|
||||
case OK:
|
||||
break;
|
||||
case NonDisqualified:
|
||||
counter++;
|
||||
break;
|
||||
default:
|
||||
nonDisqualified = false;
|
||||
break;
|
||||
}
|
||||
if (!nonDisqualified)
|
||||
break;
|
||||
}
|
||||
if(!nonDisqualified)
|
||||
break;
|
||||
}
|
||||
if(nonDisqualified && counter <= t){
|
||||
QUAL.add(i);
|
||||
if (nonDisqualified && counter <= t) {
|
||||
QUAL.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return QUAL;
|
||||
|
@ -285,7 +290,9 @@ public class Protocol<T> extends VerifiableSecretSharing<T> {
|
|||
public T calcY(Set<Integer> QUAL){
|
||||
T y = group.zero();
|
||||
for (int i : QUAL) {
|
||||
y = group.add(y , parties[i - 1].commitments.get(0));
|
||||
synchronized (parties[i - 1]) {
|
||||
y = group.add(y, parties[i - 1].commitments.get(0));
|
||||
}
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
@ -301,7 +308,9 @@ public class Protocol<T> extends VerifiableSecretSharing<T> {
|
|||
for (int k = 0; k <= t; k++){
|
||||
value = group.zero();
|
||||
for (int i : QUAL) {
|
||||
value = group.add(value, parties[i - 1].commitments.get(k));
|
||||
synchronized (parties[i - 1]) {
|
||||
value = group.add(value, parties[i - 1].commitments.get(k));
|
||||
}
|
||||
}
|
||||
commitments.add(k,value);
|
||||
}
|
||||
|
@ -315,7 +324,9 @@ public class Protocol<T> extends VerifiableSecretSharing<T> {
|
|||
public Polynomial.Point calcShare(Set<Integer> QUAL){
|
||||
BigInteger xj = BigInteger.ZERO;
|
||||
for (int i : QUAL) {
|
||||
xj = xj.add(parties[i - 1].share.y);
|
||||
synchronized (parties[i - 1]) {
|
||||
xj = xj.add(parties[i - 1].share.y);
|
||||
}
|
||||
}
|
||||
return new Polynomial.Point(BigInteger.valueOf(id) , xj.mod(q));
|
||||
}
|
||||
|
|
|
@ -1,16 +1,23 @@
|
|||
package meerkat.crypto.dkg.feldman;
|
||||
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import meerkat.crypto.utils.Channel;
|
||||
import com.google.protobuf.TextFormat;
|
||||
import meerkat.comm.Channel;
|
||||
import meerkat.crypto.dkg.comm.MessageHandler;
|
||||
import meerkat.crypto.secretsharing.shamir.Polynomial;
|
||||
import com.google.protobuf.ByteString;
|
||||
import com.google.protobuf.Message;
|
||||
import meerkat.protobuf.Comm;
|
||||
import meerkat.protobuf.DKG;
|
||||
import org.factcenter.qilin.primitives.Group;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
|
||||
import static meerkat.crypto.dkg.comm.MessageUtils.createMessage;
|
||||
|
||||
|
@ -25,7 +32,8 @@ import static meerkat.crypto.dkg.comm.MessageUtils.createMessage;
|
|||
* by the end of run(), each party in QUAL has his own share of the generated random key.
|
||||
* this key can be recover by any subset of QUAL of size at least t + 1.
|
||||
*/
|
||||
public class User<T> implements Runnable{
|
||||
public class User<T> implements Runnable {
|
||||
final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
/**
|
||||
* joint feldman protocol object
|
||||
|
@ -59,10 +67,6 @@ public class User<T> implements Runnable{
|
|||
*/
|
||||
protected final int n;
|
||||
|
||||
/**
|
||||
* mail handler registered to channel as ReceiverCallback
|
||||
*/
|
||||
protected meerkat.crypto.dkg.comm.MailHandler mailHandler;
|
||||
|
||||
/**
|
||||
* channel object
|
||||
|
@ -96,6 +100,8 @@ public class User<T> implements Runnable{
|
|||
*/
|
||||
protected T y;
|
||||
|
||||
protected BlockingQueue<Comm.BroadcastMessage> receiveQueue;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param dkg joint feldman protocol object
|
||||
|
@ -120,14 +126,45 @@ public class User<T> implements Runnable{
|
|||
this.share = null;
|
||||
this.y = null;
|
||||
|
||||
this.receiveQueue = new LinkedBlockingDeque<>();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* create MailHandler and register it as ReceiverCallback
|
||||
* create MessageHandler and register it as ReceiverCallback
|
||||
*/
|
||||
protected void registerReceiverCallback(){
|
||||
this.mailHandler = new MailHandler(new MessageHandler());
|
||||
channel.registerReceiverCallback(mailHandler);
|
||||
protected void registerReceiverCallback() {
|
||||
channel.registerReceiverCallback(new meerkat.crypto.dkg.comm.MessageHandler() {
|
||||
@Override
|
||||
public void handleMessage(Comm.BroadcastMessage envelope) throws InvalidProtocolBufferException {
|
||||
receiveQueue.add(envelope);
|
||||
}
|
||||
});
|
||||
|
||||
// this.messageHandler = new MessageHandler();
|
||||
// channel.registerReceiverCallback(messageHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for at least one message to arrive, then handle any messages currently in the queue
|
||||
*/
|
||||
protected void waitAndHandleReceivedMessages() {
|
||||
Comm.BroadcastMessage msg = null;
|
||||
while (!stop && msg == null) {
|
||||
try {
|
||||
msg = receiveQueue.take();
|
||||
} catch (InterruptedException e) {
|
||||
// Possibly stop
|
||||
}
|
||||
}
|
||||
while (!stop && msg != null) {
|
||||
try {
|
||||
handleMessage(msg);
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
logger.warn("Received invalid message: {}", TextFormat.printToString(msg));
|
||||
}
|
||||
msg = receiveQueue.poll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -140,37 +177,34 @@ public class User<T> implements Runnable{
|
|||
dkg.sendSecrets();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* wait for all shares and commitments will arrive from other parties
|
||||
* Check if all shares and commitments have arrived from other parties
|
||||
*/
|
||||
protected void waitUntilStageOneCompleted(){
|
||||
// wait for parties' share
|
||||
for (int i = 0 ; i < n ; i++){
|
||||
synchronized (parties[i]) {
|
||||
while (parties[i].share == null && !parties[i].aborted) {
|
||||
try {
|
||||
parties[i].wait();
|
||||
} catch (InterruptedException e) {
|
||||
if (stop) return;
|
||||
}
|
||||
protected boolean isStageOneCompleted() {
|
||||
for (int i = 0 ; i < n ; i++) {
|
||||
if (!parties[i].aborted) {
|
||||
if (parties[i].share == null)
|
||||
return false;
|
||||
for (int k = 0 ; k <= t ; k++) {
|
||||
if (parties[i].commitments.get(k) == null)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// wait for parties' commitments
|
||||
for (int i = 0 ; i < n ; i++){
|
||||
for (int k = 0 ; k <= t ; k++) {
|
||||
synchronized (parties[i]) {
|
||||
while (parties[i].commitments.get(k) == null && !parties[i].aborted) {
|
||||
try {
|
||||
parties[i].wait();
|
||||
} catch (InterruptedException e) {
|
||||
if (stop) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void waitUntilStageOneCompleted() {
|
||||
while (!stop && !isStageOneCompleted())
|
||||
waitAndHandleReceivedMessages();
|
||||
}
|
||||
|
||||
protected boolean isStageTwoCompleted() {
|
||||
for (int i = 0 ; i < n ; i++) {
|
||||
if (!parties[i].aborted && !parties[i].doneFlag)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -185,25 +219,28 @@ public class User<T> implements Runnable{
|
|||
channel.broadcastMessage(createMessage(DKG.Payload.Type.DONE));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* wait until all other parties done complaining by receiving done message
|
||||
*/
|
||||
protected void waitUntilStageTwoCompleted(){
|
||||
for (int i = 0 ; i < n ; i++){
|
||||
synchronized (parties[i]) {
|
||||
while (!parties[i].doneFlag && !parties[i].aborted) {
|
||||
try {
|
||||
parties[i].wait();
|
||||
} catch (InterruptedException e) {
|
||||
if (stop) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!stop && !isStageTwoCompleted())
|
||||
waitAndHandleReceivedMessages();
|
||||
}
|
||||
|
||||
|
||||
protected boolean haveReceivedAllStage3ComplaintAnswers() {
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (parties[i].aborted)
|
||||
continue;
|
||||
for (int j = 0; j < n; j++) {
|
||||
if (parties[i].complaints[j].equals(Protocol.ComplaintState.Waiting))
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* stage3 according to the protocol
|
||||
* 1. if more than t players complain against a player Pi he is disqualified.
|
||||
|
@ -213,20 +250,11 @@ public class User<T> implements Runnable{
|
|||
*/
|
||||
protected void stage3(){
|
||||
dkg.answerAllComplainingPlayers();
|
||||
|
||||
// wait until there is no complaint waiting for answer
|
||||
for (int i = 0; i < n; i++){
|
||||
for (int j = 0; j < n; j++){
|
||||
synchronized (parties[i]) {
|
||||
while (parties[i].complaints[j].equals(Protocol.ComplaintState.Waiting) && !parties[i].aborted) {
|
||||
try {
|
||||
parties[i].wait();
|
||||
} catch (InterruptedException e) {
|
||||
if (stop) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!stop && !haveReceivedAllStage3ComplaintAnswers())
|
||||
waitAndHandleReceivedMessages();
|
||||
|
||||
this.QUAL = dkg.calcQUAL();
|
||||
}
|
||||
|
||||
|
@ -245,15 +273,23 @@ public class User<T> implements Runnable{
|
|||
@Override
|
||||
public void run() {
|
||||
this.runThread = Thread.currentThread();
|
||||
stage1();
|
||||
waitUntilStageOneCompleted();
|
||||
if (stop) return;
|
||||
stage2();
|
||||
waitUntilStageTwoCompleted();
|
||||
if (stop) return;
|
||||
stage3();
|
||||
if (stop) return;
|
||||
stage4();
|
||||
// For debugging
|
||||
String previousName = runThread.getName();
|
||||
runThread.setName(getClass().getName() +":" + getID());
|
||||
|
||||
try {
|
||||
stage1();
|
||||
waitUntilStageOneCompleted();
|
||||
if (stop) return;
|
||||
stage2();
|
||||
waitUntilStageTwoCompleted();
|
||||
if (stop) return;
|
||||
stage3();
|
||||
if (stop) return;
|
||||
stage4();
|
||||
} finally {
|
||||
runThread.setName(previousName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -360,199 +396,193 @@ public class User<T> implements Runnable{
|
|||
}
|
||||
|
||||
/**
|
||||
* an implementation of MessageHandler
|
||||
* commitment message is valid if:
|
||||
* 1. it was received in broadcast chanel
|
||||
* 2. the sender didn't sent this commitment before
|
||||
*/
|
||||
public class MessageHandler implements meerkat.crypto.dkg.comm.MessageHandler {
|
||||
protected boolean isValidCommitmentMessage(int sender, boolean isBroadcast, DKG.CommitmentMessage commitmentMessage){
|
||||
int i = sender - 1;
|
||||
int k = commitmentMessage.getK();
|
||||
return isBroadcast && parties[i].commitments.get(k) == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* commitment message is valid if:
|
||||
* 1. it was received in broadcast chanel
|
||||
* 2. the sender didn't sent this commitment before
|
||||
*/
|
||||
protected boolean isValidCommitmentMessage(int sender, boolean isBroadcast, DKG.CommitmentMessage commitmentMessage){
|
||||
int i = sender - 1;
|
||||
int k = commitmentMessage.getK();
|
||||
return isBroadcast && parties[i].commitments.get(k) == null;
|
||||
}
|
||||
/**
|
||||
* secret message is valid if:
|
||||
* 1. it was received in private chanel
|
||||
* 2. the sender didn't sent secret message before
|
||||
* 3. secret.i == i
|
||||
* 4. secret.j == id
|
||||
*/
|
||||
protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKG.ShareMessage secretMessage){
|
||||
int i = secretMessage.getI();
|
||||
int j = secretMessage.getJ();
|
||||
if(sender != i || isBroadcast)
|
||||
return false;
|
||||
else
|
||||
return parties[i - 1].share == null && j == id;
|
||||
|
||||
/**
|
||||
* secret message is valid if:
|
||||
* 1. it was received in private chanel
|
||||
* 2. the sender didn't sent secret message before
|
||||
* 3. secret.i == i
|
||||
* 4. secret.j == id
|
||||
*/
|
||||
protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKG.ShareMessage secretMessage){
|
||||
int i = secretMessage.getI();
|
||||
int j = secretMessage.getJ();
|
||||
if(sender != i || isBroadcast)
|
||||
return false;
|
||||
else
|
||||
return parties[i - 1].share == null && j == id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* done message is valid if:
|
||||
* 1. it was received in broadcast chanel
|
||||
* 2. the sender didn't sent done message before
|
||||
*/
|
||||
protected boolean isValidDoneMessage(int sender, boolean isBroadcast){
|
||||
return isBroadcast && !parties[sender - 1].doneFlag;
|
||||
}
|
||||
/**
|
||||
* done message is valid if:
|
||||
* 1. it was received in broadcast chanel
|
||||
* 2. the sender didn't sent done message before
|
||||
*/
|
||||
protected boolean isValidDoneMessage(int sender, boolean isBroadcast){
|
||||
return isBroadcast && !parties[sender - 1].doneFlag;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* complaint message is valid if:
|
||||
* 1. it was received in broadcast chanel
|
||||
* 2. the sender didn't complained against id before
|
||||
*/
|
||||
protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, DKG.IDMessage complaintMessage){
|
||||
int i = sender;
|
||||
int j = complaintMessage.getId();
|
||||
return isBroadcast && parties[i - 1].complaints[j - 1].equals( Protocol.ComplaintState.OK);
|
||||
}
|
||||
/**
|
||||
* complaint message is valid if:
|
||||
* 1. it was received in broadcast chanel
|
||||
* 2. the sender didn't complained against id before
|
||||
*/
|
||||
protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, DKG.IDMessage complaintMessage){
|
||||
int i = sender;
|
||||
int j = complaintMessage.getId();
|
||||
|
||||
/**
|
||||
* answer message is valid if:
|
||||
* 1. it was received in broadcast chanel
|
||||
* 2. secret.i == i
|
||||
* 3. 1 <= secret.j <= n
|
||||
* 4. it is marked that j complained against i and i didn't received
|
||||
*/
|
||||
protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKG.ShareMessage secretMessage){
|
||||
int i = secretMessage.getI();
|
||||
int j = secretMessage.getJ();
|
||||
if(sender != i || !isBroadcast)
|
||||
return false;
|
||||
else
|
||||
return j >= 1 && j <= n && parties[i - 1].complaints[j - 1].equals(Protocol.ComplaintState.Waiting);
|
||||
}
|
||||
assert(i > 0);
|
||||
assert(j > 0);
|
||||
assert(i <= parties.length);
|
||||
assert(j <= parties[i-1].complaints.length);
|
||||
|
||||
return isBroadcast && parties[i - 1].complaints[j - 1].equals( Protocol.ComplaintState.OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* answer message is valid if:
|
||||
* 1. it was received in broadcast chanel
|
||||
* 2. secret.i == i
|
||||
* 3. 1 <= secret.j <= n
|
||||
* 4. it is marked that j complained against i and i didn't received
|
||||
*/
|
||||
protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKG.ShareMessage secretMessage){
|
||||
int i = secretMessage.getI();
|
||||
int j = secretMessage.getJ();
|
||||
if(sender != i || !isBroadcast)
|
||||
return false;
|
||||
else
|
||||
return j >= 1 && j <= n && parties[i - 1].complaints[j - 1].equals(Protocol.ComplaintState.Waiting);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handleMessage(DKG.BroadcastMessage envelope) throws InvalidProtocolBufferException {
|
||||
int sender = envelope.getSender();
|
||||
boolean isBroadcast = !envelope.getIsPrivate();
|
||||
DKG.Payload msg = DKG.Payload.parseFrom(envelope.getPayload());
|
||||
public void handleMessage(Comm.BroadcastMessage envelope) throws InvalidProtocolBufferException {
|
||||
int sender = envelope.getSender();
|
||||
boolean isBroadcast = !envelope.getIsPrivate();
|
||||
DKG.Payload msg = DKG.Payload.parseFrom(envelope.getPayload());
|
||||
|
||||
switch (msg.getType()) {
|
||||
case COMMITMENT:
|
||||
/**
|
||||
* saves the commitment
|
||||
*/
|
||||
DKG.CommitmentMessage commitmentMessage = msg.getCommitment();
|
||||
if (isValidCommitmentMessage(sender, isBroadcast, commitmentMessage)) {
|
||||
int i = sender - 1;
|
||||
int k = commitmentMessage.getK();
|
||||
synchronized (parties[i]) {
|
||||
parties[i].commitments.set(k, extractCommitment(commitmentMessage));
|
||||
parties[i].notify();
|
||||
}
|
||||
logger.debug("handling Message: Dst={}, Src={}, [{}]",
|
||||
envelope.getDestination(), envelope.getSender(), TextFormat.printToString(msg));
|
||||
|
||||
switch (msg.getType()) {
|
||||
case COMMITMENT:
|
||||
/**
|
||||
* saves the commitment
|
||||
*/
|
||||
assert msg.getPayloadDataCase() == DKG.Payload.PayloadDataCase.COMMITMENT;
|
||||
DKG.CommitmentMessage commitmentMessage = msg.getCommitment();
|
||||
if (isValidCommitmentMessage(sender, isBroadcast, commitmentMessage)) {
|
||||
int i = sender - 1;
|
||||
int k = commitmentMessage.getK();
|
||||
|
||||
parties[i].commitments.set(k, extractCommitment(commitmentMessage));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case SHARE:
|
||||
/**
|
||||
* saves the secret
|
||||
*/
|
||||
assert msg.getPayloadDataCase() == DKG.Payload.PayloadDataCase.SHARE;
|
||||
DKG.ShareMessage secretMessage = msg.getShare();
|
||||
if(isValidSecretMessage(sender,isBroadcast,secretMessage)) {
|
||||
int i = secretMessage.getI();
|
||||
Polynomial.Point secret = extractShare(id,secretMessage.getShare());
|
||||
parties[i - 1].share = secret;
|
||||
}
|
||||
break;
|
||||
|
||||
case DONE:
|
||||
|
||||
/**
|
||||
* marks that the sender was finished sending all his complaints
|
||||
*/
|
||||
if(isValidDoneMessage(sender,isBroadcast)) {
|
||||
parties[sender - 1].doneFlag = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case COMPLAINT:
|
||||
/**
|
||||
* marks that the sender was complained against id
|
||||
*/
|
||||
if (msg.getPayloadDataCase() != DKG.Payload.PayloadDataCase.ID) {
|
||||
logger.error("User {} Expecting ID message, got from SRC={} msg {}", getID(), envelope.getSender(), TextFormat.printToString(msg));
|
||||
assert (msg.getPayloadDataCase() == DKG.Payload.PayloadDataCase.ID);
|
||||
}
|
||||
|
||||
DKG.IDMessage complaintMessage = msg.getId();
|
||||
if(isValidComplaintMessage(sender,isBroadcast,complaintMessage)){
|
||||
int i = sender;
|
||||
int j = complaintMessage.getId();
|
||||
parties[j - 1].complaints[i - 1] = Protocol.ComplaintState.Waiting;
|
||||
}
|
||||
break;
|
||||
case ANSWER:
|
||||
/**
|
||||
* if the secret is valid, marks the complaint as NonDisqualified
|
||||
* else marks it as Disqualified
|
||||
* in case that the complainer is id ( j == id ), saves the secret
|
||||
*/
|
||||
assert msg.getPayloadDataCase() == DKG.Payload.PayloadDataCase.SHARE;
|
||||
secretMessage = msg.getShare();
|
||||
if(isValidAnswerMessage(sender,isBroadcast,secretMessage)) {
|
||||
int i = secretMessage.getI();
|
||||
int j = secretMessage.getJ();
|
||||
Polynomial.Point secret = extractShare(j,secretMessage.getShare());
|
||||
if (dkg.isValidShare(secret, parties[i - 1].commitments, j)) {
|
||||
parties[i - 1].complaints[j - 1] = Protocol.ComplaintState.NonDisqualified;
|
||||
} else {
|
||||
parties[i - 1].complaints[j - 1] = Protocol.ComplaintState.Disqualified;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case SHARE:
|
||||
/**
|
||||
* saves the secret
|
||||
*/
|
||||
DKG.ShareMessage secretMessage = msg.getShare();
|
||||
if(isValidSecretMessage(sender,isBroadcast,secretMessage)) {
|
||||
int i = secretMessage.getI();
|
||||
Polynomial.Point secret = extractShare(id,secretMessage.getShare());
|
||||
synchronized (parties[i -1]) {
|
||||
parties[i - 1].share = secret;
|
||||
parties[i - 1].notify();
|
||||
}
|
||||
if (j == id) {
|
||||
parties[i - 1].share = secret;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ABORT:
|
||||
/**
|
||||
* marks that the sender was aborted
|
||||
*/
|
||||
parties[sender - 1].aborted = true;
|
||||
break;
|
||||
default:
|
||||
logger.error("Bad message: SRC={}, DST={}, Payload={}", envelope.getSender(), envelope.getDestination(), TextFormat.printToString(msg));
|
||||
break;
|
||||
|
||||
case DONE:
|
||||
|
||||
/**
|
||||
* marks that the sender was finished sending all his complaints
|
||||
*/
|
||||
if(isValidDoneMessage(sender,isBroadcast)) {
|
||||
synchronized (parties[sender - 1]) {
|
||||
parties[sender - 1].doneFlag = true;
|
||||
parties[sender - 1].notify();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case COMPLAINT:
|
||||
/**
|
||||
* marks that the sender was complained against id
|
||||
*/
|
||||
DKG.IDMessage complaintMessage = msg.getId();
|
||||
if(isValidComplaintMessage(sender,isBroadcast,complaintMessage)){
|
||||
int i = sender;
|
||||
int j = complaintMessage.getId();
|
||||
synchronized (parties[j - 1]) {
|
||||
parties[j - 1].complaints[i - 1] = Protocol.ComplaintState.Waiting;
|
||||
parties[j - 1].notify();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ANSWER:
|
||||
/**
|
||||
* if the secret is valid, marks the complaint as NonDisqualified
|
||||
* else marks it as Disqualified
|
||||
* in case that the complainer is id ( j == id ), saves the secret
|
||||
*/
|
||||
secretMessage = msg.getShare();
|
||||
if(isValidAnswerMessage(sender,isBroadcast,secretMessage)) {
|
||||
int i = secretMessage.getI();
|
||||
int j = secretMessage.getJ();
|
||||
Polynomial.Point secret = extractShare(j,secretMessage.getShare());
|
||||
synchronized (parties[i - 1]) {
|
||||
if (dkg.isValidShare(secret, parties[i - 1].commitments, j)) {
|
||||
parties[i - 1].complaints[j - 1] = Protocol.ComplaintState.NonDisqualified;
|
||||
} else {
|
||||
parties[i - 1].complaints[j - 1] = Protocol.ComplaintState.Disqualified;
|
||||
}
|
||||
if (j == id) {
|
||||
parties[i - 1].share = secret;
|
||||
}
|
||||
parties[i - 1].notify();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ABORT:
|
||||
/**
|
||||
* marks that the sender was aborted
|
||||
*/
|
||||
synchronized (parties[sender - 1]) {
|
||||
parties[sender - 1].aborted = true;
|
||||
parties[sender - 1].notify();
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* extract share value from ByteString
|
||||
* @param i
|
||||
* @param share
|
||||
* @return new Point (i,share)
|
||||
*/
|
||||
public Polynomial.Point extractShare(int i, ByteString share){
|
||||
BigInteger x = BigInteger.valueOf(i);
|
||||
BigInteger y = new BigInteger(share.toByteArray());
|
||||
return new Polynomial.Point(x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param commitmentMessage
|
||||
* @return
|
||||
*/
|
||||
public T extractCommitment(DKG.CommitmentMessage commitmentMessage){
|
||||
return dkg.decodeCommitment(commitmentMessage.getCommitment().toByteArray());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* extract share value from ByteString
|
||||
* @param i
|
||||
* @param share
|
||||
* @return new Point (i,share)
|
||||
*/
|
||||
public Polynomial.Point extractShare(int i, ByteString share){
|
||||
BigInteger x = BigInteger.valueOf(i);
|
||||
BigInteger y = new BigInteger(share.toByteArray());
|
||||
return new Polynomial.Point(x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param commitmentMessage
|
||||
* @return
|
||||
*/
|
||||
public T extractCommitment(DKG.CommitmentMessage commitmentMessage){
|
||||
return dkg.decodeCommitment(commitmentMessage.getCommitment().toByteArray());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
package meerkat.crypto.dkg.gjkr;
|
||||
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.google.protobuf.Message;
|
||||
import meerkat.crypto.dkg.comm.MessageHandler;
|
||||
import meerkat.protobuf.DKG;
|
||||
|
||||
/**
|
||||
* Created by Tzlil on 2/29/2016.
|
||||
* an extension of MailHandler matching gjkr protocl
|
||||
*/
|
||||
public class MailHandler extends meerkat.crypto.dkg.comm.MailHandler {
|
||||
|
||||
/**
|
||||
* flag that indicants whether the
|
||||
* current run achieved stage 4 of the protocol or not
|
||||
*/
|
||||
private boolean isStage4;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param messageHandler
|
||||
*/
|
||||
public MailHandler(MessageHandler messageHandler) {
|
||||
super(messageHandler);
|
||||
this.isStage4 = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* setter
|
||||
* @param stage4
|
||||
*/
|
||||
public void setStage4(boolean stage4) {
|
||||
isStage4 = stage4;
|
||||
}
|
||||
}
|
|
@ -3,10 +3,10 @@ package meerkat.crypto.dkg.gjkr;
|
|||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import meerkat.crypto.utils.Arithmetic;
|
||||
import meerkat.crypto.utils.concrete.Fp;
|
||||
import meerkat.crypto.utils.Channel;
|
||||
import meerkat.comm.Channel;
|
||||
import meerkat.crypto.secretsharing.shamir.Polynomial;
|
||||
import meerkat.crypto.secretsharing.shamir.SecretSharing;
|
||||
import com.google.protobuf.Message;
|
||||
import meerkat.protobuf.Comm;
|
||||
import meerkat.protobuf.DKG;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
@ -38,10 +38,7 @@ public class User<T> extends meerkat.crypto.dkg.feldman.User<T> {
|
|||
*/
|
||||
protected final Protocol<T> sdkg;
|
||||
|
||||
/**
|
||||
* message handler
|
||||
*/
|
||||
private MessageHandler messageHandler;
|
||||
boolean isStage4;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
|
@ -55,13 +52,6 @@ public class User<T> extends meerkat.crypto.dkg.feldman.User<T> {
|
|||
this.parties = sdkg.getParties();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerReceiverCallback() {
|
||||
this.messageHandler = new MessageHandler();
|
||||
this.mailHandler = new MailHandler(messageHandler);
|
||||
this.channel.registerReceiverCallback(mailHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* stage1 according to the protocol
|
||||
* 1. Pi broadcasts Cik=Aik*Bik for k = 0,...,t.
|
||||
|
@ -73,6 +63,8 @@ public class User<T> extends meerkat.crypto.dkg.feldman.User<T> {
|
|||
sdkg.sendSecrets();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void waitUntilStageOneCompleted() {
|
||||
super.waitUntilStageOneCompleted();
|
||||
|
@ -98,40 +90,74 @@ public class User<T> extends meerkat.crypto.dkg.feldman.User<T> {
|
|||
channel.broadcastMessage(createMessage(DKG.Payload.Type.DONE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if all non-aborting qualified parties have sent commitments.
|
||||
* @return
|
||||
*/
|
||||
protected boolean haveAllQualPartiesCommitted() {
|
||||
for (int i : QUAL) {
|
||||
if (parties[i - 1].aborted)
|
||||
continue;
|
||||
for (int k = 0; k <= t; k++) {
|
||||
if (parties[i - 1].commitments.get(k) == null)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if all non-aborting qualified parties sent a done message
|
||||
* @return
|
||||
*/
|
||||
protected boolean areAllQualPartiesDone() {
|
||||
for (int i : QUAL) {
|
||||
if (parties[i - 1].aborted)
|
||||
continue;
|
||||
for (int k = 0; k <= t; k++) {
|
||||
if (!parties[i - 1].ysDoneFlag)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if at least t + 1 secrets were received foreach i in QUAL that aborted
|
||||
* @return
|
||||
*/
|
||||
protected boolean haveReceivedEnoughSecretShares() {
|
||||
for (int i : QUAL) {
|
||||
if (parties[i - 1].aborted && parties[i - 1].recoverSharesSet.size() <= t)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* broadcast commitments and recover parties information if necessary
|
||||
*/
|
||||
private void resolveQualifyingPublicKey() {
|
||||
sdkg.broadcastCommitments();
|
||||
// wait until all parties in QUAL broadcast their commitments or aborted
|
||||
for (int i : QUAL) {
|
||||
for (int k = 0; k <= t; k++) {
|
||||
synchronized (parties[i - 1]) {
|
||||
while (parties[i - 1].commitments.get(k) == null && !parties[i - 1].aborted) {
|
||||
try {
|
||||
parties[i - 1].wait();
|
||||
} catch (InterruptedException e) {
|
||||
if (stop) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!stop && !haveAllQualPartiesCommitted())
|
||||
waitAndHandleReceivedMessages();
|
||||
|
||||
if (stop)
|
||||
return;
|
||||
|
||||
sdkg.computeAndBroadcastComplaints(QUAL);
|
||||
|
||||
//broadcast done message after all complaints
|
||||
channel.broadcastMessage(createMessage(DKG.Payload.Type.DONE));
|
||||
|
||||
// wait until all parties in QUAL done or aborted
|
||||
for (int i : QUAL) {
|
||||
synchronized ((parties[i - 1])) {
|
||||
while (!parties[i - 1].ysDoneFlag && !parties[i - 1].aborted) {
|
||||
try {
|
||||
parties[i - 1].wait();
|
||||
} catch (InterruptedException e) {
|
||||
if (stop) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!stop && !areAllQualPartiesDone())
|
||||
waitAndHandleReceivedMessages();
|
||||
|
||||
if (stop)
|
||||
return;
|
||||
|
||||
// broadcast i private secret foreach i in QUAL that aborted
|
||||
for (int i : QUAL) {
|
||||
|
@ -140,19 +166,12 @@ public class User<T> extends meerkat.crypto.dkg.feldman.User<T> {
|
|||
}
|
||||
}
|
||||
// wait until at least t + 1 secrets will received foreach i in QUAL that aborted
|
||||
for (int i : QUAL) {
|
||||
synchronized ((parties[i - 1])) {
|
||||
if (parties[i - 1].aborted) {
|
||||
while (parties[i - 1].recoverSharesSet.size() <= t) {
|
||||
try {
|
||||
parties[i - 1].wait();
|
||||
} catch (InterruptedException e) {
|
||||
if (stop) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!stop && !haveReceivedEnoughSecretShares())
|
||||
waitAndHandleReceivedMessages();
|
||||
|
||||
if (stop)
|
||||
return;
|
||||
|
||||
Arithmetic<BigInteger> arithmetic = new Fp(sdkg.getQ());
|
||||
// restore necessary information
|
||||
for (int i = 0; i < n; i++) {
|
||||
|
@ -177,11 +196,10 @@ public class User<T> extends meerkat.crypto.dkg.feldman.User<T> {
|
|||
}
|
||||
|
||||
/**
|
||||
* notifies mail handler and message handler that stage 4 was started
|
||||
* notifies message handler and message handler that stage 4 was started
|
||||
*/
|
||||
protected void setStage4() {
|
||||
this.messageHandler.isStage4 = true;
|
||||
((MailHandler) this.mailHandler).setStage4(true);
|
||||
isStage4 = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -192,151 +210,150 @@ public class User<T> extends meerkat.crypto.dkg.feldman.User<T> {
|
|||
super.stage4();
|
||||
}
|
||||
|
||||
private class MessageHandler extends meerkat.crypto.dkg.feldman.User.MessageHandler {
|
||||
|
||||
boolean isStage4;
|
||||
|
||||
/**
|
||||
* if !isStage4 as super, with extension to double secret message
|
||||
* else answer message is valid if:
|
||||
* 1. it was received in broadcast chanel
|
||||
* 2. secret.j == sender
|
||||
* 3. QUAL contains i and j
|
||||
*/
|
||||
protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKG.ShareMessage doubleSecretMessage) {
|
||||
if (!isStage4) {
|
||||
return super.isValidAnswerMessage(sender, isBroadcast, doubleSecretMessage);
|
||||
} else {
|
||||
int i = doubleSecretMessage.getI();
|
||||
int j = doubleSecretMessage.getJ();
|
||||
return isBroadcast && j == sender && parties[i - 1].aborted && !parties[j - 1].aborted
|
||||
&& QUAL.contains(i) && QUAL.contains(j);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* as in super with respect to protocol stage
|
||||
*/
|
||||
@Override
|
||||
protected boolean isValidDoneMessage(int sender, boolean isBroadcast) {
|
||||
if (!isStage4) {
|
||||
return super.isValidDoneMessage(sender, isBroadcast);
|
||||
} else {
|
||||
return isBroadcast && !parties[sender - 1].ysDoneFlag;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* use only in stage4
|
||||
* complaint message is valid if:
|
||||
* 1. it was received in broadcast chanel
|
||||
* 2. secret.j == sender
|
||||
* 3. QUAL contains i and j
|
||||
*/
|
||||
protected boolean isValidComplaintMessage(int sender, boolean isBroadcast,
|
||||
DKG.ShareMessage complaintMessage) {
|
||||
int i = complaintMessage.getI();
|
||||
int j = complaintMessage.getJ();
|
||||
return isBroadcast && j == sender && QUAL.contains(i) && QUAL.contains(j);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handleMessage(DKG.BroadcastMessage envelope) throws InvalidProtocolBufferException {
|
||||
int sender = envelope.getSender();
|
||||
boolean isBroadcast = !envelope.getIsPrivate();
|
||||
DKG.Payload msg = DKG.Payload.parseFrom(envelope.getPayload());
|
||||
switch (msg.getType()) {
|
||||
case SHARE:
|
||||
/**
|
||||
* as in super, with extension to double secret message
|
||||
*/
|
||||
DKG.ShareMessage doubleSecretMessage = msg.getShare();
|
||||
if (isValidSecretMessage(sender, isBroadcast, doubleSecretMessage)) {
|
||||
int i = doubleSecretMessage.getI();
|
||||
synchronized (parties[i - 1]) {
|
||||
parties[i - 1].share = extractShare(id, doubleSecretMessage.getShare());
|
||||
parties[i - 1].shareT = extractShare(id, doubleSecretMessage.getShareT());
|
||||
parties[i - 1].notify();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ANSWER:
|
||||
/**
|
||||
* if !isStage4 as super, with extension to double secret message
|
||||
* else saves secret
|
||||
*/
|
||||
doubleSecretMessage = msg.getShare();
|
||||
if (isValidAnswerMessage(sender, isBroadcast, doubleSecretMessage)) {
|
||||
int i = doubleSecretMessage.getI();
|
||||
int j = doubleSecretMessage.getJ();
|
||||
Polynomial.Point secret = extractShare(j, doubleSecretMessage.getShare());
|
||||
Polynomial.Point secretT = extractShare(j, doubleSecretMessage.getShareT());
|
||||
synchronized (parties[i - 1]) {
|
||||
if (!isStage4) {
|
||||
if (sdkg.isValidShare(secret, secretT, parties[j - 1].verifiableValues, i)) {
|
||||
parties[i - 1].complaints[j - 1] = meerkat.crypto.dkg.feldman.Protocol.ComplaintState.NonDisqualified;
|
||||
|
||||
} else {
|
||||
parties[i - 1].complaints[j - 1] = meerkat.crypto.dkg.feldman.Protocol.ComplaintState.Disqualified;
|
||||
}
|
||||
if (j == id) {
|
||||
parties[i - 1].share = secret;
|
||||
parties[i - 1].shareT = secretT;
|
||||
}
|
||||
} else if (sdkg.isValidShare(secret, secretT, parties[i - 1].verifiableValues, j)) {
|
||||
parties[i - 1].recoverSharesSet.add(secret);
|
||||
}
|
||||
parties[i - 1].notify();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DONE:
|
||||
/**
|
||||
* as in super with respect to protocol state
|
||||
*/
|
||||
if (!isStage4)
|
||||
super.handleMessage(envelope);
|
||||
else {
|
||||
if (isValidDoneMessage(sender, isBroadcast)) {
|
||||
synchronized (parties[sender - 1]) {
|
||||
parties[sender - 1].ysDoneFlag = true;
|
||||
parties[sender - 1].notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case COMPLAINT:
|
||||
/**
|
||||
* if !isStage4 as in super
|
||||
* else if secret,secretT are valid with respect to verifiableValues but
|
||||
* secret is not valid with respect to commitments then
|
||||
* marks i as aborted
|
||||
*/
|
||||
if (!isStage4) {
|
||||
super.handleMessage(envelope);
|
||||
} else {
|
||||
DKG.ShareMessage ysComplaintMessage = msg.getShare();
|
||||
if (isValidComplaintMessage(sender, isBroadcast, ysComplaintMessage)) {
|
||||
int i = ysComplaintMessage.getI();
|
||||
int j = ysComplaintMessage.getJ();
|
||||
Polynomial.Point secret = extractShare(i, ysComplaintMessage.getShare());
|
||||
Polynomial.Point secretT = extractShare(i, ysComplaintMessage.getShareT());
|
||||
if (sdkg.isValidShare(secret, secretT, parties[i - 1].verifiableValues, j)
|
||||
&& !dkg.isValidShare(secret, parties[i - 1].commitments, j)) {
|
||||
synchronized (parties[i - 1]) {
|
||||
parties[i - 1].aborted = true;
|
||||
parties[i - 1].notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
super.handleMessage(envelope);
|
||||
break;
|
||||
}
|
||||
/**
|
||||
* if !isStage4 as super, with extension to double secret message
|
||||
* else answer message is valid if:
|
||||
* 1. it was received in broadcast chanel
|
||||
* 2. secret.j == sender
|
||||
* 3. QUAL contains i and j
|
||||
*/
|
||||
protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKG.ShareMessage doubleSecretMessage) {
|
||||
if (!isStage4) {
|
||||
return super.isValidAnswerMessage(sender, isBroadcast, doubleSecretMessage);
|
||||
} else {
|
||||
int i = doubleSecretMessage.getI();
|
||||
int j = doubleSecretMessage.getJ();
|
||||
return isBroadcast && j == sender && parties[i - 1].aborted && !parties[j - 1].aborted
|
||||
&& QUAL.contains(i) && QUAL.contains(j);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* as in super with respect to protocol stage
|
||||
*/
|
||||
@Override
|
||||
protected boolean isValidDoneMessage(int sender, boolean isBroadcast) {
|
||||
if (!isStage4) {
|
||||
return super.isValidDoneMessage(sender, isBroadcast);
|
||||
} else {
|
||||
return isBroadcast && !parties[sender - 1].ysDoneFlag;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* use only in stage4
|
||||
* complaint message is valid if:
|
||||
* 1. it was received in broadcast chanel
|
||||
* 2. secret.j == sender
|
||||
* 3. QUAL contains i and j
|
||||
*/
|
||||
protected boolean isValidComplaintMessage(int sender, boolean isBroadcast,
|
||||
DKG.ShareMessage complaintMessage) {
|
||||
int i = complaintMessage.getI();
|
||||
int j = complaintMessage.getJ();
|
||||
return isBroadcast && j == sender && QUAL.contains(i) && QUAL.contains(j);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handleMessage(Comm.BroadcastMessage envelope) throws InvalidProtocolBufferException {
|
||||
int sender = envelope.getSender();
|
||||
boolean isBroadcast = !envelope.getIsPrivate();
|
||||
DKG.Payload msg = DKG.Payload.parseFrom(envelope.getPayload());
|
||||
switch (msg.getType()) {
|
||||
case SHARE:
|
||||
/**
|
||||
* as in super, with extension to double secret message
|
||||
*/
|
||||
DKG.ShareMessage doubleSecretMessage = msg.getShare();
|
||||
if (isValidSecretMessage(sender, isBroadcast, doubleSecretMessage)) {
|
||||
int i = doubleSecretMessage.getI();
|
||||
synchronized (parties[i - 1]) {
|
||||
parties[i - 1].share = extractShare(id, doubleSecretMessage.getShare());
|
||||
parties[i - 1].shareT = extractShare(id, doubleSecretMessage.getShareT());
|
||||
parties[i - 1].notify();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ANSWER:
|
||||
/**
|
||||
* if !isStage4 as super, with extension to double secret message
|
||||
* else saves secret
|
||||
*/
|
||||
assert msg.getPayloadDataCase() == DKG.Payload.PayloadDataCase.SHARE;
|
||||
doubleSecretMessage = msg.getShare();
|
||||
if (isValidAnswerMessage(sender, isBroadcast, doubleSecretMessage)) {
|
||||
int i = doubleSecretMessage.getI();
|
||||
int j = doubleSecretMessage.getJ();
|
||||
Polynomial.Point secret = extractShare(j, doubleSecretMessage.getShare());
|
||||
Polynomial.Point secretT = extractShare(j, doubleSecretMessage.getShareT());
|
||||
synchronized (parties[i - 1]) {
|
||||
if (!isStage4) {
|
||||
if (sdkg.isValidShare(secret, secretT, parties[j - 1].verifiableValues, i)) {
|
||||
parties[i - 1].complaints[j - 1] = meerkat.crypto.dkg.feldman.Protocol.ComplaintState.NonDisqualified;
|
||||
|
||||
} else {
|
||||
parties[i - 1].complaints[j - 1] = meerkat.crypto.dkg.feldman.Protocol.ComplaintState.Disqualified;
|
||||
}
|
||||
if (j == id) {
|
||||
parties[i - 1].share = secret;
|
||||
parties[i - 1].shareT = secretT;
|
||||
}
|
||||
} else if (sdkg.isValidShare(secret, secretT, parties[i - 1].verifiableValues, j)) {
|
||||
parties[i - 1].recoverSharesSet.add(secret);
|
||||
}
|
||||
parties[i - 1].notify();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DONE:
|
||||
/**
|
||||
* as in super with respect to protocol state
|
||||
*/
|
||||
if (!isStage4)
|
||||
super.handleMessage(envelope);
|
||||
else {
|
||||
if (isValidDoneMessage(sender, isBroadcast)) {
|
||||
synchronized (parties[sender - 1]) {
|
||||
parties[sender - 1].ysDoneFlag = true;
|
||||
parties[sender - 1].notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case COMPLAINT:
|
||||
/**
|
||||
* if !isStage4 as in super
|
||||
* else if secret,secretT are valid with respect to verifiableValues but
|
||||
* secret is not valid with respect to commitments then
|
||||
* marks i as aborted
|
||||
*/
|
||||
if (!isStage4) {
|
||||
super.handleMessage(envelope);
|
||||
} else {
|
||||
assert (msg.getPayloadDataCase() == DKG.Payload.PayloadDataCase.SHARE);
|
||||
DKG.ShareMessage ysComplaintMessage = msg.getShare();
|
||||
if (isValidComplaintMessage(sender, isBroadcast, ysComplaintMessage)) {
|
||||
int i = ysComplaintMessage.getI();
|
||||
int j = ysComplaintMessage.getJ();
|
||||
Polynomial.Point secret = extractShare(i, ysComplaintMessage.getShare());
|
||||
Polynomial.Point secretT = extractShare(i, ysComplaintMessage.getShareT());
|
||||
if (sdkg.isValidShare(secret, secretT, parties[i - 1].verifiableValues, j)
|
||||
&& !dkg.isValidShare(secret, parties[i - 1].commitments, j)) {
|
||||
synchronized (parties[i - 1]) {
|
||||
parties[i - 1].aborted = true;
|
||||
parties[i - 1].notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
super.handleMessage(envelope);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -4,14 +4,6 @@ package meerkat;
|
|||
|
||||
option java_package = "meerkat.protobuf";
|
||||
|
||||
message BroadcastMessage {
|
||||
int32 sender = 1;
|
||||
int32 destination = 2;
|
||||
bool is_private = 3;
|
||||
|
||||
bytes payload = 5;
|
||||
}
|
||||
|
||||
message Payload {
|
||||
enum Type {
|
||||
SHARE = 0;
|
||||
|
@ -25,9 +17,11 @@ message Payload {
|
|||
ABORT = 8;
|
||||
}
|
||||
|
||||
|
||||
// Type of message in protocol
|
||||
Type type = 1;
|
||||
|
||||
oneof specific {
|
||||
oneof payload_data {
|
||||
IDMessage id = 5;
|
||||
ShareMessage share = 6;
|
||||
CommitmentMessage commitment = 7;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package meerkat.crypto.dkg.feldman;
|
||||
|
||||
import meerkat.crypto.utils.Channel;
|
||||
import meerkat.comm.Channel;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package meerkat.crypto.dkg.feldman;
|
||||
|
||||
import meerkat.crypto.utils.ChannelImpl;
|
||||
import meerkat.comm.ChannelImpl;
|
||||
import meerkat.crypto.utils.Arithmetic;
|
||||
import meerkat.crypto.utils.concrete.Fp;
|
||||
import meerkat.crypto.utils.Channel;
|
||||
import meerkat.comm.Channel;
|
||||
import meerkat.crypto.secretsharing.feldman.VerifiableSecretSharing;
|
||||
import meerkat.crypto.secretsharing.shamir.Polynomial;
|
||||
import meerkat.crypto.secretsharing.shamir.SecretSharing;
|
||||
|
@ -71,13 +71,6 @@ public class DKGTest {
|
|||
assert (calculatedSecret.equals(testable.secret));
|
||||
}
|
||||
|
||||
public void stopReceivers(Testable testable){
|
||||
ChannelImpl channel;
|
||||
for (int i = 0 ; i < testable.dkgs.length ; i++){
|
||||
channel = (ChannelImpl)testable.dkgs[i].getChannel();
|
||||
channel.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
|
@ -85,7 +78,6 @@ public class DKGTest {
|
|||
for (int i = 0; i < tests; i++){
|
||||
testable = new Testable(new Random());
|
||||
oneTest(testable);
|
||||
stopReceivers(testable);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,11 +107,11 @@ public class DKGTest {
|
|||
BigInteger s;
|
||||
Protocol<BigInteger> dkg;
|
||||
this.secret = BigInteger.ZERO;
|
||||
ChannelImpl channel;
|
||||
ChannelImpl channels = new ChannelImpl();
|
||||
ByteEncoder<BigInteger> byteEncoder = new BigIntegerByteEncoder();
|
||||
while (!ids.isEmpty()) {
|
||||
id = ids.remove(random.nextInt(ids.size()));
|
||||
channel = new ChannelImpl(id,n);
|
||||
Channel channel = channels.getChannel(id);
|
||||
s = randomIntModQ(random);
|
||||
dkg = new meerkat.crypto.dkg.feldman.Protocol<BigInteger>(t, n, s, random, q, g, group, id,byteEncoder);
|
||||
dkgs[id - 1] = randomDKGUser(id,channel,dkg,random);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package meerkat.crypto.dkg.feldman;
|
||||
|
||||
import meerkat.crypto.utils.Channel;
|
||||
import meerkat.comm.Channel;
|
||||
import meerkat.protobuf.DKG;
|
||||
|
||||
import static meerkat.crypto.dkg.comm.MessageUtils.createMessage;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package meerkat.crypto.dkg.gjkr;
|
||||
|
||||
import meerkat.crypto.utils.Channel;
|
||||
import meerkat.comm.Channel;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Random;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package meerkat.crypto.dkg.gjkr;
|
||||
|
||||
import meerkat.crypto.utils.ChannelImpl;
|
||||
import meerkat.comm.ChannelImpl;
|
||||
import meerkat.crypto.utils.Arithmetic;
|
||||
import meerkat.crypto.utils.concrete.Fp;
|
||||
import meerkat.crypto.utils.Channel;
|
||||
import meerkat.comm.Channel;
|
||||
import meerkat.crypto.secretsharing.feldman.VerifiableSecretSharing;
|
||||
import meerkat.crypto.dkg.feldman.DKGMaliciousUser;
|
||||
import meerkat.crypto.secretsharing.shamir.Polynomial;
|
||||
|
@ -13,34 +13,45 @@ import meerkat.crypto.utils.GenerateRandomPrime;
|
|||
import org.factcenter.qilin.primitives.Group;
|
||||
import org.factcenter.qilin.primitives.concrete.Zpstar;
|
||||
import org.factcenter.qilin.util.ByteEncoder;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.internal.runners.statements.Fail;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
* Created by Tzlil on 3/29/2016.
|
||||
* TODO: Separate into multiple tests,
|
||||
* TODO: Make tests deterministic (using constant seed for random generator)
|
||||
*/
|
||||
public class SDKGTest {
|
||||
|
||||
int tests = 10;
|
||||
private ExecutorService executorService = Executors.newCachedThreadPool();
|
||||
|
||||
final static int NUM_TESTS = 10;
|
||||
BigInteger p = GenerateRandomPrime.SafePrime100Bits;
|
||||
BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2));
|
||||
Group<BigInteger> group = new Zpstar(p);
|
||||
Arithmetic<BigInteger> arithmetic = new Fp(q);
|
||||
int t = 9;
|
||||
int t = 1;
|
||||
int n = 20;
|
||||
|
||||
Random rand = new Random(1);
|
||||
|
||||
public void oneTest(Testable testable) throws Exception {
|
||||
for (int i = 0; i < testable.threads.length ; i++){
|
||||
testable.threads[i].start();
|
||||
for (int i = 0; i < testable.sdkgs.length ; i++){
|
||||
testable.futures[i] = executorService.submit(testable.sdkgs[i]);
|
||||
}
|
||||
for (int i = 0; i < testable.threads.length ; i++){
|
||||
testable.threads[i].join();
|
||||
for (int i = 0; i < testable.futures.length ; i++){
|
||||
testable.futures[i].get();
|
||||
}
|
||||
|
||||
// got the right public value
|
||||
|
@ -73,41 +84,45 @@ public class SDKGTest {
|
|||
assert (calculatedSecret.equals(testable.secret));
|
||||
}
|
||||
|
||||
public void stopReceivers(Testable testable){
|
||||
ChannelImpl channel;
|
||||
for (int i = 0 ; i < testable.sdkgs.length ; i++){
|
||||
channel = (ChannelImpl)testable.sdkgs[i].getChannel();
|
||||
channel.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
Testable testable;
|
||||
for (int i = 0; i < tests; i++) {
|
||||
testable = new Testable(new Random());
|
||||
for (int i = 0; i < NUM_TESTS; i++) {
|
||||
testable = new Testable(n, t, group, q, rand);
|
||||
oneTest(testable);
|
||||
stopReceivers(testable);
|
||||
}
|
||||
}
|
||||
class Testable{
|
||||
|
||||
static class Testable {
|
||||
Set<Integer> valids;
|
||||
Set<Integer> QUAL;
|
||||
Set<Integer> aborted;
|
||||
Set<Integer> malicious;
|
||||
User<BigInteger>[] sdkgs;
|
||||
Thread[] threads;
|
||||
Future<?>[] futures;
|
||||
BigInteger g;
|
||||
BigInteger h;
|
||||
BigInteger secret;
|
||||
Group<BigInteger> group;
|
||||
int n;
|
||||
int t;
|
||||
BigInteger q;
|
||||
Random random;
|
||||
ChannelImpl channels = new ChannelImpl();
|
||||
|
||||
public Testable(Random random) {
|
||||
public Testable(int n, int t, Group<BigInteger> group, BigInteger q, Random random) {
|
||||
this.n = n;
|
||||
this.t = t;
|
||||
this.group = group;
|
||||
this.q = q;
|
||||
this.random = random;
|
||||
this.sdkgs = new User[n];
|
||||
this.valids = new HashSet<Integer>();
|
||||
this.QUAL = new HashSet<Integer>();
|
||||
this.aborted = new HashSet<Integer>();
|
||||
this.malicious = new HashSet<Integer>();
|
||||
this.threads = new Thread[n];
|
||||
this.futures = new Future[n];
|
||||
this.g = sampleGenerator(random);
|
||||
this.h = group.multiply(g,randomIntModQ(random));
|
||||
ArrayList<Integer> ids = new ArrayList<Integer>();
|
||||
|
@ -123,10 +138,9 @@ public class SDKGTest {
|
|||
while (!ids.isEmpty()) {
|
||||
id = ids.remove(random.nextInt(ids.size()));
|
||||
s = randomIntModQ(random);
|
||||
channel = new ChannelImpl(id,n);
|
||||
channel = channels.getChannel(id);
|
||||
sdkg = new Protocol<BigInteger>(t, n, s, random, q, g , h, group, id,encoder);
|
||||
sdkgs[id - 1] = randomSDKGUser(id,channel,sdkg,random);
|
||||
threads[id - 1] = new Thread(sdkgs[id - 1]);
|
||||
sdkgs[id - 1] = randomSDKGUser(id,channel,sdkg);
|
||||
if(QUAL.contains(id)){
|
||||
this.secret = this.secret.add(s).mod(q);
|
||||
}
|
||||
|
@ -134,33 +148,44 @@ public class SDKGTest {
|
|||
|
||||
}
|
||||
|
||||
public User<BigInteger> randomSDKGUser(int id, Channel channel, Protocol<BigInteger> sdkg, Random random){
|
||||
if (QUAL.size() <= t) {
|
||||
valids.add(id);
|
||||
QUAL.add(id);
|
||||
return new User<BigInteger>(sdkg,channel);
|
||||
}else{
|
||||
int type = random.nextInt(3);
|
||||
switch (type){
|
||||
case 0:// regular
|
||||
valids.add(id);
|
||||
enum UserType {
|
||||
HONEST,
|
||||
FAILSTOP,
|
||||
MALICIOUS,
|
||||
}
|
||||
|
||||
public User<BigInteger> newSDKGUser(int id, Channel channel, Protocol<BigInteger> sdkg, UserType userType) {
|
||||
switch(userType) {
|
||||
case HONEST:
|
||||
valids.add(id);
|
||||
QUAL.add(id);
|
||||
return new User<BigInteger>(sdkg,channel);
|
||||
|
||||
case FAILSTOP:
|
||||
int abortStage = random.nextInt(3) + 1; // 1 or 2 or 3
|
||||
aborted.add(id);
|
||||
if (abortStage > 1){
|
||||
QUAL.add(id);
|
||||
return new User<BigInteger>(sdkg,channel);
|
||||
case 1:// abort
|
||||
int abortStage = random.nextInt(3) + 1; // 1 or 2 or 3
|
||||
aborted.add(id);
|
||||
if (abortStage > 1){
|
||||
QUAL.add(id);
|
||||
}
|
||||
return new SDKGUserImplAbort(sdkg,channel,abortStage);
|
||||
case 2:// malicious
|
||||
malicious.add(id);
|
||||
Set<Integer> falls = DKGMaliciousUser.selectFallsRandomly(valids,random);
|
||||
Protocol<BigInteger> maliciousSDKG = SDKGMaliciousUserImpl.generateMaliciousSDKG(sdkg,channel,random);
|
||||
return new SDKGMaliciousUserImpl(sdkg,maliciousSDKG,channel,falls);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return new SDKGUserImplAbort(sdkg,channel,abortStage);
|
||||
|
||||
case MALICIOUS:
|
||||
malicious.add(id);
|
||||
Set<Integer> falls = DKGMaliciousUser.selectFallsRandomly(valids,random);
|
||||
Protocol<BigInteger> maliciousSDKG = SDKGMaliciousUserImpl.generateMaliciousSDKG(sdkg,channel,random);
|
||||
return new SDKGMaliciousUserImpl(sdkg,maliciousSDKG,channel,falls);
|
||||
|
||||
}
|
||||
fail("Unknown user type");
|
||||
return null;
|
||||
}
|
||||
|
||||
public User<BigInteger> randomSDKGUser(int id, Channel channel, Protocol<BigInteger> sdkg){
|
||||
if (QUAL.size() <= t) {
|
||||
return newSDKGUser(id, channel, sdkg, UserType.HONEST);
|
||||
} else {
|
||||
UserType type = UserType.values()[random.nextInt(UserType.values().length)];
|
||||
return newSDKGUser(id, channel, sdkg, type);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package meerkat.crypto.dkg.gjkr;
|
||||
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import meerkat.crypto.dkg.comm.MessageUtils;
|
||||
import meerkat.crypto.utils.Channel;
|
||||
import meerkat.comm.Channel;
|
||||
import meerkat.protobuf.Comm;
|
||||
import meerkat.protobuf.DKG;
|
||||
|
||||
/**
|
||||
|
@ -9,6 +11,10 @@ import meerkat.protobuf.DKG;
|
|||
*/
|
||||
public class SDKGUserImplAbort<T> extends User<T> {
|
||||
|
||||
public static class AbortException extends RuntimeException {
|
||||
|
||||
}
|
||||
|
||||
final int abortStage;
|
||||
int stage;
|
||||
public SDKGUserImplAbort(Protocol<T> sdkg, Channel channel, int abortStage) {
|
||||
|
@ -20,6 +26,7 @@ public class SDKGUserImplAbort<T> extends User<T> {
|
|||
private void abort(){
|
||||
//stopReceiver();
|
||||
channel.broadcastMessage(MessageUtils.createMessage(DKG.Payload.Type.ABORT));
|
||||
throw new AbortException();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -61,4 +68,13 @@ public class SDKGUserImplAbort<T> extends User<T> {
|
|||
}
|
||||
stage++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
super.run();
|
||||
} catch (AbortException e) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
package meerkat.crypto.utils;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
import meerkat.protobuf.DKG;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
|
||||
/**
|
||||
* Created by Tzlil on 2/14/2016.
|
||||
*/
|
||||
// TODO: Change nane to network
|
||||
|
||||
public class ChannelImpl implements Channel {
|
||||
|
||||
public static int BROADCAST = 0;
|
||||
private static ChannelImpl[] channels = null;
|
||||
|
||||
protected final Queue<DKG.BroadcastMessage> mailbox;
|
||||
protected final int id;
|
||||
protected final int n;
|
||||
protected Thread receiverThread;
|
||||
|
||||
|
||||
public ChannelImpl(int id, int n) {
|
||||
if (channels == null){
|
||||
channels = new ChannelImpl[n];
|
||||
}
|
||||
this.mailbox = new ArrayBlockingQueue<DKG.BroadcastMessage>( n * n * n);
|
||||
this.id = id;
|
||||
this.n = n;
|
||||
channels[id - 1] = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourceId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void sendMessage(int destUser, Message msg) {
|
||||
if(destUser < 1 || destUser > n)
|
||||
return;
|
||||
ChannelImpl channel = channels[destUser - 1];
|
||||
if (channel == null)
|
||||
return;
|
||||
DKG.BroadcastMessage broadcastMessage = DKG.BroadcastMessage.newBuilder()
|
||||
.setSender(id)
|
||||
.setDestination(destUser)
|
||||
.setIsPrivate(true)
|
||||
.setPayload(msg.toByteString())
|
||||
.build();
|
||||
synchronized (channel.mailbox) {
|
||||
channel.mailbox.add(broadcastMessage);
|
||||
channel.mailbox.notify();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void broadcastMessage(Message msg) {
|
||||
ChannelImpl channel;
|
||||
DKG.BroadcastMessage broadcastMessage = DKG.BroadcastMessage.newBuilder()
|
||||
.setSender(id)
|
||||
.setDestination(BROADCAST)
|
||||
.setIsPrivate(false)
|
||||
.setPayload(msg.toByteString())
|
||||
.build();
|
||||
for (int i = 0 ; i < n ; i++){
|
||||
channel = channels[i];
|
||||
synchronized (channel.mailbox) {
|
||||
channel.mailbox.add(broadcastMessage);
|
||||
channel.mailbox.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void stop(){
|
||||
try{
|
||||
receiverThread.interrupt();
|
||||
}catch (Exception e){
|
||||
//do nothing
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerReceiverCallback(final ReceiverCallback callback) {
|
||||
stop();
|
||||
receiverThread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
while (true){
|
||||
try {
|
||||
synchronized (mailbox) {
|
||||
while (!mailbox.isEmpty()) {
|
||||
callback.receiveMail(mailbox.remove());
|
||||
}
|
||||
mailbox.wait();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
//do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
receiverThread.start();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package meerkat.crypto.utils;
|
||||
package meerkat.comm;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
import meerkat.protobuf.DKG;
|
||||
import meerkat.protobuf.Comm;
|
||||
|
||||
/**
|
||||
* A generic communication channel that supports point-to-point and broadcast operation
|
||||
|
@ -15,7 +15,7 @@ public interface Channel {
|
|||
public int getSourceId();
|
||||
|
||||
public interface ReceiverCallback {
|
||||
public void receiveMail(DKG.BroadcastMessage envelope);
|
||||
public void receiveMessage(Comm.BroadcastMessage envelope);
|
||||
}
|
||||
|
||||
/**
|
|
@ -0,0 +1,13 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package meerkat;
|
||||
|
||||
option java_package = "meerkat.protobuf";
|
||||
|
||||
message BroadcastMessage {
|
||||
int32 sender = 1;
|
||||
int32 destination = 2;
|
||||
bool is_private = 3;
|
||||
|
||||
bytes payload = 5;
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
package meerkat.comm;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
import com.google.protobuf.TextFormat;
|
||||
import meerkat.protobuf.Comm;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
* Created by Tzlil on 2/14/2016.
|
||||
*/
|
||||
// TODO: Change nane to network
|
||||
|
||||
public class ChannelImpl {
|
||||
final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
//private ExecutorService executorService = Executors.newCachedThreadPool();
|
||||
public static int BROADCAST = 0;
|
||||
Map<Integer,SingleChannel> channels = new TreeMap<>();
|
||||
|
||||
|
||||
public ChannelImpl() {
|
||||
}
|
||||
|
||||
public Channel getChannel(int id) {
|
||||
return new SingleChannel(id);
|
||||
}
|
||||
|
||||
public class SingleChannel implements Channel {
|
||||
protected final int id;
|
||||
|
||||
ReceiverCallback callback;
|
||||
|
||||
SingleChannel(int id) {
|
||||
this.id = id;
|
||||
channels.put(id, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourceId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void sendMessage(int destUser, Message msg) {
|
||||
if (destUser < 1)
|
||||
return;
|
||||
SingleChannel channel = channels.get(destUser);
|
||||
if (channel == null) {
|
||||
logger.warn("Party {} attempting to send message to non-existing party {}", getSourceId(), destUser);
|
||||
return;
|
||||
}
|
||||
Comm.BroadcastMessage broadcastMessage = Comm.BroadcastMessage.newBuilder()
|
||||
.setSender(id)
|
||||
.setDestination(destUser)
|
||||
.setIsPrivate(true)
|
||||
.setPayload(msg.toByteString())
|
||||
.build();
|
||||
|
||||
logger.debug("sending Message: Dst={},Src={} [{}]", broadcastMessage.getDestination(),
|
||||
broadcastMessage.getSender(), TextFormat.printToString(msg));
|
||||
|
||||
channel.callback.receiveMessage(broadcastMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void broadcastMessage(Message msg) {
|
||||
Comm.BroadcastMessage broadcastMessage = Comm.BroadcastMessage.newBuilder()
|
||||
.setSender(id)
|
||||
.setDestination(BROADCAST)
|
||||
.setIsPrivate(false)
|
||||
.setPayload(msg.toByteString())
|
||||
.build();
|
||||
|
||||
logger.debug("broadcasting Message: Src={} [{}]",
|
||||
broadcastMessage.getSender(), TextFormat.printToString(msg));
|
||||
|
||||
for (SingleChannel channel : channels.values()) {
|
||||
channel.callback.receiveMessage(broadcastMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerReceiverCallback(final ReceiverCallback callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue