SDKG tested for non coruppted parties

DKG
tzlil.gon 2016-02-23 19:02:49 +02:00
parent 210cc327ac
commit 0f7dbe3d50
20 changed files with 842 additions and 608 deletions

View File

@ -9,14 +9,10 @@ import meerkat.protobuf.DKGMessages;
public class MailHandler { public class MailHandler {
private MessageHandler messageHandler; private MessageHandler messageHandler;
public MailHandler(MessageHandler messageHandler){ public MailHandler(MessageHandler messageHandler){
this.messageHandler = messageHandler; this.messageHandler = messageHandler;
} }
public MessageHandler getMessageHandler(){
return messageHandler;
}
public void handel(DKGMessages.Mail mail) throws InvalidProtocolBufferException { public void handel(DKGMessages.Mail mail) throws InvalidProtocolBufferException {
switch (mail.getType()){ switch (mail.getType()){
@ -36,8 +32,20 @@ public class MailHandler {
DKGMessages.ComplaintMessage complaintMessage = DKGMessages.ComplaintMessage.parseFrom(mail.getMessage()); DKGMessages.ComplaintMessage complaintMessage = DKGMessages.ComplaintMessage.parseFrom(mail.getMessage());
messageHandler.handelComplaintMessage(mail.getSender(),mail.getDestination()== Network.BROADCAST,complaintMessage); messageHandler.handelComplaintMessage(mail.getSender(),mail.getDestination()== Network.BROADCAST,complaintMessage);
break; break;
case DOUBLE:
DKGMessages.DoubleSecretMessage doubleSecretMessage = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage());
messageHandler.handelDoubleSecretMessage(mail.getSender(),mail.getDestination()== Network.BROADCAST,doubleSecretMessage);
default: default:
break; break;
} }
} }
public MessageHandler getMessageHandler(){
return messageHandler;
}
public void setMessageHandler(MessageHandler messageHandler) {
this.messageHandler = messageHandler;
}
} }

View File

