generic group + wait instead of sleep

DKG
tzlil.gon 2016-04-08 15:03:32 +03:00
parent 4f608e813d
commit 0ae9719bc5
43 changed files with 3351 additions and 3112 deletions

View File

@ -1,28 +0,0 @@
package Communication;
/**
* A generic commmunication channel that supports point-to-point and broadcast operation
*/
//
//public interface Channel {
// public interface ReceiverCallback {
// public void receiveMessage(UserID fromUser, boolean isBroadcast, Message message);
// }
//
// public void sendMessage(UserID destUser, Message msg);
//
// /**
// * Block until a message is available (optional).
// * @return
// */
// public Message getNextMessageBlocking(long timeout);
//
//
// /**
// * Register a callback to handle received messages.
// * The callback is called in the <b>Channel</b> thread, so no long processing should
// * occur in the callback method.
// * @param callback
// */
// public void registerReceiverCallback(ReceiverCallback callback);
//}

View File

@ -1,75 +0,0 @@
package Communication;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
import meerkat.protobuf.DKGMessages.*;
import java.util.HashSet;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
/**
* Created by Tzlil on 2/7/2016.
* Joint Feldamn protocol assumes all parties can communicate throw broadcast channel
* and private channel (for each pair)
* this class simulates it
*/
// TODO: Delete
// TODO: Move this implementation to tests
public class Network {
protected final User[] users;
protected final int n;
protected final Set<Integer> availableIDs;
public static final int BROADCAST = 0;
public Network(int n) {
this.n = n;
this.users = new User[n];
this.availableIDs = new HashSet<Integer>();
for (int id = 1; id <= n; id++){
availableIDs.add(id);
}
}
public User connect(MailHandler mailHandler,int id){
if (!availableIDs.contains(id))
return null;
availableIDs.remove(id);
users[id - 1] = new User(id,this,mailHandler);
return users[id - 1];
}
protected 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;
Mail mail = Mail.newBuilder()
.setSender(sender.getID())
.setDestination(destination)
.setIsPrivate(true)
.setType(type)
.setMessage(message.toByteString())
.build();
return user.mailbox.add(mail);
}
protected void sendBroadcast(User sender,Mail.Type type,Message message){
User user;
Mail mail = Mail.newBuilder()
.setSender(sender.getID())
.setDestination(BROADCAST)
.setIsPrivate(false)
.setType(type)
.setMessage(message.toByteString())
.build();
for (int i = 0 ; i < n ; i++){
user = users[i];
user.mailbox.add(mail);
}
}
}

View File

@ -1,74 +0,0 @@
package Communication;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
import meerkat.protobuf.DKGMessages;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
/**
* Created by Tzlil on 2/14/2016.
*/
// TODO: Change nane to network
public class User{
/*
* My view of
*/
protected final MailHandler mailHandler;
protected final Queue<DKGMessages.Mail> mailbox;
protected final int ID;
protected final Thread receiverThread;
private final Network network;
protected User(int ID, Network network, MailHandler mailHandler) {
this.mailbox = new ArrayBlockingQueue<DKGMessages.Mail>( network.n * network.n * network.n);
this.ID = ID;
this.mailHandler = mailHandler;
this.receiverThread = new Thread(new Receiver());
this.network = network;
}
public boolean send(int id, DKGMessages.Mail.Type type, Message message){
return network.sendMessage(this,id,type,message);
}
public void broadcast(DKGMessages.Mail.Type type, Message message){
network.sendBroadcast(this,type,message);
}
public MailHandler getMailHandler(){
return mailHandler;
}
public void setMessageHandler(MessageHandler messageHandler) {
mailHandler.setMessageHandler(messageHandler);
}
public int getID() {
return ID;
}
public Thread getReceiverThread(){
return receiverThread;
}
private class Receiver implements Runnable{
@Override
public void run() {
while (true){
if (!mailbox.isEmpty()){
mailHandler.handel(mailbox.poll());
}else{
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// do nothing
}
}
}
}
}
}

View File

@ -1,102 +0,0 @@
package FeldmanVerifiableSecretSharing;
import ShamirSecretSharing.Polynomial;
import ShamirSecretSharing.SecretSharing;
import org.factcenter.qilin.primitives.Group;
import java.util.Arrays;
import java.math.BigInteger;
import java.util.Random;
/**
* Created by Tzlil on 1/27/2016.
*
* an implementation of Feldman's verifiable secret sharing scheme.
*
* allows trusted dealer to share a key x among n parties.
*
* TODO: Add link to paper
*
*/
// TODO: Use Group<T> rather than fix to biginteger (allow using EC groups for better comm. complexity)
public class VerifiableSecretSharing extends SecretSharing {
protected final Group<BigInteger> group;
protected final BigInteger g; // public generator of group
protected final BigInteger[] commitmentsArray;
/**
* @param group
* @param q a large prime dividing group order.
* @param g a generator of cyclic group of order q.
* the generated group is a subgroup of the given group.
* it must be chosen such that computing discrete logarithms is hard in this group.
*/
public VerifiableSecretSharing(int t, int n, BigInteger x, Random random, BigInteger q, BigInteger g
, Group<BigInteger> group) {
super(t, n, x, random,q);
this.g = g;
this.group = group;
assert (this.group.contains(g));
this.commitmentsArray = generateCommitments();
}
/**
* TODO: comment
* @return commitments[i] = g ^ polynomial.coefficients[i]
*/
private BigInteger[] generateCommitments() {
Polynomial polynomial = getPolynomial();
BigInteger[] coefficients = polynomial.getCoefficients();
BigInteger[] commitments = new BigInteger[coefficients.length];
for (int i = 0 ; i < commitments.length;i++){
commitments[i] = group.multiply(g,coefficients[i]);
}
return commitments;
}
/**
* Compute verification value (g^{share value}) using coefficient commitments sent by dealer and my share id.
* @param j my share holder id
* @param commitments commitments to polynomial coefficients of share (received from dealer)
* @param group
*
* @return product of Aik ^ (j ^ k) == g ^ polynomial(i)
*/
public static BigInteger computeVerificationValue(int j, BigInteger[] commitments, Group<BigInteger> group) {
BigInteger v = group.zero();
BigInteger power = BigInteger.ONE;
BigInteger J = BigInteger.valueOf(j);
for (int k = 0 ; k < commitments.length ; k ++){
v = group.add(v,group.multiply(commitments[k],power));
power = power.multiply(J);
}
return v;
}
// TODO: Add verify method.
/**
* getter
* @return generator of group
*/
public BigInteger getGenerator() {
return g;
}
/**
* getter
* @return group
*/
public Group<BigInteger> getGroup(){
return group;
}
/**
* getter
* @return copy of commitmentsArray
*/
public BigInteger[] getCommitmentsArray() {
return Arrays.copyOf(commitmentsArray, commitmentsArray.length);
}
}

View File

@ -1,141 +0,0 @@
package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem;
import Communication.User;
import FeldmanVerifiableSecretSharing.VerifiableSecretSharing;
import JointFeldmanProtocol.DistributedKeyGeneration;
import ShamirSecretSharing.Polynomial;
import com.google.protobuf.ByteString;
import meerkat.protobuf.DKGMessages;
import org.factcenter.qilin.primitives.Group;
import java.math.BigInteger;
import java.util.Random;
import java.util.Set;
/**
* Created by Tzlil on 3/16/2016.
* TODO: comments
* TODO: put Channel (User) in constructor
*/
public class SecureDistributedKeyGeneration extends DistributedKeyGeneration {
private VerifiableSecretSharing maskingShares;
private final BigInteger h;
private SecureDistributedKeyGenerationParty[] parties;
public SecureDistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger q, BigInteger g
, BigInteger h, Group<BigInteger> group, int id) {
super(t, n, zi, random, q, g, group, id);
this.h = h;
BigInteger r = new BigInteger(q.bitLength(),random).mod(q);
this.maskingShares = new VerifiableSecretSharing(t,n,r,random,q,h,group);
this.parties = new SecureDistributedKeyGenerationParty[n];
for (int i = 1; i <= n ; i++){
this.parties[i - 1] = new SecureDistributedKeyGenerationParty(i,n,t);
}
this.parties[id - 1].share = getShare(id);
this.parties[id - 1].shareT = maskingShares.getShare(id);
super.setParties(parties);
}
protected SecureDistributedKeyGenerationParty[] getParties(){
return parties;
}
protected void setParties(SecureDistributedKeyGenerationParty[] parties) {
super.setParties(parties);
this.parties = parties;
}
@Override
public void sendSecret(User user, int j) {
Polynomial.Point secret = getShare(j);
Polynomial.Point secretT = maskingShares.getShare(j);
DKGMessages.DoubleSecretMessage doubleSecretMessage = doubleShareMessage(id,j,secret,secretT);
// TODO: Change SECRET to SHARE
user.send(j, DKGMessages.Mail.Type.SECRET, doubleSecretMessage);
}
public boolean isValidShare(int i){
SecureDistributedKeyGenerationParty party = parties[i - 1];
return isValidShare(party.share, party.shareT, party.verifiableValues, id);
}
/**
* TODO: comment
* @param share
* @param shareT
* @param verificationValues
* @param j
* @return computeVerificationValue(j,verificationValues,group) == (g ^ share.y) * (h ^ shareT.y) mod q
*/
public boolean isValidShare(Polynomial.Point share, Polynomial.Point shareT, BigInteger[] verificationValues, int j){
try {
BigInteger v = computeVerificationValue(j, verificationValues, group);
BigInteger exp = group.add(group.multiply(g, share.y), group.multiply(h, shareT.y));
return exp.equals(v);
}
catch (NullPointerException e){
return false;
}
}
// TODO: comment
private void broadcastComplaint(User user,Polynomial.Point share,Polynomial.Point shareT,int i){
DKGMessages.DoubleSecretMessage complaint = doubleShareMessage(i,id,share,shareT);
user.broadcast(DKGMessages.Mail.Type.COMPLAINT,complaint);
}
/**
* stage4.3 according to the protocol
* if check fails for index i, Pj
*/
public void computeAndBroadcastComplaints(User user, Set<Integer> QUAL){
SecureDistributedKeyGenerationParty party;
for (int i : QUAL) {
party = parties[i - 1];
if (i != id) {
if (!super.isValidSecret(party.share, party.commitments, id)) {
broadcastComplaint(user, party.share, party.shareT, i);
}
}
}
}
public void broadcastVerificationValues(User user){
BigInteger[] verificationValues = new BigInteger[t + 1];
BigInteger[] hBaseCommitments = maskingShares.getCommitmentsArray();
for (int k = 0 ; k < verificationValues.length ; k++){
verificationValues[k] = group.add(commitmentsArray[k],hBaseCommitments[k]);
}
broadcastCommitments(user,verificationValues);
}
private DKGMessages.DoubleSecretMessage doubleShareMessage(int i, int j, Polynomial.Point secret, Polynomial.Point secretT){
DKGMessages.DoubleSecretMessage doubleSecretMessage = DKGMessages.DoubleSecretMessage.newBuilder()
.setI(i)
.setJ(j)
.setSecret(ByteString.copyFrom(secret.y.toByteArray()))
.setSecretT(ByteString.copyFrom(secretT.y.toByteArray()))
.build();
return doubleSecretMessage;
}
@Override
public void broadcastComplaintAnswer(User user, int j) {
DKGMessages.DoubleSecretMessage answer = doubleShareMessage(id,j,getShare(j)
, maskingShares.getShare(j));
user.broadcast(DKGMessages.Mail.Type.ANSWER,answer);
}
public void broadcastAnswer(User user,Polynomial.Point secret,Polynomial.Point secretT,int i){
DKGMessages.DoubleSecretMessage complaint = doubleShareMessage(i,id,secret,secretT);
user.broadcast(DKGMessages.Mail.Type.ANSWER,complaint);
}
public BigInteger getH() {
return h;
}
}

View File

@ -1,29 +0,0 @@
package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem;
import JointFeldmanProtocol.DistributedKeyGenerationParty;
import ShamirSecretSharing.Polynomial;
import java.math.BigInteger;
import java.util.HashSet;
import java.util.Set;
/**
* Created by Tzlil on 3/16/2016.
*
* an extension of DistributedKeyGenerationParty
* contains all relevant information on specific party during
* the run of the safe protocol
*/
public class SecureDistributedKeyGenerationParty extends DistributedKeyGenerationParty {
public Polynomial.Point shareT;
public boolean ysDoneFlag;
public BigInteger[] verifiableValues;
public Set<Polynomial.Point> restoreSharesSet;
public SecureDistributedKeyGenerationParty(int id, int n, int t) {
super(id, n, t);
this.shareT = null;
this.ysDoneFlag = false;
this.verifiableValues = new BigInteger[t + 1];
this.restoreSharesSet = new HashSet<Polynomial.Point>();
}
}

View File

@ -1,13 +0,0 @@
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

@ -1,14 +0,0 @@
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

@ -1,16 +0,0 @@
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

@ -0,0 +1,11 @@
package meerkat.crypto;
import java.util.Random;
/**
* Created by Tzlil on 4/8/2016.
*/
public interface KeyGeneration<T> {
T generateKey(Random random);
}

View File

@ -0,0 +1,7 @@
package meerkat.crypto;
/**
* Created by Tzlil on 4/8/2016.
*/
public class SecretSharing {
}

View File

@ -0,0 +1,108 @@
package meerkat.crypto.concrete.distributed_key_generation.Communication;
import com.google.protobuf.Message;
import meerkat.crypto.utilitis.Channel;
import meerkat.protobuf.DKGMessages;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
/**
* Created by Tzlil on 2/14/2016.
*/
// TODO: Change nane to network
public class ChannelImpl implements Channel {
public static int BROADCAST = 0;
private static ChannelImpl[] channels = null;
protected final Queue<DKGMessages.Mail> mailbox;
protected final int id;
protected final int n;
protected Thread receiverThread;
public ChannelImpl(int id, int n) {
if (channels == null){
channels = new ChannelImpl[n];
}
this.mailbox = new ArrayBlockingQueue<DKGMessages.Mail>( n * n * n);
this.id = id;
this.n = n;
channels[id - 1] = this;
}
public int getId() {
return id;
}
@Override
public void sendMessage(int destUser, DKGMessages.Mail.Type type, Message msg) {
if(destUser < 1 || destUser > n)
return;
ChannelImpl channel = channels[destUser - 1];
if (channel == null)
return;
DKGMessages.Mail mail = DKGMessages.Mail.newBuilder()
.setSender(id)
.setDestination(destUser)
.setIsPrivate(true)
.setType(type)
.setMessage(msg.toByteString())
.build();
synchronized (channel.mailbox) {
channel.mailbox.add(mail);
channel.mailbox.notify();
}
}
@Override
public void broadcastMessage(DKGMessages.Mail.Type type,Message msg) {
ChannelImpl channel;
DKGMessages.Mail mail = DKGMessages.Mail.newBuilder()
.setSender(id)
.setDestination(BROADCAST)
.setIsPrivate(false)
.setType(type)
.setMessage(msg.toByteString())
.build();
for (int i = 0 ; i < n ; i++){
channel = channels[i];
synchronized (channel.mailbox) {
channel.mailbox.add(mail);
channel.mailbox.notify();
}
}
}
@Override
public void registerReceiverCallback(final ReceiverCallback callback) {
try{
receiverThread.interrupt();
}catch (Exception e){
//do nothing
}
receiverThread = new Thread(new Runnable() {
@Override
public void run() {
while (true){
try {
synchronized (mailbox) {
while (!mailbox.isEmpty()) {
callback.receiveMail(mailbox.remove());
}
mailbox.wait();
}
} catch (InterruptedException e) {
//do nothing
}
}
}
});
receiverThread.start();
}
}

View File

@ -1,58 +1,56 @@
package Communication; package meerkat.crypto.concrete.distributed_key_generation.Communication;
import com.google.protobuf.Message; import com.google.protobuf.Message;
import meerkat.protobuf.DKGMessages; import meerkat.crypto.utilitis.Channel;
import meerkat.protobuf.DKGMessages;
/**
* Created by Tzlil on 2/14/2016. /**
*/ * Created by Tzlil on 2/14/2016.
public abstract class MailHandler { */
public abstract class MailHandler implements Channel.ReceiverCallback{
private MessageHandler messageHandler;
public MailHandler(MessageHandler messageHandler){ private MessageHandler messageHandler;
this.messageHandler = messageHandler; public MailHandler(MessageHandler messageHandler){
} this.messageHandler = messageHandler;
}
public abstract Message extractMessage(DKGMessages.Mail mail);
public abstract Message extractMessage(DKGMessages.Mail mail);
public void handel(DKGMessages.Mail mail){
public void receiveMail(DKGMessages.Mail mail){
Message message = extractMessage(mail);
if (message == null) Message message = extractMessage(mail);
return; if (message == null)
return;
switch (mail.getType()) {
case SECRET: switch (mail.getType()) {
messageHandler.handleSecretMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST case SHARE:
, message); messageHandler.handleSecretMessage(mail.getSender(), mail.getDestination() == ChannelImpl.BROADCAST
break; , message);
case COMMITMENT: break;
messageHandler.handleCommitmentMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST case COMMITMENT:
, message); messageHandler.handleCommitmentMessage(mail.getSender(), mail.getDestination() == ChannelImpl.BROADCAST
break; , message);
case DONE: break;
messageHandler.handleDoneMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST case DONE:
, message); messageHandler.handleDoneMessage(mail.getSender(), mail.getDestination() == ChannelImpl.BROADCAST
break; , message);
case COMPLAINT: break;
messageHandler.handleComplaintMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST case COMPLAINT:
, message); messageHandler.handleComplaintMessage(mail.getSender(), mail.getDestination() == ChannelImpl.BROADCAST
break; , message);
case ANSWER: break;
messageHandler.handleAnswerMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST case ANSWER:
, message); messageHandler.handleAnswerMessage(mail.getSender(), mail.getDestination() == ChannelImpl.BROADCAST
break; , message);
case ABORT: break;
messageHandler.handleAbortMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST case ABORT:
, message); messageHandler.handleAbortMessage(mail.getSender(), mail.getDestination() == ChannelImpl.BROADCAST
break; , message);
default: break;
break; default:
} break;
}
}
public void setMessageHandler(MessageHandler messageHandler) { }
this.messageHandler = messageHandler; }
}
}

View File

@ -1,15 +1,15 @@
package Communication; package meerkat.crypto.concrete.distributed_key_generation.Communication;
import com.google.protobuf.Message; import com.google.protobuf.Message;
/** /**
* Created by Tzlil on 2/14/2016. * Created by Tzlil on 2/14/2016.
*/ */
public interface MessageHandler { public interface MessageHandler {
void handleSecretMessage(int sender, boolean isBroadcast, Message message); void handleSecretMessage(int sender, boolean isBroadcast, Message message);
void handleCommitmentMessage(int sender, boolean isBroadcast, Message message); void handleCommitmentMessage(int sender, boolean isBroadcast, Message message);
void handleComplaintMessage(int sender, boolean isBroadcast, Message message); void handleComplaintMessage(int sender, boolean isBroadcast, Message message);
void handleDoneMessage(int sender, boolean isBroadcast, Message message); void handleDoneMessage(int sender, boolean isBroadcast, Message message);
void handleAnswerMessage(int sender, boolean isBroadcast, Message message); void handleAnswerMessage(int sender, boolean isBroadcast, Message message);
void handleAbortMessage(int sender, boolean isBroadcast, Message message); void handleAbortMessage(int sender, boolean isBroadcast, Message message);
} }

View File

@ -1,63 +1,63 @@
package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol;
import Communication.MailHandler; import Communication.MailHandler;
import Communication.MessageHandler; import Communication.MessageHandler;
import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message; import com.google.protobuf.Message;
import meerkat.protobuf.DKGMessages; import meerkat.protobuf.DKGMessages;
/** /**
* Created by Tzlil on 2/29/2016. * Created by Tzlil on 2/29/2016.
*/ */
public class SecureDistributedKeyGenerationMailHandler extends MailHandler { public class MailHandler extends Communication.MailHandler {
private boolean isStage4; private boolean isStage4;
public SecureDistributedKeyGenerationMailHandler(MessageHandler messageHandler) { public MailHandler(MessageHandler messageHandler) {
super(messageHandler); super(messageHandler);
this.isStage4 = false; this.isStage4 = false;
} }
@Override @Override
public Message extractMessage(DKGMessages.Mail mail) { public Message extractMessage(DKGMessages.Mail mail) {
try { try {
Message message; Message message;
switch (mail.getType()) { switch (mail.getType()) {
case SECRET: case SHARE:
message = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage()); message = DKGMessages.DoubleShareMessage.parseFrom(mail.getMessage());
break; break;
case COMMITMENT: case COMMITMENT:
message = DKGMessages.CommitmentMessage.parseFrom(mail.getMessage()); message = DKGMessages.CommitmentMessage.parseFrom(mail.getMessage());
break; break;
case COMPLAINT: case COMPLAINT:
if(!isStage4) if(!isStage4)
message = DKGMessages.IDMessage.parseFrom(mail.getMessage()); message = DKGMessages.IDMessage.parseFrom(mail.getMessage());
else else
message = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage()); message = DKGMessages.DoubleShareMessage.parseFrom(mail.getMessage());
break; break;
case DONE: case DONE:
message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage());
break; break;
case ANSWER: case ANSWER:
message = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage()); message = DKGMessages.DoubleShareMessage.parseFrom(mail.getMessage());
break; break;
case ABORT: case ABORT:
message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage());
break; break;
default: default:
return null; return null;
} }
return message; return message;
} catch (InvalidProtocolBufferException e) { } catch (InvalidProtocolBufferException e) {
return null; return null;
} }
} }
public boolean isStage4() { public boolean isStage4() {
return isStage4; return isStage4;
} }
public void setStage4(boolean stage4) { public void setStage4(boolean stage4) {
isStage4 = stage4; isStage4 = stage4;
} }
} }

