diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java index 6962d29..49a6f17 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java @@ -6,6 +6,7 @@ import org.bouncycastle.util.Arrays; import org.factcenter.qilin.primitives.concrete.Zpstar; import java.math.BigInteger; +import java.util.HashSet; import java.util.Random; import java.util.Set; @@ -14,44 +15,55 @@ import java.util.Set; * * an implementation of a version of Pedersen's distributed key generation protocol */ -public class DKG extends VerifiableSecretSharing{ +public class DKG extends VerifiableSecretSharing implements Runnable{ private Network.User user; - private Polynomial.Point[][] shares; + private Handler handler; + private Polynomial.Point[] shares; private BigInteger[][] commitmentsArray; + private BigInteger[] ys; private Set QUAL; private BigInteger x; private BigInteger y; private BigInteger[] commitments; - public DKG(int t, int n, BigInteger x, Random random, BigInteger p, BigInteger q, BigInteger g) { + 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.handler = new Handler(); + this.user = network.connect(handler); } + private void stage1(){ int n = getN(); + int t = getT(); int i = user.getID(); BigInteger[] commitments = super.getCommitments(); System.arraycopy(commitments, 0, commitmentsArray[i - 1], 0, commitmentsArray[i - 1].length); - Network.Message message = null; + Network.CommitmentMessage commitment; for (int j = 1; j <= commitmentsArray[i - 1].length; j ++){ - //message = new Message(Type.Commitment, Shares[i - 1][j - 1]) - user.sendBroadcast(message); + commitment = new Network.CommitmentMessage(j,commitmentsArray[i - 1][j - 1]); + user.broadcast(commitment); } - - for (int j = 1; j <= shares[i - 1].length; j ++){ - shares[i - 1][j - 1] = getShare(j); - } + Network.SecretMessage secret; for (int j = 1; j <= n ; j++ ){ if(j != i){ - //message = new Message(Type.Share, Shares[i - 1][j - 1]) - user.send(j,message); + secret = new Network.SecretMessage(getShare(j)); + user.send(j,secret); + } + } + while (handler.secretsCounter < n - 1 || handler.commitmentsCounter < (n - 1) * (t + 1)){ + try { + Thread.sleep(30); + } catch (InterruptedException e) { + // do nothing } } - //Todo receive messages } private void stage2(){ @@ -59,35 +71,40 @@ public class DKG extends VerifiableSecretSharing{ BigInteger g = getGenerator(); Zpstar zpstar = getZpstar(); int i = user.getID(); + QUAL = new HashSet(); Network.Message message = null; for (int j = 1; j <= n ; j++ ){ - if(zpstar.multiply(g,shares[i - 1][j - 1].y).equals(verify(j,commitmentsArray[j],zpstar))){ + if(zpstar.multiply(g,shares[j - 1].y).equals(verify(j,commitmentsArray[j],zpstar))){ QUAL.add(j); }else{ //message = new Message(Type.Complaint, j) - user.sendBroadcast(message); + user.broadcast(message); } } - + //sending y after Complaints + Network.YMessage yMessage = new Network.YMessage(super.getY()); + user.broadcast(yMessage); } private void stage3(){ - + int n = getN(); + while (handler.ysCounter < n - 1 ){ + try { + Thread.sleep(30); + } catch (InterruptedException e) { + // do nothing + } + } //Todo receive something private from each complaint + send what necessary - - } private void stage4(){ - Network.Message message = null; - // message = new Message(Type.Y, super.getY()) - user.sendBroadcast(message); + int t = getT(); Zpstar zpstar = getZpstar(); BigInteger y = zpstar.zero(); - for (Network.User user:this.user.getNetwork()) { - //Todo receive yi from all i in QUAL and calc y total + for (int i : QUAL) { + y = zpstar.add(y , ys[i - 1]); } - int t = getT(); this.commitments = new BigInteger[t]; BigInteger commitment; for (int k = 1; k <= t ; k++){ @@ -101,7 +118,7 @@ public class DKG extends VerifiableSecretSharing{ int j = user.getID(); BigInteger x = BigInteger.ZERO; for (int i : QUAL) { - x = x.add(shares[i][j].y); + x = x.add(shares[i - 1].y); } this.x = x.mod(getQ()); } @@ -120,4 +137,54 @@ public class DKG extends VerifiableSecretSharing{ protected Polynomial.Point getShare(int i) { return null; } + + @Override + public void run() { + stage1(); + stage2(); + stage3(); + stage4(); + } + + private class Handler implements Network.MailHandler { + + final int id; + int secretsCounter; + int commitmentsCounter; + int ysCounter; + + private Handler() { + this.id = user.getID(); + this.secretsCounter = 0; + this.commitmentsCounter = 0; + this.ysCounter = 0; + } + + @Override + public void handel(Network.Mail mail) { + if(mail.isPrivate){ + if(mail.message instanceof Network.SecretMessage){ + Polynomial.Point secret = ((Network.SecretMessage)mail.message).secret; + if(shares[id - 1] == null) { + shares[id - 1] = secret; + secretsCounter++; + } + } + }else{ + if(mail.message instanceof Network.CommitmentMessage){ + Network.CommitmentMessage commitmentMessage = (Network.CommitmentMessage)mail.message; + if(commitmentsArray[mail.senderID - 1][commitmentMessage.k] == null) { + commitmentsArray[mail.senderID - 1][commitmentMessage.k] = commitmentMessage.commitment; + commitmentsCounter++; + } + }else if(mail.message instanceof Network.YMessage){ + BigInteger y = ((Network.YMessage)mail.message).y; + if(ys[mail.senderID - 1] == null){ + ys[mail.senderID - 1] = y; + ysCounter ++; + } + } + } + } + } } diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java index 46c1d44..8468d2d 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java @@ -1,27 +1,147 @@ package JointFeldmanProtocol; +import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; + +import java.lang.reflect.Type; +import java.math.BigInteger; +import java.util.Queue; +import java.util.concurrent.ArrayBlockingQueue; /** - * Created by Tzlil on 2/5/2016. + * Created by Tzlil on 2/7/2016. */ -public interface Network extends Iterable{ +public class Network { - User connect(); + private final User[] users; + private final int n; + private final Queue availableIDs; - interface User{ - int getID(); - void send(int userID,Message message); - void sendBroadcast(Message message); - void receive(int userID,Message message); - void receiveBroadcast(Message message); - Network getNetwork(); + + public Network(int n) { + this.n = n; + this.users = new User[n]; + this.availableIDs = new ArrayBlockingQueue(n); + for (int id = 1; id <= n; id++){ + availableIDs.add(id); + } } - interface Message{ - enum Type { - Commitment, Share, Complaint, Y + public User connect(MailHandler messageHandler){ + Integer id = availableIDs.poll(); + if (id == null) + return null; + return new User(id,messageHandler); + } + + private boolean sendMessage(User sender,int destination,Message message){ + if(destination < 1 || destination > n) + return false; + User user = users[destination - 1]; + if (user == null) + return false; + return user.mailbox.add(new Mail(sender.ID,false,message)); + } + + private void sendBroadcast(User sender,Message message){ + User user; + int ID = sender.ID; + for (int i = 0 ; i < n ; i++){ + if (i + 1 == ID) { + continue; + } + user = users[i]; + user.mailbox.add(new Mail(ID,true,message)); + } + } + + public class User{ + private final MailHandler messageHandler; + private final Queue mailbox; + private final int ID; + + public User(int ID, MailHandler messageHandler) { + this.mailbox = new ArrayBlockingQueue(n*n); + this.ID = ID; + this.messageHandler = messageHandler; + Thread thread = new Thread(new Receiver()); + thread.run(); + } + + + public boolean send(int id, Message message){ + return sendMessage(this,id,message); + } + public void broadcast(Message message){ + sendBroadcast(this,message); + } + + public int getID() { + return ID; + } + + private class Receiver implements Runnable{ + @Override + public void run() { + while (true){ + if (!mailbox.isEmpty()){ + messageHandler.handel(mailbox.poll()); + }else{ + try { + Thread.sleep(30); + } catch (InterruptedException e) { + // do nothing + } + } + } + } } - Type getType(); } + + public class Mail{ + public final int senderID; + public final boolean isPrivate; + public final Message message; + + private Mail(int senderID, boolean isPrivate, Message message) { + this.senderID = senderID; + this.isPrivate = isPrivate; + this.message = message; + } + } + + public static abstract class Message{ + + } + public static class CommitmentMessage extends Message{ + public final int k; + public final BigInteger commitment; + + + public CommitmentMessage(int k, BigInteger commitment) { + this.k = k; + this.commitment = commitment; + } + } + + public static class YMessage extends Message{ + + public final BigInteger y; + + public YMessage(BigInteger y) { + this.y = y; + } + } + + public static class SecretMessage extends Message{ + public final Polynomial.Point secret; + + public SecretMessage(Polynomial.Point secret) { + this.secret = secret; + } + } + + public interface MailHandler { + public void handel(Mail mail); + } } diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java index cb18f3f..8a4f15d 100644 --- a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java +++ b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java @@ -1,8 +1,6 @@ package FeldmanVerifiableSecretSharing; import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; -import org.factcenter.qilin.primitives.CyclicGroup; -import org.factcenter.qilin.primitives.concrete.Zn; import org.factcenter.qilin.primitives.concrete.Zpstar; import org.junit.Before; import org.junit.Test; @@ -20,15 +18,20 @@ public class VerifiableSecretSharingTest { int tests = 1 << 10; Random random; - //@Before + @Before public void settings(){ BigInteger p = BigInteger.valueOf(2903); BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); - + Zpstar zpstar = new Zpstar(p); + random = new Random(); + BigInteger g; + BigInteger ZERO = zpstar.zero(); + do{ + g = zpstar.sample(random); + }while (!g.equals(ZERO) && !zpstar.multiply(g,q).equals(ZERO));// sample from QRZp* int t = 8; int n = 20; - random = new Random(); - BigInteger g = null; //Todo + verifiableSecretSharingArray = new VerifiableSecretSharing[tests]; for (int i = 0; i < verifiableSecretSharingArray.length; i++){ verifiableSecretSharingArray[i] = new VerifiableSecretSharing(t,n @@ -38,8 +41,7 @@ public class VerifiableSecretSharingTest { public void oneTest(VerifiableSecretSharing verifiableSecretSharing) throws Exception { int n = verifiableSecretSharing.getN(); - BigInteger p = verifiableSecretSharing.getQ(); - Zpstar zpstar = new Zpstar(p); + Zpstar zpstar = verifiableSecretSharing.getZpstar(); BigInteger g = verifiableSecretSharing.getGenerator(); Polynomial.Point[] shares = new Polynomial.Point[n]; BigInteger[] commitments = verifiableSecretSharing.getCommitments(); @@ -56,7 +58,7 @@ public class VerifiableSecretSharingTest { } - //@Test + @Test public void secretSharingTest() throws Exception { for (int i = 0 ; i < verifiableSecretSharingArray.length; i ++){ oneTest(verifiableSecretSharingArray[i]);