@ -33,8 +33,8 @@ public class User{
network.sendBroadcast(this,type,message); network.sendBroadcast(this,type,message);
} }
public MessageHandler getMessageHandler(){ public void setMessageHandler(MessageHandler messageHandler) {
return mailHandler.getMessageHandler(); mailHandler.setMessageHandler(messageHandler);
} }
public int getID() { public int getID() {

View File

@ -1,12 +1,11 @@
package FeldmanVerifiableSecretSharing; package FeldmanVerifiableSecretSharing;
import Communication.Network;
import Communication.User;
import ShamirSecretSharing.Polynomial; import ShamirSecretSharing.Polynomial;
import ShamirSecretSharing.SecretSharing; import ShamirSecretSharing.SecretSharing;
import com.google.protobuf.ByteString;
import meerkat.protobuf.DKGMessages;
import java.util.Arrays; import java.util.Arrays;
import org.factcenter.qilin.primitives.Group;
import org.factcenter.qilin.primitives.concrete.Zpstar; import org.factcenter.qilin.primitives.concrete.Zpstar;
import java.math.BigInteger; import java.math.BigInteger;
@ -21,31 +20,23 @@ import java.util.Random;
* *
*/ */
public class VerifiableSecretSharing extends SecretSharing { public class VerifiableSecretSharing extends SecretSharing {
protected final Zpstar zpstar; protected final Group<BigInteger> group;
protected final BigInteger g; // public generator of group protected final BigInteger g; // public generator of group
private final BigInteger y; // y = g ^ x protected final BigInteger[] commitmentsArray;
protected final BigInteger[] commitments;
/** /**
* @param p a large prime * @param group
* @param q a large prime dividing p - 1. * @param q a large prime dividing group order.
* @param g a generator of cyclic group of order q. * @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. * it must be chosen such that computing discrete logarithms is hard in this group.
*/ */
public VerifiableSecretSharing(int t, int n, BigInteger x, Random random, BigInteger p, BigInteger q, BigInteger g public VerifiableSecretSharing(int t, int n, BigInteger x, Random random, BigInteger q, BigInteger g
, User user) { , Group<BigInteger> group) {
super(t, n, x, random,q,user); super(t, n, x, random,q);
this.g = g; this.g = g;
this.zpstar = new Zpstar(p); this.group = group;
assert (zpstar.contains(g)); assert (this.group.contains(g));
assert (p.subtract(BigInteger.ONE).mod(q).equals(BigInteger.ZERO)); // assert p - 1 % q == 0 this.commitmentsArray = generateCommitments();
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)));
} }
/** /**
@ -57,7 +48,7 @@ public class VerifiableSecretSharing extends SecretSharing {
BigInteger[] coefficients = polynomial.getCoefficients(); BigInteger[] coefficients = polynomial.getCoefficients();
BigInteger[] commitments = new BigInteger[coefficients.length]; BigInteger[] commitments = new BigInteger[coefficients.length];
for (int i = 0 ; i < commitments.length;i++){ for (int i = 0 ; i < commitments.length;i++){
commitments[i] = zpstar.multiply(g,coefficients[i]); commitments[i] = group.multiply(g,coefficients[i]);
} }
return commitments; return commitments;
} }
@ -65,16 +56,16 @@ public class VerifiableSecretSharing extends SecretSharing {
/** /**
* @param j share holder id * @param j share holder id
* @param commitments * @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) { public static BigInteger verify(int j,BigInteger[] commitments,Group<BigInteger> group) {
BigInteger v = zpstar.zero(); BigInteger v = group.zero();
BigInteger power = BigInteger.ONE; BigInteger power = BigInteger.ONE;
BigInteger J = BigInteger.valueOf(j); BigInteger J = BigInteger.valueOf(j);
for (int k = 0 ; k < commitments.length ; k ++){ 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); power = power.multiply(J);
} }
return v; return v;
@ -91,49 +82,18 @@ public class VerifiableSecretSharing extends SecretSharing {
/** /**
* getter * getter
* @return zpstar * @return group
*/ */
public Zpstar getZpstar(){ public Group<BigInteger> getGroup(){
return zpstar; return group;
} }
/** /**
* getter * getter
* @return public value of this * @return copy of commitmentsArray
*/ */
public BigInteger getY(){ public BigInteger[] getCommitmentsArray() {
return y; 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();
}
} }

View File

@ -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];
}
}

View File