View File

@ -0,0 +1,29 @@
package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol;
import meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.DistributedKeyGenerationParty;
import meerkat.crypto.concrete.secret_shring.shamir.Polynomial;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
/**
* Created by Tzlil on 3/16/2016.
*
* an extension of DistributedKeyGenerationParty
* contains all relevant information on specific party during
* the run of the safe protocol
*/
public class Party<T> extends DistributedKeyGenerationParty<T> {
public Polynomial.Point shareT;
public boolean ysDoneFlag;
public ArrayList<T> verifiableValues;
public Set<Polynomial.Point> recoverSharesSet;
public Party(int id, int n, int t) {
super(id, n, t);
this.shareT = null;
this.ysDoneFlag = false;
this.verifiableValues = new ArrayList<T>(this.commitments);
this.recoverSharesSet = new HashSet<Polynomial.Point>();
}
}

View File

@ -0,0 +1,165 @@
package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol;
import meerkat.crypto.concrete.secret_shring.feldman_verifiable.VerifiableSecretSharing;
import meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.Protocol;
import meerkat.crypto.concrete.secret_shring.shamir.Polynomial;
import com.google.protobuf.ByteString;
import meerkat.protobuf.DKGMessages;
import org.factcenter.qilin.primitives.Group;
import org.factcenter.qilin.util.ByteEncoder;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Random;
import java.util.Set;
/**
* Created by Tzlil on 3/16/2016.
* TODO: comments
* TODO: put Channel (ChannelImpl) in constructor
*/
public class Protocol<T> extends meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.Protocol<T> {
private VerifiableSecretSharing<T> maskingShares;
private final T h;
private Party<T>[] parties;
public Protocol(int t, int n, BigInteger zi, Random random, BigInteger q, T g
, T h, Group<T> group, int id, ByteEncoder<T> byteEncoder) {
super(t, n, zi, random, q, g, group, id,byteEncoder);
this.h = h;
BigInteger r = new BigInteger(q.bitLength(),random).mod(q);
this.maskingShares = new VerifiableSecretSharing(t,n,r,random,q,h,group);
this.parties = new Party[n];
for (int i = 1; i <= n ; i++){
this.parties[i - 1] = new Party(i,n,t);
}
this.parties[id - 1].share = getShare(id);
this.parties[id - 1].shareT = maskingShares.getShare(id);
super.setParties(parties);
}
protected Party[] getParties(){
return parties;
}
protected void setParties(Party[] parties) {
super.setParties(parties);
this.parties = parties;
}
@Override
public void sendSecret(int j) {
Polynomial.Point secret = getShare(j);
Polynomial.Point secretT = maskingShares.getShare(j);
DKGMessages.DoubleShareMessage doubleSecretMessage = doubleShareMessage(id,j,secret,secretT);
// TODO: Change SHARE to SHARE
channel.sendMessage(j, DKGMessages.Mail.Type.SHARE, doubleSecretMessage);
}
@Override
public boolean isValidShare(int i){
Party party = parties[i - 1];
return isValidShare(party.share, party.shareT, party.verifiableValues, id);
}
/**
* test if share, shareT are valid with respect to verificationValues
* @param share
* @param shareT
* @param verificationValues
* @param j
* @return computeVerificationValue(j,verificationValues,group) == (g ^ share.y) * (h ^ shareT.y) mod q
*/
public boolean isValidShare(Polynomial.Point share, Polynomial.Point shareT, ArrayList<T> verificationValues, int j){
try {
T v = computeVerificationValue(j, verificationValues, group);
T exp = group.add(group.multiply(g, share.y), group.multiply(h, shareT.y));
return exp.equals(v);
}
catch (NullPointerException e){
return false;
}
}
/**
* create complaint message against i and broadcast it
* @param share
* @param shareT
* @param i
*/
private void broadcastComplaint(Polynomial.Point share, Polynomial.Point shareT, int i){
DKGMessages.DoubleShareMessage complaint = doubleShareMessage(i,id,share,shareT);
channel.broadcastMessage(DKGMessages.Mail.Type.COMPLAINT,complaint);
}
/**
* stage4.3 according to the protocol
* if check fails for index i, Pj
*/
public void computeAndBroadcastComplaints(Set<Integer> QUAL){
Party party;
for (int i : QUAL) {
party = parties[i - 1];
if (i != id) {
if (!super.isValidShare(party.share, party.commitments, id)) {
broadcastComplaint(party.share, party.shareT, i);
}
}
}
}
/**
* compute verification values and broadcast them
* verificationValues[k] = g ^ commitments [k] * h ^ maskingShares.commitments [k]
*/
public void computeAndBroadcastVerificationValues(){
ArrayList<T> verificationValues = new ArrayList<T>(t+1);
ArrayList<T> hBaseCommitments = maskingShares.getCommitmentsArrayList();
for (int k = 0 ; k <= t ; k++){
verificationValues.add(k,group.add(commitmentsArrayList.get(k),hBaseCommitments.get(k)));
}
broadcastCommitments(verificationValues);
}
/**
* pack share, shareT i,j to doubleShareMessage
* @param i
* @param j
* @param share
* @param shareT
* @return
*/
private DKGMessages.DoubleShareMessage doubleShareMessage(int i, int j, Polynomial.Point share, Polynomial.Point shareT){
DKGMessages.DoubleShareMessage doubleShareMessage = DKGMessages.DoubleShareMessage.newBuilder()
.setI(i)
.setJ(j)
.setSecret(ByteString.copyFrom(share.y.toByteArray()))
.setSecretT(ByteString.copyFrom(shareT.y.toByteArray()))
.build();
return doubleShareMessage;
}
@Override
public void broadcastComplaintAnswer(int j) {
DKGMessages.DoubleShareMessage answer = doubleShareMessage(id,j,getShare(j)
, maskingShares.getShare(j));
channel.broadcastMessage(DKGMessages.Mail.Type.ANSWER,answer);
}
public void broadcastAnswer(Polynomial.Point secret, Polynomial.Point secretT, int i){
DKGMessages.DoubleShareMessage complaint = doubleShareMessage(i,id,secret,secretT);
channel.broadcastMessage(DKGMessages.Mail.Type.ANSWER,complaint);
}
/**
* getter
* @return h
*/
public T getH() {
return h;
}
}

View File

@ -1,307 +1,326 @@
package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol;
import Arithmetics.Arithmetic; import meerkat.crypto.utilitis.Arithmetic;
import Arithmetics.Fp; import meerkat.crypto.utilitis.concrete.Fp;
import Communication.Network; import meerkat.crypto.utilitis.Channel;
import JointFeldmanProtocol.DistributedKeyGeneration; import meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.User;
import JointFeldmanProtocol.DistributedKeyGenerationUserImpl; import meerkat.crypto.concrete.secret_shring.shamir.Polynomial;
import ShamirSecretSharing.Polynomial; import meerkat.crypto.concrete.secret_shring.shamir.SecretSharing;
import ShamirSecretSharing.SecretSharing; import com.google.protobuf.Message;
import com.google.protobuf.Message; import meerkat.protobuf.DKGMessages;
import meerkat.protobuf.DKGMessages;
import java.math.BigInteger;
import java.math.BigInteger; import java.util.ArrayList;
/** /**
* Created by Tzlil on 3/16/2016. * Created by Tzlil on 3/16/2016.
*/ */
public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenerationUserImpl { public class User<T> extends meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.User<T> {
protected SecureDistributedKeyGenerationParty[] parties; protected Party<T>[] parties;
protected final SecureDistributedKeyGeneration sdkg; protected final Protocol<T> sdkg;
private Arithmetic<BigInteger> arithmetic; private Arithmetic<BigInteger> arithmetic;
private boolean isStage4; private boolean isStage4;
public SecureDistributedKeyGenerationUserImpl(SecureDistributedKeyGeneration sdkg, Network network) { public User(Protocol sdkg, Channel channel) {
super(sdkg, network,new SecureDistributedKeyGenerationMailHandler(null)); super(sdkg, channel);
this.sdkg = sdkg; this.sdkg = sdkg;
this.messageHandler = new MessageHandler(); this.parties = sdkg.getParties();
this.user.setMessageHandler(this.messageHandler); this.arithmetic = new Fp(sdkg.getQ());
this.parties = sdkg.getParties(); this.isStage4 = false;
this.arithmetic = new Fp(sdkg.getQ()); }
this.isStage4 = false;
} @Override
protected void registerReceiverCallback(){
/** this.mailHandler = new MailHandler(new MessageHandler());
* stage1 according to the protocol this.channel.registerReceiverCallback(mailHandler);
* 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. /**
*/ * stage1 according to the protocol
@Override * 1. Pi broadcasts Cik=Aik*Bik for k = 0,...,t.
protected void stage1() { * 2. Pi computes the shares Sij,Sij' for j = 1,...,n and sends Sij,Sij' secretly to Pj.
sdkg.broadcastVerificationValues(user); */
sdkg.sendSecrets(user); @Override
} protected void stage1() {
sdkg.computeAndBroadcastVerificationValues();
@Override sdkg.sendSecrets();
protected void waitUntilStageOneCompleted(){ }
super.waitUntilStageOneCompleted();
// save the received commitments as verification values @Override
BigInteger[] temp; protected void waitUntilStageOneCompleted(){
for (int i = 0 ; i < n; i++){ super.waitUntilStageOneCompleted();
temp = parties[i].verifiableValues; // save the received commitments as verification values
parties[i].verifiableValues = parties[i].commitments; ArrayList<T> temp;
parties[i].commitments = temp; for (int i = 0 ; i < n; i++){
} temp = parties[i].verifiableValues;
} parties[i].verifiableValues = parties[i].commitments;
parties[i].commitments = temp;
/** }
* 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 * stage2 according to the protocol
*/ * Pj verifies all the shares,sharesT he received
@Override * if check fails for an index i, Pj broadcasts a complaint against Pi.
protected void stage2(){ * Pj broadcasts done message at the end of this stage
sdkg.broadcastComplaints(user); */
//broadcast done message after all complaints @Override
DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build(); protected void stage2(){
user.broadcast(DKGMessages.Mail.Type.DONE,doneMessage); sdkg.broadcastComplaints();
} //broadcast done message after all complaints
DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build();
// TODO: ?? channel.broadcastMessage(DKGMessages.Mail.Type.DONE,doneMessage);
private void resolveQualifyingPublicKey(){ }
sdkg.broadcastCommitments(user);
// wait until all parties in QUAL broadcast their commitments or aborted /**
// TODO: in main run loop * broadcast commitments and recover parties information if necessary
for (int i:QUAL) { */
for(int k = 0; k <= t; k++) { private void resolveQualifyingPublicKey(){
while (parties[i - 1].commitments[k] == null && !parties[i - 1].aborted) { sdkg.broadcastCommitments();
try { // wait until all parties in QUAL broadcast their commitments or aborted
Thread.sleep(SleepTime); for (int i:QUAL) {
} catch (InterruptedException e) { for(int k = 0; k <= t; k++) {
// do nothing synchronized (parties[i - 1]) {
} while (parties[i - 1].commitments.get(k) == null && !parties[i - 1].aborted) {
} try {
} parties[i - 1].wait();
} } catch (InterruptedException e) {
sdkg.computeAndBroadcastComplaints(user,QUAL); //do nothing
//broadcast done message after all complaints }
DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build(); }
user.broadcast(DKGMessages.Mail.Type.DONE,doneMessage); }
}
// wait until all parties in QUAL done or aborted }
for (int i:QUAL) { sdkg.computeAndBroadcastComplaints(QUAL);
while (!parties[i - 1].ysDoneFlag && !parties[i - 1].aborted) { //broadcast done message after all complaints
try { DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build();
Thread.sleep(SleepTime); channel.broadcastMessage(DKGMessages.Mail.Type.DONE,doneMessage);
} catch (InterruptedException e) {
// do nothing // wait until all parties in QUAL done or aborted
} for (int i:QUAL) {
} synchronized ((parties[i - 1])) {
} while (!parties[i - 1].ysDoneFlag && !parties[i - 1].aborted) {
try {
// broadcast i private secret foreach i in QUAL that aborted parties[i - 1].wait();
for (int i:QUAL) { } catch (InterruptedException e) {
if(parties[i - 1].aborted){ //do nothing
sdkg.broadcastAnswer(user, parties[i - 1].share, parties[i - 1].shareT, i); }
} }
} }
// wait until at least t + 1 secrets will received foreach i in QUAL that aborted }
for (int i:QUAL) {
if(parties[i - 1].aborted){ // broadcast i private secret foreach i in QUAL that aborted
while (parties[i - 1].restoreSharesSet.size() <= t) { for (int i:QUAL) {
try { if(parties[i - 1].aborted){
Thread.sleep(SleepTime); sdkg.broadcastAnswer(parties[i - 1].share, parties[i - 1].shareT, i);
} catch (InterruptedException e) { }
// do nothing }
} // wait until at least t + 1 secrets will received foreach i in QUAL that aborted
} for (int i:QUAL) {
} synchronized ((parties[i - 1])) {
} if (parties[i - 1].aborted) {
while (parties[i - 1].recoverSharesSet.size() <= t) {
// restore necessary information try {
for (int i = 0; i < n ; i++) { parties[i - 1].wait();
if(parties[i].restoreSharesSet.isEmpty()){ } catch (InterruptedException e) {
continue; //do nothing
} }
Polynomial.Point[] shares = new Polynomial.Point[t + 1]; }
int j = 0; }
for (Polynomial.Point share: parties[i].restoreSharesSet){ }
shares[j++] = share; }
if (j >= shares.length){
break; // restore necessary information
} for (int i = 0; i < n ; i++) {
} if(parties[i].recoverSharesSet.isEmpty()){
Polynomial polynomial = SecretSharing.recoverPolynomial(shares,arithmetic); continue;
BigInteger[] coefficients = polynomial.getCoefficients(); }
for (int k = 0 ; k <= t; k++){ Polynomial.Point[] shares = new Polynomial.Point[t + 1];
parties[i].commitments[k] = group.multiply(g,coefficients[k]); int j = 0;
} for (Polynomial.Point share: parties[i].recoverSharesSet){
parties[i].share = new Polynomial.Point(BigInteger.valueOf(id),polynomial); shares[j++] = share;
} if (j >= shares.length){
} break;
}
/** }
* notifies mail handler that stage 4 was started Polynomial polynomial = SecretSharing.recoverPolynomial(shares,arithmetic);
*/ BigInteger[] coefficients = polynomial.getCoefficients();
protected void setStage4(){ for (int k = 0 ; k <= t; k++){
this.isStage4 = true; parties[i].commitments.add(k,group.multiply(g,coefficients[k]));
SecureDistributedKeyGenerationMailHandler handler = }
(SecureDistributedKeyGenerationMailHandler)user.getMailHandler(); parties[i].share = new Polynomial.Point(BigInteger.valueOf(id),polynomial);
handler.setStage4(true); }
} }
@Override /**
protected void stage4() { * notifies mail handler that stage 4 was started
setStage4(); */
resolveQualifyingPublicKey(); protected void setStage4(){
super.stage4(); this.isStage4 = true;
} ((MailHandler)this.mailHandler).setStage4(true);
}
private class MessageHandler extends DistributedKeyGenerationUserImpl.MessageHandler{
@Override
/** protected void stage4() {
* as in super, with extension to double secret message setStage4();
*/ resolveQualifyingPublicKey();
protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { super.stage4();
DKGMessages.SecretMessage secretMessage = DKGMessages.SecretMessage.newBuilder() }
.setI(doubleSecretMessage.getI())
.setJ(doubleSecretMessage.getJ()) private class MessageHandler extends meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.User.MessageHandler {
.setSecret(doubleSecretMessage.getSecret())
.build(); /**
return super.isValidSecretMessage(sender,isBroadcast,secretMessage); * as in super, with extension to double secret message
} */
protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleShareMessage doubleSecretMessage) {
/** DKGMessages.ShareMessage secretMessage = DKGMessages.ShareMessage.newBuilder()
* as in super, with extension to double secret message .setI(doubleSecretMessage.getI())
*/ .setJ(doubleSecretMessage.getJ())
@Override .setSecret(doubleSecretMessage.getSecret())
public void handleSecretMessage(int sender, boolean isBroadcast, Message message) { .build();
DKGMessages.DoubleSecretMessage doubleSecretMessage = (DKGMessages.DoubleSecretMessage)message; return super.isValidSecretMessage(sender,isBroadcast,secretMessage);
if (isValidSecretMessage(sender,isBroadcast,doubleSecretMessage)) { }
int i = doubleSecretMessage.getI();
parties[i - 1].share = extractSecret(id, doubleSecretMessage.getSecret()); /**
parties[i - 1].shareT = extractSecret(id, doubleSecretMessage.getSecretT()); * as in super, with extension to double secret message
} */
} @Override
public void handleSecretMessage(int sender, boolean isBroadcast, Message message) {
/** DKGMessages.DoubleShareMessage doubleSecretMessage = (DKGMessages.DoubleShareMessage)message;
* if !isStage4 as super, with extension to double secret message if (isValidSecretMessage(sender,isBroadcast,doubleSecretMessage)) {
* else answer message is valid if: int i = doubleSecretMessage.getI();
* 1. it was received in broadcast chanel synchronized (parties[i - 1]) {
* 2. secret.j == sender parties[i - 1].share = extractShare(id, doubleSecretMessage.getSecret());
* 3. QUAL contains i and j parties[i - 1].shareT = extractShare(id, doubleSecretMessage.getSecretT());
*/ parties[i - 1].notify();
protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { }
if(!isStage4) { }
DKGMessages.SecretMessage secretMessage = DKGMessages.SecretMessage.newBuilder() }
.setI(doubleSecretMessage.getI())
.setJ(doubleSecretMessage.getJ()) /**
.setSecret(doubleSecretMessage.getSecret()) * if !isStage4 as super, with extension to double secret message
.build(); * else answer message is valid if:
return super.isValidAnswerMessage(sender, isBroadcast, secretMessage); * 1. it was received in broadcast chanel
}else{ * 2. secret.j == sender
int i = doubleSecretMessage.getI(); * 3. QUAL contains i and j
int j = doubleSecretMessage.getJ(); */
return isBroadcast && j == sender && parties[i -1].aborted && !parties[j - 1].aborted protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKGMessages.DoubleShareMessage doubleSecretMessage) {
&& QUAL.contains(i) && QUAL.contains(j); if(!isStage4) {
} DKGMessages.ShareMessage secretMessage = DKGMessages.ShareMessage.newBuilder()
} .setI(doubleSecretMessage.getI())
.setJ(doubleSecretMessage.getJ())
/** .setSecret(doubleSecretMessage.getSecret())
* if !isStage4 as super, with extension to double secret message .build();
* else saves secret return super.isValidAnswerMessage(sender, isBroadcast, secretMessage);
*/ }else{
@Override int i = doubleSecretMessage.getI();
public void handleAnswerMessage(int sender, boolean isBroadcast, Message message) { int j = doubleSecretMessage.getJ();
DKGMessages.DoubleSecretMessage doubleSecretMessage = (DKGMessages.DoubleSecretMessage)message; return isBroadcast && j == sender && parties[i -1].aborted && !parties[j - 1].aborted
if(isValidAnswerMessage(sender,isBroadcast,doubleSecretMessage)) { && QUAL.contains(i) && QUAL.contains(j);
int i = doubleSecretMessage.getI(); }
int j = doubleSecretMessage.getJ(); }
Polynomial.Point secret = extractSecret(j, doubleSecretMessage.getSecret());
Polynomial.Point secretT = extractSecret(j, doubleSecretMessage.getSecretT()); /**
if (!isStage4) { * if !isStage4 as super, with extension to double secret message
if (sdkg.isValidShare(secret, secretT, parties[j - 1].verifiableValues, i)) { * else saves secret
parties[i - 1].complaints[j - 1] = DistributedKeyGeneration.ComplaintState.NonDisqualified; */
@Override
} else { public void handleAnswerMessage(int sender, boolean isBroadcast, Message message) {
parties[i - 1].complaints[j - 1] = DistributedKeyGeneration.ComplaintState.Disqualified; DKGMessages.DoubleShareMessage doubleSecretMessage = (DKGMessages.DoubleShareMessage)message;
} if(isValidAnswerMessage(sender,isBroadcast,doubleSecretMessage)) {
if(j == id){ int i = doubleSecretMessage.getI();
parties[i - 1].share = secret; int j = doubleSecretMessage.getJ();
parties[i - 1].shareT = secretT; Polynomial.Point secret = extractShare(j, doubleSecretMessage.getSecret());
} Polynomial.Point secretT = extractShare(j, doubleSecretMessage.getSecretT());
} else if (sdkg.isValidShare(secret, secretT, parties[j - 1].verifiableValues, i)) { synchronized (parties[i - 1]) {
// TODO: Check that this is ok if (!isStage4) {
parties[i - 1].restoreSharesSet.add(secret); if (sdkg.isValidShare(secret, secretT, parties[j - 1].verifiableValues, i)) {
} parties[i - 1].complaints[j - 1] = meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.Protocol.ComplaintState.NonDisqualified;
}
} } else {
parties[i - 1].complaints[j - 1] = meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.Protocol.ComplaintState.Disqualified;
/** }
* as in super with respect to protocol stage if (j == id) {
*/ parties[i - 1].share = secret;
@Override parties[i - 1].shareT = secretT;
protected boolean isValidDoneMessage(int sender, boolean isBroadcast) { }
if(!isStage4) { } else if (sdkg.isValidShare(secret, secretT, parties[i - 1].verifiableValues, j)) {
return super.isValidDoneMessage(sender, isBroadcast); parties[i - 1].recoverSharesSet.add(secret);
}else{ }
return isBroadcast && !parties[sender - 1].ysDoneFlag; parties[i - 1].notify();
} }
} }
}
/**
* as in super with respect to protocol state /**
*/ * as in super with respect to protocol stage
@Override */
public void handleDoneMessage(int sender, boolean isBroadcast, Message message) { @Override
if(!isStage4) protected boolean isValidDoneMessage(int sender, boolean isBroadcast) {
super.handleDoneMessage(sender, isBroadcast, message); if(!isStage4) {
else{ return super.isValidDoneMessage(sender, isBroadcast);
if(isValidDoneMessage(sender,isBroadcast)) { }else{
parties[sender - 1].ysDoneFlag = true; return isBroadcast && !parties[sender - 1].ysDoneFlag;
} }
} }
}
/**
/** * as in super with respect to protocol state
* use only in stage4 */
* complaint message is valid if: @Override
* 1. it was received in broadcast chanel public void handleDoneMessage(int sender, boolean isBroadcast, Message message) {
* 2. secret.j == sender if(!isStage4)
* 3. QUAL contains i and j super.handleDoneMessage(sender, isBroadcast, message);
*/ else{
protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, if(isValidDoneMessage(sender,isBroadcast)) {
DKGMessages.DoubleSecretMessage complaintMessage){ synchronized (parties[sender - 1]) {
int i = complaintMessage.getI(); parties[sender - 1].ysDoneFlag = true;
int j = complaintMessage.getJ(); parties[sender - 1].notify();
return isBroadcast && j == sender && QUAL.contains(i) && QUAL.contains(j); }
} }
}
/** }
* if !isStage4 as in super
* else if secret,secretT are valid with respect to verifiableValues but /**
* secret is not valid with respect to commitments then * use only in stage4
* marks i as aborted * complaint message is valid if:
*/ * 1. it was received in broadcast chanel
@Override * 2. secret.j == sender
public void handleComplaintMessage(int sender, boolean isBroadcast, Message message) { * 3. QUAL contains i and j
if(!isStage4) { */
super.handleComplaintMessage(sender, isBroadcast, message); protected boolean isValidComplaintMessage(int sender, boolean isBroadcast,
}else { DKGMessages.DoubleShareMessage complaintMessage){
DKGMessages.DoubleSecretMessage ysComplaintMessage =(DKGMessages.DoubleSecretMessage)message; int i = complaintMessage.getI();
if (isValidComplaintMessage(sender,isBroadcast,ysComplaintMessage)) { int j = complaintMessage.getJ();
int i = ysComplaintMessage.getI(); return isBroadcast && j == sender && QUAL.contains(i) && QUAL.contains(j);
int j = ysComplaintMessage.getJ(); }
Polynomial.Point secret = extractSecret(i,ysComplaintMessage.getSecret());
Polynomial.Point secretT = extractSecret(i,ysComplaintMessage.getSecretT()); /**
if (sdkg.isValidShare(secret, secretT, parties[i - 1].verifiableValues, j) * if !isStage4 as in super
&& !dkg.isValidSecret(secret,parties[i - 1].commitments, j)) { * else if secret,secretT are valid with respect to verifiableValues but
parties[i - 1].aborted = true; * secret is not valid with respect to commitments then
} * marks i as aborted
} */
} @Override
} public void handleComplaintMessage(int sender, boolean isBroadcast, Message message) {
} if(!isStage4) {
} super.handleComplaintMessage(sender, isBroadcast, message);
}else {
DKGMessages.DoubleShareMessage ysComplaintMessage =(DKGMessages.DoubleShareMessage)message;
if (isValidComplaintMessage(sender,isBroadcast,ysComplaintMessage)) {
int i = ysComplaintMessage.getI();
int j = ysComplaintMessage.getJ();
Polynomial.Point secret = extractShare(i,ysComplaintMessage.getSecret());
Polynomial.Point secretT = extractShare(i,ysComplaintMessage.getSecretT());
if (sdkg.isValidShare(secret, secretT, parties[i - 1].verifiableValues, j)
&& !dkg.isValidShare(secret,parties[i - 1].commitments, j)) {
synchronized (parties[i - 1]) {
parties[i - 1].aborted = true;
parties[i - 1].notify();
}
}
}
}
}
}
}

