From 8288b07d8001ca6748562f187b6f9c5905cab539 Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Mon, 8 Feb 2016 15:20:43 +0200 Subject: [PATCH] joint feldman with protos --- .../ShamirSecretSharing/Polynomial.java | 23 +- .../ShamirSecretSharing/SecretSharing.java | 6 +- .../VerifiableSecretSharing.java | 34 +-- .../main/java/JointFeldmanProtocol/DKG.java | 262 ++++++++++++++---- .../java/JointFeldmanProtocol/Network.java | 90 +++--- .../src/main/proto/meerkat/DKGMessages.proto | 40 +++ 6 files changed, 310 insertions(+), 145 deletions(-) create mode 100644 meerkat-common/src/main/proto/meerkat/DKGMessages.proto diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java index e285e01..30a56ed 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java @@ -1,7 +1,8 @@ package FeldmanVerifiableSecretSharing.ShamirSecretSharing; +import com.google.protobuf.ByteString; +import meerkat.protobuf.DKGMessages; import org.bouncycastle.util.Arrays; - import java.math.BigInteger; /** @@ -172,7 +173,7 @@ public class Polynomial implements Comparable { * inner class * container for (x,y) x from range and y from image of polynomial */ - public static class Point{ + public static class Point implements java.io.Serializable { public final BigInteger x; public final BigInteger y; @@ -199,13 +200,21 @@ public class Polynomial implements Comparable { } /** - * copy constructor - * @param point + * constructor - restore point from message + * @param pointMessage */ - public Point(Point point) { - this.x = point.x; - this.y = point.y; + public Point(DKGMessages.SecretMessage.Point pointMessage) { + this.x = new BigInteger(pointMessage.getX().toByteArray()); + this.y = new BigInteger(pointMessage.getY().toByteArray()); } + + public DKGMessages.SecretMessage.Point asMessage(){ + return DKGMessages.SecretMessage.Point.newBuilder() + .setX(ByteString.copyFrom(x.toByteArray())) + .setY(ByteString.copyFrom(y.toByteArray())) + .build(); + } + } } diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java index 0559a7c..ebed7a2 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java @@ -9,9 +9,9 @@ import java.util.Random; * an implementation of Shamire's secret sharing scheme */ public class SecretSharing { - private final int t; - private final int n; - private final BigInteger q; + protected final int t; + protected final int n; + protected final BigInteger q; private final Polynomial polynomial; diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java index e8d5c98..eb3dc07 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java @@ -18,10 +18,10 @@ import java.util.Random; * */ public class VerifiableSecretSharing extends SecretSharing { - private final Zpstar zpstar; - private final BigInteger g; // public generator of group - private final BigInteger[] commitments; + protected final Zpstar zpstar; + protected final BigInteger g; // public generator of group private final BigInteger y; // y = g ^ x + private final BigInteger[] commitments; /** * @param p a large prime @@ -55,19 +55,19 @@ public class VerifiableSecretSharing extends SecretSharing { } /** - * @param i share holder id + * @param j share holder id * @param commitments * @param zpstar * * @return product of commitments[j] ^ (i ^ j) == g ^ polynomial(i) */ - public static BigInteger verify(int i,BigInteger[] commitments,Zpstar zpstar) { + public static BigInteger verify(int j,BigInteger[] commitments,Zpstar zpstar) { BigInteger v = zpstar.zero(); BigInteger power = BigInteger.ONE; - BigInteger I = BigInteger.valueOf(i); - for (int j = 0 ; j < commitments.length ; j ++){ - v = zpstar.add(v,zpstar.multiply(commitments[j],power)); - power = power.multiply(I); + BigInteger J = BigInteger.valueOf(j); + for (int k = 0 ; k < commitments.length ; k ++){ + v = zpstar.add(v,zpstar.multiply(commitments[k],power)); + power = power.multiply(J); } return v; } @@ -81,14 +81,6 @@ public class VerifiableSecretSharing extends SecretSharing { return g; } - /** - * getter - * @return copy of commitments - */ - public BigInteger[] getCommitments() { - return Arrays.clone(commitments); - } - /** * getter * @return zpstar @@ -104,4 +96,12 @@ public class VerifiableSecretSharing extends SecretSharing { public BigInteger getY(){ return y; } + + /** + * getter + * @return copy of commitments + */ + public BigInteger[] getCommitments() { + return Arrays.clone(commitments); + } } diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java index 49a6f17..dcd12fa 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java @@ -2,8 +2,10 @@ 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 org.factcenter.qilin.primitives.concrete.Zpstar; +import meerkat.protobuf.DKGMessages.*; import java.math.BigInteger; import java.util.HashSet; @@ -18,10 +20,12 @@ import java.util.Set; public class DKG extends VerifiableSecretSharing implements Runnable{ private Network.User user; - private Handler handler; + private Network.MailHandler handler; private Polynomial.Point[] shares; + private Polynomial.Point[] myshares; private BigInteger[][] commitmentsArray; private BigInteger[] ys; + final ComplainState[][] complainStates; private Set QUAL; private BigInteger x; @@ -30,34 +34,47 @@ public class DKG extends VerifiableSecretSharing implements Runnable{ 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.myshares = new Polynomial.Point[n]; this.handler = new Handler(); this.user = network.connect(handler); + this.complainStates = new ComplainState[n][n]; + + for (int i = 0; i < n; i ++){ + for (int j = 0 ; j < n ; j ++) + complainStates[i][j] = ComplainState.Non; + } + } 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.CommitmentMessage commitment; - for (int j = 1; j <= commitmentsArray[i - 1].length; j ++){ - commitment = new Network.CommitmentMessage(j,commitmentsArray[i - 1][j - 1]); - user.broadcast(commitment); + CommitmentMessage commitment; + for (int k = 1; k <= commitmentsArray[i - 1].length; k ++){ + commitment = CommitmentMessage.newBuilder() + .setK(k) + .setCommitment(ByteString.copyFrom(commitmentsArray[i - 1][k - 1].toByteArray())) + .build(); + user.broadcast(Mail.Type.COMMITMENT,commitment); } - Network.SecretMessage secret; + SecretMessage secret; for (int j = 1; j <= n ; j++ ){ if(j != i){ - secret = new Network.SecretMessage(getShare(j)); - user.send(j,secret); + myshares[j - 1] = super.getShare(j); + secret = SecretMessage.newBuilder() + .setSecret(myshares[j - 1].asMessage()) + .build(); + user.send(j, Mail.Type.SECRET,secret); } } - while (handler.secretsCounter < n - 1 || handler.commitmentsCounter < (n - 1) * (t + 1)){ + while (!isStage1Complete()){ try { Thread.sleep(30); } catch (InterruptedException e) { @@ -66,41 +83,112 @@ public class DKG extends VerifiableSecretSharing implements Runnable{ } } + private boolean isStage1Complete(){ + int id = user.getID(); + for (int j = 1 ; j <= n ; j++){ + if(id != j && shares[j - 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; + } + + private boolean isValidSecret(Polynomial.Point secret, int i){ + int j = secret.x.intValue(); + return zpstar.multiply(g,secret.y).equals(verify(j,commitmentsArray[i],zpstar)); + } + private void stage2(){ - int n = getN(); - BigInteger g = getGenerator(); - Zpstar zpstar = getZpstar(); - int i = user.getID(); + int j = user.getID(); QUAL = new HashSet(); - Network.Message message = null; - for (int j = 1; j <= n ; j++ ){ - if(zpstar.multiply(g,shares[j - 1].y).equals(verify(j,commitmentsArray[j],zpstar))){ - QUAL.add(j); + ComplaintMessage complaint; + for (int i = 1; i <= n ; i++ ){ + if(isValidSecret(shares[i - 1],j)) { + QUAL.add(i); }else{ //message = new Message(Type.Complaint, j) - user.broadcast(message); + complaint = ComplaintMessage.newBuilder() + .setId(i) + .build(); + user.broadcast(Mail.Type.COMPLAINT,complaint); + complainStates[j - 1][i - 1] = ComplainState.Waiting; } } //sending y after Complaints - Network.YMessage yMessage = new Network.YMessage(super.getY()); - user.broadcast(yMessage); - } + YMessage yMessage = YMessage.newBuilder() + .setY(ByteString.copyFrom(super.getY().toByteArray())) + .build(); + user.broadcast(Mail.Type.Y,yMessage); - private void stage3(){ - int n = getN(); - while (handler.ysCounter < n - 1 ){ + while (!isStage2Complete()){ try { Thread.sleep(30); } catch (InterruptedException e) { // do nothing } } - //Todo receive something private from each complaint + send what necessary + } + + private boolean isStage2Complete() { + int id = user.getID(); + for (int j = 1; j <= n ; j++) { + if (id != j && ys[j - 1] == null) + return false; + } + for (int i = 0; i < complainStates.length;i++){ + for (int j =0 ; j < complainStates[i].length;j++){ + switch (complainStates[i][j]){ + case Waiting: + return false; + default: + break; + } + } + } + return true; + } + + private void stage3(){ + for (int i = 0; i < complainStates.length;i++){ + ComplainState state = ComplainState.Non; + for (int j = 0 ; j < complainStates[i].length;j++){ + switch (complainStates[i][j]){ + case Disqualified: + state = ComplainState.Disqualified; + break; + case NonDisqualified: + if(state == ComplainState.Non){ + state = ComplainState.NonDisqualified; + } + break; + default: + break; + } + } + switch (state){ + case Disqualified: + if(QUAL.contains(i + 1)){ + QUAL.remove(i + 1); + } + break; + case NonDisqualified: + if (!QUAL.contains(i + 1)){ + QUAL.add(i + 1); + } + break; + default: + break; + } + } } private void stage4(){ - int t = getT(); - Zpstar zpstar = getZpstar(); BigInteger y = zpstar.zero(); for (int i : QUAL) { y = zpstar.add(y , ys[i - 1]); @@ -120,7 +208,7 @@ public class DKG extends VerifiableSecretSharing implements Runnable{ for (int i : QUAL) { x = x.add(shares[i - 1].y); } - this.x = x.mod(getQ()); + this.x = x.mod(q); } @Override @@ -146,45 +234,101 @@ public class DKG extends VerifiableSecretSharing implements Runnable{ stage4(); } + private enum ComplainState{ + Non, Waiting,Disqualified,NonDisqualified + } + 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 ++; + 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][j]){ + case Waiting: + if(isValidSecret(secret,i)){ + complainStates[i][j] = ComplainState.NonDisqualified; + }else{ + complainStates[i][j] = 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 { + if(!mail.getIsPrivate()) { //broadcast only + ComplaintMessage complaintMessage = ComplaintMessage.parseFrom(mail.getMessage()); + int i = complaintMessage.getId(); + int j = mail.getSender(); + if(i == id){ + user.broadcast(Mail.Type.SECRET,SecretMessage.newBuilder() + .setSecret(myshares[j].asMessage()) + .build()); + }else{ + 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; + } + } } } diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java index 8468d2d..3cc3c85 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java @@ -1,9 +1,8 @@ package JointFeldmanProtocol; -import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; - -import java.lang.reflect.Type; -import java.math.BigInteger; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; +import meerkat.protobuf.DKGMessages.*; import java.util.Queue; import java.util.concurrent.ArrayBlockingQueue; /** @@ -32,24 +31,38 @@ public class Network { return new User(id,messageHandler); } - private boolean sendMessage(User sender,int destination,Message message){ + 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; - return user.mailbox.add(new Mail(sender.ID,false,message)); + 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,Message message){ + 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(new Mail(ID,true,message)); + user.mailbox.add(mail); } } @@ -66,14 +79,12 @@ public class Network { thread.run(); } - - public boolean send(int id, Message message){ - return sendMessage(this,id,message); + public boolean send(int id, Mail.Type type,Message message){ + return sendMessage(this,id,type,message); } - public void broadcast(Message message){ - sendBroadcast(this,message); + public void broadcast(Mail.Type type,Message message){ + sendBroadcast(this,type,message); } - public int getID() { return ID; } @@ -83,7 +94,11 @@ public class Network { public void run() { while (true){ if (!mailbox.isEmpty()){ - messageHandler.handel(mailbox.poll()); + try { + messageHandler.handel(mailbox.poll()); + } catch (InvalidProtocolBufferException e) { + e.printStackTrace(); + } }else{ try { Thread.sleep(30); @@ -98,50 +113,7 @@ public class Network { } - 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); + public void handel(Mail mail) throws InvalidProtocolBufferException; } } diff --git a/meerkat-common/src/main/proto/meerkat/DKGMessages.proto b/meerkat-common/src/main/proto/meerkat/DKGMessages.proto new file mode 100644 index 0000000..e874f5a --- /dev/null +++ b/meerkat-common/src/main/proto/meerkat/DKGMessages.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; + +package meerkat; + +option java_package = "meerkat.protobuf"; + +message Mail{ + enum Type { + SECRET = 0; + COMMITMENT = 1; + Y = 2; + COMPLAINT = 3; + } + int32 sender = 1; + int32 destination = 2; + bool isPrivate = 3; + Type type = 4; + bytes message = 5; +} + +message SecretMessage { + message Point{ + bytes x = 1; + bytes y = 2; + } + Point secret = 1; +} + +message CommitmentMessage{ + int32 k = 1; + bytes commitment = 2; +} + +message YMessage{ + bytes y = 1; +} + +message ComplaintMessage{ + int32 id = 1; +} \ No newline at end of file