@ -1,156 +1,138 @@
package JointFeldmanProtocol; package JointFeldmanProtocol;
import Communication.Network;
import Communication.User; import Communication.User;
import ShamirSecretSharing.Polynomial; import ShamirSecretSharing.Polynomial;
import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; import FeldmanVerifiableSecretSharing.VerifiableSecretSharing;
import com.google.protobuf.ByteString;
import meerkat.protobuf.DKGMessages.*; import meerkat.protobuf.DKGMessages.*;
import org.factcenter.qilin.primitives.concrete.Zpstar; import org.factcenter.qilin.primitives.Group;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.Arrays;
/** /**
* Created by Tzlil on 2/5/2016. * Created by Tzlil on 2/5/2016.
* *
* an implementation of a version of Pedersen's distributed key generation protocol * 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<Integer> QUAL; // set of all non-disqualified parties public DistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger q, BigInteger g
private final BigInteger[] finalCommitments; // public verification values , Group<BigInteger> group, int id) {
super(t, n, zi, random, q, g,group);
private Polynomial.Point share; // final share of the secrete this.id = id;
private BigInteger y; // final public value this.shares = null;
private final DistributedKeyGenerationMessageHandler handler;
public DistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger p, BigInteger q, BigInteger g
, User user) {
super(t, n, zi, random, p, q, g,user);
this.handler = (DistributedKeyGenerationMessageHandler) user.getMessageHandler();
this.id = user.getID();
this.QUAL = new HashSet<Integer>();
this.finalCommitments = new BigInteger[t + 1];
Arrays.fill(this.finalCommitments,zpstar.zero());
}
public DistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger p, BigInteger q, BigInteger g
, Network network) {
this(t,n,zi,random,p,q,g,network.connect(new DistributedKeyGenerationMessageHandler(t,n,g,new Zpstar(p))));
} }
/** /**
* use for simulate real distributed protocol * stage1.1 according to the protocol
* Pi broadcasts Aik for k = 0,...,t.
*/ */
@Override public void broadcastCommitments(User user){
public void run() { broadcastCommitments(user,commitmentsArray);
user.getReceiverThread().start(); }
stage1();
stage2(); public void broadcastCommitments(User user, BigInteger[] commitments){
stage3(); CommitmentMessage commitmentMessage;
stage4(); for (int k = 0; k <= t ; k++){
user.getReceiverThread().interrupt(); 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 * stage1.2 according to the protocol
* 1. Pi broadcasts Aik for k = 0,...,t. * Pi computes the shares Sij for j = 1,...,n and sends Sij secretly to Pj.
* 2. Pi computes the shares Sij for j = 1,...,n and sends Sij secretly to Pj.
*/ */
protected void stage1(){ public void sendSecrets(User user){
super.run(); for (int j = 1; j <= n ; j++){
while (!handler.isStage1Complete()){ if(j != id){
try { sendSecret(user,j);
Thread.sleep(300);
} catch (InterruptedException e) {
// do nothing
} }
} }
} }
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 * stage2 according to the protocol
* Pj verifies all the shares he received (using isValidSecret) * Pj verifies all the shares he received (using isValidSecret)
* if check fails for an index i, Pj broadcasts a complaint against Pi. * 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; ComplaintMessage complaint;
for (int i = 1; i <= n ; i++ ){ for (int j = 1; j <= n ; j++ ){
if(id != i && !handler.isValidSecret(i)) { if(j != id) {
//message = new Message(Type.Complaint, j) if (!isValidSecret(j,commitmentsTable[j - 1],id)) {
complaint = ComplaintMessage.newBuilder() //message = new Message(Type.Complaint, j)
.setId(i) complaint = ComplaintMessage.newBuilder()
.build(); .setId(j)
user.broadcast(Mail.Type.COMPLAINT,complaint); .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
} }
} }
} }
public void broadcastComplaintAnswer(User user, int j){
protected void answerComplaint(int j){
user.broadcast(Mail.Type.SECRET, SecretMessage.newBuilder() user.broadcast(Mail.Type.SECRET, SecretMessage.newBuilder()
.setSecret(getShare(j).asMessage()) .setSecret(getShare(j).asMessage())
.build()); .build());
} }
/** /**
* stage3 according to the protocol * stage3.1 according to the protocol
* 1. if more than t players complain against a player Pi he is disqualified. * if more than t players complain against a player Pi he is disqualified.
* 2. Pi broadcasts the share Sij for each complaining player Pj.
* 3. if any of the revealed shares fails the verification test, player Pi is disqualified.
* 4. set QUAL to be the set of non-disqualified players.
*/ */
private void stage3(){ public void answerAllComplainingPlayers(User user, DistributedKeyGenerationUserImpl.ComplainState[] complains){
DistributedKeyGenerationMessageHandler.ComplainState[][] complainStates = handler.getComplainStates(); for (int j = 1; j <= n ; j++) {
// broadcasts Sij for each complaint against Pid switch (complains[j - 1]) {
for (int j = 1; j <= complainStates[id - 1].length; j++) {
switch (complainStates[id - 1][j - 1]) {
case Waiting: case Waiting:
answerComplaint(j); broadcastComplaintAnswer(user,j);
break; break;
default: default:
break; break;
} }
} }
}
// wait until there is no complaint waiting for answer /**
for (int i = 0; i < complainStates.length; i++){ * stage3.2 according to the protocol
for (int j = 0; j < complainStates[i].length; j++){ * if any of the revealed shares fails the verification test, player Pi is disqualified.
while (complainStates[i][j].equals(DistributedKeyGenerationMessageHandler.ComplainState.Waiting)){ * set QUAL to be the set of non-disqualified players.
try { */
Thread.sleep(300); public Set<Integer> calcQUAL(DistributedKeyGenerationUserImpl.ComplainState[][] complains){
} catch (InterruptedException e) { Set<Integer> QUAL = new HashSet<Integer>();
// do nothing
}
}
}
}
// add each non-disqualified player to QUAL
boolean nonDisqualified; boolean nonDisqualified;
int counter; int counter;
for (int i = 1; i <= complainStates.length; i++){ for (int i = 1; i <= complains.length; i++){
nonDisqualified = true; nonDisqualified = true;
counter = 0; counter = 0;
for (int j = 1; j <= complainStates[i - 1].length; j++){ for (int j = 1; j <= complains[i - 1].length; j++){
switch (complainStates[i - 1][j - 1]) { switch (complains[i - 1][j - 1]) {
case Non: case Non:
break; break;
case NonDisqualified: case NonDisqualified:
@ -165,52 +147,54 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing implements
QUAL.add(i); QUAL.add(i);
} }
} }
return QUAL;
} }
/** /**
* stage4 according to the protocol * stage4.1 according to the protocol
* 1. public value y is computed as y = multiplication of yi mod p for i in QUAL * public value y is computed as y = multiplication of yi mod p for i in QUAL
* 2. public verification values are computed as Ak = multiplication of Aik mod p for i in QUAL for k = 0,...,t
* 3. Pj sets is share of the secret as xj = sum of Sij mod q for i in QUAL
*/ */
private void stage4(){ public BigInteger calcY(BigInteger[] ys,Set<Integer> QUAL){
this.y = zpstar.zero(); BigInteger y = group.zero();
for (int i : QUAL) { 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; return y;
} }
@Override /**
public BigInteger[] getCommitments() { * stage4.2 according to the protocol
return Arrays.copyOf(finalCommitments, finalCommitments.length); * 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<Integer> 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<Integer> 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;
} }
} }

View File

@ -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();
}
}

View File

@ -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<BigInteger> 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<Integer> 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<BigInteger> 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<Integer> 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());
}
}
}

View File

@ -1,10 +1,13 @@
package SecureDistributedKeyGeneration; package SecureDistributedKeyGeneration;
import Communication.Network; import Communication.Network;
import Communication.User;
import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; import FeldmanVerifiableSecretSharing.VerifiableSecretSharing;
import JointFeldmanProtocol.DistributedKeyGeneration; import JointFeldmanProtocol.DistributedKeyGeneration;
import ShamirSecretSharing.Polynomial;
import com.google.protobuf.ByteString; import com.google.protobuf.ByteString;
import meerkat.protobuf.DKGMessages; import meerkat.protobuf.DKGMessages;
import org.factcenter.qilin.primitives.Group;
import org.factcenter.qilin.primitives.concrete.Zpstar; import org.factcenter.qilin.primitives.concrete.Zpstar;
import java.math.BigInteger; import java.math.BigInteger;
@ -15,54 +18,91 @@ import java.util.Random;
*/ */
public class SecureDistributedKeyGeneration extends DistributedKeyGeneration { 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 public SecureDistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger q, BigInteger g
,BigInteger h, Network network) { , BigInteger h, Group<BigInteger> group, int id) {
super(t, n, zi, random, p, q, g, network.connect(new SecureDistributedKeyGenerationMessageHandler(t,n,g,new Zpstar(p)))); super(t, n, zi, random, q, g, group, id);
this.verifiableSecretSharing = new VerifiableSecretSharing(t,n,new BigInteger(q.bitLength(), random).mod(q),random,p,q,h,user); this.h = h;
BigInteger r = new BigInteger(q.bitLength(),random).mod(q);
this.verifiableSecretSharing = new VerifiableSecretSharing(t,n,r,random,q,h,group);
} }
@Override @Override
protected void computeAndSendSecrets() { public void sendSecret(User user,int j) {
DKGMessages.SecretMessage[] secretMessages1 = prepareSecretMessages(); DKGMessages.SecretMessage.Point secret = getShare(j).asMessage();;
DKGMessages.SecretMessage[] secretMessages2 = verifiableSecretSharing.prepareSecretMessages(); DKGMessages.SecretMessage.Point secretT = verifiableSecretSharing.getShare(j).asMessage();;
DKGMessages.DoubleSecretMessage doubleSecretMessage; 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++ ){ @Override
doubleSecretMessage = DKGMessages.DoubleSecretMessage.newBuilder() public boolean isValidSecret(int j, BigInteger[] commitments, int i){
.setS1(secretMessages1[j - 1]) Polynomial.Point secret = shares[j - 1];
.setS1(secretMessages2[j - 1]) Polynomial.Point secretT = sharesT[j - 1];
.build(); return isValidSecret(secret,secretT,commitments,i);
user.send(j, DKGMessages.Mail.Type.SECRET,doubleSecretMessage); }
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() { public void broadcastVerificationValues(User user){
DKGMessages.CommitmentMessage[] commitmentMessages = new DKGMessages.CommitmentMessage[t + 1]; BigInteger[] verificationValues = new BigInteger[t + 1];
BigInteger[] commitments2 = verifiableSecretSharing.getCommitments(); BigInteger[] hBaseCommitments = verifiableSecretSharing.getCommitmentsArray();
for (int k = 0; k <= t ; k ++) { for (int k = 0 ; k < verificationValues.length ; k++){
commitmentMessages[k] = DKGMessages.CommitmentMessage.newBuilder() verificationValues[k] = group.add(commitmentsArray[k],hBaseCommitments[k]);
.setK(k)
.setCommitment(ByteString.copyFrom(zpstar.add(commitments[k],commitments2[k]).toByteArray()))
.build();
} }
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 @Override
protected void answerComplaint(int j) { public void broadcastComplaintAnswer(User user, int j) {
DKGMessages.SecretMessage secretMessage1 = DKGMessages.SecretMessage.newBuilder() broadcastDoubleSecret(user,getShare(j),verifiableSecretSharing.getShare(j));
.setSecret(getShare(j).asMessage()) }
.build();
DKGMessages.SecretMessage secretMessage2 = DKGMessages.SecretMessage.newBuilder()
.setSecret(verifiableSecretSharing.getShare(j).asMessage())
.build();
user.broadcast(DKGMessages.Mail.Type.SECRET, DKGMessages.DoubleSecretMessage.newBuilder() public void setSharesT(Polynomial.Point[] sharesT) {
.setS1(secretMessage1) this.sharesT = sharesT;
.setS2(secretMessage2)
.build());
} }
} }

View File

@ -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;
}
}
}
}