View File

@ -1,49 +1,49 @@
package JointFeldmanProtocol; package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol;
import Communication.MailHandler; import Communication.MailHandler;
import Communication.MessageHandler; import Communication.MessageHandler;
import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message; import com.google.protobuf.Message;
import meerkat.protobuf.DKGMessages; import meerkat.protobuf.DKGMessages;
/** /**
* Created by Tzlil on 2/29/2016. * Created by Tzlil on 2/29/2016.
*/ */
public class DistributedKeyGenerationMailHandler extends MailHandler { public class MailHandler extends Communication.MailHandler {
public DistributedKeyGenerationMailHandler(MessageHandler messageHandler) { public MailHandler(MessageHandler messageHandler) {
super(messageHandler); super(messageHandler);
} }
@Override @Override
public Message extractMessage(DKGMessages.Mail mail) { public Message extractMessage(DKGMessages.Mail mail) {
try { try {
Message message; Message message;
switch (mail.getType()) { switch (mail.getType()) {
case SECRET: case SHARE:
message = DKGMessages.SecretMessage.parseFrom(mail.getMessage()); message = DKGMessages.ShareMessage.parseFrom(mail.getMessage());
break; break;
case COMMITMENT: case COMMITMENT:
message = DKGMessages.CommitmentMessage.parseFrom(mail.getMessage()); message = DKGMessages.CommitmentMessage.parseFrom(mail.getMessage());
break; break;
case COMPLAINT: case COMPLAINT:
message = DKGMessages.IDMessage.parseFrom(mail.getMessage()); message = DKGMessages.IDMessage.parseFrom(mail.getMessage());
break; break;
case DONE: case DONE:
message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage());
break; break;
case ANSWER: case ANSWER:
message = DKGMessages.SecretMessage.parseFrom(mail.getMessage()); message = DKGMessages.ShareMessage.parseFrom(mail.getMessage());
break; break;
case ABORT: case ABORT:
message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage());
break; break;
default: default:
return null; return null;
} }
return message; return message;
} catch (InvalidProtocolBufferException e) { } catch (InvalidProtocolBufferException e) {
return null; return null;
} }
} }
} }

View File

@ -1,32 +1,35 @@
package JointFeldmanProtocol; package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol;
import ShamirSecretSharing.Polynomial; import meerkat.crypto.concrete.secret_shring.shamir.Polynomial;
import java.math.BigInteger; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
/** /**
* Created by Tzlil on 3/14/2016. * Created by Tzlil on 3/14/2016.
* *
* contains all relevant information on specific party during * contains all relevant information on specific party during
* the run of Joint Feldamn protocol * the run of Joint Feldamn protocol
*/ */
// TODO: comments for every field. // TODO: comments for every field.
public class DistributedKeyGenerationParty { public class Party<T> {
public final int id; public final int id;
public Polynomial.Point share; public Polynomial.Point share;
public BigInteger[] commitments; public ArrayList<T> commitments;
public boolean doneFlag; public boolean doneFlag;
public DistributedKeyGeneration.ComplaintState[] complaints; public DistributedKeyGeneration.ComplaintState[] complaints;
public boolean aborted; public boolean aborted;
public DistributedKeyGenerationParty(int id, int n, int t) { public Party(int id, int n, int t) {
this.id = id; this.id = id;
this.share = null; this.share = null;
this.doneFlag = false; this.doneFlag = false;
this.complaints = new DistributedKeyGeneration.ComplaintState[n]; this.complaints = new DistributedKeyGeneration.ComplaintState[n];
Arrays.fill(this.complaints, DistributedKeyGeneration.ComplaintState.OK); Arrays.fill(this.complaints, DistributedKeyGeneration.ComplaintState.OK);
this.commitments = new BigInteger[t + 1]; this.commitments = new ArrayList<T>(t + 1);
this.aborted = false; for (int i = 0; i <= t ; i++){
} commitments.add(null);
} }
this.aborted = false;
}
}

View File

