From 0f7dbe3d50f1d20554d2d9ca7c58888b5943c375 Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Tue, 23 Feb 2016 19:02:49 +0200 Subject: [PATCH] SDKG tested for non coruppted parties --- .../main/java/Communication/MailHandler.java | 16 +- .../src/main/java/Communication/User.java | 4 +- .../VerifiableSecretSharing.java | 92 ++---- ...VerifiableSecretSharingMessageHandler.java | 40 --- .../DistributedKeyGeneration.java | 242 +++++++-------- ...istributedKeyGenerationMessageHandler.java | 161 ---------- .../DistributedKeyGenerationUserImpl.java | 288 ++++++++++++++++++ .../SecureDistributedKeyGeneration.java | 112 ++++--- ...istributedKeyGenerationMessageHandler.java | 61 ---- ...ecureDistributedKeyGenerationUserImpl.java | 138 +++++++++ .../ShamirSecretSharing/SecretSharing.java | 44 +-- .../SecretSharingMessageHandler.java | 47 --- .../DistributedKeyGenerationUser.java | 13 + .../java/UserInterface/SecretSharingUser.java | 14 + .../VerifiableSecretSharingUser.java | 16 + .../VerifiableSecretSharingTest.java | 9 +- .../java/JointFeldmanProtocol/DKGTest.java | 31 +- .../src/test/java/SDKGTest.java | 113 +++++++ .../SecretSharingTest.java | 8 +- .../src/main/proto/meerkat/DKGMessages.proto | 1 + 20 files changed, 842 insertions(+), 608 deletions(-) delete mode 100644 destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingMessageHandler.java delete mode 100644 destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMessageHandler.java create mode 100644 destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java delete mode 100644 destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationMessageHandler.java create mode 100644 destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationUserImpl.java delete mode 100644 destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharingMessageHandler.java create mode 100644 destributed-key-generation/src/main/java/UserInterface/DistributedKeyGenerationUser.java create mode 100644 destributed-key-generation/src/main/java/UserInterface/SecretSharingUser.java create mode 100644 destributed-key-generation/src/main/java/UserInterface/VerifiableSecretSharingUser.java create mode 100644 destributed-key-generation/src/test/java/SDKGTest.java diff --git a/destributed-key-generation/src/main/java/Communication/MailHandler.java b/destributed-key-generation/src/main/java/Communication/MailHandler.java index c70032f..618ba4f 100644 --- a/destributed-key-generation/src/main/java/Communication/MailHandler.java +++ b/destributed-key-generation/src/main/java/Communication/MailHandler.java @@ -9,14 +9,10 @@ import meerkat.protobuf.DKGMessages; 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()){ @@ -36,8 +32,20 @@ public class MailHandler { DKGMessages.ComplaintMessage complaintMessage = DKGMessages.ComplaintMessage.parseFrom(mail.getMessage()); messageHandler.handelComplaintMessage(mail.getSender(),mail.getDestination()== Network.BROADCAST,complaintMessage); break; + case DOUBLE: + DKGMessages.DoubleSecretMessage doubleSecretMessage = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage()); + messageHandler.handelDoubleSecretMessage(mail.getSender(),mail.getDestination()== Network.BROADCAST,doubleSecretMessage); default: break; } } + + + public MessageHandler getMessageHandler(){ + return messageHandler; + } + + public void setMessageHandler(MessageHandler messageHandler) { + this.messageHandler = messageHandler; + } } diff --git a/destributed-key-generation/src/main/java/Communication/User.java b/destributed-key-generation/src/main/java/Communication/User.java index e28347c..2de1ba1 100644 --- a/destributed-key-generation/src/main/java/Communication/User.java +++ b/destributed-key-generation/src/main/java/Communication/User.java @@ -33,8 +33,8 @@ public class User{ network.sendBroadcast(this,type,message); } - public MessageHandler getMessageHandler(){ - return mailHandler.getMessageHandler(); + public void setMessageHandler(MessageHandler messageHandler) { + mailHandler.setMessageHandler(messageHandler); } public int getID() { diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java index 796aaa9..51ae86e 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java @@ -1,12 +1,11 @@ package FeldmanVerifiableSecretSharing; -import Communication.Network; -import Communication.User; import ShamirSecretSharing.Polynomial; import ShamirSecretSharing.SecretSharing; -import com.google.protobuf.ByteString; -import meerkat.protobuf.DKGMessages; + import java.util.Arrays; + +import org.factcenter.qilin.primitives.Group; import org.factcenter.qilin.primitives.concrete.Zpstar; import java.math.BigInteger; @@ -21,31 +20,23 @@ import java.util.Random; * */ public class VerifiableSecretSharing extends SecretSharing { - protected final Zpstar zpstar; + protected final Group group; protected final BigInteger g; // public generator of group - private final BigInteger y; // y = g ^ x - protected final BigInteger[] commitments; + protected final BigInteger[] commitmentsArray; /** - * @param p a large prime - * @param q a large prime dividing p - 1. + * @param group + * @param q a large prime dividing group order. * @param g a generator of cyclic group of order q. - * the generated group is a subgroup of Zp*. + * the generated group is a subgroup of the given 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 - , User user) { - super(t, n, x, random,q,user); + public VerifiableSecretSharing(int t, int n, BigInteger x, Random random, BigInteger q, BigInteger g + , Group group) { + super(t, n, x, random,q); this.g = g; - this.zpstar = new Zpstar(p); - assert (zpstar.contains(g)); - assert (p.subtract(BigInteger.ONE).mod(q).equals(BigInteger.ZERO)); // assert p - 1 % q == 0 - this.commitments = generateCommitments(); - 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))); + this.group = group; + assert (this.group.contains(g)); + this.commitmentsArray = generateCommitments(); } /** @@ -57,7 +48,7 @@ public class VerifiableSecretSharing extends SecretSharing { BigInteger[] coefficients = polynomial.getCoefficients(); BigInteger[] commitments = new BigInteger[coefficients.length]; for (int i = 0 ; i < commitments.length;i++){ - commitments[i] = zpstar.multiply(g,coefficients[i]); + commitments[i] = group.multiply(g,coefficients[i]); } return commitments; } @@ -65,16 +56,16 @@ public class VerifiableSecretSharing extends SecretSharing { /** * @param j share holder id * @param commitments - * @param zpstar + * @param group * - * @return product of commitments[j] ^ (i ^ j) == g ^ polynomial(i) + * @return product of commitmentsArray[j] ^ (i ^ j) == g ^ polynomial(i) */ - public static BigInteger verify(int j,BigInteger[] commitments,Zpstar zpstar) { - BigInteger v = zpstar.zero(); + public static BigInteger verify(int j,BigInteger[] commitments,Group group) { + BigInteger v = group.zero(); BigInteger power = BigInteger.ONE; BigInteger J = BigInteger.valueOf(j); for (int k = 0 ; k < commitments.length ; k ++){ - v = zpstar.add(v,zpstar.multiply(commitments[k],power)); + v = group.add(v,group.multiply(commitments[k],power)); power = power.multiply(J); } return v; @@ -91,49 +82,18 @@ public class VerifiableSecretSharing extends SecretSharing { /** * getter - * @return zpstar + * @return group */ - public Zpstar getZpstar(){ - return zpstar; + public Group getGroup(){ + return group; } /** * getter - * @return public value of this + * @return copy of commitmentsArray */ - public BigInteger getY(){ - return y; + public BigInteger[] getCommitmentsArray() { + return Arrays.copyOf(commitmentsArray, commitmentsArray.length); } - /** - * getter - * @return copy of commitments - */ - public BigInteger[] getCommitments() { - 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(); - } } diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingMessageHandler.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingMessageHandler.java deleted file mode 100644 index bfa23e5..0000000 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingMessageHandler.java +++ /dev/null @@ -1,40 +0,0 @@ -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]; - } -} diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java index a9bd311..bf789f1 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java @@ -1,156 +1,138 @@ package JointFeldmanProtocol; -import Communication.Network; import Communication.User; import ShamirSecretSharing.Polynomial; import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; +import com.google.protobuf.ByteString; import meerkat.protobuf.DKGMessages.*; -import org.factcenter.qilin.primitives.concrete.Zpstar; +import org.factcenter.qilin.primitives.Group; import java.math.BigInteger; +import java.util.Arrays; 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{ +public class DistributedKeyGeneration extends VerifiableSecretSharing{ - private final int id; + protected final int id; + protected Polynomial.Point[] shares; - private final Set 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(); - 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)))); + public DistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger q, BigInteger g + , Group group, int id) { + super(t, n, zi, random, q, g,group); + this.id = id; + this.shares = null; } /** - * use for simulate real distributed protocol + * stage1.1 according to the protocol + * Pi broadcasts Aik for k = 0,...,t. */ - @Override - public void run() { - user.getReceiverThread().start(); - stage1(); - stage2(); - stage3(); - stage4(); - user.getReceiverThread().interrupt(); + public void broadcastCommitments(User user){ + broadcastCommitments(user,commitmentsArray); + } + + public void broadcastCommitments(User user, BigInteger[] commitments){ + CommitmentMessage commitmentMessage; + for (int k = 0; k <= t ; k++){ + commitmentMessage = CommitmentMessage.newBuilder() + .setCommitment(ByteString.copyFrom(commitments[k].toByteArray())) + .setK(k) + .build(); + user.broadcast(Mail.Type.COMMITMENT, commitmentMessage); + } + } + + public void sendSecret(User user, int j){ + SecretMessage.Point secret = getShare(j).asMessage(); + user.send(j, Mail.Type.DOUBLE,SecretMessage.newBuilder().setSecret(secret).build()); } /** - * 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. + * stage1.2 according to the protocol + * 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 + public void sendSecrets(User user){ + for (int j = 1; j <= n ; j++){ + if(j != id){ + sendSecret(user,j); } } } + public boolean isValidSecret(int j,BigInteger[] commitments,int i){ + Polynomial.Point secret = shares[j - 1]; + return isValidSecret(secret,commitments,i); + } + + public boolean isValidSecret(Polynomial.Point secret, BigInteger[] commitments, int i){ + BigInteger v = verify(i,commitments,group); + return group.multiply(g,secret.y).equals(v); + } + /** * 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(){ + public void broadcastComplains(User user, BigInteger[][]commitmentsTable){ 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 + for (int j = 1; j <= n ; j++ ){ + if(j != id) { + if (!isValidSecret(j,commitmentsTable[j - 1],id)) { + //message = new Message(Type.Complaint, j) + complaint = ComplaintMessage.newBuilder() + .setId(j) + .build(); + user.broadcast(Mail.Type.COMPLAINT, complaint); + } } } } - - protected void answerComplaint(int j){ + public void broadcastComplaintAnswer(User user, 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. + * stage3.1 according to the protocol + * if more than t players complain against a player Pi he is disqualified. */ - 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]) { + public void answerAllComplainingPlayers(User user, DistributedKeyGenerationUserImpl.ComplainState[] complains){ + for (int j = 1; j <= n ; j++) { + switch (complains[j - 1]) { case Waiting: - answerComplaint(j); + broadcastComplaintAnswer(user,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 + /** + * stage3.2 according to the protocol + * if any of the revealed shares fails the verification test, player Pi is disqualified. + * set QUAL to be the set of non-disqualified players. + */ + public Set calcQUAL(DistributedKeyGenerationUserImpl.ComplainState[][] complains){ + Set QUAL = new HashSet(); boolean nonDisqualified; int counter; - for (int i = 1; i <= complainStates.length; i++){ + for (int i = 1; i <= complains.length; i++){ nonDisqualified = true; counter = 0; - for (int j = 1; j <= complainStates[i - 1].length; j++){ - switch (complainStates[i - 1][j - 1]) { + for (int j = 1; j <= complains[i - 1].length; j++){ + switch (complains[i - 1][j - 1]) { case Non: break; case NonDisqualified: @@ -165,52 +147,54 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing implements QUAL.add(i); } } + return QUAL; } /** - * 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 + * stage4.1 according to the protocol + * public value y is computed as y = multiplication of yi mod p for i in QUAL */ - private void stage4(){ - this.y = zpstar.zero(); + public BigInteger calcY(BigInteger[] ys,Set QUAL){ + BigInteger y = group.zero(); for (int i : QUAL) { - this.y = zpstar.add(this.y , handler.getY(i)); + y = group.add(y , ys[i - 1]); } - - 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); + /** + * stage4.2 according to the protocol + * public verification values are computed as Ak = multiplication of Aik mod p for i in QUAL for k = 0,...,t + */ + public BigInteger[] calcCommitments(BigInteger[][] commitmentsTable,Set QUAL){ + BigInteger[] commitments = new BigInteger[t + 1]; + Arrays.fill(commitments,group.zero()); + for (int i : QUAL) { + for (int k = 0; k <= t; k++){ + commitments[k] = group.add(commitments[k],commitmentsTable[i - 1][k]); + } + } + return commitments; } - public Polynomial.Point getShare() { - return share; + /** + * stage4.3 according to the protocol + * Pj sets is share of the secret as xj = sum of Sij mod q for i in QUAL + */ + public Polynomial.Point calcShare(Polynomial.Point[] shares,Set QUAL){ + BigInteger xj = BigInteger.ZERO; + for (int i : QUAL) { + xj = xj.add(shares[i - 1].y); + } + return new Polynomial.Point(BigInteger.valueOf(id) , xj.mod(q)); + } + + public int getId() { + return id; + } + + public void setShares(Polynomial.Point[] shares){ + this.shares = shares; } } diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMessageHandler.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMessageHandler.java deleted file mode 100644 index 2314469..0000000 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMessageHandler.java +++ /dev/null @@ -1,161 +0,0 @@ -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(); - } -} diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java new file mode 100644 index 0000000..faf0048 --- /dev/null +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java @@ -0,0 +1,288 @@ +package JointFeldmanProtocol; + +import Communication.Network; +import Communication.User; +import ShamirSecretSharing.Polynomial; +import UserInterface.DistributedKeyGenerationUser; +import meerkat.protobuf.DKGMessages; +import org.factcenter.qilin.primitives.Group; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Set; + +/** + * Created by Tzlil on 2/21/2016. + */ +public class DistributedKeyGenerationUserImpl implements DistributedKeyGenerationUser { + protected enum ComplainState{ + Non, Waiting,Disqualified,NonDisqualified + } + + protected final DistributedKeyGeneration dkg; + + protected final BigInteger g; + protected final Group group; + protected final int n; + protected final int t; + protected final int id; + + protected MessageHandler messageHandler; + protected final Polynomial.Point[] shares; + protected final BigInteger[][] commitmentsTable; + protected final boolean[] doneFlags; + protected final User user; + protected final ComplainState[][] complaintsTable; + + protected Set QUAL; // set of all non-disqualified parties + protected BigInteger[] commitments; // public verification values + protected Polynomial.Point share; // final share of the secrete + protected BigInteger y; // final public value + + public DistributedKeyGenerationUserImpl(DistributedKeyGeneration dkg, Network network) { + this.dkg = dkg; + + this.g = dkg.getGenerator(); + this.group = dkg.getGroup(); + this.n = dkg.getN(); + this.t = dkg.getT(); + this.id = dkg.getId(); + + this.messageHandler = new MessageHandler(); + this.shares = new Polynomial.Point[n]; + this.shares[id - 1] = dkg.getShare(id); + this.commitmentsTable = new BigInteger[n][t + 1]; + this.doneFlags = new boolean[n]; + this.user = network.connect(messageHandler); + this.complaintsTable = new ComplainState[n][n]; + for (int i = 0; i < n; i++){ + Arrays.fill(complaintsTable[i],ComplainState.Non); + } + + this.QUAL = null; + this.commitments = null; + this.share = null; + this.y = null; + } + + /** + * 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() { + dkg.broadcastCommitments(user); + dkg.sendSecrets(user); + } + + /** + * stage2 according to the protocol + * Pj verifies all the shares he received + * if check fails for an index i, Pj broadcasts a complaint against Pi. + * Pj broadcasts done message at the end of this stage + */ + protected void stage2(){ + dkg.setShares(shares); + dkg.broadcastComplains(user,commitmentsTable); + //broadcast done message after all complaints + DKGMessages.DoneMessage doneMessage = DKGMessages.DoneMessage.newBuilder().build(); + user.broadcast(DKGMessages.Mail.Type.DONE,doneMessage); + } + + /** + * stage3 according to the protocol + * 1. if more than t players complain against a player Pi he is disqualified. + * otherwise Pi broadcasts the share Sij for each complaining player Pj. + * 2. if any of the revealed shares fails the verification test, player Pi is disqualified. + * set QUAL to be the set of non-disqualified players. + */ + protected void stage3(){ + + dkg.answerAllComplainingPlayers(user,complaintsTable[id - 1]); + + // wait until there is no complaint waiting for answer + for (int i = 0; i < complaintsTable.length; i++){ + for (int j = 0; j < complaintsTable[i].length; j++){ + while (complaintsTable[i][j].equals(ComplainState.Waiting)){ + try { + Thread.sleep(300); + } catch (InterruptedException e) { + // do nothing + } + } + } + } + this.QUAL = dkg.calcQUAL(complaintsTable); + } + + /** + * 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 + */ + protected void stage4(){ + BigInteger[] ys = new BigInteger[n]; + for (int i = 0; i < n; i++){ + ys[i] = commitmentsTable[i][0]; + } + this.y = dkg.calcY(ys,QUAL); + this.commitments = dkg.calcCommitments(commitmentsTable,QUAL); + this.share = dkg.calcShare(shares,QUAL); + } + + @Override + public void run() { + user.getReceiverThread().start(); + stage1(); + while (messageHandler.secretsCounter != n - 1 || messageHandler.commitmentsCounter != n * (t + 1)){ + try { + Thread.sleep(300); + } catch (InterruptedException e) { + // do nothing + } + } + stage2(); + while (messageHandler.doneCounter != n){ + try { + Thread.sleep(300); + } catch (InterruptedException e) { + // do nothing + } + } + stage3(); + stage4(); + user.getReceiverThread().interrupt(); + } + + @Override + public BigInteger[] getCommitments() { + return Arrays.copyOf(commitments, commitments.length); + } + + @Override + public BigInteger getGenerator() { + return g; + } + + @Override + public Group getGroup() { + return group; + } + + @Override + public Polynomial.Point getShare() { + return share; + } + + @Override + public int getID() { + return id; + } + + @Override + public int getN() { + return n; + } + + @Override + public int getT() { + return t; + } + + @Override + public BigInteger getPublicValue() { + return y; + } + + @Override + public Set getQUAL() { + return QUAL; + } + + protected class MessageHandler implements Communication.MessageHandler{ + + public int doneCounter; + public int commitmentsCounter; + public int secretsCounter; + + public MessageHandler() { + this.doneCounter = 0; + this.secretsCounter = 0; + this.commitmentsCounter = 0; + } + + @Override + public void handelComplaintMessage(int sender, boolean isBroadcast, DKGMessages.ComplaintMessage complaintMessage) { + if(isBroadcast) { + int i = sender - 1; + int j = complaintMessage.getId() - 1; + switch (complaintsTable[i][j]) { + case Non: + complaintsTable[i][j] = ComplainState.Waiting; + break; + default: + break; + } + } + } + + @Override + public void handelDoneMessage(int sender, boolean isBroadcast, DKGMessages.DoneMessage doneMessage) { + if(isBroadcast && !doneFlags[sender - 1]) { + doneFlags[sender - 1] = true; + doneCounter++; + } + } + + @Override + public void handelCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage) { + if(isBroadcast){ + int i = sender - 1; + int k = commitmentMessage.getK(); + if(commitmentsTable[i][k] == null){ + commitmentsTable[i][k] = extractCommitment(commitmentMessage); + commitmentsCounter++; + } + } + } + + @Override + public void handelSecretMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage) { + Polynomial.Point secret = extractSecret(secretMessage); + if(!isBroadcast){ + if(shares[sender - 1] == null) { + shares[sender - 1] = secret; + secretsCounter++; + } + }else { + int i = sender; + int j = secret.x.intValue(); + switch (complaintsTable[i - 1][j - 1]){ + case Waiting: + if(dkg.isValidSecret(secret,commitmentsTable[i - 1],j)){ + complaintsTable[i - 1][j - 1] = ComplainState.NonDisqualified; + }else{ + complaintsTable[i - 1][j - 1] = ComplainState.Disqualified; + } + break; + default: + break; + } + } + } + + @Override + public void handelDoubleSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { + + } + + public Polynomial.Point extractSecret(DKGMessages.SecretMessage secretMessage){ + return new Polynomial.Point(secretMessage.getSecret()); + } + + public BigInteger extractCommitment(DKGMessages.CommitmentMessage commitmentMessage){ + return new BigInteger(commitmentMessage.getCommitment().toByteArray()); + } + } +} diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGeneration.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGeneration.java index cf0a429..bd204c8 100644 --- a/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGeneration.java +++ b/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGeneration.java @@ -1,10 +1,13 @@ package SecureDistributedKeyGeneration; import Communication.Network; +import Communication.User; import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; import JointFeldmanProtocol.DistributedKeyGeneration; +import ShamirSecretSharing.Polynomial; import com.google.protobuf.ByteString; import meerkat.protobuf.DKGMessages; +import org.factcenter.qilin.primitives.Group; import org.factcenter.qilin.primitives.concrete.Zpstar; import java.math.BigInteger; @@ -15,54 +18,91 @@ import java.util.Random; */ public class SecureDistributedKeyGeneration extends DistributedKeyGeneration { - VerifiableSecretSharing verifiableSecretSharing; + private VerifiableSecretSharing verifiableSecretSharing; + private final BigInteger h; + private Polynomial.Point[] sharesT; - 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); + public SecureDistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger q, BigInteger g + , BigInteger h, Group group, int id) { + super(t, n, zi, random, q, g, group, id); + this.h = h; + BigInteger r = new BigInteger(q.bitLength(),random).mod(q); + this.verifiableSecretSharing = new VerifiableSecretSharing(t,n,r,random,q,h,group); } @Override - protected void computeAndSendSecrets() { - DKGMessages.SecretMessage[] secretMessages1 = prepareSecretMessages(); - DKGMessages.SecretMessage[] secretMessages2 = verifiableSecretSharing.prepareSecretMessages(); - DKGMessages.DoubleSecretMessage doubleSecretMessage; + public void sendSecret(User user,int j) { + DKGMessages.SecretMessage.Point secret = getShare(j).asMessage();; + DKGMessages.SecretMessage.Point secretT = verifiableSecretSharing.getShare(j).asMessage();; + DKGMessages.DoubleSecretMessage doubleSecretMessage = DKGMessages.DoubleSecretMessage.newBuilder() + .setS1(DKGMessages.SecretMessage.newBuilder().setSecret(secret).build()) + .setS2(DKGMessages.SecretMessage.newBuilder().setSecret(secretT).build()) + .build(); + user.send(j, DKGMessages.Mail.Type.DOUBLE, 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 boolean isValidSecret(int j, BigInteger[] commitments, int i){ + Polynomial.Point secret = shares[j - 1]; + Polynomial.Point secretT = sharesT[j - 1]; + return isValidSecret(secret,secretT,commitments,i); + } + + public boolean isValidSecret(Polynomial.Point secret,Polynomial.Point secretT, BigInteger[] verificationValues, int i){ + BigInteger v = verify(i,verificationValues,group); + BigInteger exp = group.add(group.multiply(g, secret.y),group.multiply(h, secretT.y)); + return exp.equals(v); + } + + public boolean isValidComplaint(Polynomial.Point secret,Polynomial.Point secretT, BigInteger[] commitments + ,BigInteger[] verificationValues, int i){ + return isValidSecret(secret,secretT,verificationValues,i) && !isValidSecret(secret,commitments,i); + } + + /** + * stage4.3 according to the protocol + * if check fails for index i, Pj + */ + public void broadcastComplaints(User user, BigInteger[][] commitmentsTable, boolean stage4){ + if(!stage4){ + broadcastComplains(user,commitmentsTable); + }else{ + for (int j = 1; j <= n ; j++ ){ + if(j != id) { + if (!isValidSecret(shares[j - 1],commitmentsTable[j - 1],id)) { + broadcastDoubleSecret(user,shares[j - 1],sharesT[j - 1]); + } + } + } } } - @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(); + + public void broadcastVerificationValues(User user){ + BigInteger[] verificationValues = new BigInteger[t + 1]; + BigInteger[] hBaseCommitments = verifiableSecretSharing.getCommitmentsArray(); + for (int k = 0 ; k < verificationValues.length ; k++){ + verificationValues[k] = group.add(commitmentsArray[k],hBaseCommitments[k]); } - return commitmentMessages; + broadcastCommitments(user,verificationValues); + } + + private void broadcastDoubleSecret(User user ,Polynomial.Point secret, Polynomial.Point secretT){ + DKGMessages.SecretMessage.Point secretMessage = secret.asMessage(); + DKGMessages.SecretMessage.Point secretTMessage = secretT.asMessage(); + DKGMessages.DoubleSecretMessage doubleSecretMessage = DKGMessages.DoubleSecretMessage.newBuilder() + .setS1(DKGMessages.SecretMessage.newBuilder().setSecret(secretMessage).build()) + .setS1(DKGMessages.SecretMessage.newBuilder().setSecret(secretTMessage).build()) + .build(); + user.broadcast(DKGMessages.Mail.Type.DOUBLE, doubleSecretMessage); } @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(); + public void broadcastComplaintAnswer(User user, int j) { + broadcastDoubleSecret(user,getShare(j),verifiableSecretSharing.getShare(j)); + } - user.broadcast(DKGMessages.Mail.Type.SECRET, DKGMessages.DoubleSecretMessage.newBuilder() - .setS1(secretMessage1) - .setS2(secretMessage2) - .build()); + public void setSharesT(Polynomial.Point[] sharesT) { + this.sharesT = sharesT; } } diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationMessageHandler.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationMessageHandler.java deleted file mode 100644 index 034f89c..0000000 --- a/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationMessageHandler.java +++ /dev/null @@ -1,61 +0,0 @@ -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; - } - } - } - - -} diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationUserImpl.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationUserImpl.java new file mode 100644 index 0000000..02ae13e --- /dev/null +++ b/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationUserImpl.java @@ -0,0 +1,138 @@ +package SecureDistributedKeyGeneration; + +import Communication.Network; +import JointFeldmanProtocol.DistributedKeyGenerationUserImpl; +import ShamirSecretSharing.Polynomial; +import meerkat.protobuf.DKGMessages; + +import java.math.BigInteger; + +/** + * Created by Tzlil on 2/22/2016. + */ +public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenerationUserImpl { + + private final SecureDistributedKeyGeneration sdkg; + + private final Polynomial.Point[] sharesT; + private final BigInteger[][] verificationValuesTable; + + public SecureDistributedKeyGenerationUserImpl(SecureDistributedKeyGeneration sdkg, Network network) { + super(sdkg, network); + this.sdkg = sdkg; + this.sharesT = new Polynomial.Point[n]; + this.verificationValuesTable = new BigInteger[n][t + 1]; + this.messageHandler = new MessageHandler(); + this.user.setMessageHandler(this.messageHandler); + } + + /** + * stage1 according to the protocol + * 1. Pi broadcasts Cik=Aik*Bik for k = 0,...,t. + * 2. Pi computes the shares Sij,Sij' for j = 1,...,n and sends Sij,Sij' secretly to Pj. + */ + @Override + protected void stage1() { + sdkg.broadcastVerificationValues(user); + sdkg.sendSecrets(user); + } + + /** + * stage2 according to the protocol + * Pj verifies all the shares,sharesT he received + * if check fails for an index i, Pj broadcasts a complaint against Pi. + * Pj broadcasts done message at the end of this stage + */ + @Override + protected void stage2(){ + sdkg.setShares(shares); + sdkg.setSharesT(sharesT); + sdkg.broadcastComplains(user,verificationValuesTable); + //broadcast done message after all complaints + DKGMessages.DoneMessage doneMessage = DKGMessages.DoneMessage.newBuilder().build(); + user.broadcast(DKGMessages.Mail.Type.DONE,doneMessage); + } + + private void ys(){ + sdkg.broadcastCommitments(user); + //wait for receive all commitments from all i in QUAL + for (int i:QUAL) { + for(int k = 0; k <= t; k++) { + while (commitmentsTable[i - 1][k] == null) { + try { + Thread.sleep(300); + } catch (InterruptedException e) { + // do nothing + } + } + } + } + sdkg.broadcastComplaints(user,commitmentsTable,true); + //do something with complaints' answers + + } + + @Override + protected void stage4() { + ys(); + super.stage4(); + } + + private class MessageHandler extends DistributedKeyGenerationUserImpl.MessageHandler{ + + final int NumberOfCommitmentsInStage1 = n * (t + 1); + + @Override + public void handelCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage) { + if(isBroadcast){ + if(commitmentsCounter < NumberOfCommitmentsInStage1){ + int i = sender - 1; + int k = commitmentMessage.getK(); + if(verificationValuesTable[i][k] == null){ + verificationValuesTable[i][k] = extractCommitment(commitmentMessage); + commitmentsCounter++; + } + } else{ + super.handelCommitmentMessage(sender,isBroadcast,commitmentMessage); + } + } + } + + @Override + public void handelSecretMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage) { + //there is no secret message in this protocol + } + + @Override + public void handelDoubleSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { + + Polynomial.Point secret = extractSecret(doubleSecretMessage.getS1()); + Polynomial.Point secretT = extractSecret(doubleSecretMessage.getS2()); + if(!isBroadcast){ + if(shares[sender - 1] == null) { + shares[sender - 1] = secret; + sharesT[sender - 1] = secretT; + secretsCounter++; + } + }else { + if(commitmentsCounter <= NumberOfCommitmentsInStage1) { + int i = sender; + int j = secret.x.intValue(); + switch (complaintsTable[i - 1][j - 1]) { + case Waiting: + if (sdkg.isValidSecret(secret,secretT, verificationValuesTable[j - 1], i)) { + complaintsTable[i - 1][j - 1] = ComplainState.NonDisqualified; + } else { + complaintsTable[i - 1][j - 1] = ComplainState.Disqualified; + } + break; + default: + break; + } + }else{ // stage4 + + } + } + } + } +} diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java index de6b847..7dc0bca 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java @@ -12,13 +12,11 @@ import java.util.Random; * Created by Tzlil on 1/27/2016. * an implementation of Shamire's secret sharing scheme */ -public class SecretSharing implements Runnable{ +public class SecretSharing{ protected final int t; protected final int n; protected final BigInteger q; - - protected final User user; // send and receive messages throw network - private final Polynomial polynomial; + protected final Polynomial polynomial; /** * constructor @@ -29,16 +27,11 @@ public class SecretSharing implements Runnable{ * @param x secret, chosen from Zq * @param random use for generate random polynomial */ - 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) { + public SecretSharing(int t, int n, BigInteger x, Random random, BigInteger q) { this.q = q; this.t = t; this.n = n; this.polynomial = generateRandomPolynomial(x,random); - this.user = user; } /** @@ -73,7 +66,7 @@ public class SecretSharing implements Runnable{ * * @return image of interpolation(shares) at x = 0 */ - public static BigInteger getSecrete(Polynomial.Point[] shares) throws Exception { + public static BigInteger restoreSecrete(Polynomial.Point[] shares) throws Exception { Polynomial polynomial = Polynomial.interpolation(shares); return polynomial.image(BigInteger.ZERO); } @@ -102,31 +95,12 @@ public class SecretSharing implements Runnable{ return q; } - public Polynomial getPolynomial() { + /** + * getter + * @return the polynomial was generated in constructor + */ + public Polynomial getPolynomial() { 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(); - } } diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharingMessageHandler.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharingMessageHandler.java deleted file mode 100644 index 6230c05..0000000 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharingMessageHandler.java +++ /dev/null @@ -1,47 +0,0 @@ -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; - } -} diff --git a/destributed-key-generation/src/main/java/UserInterface/DistributedKeyGenerationUser.java b/destributed-key-generation/src/main/java/UserInterface/DistributedKeyGenerationUser.java new file mode 100644 index 0000000..d8eb5ef --- /dev/null +++ b/destributed-key-generation/src/main/java/UserInterface/DistributedKeyGenerationUser.java @@ -0,0 +1,13 @@ +package UserInterface; + +import java.math.BigInteger; +import java.util.Set; + +/** + * Created by Tzlil on 2/21/2016. + */ +public interface DistributedKeyGenerationUser extends VerifiableSecretSharingUser { + + BigInteger getPublicValue(); + Set getQUAL(); +} diff --git a/destributed-key-generation/src/main/java/UserInterface/SecretSharingUser.java b/destributed-key-generation/src/main/java/UserInterface/SecretSharingUser.java new file mode 100644 index 0000000..dc4a6e4 --- /dev/null +++ b/destributed-key-generation/src/main/java/UserInterface/SecretSharingUser.java @@ -0,0 +1,14 @@ +package UserInterface; + +import ShamirSecretSharing.Polynomial; + +/** + * Created by Tzlil on 2/21/2016. + */ +public interface SecretSharingUser extends Runnable { + + Polynomial.Point getShare(); + int getID(); + int getN(); + int getT(); +} diff --git a/destributed-key-generation/src/main/java/UserInterface/VerifiableSecretSharingUser.java b/destributed-key-generation/src/main/java/UserInterface/VerifiableSecretSharingUser.java new file mode 100644 index 0000000..79cd404 --- /dev/null +++ b/destributed-key-generation/src/main/java/UserInterface/VerifiableSecretSharingUser.java @@ -0,0 +1,16 @@ +package UserInterface; + +import UserInterface.SecretSharingUser; +import org.factcenter.qilin.primitives.Group; + +import java.math.BigInteger; + +/** + * Created by Tzlil on 2/21/2016. + */ +public interface VerifiableSecretSharingUser extends SecretSharingUser { + + BigInteger[] getCommitments(); + BigInteger getGenerator(); + Group getGroup(); +} diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java index f773237..fff8952 100644 --- a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java +++ b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java @@ -2,6 +2,7 @@ package FeldmanVerifiableSecretSharing; import Communication.Network; import ShamirSecretSharing.Polynomial; +import org.factcenter.qilin.primitives.Group; import org.factcenter.qilin.primitives.concrete.Zpstar; import org.junit.Before; import org.junit.Test; @@ -32,21 +33,19 @@ public class VerifiableSecretSharingTest { }while (!g.equals(ZERO) && !zpstar.multiply(g,q).equals(ZERO));// sample from QRZp* int t = 8; int n = 20; - Network network; verifiableSecretSharingArray = new VerifiableSecretSharing[tests]; for (int i = 0; i < verifiableSecretSharingArray.length; i++){ - network = new Network(n); verifiableSecretSharingArray[i] = new VerifiableSecretSharing(t,n - ,new BigInteger(q.bitLength(),random).mod(q),random,p,q,g,network); + ,new BigInteger(q.bitLength(),random).mod(q),random,q,g,zpstar); } } public void oneTest(VerifiableSecretSharing verifiableSecretSharing) throws Exception { int n = verifiableSecretSharing.getN(); - Zpstar zpstar = verifiableSecretSharing.getZpstar(); + Group zpstar = verifiableSecretSharing.getGroup(); BigInteger g = verifiableSecretSharing.getGenerator(); Polynomial.Point[] shares = new Polynomial.Point[n]; - BigInteger[] commitments = verifiableSecretSharing.getCommitments(); + BigInteger[] commitments = verifiableSecretSharing.getCommitmentsArray(); BigInteger[] verifications = new BigInteger[n]; for (int i = 1 ; i <= shares.length; i ++){ shares[i - 1] = verifiableSecretSharing.getShare(i); diff --git a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java index 9171f3d..4000ec0 100644 --- a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java +++ b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java @@ -4,13 +4,13 @@ import Communication.Network; import ShamirSecretSharing.Polynomial; import ShamirSecretSharing.SecretSharing; import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; +import UserInterface.DistributedKeyGenerationUser; +import org.factcenter.qilin.primitives.Group; import org.factcenter.qilin.primitives.concrete.Zpstar; import org.junit.Before; import org.junit.Test; import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; import java.util.Random; /** @@ -19,7 +19,7 @@ import java.util.Random; public class DKGTest { - DistributedKeyGeneration[][] dkgsArrays; + DistributedKeyGenerationUser[][] dkgsArrays; Thread[][] threadsArrays; int tests = 10; BigInteger p = BigInteger.valueOf(2903); @@ -33,9 +33,10 @@ public class DKGTest { int t = 9; int n = 20; BigInteger ZERO = zpstar.zero(); - dkgsArrays = new DistributedKeyGeneration[tests][n]; + dkgsArrays = new DistributedKeyGenerationUserImpl[tests][n]; threadsArrays = new Thread[tests][n]; secrets = new BigInteger[tests]; + DistributedKeyGeneration dkg; for (int test = 0; test < tests; test++) { do { g = zpstar.sample(random); @@ -45,13 +46,14 @@ public class DKGTest { for (int i = 0; i < n; i++) { BigInteger secret = new BigInteger(q.bitLength(), random).mod(q); secrets[test] = secrets[test].add(secret).mod(q); - dkgsArrays[test][i] = new DistributedKeyGeneration(t, n,secret, random, p, q, g, network); + dkg = new DistributedKeyGeneration(t,n,secret,random,q,g,zpstar,i + 1); + dkgsArrays[test][i] = new DistributedKeyGenerationUserImpl(dkg,network); threadsArrays[test][i] = new Thread(dkgsArrays[test][i]); } } } - public void oneTest(Thread[] threads, DistributedKeyGeneration[] dkgs,BigInteger secret) throws Exception { + public void oneTest(Thread[] threads, DistributedKeyGenerationUser[] dkgs,BigInteger secret) throws Exception { for (int i = 0; i < threads.length ; i++){ threads[i].start(); } @@ -61,15 +63,16 @@ public class DKGTest { int t = dkgs[0].getT(); int n = dkgs[0].getN(); - Zpstar zpstar = dkgs[0].getZpstar(); + Group zpstar = dkgs[0].getGroup(); BigInteger g = dkgs[0].getGenerator(); // got the right public value - assert(zpstar.multiply(g,secret).equals(dkgs[0].getY())); + BigInteger publicValue = dkgs[0].getPublicValue(); + assert(zpstar.multiply(g,secret).equals(publicValue)); // assert all players agreed on the same public value for (int i = 0; i < dkgs.length - 1 ; i++){ - assert (dkgs[i].getY().equals(dkgs[i+1].getY())); + assert (dkgs[i].getPublicValue().equals(dkgs[i+1].getPublicValue())); } // assert valid verification values @@ -96,19 +99,13 @@ public class DKGTest { // 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()); - } - + BigInteger calculatedSecret = SecretSharing.restoreSecrete(shares).mod(q); assert (calculatedSecret.equals(secret)); } @Test - public void secretSharingTest() throws Exception { + public void DKGTest() throws Exception { for (int i = 0 ; i < dkgsArrays.length; i ++){ oneTest(threadsArrays[i],dkgsArrays[i],secrets[i]); } diff --git a/destributed-key-generation/src/test/java/SDKGTest.java b/destributed-key-generation/src/test/java/SDKGTest.java new file mode 100644 index 0000000..09bfc2e --- /dev/null +++ b/destributed-key-generation/src/test/java/SDKGTest.java @@ -0,0 +1,113 @@ +import Communication.Network; +import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; +import SecureDistributedKeyGeneration.SecureDistributedKeyGeneration; +import SecureDistributedKeyGeneration.SecureDistributedKeyGenerationUserImpl; +import ShamirSecretSharing.Polynomial; +import ShamirSecretSharing.SecretSharing; +import UserInterface.DistributedKeyGenerationUser; +import org.factcenter.qilin.primitives.Group; +import org.factcenter.qilin.primitives.concrete.Zpstar; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 2/23/2016. + */ +public class SDKGTest { + + DistributedKeyGenerationUser[][] sdkgsArrays; + Thread[][] threadsArrays; + int tests = 10; + BigInteger p = BigInteger.valueOf(2903); + BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); + BigInteger[] secrets; + @Before + public void settings(){ + Zpstar zpstar = new Zpstar(p); + Random random = new Random(); + BigInteger g,h; + int t = 9; + int n = 20; + BigInteger ZERO = zpstar.zero(); + sdkgsArrays = new SecureDistributedKeyGenerationUserImpl[tests][n]; + threadsArrays = new Thread[tests][n]; + secrets = new BigInteger[tests]; + SecureDistributedKeyGeneration sdkg; + for (int test = 0; test < tests; test++) { + do { + g = zpstar.sample(random); + } while (!g.equals(ZERO) && !zpstar.multiply(g, q).equals(ZERO));// sample from QRZp* + h = zpstar.multiply(g,BigInteger.valueOf(2)); + secrets[test] = BigInteger.ZERO; + Network network = new Network(n); + for (int i = 0; i < n; i++) { + BigInteger secret = new BigInteger(q.bitLength(), random).mod(q); + secrets[test] = secrets[test].add(secret).mod(q); + sdkg = new SecureDistributedKeyGeneration(t,n,secret,random,q,g,h,zpstar,i + 1); + sdkgsArrays[test][i] = new SecureDistributedKeyGenerationUserImpl(sdkg,network); + threadsArrays[test][i] = new Thread(sdkgsArrays[test][i]); + } + } + } + + public void oneTest(Thread[] threads, DistributedKeyGenerationUser[] dkgs,BigInteger secret) throws Exception { + for (int i = 0; i < threads.length ; i++){ + threads[i].start(); + } + for (int i = 0; i < threads.length ; i++){ + threads[i].join(); + } + int t = dkgs[0].getT(); + int n = dkgs[0].getN(); + + Group zpstar = dkgs[0].getGroup(); + BigInteger g = dkgs[0].getGenerator(); + + // got the right public value + BigInteger publicValue = dkgs[0].getPublicValue(); + assert(zpstar.multiply(g,secret).equals(publicValue)); + + // assert all players agreed on the same public value + for (int i = 0; i < dkgs.length - 1 ; i++){ + assert (dkgs[i].getPublicValue().equals(dkgs[i+1].getPublicValue())); + } + + // 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 indexes = new ArrayList(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.restoreSecrete(shares).mod(q); + assert (calculatedSecret.equals(secret)); + + } + + @Test + public void SDKGTest() throws Exception { + for (int i = 0 ; i < sdkgsArrays.length; i ++){ + oneTest(threadsArrays[i],sdkgsArrays[i],secrets[i]); + } + } +} diff --git a/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java b/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java index 02b8898..8c73ee0 100644 --- a/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java +++ b/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java @@ -1,7 +1,6 @@ package ShamirSecretSharing; import Communication.Network; -import Communication.User; import org.factcenter.qilin.primitives.CyclicGroup; import org.factcenter.qilin.primitives.concrete.Zn; import org.junit.Before; @@ -26,18 +25,17 @@ public class SecretSharingTest { @Before public void settings(){ BigInteger p = BigInteger.valueOf(2903); + BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); group = new Zn(p); int t = 9; int n = 20; random = new Random(); secretSharingArray = new SecretSharing[tests]; secrets = new BigInteger[tests]; - Network network; for (int i = 0; i < secretSharingArray.length; i++){ secrets[i] = group.sample(random); - network = new Network(n); - secretSharingArray[i] = new SecretSharing(t,n,secrets[i],random,p,network); + secretSharingArray[i] = new SecretSharing(t,n,secrets[i],random,q); } } @@ -52,7 +50,7 @@ public class SecretSharingTest { for (int i = 0 ; i < shares.length ; i++){ shares[i] = secretSharing.getShare(indexes.remove(random.nextInt(indexes.size()))); } - assert(secret.equals(SecretSharing.getSecrete(shares))); + assert(secret.equals(SecretSharing.restoreSecrete(shares))); } @Test diff --git a/meerkat-common/src/main/proto/meerkat/DKGMessages.proto b/meerkat-common/src/main/proto/meerkat/DKGMessages.proto index c01b004..4fbc4da 100644 --- a/meerkat-common/src/main/proto/meerkat/DKGMessages.proto +++ b/meerkat-common/src/main/proto/meerkat/DKGMessages.proto @@ -10,6 +10,7 @@ message Mail{ COMMITMENT = 1; DONE = 2; COMPLAINT = 3; + DOUBLE = 4; } int32 sender = 1; int32 destination = 2;