View File

@ -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
}
}
}
}
}

View File

@ -12,13 +12,11 @@ import java.util.Random;
* Created by Tzlil on 1/27/2016. * Created by Tzlil on 1/27/2016.
* an implementation of Shamire's secret sharing scheme * an implementation of Shamire's secret sharing scheme
*/ */
public class SecretSharing implements Runnable{ public class SecretSharing{
protected final int t; protected final int t;
protected final int n; protected final int n;
protected final BigInteger q; protected final BigInteger q;
protected final Polynomial polynomial;
protected final User user; // send and receive messages throw network
private final Polynomial polynomial;
/** /**
* constructor * constructor
@ -29,16 +27,11 @@ public class SecretSharing implements Runnable{
* @param x secret, chosen from Zq * @param x secret, chosen from Zq
* @param random use for generate random polynomial * @param random use for generate random polynomial
*/ */
public SecretSharing(int t, int n, BigInteger x, Random random, BigInteger q, Network network) { public SecretSharing(int t, int n, BigInteger x, Random random, BigInteger q) {
this(t,n,x,random,q,network.connect(new SecretSharingMessageHandler()));
}
public SecretSharing(int t, int n, BigInteger x, Random random, BigInteger q, User user) {
this.q = q; this.q = q;
this.t = t; this.t = t;
this.n = n; this.n = n;
this.polynomial = generateRandomPolynomial(x,random); this.polynomial = generateRandomPolynomial(x,random);
this.user = user;
} }
/** /**
@ -73,7 +66,7 @@ public class SecretSharing implements Runnable{
* *
* @return image of interpolation(shares) at x = 0 * @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); Polynomial polynomial = Polynomial.interpolation(shares);
return polynomial.image(BigInteger.ZERO); return polynomial.image(BigInteger.ZERO);
} }
@ -102,31 +95,12 @@ public class SecretSharing implements Runnable{
return q; return q;
} }
public Polynomial getPolynomial() {
/**
* getter
* @return the polynomial was generated in constructor
*/
public Polynomial getPolynomial() {
return polynomial; return polynomial;
} }
public DKGMessages.SecretMessage[] prepareSecretMessages(){
DKGMessages.SecretMessage[] secretMessages = new DKGMessages.SecretMessage[n];
for (int j = 1; j <= n ; j++ ){
secretMessages[j - 1] = DKGMessages.SecretMessage.newBuilder()
.setSecret(getShare(j).asMessage())
.build();
}
return secretMessages;
}
protected void computeAndSendSecrets(){
DKGMessages.SecretMessage[] secretMessages = prepareSecretMessages();
for (int j = 1; j <= n ; j++ ){
user.send(j, DKGMessages.Mail.Type.SECRET,secretMessages[j - 1]);
}
}
@Override
public void run() {
// computes and sends shares
computeAndSendSecrets();
}
} }