@ -1,280 +1,356 @@
package JointFeldmanProtocol; package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol;
import Communication.User; import meerkat.crypto.utilitis.Channel;
import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; import meerkat.crypto.concrete.secret_shring.feldman_verifiable.VerifiableSecretSharing;
import ShamirSecretSharing.Polynomial; import meerkat.crypto.concrete.secret_shring.shamir.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.Group;
import org.factcenter.qilin.util.ByteEncoder;
import java.math.BigInteger;
import java.util.Arrays; import java.math.BigInteger;
import java.util.HashSet; import java.util.*;
import java.util.Random;
import java.util.Set; /**
* Created by Tzlil on 3/14/2016.
/** *
* Created by Tzlil on 3/14/2016. * an implementation of JointFeldman distributed key generation protocol.
*/ *
// TODO: Lots of comments... * allows set of n parties to generate random key with threshold t.
// TODO: User Channel instead of User */
public class DistributedKeyGeneration extends VerifiableSecretSharing { public class Protocol<T> extends VerifiableSecretSharing<T> {
public enum ComplaintState { public enum ComplaintState {
/** /**
* No complaints, no response required at this point. * No complaints, no response required at this point.
*/ */
OK, OK,
/** /**
* Party received complaint, waiting for response from party * Party received complaint, waiting for response from party
*/ */
Waiting, Waiting,
/** /**
* Party gave invalid answer to conplaint. * Party gave invalid answer to conplaint.
*/ */
Disqualified, Disqualified,
/** /**
* Party received complaint, gave valid answer. * Party received complaint, gave valid answer.
*/ */
NonDisqualified NonDisqualified
} }
/** /**
* My share id. * My share id.
*/ */
protected final int id; protected final int id;
/** /**
* All parties participating in key generation. * All parties participating in key generation.
* parties[id-1] has my info. * parties[id-1] has my info.
*/ */
private DistributedKeyGenerationParty[] parties; private Party<T>[] parties;
/**
// TODO: Copy comment * communication object
public DistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger q, BigInteger g */
, Group<BigInteger> group, int id) { protected Channel channel;
super(t, n, zi, random, q, g,group);
this.id = id;
this.parties = new DistributedKeyGenerationParty[n]; /**
for (int i = 1; i <= n ; i++){ * Encode/Decode group elements
this.parties[i - 1] = new DistributedKeyGenerationParty(i,n,t); */
} protected final ByteEncoder<T> encoder;
this.parties[id - 1].share = getShare(id);
} /**
* constructor
protected void setParties(DistributedKeyGenerationParty[] parties){ * @param q a large prime.
this.parties = parties; * @param t threshold. Any t+1 share holders can recover the secret,
} * but any set of at most t share holders cannot
* @param n number of share holders
protected DistributedKeyGenerationParty[] getParties(){ * @param zi secret, chosen from Zq
return parties; * @param random use for generate random polynomial
} * @param group
* @param q a large prime dividing group order.
/** * @param g a generator of cyclic group of order q.
* stage1.1 according to the protocol * the generated group is a subgroup of the given group.
* Pi broadcasts Aik for k = 0,...,t. * it must be chosen such that computing discrete logarithms is hard in this group.
*/ */
public void broadcastCommitments(User user){ public Protocol(int t, int n, BigInteger zi, Random random, BigInteger q, T g
broadcastCommitments(user,commitmentsArray); , Group<T> group, int id, ByteEncoder<T> byteEncoder) {
} super(t, n, zi, random, q, g,group);
this.id = id;
public void broadcastCommitments(User user, BigInteger[] commitments){ this.parties = new Party[n];
DKGMessages.CommitmentMessage commitmentMessage; for (int i = 1; i <= n ; i++){
for (int k = 0; k <= t ; k++){ this.parties[i - 1] = new Party(i,n,t);
commitmentMessage = DKGMessages.CommitmentMessage.newBuilder() }
.setCommitment(ByteString.copyFrom(commitments[k].toByteArray())) this.parties[id - 1].share = getShare(id);
.setK(k) this.encoder = byteEncoder;
.build(); }
user.broadcast(DKGMessages.Mail.Type.COMMITMENT, commitmentMessage);
} /**
} * setter
* @param channel
/** */
* Send user j her secret share (of my polynomial) public void setChannel(Channel channel){
* @param user this.channel = channel;
* @param j }
*/
public void sendSecret(User user, int j){ /**
ByteString secret = ByteString.copyFrom(getShare(j).y.toByteArray()); * setter
user.send(j, DKGMessages.Mail.Type.SECRET, * @param parties
DKGMessages.SecretMessage.newBuilder() */
.setI(id) protected void setParties(Party[] parties){
.setJ(j) this.parties = parties;
.setSecret(secret) }
.build());
} /**
* getter
/** * @return
* stage1.2 according to the protocol */
* Pi computes the shares Sij for j = 1,...,n and sends Sij secretly to Pj. protected Party[] getParties(){
*/ return parties;
public void sendSecrets(User user){ }
for (int j = 1; j <= n ; j++){
if(j != id){ /**
sendSecret(user,j); * stage1.1 according to the protocol
} * Pi broadcasts Aik for k = 0,...,t.
} */
} public void broadcastCommitments(){
broadcastCommitments(commitmentsArrayList);
/** }
* TODO: comment
* @param i /**
* @return * pack commitments as messages and broadcast them
*/ * @param commitments
public boolean isValidSecret(int i){ */
DistributedKeyGenerationParty party = parties[i - 1]; public void broadcastCommitments(ArrayList<T> commitments){
return isValidSecret(party.share,party.commitments,id); DKGMessages.CommitmentMessage commitmentMessage;
} for (int k = 0; k <= t ; k++){
commitmentMessage = DKGMessages.CommitmentMessage.newBuilder()
/** .setCommitment(ByteString.copyFrom(encoder.encode(commitments.get(k))))
* TODO: Move to VerifiableSecretSharing .setK(k)
* @param secret .build();
* @param commitments channel.broadcastMessage(DKGMessages.Mail.Type.COMMITMENT, commitmentMessage);
* @param j }
* @return computeVerificationValue(j,commitments,group) == g ^ secret.y mod q }
*/
public boolean isValidSecret(Polynomial.Point secret, BigInteger[] commitments, int j){ /**
try{ * Send channel j her secret share (of my polynomial)
BigInteger v = computeVerificationValue(j,commitments,group); * @param j
return group.multiply(g,secret.y).equals(v); */
} public void sendSecret(int j){
catch (NullPointerException e){ ByteString secret = ByteString.copyFrom(getShare(j).y.toByteArray());
return false; channel.sendMessage(j, DKGMessages.Mail.Type.SHARE,
} DKGMessages.ShareMessage.newBuilder()
} .setI(id)
.setJ(j)
/** .setSecret(secret)
* stage2 according to the protocol .build());
* Pj verifies all the shares he received (using isValidShare) }
* if check fails for an index i, Pj broadcasts a complaint against Pi.
*/ /**
public void broadcastComplaints(User user){ * stage1.2 according to the protocol
for (int i = 1; i <= n ; i++ ){ * Pi computes the shares Sij for j = 1,...,n and sends Sij secretly to Pj.
if(i != id && !isValidSecret(i)) { */
broadcastComplaint(user,i); public void sendSecrets(){
} for (int j = 1; j <= n ; j++){
} if(j != id){
} sendSecret(j);
}
private void broadcastComplaint(User user, int i){ }
//message = new Message(Type.Complaint, j) }
DKGMessages.IDMessage complaint = DKGMessages.IDMessage.newBuilder()
.setId(i) /**
.build(); *
user.broadcast(DKGMessages.Mail.Type.COMPLAINT, complaint); * @param i
} * @return computeVerificationValue(j,parties[i - 1].commitments,group) == g ^ parties[i - 1].share mod q
*/
public void broadcastComplaintAnswer(User user, int j){ public boolean isValidShare(int i){
user.broadcast(DKGMessages.Mail.Type.ANSWER, DKGMessages.SecretMessage.newBuilder() Party<T> party = parties[i - 1];
.setI(id) return isValidShare(party.share,party.commitments,id);
.setJ(j) }
.setSecret(ByteString.copyFrom(getShare(j).y.toByteArray()))
.build()); /**
} * @param share
* @param commitments
/** * @param j
* stage3.1 according to the protocol * @return computeVerificationValue(j,commitments,group) == g ^ secret.y mod q
* if more than t players complain against a player Pi he is disqualified. */
*/ public boolean isValidShare(Polynomial.Point share, ArrayList<T> commitments, int j){
public void answerAllComplainingPlayers(User user){ try{
ComplaintState[] complaints = parties[id - 1].complaints; T v = computeVerificationValue(j,commitments,group);
for (int i = 1; i <= n ; i++) { return group.multiply(g,share.y).equals(v);
switch (complaints[i - 1]) { }
case Waiting: catch (NullPointerException e){
broadcastComplaintAnswer(user,i); return false;
break; }
default: }
break;
} /**
} * stage2 according to the protocol
} * Pj verifies all the shares he received (using isValidShare)
* if check fails for an index i, Pj broadcasts a complaint against Pi.
/** */
* stage3.2 according to the protocol public void broadcastComplaints(){
* if any of the revealed shares fails the verification test, player Pi is disqualified. for (int i = 1; i <= n ; i++ ){
* set QUAL to be the set of non-disqualified players. if(i != id && !isValidShare(i)) {
*/ broadcastComplaint(i);
public Set<Integer> calcQUAL(){ }
Set<Integer> QUAL = new HashSet<Integer>(); }
boolean nonDisqualified; }
int counter;
for (int i = 1; i <= n; i++){ /**
ComplaintState[] complaints = parties[i - 1].complaints; * create a complaint message against i and broadcast it
nonDisqualified = true; * @param i
counter = 0; */
for (int j = 1; j <= n; j++){ private void broadcastComplaint(int i){
switch (complaints[j - 1]) { //message = new Message(Type.Complaint, j)
case OK: DKGMessages.IDMessage complaint = DKGMessages.IDMessage.newBuilder()
break; .setId(i)
case NonDisqualified: .build();
// TODO: Add test for false complaint channel.broadcastMessage(DKGMessages.Mail.Type.COMPLAINT, complaint);
counter++; }
break;
default: /**
nonDisqualified = false; * create an answer message for j and broadcast it
break; * @param j
} */
if(!nonDisqualified) public void broadcastComplaintAnswer(int j){
break; channel.broadcastMessage(DKGMessages.Mail.Type.ANSWER, DKGMessages.ShareMessage.newBuilder()
} .setI(id)
if(nonDisqualified && counter <= t){ .setJ(j)
QUAL.add(i); .setSecret(ByteString.copyFrom(getShare(j).y.toByteArray()))
} .build());
} }
return QUAL;
} /**
* stage3.1 according to the protocol
/** * if more than t players complain against a player Pi he is disqualified.
* compute Y, the commitment to the final public key (includes only qualifying set) */
* stage4.1 according to the protocol public void answerAllComplainingPlayers(){
* public value y is computed as y = multiplication of yi mod p for i in QUAL ComplaintState[] complaints = parties[id - 1].complaints;
*/ for (int i = 1; i <= n ; i++) {
public BigInteger calcY(Set<Integer> QUAL){ switch (complaints[i - 1]) {
BigInteger y = group.zero(); case Waiting:
for (int i : QUAL) { broadcastComplaintAnswer(i);
y = group.add(y , parties[i - 1].commitments[0]); break;
} default:
return y; break;
} }
}
/** }
* TODO: better comment.
* stage4.2 according to the protocol /**
* public verification values are computed as Ak = multiplication of Aik mod p for i in QUAL for k = 0,...,t * stage3.2 according to the protocol
*/ * if any of the revealed shares fails the verification test, player Pi is disqualified.
public BigInteger[] calcCommitments(Set<Integer> QUAL){ * set QUAL to be the set of non-disqualified players.
BigInteger[] commitments = new BigInteger[t + 1]; */
Arrays.fill(commitments,group.zero()); public Set<Integer> calcQUAL(){
for (int i : QUAL) { Set<Integer> QUAL = new HashSet<Integer>();
for (int k = 0; k <= t; k++){ boolean nonDisqualified;
commitments[k] = group.add(commitments[k], parties[i - 1].commitments[k]); int counter;
} for (int i = 1; i <= n; i++){
} ComplaintState[] complaints = parties[i - 1].complaints;
return commitments; nonDisqualified = true;
} counter = 0;
for (int j = 1; j <= n; j++){
/** switch (complaints[j - 1]) {
* TODO: better comment. case OK:
* stage4.3 according to the protocol break;
* Pj sets is share of the secret as xj = sum of Sij mod q for i in QUAL case NonDisqualified:
*/ counter++;
public Polynomial.Point calcShare(Set<Integer> QUAL){ break;
BigInteger xj = BigInteger.ZERO; default:
for (int i : QUAL) { nonDisqualified = false;
xj = xj.add(parties[i - 1].share.y); break;
} }
return new Polynomial.Point(BigInteger.valueOf(id) , xj.mod(q)); if(!nonDisqualified)
} break;
}
/** if(nonDisqualified && counter <= t){
* getter QUAL.add(i);
* @return id }
*/ }
public int getId() { return QUAL;
return id; }
}
/**
} * compute Y, the commitment to the final public key (includes only qualifying set)
* stage4.1 according to the protocol
* public value y is computed as y = multiplication of yi mod p for i in QUAL
*/
public T calcY(Set<Integer> QUAL){
T y = group.zero();
for (int i : QUAL) {
y = group.add(y , parties[i - 1].commitments.get(0));
}
return y;
}
/**
* stage4.2 according to the protocol
* public verification values are computed as Ak = multiplication
* of Aik mod p for i in QUAL for k = 0,...,t
*/
public ArrayList<T> calcCommitments(Set<Integer> QUAL){
ArrayList<T> commitments = new ArrayList<T>(t+1);
T value;
for (int k = 0; k <= t; k++){
value = group.zero();
for (int i : QUAL) {
value = group.add(value, parties[i - 1].commitments.get(k));
}
commitments.add(k,value);
}
return commitments;
}
/**
* stage4.3 according to the protocol
* Pj sets is share of the share as xj = sum of Sij mod q for i in QUAL
*/
public Polynomial.Point calcShare(Set<Integer> QUAL){
BigInteger xj = BigInteger.ZERO;
for (int i : QUAL) {
xj = xj.add(parties[i - 1].share.y);
}
return new Polynomial.Point(BigInteger.valueOf(id) , xj.mod(q));
}
/**
* decode commitment from arr
* @param arr
* @return
*/
public T decodeCommitment(byte[] arr){
return encoder.decode(arr);
}
/**
* getter
* @return id
*/
public int getId() {
return id;
}
/**
* getter
* @return channel
*/
public Channel getChannel() {
return channel;
}
/**
* getter
* @return encoder
*/
public ByteEncoder<T> getEncoder() {
return encoder;
}
}

View File

@ -1,393 +1,454 @@
package JointFeldmanProtocol; package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol;
import Communication.MailHandler; import meerkat.crypto.utilitis.Channel;
import Communication.Network; import Communication.MailHandler;
import Communication.User; import meerkat.crypto.concrete.secret_shring.shamir.Polynomial;
import ShamirSecretSharing.Polynomial; import com.google.protobuf.ByteString;
import UserInterface.DistributedKeyGenerationUser; import com.google.protobuf.Message;
import com.google.protobuf.ByteString; import meerkat.protobuf.DKGMessages;
import com.google.protobuf.Message; import org.factcenter.qilin.primitives.Group;
import meerkat.protobuf.DKGMessages;
import org.factcenter.qilin.primitives.Group; import java.math.BigInteger;
import java.util.ArrayList;
import java.math.BigInteger; import java.util.Set;
import java.util.Arrays; import meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.DistributedKeyGeneration.ComplaintState;
import java.util.Set;
import JointFeldmanProtocol.DistributedKeyGeneration.ComplaintState; /**
* Created by Tzlil on 3/14/2016.
/** * TODO: Comments
* Created by Tzlil on 3/14/2016. * TODO: Replace polling with monitors/wait/notify (remember synchronization)
* TODO: Comments */
* TODO: Replace polling with monitors/wait/notify (remember synchronization) public class User<T> implements Runnable{
*/
public class DistributedKeyGenerationUserImpl implements DistributedKeyGenerationUser { protected final DistributedKeyGeneration<T> dkg;
// TODO: remove protected final T g;
protected final static int SleepTime = 300; protected final Group<T> group;
protected final int n;
protected final DistributedKeyGeneration dkg; protected final int t;
protected final int id;
protected final BigInteger g; protected MailHandler mailHandler;
protected final Group<BigInteger> group;
protected final int n; protected final Channel channel;
protected final int t; protected final Party[] parties;
protected final int id; protected Set<Integer> QUAL; // set of all non-disqualified parties
protected Polynomial.Point share; // final share of the secrete
protected MessageHandler messageHandler; protected ArrayList<T> commitments; // public verification values
protected final User user; protected T y; // final public value
protected final DistributedKeyGenerationParty[] parties;
protected Set<Integer> QUAL; // set of all non-disqualified parties public User(DistributedKeyGeneration<T> dkg, Channel channel) {
protected BigInteger[] commitments; // public verification values this.dkg = dkg;
protected Polynomial.Point share; // final share of the secrete
protected BigInteger y; // final public value this.g = dkg.getGenerator();
this.group = dkg.getGroup();
public DistributedKeyGenerationUserImpl(DistributedKeyGeneration dkg, Network network){ this.n = dkg.getN();
this(dkg,network,new DistributedKeyGenerationMailHandler(null)); this.t = dkg.getT();
} this.id = dkg.getId();
public DistributedKeyGenerationUserImpl(DistributedKeyGeneration dkg, Network network, MailHandler mailHandler) {
this.dkg = dkg; this.channel = channel;
dkg.setChannel(channel);
this.g = dkg.getGenerator(); registerReceiverCallback();
this.group = dkg.getGroup();
this.n = dkg.getN(); this.parties = dkg.getParties();
this.t = dkg.getT(); this.QUAL = null;
this.id = dkg.getId(); this.commitments = null;
this.share = null;
this.messageHandler = new MessageHandler(); this.y = null;
mailHandler.setMessageHandler(this.messageHandler);
this.user = network.connect(mailHandler,dkg.getId()); }
this.parties = dkg.getParties();
this.QUAL = null; /**
this.commitments = null; * create MailHandler and register it as ReceiverCallback
this.share = null; */
this.y = null; protected void registerReceiverCallback(){
} this.mailHandler = new DistributedKeyGenerationMailHandler(new MessageHandler());
channel.registerReceiverCallback(mailHandler);
/** }
* stage1 according to the protocol
* 1. Pi broadcasts Aik for k = 0,...,t. /**
* 2. Pi computes the shares Sij for j = 1,...,n and sends Sij secretly to Pj. * stage1 according to the protocol
*/ * 1. Pi broadcasts Aik for k = 0,...,t.
protected void stage1() { * 2. Pi computes the shares Sij for j = 1,...,n and sends Sij secretly to Pj.
dkg.broadcastCommitments(user); */
dkg.sendSecrets(user); protected void stage1() {
} dkg.broadcastCommitments();
dkg.sendSecrets();
}
protected void waitUntilStageOneCompleted(){
// all parties send their share or aborted
for (int i = 0 ; i < n ; i++){ protected void waitUntilStageOneCompleted(){
while (parties[i].share == null && !parties[i].aborted){ // all parties send their share or aborted
try { for (int i = 0 ; i < n ; i++){
Thread.sleep(SleepTime); synchronized (parties[i]) {
} catch (InterruptedException e) { while (parties[i].share == null && !parties[i].aborted) {
// do nothing try {
} parties[i].wait();
} } catch (InterruptedException e) {
} //do nothing
// all parties broadcast their commitments or aborted }
for (int i = 0 ; i < n ; i++){ }
for (int k = 0 ; k <= t ; k++) { }
while (parties[i].commitments[k] == null && !parties[i].aborted) { }
try { // all parties broadcast their commitments or aborted
Thread.sleep(SleepTime); for (int i = 0 ; i < n ; i++){
} catch (InterruptedException e) { for (int k = 0 ; k <= t ; k++) {
// do nothing synchronized (parties[i]) {
} while (parties[i].commitments.get(k) == null && !parties[i].aborted) {
} try {
} parties[i].wait();
} } catch (InterruptedException e) {
} //do nothing
}
/** }
* 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.broadcastComplaints(user); * stage2 according to the protocol
//broadcast done message after all complaints * Pj verifies all the shares he received
DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build(); * if check fails for an index i, Pj broadcasts a complaint against Pi.
user.broadcast(DKGMessages.Mail.Type.DONE,doneMessage); * Pj broadcasts done message at the end of this stage
} */
protected void stage2(){
dkg.broadcastComplaints();
protected void waitUntilStageTwoCompleted(){ //broadcast done message after all complaints
// all parties done or aborted DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build();
for (int i = 0 ; i < n ; i++){ channel.broadcastMessage(DKGMessages.Mail.Type.DONE,doneMessage);
while (!parties[i].doneFlag && !parties[i].aborted){ }
try {
Thread.sleep(SleepTime);
} catch (InterruptedException e) { protected void waitUntilStageTwoCompleted(){
// do nothing // all parties done or aborted
} for (int i = 0 ; i < n ; i++){
} synchronized (parties[i]) {
} while (!parties[i].doneFlag && !parties[i].aborted) {
} try {
parties[i].wait();
/** } catch (InterruptedException e) {
* stage3 according to the protocol //do nothing
* 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);
// wait until there is no complaint waiting for answer /**
for (int i = 0; i < n; i++){ * stage3 according to the protocol
for (int j = 0; j < n; j++){ * 1. if more than t players complain against a player Pi he is disqualified.
while (parties[i].complaints[j].equals(ComplaintState.Waiting) && !parties[i].aborted){ * otherwise Pi broadcasts the share Sij for each complaining player Pj.
try { * 2. if any of the revealed shares fails the verification test, player Pi is disqualified.
Thread.sleep(SleepTime); * set QUAL to be the set of non-disqualified players.
} catch (InterruptedException e) { */
// do nothing protected void stage3(){
} dkg.answerAllComplainingPlayers();
} // wait until there is no complaint waiting for answer
} for (int i = 0; i < n; i++){
} for (int j = 0; j < n; j++){
this.QUAL = dkg.calcQUAL(); synchronized (parties[i]) {
} while (parties[i].complaints[j].equals(ComplaintState.Waiting) && !parties[i].aborted) {
try {
/** parties[i].wait();
* stage4 according to the protocol } catch (InterruptedException e) {
* 1. public value y is computed as y = multiplication of yi mod p for i in QUAL //do nothing
* 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(){ }
this.y = dkg.calcY(QUAL); }
this.commitments = dkg.calcCommitments(QUAL); this.QUAL = dkg.calcQUAL();
this.share = dkg.calcShare(QUAL); }
}
/**
protected void startReceiver(){ * stage4 according to the protocol
user.getReceiverThread().start(); * 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
protected void stopReceiver(){ * 3. Pj sets is share of the secret as xj = sum of Sij mod q for i in QUAL
user.getReceiverThread().interrupt(); */
} protected void stage4(){
this.y = dkg.calcY(QUAL);
@Override this.commitments = dkg.calcCommitments(QUAL);
public void run() { this.share = dkg.calcShare(QUAL);
startReceiver(); }
stage1();
waitUntilStageOneCompleted(); @Override
stage2(); public void run() {
waitUntilStageTwoCompleted(); stage1();
stage3(); waitUntilStageOneCompleted();
stage4(); stage2();
stopReceiver(); waitUntilStageTwoCompleted();
} stage3();
stage4();
/** }
* Request the current run loop to exit gracefully
*/ /**
public void stop() { * Request the current run loop to exit gracefully
// TODO: implement */
} public void stop() {
@Override }
public BigInteger[] getCommitments() {
return Arrays.copyOf(commitments, commitments.length); /**
} * getter
* @return commitments
@Override */
public BigInteger getGenerator() { public ArrayList<T> getCommitments() {
return g; return commitments;
} }
@Override /**
public Group<BigInteger> getGroup() { * getter
return group; * @return g
} */
public T getGenerator() {
@Override return g;
public Polynomial.Point getShare() { }
return share;
} /**
* getter
@Override * @return group
public int getID() { */
return id; public Group<T> getGroup() {
} return group;
}
@Override
public int getN() { /**
return n; * getter
} * @return share
*/
@Override public Polynomial.Point getShare() {
public int getT() { return share;
return t; }
}
/**
@Override * getter
public BigInteger getPublicValue() { * @return id
return y; */
} public int getID() {
return id;
@Override }
public Set<Integer> getQUAL() {
return QUAL; /**
} * getter
* @return n
*/
protected class MessageHandler implements Communication.MessageHandler{ public int getN() {
return n;
/** }
* commitment message is valid if:
* 1. it was received in broadcast chanel /**
* 2. the sender didn't sent this commitment before * getter
*/ * @return t
protected boolean isValidCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage){ */
int i = sender - 1; public int getT() {
int k = commitmentMessage.getK(); return t;
return isBroadcast && parties[i].commitments[k] == null; }
}
/**
/** * getter
* saves the commitment * @return y
*/ */
@Override public T getPublicValue() {
public void handleCommitmentMessage(int sender, boolean isBroadcast, Message message) { return y;
DKGMessages.CommitmentMessage commitmentMessage = (DKGMessages.CommitmentMessage) message; }
if(isValidCommitmentMessage(sender,isBroadcast,commitmentMessage)){
int i = sender - 1; /**
int k = commitmentMessage.getK(); * getter
parties[i].commitments[k] = extractCommitment(commitmentMessage); * @return QUAL
} */
} public Set<Integer> getQUAL() {
return QUAL;
/** }
* secret message is valid if:
* 1. it was received in private chanel
* 2. the sender didn't sent secret message before public class MessageHandler implements Communication.MessageHandler{
* 3. secret.i == i
* 4. secret.j == id public MessageHandler(){
*/
protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage){ }
int i = secretMessage.getI(); /**
int j = secretMessage.getJ(); * commitment message is valid if:
if(sender != i || isBroadcast) * 1. it was received in broadcast chanel
return false; * 2. the sender didn't sent this commitment before
else */
return parties[i - 1].share == null && j == id; protected boolean isValidCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage){
int i = sender - 1;
} int k = commitmentMessage.getK();
return isBroadcast && parties[i].commitments.get(k) == null;
/** }
* saves the secret
*/ /**
@Override * saves the commitment
public void handleSecretMessage(int sender, boolean isBroadcast, Message message) { */
DKGMessages.SecretMessage secretMessage = (DKGMessages.SecretMessage) message; @Override
if(isValidSecretMessage(sender,isBroadcast,secretMessage)) { public void handleCommitmentMessage(int sender, boolean isBroadcast, Message message) {
int i = secretMessage.getI(); DKGMessages.CommitmentMessage commitmentMessage = (DKGMessages.CommitmentMessage) message;
Polynomial.Point secret = extractSecret(id,secretMessage.getSecret()); if(isValidCommitmentMessage(sender,isBroadcast,commitmentMessage)){
parties[i - 1].share = secret; int i = sender - 1;
} int k = commitmentMessage.getK();
} synchronized (parties[i]) {
parties[i].commitments.set(k, extractCommitment(commitmentMessage));
/** parties[i].notify();
* done message is valid if: }
* 1. it was received in broadcast chanel }
* 2. the sender didn't sent done message before }
*/
protected boolean isValidDoneMessage(int sender, boolean isBroadcast){ /**
return isBroadcast && !parties[sender - 1].doneFlag; * secret message is valid if:
} * 1. it was received in private chanel
* 2. the sender didn't sent secret message before
/** * 3. secret.i == i
* marks that the sender was finished sending all his complaints * 4. secret.j == id
*/ */
@Override protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKGMessages.ShareMessage secretMessage){
public void handleDoneMessage(int sender, boolean isBroadcast, Message message) { int i = secretMessage.getI();
if(isValidDoneMessage(sender,isBroadcast)) { int j = secretMessage.getJ();
parties[sender - 1].doneFlag = true; if(sender != i || isBroadcast)
} return false;
} else
return parties[i - 1].share == null && j == id;
/**
* complaint message is valid if: }
* 1. it was received in broadcast chanel
* 2. the sender didn't complained against id before /**
*/ * saves the secret
protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, DKGMessages.IDMessage complaintMessage){ */
int i = sender; @Override
int j = complaintMessage.getId(); public void handleSecretMessage(int sender, boolean isBroadcast, Message message) {
return isBroadcast && parties[i - 1].complaints[j - 1].equals( ComplaintState.OK); DKGMessages.ShareMessage secretMessage = (DKGMessages.ShareMessage) message;
} if(isValidSecretMessage(sender,isBroadcast,secretMessage)) {
int i = secretMessage.getI();
/** Polynomial.Point secret = extractShare(id,secretMessage.getSecret());
* marks that the sender was complained against id synchronized (parties[i -1]) {
*/ parties[i - 1].share = secret;
@Override parties[i - 1].notify();
public void handleComplaintMessage(int sender, boolean isBroadcast, Message message) { }
DKGMessages.IDMessage complaintMessage = (DKGMessages.IDMessage)message; }
if(isValidComplaintMessage(sender,isBroadcast,complaintMessage)){ }
int i = sender;
int j = complaintMessage.getId(); /**
parties[j - 1].complaints[i - 1] = ComplaintState.Waiting; * done message is valid if:
} * 1. it was received in broadcast chanel
} * 2. the sender didn't sent done message before
*/
/** protected boolean isValidDoneMessage(int sender, boolean isBroadcast){
* answer message is valid if: return isBroadcast && !parties[sender - 1].doneFlag;
* 1. it was received in broadcast chanel }
* 2. secret.i == i
* 3. 1 <= secret.j <= n /**
* 4. it is marked that j complained against i and i didn't received * marks that the sender was finished sending all his complaints
*/ */
protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage){ @Override
int i = secretMessage.getI(); public void handleDoneMessage(int sender, boolean isBroadcast, Message message) {
int j = secretMessage.getJ(); if(isValidDoneMessage(sender,isBroadcast)) {
if(sender != i || !isBroadcast) synchronized (parties[sender - 1]) {
return false; parties[sender - 1].doneFlag = true;
else parties[sender - 1].notify();
return j >= 1 && j <= n && parties[i - 1].complaints[j - 1].equals(ComplaintState.Waiting); }
} }
}
/**
* if the secret is valid, marks the complaint as NonDisqualified /**
* else marks it as Disqualified * complaint message is valid if:
* in case that the complainer is id ( j == id ), saves the secret * 1. it was received in broadcast chanel
*/ * 2. the sender didn't complained against id before
@Override */
public void handleAnswerMessage(int sender, boolean isBroadcast, Message message) { protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, DKGMessages.IDMessage complaintMessage){
DKGMessages.SecretMessage secretMessage = (DKGMessages.SecretMessage) message; int i = sender;
if(isValidAnswerMessage(sender,isBroadcast,secretMessage)) { int j = complaintMessage.getId();
int i = secretMessage.getI(); return isBroadcast && parties[i - 1].complaints[j - 1].equals( ComplaintState.OK);
int j = secretMessage.getJ(); }
Polynomial.Point secret = extractSecret(j,secretMessage.getSecret());
if (dkg.isValidSecret(secret, parties[i - 1].commitments, j)) { /**
parties[i - 1].complaints[j - 1] = ComplaintState.NonDisqualified; * marks that the sender was complained against id
} else { */
parties[i - 1].complaints[j - 1] = ComplaintState.Disqualified; @Override
} public void handleComplaintMessage(int sender, boolean isBroadcast, Message message) {
if(j == id){ DKGMessages.IDMessage complaintMessage = (DKGMessages.IDMessage)message;
parties[i - 1].share = secret; if(isValidComplaintMessage(sender,isBroadcast,complaintMessage)){
} int i = sender;
} int j = complaintMessage.getId();
} synchronized (parties[j - 1]) {
parties[j - 1].complaints[i - 1] = ComplaintState.Waiting;
/** parties[j - 1].notify();
* marks that the sender was aborted }
*/ }
@Override }
public void handleAbortMessage(int sender, boolean isBroadcast, Message message) {
parties[sender - 1].aborted = true; /**
} * answer message is valid if:
* 1. it was received in broadcast chanel
public Polynomial.Point extractSecret(int i, ByteString secret){ * 2. secret.i == i
BigInteger x = BigInteger.valueOf(i); * 3. 1 <= secret.j <= n
BigInteger y = new BigInteger(secret.toByteArray()); * 4. it is marked that j complained against i and i didn't received
return new Polynomial.Point(x,y); */
} protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKGMessages.ShareMessage secretMessage){
int i = secretMessage.getI();
public BigInteger extractCommitment(DKGMessages.CommitmentMessage commitmentMessage){ int j = secretMessage.getJ();
return new BigInteger(commitmentMessage.getCommitment().toByteArray()); if(sender != i || !isBroadcast)
} return false;
} else
} return j >= 1 && j <= n && parties[i - 1].complaints[j - 1].equals(ComplaintState.Waiting);
}
/**
* if the secret is valid, marks the complaint as NonDisqualified
* else marks it as Disqualified
* in case that the complainer is id ( j == id ), saves the secret
*/
@Override
public void handleAnswerMessage(int sender, boolean isBroadcast, Message message) {
DKGMessages.ShareMessage secretMessage = (DKGMessages.ShareMessage) message;
if(isValidAnswerMessage(sender,isBroadcast,secretMessage)) {
int i = secretMessage.getI();
int j = secretMessage.getJ();
Polynomial.Point secret = extractShare(j,secretMessage.getSecret());
synchronized (parties[i - 1]) {
if (dkg.isValidShare(secret, parties[i - 1].commitments, j)) {
parties[i - 1].complaints[j - 1] = ComplaintState.NonDisqualified;
} else {
parties[i - 1].complaints[j - 1] = ComplaintState.Disqualified;
}
if (j == id) {
parties[i - 1].share = secret;
}
parties[i - 1].notify();
}
}
}
/**
* marks that the sender was aborted
*/
@Override
public void handleAbortMessage(int sender, boolean isBroadcast, Message message) {
synchronized (parties[sender - 1]) {
parties[sender - 1].aborted = true;
parties[sender - 1].notify();
}
}
/**
* extract share value from ByteString
* @param i
* @param share
* @return new Point (i,share)
*/
public Polynomial.Point extractShare(int i, ByteString share){
BigInteger x = BigInteger.valueOf(i);
BigInteger y = new BigInteger(share.toByteArray());
return new Polynomial.Point(x,y);
}
/**
*
* @param commitmentMessage
* @return
*/
public T extractCommitment(DKGMessages.CommitmentMessage commitmentMessage){
return dkg.decodeCommitment(commitmentMessage.getCommitment().toByteArray());
}
}
}

View File

@ -0,0 +1,108 @@
package meerkat.crypto.concrete.secret_shring.feldman_verifiable;
import meerkat.crypto.concrete.secret_shring.ShamirSecretSharing.Polynomial;
import meerkat.crypto.concrete.secret_shring.ShamirSecretSharing.SecretSharing;
import org.factcenter.qilin.primitives.Group;
import java.util.ArrayList;
import java.math.BigInteger;
import java.util.Random;
/**
* Created by Tzlil on 1/27/2016.
*
* an implementation of Feldman's verifiable secret sharing scheme.
*
* allows trusted dealer to share a key x among n parties.
*
*/
public class VerifiableSecretSharing<T> extends SecretSharing {
protected final Group<T> group;
protected final T g; // public generator of group
protected final ArrayList<T> commitmentsArrayList;
/**
* constructor
* @param q a large prime.
* @param t threshold. Any t+1 share holders can recover the secret,
* but any set of at most t share holders cannot
* @param n number of share holders
* @param zi secret, chosen from Zq
* @param random use for generate random polynomial
* @param group
* @param q a large prime dividing group order.
* @param g a generator of cyclic group of order q.
* the generated group is a subgroup of the given group.
* it must be chosen such that computing discrete logarithms is hard in this group.
*/
public VerifiableSecretSharing(int t, int n, BigInteger zi, Random random, BigInteger q, T g
, Group<T> group) {
super(t, n, zi, random,q);
this.g = g;
this.group = group;
assert (this.group.contains(g));
this.commitmentsArrayList = generateCommitments();
}
/**
* commitments[i] = g ^ polynomial.coefficients[i]
* @return commitments
*/
private ArrayList<T> generateCommitments() {
Polynomial polynomial = getPolynomial();
BigInteger[] coefficients = polynomial.getCoefficients();
ArrayList<T> commitments = new ArrayList<T>(t + 1);
for (int i = 0 ; i <= t;i++){
commitments.add(i,group.multiply(g,coefficients[i]));
}
return commitments;
}
/**
* Compute verification value (g^{share value}) using coefficient commitments sent by dealer and my share id.
* @param j my share holder id
* @param commitments commitments to polynomial coefficients of share (received from dealer)
* @param group
*
* @return product of Aik ^ (j ^ k) == g ^ polynomial(i)
*/
public static <T> T computeVerificationValue(int j, ArrayList<T> commitments, Group<T> group) {
T v = group.zero();
BigInteger power = BigInteger.ONE;
BigInteger J = BigInteger.valueOf(j);
for (int k = 0 ; k < commitments.size() ; k ++){
v = group.add(v,group.multiply(commitments.get(k),power));
power = power.multiply(J);
}
return v;
}
/**
* getter
* @return generator of group
*/
public T getGenerator() {
return g;
}
/**
* getter
* @return group
*/
public Group<T> getGroup(){
return group;
}
/**
* getter
* @return commitmentsArrayList
*/
public ArrayList<T> getCommitmentsArrayList() {
return commitmentsArrayList;
}
}

View File

@ -1,66 +1,66 @@
package ShamirSecretSharing; package meerkat.crypto.concrete.secret_shring.shamir;
import Arithmetics.Arithmetic; import meerkat.crypto.utilitis.Arithmetic;
import java.math.BigInteger; import java.math.BigInteger;
/** /**
* Created by Tzlil on 1/28/2016. * Created by Tzlil on 1/28/2016.
* *
* container of lagrange polynomial * container of lagrange polynomial
* *
* Constructor is private (use {@link #lagrangePolynomials(Polynomial.Point[], Arithmetic)} to construct) * Constructor is private (use {@link #lagrangePolynomials(Polynomial.Point[], Arithmetic)} to construct)
* *
* l = (evaluate/divisor)* polynomial * l = (evaluate/divisor)* polynomial
* *
* Note : image and divisor stored separately for avoiding lose of information by division * Note : image and divisor stored separately for avoiding lose of information by division
*/ */
class LagrangePolynomial{ class LagrangePolynomial{
public final Polynomial polynomial; public final Polynomial polynomial;
public final BigInteger image; public final BigInteger image;
public final BigInteger divisor; public final BigInteger divisor;
/** /**
* inner constructor, stores all given parameters * inner constructor, stores all given parameters
* @param polynomial * @param polynomial
* @param image * @param image
* @param divisor * @param divisor
*/ */
private LagrangePolynomial(Polynomial polynomial, BigInteger image, BigInteger divisor) { private LagrangePolynomial(Polynomial polynomial, BigInteger image, BigInteger divisor) {
this.polynomial = polynomial; this.polynomial = polynomial;
this.image = image; this.image = image;
this.divisor = divisor; this.divisor = divisor;
} }
/** /**
* static method * static method
* @param points array points s.t there are no couple of points that shares the same x value * @param points array points s.t there are no couple of points that shares the same x value
* *
* @return the lagrange polynomials that mach to given points. * @return the lagrange polynomials that mach to given points.
* in case there exists i != j s.t points[i].x == points[j].x returns null. * in case there exists i != j s.t points[i].x == points[j].x returns null.
*/ */
public static LagrangePolynomial[] lagrangePolynomials(Polynomial.Point[] points,Arithmetic<BigInteger> arithmetic) { public static LagrangePolynomial[] lagrangePolynomials(Polynomial.Point[] points,Arithmetic<BigInteger> arithmetic) {
Polynomial one = new Polynomial(new BigInteger[]{BigInteger.ONE},arithmetic); Polynomial one = new Polynomial(new BigInteger[]{BigInteger.ONE},arithmetic);
LagrangePolynomial[] lagrangePolynomials = new LagrangePolynomial[points.length]; LagrangePolynomial[] lagrangePolynomials = new LagrangePolynomial[points.length];
Polynomial[] factors = new Polynomial[points.length]; Polynomial[] factors = new Polynomial[points.length];
for (int i = 0 ; i < factors.length ; i++){ for (int i = 0 ; i < factors.length ; i++){
factors[i] = new Polynomial(new BigInteger[]{points[i].x.negate(),BigInteger.ONE},arithmetic); // X - Xi factors[i] = new Polynomial(new BigInteger[]{points[i].x.negate(),BigInteger.ONE},arithmetic); // X - Xi
} }
Polynomial product; Polynomial product;
BigInteger divisor; BigInteger divisor;
for(int i = 0; i < points.length; i ++) { for(int i = 0; i < points.length; i ++) {
product = one; product = one;
divisor = BigInteger.ONE; divisor = BigInteger.ONE;
for (int j = 0; j < points.length; j++) { for (int j = 0; j < points.length; j++) {
if (i != j) { if (i != j) {
divisor = arithmetic.mul(divisor,arithmetic.sub(points[i].x,points[j].x)); divisor = arithmetic.mul(divisor,arithmetic.sub(points[i].x,points[j].x));
product = product.mul(factors[j]); product = product.mul(factors[j]);
} }
} }
if(divisor.equals(BigInteger.ZERO)) if(divisor.equals(BigInteger.ZERO))
return null; return null;
lagrangePolynomials[i] = new LagrangePolynomial(product,points[i].y,divisor); lagrangePolynomials[i] = new LagrangePolynomial(product,points[i].y,divisor);
} }
return lagrangePolynomials; return lagrangePolynomials;
} }
} }

View File

@ -1,208 +1,208 @@
package ShamirSecretSharing; package meerkat.crypto.concrete.secret_shring.shamir;
import Arithmetics.Arithmetic; import meerkat.crypto.utilitis.Arithmetic;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Arrays; import java.util.Arrays;
/** /**
* Created by Tzlil on 1/27/2016. * Created by Tzlil on 1/27/2016.
*/ */
public class Polynomial implements Comparable<Polynomial> { public class Polynomial implements Comparable<Polynomial> {
private final int degree; private final int degree;
private final BigInteger[] coefficients; private final BigInteger[] coefficients;
private final Arithmetic<BigInteger> arithmetic; private final Arithmetic<BigInteger> arithmetic;
/** /**
* constructor * constructor
* @param coefficients * @param coefficients
* @param arithmetic * @param arithmetic
* degree set as max index such that coefficients[degree] not equals zero * degree set as max index such that coefficients[degree] not equals zero
*/ */
public Polynomial(BigInteger[] coefficients,Arithmetic<BigInteger> arithmetic) { public Polynomial(BigInteger[] coefficients,Arithmetic<BigInteger> arithmetic) {
int d = coefficients.length - 1; int d = coefficients.length - 1;
while (d > 0 && coefficients[d].equals(BigInteger.ZERO)){ while (d > 0 && coefficients[d].equals(BigInteger.ZERO)){
d--; d--;
} }
this.degree = d; this.degree = d;
this.coefficients = coefficients; this.coefficients = coefficients;
this.arithmetic = arithmetic; this.arithmetic = arithmetic;
} }
/** /**
* Compare to another polynomial (order by degree, then coefficients). * Compare to another polynomial (order by degree, then coefficients).
*/ */
@Override @Override
public int compareTo(Polynomial other) { public int compareTo(Polynomial other) {
if (this.degree != other.degree) if (this.degree != other.degree)
return this.degree - other.degree; return this.degree - other.degree;
int compare; int compare;
for (int i = degree; i >= degree ; i--){ for (int i = degree; i >= degree ; i--){
compare = this.coefficients[i].compareTo(other.coefficients[i]); compare = this.coefficients[i].compareTo(other.coefficients[i]);
if (compare != 0){ if (compare != 0){
return compare; return compare;
} }
} }
return 0; return 0;
} }
/** /**
* @param x * @param x
* @return sum of coefficients[i] * (x ^ i) * @return sum of coefficients[i] * (x ^ i)
*/ */
public BigInteger evaluate(BigInteger x){ public BigInteger evaluate(BigInteger x){
BigInteger result = BigInteger.ZERO; BigInteger result = BigInteger.ZERO;
BigInteger power = BigInteger.ONE; BigInteger power = BigInteger.ONE;
for(int i = 0 ; i <= degree ; i++){ for(int i = 0 ; i <= degree ; i++){
result = arithmetic.add(result,arithmetic.mul(coefficients[i],power)); result = arithmetic.add(result,arithmetic.mul(coefficients[i],power));
power = power.multiply(x); power = power.multiply(x);
} }
return result; return result;
} }
/** /**
* @param points * @param points
* @return polynomial of minimal degree which goes through all points. * @return polynomial of minimal degree which goes through all points.
* If there exists i != j s.t points[i].x == points[j].x, method returns null. * If there exists i != j s.t points[i].x == points[j].x, method returns null.
*/ */
public static Polynomial interpolation(Point[] points, Arithmetic<BigInteger> arithmetic) { public static Polynomial interpolation(Point[] points, Arithmetic<BigInteger> arithmetic) {
LagrangePolynomial[] l = LagrangePolynomial.lagrangePolynomials(points,arithmetic); LagrangePolynomial[] l = LagrangePolynomial.lagrangePolynomials(points,arithmetic);
if (l == null){ if (l == null){
return null; return null;
} }
// product = product of l[i].divisor // product = product of l[i].divisor
BigInteger product = BigInteger.ONE; BigInteger product = BigInteger.ONE;
for (int i = 0; i < l.length;i++){ for (int i = 0; i < l.length;i++){
product = arithmetic.mul(product,l[i].divisor); product = arithmetic.mul(product,l[i].divisor);
} }
// factor[i] = product divided by l[i].divisor = product of l[j].divisor s.t j!=i // factor[i] = product divided by l[i].divisor = product of l[j].divisor s.t j!=i
BigInteger[] factors = new BigInteger[l.length]; BigInteger[] factors = new BigInteger[l.length];
for (int i = 0; i < l.length;i++){ for (int i = 0; i < l.length;i++){
factors[i] = arithmetic.div(product,l[i].divisor); factors[i] = arithmetic.div(product,l[i].divisor);
} }
int degree = l[0].polynomial.degree; int degree = l[0].polynomial.degree;
// coefficients[j] = (sum of l[i].evaluate * factor[i] * l[i].coefficients[j] s.t i!=j) divide by product = // coefficients[j] = (sum of l[i].evaluate * factor[i] * l[i].coefficients[j] s.t i!=j) divide by product =
// = sum of l[i].evaluate * l[i].coefficients[j] / l[i].divisor s.t i!=j // = sum of l[i].evaluate * l[i].coefficients[j] / l[i].divisor s.t i!=j
BigInteger[] coefficients = new BigInteger[degree + 1]; BigInteger[] coefficients = new BigInteger[degree + 1];
for (int j = 0; j < coefficients.length;j++){ for (int j = 0; j < coefficients.length;j++){
coefficients[j] = BigInteger.ZERO; coefficients[j] = BigInteger.ZERO;
for (int i = 0; i < l.length; i++){ for (int i = 0; i < l.length; i++){
BigInteger current = arithmetic.mul(l[i].image,factors[i]); BigInteger current = arithmetic.mul(l[i].image,factors[i]);
current = arithmetic.mul(current,l[i].polynomial.coefficients[j]); current = arithmetic.mul(current,l[i].polynomial.coefficients[j]);
coefficients[j] = arithmetic.add(coefficients[j],current); coefficients[j] = arithmetic.add(coefficients[j],current);
} }
coefficients[j] = arithmetic.div(coefficients[j],product); coefficients[j] = arithmetic.div(coefficients[j],product);
} }
return new Polynomial(coefficients,arithmetic); return new Polynomial(coefficients,arithmetic);
} }
/** /**
* @param other * @param other
* @return new ShamirSecretSharing.PolynomialTests of degree max(this degree,other degree) s.t for all x in Z * @return new meerkat.crypto.concrete.secret_shring.shamir.Polynomial of degree max(this degree,other degree) s.t for all x
* new.evaluate(x) = this.evaluate(x) + other.evaluate(x) * new.evaluate(x) = this.evaluate(x) + other.evaluate(x)
*/ */
public Polynomial add(Polynomial other){ public Polynomial add(Polynomial other){
Polynomial bigger,smaller; Polynomial bigger,smaller;
if(this.degree < other.degree){ if(this.degree < other.degree){
bigger = other; bigger = other;
smaller = this; smaller = this;
}else{ }else{
bigger = this; bigger = this;
smaller = other; smaller = other;
} }
BigInteger[] coefficients = bigger.getCoefficients(); BigInteger[] coefficients = bigger.getCoefficients();
for (int i = 0; i <= smaller.degree ; i++){ for (int i = 0; i <= smaller.degree ; i++){
coefficients[i] = arithmetic.add(smaller.coefficients[i],bigger.coefficients[i]); coefficients[i] = arithmetic.add(smaller.coefficients[i],bigger.coefficients[i]);
} }
return new Polynomial(coefficients,other.arithmetic); return new Polynomial(coefficients,other.arithmetic);
} }
/** /**
* @param constant * @param constant
* @return new Polynomial of degree this.degree s.t for all x in Z * @return new Polynomial of degree this.degree s.t for all x
* new.evaluate(x) = constant * this.evaluate(x) * new.evaluate(x) = constant * this.evaluate(x)
*/ */
public Polynomial mul(BigInteger constant){ public Polynomial mul(BigInteger constant){
BigInteger[] coefficients = this.getCoefficients(); BigInteger[] coefficients = this.getCoefficients();
for (int i = 0; i <= this.degree ; i++){ for (int i = 0; i <= this.degree ; i++){
coefficients[i] = arithmetic.mul(constant,coefficients[i]); coefficients[i] = arithmetic.mul(constant,coefficients[i]);
} }
return new Polynomial(coefficients,arithmetic); return new Polynomial(coefficients,arithmetic);
} }
/** /**
* @param other * @param other
* @return new Polynomial of degree this degree + other degree + 1 s.t for all x in Z * @return new Polynomial of degree this degree + other degree + 1 s.t for all x
* new.evaluate(x) = this.evaluate(x) * other.evaluate(x) * new.evaluate(x) = this.evaluate(x) * other.evaluate(x)
*/ */
public Polynomial mul(Polynomial other){ public Polynomial mul(Polynomial other){
BigInteger[] coefficients = new BigInteger[this.degree + other.degree + 1]; BigInteger[] coefficients = new BigInteger[this.degree + other.degree + 1];
Arrays.fill(coefficients,BigInteger.ZERO); Arrays.fill(coefficients,BigInteger.ZERO);
for (int i = 0; i <= this.degree ; i++){ for (int i = 0; i <= this.degree ; i++){
for (int j = 0; j <= other.degree; j++){ for (int j = 0; j <= other.degree; j++){
coefficients[i+j] = arithmetic.add(coefficients[i+j],arithmetic.mul(this.coefficients[i],other.coefficients[j])); coefficients[i+j] = arithmetic.add(coefficients[i+j],arithmetic.mul(this.coefficients[i],other.coefficients[j]));
} }
} }
return new Polynomial(coefficients,arithmetic); return new Polynomial(coefficients,arithmetic);
} }
/** getter /** getter
* @return copy of coefficients * @return copy of coefficients
*/ */
public BigInteger[] getCoefficients() { public BigInteger[] getCoefficients() {
return Arrays.copyOf(coefficients,coefficients.length); return Arrays.copyOf(coefficients,coefficients.length);
} }
/** getter /** getter
* @return degree * @return degree
*/ */
public int getDegree() { public int getDegree() {
return degree; return degree;
} }
/** /**
* inner class * inner class
* container for (x,y) x from range and y from evaluate of polynomial * container for (x,y) x from range and y from evaluate of polynomial
*/ */
public static class Point implements java.io.Serializable { public static class Point implements java.io.Serializable {
public final BigInteger x; public final BigInteger x;
public final BigInteger y; public final BigInteger y;
/** /**
* constructor * constructor
* @param x * @param x
* @param polynomial y = polynomial.evaluate(x) * @param polynomial y = polynomial.evaluate(x)
*/ */
public Point(BigInteger x, Polynomial polynomial) { public Point(BigInteger x, Polynomial polynomial) {
this.x = x; this.x = x;
this.y = polynomial.evaluate(x); this.y = polynomial.evaluate(x);
} }
/** /**
* constructor * constructor
* @param x * @param x
* @param y * @param y
*/ */
public Point(BigInteger x,BigInteger y) { public Point(BigInteger x,BigInteger y) {
this.x = x; this.x = x;
this.y = y; this.y = y;
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(!super.equals(obj)) if(!super.equals(obj))
return false; return false;
Point other = (Point)obj; Point other = (Point)obj;
return this.x.equals(other.x) && this.y.equals(other.y); return this.x.equals(other.x) && this.y.equals(other.y);
} }
} }
} }

View File

@ -1,111 +1,111 @@
package ShamirSecretSharing; package meerkat.crypto.concrete.secret_shring.shamir;
import Arithmetics.Arithmetic; import meerkat.crypto.utilitis.Arithmetic;
import Arithmetics.Fp; import meerkat.crypto.utilitis.concrete.Fp;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Random; 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{ 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 Polynomial polynomial;
/** /**
* constructor * constructor
* @param q a large prime. * @param q a large prime.
* @param t threshold. Any t+1 share holders can recover the secret, * @param t threshold. Any t+1 share holders can recover the secret,
* but any set of at most t share holders cannot * but any set of at most t share holders cannot
* @param n number of share holders * @param n number of share holders
* @param x secret, chosen from Zq * @param zi 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) { public SecretSharing(int t, int n, BigInteger zi, Random random, BigInteger q) {
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(zi,random);
} }
/** /**
* @param x * @param x
* @param random * @param random
* @return new Polynomial polynomial of degree t ,such that * @return new Polynomial polynomial of degree t ,such that
* 1. polynomial(0) = x * 1. polynomial(0) = x
* 2. polynomial coefficients randomly chosen from Zq (except of coefficients[0] = x) * 2. polynomial coefficients randomly chosen from Zq (except of coefficients[0] = x)
*/ */
private Polynomial generateRandomPolynomial(BigInteger x, Random random) { private Polynomial generateRandomPolynomial(BigInteger x, Random random) {
BigInteger[] coefficients = new BigInteger[t + 1]; BigInteger[] coefficients = new BigInteger[t + 1];
coefficients[0] = x.mod(q); coefficients[0] = x.mod(q);
int bits = q.bitLength(); int bits = q.bitLength();
for (int i = 1 ; i <= t; i++ ){ for (int i = 1 ; i <= t; i++ ){
coefficients[i] = new BigInteger(bits,random).mod(q); coefficients[i] = new BigInteger(bits,random).mod(q);
} }
return new Polynomial(coefficients,new Fp(q)); return new Polynomial(coefficients,new Fp(q));
} }
/** /**
* @param i in range of [1,...n] * @param i in range of [1,...n]
* *
* @return polynomial.evaluate(i)%q * @return polynomial.evaluate(i)
*/ */
public Polynomial.Point getShare(int i){ public Polynomial.Point getShare(int i){
assert (i > 0 && i <= n); assert (i > 0 && i <= n);
return new Polynomial.Point(BigInteger.valueOf(i), polynomial); return new Polynomial.Point(BigInteger.valueOf(i), polynomial);
} }
/** /**
* @param shares - subset of the original shares * @param shares - subset of the original shares
* *
* @return evaluate of interpolation(shares) at x = 0 * @return evaluate of interpolation(shares) at x = 0
*/ */
public static BigInteger recoverSecret(Polynomial.Point[] shares, Arithmetic<BigInteger> arithmetic) throws Exception { public static BigInteger recoverSecret(Polynomial.Point[] shares, Arithmetic<BigInteger> arithmetic) {
return recoverPolynomial(shares,arithmetic).evaluate(BigInteger.ZERO); return recoverPolynomial(shares,arithmetic).evaluate(BigInteger.ZERO);
} }
/** /**
* @param shares - subset of the original shares * @param shares - subset of the original shares
* *
* @return interpolation(shares) * @return interpolation(shares)
*/ */
public static Polynomial recoverPolynomial(Polynomial.Point[] shares, Arithmetic<BigInteger> arithmetic) { public static Polynomial recoverPolynomial(Polynomial.Point[] shares, Arithmetic<BigInteger> arithmetic) {
return Polynomial.interpolation(shares,arithmetic); return Polynomial.interpolation(shares,arithmetic);
} }
/** /**
* getter * getter
* @return threshold * @return threshold
*/ */
public int getT() { public int getT() {
return t; return t;
} }
/** /**
* getter * getter
* @return number of share holders * @return number of share holders
*/ */
public int getN() { public int getN() {
return n; return n;
} }
/** /**
* getter * getter
* @return the prime was given in the constructor * @return the prime was given in the constructor
*/ */
public BigInteger getQ() { public BigInteger getQ() {
return q; return q;
} }
/** /**
* getter * getter
* @return the polynomial was generated in constructor * @return the polynomial was generated in constructor
*/ */
public Polynomial getPolynomial() { public Polynomial getPolynomial() {
return polynomial; return polynomial;
} }
} }

View File

@ -1,18 +1,18 @@
package Arithmetics; package meerkat.crypto.utilitis;
/** /**
* Created by Tzlil on 3/17/2016. * Created by Tzlil on 3/17/2016.
*/ */
public interface Arithmetic<T> { public interface Arithmetic<T> {
/** /**
* *
* @param a * @param a
* @param b * @param b
* @return * @return
*/ */
T add(T a, T b); T add(T a, T b);
T sub(T a, T b); T sub(T a, T b);
T mul(T a, T b); T mul(T a, T b);
T div(T a, T b); T div(T a, T b);
} }

View File

@ -0,0 +1,26 @@
package meerkat.crypto.utilitis;
import com.google.protobuf.Message;
import meerkat.protobuf.DKGMessages;
/**
* A generic commmunication channel that supports point-to-point and broadcast operation
*/
public interface Channel {
public interface ReceiverCallback {
public void receiveMail(DKGMessages.Mail mail);
}
public void sendMessage(int destUser, DKGMessages.Mail.Type type, Message msg);
public void broadcastMessage(DKGMessages.Mail.Type type, Message msg);
/**
* Register a callback to handle received messages.
* The callback is called in the <b>Channel</b> thread, so no long processing should
* occur in the callback method.
* @param callback
*/
public void registerReceiverCallback(ReceiverCallback callback);
}

View File

@ -1,38 +1,39 @@
package Arithmetics; package meerkat.crypto.utilitis.concrete;
import org.factcenter.qilin.primitives.concrete.Zpstar; import meerkat.crypto.utilitis.Arithmetic;
import org.factcenter.qilin.primitives.concrete.Zpstar;
import java.math.BigInteger;
import java.math.BigInteger;
/**
* Created by Tzlil on 3/17/2016. /**
*/ * Created by Tzlil on 3/17/2016.
public class Fp implements Arithmetic<BigInteger> { */
public final BigInteger p; public class Fp implements Arithmetic<BigInteger> {
private final Zpstar zp; public final BigInteger p;
private final Zpstar zp;
public Fp(BigInteger p) {
this.p = p; public Fp(BigInteger p) {
this.zp = new Zpstar(p); this.p = p;
} this.zp = new Zpstar(p);
}
@Override
public BigInteger add(BigInteger a, BigInteger b){ @Override
return a.add(b).mod(p); public BigInteger add(BigInteger a, BigInteger b){
} return a.add(b).mod(p);
}
@Override
public BigInteger sub(BigInteger a, BigInteger b){ @Override
return a.add(p).subtract(b).mod(p); public BigInteger sub(BigInteger a, BigInteger b){
} return a.add(p).subtract(b).mod(p);
}
@Override
public BigInteger mul(BigInteger a, BigInteger b){ @Override
return zp.add(a,b); public BigInteger mul(BigInteger a, BigInteger b){
} return zp.add(a,b);
}
@Override
public BigInteger div(BigInteger a, BigInteger b){ @Override
return mul(a,zp.negate(b)); public BigInteger div(BigInteger a, BigInteger b){
} return mul(a,zp.negate(b));
} }
}

View File

@ -0,0 +1,108 @@
package Utils;
import com.google.protobuf.Message;
import meerkat.crypto.utilitis.Channel;
import meerkat.protobuf.DKGMessages;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
/**
* Created by Tzlil on 2/14/2016.
*/
// TODO: Change nane to network
public class ChannelImpl implements Channel {
public static int BROADCAST = 0;
private static ChannelImpl[] channels = null;
protected final Queue<DKGMessages.Mail> mailbox;
protected final int id;
protected final int n;
protected Thread receiverThread;
public ChannelImpl(int id, int n) {
if (channels == null){
channels = new ChannelImpl[n];
}
this.mailbox = new ArrayBlockingQueue<DKGMessages.Mail>( n * n * n);
this.id = id;
this.n = n;
channels[id - 1] = this;
}
public int getId() {
return id;
}
@Override
public void sendMessage(int destUser, DKGMessages.Mail.Type type, Message msg) {
if(destUser < 1 || destUser > n)
return;
ChannelImpl channel = channels[destUser - 1];
if (channel == null)
return;
DKGMessages.Mail mail = DKGMessages.Mail.newBuilder()
.setSender(id)
.setDestination(destUser)
.setIsPrivate(true)
.setType(type)
.setMessage(msg.toByteString())
.build();
synchronized (channel.mailbox) {
channel.mailbox.add(mail);
channel.mailbox.notify();
}
}
@Override
public void broadcastMessage(DKGMessages.Mail.Type type,Message msg) {
ChannelImpl channel;
DKGMessages.Mail mail = DKGMessages.Mail.newBuilder()
.setSender(id)
.setDestination(BROADCAST)
.setIsPrivate(false)
.setType(type)
.setMessage(msg.toByteString())
.build();
for (int i = 0 ; i < n ; i++){
channel = channels[i];
synchronized (channel.mailbox) {
channel.mailbox.add(mail);
channel.mailbox.notify();
}
}
}
@Override
public void registerReceiverCallback(final ReceiverCallback callback) {
try{
receiverThread.interrupt();
}catch (Exception e){
//do nothing
}
receiverThread = new Thread(new Runnable() {
@Override
public void run() {
while (true){
try {
synchronized (mailbox) {
while (!mailbox.isEmpty()) {
callback.receiveMail(mailbox.remove());
}
mailbox.wait();
}
} catch (InterruptedException e) {
//do nothing
}
}
}
});
receiverThread.start();
}
}

View File

@ -1,29 +1,30 @@
package Arithmetics; package Utils;
import java.math.BigInteger; import meerkat.crypto.utilitis.Arithmetic;
/** import java.math.BigInteger;
* Created by Tzlil on 3/17/2016.
*/ /**
public class Z implements Arithmetic<BigInteger> { * Created by Tzlil on 4/8/2016.
*/
@Override public class Z implements Arithmetic<BigInteger> {
public BigInteger add(BigInteger a, BigInteger b) { @Override
return a.add(b); public BigInteger add(BigInteger a, BigInteger b) {
} return a.add(b);
}
@Override
public BigInteger sub(BigInteger a, BigInteger b) { @Override
return a.subtract(b); public BigInteger sub(BigInteger a, BigInteger b) {
} return a.subtract(b);
}
@Override
public BigInteger mul(BigInteger a, BigInteger b) { @Override
return a.multiply(b); public BigInteger mul(BigInteger a, BigInteger b) {
} return a.multiply(b);
}
@Override
public BigInteger div(BigInteger a, BigInteger b) { @Override
return a.divide(b); public BigInteger div(BigInteger a, BigInteger b) {
} return a.divide(b);
} }
}

View File

@ -1,61 +1,62 @@
package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol;
import Communication.Network; import meerkat.crypto.utilitis.Channel;
import JointFeldmanProtocol.DistributedKeyGeneration; import meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.DistributedKeyGeneration;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
/** /**
* Created by Tzlil on 3/29/2016. * Created by Tzlil on 3/29/2016.
*/ */
public class SDKGMaliciousUserImpl extends SecureDistributedKeyGenerationUserImpl { public class SDKGMaliciousUserImpl extends SecureDistributedKeyGenerationUser {
private final DistributedKeyGeneration maliciousSDKG; private final DistributedKeyGeneration maliciousSDKG;
private final Set<Integer> falls; private final Set<Integer> falls;
public SDKGMaliciousUserImpl(SecureDistributedKeyGeneration sdkg,SecureDistributedKeyGeneration maliciousSDKG public SDKGMaliciousUserImpl(SecureDistributedKeyGeneration sdkg, SecureDistributedKeyGeneration maliciousSDKG
, Network network,Set<Integer> falls) { , Channel channel, Set<Integer> falls) {
super(sdkg, network); super(sdkg, channel);
this.falls = falls; this.falls = falls;
this.maliciousSDKG = maliciousSDKG; this.maliciousSDKG = maliciousSDKG;
maliciousSDKG.setParties(parties); maliciousSDKG.setParties(parties);
} }
public static SecureDistributedKeyGeneration generateMaliciousSDKG(SecureDistributedKeyGeneration sdkg,Random random){ public static SecureDistributedKeyGeneration generateMaliciousSDKG(SecureDistributedKeyGeneration sdkg,Channel channel,Random random){
BigInteger q = sdkg.getQ(); BigInteger q = sdkg.getQ();
BigInteger zi = new BigInteger(q.bitLength(), random).mod(q); BigInteger zi = new BigInteger(q.bitLength(), random).mod(q);
return new SecureDistributedKeyGeneration(sdkg.getT(),sdkg.getN(),zi,random,sdkg.getQ() SecureDistributedKeyGeneration malicious = new SecureDistributedKeyGeneration(sdkg.getT(),sdkg.getN(),zi,random,sdkg.getQ()
,sdkg.getGenerator(),sdkg.getH(),sdkg.getGroup(),sdkg.getId()); ,sdkg.getGenerator(),sdkg.getH(),sdkg.getGroup(),sdkg.getId(),sdkg.getEncoder());
} malicious.setChannel(channel);
return malicious;
@Override }
public void stage1() {
sdkg.broadcastVerificationValues(user); @Override
sendSecrets(); //insteadof dkg.sendSecrets(user); public void stage1() {
} sdkg.computeAndBroadcastVerificationValues();
sendSecrets(); //insteadof dkg.sendSecrets(channel);
@Override }
public void stage3() {
stopReceiver(); @Override
maliciousSDKG.answerAllComplainingPlayers(user); public void stage3() {
} maliciousSDKG.answerAllComplainingPlayers();
}
@Override
public void stage4(){ @Override
//do nothing public void stage4(){
} //do nothing
}
private void sendSecrets(){
for (int j = 1; j <= n ; j++){ private void sendSecrets(){
if(j != id){ for (int j = 1; j <= n ; j++){
if(falls.contains(j)){ if(j != id){
maliciousSDKG.sendSecret(user,j); if(falls.contains(j)){
}else { maliciousSDKG.sendSecret(j);
sdkg.sendSecret(user, j); }else {
} sdkg.sendSecret(j);
} }
} }
} }
}
}
}

View File

@ -1,177 +1,181 @@
package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol;
import Arithmetics.Arithmetic; import meerkat.crypto.utilitis.Arithmetic;
import Arithmetics.Fp; import meerkat.crypto.utilitis.concrete.Fp;
import Communication.Network; import meerkat.crypto.utilitis.Channel;
import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; import Communication.ChannelImpl;
import JointFeldmanProtocol.DKGMaliciousUserImpl; import meerkat.crypto.concrete.secret_shring.feldman_verifiable.VerifiableSecretSharing;
import ShamirSecretSharing.Polynomial; import meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.DKGMaliciousUser;
import ShamirSecretSharing.SecretSharing; import meerkat.crypto.concrete.secret_shring.shamir.Polynomial;
import UserInterface.DistributedKeyGenerationUser; import meerkat.crypto.concrete.secret_shring.shamir.SecretSharing;
import Utils.GenerateRandomPrime; import Utils.BigIntegerByteEncoder;
import org.factcenter.qilin.primitives.Group; import Utils.GenerateRandomPrime;
import org.factcenter.qilin.primitives.concrete.Zpstar; import org.factcenter.qilin.primitives.Group;
import org.junit.Before; import org.factcenter.qilin.primitives.concrete.Zpstar;
import org.junit.Test; import org.factcenter.qilin.util.ByteEncoder;
import org.junit.Before;
import java.math.BigInteger; import org.junit.Test;
import java.util.ArrayList;
import java.util.HashSet; import java.math.BigInteger;
import java.util.Random; import java.util.ArrayList;
import java.util.Set; import java.util.HashSet;
import java.util.Random;
/** import java.util.Set;
* Created by Tzlil on 3/29/2016.
*/ /**
public class SDKGTest { * Created by Tzlil on 3/29/2016.
*/
int tests = 10; public class SDKGTest {
BigInteger p = GenerateRandomPrime.SafePrime100Bits;
BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); int tests = 1;
Group<BigInteger> group = new Zpstar(p); BigInteger p = GenerateRandomPrime.SafePrime100Bits;
Arithmetic<BigInteger> arithmetic = new Fp(q); BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2));
int t = 9; Group<BigInteger> group = new Zpstar(p);
int n = 20; Arithmetic<BigInteger> arithmetic = new Fp(q);
Testable[] testables; int t = 9;
int n = 20;
@Before Testable[] testables;
public void settings(){
testables = new Testable[tests]; @Before
for (int i = 0; i < tests; i++){ public void settings(){
testables[i] = new Testable(new Random()); testables = new Testable[tests];
} for (int i = 0; i < tests; i++){
} testables[i] = new Testable(new Random());
}
public void oneTest(int test) throws Exception { }
Testable testable = testables[test];
for (int i = 0; i < testable.threads.length ; i++){ public void oneTest(int test) throws Exception {
testable.threads[i].start(); Testable testable = testables[test];
} for (int i = 0; i < testable.threads.length ; i++){
for (int i = 0; i < testable.threads.length ; i++){ testable.threads[i].start();
testable.threads[i].join(); }
} for (int i = 0; i < testable.threads.length ; i++){
testable.threads[i].join();
// got the right public value }
BigInteger publicValue = group.multiply(testable.g,testable.secret);
for (int i: testable.valids){ // got the right public value
assert (testable.sdkgs[i - 1].getPublicValue().equals(publicValue)); BigInteger publicValue = group.multiply(testable.g,testable.secret);
} for (int i: testable.valids){
assert (testable.sdkgs[i - 1].getPublicValue().equals(publicValue));
// assert valid verification values }
BigInteger expected,verification;
for (int i: testable.valids){ // assert valid verification values
expected = group.multiply(testable.g, testable.sdkgs[i - 1].getShare().y); BigInteger expected,verification;
verification = VerifiableSecretSharing.computeVerificationValue(i, testable.sdkgs[i - 1].getCommitments(), group); for (int i: testable.valids){
assert (expected.equals(verification)); expected = group.multiply(testable.g, testable.sdkgs[i - 1].getShare().y);
} verification = VerifiableSecretSharing.computeVerificationValue(i, testable.sdkgs[i - 1].getCommitments(), group);
assert (expected.equals(verification));
}
// restore the secret from shares
ArrayList<Polynomial.Point> sharesList = new ArrayList<Polynomial.Point>();
// restore the secret from shares
for (int i: testable.valids){ ArrayList<Polynomial.Point> sharesList = new ArrayList<Polynomial.Point>();
sharesList.add(testable.sdkgs[i - 1].getShare());
} for (int i: testable.valids){
Polynomial.Point[] shares = new Polynomial.Point[sharesList.size()]; sharesList.add(testable.sdkgs[i - 1].getShare());
for (int i = 0; i < shares.length; i ++){ }
shares[i] = sharesList.get(i); Polynomial.Point[] shares = new Polynomial.Point[sharesList.size()];
} for (int i = 0; i < shares.length; i ++){
shares[i] = sharesList.get(i);
BigInteger calculatedSecret = SecretSharing.recoverSecret(shares,arithmetic); }
assert (calculatedSecret.equals(testable.secret));
} BigInteger calculatedSecret = SecretSharing.recoverSecret(shares,arithmetic);
assert (calculatedSecret.equals(testable.secret));
@Test }
public void test() throws Exception {
for (int i = 0; i < tests; i++){ @Test
oneTest(i); public void test() throws Exception {
} for (int i = 0; i < tests; i++){
} oneTest(i);
}
class Testable{ }
Set<Integer> valids;
Set<Integer> QUAL; class Testable{
Set<Integer> aborted; Set<Integer> valids;
Set<Integer> malicious; Set<Integer> QUAL;
DistributedKeyGenerationUser[] sdkgs; Set<Integer> aborted;
Thread[] threads; Set<Integer> malicious;
BigInteger g; SecureDistributedKeyGenerationUser[] sdkgs;
BigInteger h; Thread[] threads;
BigInteger secret; BigInteger g;
BigInteger h;
public Testable(Random random) { BigInteger secret;
this.sdkgs = new SecureDistributedKeyGenerationUserImpl[n];
this.valids = new HashSet<Integer>(); public Testable(Random random) {
this.QUAL = new HashSet<Integer>(); this.sdkgs = new SecureDistributedKeyGenerationUser[n];
this.aborted = new HashSet<Integer>(); this.valids = new HashSet<Integer>();
this.malicious = new HashSet<Integer>(); this.QUAL = new HashSet<Integer>();
this.threads = new Thread[n]; this.aborted = new HashSet<Integer>();
this.g = sampleGenerator(random); this.malicious = new HashSet<Integer>();
this.h = group.multiply(g,randomIntModQ(random)); this.threads = new Thread[n];
ArrayList<Integer> ids = new ArrayList<Integer>(); this.g = sampleGenerator(random);
for (int id = 1; id<= n ; id++){ this.h = group.multiply(g,randomIntModQ(random));
ids.add(id); ArrayList<Integer> ids = new ArrayList<Integer>();
} for (int id = 1; id<= n ; id++){
Network network = new Network(n); ids.add(id);
int id; }
BigInteger s; int id;
SecureDistributedKeyGeneration sdkg; BigInteger s;
this.secret = BigInteger.ZERO; Channel channel;
while (!ids.isEmpty()) { SecureDistributedKeyGeneration sdkg;
id = ids.remove(random.nextInt(ids.size())); this.secret = BigInteger.ZERO;
s = randomIntModQ(random); ByteEncoder<BigInteger> encoder = new BigIntegerByteEncoder();
sdkg = new SecureDistributedKeyGeneration(t, n, s, random, q, g , h, group, id); while (!ids.isEmpty()) {
sdkgs[id - 1] = randomSDKGUser(id,network,sdkg,random); id = ids.remove(random.nextInt(ids.size()));
threads[id - 1] = new Thread(sdkgs[id - 1]); s = randomIntModQ(random);
if(QUAL.contains(id)){ channel = new ChannelImpl(id,n);
this.secret = this.secret.add(s).mod(q); sdkg = new SecureDistributedKeyGeneration(t, n, s, random, q, g , h, group, id,encoder);
} sdkgs[id - 1] = randomSDKGUser(id,channel,sdkg,random);
} threads[id - 1] = new Thread(sdkgs[id - 1]);
if(QUAL.contains(id)){
} this.secret = this.secret.add(s).mod(q);
}
public SecureDistributedKeyGenerationUserImpl randomSDKGUser(int id,Network network, SecureDistributedKeyGeneration sdkg,Random random){ }
if (QUAL.size() <= t) {
valids.add(id); }
QUAL.add(id);
return new SecureDistributedKeyGenerationUserImpl(sdkg,network); public SecureDistributedKeyGenerationUser randomSDKGUser(int id, Channel channel, SecureDistributedKeyGeneration sdkg, Random random){
}else{ if (QUAL.size() <= t) {
int type = random.nextInt(3); valids.add(id);
switch (type){ QUAL.add(id);
case 0:// regular return new SecureDistributedKeyGenerationUser(sdkg,channel);
valids.add(id); }else{
QUAL.add(id); int type = random.nextInt(3);
return new SecureDistributedKeyGenerationUserImpl(sdkg,network); switch (type){
case 1:// abort case 0:// regular
int abortStage = random.nextInt(3) + 1; // 1 or 2 or 3 valids.add(id);
aborted.add(id); QUAL.add(id);
if (abortStage > 1){ return new SecureDistributedKeyGenerationUser(sdkg,channel);
QUAL.add(id); case 1:// abort
} int abortStage = random.nextInt(3) + 1; // 1 or 2 or 3
return new SDKGUserImplAbort(sdkg,network,abortStage); aborted.add(id);
case 2:// malicious if (abortStage > 1){
malicious.add(id); QUAL.add(id);
Set<Integer> falls = DKGMaliciousUserImpl.selectFallsRandomly(valids,random); }
SecureDistributedKeyGeneration maliciousSDKG = SDKGMaliciousUserImpl.generateMaliciousSDKG(sdkg,random); return new SDKGUserImplAbort(sdkg,channel,abortStage);
return new SDKGMaliciousUserImpl(sdkg,maliciousSDKG,network,falls); case 2:// malicious
default: malicious.add(id);
return null; Set<Integer> falls = DKGMaliciousUser.selectFallsRandomly(valids,random);
} SecureDistributedKeyGeneration maliciousSDKG = SDKGMaliciousUserImpl.generateMaliciousSDKG(sdkg,channel,random);
} return new SDKGMaliciousUserImpl(sdkg,maliciousSDKG,channel,falls);
} default:
return null;
public BigInteger sampleGenerator(Random random){ }
BigInteger ZERO = group.zero(); }
BigInteger g; }
do {
g = group.sample(random); public BigInteger sampleGenerator(Random random){
} while (!g.equals(ZERO) && !group.multiply(g, q).equals(ZERO)); BigInteger ZERO = group.zero();
return g; BigInteger g;
} do {
g = group.sample(random);
public BigInteger randomIntModQ(Random random){ } while (!g.equals(ZERO) && !group.multiply(g, q).equals(ZERO));
return new BigInteger(q.bitLength(), random).mod(q); return g;
} }
} public BigInteger randomIntModQ(Random random){
} return new BigInteger(q.bitLength(), random).mod(q);
}
}
}

View File

@ -1,65 +1,63 @@
package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol;
import Communication.Network; import meerkat.crypto.utilitis.Channel;
import SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem.SecureDistributedKeyGeneration; import meerkat.protobuf.DKGMessages;
import SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem.SecureDistributedKeyGenerationUserImpl;
import meerkat.protobuf.DKGMessages; /**
* Created by Tzlil on 3/14/2016.
/** */
* Created by Tzlil on 3/14/2016. public class SDKGUserImplAbort extends SecureDistributedKeyGenerationUser {
*/
public class SDKGUserImplAbort extends SecureDistributedKeyGenerationUserImpl { final int abortStage;
int stage;
final int abortStage; public SDKGUserImplAbort(SecureDistributedKeyGeneration sdkg, Channel channel, int abortStage) {
int stage; super(sdkg, channel);
public SDKGUserImplAbort(SecureDistributedKeyGeneration sdkg, Network network, int abortStage) { this.abortStage = abortStage;// 1 - 4
super(sdkg, network); this.stage = 1;
this.abortStage = abortStage;// 1 - 4 }
this.stage = 1;
} private void abort(){
//stopReceiver();
private void abort(){ channel.broadcastMessage(DKGMessages.Mail.Type.ABORT,DKGMessages.EmptyMessage.getDefaultInstance());
stopReceiver(); }
user.broadcast(DKGMessages.Mail.Type.ABORT,DKGMessages.EmptyMessage.getDefaultInstance());
} @Override
protected void stage1() {
@Override if(stage < abortStage)
protected void stage1() { super.stage1();
if(stage < abortStage) else if(stage == abortStage){
super.stage1(); abort();
else if(stage == abortStage){ }
abort(); stage++;
} }
stage++;
} @Override
protected void stage2() {
@Override if(stage < abortStage)
protected void stage2() { super.stage2();
if(stage < abortStage) else if(stage == abortStage){
super.stage2(); abort();
else if(stage == abortStage){ }
abort(); stage++;
} }
stage++;
} @Override
protected void stage3() {
@Override if(stage < abortStage)
protected void stage3() { super.stage3();
if(stage < abortStage) else if(stage == abortStage){
super.stage3(); abort();
else if(stage == abortStage){ }
abort(); stage++;
} }
stage++;
} @Override
protected void stage4() {
@Override if(stage < abortStage)
protected void stage4() { super.stage4();
if(stage < abortStage) else if(stage == abortStage){
super.stage4(); abort();
else if(stage == abortStage){ }
abort(); stage++;
} }
stage++; }
}
}

View File

@ -1,72 +1,73 @@
package JointFeldmanProtocol; package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol;
import Communication.MailHandler; import meerkat.crypto.utilitis.Channel;
import Communication.Network;
import java.math.BigInteger;
import java.math.BigInteger; import java.util.*;
import java.util.*;
/**
/** * Created by Tzlil on 3/21/2016.
* Created by Tzlil on 3/21/2016. */
*/ public class DKGMaliciousUser extends DistributedKeyGenerationUser {
public class DKGMaliciousUserImpl extends DistributedKeyGenerationUserImpl {
private final DistributedKeyGeneration maliciousDkg;
private final DistributedKeyGeneration maliciousDkg; private final Set<Integer> falls;
private final Set<Integer> falls; public DKGMaliciousUser(DistributedKeyGeneration dkg, DistributedKeyGeneration maliciousDKG, Channel channel, Set<Integer> falls) {
public DKGMaliciousUserImpl(DistributedKeyGeneration dkg,DistributedKeyGeneration maliciousDKG, Network network,Set<Integer> falls) { super(dkg, channel);
super(dkg, network); this.falls = falls;
this.falls = falls; this.maliciousDkg = maliciousDKG;
this.maliciousDkg = maliciousDKG; maliciousDKG.setParties(parties);
maliciousDKG.setParties(parties); }
}
public static Set<Integer> selectFallsRandomly(Set<Integer> ids, Random random){
public static Set<Integer> selectFallsRandomly(Set<Integer> ids, Random random){ Set<Integer> falls = new HashSet<Integer>();
Set<Integer> falls = new HashSet<Integer>(); ArrayList<Integer> idsList = new ArrayList<Integer>();
ArrayList<Integer> idsList = new ArrayList<Integer>(); for (int id : ids){
for (int id : ids){ idsList.add(id);
idsList.add(id); }
} int fallsSize = random.nextInt(idsList.size()) + 1;// 1 - (n-1)
int fallsSize = random.nextInt(idsList.size()) + 1;// 1 - (n-1) while (falls.size() < fallsSize){
while (falls.size() < fallsSize){ falls.add(idsList.remove(random.nextInt(idsList.size())));
falls.add(idsList.remove(random.nextInt(idsList.size()))); }
} return falls;
return falls; }
}
public static DistributedKeyGeneration generateMaliciousDKG(DistributedKeyGeneration dkg,Channel channel,Random random){
public static DistributedKeyGeneration generateMaliciousDKG(DistributedKeyGeneration dkg,Random random){ BigInteger q = dkg.getQ();
BigInteger q = dkg.getQ(); BigInteger zi = new BigInteger(q.bitLength(), random).mod(q);
BigInteger zi = new BigInteger(q.bitLength(), random).mod(q); DistributedKeyGeneration malicious = new DistributedKeyGeneration(dkg.getT(),dkg.getN(),zi,random,dkg.getQ()
return new DistributedKeyGeneration(dkg.getT(),dkg.getN(),zi,random,dkg.getQ() ,dkg.getGenerator(),dkg.getGroup(),dkg.getId(),dkg.getEncoder());
,dkg.getGenerator(),dkg.getGroup(),dkg.getId()); malicious.setChannel(channel);
} return malicious;
}
@Override
public void stage1() { @Override
dkg.broadcastCommitments(user); public void stage1() {
sendSecrets(); //insteadof dkg.sendSecrets(user); dkg.broadcastCommitments();
} sendSecrets(); //insteadof dkg.sendSecrets(channel);
}
@Override
public void stage3() { @Override
maliciousDkg.answerAllComplainingPlayers(user); public void stage3() {
} maliciousDkg.answerAllComplainingPlayers();
}
@Override
public void stage4(){ @Override
// do nothing public void stage4(){
} // do nothing
}
private void sendSecrets(){
for (int j = 1; j <= n ; j++){ private void sendSecrets(){
if(j != id){ for (int j = 1; j <= n ; j++){
if(falls.contains(j)){ if(j != id){
maliciousDkg.sendSecret(user,j); if(falls.contains(j)){
}else { maliciousDkg.sendSecret(j);
dkg.sendSecret(user, j); }else {
} dkg.sendSecret(j);
} }
} }
} }
}
}
}

View File

@ -1,175 +1,179 @@
package JointFeldmanProtocol; package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol;
import Arithmetics.Arithmetic; import meerkat.crypto.utilitis.Arithmetic;
import Arithmetics.Fp; import meerkat.crypto.utilitis.concrete.Fp;
import Communication.Network; import meerkat.crypto.utilitis.Channel;
import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; import Communication.ChannelImpl;
import ShamirSecretSharing.Polynomial; import meerkat.crypto.concrete.secret_shring.feldman_verifiable.VerifiableSecretSharing;
import ShamirSecretSharing.SecretSharing; import meerkat.crypto.concrete.secret_shring.shamir.Polynomial;
import UserInterface.DistributedKeyGenerationUser; import meerkat.crypto.concrete.secret_shring.shamir.SecretSharing;
import Utils.GenerateRandomPrime; import Utils.BigIntegerByteEncoder;
import org.factcenter.qilin.primitives.Group; import Utils.GenerateRandomPrime;
import org.factcenter.qilin.primitives.concrete.Zpstar; import org.factcenter.qilin.primitives.Group;
import org.junit.Before; import org.factcenter.qilin.primitives.concrete.Zpstar;
import org.junit.Test; import org.factcenter.qilin.util.ByteEncoder;
import org.junit.Before;
import java.math.BigInteger; import org.junit.Test;
import java.util.ArrayList;
import java.util.HashSet; import java.math.BigInteger;
import java.util.Random; import java.util.ArrayList;
import java.util.Set; import java.util.HashSet;
import java.util.Random;
/** import java.util.Set;
* Created by Tzlil on 3/21/2016.
*/ /**
public class DKGTest { * Created by Tzlil on 3/21/2016.
*/
int tests = 10; public class DKGTest {
BigInteger p = GenerateRandomPrime.SafePrime100Bits;
BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); int tests = 1;
Group<BigInteger> group = new Zpstar(p); BigInteger p = GenerateRandomPrime.SafePrime100Bits;
Arithmetic<BigInteger> arithmetic = new Fp(q); BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2));
int t = 9; Group<BigInteger> group = new Zpstar(p);
int n = 20; Arithmetic<BigInteger> arithmetic = new Fp(q);
int t = 9;
Testable[] testables; int n = 20;
@Before Testable[] testables;
public void settings(){
testables = new Testable[tests]; @Before
for (int i = 0; i < tests; i++){ public void settings(){
testables[i] = new Testable(new Random()); testables = new Testable[tests];
} for (int i = 0; i < tests; i++){
} testables[i] = new Testable(new Random());
}
public void oneTest(int test) throws Exception { }
Testable testable = testables[test];
for (int i = 0; i < testable.threads.length ; i++){ public void oneTest(int test) throws Exception {
testable.threads[i].start(); Testable testable = testables[test];
} for (int i = 0; i < testable.threads.length ; i++){
for (int i = 0; i < testable.threads.length ; i++){ testable.threads[i].start();
testable.threads[i].join(); }
} for (int i = 0; i < testable.threads.length ; i++){
testable.threads[i].join();
// got the right public value }
BigInteger publicValue = group.multiply(testable.g,testable.secret);
for (int i: testable.valids){ // got the right public value
assert (testable.dkgs[i - 1].getPublicValue().equals(publicValue)); BigInteger publicValue = group.multiply(testable.g,testable.secret);
} for (int i: testable.valids){
assert (testable.dkgs[i - 1].getPublicValue().equals(publicValue));
// assert valid verification values }
BigInteger expected,verification;
for (int i: testable.valids){ // assert valid verification values
expected = group.multiply(testable.g, testable.dkgs[i - 1].getShare().y); BigInteger expected,verification;
verification = VerifiableSecretSharing.computeVerificationValue(i, testable.dkgs[i - 1].getCommitments(), group); for (int i: testable.valids){
assert (expected.equals(verification)); expected = group.multiply(testable.g, testable.dkgs[i - 1].getShare().y);
} verification = VerifiableSecretSharing.computeVerificationValue(i, testable.dkgs[i - 1].getCommitments(), group);
assert (expected.equals(verification));
}
// restore the secret from shares
ArrayList<Polynomial.Point> sharesList = new ArrayList<Polynomial.Point>();
// restore the secret from shares
for (int i: testable.valids){ ArrayList<Polynomial.Point> sharesList = new ArrayList<Polynomial.Point>();
sharesList.add(testable.dkgs[i - 1].getShare());
} for (int i: testable.valids){
Polynomial.Point[] shares = new Polynomial.Point[sharesList.size()]; sharesList.add(testable.dkgs[i - 1].getShare());
for (int i = 0; i < shares.length; i ++){ }
shares[i] = sharesList.get(i); Polynomial.Point[] shares = new Polynomial.Point[sharesList.size()];
} for (int i = 0; i < shares.length; i ++){
shares[i] = sharesList.get(i);
BigInteger calculatedSecret = SecretSharing.recoverSecret(shares,arithmetic); }
assert (calculatedSecret.equals(testable.secret));
} BigInteger calculatedSecret = SecretSharing.recoverSecret(shares,arithmetic);
assert (calculatedSecret.equals(testable.secret));
@Test }
public void test() throws Exception {
for (int i = 0; i < tests; i++){ @Test
oneTest(i); public void test() throws Exception {
} for (int i = 0; i < tests; i++){
} oneTest(i);
}
class Testable{ }
Set<Integer> valids;
Set<Integer> QUAL; class Testable{
Set<Integer> aborted; Set<Integer> valids;
Set<Integer> malicious; Set<Integer> QUAL;
DistributedKeyGenerationUser[] dkgs; Set<Integer> aborted;
Thread[] threads; Set<Integer> malicious;
BigInteger g; DistributedKeyGenerationUser[] dkgs;
BigInteger secret; Thread[] threads;
BigInteger g;
public Testable(Random random) { BigInteger secret;
this.dkgs = new DistributedKeyGenerationUserImpl[n];
this.valids = new HashSet<Integer>(); public Testable(Random random) {
this.QUAL = new HashSet<Integer>(); this.dkgs = new DistributedKeyGenerationUser[n];
this.aborted = new HashSet<Integer>(); this.valids = new HashSet<Integer>();
this.malicious = new HashSet<Integer>(); this.QUAL = new HashSet<Integer>();
this.threads = new Thread[n]; this.aborted = new HashSet<Integer>();
this.g = sampleGenerator(random); this.malicious = new HashSet<Integer>();
ArrayList<Integer> ids = new ArrayList<Integer>(); this.threads = new Thread[n];
for (int id = 1; id<= n ; id++){ this.g = sampleGenerator(random);
ids.add(id); ArrayList<Integer> ids = new ArrayList<Integer>();
} for (int id = 1; id<= n ; id++){
Network network = new Network(n); ids.add(id);
int id; }
BigInteger s; int id;
DistributedKeyGeneration dkg; BigInteger s;
this.secret = BigInteger.ZERO; DistributedKeyGeneration dkg;
while (!ids.isEmpty()) { this.secret = BigInteger.ZERO;
id = ids.remove(random.nextInt(ids.size())); Channel channel;
s = randomIntModQ(random); ByteEncoder<BigInteger> byteEncoder = new BigIntegerByteEncoder();
dkg = new DistributedKeyGeneration(t, n, s, random, q, g, group, id); while (!ids.isEmpty()) {
dkgs[id - 1] = randomDKGUser(id,network,dkg,random); id = ids.remove(random.nextInt(ids.size()));
threads[id - 1] = new Thread(dkgs[id - 1]); channel = new ChannelImpl(id,n);
if(QUAL.contains(id)){ s = randomIntModQ(random);
this.secret = this.secret.add(s).mod(q); dkg = new DistributedKeyGeneration(t, n, s, random, q, g, group, id,byteEncoder);
} dkgs[id - 1] = randomDKGUser(id,channel,dkg,random);
} threads[id - 1] = new Thread(dkgs[id - 1]);
if(QUAL.contains(id)){
} this.secret = this.secret.add(s).mod(q);
}
public DistributedKeyGenerationUser randomDKGUser(int id,Network network, DistributedKeyGeneration dkg,Random random){ }
if (QUAL.size() <= t) {
valids.add(id); }
QUAL.add(id);
return new DistributedKeyGenerationUserImpl(dkg,network); public DistributedKeyGenerationUser randomDKGUser(int id, Channel channel, DistributedKeyGeneration dkg, Random random){
}else{ if (QUAL.size() <= t) {
int type = random.nextInt(3); valids.add(id);
switch (type){ QUAL.add(id);
case 0:// regular return new DistributedKeyGenerationUser(dkg,channel);
valids.add(id); }else{
QUAL.add(id); int type = random.nextInt(3);
return new DistributedKeyGenerationUserImpl(dkg,network); switch (type){
case 1:// abort case 0:// regular
int abortStage = random.nextInt(2) + 1; // 1 or 2 valids.add(id);
aborted.add(id); QUAL.add(id);
if (abortStage == 2){ return new DistributedKeyGenerationUser(dkg,channel);
QUAL.add(id); case 1:// abort
} int abortStage = random.nextInt(2) + 1; // 1 or 2
return new DKGUserImplAbort(dkg,network,abortStage); aborted.add(id);
case 2:// malicious if (abortStage == 2){
malicious.add(id); QUAL.add(id);
Set<Integer> falls = DKGMaliciousUserImpl.selectFallsRandomly(valids,random); }
DistributedKeyGeneration maliciousDKG = DKGMaliciousUserImpl.generateMaliciousDKG(dkg,random); return new DKGUserImplAbort(dkg,channel,abortStage);
return new DKGMaliciousUserImpl(dkg,maliciousDKG,network,falls); case 2:// malicious
default: malicious.add(id);
return null; Set<Integer> falls = DKGMaliciousUser.selectFallsRandomly(valids,random);
} DistributedKeyGeneration maliciousDKG = DKGMaliciousUser.generateMaliciousDKG(dkg,channel,random);
} return new DKGMaliciousUser(dkg,maliciousDKG,channel,falls);
} default:
return null;
public BigInteger sampleGenerator(Random random){ }
BigInteger ZERO = group.zero(); }
BigInteger g; }
do {
g = group.sample(random); public BigInteger sampleGenerator(Random random){
} while (!g.equals(ZERO) && !group.multiply(g, q).equals(ZERO)); BigInteger ZERO = group.zero();
return g; BigInteger g;
} do {
g = group.sample(random);
public BigInteger randomIntModQ(Random random){ } while (!g.equals(ZERO) && !group.multiply(g, q).equals(ZERO));
return new BigInteger(q.bitLength(), random).mod(q); return g;
} }
} public BigInteger randomIntModQ(Random random){
} return new BigInteger(q.bitLength(), random).mod(q);
}
}
}

View File

@ -1,63 +1,63 @@
package JointFeldmanProtocol; package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol;
import Communication.Network; import meerkat.crypto.utilitis.Channel;
import meerkat.protobuf.DKGMessages; import meerkat.protobuf.DKGMessages;
/** /**
* Created by Tzlil on 3/14/2016. * Created by Tzlil on 3/14/2016.
*/ */
public class DKGUserImplAbort extends DistributedKeyGenerationUserImpl { public class DKGUserImplAbort extends DistributedKeyGenerationUser {
final int abortStage; final int abortStage;
int stage; int stage;
public DKGUserImplAbort(DistributedKeyGeneration dkg, Network network, int abortStage) { public DKGUserImplAbort(DistributedKeyGeneration dkg, Channel channel, int abortStage) {
super(dkg, network); super(dkg, channel);
this.abortStage = abortStage;// 1 - 2 this.abortStage = abortStage;// 1 - 2
this.stage = 1; this.stage = 1;
} }
private void sendAbort(){ private void sendAbort(){
user.broadcast(DKGMessages.Mail.Type.ABORT,DKGMessages.EmptyMessage.getDefaultInstance()); channel.broadcastMessage(DKGMessages.Mail.Type.ABORT,DKGMessages.EmptyMessage.getDefaultInstance());
} }
@Override @Override
protected void stage1() { protected void stage1() {
if(stage < abortStage) if(stage < abortStage)
super.stage1(); super.stage1();
else if(stage == abortStage){ else if(stage == abortStage){
sendAbort(); sendAbort();
} }
stage++; stage++;
} }
@Override @Override
protected void stage2() { protected void stage2() {
if(stage < abortStage) if(stage < abortStage)
super.stage2(); super.stage2();
else if(stage == abortStage){ else if(stage == abortStage){
sendAbort(); sendAbort();
} }
stage++; stage++;
} }
@Override @Override
protected void stage3() { protected void stage3() {
if(stage < abortStage) if(stage < abortStage)
super.stage3(); super.stage3();
else if(stage == abortStage){ else if(stage == abortStage){
sendAbort(); sendAbort();
} }
stage++; stage++;
} }
@Override @Override
protected void stage4() { protected void stage4() {
if(stage < abortStage) if(stage < abortStage)
super.stage4(); super.stage4();
else if(stage == abortStage){ else if(stage == abortStage){
sendAbort(); sendAbort();
} }
stage++; stage++;
} }
} }

View File

@ -1,67 +1,68 @@
package FeldmanVerifiableSecretSharing; package meerkat.crypto.concrete.secret_shring.feldman_verifiable;
import ShamirSecretSharing.Polynomial; import meerkat.crypto.concrete.secret_shring.ShamirSecretSharing.Polynomial;
import org.factcenter.qilin.primitives.Group; 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.Random; import java.util.ArrayList;
import java.util.Random;
/**
* Created by Tzlil on 1/29/2016. /**
*/ * Created by Tzlil on 1/29/2016.
public class VerifiableSecretSharingTest { */
public class VerifiableSecretSharingTest {
VerifiableSecretSharing[] verifiableSecretSharingArray;
int tests = 1 << 10; VerifiableSecretSharing[] verifiableSecretSharingArray;
Random random; int tests = 1 << 10;
Random random;
@Before
public void settings(){ @Before
BigInteger p = BigInteger.valueOf(2903); public void settings(){
BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); BigInteger p = BigInteger.valueOf(2903);
Zpstar zpstar = new Zpstar(p); BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2));
random = new Random(); Zpstar zpstar = new Zpstar(p);
BigInteger g; random = new Random();
BigInteger ZERO = zpstar.zero(); BigInteger g;
do{ BigInteger ZERO = zpstar.zero();
g = zpstar.sample(random); do{
}while (!g.equals(ZERO) && !zpstar.multiply(g,q).equals(ZERO));// sample from QRZp* g = zpstar.sample(random);
int t = 8; }while (!g.equals(ZERO) && !zpstar.multiply(g,q).equals(ZERO));// sample from QRZp*
int n = 20; int t = 8;
verifiableSecretSharingArray = new VerifiableSecretSharing[tests]; int n = 20;
for (int i = 0; i < verifiableSecretSharingArray.length; i++){ verifiableSecretSharingArray = new VerifiableSecretSharing[tests];
verifiableSecretSharingArray[i] = new VerifiableSecretSharing(t,n for (int i = 0; i < verifiableSecretSharingArray.length; i++){
,new BigInteger(q.bitLength(),random).mod(q),random,q,g,zpstar); verifiableSecretSharingArray[i] = new VerifiableSecretSharing(t,n
} ,new BigInteger(q.bitLength(),random).mod(q),random,q,g,zpstar);
} }
}
public void oneTest(VerifiableSecretSharing verifiableSecretSharing) throws Exception {
int n = verifiableSecretSharing.getN(); public void oneTest(VerifiableSecretSharing<BigInteger> verifiableSecretSharing) throws Exception {
Group<BigInteger> zpstar = verifiableSecretSharing.getGroup(); int n = verifiableSecretSharing.getN();
BigInteger g = verifiableSecretSharing.getGenerator(); Group<BigInteger> zpstar = verifiableSecretSharing.getGroup();
Polynomial.Point[] shares = new Polynomial.Point[n]; BigInteger g = verifiableSecretSharing.getGenerator();
BigInteger[] commitments = verifiableSecretSharing.getCommitmentsArray(); Polynomial.Point[] shares = new Polynomial.Point[n];
BigInteger[] verifications = new BigInteger[n]; ArrayList<BigInteger> commitments = verifiableSecretSharing.getCommitmentsArrayList();
for (int i = 1 ; i <= shares.length; i ++){ BigInteger[] verifications = new BigInteger[n];
shares[i - 1] = verifiableSecretSharing.getShare(i); for (int i = 1 ; i <= shares.length; i ++){
verifications[i - 1] = VerifiableSecretSharing.computeVerificationValue(i,commitments,zpstar); shares[i - 1] = verifiableSecretSharing.getShare(i);
} verifications[i - 1] = VerifiableSecretSharing.computeVerificationValue(i,commitments,zpstar);
BigInteger expected; }
for (int i = 0 ; i < shares.length ; i++){ BigInteger expected;
expected = zpstar.multiply(g,shares[i].y); for (int i = 0 ; i < shares.length ; i++){
assert (expected.equals(verifications[i])); expected = zpstar.multiply(g,shares[i].y);
} assert (expected.equals(verifications[i]));
}
}
}
@Test
public void secretSharingTest() throws Exception { @Test
for (int i = 0 ; i < verifiableSecretSharingArray.length; i ++){ public void secretSharingTest() throws Exception {
oneTest(verifiableSecretSharingArray[i]); for (int i = 0 ; i < verifiableSecretSharingArray.length; i ++){
} oneTest(verifiableSecretSharingArray[i]);
} }
} }
}

View File

@ -1,46 +1,46 @@
package ShamirSecretSharing.PolynomialTests; package meerkat.crypto.concrete.secret_shring.shamir.PolynomialTests;
import Arithmetics.Z; import Arithmetics.Z;
import Utils.GenerateRandomPolynomial; import Utils.GenerateRandomPolynomial;
import ShamirSecretSharing.Polynomial; import meerkat.crypto.concrete.secret_shring.shamir.Polynomial;
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.Random; import java.util.Random;
/** /**
* Created by Tzlil on 1/27/2016. * Created by Tzlil on 1/27/2016.
*/ */
public class AddTest { public class AddTest {
Polynomial[] arr1; Polynomial[] arr1;
Polynomial[] arr2; Polynomial[] arr2;
int tests = 1 << 12; int tests = 1 << 12;
int maxDegree = 15; int maxDegree = 15;
int bits = 128; int bits = 128;
Random random; Random random;
@Before @Before
public void settings(){ public void settings(){
random = new Random(); random = new Random();
arr1 = new Polynomial[tests]; arr1 = new Polynomial[tests];
arr2 = new Polynomial[tests]; arr2 = new Polynomial[tests];
for (int i = 0; i < arr1.length; i++){ for (int i = 0; i < arr1.length; i++){
arr1[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,new Z()); arr1[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,new Z());
arr2[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,new Z()); arr2[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,new Z());
} }
} }
public void oneTest(Polynomial p1, Polynomial p2){ public void oneTest(Polynomial p1, Polynomial p2){
Polynomial sum = p1.add(p2); Polynomial sum = p1.add(p2);
BigInteger x = new BigInteger(bits,random); BigInteger x = new BigInteger(bits,random);
assert(sum.evaluate(x).equals(p1.evaluate(x).add(p2.evaluate(x)))); assert(sum.evaluate(x).equals(p1.evaluate(x).add(p2.evaluate(x))));
} }
@Test @Test
public void addTest(){ public void addTest(){
for (int i = 0 ; i < arr1.length; i ++){ for (int i = 0 ; i < arr1.length; i ++){
oneTest(arr1[i],arr2[i]); oneTest(arr1[i],arr2[i]);
} }
} }
} }

View File

@ -1,68 +1,68 @@
package ShamirSecretSharing.PolynomialTests; package meerkat.crypto.concrete.secret_shring.shamir.PolynomialTests;
import Arithmetics.Arithmetic; import meerkat.crypto.utilitis.Arithmetic;
import Arithmetics.Fp; import meerkat.crypto.utilitis.concrete.Fp;
import Utils.GenerateRandomPolynomial; import Utils.GenerateRandomPolynomial;
import ShamirSecretSharing.Polynomial; import meerkat.crypto.concrete.secret_shring.shamir.Polynomial;
import Utils.GenerateRandomPrime; import Utils.GenerateRandomPrime;
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.HashSet; import java.util.HashSet;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
/** /**
* Created by Tzlil on 1/27/2016. * Created by Tzlil on 1/27/2016.
*/ */
public class InterpolationTest { public class InterpolationTest {
Polynomial[] polynomials; Polynomial[] polynomials;
int tests = 1 << 10; int tests = 1 << 10;
int maxDegree = 15; int maxDegree = 15;
int bits = 128; int bits = 128;
Random random; Random random;
Polynomial.Point[][] pointsArrays; Polynomial.Point[][] pointsArrays;
Arithmetic<BigInteger> arithmetic; Arithmetic<BigInteger> arithmetic;
BigInteger p = GenerateRandomPrime.SafePrime100Bits; BigInteger p = GenerateRandomPrime.SafePrime100Bits;
@Before @Before
public void settings(){ public void settings(){
random = new Random(); random = new Random();
polynomials = new Polynomial[tests]; polynomials = new Polynomial[tests];
pointsArrays = new Polynomial.Point[tests][]; pointsArrays = new Polynomial.Point[tests][];
for (int i = 0; i < polynomials.length; i++){ arithmetic = new Fp(p);
polynomials[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,p); for (int i = 0; i < polynomials.length; i++){
pointsArrays[i] = randomPoints(polynomials[i]); polynomials[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,p);
} pointsArrays[i] = randomPoints(polynomials[i]);
arithmetic = new Fp(p); }
} }
public Polynomial.Point[] randomPoints(Polynomial polynomial){ public Polynomial.Point[] randomPoints(Polynomial polynomial){
Polynomial.Point[] points = new Polynomial.Point[polynomial.getDegree() + 1]; Polynomial.Point[] points = new Polynomial.Point[polynomial.getDegree() + 1];
BigInteger x; BigInteger x;
Set<BigInteger> set = new HashSet(); Set<BigInteger> set = new HashSet();
for (int i = 0; i < points.length; i++){ for (int i = 0; i < points.length; i++){
x = new BigInteger(bits,random).mod(p); x = new BigInteger(bits,random).mod(p);
if(set.contains(x)){ if(set.contains(x)){
i--; i--;
continue; continue;
} }
set.add(x); set.add(x);
points[i] = new Polynomial.Point(x,polynomial); points[i] = new Polynomial.Point(x,polynomial);
} }
return points; return points;
} }
public void oneTest(Polynomial p, Polynomial.Point[] points) throws Exception { public void oneTest(Polynomial p, Polynomial.Point[] points) throws Exception {
Polynomial interpolation = Polynomial.interpolation(points,arithmetic); Polynomial interpolation = Polynomial.interpolation(points,arithmetic);
assert (p.compareTo(interpolation) == 0); assert (p.compareTo(interpolation) == 0);
} }
@Test @Test
public void interpolationTest() throws Exception { public void interpolationTest() throws Exception {
for (int i = 0; i < polynomials.length; i ++){ for (int i = 0; i < polynomials.length; i ++){
oneTest(polynomials[i],pointsArrays[i]); oneTest(polynomials[i],pointsArrays[i]);
} }
} }
} }

View File

@ -1,48 +1,48 @@
package ShamirSecretSharing.PolynomialTests; package meerkat.crypto.concrete.secret_shring.shamir.PolynomialTests;
import Arithmetics.Z; import Arithmetics.Z;
import Utils.GenerateRandomPolynomial; import Utils.GenerateRandomPolynomial;
import ShamirSecretSharing.Polynomial; import meerkat.crypto.concrete.secret_shring.shamir.Polynomial;
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.Random; import java.util.Random;
/** /**
* Created by Tzlil on 1/27/2016. * Created by Tzlil on 1/27/2016.
*/ */
public class MulByConstTest { public class MulByConstTest {
Polynomial[] arr1; Polynomial[] arr1;
BigInteger[] arr2; BigInteger[] arr2;
int tests = 1 << 12; int tests = 1 << 12;
int maxDegree = 15; int maxDegree = 15;
int bits = 128; int bits = 128;
Random random; Random random;
@Before @Before
public void settings(){ public void settings(){
random = new Random(); random = new Random();
arr1 = new Polynomial[tests]; arr1 = new Polynomial[tests];
arr2 = new BigInteger[tests]; arr2 = new BigInteger[tests];
for (int i = 0; i < arr1.length; i++){ for (int i = 0; i < arr1.length; i++){
arr1[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,new Z()); arr1[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,new Z());
arr2[i] = new BigInteger(bits,random); arr2[i] = new BigInteger(bits,random);
} }
} }
public void oneTest(Polynomial p, BigInteger c){ public void oneTest(Polynomial p, BigInteger c){
Polynomial product = p.mul(c); Polynomial product = p.mul(c);
BigInteger x = new BigInteger(bits,random); BigInteger x = new BigInteger(bits,random);
assert(product.evaluate(x).equals(p.evaluate(x).multiply(c))); assert(product.evaluate(x).equals(p.evaluate(x).multiply(c)));
} }
@Test @Test
public void mulByConstTest(){ public void mulByConstTest(){
for (int i = 0 ; i < arr1.length; i ++){ for (int i = 0 ; i < arr1.length; i ++){
oneTest(arr1[i],arr2[i]); oneTest(arr1[i],arr2[i]);
} }
} }
} }

View File

@ -1,48 +1,48 @@
package ShamirSecretSharing.PolynomialTests; package meerkat.crypto.concrete.secret_shring.shamir.PolynomialTests;
import Arithmetics.Z; import Arithmetics.Z;
import Utils.GenerateRandomPolynomial; import Utils.GenerateRandomPolynomial;
import ShamirSecretSharing.Polynomial; import meerkat.crypto.concrete.secret_shring.shamir.Polynomial;
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.Random; import java.util.Random;
/** /**
* Created by Tzlil on 1/27/2016. * Created by Tzlil on 1/27/2016.
*/ */
public class MulTest { public class MulTest {
Polynomial[] arr1; Polynomial[] arr1;
Polynomial[] arr2; Polynomial[] arr2;
int tests = 1 << 12; int tests = 1 << 12;
int maxDegree = 15; int maxDegree = 15;
int bits = 128; int bits = 128;
Random random; Random random;
@Before @Before
public void settings(){ public void settings(){
random = new Random(); random = new Random();
arr1 = new Polynomial[tests]; arr1 = new Polynomial[tests];
arr2 = new Polynomial[tests]; arr2 = new Polynomial[tests];
for (int i = 0; i < arr1.length; i++){ for (int i = 0; i < arr1.length; i++){
arr1[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,new Z()); arr1[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,new Z());
arr2[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,new Z()); arr2[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,new Z());
} }
} }
public void oneTest(Polynomial p1, Polynomial p2){ public void oneTest(Polynomial p1, Polynomial p2){
Polynomial product = p1.mul(p2); Polynomial product = p1.mul(p2);
BigInteger x = new BigInteger(bits,random); BigInteger x = new BigInteger(bits,random);
assert(product.evaluate(x).equals(p1.evaluate(x).multiply(p2.evaluate(x)))); assert(product.evaluate(x).equals(p1.evaluate(x).multiply(p2.evaluate(x))));
} }
@Test @Test
public void mulTest(){ public void mulTest(){
for (int i = 0 ; i < arr1.length; i ++){ for (int i = 0 ; i < arr1.length; i ++){
oneTest(arr1[i],arr2[i]); oneTest(arr1[i],arr2[i]);
} }
} }
} }

View File

@ -1,63 +1,64 @@
package ShamirSecretSharing; package meerkat.crypto.concrete.secret_shring.shamir;
import Arithmetics.Z; import meerkat.crypto.utilitis.concrete.Fp;
import Utils.GenerateRandomPrime; import Utils.GenerateRandomPrime;
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;
import org.junit.Test; import org.junit.Test;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
/** /**
* Created by Tzlil on 1/29/2016. * Created by Tzlil on 1/29/2016.
*/ */
public class SecretSharingTest { public class SecretSharingTest {
SecretSharing[] secretSharingArray; SecretSharing[] secretSharingArray;
BigInteger[] secrets; BigInteger[] secrets;
CyclicGroup<BigInteger> group; CyclicGroup<BigInteger> group;
int tests = 1 << 10; int tests = 1 << 10;
Random random; Random random;
BigInteger p = GenerateRandomPrime.SafePrime100Bits;
@Before BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2));
public void settings(){
BigInteger p = GenerateRandomPrime.SafePrime100Bits; @Before
BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); public void settings(){
group = new Zn(p); group = new Zn(q);
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];
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);
secretSharingArray[i] = new SecretSharing(t,n,secrets[i],random,q); secretSharingArray[i] = new SecretSharing(t,n,secrets[i],random,q);
} }
} }
public void oneTest(SecretSharing secretSharing, BigInteger secret) throws Exception { public void oneTest(SecretSharing secretSharing, BigInteger secret) throws Exception {
int t = secretSharing.getT(); int t = secretSharing.getT();
int n = secretSharing.getN(); int n = secretSharing.getN();
Polynomial.Point[] shares = new Polynomial.Point[t + 1]; Polynomial.Point[] shares = new Polynomial.Point[t + 1];
List<Integer> indexes = new ArrayList<Integer>(n); List<Integer> indexes = new ArrayList<Integer>(n);
for (int i = 1 ; i <= n; i ++){ for (int i = 1 ; i <= n; i ++){
indexes.add(i); indexes.add(i);
} }
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.recoverSecret(shares,new Z()))); BigInteger calculated = SecretSharing.recoverSecret(shares,new Fp(q));
} assert (secret.equals(calculated));
}
@Test
public void secretSharingTest() throws Exception { @Test
for (int i = 0 ; i < secretSharingArray.length; i ++){ public void secretSharingTest() throws Exception {
oneTest(secretSharingArray[i],secrets[i]); for (int i = 0 ; i < secretSharingArray.length; i ++){
} oneTest(secretSharingArray[i],secrets[i]);
} }
} }
}