joint feldman with protos

DKG
tzlil.gon 2016-02-08 15:20:43 +02:00
parent 91dd19ead2
commit 8288b07d80
6 changed files with 310 additions and 145 deletions

View File

@ -1,7 +1,8 @@
package FeldmanVerifiableSecretSharing.ShamirSecretSharing; package FeldmanVerifiableSecretSharing.ShamirSecretSharing;
import com.google.protobuf.ByteString;
import meerkat.protobuf.DKGMessages;
import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Arrays;
import java.math.BigInteger; import java.math.BigInteger;
/** /**
@ -172,7 +173,7 @@ public class Polynomial implements Comparable<Polynomial> {
* inner class * inner class
* container for (x,y) x from range and y from image of polynomial * 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 x;
public final BigInteger y; public final BigInteger y;
@ -199,13 +200,21 @@ public class Polynomial implements Comparable<Polynomial> {
} }
/** /**
* copy constructor * constructor - restore point from message
* @param point * @param pointMessage
*/ */
public Point(Point point) { public Point(DKGMessages.SecretMessage.Point pointMessage) {
this.x = point.x; this.x = new BigInteger(pointMessage.getX().toByteArray());
this.y = point.y; 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();
}
} }
} }

View File

@ -9,9 +9,9 @@ import java.util.Random;
* an implementation of Shamire's secret sharing scheme * an implementation of Shamire's secret sharing scheme
*/ */
public class SecretSharing { public class SecretSharing {
private final int t; protected final int t;
private final int n; protected final int n;
private final BigInteger q; protected final BigInteger q;
private final Polynomial polynomial; private final Polynomial polynomial;

View File

@ -18,10 +18,10 @@ import java.util.Random;
* *
*/ */
public class VerifiableSecretSharing extends SecretSharing { public class VerifiableSecretSharing extends SecretSharing {
private final Zpstar zpstar; protected final Zpstar zpstar;
private final BigInteger g; // public generator of group protected final BigInteger g; // public generator of group
private final BigInteger[] commitments;
private final BigInteger y; // y = g ^ x private final BigInteger y; // y = g ^ x
private final BigInteger[] commitments;
/** /**
* @param p a large prime * @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 commitments
* @param zpstar * @param zpstar
* *
* @return product of commitments[j] ^ (i ^ j) == g ^ polynomial(i) * @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 v = zpstar.zero();
BigInteger power = BigInteger.ONE; BigInteger power = BigInteger.ONE;
BigInteger I = BigInteger.valueOf(i); BigInteger J = BigInteger.valueOf(j);
for (int j = 0 ; j < commitments.length ; j ++){ for (int k = 0 ; k < commitments.length ; k ++){
v = zpstar.add(v,zpstar.multiply(commitments[j],power)); v = zpstar.add(v,zpstar.multiply(commitments[k],power));
power = power.multiply(I); power = power.multiply(J);
} }
return v; return v;
} }
@ -81,14 +81,6 @@ public class VerifiableSecretSharing extends SecretSharing {
return g; return g;
} }
/**
* getter
* @return copy of commitments
*/
public BigInteger[] getCommitments() {
return Arrays.clone(commitments);
}
/** /**
* getter * getter
* @return zpstar * @return zpstar
@ -104,4 +96,12 @@ public class VerifiableSecretSharing extends SecretSharing {
public BigInteger getY(){ public BigInteger getY(){
return y; return y;
} }
/**
* getter
* @return copy of commitments
*/
public BigInteger[] getCommitments() {
return Arrays.clone(commitments);
}
} }

View File

@ -2,8 +2,10 @@ package JointFeldmanProtocol;
import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial;
import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; import FeldmanVerifiableSecretSharing.VerifiableSecretSharing;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Arrays;
import org.factcenter.qilin.primitives.concrete.Zpstar; import meerkat.protobuf.DKGMessages.*;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.HashSet; import java.util.HashSet;
@ -18,10 +20,12 @@ import java.util.Set;
public class DKG extends VerifiableSecretSharing implements Runnable{ public class DKG extends VerifiableSecretSharing implements Runnable{
private Network.User user; private Network.User user;
private Handler handler; private Network.MailHandler handler;
private Polynomial.Point[] shares; private Polynomial.Point[] shares;
private Polynomial.Point[] myshares;
private BigInteger[][] commitmentsArray; private BigInteger[][] commitmentsArray;
private BigInteger[] ys; private BigInteger[] ys;
final ComplainState[][] complainStates;
private Set<Integer> QUAL; private Set<Integer> QUAL;
private BigInteger x; 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) { 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); super(t, n, x, random, p, q, g);
this.commitmentsArray = new BigInteger[n][t + 1]; this.commitmentsArray = new BigInteger[n][t + 1];
this.shares = new Polynomial.Point[n]; this.shares = new Polynomial.Point[n];
this.myshares = new Polynomial.Point[n];
this.handler = new Handler(); this.handler = new Handler();
this.user = network.connect(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(){ private void stage1(){
int n = getN();
int t = getT();
int i = user.getID(); int i = user.getID();
BigInteger[] commitments = super.getCommitments(); BigInteger[] commitments = super.getCommitments();
System.arraycopy(commitments, 0, commitmentsArray[i - 1], 0, commitmentsArray[i - 1].length); System.arraycopy(commitments, 0, commitmentsArray[i - 1], 0, commitmentsArray[i - 1].length);
Network.CommitmentMessage commitment; CommitmentMessage commitment;
for (int j = 1; j <= commitmentsArray[i - 1].length; j ++){ for (int k = 1; k <= commitmentsArray[i - 1].length; k ++){
commitment = new Network.CommitmentMessage(j,commitmentsArray[i - 1][j - 1]); commitment = CommitmentMessage.newBuilder()
user.broadcast(commitment); .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++ ){ for (int j = 1; j <= n ; j++ ){
if(j != i){ if(j != i){
secret = new Network.SecretMessage(getShare(j)); myshares[j - 1] = super.getShare(j);
user.send(j,secret); 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 { try {
Thread.sleep(30); Thread.sleep(30);
} catch (InterruptedException e) { } 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(){ private void stage2(){
int n = getN(); int j = user.getID();
BigInteger g = getGenerator();
Zpstar zpstar = getZpstar();
int i = user.getID();
QUAL = new HashSet<Integer>(); QUAL = new HashSet<Integer>();
Network.Message message = null; ComplaintMessage complaint;
for (int j = 1; j <= n ; j++ ){ for (int i = 1; i <= n ; i++ ){
if(zpstar.multiply(g,shares[j - 1].y).equals(verify(j,commitmentsArray[j],zpstar))){ if(isValidSecret(shares[i - 1],j)) {
QUAL.add(j); QUAL.add(i);
}else{ }else{
//message = new Message(Type.Complaint, j) //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 //sending y after Complaints
Network.YMessage yMessage = new Network.YMessage(super.getY()); YMessage yMessage = YMessage.newBuilder()
user.broadcast(yMessage); .setY(ByteString.copyFrom(super.getY().toByteArray()))
} .build();
user.broadcast(Mail.Type.Y,yMessage);
private void stage3(){ while (!isStage2Complete()){
int n = getN();
while (handler.ysCounter < n - 1 ){
try { try {
Thread.sleep(30); Thread.sleep(30);
} catch (InterruptedException e) { } catch (InterruptedException e) {
// do nothing // 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(){ private void stage4(){
int t = getT();
Zpstar zpstar = getZpstar();
BigInteger y = zpstar.zero(); BigInteger y = zpstar.zero();
for (int i : QUAL) { for (int i : QUAL) {
y = zpstar.add(y , ys[i - 1]); y = zpstar.add(y , ys[i - 1]);
@ -120,7 +208,7 @@ public class DKG extends VerifiableSecretSharing implements Runnable{
for (int i : QUAL) { for (int i : QUAL) {
x = x.add(shares[i - 1].y); x = x.add(shares[i - 1].y);
} }
this.x = x.mod(getQ()); this.x = x.mod(q);
} }
@Override @Override
@ -146,45 +234,101 @@ public class DKG extends VerifiableSecretSharing implements Runnable{
stage4(); stage4();
} }
private enum ComplainState{
Non, Waiting,Disqualified,NonDisqualified
}
private class Handler implements Network.MailHandler { private class Handler implements Network.MailHandler {
final int id; final int id;
int secretsCounter;
int commitmentsCounter;
int ysCounter;
private Handler() { private Handler() {
this.id = user.getID(); this.id = user.getID();
this.secretsCounter = 0;
this.commitmentsCounter = 0;
this.ysCounter = 0;
} }
@Override void handelSecretMessage(Mail mail) throws InvalidProtocolBufferException {
public void handel(Network.Mail mail) { if(shares[mail.getSender() - 1] == null) {
if(mail.isPrivate){ SecretMessage secretMessage = SecretMessage.parseFrom(mail.getMessage());
if(mail.message instanceof Network.SecretMessage){ Polynomial.Point secret = new Polynomial.Point(secretMessage.getSecret());
Polynomial.Point secret = ((Network.SecretMessage)mail.message).secret; if(mail.getIsPrivate()){
if(shares[id - 1] == null) { shares[mail.getSender() - 1] = secret;
shares[id - 1] = secret; }else{
secretsCounter++; int i = mail.getSender();
} int j = secret.x.intValue();
} switch (complainStates[i][j]){
}else{ case Waiting:
if(mail.message instanceof Network.CommitmentMessage){ if(isValidSecret(secret,i)){
Network.CommitmentMessage commitmentMessage = (Network.CommitmentMessage)mail.message; complainStates[i][j] = ComplainState.NonDisqualified;
if(commitmentsArray[mail.senderID - 1][commitmentMessage.k] == null) { }else{
commitmentsArray[mail.senderID - 1][commitmentMessage.k] = commitmentMessage.commitment; complainStates[i][j] = ComplainState.Disqualified;
commitmentsCounter++; }
} break;
}else if(mail.message instanceof Network.YMessage){ default:
BigInteger y = ((Network.YMessage)mail.message).y; break;
if(ys[mail.senderID - 1] == null){
ys[mail.senderID - 1] = y;
ysCounter ++;
} }
} }
} }
} }
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;
}
}
} }
} }

View File

@ -1,9 +1,8 @@
package JointFeldmanProtocol; package JointFeldmanProtocol;
import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
import java.lang.reflect.Type; import meerkat.protobuf.DKGMessages.*;
import java.math.BigInteger;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ArrayBlockingQueue;
/** /**
@ -32,24 +31,38 @@ public class Network {
return new User(id,messageHandler); 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) if(destination < 1 || destination > n)
return false; return false;
User user = users[destination - 1]; User user = users[destination - 1];
if (user == null) if (user == null)
return false; 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; User user;
int ID = sender.ID; 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++){ for (int i = 0 ; i < n ; i++){
if (i + 1 == ID) { if (i + 1 == ID) {
continue; continue;
} }
user = users[i]; user = users[i];
user.mailbox.add(new Mail(ID,true,message)); user.mailbox.add(mail);
} }
} }
@ -66,14 +79,12 @@ public class Network {
thread.run(); thread.run();
} }
public boolean send(int id, Mail.Type type,Message message){
public boolean send(int id, Message message){ return sendMessage(this,id,type,message);
return sendMessage(this,id,message);
} }
public void broadcast(Message message){ public void broadcast(Mail.Type type,Message message){
sendBroadcast(this,message); sendBroadcast(this,type,message);
} }
public int getID() { public int getID() {
return ID; return ID;
} }
@ -83,7 +94,11 @@ public class Network {
public void run() { public void run() {
while (true){ while (true){
if (!mailbox.isEmpty()){ if (!mailbox.isEmpty()){
messageHandler.handel(mailbox.poll()); try {
messageHandler.handel(mailbox.poll());
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
}else{ }else{
try { try {
Thread.sleep(30); 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 interface MailHandler {
public void handel(Mail mail); public void handel(Mail mail) throws InvalidProtocolBufferException;
} }
} }

View File

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