secure dkg without stage 4
parent
a233f2f713
commit
210cc327ac
|
@ -0,0 +1,43 @@
|
||||||
|
package Communication;
|
||||||
|
|
||||||
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
|
import meerkat.protobuf.DKGMessages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Tzlil on 2/14/2016.
|
||||||
|
*/
|
||||||
|
public class MailHandler {
|
||||||
|
|
||||||
|
private MessageHandler messageHandler;
|
||||||
|
|
||||||
|
public MailHandler(MessageHandler messageHandler){
|
||||||
|
this.messageHandler = messageHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageHandler getMessageHandler(){
|
||||||
|
return messageHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handel(DKGMessages.Mail mail) throws InvalidProtocolBufferException {
|
||||||
|
switch (mail.getType()){
|
||||||
|
case SECRET:
|
||||||
|
DKGMessages.SecretMessage secretMessage = DKGMessages.SecretMessage.parseFrom(mail.getMessage());
|
||||||
|
messageHandler.handelSecretMessage(mail.getSender(),mail.getDestination()== Network.BROADCAST,secretMessage);
|
||||||
|
break;
|
||||||
|
case COMMITMENT:
|
||||||
|
DKGMessages.CommitmentMessage commitmentMessage = DKGMessages.CommitmentMessage.parseFrom(mail.getMessage());
|
||||||
|
messageHandler.handelCommitmentMessage(mail.getSender(),mail.getDestination()== Network.BROADCAST,commitmentMessage);
|
||||||
|
break;
|
||||||
|
case DONE:
|
||||||
|
DKGMessages.DoneMessage doneMessage = DKGMessages.DoneMessage.parseFrom(mail.getMessage());
|
||||||
|
messageHandler.handelDoneMessage(mail.getSender(),mail.getDestination()== Network.BROADCAST,doneMessage);
|
||||||
|
break;
|
||||||
|
case COMPLAINT:
|
||||||
|
DKGMessages.ComplaintMessage complaintMessage = DKGMessages.ComplaintMessage.parseFrom(mail.getMessage());
|
||||||
|
messageHandler.handelComplaintMessage(mail.getSender(),mail.getDestination()== Network.BROADCAST,complaintMessage);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package Communication;
|
||||||
|
|
||||||
|
import meerkat.protobuf.DKGMessages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Tzlil on 2/14/2016.
|
||||||
|
*/
|
||||||
|
public interface MessageHandler {
|
||||||
|
void handelComplaintMessage(int sender, boolean isBroadcast,DKGMessages.ComplaintMessage complaintMessage);
|
||||||
|
void handelDoneMessage(int sender, boolean isBroadcast, DKGMessages.DoneMessage doneMessage);
|
||||||
|
void handelCommitmentMessage(int sender, boolean isBroadcast,DKGMessages.CommitmentMessage commitmentMessage);
|
||||||
|
void handelSecretMessage(int sender, boolean isBroadcast,DKGMessages.SecretMessage secretMessage);
|
||||||
|
void handelDoubleSecretMessage(int sender, boolean isBroadcast,DKGMessages.DoubleSecretMessage doubleSecretMessage);
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
package Communication;
|
||||||
|
|
||||||
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
|
import com.google.protobuf.Message;
|
||||||
|
import meerkat.protobuf.DKGMessages.*;
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
|
/**
|
||||||
|
* Created by Tzlil on 2/7/2016.
|
||||||
|
* JointFeldamn protocol assumes all parties can communicate throw broadcast chanel
|
||||||
|
* and private chanel (for each pair)
|
||||||
|
* this class simulates it
|
||||||
|
*/
|
||||||
|
public class Network {
|
||||||
|
|
||||||
|
protected final User[] users;
|
||||||
|
protected final int n;
|
||||||
|
protected final Queue<Integer> availableIDs;
|
||||||
|
public static final int BROADCAST = 0;
|
||||||
|
|
||||||
|
|
||||||
|
public Network(int n) {
|
||||||
|
this.n = n;
|
||||||
|
this.users = new User[n];
|
||||||
|
this.availableIDs = new ArrayBlockingQueue<Integer>(n);
|
||||||
|
for (int id = 1; id <= n; id++){
|
||||||
|
availableIDs.add(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public User connect(MessageHandler messageHandler){
|
||||||
|
Integer id = availableIDs.poll();
|
||||||
|
if (id == null)
|
||||||
|
return null;
|
||||||
|
users[id - 1] = new User(id,this,new MailHandler(messageHandler));
|
||||||
|
return users[id - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean sendMessage(User sender,int destination,Mail.Type type,Message message){
|
||||||
|
if(destination < 1 || destination > n)
|
||||||
|
return false;
|
||||||
|
User user = users[destination - 1];
|
||||||
|
if (user == null)
|
||||||
|
return false;
|
||||||
|
Mail mail = Mail.newBuilder()
|
||||||
|
.setSender(sender.getID())
|
||||||
|
.setDestination(destination)
|
||||||
|
.setIsPrivate(true)
|
||||||
|
.setType(type)
|
||||||
|
.setMessage(message.toByteString())
|
||||||
|
.build();
|
||||||
|
return user.mailbox.add(mail);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void sendBroadcast(User sender,Mail.Type type,Message message){
|
||||||
|
User user;
|
||||||
|
Mail mail = Mail.newBuilder()
|
||||||
|
.setSender(sender.getID())
|
||||||
|
.setDestination(BROADCAST)
|
||||||
|
.setIsPrivate(false)
|
||||||
|
.setType(type)
|
||||||
|
.setMessage(message.toByteString())
|
||||||
|
.build();
|
||||||
|
for (int i = 0 ; i < n ; i++){
|
||||||
|
user = users[i];
|
||||||
|
user.mailbox.add(mail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package Communication;
|
||||||
|
|
||||||
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
|
import com.google.protobuf.Message;
|
||||||
|
import meerkat.protobuf.DKGMessages;
|
||||||
|
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Tzlil on 2/14/2016.
|
||||||
|
*/
|
||||||
|
public class User{
|
||||||
|
protected final MailHandler mailHandler;
|
||||||
|
protected final Queue<DKGMessages.Mail> mailbox;
|
||||||
|
protected final int ID;
|
||||||
|
protected final Thread receiverThread;
|
||||||
|
private final Network network;
|
||||||
|
|
||||||
|
protected User(int ID, Network network, MailHandler mailHandler) {
|
||||||
|
this.mailbox = new ArrayBlockingQueue<DKGMessages.Mail>(2 * network.n * network.n);
|
||||||
|
this.ID = ID;
|
||||||
|
this.mailHandler = mailHandler;
|
||||||
|
this.receiverThread = new Thread(new Receiver());
|
||||||
|
this.network = network;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean send(int id, DKGMessages.Mail.Type type, Message message){
|
||||||
|
return network.sendMessage(this,id,type,message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void broadcast(DKGMessages.Mail.Type type, Message message){
|
||||||
|
network.sendBroadcast(this,type,message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageHandler getMessageHandler(){
|
||||||
|
return mailHandler.getMessageHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getID() {
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
public Thread getReceiverThread(){
|
||||||
|
return receiverThread;
|
||||||
|
}
|
||||||
|
private class Receiver implements Runnable{
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (true){
|
||||||
|
if (!mailbox.isEmpty()){
|
||||||
|
try {
|
||||||
|
mailHandler.handel(mailbox.poll());
|
||||||
|
} catch (InvalidProtocolBufferException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
try {
|
||||||
|
Thread.sleep(30);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,9 +1,12 @@
|
||||||
package FeldmanVerifiableSecretSharing;
|
package FeldmanVerifiableSecretSharing;
|
||||||
|
|
||||||
import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial;
|
import Communication.Network;
|
||||||
import FeldmanVerifiableSecretSharing.ShamirSecretSharing.SecretSharing;
|
import Communication.User;
|
||||||
import org.bouncycastle.util.Arrays;
|
import ShamirSecretSharing.Polynomial;
|
||||||
import org.factcenter.qilin.primitives.CyclicGroup;
|
import ShamirSecretSharing.SecretSharing;
|
||||||
|
import com.google.protobuf.ByteString;
|
||||||
|
import meerkat.protobuf.DKGMessages;
|
||||||
|
import java.util.Arrays;
|
||||||
import org.factcenter.qilin.primitives.concrete.Zpstar;
|
import org.factcenter.qilin.primitives.concrete.Zpstar;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
@ -21,8 +24,7 @@ public class VerifiableSecretSharing extends SecretSharing {
|
||||||
protected final Zpstar zpstar;
|
protected final Zpstar zpstar;
|
||||||
protected final BigInteger g; // public generator of group
|
protected final BigInteger g; // public generator of group
|
||||||
private final BigInteger y; // y = g ^ x
|
private final BigInteger y; // y = g ^ x
|
||||||
private final BigInteger[] commitments;
|
protected final BigInteger[] commitments;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param p a large prime
|
* @param p a large prime
|
||||||
* @param q a large prime dividing p - 1.
|
* @param q a large prime dividing p - 1.
|
||||||
|
@ -30,8 +32,9 @@ public class VerifiableSecretSharing extends SecretSharing {
|
||||||
* the generated group is a subgroup of Zp*.
|
* the generated group is a subgroup of Zp*.
|
||||||
* it must be chosen such that computing discrete logarithms is hard in this group.
|
* it must be chosen such that computing discrete logarithms is hard in this group.
|
||||||
*/
|
*/
|
||||||
public VerifiableSecretSharing(int t, int n, BigInteger x, Random random,BigInteger p,BigInteger q,BigInteger g) {
|
public VerifiableSecretSharing(int t, int n, BigInteger x, Random random, BigInteger p, BigInteger q, BigInteger g
|
||||||
super(t, n, x, random,q);
|
, User user) {
|
||||||
|
super(t, n, x, random,q,user);
|
||||||
this.g = g;
|
this.g = g;
|
||||||
this.zpstar = new Zpstar(p);
|
this.zpstar = new Zpstar(p);
|
||||||
assert (zpstar.contains(g));
|
assert (zpstar.contains(g));
|
||||||
|
@ -40,6 +43,11 @@ public class VerifiableSecretSharing extends SecretSharing {
|
||||||
this.y = zpstar.multiply(g,x);
|
this.y = zpstar.multiply(g,x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public VerifiableSecretSharing(int t, int n, BigInteger x, Random random, BigInteger p, BigInteger q, BigInteger g
|
||||||
|
, Network network) {
|
||||||
|
this(t,n,x,random,p,q,g,network.connect(new VerifiableSecretSharingMessageHandler(t)));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return commitments[i] = g ^ polynomial.coefficients[i]
|
* @return commitments[i] = g ^ polynomial.coefficients[i]
|
||||||
*/
|
*/
|
||||||
|
@ -102,6 +110,30 @@ public class VerifiableSecretSharing extends SecretSharing {
|
||||||
* @return copy of commitments
|
* @return copy of commitments
|
||||||
*/
|
*/
|
||||||
public BigInteger[] getCommitments() {
|
public BigInteger[] getCommitments() {
|
||||||
return Arrays.clone(commitments);
|
return Arrays.copyOf(commitments,commitments.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DKGMessages.CommitmentMessage[] prepareCommitmentMessages(){
|
||||||
|
DKGMessages.CommitmentMessage[] commitmentMessages = new DKGMessages.CommitmentMessage[t + 1];
|
||||||
|
for (int k = 0; k <= t ; k ++) {
|
||||||
|
commitmentMessages[k] = DKGMessages.CommitmentMessage.newBuilder()
|
||||||
|
.setK(k)
|
||||||
|
.setCommitment(ByteString.copyFrom(commitments[k].toByteArray()))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
return commitmentMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void computeAndSendCommitments(){
|
||||||
|
DKGMessages.CommitmentMessage[] commitmentMessages = prepareCommitmentMessages();
|
||||||
|
for (int k = 0; k <= t ; k ++){
|
||||||
|
user.broadcast(DKGMessages.Mail.Type.COMMITMENT,commitmentMessages[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
super.run();
|
||||||
|
computeAndSendCommitments();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
package FeldmanVerifiableSecretSharing;
|
||||||
|
|
||||||
|
import Communication.Network;
|
||||||
|
import ShamirSecretSharing.SecretSharingMessageHandler;
|
||||||
|
import meerkat.protobuf.DKGMessages;
|
||||||
|
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Tzlil on 2/16/2016.
|
||||||
|
*/
|
||||||
|
public class VerifiableSecretSharingMessageHandler extends SecretSharingMessageHandler {
|
||||||
|
|
||||||
|
private final BigInteger[] commitments;
|
||||||
|
|
||||||
|
public VerifiableSecretSharingMessageHandler(int t) {
|
||||||
|
this.commitments = new BigInteger[t + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BigInteger extractCommitment(DKGMessages.CommitmentMessage commitmentMessage){
|
||||||
|
return new BigInteger(commitmentMessage.getCommitment().toByteArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handelCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage) {
|
||||||
|
if(isBroadcast) { // receive in broadcast only
|
||||||
|
commitments[commitmentMessage.getK()] = extractCommitment(commitmentMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigInteger[] getCommitments() {
|
||||||
|
return commitments;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigInteger getY(){
|
||||||
|
return commitments[0];
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,362 +0,0 @@
|
||||||
package JointFeldmanProtocol;
|
|
||||||
|
|
||||||
import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial;
|
|
||||||
import FeldmanVerifiableSecretSharing.VerifiableSecretSharing;
|
|
||||||
import com.google.protobuf.ByteString;
|
|
||||||
import com.google.protobuf.InvalidProtocolBufferException;
|
|
||||||
import org.bouncycastle.util.Arrays;
|
|
||||||
import meerkat.protobuf.DKGMessages.*;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Tzlil on 2/5/2016.
|
|
||||||
*
|
|
||||||
* an implementation of a version of Pedersen's distributed key generation protocol
|
|
||||||
*/
|
|
||||||
public class DKG extends VerifiableSecretSharing implements Runnable{
|
|
||||||
|
|
||||||
private final int id;
|
|
||||||
private final Network.User user; // send and receive messages throw network
|
|
||||||
|
|
||||||
private final BigInteger[] ys; // container for y values that
|
|
||||||
private final Polynomial.Point[] shares; // shares[i] equivalent to Si,id in terms of the protocol
|
|
||||||
private final BigInteger[][] commitmentsArray; // commitmentsArray[i] equivalent to Ai in terms of the protocol
|
|
||||||
private final ComplainState[][] complainStates; // complainStates[i][j] == state of Pj's complaint against Pi
|
|
||||||
|
|
||||||
private final Set<Integer> QUAL; // set of all non-disqualified parties
|
|
||||||
private final BigInteger[] commitments; // public verification values
|
|
||||||
private Polynomial.Point share; // final share of the secrete
|
|
||||||
private BigInteger y; // final public value
|
|
||||||
|
|
||||||
|
|
||||||
public DKG(int t, int n, BigInteger x, Random random, BigInteger p, BigInteger q, BigInteger g,Network network) {
|
|
||||||
super(t, n, x, random, p, q, g);
|
|
||||||
|
|
||||||
this.commitmentsArray = new BigInteger[n][t + 1];
|
|
||||||
this.shares = new Polynomial.Point[n];
|
|
||||||
this.user = network.connect(new Handler());
|
|
||||||
this.id = user.getID();
|
|
||||||
this.complainStates = new ComplainState[n][n];
|
|
||||||
this.QUAL = new HashSet<Integer>();
|
|
||||||
this.ys = new BigInteger[n];
|
|
||||||
this.commitments = new BigInteger[t + 1];
|
|
||||||
|
|
||||||
for (int i = 0; i < n; i ++){
|
|
||||||
for (int j = 0 ; j < n ; j ++)
|
|
||||||
complainStates[i][j] = ComplainState.Non;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* use for simulate real distributed protocol
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
user.getReceiverThread().start();
|
|
||||||
stage1();
|
|
||||||
stage2();
|
|
||||||
stage3();
|
|
||||||
stage4();
|
|
||||||
user.getReceiverThread().interrupt();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* stage1 according to the protocol
|
|
||||||
* 1. Pi broadcasts Aik for k = 0,...,t.
|
|
||||||
* 2. Pi computes the shares Sij for j = 1,...,n and sends Sij secretly to Pj.
|
|
||||||
*/
|
|
||||||
private void stage1(){
|
|
||||||
// for avoiding edge cases, sets commitmentsArray[id - 1]
|
|
||||||
BigInteger[] commitments = super.getCommitments();
|
|
||||||
System.arraycopy(commitments, 0, commitmentsArray[id - 1], 0, commitmentsArray[id - 1].length);
|
|
||||||
|
|
||||||
// broadcasts commitments
|
|
||||||
CommitmentMessage commitment;
|
|
||||||
for (int k = 0; k <= t ; k ++){
|
|
||||||
commitment = CommitmentMessage.newBuilder()
|
|
||||||
.setK(k)
|
|
||||||
.setCommitment(ByteString.copyFrom(commitmentsArray[id - 1][k].toByteArray()))
|
|
||||||
.build();
|
|
||||||
user.broadcast(Mail.Type.COMMITMENT,commitment);
|
|
||||||
}
|
|
||||||
|
|
||||||
// computes and sends shares
|
|
||||||
SecretMessage secret;
|
|
||||||
for (int j = 1; j <= n ; j++ ){
|
|
||||||
if(j != id){
|
|
||||||
secret = SecretMessage.newBuilder()
|
|
||||||
.setSecret(getShare(j).asMessage())
|
|
||||||
.build();
|
|
||||||
user.send(j, Mail.Type.SECRET,secret);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
shares[id - 1] = super.getShare(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (!isStage1Complete()){
|
|
||||||
try {
|
|
||||||
Thread.sleep(300);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true iff all shares and commitments were received
|
|
||||||
*/
|
|
||||||
private boolean isStage1Complete(){
|
|
||||||
for (int i = 1 ; i <= n ; i++){
|
|
||||||
if(shares[i - 1] == null)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < commitmentsArray.length; i++){
|
|
||||||
for (int j = 0; j < commitmentsArray[i].length; j++){
|
|
||||||
if(commitmentsArray[i][j] == null)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param secret
|
|
||||||
* @param i
|
|
||||||
* @return g ^ Sij == verify(j,Ai,zpstar) (mod p)
|
|
||||||
*/
|
|
||||||
private boolean isValidSecret(Polynomial.Point secret, int i){
|
|
||||||
int j = secret.x.intValue();
|
|
||||||
return zpstar.multiply(g,secret.y).equals(verify(j,commitmentsArray[i - 1],zpstar));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* stage2 according to the protocol
|
|
||||||
* Pj verifies all the shares he received (using isValidSecret)
|
|
||||||
* if check fails for an index i, Pj broadcasts a complaint against Pi.
|
|
||||||
* Pj broadcasts yj value at the end of this stage
|
|
||||||
*/
|
|
||||||
private void stage2(){
|
|
||||||
ys[id - 1] = super.getY();
|
|
||||||
ComplaintMessage complaint;
|
|
||||||
for (int i = 1; i <= n ; i++ ){
|
|
||||||
if(id != i && !isValidSecret(shares[i - 1],i)) {
|
|
||||||
//message = new Message(Type.Complaint, j)
|
|
||||||
complaint = ComplaintMessage.newBuilder()
|
|
||||||
.setId(i)
|
|
||||||
.build();
|
|
||||||
user.broadcast(Mail.Type.COMPLAINT,complaint);
|
|
||||||
complainStates[i - 1][id - 1] = ComplainState.Waiting;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//broadcast y after all complaints
|
|
||||||
YMessage yMessage = YMessage.newBuilder()
|
|
||||||
.setY(ByteString.copyFrom(super.getY().toByteArray()))
|
|
||||||
.build();
|
|
||||||
user.broadcast(Mail.Type.Y,yMessage);
|
|
||||||
|
|
||||||
while (!isStage2Complete()){
|
|
||||||
try {
|
|
||||||
Thread.sleep(300);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true iff all yi received for i = 1,...,n .
|
|
||||||
*/
|
|
||||||
private boolean isStage2Complete() {
|
|
||||||
for (int j = 1; j <= n ; j++) {
|
|
||||||
if (j != id && ys[j - 1] == null)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* stage3 according to the protocol
|
|
||||||
* 1. if more than t players complain against a player Pi he is disqualified.
|
|
||||||
* 2. Pi broadcasts the share Sij for each complaining player Pj.
|
|
||||||
* 3. if any of the revealed shares fails the verification test, player Pi is disqualified.
|
|
||||||
* 4. set QUAL to be the set of non-disqualified players.
|
|
||||||
*/
|
|
||||||
private void stage3(){
|
|
||||||
|
|
||||||
// broadcasts Sij for each complaint against Pid
|
|
||||||
for (int j = 1 ; j <= complainStates[id - 1].length;j++) {
|
|
||||||
switch (complainStates[id - 1][j - 1]) {
|
|
||||||
case Waiting:
|
|
||||||
user.broadcast(Mail.Type.SECRET, SecretMessage.newBuilder()
|
|
||||||
.setSecret(getShare(j).asMessage())
|
|
||||||
.build());
|
|
||||||
complainStates[id - 1][j - 1] = ComplainState.NonDisqualified;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait until there is no complaint waiting for answer
|
|
||||||
for (int i = 0; i < complainStates.length;i++){
|
|
||||||
for (int j = 0 ; j < complainStates[i].length;j++){
|
|
||||||
while (complainStates[i][j].equals(ComplainState.Waiting)){
|
|
||||||
try {
|
|
||||||
Thread.sleep(300);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// add each non-disqualified player to QUAL
|
|
||||||
boolean nonDisqualified;
|
|
||||||
for (int i = 1; i <= complainStates.length;i++){
|
|
||||||
nonDisqualified = true;
|
|
||||||
for (int j = 1 ; j <= complainStates[i - 1].length;j++){
|
|
||||||
nonDisqualified &= complainStates[i - 1][j - 1].equals(ComplainState.Disqualified);
|
|
||||||
}
|
|
||||||
if(nonDisqualified){
|
|
||||||
QUAL.add(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* stage4 according to the protocol
|
|
||||||
* 1. public value y is computed as y = multiplication of yi mod p for i in QUAL
|
|
||||||
* 2. public verification values are computed as Ak = multiplication of Aik mod p for i in QUAL for k = 0,...,t
|
|
||||||
* 3. Pj sets is share of the secret as xj = sum of Sij mod q for i in QUAL
|
|
||||||
*/
|
|
||||||
private void stage4(){
|
|
||||||
this.y = zpstar.zero();
|
|
||||||
for (int i : QUAL) {
|
|
||||||
this.y = zpstar.add(this.y , ys[i - 1]);
|
|
||||||
}
|
|
||||||
BigInteger commitment;
|
|
||||||
for (int k = 0; k <= t ; k++){
|
|
||||||
commitment = zpstar.zero();
|
|
||||||
for (int i : QUAL) {
|
|
||||||
commitment = zpstar.add(commitment,commitmentsArray[i - 1][k]);
|
|
||||||
}
|
|
||||||
commitments[k] = commitment;
|
|
||||||
}
|
|
||||||
|
|
||||||
BigInteger xj = BigInteger.ZERO;
|
|
||||||
for (int i : QUAL) {
|
|
||||||
xj = xj.add(shares[i - 1].y);
|
|
||||||
}
|
|
||||||
this.share = new Polynomial.Point(BigInteger.valueOf(id) , xj.mod(q));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BigInteger getY() {
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BigInteger[] getCommitments() {
|
|
||||||
return Arrays.clone(commitments);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private enum ComplainState{
|
|
||||||
Non, Waiting,Disqualified,NonDisqualified
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Handler implements Network.MailHandler {
|
|
||||||
|
|
||||||
private Handler() {}
|
|
||||||
|
|
||||||
void handelSecretMessage(Mail mail) throws InvalidProtocolBufferException {
|
|
||||||
if(shares[mail.getSender() - 1] == null) {
|
|
||||||
SecretMessage secretMessage = SecretMessage.parseFrom(mail.getMessage());
|
|
||||||
Polynomial.Point secret = new Polynomial.Point(secretMessage.getSecret());
|
|
||||||
if(mail.getIsPrivate()){
|
|
||||||
shares[mail.getSender() - 1] = secret;
|
|
||||||
}else{
|
|
||||||
int i = mail.getSender();
|
|
||||||
int j = secret.x.intValue();
|
|
||||||
switch (complainStates[i - 1][j - 1]){
|
|
||||||
case Waiting:
|
|
||||||
if(isValidSecret(secret,i)){
|
|
||||||
complainStates[i - 1][j - 1] = ComplainState.NonDisqualified;
|
|
||||||
}else{
|
|
||||||
complainStates[i - 1][j - 1] = ComplainState.Disqualified;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void handelCommitmentMessage(Mail mail) throws InvalidProtocolBufferException {
|
|
||||||
if(!mail.getIsPrivate()) { //broadcast only
|
|
||||||
CommitmentMessage commitmentMessage = CommitmentMessage.parseFrom(mail.getMessage());
|
|
||||||
if (commitmentsArray[mail.getSender() - 1][commitmentMessage.getK()] == null) {
|
|
||||||
BigInteger commitment = new BigInteger(commitmentMessage.getCommitment().toByteArray());
|
|
||||||
commitmentsArray[mail.getSender() - 1][commitmentMessage.getK()] = commitment;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void handelYMessage(Mail mail) throws InvalidProtocolBufferException {
|
|
||||||
if(!mail.getIsPrivate()) { //broadcast only
|
|
||||||
if (ys[mail.getSender() - 1] == null) {
|
|
||||||
YMessage yMessage = YMessage.parseFrom(mail.getMessage());
|
|
||||||
BigInteger y = new BigInteger(yMessage.getY().toByteArray());
|
|
||||||
ys[mail.getSender() - 1] = y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void handelComplaintMessage(Mail mail) throws InvalidProtocolBufferException {
|
|
||||||
int id = user.getID();
|
|
||||||
if(!mail.getIsPrivate()) { //broadcast only
|
|
||||||
ComplaintMessage complaintMessage = ComplaintMessage.parseFrom(mail.getMessage());
|
|
||||||
int i = complaintMessage.getId();
|
|
||||||
int j = mail.getSender();
|
|
||||||
switch (complainStates[i - 1][j - 1]){
|
|
||||||
case Non:
|
|
||||||
complainStates[i - 1][j - 1] = ComplainState.Waiting;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handel(Mail mail) throws InvalidProtocolBufferException {
|
|
||||||
switch (mail.getType()){
|
|
||||||
case SECRET:
|
|
||||||
handelSecretMessage(mail);
|
|
||||||
break;
|
|
||||||
case COMMITMENT:
|
|
||||||
handelCommitmentMessage(mail);
|
|
||||||
break;
|
|
||||||
case Y:
|
|
||||||
handelYMessage(mail);
|
|
||||||
break;
|
|
||||||
case COMPLAINT:
|
|
||||||
handelComplaintMessage(mail);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,216 @@
|
||||||
|
package JointFeldmanProtocol;
|
||||||
|
|
||||||
|
import Communication.Network;
|
||||||
|
import Communication.User;
|
||||||
|
import ShamirSecretSharing.Polynomial;
|
||||||
|
import FeldmanVerifiableSecretSharing.VerifiableSecretSharing;
|
||||||
|
import meerkat.protobuf.DKGMessages.*;
|
||||||
|
import org.factcenter.qilin.primitives.concrete.Zpstar;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Tzlil on 2/5/2016.
|
||||||
|
*
|
||||||
|
* an implementation of a version of Pedersen's distributed key generation protocol
|
||||||
|
*/
|
||||||
|
public class DistributedKeyGeneration extends VerifiableSecretSharing implements Runnable{
|
||||||
|
|
||||||
|
private final int id;
|
||||||
|
|
||||||
|
private final Set<Integer> QUAL; // set of all non-disqualified parties
|
||||||
|
private final BigInteger[] finalCommitments; // public verification values
|
||||||
|
|
||||||
|
private Polynomial.Point share; // final share of the secrete
|
||||||
|
private BigInteger y; // final public value
|
||||||
|
|
||||||
|
private final DistributedKeyGenerationMessageHandler handler;
|
||||||
|
|
||||||
|
public DistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger p, BigInteger q, BigInteger g
|
||||||
|
, User user) {
|
||||||
|
super(t, n, zi, random, p, q, g,user);
|
||||||
|
this.handler = (DistributedKeyGenerationMessageHandler) user.getMessageHandler();
|
||||||
|
this.id = user.getID();
|
||||||
|
this.QUAL = new HashSet<Integer>();
|
||||||
|
this.finalCommitments = new BigInteger[t + 1];
|
||||||
|
Arrays.fill(this.finalCommitments,zpstar.zero());
|
||||||
|
}
|
||||||
|
public DistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger p, BigInteger q, BigInteger g
|
||||||
|
, Network network) {
|
||||||
|
this(t,n,zi,random,p,q,g,network.connect(new DistributedKeyGenerationMessageHandler(t,n,g,new Zpstar(p))));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* use for simulate real distributed protocol
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
user.getReceiverThread().start();
|
||||||
|
stage1();
|
||||||
|
stage2();
|
||||||
|
stage3();
|
||||||
|
stage4();
|
||||||
|
user.getReceiverThread().interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stage1 according to the protocol
|
||||||
|
* 1. Pi broadcasts Aik for k = 0,...,t.
|
||||||
|
* 2. Pi computes the shares Sij for j = 1,...,n and sends Sij secretly to Pj.
|
||||||
|
*/
|
||||||
|
protected void stage1(){
|
||||||
|
super.run();
|
||||||
|
while (!handler.isStage1Complete()){
|
||||||
|
try {
|
||||||
|
Thread.sleep(300);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stage2 according to the protocol
|
||||||
|
* Pj verifies all the shares he received (using isValidSecret)
|
||||||
|
* if check fails for an index i, Pj broadcasts a complaint against Pi.
|
||||||
|
* Pj broadcasts yj value at the end of this stage
|
||||||
|
*/
|
||||||
|
private void stage2(){
|
||||||
|
ComplaintMessage complaint;
|
||||||
|
for (int i = 1; i <= n ; i++ ){
|
||||||
|
if(id != i && !handler.isValidSecret(i)) {
|
||||||
|
//message = new Message(Type.Complaint, j)
|
||||||
|
complaint = ComplaintMessage.newBuilder()
|
||||||
|
.setId(i)
|
||||||
|
.build();
|
||||||
|
user.broadcast(Mail.Type.COMPLAINT,complaint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//broadcast done message after all complaints
|
||||||
|
DoneMessage doneMessage = DoneMessage.newBuilder().build();
|
||||||
|
user.broadcast(Mail.Type.DONE,doneMessage);
|
||||||
|
|
||||||
|
while (!handler.isStage2Complete()){
|
||||||
|
try {
|
||||||
|
Thread.sleep(300);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected void answerComplaint(int j){
|
||||||
|
user.broadcast(Mail.Type.SECRET, SecretMessage.newBuilder()
|
||||||
|
.setSecret(getShare(j).asMessage())
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* stage3 according to the protocol
|
||||||
|
* 1. if more than t players complain against a player Pi he is disqualified.
|
||||||
|
* 2. Pi broadcasts the share Sij for each complaining player Pj.
|
||||||
|
* 3. if any of the revealed shares fails the verification test, player Pi is disqualified.
|
||||||
|
* 4. set QUAL to be the set of non-disqualified players.
|
||||||
|
*/
|
||||||
|
private void stage3(){
|
||||||
|
DistributedKeyGenerationMessageHandler.ComplainState[][] complainStates = handler.getComplainStates();
|
||||||
|
// broadcasts Sij for each complaint against Pid
|
||||||
|
for (int j = 1; j <= complainStates[id - 1].length; j++) {
|
||||||
|
switch (complainStates[id - 1][j - 1]) {
|
||||||
|
case Waiting:
|
||||||
|
answerComplaint(j);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait until there is no complaint waiting for answer
|
||||||
|
for (int i = 0; i < complainStates.length; i++){
|
||||||
|
for (int j = 0; j < complainStates[i].length; j++){
|
||||||
|
while (complainStates[i][j].equals(DistributedKeyGenerationMessageHandler.ComplainState.Waiting)){
|
||||||
|
try {
|
||||||
|
Thread.sleep(300);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add each non-disqualified player to QUAL
|
||||||
|
boolean nonDisqualified;
|
||||||
|
int counter;
|
||||||
|
for (int i = 1; i <= complainStates.length; i++){
|
||||||
|
nonDisqualified = true;
|
||||||
|
counter = 0;
|
||||||
|
for (int j = 1; j <= complainStates[i - 1].length; j++){
|
||||||
|
switch (complainStates[i - 1][j - 1]) {
|
||||||
|
case Non:
|
||||||
|
break;
|
||||||
|
case NonDisqualified:
|
||||||
|
counter++;
|
||||||
|
default:
|
||||||
|
nonDisqualified = false;
|
||||||
|
}
|
||||||
|
if(!nonDisqualified)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(nonDisqualified && counter <= t){
|
||||||
|
QUAL.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stage4 according to the protocol
|
||||||
|
* 1. public value y is computed as y = multiplication of yi mod p for i in QUAL
|
||||||
|
* 2. public verification values are computed as Ak = multiplication of Aik mod p for i in QUAL for k = 0,...,t
|
||||||
|
* 3. Pj sets is share of the secret as xj = sum of Sij mod q for i in QUAL
|
||||||
|
*/
|
||||||
|
private void stage4(){
|
||||||
|
this.y = zpstar.zero();
|
||||||
|
for (int i : QUAL) {
|
||||||
|
this.y = zpstar.add(this.y , handler.getY(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInteger[] commitments;
|
||||||
|
|
||||||
|
for (int i : QUAL) {
|
||||||
|
commitments = handler.getCommitments(i);
|
||||||
|
for (int k = 0; k <= t; k++){
|
||||||
|
this.finalCommitments[k] = zpstar.add(this.finalCommitments[k],commitments[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInteger xj = BigInteger.ZERO;
|
||||||
|
for (int i : QUAL) {
|
||||||
|
if( i == id){
|
||||||
|
xj = xj.add(super.getShare(i).y);
|
||||||
|
}else{
|
||||||
|
xj = xj.add(handler.getShare(i).y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.share = new Polynomial.Point(BigInteger.valueOf(id) , xj.mod(q));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BigInteger getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BigInteger[] getCommitments() {
|
||||||
|
return Arrays.copyOf(finalCommitments, finalCommitments.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Polynomial.Point getShare() {
|
||||||
|
return share;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,161 @@
|
||||||
|
package JointFeldmanProtocol;
|
||||||
|
|
||||||
|
import Communication.MessageHandler;
|
||||||
|
import Communication.Network;
|
||||||
|
import FeldmanVerifiableSecretSharing.VerifiableSecretSharing;
|
||||||
|
import FeldmanVerifiableSecretSharing.VerifiableSecretSharingMessageHandler;
|
||||||
|
import ShamirSecretSharing.Polynomial;
|
||||||
|
import ShamirSecretSharing.SecretSharingMessageHandler;
|
||||||
|
import meerkat.protobuf.DKGMessages;
|
||||||
|
import org.factcenter.qilin.primitives.concrete.Zpstar;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Tzlil on 2/16/2016.
|
||||||
|
*/
|
||||||
|
public class DistributedKeyGenerationMessageHandler implements MessageHandler {
|
||||||
|
|
||||||
|
protected enum ComplainState{
|
||||||
|
Non, Waiting,Disqualified,NonDisqualified
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final VerifiableSecretSharingMessageHandler[] vssHandlers;
|
||||||
|
protected final ComplainState[][] complainStates; // complainStates[i][j] == state of Pj's complaint against Pi
|
||||||
|
protected final BigInteger g;
|
||||||
|
protected final Zpstar zpstar;
|
||||||
|
protected final int n;
|
||||||
|
private final boolean[] doneFlags;
|
||||||
|
|
||||||
|
public DistributedKeyGenerationMessageHandler(int t, int n, BigInteger g, Zpstar zpstar) {
|
||||||
|
this.g = g;
|
||||||
|
this.zpstar = zpstar;
|
||||||
|
this.n = n;
|
||||||
|
this.doneFlags = new boolean[n];
|
||||||
|
this.vssHandlers = new VerifiableSecretSharingMessageHandler[n];
|
||||||
|
for (int i = 1; i <= n ; i++){
|
||||||
|
vssHandlers[i - 1] = new VerifiableSecretSharingMessageHandler(t);
|
||||||
|
}
|
||||||
|
this.complainStates = new ComplainState[n][n];
|
||||||
|
for (int i = 0; i < n; i ++){
|
||||||
|
for (int j = 0 ; j < n ; j ++)
|
||||||
|
this.complainStates[i][j] = ComplainState.Non;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true iff all shares and commitments were received
|
||||||
|
*/
|
||||||
|
protected boolean isStage1Complete(){
|
||||||
|
for (int i = 1 ; i <= n ; i++){
|
||||||
|
if(vssHandlers[i - 1].getShare() == null)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInteger[] commitments;
|
||||||
|
for (int i = 0; i < vssHandlers.length; i++){
|
||||||
|
commitments = vssHandlers[i].getCommitments();
|
||||||
|
for (int j = 0; j < commitments.length; j++){
|
||||||
|
if(commitments[j] == null)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true iff all flags in doneFlags are true
|
||||||
|
*/
|
||||||
|
protected boolean isStage2Complete() {
|
||||||
|
for (int j = 0; j < n ; j++) {
|
||||||
|
if(!doneFlags[j])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handelComplaintMessage(int sender, boolean isBroadcast, DKGMessages.ComplaintMessage complaintMessage) {
|
||||||
|
if(isBroadcast){
|
||||||
|
int i = complaintMessage.getId();
|
||||||
|
int j = sender;
|
||||||
|
switch (complainStates[i - 1][j - 1]){
|
||||||
|
case Non:
|
||||||
|
complainStates[i - 1][j - 1] = ComplainState.Waiting;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handelDoneMessage(int sender, boolean isBroadcast, DKGMessages.DoneMessage doneMessage) {
|
||||||
|
if(isBroadcast)
|
||||||
|
this.doneFlags[sender - 1] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handelCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage) {
|
||||||
|
vssHandlers[sender - 1].handelCommitmentMessage(sender, isBroadcast, commitmentMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param secret
|
||||||
|
* @param i
|
||||||
|
* @return g ^ Sij == verify(j,Ai,zpstar) (mod p)
|
||||||
|
*/
|
||||||
|
private boolean isValidSecret(Polynomial.Point secret, int i){
|
||||||
|
int j = secret.x.intValue();
|
||||||
|
BigInteger[] commitments = vssHandlers[i - 1].getCommitments();
|
||||||
|
return zpstar.multiply(g,secret.y).equals(VerifiableSecretSharing.verify(j,commitments,zpstar));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isValidSecret(int i){
|
||||||
|
return isValidSecret(getShare(i),i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handelSecretMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage) {
|
||||||
|
vssHandlers[sender - 1].handelSecretMessage(sender, isBroadcast, secretMessage);
|
||||||
|
if(isBroadcast){
|
||||||
|
Polynomial.Point secret = SecretSharingMessageHandler.extractSecret(secretMessage);
|
||||||
|
int i = sender;
|
||||||
|
int j = secret.x.intValue();
|
||||||
|
switch (complainStates[i - 1][j - 1]){
|
||||||
|
case Waiting:
|
||||||
|
if(isValidSecret(secret,i)){
|
||||||
|
complainStates[i - 1][j - 1] = ComplainState.NonDisqualified;
|
||||||
|
}else{
|
||||||
|
complainStates[i - 1][j - 1] = ComplainState.Disqualified;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handelDoubleSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected ComplainState[][] getComplainStates() {
|
||||||
|
return complainStates;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected BigInteger getY(int i){
|
||||||
|
return vssHandlers[i - 1].getY();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected BigInteger[] getCommitments(int i){
|
||||||
|
return vssHandlers[i -1].getCommitments();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Polynomial.Point getShare(int i){
|
||||||
|
return vssHandlers[i-1].getShare();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,124 +0,0 @@
|
||||||
package JointFeldmanProtocol;
|
|
||||||
|
|
||||||
import com.google.protobuf.InvalidProtocolBufferException;
|
|
||||||
import com.google.protobuf.Message;
|
|
||||||
import meerkat.protobuf.DKGMessages.*;
|
|
||||||
import java.util.Queue;
|
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
|
||||||
/**
|
|
||||||
* Created by Tzlil on 2/7/2016.
|
|
||||||
* JointFeldamn protocol assumes all parties can communicate throw broadcast chanel
|
|
||||||
* and private chanel (for each pair)
|
|
||||||
* this class simulates it
|
|
||||||
*/
|
|
||||||
public class Network {
|
|
||||||
|
|
||||||
private final User[] users;
|
|
||||||
private final int n;
|
|
||||||
private final Queue<Integer> availableIDs;
|
|
||||||
|
|
||||||
|
|
||||||
public Network(int n) {
|
|
||||||
this.n = n;
|
|
||||||
this.users = new User[n];
|
|
||||||
this.availableIDs = new ArrayBlockingQueue<Integer>(n);
|
|
||||||
for (int id = 1; id <= n; id++){
|
|
||||||
availableIDs.add(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public User connect(MailHandler messageHandler){
|
|
||||||
Integer id = availableIDs.poll();
|
|
||||||
if (id == null)
|
|
||||||
return null;
|
|
||||||
users[id - 1] = new User(id,messageHandler);
|
|
||||||
return users[id - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean sendMessage(User sender,int destination,Mail.Type type,Message message){
|
|
||||||
if(destination < 1 || destination > n)
|
|
||||||
return false;
|
|
||||||
User user = users[destination - 1];
|
|
||||||
if (user == null)
|
|
||||||
return false;
|
|
||||||
Mail mail = Mail.newBuilder()
|
|
||||||
.setSender(sender.getID())
|
|
||||||
.setDestination(destination)
|
|
||||||
.setIsPrivate(true)
|
|
||||||
.setType(type)
|
|
||||||
.setMessage(message.toByteString())
|
|
||||||
.build();
|
|
||||||
return user.mailbox.add(mail);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendBroadcast(User sender,Mail.Type type,Message message){
|
|
||||||
User user;
|
|
||||||
int ID = sender.ID;
|
|
||||||
Mail mail = Mail.newBuilder()
|
|
||||||
.setSender(sender.getID())
|
|
||||||
.setDestination(0)
|
|
||||||
.setIsPrivate(false)
|
|
||||||
.setType(type)
|
|
||||||
.setMessage(message.toByteString())
|
|
||||||
.build();
|
|
||||||
for (int i = 0 ; i < n ; i++){
|
|
||||||
if (i + 1 == ID) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
user = users[i];
|
|
||||||
user.mailbox.add(mail);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class User{
|
|
||||||
private final MailHandler messageHandler;
|
|
||||||
private final Queue<Mail> mailbox;
|
|
||||||
private final int ID;
|
|
||||||
private final Thread receiverThread;
|
|
||||||
public User(int ID, MailHandler messageHandler) {
|
|
||||||
this.mailbox = new ArrayBlockingQueue<Mail>(1 << n);
|
|
||||||
this.ID = ID;
|
|
||||||
this.messageHandler = messageHandler;
|
|
||||||
this.receiverThread = new Thread(new Receiver());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean send(int id, Mail.Type type,Message message){
|
|
||||||
return sendMessage(this,id,type,message);
|
|
||||||
}
|
|
||||||
public void broadcast(Mail.Type type,Message message){
|
|
||||||
sendBroadcast(this,type,message);
|
|
||||||
}
|
|
||||||
public int getID() {
|
|
||||||
return ID;
|
|
||||||
}
|
|
||||||
public Thread getReceiverThread(){
|
|
||||||
return receiverThread;
|
|
||||||
}
|
|
||||||
private class Receiver implements Runnable{
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
while (true){
|
|
||||||
if (!mailbox.isEmpty()){
|
|
||||||
try {
|
|
||||||
messageHandler.handel(mailbox.poll());
|
|
||||||
} catch (InvalidProtocolBufferException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
try {
|
|
||||||
Thread.sleep(30);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface MailHandler {
|
|
||||||
public void handel(Mail mail) throws InvalidProtocolBufferException;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
package SecureDistributedKeyGeneration;
|
||||||
|
|
||||||
|
import Communication.Network;
|
||||||
|
import FeldmanVerifiableSecretSharing.VerifiableSecretSharing;
|
||||||
|
import JointFeldmanProtocol.DistributedKeyGeneration;
|
||||||
|
import com.google.protobuf.ByteString;
|
||||||
|
import meerkat.protobuf.DKGMessages;
|
||||||
|
import org.factcenter.qilin.primitives.concrete.Zpstar;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Tzlil on 2/17/2016.
|
||||||
|
*/
|
||||||
|
public class SecureDistributedKeyGeneration extends DistributedKeyGeneration {
|
||||||
|
|
||||||
|
VerifiableSecretSharing verifiableSecretSharing;
|
||||||
|
|
||||||
|
public SecureDistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger p, BigInteger q, BigInteger g
|
||||||
|
,BigInteger h, Network network) {
|
||||||
|
super(t, n, zi, random, p, q, g, network.connect(new SecureDistributedKeyGenerationMessageHandler(t,n,g,new Zpstar(p))));
|
||||||
|
this.verifiableSecretSharing = new VerifiableSecretSharing(t,n,new BigInteger(q.bitLength(), random).mod(q),random,p,q,h,user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void computeAndSendSecrets() {
|
||||||
|
DKGMessages.SecretMessage[] secretMessages1 = prepareSecretMessages();
|
||||||
|
DKGMessages.SecretMessage[] secretMessages2 = verifiableSecretSharing.prepareSecretMessages();
|
||||||
|
DKGMessages.DoubleSecretMessage doubleSecretMessage;
|
||||||
|
|
||||||
|
for (int j = 1; j <= n ; j++ ){
|
||||||
|
doubleSecretMessage = DKGMessages.DoubleSecretMessage.newBuilder()
|
||||||
|
.setS1(secretMessages1[j - 1])
|
||||||
|
.setS1(secretMessages2[j - 1])
|
||||||
|
.build();
|
||||||
|
user.send(j, DKGMessages.Mail.Type.SECRET,doubleSecretMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DKGMessages.CommitmentMessage[] prepareCommitmentMessages() {
|
||||||
|
DKGMessages.CommitmentMessage[] commitmentMessages = new DKGMessages.CommitmentMessage[t + 1];
|
||||||
|
BigInteger[] commitments2 = verifiableSecretSharing.getCommitments();
|
||||||
|
for (int k = 0; k <= t ; k ++) {
|
||||||
|
commitmentMessages[k] = DKGMessages.CommitmentMessage.newBuilder()
|
||||||
|
.setK(k)
|
||||||
|
.setCommitment(ByteString.copyFrom(zpstar.add(commitments[k],commitments2[k]).toByteArray()))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
return commitmentMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void answerComplaint(int j) {
|
||||||
|
DKGMessages.SecretMessage secretMessage1 = DKGMessages.SecretMessage.newBuilder()
|
||||||
|
.setSecret(getShare(j).asMessage())
|
||||||
|
.build();
|
||||||
|
DKGMessages.SecretMessage secretMessage2 = DKGMessages.SecretMessage.newBuilder()
|
||||||
|
.setSecret(verifiableSecretSharing.getShare(j).asMessage())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
user.broadcast(DKGMessages.Mail.Type.SECRET, DKGMessages.DoubleSecretMessage.newBuilder()
|
||||||
|
.setS1(secretMessage1)
|
||||||
|
.setS2(secretMessage2)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package SecureDistributedKeyGeneration;
|
||||||
|
|
||||||
|
import Communication.Network;
|
||||||
|
import FeldmanVerifiableSecretSharing.VerifiableSecretSharing;
|
||||||
|
import JointFeldmanProtocol.DistributedKeyGenerationMessageHandler;
|
||||||
|
import ShamirSecretSharing.Polynomial;
|
||||||
|
import ShamirSecretSharing.SecretSharingMessageHandler;
|
||||||
|
import meerkat.protobuf.DKGMessages;
|
||||||
|
import org.factcenter.qilin.primitives.concrete.Zpstar;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Tzlil on 2/17/2016.
|
||||||
|
*/
|
||||||
|
public class SecureDistributedKeyGenerationMessageHandler extends DistributedKeyGenerationMessageHandler {
|
||||||
|
|
||||||
|
private final SecretSharingMessageHandler[] ssHandlers;
|
||||||
|
public SecureDistributedKeyGenerationMessageHandler(int t, int n, BigInteger g, Zpstar zpstar) {
|
||||||
|
super(t, n, g, zpstar);
|
||||||
|
this.ssHandlers = new SecretSharingMessageHandler[n];
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValidSecret(Polynomial.Point secret1,Polynomial.Point secret2,int i){
|
||||||
|
int j = secret1.x.intValue();
|
||||||
|
BigInteger[] commitments = vssHandlers[i - 1].getCommitments();
|
||||||
|
return zpstar.multiply(g,zpstar.add(secret1.y,secret2.y)).equals(VerifiableSecretSharing.verify(j,commitments,zpstar));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isValidSecret(int i) {
|
||||||
|
return isValidSecret(getShare(i),ssHandlers[i - 1].getShare(),i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handelDoubleSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) {
|
||||||
|
if(!isBroadcast){
|
||||||
|
this.handelSecretMessage(sender,isBroadcast,doubleSecretMessage.getS1());
|
||||||
|
ssHandlers[sender - 1].handelSecretMessage(sender,isBroadcast,doubleSecretMessage.getS2());
|
||||||
|
}else{
|
||||||
|
Polynomial.Point secret1 = SecretSharingMessageHandler.extractSecret(doubleSecretMessage.getS1());
|
||||||
|
Polynomial.Point secret2 = SecretSharingMessageHandler.extractSecret(doubleSecretMessage.getS2());
|
||||||
|
int i = sender;
|
||||||
|
int j = secret1.x.intValue();
|
||||||
|
switch (complainStates[i - 1][j - 1]){
|
||||||
|
case Waiting:
|
||||||
|
if(isValidSecret(secret1,secret2,i)){
|
||||||
|
complainStates[i - 1][j - 1] = ComplainState.NonDisqualified;
|
||||||
|
}else{
|
||||||
|
complainStates[i - 1][j - 1] = ComplainState.Disqualified;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package FeldmanVerifiableSecretSharing.ShamirSecretSharing;
|
package ShamirSecretSharing;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package FeldmanVerifiableSecretSharing.ShamirSecretSharing;
|
package ShamirSecretSharing;
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
import meerkat.protobuf.DKGMessages;
|
import meerkat.protobuf.DKGMessages;
|
||||||
|
@ -9,8 +9,8 @@ import java.math.BigInteger;
|
||||||
* Created by Tzlil on 1/27/2016.
|
* Created by Tzlil on 1/27/2016.
|
||||||
*/
|
*/
|
||||||
public class Polynomial implements Comparable<Polynomial> {
|
public class Polynomial implements Comparable<Polynomial> {
|
||||||
protected static final Polynomial ZERO = new Polynomial(new BigInteger[]{BigInteger.ZERO}); // neutral for add
|
public static final Polynomial ZERO = new Polynomial(new BigInteger[]{BigInteger.ZERO}); // neutral for add
|
||||||
protected static final Polynomial ONE = new Polynomial(new BigInteger[]{BigInteger.ONE}); // neutral for mul
|
public static final Polynomial ONE = new Polynomial(new BigInteger[]{BigInteger.ONE}); // neutral for mul
|
||||||
private final int degree;
|
private final int degree;
|
||||||
private final BigInteger[] coefficients;
|
private final BigInteger[] coefficients;
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ public class Polynomial implements Comparable<Polynomial> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests{" +
|
return "ShamirSecretSharing.PolynomialTests{" +
|
||||||
"degree=" + degree +
|
"degree=" + degree +
|
||||||
", coefficients=" + java.util.Arrays.toString(coefficients) +
|
", coefficients=" + java.util.Arrays.toString(coefficients) +
|
||||||
'}';
|
'}';
|
||||||
|
@ -101,7 +101,7 @@ public class Polynomial implements Comparable<Polynomial> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param other
|
* @param other
|
||||||
* @return new FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests of degree max(this degree,other degree) s.t for all x in Z
|
* @return new ShamirSecretSharing.PolynomialTests of degree max(this degree,other degree) s.t for all x in Z
|
||||||
* new.image(x) = this.image(x) + other.image(x)
|
* new.image(x) = this.image(x) + other.image(x)
|
||||||
*/
|
*/
|
||||||
public Polynomial add(Polynomial other){
|
public Polynomial add(Polynomial other){
|
||||||
|
@ -123,7 +123,7 @@ public class Polynomial implements Comparable<Polynomial> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param constant
|
* @param constant
|
||||||
* @return new FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests of degree this.degree s.t for all x in Z
|
* @return new ShamirSecretSharing.PolynomialTests of degree this.degree s.t for all x in Z
|
||||||
* new.image(x) = constant * this.image(x)
|
* new.image(x) = constant * this.image(x)
|
||||||
*/
|
*/
|
||||||
public Polynomial mul(BigInteger constant){
|
public Polynomial mul(BigInteger constant){
|
||||||
|
@ -138,7 +138,7 @@ public class Polynomial implements Comparable<Polynomial> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param other
|
* @param other
|
||||||
* @return new FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests of degree this degree + other degree + 1 s.t for all x in Z
|
* @return new ShamirSecretSharing.PolynomialTests of degree this degree + other degree + 1 s.t for all x in Z
|
||||||
* new.image(x) = this.image(x) * other.image(x)
|
* new.image(x) = this.image(x) * other.image(x)
|
||||||
*/
|
*/
|
||||||
public Polynomial mul(Polynomial other){
|
public Polynomial mul(Polynomial other){
|
|
@ -1,6 +1,10 @@
|
||||||
package FeldmanVerifiableSecretSharing.ShamirSecretSharing;
|
package ShamirSecretSharing;
|
||||||
|
|
||||||
|
|
||||||
|
import Communication.Network;
|
||||||
|
import Communication.User;
|
||||||
|
import meerkat.protobuf.DKGMessages;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
@ -8,11 +12,12 @@ import java.util.Random;
|
||||||
* Created by Tzlil on 1/27/2016.
|
* Created by Tzlil on 1/27/2016.
|
||||||
* an implementation of Shamire's secret sharing scheme
|
* an implementation of Shamire's secret sharing scheme
|
||||||
*/
|
*/
|
||||||
public class SecretSharing {
|
public class SecretSharing implements Runnable{
|
||||||
protected final int t;
|
protected final int t;
|
||||||
protected final int n;
|
protected final int n;
|
||||||
protected final BigInteger q;
|
protected final BigInteger q;
|
||||||
|
|
||||||
|
protected final User user; // send and receive messages throw network
|
||||||
private final Polynomial polynomial;
|
private final Polynomial polynomial;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,11 +29,16 @@ public class SecretSharing {
|
||||||
* @param x secret, chosen from Zq
|
* @param x secret, chosen from Zq
|
||||||
* @param random use for generate random polynomial
|
* @param random use for generate random polynomial
|
||||||
*/
|
*/
|
||||||
public SecretSharing(int t, int n, BigInteger x, Random random,BigInteger q) {
|
public SecretSharing(int t, int n, BigInteger x, Random random, BigInteger q, Network network) {
|
||||||
|
this(t,n,x,random,q,network.connect(new SecretSharingMessageHandler()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public SecretSharing(int t, int n, BigInteger x, Random random, BigInteger q, User user) {
|
||||||
this.q = q;
|
this.q = q;
|
||||||
this.t = t;
|
this.t = t;
|
||||||
this.n = n;
|
this.n = n;
|
||||||
this.polynomial = generateRandomPolynomial(x,random);
|
this.polynomial = generateRandomPolynomial(x,random);
|
||||||
|
this.user = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,18 +63,11 @@ public class SecretSharing {
|
||||||
*
|
*
|
||||||
* @return polynomial.image(i)%q
|
* @return polynomial.image(i)%q
|
||||||
*/
|
*/
|
||||||
protected final Polynomial.Point getShare(int i){
|
public Polynomial.Point getShare(int i){
|
||||||
assert (i > 0 && i <= n);
|
assert (i > 0 && i <= n);
|
||||||
return new Polynomial.Point(BigInteger.valueOf(i), polynomial, q);
|
return new Polynomial.Point(BigInteger.valueOf(i), polynomial, q);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* use for test only
|
|
||||||
*/
|
|
||||||
public Polynomial.Point getShareForTest(int i){
|
|
||||||
return getShare(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param shares - subset of the original shares
|
* @param shares - subset of the original shares
|
||||||
*
|
*
|
||||||
|
@ -99,8 +102,31 @@ public class SecretSharing {
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Polynomial getPolynomial() {
|
public Polynomial getPolynomial() {
|
||||||
|
|
||||||
return polynomial;
|
return polynomial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DKGMessages.SecretMessage[] prepareSecretMessages(){
|
||||||
|
DKGMessages.SecretMessage[] secretMessages = new DKGMessages.SecretMessage[n];
|
||||||
|
for (int j = 1; j <= n ; j++ ){
|
||||||
|
secretMessages[j - 1] = DKGMessages.SecretMessage.newBuilder()
|
||||||
|
.setSecret(getShare(j).asMessage())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
return secretMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void computeAndSendSecrets(){
|
||||||
|
DKGMessages.SecretMessage[] secretMessages = prepareSecretMessages();
|
||||||
|
for (int j = 1; j <= n ; j++ ){
|
||||||
|
user.send(j, DKGMessages.Mail.Type.SECRET,secretMessages[j - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// computes and sends shares
|
||||||
|
computeAndSendSecrets();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package ShamirSecretSharing;
|
||||||
|
|
||||||
|
import Communication.MessageHandler;
|
||||||
|
import Communication.Network;
|
||||||
|
import meerkat.protobuf.DKGMessages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Tzlil on 2/16/2016.
|
||||||
|
*/
|
||||||
|
public class SecretSharingMessageHandler implements MessageHandler{
|
||||||
|
|
||||||
|
private Polynomial.Point share;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handelComplaintMessage(int sender, boolean isBroadcast, DKGMessages.ComplaintMessage complaintMessage) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handelDoneMessage(int sender, boolean isBroadcast, DKGMessages.DoneMessage doneMessage) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handelCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handelDoubleSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handelSecretMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage) {
|
||||||
|
if(!isBroadcast)
|
||||||
|
this.share = extractSecret(secretMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Polynomial.Point extractSecret(DKGMessages.SecretMessage secretMessage){
|
||||||
|
return new Polynomial.Point(secretMessage.getSecret());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Polynomial.Point getShare() {
|
||||||
|
return share;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package FeldmanVerifiableSecretSharing;
|
package FeldmanVerifiableSecretSharing;
|
||||||
|
|
||||||
import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial;
|
import Communication.Network;
|
||||||
|
import ShamirSecretSharing.Polynomial;
|
||||||
import org.factcenter.qilin.primitives.concrete.Zpstar;
|
import org.factcenter.qilin.primitives.concrete.Zpstar;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -31,11 +32,12 @@ public class VerifiableSecretSharingTest {
|
||||||
}while (!g.equals(ZERO) && !zpstar.multiply(g,q).equals(ZERO));// sample from QRZp*
|
}while (!g.equals(ZERO) && !zpstar.multiply(g,q).equals(ZERO));// sample from QRZp*
|
||||||
int t = 8;
|
int t = 8;
|
||||||
int n = 20;
|
int n = 20;
|
||||||
|
Network network;
|
||||||
verifiableSecretSharingArray = new VerifiableSecretSharing[tests];
|
verifiableSecretSharingArray = new VerifiableSecretSharing[tests];
|
||||||
for (int i = 0; i < verifiableSecretSharingArray.length; i++){
|
for (int i = 0; i < verifiableSecretSharingArray.length; i++){
|
||||||
|
network = new Network(n);
|
||||||
verifiableSecretSharingArray[i] = new VerifiableSecretSharing(t,n
|
verifiableSecretSharingArray[i] = new VerifiableSecretSharing(t,n
|
||||||
,new BigInteger(q.bitLength(),random).mod(q),random,p,q,g);
|
,new BigInteger(q.bitLength(),random).mod(q),random,p,q,g,network);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +49,7 @@ public class VerifiableSecretSharingTest {
|
||||||
BigInteger[] commitments = verifiableSecretSharing.getCommitments();
|
BigInteger[] commitments = verifiableSecretSharing.getCommitments();
|
||||||
BigInteger[] verifications = new BigInteger[n];
|
BigInteger[] verifications = new BigInteger[n];
|
||||||
for (int i = 1 ; i <= shares.length; i ++){
|
for (int i = 1 ; i <= shares.length; i ++){
|
||||||
shares[i - 1] = verifiableSecretSharing.getShareForTest(i);
|
shares[i - 1] = verifiableSecretSharing.getShare(i);
|
||||||
verifications[i - 1] = VerifiableSecretSharing.verify(i,commitments,zpstar);
|
verifications[i - 1] = VerifiableSecretSharing.verify(i,commitments,zpstar);
|
||||||
}
|
}
|
||||||
BigInteger expected;
|
BigInteger expected;
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
package JointFeldmanProtocol;
|
package JointFeldmanProtocol;
|
||||||
|
|
||||||
|
import Communication.Network;
|
||||||
|
import ShamirSecretSharing.Polynomial;
|
||||||
|
import ShamirSecretSharing.SecretSharing;
|
||||||
|
import FeldmanVerifiableSecretSharing.VerifiableSecretSharing;
|
||||||
import org.factcenter.qilin.primitives.concrete.Zpstar;
|
import org.factcenter.qilin.primitives.concrete.Zpstar;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -13,45 +19,98 @@ import java.util.Random;
|
||||||
public class DKGTest {
|
public class DKGTest {
|
||||||
|
|
||||||
|
|
||||||
DKG[] dkgs;
|
DistributedKeyGeneration[][] dkgsArrays;
|
||||||
Thread[] threads;
|
Thread[][] threadsArrays;
|
||||||
int tests = 1 << 10;
|
int tests = 10;
|
||||||
Random random;
|
BigInteger p = BigInteger.valueOf(2903);
|
||||||
|
BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2));
|
||||||
|
BigInteger[] secrets;
|
||||||
@Before
|
@Before
|
||||||
public void settings(){
|
public void settings(){
|
||||||
BigInteger p = BigInteger.valueOf(2903);
|
|
||||||
BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2));
|
|
||||||
Zpstar zpstar = new Zpstar(p);
|
Zpstar zpstar = new Zpstar(p);
|
||||||
random = new Random();
|
Random random = new Random();
|
||||||
BigInteger g;
|
BigInteger g;
|
||||||
|
int t = 9;
|
||||||
|
int n = 20;
|
||||||
BigInteger ZERO = zpstar.zero();
|
BigInteger ZERO = zpstar.zero();
|
||||||
do{
|
dkgsArrays = new DistributedKeyGeneration[tests][n];
|
||||||
g = zpstar.sample(random);
|
threadsArrays = new Thread[tests][n];
|
||||||
}while (!g.equals(ZERO) && !zpstar.multiply(g,q).equals(ZERO));// sample from QRZp*
|
secrets = new BigInteger[tests];
|
||||||
int t = 8;
|
for (int test = 0; test < tests; test++) {
|
||||||
int n = 20
|
do {
|
||||||
;
|
g = zpstar.sample(random);
|
||||||
Network network = new Network(n);
|
} while (!g.equals(ZERO) && !zpstar.multiply(g, q).equals(ZERO));// sample from QRZp*
|
||||||
dkgs = new DKG[n];
|
secrets[test] = BigInteger.ZERO;
|
||||||
threads = new Thread[n];
|
Network network = new Network(n);
|
||||||
for (int i = 0 ; i < n ; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
dkgs[i] = new DKG(t, n, new BigInteger(q.bitLength(), random).mod(q), random, p, q, g, network);
|
BigInteger secret = new BigInteger(q.bitLength(), random).mod(q);
|
||||||
threads[i] = new Thread(dkgs[i]);
|
secrets[test] = secrets[test].add(secret).mod(q);
|
||||||
|
dkgsArrays[test][i] = new DistributedKeyGeneration(t, n,secret, random, p, q, g, network);
|
||||||
|
threadsArrays[test][i] = new Thread(dkgsArrays[test][i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
public void oneTest(Thread[] threads, DistributedKeyGeneration[] dkgs,BigInteger secret) throws Exception {
|
||||||
public void DKGTest() throws Exception {
|
for (int i = 0; i < threads.length ; i++){
|
||||||
for (int i = 0 ; i < threads.length ; i++){
|
|
||||||
threads[i].start();
|
threads[i].start();
|
||||||
}
|
}
|
||||||
for (int i = 0 ; i < threads.length ; i++){
|
for (int i = 0; i < threads.length ; i++){
|
||||||
threads[i].join();
|
threads[i].join();
|
||||||
}
|
}
|
||||||
|
int t = dkgs[0].getT();
|
||||||
|
int n = dkgs[0].getN();
|
||||||
|
|
||||||
|
Zpstar zpstar = dkgs[0].getZpstar();
|
||||||
|
BigInteger g = dkgs[0].getGenerator();
|
||||||
|
|
||||||
|
// got the right public value
|
||||||
|
assert(zpstar.multiply(g,secret).equals(dkgs[0].getY()));
|
||||||
|
|
||||||
|
// assert all players agreed on the same public value
|
||||||
for (int i = 0; i < dkgs.length - 1 ; i++){
|
for (int i = 0; i < dkgs.length - 1 ; i++){
|
||||||
assert (dkgs[i].getY().equals(dkgs[i+1].getY()));
|
assert (dkgs[i].getY().equals(dkgs[i+1].getY()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// assert valid verification values
|
||||||
|
BigInteger expected,verification;
|
||||||
|
for (int j = 1; j <= dkgs.length ; j++){
|
||||||
|
expected = zpstar.multiply(g, dkgs[j - 1].getShare().y);
|
||||||
|
verification = VerifiableSecretSharing.verify(j, dkgs[j - 1].getCommitments(),zpstar);
|
||||||
|
assert (expected.equals(verification));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// restore the secret from t + 1 random shares
|
||||||
|
Polynomial.Point[] shares = new Polynomial.Point[t + 1];
|
||||||
|
for (int i = 0 ; i < shares.length; i++){
|
||||||
|
shares[i] = dkgs[i].getShare();
|
||||||
|
}
|
||||||
|
//List<Integer> indexes = new ArrayList<Integer>(n);
|
||||||
|
//for (int i = 1 ; i <= n; i ++){
|
||||||
|
// indexes.add(i);
|
||||||
|
//}
|
||||||
|
//Random random = new Random();
|
||||||
|
//int index;
|
||||||
|
//for (int i = 0 ; i < shares.length ; i++){
|
||||||
|
// index = indexes.remove(random.nextInt(indexes.size()));
|
||||||
|
// shares[i] = dkgs[index - 1].getShare();
|
||||||
|
//}
|
||||||
|
BigInteger calculatedSecret = SecretSharing.getSecrete(shares).mod(q);
|
||||||
|
|
||||||
|
Polynomial polynomial = Polynomial.ZERO;
|
||||||
|
for (int i = 0 ; i < dkgs.length ; i++){
|
||||||
|
polynomial = polynomial.add(dkgs[i].getPolynomial());
|
||||||
|
}
|
||||||
|
|
||||||
|
assert (calculatedSecret.equals(secret));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void secretSharingTest() throws Exception {
|
||||||
|
for (int i = 0 ; i < dkgsArrays.length; i ++){
|
||||||
|
oneTest(threadsArrays[i],dkgsArrays[i],secrets[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
package FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests;
|
package ShamirSecretSharing.PolynomialTests;
|
||||||
import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial;
|
import ShamirSecretSharing.Polynomial;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests;
|
package ShamirSecretSharing.PolynomialTests;
|
||||||
|
|
||||||
import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial;
|
import ShamirSecretSharing.Polynomial;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests;
|
package ShamirSecretSharing.PolynomialTests;
|
||||||
|
|
||||||
import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial;
|
import ShamirSecretSharing.Polynomial;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests;
|
package ShamirSecretSharing.PolynomialTests;
|
||||||
|
|
||||||
import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial;
|
import ShamirSecretSharing.Polynomial;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests;
|
package ShamirSecretSharing.PolynomialTests;
|
||||||
|
|
||||||
import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial;
|
import ShamirSecretSharing.Polynomial;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
|
@ -1,6 +1,7 @@
|
||||||
package FeldmanVerifiableSecretSharing.ShamirSecretSharing;
|
package ShamirSecretSharing;
|
||||||
|
|
||||||
import FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests.Utils;
|
import Communication.Network;
|
||||||
|
import Communication.User;
|
||||||
import org.factcenter.qilin.primitives.CyclicGroup;
|
import org.factcenter.qilin.primitives.CyclicGroup;
|
||||||
import org.factcenter.qilin.primitives.concrete.Zn;
|
import org.factcenter.qilin.primitives.concrete.Zn;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
@ -26,14 +27,17 @@ public class SecretSharingTest {
|
||||||
public void settings(){
|
public void settings(){
|
||||||
BigInteger p = BigInteger.valueOf(2903);
|
BigInteger p = BigInteger.valueOf(2903);
|
||||||
group = new Zn(p);
|
group = new Zn(p);
|
||||||
int t = 10;
|
int t = 9;
|
||||||
int n = 20;
|
int n = 20;
|
||||||
random = new Random();
|
random = new Random();
|
||||||
secretSharingArray = new SecretSharing[tests];
|
secretSharingArray = new SecretSharing[tests];
|
||||||
secrets = new BigInteger[tests];
|
secrets = new BigInteger[tests];
|
||||||
|
Network network;
|
||||||
|
|
||||||
for (int i = 0; i < secretSharingArray.length; i++){
|
for (int i = 0; i < secretSharingArray.length; i++){
|
||||||
secrets[i] = group.sample(random);
|
secrets[i] = group.sample(random);
|
||||||
secretSharingArray[i] = new SecretSharing(t,n,secrets[i],random,p);
|
network = new Network(n);
|
||||||
|
secretSharingArray[i] = new SecretSharing(t,n,secrets[i],random,p,network);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ message Mail{
|
||||||
enum Type {
|
enum Type {
|
||||||
SECRET = 0;
|
SECRET = 0;
|
||||||
COMMITMENT = 1;
|
COMMITMENT = 1;
|
||||||
Y = 2;
|
DONE = 2;
|
||||||
COMPLAINT = 3;
|
COMPLAINT = 3;
|
||||||
}
|
}
|
||||||
int32 sender = 1;
|
int32 sender = 1;
|
||||||
|
@ -26,14 +26,17 @@ message SecretMessage {
|
||||||
Point secret = 1;
|
Point secret = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message DoubleSecretMessage{
|
||||||
|
SecretMessage s1 = 1;
|
||||||
|
SecretMessage s2 = 2;
|
||||||
|
}
|
||||||
|
|
||||||
message CommitmentMessage{
|
message CommitmentMessage{
|
||||||
int32 k = 1;
|
int32 k = 1;
|
||||||
bytes commitment = 2;
|
bytes commitment = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message YMessage{
|
message DoneMessage{}
|
||||||
bytes y = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ComplaintMessage{
|
message ComplaintMessage{
|
||||||
int32 id = 1;
|
int32 id = 1;
|
||||||
|
|
Loading…
Reference in New Issue