View File

@ -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;
}
}

View File

@ -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<Integer> getQUAL();
}

View File

@ -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();
}

View File

@ -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<BigInteger> getGroup();
}

View File

@ -2,6 +2,7 @@ package FeldmanVerifiableSecretSharing;
import Communication.Network; import Communication.Network;
import ShamirSecretSharing.Polynomial; import ShamirSecretSharing.Polynomial;
import org.factcenter.qilin.primitives.Group;
import org.factcenter.qilin.primitives.concrete.Zpstar; import org.factcenter.qilin.primitives.concrete.Zpstar;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -32,21 +33,19 @@ public class VerifiableSecretSharingTest {
}while (!g.equals(ZERO) && !zpstar.multiply(g,q).equals(ZERO));// sample from QRZp* }while (!g.equals(ZERO) && !zpstar.multiply(g,q).equals(ZERO));// sample from QRZp*
int t = 8; int t = 8;
int n = 20; int n = 20;
Network network;
verifiableSecretSharingArray = new VerifiableSecretSharing[tests]; verifiableSecretSharingArray = new VerifiableSecretSharing[tests];
for (int i = 0; i < verifiableSecretSharingArray.length; i++){ for (int i = 0; i < verifiableSecretSharingArray.length; i++){
network = new Network(n);
verifiableSecretSharingArray[i] = new VerifiableSecretSharing(t,n verifiableSecretSharingArray[i] = new VerifiableSecretSharing(t,n
,new BigInteger(q.bitLength(),random).mod(q),random,p,q,g,network); ,new BigInteger(q.bitLength(),random).mod(q),random,q,g,zpstar);
} }
} }
public void oneTest(VerifiableSecretSharing verifiableSecretSharing) throws Exception { public void oneTest(VerifiableSecretSharing verifiableSecretSharing) throws Exception {
int n = verifiableSecretSharing.getN(); int n = verifiableSecretSharing.getN();
Zpstar zpstar = verifiableSecretSharing.getZpstar(); Group<BigInteger> zpstar = verifiableSecretSharing.getGroup();
BigInteger g = verifiableSecretSharing.getGenerator(); BigInteger g = verifiableSecretSharing.getGenerator();
Polynomial.Point[] shares = new Polynomial.Point[n]; Polynomial.Point[] shares = new Polynomial.Point[n];
BigInteger[] commitments = verifiableSecretSharing.getCommitments(); BigInteger[] commitments = verifiableSecretSharing.getCommitmentsArray();
BigInteger[] verifications = new BigInteger[n]; BigInteger[] verifications = new BigInteger[n];
for (int i = 1 ; i <= shares.length; i ++){ for (int i = 1 ; i <= shares.length; i ++){
shares[i - 1] = verifiableSecretSharing.getShare(i); shares[i - 1] = verifiableSecretSharing.getShare(i);

View File

@ -4,13 +4,13 @@ import Communication.Network;
import ShamirSecretSharing.Polynomial; import ShamirSecretSharing.Polynomial;
import ShamirSecretSharing.SecretSharing; import ShamirSecretSharing.SecretSharing;
import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; import FeldmanVerifiableSecretSharing.VerifiableSecretSharing;
import UserInterface.DistributedKeyGenerationUser;
import org.factcenter.qilin.primitives.Group;
import org.factcenter.qilin.primitives.concrete.Zpstar; import org.factcenter.qilin.primitives.concrete.Zpstar;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Random; import java.util.Random;
/** /**
@ -19,7 +19,7 @@ import java.util.Random;
public class DKGTest { public class DKGTest {
DistributedKeyGeneration[][] dkgsArrays; DistributedKeyGenerationUser[][] dkgsArrays;
Thread[][] threadsArrays; Thread[][] threadsArrays;
int tests = 10; int tests = 10;
BigInteger p = BigInteger.valueOf(2903); BigInteger p = BigInteger.valueOf(2903);
@ -33,9 +33,10 @@ public class DKGTest {
int t = 9; int t = 9;
int n = 20; int n = 20;
BigInteger ZERO = zpstar.zero(); BigInteger ZERO = zpstar.zero();
dkgsArrays = new DistributedKeyGeneration[tests][n]; dkgsArrays = new DistributedKeyGenerationUserImpl[tests][n];
threadsArrays = new Thread[tests][n]; threadsArrays = new Thread[tests][n];
secrets = new BigInteger[tests]; secrets = new BigInteger[tests];
DistributedKeyGeneration dkg;
for (int test = 0; test < tests; test++) { for (int test = 0; test < tests; test++) {
do { do {
g = zpstar.sample(random); g = zpstar.sample(random);
@ -45,13 +46,14 @@ public class DKGTest {
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
BigInteger secret = new BigInteger(q.bitLength(), random).mod(q); BigInteger secret = new BigInteger(q.bitLength(), random).mod(q);
secrets[test] = secrets[test].add(secret).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]); 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++){ for (int i = 0; i < threads.length ; i++){
threads[i].start(); threads[i].start();
} }
@ -61,15 +63,16 @@ public class DKGTest {
int t = dkgs[0].getT(); int t = dkgs[0].getT();
int n = dkgs[0].getN(); int n = dkgs[0].getN();
Zpstar zpstar = dkgs[0].getZpstar(); Group<BigInteger> zpstar = dkgs[0].getGroup();
BigInteger g = dkgs[0].getGenerator(); BigInteger g = dkgs[0].getGenerator();
// got the right public value // 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 // assert all players agreed on the same public value
for (int i = 0; i < dkgs.length - 1 ; i++){ for (int i = 0; i < dkgs.length - 1 ; i++){
assert (dkgs[i].getY().equals(dkgs[i+1].getY())); assert (dkgs[i].getPublicValue().equals(dkgs[i+1].getPublicValue()));
} }
// assert valid verification values // assert valid verification values
@ -96,19 +99,13 @@ public class DKGTest {
// index = indexes.remove(random.nextInt(indexes.size())); // index = indexes.remove(random.nextInt(indexes.size()));
// shares[i] = dkgs[index - 1].getShare(); // shares[i] = dkgs[index - 1].getShare();
//} //}
BigInteger calculatedSecret = SecretSharing.getSecrete(shares).mod(q); BigInteger calculatedSecret = SecretSharing.restoreSecrete(shares).mod(q);
Polynomial polynomial = Polynomial.ZERO;
for (int i = 0 ; i < dkgs.length ; i++){
polynomial = polynomial.add(dkgs[i].getPolynomial());
}
assert (calculatedSecret.equals(secret)); assert (calculatedSecret.equals(secret));
} }
@Test @Test
public void secretSharingTest() throws Exception { public void DKGTest() throws Exception {
for (int i = 0 ; i < dkgsArrays.length; i ++){ for (int i = 0 ; i < dkgsArrays.length; i ++){
oneTest(threadsArrays[i],dkgsArrays[i],secrets[i]); oneTest(threadsArrays[i],dkgsArrays[i],secrets[i]);
} }

View File

@ -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<BigInteger> 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<Integer> indexes = new ArrayList<Integer>(n);
//for (int i = 1 ; i <= n; i ++){
// indexes.add(i);
//}
//Random random = new Random();
//int index;
//for (int i = 0 ; i < shares.length ; i++){
// index = indexes.remove(random.nextInt(indexes.size()));
// shares[i] = dkgs[index - 1].getShare();
//}
BigInteger calculatedSecret = SecretSharing.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]);
}
}
}

View File

@ -1,7 +1,6 @@
package ShamirSecretSharing; package ShamirSecretSharing;
import Communication.Network; import Communication.Network;
import Communication.User;
import org.factcenter.qilin.primitives.CyclicGroup; import org.factcenter.qilin.primitives.CyclicGroup;
import org.factcenter.qilin.primitives.concrete.Zn; import org.factcenter.qilin.primitives.concrete.Zn;
import org.junit.Before; import org.junit.Before;
@ -26,18 +25,17 @@ public class SecretSharingTest {
@Before @Before
public void settings(){ public void settings(){
BigInteger p = BigInteger.valueOf(2903); BigInteger p = BigInteger.valueOf(2903);
BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2));
group = new Zn(p); group = new Zn(p);
int t = 9; int t = 9;
int n = 20; int n = 20;
random = new Random(); random = new Random();
secretSharingArray = new SecretSharing[tests]; secretSharingArray = new SecretSharing[tests];
secrets = new BigInteger[tests]; secrets = new BigInteger[tests];
Network network;
for (int i = 0; i < secretSharingArray.length; i++){ for (int i = 0; i < secretSharingArray.length; i++){
secrets[i] = group.sample(random); secrets[i] = group.sample(random);
network = new Network(n); secretSharingArray[i] = new SecretSharing(t,n,secrets[i],random,q);
secretSharingArray[i] = new SecretSharing(t,n,secrets[i],random,p,network);
} }
} }
@ -52,7 +50,7 @@ public class SecretSharingTest {
for (int i = 0 ; i < shares.length ; i++){ for (int i = 0 ; i < shares.length ; i++){
shares[i] = secretSharing.getShare(indexes.remove(random.nextInt(indexes.size()))); shares[i] = secretSharing.getShare(indexes.remove(random.nextInt(indexes.size())));
} }
assert(secret.equals(SecretSharing.getSecrete(shares))); assert(secret.equals(SecretSharing.restoreSecrete(shares)));
} }
@Test @Test

View File

@ -10,6 +10,7 @@ message Mail{
COMMITMENT = 1; COMMITMENT = 1;
DONE = 2; DONE = 2;
COMPLAINT = 3; COMPLAINT = 3;
DOUBLE = 4;
} }
int32 sender = 1; int32 sender = 1;
int32 destination = 2; int32 destination = 2;