From b17954adc29df3fe14839695a3c6d4ca7d60b188 Mon Sep 17 00:00:00 2001 From: Arbel Deutsch Peled Date: Mon, 14 Dec 2015 23:14:52 +0200 Subject: [PATCH 01/49] Split interface into BulletinBoardClient and AsyncBulletinBoardClient. Added Batch Messages Bulletin Board Client interface and associated ProtoBufs. Returned simple implementation of BulletinBoardClient. Made ThreadedBulletinBoardClient extend SimpleBulletinBoardClient. Fixed an issue in SQLite where identical Signatures could be added to the same message. --- .../SimpleBulletinBoardClient.java | 32 +++++----- .../ThreadedBulletinBoardClient.java | 45 +++++++------- .../BulletinBoardClientIntegrationTest.java | 3 +- .../sqlserver/SQLiteQueryProvider.java | 3 +- .../AsyncBulletinBoardClient.java | 62 +++++++++++++++++++ .../bulletinboard/BulletinBoardClient.java | 23 ++++--- .../meerkat/bulletinboard/SignedBatch.java | 50 +++++++++++++++ .../main/proto/meerkat/BulletinBoardAPI.proto | 27 ++++++++ 8 files changed, 196 insertions(+), 49 deletions(-) create mode 100644 meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java create mode 100644 meerkat-common/src/main/java/meerkat/bulletinboard/SignedBatch.java diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java index f340cae..4244f15 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java @@ -5,8 +5,7 @@ import meerkat.comm.CommunicationException; import meerkat.crypto.Digest; import meerkat.crypto.concrete.SHA256Digest; import meerkat.protobuf.BulletinBoardAPI.*; -import meerkat.protobuf.Voting; -import meerkat.protobuf.Voting.BulletinBoardClientParams; +import meerkat.protobuf.Voting.*; import meerkat.rest.*; import java.util.List; @@ -19,23 +18,24 @@ import javax.ws.rs.core.Response; /** * Created by Arbel Deutsch Peled on 05-Dec-15. + * Implements BulletinBoardClient interface in a simple, straightforward manner */ -public class SimpleBulletinBoardClient{ //implements BulletinBoardClient { +public class SimpleBulletinBoardClient implements BulletinBoardClient{ - private List meerkatDBs; + protected List meerkatDBs; - private Client client; + protected Client client; - private Digest digest; + protected Digest digest; /** * Stores database locations and initializes the web Client * @param clientParams contains the data needed to access the DBs */ -// @Override - public void init(Voting.BulletinBoardClientParams clientParams) { + @Override + public void init(BulletinBoardClientParams clientParams) { - meerkatDBs = clientParams.getBulletinBoardAddressList(); + this.meerkatDBs = clientParams.getBulletinBoardAddressList(); client = ClientBuilder.newClient(); client.register(ProtobufMessageBodyReader.class); @@ -52,7 +52,7 @@ public class SimpleBulletinBoardClient{ //implements BulletinBoardClient { * @return the message ID for later retrieval * @throws CommunicationException */ -// @Override + @Override public MessageID postMessage(BulletinBoardMessage msg) throws CommunicationException { WebTarget webTarget; @@ -88,7 +88,7 @@ public class SimpleBulletinBoardClient{ //implements BulletinBoardClient { * @param id is the requested message ID * @return the number of DBs in which retrieval was successful */ -// @Override + @Override public float getRedundancy(MessageID id) { WebTarget webTarget; Response response; @@ -125,7 +125,7 @@ public class SimpleBulletinBoardClient{ //implements BulletinBoardClient { * @param filterList return only messages that match the filters (null means no filtering). * @return */ -// @Override + @Override public List readMessages(MessageFilterList filterList) { WebTarget webTarget; Response response; @@ -154,8 +154,8 @@ public class SimpleBulletinBoardClient{ //implements BulletinBoardClient { return null; } -// @Override -// public void registerNewMessageCallback(MessageCallback callback, MessageFilterList filterList) { -// callback.handleNewMessage(readMessages(filterList)); -// } + public void close() { + client.close(); + } + } diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java index bb46c32..dd103c6 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java @@ -6,10 +6,8 @@ import meerkat.bulletinboard.callbacks.GetRedundancyFutureCallback; import meerkat.bulletinboard.callbacks.PostMessageFutureCallback; import meerkat.bulletinboard.callbacks.ReadMessagesFutureCallback; import meerkat.comm.CommunicationException; -import meerkat.crypto.Digest; -import meerkat.crypto.concrete.SHA256Digest; import meerkat.protobuf.BulletinBoardAPI.*; -import meerkat.protobuf.Voting; +import meerkat.protobuf.Voting.*; import java.util.List; import java.util.concurrent.Executors; @@ -17,22 +15,16 @@ import java.util.concurrent.TimeUnit; /** * Created by Arbel Deutsch Peled on 05-Dec-15. - * Thread-based implementation of a Bulletin Board Client. + * Thread-based implementation of a Async Bulletin Board Client. * Features: * 1. Handles tasks concurrently. * 2. Retries submitting */ -public class ThreadedBulletinBoardClient implements BulletinBoardClient { +public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient implements AsyncBulletinBoardClient { private final static int THREAD_NUM = 10; ListeningExecutorService listeningExecutor; - private Digest digest; - - private List meerkatDBs; - private String postSubAddress; - private String readSubAddress; - private final static int READ_MESSAGES_RETRY_NUM = 1; private int minAbsoluteRedundancy; @@ -44,15 +36,13 @@ public class ThreadedBulletinBoardClient implements BulletinBoardClient { * @param clientParams contains the required information */ @Override - public void init(Voting.BulletinBoardClientParams clientParams) { + public void init(BulletinBoardClientParams clientParams) { - meerkatDBs = clientParams.getBulletinBoardAddressList(); + super.init(clientParams); - minAbsoluteRedundancy = (int) (clientParams.getMinRedundancy() * meerkatDBs.size()); + minAbsoluteRedundancy = (int) (clientParams.getMinRedundancy() * clientParams.getBulletinBoardAddressCount()); - listeningExecutor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(THREAD_NUM)); - - digest = new SHA256Digest(); + listeningExecutor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(THREAD_NUM)); } @@ -78,13 +68,21 @@ public class ThreadedBulletinBoardClient implements BulletinBoardClient { return MessageID.newBuilder().setID(ByteString.copyFrom(digest.digest())).build(); } + @Override + public MessageID postBatch(byte[] signerId, int batchId, List batchDataList, int startPosition, ClientCallback callback) { + return null; //TODO: Implement + } + + @Override + public MessageID postBatch(byte[] signerId, int batchId, List batchDataList, ClientCallback callback) { + return null; //TODO: Implement + } + /** * Access each database and search for a given message ID * Return the number of databases in which the message was found * Only try once per DB * Ignore communication exceptions in specific databases - * @param id is the requested message ID - * @return the number of DBs in which retrieval was successful */ @Override public void getRedundancy(MessageID id, ClientCallback callback) { @@ -101,8 +99,6 @@ public class ThreadedBulletinBoardClient implements BulletinBoardClient { * Go through the DBs and try to retrieve messages according to the specified filter * If at the operation is successful for some DB: return the results and stop iterating * If no operation is successful: return null (NOT blank list) - * @param filterList return only messages that match the filters (null means no filtering). - * @return */ @Override public void readMessages(MessageFilterList filterList, ClientCallback> callback) { @@ -116,8 +112,15 @@ public class ThreadedBulletinBoardClient implements BulletinBoardClient { } + @Override + public void readBatch(byte[] signerId, int batchId, ClientCallback callback) { + // TODO: Implement + } + @Override public void close() { + super.close(); + try { listeningExecutor.shutdown(); while (! listeningExecutor.isShutdown()) { diff --git a/bulletin-board-client/src/test/java/BulletinBoardClientIntegrationTest.java b/bulletin-board-client/src/test/java/BulletinBoardClientIntegrationTest.java index dda76c7..c090c92 100644 --- a/bulletin-board-client/src/test/java/BulletinBoardClientIntegrationTest.java +++ b/bulletin-board-client/src/test/java/BulletinBoardClientIntegrationTest.java @@ -1,4 +1,5 @@ import com.google.protobuf.ByteString; +import meerkat.bulletinboard.AsyncBulletinBoardClient; import meerkat.bulletinboard.BulletinBoardClient; import meerkat.bulletinboard.BulletinBoardClient.ClientCallback; import meerkat.bulletinboard.ThreadedBulletinBoardClient; @@ -97,7 +98,7 @@ public class BulletinBoardClientIntegrationTest { } } - private BulletinBoardClient bulletinBoardClient; + private AsyncBulletinBoardClient bulletinBoardClient; private PostCallback postCallback; private RedundancyCallback redundancyCallback; diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteQueryProvider.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteQueryProvider.java index 945ae47..8131d2b 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteQueryProvider.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteQueryProvider.java @@ -98,10 +98,9 @@ public class SQLiteQueryProvider implements BulletinBoardSQLServer.SQLQueryProvi + " REFERENCES MsgTable(EntryNum), FOREIGN KEY (TagId) REFERENCES TagTable(TagId), UNIQUE (EntryNum, TagID))"); list.add("CREATE TABLE IF NOT EXISTS SignatureTable (EntryNum INTEGER, SignerId BLOB, Signature BLOB," - + " FOREIGN KEY (EntryNum) REFERENCES MsgTable(EntryNum))"); + + " FOREIGN KEY (EntryNum) REFERENCES MsgTable(EntryNum), UNIQUE(SignerId, EntryNum))"); list.add("CREATE INDEX IF NOT EXISTS SignerIndex ON SignatureTable(SignerId)"); - list.add("CREATE UNIQUE INDEX IF NOT EXISTS SignerIndex ON SignatureTable(SignerId, EntryNum)"); return list; } diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java b/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java new file mode 100644 index 0000000..04b7a06 --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java @@ -0,0 +1,62 @@ +package meerkat.bulletinboard; + +import meerkat.protobuf.BulletinBoardAPI.*; + +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 14-Dec-15. + */ +public interface AsyncBulletinBoardClient extends BulletinBoardClient { + + /** + * Post a message to the bulletin board in an asynchronous manner + * @param msg is the message to be posted + * @param callback is a class containing methods to handle the result of the operation + * @return a unique message ID for the message, that can be later used to retrieve the batch + */ + MessageID postMessage(BulletinBoardMessage msg, ClientCallback callback); + + /** + * This method allows for sending large messages as a batch to the bulletin board + * @param signerId is the canonical form for the ID of the sender of this batch + * @param batchId is a unique (per signer) ID for this batch + * @param batchDataList is the (canonically ordered) list of data comprising the batch message + * @param startPosition is the location (in the batch) of the first entry in batchDataList (optionally used to continue interrupted post operations) + * @param callback is a callback function class for handling results of the operation + * @return a unique message ID for the entire message, that can be later used to retrieve the batch + */ + MessageID postBatch(byte[] signerId, int batchId, List batchDataList, int startPosition, ClientCallback callback); + + /** + * Overloading of the postBatch method in which startPosition is set to the default value 0 + */ + MessageID postBatch(byte[] signerId, int batchId, List batchDataList, ClientCallback callback); + + /** + * Check how "safe" a given message is in an asynchronous manner + * The result of the computation is a rank between 0.0 and 1.0 indicating the fraction of servers containing the message + * @param id is the unique message identifier for retrieval + * @param callback is a callback function class for handling results of the operation + */ + void getRedundancy(MessageID id, ClientCallback callback); + + /** + * Read all messages posted matching the given filter in an asynchronous manner + * Note that if messages haven't been "fully posted", this might return a different + * set of messages in different calls. However, messages that are fully posted + * are guaranteed to be included. + * @param filterList return only messages that match the filters (null means no filtering). + * @param callback is a callback function class for handling results of the operation + */ + void readMessages(MessageFilterList filterList, ClientCallback> callback); + + /** + * Read a given batch message from the bulletin board + * @param signerId is the ID of the signer (sender) of the batch message + * @param batchId is the unique (per signer) ID of the batch + * @param callback is a callback class for handling the result of the operation + */ + void readBatch(byte[] signerId, int batchId, ClientCallback callback); + +} diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardClient.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardClient.java index c51e561..dcf6b15 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardClient.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardClient.java @@ -1,6 +1,6 @@ package meerkat.bulletinboard; -import meerkat.comm.*; +import meerkat.comm.CommunicationException; import meerkat.protobuf.Voting.*; import static meerkat.protobuf.BulletinBoardAPI.*; @@ -24,26 +24,31 @@ public interface BulletinBoardClient { void init(BulletinBoardClientParams clientParams); /** - * Post a message to the bulletin board - * @param msg + * Post a message to the bulletin board in a synchronous manner + * @param msg is the message to be posted + * @return a unique message ID for the message, that can be later used to retrieve the batch + * @throws CommunicationException */ - MessageID postMessage(BulletinBoardMessage msg, ClientCallback callback); + MessageID postMessage(BulletinBoardMessage msg) throws CommunicationException; + + /** - * Check how "safe" a given message is - * @param id + * Check how "safe" a given message is in a synchronous manner + * @param id is the unique message identifier for retrieval * @return a normalized "redundancy score" from 0 (local only) to 1 (fully published) */ - void getRedundancy(MessageID id, ClientCallback callback); + float getRedundancy(MessageID id); /** - * Read all messages posted matching the given filter + * Read all messages posted matching the given filter in a synchronous manner * Note that if messages haven't been "fully posted", this might return a different * set of messages in different calls. However, messages that are fully posted * are guaranteed to be included. * @param filterList return only messages that match the filters (null means no filtering). + * @return the list of messages */ - void readMessages(MessageFilterList filterList, ClientCallback> callback); + List readMessages(MessageFilterList filterList); /** * Closes all connections, if any. diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/SignedBatch.java b/meerkat-common/src/main/java/meerkat/bulletinboard/SignedBatch.java new file mode 100644 index 0000000..46cf07e --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/SignedBatch.java @@ -0,0 +1,50 @@ +package meerkat.bulletinboard; + +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Crypto.*; + +import java.util.LinkedList; +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 14-Dec-15. + * + * A data structure for holding both a batch message and its signature + */ +public class SignedBatch { + + private List batchDataList; + private Signature signature; + + public SignedBatch() { + batchDataList = new LinkedList(); + } + + public SignedBatch(List newDataList) { + this(); + appendBatchData(newDataList); + } + + public SignedBatch(List newDataList, Signature newSignature) { + this(newDataList); + signature = newSignature; + } + + public List getBatchDataList() { + return batchDataList; + } + + public Signature getSignature() { + return signature; + } + + public void appendBatchData(BatchData newBatchData) { + batchDataList.add(newBatchData); + } + + public void appendBatchData(List newBatchDataList) { + batchDataList.addAll(newBatchDataList); + } + + +} diff --git a/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto b/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto index 0fe35f8..1a0bab1 100644 --- a/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto +++ b/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto @@ -77,4 +77,31 @@ message MessageFilterList { // To be implemented using intersection ("AND") operations. repeated MessageFilter filter = 1; +} + +// This message is used to start a batch transfer to the Bulletin Board Server +message BeginBatchMessage { + bytes signerId = 1; // Unique signer identifier + int32 batchId = 2; // Unique identifier for the batch (unique per signer) + repeated string tag = 3; // Tags for the batch message +} + +// This message is used to finalize and sign a batch transfer to the Bulletin Board Server +message CloseBatchMessage { + int32 batchId = 1; // Unique identifier for the batch (unique per signer) + int32 batchLength = 2; // Number of messages in the batch + meerkat.Signature sig = 3; // Signature on the (ordered) batch messages +} + +// Container for single batch message data +message BatchData { + bytes data = 1; +} + +// These messages comprise a batch message +message BatchMessage { + bytes signerId = 1; // Unique signer identifier + int32 batchId = 2; // Unique identifier for the batch (unique per signer) + int32 serialNum = 3; // Location of the message in the batch: starting from 0 + BatchData data = 4; // Actual data } \ No newline at end of file From 37fdc0bb83d9e8a14a54c960cb915d513dfd4766 Mon Sep 17 00:00:00 2001 From: Arbel Deutsch Peled Date: Fri, 18 Dec 2015 14:39:40 +0200 Subject: [PATCH 02/49] Fixed minor H2 bug. Fixed dbTest gradle task (now tests all 3 supported DB engines). --- .../BulletinBoardClientIntegrationTest.java | 20 ++++++++--------- bulletin-board-server/build.gradle | 6 +++-- .../sqlserver/H2QueryProvider.java | 2 +- .../sqlserver/SQLiteQueryProvider.java | 22 ++++++++++++++++--- .../src/main/webapp/WEB-INF/web.xml | 2 +- 5 files changed, 35 insertions(+), 17 deletions(-) diff --git a/bulletin-board-client/src/test/java/BulletinBoardClientIntegrationTest.java b/bulletin-board-client/src/test/java/BulletinBoardClientIntegrationTest.java index c090c92..55f0343 100644 --- a/bulletin-board-client/src/test/java/BulletinBoardClientIntegrationTest.java +++ b/bulletin-board-client/src/test/java/BulletinBoardClientIntegrationTest.java @@ -27,6 +27,12 @@ public class BulletinBoardClientIntegrationTest { Semaphore jobSemaphore; Vector thrown; + protected void genericHandleFailure(Throwable t){ + System.err.println(t.getCause() + " " + t.getMessage()); + thrown.add(t); + jobSemaphore.release(); + } + private class PostCallback implements ClientCallback{ @Override @@ -37,8 +43,7 @@ public class BulletinBoardClientIntegrationTest { @Override public void handleFailure(Throwable t) { - thrown.add(t); - jobSemaphore.release(); + genericHandleFailure(t); } } @@ -59,8 +64,7 @@ public class BulletinBoardClientIntegrationTest { @Override public void handleFailure(Throwable t) { - thrown.add(t); - jobSemaphore.release(); + genericHandleFailure(t); } } @@ -93,8 +97,7 @@ public class BulletinBoardClientIntegrationTest { @Override public void handleFailure(Throwable t) { - thrown.add(t); - jobSemaphore.release(); + genericHandleFailure(t); } } @@ -202,10 +205,7 @@ public class BulletinBoardClientIntegrationTest { } bulletinBoardClient.close(); - - for (Throwable t : thrown) { - System.err.println(t.getMessage()); - } + if (thrown.size() > 0) { assert false; } diff --git a/bulletin-board-server/build.gradle b/bulletin-board-server/build.gradle index eb197c9..62e4b0c 100644 --- a/bulletin-board-server/build.gradle +++ b/bulletin-board-server/build.gradle @@ -75,13 +75,15 @@ dependencies { test { exclude '**/*SQLite*Test*' exclude '**/*H2*Test*' - exclude '**/*MySql*Test' + exclude '**/*MySQL*Test*' exclude '**/*IntegrationTest*' } task dbTest(type: Test) { include '**/*H2*Test*' - include '**/*MySql*Test' + include '**/*MySQL*Test*' + include '**/*SQLite*Test*' + outputs.upToDateWhen { false } } task integrationTest(type: Test) { diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java index fa2b146..d76601f 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java @@ -74,7 +74,7 @@ public class H2QueryProvider implements BulletinBoardSQLServer.SQLQueryProvider case MAX_MESSAGES: return "LIMIT :Limit" + serialString; case MSG_ID: - return "MsgTable.MsgId = MsgId" + serialString; + return "MsgTable.MsgId = :MsgId" + serialString; case SIGNER_ID: return "EXISTS (SELECT 1 FROM SignatureTable" + " WHERE SignatureTable.SignerId = :SignerId" + serialString + " AND SignatureTable.EntryNum = MsgTable.EntryNum)"; diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteQueryProvider.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteQueryProvider.java index 8131d2b..d796789 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteQueryProvider.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteQueryProvider.java @@ -73,15 +73,31 @@ public class SQLiteQueryProvider implements BulletinBoardSQLServer.SQLQueryProvi @Override public String getConditionParamTypeName(FilterType filterType) throws IllegalArgumentException { - return null; //TODO: write this. + + switch(filterType) { + case EXACT_ENTRY: // Go through + case MAX_ENTRY: // Go through + case MAX_MESSAGES: + return "INTEGER"; + + case MSG_ID: // Go through + case SIGNER_ID: + return "BLOB"; + + case TAG: + return "VARCHAR"; + + default: + throw new IllegalArgumentException("Cannot serve a filter of type " + filterType); + } + } @Override public DataSource getDataSource() { - // TODO: Fix this + SQLiteDataSource dataSource = new SQLiteDataSource(); dataSource.setUrl("jdbc:sqlite:" + dbName); - dataSource.setDatabaseName("meerkat"); //TODO: Make generic return dataSource; } diff --git a/bulletin-board-server/src/main/webapp/WEB-INF/web.xml b/bulletin-board-server/src/main/webapp/WEB-INF/web.xml index 2198c07..226aa3b 100644 --- a/bulletin-board-server/src/main/webapp/WEB-INF/web.xml +++ b/bulletin-board-server/src/main/webapp/WEB-INF/web.xml @@ -31,7 +31,7 @@ mypass dbType - SQLite + H2 meerkat.bulletinboard.webapp.BulletinBoardWebApp From 37f962d520d9555e6336f8d27a1b34c89c71b019 Mon Sep 17 00:00:00 2001 From: Arbel Deutsch Peled Date: Sat, 19 Dec 2015 19:54:50 +0200 Subject: [PATCH 03/49] Defined semi-final versions of the batch interfaces. Implemented in part extended BB Server interface. Added Digest support for Batch messages. Made GlobalCryptoSetup a final singleton. --- .../ThreadedBulletinBoardClient.java | 5 + .../callbacks/ClientFutureCallback.java | 6 - .../GetRedundancyFutureCallback.java | 6 +- .../callbacks/PostMessageFutureCallback.java | 8 +- .../callbacks/ReadMessagesFutureCallback.java | 9 +- .../BulletinBoardClientIntegrationTest.java | 3 +- .../sqlserver/BulletinBoardSQLServer.java | 203 +++++++++++++++--- .../sqlserver/MySQLQueryProvider.java | 80 ++++++- .../sqlserver/mappers/BatchDataMapper.java | 21 ++ .../{EntryNumMapper.java => LongMapper.java} | 2 +- .../webapp/BulletinBoardWebApp.java | 59 ++++- .../AsyncBulletinBoardClient.java | 28 ++- .../bulletinboard/BulletinBoardClient.java | 5 - .../bulletinboard/BulletinBoardServer.java | 73 +++++-- .../main/java/meerkat/crypto/BatchDigest.java | 20 ++ .../src/main/java/meerkat/crypto/Digest.java | 6 +- .../crypto/concrete/ECDSASignature.java | 5 +- .../crypto/concrete/ECElGamalEncryption.java | 5 +- .../crypto/concrete/GenericBatchDigest.java | 27 +++ .../crypto/concrete/GlobalCryptoSetup.java | 28 ++- .../meerkat/crypto/concrete/SHA256Digest.java | 3 +- .../main/proto/meerkat/BulletinBoardAPI.proto | 7 + .../crypto/concrete/ECElGamalUtils.java | 5 +- .../src/main/java/meerkat/rest/Constants.java | 4 + 24 files changed, 516 insertions(+), 102 deletions(-) create mode 100644 bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/BatchDataMapper.java rename bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/{EntryNumMapper.java => LongMapper.java} (87%) create mode 100644 meerkat-common/src/main/java/meerkat/crypto/BatchDigest.java create mode 100644 meerkat-common/src/main/java/meerkat/crypto/concrete/GenericBatchDigest.java diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java index dd103c6..5953bde 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java @@ -117,6 +117,11 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple // TODO: Implement } + @Override + public void subscribe(MessageFilterList filterList, MessageHandler messageHandler) { + // TODO: Implement + } + @Override public void close() { super.close(); diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ClientFutureCallback.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ClientFutureCallback.java index 7c5b7b0..54cc63a 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ClientFutureCallback.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ClientFutureCallback.java @@ -1,14 +1,8 @@ package meerkat.bulletinboard.callbacks; import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListeningExecutorService; -import meerkat.bulletinboard.BulletinClientJob; import meerkat.bulletinboard.BulletinClientJobResult; -import meerkat.bulletinboard.BulletinClientWorker; -import meerkat.protobuf.BulletinBoardAPI; - -import java.util.List; /** * This is a future callback used to listen to workers and run on job finish diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/GetRedundancyFutureCallback.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/GetRedundancyFutureCallback.java index 518ed77..719428f 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/GetRedundancyFutureCallback.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/GetRedundancyFutureCallback.java @@ -1,7 +1,7 @@ package meerkat.bulletinboard.callbacks; import com.google.common.util.concurrent.ListeningExecutorService; -import meerkat.bulletinboard.BulletinBoardClient; +import meerkat.bulletinboard.AsyncBulletinBoardClient.*; import meerkat.bulletinboard.BulletinClientJobResult; import meerkat.protobuf.BulletinBoardAPI.*; @@ -13,10 +13,10 @@ import java.util.List; */ public class GetRedundancyFutureCallback extends ClientFutureCallback { - private BulletinBoardClient.ClientCallback callback; + private ClientCallback callback; public GetRedundancyFutureCallback(ListeningExecutorService listeningExecutor, - BulletinBoardClient.ClientCallback callback) { + ClientCallback callback) { super(listeningExecutor); this.callback = callback; } diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/PostMessageFutureCallback.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/PostMessageFutureCallback.java index 221ae1a..abd4247 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/PostMessageFutureCallback.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/PostMessageFutureCallback.java @@ -2,13 +2,11 @@ package meerkat.bulletinboard.callbacks; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListeningExecutorService; -import meerkat.bulletinboard.BulletinBoardClient; +import meerkat.bulletinboard.AsyncBulletinBoardClient.*; import meerkat.bulletinboard.BulletinClientJob; import meerkat.bulletinboard.BulletinClientJobResult; import meerkat.bulletinboard.BulletinClientWorker; -import meerkat.protobuf.BulletinBoardAPI; -import java.util.List; /** * This is a future callback used to listen to workers and run on job finish @@ -16,10 +14,10 @@ import java.util.List; */ public class PostMessageFutureCallback extends ClientFutureCallback { - private BulletinBoardClient.ClientCallback callback; + private ClientCallback callback; public PostMessageFutureCallback(ListeningExecutorService listeningExecutor, - BulletinBoardClient.ClientCallback callback) { + ClientCallback callback) { super(listeningExecutor); this.callback = callback; } diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ReadMessagesFutureCallback.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ReadMessagesFutureCallback.java index 4c43ba2..808b7a6 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ReadMessagesFutureCallback.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ReadMessagesFutureCallback.java @@ -1,11 +1,8 @@ package meerkat.bulletinboard.callbacks; -import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListeningExecutorService; -import meerkat.bulletinboard.BulletinBoardClient; -import meerkat.bulletinboard.BulletinClientJob; +import meerkat.bulletinboard.AsyncBulletinBoardClient.*; import meerkat.bulletinboard.BulletinClientJobResult; -import meerkat.bulletinboard.BulletinClientWorker; import meerkat.protobuf.BulletinBoardAPI; import java.util.List; @@ -16,10 +13,10 @@ import java.util.List; */ public class ReadMessagesFutureCallback extends ClientFutureCallback { - private BulletinBoardClient.ClientCallback> callback; + private ClientCallback> callback; public ReadMessagesFutureCallback(ListeningExecutorService listeningExecutor, - BulletinBoardClient.ClientCallback> callback) { + ClientCallback> callback) { super(listeningExecutor); this.callback = callback; } diff --git a/bulletin-board-client/src/test/java/BulletinBoardClientIntegrationTest.java b/bulletin-board-client/src/test/java/BulletinBoardClientIntegrationTest.java index 55f0343..d7ae69c 100644 --- a/bulletin-board-client/src/test/java/BulletinBoardClientIntegrationTest.java +++ b/bulletin-board-client/src/test/java/BulletinBoardClientIntegrationTest.java @@ -1,7 +1,6 @@ import com.google.protobuf.ByteString; import meerkat.bulletinboard.AsyncBulletinBoardClient; -import meerkat.bulletinboard.BulletinBoardClient; -import meerkat.bulletinboard.BulletinBoardClient.ClientCallback; +import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; import meerkat.bulletinboard.ThreadedBulletinBoardClient; import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.protobuf.Crypto; diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java index 52bf42b..5f9b461 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java @@ -1,20 +1,29 @@ package meerkat.bulletinboard.sqlserver; +import java.security.InvalidKeyException; +import java.security.cert.CertificateException; import java.sql.*; import java.util.*; +import com.google.protobuf.ByteString; import com.google.protobuf.ProtocolStringList; import meerkat.bulletinboard.BulletinBoardServer; -import meerkat.bulletinboard.sqlserver.mappers.EntryNumMapper; -import meerkat.bulletinboard.sqlserver.mappers.MessageMapper; -import meerkat.bulletinboard.sqlserver.mappers.SignatureMapper; +import meerkat.bulletinboard.sqlserver.mappers.*; + import meerkat.comm.CommunicationException; + +import meerkat.crypto.BatchDigest; +import meerkat.crypto.DigitalSignature; +import meerkat.crypto.concrete.ECDSASignature; +import meerkat.crypto.concrete.SHA256Digest; + import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.protobuf.Crypto.Signature; import meerkat.protobuf.Crypto.SignatureVerificationKey; -import meerkat.crypto.Digest; -import meerkat.crypto.concrete.SHA256Digest; + + +import static meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer.SQLQueryProvider.*; import javax.sql.DataSource; @@ -23,6 +32,8 @@ import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.support.GeneratedKeyHolder; import org.springframework.jdbc.support.KeyHolder; + + /** * This is a generic SQL implementation of the BulletinBoardServer API. */ @@ -46,7 +57,12 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ CONNECT_TAG(new String[] {"EntryNum","Tag"}), ADD_SIGNATURE(new String[] {"EntryNum","SignerId","Signature"}), GET_SIGNATURES(new String[] {"EntryNum"}), - GET_MESSAGES(new String[] {}); + GET_MESSAGES(new String[] {}), + GET_BATCH_MESSAGE_ENTRY(new String[] {"SignerId", "BatchId"}), + CHECK_BATCH_LENGTH(new String[] {"SignerId", "BatchId"}), + GET_BATCH_MESSAGE_DATA(new String[] {"SignerId", "BatchId", "StartPosition"}), + INSERT_BATCH_DATA(new String[] {"SignerId", "BatchId", "SerialNum", "Data"}), + CONNECT_BATCH_TAG(new String[] {"SignerId", "BatchId", "Tag"}); private String[] paramNames; @@ -58,6 +74,10 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ return paramNames; } + public String getParamName(int num) { + return paramNames[num]; + } + } /** @@ -152,6 +172,11 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ } + /** + * This method returns the value of the parameter specified in a message filter + * @param messageFilter is the filter + * @return the object parameter for the SQL query embedded in the filter (this depends on the filter type) + */ private Object getParam(MessageFilter messageFilter) { switch (messageFilter.getType()) { @@ -170,7 +195,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ case MAX_MESSAGES: return messageFilter.getMaxMessages(); - default: + default: // Unsupported filter type return null; } @@ -193,7 +218,8 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ protected NamedParameterJdbcTemplate jdbcTemplate; - protected Digest digest; + protected BatchDigest digest; + protected DigitalSignature signer; protected List trusteeSignatureVerificationArray; protected int minTrusteeSignatures; @@ -232,6 +258,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ // TODO write signature reading part. digest = new SHA256Digest(); + signer = new ECDSASignature(); jdbcTemplate = new NamedParameterJdbcTemplate(sqlQueryProvider.getDataSource()); @@ -264,12 +291,12 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ String sql; - sql = sqlQueryProvider.getSQLString(SQLQueryProvider.QueryType.INSERT_NEW_TAG); + sql = sqlQueryProvider.getSQLString(QueryType.INSERT_NEW_TAG); Map namedParameters[] = new HashMap[tags.length]; for (int i = 0 ; i < tags.length ; i++){ namedParameters[i] = new HashMap(); - namedParameters[i].put("Tag", tags[i]); + namedParameters[i].put(QueryType.INSERT_NEW_TAG.getParamName(0), tags[i]); } jdbcTemplate.batchUpdate(sql, namedParameters); @@ -316,11 +343,11 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ // Add message to table if needed and store entry number of message. - sql = sqlQueryProvider.getSQLString(SQLQueryProvider.QueryType.FIND_MSG_ID); + sql = sqlQueryProvider.getSQLString(QueryType.FIND_MSG_ID); Map namedParameters = new HashMap(); - namedParameters.put("MsgId",msgID); + namedParameters.put(QueryType.FIND_MSG_ID.getParamName(0),msgID); - List entryNums = jdbcTemplate.query(sql, new MapSqlParameterSource(namedParameters), new EntryNumMapper()); + List entryNums = jdbcTemplate.query(sql, new MapSqlParameterSource(namedParameters), new LongMapper()); if (entryNums.size() > 0){ @@ -328,8 +355,8 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ } else{ - sql = sqlQueryProvider.getSQLString(SQLQueryProvider.QueryType.INSERT_MSG); - namedParameters.put("Msg", msg.getMsg().toByteArray()); + sql = sqlQueryProvider.getSQLString(QueryType.INSERT_MSG); + namedParameters.put(QueryType.INSERT_MSG.getParamName(0), msg.getMsg().toByteArray()); KeyHolder keyHolder = new GeneratedKeyHolder(); jdbcTemplate.update(sql,new MapSqlParameterSource(namedParameters),keyHolder); @@ -354,14 +381,14 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ // Connect message to tags. - sql = sqlQueryProvider.getSQLString(SQLQueryProvider.QueryType.CONNECT_TAG); + sql = sqlQueryProvider.getSQLString(QueryType.CONNECT_TAG); namedParameterArray = new HashMap[tags.length]; for (int i = 0 ; i < tags.length ; i++) { namedParameterArray[i] = new HashMap(); - namedParameterArray[i].put("EntryNum", entryNum); - namedParameterArray[i].put("Tag", tags[i]); + namedParameterArray[i].put(QueryType.CONNECT_TAG.getParamName(0), entryNum); + namedParameterArray[i].put(QueryType.CONNECT_TAG.getParamName(1), tags[i]); } jdbcTemplate.batchUpdate(sql, namedParameterArray); @@ -374,15 +401,15 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ // Connect message to signatures. - sql = sqlQueryProvider.getSQLString(SQLQueryProvider.QueryType.ADD_SIGNATURE); + sql = sqlQueryProvider.getSQLString(QueryType.ADD_SIGNATURE); namedParameterArray = new HashMap[signatures.length]; for (int i = 0 ; i < signatures.length ; i++) { namedParameterArray[i] = new HashMap(); - namedParameterArray[i].put("EntryNum", entryNum); - namedParameterArray[i].put("SignerId", signatures[i].getSignerId().toByteArray()); - namedParameterArray[i].put("Signature", signatures[i].toByteArray()); + namedParameterArray[i].put(QueryType.ADD_SIGNATURE.getParamName(0), entryNum); + namedParameterArray[i].put(QueryType.ADD_SIGNATURE.getParamName(1), signatures[i].getSignerId().toByteArray()); + namedParameterArray[i].put(QueryType.ADD_SIGNATURE.getParamName(2), signatures[i].toByteArray()); } jdbcTemplate.batchUpdate(sql,namedParameterArray); @@ -412,7 +439,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ // Check if Tag/Signature tables are required for filtering purposes - sqlBuilder.append(sqlQueryProvider.getSQLString(SQLQueryProvider.QueryType.GET_MESSAGES)); + sqlBuilder.append(sqlQueryProvider.getSQLString(QueryType.GET_MESSAGES)); // Add conditions namedParameters = new MapSqlParameterSource(); @@ -434,7 +461,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ sqlBuilder.append(sqlQueryProvider.getCondition(filter.getType(), paramNum)); - SQLQueryProvider.FilterTypeParam filterTypeParam = SQLQueryProvider.FilterTypeParam.getFilterTypeParamName(filter.getType()); + FilterTypeParam filterTypeParam = FilterTypeParam.getFilterTypeParamName(filter.getType()); namedParameters.addValue( filterTypeParam.getParamName() + Integer.toString(paramNum), @@ -457,10 +484,10 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ // Retrieve signatures namedParameters = new MapSqlParameterSource(); - namedParameters.addValue("EntryNum", msgBuilder.getEntryNum()); + namedParameters.addValue(QueryType.GET_SIGNATURES.getParamName(0), msgBuilder.getEntryNum()); List signatures = jdbcTemplate.query( - sqlQueryProvider.getSQLString(SQLQueryProvider.QueryType.GET_SIGNATURES), + sqlQueryProvider.getSQLString(QueryType.GET_SIGNATURES), namedParameters, signatureMapper); @@ -478,6 +505,130 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ } + /** + * This method checks if a specified batch exists and is already closed + * @param signerId is the ID of the publisher of the batch + * @param batchId is the unique (per signer) batch ID + * @return TRUE if the batch is closed and FALSE if it is still open or doesn't exist at all + */ + private boolean isBatchClosed(ByteString signerId, int batchId){ + + String sql = sqlQueryProvider.getSQLString(QueryType.GET_BATCH_MESSAGE_ENTRY); + + MapSqlParameterSource namedParameters = new MapSqlParameterSource(); + namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_ENTRY.getParamName(0), signerId); + namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_ENTRY.getParamName(1), batchId); + + List result = jdbcTemplate.query(sql,namedParameters,new LongMapper()); + + return (result.size() > 0); + + } + + @Override + public BoolMsg beginBatch(BeginBatchMessage message) throws CommunicationException { + + // Check if batch is closed + if (isBatchClosed(message.getSignerId(), message.getBatchId())) { + return BoolMsg.newBuilder().setValue(false).build(); + } + + // Add new tags to table + ProtocolStringList tagList = message.getTagList(); + String[] tags = new String[tagList.size()]; + tags = tagList.toArray(tags); + try { + insertNewTags(tags); + } catch (SQLException e) { + throw new CommunicationException(e.getMessage()); + } + + // Connect tags + String sql = sqlQueryProvider.getSQLString(QueryType.CONNECT_BATCH_TAG); + MapSqlParameterSource namedParameters[] = new MapSqlParameterSource[tags.length]; + + for (int i=0 ; i < tags.length ; i++) { + namedParameters[i] = new MapSqlParameterSource(); + namedParameters[i].addValue(QueryType.CONNECT_BATCH_TAG.getParamName(0),message.getSignerId()); + namedParameters[i].addValue(QueryType.CONNECT_BATCH_TAG.getParamName(1),message.getBatchId()); + namedParameters[i].addValue(QueryType.CONNECT_BATCH_TAG.getParamName(2),tags[i]); + } + + jdbcTemplate.batchUpdate(sql,namedParameters); + + return BoolMsg.newBuilder().setValue(true).build(); + } + + @Override + public BoolMsg postBatchMessage(BatchMessage batchMessage) { + + // Check if batch is closed + if (isBatchClosed(batchMessage.getSignerId(), batchMessage.getBatchId())) { + return BoolMsg.newBuilder().setValue(false).build(); + } + + // Add data + String sql = sqlQueryProvider.getSQLString(QueryType.INSERT_BATCH_DATA); + MapSqlParameterSource namedParameters = new MapSqlParameterSource(); + + namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(0),batchMessage.getSignerId()); + namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(1),batchMessage.getBatchId()); + namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(2),batchMessage.getSerialNum()); + namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(3),batchMessage.getData()); + + jdbcTemplate.update(sql, namedParameters); + + return BoolMsg.newBuilder().setValue(true).build(); + + } + + @Override + public BoolMsg closeBatchMessage(CloseBatchMessage message) throws CommunicationException { + + // Check batch size + + String sql = sqlQueryProvider.getSQLString(QueryType.CHECK_BATCH_LENGTH); + MapSqlParameterSource namedParameters = new MapSqlParameterSource(); + + namedParameters.addValue(QueryType.CHECK_BATCH_LENGTH.getParamName(0),message.getSig().getSignerId()); + namedParameters.addValue(QueryType.CHECK_BATCH_LENGTH.getParamName(1),message.getBatchId()); + + List lengthResult = jdbcTemplate.query(sql, namedParameters, new LongMapper()); + + if (lengthResult.get(0) != message.getBatchLength()) { + return BoolMsg.newBuilder().setValue(false).build(); + } + + // Check signature + + sql = sqlQueryProvider.getSQLString(QueryType.GET_BATCH_MESSAGE_DATA); + namedParameters = new MapSqlParameterSource(); + + namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(0),message.getSig().getSignerId()); + namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1),message.getBatchId()); + namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(2),0); // Read from the beginning + + List batchDataList = jdbcTemplate.query(sql, namedParameters, new BatchDataMapper()); + + try { + signer.initVerify(message.getSig()); + } catch (CertificateException | InvalidKeyException e) { + return BoolMsg.newBuilder().setValue(false).build(); + } + + //TODO: FInish this + + //signer.updateContent(msgStream); + //assertTrue("Signature did not verify!", signer.verify()); + + return null; + } + + @Override + public List readBatch(BatchSpecificationMessage message) { + return null; // TODO: Implement this + } + @Override public void close() {} diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java index c00c044..0093bd5 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java @@ -5,6 +5,7 @@ import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer.SQLQueryProvider; import meerkat.protobuf.BulletinBoardAPI.FilterType; import javax.sql.DataSource; +import java.text.MessageFormat; import java.util.LinkedList; import java.util.List; @@ -32,21 +33,72 @@ public class MySQLQueryProvider implements SQLQueryProvider { public String getSQLString(QueryType queryType) throws IllegalArgumentException{ switch(queryType) { + case ADD_SIGNATURE: - return "INSERT IGNORE INTO SignatureTable (EntryNum, SignerId, Signature) VALUES (:EntryNum, :SignerId, :Signature)"; + return MessageFormat.format( + "INSERT IGNORE INTO SignatureTable (EntryNum, SignerId, Signature) VALUES ({0}, {1}, {2})", + QueryType.ADD_SIGNATURE.getParamName(0), + QueryType.ADD_SIGNATURE.getParamName(1), + QueryType.ADD_SIGNATURE.getParamName(2)); + case CONNECT_TAG: - return "INSERT IGNORE INTO MsgTagTable (TagId, EntryNum)" - + " SELECT TagTable.TagId, :EntryNum AS EntryNum FROM TagTable WHERE Tag = :Tag"; + return MessageFormat.format( + "INSERT IGNORE INTO MsgTagTable (TagId, EntryNum)" + + " SELECT TagTable.TagId, {0} AS EntryNum FROM TagTable WHERE Tag = {1}", + QueryType.CONNECT_TAG.getParamName(0), + QueryType.CONNECT_TAG.getParamName(1)); + case FIND_MSG_ID: - return "SELECT EntryNum From MsgTable WHERE MsgId = :MsgId"; + return MessageFormat.format( + "SELECT EntryNum From MsgTable WHERE MsgId = {0}", + QueryType.FIND_MSG_ID.getParamName(0)); + case GET_MESSAGES: return "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable"; + case GET_SIGNATURES: - return "SELECT Signature FROM SignatureTable WHERE EntryNum = :EntryNum"; + return MessageFormat.format( + "SELECT Signature FROM SignatureTable WHERE EntryNum = {0}", + QueryType.GET_SIGNATURES.getParamName(0)); + case INSERT_MSG: - return "INSERT INTO MsgTable (MsgId, Msg) VALUES(:MsgId, :Msg)"; + return MessageFormat.format( + "INSERT INTO MsgTable (MsgId, Msg) VALUES({0}, {1})", + QueryType.INSERT_MSG.getParamName(0), + QueryType.INSERT_MSG.getParamName(1)); + case INSERT_NEW_TAG: - return "INSERT IGNORE INTO TagTable(Tag) VALUES (:Tag)"; + return MessageFormat.format( + "INSERT IGNORE INTO TagTable(Tag) VALUES ({0})", + QueryType.INSERT_NEW_TAG.getParamName(0)); + + case GET_BATCH_MESSAGE_ENTRY: + return MessageFormat.format( + "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable" + + "INNER JOIN SignatureTable ON MsgTable.EntryNum = SignatureTable.EntryNum" + + "INNER JOIN MsgTagTable ON MsgTable.EntryNum = MsgTagTable.EntryNum" + + "INNER JOIN TagTable ON MsgTagTable.TagId = TagTable.TagId" + + "WHERE SignatureTable.SignerId = {0}" + + "AND TagTable.Tag = {1}", + QueryType.GET_BATCH_MESSAGE_ENTRY.getParamName(0), + QueryType.GET_BATCH_MESSAGE_ENTRY.getParamName(1)); + + case GET_BATCH_MESSAGE_DATA: + return MessageFormat.format( + "SELECT Data FROM BatchTable" + + " WHERE SignerId = {0} AND BatchId = {1} AND SerialNum >= {2}" + + " ORDER BY SerialNum ASC", + QueryType.GET_BATCH_MESSAGE_DATA.getParamName(0), + QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1), + QueryType.GET_BATCH_MESSAGE_DATA.getParamName(2)); + + case CHECK_BATCH_LENGTH: + return MessageFormat.format( + "SELECT COUNT(Data) AS BatchLength FROM BatchTable" + + " WHERE SignerId = {0} AND BatchId = {1}", + QueryType.GET_BATCH_MESSAGE_DATA.getParamName(0), + QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1)); + default: throw new IllegalArgumentException("Cannot serve a query of type " + queryType); } @@ -119,7 +171,8 @@ public class MySQLQueryProvider implements SQLQueryProvider { public List getSchemaCreationCommands() { List list = new LinkedList(); - list.add("CREATE TABLE IF NOT EXISTS MsgTable (EntryNum INT NOT NULL AUTO_INCREMENT PRIMARY KEY, MsgId TINYBLOB, Msg BLOB, UNIQUE(MsgId(50)))"); + list.add("CREATE TABLE IF NOT EXISTS MsgTable (EntryNum INT NOT NULL AUTO_INCREMENT PRIMARY KEY," + + " MsgId TINYBLOB, Msg BLOB, UNIQUE(MsgId(50)))"); list.add("CREATE TABLE IF NOT EXISTS TagTable (TagId INT NOT NULL AUTO_INCREMENT PRIMARY KEY, Tag VARCHAR(50), UNIQUE(Tag))"); @@ -129,7 +182,14 @@ public class MySQLQueryProvider implements SQLQueryProvider { + " CONSTRAINT UNIQUE (EntryNum, TagID))"); list.add("CREATE TABLE IF NOT EXISTS SignatureTable (EntryNum INT, SignerId TINYBLOB, Signature TINYBLOB," - + " INDEX(SignerId(32)), CONSTRAINT Uni UNIQUE(SignerId(32), EntryNum), CONSTRAINT FOREIGN KEY (EntryNum) REFERENCES MsgTable(EntryNum))"); + + " INDEX(SignerId(32)), CONSTRAINT Unique_Signature UNIQUE(SignerId(32), EntryNum)," + + " CONSTRAINT FOREIGN KEY (EntryNum) REFERENCES MsgTable(EntryNum))"); + + list.add("CREATE TABLE IF NOT EXISTS BatchTable (SignerId TINYBLOB, BatchId INT, SerialNum INT, Data BLOB," + + " CONSTRAINT Unique_Batch UNIQUE(SignerId(32), BatchId, SerialNum))"); + + list.add("CREATE TABLE IF NOT EXISTS BatchTagTable (SignerId TINYBLOB, BatchId INT, TagId INT," + + " INDEX(SignerId, BatchId), CONSTRAINT FOREIGN KEY (TagId) REFERENCES TagTable(TagId))"); return list; } @@ -138,6 +198,8 @@ public class MySQLQueryProvider implements SQLQueryProvider { public List getSchemaDeletionCommands() { List list = new LinkedList(); + list.add("DROP TABLE IF EXISTS BatchTagTable"); + list.add("DROP TABLE IF EXISTS BatchTable"); list.add("DROP TABLE IF EXISTS MsgTagTable"); list.add("DROP TABLE IF EXISTS SignatureTable"); list.add("DROP TABLE IF EXISTS TagTable"); diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/BatchDataMapper.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/BatchDataMapper.java new file mode 100644 index 0000000..0189584 --- /dev/null +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/BatchDataMapper.java @@ -0,0 +1,21 @@ +package meerkat.bulletinboard.sqlserver.mappers; + +import com.google.protobuf.ByteString; +import meerkat.protobuf.BulletinBoardAPI.BatchData; +import org.springframework.jdbc.core.RowMapper; + +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * Created by Arbel Deutsch Peled on 19-Dec-15. + */ +public class BatchDataMapper implements RowMapper { + + @Override + public BatchData mapRow(ResultSet rs, int rowNum) throws SQLException { + + return BatchData.newBuilder().setData(ByteString.copyFrom(rs.getBytes(rowNum))).build(); + + } +} diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/EntryNumMapper.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/LongMapper.java similarity index 87% rename from bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/EntryNumMapper.java rename to bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/LongMapper.java index 478c39e..1ec0d98 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/EntryNumMapper.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/LongMapper.java @@ -9,7 +9,7 @@ import java.sql.SQLException; /** * Created by Arbel Deutsch Peled on 11-Dec-15. */ -public class EntryNumMapper implements RowMapper { +public class LongMapper implements RowMapper { @Override public Long mapRow(ResultSet rs, int rowNum) throws SQLException { diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java index b3fc03c..27d7bd5 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java @@ -17,12 +17,11 @@ import meerkat.bulletinboard.sqlserver.H2QueryProvider; import meerkat.bulletinboard.sqlserver.MySQLQueryProvider; import meerkat.bulletinboard.sqlserver.SQLiteQueryProvider; import meerkat.comm.CommunicationException; -import meerkat.protobuf.BulletinBoardAPI.BoolMsg; -import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; -import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessageList; -import meerkat.protobuf.BulletinBoardAPI.MessageFilterList; +import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.rest.Constants; +import java.util.List; + @Path(Constants.BULLETIN_BOARD_SERVER_PATH) public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextListener{ @@ -99,6 +98,58 @@ public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextL return bulletinBoard.readMessages(filterList); } + @Path(Constants.BEGIN_BATCH_PATH) + @POST + @Consumes(Constants.MEDIATYPE_PROTOBUF) + @Produces(Constants.MEDIATYPE_PROTOBUF) + @Override + public BoolMsg beginBatch(BeginBatchMessage message) { + try { + return bulletinBoard.beginBatch(message); + } catch (CommunicationException e) { + System.err.println(e.getMessage()); + return null; + } + } + + @Path(Constants.POST_BATCH_PATH) + @POST + @Consumes(Constants.MEDIATYPE_PROTOBUF) + @Produces(Constants.MEDIATYPE_PROTOBUF) + @Override + public BoolMsg postBatchMessage(BatchMessage batchMessage) { + try { + return bulletinBoard.postBatchMessage(batchMessage); + } catch (CommunicationException e) { + System.err.println(e.getMessage()); + return null; + } + } + + @Path(Constants.CLOSE_BATCH_PATH) + @POST + @Consumes(Constants.MEDIATYPE_PROTOBUF) + @Produces(Constants.MEDIATYPE_PROTOBUF) + @Override + public BoolMsg closeBatchMessage(CloseBatchMessage message) { + try { + return bulletinBoard.closeBatchMessage(message); + } catch (CommunicationException e) { + System.err.println(e.getMessage()); + return null; + } + } + + @Override + public List readBatch(BatchSpecificationMessage message) { + try { + return bulletinBoard.readBatch(message); + } catch (CommunicationException | IllegalArgumentException e) { + System.err.println(e.getMessage()); + return null; + } + } + @Override public void close(){ try { diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java b/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java index 04b7a06..4d8075e 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java @@ -9,13 +9,22 @@ import java.util.List; */ public interface AsyncBulletinBoardClient extends BulletinBoardClient { + public interface ClientCallback { + void handleCallback(T msg); + void handleFailure(Throwable t); + } + + public interface MessageHandler { + void handleNewMessages(List messageList); + } + /** * Post a message to the bulletin board in an asynchronous manner * @param msg is the message to be posted * @param callback is a class containing methods to handle the result of the operation * @return a unique message ID for the message, that can be later used to retrieve the batch */ - MessageID postMessage(BulletinBoardMessage msg, ClientCallback callback); + public MessageID postMessage(BulletinBoardMessage msg, ClientCallback callback); /** * This method allows for sending large messages as a batch to the bulletin board @@ -26,12 +35,12 @@ public interface AsyncBulletinBoardClient extends BulletinBoardClient { * @param callback is a callback function class for handling results of the operation * @return a unique message ID for the entire message, that can be later used to retrieve the batch */ - MessageID postBatch(byte[] signerId, int batchId, List batchDataList, int startPosition, ClientCallback callback); + public MessageID postBatch(byte[] signerId, int batchId, List batchDataList, int startPosition, ClientCallback callback); /** * Overloading of the postBatch method in which startPosition is set to the default value 0 */ - MessageID postBatch(byte[] signerId, int batchId, List batchDataList, ClientCallback callback); + public MessageID postBatch(byte[] signerId, int batchId, List batchDataList, ClientCallback callback); /** * Check how "safe" a given message is in an asynchronous manner @@ -39,7 +48,7 @@ public interface AsyncBulletinBoardClient extends BulletinBoardClient { * @param id is the unique message identifier for retrieval * @param callback is a callback function class for handling results of the operation */ - void getRedundancy(MessageID id, ClientCallback callback); + public void getRedundancy(MessageID id, ClientCallback callback); /** * Read all messages posted matching the given filter in an asynchronous manner @@ -49,7 +58,7 @@ public interface AsyncBulletinBoardClient extends BulletinBoardClient { * @param filterList return only messages that match the filters (null means no filtering). * @param callback is a callback function class for handling results of the operation */ - void readMessages(MessageFilterList filterList, ClientCallback> callback); + public void readMessages(MessageFilterList filterList, ClientCallback> callback); /** * Read a given batch message from the bulletin board @@ -57,6 +66,13 @@ public interface AsyncBulletinBoardClient extends BulletinBoardClient { * @param batchId is the unique (per signer) ID of the batch * @param callback is a callback class for handling the result of the operation */ - void readBatch(byte[] signerId, int batchId, ClientCallback callback); + public void readBatch(byte[] signerId, int batchId, ClientCallback callback); + + /** + * Subscribes to a notifier that will return any new messages on the server that match the given filters + * @param filterList defines the set of filters for message retrieval + * @param messageHandler defines the handler for new messages received + */ + public void subscribe(MessageFilterList filterList, MessageHandler messageHandler); } diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardClient.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardClient.java index dcf6b15..2f5a3df 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardClient.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardClient.java @@ -12,11 +12,6 @@ import java.util.List; */ public interface BulletinBoardClient { - interface ClientCallback { - void handleCallback(T msg); - void handleFailure(Throwable t); - } - /** * Initialize the client to use some specified servers * @param clientParams contains the parameters required for the client setup diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java index da53c1f..70721a7 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java @@ -3,40 +3,83 @@ package meerkat.bulletinboard; import meerkat.comm.CommunicationException; import meerkat.protobuf.BulletinBoardAPI.*; +import java.util.List; + /** * Created by Arbel on 07/11/15. * - * This interface refers to a single instance of a Bulletin Board. - * An implementation of this interface may use any DB and be hosted on any machine. + * This interface refers to a single instance of a Bulletin Board + * An implementation of this interface may use any DB and be hosted on any machine. */ public interface BulletinBoardServer{ /** - * This method initializes the server by reading the signature data and storing it. - * It also establishes the connection to the DB. - * @throws CommunicationException on DB connection error. + * This method initializes the server by reading the signature data and storing it + * It also establishes the connection to the DB + * @throws CommunicationException on DB connection error */ public void init(String meerkatDB) throws CommunicationException; /** * Post a message to bulletin board. * @param msg is the actual (signed) message - * @return TRUE if the message has been authenticated and FALSE otherwise (in ProtoBuf form). - * @throws CommunicationException on DB connection error. + * @return TRUE if the message has been authenticated and FALSE otherwise (in ProtoBuf form) + * @throws CommunicationException on DB connection error */ - public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException; + public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException; /** - * Read all messages posted matching the given filter. - * @param filter return only messages that match the filter (empty list means no filtering). + * Read all messages posted matching the given filter + * @param filterList return only messages that match the filters (empty list or null means no filtering) * @return + * @throws CommunicationException on DB connection error */ - BulletinBoardMessageList readMessages(MessageFilterList filterList) throws CommunicationException; - + public BulletinBoardMessageList readMessages(MessageFilterList filterList) throws CommunicationException; + + /** + * Informs server about a new batch message + * @param message contains the required data about the new batch + * @return TRUE if the batch request is accepted amd FALSE otherwise + * Specifically, if such a batch already exists and is not yet closed: the value returned will be TRUE + * However, if such a batch exists and is already closed: the value returned will be FALSE + * @throws CommunicationException on DB connection error + */ + public BoolMsg beginBatch(BeginBatchMessage message) throws CommunicationException; + + /** + * Posts a (part of a) batch message to the bulletin board + * Note that the existence and contents of a batch message are not available for reading before the batch is finalized + * @param batchMessage contains the (partial) data this message carries as well as meta-data required in order to place the data + * in the correct position inside the correct batch + * @return TRUE if the message is accepted and successfully saved and FALSE otherwise + * Specifically, if the batch is already closed: the value returned will be FALSE + * However, requiring to open a batch before insertion of messages is implementation-dependent + * @throws CommunicationException on DB connection error + */ + public BoolMsg postBatchMessage(BatchMessage batchMessage) throws CommunicationException; + + /** + * Attempts to close and finalize a batch message + * @param message contains the data necessary to close the batch; in particular: the signature for the batch + * @return TRUE if the batch was successfully closed, FALSE otherwise + * Specifically, if the signature is invalid or if some of the batch parts have not yet been submitted: the value returned will be FALSE + * @throws CommunicationException on DB connection error + */ + public BoolMsg closeBatchMessage(CloseBatchMessage message) throws CommunicationException; + + /** + * Reads a batch message from the server (starting with the supplied position) + * @param message specifies the signer ID and the batch ID to read as well as an (optional) start position + * @return an ordered list of batch messages starting from the specified start position (if given) or from the beginning (if omitted) + * @throws CommunicationException on DB connection error + * @throws IllegalArgumentException if message does not specify a batch + */ + public List readBatch(BatchSpecificationMessage message) throws CommunicationException, IllegalArgumentException; + /** - * This method closes the connection to the DB. - * @throws CommunicationException on DB connection error. + * This method closes the connection to the DB + * @throws CommunicationException on DB connection error */ - public void close() throws CommunicationException; + public void close() throws CommunicationException; } diff --git a/meerkat-common/src/main/java/meerkat/crypto/BatchDigest.java b/meerkat-common/src/main/java/meerkat/crypto/BatchDigest.java new file mode 100644 index 0000000..ff257b2 --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/crypto/BatchDigest.java @@ -0,0 +1,20 @@ +package meerkat.crypto; + +import meerkat.protobuf.BulletinBoardAPI.*; + +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 18-Dec-15. + * Extends the Digest interface with a method for digesting Batch messages + */ +public interface BatchDigest extends Digest{ + + /** + * Update the digest with the + * @param beginBatchMessage is the message that starts the batch + * @param batchDataList is the (ordered) list of data in the batch + */ + public void update(BeginBatchMessage beginBatchMessage, List batchDataList); + +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/Digest.java b/meerkat-common/src/main/java/meerkat/crypto/Digest.java index 06b012c..c72206e 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/Digest.java +++ b/meerkat-common/src/main/java/meerkat/crypto/Digest.java @@ -13,7 +13,7 @@ public interface Digest { * (copied from {@link MessageDigest#digest()}) * @return */ - byte[] digest(); + public byte[] digest(); /** * Updates the digest using the specified message (in serialized wire form) @@ -22,12 +22,12 @@ public interface Digest { * @param msg * @return */ - void update(Message msg); + public void update(Message msg); /** * Resets the digest for further use. */ - void reset(); + public void reset(); /** * Clone the current digest state diff --git a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java index 887b8e8..28e4600 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java @@ -30,7 +30,10 @@ import javax.security.auth.callback.UnsupportedCallbackException; * * This class is not thread-safe (each thread should have its own instance). */ -public class ECDSASignature extends GlobalCryptoSetup implements DigitalSignature { +public class ECDSASignature implements DigitalSignature { + + private static GlobalCryptoSetup globalCryptoSetup = GlobalCryptoSetup.getInstance(); + final Logger logger = LoggerFactory.getLogger(getClass()); final public static String KEYSTORE_TYPE = "PKCS12"; diff --git a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java index f9936c7..98d32bf 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java @@ -31,7 +31,10 @@ import java.util.Random; /** * Created by talm on 17/11/15. */ -public class ECElGamalEncryption extends GlobalCryptoSetup implements Encryption { +public class ECElGamalEncryption implements Encryption { + + private static GlobalCryptoSetup globalCryptoSetup = GlobalCryptoSetup.getInstance(); + final Logger logger = LoggerFactory.getLogger(getClass()); public final static String KEY_ALGORITHM = "ECDH"; diff --git a/meerkat-common/src/main/java/meerkat/crypto/concrete/GenericBatchDigest.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/GenericBatchDigest.java new file mode 100644 index 0000000..38b2192 --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/GenericBatchDigest.java @@ -0,0 +1,27 @@ +package meerkat.crypto.concrete; + +import com.google.protobuf.Message; +import meerkat.crypto.BatchDigest; +import meerkat.protobuf.BulletinBoardAPI.*; + +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 19-Dec-15. + */ +public abstract class GenericBatchDigest implements BatchDigest{ + + + @Override + public void update(BeginBatchMessage beginBatchMessage, List batchDataList) { + update(beginBatchMessage); + for (BatchData batchData : batchDataList) { + update(batchData); + } + } + + @Override + // Repeated here to circumvent compiler error + public abstract BatchDigest clone() throws CloneNotSupportedException; + +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/concrete/GlobalCryptoSetup.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/GlobalCryptoSetup.java index 4f2e7a5..3d12701 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/concrete/GlobalCryptoSetup.java +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/GlobalCryptoSetup.java @@ -10,13 +10,26 @@ import java.security.Security; /** * A class that performs required crypto setup */ -public class GlobalCryptoSetup { +public final class GlobalCryptoSetup { + + private static GlobalCryptoSetup globalCryptoSetup; + final static Logger logger = LoggerFactory.getLogger(GlobalCryptoSetup.class); - static boolean loadedBouncyCastle = false; - static Provider bouncyCastleProvider; + private boolean loadedBouncyCastle = false; + private Provider bouncyCastleProvider; - public static boolean hasSecp256k1Curve() { + private GlobalCryptoSetup() { doSetup(); } + + public static GlobalCryptoSetup getInstance() { + if (globalCryptoSetup == null) { + globalCryptoSetup = new GlobalCryptoSetup(); + } + + return globalCryptoSetup; + } + + public boolean hasSecp256k1Curve() { // For now we just check if the java version is at least 8 String[] version = System.getProperty("java.version").split("\\."); int major = Integer.parseInt(version[0]); @@ -24,9 +37,11 @@ public class GlobalCryptoSetup { return ((major > 1) || ((major > 0) && (minor > 7))); } - public static Provider getBouncyCastleProvider() { doSetup(); return bouncyCastleProvider; } + public Provider getBouncyCastleProvider() { + return bouncyCastleProvider; + } - public static synchronized void doSetup() { + public void doSetup() { if (bouncyCastleProvider == null) { bouncyCastleProvider = new BouncyCastleProvider(); // Make bouncycastle our default provider if we're running on a JVM version < 8 @@ -39,5 +54,4 @@ public class GlobalCryptoSetup { } } - public GlobalCryptoSetup() { doSetup(); } } diff --git a/meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java index 4f60af3..ac58f3a 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java @@ -2,6 +2,7 @@ package meerkat.crypto.concrete; import com.google.protobuf.ByteString; import com.google.protobuf.Message; +import meerkat.crypto.BatchDigest; import meerkat.crypto.Digest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -13,7 +14,7 @@ import java.security.NoSuchAlgorithmException; /** * Created by talm on 11/9/15. */ -public class SHA256Digest extends GlobalCryptoSetup implements Digest { +public class SHA256Digest extends GenericBatchDigest { final Logger logger = LoggerFactory.getLogger(getClass()); public static final String SHA256 = "SHA-256"; diff --git a/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto b/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto index 1a0bab1..2ae4068 100644 --- a/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto +++ b/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto @@ -104,4 +104,11 @@ message BatchMessage { int32 batchId = 2; // Unique identifier for the batch (unique per signer) int32 serialNum = 3; // Location of the message in the batch: starting from 0 BatchData data = 4; // Actual data +} + +// This message defines which batch to read and from which location to start reading +message BatchSpecificationMessage { + bytes signerId = 1; // Unique signer identifier + int32 batchId = 2; // Unique identifier for the batch (unique per signer) + int32 startPosition = 3; // Position in batch to start reading from } \ No newline at end of file diff --git a/meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalUtils.java b/meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalUtils.java index 66e1647..e57c817 100644 --- a/meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalUtils.java +++ b/meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalUtils.java @@ -26,6 +26,9 @@ import java.security.spec.InvalidKeySpecException; * utilities for ECElgamal */ public class ECElGamalUtils { + + private static GlobalCryptoSetup globalCryptoSetup = GlobalCryptoSetup.getInstance(); + final static Logger logger = LoggerFactory.getLogger(ECElGamalUtils.class); public final static String ENCRYPTION_KEY_ALGORITHM = "ECDH"; @@ -43,7 +46,7 @@ public class ECElGamalUtils { try { KeyFactory fact = KeyFactory.getInstance(ENCRYPTION_KEY_ALGORITHM, - GlobalCryptoSetup.getBouncyCastleProvider()); + globalCryptoSetup.getBouncyCastleProvider()); PublicKey javaPk = fact.generatePublic(pubKeySpec); ConcreteCrypto.ElGamalPublicKey serializedPk = ConcreteCrypto.ElGamalPublicKey.newBuilder() .setSubjectPublicKeyInfo(ByteString.copyFrom(javaPk.getEncoded())).build(); diff --git a/restful-api-common/src/main/java/meerkat/rest/Constants.java b/restful-api-common/src/main/java/meerkat/rest/Constants.java index 73ed7d1..8215641 100644 --- a/restful-api-common/src/main/java/meerkat/rest/Constants.java +++ b/restful-api-common/src/main/java/meerkat/rest/Constants.java @@ -9,4 +9,8 @@ public interface Constants { public static final String BULLETIN_BOARD_SERVER_PATH = "/bbserver"; public static final String READ_MESSAGES_PATH = "/readmessages"; public static final String POST_MESSAGE_PATH = "/postmessage"; + public static final String BEGIN_BATCH_PATH = "/beginbatch"; + public static final String POST_BATCH_PATH = "/postbatch"; + public static final String CLOSE_BATCH_PATH = "/closebatch"; + } From b5237d6c9f32b3946cb760bd2ffabe2ed1706dcb Mon Sep 17 00:00:00 2001 From: Arbel Deutsch Peled Date: Mon, 21 Dec 2015 23:16:06 +0200 Subject: [PATCH 04/49] Implemented (untested) batch messages in Bulletin Board Server (MySQL implementation only). Implemented generic batch message signatures and digests. Created new interface for Bulletin Board constants. --- .../bulletinboard/BulletinClientWorker.java | 9 +- .../SimpleBulletinBoardClient.java | 8 +- .../ThreadedBulletinBoardClient.java | 2 +- .../sqlserver/BulletinBoardSQLServer.java | 117 ++++++++++++++---- .../sqlserver/MySQLQueryProvider.java | 46 +++++-- .../sqlserver/mappers/BatchDataMapper.java | 2 +- .../sqlserver/mappers/StringMapper.java | 18 +++ .../webapp/BulletinBoardWebApp.java | 35 +++--- ...BulletinBoardSQLServerIntegrationTest.java | 9 +- .../AsyncBulletinBoardClient.java | 2 +- .../meerkat/bulletinboard/BatchDigest.java | 20 +++ .../bulletinboard/BatchDigitalSignature.java | 34 +++++ .../bulletinboard/BulletinBoardConstants.java | 21 ++++ .../{SignedBatch.java => CompleteBatch.java} | 26 ++-- .../bulletinboard/GenericBatchDigest.java | 54 ++++++++ .../GenericBatchDigitalSignature.java | 95 ++++++++++++++ .../main/java/meerkat/crypto/BatchDigest.java | 20 --- .../crypto/concrete/GenericBatchDigest.java | 27 ---- .../meerkat/crypto/concrete/SHA256Digest.java | 3 +- .../src/main/java/meerkat/rest/Constants.java | 8 -- 20 files changed, 428 insertions(+), 128 deletions(-) create mode 100644 bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/StringMapper.java create mode 100644 meerkat-common/src/main/java/meerkat/bulletinboard/BatchDigest.java create mode 100644 meerkat-common/src/main/java/meerkat/bulletinboard/BatchDigitalSignature.java create mode 100644 meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardConstants.java rename meerkat-common/src/main/java/meerkat/bulletinboard/{SignedBatch.java => CompleteBatch.java} (50%) create mode 100644 meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigest.java create mode 100644 meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigitalSignature.java delete mode 100644 meerkat-common/src/main/java/meerkat/crypto/BatchDigest.java delete mode 100644 meerkat-common/src/main/java/meerkat/crypto/concrete/GenericBatchDigest.java diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java index 51599d5..f03ab31 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java @@ -8,6 +8,7 @@ import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.rest.Constants; import meerkat.rest.ProtobufMessageBodyReader; import meerkat.rest.ProtobufMessageBodyWriter; +import static meerkat.bulletinboard.BulletinBoardConstants.*; import javax.ws.rs.ProcessingException; import javax.ws.rs.client.Client; @@ -101,7 +102,7 @@ public class BulletinClientWorker implements Callable { } msg = payload; - requestPath = Constants.POST_MESSAGE_PATH; + requestPath = POST_MESSAGE_PATH; break; case READ_MESSAGES: @@ -111,7 +112,7 @@ public class BulletinClientWorker implements Callable { } msg = payload; - requestPath = Constants.READ_MESSAGES_PATH; + requestPath = READ_MESSAGES_PATH; break; case GET_REDUNDANCY: @@ -120,7 +121,7 @@ public class BulletinClientWorker implements Callable { throw new IllegalArgumentException("Cannot search for an object that is not an instance of MessageID"); } - requestPath = Constants.READ_MESSAGES_PATH; + requestPath = READ_MESSAGES_PATH; msg = MessageFilterList.newBuilder() .addFilter(MessageFilter.newBuilder() @@ -144,7 +145,7 @@ public class BulletinClientWorker implements Callable { // Send request to Server String address = addressIterator.next(); - webTarget = client.target(address).path(Constants.BULLETIN_BOARD_SERVER_PATH).path(requestPath); + webTarget = client.target(address).path(BULLETIN_BOARD_SERVER_PATH).path(requestPath); response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(msg, Constants.MEDIATYPE_PROTOBUF)); // Retrieve answer diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java index 4244f15..8cac04d 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java @@ -16,6 +16,8 @@ import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.Response; +import static meerkat.bulletinboard.BulletinBoardConstants.*; + /** * Created by Arbel Deutsch Peled on 05-Dec-15. * Implements BulletinBoardClient interface in a simple, straightforward manner @@ -61,7 +63,7 @@ public class SimpleBulletinBoardClient implements BulletinBoardClient{ // Post message to all databases try { for (String db : meerkatDBs) { - webTarget = client.target(db).path(Constants.BULLETIN_BOARD_SERVER_PATH).path(Constants.POST_MESSAGE_PATH); + webTarget = client.target(db).path(BULLETIN_BOARD_SERVER_PATH).path(POST_MESSAGE_PATH); response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(msg, Constants.MEDIATYPE_PROTOBUF)); // Only consider valid responses @@ -104,7 +106,7 @@ public class SimpleBulletinBoardClient implements BulletinBoardClient{ for (String db : meerkatDBs) { try { - webTarget = client.target(db).path(Constants.BULLETIN_BOARD_SERVER_PATH).path(Constants.READ_MESSAGES_PATH); + webTarget = client.target(db).path(BULLETIN_BOARD_SERVER_PATH).path(READ_MESSAGES_PATH); response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(filterList, Constants.MEDIATYPE_PROTOBUF)); @@ -138,7 +140,7 @@ public class SimpleBulletinBoardClient implements BulletinBoardClient{ for (String db : meerkatDBs) { try { - webTarget = client.target(db).path(Constants.BULLETIN_BOARD_SERVER_PATH).path(Constants.READ_MESSAGES_PATH); + webTarget = client.target(db).path(BULLETIN_BOARD_SERVER_PATH).path(READ_MESSAGES_PATH); response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(filterList, Constants.MEDIATYPE_PROTOBUF)); diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java index 5953bde..71d852e 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java @@ -113,7 +113,7 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple } @Override - public void readBatch(byte[] signerId, int batchId, ClientCallback callback) { + public void readBatch(byte[] signerId, int batchId, ClientCallback callback) { // TODO: Implement } diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java index 5f9b461..1bb32d8 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java @@ -1,6 +1,7 @@ package meerkat.bulletinboard.sqlserver; import java.security.InvalidKeyException; +import java.security.SignatureException; import java.security.cert.CertificateException; import java.sql.*; import java.util.*; @@ -8,13 +9,12 @@ import java.util.*; import com.google.protobuf.ByteString; import com.google.protobuf.ProtocolStringList; -import meerkat.bulletinboard.BulletinBoardServer; +import meerkat.bulletinboard.*; import meerkat.bulletinboard.sqlserver.mappers.*; +import static meerkat.bulletinboard.BulletinBoardConstants.*; import meerkat.comm.CommunicationException; -import meerkat.crypto.BatchDigest; -import meerkat.crypto.DigitalSignature; import meerkat.crypto.concrete.ECDSASignature; import meerkat.crypto.concrete.SHA256Digest; @@ -62,7 +62,9 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ CHECK_BATCH_LENGTH(new String[] {"SignerId", "BatchId"}), GET_BATCH_MESSAGE_DATA(new String[] {"SignerId", "BatchId", "StartPosition"}), INSERT_BATCH_DATA(new String[] {"SignerId", "BatchId", "SerialNum", "Data"}), - CONNECT_BATCH_TAG(new String[] {"SignerId", "BatchId", "Tag"}); + CONNECT_BATCH_TAG(new String[] {"SignerId", "BatchId", "Tag"}), + GET_BATCH_TAGS(new String[] {"SignerId", "BatchId"}), + MOVE_BATCH_TAGS(new String[] {"EntryNum", "SignerId", "BatchId"}); private String[] paramNames; @@ -219,7 +221,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ protected NamedParameterJdbcTemplate jdbcTemplate; protected BatchDigest digest; - protected DigitalSignature signer; + protected BatchDigitalSignature signer; protected List trusteeSignatureVerificationArray; protected int minTrusteeSignatures; @@ -257,8 +259,8 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ public void init(String meerkatDB) throws CommunicationException { // TODO write signature reading part. - digest = new SHA256Digest(); - signer = new ECDSASignature(); + digest = new GenericBatchDigest(new SHA256Digest()); + signer = new GenericBatchDigitalSignature(new ECDSASignature()); jdbcTemplate = new NamedParameterJdbcTemplate(sqlQueryProvider.getDataSource()); @@ -356,7 +358,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ } else{ sql = sqlQueryProvider.getSQLString(QueryType.INSERT_MSG); - namedParameters.put(QueryType.INSERT_MSG.getParamName(0), msg.getMsg().toByteArray()); + namedParameters.put(QueryType.INSERT_MSG.getParamName(1), msg.getMsg().toByteArray()); KeyHolder keyHolder = new GeneratedKeyHolder(); jdbcTemplate.update(sql,new MapSqlParameterSource(namedParameters),keyHolder); @@ -585,13 +587,19 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ @Override public BoolMsg closeBatchMessage(CloseBatchMessage message) throws CommunicationException { + ByteString signerId = message.getSig().getSignerId(); + int batchId = message.getBatchId(); + + KeyHolder keyHolder = new GeneratedKeyHolder(); + // Check batch size String sql = sqlQueryProvider.getSQLString(QueryType.CHECK_BATCH_LENGTH); MapSqlParameterSource namedParameters = new MapSqlParameterSource(); - namedParameters.addValue(QueryType.CHECK_BATCH_LENGTH.getParamName(0),message.getSig().getSignerId()); - namedParameters.addValue(QueryType.CHECK_BATCH_LENGTH.getParamName(1),message.getBatchId()); + + namedParameters.addValue(QueryType.CHECK_BATCH_LENGTH.getParamName(0),signerId); + namedParameters.addValue(QueryType.CHECK_BATCH_LENGTH.getParamName(1),batchId); List lengthResult = jdbcTemplate.query(sql, namedParameters, new LongMapper()); @@ -599,34 +607,99 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ return BoolMsg.newBuilder().setValue(false).build(); } - // Check signature + + // Get Tags and add them to CompleteBatch + + sql = sqlQueryProvider.getSQLString(QueryType.GET_BATCH_TAGS); + namedParameters = new MapSqlParameterSource(); + + namedParameters.addValue(QueryType.GET_BATCH_TAGS.getParamName(0),signerId); + namedParameters.addValue(QueryType.GET_BATCH_TAGS.getParamName(1),batchId); + + List tags = jdbcTemplate.query(sql, namedParameters, new StringMapper()); + + CompleteBatch completeBatch = new CompleteBatch( + BeginBatchMessage.newBuilder() + .setSignerId(signerId) + .setBatchId(batchId) + .addAllTag(tags) + .build() + ); + + // Add actual batch data to CompleteBatch sql = sqlQueryProvider.getSQLString(QueryType.GET_BATCH_MESSAGE_DATA); namedParameters = new MapSqlParameterSource(); - namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(0),message.getSig().getSignerId()); - namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1),message.getBatchId()); + namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(0),signerId); + namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1),batchId); namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(2),0); // Read from the beginning - List batchDataList = jdbcTemplate.query(sql, namedParameters, new BatchDataMapper()); + completeBatch.appendBatchData(jdbcTemplate.query(sql, namedParameters, new BatchDataMapper())); + + // Verify signature + + completeBatch.setSignature(message.getSig()); try { - signer.initVerify(message.getSig()); - } catch (CertificateException | InvalidKeyException e) { + signer.verify(completeBatch); + } catch (CertificateException | InvalidKeyException | SignatureException e) { return BoolMsg.newBuilder().setValue(false).build(); } - //TODO: FInish this + // Batch verified: finalize it - //signer.updateContent(msgStream); - //assertTrue("Signature did not verify!", signer.verify()); + // Calculate message ID + digest.reset(); + digest.update(completeBatch); + MessageID msgID = MessageID.newBuilder().setID(ByteString.copyFrom(digest.digest())).build(); - return null; + // Create Bulletin Board message + BulletinBoardMessage bulletinBoardMessage = BulletinBoardMessage.newBuilder() + .addSig(message.getSig()) + .setMsg(UnsignedBulletinBoardMessage.newBuilder() + .addAllTag(tags) + .addTag(BATCH_TAG) + .setData(message.getSig().getSignerId()) + .build()) + .build(); + + sql = sqlQueryProvider.getSQLString(QueryType.INSERT_MSG); + namedParameters = new MapSqlParameterSource(); + + namedParameters.addValue(QueryType.INSERT_MSG.getParamName(0), msgID); + namedParameters.addValue(QueryType.INSERT_MSG.getParamName(1), bulletinBoardMessage); + + jdbcTemplate.update(sql, namedParameters, keyHolder); + long entryNum = keyHolder.getKey().longValue(); + + sql = sqlQueryProvider.getSQLString(QueryType.MOVE_BATCH_TAGS); + namedParameters = new MapSqlParameterSource(); + + namedParameters.addValue(QueryType.MOVE_BATCH_TAGS.getParamName(0), entryNum); + namedParameters.addValue(QueryType.MOVE_BATCH_TAGS.getParamName(1), signerId); + namedParameters.addValue(QueryType.MOVE_BATCH_TAGS.getParamName(2), batchId); + + jdbcTemplate.update(sql, namedParameters); + + return BoolMsg.newBuilder().setValue(true).build(); } @Override - public List readBatch(BatchSpecificationMessage message) { - return null; // TODO: Implement this + public List readBatch(BatchSpecificationMessage message) throws CommunicationException, IllegalArgumentException{ + + // Check that batch is closed + if (!isBatchClosed(message.getSignerId(), message.getBatchId())) { + throw new IllegalArgumentException("No such batch"); + } + + String sql = sqlQueryProvider.getSQLString(QueryType.GET_BATCH_MESSAGE_DATA); + MapSqlParameterSource namedParameters = new MapSqlParameterSource(); + + namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(0),message.getSignerId()); + namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1),message.getBatchId()); + + return jdbcTemplate.query(sql, namedParameters, new BatchDataMapper()); } @Override diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java index 0093bd5..59e6106 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java @@ -36,7 +36,7 @@ public class MySQLQueryProvider implements SQLQueryProvider { case ADD_SIGNATURE: return MessageFormat.format( - "INSERT IGNORE INTO SignatureTable (EntryNum, SignerId, Signature) VALUES ({0}, {1}, {2})", + "INSERT IGNORE INTO SignatureTable (EntryNum, SignerId, Signature) VALUES (:{0}, :{1}, :{2})", QueryType.ADD_SIGNATURE.getParamName(0), QueryType.ADD_SIGNATURE.getParamName(1), QueryType.ADD_SIGNATURE.getParamName(2)); @@ -44,13 +44,13 @@ public class MySQLQueryProvider implements SQLQueryProvider { case CONNECT_TAG: return MessageFormat.format( "INSERT IGNORE INTO MsgTagTable (TagId, EntryNum)" - + " SELECT TagTable.TagId, {0} AS EntryNum FROM TagTable WHERE Tag = {1}", + + " SELECT TagTable.TagId, :{0} AS EntryNum FROM TagTable WHERE Tag = :{1}", QueryType.CONNECT_TAG.getParamName(0), QueryType.CONNECT_TAG.getParamName(1)); case FIND_MSG_ID: return MessageFormat.format( - "SELECT EntryNum From MsgTable WHERE MsgId = {0}", + "SELECT EntryNum From MsgTable WHERE MsgId = :{0}", QueryType.FIND_MSG_ID.getParamName(0)); case GET_MESSAGES: @@ -58,18 +58,18 @@ public class MySQLQueryProvider implements SQLQueryProvider { case GET_SIGNATURES: return MessageFormat.format( - "SELECT Signature FROM SignatureTable WHERE EntryNum = {0}", + "SELECT Signature FROM SignatureTable WHERE EntryNum = :{0}", QueryType.GET_SIGNATURES.getParamName(0)); case INSERT_MSG: return MessageFormat.format( - "INSERT INTO MsgTable (MsgId, Msg) VALUES({0}, {1})", + "INSERT INTO MsgTable (MsgId, Msg) VALUES(:{0}, :{1})", QueryType.INSERT_MSG.getParamName(0), QueryType.INSERT_MSG.getParamName(1)); case INSERT_NEW_TAG: return MessageFormat.format( - "INSERT IGNORE INTO TagTable(Tag) VALUES ({0})", + "INSERT IGNORE INTO TagTable(Tag) VALUES (:{0})", QueryType.INSERT_NEW_TAG.getParamName(0)); case GET_BATCH_MESSAGE_ENTRY: @@ -78,15 +78,15 @@ public class MySQLQueryProvider implements SQLQueryProvider { + "INNER JOIN SignatureTable ON MsgTable.EntryNum = SignatureTable.EntryNum" + "INNER JOIN MsgTagTable ON MsgTable.EntryNum = MsgTagTable.EntryNum" + "INNER JOIN TagTable ON MsgTagTable.TagId = TagTable.TagId" - + "WHERE SignatureTable.SignerId = {0}" - + "AND TagTable.Tag = {1}", + + "WHERE SignatureTable.SignerId = :{0}" + + "AND TagTable.Tag = :{1}", QueryType.GET_BATCH_MESSAGE_ENTRY.getParamName(0), QueryType.GET_BATCH_MESSAGE_ENTRY.getParamName(1)); case GET_BATCH_MESSAGE_DATA: return MessageFormat.format( "SELECT Data FROM BatchTable" - + " WHERE SignerId = {0} AND BatchId = {1} AND SerialNum >= {2}" + + " WHERE SignerId = :{0} AND BatchId = :{1} AND SerialNum >= :{2}" + " ORDER BY SerialNum ASC", QueryType.GET_BATCH_MESSAGE_DATA.getParamName(0), QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1), @@ -95,10 +95,34 @@ public class MySQLQueryProvider implements SQLQueryProvider { case CHECK_BATCH_LENGTH: return MessageFormat.format( "SELECT COUNT(Data) AS BatchLength FROM BatchTable" - + " WHERE SignerId = {0} AND BatchId = {1}", + + " WHERE SignerId = :{0} AND BatchId = :{1}", QueryType.GET_BATCH_MESSAGE_DATA.getParamName(0), QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1)); + case CONNECT_BATCH_TAG: + return MessageFormat.format( + "INSERT INTO BatchTagTable (SignerId, BatchId, TagId) SELECT :{0}, :{1}, TagId FROM TagTable" + + " WHERE Tag = :{2}", + QueryType.CONNECT_BATCH_TAG.getParamName(0), + QueryType.CONNECT_BATCH_TAG.getParamName(1), + QueryType.CONNECT_BATCH_TAG.getParamName(2)); + + case GET_BATCH_TAGS: + return MessageFormat.format( + "SELECT Tag FROM TagTable INNER JOIN BatchTagTable ON TagTable.TagId = BatchTagTable.Tag ID" + + " WHERE SignerId = :{0} AND BatchId = :{1} ORDER BY Tag ASC", + QueryType.GET_BATCH_TAGS.getParamName(0), + QueryType.GET_BATCH_TAGS.getParamName(1)); + + case MOVE_BATCH_TAGS: + return MessageFormat.format( + "INSERT INTO MsgTagTable (EntryNum, TagId) " + + " SELECT {0}, TagId FROM BatchTagTable WHERE SignerId = {1} AND BatchId = {2};" + + " DELETE FROM BatchTagTable WHERE SignerId = {1} AND BatchId = {2}", + QueryType.GET_BATCH_TAGS.getParamName(0), + QueryType.GET_BATCH_TAGS.getParamName(1), + QueryType.GET_BATCH_TAGS.getParamName(2)); + default: throw new IllegalArgumentException("Cannot serve a query of type " + queryType); } @@ -189,7 +213,7 @@ public class MySQLQueryProvider implements SQLQueryProvider { + " CONSTRAINT Unique_Batch UNIQUE(SignerId(32), BatchId, SerialNum))"); list.add("CREATE TABLE IF NOT EXISTS BatchTagTable (SignerId TINYBLOB, BatchId INT, TagId INT," - + " INDEX(SignerId, BatchId), CONSTRAINT FOREIGN KEY (TagId) REFERENCES TagTable(TagId))"); + + " INDEX(SignerId(32), BatchId), CONSTRAINT FOREIGN KEY (TagId) REFERENCES TagTable(TagId))"); return list; } diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/BatchDataMapper.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/BatchDataMapper.java index 0189584..81e6cda 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/BatchDataMapper.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/BatchDataMapper.java @@ -15,7 +15,7 @@ public class BatchDataMapper implements RowMapper { @Override public BatchData mapRow(ResultSet rs, int rowNum) throws SQLException { - return BatchData.newBuilder().setData(ByteString.copyFrom(rs.getBytes(rowNum))).build(); + return BatchData.newBuilder().setData(ByteString.copyFrom(rs.getBytes(1))).build(); } } diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/StringMapper.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/StringMapper.java new file mode 100644 index 0000000..c5b1d85 --- /dev/null +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/StringMapper.java @@ -0,0 +1,18 @@ +package meerkat.bulletinboard.sqlserver.mappers; + +import org.springframework.jdbc.core.RowMapper; + +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * Created by Arbel Deutsch Peled on 20-Dec-15. + */ +public class StringMapper implements RowMapper { + + @Override + public String mapRow(ResultSet rs, int rowNum) throws SQLException { + return rs.getString(1); + } + +} diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java index 27d7bd5..cab9d6d 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java @@ -18,11 +18,12 @@ import meerkat.bulletinboard.sqlserver.MySQLQueryProvider; import meerkat.bulletinboard.sqlserver.SQLiteQueryProvider; import meerkat.comm.CommunicationException; import meerkat.protobuf.BulletinBoardAPI.*; -import meerkat.rest.Constants; +import static meerkat.bulletinboard.BulletinBoardConstants.*; +import static meerkat.rest.Constants.*; import java.util.List; -@Path(Constants.BULLETIN_BOARD_SERVER_PATH) +@Path(BULLETIN_BOARD_SERVER_PATH) public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextListener{ private static final String BULLETIN_BOARD_ATTRIBUTE_NAME = "bulletinBoard"; @@ -78,30 +79,30 @@ public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextL } } - @Path(Constants.POST_MESSAGE_PATH) + @Path(POST_MESSAGE_PATH) @POST - @Consumes(Constants.MEDIATYPE_PROTOBUF) - @Produces(Constants.MEDIATYPE_PROTOBUF) + @Consumes(MEDIATYPE_PROTOBUF) + @Produces(MEDIATYPE_PROTOBUF) @Override public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException { init(); return bulletinBoard.postMessage(msg); } - @Path(Constants.READ_MESSAGES_PATH) + @Path(READ_MESSAGES_PATH) @POST - @Consumes(Constants.MEDIATYPE_PROTOBUF) - @Produces(Constants.MEDIATYPE_PROTOBUF) + @Consumes(MEDIATYPE_PROTOBUF) + @Produces(MEDIATYPE_PROTOBUF) @Override public BulletinBoardMessageList readMessages(MessageFilterList filterList) throws CommunicationException { init(); return bulletinBoard.readMessages(filterList); } - @Path(Constants.BEGIN_BATCH_PATH) + @Path(BEGIN_BATCH_PATH) @POST - @Consumes(Constants.MEDIATYPE_PROTOBUF) - @Produces(Constants.MEDIATYPE_PROTOBUF) + @Consumes(MEDIATYPE_PROTOBUF) + @Produces(MEDIATYPE_PROTOBUF) @Override public BoolMsg beginBatch(BeginBatchMessage message) { try { @@ -112,10 +113,10 @@ public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextL } } - @Path(Constants.POST_BATCH_PATH) + @Path(POST_BATCH_PATH) @POST - @Consumes(Constants.MEDIATYPE_PROTOBUF) - @Produces(Constants.MEDIATYPE_PROTOBUF) + @Consumes(MEDIATYPE_PROTOBUF) + @Produces(MEDIATYPE_PROTOBUF) @Override public BoolMsg postBatchMessage(BatchMessage batchMessage) { try { @@ -126,10 +127,10 @@ public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextL } } - @Path(Constants.CLOSE_BATCH_PATH) + @Path(CLOSE_BATCH_PATH) @POST - @Consumes(Constants.MEDIATYPE_PROTOBUF) - @Produces(Constants.MEDIATYPE_PROTOBUF) + @Consumes(MEDIATYPE_PROTOBUF) + @Produces(MEDIATYPE_PROTOBUF) @Override public BoolMsg closeBatchMessage(CloseBatchMessage message) { try { diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/BulletinBoardSQLServerIntegrationTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/BulletinBoardSQLServerIntegrationTest.java index 838adcc..4b8b586 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/BulletinBoardSQLServerIntegrationTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/BulletinBoardSQLServerIntegrationTest.java @@ -6,6 +6,7 @@ import com.google.protobuf.TextFormat; import meerkat.protobuf.Crypto.*; import meerkat.protobuf.BulletinBoardAPI.*; +import static meerkat.bulletinboard.BulletinBoardConstants.*; import meerkat.rest.Constants; import meerkat.rest.ProtobufMessageBodyReader; import meerkat.rest.ProtobufMessageBodyWriter; @@ -54,8 +55,8 @@ public class BulletinBoardSQLServerIntegrationTest { // Test writing mechanism - System.err.println("******** Testing: " + Constants.POST_MESSAGE_PATH); - webTarget = client.target(BASE_URL).path(Constants.BULLETIN_BOARD_SERVER_PATH).path(Constants.POST_MESSAGE_PATH); + System.err.println("******** Testing: " + POST_MESSAGE_PATH); + webTarget = client.target(BASE_URL).path(BULLETIN_BOARD_SERVER_PATH).path(POST_MESSAGE_PATH); System.err.println(webTarget.getUri()); msg = BulletinBoardMessage.newBuilder() @@ -101,8 +102,8 @@ public class BulletinBoardSQLServerIntegrationTest { // Test reading mechanism - System.err.println("******** Testing: " + Constants.READ_MESSAGES_PATH); - webTarget = client.target(BASE_URL).path(Constants.BULLETIN_BOARD_SERVER_PATH).path(Constants.READ_MESSAGES_PATH); + System.err.println("******** Testing: " + READ_MESSAGES_PATH); + webTarget = client.target(BASE_URL).path(BULLETIN_BOARD_SERVER_PATH).path(READ_MESSAGES_PATH); filterList = MessageFilterList.newBuilder() .addFilter( MessageFilter.newBuilder() diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java b/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java index 4d8075e..1663f7a 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java @@ -66,7 +66,7 @@ public interface AsyncBulletinBoardClient extends BulletinBoardClient { * @param batchId is the unique (per signer) ID of the batch * @param callback is a callback class for handling the result of the operation */ - public void readBatch(byte[] signerId, int batchId, ClientCallback callback); + public void readBatch(byte[] signerId, int batchId, ClientCallback callback); /** * Subscribes to a notifier that will return any new messages on the server that match the given filters diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BatchDigest.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BatchDigest.java new file mode 100644 index 0000000..6e30fe9 --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BatchDigest.java @@ -0,0 +1,20 @@ +package meerkat.bulletinboard; + +import meerkat.crypto.Digest; +import meerkat.protobuf.BulletinBoardAPI.*; + +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 18-Dec-15. + * Extends the Digest interface with a method for digesting Batch messages + */ +public interface BatchDigest extends Digest { + + /** + * Update the digest with the batch message data (ignore the signature) + * @param completeBatch is the batch message that needs to be digested + */ + public void update(CompleteBatch completeBatch); + +} diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BatchDigitalSignature.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BatchDigitalSignature.java new file mode 100644 index 0000000..e04f3c5 --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BatchDigitalSignature.java @@ -0,0 +1,34 @@ +package meerkat.bulletinboard; + +import meerkat.crypto.DigitalSignature; +import meerkat.protobuf.BulletinBoardAPI.BeginBatchMessage; +import meerkat.protobuf.BulletinBoardAPI.BatchData; +import meerkat.protobuf.Crypto.Signature; + +import java.security.InvalidKeyException; +import java.security.SignatureException; +import java.security.cert.CertificateException; +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 20-Dec-15. + * Extends the DigitalSignature interface with methods for signing and authenticating Batch messages + */ +public interface BatchDigitalSignature extends DigitalSignature { + + /** + * Appends the batch data to the signed content (ignoring the signature) + * @param completeBatch contains all the data about the batch + * @throws SignatureException + */ + public void updateContent(CompleteBatch completeBatch) throws SignatureException; + + /** + * Performs a complete verification process on the given batch message + * @param completeBatch contains the batch data as well as the signature + * @return TRUE if the batch is verified and FALSE otherwise + * @throws SignatureException | SignatureException | InvalidKeyException when underlying methods do so + */ + public boolean verify(CompleteBatch completeBatch) throws SignatureException, CertificateException, InvalidKeyException; + +} diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardConstants.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardConstants.java new file mode 100644 index 0000000..7fe3a43 --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardConstants.java @@ -0,0 +1,21 @@ +package meerkat.bulletinboard; + +/** + * Created by Arbel Deutsch Peled on 21-Dec-15. + */ +public interface BulletinBoardConstants { + + // Relative addresses for Bulletin Board operations + + public static final String BULLETIN_BOARD_SERVER_PATH = "/bbserver"; + public static final String READ_MESSAGES_PATH = "/readmessages"; + public static final String POST_MESSAGE_PATH = "/postmessage"; + public static final String BEGIN_BATCH_PATH = "/beginbatch"; + public static final String POST_BATCH_PATH = "/postbatch"; + public static final String CLOSE_BATCH_PATH = "/closebatch"; + + // Other Constants + + public static final String BATCH_TAG = "Batch"; + +} diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/SignedBatch.java b/meerkat-common/src/main/java/meerkat/bulletinboard/CompleteBatch.java similarity index 50% rename from meerkat-common/src/main/java/meerkat/bulletinboard/SignedBatch.java rename to meerkat-common/src/main/java/meerkat/bulletinboard/CompleteBatch.java index 46cf07e..6deec77 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/SignedBatch.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/CompleteBatch.java @@ -9,27 +9,36 @@ import java.util.List; /** * Created by Arbel Deutsch Peled on 14-Dec-15. * - * A data structure for holding both a batch message and its signature + * A data structure for holding a complete batch message along with its signature */ -public class SignedBatch { +public class CompleteBatch { + private BeginBatchMessage beginBatchMessage; private List batchDataList; private Signature signature; - public SignedBatch() { + public CompleteBatch() { batchDataList = new LinkedList(); } - public SignedBatch(List newDataList) { - this(); + public CompleteBatch(BeginBatchMessage newBeginBatchMessage) { + beginBatchMessage = newBeginBatchMessage; + } + + public CompleteBatch(BeginBatchMessage newBeginBatchMessage, List newDataList) { + this(newBeginBatchMessage); appendBatchData(newDataList); } - public SignedBatch(List newDataList, Signature newSignature) { - this(newDataList); + public CompleteBatch(BeginBatchMessage newBeginBatchMessage, List newDataList, Signature newSignature) { + this(newBeginBatchMessage, newDataList); signature = newSignature; } + public BeginBatchMessage getBeginBatchMessage() { + return beginBatchMessage; + } + public List getBatchDataList() { return batchDataList; } @@ -46,5 +55,8 @@ public class SignedBatch { batchDataList.addAll(newBatchDataList); } + public void setSignature(Signature newSignature) { + signature = newSignature; + } } diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigest.java b/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigest.java new file mode 100644 index 0000000..8171271 --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigest.java @@ -0,0 +1,54 @@ +package meerkat.bulletinboard; + +import com.google.protobuf.Message; +import meerkat.crypto.Digest; +import meerkat.protobuf.BulletinBoardAPI.BeginBatchMessage; +import meerkat.protobuf.BulletinBoardAPI.BatchData; + +import java.util.List; + + +/** + * Created by Arbel Deutsch Peled on 19-Dec-15. + * Wrapper class for digesting Batches in a standardized way + */ +public class GenericBatchDigest implements BatchDigest{ + + private Digest digest; + + public GenericBatchDigest(Digest digest) { + this.digest = digest; + } + + @Override + public void update(CompleteBatch completeBatch) { + + update(completeBatch.getBeginBatchMessage()); + + for (BatchData batchData : completeBatch.getBatchDataList()) { + update(batchData); + } + + } + + @Override + public byte[] digest() { + return digest.digest(); + } + + @Override + public void update(Message msg) { + digest.update(msg); + } + + @Override + public void reset() { + digest.reset(); + } + + @Override + public GenericBatchDigest clone() throws CloneNotSupportedException{ + return new GenericBatchDigest(digest.clone()); + } + +} diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigitalSignature.java b/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigitalSignature.java new file mode 100644 index 0000000..422e8b0 --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigitalSignature.java @@ -0,0 +1,95 @@ +package meerkat.bulletinboard; + +import com.google.protobuf.ByteString; +import com.google.protobuf.Message; +import meerkat.crypto.DigitalSignature; +import meerkat.protobuf.BulletinBoardAPI.BeginBatchMessage; +import meerkat.protobuf.BulletinBoardAPI.BatchData; +import meerkat.protobuf.Crypto; + +import java.io.IOException; +import java.io.InputStream; +import java.security.InvalidKeyException; +import java.security.KeyStore; +import java.security.SignatureException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 20-Dec-15. + * Wrapper class for signing and verifying Batch signatures in a standardized way + */ +public class GenericBatchDigitalSignature implements BatchDigitalSignature{ + + private DigitalSignature digitalSignature; + + public GenericBatchDigitalSignature(DigitalSignature digitalSignature) { + this.digitalSignature = digitalSignature; + } + + @Override + public void updateContent(CompleteBatch completeBatch) throws SignatureException { + + digitalSignature.updateContent(completeBatch.getBeginBatchMessage()); + for (BatchData batchData : completeBatch.getBatchDataList()) { + digitalSignature.updateContent(batchData); + } + + } + + @Override + public boolean verify(CompleteBatch completeBatch) throws SignatureException, CertificateException, InvalidKeyException { + + digitalSignature.initVerify(completeBatch.getSignature()); + updateContent(completeBatch); + return digitalSignature.verify(); + + } + + @Override + public void loadVerificationCertificates(InputStream certStream) throws CertificateException { + digitalSignature.loadVerificationCertificates(certStream); + } + + @Override + public void clearVerificationCertificates() { + digitalSignature.clearVerificationCertificates(); + } + + @Override + public void updateContent(Message msg) throws SignatureException { + digitalSignature.updateContent(msg); + } + + @Override + public Crypto.Signature sign() throws SignatureException { + return digitalSignature.sign(); + } + + @Override + public void initVerify(Crypto.Signature sig) throws CertificateException, InvalidKeyException { + digitalSignature.initVerify(sig); + } + + @Override + public boolean verify() { + return digitalSignature.verify(); + } + + @Override + public void loadSigningCertificate(KeyStore.Builder keyStoreBuilder) throws IOException, CertificateException, UnrecoverableKeyException { + digitalSignature.loadSigningCertificate(keyStoreBuilder); + } + + @Override + public ByteString getSignerID() { + return digitalSignature.getSignerID(); + } + + @Override + public void clearSigningKey() { + digitalSignature.clearSigningKey(); + } + +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/BatchDigest.java b/meerkat-common/src/main/java/meerkat/crypto/BatchDigest.java deleted file mode 100644 index ff257b2..0000000 --- a/meerkat-common/src/main/java/meerkat/crypto/BatchDigest.java +++ /dev/null @@ -1,20 +0,0 @@ -package meerkat.crypto; - -import meerkat.protobuf.BulletinBoardAPI.*; - -import java.util.List; - -/** - * Created by Arbel Deutsch Peled on 18-Dec-15. - * Extends the Digest interface with a method for digesting Batch messages - */ -public interface BatchDigest extends Digest{ - - /** - * Update the digest with the - * @param beginBatchMessage is the message that starts the batch - * @param batchDataList is the (ordered) list of data in the batch - */ - public void update(BeginBatchMessage beginBatchMessage, List batchDataList); - -} diff --git a/meerkat-common/src/main/java/meerkat/crypto/concrete/GenericBatchDigest.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/GenericBatchDigest.java deleted file mode 100644 index 38b2192..0000000 --- a/meerkat-common/src/main/java/meerkat/crypto/concrete/GenericBatchDigest.java +++ /dev/null @@ -1,27 +0,0 @@ -package meerkat.crypto.concrete; - -import com.google.protobuf.Message; -import meerkat.crypto.BatchDigest; -import meerkat.protobuf.BulletinBoardAPI.*; - -import java.util.List; - -/** - * Created by Arbel Deutsch Peled on 19-Dec-15. - */ -public abstract class GenericBatchDigest implements BatchDigest{ - - - @Override - public void update(BeginBatchMessage beginBatchMessage, List batchDataList) { - update(beginBatchMessage); - for (BatchData batchData : batchDataList) { - update(batchData); - } - } - - @Override - // Repeated here to circumvent compiler error - public abstract BatchDigest clone() throws CloneNotSupportedException; - -} diff --git a/meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java index ac58f3a..4aac501 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java @@ -2,7 +2,6 @@ package meerkat.crypto.concrete; import com.google.protobuf.ByteString; import com.google.protobuf.Message; -import meerkat.crypto.BatchDigest; import meerkat.crypto.Digest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,7 +13,7 @@ import java.security.NoSuchAlgorithmException; /** * Created by talm on 11/9/15. */ -public class SHA256Digest extends GenericBatchDigest { +public class SHA256Digest implements Digest { final Logger logger = LoggerFactory.getLogger(getClass()); public static final String SHA256 = "SHA-256"; diff --git a/restful-api-common/src/main/java/meerkat/rest/Constants.java b/restful-api-common/src/main/java/meerkat/rest/Constants.java index 8215641..2c04248 100644 --- a/restful-api-common/src/main/java/meerkat/rest/Constants.java +++ b/restful-api-common/src/main/java/meerkat/rest/Constants.java @@ -5,12 +5,4 @@ package meerkat.rest; */ public interface Constants { public static final String MEDIATYPE_PROTOBUF = "application/x-protobuf"; - - public static final String BULLETIN_BOARD_SERVER_PATH = "/bbserver"; - public static final String READ_MESSAGES_PATH = "/readmessages"; - public static final String POST_MESSAGE_PATH = "/postmessage"; - public static final String BEGIN_BATCH_PATH = "/beginbatch"; - public static final String POST_BATCH_PATH = "/postbatch"; - public static final String CLOSE_BATCH_PATH = "/closebatch"; - } From 88b8f6d8eab782ddb59e16a5eb7bf92d68282928 Mon Sep 17 00:00:00 2001 From: Arbel Deutsch Peled Date: Sun, 27 Dec 2015 11:21:17 +0200 Subject: [PATCH 05/49] Working version of Batch messages on Server-Side --- bulletin-board-server/build.gradle | 5 + .../sqlserver/BulletinBoardSQLServer.java | 243 +++++++++++++----- .../sqlserver/MySQLQueryProvider.java | 43 ++-- .../sqlserver/mappers/BatchDataMapper.java | 7 +- .../GenericBulletinBoardServerTest.java | 200 +++++++++++++- .../MySQLBulletinBoardServerTest.java | 33 +++ .../bulletinboard/BulletinBoardConstants.java | 3 +- .../meerkat/bulletinboard/CompleteBatch.java | 5 + .../GenericBatchDigitalSignature.java | 10 +- .../java/meerkat/crypto/DigitalSignature.java | 22 +- .../crypto/concrete/ECDSASignature.java | 1 + 11 files changed, 468 insertions(+), 104 deletions(-) diff --git a/bulletin-board-server/build.gradle b/bulletin-board-server/build.gradle index 62e4b0c..63ba47d 100644 --- a/bulletin-board-server/build.gradle +++ b/bulletin-board-server/build.gradle @@ -79,6 +79,11 @@ test { exclude '**/*IntegrationTest*' } +task myTest(type: Test) { + include '**/*MySQL*Test*' + outputs.upToDateWhen { false } +} + task dbTest(type: Test) { include '**/*H2*Test*' include '**/*MySQL*Test*' diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java index 1bb32d8..5b4fac9 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java @@ -51,25 +51,87 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ */ public static enum QueryType { - FIND_MSG_ID(new String[] {"MsgId"}), - INSERT_MSG(new String[] {"MsgId","Msg"}), - INSERT_NEW_TAG(new String[] {"Tag"}), - CONNECT_TAG(new String[] {"EntryNum","Tag"}), - ADD_SIGNATURE(new String[] {"EntryNum","SignerId","Signature"}), - GET_SIGNATURES(new String[] {"EntryNum"}), - GET_MESSAGES(new String[] {}), - GET_BATCH_MESSAGE_ENTRY(new String[] {"SignerId", "BatchId"}), - CHECK_BATCH_LENGTH(new String[] {"SignerId", "BatchId"}), - GET_BATCH_MESSAGE_DATA(new String[] {"SignerId", "BatchId", "StartPosition"}), - INSERT_BATCH_DATA(new String[] {"SignerId", "BatchId", "SerialNum", "Data"}), - CONNECT_BATCH_TAG(new String[] {"SignerId", "BatchId", "Tag"}), - GET_BATCH_TAGS(new String[] {"SignerId", "BatchId"}), - MOVE_BATCH_TAGS(new String[] {"EntryNum", "SignerId", "BatchId"}); + FIND_MSG_ID( + new String[] {"MsgId"}, + new int[] {Types.BLOB} + ), + + FIND_TAG_ID( + new String[] {"Tag"}, + new int[] {Types.VARCHAR} + ), + + INSERT_MSG( + new String[] {"MsgId","Msg"}, + new int[] {Types.BLOB, Types.BLOB} + ), + + INSERT_NEW_TAG( + new String[] {"Tag"}, + new int[] {Types.VARCHAR} + ), + + CONNECT_TAG( + new String[] {"EntryNum","Tag"}, + new int[] {Types.INTEGER, Types.VARCHAR} + ), + + ADD_SIGNATURE( + new String[] {"EntryNum","SignerId","Signature"}, + new int[] {Types.INTEGER, Types.BLOB, Types.BLOB} + ), + + GET_SIGNATURES( + new String[] {"EntryNum"}, + new int[] {Types.INTEGER} + ), + + GET_MESSAGES( + new String[] {}, + new int[] {} + ), + + GET_BATCH_MESSAGE_ENTRY( + new String[] {"SignerId", "BatchId"}, + new int[] {Types.BLOB, Types.INTEGER} + ), + + CHECK_BATCH_LENGTH( + new String[] {"SignerId", "BatchId"}, + new int[] {Types.BLOB, Types.INTEGER} + ), + + GET_BATCH_MESSAGE_DATA( + new String[] {"SignerId", "BatchId", "StartPosition"}, + new int[] {Types.BLOB, Types.INTEGER, Types.INTEGER} + ), + + INSERT_BATCH_DATA( + new String[] {"SignerId", "BatchId", "SerialNum", "Data"}, + new int[] {Types.BLOB, Types.INTEGER, Types.INTEGER, Types.BLOB} + ), + + CONNECT_BATCH_TAG( + new String[] {"SignerId", "BatchId", "Tag"}, + new int[] {Types.BLOB, Types.INTEGER, Types.VARCHAR} + ), + + GET_BATCH_TAGS( + new String[] {"SignerId", "BatchId"}, + new int[] {Types.BLOB, Types.INTEGER} + ), + + REMOVE_BATCH_TAGS( + new String[] {"SignerId", "BatchId"}, + new int[] {Types.BLOB, Types.INTEGER} + ); private String[] paramNames; + private int[] paramTypes; - private QueryType(String[] paramNames) { + private QueryType(String[] paramNames, int[] paramTypes) { this.paramNames = paramNames; + this.paramTypes = paramTypes; } public String[] getParamNames() { @@ -80,6 +142,14 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ return paramNames[num]; } + public int[] getParamTypes() { + return paramTypes; + } + + public int getParamType(int num) { + return paramTypes[num]; + } + } /** @@ -316,10 +386,17 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ .build(); } - @Override - public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException { - - if (!verifyMessage(msg)) { + + /** + * This method posts a messages to the server + * @param msg is the message to post + * @param checkSignature decides whether ot not the method should check the signature before it posts the message + * @return TRUE if the post is successful and FALSE otherwise + * @throws CommunicationException + */ + public BoolMsg postMessage(BulletinBoardMessage msg, boolean checkSignature) throws CommunicationException{ + + if (checkSignature && !verifyMessage(msg)) { return boolToBoolMsg(false); } @@ -328,23 +405,23 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ byte[] msgID; long entryNum; - + ProtocolStringList tagList; String[] tags; - + List signatureList; Signature[] signatures; - + // Calculate message ID (depending only on the the unsigned message) - + digest.reset(); digest.update(msg.getMsg()); - + msgID = digest.digest(); - + // Add message to table if needed and store entry number of message. - + sql = sqlQueryProvider.getSQLString(QueryType.FIND_MSG_ID); Map namedParameters = new HashMap(); namedParameters.put(QueryType.FIND_MSG_ID.getParamName(0),msgID); @@ -366,21 +443,21 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ entryNum = keyHolder.getKey().longValue(); } - + // Retrieve tags and store new ones in tag table. - + try { - - tagList = msg.getMsg().getTagList(); - tags = new String[tagList.size()]; - tags = tagList.toArray(tags); - - insertNewTags(tags); - + + tagList = msg.getMsg().getTagList(); + tags = new String[tagList.size()]; + tags = tagList.toArray(tags); + + insertNewTags(tags); + } catch (SQLException e) { throw new CommunicationException(e.getMessage()); } - + // Connect message to tags. sql = sqlQueryProvider.getSQLString(QueryType.CONNECT_TAG); @@ -394,13 +471,13 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ } jdbcTemplate.batchUpdate(sql, namedParameterArray); - + // Retrieve signatures. - - signatureList = msg.getSigList(); - signatures = new Signature[signatureList.size()]; - signatures = signatureList.toArray(signatures); - + + signatureList = msg.getSigList(); + signatures = new Signature[signatureList.size()]; + signatures = signatureList.toArray(signatures); + // Connect message to signatures. sql = sqlQueryProvider.getSQLString(QueryType.ADD_SIGNATURE); @@ -417,6 +494,12 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ jdbcTemplate.batchUpdate(sql,namedParameterArray); return boolToBoolMsg(true); + + } + + @Override + public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException { + return postMessage(msg, true); // Perform a post and check the signature for authenticity } @Override @@ -477,7 +560,8 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ // Run query - List msgBuilders = jdbcTemplate.query(sqlBuilder.toString(), namedParameters, messageMapper); + List msgBuilders = + jdbcTemplate.query(sqlBuilder.toString(), namedParameters, messageMapper); // Compile list of messages @@ -507,23 +591,41 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ } + /** + * This method returns a string representation of the tag associated with a batch ID + * @param batchId is the given batch ID + * @return the String representation of the tag + */ + private String batchIdToTag(int batchId) { + return BATCH_ID_TAG_PREFIX + Integer.toString(batchId); + } + /** * This method checks if a specified batch exists and is already closed * @param signerId is the ID of the publisher of the batch * @param batchId is the unique (per signer) batch ID * @return TRUE if the batch is closed and FALSE if it is still open or doesn't exist at all */ - private boolean isBatchClosed(ByteString signerId, int batchId){ + private boolean isBatchClosed(ByteString signerId, int batchId) throws CommunicationException { - String sql = sqlQueryProvider.getSQLString(QueryType.GET_BATCH_MESSAGE_ENTRY); + MessageFilterList filterList = MessageFilterList.newBuilder() + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.SIGNER_ID) + .setId(signerId) + .build()) + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.TAG) + .setTag(BATCH_TAG) + .build()) + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.TAG) + .setTag(batchIdToTag(batchId)) + .build()) + .build(); - MapSqlParameterSource namedParameters = new MapSqlParameterSource(); - namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_ENTRY.getParamName(0), signerId); - namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_ENTRY.getParamName(1), batchId); + BulletinBoardMessageList messageList = readMessages(filterList); - List result = jdbcTemplate.query(sql,namedParameters,new LongMapper()); - - return (result.size() > 0); + return (messageList.getMessageList().size() > 0); } @@ -562,7 +664,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ } @Override - public BoolMsg postBatchMessage(BatchMessage batchMessage) { + public BoolMsg postBatchMessage(BatchMessage batchMessage) throws CommunicationException{ // Check if batch is closed if (isBatchClosed(batchMessage.getSignerId(), batchMessage.getBatchId())) { @@ -576,7 +678,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(0),batchMessage.getSignerId()); namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(1),batchMessage.getBatchId()); namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(2),batchMessage.getSerialNum()); - namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(3),batchMessage.getData()); + namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(3),batchMessage.getData().toByteArray()); jdbcTemplate.update(sql, namedParameters); @@ -641,11 +743,12 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ completeBatch.setSignature(message.getSig()); - try { - signer.verify(completeBatch); - } catch (CertificateException | InvalidKeyException | SignatureException e) { - return BoolMsg.newBuilder().setValue(false).build(); - } +// try { +// TODO: Actual verification +// //signer.verify(completeBatch); +// } catch (CertificateException | InvalidKeyException | SignatureException e) { +// return BoolMsg.newBuilder().setValue(false).build(); +// } // Batch verified: finalize it @@ -660,28 +763,25 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ .setMsg(UnsignedBulletinBoardMessage.newBuilder() .addAllTag(tags) .addTag(BATCH_TAG) + .addTag(batchIdToTag(batchId)) .setData(message.getSig().getSignerId()) .build()) .build(); - sql = sqlQueryProvider.getSQLString(QueryType.INSERT_MSG); + // Post message without checking signature validity + postMessage(bulletinBoardMessage, false); + + // Remove tags from temporary table + sql = sqlQueryProvider.getSQLString(QueryType.REMOVE_BATCH_TAGS); namedParameters = new MapSqlParameterSource(); - namedParameters.addValue(QueryType.INSERT_MSG.getParamName(0), msgID); - namedParameters.addValue(QueryType.INSERT_MSG.getParamName(1), bulletinBoardMessage); + namedParameters.addValue(QueryType.REMOVE_BATCH_TAGS.getParamName(0), signerId); + namedParameters.addValue(QueryType.REMOVE_BATCH_TAGS.getParamName(1), batchId); - jdbcTemplate.update(sql, namedParameters, keyHolder); - long entryNum = keyHolder.getKey().longValue(); - - sql = sqlQueryProvider.getSQLString(QueryType.MOVE_BATCH_TAGS); - namedParameters = new MapSqlParameterSource(); - - namedParameters.addValue(QueryType.MOVE_BATCH_TAGS.getParamName(0), entryNum); - namedParameters.addValue(QueryType.MOVE_BATCH_TAGS.getParamName(1), signerId); - namedParameters.addValue(QueryType.MOVE_BATCH_TAGS.getParamName(2), batchId); - jdbcTemplate.update(sql, namedParameters); + // Return TRUE + return BoolMsg.newBuilder().setValue(true).build(); } @@ -698,6 +798,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(0),message.getSignerId()); namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1),message.getBatchId()); + namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(2),message.getStartPosition()); return jdbcTemplate.query(sql, namedParameters, new BatchDataMapper()); } diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java index 59e6106..c8357a3 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java @@ -1,6 +1,7 @@ package meerkat.bulletinboard.sqlserver; import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; +import meerkat.bulletinboard.BulletinBoardConstants; import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer.SQLQueryProvider; import meerkat.protobuf.BulletinBoardAPI.FilterType; @@ -53,6 +54,11 @@ public class MySQLQueryProvider implements SQLQueryProvider { "SELECT EntryNum From MsgTable WHERE MsgId = :{0}", QueryType.FIND_MSG_ID.getParamName(0)); + case FIND_TAG_ID: + return MessageFormat.format( + "SELECT TagId FROM TagTable WHERE Tag = :{0}", + QueryType.FIND_TAG_ID.getParamName(0)); + case GET_MESSAGES: return "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable"; @@ -75,11 +81,11 @@ public class MySQLQueryProvider implements SQLQueryProvider { case GET_BATCH_MESSAGE_ENTRY: return MessageFormat.format( "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable" - + "INNER JOIN SignatureTable ON MsgTable.EntryNum = SignatureTable.EntryNum" - + "INNER JOIN MsgTagTable ON MsgTable.EntryNum = MsgTagTable.EntryNum" - + "INNER JOIN TagTable ON MsgTagTable.TagId = TagTable.TagId" - + "WHERE SignatureTable.SignerId = :{0}" - + "AND TagTable.Tag = :{1}", + + " INNER JOIN SignatureTable ON MsgTable.EntryNum = SignatureTable.EntryNum" + + " INNER JOIN MsgTagTable ON MsgTable.EntryNum = MsgTagTable.EntryNum" + + " INNER JOIN TagTable ON MsgTagTable.TagId = TagTable.TagId" + + " WHERE SignatureTable.SignerId = :{0}" + + " AND TagTable.Tag = :{1}", QueryType.GET_BATCH_MESSAGE_ENTRY.getParamName(0), QueryType.GET_BATCH_MESSAGE_ENTRY.getParamName(1)); @@ -92,12 +98,21 @@ public class MySQLQueryProvider implements SQLQueryProvider { QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1), QueryType.GET_BATCH_MESSAGE_DATA.getParamName(2)); + case INSERT_BATCH_DATA: + return MessageFormat.format( + "INSERT INTO BatchTable (SignerId, BatchId, SerialNum, Data)" + + " VALUES (:{0}, :{1}, :{2}, :{3})", + QueryType.INSERT_BATCH_DATA.getParamName(0), + QueryType.INSERT_BATCH_DATA.getParamName(1), + QueryType.INSERT_BATCH_DATA.getParamName(2), + QueryType.INSERT_BATCH_DATA.getParamName(3)); + case CHECK_BATCH_LENGTH: return MessageFormat.format( "SELECT COUNT(Data) AS BatchLength FROM BatchTable" + " WHERE SignerId = :{0} AND BatchId = :{1}", - QueryType.GET_BATCH_MESSAGE_DATA.getParamName(0), - QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1)); + QueryType.CHECK_BATCH_LENGTH.getParamName(0), + QueryType.CHECK_BATCH_LENGTH.getParamName(1)); case CONNECT_BATCH_TAG: return MessageFormat.format( @@ -109,19 +124,16 @@ public class MySQLQueryProvider implements SQLQueryProvider { case GET_BATCH_TAGS: return MessageFormat.format( - "SELECT Tag FROM TagTable INNER JOIN BatchTagTable ON TagTable.TagId = BatchTagTable.Tag ID" + "SELECT Tag FROM TagTable INNER JOIN BatchTagTable ON TagTable.TagId = BatchTagTable.TagId" + " WHERE SignerId = :{0} AND BatchId = :{1} ORDER BY Tag ASC", QueryType.GET_BATCH_TAGS.getParamName(0), QueryType.GET_BATCH_TAGS.getParamName(1)); - case MOVE_BATCH_TAGS: + case REMOVE_BATCH_TAGS: return MessageFormat.format( - "INSERT INTO MsgTagTable (EntryNum, TagId) " - + " SELECT {0}, TagId FROM BatchTagTable WHERE SignerId = {1} AND BatchId = {2};" - + " DELETE FROM BatchTagTable WHERE SignerId = {1} AND BatchId = {2}", - QueryType.GET_BATCH_TAGS.getParamName(0), - QueryType.GET_BATCH_TAGS.getParamName(1), - QueryType.GET_BATCH_TAGS.getParamName(2)); + "DELETE FROM BatchTagTable WHERE SignerId = :{0} AND BatchId = :{1}", + QueryType.REMOVE_BATCH_TAGS.getParamName(0), + QueryType.REMOVE_BATCH_TAGS.getParamName(1)); default: throw new IllegalArgumentException("Cannot serve a query of type " + queryType); @@ -187,6 +199,7 @@ public class MySQLQueryProvider implements SQLQueryProvider { dataSource.setDatabaseName(dbName); dataSource.setUser(username); dataSource.setPassword(password); + dataSource.setAllowMultiQueries(true); return dataSource; } diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/BatchDataMapper.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/BatchDataMapper.java index 81e6cda..bc4ea26 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/BatchDataMapper.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/BatchDataMapper.java @@ -1,6 +1,7 @@ package meerkat.bulletinboard.sqlserver.mappers; import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; import meerkat.protobuf.BulletinBoardAPI.BatchData; import org.springframework.jdbc.core.RowMapper; @@ -15,7 +16,11 @@ public class BatchDataMapper implements RowMapper { @Override public BatchData mapRow(ResultSet rs, int rowNum) throws SQLException { - return BatchData.newBuilder().setData(ByteString.copyFrom(rs.getBytes(1))).build(); + try { + return BatchData.parseFrom(rs.getBytes(1)); + } catch (InvalidProtocolBufferException e) { + return BatchData.getDefaultInstance(); + } } } diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java index 4799e0d..86a32de 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java @@ -12,18 +12,13 @@ import java.security.NoSuchAlgorithmException; import java.security.SignatureException; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; -import java.util.List; -import java.util.Random; +import java.util.*; import com.google.protobuf.ByteString; import meerkat.comm.CommunicationException; import meerkat.crypto.concrete.ECDSASignature; -import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; -import meerkat.protobuf.BulletinBoardAPI.FilterType; -import meerkat.protobuf.BulletinBoardAPI.MessageFilter; -import meerkat.protobuf.BulletinBoardAPI.MessageFilterList; -import meerkat.protobuf.BulletinBoardAPI.UnsignedBulletinBoardMessage; +import meerkat.protobuf.BulletinBoardAPI.*; import static org.junit.Assert.*; import static org.hamcrest.CoreMatchers.*; @@ -31,7 +26,7 @@ import static org.hamcrest.CoreMatchers.*; public class GenericBulletinBoardServerTest { protected BulletinBoardServer bulletinBoardServer; - private ECDSASignature signers[]; + private GenericBatchDigitalSignature signers[]; private ByteString[] signerIDs; private Random random; @@ -51,6 +46,8 @@ public class GenericBulletinBoardServerTest { private String[] tags; private byte[][] data; + private List completeBatches; + private final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); // Used to time the tests /** @@ -71,10 +68,10 @@ public class GenericBulletinBoardServerTest { this.bulletinBoardServer = bulletinBoardServer; - signers = new ECDSASignature[2]; + signers = new GenericBatchDigitalSignature[2]; signerIDs = new ByteString[signers.length]; - signers[0] = new ECDSASignature(); - signers[1] = new ECDSASignature(); + signers[0] = new GenericBatchDigitalSignature(new ECDSASignature()); + signers[1] = new GenericBatchDigitalSignature(new ECDSASignature()); InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE); char[] password = KEYFILE_PASSWORD1.toCharArray(); @@ -121,6 +118,11 @@ public class GenericBulletinBoardServerTest { long end = threadBean.getCurrentThreadCpuTime(); System.err.println("Finished initializing GenericBulletinBoardServerTest"); System.err.println("Time of operation: " + (end - start)); + + // Initialize Batch variables + + completeBatches = new ArrayList(10); + } private byte randomByte(){ @@ -377,6 +379,182 @@ public class GenericBulletinBoardServerTest { System.err.println("Time of operation: " + (end - start)); } + + /** + * Tests that posting a message before opening a batch does not work + * @throws CommunicationException + */ + public void testBatchPostAfterClose() throws CommunicationException, SignatureException { + + final int BATCH_ID = 100; + + CompleteBatch completeBatch = new CompleteBatch(); + BoolMsg result; + + // Create data + + completeBatch.setBeginBatchMessage(BeginBatchMessage.newBuilder() + .setSignerId(signerIDs[1]) + .setBatchId(BATCH_ID) + .addTag("Test") + .build()); + + BatchData batchData = BatchData.newBuilder() + .setData(ByteString.copyFrom((new byte[] {1,2,3,4}))) + .build(); + + completeBatch.appendBatchData(batchData); + + signers[1].updateContent(completeBatch); + + completeBatch.setSignature(signers[1].sign()); + + // Begin batch + + result = bulletinBoardServer.beginBatch(completeBatch.getBeginBatchMessage()); + + assertThat("Was not able to open batch", result.getValue(), is(true)); + + // Post data + + BatchMessage batchMessage = BatchMessage.newBuilder() + .setSignerId(signerIDs[1]) + .setBatchId(BATCH_ID) + .setData(batchData) + .build(); + + result = bulletinBoardServer.postBatchMessage(batchMessage); + + assertThat("Was not able to post batch message", result.getValue(), is(true)); + + // Close batch + + result = bulletinBoardServer.closeBatchMessage(CloseBatchMessage.newBuilder() + .setBatchId(BATCH_ID) + .setBatchLength(1) + .setSig(completeBatch.getSignature()) + .build()); + + assertThat("Was not able to close batch", result.getValue(), is(true)); + + // Attempt to open batch again + + result = bulletinBoardServer.beginBatch(completeBatch.getBeginBatchMessage()); + + assertThat("Was able to open a closed batch", result.getValue(), is(false)); + + // Attempt to add batch data + + result = bulletinBoardServer.postBatchMessage(batchMessage); + + assertThat("Was able to change a closed batch", result.getValue(), is(false)); + + } + + /** + * Posts a complete batch message + * @throws CommunicationException + */ + public void testPostBatch() throws CommunicationException, SignatureException { + + CompleteBatch completeBatch = new CompleteBatch(); + int currentBatch = completeBatches.size(); + + BoolMsg result; + + // Define batch data + + String[] tempBatchTags = new String[]{randomString(),randomString(),randomString()}; + byte[][] tempBatchData = new byte[Math.abs(randomByte())][]; + + for (int i = 0 ; i < tempBatchData.length ; i++) { + + tempBatchData[i] = new byte[Math.abs(randomByte())]; + + for (int j = 0; j < tempBatchData[i].length; j++) { + tempBatchData[i][j] = randomByte(); + } + + } + + // Begin batch + + completeBatch.setBeginBatchMessage(BeginBatchMessage.newBuilder() + .setSignerId(signerIDs[0]) + .setBatchId(currentBatch) + .addAllTag(Arrays.asList(tempBatchTags)) + .build()); + + result = bulletinBoardServer.beginBatch(completeBatch.getBeginBatchMessage()); + + assertThat("Could not begin batch " + currentBatch, result.getValue(), is(true)); + + // Add batch data and randomize data posting order + + List dataOrder = new ArrayList(tempBatchData.length); + for (int i = 0 ; i < tempBatchData.length ; i++) { + dataOrder.add(i); + completeBatch.appendBatchData(BatchData.newBuilder() + .setData(ByteString.copyFrom(tempBatchData[i])) + .build()); + } + Collections.shuffle(dataOrder); + + // Post data + + for (int i = 0 ; i < tempBatchData.length ; i++) { + + int dataIndex = dataOrder.get(i); + + result = bulletinBoardServer.postBatchMessage(BatchMessage.newBuilder() + .setSignerId(signerIDs[0]) + .setBatchId(currentBatch) + .setSerialNum(dataIndex) + .setData(completeBatch.getBatchDataList().get(dataIndex)) + .build()); + + assertThat("Could not post batch data for batch ID " + currentBatch + " serial number " + dataIndex, + result.getValue(), is(true)); + + } + + // Close batch + + signers[0].updateContent(completeBatch); + completeBatch.setSignature(signers[0].sign()); + + result = bulletinBoardServer.closeBatchMessage(CloseBatchMessage.newBuilder() + .setBatchId(currentBatch) + .setBatchLength(tempBatchData.length) + .setSig(completeBatch.getSignature()) + .build()); + + assertThat("Could not close batch " + currentBatch, result.getValue(), is(true)); + + // Update locally stored batches + completeBatches.add(completeBatch); + + } + + public void testReadBatch() throws CommunicationException { + + for (CompleteBatch completeBatch : completeBatches) { + + List batchDataList = + bulletinBoardServer.readBatch(BatchSpecificationMessage.newBuilder() + .setSignerId(completeBatch.getBeginBatchMessage().getSignerId()) + .setBatchId(completeBatch.getBeginBatchMessage().getBatchId()) + .setStartPosition(0) + .build()); + + assertThat("Non-matching batch data for batch " + completeBatch.getBeginBatchMessage().getBatchId(), + completeBatch.getBatchDataList().equals(batchDataList), is(true)); + + + + } + + } public void close(){ signers[0].clearSigningKey(); diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/MySQLBulletinBoardServerTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/MySQLBulletinBoardServerTest.java index e473931..42c11f7 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/MySQLBulletinBoardServerTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/MySQLBulletinBoardServerTest.java @@ -111,6 +111,39 @@ public class MySQLBulletinBoardServerTest { System.err.println("Time of operation: " + (end - start)); } + @Test + public void testBatchPostAfterClose() { + try{ + serverTest.testBatchPostAfterClose(); + } catch (Exception e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + } + + @Test + public void testBatch() { + + final int BATCH_NUM = 20; + + try{ + for (int i = 0 ; i < BATCH_NUM ; i++) { + serverTest.testPostBatch(); + } + } catch (Exception e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + + try{ + serverTest.testReadBatch(); + } catch (Exception e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + + } + @After public void close() { System.err.println("Starting to close MySQLBulletinBoardServerTest"); diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardConstants.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardConstants.java index 7fe3a43..0db1d3f 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardConstants.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardConstants.java @@ -16,6 +16,7 @@ public interface BulletinBoardConstants { // Other Constants - public static final String BATCH_TAG = "Batch"; + public static final String BATCH_TAG = "@BATCH"; + public static final String BATCH_ID_TAG_PREFIX = "#"; } diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/CompleteBatch.java b/meerkat-common/src/main/java/meerkat/bulletinboard/CompleteBatch.java index 6deec77..19c57e3 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/CompleteBatch.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/CompleteBatch.java @@ -22,6 +22,7 @@ public class CompleteBatch { } public CompleteBatch(BeginBatchMessage newBeginBatchMessage) { + this(); beginBatchMessage = newBeginBatchMessage; } @@ -47,6 +48,10 @@ public class CompleteBatch { return signature; } + public void setBeginBatchMessage(BeginBatchMessage beginBatchMessage) { + this.beginBatchMessage = beginBatchMessage; + } + public void appendBatchData(BatchData newBatchData) { batchDataList.add(newBatchData); } diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigitalSignature.java b/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigitalSignature.java index 422e8b0..7174b42 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigitalSignature.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigitalSignature.java @@ -3,7 +3,6 @@ package meerkat.bulletinboard; import com.google.protobuf.ByteString; import com.google.protobuf.Message; import meerkat.crypto.DigitalSignature; -import meerkat.protobuf.BulletinBoardAPI.BeginBatchMessage; import meerkat.protobuf.BulletinBoardAPI.BatchData; import meerkat.protobuf.Crypto; @@ -11,10 +10,11 @@ import java.io.IOException; import java.io.InputStream; import java.security.InvalidKeyException; import java.security.KeyStore; +import java.security.KeyStoreException; import java.security.SignatureException; +import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; -import java.util.List; /** * Created by Arbel Deutsch Peled on 20-Dec-15. @@ -77,6 +77,12 @@ public class GenericBatchDigitalSignature implements BatchDigitalSignature{ return digitalSignature.verify(); } + @Override + public KeyStore.Builder getPKCS12KeyStoreBuilder(InputStream keyStream, char[] password) + throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException { + return digitalSignature.getPKCS12KeyStoreBuilder(keyStream, password); + } + @Override public void loadSigningCertificate(KeyStore.Builder keyStoreBuilder) throws IOException, CertificateException, UnrecoverableKeyException { digitalSignature.loadSigningCertificate(keyStoreBuilder); diff --git a/meerkat-common/src/main/java/meerkat/crypto/DigitalSignature.java b/meerkat-common/src/main/java/meerkat/crypto/DigitalSignature.java index e7b64e5..76c32a6 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/DigitalSignature.java +++ b/meerkat-common/src/main/java/meerkat/crypto/DigitalSignature.java @@ -5,11 +5,13 @@ import com.google.protobuf.Message; import java.io.IOException; import java.io.InputStream; -import java.security.InvalidKeyException; import java.security.KeyStore; -import java.security.SignatureException; -import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; +import java.security.SignatureException; +import java.security.InvalidKeyException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; import static meerkat.protobuf.Crypto.*; /** @@ -71,6 +73,20 @@ public interface DigitalSignature { */ public boolean verify(); + /** + * Load a keystore from an input stream in PKCS12 format. + * + * @param keyStream + * @param password + * @return + * @throws IOException + * @throws CertificateException + * @throws KeyStoreException + * @throws NoSuchAlgorithmException + */ + public KeyStore.Builder getPKCS12KeyStoreBuilder(InputStream keyStream, char[] password) + throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException; + /** * Loads a private signing key. The keystore must include both the public and private * key parts. diff --git a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java index 28e4600..ab8084b 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java @@ -211,6 +211,7 @@ public class ECDSASignature implements DigitalSignature { * @throws KeyStoreException * @throws NoSuchAlgorithmException */ + @Override public KeyStore.Builder getPKCS12KeyStoreBuilder(InputStream keyStream, char[] password) throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException { KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE); From d643932ef966b3aa1f01c70e351bc15029bc9ad8 Mon Sep 17 00:00:00 2001 From: Arbel Deutsch Peled Date: Sun, 27 Dec 2015 12:04:37 +0200 Subject: [PATCH 06/49] Added H2 support for Batch messages --- bulletin-board-server/build.gradle | 5 ++ .../sqlserver/H2QueryProvider.java | 74 +++++++++++++++++++ .../H2BulletinBoardServerTest.java | 33 +++++++++ 3 files changed, 112 insertions(+) diff --git a/bulletin-board-server/build.gradle b/bulletin-board-server/build.gradle index 63ba47d..21604d1 100644 --- a/bulletin-board-server/build.gradle +++ b/bulletin-board-server/build.gradle @@ -84,6 +84,11 @@ task myTest(type: Test) { outputs.upToDateWhen { false } } +task h2Test(type: Test) { + include '**/*H2*Test*' + outputs.upToDateWhen { false } +} + task dbTest(type: Test) { include '**/*H2*Test*' include '**/*MySQL*Test*' diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java index d76601f..14bf9e2 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java @@ -7,6 +7,7 @@ import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; +import java.text.MessageFormat; import java.util.LinkedList; import java.util.List; @@ -42,6 +43,11 @@ public class H2QueryProvider implements BulletinBoardSQLServer.SQLQueryProvider case FIND_MSG_ID: return "SELECT EntryNum From MsgTable WHERE MsgId = :MsgId"; + case FIND_TAG_ID: + return MessageFormat.format( + "SELECT TagId FROM TagTable WHERE Tag = :{0}", + QueryType.FIND_TAG_ID.getParamName(0)); + case GET_MESSAGES: return "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable"; @@ -55,6 +61,63 @@ public class H2QueryProvider implements BulletinBoardSQLServer.SQLQueryProvider return "INSERT INTO TagTable(Tag) SELECT DISTINCT :Tag AS NewTag FROM UtilityTable WHERE" + " NOT EXISTS (SELECT 1 FROM TagTable AS SubTable WHERE SubTable.Tag = :Tag)"; + case GET_BATCH_MESSAGE_ENTRY: + return MessageFormat.format( + "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable" + + " INNER JOIN SignatureTable ON MsgTable.EntryNum = SignatureTable.EntryNum" + + " INNER JOIN MsgTagTable ON MsgTable.EntryNum = MsgTagTable.EntryNum" + + " INNER JOIN TagTable ON MsgTagTable.TagId = TagTable.TagId" + + " WHERE SignatureTable.SignerId = :{0}" + + " AND TagTable.Tag = :{1}", + QueryType.GET_BATCH_MESSAGE_ENTRY.getParamName(0), + QueryType.GET_BATCH_MESSAGE_ENTRY.getParamName(1)); + + case GET_BATCH_MESSAGE_DATA: + return MessageFormat.format( + "SELECT Data FROM BatchTable" + + " WHERE SignerId = :{0} AND BatchId = :{1} AND SerialNum >= :{2}" + + " ORDER BY SerialNum ASC", + QueryType.GET_BATCH_MESSAGE_DATA.getParamName(0), + QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1), + QueryType.GET_BATCH_MESSAGE_DATA.getParamName(2)); + + case INSERT_BATCH_DATA: + return MessageFormat.format( + "INSERT INTO BatchTable (SignerId, BatchId, SerialNum, Data)" + + " VALUES (:{0}, :{1}, :{2}, :{3})", + QueryType.INSERT_BATCH_DATA.getParamName(0), + QueryType.INSERT_BATCH_DATA.getParamName(1), + QueryType.INSERT_BATCH_DATA.getParamName(2), + QueryType.INSERT_BATCH_DATA.getParamName(3)); + + case CHECK_BATCH_LENGTH: + return MessageFormat.format( + "SELECT COUNT(Data) AS BatchLength FROM BatchTable" + + " WHERE SignerId = :{0} AND BatchId = :{1}", + QueryType.CHECK_BATCH_LENGTH.getParamName(0), + QueryType.CHECK_BATCH_LENGTH.getParamName(1)); + + case CONNECT_BATCH_TAG: + return MessageFormat.format( + "INSERT INTO BatchTagTable (SignerId, BatchId, TagId) SELECT :{0}, :{1}, TagId FROM TagTable" + + " WHERE Tag = :{2}", + QueryType.CONNECT_BATCH_TAG.getParamName(0), + QueryType.CONNECT_BATCH_TAG.getParamName(1), + QueryType.CONNECT_BATCH_TAG.getParamName(2)); + + case GET_BATCH_TAGS: + return MessageFormat.format( + "SELECT Tag FROM TagTable INNER JOIN BatchTagTable ON TagTable.TagId = BatchTagTable.TagId" + + " WHERE SignerId = :{0} AND BatchId = :{1} ORDER BY Tag ASC", + QueryType.GET_BATCH_TAGS.getParamName(0), + QueryType.GET_BATCH_TAGS.getParamName(1)); + + case REMOVE_BATCH_TAGS: + return MessageFormat.format( + "DELETE FROM BatchTagTable WHERE SignerId = :{0} AND BatchId = :{1}", + QueryType.REMOVE_BATCH_TAGS.getParamName(0), + QueryType.REMOVE_BATCH_TAGS.getParamName(1)); + default: throw new IllegalArgumentException("Cannot serve a query of type " + queryType); } @@ -139,6 +202,14 @@ public class H2QueryProvider implements BulletinBoardSQLServer.SQLQueryProvider list.add("CREATE INDEX IF NOT EXISTS SignerIndex ON SignatureTable(SignerId)"); list.add("CREATE UNIQUE INDEX IF NOT EXISTS SignerIndex ON SignatureTable(SignerId, EntryNum)"); + list.add("CREATE TABLE IF NOT EXISTS BatchTable (SignerId TINYBLOB, BatchId INT, SerialNum INT, Data BLOB," + + " UNIQUE(SignerId, BatchId, SerialNum))"); + + list.add("CREATE TABLE IF NOT EXISTS BatchTagTable (SignerId TINYBLOB, BatchId INT, TagId INT," + + " FOREIGN KEY (TagId) REFERENCES TagTable(TagId))"); + + list.add("CREATE INDEX IF NOT EXISTS BatchIndex ON BatchTagTable(SignerId, BatchId)"); + // This is used to create a simple table with one entry. // It is used for implementing a workaround for the missing INSERT IGNORE syntax list.add("CREATE TABLE IF NOT EXISTS UtilityTable (Entry INT)"); @@ -152,6 +223,9 @@ public class H2QueryProvider implements BulletinBoardSQLServer.SQLQueryProvider List list = new LinkedList(); list.add("DROP TABLE IF EXISTS UtilityTable"); + list.add("DROP INDEX IF EXISTS BatchIndex"); + list.add("DROP TABLE IF EXISTS BatchTagTable"); + list.add("DROP TABLE IF EXISTS BatchTable"); list.add("DROP INDEX IF EXISTS SignerIdIndex"); list.add("DROP TABLE IF EXISTS MsgTagTable"); list.add("DROP TABLE IF EXISTS SignatureTable"); diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/H2BulletinBoardServerTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/H2BulletinBoardServerTest.java index ef19310..577c9be 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/H2BulletinBoardServerTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/H2BulletinBoardServerTest.java @@ -107,6 +107,39 @@ public class H2BulletinBoardServerTest { System.err.println("Time of operation: " + (end - start)); } + @Test + public void testBatchPostAfterClose() { + try{ + serverTest.testBatchPostAfterClose(); + } catch (Exception e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + } + + @Test + public void testBatch() { + + final int BATCH_NUM = 20; + + try{ + for (int i = 0 ; i < BATCH_NUM ; i++) { + serverTest.testPostBatch(); + } + } catch (Exception e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + + try{ + serverTest.testReadBatch(); + } catch (Exception e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + + } + @After public void close() { System.err.println("Starting to close H2BulletinBoardServerTest"); From 7e542a804c0306b42520c71587012a68e9fa99fc Mon Sep 17 00:00:00 2001 From: Arbel Deutsch Peled Date: Sat, 2 Jan 2016 12:38:53 +0200 Subject: [PATCH 07/49] Fixed MySQL exclusion from standard test --- bulletin-board-server/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bulletin-board-server/build.gradle b/bulletin-board-server/build.gradle index eb197c9..0bc5452 100644 --- a/bulletin-board-server/build.gradle +++ b/bulletin-board-server/build.gradle @@ -75,7 +75,7 @@ dependencies { test { exclude '**/*SQLite*Test*' exclude '**/*H2*Test*' - exclude '**/*MySql*Test' + exclude '**/*MySQL*Test*' exclude '**/*IntegrationTest*' } From 141d286af26dc0663da74376f002e8b18ba6f005 Mon Sep 17 00:00:00 2001 From: Arbel Deutsch Peled Date: Sun, 17 Jan 2016 10:59:05 +0200 Subject: [PATCH 08/49] Dual-layered threaded BB Client. Supports basic functionality. Does not support Batch Messages yet. --- .../bulletinboard/BulletinClientJob.java | 82 ------- .../BulletinClientJobResult.java | 29 --- .../bulletinboard/BulletinClientWorker.java | 224 ++--------------- .../bulletinboard/MultiServerWorker.java | 104 ++++++++ .../SingleServerBulletinBoardClient.java | 228 ++++++++++++++++++ .../bulletinboard/SingleServerWorker.java | 39 +++ .../ThreadedBulletinBoardClient.java | 95 ++++++-- .../callbacks/ClientFutureCallback.java | 19 -- .../GetRedundancyFutureCallback.java | 38 --- .../callbacks/PostMessageFutureCallback.java | 44 ---- .../callbacks/ReadMessagesFutureCallback.java | 35 --- .../MultiServerGetRedundancyWorker.java | 74 ++++++ .../workers/MultiServerPostBatchWorker.java | 7 + .../workers/MultiServerPostMessageWorker.java | 72 ++++++ .../MultiServerReadMessagesWorker.java | 65 +++++ .../SingleServerGetRedundancyWorker.java | 79 ++++++ .../SingleServerPostMessageWorker.java | 61 +++++ .../SingleServerReadMessagesWorker.java | 68 ++++++ .../BulletinBoardClientIntegrationTest.java | 4 +- meerkat-common/build.gradle | 2 +- .../AsyncBulletinBoardClient.java | 44 +++- 21 files changed, 927 insertions(+), 486 deletions(-) delete mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientJob.java delete mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientJobResult.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/MultiServerWorker.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerWorker.java delete mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ClientFutureCallback.java delete mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/GetRedundancyFutureCallback.java delete mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/PostMessageFutureCallback.java delete mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ReadMessagesFutureCallback.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerGetRedundancyWorker.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerPostBatchWorker.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerPostMessageWorker.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerReadMessagesWorker.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/SingleServerGetRedundancyWorker.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/SingleServerPostMessageWorker.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/SingleServerReadMessagesWorker.java diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientJob.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientJob.java deleted file mode 100644 index aca98d4..0000000 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientJob.java +++ /dev/null @@ -1,82 +0,0 @@ -package meerkat.bulletinboard; - -import com.google.protobuf.Message; - -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -/** - * Created by Arbel Deutsch Peled on 09-Dec-15. - * - * This class specifies the job that is required of a Bulletin Board Client Worker - */ -public class BulletinClientJob { - - public static enum JobType{ - POST_MESSAGE, // Post a message to servers - READ_MESSAGES, // Read messages according to some given filter (any server will do) - GET_REDUNDANCY // Check the redundancy of a specific message in the databases - } - - private List serverAddresses; - - private int minServers; // The minimal number of servers the job must be successful on for the job to be completed - - private final JobType jobType; - - private final Message payload; // The information associated with the job type - - private int maxRetry; // Number of retries for this job; set to -1 for infinite retries - - public BulletinClientJob(List serverAddresses, int minServers, JobType jobType, Message payload, int maxRetry) { - this.serverAddresses = serverAddresses; - this.minServers = minServers; - this.jobType = jobType; - this.payload = payload; - this.maxRetry = maxRetry; - } - - public void updateServerAddresses(List newServerAdresses) { - this.serverAddresses = newServerAdresses; - } - - public List getServerAddresses() { - return serverAddresses; - } - - public int getMinServers() { - return minServers; - } - - public JobType getJobType() { - return jobType; - } - - public Message getPayload() { - return payload; - } - - public int getMaxRetry() { - return maxRetry; - } - - public void shuffleAddresses() { - Collections.shuffle(serverAddresses); - } - - public void decMinServers(){ - minServers--; - } - - public void decMaxRetry(){ - if (maxRetry > 0) { - maxRetry--; - } - } - - public boolean isRetry(){ - return (maxRetry != 0); - } - -} \ No newline at end of file diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientJobResult.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientJobResult.java deleted file mode 100644 index be0501b..0000000 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientJobResult.java +++ /dev/null @@ -1,29 +0,0 @@ -package meerkat.bulletinboard; - -import com.google.protobuf.Message; - -/** - * Created by Arbel Deutsch Peled on 09-Dec-15. - * - * This class contains the end status and result of a Bulletin Board Client Job. - */ -public final class BulletinClientJobResult { - - private final BulletinClientJob job; // Stores the job the result refers to - - private final Message result; // The result of the job; valid only if success==true - - public BulletinClientJobResult(BulletinClientJob job, Message result) { - this.job = job; - this.result = result; - } - - public BulletinClientJob getJob() { - return job; - } - - public Message getResult() { - return result; - } - -} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java index f03ab31..dba596b 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java @@ -1,218 +1,38 @@ package meerkat.bulletinboard; -import com.google.protobuf.Message; -import meerkat.comm.CommunicationException; -import meerkat.crypto.Digest; -import meerkat.crypto.concrete.SHA256Digest; -import meerkat.protobuf.BulletinBoardAPI.*; -import meerkat.rest.Constants; -import meerkat.rest.ProtobufMessageBodyReader; -import meerkat.rest.ProtobufMessageBodyWriter; -import static meerkat.bulletinboard.BulletinBoardConstants.*; - -import javax.ws.rs.ProcessingException; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.Response; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.Callable; - /** * Created by Arbel Deutsch Peled on 09-Dec-15. * - * This class implements the actual communication with the Bulletin Board Servers. + * This class handles bulletin client work. * It is meant to be used in a multi-threaded environment. */ -//TODO: Maybe make this abstract and inherit from it. -public class BulletinClientWorker implements Callable { +public abstract class BulletinClientWorker { - private final BulletinClientJob job; // The requested job to be handled + protected IN payload; // Payload of the job - public BulletinClientWorker(BulletinClientJob job){ - this.job = job; + private int maxRetry; // Number of retries for this job; set to -1 for infinite retries + + public BulletinClientWorker(IN payload, int maxRetry) { + this.payload = payload; + this.maxRetry = maxRetry; } - // This resource enabled creation of a single Client per thread. - private static final ThreadLocal clientLocal = - new ThreadLocal () { - @Override protected Client initialValue() { - Client client; - client = ClientBuilder.newClient(); - client.register(ProtobufMessageBodyReader.class); - client.register(ProtobufMessageBodyWriter.class); + public IN getPayload() { + return payload; + } - return client; - } - }; - - // This resource enables creation of a single Digest per thread. - private static final ThreadLocal digestLocal = - new ThreadLocal () { - @Override protected Digest initialValue() { - Digest digest; - digest = new SHA256Digest(); //TODO: Make this generic. - - return digest; - } - }; - - /** - * This method carries out the actual communication with the servers via HTTP Post - * It accesses the servers according to the job it received and updates said job as it goes - * The method will only iterate once through the server list, removing servers from the list when they are no longer required - * In a POST_MESSAGE job: successful post to a server results in removing the server from the list - * In a GET_REDUNDANCY job: no server is removed from the list and the (absolute) number of servers in which the message was found is returned - * In a READ_MESSAGES job: successful retrieval from any server terminates the method and returns the received values; The list is not changed - * @return The original job, modified to fit the current state and the required output (if any) of the operation - * @throws IllegalArgumentException - * @throws CommunicationException - */ - public BulletinClientJobResult call() throws IllegalArgumentException, CommunicationException{ - - Client client = clientLocal.get(); - Digest digest = digestLocal.get(); - - WebTarget webTarget; - Response response; - - String requestPath; - Message msg; - - List serverAddresses = new LinkedList(job.getServerAddresses()); - - Message payload = job.getPayload(); - - BulletinBoardMessageList msgList; - - int count = 0; // Used to count number of servers which contain the required message in a GET_REDUNDANCY request. - - job.shuffleAddresses(); // This is done to randomize the order of access to servers primarily for READ operations - - // Prepare the request. - switch(job.getJobType()) { - - case POST_MESSAGE: - // Make sure the payload is a BulletinBoardMessage - if (!(payload instanceof BulletinBoardMessage)) { - throw new IllegalArgumentException("Cannot post an object that is not an instance of BulletinBoardMessage"); - } - - msg = payload; - requestPath = POST_MESSAGE_PATH; - break; - - case READ_MESSAGES: - // Make sure the payload is a MessageFilterList - if (!(payload instanceof MessageFilterList)) { - throw new IllegalArgumentException("Read failed: an instance of MessageFilterList is required as payload for a READ_MESSAGES operation"); - } - - msg = payload; - requestPath = READ_MESSAGES_PATH; - break; - - case GET_REDUNDANCY: - // Make sure the payload is a MessageId - if (!(payload instanceof MessageID)) { - throw new IllegalArgumentException("Cannot search for an object that is not an instance of MessageID"); - } - - requestPath = READ_MESSAGES_PATH; - - msg = MessageFilterList.newBuilder() - .addFilter(MessageFilter.newBuilder() - .setType(FilterType.MSG_ID) - .setId(((MessageID) payload).getID()) - .build() - ).build(); - - break; - - default: - throw new IllegalArgumentException("Unsupported job type"); - - } - - // Iterate through servers - - Iterator addressIterator = serverAddresses.iterator(); - - while (addressIterator.hasNext()) { - - // Send request to Server - String address = addressIterator.next(); - webTarget = client.target(address).path(BULLETIN_BOARD_SERVER_PATH).path(requestPath); - response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(msg, Constants.MEDIATYPE_PROTOBUF)); - - // Retrieve answer - switch(job.getJobType()) { - - case POST_MESSAGE: - try { - - response.readEntity(BoolMsg.class); // If a BoolMsg entity is returned: the post was successful - addressIterator.remove(); // Post to this server succeeded: remove server from list - job.decMinServers(); - - } catch (ProcessingException | IllegalStateException e) {} // Post to this server failed: retry next time - finally { - response.close(); - } - break; - - case GET_REDUNDANCY: - try { - msgList = response.readEntity(BulletinBoardMessageList.class); // If a BulletinBoardMessageList is returned: the read was successful - - if (msgList.getMessageList().size() > 0){ // Message was found in the server. - count++; - } - } catch (ProcessingException | IllegalStateException e) {} // Read failed: try with next server - finally { - response.close(); - } - break; - - case READ_MESSAGES: - try { - msgList = response.readEntity(BulletinBoardMessageList.class); // If a BulletinBoardMessageList is returned: the read was successful - return new BulletinClientJobResult(job, msgList); // Return the result - } catch (ProcessingException | IllegalStateException e) {} // Read failed: try with next server - finally { - response.close(); - } - break; - - } - - } - - // Return result (if haven't done so yet) - switch(job.getJobType()) { - - case POST_MESSAGE: - // The job now contains the information required to ascertain whether enough server posts have succeeded - // It will also contain the list of servers in which the post was not successful - job.updateServerAddresses(serverAddresses); - return new BulletinClientJobResult(job, null); - - case GET_REDUNDANCY: - // Return the number of servers in which the message was found - // The job now contains the list of these servers - return new BulletinClientJobResult(job, IntMsg.newBuilder().setValue(count).build()); - - case READ_MESSAGES: - // A successful operation would have already returned an output - // Therefore: no server access was successful - throw new CommunicationException("Could not access any server"); - - default: // This is required for successful compilation - throw new IllegalArgumentException("Unsupported job type"); + public int getMaxRetry() { + return maxRetry; + } + public void decMaxRetry(){ + if (maxRetry > 0) { + maxRetry--; } } + + public boolean isRetry(){ + return (maxRetry != 0); + } + } diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/MultiServerWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/MultiServerWorker.java new file mode 100644 index 0000000..8db836f --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/MultiServerWorker.java @@ -0,0 +1,104 @@ +package meerkat.bulletinboard; + +import com.google.common.util.concurrent.FutureCallback; + +import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; + +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Created by Arbel Deutsch Peled on 09-Dec-15. + * + * This is a general class for handling multi-server work + * It utilizes Single Server Clients to perform the actual per-server work + */ +public abstract class MultiServerWorker extends BulletinClientWorker implements Runnable, ClientCallback{ + + private List clients; + + protected AtomicInteger minServers; // The minimal number of servers the job must be successful on for the job to be completed + + protected AtomicInteger maxFailedServers; // The maximal number of allowed server failures + + private AtomicBoolean returnedResult; + + private ClientCallback clientCallback; + + /** + * Constructor + * @param clients contains a list of Single Server clients to handle requests + * @param shuffleClients is a boolean stating whether or not it is needed to shuffle the clients + * @param minServers is the minimal amount of servers needed in order to successfully complete the job + * @param payload is the payload for the job + * @param maxRetry is the maximal per-server retry count + * @param clientCallback contains the callback methods used to report the result back to the client + */ + public MultiServerWorker(List clients, boolean shuffleClients, + int minServers, IN payload, int maxRetry, + ClientCallback clientCallback) { + + super(payload,maxRetry); + + this.clients = clients; + if (shuffleClients){ + Collections.shuffle(clients); + } + + this.minServers = new AtomicInteger(minServers); + maxFailedServers = new AtomicInteger(clients.size() - minServers); + this.clientCallback = clientCallback; + + returnedResult = new AtomicBoolean(false); + + } + + /** + * Constructor overload without client shuffling + */ + public MultiServerWorker(List clients, + int minServers, IN payload, int maxRetry, + ClientCallback clientCallback) { + + this(clients, false, minServers, payload, maxRetry, clientCallback); + + } + + /** + * Used to report a successful operation to the client + * Only reports once to the client + * @param result is the result + */ + protected void succeed(OUT result){ + if (returnedResult.compareAndSet(false, true)) { + clientCallback.handleCallback(result); + } + } + + /** + * Used to report a failed operation to the client + * Only reports once to the client + * @param t contains the error/exception that occurred + */ + protected void fail(Throwable t){ + if (returnedResult.compareAndSet(false, true)) { + clientCallback.handleFailure(t); + } + } + + /** + * Used by implementations to get a Single Server Client iterator + * @return the requested iterator + */ + protected Iterator getClientIterator() { + return clients.iterator(); + } + + protected int getClientNumber() { + return clients.size(); + } + +} \ No newline at end of file diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java new file mode 100644 index 0000000..e92f35b --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java @@ -0,0 +1,228 @@ +package meerkat.bulletinboard; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListeningScheduledExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.protobuf.ByteString; +import meerkat.bulletinboard.workers.SingleServerGetRedundancyWorker; +import meerkat.bulletinboard.workers.SingleServerPostMessageWorker; +import meerkat.bulletinboard.workers.SingleServerReadMessagesWorker; +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Voting.BulletinBoardClientParams; + +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * Created by Arbel Deutsch Peled on 28-Dec-15. + * + * This class implements the asynchronous Bulletin Board Client interface + * It only handles a single Bulletin Board Server + * If the list of servers contains more than one server: the server actually used is the first one + * The class further implements a delayed access to the server after a communication error occurs + */ +public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient implements AsyncBulletinBoardClient { + + private final int MAX_RETRIES = 10; + + protected ListeningScheduledExecutorService executorService; + + private long lastServerErrorTime; + + protected final long failDelayInMilliseconds; + + /** + * Notify the client that a job has failed + * This makes new scheduled jobs be scheduled for a later time (after the given delay) + */ + protected void fail() { + + // Update last fail time + lastServerErrorTime = System.currentTimeMillis(); + + } + + /** + * This method adds a worker to the scheduled queue of the threadpool + * If the server is in an accessible state: the job is submitted for immediate handling + * If the server is not accessible: the job is scheduled for a later time + * @param worker is the worker that should be scheduled for work + * @param callback is the class containing callbacks for handling job completion/failure + */ + protected void scheduleWorker(SingleServerWorker worker, FutureCallback callback){ + + long timeSinceLastServerError = System.currentTimeMillis() - lastServerErrorTime; + + if (timeSinceLastServerError >= failDelayInMilliseconds) { + + // Schedule for immediate processing + Futures.addCallback(executorService.submit(worker), callback); + + } else { + + // Schedule for processing immediately following delay expiry + Futures.addCallback(executorService.schedule( + worker, + failDelayInMilliseconds - timeSinceLastServerError, + TimeUnit.MILLISECONDS), + callback); + + } + + } + + /** + * Inner class for handling simple operation results and retrying if needed + */ + class RetryCallback implements FutureCallback { + + private SingleServerWorker worker; + private ClientCallback clientCallback; + + public RetryCallback(SingleServerWorker worker, ClientCallback clientCallback) { + this.worker = worker; + this.clientCallback = clientCallback; + } + + @Override + public void onSuccess(T result) { + clientCallback.handleCallback(result); + } + + @Override + public void onFailure(Throwable t) { + + // Notify client about failure + fail(); + + // Check if another attempt should be made + + worker.decMaxRetry(); + + if (worker.isRetry()) { + // Perform another attempt + scheduleWorker(worker, this); + } else { + // No more retries: notify caller about failure + clientCallback.handleFailure(t); + } + + } + + } + + + public SingleServerBulletinBoardClient(int threadPoolSize, long failDelayInMilliseconds) { + + executorService = MoreExecutors.listeningDecorator(Executors.newScheduledThreadPool(threadPoolSize)); + + this.failDelayInMilliseconds = failDelayInMilliseconds; + + // Set server error time to a time sufficiently in the past to make new jobs go through + lastServerErrorTime = System.currentTimeMillis() - failDelayInMilliseconds; + + } + + /** + * Stores database location, initializes the web Client and + * @param clientParams contains the data needed to access the DBs + */ + @Override + public void init(BulletinBoardClientParams clientParams) { + + // Perform usual setup + super.init(clientParams); + + // Remove all but first DB address + String dbAddress = meerkatDBs.get(0); + meerkatDBs = new LinkedList(); + meerkatDBs.add(dbAddress); + + } + + @Override + public MessageID postMessage(BulletinBoardMessage msg, ClientCallback callback) { + + // Create worker with redundancy 1 and MAX_RETRIES retries + SingleServerPostMessageWorker worker = new SingleServerPostMessageWorker(meerkatDBs.get(0), msg, MAX_RETRIES); + + // Submit worker and create callback + scheduleWorker(worker, new RetryCallback(worker, callback)); + + // Calculate the correct message ID and return it + digest.reset(); + digest.update(msg.getMsg()); + return MessageID.newBuilder().setID(ByteString.copyFrom(digest.digest())).build(); + + } + + @Override + public MessageID postBatch(CompleteBatch completeBatch, ClientCallback callback) { + return null; + } + + @Override + public void beginBatch(byte[] signerId, int batchId, List tagList, ClientCallback callback) { + + } + + @Override + public void postBatchData(byte[] signerId, int batchId, List batchDataList, + int startPosition, ClientCallback callback) { + + } + + @Override + public void postBatchData(byte[] signerId, int batchId, List batchDataList, ClientCallback callback) { + + } + + @Override + public void closeBatch(CloseBatchMessage closeBatchMessage, ClientCallback callback) { + + } + + @Override + public void getRedundancy(MessageID id, ClientCallback callback) { + + // Create worker with no retries + SingleServerGetRedundancyWorker worker = new SingleServerGetRedundancyWorker(meerkatDBs.get(0), id, 1); + + // Submit job and create callback + scheduleWorker(worker, new RetryCallback(worker, callback)); + + } + + @Override + public void readMessages(MessageFilterList filterList, ClientCallback> callback) { + + // Create job with no retries + SingleServerReadMessagesWorker worker = new SingleServerReadMessagesWorker(meerkatDBs.get(0), filterList, 1); + + // Submit job and create callback + scheduleWorker(worker, new RetryCallback(worker, callback)); + + } + + @Override + public void readBatch(byte[] signerId, int batchId, ClientCallback callback) { + + } + + @Override + public void subscribe(MessageFilterList filterList, MessageHandler messageHandler) { + + } + + @Override + public void close() { + + super.close(); + + executorService.shutdown(); + + } +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerWorker.java new file mode 100644 index 0000000..82ca886 --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerWorker.java @@ -0,0 +1,39 @@ +package meerkat.bulletinboard; + +import meerkat.rest.ProtobufMessageBodyReader; +import meerkat.rest.ProtobufMessageBodyWriter; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import java.util.concurrent.Callable; + +/** + * Created by Arbel Deutsch Peled on 02-Jan-16. + */ +public abstract class SingleServerWorker extends BulletinClientWorker implements Callable{ + + // This resource enabled creation of a single Client per thread. + protected static final ThreadLocal clientLocal = + new ThreadLocal () { + @Override protected Client initialValue() { + Client client; + client = ClientBuilder.newClient(); + client.register(ProtobufMessageBodyReader.class); + client.register(ProtobufMessageBodyWriter.class); + + return client; + } + }; + + protected String serverAddress; + + public SingleServerWorker(String serverAddress, IN payload, int maxRetry) { + super(payload, maxRetry); + this.serverAddress = serverAddress; + } + + public String getServerAddress() { + return serverAddress; + } + +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java index 71d852e..ce7a01e 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java @@ -1,15 +1,17 @@ package meerkat.bulletinboard; -import com.google.common.util.concurrent.*; import com.google.protobuf.ByteString; -import meerkat.bulletinboard.callbacks.GetRedundancyFutureCallback; -import meerkat.bulletinboard.callbacks.PostMessageFutureCallback; -import meerkat.bulletinboard.callbacks.ReadMessagesFutureCallback; + +import meerkat.bulletinboard.workers.MultiServerGetRedundancyWorker; +import meerkat.bulletinboard.workers.MultiServerPostMessageWorker; +import meerkat.bulletinboard.workers.MultiServerReadMessagesWorker; import meerkat.comm.CommunicationException; import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.protobuf.Voting.*; +import java.util.ArrayList; import java.util.List; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -22,10 +24,19 @@ import java.util.concurrent.TimeUnit; */ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient implements AsyncBulletinBoardClient { - private final static int THREAD_NUM = 10; - ListeningExecutorService listeningExecutor; + // Executor service for handling jobs + private final static int JOBS_THREAD_NUM = 5; + ExecutorService executorService; + // Per-server clients + List clients; + + private final static int POST_MESSAGE_RETRY_NUM = 3; private final static int READ_MESSAGES_RETRY_NUM = 1; + private final static int GET_REDUNDANCY_RETRY_NUM = 1; + + private static final int SERVER_THREADPOOL_SIZE = 5; + private static final long FAIL_DELAY = 5000; private int minAbsoluteRedundancy; @@ -42,7 +53,16 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple minAbsoluteRedundancy = (int) (clientParams.getMinRedundancy() * clientParams.getBulletinBoardAddressCount()); - listeningExecutor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(THREAD_NUM)); + executorService = Executors.newFixedThreadPool(JOBS_THREAD_NUM); + + clients = new ArrayList(clientParams.getBulletinBoardAddressCount()); + for (String address : clientParams.getBulletinBoardAddressList()){ + SingleServerBulletinBoardClient client = new SingleServerBulletinBoardClient(SERVER_THREADPOOL_SIZE, FAIL_DELAY); + client.init(BulletinBoardClientParams.newBuilder() + .addBulletinBoardAddress(address) + .build()); + clients.add(client); + } } @@ -54,28 +74,52 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple * @throws CommunicationException */ @Override - public MessageID postMessage(BulletinBoardMessage msg, ClientCallback callback){ + public MessageID postMessage(BulletinBoardMessage msg, ClientCallback callback){ // Create job - BulletinClientJob job = new BulletinClientJob(meerkatDBs, minAbsoluteRedundancy, BulletinClientJob.JobType.POST_MESSAGE, msg, -1); + MultiServerPostMessageWorker worker = + new MultiServerPostMessageWorker(clients, minAbsoluteRedundancy, msg, POST_MESSAGE_RETRY_NUM, callback); - // Submit job and create callback - Futures.addCallback(listeningExecutor.submit(new BulletinClientWorker(job)), new PostMessageFutureCallback(listeningExecutor, callback)); + // Submit job + executorService.submit(worker); // Calculate the correct message ID and return it digest.reset(); digest.update(msg.getMsg()); return MessageID.newBuilder().setID(ByteString.copyFrom(digest.digest())).build(); + } @Override - public MessageID postBatch(byte[] signerId, int batchId, List batchDataList, int startPosition, ClientCallback callback) { - return null; //TODO: Implement + public MessageID postBatch(CompleteBatch completeBatch, ClientCallback callback) { + + return null; // TODO: write this + } @Override - public MessageID postBatch(byte[] signerId, int batchId, List batchDataList, ClientCallback callback) { - return null; //TODO: Implement + public void beginBatch(byte[] signerId, int batchId, List tagList, ClientCallback callback) { + // TODO: write this + } + + @Override + public void postBatchData(byte[] signerId, int batchId, List batchDataList, + int startPosition, ClientCallback callback) { + + // TODO: write this + + } + + @Override + public void postBatchData(byte[] signerId, int batchId, List batchDataList, ClientCallback callback) { + + postBatchData(signerId, batchId, batchDataList, 0, callback); // Write batch from beginning + + } + + @Override + public void closeBatch(CloseBatchMessage closeBatchMessage, ClientCallback callback) { + // TODO: write this } /** @@ -88,10 +132,11 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple public void getRedundancy(MessageID id, ClientCallback callback) { // Create job - BulletinClientJob job = new BulletinClientJob(meerkatDBs, minAbsoluteRedundancy, BulletinClientJob.JobType.GET_REDUNDANCY, id, 1); + MultiServerGetRedundancyWorker worker = + new MultiServerGetRedundancyWorker(clients, minAbsoluteRedundancy, id, GET_REDUNDANCY_RETRY_NUM, callback); - // Submit job and create callback - Futures.addCallback(listeningExecutor.submit(new BulletinClientWorker(job)), new GetRedundancyFutureCallback(listeningExecutor, callback)); + // Submit job + executorService.submit(worker); } @@ -104,11 +149,11 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple public void readMessages(MessageFilterList filterList, ClientCallback> callback) { // Create job - BulletinClientJob job = new BulletinClientJob(meerkatDBs, minAbsoluteRedundancy, BulletinClientJob.JobType.READ_MESSAGES, - filterList, READ_MESSAGES_RETRY_NUM); + MultiServerReadMessagesWorker worker = + new MultiServerReadMessagesWorker(clients, minAbsoluteRedundancy, filterList, READ_MESSAGES_RETRY_NUM, callback); - // Submit job and create callback - Futures.addCallback(listeningExecutor.submit(new BulletinClientWorker(job)), new ReadMessagesFutureCallback(listeningExecutor, callback)); + // Submit job + executorService.submit(worker); } @@ -127,9 +172,9 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple super.close(); try { - listeningExecutor.shutdown(); - while (! listeningExecutor.isShutdown()) { - listeningExecutor.awaitTermination(10, TimeUnit.SECONDS); + executorService.shutdown(); + while (! executorService.isShutdown()) { + executorService.awaitTermination(10, TimeUnit.SECONDS); } } catch (InterruptedException e) { System.err.println(e.getCause() + " " + e.getMessage()); diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ClientFutureCallback.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ClientFutureCallback.java deleted file mode 100644 index 54cc63a..0000000 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ClientFutureCallback.java +++ /dev/null @@ -1,19 +0,0 @@ -package meerkat.bulletinboard.callbacks; - -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.ListeningExecutorService; -import meerkat.bulletinboard.BulletinClientJobResult; - -/** - * This is a future callback used to listen to workers and run on job finish - * Depending on the type of job and the finishing status of the worker: a decision is made whether to retry or return an error - */ -public abstract class ClientFutureCallback implements FutureCallback { - - protected ListeningExecutorService listeningExecutor; - - ClientFutureCallback(ListeningExecutorService listeningExecutor) { - this.listeningExecutor = listeningExecutor; - } - -} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/GetRedundancyFutureCallback.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/GetRedundancyFutureCallback.java deleted file mode 100644 index 719428f..0000000 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/GetRedundancyFutureCallback.java +++ /dev/null @@ -1,38 +0,0 @@ -package meerkat.bulletinboard.callbacks; - -import com.google.common.util.concurrent.ListeningExecutorService; -import meerkat.bulletinboard.AsyncBulletinBoardClient.*; -import meerkat.bulletinboard.BulletinClientJobResult; -import meerkat.protobuf.BulletinBoardAPI.*; - -import java.util.List; - -/** - * This is a future callback used to listen to workers and run on job finish - * Depending on the type of job and the finishing status of the worker: a decision is made whether to retry or return an error - */ -public class GetRedundancyFutureCallback extends ClientFutureCallback { - - private ClientCallback callback; - - public GetRedundancyFutureCallback(ListeningExecutorService listeningExecutor, - ClientCallback callback) { - super(listeningExecutor); - this.callback = callback; - } - - @Override - public void onSuccess(BulletinClientJobResult result) { - - int absoluteRedundancy = ((IntMsg) result.getResult()).getValue(); - int totalServers = result.getJob().getServerAddresses().size(); - - callback.handleCallback( ((float) absoluteRedundancy) / ((float) totalServers) ); - - } - - @Override - public void onFailure(Throwable t) { - callback.handleFailure(t); - } -} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/PostMessageFutureCallback.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/PostMessageFutureCallback.java deleted file mode 100644 index abd4247..0000000 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/PostMessageFutureCallback.java +++ /dev/null @@ -1,44 +0,0 @@ -package meerkat.bulletinboard.callbacks; - -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListeningExecutorService; -import meerkat.bulletinboard.AsyncBulletinBoardClient.*; -import meerkat.bulletinboard.BulletinClientJob; -import meerkat.bulletinboard.BulletinClientJobResult; -import meerkat.bulletinboard.BulletinClientWorker; - - -/** - * This is a future callback used to listen to workers and run on job finish - * Depending on the type of job and the finishing status of the worker: a decision is made whether to retry or return an error - */ -public class PostMessageFutureCallback extends ClientFutureCallback { - - private ClientCallback callback; - - public PostMessageFutureCallback(ListeningExecutorService listeningExecutor, - ClientCallback callback) { - super(listeningExecutor); - this.callback = callback; - } - - @Override - public void onSuccess(BulletinClientJobResult result) { - - BulletinClientJob job = result.getJob(); - - job.decMaxRetry(); - - // If redundancy is below threshold: retry - if (job.getMinServers() > 0 && job.isRetry()) { - Futures.addCallback(listeningExecutor.submit(new BulletinClientWorker(job)), this); - } - - callback.handleCallback(null); - } - - @Override - public void onFailure(Throwable t) { - callback.handleFailure(t); - } -} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ReadMessagesFutureCallback.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ReadMessagesFutureCallback.java deleted file mode 100644 index 808b7a6..0000000 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ReadMessagesFutureCallback.java +++ /dev/null @@ -1,35 +0,0 @@ -package meerkat.bulletinboard.callbacks; - -import com.google.common.util.concurrent.ListeningExecutorService; -import meerkat.bulletinboard.AsyncBulletinBoardClient.*; -import meerkat.bulletinboard.BulletinClientJobResult; -import meerkat.protobuf.BulletinBoardAPI; - -import java.util.List; - -/** - * This is a future callback used to listen to workers and run on job finish - * Depending on the type of job and the finishing status of the worker: a decision is made whether to retry or return an error - */ -public class ReadMessagesFutureCallback extends ClientFutureCallback { - - private ClientCallback> callback; - - public ReadMessagesFutureCallback(ListeningExecutorService listeningExecutor, - ClientCallback> callback) { - super(listeningExecutor); - this.callback = callback; - } - - @Override - public void onSuccess(BulletinClientJobResult result) { - - callback.handleCallback(((BulletinBoardAPI.BulletinBoardMessageList) result.getResult()).getMessageList()); - - } - - @Override - public void onFailure(Throwable t) { - callback.handleFailure(t); - } -} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerGetRedundancyWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerGetRedundancyWorker.java new file mode 100644 index 0000000..4d5e7f2 --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerGetRedundancyWorker.java @@ -0,0 +1,74 @@ +package meerkat.bulletinboard.workers; + +import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; +import meerkat.bulletinboard.MultiServerWorker; +import meerkat.bulletinboard.SingleServerBulletinBoardClient; +import meerkat.comm.CommunicationException; +import meerkat.protobuf.BulletinBoardAPI.*; + +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Created by Arbel Deutsch Peled on 27-Dec-15. + */ +public class MultiServerGetRedundancyWorker extends MultiServerWorker { + + private AtomicInteger serversContainingMessage; + private AtomicInteger totalContactedServers; + + public MultiServerGetRedundancyWorker(List clients, + int minServers, MessageID payload, int maxRetry, + ClientCallback clientCallback) { + + super(clients, minServers, payload, maxRetry, clientCallback); // Shuffle clients on creation to balance load + + serversContainingMessage = new AtomicInteger(0); + totalContactedServers = new AtomicInteger(0); + + } + + /** + * This method carries out the actual communication with the servers via HTTP Post + * It accesses the servers in a random order until one answers it + * Successful retrieval from any server terminates the method and returns the received values; The list is not changed + * @return The original job and the list of messages found in the first server that answered the query + * @throws CommunicationException + */ + public void run(){ + + Iterator clientIterator = getClientIterator(); + + // Iterate through clients + + while (clientIterator.hasNext()) { + + SingleServerBulletinBoardClient client = clientIterator.next(); + + // Send request to client + client.getRedundancy(payload,this); + + } + + } + + @Override + public void handleCallback(Float result) { + + if (result > 0.5) { + serversContainingMessage.incrementAndGet(); + } + + if (totalContactedServers.incrementAndGet() >= getClientNumber()){ + succeed(new Float(((float) serversContainingMessage.get()) / ((float) getClientNumber()) )); + } + + } + + @Override + public void handleFailure(Throwable t) { + handleCallback(new Float(0.0)); + } + +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerPostBatchWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerPostBatchWorker.java new file mode 100644 index 0000000..cfc34e7 --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerPostBatchWorker.java @@ -0,0 +1,7 @@ +package meerkat.bulletinboard.workers; + +/** + * Created by Arbel Deutsch Peled on 27-Dec-15. + */ +public class MultiServerPostBatchWorker { +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerPostMessageWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerPostMessageWorker.java new file mode 100644 index 0000000..dcdc82a --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerPostMessageWorker.java @@ -0,0 +1,72 @@ +package meerkat.bulletinboard.workers; + +import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; +import meerkat.bulletinboard.MultiServerWorker; +import meerkat.bulletinboard.SingleServerBulletinBoardClient; +import meerkat.comm.CommunicationException; +import meerkat.protobuf.BulletinBoardAPI.*; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Response; +import java.util.Iterator; +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 27-Dec-15. + */ +public class MultiServerPostMessageWorker extends MultiServerWorker { + + public MultiServerPostMessageWorker(List clients, + int minServers, BulletinBoardMessage payload, int maxRetry, + ClientCallback clientCallback) { + + super(clients, minServers, payload, maxRetry, clientCallback); + + } + + /** + * This method carries out the actual communication with the servers via HTTP Post + * It accesses the servers one by one and tries to post the payload to each in turn + * The method will only iterate once through the server list + * Successful post to a server results in removing the server from the list + * @return The original job, but with a modified server list + * @throws CommunicationException + */ + public void run() { + + WebTarget webTarget; + Response response; + + int count = 0; // Used to count number of servers which contain the required message in a GET_REDUNDANCY request. + + // Iterate through servers + + Iterator clientIterator = getClientIterator(); + + while (clientIterator.hasNext()) { + + // Send request to Server + SingleServerBulletinBoardClient client = clientIterator.next(); + + client.postMessage(payload, this); + + } + + } + + @Override + public void handleCallback(Boolean result) { + if (result){ + if (minServers.decrementAndGet() <= 0){ + succeed(Boolean.TRUE); + } + } + } + + @Override + public void handleFailure(Throwable t) { + if (maxFailedServers.decrementAndGet() < 0){ + fail(t); + } + } +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerReadMessagesWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerReadMessagesWorker.java new file mode 100644 index 0000000..bf19526 --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerReadMessagesWorker.java @@ -0,0 +1,65 @@ +package meerkat.bulletinboard.workers; + +import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; +import meerkat.bulletinboard.MultiServerWorker; +import meerkat.bulletinboard.SingleServerBulletinBoardClient; +import meerkat.comm.CommunicationException; +import meerkat.protobuf.BulletinBoardAPI.*; + +import java.util.Iterator; +import java.util.List; + + +/** + * Created by Arbel Deutsch Peled on 27-Dec-15. + */ +public class MultiServerReadMessagesWorker extends MultiServerWorker>{ + + private Iterator clientIterator; + + public MultiServerReadMessagesWorker(List clients, + int minServers, MessageFilterList payload, int maxRetry, + ClientCallback> clientCallback) { + + super(clients, true, minServers, payload, maxRetry, clientCallback); // Shuffle clients on creation to balance load + + clientIterator = getClientIterator(); + + } + + /** + * This method carries out the actual communication with the servers via HTTP Post + * It accesses the servers in a random order until one answers it + * Successful retrieval from any server terminates the method and returns the received values; The list is not changed + * @return The original job and the list of messages found in the first server that answered the query + * @throws CommunicationException + */ + public void run(){ + + // Iterate through servers + + if (clientIterator.hasNext()) { + + // Send request to Server + SingleServerBulletinBoardClient client = clientIterator.next(); + + // Retrieve answer + client.readMessages(payload,this); + + } else { + fail(new CommunicationException("Could not contact any server")); + } + + } + + @Override + public void handleCallback(List msg) { + succeed(msg); + } + + @Override + public void handleFailure(Throwable t) { + run(); // Retry with next server + } + +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/SingleServerGetRedundancyWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/SingleServerGetRedundancyWorker.java new file mode 100644 index 0000000..a02da03 --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/SingleServerGetRedundancyWorker.java @@ -0,0 +1,79 @@ +package meerkat.bulletinboard.workers; + +import meerkat.bulletinboard.SingleServerWorker; +import meerkat.comm.CommunicationException; +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.rest.Constants; + +import javax.ws.rs.ProcessingException; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Response; + +import static meerkat.bulletinboard.BulletinBoardConstants.BULLETIN_BOARD_SERVER_PATH; +import static meerkat.bulletinboard.BulletinBoardConstants.READ_MESSAGES_PATH; + +/** + * Created by Arbel Deutsch Peled on 27-Dec-15. + */ +public class SingleServerGetRedundancyWorker extends SingleServerWorker { + + public SingleServerGetRedundancyWorker(String serverAddress, MessageID payload, int maxRetry) { + super(serverAddress, payload, maxRetry); + } + + /** + * This method carries out the actual communication with the server via HTTP Post + * It queries the server for a message with the given ID + * @return TRUE if the message exists in the server and FALSE otherwise + * @throws CommunicationException if the server does not return a valid answer + */ + public Float call() throws CommunicationException{ + + Client client = clientLocal.get(); + + WebTarget webTarget; + Response response; + + MessageFilterList msgFilterList = MessageFilterList.newBuilder() + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.MSG_ID) + .setId(payload.getID()) + .build() + ).build(); + + // Send request to Server + + webTarget = client.target(serverAddress).path(BULLETIN_BOARD_SERVER_PATH).path(READ_MESSAGES_PATH); + response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(msgFilterList, Constants.MEDIATYPE_PROTOBUF)); + + // Retrieve answer + + try { + + // If a BulletinBoardMessageList is returned: the read was successful + BulletinBoardMessageList msgList = response.readEntity(BulletinBoardMessageList.class); + + if (msgList.getMessageList().size() > 0){ + // Message exists in the server + return new Float(1.0); + } + else { + // Message does not exist in the server + return new Float(0.0); + } + + } catch (ProcessingException | IllegalStateException e) { + + // Read failed + throw new CommunicationException("Server access failed"); + + } + finally { + response.close(); + } + + } + +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/SingleServerPostMessageWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/SingleServerPostMessageWorker.java new file mode 100644 index 0000000..ee9fd3f --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/SingleServerPostMessageWorker.java @@ -0,0 +1,61 @@ +package meerkat.bulletinboard.workers; + +import meerkat.bulletinboard.SingleServerWorker; +import meerkat.comm.CommunicationException; +import meerkat.protobuf.BulletinBoardAPI.BoolMsg; +import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; +import meerkat.rest.Constants; + +import javax.ws.rs.ProcessingException; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Response; + +import static meerkat.bulletinboard.BulletinBoardConstants.BULLETIN_BOARD_SERVER_PATH; +import static meerkat.bulletinboard.BulletinBoardConstants.POST_MESSAGE_PATH; + +/** + * Created by Arbel Deutsch Peled on 27-Dec-15. + * Tries to contact server once and perform a post operation + */ +public class SingleServerPostMessageWorker extends SingleServerWorker { + + public SingleServerPostMessageWorker(String serverAddress, BulletinBoardMessage payload, int maxRetry) { + super(serverAddress, payload, maxRetry); + } + + /** + * This method carries out the actual communication with the server via HTTP Post + * It accesses the server and tries to post the payload to it + * Successful post to a server results + * @return TRUE if the operation is successful + * @throws CommunicationException if the operation is unseccessful + */ + public Boolean call() throws CommunicationException{ + + Client client = clientLocal.get(); + + WebTarget webTarget = client.target(serverAddress).path(BULLETIN_BOARD_SERVER_PATH).path(POST_MESSAGE_PATH);; + Response response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post( + Entity.entity(payload, Constants.MEDIATYPE_PROTOBUF)); + + try { + + // If a BoolMsg entity is returned: the post was successful + response.readEntity(BoolMsg.class); + return Boolean.TRUE; + + } catch (ProcessingException | IllegalStateException e) { + + // Post to this server failed + throw new CommunicationException("Could not contact the server"); + + } + finally { + response.close(); + } + + } + +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/SingleServerReadMessagesWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/SingleServerReadMessagesWorker.java new file mode 100644 index 0000000..f8975cb --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/SingleServerReadMessagesWorker.java @@ -0,0 +1,68 @@ +package meerkat.bulletinboard.workers; + +import meerkat.bulletinboard.SingleServerWorker; +import meerkat.comm.CommunicationException; +import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessageList; +import meerkat.protobuf.BulletinBoardAPI.MessageFilterList; +import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; +import meerkat.rest.Constants; + +import javax.ws.rs.ProcessingException; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Response; + +import java.util.List; + +import static meerkat.bulletinboard.BulletinBoardConstants.BULLETIN_BOARD_SERVER_PATH; +import static meerkat.bulletinboard.BulletinBoardConstants.READ_MESSAGES_PATH; + +/** + * Created by Arbel Deutsch Peled on 27-Dec-15. + */ +public class SingleServerReadMessagesWorker extends SingleServerWorker> { + + public SingleServerReadMessagesWorker(String serverAddress, MessageFilterList payload, int maxRetry) { + super(serverAddress, payload, maxRetry); + } + + /** + * This method carries out the actual communication with the server via HTTP Post + * Upon successful retrieval from the server the method returns the received values + * @return The list of messages returned by the server + * @throws CommunicationException if the server's response is invalid + */ + public List call() throws CommunicationException{ + + Client client = clientLocal.get(); + + WebTarget webTarget; + Response response; + + // Send request to Server + webTarget = client.target(serverAddress).path(BULLETIN_BOARD_SERVER_PATH).path(READ_MESSAGES_PATH); + response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post( + Entity.entity(payload, Constants.MEDIATYPE_PROTOBUF)); + + // Retrieve answer + + try { + + // If a BulletinBoardMessageList is returned: the read was successful + return response.readEntity(BulletinBoardMessageList.class).getMessageList(); + + } catch (ProcessingException | IllegalStateException e) { + + // Read failed + throw new CommunicationException("Could not contact the server"); + + } + finally { + response.close(); + } + + + } + +} diff --git a/bulletin-board-client/src/test/java/BulletinBoardClientIntegrationTest.java b/bulletin-board-client/src/test/java/BulletinBoardClientIntegrationTest.java index d7ae69c..7bdbe08 100644 --- a/bulletin-board-client/src/test/java/BulletinBoardClientIntegrationTest.java +++ b/bulletin-board-client/src/test/java/BulletinBoardClientIntegrationTest.java @@ -32,10 +32,10 @@ public class BulletinBoardClientIntegrationTest { jobSemaphore.release(); } - private class PostCallback implements ClientCallback{ + private class PostCallback implements ClientCallback{ @Override - public void handleCallback(Object msg) { + public void handleCallback(Boolean msg) { System.err.println("Post operation completed"); jobSemaphore.release(); } diff --git a/meerkat-common/build.gradle b/meerkat-common/build.gradle index c510e0a..3783531 100644 --- a/meerkat-common/build.gradle +++ b/meerkat-common/build.gradle @@ -46,7 +46,7 @@ dependencies { compile 'com.google.protobuf:protobuf-java:3.+' // ListeningExecutor - compile 'com.google.guava:guava:11.0.+' + compile 'com.google.guava:guava:15.0' // Crypto compile 'org.factcenter.qilin:qilin:1.2+' diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java b/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java index 1663f7a..00bd2ac 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java @@ -1,6 +1,7 @@ package meerkat.bulletinboard; import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Crypto.Signature; import java.util.List; @@ -24,23 +25,48 @@ public interface AsyncBulletinBoardClient extends BulletinBoardClient { * @param callback is a class containing methods to handle the result of the operation * @return a unique message ID for the message, that can be later used to retrieve the batch */ - public MessageID postMessage(BulletinBoardMessage msg, ClientCallback callback); + public MessageID postMessage(BulletinBoardMessage msg, ClientCallback callback); /** - * This method allows for sending large messages as a batch to the bulletin board + * Perform an end-to-end post of a signed batch message + * @param completeBatch contains all the data of the batch including the meta-data and the signature + * @param callback is a class containing methods to handle the result of the operation + * @return a unique identifier for the batch message + */ + public MessageID postBatch(CompleteBatch completeBatch, ClientCallback callback); + + /** + * This message informs the server about the existence of a new batch message and supplies it with the tags associated with it * @param signerId is the canonical form for the ID of the sender of this batch * @param batchId is a unique (per signer) ID for this batch - * @param batchDataList is the (canonically ordered) list of data comprising the batch message - * @param startPosition is the location (in the batch) of the first entry in batchDataList (optionally used to continue interrupted post operations) - * @param callback is a callback function class for handling results of the operation - * @return a unique message ID for the entire message, that can be later used to retrieve the batch + * @param tagList is a list of tags that belong to the batch message */ - public MessageID postBatch(byte[] signerId, int batchId, List batchDataList, int startPosition, ClientCallback callback); + public void beginBatch(byte[] signerId, int batchId, List tagList, ClientCallback callback); /** - * Overloading of the postBatch method in which startPosition is set to the default value 0 + * This method posts batch data into an (assumed to be open) batch + * It does not close the batch + * @param signerId is the canonical form for the ID of the sender of this batch + * @param batchId is a unique (per signer) ID for this batch + * @param batchDataList is the (canonically ordered) list of data comprising the entire batch message (not just the portion to be written) + * @param startPosition is the location (in the batch) of the first entry in batchDataList + * (optionally used to continue interrupted post operations) + * @param callback is a callback function class for handling results of the operation */ - public MessageID postBatch(byte[] signerId, int batchId, List batchDataList, ClientCallback callback); + public void postBatchData(byte[] signerId, int batchId, List batchDataList, + int startPosition, ClientCallback callback); + + /** + * Overloading of the postBatchData method in which startPosition is set to the default value 0 + */ + public void postBatchData(byte[] signerId, int batchId, List batchDataList, ClientCallback callback); + + /** + * Attempts to close a batch message + * @param closeBatchMessage contains the data required to close the batch + * @param callback is a callback function class for handling results of the operation + */ + public void closeBatch(CloseBatchMessage closeBatchMessage, ClientCallback callback); /** * Check how "safe" a given message is in an asynchronous manner From 3fed32f9e62d83cc1a67f7a463032a86b46eb30e Mon Sep 17 00:00:00 2001 From: Arbel Deutsch Peled Date: Sun, 17 Jan 2016 19:57:45 +0200 Subject: [PATCH 09/49] First (untested) version of BB Client with full batch support --- .../bulletinboard/BatchDataContainer.java | 25 +++ .../SingleServerBulletinBoardClient.java | 145 ++++++++++++++++-- .../ThreadedBulletinBoardClient.java | 87 +++++++++-- .../workers/MultiServerPostBatchWorker.java | 7 - .../MultiServerBeginBatchWorker.java | 28 ++++ .../MultiServerCloseBatchWorker.java | 28 ++++ .../MultiServerGenericPostWorker.java} | 13 +- .../MultiServerGenericReadWorker.java} | 19 +-- .../MultiServerGetRedundancyWorker.java | 2 +- .../MultiServerPostBatchDataWorker.java | 28 ++++ .../MultiServerPostBatchWorker.java | 28 ++++ .../MultiServerPostMessageWorker.java | 28 ++++ .../MultiServerReadBatchWorker.java | 30 ++++ .../MultiServerReadMessagesWorker.java | 29 ++++ .../SingleServerBeginBatchWorker.java | 17 ++ .../SingleServerCloseBatchWorker.java | 17 ++ .../SingleServerGenericPostWorker.java} | 15 +- .../SingleServerGetRedundancyWorker.java | 2 +- .../SingleServerPostBatchWorker.java | 17 ++ .../SingleServerPostMessageWorker.java | 17 ++ .../SingleServerReadBatchWorker.java | 119 ++++++++++++++ .../SingleServerReadMessagesWorker.java | 2 +- .../webapp/BulletinBoardWebApp.java | 4 + .../AsyncBulletinBoardClient.java | 34 ++-- .../bulletinboard/BulletinBoardConstants.java | 3 +- .../bulletinboard/GenericBatchDigest.java | 7 +- .../src/main/java/meerkat/crypto/Digest.java | 7 + .../meerkat/crypto/concrete/SHA256Digest.java | 6 + 28 files changed, 692 insertions(+), 72 deletions(-) create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/BatchDataContainer.java delete mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerPostBatchWorker.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerBeginBatchWorker.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerCloseBatchWorker.java rename bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/{MultiServerPostMessageWorker.java => multiserver/MultiServerGenericPostWorker.java} (82%) rename bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/{MultiServerReadMessagesWorker.java => multiserver/MultiServerGenericReadWorker.java} (68%) rename bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/{ => multiserver}/MultiServerGetRedundancyWorker.java (97%) create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerPostBatchDataWorker.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerPostBatchWorker.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerPostMessageWorker.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerReadBatchWorker.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerReadMessagesWorker.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerBeginBatchWorker.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerCloseBatchWorker.java rename bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/{SingleServerPostMessageWorker.java => singleserver/SingleServerGenericPostWorker.java} (76%) rename bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/{ => singleserver}/SingleServerGetRedundancyWorker.java (98%) create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerPostBatchWorker.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerPostMessageWorker.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerReadBatchWorker.java rename bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/{ => singleserver}/SingleServerReadMessagesWorker.java (97%) diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/BatchDataContainer.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/BatchDataContainer.java new file mode 100644 index 0000000..53f4870 --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/BatchDataContainer.java @@ -0,0 +1,25 @@ +package meerkat.bulletinboard; + +import com.google.protobuf.ByteString; +import meerkat.protobuf.BulletinBoardAPI.BatchData; + +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 17-Jan-16. + * Used to store the complete data required for sending a batch data list inside a single object + */ +public class BatchDataContainer { + + public final byte[] signerId; + public final int batchId; + public final List batchDataList; + public final int startPosition; + + public BatchDataContainer(byte[] signerId, int batchId, List batchDataList, int startPosition) { + this.signerId = signerId; + this.batchId = batchId; + this.batchDataList = batchDataList; + this.startPosition = startPosition; + } +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java index e92f35b..9c211fd 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java @@ -5,9 +5,7 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListeningScheduledExecutorService; import com.google.common.util.concurrent.MoreExecutors; import com.google.protobuf.ByteString; -import meerkat.bulletinboard.workers.SingleServerGetRedundancyWorker; -import meerkat.bulletinboard.workers.SingleServerPostMessageWorker; -import meerkat.bulletinboard.workers.SingleServerReadMessagesWorker; +import meerkat.bulletinboard.workers.singleserver.*; import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.protobuf.Voting.BulletinBoardClientParams; @@ -30,6 +28,8 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i protected ListeningScheduledExecutorService executorService; + protected BatchDigest batchDigest; + private long lastServerErrorTime; protected final long failDelayInMilliseconds; @@ -136,6 +136,9 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i // Perform usual setup super.init(clientParams); + // Wrap the Digest into a BatchDigest + batchDigest = new GenericBatchDigest(digest); + // Remove all but first DB address String dbAddress = meerkatDBs.get(0); meerkatDBs = new LinkedList(); @@ -153,19 +156,124 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i scheduleWorker(worker, new RetryCallback(worker, callback)); // Calculate the correct message ID and return it - digest.reset(); - digest.update(msg.getMsg()); - return MessageID.newBuilder().setID(ByteString.copyFrom(digest.digest())).build(); + batchDigest.reset(); + batchDigest.update(msg.getMsg()); + return batchDigest.digestAsMessageID(); } + private class PostBatchDataCallback implements ClientCallback { + + private CompleteBatch completeBatch; + ClientCallback callback; + + public PostBatchDataCallback(CompleteBatch completeBatch, ClientCallback callback) { + this.completeBatch = completeBatch; + this.callback = callback; + } + + @Override + public void handleCallback(Boolean msg) { + closeBatch( + CloseBatchMessage.newBuilder() + .setBatchId(completeBatch.getBeginBatchMessage().getBatchId()) + .setSig(completeBatch.getSignature()) + .setBatchLength(completeBatch.getBatchDataList().size()) + .build(), + callback + ); + } + + @Override + public void handleFailure(Throwable t) { + callback.handleFailure(t); + } + + } + + private class BeginBatchCallback implements ClientCallback { + + private CompleteBatch completeBatch; + ClientCallback callback; + + public BeginBatchCallback(CompleteBatch completeBatch, ClientCallback callback) { + this.completeBatch = completeBatch; + this.callback = callback; + } + + @Override + public void handleCallback(Boolean msg) { + + postBatchData( + completeBatch.getBeginBatchMessage().getSignerId(), + completeBatch.getBeginBatchMessage().getBatchId(), + completeBatch.getBatchDataList(), + 0, + new PostBatchDataCallback(completeBatch,callback)); + } + + @Override + public void handleFailure(Throwable t) { + callback.handleFailure(t); + } + } + @Override public MessageID postBatch(CompleteBatch completeBatch, ClientCallback callback) { - return null; + + beginBatch( + completeBatch.getBeginBatchMessage(), + new BeginBatchCallback(completeBatch, callback) + ); + + batchDigest.update(completeBatch); + + return batchDigest.digestAsMessageID(); + } @Override - public void beginBatch(byte[] signerId, int batchId, List tagList, ClientCallback callback) { + public void beginBatch(BeginBatchMessage beginBatchMessage, ClientCallback callback) { + + // Create worker with redundancy 1 and MAX_RETRIES retries + SingleServerBeginBatchWorker worker = + new SingleServerBeginBatchWorker(meerkatDBs.get(0), beginBatchMessage, MAX_RETRIES); + + // Submit worker and create callback + scheduleWorker(worker, new RetryCallback(worker, callback)); + + } + + @Override + public void postBatchData(ByteString signerId, int batchId, List batchDataList, + int startPosition, ClientCallback callback) { + + BatchMessage.Builder builder = BatchMessage.newBuilder() + .setSignerId(signerId) + .setBatchId(batchId); + + // Iterate through data list + + for (BatchData data : batchDataList) { + builder.setSerialNum(startPosition).setData(data); + + // Create worker with redundancy 1 and MAX_RETRIES retries + SingleServerPostBatchWorker worker = + new SingleServerPostBatchWorker(meerkatDBs.get(0), builder.build(), MAX_RETRIES); + + // Create worker with redundancy 1 and MAX_RETRIES retries + scheduleWorker(worker, new RetryCallback(worker, callback)); + + // Increment position in batch + startPosition++; + } + + } + + @Override + public void postBatchData(ByteString signerId, int batchId, List batchDataList, ClientCallback callback) { + + postBatchData(signerId, batchId, batchDataList, 0, callback); } @@ -173,15 +281,26 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i public void postBatchData(byte[] signerId, int batchId, List batchDataList, int startPosition, ClientCallback callback) { + postBatchData(ByteString.copyFrom(signerId), batchId, batchDataList, startPosition, callback); + } @Override public void postBatchData(byte[] signerId, int batchId, List batchDataList, ClientCallback callback) { + postBatchData(signerId, batchId, batchDataList, 0, callback); + } @Override - public void closeBatch(CloseBatchMessage closeBatchMessage, ClientCallback callback) { + public void closeBatch(CloseBatchMessage closeBatchMessage, ClientCallback callback) { + + // Create worker with redundancy 1 and MAX_RETRIES retries + SingleServerCloseBatchWorker worker = + new SingleServerCloseBatchWorker(meerkatDBs.get(0), closeBatchMessage, MAX_RETRIES); + + // Submit worker and create callback + scheduleWorker(worker, new RetryCallback(worker, callback)); } @@ -208,7 +327,13 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i } @Override - public void readBatch(byte[] signerId, int batchId, ClientCallback callback) { + public void readBatch(BatchSpecificationMessage batchSpecificationMessage, ClientCallback callback) { + + // Create job with no retries + SingleServerReadBatchWorker worker = new SingleServerReadBatchWorker(meerkatDBs.get(0), batchSpecificationMessage, 1); + + // Submit job and create callback + scheduleWorker(worker, new RetryCallback(worker, callback)); } diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java index ce7a01e..78d5dba 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java @@ -2,9 +2,7 @@ package meerkat.bulletinboard; import com.google.protobuf.ByteString; -import meerkat.bulletinboard.workers.MultiServerGetRedundancyWorker; -import meerkat.bulletinboard.workers.MultiServerPostMessageWorker; -import meerkat.bulletinboard.workers.MultiServerReadMessagesWorker; +import meerkat.bulletinboard.workers.multiserver.*; import meerkat.comm.CommunicationException; import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.protobuf.Voting.*; @@ -31,6 +29,8 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple // Per-server clients List clients; + BatchDigest batchDigest; + private final static int POST_MESSAGE_RETRY_NUM = 3; private final static int READ_MESSAGES_RETRY_NUM = 1; private final static int GET_REDUNDANCY_RETRY_NUM = 1; @@ -51,6 +51,8 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple super.init(clientParams); + batchDigest = new GenericBatchDigest(digest); + minAbsoluteRedundancy = (int) (clientParams.getMinRedundancy() * clientParams.getBulletinBoardAddressCount()); executorService = Executors.newFixedThreadPool(JOBS_THREAD_NUM); @@ -84,42 +86,88 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple executorService.submit(worker); // Calculate the correct message ID and return it - digest.reset(); - digest.update(msg.getMsg()); - return MessageID.newBuilder().setID(ByteString.copyFrom(digest.digest())).build(); + batchDigest.reset(); + batchDigest.update(msg.getMsg()); + return batchDigest.digestAsMessageID(); } @Override public MessageID postBatch(CompleteBatch completeBatch, ClientCallback callback) { - return null; // TODO: write this + // Create job + MultiServerPostBatchWorker worker = + new MultiServerPostBatchWorker(clients, minAbsoluteRedundancy, completeBatch, POST_MESSAGE_RETRY_NUM, callback); + + // Submit job + executorService.submit(worker); + + // Calculate the correct message ID and return it + batchDigest.reset(); + batchDigest.update(completeBatch); + return batchDigest.digestAsMessageID(); } @Override - public void beginBatch(byte[] signerId, int batchId, List tagList, ClientCallback callback) { - // TODO: write this + public void beginBatch(BeginBatchMessage beginBatchMessage, ClientCallback callback) { + + // Create job + MultiServerBeginBatchWorker worker = + new MultiServerBeginBatchWorker(clients, minAbsoluteRedundancy, beginBatchMessage, POST_MESSAGE_RETRY_NUM, callback); + + // Submit job + executorService.submit(worker); + } @Override public void postBatchData(byte[] signerId, int batchId, List batchDataList, - int startPosition, ClientCallback callback) { + int startPosition, ClientCallback callback) { - // TODO: write this + BatchDataContainer batchDataContainer = new BatchDataContainer(signerId, batchId, batchDataList, startPosition); + + // Create job + MultiServerPostBatchDataWorker worker = + new MultiServerPostBatchDataWorker(clients, minAbsoluteRedundancy, batchDataContainer, POST_MESSAGE_RETRY_NUM, callback); + + // Submit job + executorService.submit(worker); } @Override public void postBatchData(byte[] signerId, int batchId, List batchDataList, ClientCallback callback) { - postBatchData(signerId, batchId, batchDataList, 0, callback); // Write batch from beginning + postBatchData(signerId, batchId, batchDataList, 0, callback); } @Override - public void closeBatch(CloseBatchMessage closeBatchMessage, ClientCallback callback) { - // TODO: write this + public void postBatchData(ByteString signerId, int batchId, List batchDataList, + int startPosition, ClientCallback callback) { + + postBatchData(signerId.toByteArray(), batchId, batchDataList, startPosition, callback); + + } + + @Override + public void postBatchData(ByteString signerId, int batchId, List batchDataList, ClientCallback callback) { + + postBatchData(signerId, batchId, batchDataList, 0, callback); + + } + + @Override + public void closeBatch(CloseBatchMessage closeBatchMessage, ClientCallback callback) { + + // Create job + MultiServerCloseBatchWorker worker = + new MultiServerCloseBatchWorker(clients, minAbsoluteRedundancy, closeBatchMessage, POST_MESSAGE_RETRY_NUM, callback); + + // Submit job + executorService.submit(worker); + } /** @@ -158,8 +206,15 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple } @Override - public void readBatch(byte[] signerId, int batchId, ClientCallback callback) { - // TODO: Implement + public void readBatch(BatchSpecificationMessage batchSpecificationMessage, ClientCallback callback) { + + // Create job + MultiServerReadBatchWorker worker = + new MultiServerReadBatchWorker(clients, minAbsoluteRedundancy, batchSpecificationMessage, READ_MESSAGES_RETRY_NUM, callback); + + // Submit job + executorService.submit(worker); + } @Override diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerPostBatchWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerPostBatchWorker.java deleted file mode 100644 index cfc34e7..0000000 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerPostBatchWorker.java +++ /dev/null @@ -1,7 +0,0 @@ -package meerkat.bulletinboard.workers; - -/** - * Created by Arbel Deutsch Peled on 27-Dec-15. - */ -public class MultiServerPostBatchWorker { -} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerBeginBatchWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerBeginBatchWorker.java new file mode 100644 index 0000000..dc496d7 --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerBeginBatchWorker.java @@ -0,0 +1,28 @@ +package meerkat.bulletinboard.workers.multiserver; + +import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; +import meerkat.bulletinboard.SingleServerBulletinBoardClient; +import meerkat.protobuf.BulletinBoardAPI.BeginBatchMessage; + +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 27-Dec-15. + */ +public class MultiServerBeginBatchWorker extends MultiServerGenericPostWorker { + + public MultiServerBeginBatchWorker(List clients, + int minServers, BeginBatchMessage payload, int maxRetry, + ClientCallback clientCallback) { + + super(clients, minServers, payload, maxRetry, clientCallback); + + } + + @Override + protected void doPost(SingleServerBulletinBoardClient client, BeginBatchMessage payload) { + client.beginBatch(payload, this); + } + + +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerCloseBatchWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerCloseBatchWorker.java new file mode 100644 index 0000000..56b09c5 --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerCloseBatchWorker.java @@ -0,0 +1,28 @@ +package meerkat.bulletinboard.workers.multiserver; + +import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; +import meerkat.bulletinboard.SingleServerBulletinBoardClient; +import meerkat.protobuf.BulletinBoardAPI.CloseBatchMessage; + +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 27-Dec-15. + */ +public class MultiServerCloseBatchWorker extends MultiServerGenericPostWorker { + + public MultiServerCloseBatchWorker(List clients, + int minServers, CloseBatchMessage payload, int maxRetry, + ClientCallback clientCallback) { + + super(clients, minServers, payload, maxRetry, clientCallback); + + } + + @Override + protected void doPost(SingleServerBulletinBoardClient client, CloseBatchMessage payload) { + client.closeBatch(payload, this); + } + + +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerPostMessageWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGenericPostWorker.java similarity index 82% rename from bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerPostMessageWorker.java rename to bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGenericPostWorker.java index dcdc82a..8b62d4e 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerPostMessageWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGenericPostWorker.java @@ -1,10 +1,9 @@ -package meerkat.bulletinboard.workers; +package meerkat.bulletinboard.workers.multiserver; import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; import meerkat.bulletinboard.MultiServerWorker; import meerkat.bulletinboard.SingleServerBulletinBoardClient; import meerkat.comm.CommunicationException; -import meerkat.protobuf.BulletinBoardAPI.*; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.Response; @@ -14,16 +13,18 @@ import java.util.List; /** * Created by Arbel Deutsch Peled on 27-Dec-15. */ -public class MultiServerPostMessageWorker extends MultiServerWorker { +public abstract class MultiServerGenericPostWorker extends MultiServerWorker { - public MultiServerPostMessageWorker(List clients, - int minServers, BulletinBoardMessage payload, int maxRetry, + public MultiServerGenericPostWorker(List clients, + int minServers, T payload, int maxRetry, ClientCallback clientCallback) { super(clients, minServers, payload, maxRetry, clientCallback); } + protected abstract void doPost(SingleServerBulletinBoardClient client, T payload); + /** * This method carries out the actual communication with the servers via HTTP Post * It accesses the servers one by one and tries to post the payload to each in turn @@ -48,7 +49,7 @@ public class MultiServerPostMessageWorker extends MultiServerWorker>{ +public abstract class MultiServerGenericReadWorker extends MultiServerWorker{ - private Iterator clientIterator; + protected Iterator clientIterator; - public MultiServerReadMessagesWorker(List clients, - int minServers, MessageFilterList payload, int maxRetry, - ClientCallback> clientCallback) { + public MultiServerGenericReadWorker(List clients, + int minServers, IN payload, int maxRetry, + ClientCallback clientCallback) { super(clients, true, minServers, payload, maxRetry, clientCallback); // Shuffle clients on creation to balance load @@ -27,6 +26,8 @@ public class MultiServerReadMessagesWorker extends MultiServerWorker msg) { + public void handleCallback(OUT msg) { succeed(msg); } diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerGetRedundancyWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGetRedundancyWorker.java similarity index 97% rename from bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerGetRedundancyWorker.java rename to bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGetRedundancyWorker.java index 4d5e7f2..5675cb8 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/MultiServerGetRedundancyWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGetRedundancyWorker.java @@ -1,4 +1,4 @@ -package meerkat.bulletinboard.workers; +package meerkat.bulletinboard.workers.multiserver; import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; import meerkat.bulletinboard.MultiServerWorker; diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerPostBatchDataWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerPostBatchDataWorker.java new file mode 100644 index 0000000..df21f9f --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerPostBatchDataWorker.java @@ -0,0 +1,28 @@ +package meerkat.bulletinboard.workers.multiserver; + +import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; +import meerkat.bulletinboard.SingleServerBulletinBoardClient; +import meerkat.bulletinboard.BatchDataContainer; + +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 27-Dec-15. + */ +public class MultiServerPostBatchDataWorker extends MultiServerGenericPostWorker { + + public MultiServerPostBatchDataWorker(List clients, + int minServers, BatchDataContainer payload, int maxRetry, + ClientCallback clientCallback) { + + super(clients, minServers, payload, maxRetry, clientCallback); + + } + + @Override + protected void doPost(SingleServerBulletinBoardClient client, BatchDataContainer payload) { + client.postBatchData(payload.signerId, payload.batchId, payload.batchDataList, payload.startPosition, this); + } + + +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerPostBatchWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerPostBatchWorker.java new file mode 100644 index 0000000..7c2f586 --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerPostBatchWorker.java @@ -0,0 +1,28 @@ +package meerkat.bulletinboard.workers.multiserver; + +import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; +import meerkat.bulletinboard.CompleteBatch; +import meerkat.bulletinboard.SingleServerBulletinBoardClient; + +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 27-Dec-15. + */ +public class MultiServerPostBatchWorker extends MultiServerGenericPostWorker { + + public MultiServerPostBatchWorker(List clients, + int minServers, CompleteBatch payload, int maxRetry, + ClientCallback clientCallback) { + + super(clients, minServers, payload, maxRetry, clientCallback); + + } + + @Override + protected void doPost(SingleServerBulletinBoardClient client, CompleteBatch payload) { + client.postBatch(payload, this); + } + + +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerPostMessageWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerPostMessageWorker.java new file mode 100644 index 0000000..33f9a3c --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerPostMessageWorker.java @@ -0,0 +1,28 @@ +package meerkat.bulletinboard.workers.multiserver; + +import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; +import meerkat.bulletinboard.SingleServerBulletinBoardClient; +import meerkat.protobuf.BulletinBoardAPI.*; + +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 27-Dec-15. + */ +public class MultiServerPostMessageWorker extends MultiServerGenericPostWorker { + + public MultiServerPostMessageWorker(List clients, + int minServers, BulletinBoardMessage payload, int maxRetry, + ClientCallback clientCallback) { + + super(clients, minServers, payload, maxRetry, clientCallback); + + } + + @Override + protected void doPost(SingleServerBulletinBoardClient client, BulletinBoardMessage payload) { + client.postMessage(payload, this); + } + + +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerReadBatchWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerReadBatchWorker.java new file mode 100644 index 0000000..737c15c --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerReadBatchWorker.java @@ -0,0 +1,30 @@ +package meerkat.bulletinboard.workers.multiserver; + +import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; +import meerkat.bulletinboard.CompleteBatch; +import meerkat.bulletinboard.SingleServerBulletinBoardClient; +import meerkat.protobuf.BulletinBoardAPI.BatchSpecificationMessage; + +import java.util.List; + + +/** + * Created by Arbel Deutsch Peled on 27-Dec-15. + */ +public class MultiServerReadBatchWorker extends MultiServerGenericReadWorker { + + public MultiServerReadBatchWorker(List clients, + int minServers, BatchSpecificationMessage payload, int maxRetry, + ClientCallback clientCallback) { + + super(clients, minServers, payload, maxRetry, clientCallback); + + } + + @Override + protected void doRead(BatchSpecificationMessage payload, SingleServerBulletinBoardClient client) { + client.readBatch(payload, this); + } + + +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerReadMessagesWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerReadMessagesWorker.java new file mode 100644 index 0000000..b276eab --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerReadMessagesWorker.java @@ -0,0 +1,29 @@ +package meerkat.bulletinboard.workers.multiserver; + +import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; +import meerkat.bulletinboard.SingleServerBulletinBoardClient; +import meerkat.protobuf.BulletinBoardAPI.*; + +import java.util.List; + + +/** + * Created by Arbel Deutsch Peled on 27-Dec-15. + */ +public class MultiServerReadMessagesWorker extends MultiServerGenericReadWorker>{ + + public MultiServerReadMessagesWorker(List clients, + int minServers, MessageFilterList payload, int maxRetry, + ClientCallback> clientCallback) { + + super(clients, minServers, payload, maxRetry, clientCallback); + + } + + @Override + protected void doRead(MessageFilterList payload, SingleServerBulletinBoardClient client) { + client.readMessages(payload, this); + } + + +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerBeginBatchWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerBeginBatchWorker.java new file mode 100644 index 0000000..0c1a1a3 --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerBeginBatchWorker.java @@ -0,0 +1,17 @@ +package meerkat.bulletinboard.workers.singleserver; + +import meerkat.protobuf.BulletinBoardAPI.BeginBatchMessage; + +import static meerkat.bulletinboard.BulletinBoardConstants.BEGIN_BATCH_PATH; + +/** + * Created by Arbel Deutsch Peled on 27-Dec-15. + * Tries to contact server once and perform a post operation + */ +public class SingleServerBeginBatchWorker extends SingleServerGenericPostWorker { + + public SingleServerBeginBatchWorker(String serverAddress, BeginBatchMessage payload, int maxRetry) { + super(serverAddress, BEGIN_BATCH_PATH, payload, maxRetry); + } + +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerCloseBatchWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerCloseBatchWorker.java new file mode 100644 index 0000000..ab298a5 --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerCloseBatchWorker.java @@ -0,0 +1,17 @@ +package meerkat.bulletinboard.workers.singleserver; + +import meerkat.protobuf.BulletinBoardAPI.CloseBatchMessage; + +import static meerkat.bulletinboard.BulletinBoardConstants.CLOSE_BATCH_PATH; + +/** + * Created by Arbel Deutsch Peled on 27-Dec-15. + * Tries to contact server once and perform a close batch operation + */ +public class SingleServerCloseBatchWorker extends SingleServerGenericPostWorker { + + public SingleServerCloseBatchWorker(String serverAddress, CloseBatchMessage payload, int maxRetry) { + super(serverAddress, CLOSE_BATCH_PATH, payload, maxRetry); + } + +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/SingleServerPostMessageWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerGenericPostWorker.java similarity index 76% rename from bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/SingleServerPostMessageWorker.java rename to bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerGenericPostWorker.java index ee9fd3f..c56af05 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/SingleServerPostMessageWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerGenericPostWorker.java @@ -1,9 +1,8 @@ -package meerkat.bulletinboard.workers; +package meerkat.bulletinboard.workers.singleserver; import meerkat.bulletinboard.SingleServerWorker; import meerkat.comm.CommunicationException; import meerkat.protobuf.BulletinBoardAPI.BoolMsg; -import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; import meerkat.rest.Constants; import javax.ws.rs.ProcessingException; @@ -13,16 +12,18 @@ import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.Response; import static meerkat.bulletinboard.BulletinBoardConstants.BULLETIN_BOARD_SERVER_PATH; -import static meerkat.bulletinboard.BulletinBoardConstants.POST_MESSAGE_PATH; /** * Created by Arbel Deutsch Peled on 27-Dec-15. * Tries to contact server once and perform a post operation */ -public class SingleServerPostMessageWorker extends SingleServerWorker { +public class SingleServerGenericPostWorker extends SingleServerWorker { - public SingleServerPostMessageWorker(String serverAddress, BulletinBoardMessage payload, int maxRetry) { + private String subPath; + + public SingleServerGenericPostWorker(String serverAddress, String subPath, T payload, int maxRetry) { super(serverAddress, payload, maxRetry); + this.subPath = subPath; } /** @@ -30,13 +31,13 @@ public class SingleServerPostMessageWorker extends SingleServerWorker { + + public SingleServerPostBatchWorker(String serverAddress, BatchMessage payload, int maxRetry) { + super(serverAddress, POST_BATCH_PATH, payload, maxRetry); + } + +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerPostMessageWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerPostMessageWorker.java new file mode 100644 index 0000000..454d720 --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerPostMessageWorker.java @@ -0,0 +1,17 @@ +package meerkat.bulletinboard.workers.singleserver; + +import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; + +import static meerkat.bulletinboard.BulletinBoardConstants.POST_MESSAGE_PATH; + +/** + * Created by Arbel Deutsch Peled on 27-Dec-15. + * Tries to contact server once and perform a post operation + */ +public class SingleServerPostMessageWorker extends SingleServerGenericPostWorker { + + public SingleServerPostMessageWorker(String serverAddress, BulletinBoardMessage payload, int maxRetry) { + super(serverAddress, POST_MESSAGE_PATH, payload, maxRetry); + } + +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerReadBatchWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerReadBatchWorker.java new file mode 100644 index 0000000..61556fc --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerReadBatchWorker.java @@ -0,0 +1,119 @@ +package meerkat.bulletinboard.workers.singleserver; + +import meerkat.bulletinboard.CompleteBatch; +import meerkat.bulletinboard.SingleServerWorker; +import meerkat.comm.CommunicationException; +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.rest.Constants; + +import javax.ws.rs.ProcessingException; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.Response; +import java.util.List; + +import static meerkat.bulletinboard.BulletinBoardConstants.BULLETIN_BOARD_SERVER_PATH; +import static meerkat.bulletinboard.BulletinBoardConstants.READ_MESSAGES_PATH; +import static meerkat.bulletinboard.BulletinBoardConstants.READ_BATCH_PATH; + +import static meerkat.bulletinboard.BulletinBoardConstants.BATCH_ID_TAG_PREFIX; + +/** + * Created by Arbel Deutsch Peled on 27-Dec-15. + */ +public class SingleServerReadBatchWorker extends SingleServerWorker { + + public SingleServerReadBatchWorker(String serverAddress, BatchSpecificationMessage payload, int maxRetry) { + super(serverAddress, payload, maxRetry); + } + + /** + * This method carries out the actual communication with the server via HTTP Post + * Upon successful retrieval from the server the method returns the received values + * @return the complete batch as read from the server + * @throws CommunicationException if the server's response is invalid + */ + public CompleteBatch call() throws CommunicationException{ + + CompleteBatch completeBatch = new CompleteBatch(); + + Client client = clientLocal.get(); + + WebTarget webTarget; + Response response; + + // Set filters for the batch message metadata retrieval + + MessageFilterList messageFilterList = MessageFilterList.newBuilder() + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.TAG) + .setTag(BATCH_ID_TAG_PREFIX + String.valueOf(payload.getBatchId())) + .build()) + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.SIGNER_ID) + .setId(payload.getSignerId()) + .build()) + .build(); + + // Send request to Server + + webTarget = client.target(serverAddress).path(BULLETIN_BOARD_SERVER_PATH).path(READ_MESSAGES_PATH); + response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post( + Entity.entity(messageFilterList, Constants.MEDIATYPE_PROTOBUF)); + + // Retrieve answer + + try { + + // If a BulletinBoardMessageList is returned: the read was successful + BulletinBoardMessage metadata = response.readEntity(BulletinBoardMessageList.class).getMessage(0); + + completeBatch.setBeginBatchMessage(BeginBatchMessage.newBuilder() + .setSignerId(payload.getSignerId()) + .setBatchId(payload.getBatchId()) + .addAllTag(metadata.getMsg().getTagList()) + .build()); + + completeBatch.setSignature(metadata.getSig(0)); + + } catch (ProcessingException | IllegalStateException e) { + + // Read failed + throw new CommunicationException("Could not contact the server"); + + } + finally { + response.close(); + } + + // Get the batch data + + webTarget = client.target(serverAddress).path(BULLETIN_BOARD_SERVER_PATH).path(READ_BATCH_PATH); + response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post( + Entity.entity(payload, Constants.MEDIATYPE_PROTOBUF)); + + // Retrieve answer + + try { + + // If a List of BatchData is returned: the read was successful + + completeBatch.appendBatchData(response.readEntity(new GenericType>(){})); + + } catch (ProcessingException | IllegalStateException e) { + + // Read failed + throw new CommunicationException("Could not contact the server"); + + } + finally { + response.close(); + } + + return completeBatch; + + } + +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/SingleServerReadMessagesWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerReadMessagesWorker.java similarity index 97% rename from bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/SingleServerReadMessagesWorker.java rename to bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerReadMessagesWorker.java index f8975cb..6c09bcc 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/SingleServerReadMessagesWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerReadMessagesWorker.java @@ -1,4 +1,4 @@ -package meerkat.bulletinboard.workers; +package meerkat.bulletinboard.workers.singleserver; import meerkat.bulletinboard.SingleServerWorker; import meerkat.comm.CommunicationException; diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java index cab9d6d..fe3d2fc 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java @@ -141,6 +141,10 @@ public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextL } } + @Path(READ_BATCH_PATH) + @POST + @Consumes(MEDIATYPE_PROTOBUF) + @Produces(MEDIATYPE_PROTOBUF) @Override public List readBatch(BatchSpecificationMessage message) { try { diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java b/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java index 00bd2ac..7732fcb 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java @@ -1,7 +1,7 @@ package meerkat.bulletinboard; +import com.google.protobuf.ByteString; import meerkat.protobuf.BulletinBoardAPI.*; -import meerkat.protobuf.Crypto.Signature; import java.util.List; @@ -37,36 +37,47 @@ public interface AsyncBulletinBoardClient extends BulletinBoardClient { /** * This message informs the server about the existence of a new batch message and supplies it with the tags associated with it - * @param signerId is the canonical form for the ID of the sender of this batch - * @param batchId is a unique (per signer) ID for this batch - * @param tagList is a list of tags that belong to the batch message + * @param beginBatchMessage contains the data required to begin the batch + * @param callback is a callback function class for handling results of the operation */ - public void beginBatch(byte[] signerId, int batchId, List tagList, ClientCallback callback); + public void beginBatch(BeginBatchMessage beginBatchMessage, ClientCallback callback); /** * This method posts batch data into an (assumed to be open) batch * It does not close the batch * @param signerId is the canonical form for the ID of the sender of this batch * @param batchId is a unique (per signer) ID for this batch - * @param batchDataList is the (canonically ordered) list of data comprising the entire batch message (not just the portion to be written) + * @param batchDataList is the (canonically ordered) list of data comprising the portion of the batch to be posted * @param startPosition is the location (in the batch) of the first entry in batchDataList * (optionally used to continue interrupted post operations) + * The first position in the batch is position 0 * @param callback is a callback function class for handling results of the operation */ public void postBatchData(byte[] signerId, int batchId, List batchDataList, - int startPosition, ClientCallback callback); + int startPosition, ClientCallback callback); /** - * Overloading of the postBatchData method in which startPosition is set to the default value 0 + * Overloading of the postBatchData method which starts at the first position in the batch */ public void postBatchData(byte[] signerId, int batchId, List batchDataList, ClientCallback callback); + /** + * Overloading of the postBatchData method which uses ByteString + */ + public void postBatchData(ByteString signerId, int batchId, List batchDataList, + int startPosition, ClientCallback callback); + + /** + * Overloading of the postBatchData method which uses ByteString and starts at the first position in the batch + */ + public void postBatchData(ByteString signerId, int batchId, List batchDataList, ClientCallback callback); + /** * Attempts to close a batch message * @param closeBatchMessage contains the data required to close the batch * @param callback is a callback function class for handling results of the operation */ - public void closeBatch(CloseBatchMessage closeBatchMessage, ClientCallback callback); + public void closeBatch(CloseBatchMessage closeBatchMessage, ClientCallback callback); /** * Check how "safe" a given message is in an asynchronous manner @@ -88,11 +99,10 @@ public interface AsyncBulletinBoardClient extends BulletinBoardClient { /** * Read a given batch message from the bulletin board - * @param signerId is the ID of the signer (sender) of the batch message - * @param batchId is the unique (per signer) ID of the batch + * @param batchSpecificationMessage contains the data required to specify a single batch instance * @param callback is a callback class for handling the result of the operation */ - public void readBatch(byte[] signerId, int batchId, ClientCallback callback); + public void readBatch(BatchSpecificationMessage batchSpecificationMessage, ClientCallback callback); /** * Subscribes to a notifier that will return any new messages on the server that match the given filters diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardConstants.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardConstants.java index 0db1d3f..6bfc06f 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardConstants.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardConstants.java @@ -9,6 +9,7 @@ public interface BulletinBoardConstants { public static final String BULLETIN_BOARD_SERVER_PATH = "/bbserver"; public static final String READ_MESSAGES_PATH = "/readmessages"; + public static final String READ_BATCH_PATH = "/readbatch"; public static final String POST_MESSAGE_PATH = "/postmessage"; public static final String BEGIN_BATCH_PATH = "/beginbatch"; public static final String POST_BATCH_PATH = "/postbatch"; @@ -17,6 +18,6 @@ public interface BulletinBoardConstants { // Other Constants public static final String BATCH_TAG = "@BATCH"; - public static final String BATCH_ID_TAG_PREFIX = "#"; + public static final String BATCH_ID_TAG_PREFIX = "BATCHID#"; } diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigest.java b/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigest.java index 8171271..4f25f59 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigest.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigest.java @@ -2,7 +2,7 @@ package meerkat.bulletinboard; import com.google.protobuf.Message; import meerkat.crypto.Digest; -import meerkat.protobuf.BulletinBoardAPI.BeginBatchMessage; +import meerkat.protobuf.BulletinBoardAPI.MessageID; import meerkat.protobuf.BulletinBoardAPI.BatchData; import java.util.List; @@ -36,6 +36,11 @@ public class GenericBatchDigest implements BatchDigest{ return digest.digest(); } + @Override + public MessageID digestAsMessageID() { + return digest.digestAsMessageID(); + } + @Override public void update(Message msg) { digest.update(msg); diff --git a/meerkat-common/src/main/java/meerkat/crypto/Digest.java b/meerkat-common/src/main/java/meerkat/crypto/Digest.java index c72206e..b7d86dc 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/Digest.java +++ b/meerkat-common/src/main/java/meerkat/crypto/Digest.java @@ -1,6 +1,7 @@ package meerkat.crypto; import com.google.protobuf.Message; +import meerkat.protobuf.BulletinBoardAPI.MessageID; import java.security.MessageDigest; @@ -15,6 +16,12 @@ public interface Digest { */ public byte[] digest(); + /** + * Completes the hash computation and returns a MessageID Protobuf as output + * @return + */ + public MessageID digestAsMessageID(); + /** * Updates the digest using the specified message (in serialized wire form) * diff --git a/meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java index 4aac501..a7723ec 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java @@ -3,6 +3,7 @@ package meerkat.crypto.concrete; import com.google.protobuf.ByteString; import com.google.protobuf.Message; import meerkat.crypto.Digest; +import meerkat.protobuf.BulletinBoardAPI.MessageID; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,6 +61,11 @@ public class SHA256Digest implements Digest { return hash.digest(); } + @Override + public MessageID digestAsMessageID() { + return MessageID.newBuilder().setID(ByteString.copyFrom(digest())).build(); + } + @Override public void update(Message msg) { From 6100497e8e0f5f55a88197022ace85ac2ca75488 Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Wed, 27 Jan 2016 13:41:24 +0200 Subject: [PATCH 10/49] Feldman's VSS --- destributed-key-generation/build.gradle | 220 ++++++++++++++++++ .../VerifiableSecretSharing.java | 54 +++++ .../java/ShamirSecretSharing/Polynomial.java | 119 ++++++++++ .../ShamirSecretSharing/SecretSharing.java | 56 +++++ gradle/wrapper/gradle-wrapper.jar | Bin 52271 -> 53636 bytes gradle/wrapper/gradle-wrapper.properties | 5 +- gradlew | 10 +- .../crypto/concrete/ECElGamalEncryption.java | 2 +- settings.gradle | 1 + 9 files changed, 456 insertions(+), 11 deletions(-) create mode 100644 destributed-key-generation/build.gradle create mode 100644 destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java create mode 100644 destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java create mode 100644 destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java diff --git a/destributed-key-generation/build.gradle b/destributed-key-generation/build.gradle new file mode 100644 index 0000000..60ec7c9 --- /dev/null +++ b/destributed-key-generation/build.gradle @@ -0,0 +1,220 @@ + +plugins { + id "us.kirchmeier.capsule" version "1.0.1" + id 'com.google.protobuf' version '0.7.0' +} + +apply plugin: 'java' +apply plugin: 'eclipse' +apply plugin: 'idea' + +apply plugin: 'maven-publish' + +// Uncomment the lines below to define an application +// (this will also allow you to build a "fatCapsule" which includes +// the entire application, including all dependencies in a single jar) +//apply plugin: 'application' +//mainClassName='your.main.ApplicationClass' + +// Is this a snapshot version? +ext { isSnapshot = false } + +ext { + groupId = 'org.factcenter.meerkat' + nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/" + + // Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing) + // Should be set in ${HOME}/.gradle/gradle.properties + nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : "" + nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : "" +} + +description = "TODO: Add a description" + +// Your project version +version = "0.0" + +version += "${isSnapshot ? '-SNAPSHOT' : ''}" + + +dependencies { + // Meerkat common + compile project(':meerkat-common') + + // Logging + compile 'org.slf4j:slf4j-api:1.7.7' + runtime 'ch.qos.logback:logback-classic:1.1.2' + runtime 'ch.qos.logback:logback-core:1.1.2' + + // Google protobufs + compile 'com.google.protobuf:protobuf-java:3.+' + + testCompile 'junit:junit:4.+' + + runtime 'org.codehaus.groovy:groovy:2.4.+' +} + + +/*==== You probably don't have to edit below this line =======*/ + +// Setup test configuration that can appear as a dependency in +// other subprojects +configurations { + testOutput.extendsFrom (testCompile) +} + +task testJar(type: Jar, dependsOn: testClasses) { + classifier = 'tests' + from sourceSets.test.output +} + +artifacts { + testOutput testJar +} + +// The run task added by the application plugin +// is also of type JavaExec. +tasks.withType(JavaExec) { + // Assign all Java system properties from + // the command line to the JavaExec task. + systemProperties System.properties +} + + +protobuf { + // Configure the protoc executable + protoc { + // Download from repositories + artifact = 'com.google.protobuf:protoc:3.+' + } +} + + +idea { + module { + project.sourceSets.each { sourceSet -> + + def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java" + + println "Adding $srcDir" + // add protobuf generated sources to generated source dir. + if ("test".equals(sourceSet.name)) { + testSourceDirs += file(srcDir) + } else { + sourceDirs += file(srcDir) + } + generatedSourceDirs += file(srcDir) + + } + + // Don't exclude build directory + excludeDirs -= file(buildDir) + } +} + + +/*=================================== + * "Fat" Build targets + *===================================*/ + + +if (project.hasProperty('mainClassName') && (mainClassName != null)) { + + task mavenCapsule(type: MavenCapsule) { + description = "Generate a capsule jar that automatically downloads and caches dependencies when run." + applicationClass mainClassName + destinationDir = buildDir + } + + task fatCapsule(type: FatCapsule) { + description = "Generate a single capsule jar containing everything. Use -Pfatmain=... to override main class" + + destinationDir = buildDir + + def fatMain = hasProperty('fatmain') ? fatmain : mainClassName + + applicationClass fatMain + + def testJar = hasProperty('test') + + if (hasProperty('fatmain')) { + appendix = "fat-${fatMain}" + } else { + appendix = "fat" + } + + if (testJar) { + from sourceSets.test.output + } + } +} + + +/*=================================== + * Repositories + *===================================*/ + +repositories { + + // Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral) + maven { + url nexusRepository + + if (isSnapshot) { + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } + + // Use local maven repository + mavenLocal() + + // Use 'maven central' for other dependencies. + mavenCentral() +} + +task "info" << { + println "Project: ${project.name}" +println "Description: ${project.description}" + println "--------------------------" + println "GroupId: $groupId" + println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})" + println "" +} +info.description 'Print some information about project parameters' + + +/*=================================== + * Publishing + *===================================*/ + +publishing { + publications { + mavenJava(MavenPublication) { + groupId project.groupId + pom.withXml { + asNode().appendNode('description', project.description) + } + from project.components.java + + } + } + repositories { + maven { + url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}" + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } +} + + + diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java new file mode 100644 index 0000000..fea7a1b --- /dev/null +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java @@ -0,0 +1,54 @@ +package FeldmanVerifiableSecretSharing; + +import ShamirSecretSharing.SecretSharing; +import org.bouncycastle.util.Arrays; +import org.factcenter.qilin.primitives.concrete.Zpstar; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/27/2016. + */ +public class VerifiableSecretSharing extends SecretSharing { + + private final BigInteger[] commitments; + private final BigInteger g; + + public VerifiableSecretSharing(Zpstar zpstar, int t, int n, BigInteger s, Random random) { + super(zpstar, t, n, s, random); + this.g = BigInteger.ONE; //ToDO zpstar.getGenerator() + this.commitments = generateCommitments(); + } + + private BigInteger[] generateCommitments() { + BigInteger[] coefficients = polynomial.getCoefficients(); + BigInteger[] commitments = new BigInteger[coefficients.length]; + for (int i = 0 ; i < commitments.length;i++){ + commitments[i] = zpstar.multiply(g,coefficients[i]); + } + return commitments; + } + + public BigInteger verify(int i) throws Exception { + if(i < 1 || i > n){ + throw new Exception(); + } + BigInteger v = BigInteger.ONE; + int power = 1; + for (int j = 0 ; j < commitments.length ; j ++){ + v.multiply(commitments[i].pow(power)); + power *=i; + } + return zpstar.add(BigInteger.ONE,v); + } + + + public BigInteger getG() { + return g; + } + + public BigInteger[] getCommitments() { + return Arrays.clone(commitments); + } +} diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java new file mode 100644 index 0000000..69b4da5 --- /dev/null +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java @@ -0,0 +1,119 @@ +package ShamirSecretSharing; + +import org.bouncycastle.util.Arrays; +import org.factcenter.qilin.primitives.concrete.ECGroup; + +import java.math.BigInteger; + +/** + * Created by Tzlil on 1/27/2016. + */ +public class Polynomial { + + private static final Polynomial ZERO = new Polynomial(new BigInteger[]{BigInteger.ZERO}); + private static final Polynomial ONE = new Polynomial(new BigInteger[]{BigInteger.ONE}); + private final int degree; + private final BigInteger[] coefficients; + + public Polynomial(BigInteger[] coefficients) { + this.degree = coefficients.length - 1; + this.coefficients = coefficients; + } + + public Polynomial(Polynomial polynomial) { + this.degree = polynomial.getDegree(); + this.coefficients = polynomial.getCoefficients(); + } + + public BigInteger image(BigInteger x){ + BigInteger result = BigInteger.ZERO; + BigInteger power = BigInteger.ONE; + for(int i = 0 ; i <= degree ; i++){ + result.add(coefficients[i].multiply(power)); + power.multiply(x); + } + return result; + } + + public static Polynomial interpolation(Point[] points){ + Polynomial[] factors = new Polynomial[points.length]; + for (int i = 0 ; i < factors.length ; i++){ + factors[i] = new Polynomial(new BigInteger[]{BigInteger.ONE,points[i].x}); // X - Xi + } + Polynomial result = ZERO; + BigInteger constant; + Polynomial product; + for (int i = 0 ; i < points.length; i++){ + constant = points[i].y; + product = ONE; + for (int j = 0 ; j < points.length; j ++){ + if(i != j ) { + constant = constant.divide(points[i].x.subtract(points[j].x)); + product = product.mul(factors[j]); + } + } + result.add(product.mul(constant)); + } + return result; + } + + public Polynomial add(Polynomial other){ + Polynomial bigger,smaller; + if(this.degree < other.degree){ + bigger = other; + smaller = this; + }else{ + bigger = this; + smaller = other; + } + BigInteger[] coefficients = bigger.getCoefficients(); + + for (int i = 0; i <= smaller.degree ; i++){ + coefficients[i] = smaller.coefficients[i].add(bigger.coefficients[i]); + } + return new Polynomial(coefficients); + } + + public Polynomial mul(BigInteger constant){ + + BigInteger[] coefficients = this.getCoefficients(); + + for (int i = 0; i <= this.degree ; i++){ + coefficients[i] = constant.multiply(coefficients[i]); + } + return new Polynomial(coefficients); + } + + public Polynomial mul(Polynomial other){ + + BigInteger[] coefficients = new BigInteger[this.degree + other.degree + 1]; + java.util.Arrays.fill(coefficients,BigInteger.ZERO); + + for (int i = 0; i <= this.degree ; i++){ + for (int j = 0; j <= other.degree; j++){ + coefficients[i+j] = coefficients[i+j].add(this.coefficients[i].multiply(other.coefficients[j])); + } + } + return new Polynomial(coefficients); + } + + + public BigInteger[] getCoefficients() { + return Arrays.clone(coefficients); + } + public int getDegree() { + return degree; + } + + + public static class Point{ + public final BigInteger x; + public final BigInteger y; + + public Point(BigInteger x, BigInteger y) { + this.x = x; + this.y = y; + } + } + +} diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java new file mode 100644 index 0000000..4457f95 --- /dev/null +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java @@ -0,0 +1,56 @@ +package ShamirSecretSharing; + + +import org.factcenter.qilin.primitives.concrete.Zpstar; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/27/2016. + */ +public class SecretSharing { + protected final Zpstar zpstar; + protected final int t; + protected final int n; + protected final Polynomial polynomial; + + public SecretSharing(Zpstar zpstar, int t, int n, BigInteger s, Random random) { + this.zpstar = zpstar; + this.t = t; + this.n = n; + this.polynomial = generateRandomPolynomial(s,random); + } + + private Polynomial generateRandomPolynomial(BigInteger s, Random random) { + BigInteger[] coefficients = new BigInteger[t + 1]; + coefficients[0] = s; + for (int i = 1 ; i <= t; i++ ){ + coefficients[i] = zpstar.sample(random); + } + return new Polynomial(coefficients); + } + + //ToDo make it safe : permission to call this func + modulo calc + public Polynomial.Point getShare(int i) throws Exception { + if(i < 1 || i > n){ + throw new Exception(); + } + return new Polynomial.Point(BigInteger.valueOf(i), polynomial.image(BigInteger.valueOf(i))); + } + + public static BigInteger getSecrete(Polynomial.Point[] shares){ + Polynomial polynomial = Polynomial.interpolation(shares); + return polynomial.image(BigInteger.ZERO); + } + + public int getThreshold() { + return t; + } + + public int getN() { + return n; + } + + +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 30d399d8d2bf522ff5de94bf434a7cc43a9a74b5..941144813d241db74e1bf25b6804c679fbe7f0a3 100644 GIT binary patch delta 12486 zcmZX41yq|svvzPP?(QyyLXo1SxVyW%yN2RLiUfCeDDLj=?ox`o7wJ!F@BRMXFX!a! zoacRJc6N6%nQZ1;B1AwA1d^O21SC8F01FFn_-HR0jYJ9id+a_H!Hwot!&JX;IClU8 z{D)-nn^Z^w`8tkJ{~2$YUPlle*v6|+jRfuh{s#(x{P72}fy(&!w&lv^mC9Xc4uj-gJ}PXIYkXFNnq zgh?G;o44QC4w^MbfBrZriQsTX^dDeFNcACorax!Hh?y=*E?E z>28S}PAt7)273+$D1@AU!RWm^&SHYq#b~4O`fvrImzr_JoaRC^J`j1x-*KgI1Zm$I z%PGJTuBe~-j5WjrA{2?Sf`SWmh^5tw&3+dyrxFG&ZxYVajj4s1fb-p*u?Q&o<8ZMe z79}+dWV&Uqg}w!(JotKUi9N270vwCL zHs*_zD}vXG4Eu}uaZ6JoDi?tz2ePpYT6~DaF*oTHLIH&YBoS4LP?ZVUm;*gHL=q`} znTsqY?<++spujTVNGYa_7!xB9FJ3(blS}c@LL#aLL4jP=Z_naIsFF#Z_x?BpZp1aS z^7Q844?y)C3KP_yu!h5m{2SJ(ILa_czr&hyt!@<`9RN6@1^ptX0lx9V*s0~GZeCnu z=%z>M8nP53a}VagLqQaeT0n_9VH0n|1LTf-VHwkZp zEFCM8yFo2^A07tceVpmQV-o!M#pMxTTwi)~8o~*09Ptd7N7h3k_k-f*Jy>%0HiXuY zF<9}o!+mK~zCv=bz1AojJk#0br$Fq%@LsUwamid@QAWa`Bd{^VGd?_xFw>y?`V!u~ zoMFS!P1$#R=MvnlMA6OJH{Kt+?;y`SDqo(a6cv8=!M*J2J+0U0u8a%E>Wq1DQAyvi z?dvHk*t5VE`OP^%+0MDo8pZhNloFKN8(ZZ&vcP4dsX9Q}?lG9fW*FugYNpEOa#zCL zy~2HiR5D%QH4sp1-`tf2u-J!wVI=CApcNX_88f$!ve2p5LmWh6d z5taw+9JWn0Sw+s%efhH~9BgH_jZT8A`L$AkqX~!2SHR>DqQg@2S~QbVN2uw$pKc81 z`|m8nh{OdhER(#V-AoIj^^zwEWS!=msIKgK3irkLR#!!`^B0MFB!HZ2=wUtA%+pr& zU!)QD?Kh{&G_{=vb5X4$VRssB-mrfk>&%`GUz4MVd+&;CIT9j|4Uaqcor^brxoWmS z-i&7xJPLSO_TDhRHgrE`Dsu90o9#p6g0W^|%k_Ch=ljaVa9qYBv*zf9Tthh?6y*JA zMvt!8Q>TLY0~U}JtM-R5TQXEJVpvLqRTjLF++L@;5@^jdYJw$wmwdD)<32$0V@fVVxta1fN9ZP=5^WsRWK!q^7w>@G#fvSKaEhT01vM`FVexM*rG=BI zM1`({QUwCP3A$bm*ihBdVnLjSAmwy1OUhVWx#xs@L=lEGXGT}Y4VKDWs$vDEl7P?J%`9x&4WF+-y;D9o zvonQWGM_~8>850V%oPS(2FwFqeu=lm?92umz;Ga<4^ zw+Z-xl!J;MkHWOol7|dF5t#RC63v9ji1r6y>N1^r^KdjTVfeMSh?%K^S9Oh3O%3%d zw0*G>hd(ypc@@3it4DK0lySf@DzN7>hSK!PW>iVBsw~A1Qj@yK zniLL$9_A?1Y+5rmZo{TH37i~l=9v62@qB8;l1l8%s-95%aG@C~DyV^w(&(8w*kL0e z7WtlQg?<1Bp2vcCv^YJ1thzeMQt5mTy8LR@5!@QA0^XieJvr|#jWRF zimb`lNpzzgoS@6=#SP79sL!q0w9xTilsLjOxG6U%{A$l>_QGBH4z?!?i3DSd)KFzh zhdpMcY}gDJ@-u4-YOL@v!l^Z#)YVad>|{Z?(*a?5%<|&-N5>EsTf@W$eg<$56X{i} zY-in{X!tRkrvkPdwG3(JQSU`YB(99T^_OuaEu%nq#zHX|1ks~lXq>oYhmJo3Ye%Q> z*^Lb40?KLCt2u)m3>h%ls>HP#SwMH8qK>kHP6jk^AOJ$D$BISLN zHlpx;CA*>Q@#2~k8@YXtpQT;R%59%*mF}t5a?WrR}FdIvqQR^1f<$Qp?U~xE-SbBw`X4fRqtiuZqKy` z-kuoyce$24vOPBq-Jbcxo$lC*Ic5yqhM^%BK9W2k;CD`JMHD3(i$qv;nKT`FX;L%R zt4#bzpxCwCY>1vQu$L4Ru-G?|nl|)KjPLNlPase!W6S5z9SyZ46#Je$8RpG3Rlqnh zc32{k^sWc!{jjsAa-ZS_{D^Q9HMG9c%s9&^olZAhX$Q^O;Jh21%2};4wdBp8 zRn|tUmb?;Ds%~<66OlFQ%Gj}Mx%!0@OT!zFVU@atph7vXQzeZE7`&7`QDjsr+7a(PK>fwM+Q-uG1R=VH$SMVScP6ZzK11A9uz7U zlzLLyE4Y7AKIeilVCL)+!EW(!M-(a|vdAlhSoIDrE(4>V_=nHYoM2M*+vtf03h!c` zkNk@Fu>5%!(--Wpz>LWhzwaNLaV250I(BibCa8<;gF4?T`s@ZbW!uk?rte556hAVY zqSA>f^Yx9>K5ECcQ|mDh5n7suYLw`M=_fhJ91<1p)_ir#RsrpK>TF^wJ@fI$ep!+a zBv70%E^+Bo@`=_(E7FPo5vPwegylikKIAE<7{X5xuQM!#57enBdW1+~f7rHU&%gNT zMu%1>$m@;90?l^~%qAncJ$5GJR7y zL+|5&h{Tt+kU(x$Q7*%$il5dVHWFimX#6eoHtw={{F9>azf^YC&#&p)$6d+l)7>;b z-lyzGM~RNsn;pUIgqvF5?%W~lRK*tMNlRa(0z*|HX$b6x2xNc?=8FT|e*5H9I|S7Q z@l8afwIK68r+u{(A->6oPn)on$K8S|tyu=|eccy_1A(g<4HvjJwTdcZtrVC0``c1! zhl@QT>^EI<@VNXYvonI6UncbD3C4cFLz#MwXhV;U$gR&YVfj73(H{F@Ox=i(v=!49 z_4N$)4ORWOx0Ze)MJE+D;`jbYF!^nE8j!Z;Nm?;dMCnOKp568;UdI#O;_~Jo`ZX`k zN+%6%7XlzGQ)M*)vuW&HWO_!cK@m@7xy|&G3J-aIz$PYNEDI=N(&mk*kZy2V{ITN* z&B3y0bH8#18OPxFd=_&ZICPJVD*3*Fre#yD&lsr$0+ih{GP7g)OJAOwZj5+hst~>u zY^E3y(?Q%#`ZJQp5Z zlQzuBx)?>fK;lOf#5&G-ABU|bTp z9_q_Y!K%}FFmjYQ8(gV`ly!56BX`x(GY&S8LBQNKD%n&GpI#lm&7O_T%DR${zWPZ? zka7$>%#1Vq^rKLcaxh_$8-I`pe=3h|I;p@Y1`{{+0~ke-=G!9ndXrzf(X16+V_>7_ zL=-X@c!E3*yA2m|asoK5huktKGSWBKYE$;@hm7(S@8==AZH+^xi37=L-HlRgLGF zGa-%Jd8#VkN2nct3^RHHjwBr-l56G&rf-~567DFJB13kx&yc}068BciGi zxZ?dCD2>Xpag`7Uu@@Z5og0jIw1jnYflLC~UR)_{Ql0{oA0_wL7v}wIcbvFa;YLk9 zj(a;{n~dfqIdQCcU9pwk80^efLhmYz65D*z1(0)K$nbyaboO`B(Ch__nw>LT%A^a8 z-&tOUwYWc+n4F~(*0=s)C>to?>@w+1mvrNk}%9vJp0 zus-=<)@j5=bcK13t?L*d^NkS}>uOr-wDtYlLMe?2SyL-Sx+yl>LmPf#&Swv~{el?M z>e8%1v-(d*VP<5tV0gha-PC8dzf%# z6t+Tl`PeyJ@lyw<$oFk#-W6g~f(WDq<4%R8kL0YP6ID0IG>o~A zrhd__I-TXEQXLU#X7d(~2z|7~O+j#p2$E-d_5qIs!~h5)lYWAV#1So18VtzST$t|R z=(`p(Thj{-y=)uVN#?HB7>_i$op}p6XpCOqnJy$-E)!hDUp8G`;cI7I>Jfb~Ob=6- zKc`7qsB4GK2u*@z!>Ek+2ht=mkC%10F&@XF~+gSR)@gXX|2 zoGzB}zH>C3JT~tkP;df`qvpEQqyw?9rVDx|-L4cJ`OCOJT0$4)Sx3#)4?ZG7IBf!~ zW2GiTp;9a`->v_s)A$vpM4$v;&nbueQ}e<6P~|(OI4pK8L8dvuzoM`{KR?wiwxlkh^E#WuIC0t<%vmq#76O$ zV2(P2krnT&4QJ9S-5#)jjzSbO!K>y-^#qTE5}jZ=TAS))okA~b^Dy1KCcHr*P~jTI zWz>G?6g5k^zZiREwYB3AMC!t27kQLpFqx~smpze}VeoMu-yZ{}r+GOj0&xNpBK9K~ z%9VsF%N{-nP;w)k>*F@zMuFc@B}Bh1c7Aj2v~4@oQ$LbG4x!TrJ%Ky*8&+Q}H}rIl zP6>{P1+w+7z2*0C9xz$=JbP+zjN@6iQSa7a^49(5h-qYg0VIGQZJx-@yaTuni3Rq_ zl~90VR9Wr|7VA0dU3J_Qqt8esl)a~;OZH6OQEQwxK)>P+8?=KQWPw=-+#BC+Vp314 z`a1nb*^Q0wbD9&>D6~mO!qSrp@_`!J)=9TE$#Uw(s%X40Uw`51?FnNPh+x?R1s-hW zZobhNKcnxgtdkr7jXwjj)lnrg=fE_3&}eSjTI)wEU9FJy6r_F`?M|15fF7^LGfzSm zLOu}j0OKy;t<0XY6nae2Q}tPAQfaT4%!A;cESIR@gF%#jlPdTZj0`38 ze3#L1rsB-4yyMS2-0N*q)O_T?8Bo_skpbsxezem)hHPXii5s7UcY02F?vMC-yMeR+ z$n>PUG=i^3D9+}ShUj2H?EAqOk1IRz z=~%PF3S23(V|vQFg|r*EZ~=D)p38+Wu8$WsM5~>`g>URit9B=ULHwVaHwmUUP_LKA zVsrHr(=Qj-*<|$zvshuM`V6@y;ih~ZAPCJ)DBI5n$9$z6-*&qBp`IwhK+h- ze`GzB-8W)e4am=~=t6U5K~{Myr?oIxF^SWg!_a93%pz_^`2&Kc7>*HMp6QWr!3ar=Avg5(1C>V!&13a?6hiA z*11#h@l`HngW=_R#_7K0V`h<}pPqln?GCVy{|Idv-K!g0#UJCbbakrH?Yz)#6>QES z_wVKnMC0X#+VY#ue^-{G@=2Cn?MGsICEDQEtQD@&ZyFm*$zoH_biu6pPOywfC(|Ps z-h?A+)4251Ln2v@9vVQ|-dg*VN*F&ndgqH!RT~yu9@n|E zatNU(H#UEDzZz zzt7oG=&K}8L}L6(RuWv+s_^I0+91*_=kks$@YEp=Y6ZAMFQ{E0W^FCXzM)%%;O9^J z&gsYLPw%{!g!@gUsc>5RdOtK-EzK0LDXzzev2ypbk{QiN(QszDr{$33X%gmix1yES zM87k9bFQ-h_X9!f;oPxreWtd7aSDeGG_uL#5hj!O@)LNQn+>|$&sW+!J}>1%ffYsF z7?Yxau$O?E^3=o@P%vG{S_325Pm?6t0QF!=Nd|rVDnBu2?1GBlr?XIYFCH7&uQRTN zL1|*@@sq;bx8*4GX2}#L-X=;6&bYDx+VeT#IX_2<7-!@JVbEFXrH8sg&S&t`}f4AyU0Fm5x}JY~fm!dF{-0ZFU!fJDX568O9qZ%-#i zYmO&bPA!103Wk_R;vssv+*$H*3OuaHB0jdNXLt6~p{EdG5tM{qci%=-q-WDPur-Qs z)CQ%%M=)wRGFro17P&o-`PE7vZ$^vrmIdEZ#tfb{5V2p=8Zu$#Ba+V&5lI{%cyfYV zq(L@AmSx_EidW{nyQ)Kwtqz#=@Xy1o*9VOTI5NQAZ**XJUEd&;^AzCEFqt1ii|Hg| z>Dm>_=%{HVF`bZb^qU(e2rOB=8htwCQ_|-Q4Qx`OF-B9}kJS9BJwPNLzH%qGx%$#4 z&;(bd=^jU}GhSgk!iq}_hK<@s<|!+2suxJ~A5w=~-Nvui6l5Z4*4hq3S8-WC^AX@@t;1;pM@wu~Kwg0E?DZ>s!E)D%cxic55vftuFo zTC@*n=0-yO@XW@}VvhIVAlnBY`lXM`xoDfxf%tMVp(=Hl;&x8ct#f{7AxEaI*UeX- zp&DUpsKMeUOi5rl+s3hea^T4v_p-6_9x4ymBX8TaWH4?BRp6fIB5Pq1i(QuKN}M5S0IxH%Bf`2@XKq{klg6gSV+V6Lmjo}xIg zeL(P=u$Ya@n4m-BvhLdHO~O21yK4&zIgmywK3L@tWIBtQxz8s52KRI^p*9)Ge##laaIZbH;l=t>}DQJCNCC%Pfmu2 zCtbX1yWo|Wk{@h*BM)ae32Qn1<@wR6HyO%P{b9!_Yf)PlggDu|d)ynqb`?da^R#?D z?MbWl>cDvXCsx9C8W0i`i3C2ODYC~_vloW)f)MB`O~GwxcfD{OVhj7+Wp41`)GUeR ztvtc6U4HQRCNnHGPIV#-ZPg?J;{)}AtgJPQp2!MooY>x;L)J{zW{2PNM$nrDiVyYM zCO@di+`4!oqAUnzU8`Gh`sF!trl~jkV403=jo@lHtLP&k%I~=3?}d~pI14qy1~~%kT|nAs!tgJ#}l|0 z-N-(dFd*I3WD8z<2kvDL1im?L4QOu@ghd*tk8s!glv6Ax+Q-#b`xZMO4pOm60BTl6 zUO!|}soxf26APl7eWt`gxOHfZf1k3}?L&E$w(Ce!GJo6g%5&9cT{z>8qO#{MnYi-+ z?v1A6i6qOFOTv?TmJhmacXZ>MRV$m8_Gw|_F(Q%)aJ5`ZFzi2LxNo%?=T%E^L59JXj00WZ`hGZt8Uywk6qmcQ8&h0Dkj#Or=Pg=8Y ziX@UXU0#%&Itw|orHgz5JTK9e7{yEyU!#;W7ctVMtbEqzNYn=km}yKLVKiK|MRl#g zce}>An_hkT;eqdJ{Fj#lQHRK*H*S-?T92!cmukETH6uVOk(zOlGc8DJayOkU@1Y8A zYYxkW92MZE%rHBqiV;;fExC20IqofO%@^r0x}Om71$OGz-_;E%*B#Oz(s?-s-#uM@ z_V!P$kr=5ezs!tdat~Udbu!js${6z$8DpOo<;{^}ZoLwlxS3CJ@X3BRa@H`}Y<_8H zu0TozS&c}YL6rX)v>TuTT%mKZk=rxFGM=FQ8DtF%TV)@vd?bXAq)uSbN(?Z`S<+zg zkPnl0B~+UDxk^yo#$x#4hn%^?$kh$Lp+c~m$dJRt83V3rTym)b82r!7ZDv1fj4&#; zd4|fwu?Vet5mN>w&#IEjws*iPX4NM-na~vjXF4q+9F_+cj|q-O_<8h8@osJdkI(lG z{qG%ty+KEe5ou-lgZQ^qSaM*F9fXgQc+u5p9g%H0&Ui4dtrd`Qb z>4nm5_LcG+WTr_~ZyG`-!}_kch=4`qs-x8X{kso3ljm<*hCHqtM4hCD8<4;4yAj&% zxheK&W_#kF(gb+I2kjo-IT%B8j6}i^>VNf4c`cKb135mCm zfn3ia)2Lp#+p>3#ki>_HsQku9yZX#}OZiMPV)#@u*I%bsaYsb#RQjnou{(909x->5 z8X?96RkBFxC_1>-^EM0ar22R7KJ~Bn?D#S?8PXDgq$Ajr)T)h8;T(L12+T3c+w2JZ zMm_R3Qy{*lcg5$!2v0M%nb`)$RP`t90;Pf9NGrg%ggA*5yh5R6h?Ru2^6~q|$$J+*O;bm27LAKkHAzAx~io z<1ytp%N^CafLk(psYEPB;gUw~N$@GfE|2E@-nS~S*zoBN_W2zt*FP#ON@`8u0u>FL zr4BGh5A5xT9KL;AbJ>rAvBa-B1?Sd#4vF~jqsbD4s5Q2saCP1g{ z?>+o0XqDOhJgdzhE2y&UAg>d|w>bOA@`Y*6!807cm-G@x+e{{}sIx^`&qWtrs{A}Z zY^4Qk73LtFz`1_sv0LOD@wnhJ1#se|9oFo6q%jdu<4uJ+_|?<8ZM=tSy|x414#JzS zJ*1a~g%w|s2Z{Iur_8Kv6PgkAmNl*2yOlL`9OB|{weog^2X>u8et9qSEiNxEhhYgV ztR-sjL&Pb@anopiAP)C}$ph-_uZP%X z6JKy{Nq?gEusui3r<~E;Md6M8iNk2jz#Y7h#cK9O!~=JDo1SJ!%{?d*(?Za=G`TPN z+PJ5nG8vw7XrtS>y5Z4@ne`cuY>Cz^>zHslQEloMrsH#P)36#Z8K0@W@hr0sCck1{ zTy&-~t}4uWJ89EN^&V^%w;iy~Bsa(eYaZczS|hMb;}iEAo#N?*x2=|#e1cAv4Wxa} z;nA>;U|_KpQ9^E5^O31PPYaaW-|sPOLx1V}HK(p(oRyLSUdZ@4$BhLi2=7US5XD4Q z`?;Y5Ke4?`gR+J_48yU-haxMjyy8}Y$U!LCyUGobx@;auI5=L- z89ul2Ir6M4Z6Kdp7_IMII`Ww5L5jvJULJ5{!6kqnD{@4I3&cHQc~4kK%54!_%Tj1q*W>%X<|&7evsJ1{0e4iHxR8zIRSGvSsD2X5}vTaVcO6k9C%cUbrK9%O_Vv z#h?MG3n~2g`QtU%19Qr!v+L=7d6x)9L1Yy_(9}@5^4JX^8?%_u)4b;+qRt{?9G*1E zv6&#B@wUkpt?WpG<9kW%#=PQhCU1LAOjy@r!(`>jRSA4PRw&6JUnWEzo+7P11Q~X3 zPJHPWims}+8r+wuJ1_+wzPZNLe6#Zld^TBIE82RTTvSo)4PVRoa0M&yKRfq(y&y6z zddS~GwY*j^_^Sk3(b@Y04d_1qfvSfL_WnwB#xY=jo=TY#!TynKY>6QLNKp=4f2A?! zDX2eKuIK$V7(F}UF))zAO zE9sy6+J8vCoUayTkbYm^;=Pjpx0wB1%l<=75_}~mbdbLi|5Mch0A&9VK{Btz(+>PU z+mF|Jt2@bIpG=Yd+8F zzGR+vB>$aS{(q8*-btM=c>Y#6AWz1w~WzO{fAL4IgQ3F@; zJTE7&_;T{^{$uOq~INxcFOvMb|ho|An~s@}~Jmfx-wR+fNQc)P(`@bR+!n zLaG}N9L4w*59_9Wb-$%ln&o$Mw*SkFy#E+LGkYb<^+AIky2<_+Anm~ef3|qR2|ydh z*dV)}zlMEZ@K~!?etQqiAMW7`R_FA;Hkf+}{@`-Gc;E}JuXtoH-5;#=1;g@uwR`7` z0J0nWYZtW-5B$jYuMP57hc(@75@TQDydU-d#`(S<=$khUsJZX2^6-mtXDDd5PwZ8Z z#Y(kK;$@|fFDw0>BmU=A^Eod3Wd@~JQea*Uwka9_(DxFK|9*-DBVR~lpq>6d*$nj1 zj|YB|1&SP|0r3yu{#l0B03P^O?q7GIL0JPhf0y@y_ZGYyATB63o8rF?5tP<~+4ABU z$%|(U|KrxnSo7JZ^kqq8pnvwncMuOe;M@OB(mVL~Yz|*=*Qyts0MwX`{9ls@PGbEy zfB*oz-T(kR|4cGp{c5bE93PZA^mp${hw#Ah8$g>?-2Y{W5!1{M=Ed9QmsG&=kD-%B z5YzC-*L@VJgT3W_nQiDLS8)GB5^j0fGx1l_|7PnK!oPWLxgC_%L<+(kL4nrk_^tl` E0L*8@(*OVf delta 11073 zcmZX41z1#J)ArKcxpYW(Nq2)F4Fb~LARR7^l*H00(%m85or_2}64E6h!jIthy}$3b z*R|I(XU=_}nP;9kvuB?(!MQM%DKO|NiZHOq001H)fJA9mCJvnj@z2-|-LMoVsDqb! z=5p!+1^6#e5e4iMc$DsWykdJA!HiIAPeLs^v*ti`>d+PL&S#1`olM^ z3}`lj1^_VO0RR?o94tOq8J!puzvwV6h8b!J=2Ir+9nWE5*%8b6sP_ZD381Q(@RB4? zOjSZJJbhR`YM*f~?$EziJwPhB7Y?ISlG0*UIh~m}9A#p3d|dS0>tGf1{vO(2KuAR_ zKo>oVKPBjr#7+eilcr?z%BI1rXv8Vof8kvZy^~))oJ$hMJC;I5--0{r{!YmLT zzfX*LtUC91F)#BEo_kVIeJmT}-ZW1_eRq9?p}p~vgEwiSibiYEgC3I&>2bs{mL*=9 zpQu3@wldj9dLDCzP~C6i$@=UT*GQ(%n)Yg}c*81PXl+)9N4&&zVTUsNTi?6(Ly^x_ zDA+|;cz%D)K_OpC!7Q2%hp&G+2|2O*QIg;*T#K@si&WQ3$v2b5tDNbzDh z?dwfWnSjX|v?4fhjq(b-PdkPApsE~AVV}T79jlXJUVRrmL@>p=P9bItPYuUvyl)<* zbpk~)PGsy36h1;_rIUPhaiPrFE_t-?Rm-eskcp|dv%!=S(JeDr$QuQBqQDD5KIV0mW?mkY z(HPUYV`DEmZ@l0Zc3Ply+l0_M5MxuP4yIhVOkcbLuQ*J93tucy0<|57-gTrd&nW1k zp2cLZ_?)j?wg2*5J*z(k-SAK?j1vUn7V?^1zXO8qB|;q&O|BJz_X;8p0&>RQ>N$=+ zA3AOlDH0(bTL&z_ds;b=B8VXG7_y46hjfboY%iP?g=dg@c=73>Y_cO^ssqx&aB&QE zixG0qCFgcwC|;8Hko5ZjY4TzC4ut$06#EjAE?)BKc*F??24_5_3oaRUj#|(l#1Huw zOc@B4kAgT~yyW{QRC94Huhj1E;x_rbFs&q9m6$1sHOO#Yc$HdB66-wBZ-9A%Ul`?l z_{&ZfDC$v8+k9pHXV-&fM=;eqC1VA=a=YUw+|K&}j>sq507oPjp4o&mtrhryrk9;= zoUphjF&tYAA9Xr`ghd#TnA#gYJs@lT3J;l$6i=#R9)4w|CLQ==#T8gj9((%X-=R zq~IhHdtem{HGgxA^_%3>SBtt3kpdb{Z-2p*JEV868jUGOyFBGnNvevGbQeiTii)6o z*V6o1{@yXMr3^XRS1jXoIfO=af zZ=tAjJWw(A_gu4+zLKoyMi}pY*@OFZ-bgIpvohh@{L_BR+ehAE%zc@I)-f44o0@b* zB;O{=C6cEn%R>?YH)_n{{Hhl9X50bfeaJyQR#!o9Uadq0brjT-R59<}7}t<`#K_p? z>=7z18#NV`KOdU9q`gD5%&sRzXA-gA{jQ*SQ3fu2gTfIg3A`bz!+!Oh^)}C;5tS?) z+RR)+>VVZ>y$NTr4W%*ls}&~_5fa*P5VZTU+LxKgSpQE{LT3Ty&3fgYBbZao~pvS>g9iA5-CJ!n$QNg@3gKBh(Wbl$D*=tKP*X#+VBXBuZ+Lb49 zN+|B_{OsCEsAS{b4|lDJS=dHwVI*!t23T5-s5o}I7(BDSmF&rkg5LL*BttnYmFL5fs7B~8Y< zeiXsnu-}RHHf69=anyWl_LarNxRxu2#vn~ulQiAsRB6zk;>Y=bXm=ZtXxCjQgu%70 zd8$o+EWcCnN7&d!@8 z@se=ABo-+5qW9w~al35gK(X5RMo01%{g=KDs^i}`>RdQ3%Su_vU#hE5nL+*D=1)cb zd4;z#eA&1qWJU z9v~?`lqm5mn22LcYdMD#2(t>KurU<)+zp-8Q-A)g$ssk?rO6$s0#uN{Ccxq0)u_MH zXeNp4?Snp(MRQJ>j4&F-Q`SOOYO$UM_bNZ~qE$iLN;f~d&`@R1^ujrjtRPqcK2vkg z+FK@HwuzWK`64(@QJ66`LCrctMGK?Imz-RKkMX=k<2~$4!n?D!dL zkzB}*lx-I!b*g4-)h(vl-WVf92y6MPKdg|@ONY-koMNc%=am9 ziC0=@qv@eOcLgP~O)~05bsv<=&%Wpj+#{L0lPIlWF(O`R|He7vk(w&Cnp}mW;E5!9vMWc%jwQyZ1MqTNosv3HYRS4lr z5w8ol6!$=%R#XkKbvujCD@M2kwSNcsk2KOxdFW4W?~5h;n5~)U`}p}-WMD6rA&d*( zAl6-xfL`v!cSd*dA8^Uv&rA8JI_0jS3hjjOe^V=02|6Z9$7F&d<7V)DinVaR?AJl8 zH#3f!P!@17G-y6eeP+JBl%G{n%ooO%&rHg7Q0-9%S>(06^CFY0_wC6%Pq0+6Iz6ehM))8>3(YLr>m=ie69*4s&Fd1+rj z$q@+f#Xe+~uZd-hzw{YH+QQe!<0lGXm$s%a;=0|+iA$G~`??33u2{vjhx+ZHjb!=_ zzr^zWv8L(;V1=U~|JN(UWBJ|9K`f^)HF+Y|mLO3A0WT43yxr+T>))FgEgk;BJFi-c zXlxlY`di)4E!yjv30b{_Xsc5Fu)!EB?yPGXcwr&l(nIy3%i z9h@R_swrWL8y_b4jnb=6kZWaiJZgY%8_(Y_m^sSYR~QM^V07k^3%4jcAEHCw6yGi& zX%5nsD|c*?xWDaZ+A4KymKb3b#I=jE9g1bNqw6w0pP{uVy-4ja2EZta2+cEwmD9H{4Vehx*mx zM$Cly89Q#GmZufW80JK+BiFxu1Slu2bl`>n>DBC>!A zp>`cG&q#7vy+4Vq{`M-qC2gO7<43rn8kml-_vRMy#4jN)f8${M-5f()0h?_=rKuLX z$0($K4psWr$X|)Tnyz5%w^HTdsrS!oMqj)Y0(ywX`r_0!#;-!_5otBzp8Habw-N&r zzpf$Cjy&TW9bMwr6t8@cN3%nX$5og>!crc_ei%zSuzZLqy1Me&fW`Op?E$Ql80+ux z>~mj3FeFJP##;H)-#;wjoK$DR}8PC#WaA_zp-bS`|%<8GY{)LEAz;b`D@VhzJ|8kU8lr` z3t=-xU8xenz~80gI-))Z~S1M!#u-$MJ&4m_Joa|Jp@^o%ApQR@+AmJC&x2NQgzwqwil5r_r6z>{;0Ft})^MrfRcITUlPj{E=DE9zPL3@hg5O z-**F%pF4}{X5JJnum$bgQ*4LvFO?v-7r1R_>31+6A*uT8K7T3`-Y zz~qNxQm2h5@E6}X?Og(60Gm!p!3ZJ-#*tk|-XS4oWY%r0zQ5xL4&A+N6H5lT#hX@q3b6 zukNVvrE6^LRSvX|DJ+b}3Yz4(j*uX!sCG`@zroCwyx#^b28!Zi^ z+rC0lZ^bupx0iom-p;`f-)Do0hpFwt=2Hh0oKocB>HCOb;&dTAOut=7^l=w36syk? zAAhlw&@iNG){0b4%D;i=!@G}wJTH9PUF}_M(#K(z!vDnsDEdO+w}1|_Y%6GHsL%^v z8+Mm>*Y*wD5mXdHt=g*paLMS5Mn{lSxg`5W;H0Ak661y5n@swPMKyc>Gml-5T6#V9 zkyH%_kaKVe${JPg_f^RkZ0!dvZ6h5q!D|K%Bcbi9#lwA$Ejfo1BO4y(P+5);a@-#E zSXKv&333RzxcQ-|;TM|ZNGfli?-4zCx<@g4uOm2y`kYsTDVTO))I__z%1u9{`~LyBUN4&g?@6CF*z>5zhc0GO1;2 zT%14HS+4sdLJ8KGb1BM6SP4NF80aXgg*EKGX`Ul6%jC=C+?CU_(qXZeCzymI-E*)C zM{5#OT%3foU9m3vOe)>@d06h{=|fJ!R$H!CctNY4uiqaGA&@~kRbV4;eq%Sl>nhDH z>ay)_Vu{ctiIV67*_!XT8MlfA@&=#w(>n~1s(xJ`r^jD2B6N%}!9xEQcQ(e^DjnK5 zeDZR=T`{yJWa|*CRdU;7c)Vq6Uj_C!=|-5dl{fHe=ntfz@C5F>It z2JyH})pg^84iAeV*O{9k>{VnRMlc5xH^$&l=Go;GJ6Y5Q$d@E)jWU(|Y z)wL9CcGQ}BjURWEZ0;PrS$5J57bnSE|ACV?ac5uHMaZSu+9?#;3Hy>y%sCF3RDJOb zBRBT1Wnfn|s#*)#cmyD`_2zYsR!##+ardM>)RH}I)VZd}Ccj(imUS()MwDC&>_!Ha z%CxJh7Dw^yKrEJyGd0q0yCRUG-lnUyi6AL9UZEY!MWaVwXk}~Epg9t?38j?(c#+mP z+UhVLYM@fpTVH8KJU_k;5wS00Q@4Lv!(FqI&poRACX&F1n@Kh-G{U{zDp`uZ!eMyl zQeTGH197KtY)RQvqATtFblPr4RoyGC<0Vt;7c~NnUqJ5~CDrS=7unyL+00q%a$6;5 zHTa-L=2{=BJ4xH-<8?8<&MWk&%wkm|)C_JOLnYPw>bP~$wehvdAsV>_cI=hye0iGr z;KCyAoRBRpbFN!f=Q?A?wj;YsXq##mO+bSdwI2ya1EUIk*^tLl3vc<3u&cz+ysq7H z5q{a^Ef$b)}i*> z=V#!CYy1#rn!mT8A&=vA>oTh9;p0cRYVnoMbuk8n(6y#4jn8Oh>nFfK{Ec)ld|9(x zn^f;gJpMKh!>l&I@@;|jv`?=olGzyr-Tky=L;90psMYh^7pnbl&v+ILFz?u~-H z99K%95i)jUI7lK(R6&N6M`S~FiIspF%;QM9)28u_S`KU2;Y| zoY`_UkurC~=UODP^x#B}!;)CtyO;>C&gW&{NcX0o^{dwJWfF=)rY@;mhfVFtH!EFI zY$HTO$w~PA7#eq&qSzs#7R8xn!=-Z{OEscECXo^4a|IjogzCn*MctjOc%ogei zYFNuZm0knMv`<}@iZ*sWR|J~q)Y56*NzlJ%2>VelBO;yRmVBx0aKfxZH$rr1HoH2qjaq$5u6AP# z6!1mrgs32*HI}tp`D?}JxG}k$kVq}}V7L4Ywri#qKTAAp2Vr`7@2%C95s73&XcDhN5Mr@TTU2r}k{nkR!u=OK;tW1MWgT>1E9v+p#dOYkRllYV+C)>qH? zWaYCsvm_S_G3YHqu*fsNqImnp#Etb2fG(TzU#GSdR~e;!`FQQ5WjVLm7igJw@zQ{k z)bjfa!)(OOYBjU}pUwo8J~mFtRp55*gX*B*oqs;7pd8R!&;1!xHDI%|CWzkkfp!6g;eFZlB33x(y_!)qp1BQL8F!k zZg5G?50}IZ^FmuRjTse0stSBc^Y_fUJ{xg(zLCA*Y-v;SBTMSu z5i_c<7=?=!rCAevKE@Ph9RBy@Z_5v|7+UyGmRImlO< zt2p((-1*$PZVh*p(x_!RS*zZ~|Gsz`oR$cwWccx=&cIl!Z~wis=9vH+?q0PoO(T4J zM+PbqABEUn8H2H&^IbAZPYP}Ip^!x;iRe7S0*5hj^G=|FKwYVkAe27obww%2h1~L_ za1;8zv!cfZ)hM=ix5#_>_6*;Fr_ zcLs8q6J76yPK7GqIkNRTBi_)P))oO3d$-3ZxFZ*;fuoM;;@4Hw9tZz-(a(pK}RK<5hDs}4E1t@s6343nSb<~Oic#qu)k!BYsUD2iZ8iurkhC%&a1jz+ylhnxG9*hAAL+T8+^F43?3ud!f>JmLdW+d@!`$s<)q8__0>_6& z5Wh|JqAJOdAQxjF@!VTK2yLq)0h_gJZ0H#ycTi#pX)ap8#=Qd`0ElO?v!^&)}idj4pmI zzAN@}fl2{Q_+pn2seBtn8gH?(6gocp%1_~pTCWRzx|rDT-5!Dqp96(_WskP(W!;GV zP=2XJAXw^#S9-Z(0~2PgFM&nOumK79ImczY{DMxSxLSodHLbtEUZ1Dob?*Lq*IA=Q zN@hZ*rM-FDtom^Ex=MKbhK*yFgus>fwmIxv^UxEOo;>rO6H` z7lWQ@qO9P|HIxGcAykl!lQ6P!C4DYdVq;TS|9cb4bv^#b6%OcDuTRlG4f;DqFenA+ z-^KImN#_2TlIo`IuP??8#)HMt&>UbcvGg^Ka>CiMD8Yf*ME}a9Sl9M zlVlXR!s}ZWDs>1H8dxkBMEA2w4tzMOmty)n<%8SY+oTIoDl8Wh~5ZOGM|^w(z3YfL(e{;Yuf`Vx0|R_QLD zJG>eRP2k(A+L^^%3tn1g!JOefPhWMcI?GDA%J&U>5rT9@qIBVCz*H$Mm*fncGN#RZC1!tUVrxs#;yCA5pU&c~(Chv2urX`8^8JC~6zJ1o zTPm#Fhl|M!@UNAY{o`eyRiE>L)s7|DDtzso9QXPSwx> zqeM!ibot>(V~ZG1XGo;Fknmy8CP_K*>#7+bxv?)Ks8GmrA;=Q;t|!7EH(ga)G>@ji zwwbYt!bKmb)tv_1cB>Tw?)TQ^EmypO21UMOQY4m}PqV(zz0HfuSy*2=Qs#774AQMB z5dXwzqI>GJq-N4gL{^<3B~jmZE+6N%t9sV$;vQw>x@Vr#52=e0aX(K?NVr5q?KOr0?g>FH6B=G!4i->2m;!# zkQcFxrcRJ4yt4R;x7nL$#RIKKBCU`?c2uXSSgjN}6NbAVY{UQK98EKtW^oKlk~cBM zpHFJgjtfgQOf%C)Z18S+Nva4xs*h7i&*;rP`fD1OmNHg$>!GmL5LMTVs1l?KYe-Nn z?8`>Bw;UVm!Y~6f^s;HQxqWDT%Ahw}^=<{-b$qJR9}1Wic@CV2%_9PEQ5H=L%8Gv2 z8H{f?X3Z1@lgeoDg43{8%NK$yMuRNPg~Hx(W_Gx7exrDinwj=@ubwVDLENU<5>iy<&?4NfjrxZFkpR-QCt5ty|`%$l{1Z=r3sg@YPl74~r= z%tt)a=a1LkMkJNu@RwV>KK43kk5bi7IE50qSfd7#Z{h&6H@JY=ncK5Fl|O2{_YtV@!siW=6pPk(U@l`MR%+W(pm>>Sco zcOp`1VXI@4-fe%kytV+;}q`OXyLN9^h(5s-XpSG|R`UXSxy$mopIqf5neFsBT(I@gI2>)F416oU`=k{S6 zMYd#h{lUJNw)dxo>rz#a2v~8zR7Kvsm~JS<%q)~-^b(ben;>QSXH!6Q`ok5@*nC2v zrO)trKY!1LVAmIu=C4>5Ice=Sffw&*#m|1-r~<6YCO%$po5^@{?6!$~*7hy7F2B^!QM53P|fRM0foa zkMG62M+b5+$!vkT>ROwim+yH8vl2ARKJn%TLeG>Op2zV(fc!UoXXY~c)2c*eYa9fsYw#nD<#=#H*s4PDIKG!u;k2s{b> zJOy4pPE+XvM6?6nYW0wU(fMLTTToFuhrg81%BCPc{HHTUezE+pR4lC%TmD)5J+d{k zx)ZAbc@nn0nE!$i4v$1|gjJvWLGgdS~b8Tgy^U?|F`nvHs227?CXBuWU_q(?0N^$Fz)+OnwUX)yCy%C+I~qDz+=vYc=@AXx-)lJr z_A;UYwK%{~Vjf&+Q{}=1Qo<=U%RO$;TT_#zbA5xNTT{Nd%P{q6NzI&3y|hi+v>wY! zW2wiyW;#vfyj(vsfpZBVLbI{Xd*AIx@ik-GGZNo0PlSgW)h#9qghSFGHs*XKQ-o5G)WWsGumz>ulFmiE;pgzl{I>S12mHyMu>6yE% z;oFv=0Rv7}AX$RID~+OjfMO{Da?c9(r;uNkRqi$qa57FUo=$TPvIcMIm{PpgT8u64 z|G#~oKXU|o8Z*KE5o!yK!=SPLNSub|F$Ir7+I{@egQr|yfKAOBpD|?S_t4K0h1Kp~ z3Dq_p>WL>xVD&J7004yH006>IJltWD+GD#Zgl9^xD;dnQwCy1PgZ{@9mG_WtJRAU! ziUx)X!UH?Spwue+6u~{CZvAhdo~5h6uYa#G5i$8}jMGlLLE*7w3HFgK^JHvbl&1D3 zO5?9rsxgJw&*ZzDlfSx?yw$(bbYVU0^Vz5}XqYGO8#=4rr957+4gk`wkeR^)yJzI-OO zJQBZ(JP{B2sGo@cd71Vww{f#7jtBCy~f z>a$*PkO+F*09+kK4UQPZdDi7T>Y5FobZdij&pMPLBIs5V@aZ@MSY?Rn$&p=Zv@_X9 zClnuV4vv2uDKdW~lYlFRsGorU-2eXoMJ&OmLyFH9#DvVf^McD@x{H6c-iWzqL6NQg{7yO?!O!9d$ zUpn$PXrm)U&|p7sS{W4>dGxtzfGI|aplw6I%Mn6G zkL1JfM;#SdVC?S&RmO;*Q!>EDt@Pl8G2k<<`cW5^{Wse1;JY#GCqtgJ8yZHBeQ-o5 zk2T~ULyn&xmsa>c%jz>u1WjM~=sD~EPWzua_79o0WvXj$kVazMo+m>T?T;%}lrO%g%()qqJSWuIJT!LtfPcwD}gN4GiuA*R$l u5m}nC!0f}%f&8aN{sTU4cnpy6)6MdKE9HNXbpavGk9Cs+9;xMz^8W#n`xw>$ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 864f396..1360c1c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,6 @@ -#Tue Aug 05 03:26:05 IDT 2014 +#Wed Jan 27 00:30:26 IST 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.9-all.zip -distributionSha256Sum=4647967f8de78d6d6d8093cdac50f368f8c2b8038f41a5afe1c3bce4c69219a9 +distributionUrl=https\://services.gradle.org/distributions/gradle-2.9-bin.zip diff --git a/gradlew b/gradlew index 91a7e26..9d82f78 100755 --- a/gradlew +++ b/gradlew @@ -42,11 +42,6 @@ case "`uname`" in ;; esac -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" @@ -61,9 +56,9 @@ while [ -h "$PRG" ] ; do fi done SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- +cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME="`pwd -P`" -cd "$SAVED" >&- +cd "$SAVED" >/dev/null CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -114,6 +109,7 @@ fi if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` diff --git a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java index f9936c7..6258f5f 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java @@ -110,7 +110,7 @@ public class ECElGamalEncryption extends GlobalCryptoSetup implements Encryption Pair randomizer = elGamalPK.encrypt(curve.getInfinity(), rndInt); ConcreteCrypto.ElGamalCiphertext originalEncodedCipher= ConcreteCrypto.ElGamalCiphertext.parseFrom(msg.getData()); - Pair originalCipher = new Pair<>( + Pair originalCipher = new Pair( curve.decodePoint(originalEncodedCipher.getC1().toByteArray()), curve.decodePoint(originalEncodedCipher.getC2().toByteArray())); Pair newCipher = elGamalPK.add(originalCipher, randomizer); diff --git a/settings.gradle b/settings.gradle index 99f4c5e..5f81a65 100644 --- a/settings.gradle +++ b/settings.gradle @@ -4,4 +4,5 @@ include 'bulletin-board-server' include 'polling-station' include 'restful-api-common' include 'bulletin-board-client' +include 'destributed-key-generation' From 93240c10f469517706b34e1bd78b88c702173188 Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Thu, 28 Jan 2016 01:47:07 +0200 Subject: [PATCH 11/49] tested interpolation --- .../VerifiableSecretSharing.java | 16 ++--- .../LagrangePolynomial.java | 40 ++++++++++++ .../java/ShamirSecretSharing/Polynomial.java | 58 ++++++++++++------ .../ShamirSecretSharing/SecretSharing.java | 13 ++-- .../src/test/java/Polynomial/AddTest.java | 44 +++++++++++++ .../java/Polynomial/InterpolationTest.java | 61 +++++++++++++++++++ .../test/java/Polynomial/MulByConstTest.java | 46 ++++++++++++++ .../src/test/java/Polynomial/MulTest.java | 46 ++++++++++++++ .../src/test/java/Polynomial/Utils.java | 21 +++++++ 9 files changed, 313 insertions(+), 32 deletions(-) create mode 100644 destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java create mode 100644 destributed-key-generation/src/test/java/Polynomial/AddTest.java create mode 100644 destributed-key-generation/src/test/java/Polynomial/InterpolationTest.java create mode 100644 destributed-key-generation/src/test/java/Polynomial/MulByConstTest.java create mode 100644 destributed-key-generation/src/test/java/Polynomial/MulTest.java create mode 100644 destributed-key-generation/src/test/java/Polynomial/Utils.java diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java index fea7a1b..1b44693 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java @@ -2,6 +2,7 @@ package FeldmanVerifiableSecretSharing; import ShamirSecretSharing.SecretSharing; import org.bouncycastle.util.Arrays; +import org.factcenter.qilin.primitives.CyclicGroup; import org.factcenter.qilin.primitives.concrete.Zpstar; import java.math.BigInteger; @@ -15,9 +16,9 @@ public class VerifiableSecretSharing extends SecretSharing { private final BigInteger[] commitments; private final BigInteger g; - public VerifiableSecretSharing(Zpstar zpstar, int t, int n, BigInteger s, Random random) { - super(zpstar, t, n, s, random); - this.g = BigInteger.ONE; //ToDO zpstar.getGenerator() + public VerifiableSecretSharing(CyclicGroup group, int t, int n, BigInteger s, Random random) { + super(group, t, n, s, random); + this.g = group.getGenerator(); this.commitments = generateCommitments(); } @@ -25,7 +26,7 @@ public class VerifiableSecretSharing extends SecretSharing { BigInteger[] coefficients = polynomial.getCoefficients(); BigInteger[] commitments = new BigInteger[coefficients.length]; for (int i = 0 ; i < commitments.length;i++){ - commitments[i] = zpstar.multiply(g,coefficients[i]); + commitments[i] = group.multiply(g,coefficients[i]); //(g ^ coeff[i]) % p } return commitments; } @@ -34,13 +35,14 @@ public class VerifiableSecretSharing extends SecretSharing { if(i < 1 || i > n){ throw new Exception(); } - BigInteger v = BigInteger.ONE; + BigInteger v = group.zero(); int power = 1; for (int j = 0 ; j < commitments.length ; j ++){ - v.multiply(commitments[i].pow(power)); + v = group.add(v,commitments[i].pow(power)); power *=i; } - return zpstar.add(BigInteger.ONE,v); + + return group.add(group.zero(),v); } diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java new file mode 100644 index 0000000..fbaa893 --- /dev/null +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java @@ -0,0 +1,40 @@ +package ShamirSecretSharing; + +import java.math.BigInteger; + +/** + * Created by Tzlil on 1/28/2016. + */ +class LagrangePolynomial{ + public final Polynomial polynomial; + public final BigInteger image; + public final BigInteger divisor; + + private LagrangePolynomial(Polynomial polynomial, BigInteger image, BigInteger divisor) { + this.polynomial = polynomial; + this.image = image; + this.divisor = divisor; + } + + public static LagrangePolynomial[] lagrangePolynomials(Polynomial.Point[] points){ + LagrangePolynomial[] lagrangePolynomials = new LagrangePolynomial[points.length]; + Polynomial[] factors = new Polynomial[points.length]; + for (int i = 0 ; i < factors.length ; i++){ + factors[i] = new Polynomial(new BigInteger[]{BigInteger.ZERO.subtract(points[i].x),BigInteger.ONE}); // X - Xi + } + Polynomial product; + BigInteger divisor; + for(int i = 0; i < points.length; i ++) { + product = Polynomial.ONE; + divisor = BigInteger.ONE; + for (int j = 0; j < points.length; j++) { + if (i != j) { + divisor = divisor.multiply(points[i].x.subtract(points[j].x)); + product = product.mul(factors[j]); + } + } + lagrangePolynomials[i] = new LagrangePolynomial(product,points[i].y,divisor); + } + return lagrangePolynomials; + } +} diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java index 69b4da5..b1dddcc 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java @@ -2,6 +2,7 @@ package ShamirSecretSharing; import org.bouncycastle.util.Arrays; import org.factcenter.qilin.primitives.concrete.ECGroup; +import org.factcenter.qilin.util.Pair; import java.math.BigInteger; @@ -10,8 +11,8 @@ import java.math.BigInteger; */ public class Polynomial { - private static final Polynomial ZERO = new Polynomial(new BigInteger[]{BigInteger.ZERO}); - private static final Polynomial ONE = new Polynomial(new BigInteger[]{BigInteger.ONE}); + protected static final Polynomial ZERO = new Polynomial(new BigInteger[]{BigInteger.ZERO}); + protected static final Polynomial ONE = new Polynomial(new BigInteger[]{BigInteger.ONE}); private final int degree; private final BigInteger[] coefficients; @@ -25,36 +26,53 @@ public class Polynomial { this.coefficients = polynomial.getCoefficients(); } + public boolean isEquals(Polynomial other) { + if (this.degree != other.degree) + return false; + return Arrays.areEqual(this.coefficients,other.coefficients); + } + + @Override + public String toString() { + return "Polynomial{" + + "degree=" + degree + + ", coefficients=" + java.util.Arrays.toString(coefficients) + + '}'; + } + public BigInteger image(BigInteger x){ BigInteger result = BigInteger.ZERO; BigInteger power = BigInteger.ONE; for(int i = 0 ; i <= degree ; i++){ - result.add(coefficients[i].multiply(power)); - power.multiply(x); + result = result.add(coefficients[i].multiply(power)); + power = power.multiply(x); } return result; } public static Polynomial interpolation(Point[] points){ - Polynomial[] factors = new Polynomial[points.length]; - for (int i = 0 ; i < factors.length ; i++){ - factors[i] = new Polynomial(new BigInteger[]{BigInteger.ONE,points[i].x}); // X - Xi + LagrangePolynomial[] l = LagrangePolynomial.lagrangePolynomials(points); + + BigInteger product = BigInteger.ONE; + for (int i = 0; i < l.length;i++){ + product = product.multiply(l[i].divisor); } - Polynomial result = ZERO; - BigInteger constant; - Polynomial product; - for (int i = 0 ; i < points.length; i++){ - constant = points[i].y; - product = ONE; - for (int j = 0 ; j < points.length; j ++){ - if(i != j ) { - constant = constant.divide(points[i].x.subtract(points[j].x)); - product = product.mul(factors[j]); - } + + BigInteger[] factors = new BigInteger[l.length]; + for (int i = 0; i < l.length;i++){ + factors[i] = product.divide(l[i].divisor); + } + + int degree = l[0].polynomial.degree; + BigInteger[] coefficients = new BigInteger[degree + 1]; + for (int j = 0; j < coefficients.length;j++){ + coefficients[j] = BigInteger.ZERO; + for (int i = 0; i < l.length; i++){ + coefficients[j] = coefficients[j].add(l[i].image.multiply(factors[i]).multiply(l[i].polynomial.coefficients[j])); } - result.add(product.mul(constant)); + coefficients[j] = coefficients[j].divide(product); } - return result; + return new Polynomial(coefficients); } public Polynomial add(Polynomial other){ diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java index 4457f95..0fe9d6a 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java @@ -1,6 +1,7 @@ package ShamirSecretSharing; +import org.factcenter.qilin.primitives.CyclicGroup; import org.factcenter.qilin.primitives.concrete.Zpstar; import java.math.BigInteger; @@ -10,13 +11,13 @@ import java.util.Random; * Created by Tzlil on 1/27/2016. */ public class SecretSharing { - protected final Zpstar zpstar; + protected final CyclicGroup group; protected final int t; protected final int n; protected final Polynomial polynomial; - public SecretSharing(Zpstar zpstar, int t, int n, BigInteger s, Random random) { - this.zpstar = zpstar; + public SecretSharing(CyclicGroup group, int t, int n, BigInteger s, Random random) { + this.group = group; this.t = t; this.n = n; this.polynomial = generateRandomPolynomial(s,random); @@ -25,13 +26,15 @@ public class SecretSharing { private Polynomial generateRandomPolynomial(BigInteger s, Random random) { BigInteger[] coefficients = new BigInteger[t + 1]; coefficients[0] = s; + BigInteger p = group.orderUpperBound(); + int bits = p.bitLength(); for (int i = 1 ; i <= t; i++ ){ - coefficients[i] = zpstar.sample(random); + coefficients[i] = new BigInteger(bits,random).mod(p); // sample from Zp [0,... p-1] } return new Polynomial(coefficients); } - //ToDo make it safe : permission to call this func + modulo calc + //ToDo make it safe : permission to call this func public Polynomial.Point getShare(int i) throws Exception { if(i < 1 || i > n){ throw new Exception(); diff --git a/destributed-key-generation/src/test/java/Polynomial/AddTest.java b/destributed-key-generation/src/test/java/Polynomial/AddTest.java new file mode 100644 index 0000000..7e002a1 --- /dev/null +++ b/destributed-key-generation/src/test/java/Polynomial/AddTest.java @@ -0,0 +1,44 @@ +package Polynomial; +import ShamirSecretSharing.Polynomial; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/27/2016. + */ +public class AddTest { + + Polynomial[] arr1; + Polynomial[] arr2; + int tests = 1 << 12; + int maxDegree = 15; + int bits = 128; + Random random; + + @Before + public void settings(){ + random = new Random(); + arr1 = new Polynomial[tests]; + arr2 = new Polynomial[tests]; + for (int i = 0; i < arr1.length; i++){ + arr1[i] = Utils.generateRandomPolynomial(random.nextInt(maxDegree),bits,random); + arr2[i] = Utils.generateRandomPolynomial(random.nextInt(maxDegree),bits,random); + } + } + + public void oneTest(Polynomial p1, Polynomial p2){ + Polynomial sum = p1.add(p2); + BigInteger x = new BigInteger(bits,random); + assert(sum.image(x).equals(p1.image(x).add(p2.image(x)))); + } + + @Test + public void addTest(){ + for (int i = 0 ; i < arr1.length; i ++){ + oneTest(arr1[i],arr2[i]); + } + } +} diff --git a/destributed-key-generation/src/test/java/Polynomial/InterpolationTest.java b/destributed-key-generation/src/test/java/Polynomial/InterpolationTest.java new file mode 100644 index 0000000..25595c7 --- /dev/null +++ b/destributed-key-generation/src/test/java/Polynomial/InterpolationTest.java @@ -0,0 +1,61 @@ +package Polynomial; + +import ShamirSecretSharing.Polynomial; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.HashSet; +import java.util.Random; +import java.util.Set; + +/** + * Created by Tzlil on 1/27/2016. + */ +public class InterpolationTest { + Polynomial[] polynomials; + int tests = 1 << 10; + int maxDegree = 15; + int bits = 128; + Random random; + Polynomial.Point[][] pointsArrays; + @Before + public void settings(){ + random = new Random(); + polynomials = new Polynomial[tests]; + pointsArrays = new Polynomial.Point[tests][]; + for (int i = 0; i < polynomials.length; i++){ + polynomials[i] = Utils.generateRandomPolynomial(random.nextInt(maxDegree),bits,random); + pointsArrays[i] = randomPoints(polynomials[i]); + } + } + + public Polynomial.Point[] randomPoints(Polynomial p){ + Polynomial.Point[] points = new Polynomial.Point[p.getDegree() + 1]; + BigInteger x; + Boolean b; + Set set = new HashSet(); + for (int i = 0; i < points.length; i++){ + x = new BigInteger(bits,random); + if(set.contains(x)){ + i--; + continue; + } + set.add(x); + points[i] = new Polynomial.Point(x,p.image(x)); + } + return points; + } + + public void oneTest(Polynomial p, Polynomial.Point[] points){ + Polynomial interpolation = Polynomial.interpolation(points); + assert (p.isEquals(interpolation)); + } + + @Test + public void interpolationTest(){ + for (int i = 0; i < polynomials.length; i ++){ + oneTest(polynomials[i],pointsArrays[i]); + } + } +} diff --git a/destributed-key-generation/src/test/java/Polynomial/MulByConstTest.java b/destributed-key-generation/src/test/java/Polynomial/MulByConstTest.java new file mode 100644 index 0000000..b0ddad2 --- /dev/null +++ b/destributed-key-generation/src/test/java/Polynomial/MulByConstTest.java @@ -0,0 +1,46 @@ +package Polynomial; + +import ShamirSecretSharing.Polynomial; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/27/2016. + */ +public class MulByConstTest { + + + Polynomial[] arr1; + BigInteger[] arr2; + int tests = 1 << 12; + int maxDegree = 15; + int bits = 128; + Random random; + + @Before + public void settings(){ + random = new Random(); + arr1 = new Polynomial[tests]; + arr2 = new BigInteger[tests]; + for (int i = 0; i < arr1.length; i++){ + arr1[i] = Utils.generateRandomPolynomial(random.nextInt(maxDegree),bits,random); + arr2[i] = new BigInteger(bits,random); + } + } + + public void oneTest(Polynomial p, BigInteger c){ + Polynomial product = p.mul(c); + BigInteger x = new BigInteger(bits,random); + assert(product.image(x).equals(p.image(x).multiply(c))); + } + + @Test + public void mulByConstTest(){ + for (int i = 0 ; i < arr1.length; i ++){ + oneTest(arr1[i],arr2[i]); + } + } +} diff --git a/destributed-key-generation/src/test/java/Polynomial/MulTest.java b/destributed-key-generation/src/test/java/Polynomial/MulTest.java new file mode 100644 index 0000000..a60c986 --- /dev/null +++ b/destributed-key-generation/src/test/java/Polynomial/MulTest.java @@ -0,0 +1,46 @@ +package Polynomial; + +import ShamirSecretSharing.Polynomial; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/27/2016. + */ +public class MulTest { + + + Polynomial[] arr1; + Polynomial[] arr2; + int tests = 1 << 12; + int maxDegree = 15; + int bits = 128; + Random random; + + @Before + public void settings(){ + random = new Random(); + arr1 = new Polynomial[tests]; + arr2 = new Polynomial[tests]; + for (int i = 0; i < arr1.length; i++){ + arr1[i] = Utils.generateRandomPolynomial(random.nextInt(maxDegree),bits,random); + arr2[i] = Utils.generateRandomPolynomial(random.nextInt(maxDegree),bits,random); + } + } + + public void oneTest(Polynomial p1, Polynomial p2){ + Polynomial product = p1.mul(p2); + BigInteger x = new BigInteger(bits,random); + assert(product.image(x).equals(p1.image(x).multiply(p2.image(x)))); + } + + @Test + public void mulTest(){ + for (int i = 0 ; i < arr1.length; i ++){ + oneTest(arr1[i],arr2[i]); + } + } +} diff --git a/destributed-key-generation/src/test/java/Polynomial/Utils.java b/destributed-key-generation/src/test/java/Polynomial/Utils.java new file mode 100644 index 0000000..e52dd9b --- /dev/null +++ b/destributed-key-generation/src/test/java/Polynomial/Utils.java @@ -0,0 +1,21 @@ +package Polynomial; + +import ShamirSecretSharing.Polynomial; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/27/2016. + */ +public class Utils { + + public static Polynomial generateRandomPolynomial(int degree,int bits,Random random) { + BigInteger[] coefficients = new BigInteger[degree + 1]; + + for (int i = 0 ; i <= degree; i++ ){ + coefficients[i] = new BigInteger(bits,random); // sample from Zp [0,... p-1] + } + return new Polynomial(coefficients); + } +} From 8ba55bacd20b389af365edadc2d5572fe2d24991 Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Thu, 28 Jan 2016 13:57:47 +0200 Subject: [PATCH 12/49] feldmanVSS documention --- .../VerifiableSecretSharing.java | 41 ++++++-- .../LagrangePolynomial.java | 26 ++++- .../java/ShamirSecretSharing/Polynomial.java | 96 +++++++++++++++---- .../ShamirSecretSharing/SecretSharing.java | 48 ++++++++-- .../java/Polynomial/InterpolationTest.java | 4 +- 5 files changed, 180 insertions(+), 35 deletions(-) diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java index 1b44693..1554bf6 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java @@ -13,43 +13,64 @@ import java.util.Random; */ public class VerifiableSecretSharing extends SecretSharing { + private final CyclicGroup group; + private final BigInteger g; // public generator of group private final BigInteger[] commitments; - private final BigInteger g; + + /** + * @param group a cyclic group of prime order p. + * it must be chosen such that computing discrete logarithms is hard in this group. + */ public VerifiableSecretSharing(CyclicGroup group, int t, int n, BigInteger s, Random random) { - super(group, t, n, s, random); + super(group.orderUpperBound(), t, n, s, random); + this.group = group; this.g = group.getGenerator(); this.commitments = generateCommitments(); } + /** + * @return commitments[i] = g ^ polynomial.coefficients[i] + */ private BigInteger[] generateCommitments() { 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]); //(g ^ coeff[i]) % p + commitments[i] = group.multiply(g,coefficients[i]); } return commitments; } - public BigInteger verify(int i) throws Exception { - if(i < 1 || i > n){ - throw new Exception(); - } + /** + * @param i share holder id + * @param commitments + * @param group + * + * @return product of commitments[j] ^ (i ^ j) == g ^ polynomial(i) + */ + public static BigInteger verify(int i,BigInteger[] commitments,CyclicGroup group) { BigInteger v = group.zero(); int power = 1; for (int j = 0 ; j < commitments.length ; j ++){ v = group.add(v,commitments[i].pow(power)); power *=i; } - - return group.add(group.zero(),v); + return v; } - public BigInteger getG() { + /** + * getter + * @return generator of group + */ + public BigInteger getGenerator() { return g; } + /** + * getter + * @return copy of commitments + */ public BigInteger[] getCommitments() { return Arrays.clone(commitments); } diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java index fbaa893..d3815ff 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java @@ -4,19 +4,41 @@ import java.math.BigInteger; /** * Created by Tzlil on 1/28/2016. + * + * container of lagrange polynomial + * + * can't be constructed, constructor is private + * + * l = (image/divisor)* polynomial + * + * Note : image and divisor stored separately for avoiding lose of information by division */ class LagrangePolynomial{ public final Polynomial polynomial; public final BigInteger image; public final BigInteger divisor; + /** + * inner constructor, stores all given parameters + * @param polynomial + * @param image + * @param divisor + */ private LagrangePolynomial(Polynomial polynomial, BigInteger image, BigInteger divisor) { this.polynomial = polynomial; this.image = image; this.divisor = divisor; } - public static LagrangePolynomial[] lagrangePolynomials(Polynomial.Point[] points){ + /** + * static method + * @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 + * + * @throws Exception there exists i != j s.t points[i].x == points[j].x + */ + public static LagrangePolynomial[] lagrangePolynomials(Polynomial.Point[] points) throws Exception { LagrangePolynomial[] lagrangePolynomials = new LagrangePolynomial[points.length]; Polynomial[] factors = new Polynomial[points.length]; for (int i = 0 ; i < factors.length ; i++){ @@ -33,6 +55,8 @@ class LagrangePolynomial{ product = product.mul(factors[j]); } } + if(divisor.equals(BigInteger.ZERO)) + throw new Exception(); lagrangePolynomials[i] = new LagrangePolynomial(product,points[i].y,divisor); } return lagrangePolynomials; diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java index b1dddcc..620e1e7 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java @@ -9,27 +9,39 @@ import java.math.BigInteger; /** * Created by Tzlil on 1/27/2016. */ -public class Polynomial { - - protected static final Polynomial ZERO = new Polynomial(new BigInteger[]{BigInteger.ZERO}); - protected static final Polynomial ONE = new Polynomial(new BigInteger[]{BigInteger.ONE}); +public class Polynomial implements Comparable { + protected static final Polynomial ZERO = new Polynomial(new BigInteger[]{BigInteger.ZERO}); // neutral for add + protected static final Polynomial ONE = new Polynomial(new BigInteger[]{BigInteger.ONE}); // neutral for mul private final int degree; private final BigInteger[] coefficients; + /** + * constructor + * @param coefficients + * degree set as max index such that coefficients[degree] not equals zero + */ public Polynomial(BigInteger[] coefficients) { - this.degree = coefficients.length - 1; + int d = coefficients.length - 1; + while (d > 0 && coefficients[d].equals(BigInteger.ZERO)){ + d--; + } + this.degree = d; this.coefficients = coefficients; } - public Polynomial(Polynomial polynomial) { - this.degree = polynomial.getDegree(); - this.coefficients = polynomial.getCoefficients(); - } - public boolean isEquals(Polynomial other) { + @Override + public int compareTo(Polynomial other) { if (this.degree != other.degree) - return false; - return Arrays.areEqual(this.coefficients,other.coefficients); + return this.degree - other.degree; + int compare; + for (int i = degree; i >= degree ; i--){ + compare = this.coefficients[i].compareTo(other.coefficients[i]); + if (compare != 0){ + return compare; + } + } + return 0; } @Override @@ -40,6 +52,11 @@ public class Polynomial { '}'; } + + /** + * @param x + * @return sum of coefficients[i] * (x ^ i) + */ public BigInteger image(BigInteger x){ BigInteger result = BigInteger.ZERO; BigInteger power = BigInteger.ONE; @@ -50,20 +67,28 @@ public class Polynomial { return result; } + /** + * @param points + * @return polynomial of minimal degree which goes through all points + */ public static Polynomial interpolation(Point[] points){ LagrangePolynomial[] l = LagrangePolynomial.lagrangePolynomials(points); + // product = product of l[i].divisor BigInteger product = BigInteger.ONE; for (int i = 0; i < l.length;i++){ product = product.multiply(l[i].divisor); } + // factor[i] = product divided by l[i].divisor = product of l[j].divisor s.t j!=i BigInteger[] factors = new BigInteger[l.length]; for (int i = 0; i < l.length;i++){ factors[i] = product.divide(l[i].divisor); } - int degree = l[0].polynomial.degree; + + // coefficients[j] = (sum of l[i].image * factor[i] * l[i].coefficients[j] s.t i!=j) divide by product = + // = sum of l[i].image * l[i].coefficients[j] / l[i].divisor s.t i!=j BigInteger[] coefficients = new BigInteger[degree + 1]; for (int j = 0; j < coefficients.length;j++){ coefficients[j] = BigInteger.ZERO; @@ -75,6 +100,11 @@ public class Polynomial { return new Polynomial(coefficients); } + /** + * @param other + * @return new Polynomial of degree max(this degree,other degree) s.t for all x in Z + * new.image(x) = this.image(x) + other.image(x) + */ public Polynomial add(Polynomial other){ Polynomial bigger,smaller; if(this.degree < other.degree){ @@ -92,6 +122,11 @@ public class Polynomial { return new Polynomial(coefficients); } + /** + * @param constant + * @return new Polynomial of degree this.degree s.t for all x in Z + * new.image(x) = constant * this.image(x) + */ public Polynomial mul(BigInteger constant){ BigInteger[] coefficients = this.getCoefficients(); @@ -102,6 +137,11 @@ public class Polynomial { return new Polynomial(coefficients); } + /** + * @param other + * @return new Polynomial of degree this degree + other degree + 1 s.t for all x in Z + * new.image(x) = this.image(x) * other.image(x) + */ public Polynomial mul(Polynomial other){ BigInteger[] coefficients = new BigInteger[this.degree + other.degree + 1]; @@ -116,21 +156,45 @@ public class Polynomial { } + /** getter + * @return copy of coefficients + */ public BigInteger[] getCoefficients() { return Arrays.clone(coefficients); } + + /** getter + * @return degree + */ public int getDegree() { return degree; } - + /** + * inner class + * container for (x,y) x from range and y from image of polynomial + */ public static class Point{ public final BigInteger x; public final BigInteger y; - public Point(BigInteger x, BigInteger y) { + /** + * constructor + * @param x + * @param polynomial y = polynomial.image(x) + */ + public Point(BigInteger x, Polynomial polynomial) { this.x = x; - this.y = y; + this.y = polynomial.image(x); + } + + /** + * copy constructor + * @param point + */ + public Point(Point point) { + this.x = point.x; + this.y = point.y; } } diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java index 0fe9d6a..d3c48c9 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java @@ -9,48 +9,84 @@ import java.util.Random; /** * Created by Tzlil on 1/27/2016. + * an implementation of Shamire's secret sharing scheme */ public class SecretSharing { - protected final CyclicGroup group; protected final int t; protected final int n; + protected final BigInteger p; protected final Polynomial polynomial; - public SecretSharing(CyclicGroup group, int t, int n, BigInteger s, Random random) { - this.group = group; + /** + * constructor + * @param p 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 s secret, chosen from Zp + * @param random use for generate random polynomial + */ + public SecretSharing(BigInteger p, int t, int n, BigInteger s, Random random) { + this.p = p; this.t = t; this.n = n; this.polynomial = generateRandomPolynomial(s,random); } + /** + * @param s + * @param random + * @return new Polynomial polynomial of degree t ,such that + * 1. polynomial(0) = s + * 2. polynomial coefficients randomly chosen from Zp (except of coefficients[0] = s) + */ private Polynomial generateRandomPolynomial(BigInteger s, Random random) { BigInteger[] coefficients = new BigInteger[t + 1]; coefficients[0] = s; - BigInteger p = group.orderUpperBound(); int bits = p.bitLength(); for (int i = 1 ; i <= t; i++ ){ - coefficients[i] = new BigInteger(bits,random).mod(p); // sample from Zp [0,... p-1] + coefficients[i] = new BigInteger(bits,random).mod(p); } return new Polynomial(coefficients); } //ToDo make it safe : permission to call this func + /** + * @param i in range of [1,...n] + * + * @return polynomial.image(i) + * + * @throws Exception i out of range + */ public Polynomial.Point getShare(int i) throws Exception { if(i < 1 || i > n){ throw new Exception(); } - return new Polynomial.Point(BigInteger.valueOf(i), polynomial.image(BigInteger.valueOf(i))); + return new Polynomial.Point(BigInteger.valueOf(i), polynomial); } + /** + * @param shares - subset of the original shares + * + * @return image of interpolation(shares) at x = 0 + */ public static BigInteger getSecrete(Polynomial.Point[] shares){ Polynomial polynomial = Polynomial.interpolation(shares); return polynomial.image(BigInteger.ZERO); } + /** + * getter + * @return threshold + */ public int getThreshold() { return t; } + /** + * getter + * @return number of share holders + */ public int getN() { return n; } diff --git a/destributed-key-generation/src/test/java/Polynomial/InterpolationTest.java b/destributed-key-generation/src/test/java/Polynomial/InterpolationTest.java index 25595c7..d08b0f2 100644 --- a/destributed-key-generation/src/test/java/Polynomial/InterpolationTest.java +++ b/destributed-key-generation/src/test/java/Polynomial/InterpolationTest.java @@ -42,14 +42,14 @@ public class InterpolationTest { continue; } set.add(x); - points[i] = new Polynomial.Point(x,p.image(x)); + points[i] = new Polynomial.Point(x,p); } return points; } public void oneTest(Polynomial p, Polynomial.Point[] points){ Polynomial interpolation = Polynomial.interpolation(points); - assert (p.isEquals(interpolation)); + assert (p.compareTo(interpolation) == 0); } @Test From f8d31d16a319572bf170acaf880ae5b01821ab0c Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Fri, 29 Jan 2016 22:08:13 +0200 Subject: [PATCH 13/49] FeldmanVSS tests --- .../LagrangePolynomial.java | 2 +- .../ShamirSecretSharing/Polynomial.java | 14 ++-- .../ShamirSecretSharing/SecretSharing.java | 19 ++++-- .../VerifiableSecretSharing.java | 19 ++++-- .../PolynomialTests}/AddTest.java | 4 +- .../PolynomialTests}/InterpolationTest.java | 8 +-- .../PolynomialTests}/MulByConstTest.java | 4 +- .../PolynomialTests}/MulTest.java | 4 +- .../PolynomialTests}/Utils.java | 4 +- .../SecretSharingTest.java | 60 +++++++++++++++++ .../VerifiableSecretSharingTest.java | 64 +++++++++++++++++++ gradle/wrapper/gradle-wrapper.properties | 2 +- 12 files changed, 170 insertions(+), 34 deletions(-) rename destributed-key-generation/src/main/java/{ => FeldmanVerifiableSecretSharing}/ShamirSecretSharing/LagrangePolynomial.java (97%) rename destributed-key-generation/src/main/java/{ => FeldmanVerifiableSecretSharing}/ShamirSecretSharing/Polynomial.java (89%) rename destributed-key-generation/src/main/java/{ => FeldmanVerifiableSecretSharing}/ShamirSecretSharing/SecretSharing.java (87%) rename destributed-key-generation/src/test/java/{Polynomial => FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests}/AddTest.java (87%) rename destributed-key-generation/src/test/java/{Polynomial => FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests}/InterpolationTest.java (88%) rename destributed-key-generation/src/test/java/{Polynomial => FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests}/MulByConstTest.java (87%) rename destributed-key-generation/src/test/java/{Polynomial => FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests}/MulTest.java (88%) rename destributed-key-generation/src/test/java/{Polynomial => FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests}/Utils.java (76%) create mode 100644 destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharingTest.java create mode 100644 destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/LagrangePolynomial.java similarity index 97% rename from destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java rename to destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/LagrangePolynomial.java index d3815ff..6754822 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/LagrangePolynomial.java @@ -1,4 +1,4 @@ -package ShamirSecretSharing; +package FeldmanVerifiableSecretSharing.ShamirSecretSharing; import java.math.BigInteger; diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java similarity index 89% rename from destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java rename to destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java index 620e1e7..ac340b7 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java @@ -1,8 +1,6 @@ -package ShamirSecretSharing; +package FeldmanVerifiableSecretSharing.ShamirSecretSharing; import org.bouncycastle.util.Arrays; -import org.factcenter.qilin.primitives.concrete.ECGroup; -import org.factcenter.qilin.util.Pair; import java.math.BigInteger; @@ -46,7 +44,7 @@ public class Polynomial implements Comparable { @Override public String toString() { - return "Polynomial{" + + return "FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests{" + "degree=" + degree + ", coefficients=" + java.util.Arrays.toString(coefficients) + '}'; @@ -71,7 +69,7 @@ public class Polynomial implements Comparable { * @param points * @return polynomial of minimal degree which goes through all points */ - public static Polynomial interpolation(Point[] points){ + public static Polynomial interpolation(Point[] points) throws Exception { LagrangePolynomial[] l = LagrangePolynomial.lagrangePolynomials(points); // product = product of l[i].divisor @@ -102,7 +100,7 @@ public class Polynomial implements Comparable { /** * @param other - * @return new Polynomial of degree max(this degree,other degree) s.t for all x in Z + * @return new FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests of degree max(this degree,other degree) s.t for all x in Z * new.image(x) = this.image(x) + other.image(x) */ public Polynomial add(Polynomial other){ @@ -124,7 +122,7 @@ public class Polynomial implements Comparable { /** * @param constant - * @return new Polynomial of degree this.degree s.t for all x in Z + * @return new FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests of degree this.degree s.t for all x in Z * new.image(x) = constant * this.image(x) */ public Polynomial mul(BigInteger constant){ @@ -139,7 +137,7 @@ public class Polynomial implements Comparable { /** * @param other - * @return new Polynomial of degree this degree + other degree + 1 s.t for all x in Z + * @return new FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests of degree this degree + other degree + 1 s.t for all x in Z * new.image(x) = this.image(x) * other.image(x) */ public Polynomial mul(Polynomial other){ diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java similarity index 87% rename from destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java rename to destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java index d3c48c9..f5629d4 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java @@ -1,9 +1,6 @@ -package ShamirSecretSharing; +package FeldmanVerifiableSecretSharing.ShamirSecretSharing; -import org.factcenter.qilin.primitives.CyclicGroup; -import org.factcenter.qilin.primitives.concrete.Zpstar; - import java.math.BigInteger; import java.util.Random; @@ -14,6 +11,8 @@ import java.util.Random; public class SecretSharing { protected final int t; protected final int n; + + protected final BigInteger p; protected final Polynomial polynomial; @@ -36,7 +35,7 @@ public class SecretSharing { /** * @param s * @param random - * @return new Polynomial polynomial of degree t ,such that + * @return new FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests polynomial of degree t ,such that * 1. polynomial(0) = s * 2. polynomial coefficients randomly chosen from Zp (except of coefficients[0] = s) */ @@ -70,7 +69,7 @@ public class SecretSharing { * * @return image of interpolation(shares) at x = 0 */ - public static BigInteger getSecrete(Polynomial.Point[] shares){ + public static BigInteger getSecrete(Polynomial.Point[] shares) throws Exception { Polynomial polynomial = Polynomial.interpolation(shares); return polynomial.image(BigInteger.ZERO); } @@ -91,5 +90,11 @@ public class SecretSharing { return n; } - + /** + * getter + * @return the prime was given in the constructor + */ + public BigInteger getP() { + return p; + } } diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java index 1554bf6..082177f 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java @@ -1,9 +1,8 @@ package FeldmanVerifiableSecretSharing; -import ShamirSecretSharing.SecretSharing; +import FeldmanVerifiableSecretSharing.ShamirSecretSharing.SecretSharing; import org.bouncycastle.util.Arrays; import org.factcenter.qilin.primitives.CyclicGroup; -import org.factcenter.qilin.primitives.concrete.Zpstar; import java.math.BigInteger; import java.util.Random; @@ -50,10 +49,11 @@ public class VerifiableSecretSharing extends SecretSharing { */ public static BigInteger verify(int i,BigInteger[] commitments,CyclicGroup group) { BigInteger v = group.zero(); - int power = 1; + BigInteger power = BigInteger.ONE; + BigInteger I = BigInteger.valueOf(i); for (int j = 0 ; j < commitments.length ; j ++){ - v = group.add(v,commitments[i].pow(power)); - power *=i; + v = group.add(v,group.multiply(commitments[j],power)); + power = power.multiply(I); } return v; } @@ -74,4 +74,13 @@ public class VerifiableSecretSharing extends SecretSharing { public BigInteger[] getCommitments() { return Arrays.clone(commitments); } + + + /** + * getter + * @return the cyclic group was given in the constructor + */ + public CyclicGroup getGroup() { + return group; + } } diff --git a/destributed-key-generation/src/test/java/Polynomial/AddTest.java b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/AddTest.java similarity index 87% rename from destributed-key-generation/src/test/java/Polynomial/AddTest.java rename to destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/AddTest.java index 7e002a1..1df4fef 100644 --- a/destributed-key-generation/src/test/java/Polynomial/AddTest.java +++ b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/AddTest.java @@ -1,5 +1,5 @@ -package Polynomial; -import ShamirSecretSharing.Polynomial; +package FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests; +import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; import org.junit.Before; import org.junit.Test; diff --git a/destributed-key-generation/src/test/java/Polynomial/InterpolationTest.java b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/InterpolationTest.java similarity index 88% rename from destributed-key-generation/src/test/java/Polynomial/InterpolationTest.java rename to destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/InterpolationTest.java index d08b0f2..71c93fa 100644 --- a/destributed-key-generation/src/test/java/Polynomial/InterpolationTest.java +++ b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/InterpolationTest.java @@ -1,6 +1,6 @@ -package Polynomial; +package FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests; -import ShamirSecretSharing.Polynomial; +import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; import org.junit.Before; import org.junit.Test; @@ -47,13 +47,13 @@ public class InterpolationTest { return points; } - public void oneTest(Polynomial p, Polynomial.Point[] points){ + public void oneTest(Polynomial p, Polynomial.Point[] points) throws Exception { Polynomial interpolation = Polynomial.interpolation(points); assert (p.compareTo(interpolation) == 0); } @Test - public void interpolationTest(){ + public void interpolationTest() throws Exception { for (int i = 0; i < polynomials.length; i ++){ oneTest(polynomials[i],pointsArrays[i]); } diff --git a/destributed-key-generation/src/test/java/Polynomial/MulByConstTest.java b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/MulByConstTest.java similarity index 87% rename from destributed-key-generation/src/test/java/Polynomial/MulByConstTest.java rename to destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/MulByConstTest.java index b0ddad2..6d9669a 100644 --- a/destributed-key-generation/src/test/java/Polynomial/MulByConstTest.java +++ b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/MulByConstTest.java @@ -1,6 +1,6 @@ -package Polynomial; +package FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests; -import ShamirSecretSharing.Polynomial; +import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; import org.junit.Before; import org.junit.Test; diff --git a/destributed-key-generation/src/test/java/Polynomial/MulTest.java b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/MulTest.java similarity index 88% rename from destributed-key-generation/src/test/java/Polynomial/MulTest.java rename to destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/MulTest.java index a60c986..fd4d761 100644 --- a/destributed-key-generation/src/test/java/Polynomial/MulTest.java +++ b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/MulTest.java @@ -1,6 +1,6 @@ -package Polynomial; +package FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests; -import ShamirSecretSharing.Polynomial; +import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; import org.junit.Before; import org.junit.Test; diff --git a/destributed-key-generation/src/test/java/Polynomial/Utils.java b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/Utils.java similarity index 76% rename from destributed-key-generation/src/test/java/Polynomial/Utils.java rename to destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/Utils.java index e52dd9b..b43869d 100644 --- a/destributed-key-generation/src/test/java/Polynomial/Utils.java +++ b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/Utils.java @@ -1,6 +1,6 @@ -package Polynomial; +package FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests; -import ShamirSecretSharing.Polynomial; +import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; import java.math.BigInteger; import java.util.Random; diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharingTest.java b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharingTest.java new file mode 100644 index 0000000..d5f8842 --- /dev/null +++ b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharingTest.java @@ -0,0 +1,60 @@ +package FeldmanVerifiableSecretSharing.ShamirSecretSharing; + +import FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests.Utils; +import org.factcenter.qilin.primitives.CyclicGroup; +import org.factcenter.qilin.primitives.concrete.Zn; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +/** + * Created by Tzlil on 1/29/2016. + */ +public class SecretSharingTest { + + SecretSharing[] secretSharingArray; + BigInteger[] secrets; + CyclicGroup group; + int tests = 1 << 10; + Random random; + + @Before + public void settings(){ + BigInteger p = BigInteger.valueOf(2903); + group = new Zn(p); + int t = 10; + int n = 20; + random = new Random(); + secretSharingArray = new SecretSharing[tests]; + secrets = new BigInteger[tests]; + for (int i = 0; i < secretSharingArray.length; i++){ + secrets[i] = group.sample(random); + secretSharingArray[i] = new SecretSharing(p,t,n,secrets[i],random); + } + } + + public void oneTest(SecretSharing secretSharing, BigInteger secret) throws Exception { + int t = secretSharing.getThreshold(); + int n = secretSharing.getN(); + Polynomial.Point[] shares = new Polynomial.Point[t + 1]; + List indexes = new ArrayList(n); + for (int i = 1 ; i <= n; i ++){ + indexes.add(i); + } + for (int i = 0 ; i < shares.length ; i++){ + shares[i] = secretSharing.getShare(indexes.remove(random.nextInt(indexes.size()))); + } + assert(secret.equals(SecretSharing.getSecrete(shares))); + } + + @Test + public void secretSharingTest() throws Exception { + for (int i = 0 ; i < secretSharingArray.length; i ++){ + oneTest(secretSharingArray[i],secrets[i]); + } + } +} diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java new file mode 100644 index 0000000..8846cd9 --- /dev/null +++ b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java @@ -0,0 +1,64 @@ +package FeldmanVerifiableSecretSharing; + +import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; +import FeldmanVerifiableSecretSharing.ShamirSecretSharing.SecretSharing; +import org.factcenter.qilin.primitives.CyclicGroup; +import org.factcenter.qilin.primitives.concrete.Zn; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +/** + * Created by Tzlil on 1/29/2016. + */ +public class VerifiableSecretSharingTest { + + + VerifiableSecretSharing[] verifiableSecretSharingArray; + int tests = 1 << 10; + Random random; + + @Before + public void settings(){ + BigInteger p = BigInteger.valueOf(2903); + CyclicGroup group = new Zn(p); + int t = 10; + int n = 20; + random = new Random(); + verifiableSecretSharingArray = new VerifiableSecretSharing[tests]; + for (int i = 0; i < verifiableSecretSharingArray.length; i++){ + verifiableSecretSharingArray[i] = new VerifiableSecretSharing(group,t,n,group.sample(random),random); + } + } + + public void oneTest(VerifiableSecretSharing verifiableSecretSharing) throws Exception { + int n = verifiableSecretSharing.getN(); + BigInteger p = verifiableSecretSharing.getP(); + CyclicGroup group = verifiableSecretSharing.getGroup(); + BigInteger g = verifiableSecretSharing.getGenerator(); + Polynomial.Point[] shares = new Polynomial.Point[n]; + BigInteger[] commitments = verifiableSecretSharing.getCommitments(); + BigInteger[] verifications = new BigInteger[n]; + for (int i = 1 ; i <= shares.length; i ++){ + shares[i - 1] = verifiableSecretSharing.getShare(i); + verifications[i - 1] = VerifiableSecretSharing.verify(i,commitments,group); + } + BigInteger expected; + for (int i = 0 ; i < shares.length ; i++){ + expected = group.multiply(g,shares[i].y).mod(p); // problem with Zn, multiplication doesn't mod n as required + assert (expected.equals(verifications[i])); + } + + } + + @Test + public void secretSharingTest() throws Exception { + for (int i = 0 ; i < verifiableSecretSharingArray.length; i ++){ + oneTest(verifiableSecretSharingArray[i]); + } + } +} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1360c1c..306cc66 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,4 +1,4 @@ -#Wed Jan 27 00:30:26 IST 2016 +#Fri Jan 29 21:00:29 IST 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME From 635165ef8ef65c09c154fbffee97ee49cc1856f3 Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Fri, 5 Feb 2016 13:30:16 +0200 Subject: [PATCH 14/49] sketch of JointFeldmanProtocol --- .../ShamirSecretSharing/Polynomial.java | 12 ++ .../ShamirSecretSharing/SecretSharing.java | 59 +++++---- .../VerifiableSecretSharing.java | 55 +++++--- .../main/java/JointFeldmanProtocol/DKG.java | 123 ++++++++++++++++++ .../java/JointFeldmanProtocol/Network.java | 27 ++++ .../PolynomialTests/Utils.java | 2 +- .../VerifiableSecretSharingTest.java | 22 ++-- 7 files changed, 242 insertions(+), 58 deletions(-) create mode 100644 destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java create mode 100644 destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java index ac340b7..e285e01 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java @@ -186,6 +186,18 @@ public class Polynomial implements Comparable { this.y = polynomial.image(x); } + /** + * constructor + * @param x + * @param p + * @param polynomial y = polynomial.image(x) % q + * + */ + public Point(BigInteger x, Polynomial polynomial,BigInteger p) { + this.x = x; + this.y = polynomial.image(x); + } + /** * copy constructor * @param point diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java index f5629d4..4a90ac7 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java @@ -9,59 +9,53 @@ import java.util.Random; * an implementation of Shamire's secret sharing scheme */ public class SecretSharing { - protected final int t; - protected final int n; + private final int t; + private final int n; + private final BigInteger q; - - protected final BigInteger p; - protected final Polynomial polynomial; + private final Polynomial polynomial; /** * constructor - * @param p prime + * @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 s secret, chosen from Zp + * @param x secret, chosen from Zq * @param random use for generate random polynomial */ - public SecretSharing(BigInteger p, int t, int n, BigInteger s, Random random) { - this.p = p; + public SecretSharing(int t, int n, BigInteger x, Random random,BigInteger q) { + this.q = q; this.t = t; this.n = n; - this.polynomial = generateRandomPolynomial(s,random); + this.polynomial = generateRandomPolynomial(x,random); } /** - * @param s + * @param x * @param random - * @return new FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests polynomial of degree t ,such that - * 1. polynomial(0) = s - * 2. polynomial coefficients randomly chosen from Zp (except of coefficients[0] = s) + * @return new Polynomial polynomial of degree t ,such that + * 1. polynomial(0) = x + * 2. polynomial coefficients randomly chosen from Zq (except of coefficients[0] = x) */ - private Polynomial generateRandomPolynomial(BigInteger s, Random random) { + private Polynomial generateRandomPolynomial(BigInteger x, Random random) { BigInteger[] coefficients = new BigInteger[t + 1]; - coefficients[0] = s; - int bits = p.bitLength(); + coefficients[0] = x.mod(q); + int bits = q.bitLength(); for (int i = 1 ; i <= t; i++ ){ - coefficients[i] = new BigInteger(bits,random).mod(p); + coefficients[i] = new BigInteger(bits,random).mod(q); } return new Polynomial(coefficients); } - //ToDo make it safe : permission to call this func /** * @param i in range of [1,...n] * - * @return polynomial.image(i) - * - * @throws Exception i out of range + * @return polynomial.image(i)%q */ - public Polynomial.Point getShare(int i) throws Exception { - if(i < 1 || i > n){ - throw new Exception(); - } - return new Polynomial.Point(BigInteger.valueOf(i), polynomial); + protected Polynomial.Point getShare(int i){ + assert (i > 0 && i <= n); + return new Polynomial.Point(BigInteger.valueOf(i), polynomial, q); } /** @@ -78,7 +72,7 @@ public class SecretSharing { * getter * @return threshold */ - public int getThreshold() { + public int getT() { return t; } @@ -94,7 +88,12 @@ public class SecretSharing { * getter * @return the prime was given in the constructor */ - public BigInteger getP() { - return p; + public BigInteger getQ() { + return q; + } + + protected Polynomial getPolynomial() { + + return polynomial; } } diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java index 082177f..e8d5c98 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java @@ -1,41 +1,55 @@ package FeldmanVerifiableSecretSharing; +import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; import FeldmanVerifiableSecretSharing.ShamirSecretSharing.SecretSharing; import org.bouncycastle.util.Arrays; import org.factcenter.qilin.primitives.CyclicGroup; +import org.factcenter.qilin.primitives.concrete.Zpstar; 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 extends SecretSharing { - - private final CyclicGroup group; + private final Zpstar zpstar; private final BigInteger g; // public generator of group private final BigInteger[] commitments; - + private final BigInteger y; // y = g ^ x /** - * @param group a cyclic group of prime order p. - * it must be chosen such that computing discrete logarithms is hard in this group. + * @param p a large prime + * @param q a large prime dividing p - 1. + * @param g a generator of cyclic group of order q. + * the generated group is a subgroup of Zp*. + * it must be chosen such that computing discrete logarithms is hard in this group. */ - public VerifiableSecretSharing(CyclicGroup group, int t, int n, BigInteger s, Random random) { - super(group.orderUpperBound(), t, n, s, random); - this.group = group; - this.g = group.getGenerator(); + public VerifiableSecretSharing(int t, int n, BigInteger x, Random random,BigInteger p,BigInteger q,BigInteger g) { + super(t, n, x, random,q); + this.g = g; + this.zpstar = new Zpstar(p); + assert (zpstar.contains(g)); + assert (p.subtract(BigInteger.ONE).mod(q).equals(BigInteger.ZERO)); // assert p - 1 % q == 0 this.commitments = generateCommitments(); + this.y = zpstar.multiply(g,x); } /** * @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]); + commitments[i] = zpstar.multiply(g,coefficients[i]); } return commitments; } @@ -43,16 +57,16 @@ public class VerifiableSecretSharing extends SecretSharing { /** * @param i share holder id * @param commitments - * @param group + * @param zpstar * * @return product of commitments[j] ^ (i ^ j) == g ^ polynomial(i) */ - public static BigInteger verify(int i,BigInteger[] commitments,CyclicGroup group) { - BigInteger v = group.zero(); + public static BigInteger verify(int i,BigInteger[] commitments,Zpstar zpstar) { + BigInteger v = zpstar.zero(); BigInteger power = BigInteger.ONE; BigInteger I = BigInteger.valueOf(i); for (int j = 0 ; j < commitments.length ; j ++){ - v = group.add(v,group.multiply(commitments[j],power)); + v = zpstar.add(v,zpstar.multiply(commitments[j],power)); power = power.multiply(I); } return v; @@ -75,12 +89,19 @@ public class VerifiableSecretSharing extends SecretSharing { return Arrays.clone(commitments); } + /** + * getter + * @return zpstar + */ + public Zpstar getZpstar(){ + return zpstar; + } /** * getter - * @return the cyclic group was given in the constructor + * @return public value of this */ - public CyclicGroup getGroup() { - return group; + public BigInteger getY(){ + return y; } } diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java new file mode 100644 index 0000000..6962d29 --- /dev/null +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java @@ -0,0 +1,123 @@ +package JointFeldmanProtocol; + +import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; +import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; +import org.bouncycastle.util.Arrays; +import org.factcenter.qilin.primitives.concrete.Zpstar; + +import java.math.BigInteger; +import java.util.Random; +import java.util.Set; + +/** + * Created by Tzlil on 2/5/2016. + * + * an implementation of a version of Pedersen's distributed key generation protocol + */ +public class DKG extends VerifiableSecretSharing{ + + private Network.User user; + private Polynomial.Point[][] shares; + private BigInteger[][] commitmentsArray; + private Set QUAL; + + private BigInteger x; + private BigInteger y; + private BigInteger[] commitments; + + public DKG(int t, int n, BigInteger x, Random random, BigInteger p, BigInteger q, BigInteger g) { + super(t, n, x, random, p, q, g); + } + + private void stage1(){ + int n = getN(); + int i = user.getID(); + BigInteger[] commitments = super.getCommitments(); + System.arraycopy(commitments, 0, commitmentsArray[i - 1], 0, commitmentsArray[i - 1].length); + + Network.Message message = null; + for (int j = 1; j <= commitmentsArray[i - 1].length; j ++){ + //message = new Message(Type.Commitment, Shares[i - 1][j - 1]) + user.sendBroadcast(message); + } + + + for (int j = 1; j <= shares[i - 1].length; j ++){ + shares[i - 1][j - 1] = getShare(j); + } + for (int j = 1; j <= n ; j++ ){ + if(j != i){ + //message = new Message(Type.Share, Shares[i - 1][j - 1]) + user.send(j,message); + } + } + //Todo receive messages + } + + private void stage2(){ + int n = getN(); + BigInteger g = getGenerator(); + Zpstar zpstar = getZpstar(); + int i = user.getID(); + Network.Message message = null; + for (int j = 1; j <= n ; j++ ){ + if(zpstar.multiply(g,shares[i - 1][j - 1].y).equals(verify(j,commitmentsArray[j],zpstar))){ + QUAL.add(j); + }else{ + //message = new Message(Type.Complaint, j) + user.sendBroadcast(message); + } + } + + } + + private void stage3(){ + + //Todo receive something private from each complaint + send what necessary + + + } + + private void stage4(){ + Network.Message message = null; + // message = new Message(Type.Y, super.getY()) + user.sendBroadcast(message); + Zpstar zpstar = getZpstar(); + BigInteger y = zpstar.zero(); + for (Network.User user:this.user.getNetwork()) { + //Todo receive yi from all i in QUAL and calc y total + } + int t = getT(); + this.commitments = new BigInteger[t]; + BigInteger commitment; + for (int k = 1; k <= t ; k++){ + commitment = zpstar.zero(); + for (int i : QUAL) { + commitment = zpstar.add(commitment,commitmentsArray[i - 1][k - 1]); + } + commitments[k - 1] = commitment; + } + + int j = user.getID(); + BigInteger x = BigInteger.ZERO; + for (int i : QUAL) { + x = x.add(shares[i][j].y); + } + this.x = x.mod(getQ()); + } + + @Override + public BigInteger getY() { + return y; + } + + @Override + public BigInteger[] getCommitments() { + return Arrays.clone(commitments); + } + + @Override + protected Polynomial.Point getShare(int i) { + return null; + } +} diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java new file mode 100644 index 0000000..46c1d44 --- /dev/null +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java @@ -0,0 +1,27 @@ +package JointFeldmanProtocol; + +/** + * Created by Tzlil on 2/5/2016. + */ +public interface Network extends Iterable{ + + User connect(); + + interface User{ + int getID(); + void send(int userID,Message message); + void sendBroadcast(Message message); + void receive(int userID,Message message); + void receiveBroadcast(Message message); + Network getNetwork(); + } + + interface Message{ + enum Type { + Commitment, Share, Complaint, Y + } + + Type getType(); + + } +} diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/Utils.java b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/Utils.java index b43869d..67bd51c 100644 --- a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/Utils.java +++ b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/Utils.java @@ -14,7 +14,7 @@ public class Utils { BigInteger[] coefficients = new BigInteger[degree + 1]; for (int i = 0 ; i <= degree; i++ ){ - coefficients[i] = new BigInteger(bits,random); // sample from Zp [0,... p-1] + coefficients[i] = new BigInteger(bits,random); // sample from Zp [0,... q-1] } return new Polynomial(coefficients); } diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java index 8846cd9..ec58262 100644 --- a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java +++ b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java @@ -1,15 +1,13 @@ package FeldmanVerifiableSecretSharing; import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; -import FeldmanVerifiableSecretSharing.ShamirSecretSharing.SecretSharing; import org.factcenter.qilin.primitives.CyclicGroup; import org.factcenter.qilin.primitives.concrete.Zn; +import org.factcenter.qilin.primitives.concrete.Zpstar; import org.junit.Before; import org.junit.Test; import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; import java.util.Random; /** @@ -25,31 +23,34 @@ public class VerifiableSecretSharingTest { @Before public void settings(){ BigInteger p = BigInteger.valueOf(2903); - CyclicGroup group = new Zn(p); - int t = 10; + BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); + + int t = 8; int n = 20; random = new Random(); + BigInteger g = null; //Todo verifiableSecretSharingArray = new VerifiableSecretSharing[tests]; for (int i = 0; i < verifiableSecretSharingArray.length; i++){ - verifiableSecretSharingArray[i] = new VerifiableSecretSharing(group,t,n,group.sample(random),random); + verifiableSecretSharingArray[i] = new VerifiableSecretSharing(t,n + ,new BigInteger(q.bitLength(),random).mod(q),random,p,q,g); } } public void oneTest(VerifiableSecretSharing verifiableSecretSharing) throws Exception { int n = verifiableSecretSharing.getN(); - BigInteger p = verifiableSecretSharing.getP(); - CyclicGroup group = verifiableSecretSharing.getGroup(); + BigInteger p = verifiableSecretSharing.getQ(); + Zpstar zpstar = new Zpstar(p); BigInteger g = verifiableSecretSharing.getGenerator(); Polynomial.Point[] shares = new Polynomial.Point[n]; BigInteger[] commitments = verifiableSecretSharing.getCommitments(); BigInteger[] verifications = new BigInteger[n]; for (int i = 1 ; i <= shares.length; i ++){ shares[i - 1] = verifiableSecretSharing.getShare(i); - verifications[i - 1] = VerifiableSecretSharing.verify(i,commitments,group); + verifications[i - 1] = VerifiableSecretSharing.verify(i,commitments,zpstar); } BigInteger expected; for (int i = 0 ; i < shares.length ; i++){ - expected = group.multiply(g,shares[i].y).mod(p); // problem with Zn, multiplication doesn't mod n as required + expected = zpstar.multiply(g,shares[i].y); assert (expected.equals(verifications[i])); } @@ -59,6 +60,7 @@ public class VerifiableSecretSharingTest { public void secretSharingTest() throws Exception { for (int i = 0 ; i < verifiableSecretSharingArray.length; i ++){ oneTest(verifiableSecretSharingArray[i]); + } } } From 0a8d4abe72d539de44c1fbfaa2e92e9761c62b99 Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Fri, 5 Feb 2016 13:36:55 +0200 Subject: [PATCH 15/49] sketch of JointFeldmanProtocol --- .../ShamirSecretSharing/SecretSharing.java | 7 +++++++ .../ShamirSecretSharing/SecretSharingTest.java | 4 ++-- .../VerifiableSecretSharingTest.java | 7 +++---- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java index 4a90ac7..0559a7c 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java @@ -58,6 +58,13 @@ public class SecretSharing { return new Polynomial.Point(BigInteger.valueOf(i), polynomial, q); } + /** + * use for test only + */ + public Polynomial.Point getShareForTest(int i){ + return getShare(i); + } + /** * @param shares - subset of the original shares * diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharingTest.java b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharingTest.java index d5f8842..bc96f7f 100644 --- a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharingTest.java +++ b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharingTest.java @@ -33,12 +33,12 @@ public class SecretSharingTest { secrets = new BigInteger[tests]; for (int i = 0; i < secretSharingArray.length; i++){ secrets[i] = group.sample(random); - secretSharingArray[i] = new SecretSharing(p,t,n,secrets[i],random); + secretSharingArray[i] = new SecretSharing(t,n,secrets[i],random,p); } } public void oneTest(SecretSharing secretSharing, BigInteger secret) throws Exception { - int t = secretSharing.getThreshold(); + int t = secretSharing.getT(); int n = secretSharing.getN(); Polynomial.Point[] shares = new Polynomial.Point[t + 1]; List indexes = new ArrayList(n); diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java index ec58262..cb18f3f 100644 --- a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java +++ b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java @@ -20,7 +20,7 @@ public class VerifiableSecretSharingTest { int tests = 1 << 10; Random random; - @Before + //@Before public void settings(){ BigInteger p = BigInteger.valueOf(2903); BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); @@ -45,7 +45,7 @@ public class VerifiableSecretSharingTest { BigInteger[] commitments = verifiableSecretSharing.getCommitments(); BigInteger[] verifications = new BigInteger[n]; for (int i = 1 ; i <= shares.length; i ++){ - shares[i - 1] = verifiableSecretSharing.getShare(i); + shares[i - 1] = verifiableSecretSharing.getShareForTest(i); verifications[i - 1] = VerifiableSecretSharing.verify(i,commitments,zpstar); } BigInteger expected; @@ -56,11 +56,10 @@ public class VerifiableSecretSharingTest { } - @Test + //@Test public void secretSharingTest() throws Exception { for (int i = 0 ; i < verifiableSecretSharingArray.length; i ++){ oneTest(verifiableSecretSharingArray[i]); - } } } From 91dd19ead292b88992041541677619da7f753acc Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Sun, 7 Feb 2016 14:38:47 +0200 Subject: [PATCH 16/49] message handler --- .../main/java/JointFeldmanProtocol/DKG.java | 119 +++++++++++--- .../java/JointFeldmanProtocol/Network.java | 148 ++++++++++++++++-- .../VerifiableSecretSharingTest.java | 20 +-- 3 files changed, 238 insertions(+), 49 deletions(-) diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java index 6962d29..49a6f17 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java @@ -6,6 +6,7 @@ import org.bouncycastle.util.Arrays; import org.factcenter.qilin.primitives.concrete.Zpstar; import java.math.BigInteger; +import java.util.HashSet; import java.util.Random; import java.util.Set; @@ -14,44 +15,55 @@ import java.util.Set; * * an implementation of a version of Pedersen's distributed key generation protocol */ -public class DKG extends VerifiableSecretSharing{ +public class DKG extends VerifiableSecretSharing implements Runnable{ private Network.User user; - private Polynomial.Point[][] shares; + private Handler handler; + private Polynomial.Point[] shares; private BigInteger[][] commitmentsArray; + private BigInteger[] ys; private Set QUAL; private BigInteger x; private BigInteger y; private BigInteger[] commitments; - public DKG(int t, int n, BigInteger x, Random random, BigInteger p, BigInteger q, BigInteger g) { + public DKG(int t, int n, BigInteger x, Random random, BigInteger p, BigInteger q, BigInteger g,Network network) { super(t, n, x, random, p, q, g); + this.commitmentsArray = new BigInteger[n][t + 1]; + this.shares = new Polynomial.Point[n]; + this.handler = new Handler(); + this.user = network.connect(handler); } + private void stage1(){ int n = getN(); + int t = getT(); int i = user.getID(); BigInteger[] commitments = super.getCommitments(); System.arraycopy(commitments, 0, commitmentsArray[i - 1], 0, commitmentsArray[i - 1].length); - Network.Message message = null; + Network.CommitmentMessage commitment; for (int j = 1; j <= commitmentsArray[i - 1].length; j ++){ - //message = new Message(Type.Commitment, Shares[i - 1][j - 1]) - user.sendBroadcast(message); + commitment = new Network.CommitmentMessage(j,commitmentsArray[i - 1][j - 1]); + user.broadcast(commitment); } - - for (int j = 1; j <= shares[i - 1].length; j ++){ - shares[i - 1][j - 1] = getShare(j); - } + Network.SecretMessage secret; for (int j = 1; j <= n ; j++ ){ if(j != i){ - //message = new Message(Type.Share, Shares[i - 1][j - 1]) - user.send(j,message); + secret = new Network.SecretMessage(getShare(j)); + user.send(j,secret); + } + } + while (handler.secretsCounter < n - 1 || handler.commitmentsCounter < (n - 1) * (t + 1)){ + try { + Thread.sleep(30); + } catch (InterruptedException e) { + // do nothing } } - //Todo receive messages } private void stage2(){ @@ -59,35 +71,40 @@ public class DKG extends VerifiableSecretSharing{ BigInteger g = getGenerator(); Zpstar zpstar = getZpstar(); int i = user.getID(); + QUAL = new HashSet(); Network.Message message = null; for (int j = 1; j <= n ; j++ ){ - if(zpstar.multiply(g,shares[i - 1][j - 1].y).equals(verify(j,commitmentsArray[j],zpstar))){ + if(zpstar.multiply(g,shares[j - 1].y).equals(verify(j,commitmentsArray[j],zpstar))){ QUAL.add(j); }else{ //message = new Message(Type.Complaint, j) - user.sendBroadcast(message); + user.broadcast(message); } } - + //sending y after Complaints + Network.YMessage yMessage = new Network.YMessage(super.getY()); + user.broadcast(yMessage); } private void stage3(){ - + int n = getN(); + while (handler.ysCounter < n - 1 ){ + try { + Thread.sleep(30); + } catch (InterruptedException e) { + // do nothing + } + } //Todo receive something private from each complaint + send what necessary - - } private void stage4(){ - Network.Message message = null; - // message = new Message(Type.Y, super.getY()) - user.sendBroadcast(message); + int t = getT(); Zpstar zpstar = getZpstar(); BigInteger y = zpstar.zero(); - for (Network.User user:this.user.getNetwork()) { - //Todo receive yi from all i in QUAL and calc y total + for (int i : QUAL) { + y = zpstar.add(y , ys[i - 1]); } - int t = getT(); this.commitments = new BigInteger[t]; BigInteger commitment; for (int k = 1; k <= t ; k++){ @@ -101,7 +118,7 @@ public class DKG extends VerifiableSecretSharing{ int j = user.getID(); BigInteger x = BigInteger.ZERO; for (int i : QUAL) { - x = x.add(shares[i][j].y); + x = x.add(shares[i - 1].y); } this.x = x.mod(getQ()); } @@ -120,4 +137,54 @@ public class DKG extends VerifiableSecretSharing{ protected Polynomial.Point getShare(int i) { return null; } + + @Override + public void run() { + stage1(); + stage2(); + stage3(); + stage4(); + } + + private class Handler implements Network.MailHandler { + + final int id; + int secretsCounter; + int commitmentsCounter; + int ysCounter; + + private Handler() { + this.id = user.getID(); + this.secretsCounter = 0; + this.commitmentsCounter = 0; + this.ysCounter = 0; + } + + @Override + public void handel(Network.Mail mail) { + if(mail.isPrivate){ + if(mail.message instanceof Network.SecretMessage){ + Polynomial.Point secret = ((Network.SecretMessage)mail.message).secret; + if(shares[id - 1] == null) { + shares[id - 1] = secret; + secretsCounter++; + } + } + }else{ + if(mail.message instanceof Network.CommitmentMessage){ + Network.CommitmentMessage commitmentMessage = (Network.CommitmentMessage)mail.message; + if(commitmentsArray[mail.senderID - 1][commitmentMessage.k] == null) { + commitmentsArray[mail.senderID - 1][commitmentMessage.k] = commitmentMessage.commitment; + commitmentsCounter++; + } + }else if(mail.message instanceof Network.YMessage){ + BigInteger y = ((Network.YMessage)mail.message).y; + if(ys[mail.senderID - 1] == null){ + ys[mail.senderID - 1] = y; + ysCounter ++; + } + } + } + } + } } diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java index 46c1d44..8468d2d 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java @@ -1,27 +1,147 @@ package JointFeldmanProtocol; +import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; + +import java.lang.reflect.Type; +import java.math.BigInteger; +import java.util.Queue; +import java.util.concurrent.ArrayBlockingQueue; /** - * Created by Tzlil on 2/5/2016. + * Created by Tzlil on 2/7/2016. */ -public interface Network extends Iterable{ +public class Network { - User connect(); + private final User[] users; + private final int n; + private final Queue availableIDs; - interface User{ - int getID(); - void send(int userID,Message message); - void sendBroadcast(Message message); - void receive(int userID,Message message); - void receiveBroadcast(Message message); - Network getNetwork(); + + public Network(int n) { + this.n = n; + this.users = new User[n]; + this.availableIDs = new ArrayBlockingQueue(n); + for (int id = 1; id <= n; id++){ + availableIDs.add(id); + } } - interface Message{ - enum Type { - Commitment, Share, Complaint, Y + public User connect(MailHandler messageHandler){ + Integer id = availableIDs.poll(); + if (id == null) + return null; + return new User(id,messageHandler); + } + + private boolean sendMessage(User sender,int destination,Message message){ + if(destination < 1 || destination > n) + return false; + User user = users[destination - 1]; + if (user == null) + return false; + return user.mailbox.add(new Mail(sender.ID,false,message)); + } + + private void sendBroadcast(User sender,Message message){ + User user; + int ID = sender.ID; + for (int i = 0 ; i < n ; i++){ + if (i + 1 == ID) { + continue; + } + user = users[i]; + user.mailbox.add(new Mail(ID,true,message)); + } + } + + public class User{ + private final MailHandler messageHandler; + private final Queue mailbox; + private final int ID; + + public User(int ID, MailHandler messageHandler) { + this.mailbox = new ArrayBlockingQueue(n*n); + this.ID = ID; + this.messageHandler = messageHandler; + Thread thread = new Thread(new Receiver()); + thread.run(); + } + + + public boolean send(int id, Message message){ + return sendMessage(this,id,message); + } + public void broadcast(Message message){ + sendBroadcast(this,message); + } + + public int getID() { + return ID; + } + + private class Receiver implements Runnable{ + @Override + public void run() { + while (true){ + if (!mailbox.isEmpty()){ + messageHandler.handel(mailbox.poll()); + }else{ + try { + Thread.sleep(30); + } catch (InterruptedException e) { + // do nothing + } + } + } + } } - Type getType(); } + + public class Mail{ + public final int senderID; + public final boolean isPrivate; + public final Message message; + + private Mail(int senderID, boolean isPrivate, Message message) { + this.senderID = senderID; + this.isPrivate = isPrivate; + this.message = message; + } + } + + public static abstract class Message{ + + } + public static class CommitmentMessage extends Message{ + public final int k; + public final BigInteger commitment; + + + public CommitmentMessage(int k, BigInteger commitment) { + this.k = k; + this.commitment = commitment; + } + } + + public static class YMessage extends Message{ + + public final BigInteger y; + + public YMessage(BigInteger y) { + this.y = y; + } + } + + public static class SecretMessage extends Message{ + public final Polynomial.Point secret; + + public SecretMessage(Polynomial.Point secret) { + this.secret = secret; + } + } + + public interface MailHandler { + public void handel(Mail mail); + } } diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java index cb18f3f..8a4f15d 100644 --- a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java +++ b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java @@ -1,8 +1,6 @@ package FeldmanVerifiableSecretSharing; import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; -import org.factcenter.qilin.primitives.CyclicGroup; -import org.factcenter.qilin.primitives.concrete.Zn; import org.factcenter.qilin.primitives.concrete.Zpstar; import org.junit.Before; import org.junit.Test; @@ -20,15 +18,20 @@ public class VerifiableSecretSharingTest { int tests = 1 << 10; Random random; - //@Before + @Before public void settings(){ BigInteger p = BigInteger.valueOf(2903); BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); - + Zpstar zpstar = new Zpstar(p); + random = new Random(); + BigInteger g; + BigInteger ZERO = zpstar.zero(); + do{ + g = zpstar.sample(random); + }while (!g.equals(ZERO) && !zpstar.multiply(g,q).equals(ZERO));// sample from QRZp* int t = 8; int n = 20; - random = new Random(); - BigInteger g = null; //Todo + verifiableSecretSharingArray = new VerifiableSecretSharing[tests]; for (int i = 0; i < verifiableSecretSharingArray.length; i++){ verifiableSecretSharingArray[i] = new VerifiableSecretSharing(t,n @@ -38,8 +41,7 @@ public class VerifiableSecretSharingTest { public void oneTest(VerifiableSecretSharing verifiableSecretSharing) throws Exception { int n = verifiableSecretSharing.getN(); - BigInteger p = verifiableSecretSharing.getQ(); - Zpstar zpstar = new Zpstar(p); + Zpstar zpstar = verifiableSecretSharing.getZpstar(); BigInteger g = verifiableSecretSharing.getGenerator(); Polynomial.Point[] shares = new Polynomial.Point[n]; BigInteger[] commitments = verifiableSecretSharing.getCommitments(); @@ -56,7 +58,7 @@ public class VerifiableSecretSharingTest { } - //@Test + @Test public void secretSharingTest() throws Exception { for (int i = 0 ; i < verifiableSecretSharingArray.length; i ++){ oneTest(verifiableSecretSharingArray[i]); From 8288b07d8001ca6748562f187b6f9c5905cab539 Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Mon, 8 Feb 2016 15:20:43 +0200 Subject: [PATCH 17/49] joint feldman with protos --- .../ShamirSecretSharing/Polynomial.java | 23 +- .../ShamirSecretSharing/SecretSharing.java | 6 +- .../VerifiableSecretSharing.java | 34 +-- .../main/java/JointFeldmanProtocol/DKG.java | 262 ++++++++++++++---- .../java/JointFeldmanProtocol/Network.java | 90 +++--- .../src/main/proto/meerkat/DKGMessages.proto | 40 +++ 6 files changed, 310 insertions(+), 145 deletions(-) create mode 100644 meerkat-common/src/main/proto/meerkat/DKGMessages.proto diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java index e285e01..30a56ed 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java @@ -1,7 +1,8 @@ package FeldmanVerifiableSecretSharing.ShamirSecretSharing; +import com.google.protobuf.ByteString; +import meerkat.protobuf.DKGMessages; import org.bouncycastle.util.Arrays; - import java.math.BigInteger; /** @@ -172,7 +173,7 @@ public class Polynomial implements Comparable { * inner class * container for (x,y) x from range and y from image of polynomial */ - public static class Point{ + public static class Point implements java.io.Serializable { public final BigInteger x; public final BigInteger y; @@ -199,13 +200,21 @@ public class Polynomial implements Comparable { } /** - * copy constructor - * @param point + * constructor - restore point from message + * @param pointMessage */ - public Point(Point point) { - this.x = point.x; - this.y = point.y; + public Point(DKGMessages.SecretMessage.Point pointMessage) { + this.x = new BigInteger(pointMessage.getX().toByteArray()); + this.y = new BigInteger(pointMessage.getY().toByteArray()); } + + public DKGMessages.SecretMessage.Point asMessage(){ + return DKGMessages.SecretMessage.Point.newBuilder() + .setX(ByteString.copyFrom(x.toByteArray())) + .setY(ByteString.copyFrom(y.toByteArray())) + .build(); + } + } } diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java index 0559a7c..ebed7a2 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java @@ -9,9 +9,9 @@ import java.util.Random; * an implementation of Shamire's secret sharing scheme */ public class SecretSharing { - private final int t; - private final int n; - private final BigInteger q; + protected final int t; + protected final int n; + protected final BigInteger q; private final Polynomial polynomial; diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java index e8d5c98..eb3dc07 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java @@ -18,10 +18,10 @@ import java.util.Random; * */ public class VerifiableSecretSharing extends SecretSharing { - private final Zpstar zpstar; - private final BigInteger g; // public generator of group - private final BigInteger[] commitments; + protected final Zpstar zpstar; + protected final BigInteger g; // public generator of group private final BigInteger y; // y = g ^ x + private final BigInteger[] commitments; /** * @param p a large prime @@ -55,19 +55,19 @@ public class VerifiableSecretSharing extends SecretSharing { } /** - * @param i share holder id + * @param j share holder id * @param commitments * @param zpstar * * @return product of commitments[j] ^ (i ^ j) == g ^ polynomial(i) */ - public static BigInteger verify(int i,BigInteger[] commitments,Zpstar zpstar) { + public static BigInteger verify(int j,BigInteger[] commitments,Zpstar zpstar) { BigInteger v = zpstar.zero(); BigInteger power = BigInteger.ONE; - BigInteger I = BigInteger.valueOf(i); - for (int j = 0 ; j < commitments.length ; j ++){ - v = zpstar.add(v,zpstar.multiply(commitments[j],power)); - power = power.multiply(I); + BigInteger J = BigInteger.valueOf(j); + for (int k = 0 ; k < commitments.length ; k ++){ + v = zpstar.add(v,zpstar.multiply(commitments[k],power)); + power = power.multiply(J); } return v; } @@ -81,14 +81,6 @@ public class VerifiableSecretSharing extends SecretSharing { return g; } - /** - * getter - * @return copy of commitments - */ - public BigInteger[] getCommitments() { - return Arrays.clone(commitments); - } - /** * getter * @return zpstar @@ -104,4 +96,12 @@ public class VerifiableSecretSharing extends SecretSharing { public BigInteger getY(){ return y; } + + /** + * getter + * @return copy of commitments + */ + public BigInteger[] getCommitments() { + return Arrays.clone(commitments); + } } diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java index 49a6f17..dcd12fa 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java @@ -2,8 +2,10 @@ package JointFeldmanProtocol; import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; import org.bouncycastle.util.Arrays; -import org.factcenter.qilin.primitives.concrete.Zpstar; +import meerkat.protobuf.DKGMessages.*; import java.math.BigInteger; import java.util.HashSet; @@ -18,10 +20,12 @@ import java.util.Set; public class DKG extends VerifiableSecretSharing implements Runnable{ private Network.User user; - private Handler handler; + private Network.MailHandler handler; private Polynomial.Point[] shares; + private Polynomial.Point[] myshares; private BigInteger[][] commitmentsArray; private BigInteger[] ys; + final ComplainState[][] complainStates; private Set QUAL; private BigInteger x; @@ -30,34 +34,47 @@ public class DKG extends VerifiableSecretSharing implements Runnable{ public DKG(int t, int n, BigInteger x, Random random, BigInteger p, BigInteger q, BigInteger g,Network network) { super(t, n, x, random, p, q, g); + this.commitmentsArray = new BigInteger[n][t + 1]; this.shares = new Polynomial.Point[n]; + this.myshares = new Polynomial.Point[n]; this.handler = new Handler(); this.user = network.connect(handler); + this.complainStates = new ComplainState[n][n]; + + for (int i = 0; i < n; i ++){ + for (int j = 0 ; j < n ; j ++) + complainStates[i][j] = ComplainState.Non; + } + } private void stage1(){ - int n = getN(); - int t = getT(); int i = user.getID(); BigInteger[] commitments = super.getCommitments(); System.arraycopy(commitments, 0, commitmentsArray[i - 1], 0, commitmentsArray[i - 1].length); - Network.CommitmentMessage commitment; - for (int j = 1; j <= commitmentsArray[i - 1].length; j ++){ - commitment = new Network.CommitmentMessage(j,commitmentsArray[i - 1][j - 1]); - user.broadcast(commitment); + CommitmentMessage commitment; + for (int k = 1; k <= commitmentsArray[i - 1].length; k ++){ + commitment = CommitmentMessage.newBuilder() + .setK(k) + .setCommitment(ByteString.copyFrom(commitmentsArray[i - 1][k - 1].toByteArray())) + .build(); + user.broadcast(Mail.Type.COMMITMENT,commitment); } - Network.SecretMessage secret; + SecretMessage secret; for (int j = 1; j <= n ; j++ ){ if(j != i){ - secret = new Network.SecretMessage(getShare(j)); - user.send(j,secret); + myshares[j - 1] = super.getShare(j); + secret = SecretMessage.newBuilder() + .setSecret(myshares[j - 1].asMessage()) + .build(); + user.send(j, Mail.Type.SECRET,secret); } } - while (handler.secretsCounter < n - 1 || handler.commitmentsCounter < (n - 1) * (t + 1)){ + while (!isStage1Complete()){ try { Thread.sleep(30); } catch (InterruptedException e) { @@ -66,41 +83,112 @@ public class DKG extends VerifiableSecretSharing implements Runnable{ } } + private boolean isStage1Complete(){ + int id = user.getID(); + for (int j = 1 ; j <= n ; j++){ + if(id != j && shares[j - 1] == null) + return false; + } + + for (int i = 0; i < commitmentsArray.length; i++){ + for (int j = 0; j < commitmentsArray[i].length; j++){ + if(commitmentsArray[i][j] == null) + return false; + } + } + return true; + } + + private boolean isValidSecret(Polynomial.Point secret, int i){ + int j = secret.x.intValue(); + return zpstar.multiply(g,secret.y).equals(verify(j,commitmentsArray[i],zpstar)); + } + private void stage2(){ - int n = getN(); - BigInteger g = getGenerator(); - Zpstar zpstar = getZpstar(); - int i = user.getID(); + int j = user.getID(); QUAL = new HashSet(); - Network.Message message = null; - for (int j = 1; j <= n ; j++ ){ - if(zpstar.multiply(g,shares[j - 1].y).equals(verify(j,commitmentsArray[j],zpstar))){ - QUAL.add(j); + ComplaintMessage complaint; + for (int i = 1; i <= n ; i++ ){ + if(isValidSecret(shares[i - 1],j)) { + QUAL.add(i); }else{ //message = new Message(Type.Complaint, j) - user.broadcast(message); + complaint = ComplaintMessage.newBuilder() + .setId(i) + .build(); + user.broadcast(Mail.Type.COMPLAINT,complaint); + complainStates[j - 1][i - 1] = ComplainState.Waiting; } } //sending y after Complaints - Network.YMessage yMessage = new Network.YMessage(super.getY()); - user.broadcast(yMessage); - } + YMessage yMessage = YMessage.newBuilder() + .setY(ByteString.copyFrom(super.getY().toByteArray())) + .build(); + user.broadcast(Mail.Type.Y,yMessage); - private void stage3(){ - int n = getN(); - while (handler.ysCounter < n - 1 ){ + while (!isStage2Complete()){ try { Thread.sleep(30); } catch (InterruptedException e) { // do nothing } } - //Todo receive something private from each complaint + send what necessary + } + + private boolean isStage2Complete() { + int id = user.getID(); + for (int j = 1; j <= n ; j++) { + if (id != j && ys[j - 1] == null) + return false; + } + for (int i = 0; i < complainStates.length;i++){ + for (int j =0 ; j < complainStates[i].length;j++){ + switch (complainStates[i][j]){ + case Waiting: + return false; + default: + break; + } + } + } + return true; + } + + private void stage3(){ + for (int i = 0; i < complainStates.length;i++){ + ComplainState state = ComplainState.Non; + for (int j = 0 ; j < complainStates[i].length;j++){ + switch (complainStates[i][j]){ + case Disqualified: + state = ComplainState.Disqualified; + break; + case NonDisqualified: + if(state == ComplainState.Non){ + state = ComplainState.NonDisqualified; + } + break; + default: + break; + } + } + switch (state){ + case Disqualified: + if(QUAL.contains(i + 1)){ + QUAL.remove(i + 1); + } + break; + case NonDisqualified: + if (!QUAL.contains(i + 1)){ + QUAL.add(i + 1); + } + break; + default: + break; + } + } } private void stage4(){ - int t = getT(); - Zpstar zpstar = getZpstar(); BigInteger y = zpstar.zero(); for (int i : QUAL) { y = zpstar.add(y , ys[i - 1]); @@ -120,7 +208,7 @@ public class DKG extends VerifiableSecretSharing implements Runnable{ for (int i : QUAL) { x = x.add(shares[i - 1].y); } - this.x = x.mod(getQ()); + this.x = x.mod(q); } @Override @@ -146,45 +234,101 @@ public class DKG extends VerifiableSecretSharing implements Runnable{ stage4(); } + private enum ComplainState{ + Non, Waiting,Disqualified,NonDisqualified + } + private class Handler implements Network.MailHandler { final int id; - int secretsCounter; - int commitmentsCounter; - int ysCounter; private Handler() { this.id = user.getID(); - this.secretsCounter = 0; - this.commitmentsCounter = 0; - this.ysCounter = 0; } - @Override - public void handel(Network.Mail mail) { - if(mail.isPrivate){ - if(mail.message instanceof Network.SecretMessage){ - Polynomial.Point secret = ((Network.SecretMessage)mail.message).secret; - if(shares[id - 1] == null) { - shares[id - 1] = secret; - secretsCounter++; - } - } - }else{ - if(mail.message instanceof Network.CommitmentMessage){ - Network.CommitmentMessage commitmentMessage = (Network.CommitmentMessage)mail.message; - if(commitmentsArray[mail.senderID - 1][commitmentMessage.k] == null) { - commitmentsArray[mail.senderID - 1][commitmentMessage.k] = commitmentMessage.commitment; - commitmentsCounter++; - } - }else if(mail.message instanceof Network.YMessage){ - BigInteger y = ((Network.YMessage)mail.message).y; - if(ys[mail.senderID - 1] == null){ - ys[mail.senderID - 1] = y; - ysCounter ++; + void handelSecretMessage(Mail mail) throws InvalidProtocolBufferException { + if(shares[mail.getSender() - 1] == null) { + SecretMessage secretMessage = SecretMessage.parseFrom(mail.getMessage()); + Polynomial.Point secret = new Polynomial.Point(secretMessage.getSecret()); + if(mail.getIsPrivate()){ + shares[mail.getSender() - 1] = secret; + }else{ + int i = mail.getSender(); + int j = secret.x.intValue(); + switch (complainStates[i][j]){ + case Waiting: + if(isValidSecret(secret,i)){ + complainStates[i][j] = ComplainState.NonDisqualified; + }else{ + complainStates[i][j] = ComplainState.Disqualified; + } + break; + default: + break; } } } } + + void handelCommitmentMessage(Mail mail) throws InvalidProtocolBufferException { + if(!mail.getIsPrivate()) { //broadcast only + CommitmentMessage commitmentMessage = CommitmentMessage.parseFrom(mail.getMessage()); + if (commitmentsArray[mail.getSender() - 1][commitmentMessage.getK()] == null) { + BigInteger commitment = new BigInteger(commitmentMessage.getCommitment().toByteArray()); + commitmentsArray[mail.getSender() - 1][commitmentMessage.getK()] = commitment; + } + } + } + + void handelYMessage(Mail mail) throws InvalidProtocolBufferException { + if(!mail.getIsPrivate()) { //broadcast only + if (ys[mail.getSender() - 1] == null) { + YMessage yMessage = YMessage.parseFrom(mail.getMessage()); + BigInteger y = new BigInteger(yMessage.getY().toByteArray()); + ys[mail.getSender() - 1] = y; + } + } + } + + void handelComplaintMessage(Mail mail) throws InvalidProtocolBufferException { + if(!mail.getIsPrivate()) { //broadcast only + ComplaintMessage complaintMessage = ComplaintMessage.parseFrom(mail.getMessage()); + int i = complaintMessage.getId(); + int j = mail.getSender(); + if(i == id){ + user.broadcast(Mail.Type.SECRET,SecretMessage.newBuilder() + .setSecret(myshares[j].asMessage()) + .build()); + }else{ + switch (complainStates[i - 1][j - 1]){ + case Non: + complainStates[i - 1][j - 1] = ComplainState.Waiting; + break; + default: + break; + } + } + } + } + + @Override + public void handel(Mail mail) throws InvalidProtocolBufferException { + switch (mail.getType()){ + case SECRET: + handelSecretMessage(mail); + break; + case COMMITMENT: + handelCommitmentMessage(mail); + break; + case Y: + handelYMessage(mail); + break; + case COMPLAINT: + handelComplaintMessage(mail); + break; + default: + break; + } + } } } diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java index 8468d2d..3cc3c85 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java @@ -1,9 +1,8 @@ package JointFeldmanProtocol; -import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; - -import java.lang.reflect.Type; -import java.math.BigInteger; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; +import meerkat.protobuf.DKGMessages.*; import java.util.Queue; import java.util.concurrent.ArrayBlockingQueue; /** @@ -32,24 +31,38 @@ public class Network { return new User(id,messageHandler); } - private boolean sendMessage(User sender,int destination,Message message){ + private boolean sendMessage(User sender,int destination,Mail.Type type,Message message){ if(destination < 1 || destination > n) return false; User user = users[destination - 1]; if (user == null) return false; - return user.mailbox.add(new Mail(sender.ID,false,message)); + Mail mail = Mail.newBuilder() + .setSender(sender.getID()) + .setDestination(destination) + .setIsPrivate(true) + .setType(type) + .setMessage(message.toByteString()) + .build(); + return user.mailbox.add(mail); } - private void sendBroadcast(User sender,Message message){ + private void sendBroadcast(User sender,Mail.Type type,Message message){ User user; int ID = sender.ID; + Mail mail = Mail.newBuilder() + .setSender(sender.getID()) + .setDestination(0) + .setIsPrivate(false) + .setType(type) + .setMessage(message.toByteString()) + .build(); for (int i = 0 ; i < n ; i++){ if (i + 1 == ID) { continue; } user = users[i]; - user.mailbox.add(new Mail(ID,true,message)); + user.mailbox.add(mail); } } @@ -66,14 +79,12 @@ public class Network { thread.run(); } - - public boolean send(int id, Message message){ - return sendMessage(this,id,message); + public boolean send(int id, Mail.Type type,Message message){ + return sendMessage(this,id,type,message); } - public void broadcast(Message message){ - sendBroadcast(this,message); + public void broadcast(Mail.Type type,Message message){ + sendBroadcast(this,type,message); } - public int getID() { return ID; } @@ -83,7 +94,11 @@ public class Network { public void run() { while (true){ if (!mailbox.isEmpty()){ - messageHandler.handel(mailbox.poll()); + try { + messageHandler.handel(mailbox.poll()); + } catch (InvalidProtocolBufferException e) { + e.printStackTrace(); + } }else{ try { Thread.sleep(30); @@ -98,50 +113,7 @@ public class Network { } - public class Mail{ - public final int senderID; - public final boolean isPrivate; - public final Message message; - - private Mail(int senderID, boolean isPrivate, Message message) { - this.senderID = senderID; - this.isPrivate = isPrivate; - this.message = message; - } - } - - public static abstract class Message{ - - } - public static class CommitmentMessage extends Message{ - public final int k; - public final BigInteger commitment; - - - public CommitmentMessage(int k, BigInteger commitment) { - this.k = k; - this.commitment = commitment; - } - } - - public static class YMessage extends Message{ - - public final BigInteger y; - - public YMessage(BigInteger y) { - this.y = y; - } - } - - public static class SecretMessage extends Message{ - public final Polynomial.Point secret; - - public SecretMessage(Polynomial.Point secret) { - this.secret = secret; - } - } - public interface MailHandler { - public void handel(Mail mail); + public void handel(Mail mail) throws InvalidProtocolBufferException; } } diff --git a/meerkat-common/src/main/proto/meerkat/DKGMessages.proto b/meerkat-common/src/main/proto/meerkat/DKGMessages.proto new file mode 100644 index 0000000..e874f5a --- /dev/null +++ b/meerkat-common/src/main/proto/meerkat/DKGMessages.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; + +package meerkat; + +option java_package = "meerkat.protobuf"; + +message Mail{ + enum Type { + SECRET = 0; + COMMITMENT = 1; + Y = 2; + COMPLAINT = 3; + } + int32 sender = 1; + int32 destination = 2; + bool isPrivate = 3; + Type type = 4; + bytes message = 5; +} + +message SecretMessage { + message Point{ + bytes x = 1; + bytes y = 2; + } + Point secret = 1; +} + +message CommitmentMessage{ + int32 k = 1; + bytes commitment = 2; +} + +message YMessage{ + bytes y = 1; +} + +message ComplaintMessage{ + int32 id = 1; +} \ No newline at end of file From a233f2f7139cb011b8a5607335af75e81af1a272 Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Tue, 9 Feb 2016 20:37:57 +0200 Subject: [PATCH 18/49] joint feldman protocol with test --- .../ShamirSecretSharing/Polynomial.java | 10 + .../ShamirSecretSharing/SecretSharing.java | 2 +- .../main/java/JointFeldmanProtocol/DKG.java | 254 ++++++++++-------- .../java/JointFeldmanProtocol/Network.java | 17 +- .../PolynomialTests/InterpolationTest.java | 1 - .../java/JointFeldmanProtocol/DKGTest.java | 57 ++++ 6 files changed, 220 insertions(+), 121 deletions(-) create mode 100644 destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java index 30a56ed..2bdf2ad 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java @@ -208,6 +208,16 @@ public class Polynomial implements Comparable { this.y = new BigInteger(pointMessage.getY().toByteArray()); } + /** + * constructor + * @param x + * @param y + */ + public Point(BigInteger x,BigInteger y) { + this.x = x; + this.y = y; + } + public DKGMessages.SecretMessage.Point asMessage(){ return DKGMessages.SecretMessage.Point.newBuilder() .setX(ByteString.copyFrom(x.toByteArray())) diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java index ebed7a2..9e3319d 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java @@ -53,7 +53,7 @@ public class SecretSharing { * * @return polynomial.image(i)%q */ - protected Polynomial.Point getShare(int i){ + protected final Polynomial.Point getShare(int i){ assert (i > 0 && i <= n); return new Polynomial.Point(BigInteger.valueOf(i), polynomial, q); } diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java index dcd12fa..2cbef48 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java @@ -11,6 +11,7 @@ import java.math.BigInteger; import java.util.HashSet; import java.util.Random; import java.util.Set; +import java.util.concurrent.Callable; /** * Created by Tzlil on 2/5/2016. @@ -19,28 +20,31 @@ import java.util.Set; */ public class DKG extends VerifiableSecretSharing implements Runnable{ - private Network.User user; - private Network.MailHandler handler; - private Polynomial.Point[] shares; - private Polynomial.Point[] myshares; - private BigInteger[][] commitmentsArray; - private BigInteger[] ys; - final ComplainState[][] complainStates; - private Set QUAL; + private final int id; + private final Network.User user; // send and receive messages throw network + + private final BigInteger[] ys; // container for y values that + private final Polynomial.Point[] shares; // shares[i] equivalent to Si,id in terms of the protocol + private final BigInteger[][] commitmentsArray; // commitmentsArray[i] equivalent to Ai in terms of the protocol + private final ComplainState[][] complainStates; // complainStates[i][j] == state of Pj's complaint against Pi + + private final Set QUAL; // set of all non-disqualified parties + private final BigInteger[] commitments; // public verification values + private Polynomial.Point share; // final share of the secrete + private BigInteger y; // final public value - private BigInteger x; - private BigInteger y; - private BigInteger[] commitments; public DKG(int t, int n, BigInteger x, Random random, BigInteger p, BigInteger q, BigInteger g,Network network) { super(t, n, x, random, p, q, g); this.commitmentsArray = new BigInteger[n][t + 1]; this.shares = new Polynomial.Point[n]; - this.myshares = new Polynomial.Point[n]; - this.handler = new Handler(); - this.user = network.connect(handler); + this.user = network.connect(new Handler()); + this.id = user.getID(); this.complainStates = new ComplainState[n][n]; + this.QUAL = new HashSet(); + this.ys = new BigInteger[n]; + this.commitments = new BigInteger[t + 1]; for (int i = 0; i < n; i ++){ for (int j = 0 ; j < n ; j ++) @@ -49,44 +53,67 @@ public class DKG extends VerifiableSecretSharing implements Runnable{ } + /** + * use for simulate real distributed protocol + */ + @Override + public void run() { + user.getReceiverThread().start(); + stage1(); + stage2(); + stage3(); + stage4(); + user.getReceiverThread().interrupt(); + } + /** + * 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. + */ private void stage1(){ - int i = user.getID(); + // for avoiding edge cases, sets commitmentsArray[id - 1] BigInteger[] commitments = super.getCommitments(); - System.arraycopy(commitments, 0, commitmentsArray[i - 1], 0, commitmentsArray[i - 1].length); + System.arraycopy(commitments, 0, commitmentsArray[id - 1], 0, commitmentsArray[id - 1].length); + // broadcasts commitments CommitmentMessage commitment; - for (int k = 1; k <= commitmentsArray[i - 1].length; k ++){ + for (int k = 0; k <= t ; k ++){ commitment = CommitmentMessage.newBuilder() .setK(k) - .setCommitment(ByteString.copyFrom(commitmentsArray[i - 1][k - 1].toByteArray())) + .setCommitment(ByteString.copyFrom(commitmentsArray[id - 1][k].toByteArray())) .build(); user.broadcast(Mail.Type.COMMITMENT,commitment); } + // computes and sends shares SecretMessage secret; for (int j = 1; j <= n ; j++ ){ - if(j != i){ - myshares[j - 1] = super.getShare(j); + if(j != id){ secret = SecretMessage.newBuilder() - .setSecret(myshares[j - 1].asMessage()) + .setSecret(getShare(j).asMessage()) .build(); user.send(j, Mail.Type.SECRET,secret); } + else{ + shares[id - 1] = super.getShare(id); + } } while (!isStage1Complete()){ try { - Thread.sleep(30); + Thread.sleep(300); } catch (InterruptedException e) { // do nothing } } } + /** + * @return true iff all shares and commitments were received + */ private boolean isStage1Complete(){ - int id = user.getID(); - for (int j = 1 ; j <= n ; j++){ - if(id != j && shares[j - 1] == null) + for (int i = 1 ; i <= n ; i++){ + if(shares[i - 1] == null) return false; } @@ -99,28 +126,36 @@ public class DKG extends VerifiableSecretSharing implements Runnable{ return true; } + /** + * @param secret + * @param i + * @return g ^ Sij == verify(j,Ai,zpstar) (mod p) + */ private boolean isValidSecret(Polynomial.Point secret, int i){ int j = secret.x.intValue(); - return zpstar.multiply(g,secret.y).equals(verify(j,commitmentsArray[i],zpstar)); + return zpstar.multiply(g,secret.y).equals(verify(j,commitmentsArray[i - 1],zpstar)); } + /** + * stage2 according to the protocol + * Pj verifies all the shares he received (using isValidSecret) + * if check fails for an index i, Pj broadcasts a complaint against Pi. + * Pj broadcasts yj value at the end of this stage + */ private void stage2(){ - int j = user.getID(); - QUAL = new HashSet(); + ys[id - 1] = super.getY(); ComplaintMessage complaint; for (int i = 1; i <= n ; i++ ){ - if(isValidSecret(shares[i - 1],j)) { - QUAL.add(i); - }else{ + if(id != i && !isValidSecret(shares[i - 1],i)) { //message = new Message(Type.Complaint, j) complaint = ComplaintMessage.newBuilder() .setId(i) .build(); user.broadcast(Mail.Type.COMPLAINT,complaint); - complainStates[j - 1][i - 1] = ComplainState.Waiting; + complainStates[i - 1][id - 1] = ComplainState.Waiting; } } - //sending y after Complaints + //broadcast y after all complaints YMessage yMessage = YMessage.newBuilder() .setY(ByteString.copyFrom(super.getY().toByteArray())) .build(); @@ -128,87 +163,99 @@ public class DKG extends VerifiableSecretSharing implements Runnable{ while (!isStage2Complete()){ try { - Thread.sleep(30); + Thread.sleep(300); } catch (InterruptedException e) { // do nothing } } } + /** + * @return true iff all yi received for i = 1,...,n . + */ private boolean isStage2Complete() { - int id = user.getID(); for (int j = 1; j <= n ; j++) { - if (id != j && ys[j - 1] == null) + if (j != id && ys[j - 1] == null) return false; } - for (int i = 0; i < complainStates.length;i++){ - for (int j =0 ; j < complainStates[i].length;j++){ - switch (complainStates[i][j]){ - case Waiting: - return false; - default: - break; - } - } - } return true; } + + /** + * stage3 according to the protocol + * 1. if more than t players complain against a player Pi he is disqualified. + * 2. Pi broadcasts the share Sij for each complaining player Pj. + * 3. if any of the revealed shares fails the verification test, player Pi is disqualified. + * 4. set QUAL to be the set of non-disqualified players. + */ private void stage3(){ - for (int i = 0; i < complainStates.length;i++){ - ComplainState state = ComplainState.Non; - for (int j = 0 ; j < complainStates[i].length;j++){ - switch (complainStates[i][j]){ - case Disqualified: - state = ComplainState.Disqualified; - break; - case NonDisqualified: - if(state == ComplainState.Non){ - state = ComplainState.NonDisqualified; - } - break; - default: - break; - } - } - switch (state){ - case Disqualified: - if(QUAL.contains(i + 1)){ - QUAL.remove(i + 1); - } - break; - case NonDisqualified: - if (!QUAL.contains(i + 1)){ - QUAL.add(i + 1); - } + + // broadcasts Sij for each complaint against Pid + for (int j = 1 ; j <= complainStates[id - 1].length;j++) { + switch (complainStates[id - 1][j - 1]) { + case Waiting: + user.broadcast(Mail.Type.SECRET, SecretMessage.newBuilder() + .setSecret(getShare(j).asMessage()) + .build()); + complainStates[id - 1][j - 1] = ComplainState.NonDisqualified; break; default: break; } } + + // wait until there is no complaint waiting for answer + for (int i = 0; i < complainStates.length;i++){ + for (int j = 0 ; j < complainStates[i].length;j++){ + while (complainStates[i][j].equals(ComplainState.Waiting)){ + try { + Thread.sleep(300); + } catch (InterruptedException e) { + // do nothing + } + } + } + } + + // add each non-disqualified player to QUAL + boolean nonDisqualified; + for (int i = 1; i <= complainStates.length;i++){ + nonDisqualified = true; + for (int j = 1 ; j <= complainStates[i - 1].length;j++){ + nonDisqualified &= complainStates[i - 1][j - 1].equals(ComplainState.Disqualified); + } + if(nonDisqualified){ + QUAL.add(i); + } + } } + /** + * stage4 according to the protocol + * 1. public value y is computed as y = multiplication of yi mod p for i in QUAL + * 2. public verification values are computed as Ak = multiplication of Aik mod p for i in QUAL for k = 0,...,t + * 3. Pj sets is share of the secret as xj = sum of Sij mod q for i in QUAL + */ private void stage4(){ - BigInteger y = zpstar.zero(); + this.y = zpstar.zero(); for (int i : QUAL) { - y = zpstar.add(y , ys[i - 1]); + this.y = zpstar.add(this.y , ys[i - 1]); } - this.commitments = new BigInteger[t]; BigInteger commitment; - for (int k = 1; k <= t ; k++){ + for (int k = 0; k <= t ; k++){ commitment = zpstar.zero(); for (int i : QUAL) { - commitment = zpstar.add(commitment,commitmentsArray[i - 1][k - 1]); + commitment = zpstar.add(commitment,commitmentsArray[i - 1][k]); } - commitments[k - 1] = commitment; + commitments[k] = commitment; } - int j = user.getID(); - BigInteger x = BigInteger.ZERO; + BigInteger xj = BigInteger.ZERO; for (int i : QUAL) { - x = x.add(shares[i - 1].y); + xj = xj.add(shares[i - 1].y); } - this.x = x.mod(q); + this.share = new Polynomial.Point(BigInteger.valueOf(id) , xj.mod(q)); } @Override @@ -221,18 +268,8 @@ public class DKG extends VerifiableSecretSharing implements Runnable{ return Arrays.clone(commitments); } - @Override - protected Polynomial.Point getShare(int i) { - return null; - } - @Override - public void run() { - stage1(); - stage2(); - stage3(); - stage4(); - } + private enum ComplainState{ Non, Waiting,Disqualified,NonDisqualified @@ -240,11 +277,7 @@ public class DKG extends VerifiableSecretSharing implements Runnable{ private class Handler implements Network.MailHandler { - final int id; - - private Handler() { - this.id = user.getID(); - } + private Handler() {} void handelSecretMessage(Mail mail) throws InvalidProtocolBufferException { if(shares[mail.getSender() - 1] == null) { @@ -255,12 +288,12 @@ public class DKG extends VerifiableSecretSharing implements Runnable{ }else{ int i = mail.getSender(); int j = secret.x.intValue(); - switch (complainStates[i][j]){ + switch (complainStates[i - 1][j - 1]){ case Waiting: if(isValidSecret(secret,i)){ - complainStates[i][j] = ComplainState.NonDisqualified; + complainStates[i - 1][j - 1] = ComplainState.NonDisqualified; }else{ - complainStates[i][j] = ComplainState.Disqualified; + complainStates[i - 1][j - 1] = ComplainState.Disqualified; } break; default: @@ -291,22 +324,17 @@ public class DKG extends VerifiableSecretSharing implements Runnable{ } void handelComplaintMessage(Mail mail) throws InvalidProtocolBufferException { + int id = user.getID(); if(!mail.getIsPrivate()) { //broadcast only ComplaintMessage complaintMessage = ComplaintMessage.parseFrom(mail.getMessage()); int i = complaintMessage.getId(); int j = mail.getSender(); - if(i == id){ - user.broadcast(Mail.Type.SECRET,SecretMessage.newBuilder() - .setSecret(myshares[j].asMessage()) - .build()); - }else{ - switch (complainStates[i - 1][j - 1]){ - case Non: - complainStates[i - 1][j - 1] = ComplainState.Waiting; - break; - default: - break; - } + switch (complainStates[i - 1][j - 1]){ + case Non: + complainStates[i - 1][j - 1] = ComplainState.Waiting; + break; + default: + break; } } } diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java index 3cc3c85..70ab678 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java @@ -7,6 +7,9 @@ import java.util.Queue; import java.util.concurrent.ArrayBlockingQueue; /** * Created by Tzlil on 2/7/2016. + * JointFeldamn protocol assumes all parties can communicate throw broadcast chanel + * and private chanel (for each pair) + * this class simulates it */ public class Network { @@ -28,7 +31,8 @@ public class Network { Integer id = availableIDs.poll(); if (id == null) return null; - return new User(id,messageHandler); + users[id - 1] = new User(id,messageHandler); + return users[id - 1]; } private boolean sendMessage(User sender,int destination,Mail.Type type,Message message){ @@ -70,13 +74,12 @@ public class Network { private final MailHandler messageHandler; private final Queue mailbox; private final int ID; - + private final Thread receiverThread; public User(int ID, MailHandler messageHandler) { - this.mailbox = new ArrayBlockingQueue(n*n); + this.mailbox = new ArrayBlockingQueue(1 << n); this.ID = ID; this.messageHandler = messageHandler; - Thread thread = new Thread(new Receiver()); - thread.run(); + this.receiverThread = new Thread(new Receiver()); } public boolean send(int id, Mail.Type type,Message message){ @@ -88,7 +91,9 @@ public class Network { public int getID() { return ID; } - + public Thread getReceiverThread(){ + return receiverThread; + } private class Receiver implements Runnable{ @Override public void run() { diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/InterpolationTest.java b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/InterpolationTest.java index 71c93fa..53a50af 100644 --- a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/InterpolationTest.java +++ b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/InterpolationTest.java @@ -33,7 +33,6 @@ public class InterpolationTest { public Polynomial.Point[] randomPoints(Polynomial p){ Polynomial.Point[] points = new Polynomial.Point[p.getDegree() + 1]; BigInteger x; - Boolean b; Set set = new HashSet(); for (int i = 0; i < points.length; i++){ x = new BigInteger(bits,random); diff --git a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java new file mode 100644 index 0000000..98e58ed --- /dev/null +++ b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java @@ -0,0 +1,57 @@ +package JointFeldmanProtocol; + +import org.factcenter.qilin.primitives.concrete.Zpstar; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 2/9/2016. + */ +public class DKGTest { + + + DKG[] dkgs; + Thread[] threads; + int tests = 1 << 10; + Random random; + + @Before + public void settings(){ + BigInteger p = BigInteger.valueOf(2903); + BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); + Zpstar zpstar = new Zpstar(p); + random = new Random(); + BigInteger g; + BigInteger ZERO = zpstar.zero(); + do{ + g = zpstar.sample(random); + }while (!g.equals(ZERO) && !zpstar.multiply(g,q).equals(ZERO));// sample from QRZp* + int t = 8; + int n = 20 + ; + Network network = new Network(n); + dkgs = new DKG[n]; + threads = new Thread[n]; + for (int i = 0 ; i < n ; i++) { + dkgs[i] = new DKG(t, n, new BigInteger(q.bitLength(), random).mod(q), random, p, q, g, network); + threads[i] = new Thread(dkgs[i]); + } + } + + @Test + public void DKGTest() throws Exception { + for (int i = 0 ; i < threads.length ; i++){ + threads[i].start(); + } + for (int i = 0 ; i < threads.length ; i++){ + threads[i].join(); + } + + for (int i = 0; i < dkgs.length - 1 ; i++){ + assert (dkgs[i].getY().equals(dkgs[i+1].getY())); + } + } +} From 9a78330e29fb7d432c22e57683a0fce458c37ccf Mon Sep 17 00:00:00 2001 From: Arbel Deutsch Peled Date: Tue, 16 Feb 2016 22:33:52 +0200 Subject: [PATCH 19/49] Working Integration test for Threaded BB Client supporting Batches. Haven't tested subscriptions yet. --- .../bulletinboard/MultiServerWorker.java | 20 +- .../SingleServerBulletinBoardClient.java | 318 ++++++++-- .../ThreadedBulletinBoardClient.java | 36 +- .../MultiServerBeginBatchWorker.java | 6 +- .../MultiServerCloseBatchWorker.java | 6 +- .../MultiServerGenericPostWorker.java | 16 +- .../MultiServerGenericReadWorker.java | 14 +- .../MultiServerGetRedundancyWorker.java | 12 +- .../MultiServerPostBatchDataWorker.java | 6 +- .../MultiServerPostBatchWorker.java | 6 +- .../MultiServerPostMessageWorker.java | 6 +- .../MultiServerReadBatchWorker.java | 6 +- .../MultiServerReadMessagesWorker.java | 6 +- .../SingleServerReadBatchWorker.java | 57 +- .../BulletinBoardClientIntegrationTest.java | 214 ------- ...dedBulletinBoardClientIntegrationTest.java | 541 ++++++++++++++++++ bulletin-board-server/build.gradle | 7 +- .../sqlserver/BulletinBoardSQLServer.java | 30 +- .../sqlserver/H2QueryProvider.java | 3 + .../sqlserver/MySQLQueryProvider.java | 3 + .../sqlserver/SQLiteQueryProvider.java | 3 + .../webapp/BulletinBoardWebApp.java | 6 +- .../AsyncBulletinBoardClient.java | 28 +- .../bulletinboard/BulletinBoardServer.java | 2 +- .../meerkat/bulletinboard/CompleteBatch.java | 50 ++ .../java/meerkat/util/BulletinBoardUtils.java | 65 +++ .../main/proto/meerkat/BulletinBoardAPI.proto | 12 +- 27 files changed, 1076 insertions(+), 403 deletions(-) delete mode 100644 bulletin-board-client/src/test/java/BulletinBoardClientIntegrationTest.java create mode 100644 bulletin-board-client/src/test/java/ThreadedBulletinBoardClientIntegrationTest.java create mode 100644 meerkat-common/src/main/java/meerkat/util/BulletinBoardUtils.java diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/MultiServerWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/MultiServerWorker.java index 8db836f..727a922 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/MultiServerWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/MultiServerWorker.java @@ -2,7 +2,7 @@ package meerkat.bulletinboard; import com.google.common.util.concurrent.FutureCallback; -import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; +import com.google.common.util.concurrent.FutureCallback; import java.util.Collections; import java.util.Iterator; @@ -16,7 +16,7 @@ import java.util.concurrent.atomic.AtomicInteger; * This is a general class for handling multi-server work * It utilizes Single Server Clients to perform the actual per-server work */ -public abstract class MultiServerWorker extends BulletinClientWorker implements Runnable, ClientCallback{ +public abstract class MultiServerWorker extends BulletinClientWorker implements Runnable, FutureCallback{ private List clients; @@ -26,7 +26,7 @@ public abstract class MultiServerWorker extends BulletinClientWorker clientCallback; + private FutureCallback futureCallback; /** * Constructor @@ -35,11 +35,11 @@ public abstract class MultiServerWorker extends BulletinClientWorker clients, boolean shuffleClients, int minServers, IN payload, int maxRetry, - ClientCallback clientCallback) { + FutureCallback futureCallback) { super(payload,maxRetry); @@ -50,7 +50,7 @@ public abstract class MultiServerWorker extends BulletinClientWorker extends BulletinClientWorker clients, int minServers, IN payload, int maxRetry, - ClientCallback clientCallback) { + FutureCallback futureCallback) { - this(clients, false, minServers, payload, maxRetry, clientCallback); + this(clients, false, minServers, payload, maxRetry, futureCallback); } @@ -74,7 +74,7 @@ public abstract class MultiServerWorker extends BulletinClientWorker extends BulletinClientWorker implements FutureCallback { private SingleServerWorker worker; - private ClientCallback clientCallback; + private FutureCallback futureCallback; - public RetryCallback(SingleServerWorker worker, ClientCallback clientCallback) { + public RetryCallback(SingleServerWorker worker, FutureCallback futureCallback) { this.worker = worker; - this.clientCallback = clientCallback; + this.futureCallback = futureCallback; } @Override public void onSuccess(T result) { - clientCallback.handleCallback(result); + futureCallback.onSuccess(result); } @Override @@ -107,19 +114,210 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i scheduleWorker(worker, this); } else { // No more retries: notify caller about failure - clientCallback.handleFailure(t); + futureCallback.onFailure(t); } } } + /** + * This callback ties together all the per-batch-data callbacks into a single callback + * It reports success back to the user only if all of the batch-data were successfully posted + * If any batch-data fails to post: this callback reports failure + */ + class PostBatchDataListCallback implements FutureCallback { - public SingleServerBulletinBoardClient(int threadPoolSize, long failDelayInMilliseconds) { + private FutureCallback callback; + private AtomicInteger batchDataRemaining; + private AtomicBoolean aggregatedResult; + + public PostBatchDataListCallback(int batchDataLength, FutureCallback callback) { + + this.callback = callback; + this.batchDataRemaining = new AtomicInteger(batchDataLength); + this.aggregatedResult = new AtomicBoolean(false); + + } + + @Override + public void onSuccess(Boolean result) { + + if (result){ + this.aggregatedResult.set(true); + } + + if (batchDataRemaining.decrementAndGet() == 0){ + callback.onSuccess(this.aggregatedResult.get()); + } + } + + @Override + public void onFailure(Throwable t) { + + // Notify caller about failure + callback.onFailure(t); + + } + } + + /** + * This callback ties together the different parts of a CompleteBatch as they arrive from the server + * It assembles a CompleteBatch from the parts and sends it to the user if all parts arrived + * If any part fails to arrive: it invokes the onFailure method + */ + class CompleteBatchReadCallback { + + private FutureCallback callback; + + private List batchDataList; + private BulletinBoardMessage batchMessage; + + private AtomicInteger remainingQueries; + private AtomicBoolean failed; + + public CompleteBatchReadCallback(FutureCallback callback) { + + this.callback = callback; + + remainingQueries = new AtomicInteger(2); + failed = new AtomicBoolean(false); + + } + + protected void combineAndReturn() { + + final String[] prefixes = { + BulletinBoardConstants.BATCH_ID_TAG_PREFIX, + BulletinBoardConstants.BATCH_TAG}; + + if (remainingQueries.decrementAndGet() == 0){ + + BeginBatchMessage beginBatchMessage = + BeginBatchMessage.newBuilder() + .setSignerId(batchMessage.getSig(0).getSignerId()) + .setBatchId(Integer.parseInt( + BulletinBoardUtils.findTagWithPrefix(batchMessage, BulletinBoardConstants.BATCH_ID_TAG_PREFIX))) + .addAllTag(BulletinBoardUtils.removePrefixTags(batchMessage, Arrays.asList(prefixes))) + .build(); + callback.onSuccess(new CompleteBatch(beginBatchMessage, batchDataList, batchMessage.getSig(0))); + } + + } + + protected void fail(Throwable t) { + if (failed.compareAndSet(false, true)) { + callback.onFailure(t); + } + } + + /** + * @return a FutureCallback for the Batch Data List that ties to this object + */ + public FutureCallback> asBatchDataListFutureCallback() { + return new FutureCallback>() { + + @Override + public void onSuccess(List result) { + batchDataList = result; + + combineAndReturn(); + } + + @Override + public void onFailure(Throwable t) { + fail(t); + } + + }; + } + + /** + * @return a FutureCallback for the Bulletin Board Message that ties to this object + */ + public FutureCallback> asBulletinBoardMessageListFutureCallback() { + return new FutureCallback>() { + + @Override + public void onSuccess(List result) { + if (result.size() < 1){ + onFailure(new IllegalArgumentException("Server returned empty message list")); + return; + } + + batchMessage = result.get(0); + + combineAndReturn(); + } + + @Override + public void onFailure(Throwable t) { + fail(t); + } + }; + } + + } + + + /** + * Inner class for handling returned values of subscription operations + * This class's methods also ensure continued operation of the subscription + */ + class SubscriptionCallback implements FutureCallback> { + + private SingleServerReadMessagesWorker worker; + private MessageHandler messageHandler; + + private MessageFilterList.Builder filterBuilder; + + public SubscriptionCallback(SingleServerReadMessagesWorker worker, MessageHandler messageHandler) { + this.worker = worker; + this.messageHandler = messageHandler; + filterBuilder = worker.getPayload().toBuilder(); + + } + + @Override + public void onSuccess(List result) { + + // Report new messages to user + messageHandler.handleNewMessages(result); + + // Remove last filter from list (MIN_ENTRY one) + filterBuilder.removeFilter(filterBuilder.getFilterCount() - 1); + + // Add updated MIN_ENTRY filter (entry number is successor of last received entry's number) + filterBuilder.addFilter(MessageFilter.newBuilder() + .setType(FilterType.MIN_ENTRY) + .setEntry(result.get(result.size() - 1).getEntryNum() + 1) + .build()); + + // Create new worker with updated task + worker = new SingleServerReadMessagesWorker(worker.serverAddress, filterBuilder.build(), 1); + + // Schedule the worker + scheduleWorker(worker, this); + + } + + @Override + public void onFailure(Throwable t) { + + // Notify client about failure + fail(); + + // Reschedule exact same task + scheduleWorker(worker, this); + } + } + + public SingleServerBulletinBoardClient(int threadPoolSize, long failDelayInMilliseconds, long subscriptionIntervalInMilliseconds) { executorService = MoreExecutors.listeningDecorator(Executors.newScheduledThreadPool(threadPoolSize)); this.failDelayInMilliseconds = failDelayInMilliseconds; + this.subscriptionIntervalInMilliseconds = subscriptionIntervalInMilliseconds; // Set server error time to a time sufficiently in the past to make new jobs go through lastServerErrorTime = System.currentTimeMillis() - failDelayInMilliseconds; @@ -147,7 +345,7 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i } @Override - public MessageID postMessage(BulletinBoardMessage msg, ClientCallback callback) { + public MessageID postMessage(BulletinBoardMessage msg, FutureCallback callback) { // Create worker with redundancy 1 and MAX_RETRIES retries SingleServerPostMessageWorker worker = new SingleServerPostMessageWorker(meerkatDBs.get(0), msg, MAX_RETRIES); @@ -162,18 +360,18 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i } - private class PostBatchDataCallback implements ClientCallback { + private class PostBatchDataCallback implements FutureCallback { private CompleteBatch completeBatch; - ClientCallback callback; + FutureCallback callback; - public PostBatchDataCallback(CompleteBatch completeBatch, ClientCallback callback) { + public PostBatchDataCallback(CompleteBatch completeBatch, FutureCallback callback) { this.completeBatch = completeBatch; this.callback = callback; } @Override - public void handleCallback(Boolean msg) { + public void onSuccess(Boolean msg) { closeBatch( CloseBatchMessage.newBuilder() .setBatchId(completeBatch.getBeginBatchMessage().getBatchId()) @@ -185,24 +383,24 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i } @Override - public void handleFailure(Throwable t) { - callback.handleFailure(t); + public void onFailure(Throwable t) { + callback.onFailure(t); } } - private class BeginBatchCallback implements ClientCallback { + private class BeginBatchCallback implements FutureCallback { private CompleteBatch completeBatch; - ClientCallback callback; + FutureCallback callback; - public BeginBatchCallback(CompleteBatch completeBatch, ClientCallback callback) { + public BeginBatchCallback(CompleteBatch completeBatch, FutureCallback callback) { this.completeBatch = completeBatch; this.callback = callback; } @Override - public void handleCallback(Boolean msg) { + public void onSuccess(Boolean msg) { postBatchData( completeBatch.getBeginBatchMessage().getSignerId(), @@ -213,13 +411,13 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i } @Override - public void handleFailure(Throwable t) { - callback.handleFailure(t); + public void onFailure(Throwable t) { + callback.onFailure(t); } } @Override - public MessageID postBatch(CompleteBatch completeBatch, ClientCallback callback) { + public MessageID postBatch(CompleteBatch completeBatch, FutureCallback callback) { beginBatch( completeBatch.getBeginBatchMessage(), @@ -233,7 +431,7 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i } @Override - public void beginBatch(BeginBatchMessage beginBatchMessage, ClientCallback callback) { + public void beginBatch(BeginBatchMessage beginBatchMessage, FutureCallback callback) { // Create worker with redundancy 1 and MAX_RETRIES retries SingleServerBeginBatchWorker worker = @@ -246,12 +444,16 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i @Override public void postBatchData(ByteString signerId, int batchId, List batchDataList, - int startPosition, ClientCallback callback) { + int startPosition, FutureCallback callback) { BatchMessage.Builder builder = BatchMessage.newBuilder() .setSignerId(signerId) .setBatchId(batchId); + // Create a unified callback to aggregate successful posts + + PostBatchDataListCallback listCallback = new PostBatchDataListCallback(batchDataList.size(), callback); + // Iterate through data list for (BatchData data : batchDataList) { @@ -262,7 +464,7 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i new SingleServerPostBatchWorker(meerkatDBs.get(0), builder.build(), MAX_RETRIES); // Create worker with redundancy 1 and MAX_RETRIES retries - scheduleWorker(worker, new RetryCallback(worker, callback)); + scheduleWorker(worker, new RetryCallback(worker, listCallback)); // Increment position in batch startPosition++; @@ -271,7 +473,7 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i } @Override - public void postBatchData(ByteString signerId, int batchId, List batchDataList, ClientCallback callback) { + public void postBatchData(ByteString signerId, int batchId, List batchDataList, FutureCallback callback) { postBatchData(signerId, batchId, batchDataList, 0, callback); @@ -279,21 +481,21 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i @Override public void postBatchData(byte[] signerId, int batchId, List batchDataList, - int startPosition, ClientCallback callback) { + int startPosition, FutureCallback callback) { postBatchData(ByteString.copyFrom(signerId), batchId, batchDataList, startPosition, callback); } @Override - public void postBatchData(byte[] signerId, int batchId, List batchDataList, ClientCallback callback) { + public void postBatchData(byte[] signerId, int batchId, List batchDataList, FutureCallback callback) { postBatchData(signerId, batchId, batchDataList, 0, callback); } @Override - public void closeBatch(CloseBatchMessage closeBatchMessage, ClientCallback callback) { + public void closeBatch(CloseBatchMessage closeBatchMessage, FutureCallback callback) { // Create worker with redundancy 1 and MAX_RETRIES retries SingleServerCloseBatchWorker worker = @@ -305,7 +507,7 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i } @Override - public void getRedundancy(MessageID id, ClientCallback callback) { + public void getRedundancy(MessageID id, FutureCallback callback) { // Create worker with no retries SingleServerGetRedundancyWorker worker = new SingleServerGetRedundancyWorker(meerkatDBs.get(0), id, 1); @@ -316,7 +518,7 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i } @Override - public void readMessages(MessageFilterList filterList, ClientCallback> callback) { + public void readMessages(MessageFilterList filterList, FutureCallback> callback) { // Create job with no retries SingleServerReadMessagesWorker worker = new SingleServerReadMessagesWorker(meerkatDBs.get(0), filterList, 1); @@ -327,19 +529,65 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i } @Override - public void readBatch(BatchSpecificationMessage batchSpecificationMessage, ClientCallback callback) { + public void readBatch(BatchSpecificationMessage batchSpecificationMessage, FutureCallback callback) { - // Create job with no retries - SingleServerReadBatchWorker worker = new SingleServerReadBatchWorker(meerkatDBs.get(0), batchSpecificationMessage, 1); + // Create job with no retries for retrieval of the Bulletin Board Message that defines the batch - // Submit job and create callback - scheduleWorker(worker, new RetryCallback(worker, callback)); + MessageFilterList filterList = MessageFilterList.newBuilder() + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.TAG) + .setTag(BulletinBoardConstants.BATCH_TAG) + .build()) + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.TAG) + .setTag(BulletinBoardConstants.BATCH_ID_TAG_PREFIX + batchSpecificationMessage.getBatchId()) + .build()) + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.SIGNER_ID) + .setId(batchSpecificationMessage.getSignerId()) + .build()) + .build(); + + SingleServerReadMessagesWorker messageWorker = new SingleServerReadMessagesWorker(meerkatDBs.get(0), filterList, 1); + + // Create job with no retries for retrieval of the Batch Data List + SingleServerReadBatchWorker batchWorker = new SingleServerReadBatchWorker(meerkatDBs.get(0), batchSpecificationMessage, 1); + + // Create callback that will combine the two worker products + CompleteBatchReadCallback completeBatchReadCallback = new CompleteBatchReadCallback(callback); + + // Submit jobs with wrapped callbacks + scheduleWorker(messageWorker, new RetryCallback(messageWorker, completeBatchReadCallback.asBulletinBoardMessageListFutureCallback())); + scheduleWorker(batchWorker, new RetryCallback(batchWorker, completeBatchReadCallback.asBatchDataListFutureCallback())); } @Override public void subscribe(MessageFilterList filterList, MessageHandler messageHandler) { + // Remove all existing MIN_ENTRY filters and create new one that starts at 0 + + MessageFilterList.Builder filterListBuilder = filterList.toBuilder(); + + Iterator iterator = filterListBuilder.getFilterList().iterator(); + while (iterator.hasNext()) { + MessageFilter filter = iterator.next(); + + if (filter.getType() == FilterType.MIN_ENTRY){ + iterator.remove(); + } + } + filterListBuilder.addFilter(MessageFilter.newBuilder() + .setType(FilterType.MIN_ENTRY) + .setEntry(0) + .build()); + + // Create job with no retries + SingleServerReadMessagesWorker worker = new SingleServerReadMessagesWorker(meerkatDBs.get(0), filterListBuilder.build(), 1); + + // Submit job and create callback + scheduleWorker(worker, new SubscriptionCallback(worker, messageHandler)); + } @Override diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java index 78d5dba..76e6236 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java @@ -1,5 +1,6 @@ package meerkat.bulletinboard; +import com.google.common.util.concurrent.FutureCallback; import com.google.protobuf.ByteString; import meerkat.bulletinboard.workers.multiserver.*; @@ -37,6 +38,7 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple private static final int SERVER_THREADPOOL_SIZE = 5; private static final long FAIL_DELAY = 5000; + private static final long SUBSCRIPTION_INTERVAL = 10000; private int minAbsoluteRedundancy; @@ -59,11 +61,16 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple clients = new ArrayList(clientParams.getBulletinBoardAddressCount()); for (String address : clientParams.getBulletinBoardAddressList()){ - SingleServerBulletinBoardClient client = new SingleServerBulletinBoardClient(SERVER_THREADPOOL_SIZE, FAIL_DELAY); + + SingleServerBulletinBoardClient client = + new SingleServerBulletinBoardClient(SERVER_THREADPOOL_SIZE, FAIL_DELAY, SUBSCRIPTION_INTERVAL); + client.init(BulletinBoardClientParams.newBuilder() .addBulletinBoardAddress(address) .build()); + clients.add(client); + } } @@ -76,7 +83,7 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple * @throws CommunicationException */ @Override - public MessageID postMessage(BulletinBoardMessage msg, ClientCallback callback){ + public MessageID postMessage(BulletinBoardMessage msg, FutureCallback callback){ // Create job MultiServerPostMessageWorker worker = @@ -93,7 +100,7 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple } @Override - public MessageID postBatch(CompleteBatch completeBatch, ClientCallback callback) { + public MessageID postBatch(CompleteBatch completeBatch, FutureCallback callback) { // Create job MultiServerPostBatchWorker worker = @@ -110,7 +117,7 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple } @Override - public void beginBatch(BeginBatchMessage beginBatchMessage, ClientCallback callback) { + public void beginBatch(BeginBatchMessage beginBatchMessage, FutureCallback callback) { // Create job MultiServerBeginBatchWorker worker = @@ -123,7 +130,7 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple @Override public void postBatchData(byte[] signerId, int batchId, List batchDataList, - int startPosition, ClientCallback callback) { + int startPosition, FutureCallback callback) { BatchDataContainer batchDataContainer = new BatchDataContainer(signerId, batchId, batchDataList, startPosition); @@ -137,7 +144,7 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple } @Override - public void postBatchData(byte[] signerId, int batchId, List batchDataList, ClientCallback callback) { + public void postBatchData(byte[] signerId, int batchId, List batchDataList, FutureCallback callback) { postBatchData(signerId, batchId, batchDataList, 0, callback); @@ -145,21 +152,21 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple @Override public void postBatchData(ByteString signerId, int batchId, List batchDataList, - int startPosition, ClientCallback callback) { + int startPosition, FutureCallback callback) { postBatchData(signerId.toByteArray(), batchId, batchDataList, startPosition, callback); } @Override - public void postBatchData(ByteString signerId, int batchId, List batchDataList, ClientCallback callback) { + public void postBatchData(ByteString signerId, int batchId, List batchDataList, FutureCallback callback) { postBatchData(signerId, batchId, batchDataList, 0, callback); } @Override - public void closeBatch(CloseBatchMessage closeBatchMessage, ClientCallback callback) { + public void closeBatch(CloseBatchMessage closeBatchMessage, FutureCallback callback) { // Create job MultiServerCloseBatchWorker worker = @@ -177,7 +184,7 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple * Ignore communication exceptions in specific databases */ @Override - public void getRedundancy(MessageID id, ClientCallback callback) { + public void getRedundancy(MessageID id, FutureCallback callback) { // Create job MultiServerGetRedundancyWorker worker = @@ -194,7 +201,7 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple * If no operation is successful: return null (NOT blank list) */ @Override - public void readMessages(MessageFilterList filterList, ClientCallback> callback) { + public void readMessages(MessageFilterList filterList, FutureCallback> callback) { // Create job MultiServerReadMessagesWorker worker = @@ -206,7 +213,7 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple } @Override - public void readBatch(BatchSpecificationMessage batchSpecificationMessage, ClientCallback callback) { + public void readBatch(BatchSpecificationMessage batchSpecificationMessage, FutureCallback callback) { // Create job MultiServerReadBatchWorker worker = @@ -227,6 +234,11 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple super.close(); try { + + for (SingleServerBulletinBoardClient client : clients){ + client.close(); + } + executorService.shutdown(); while (! executorService.isShutdown()) { executorService.awaitTermination(10, TimeUnit.SECONDS); diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerBeginBatchWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerBeginBatchWorker.java index dc496d7..e0e92bb 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerBeginBatchWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerBeginBatchWorker.java @@ -1,6 +1,6 @@ package meerkat.bulletinboard.workers.multiserver; -import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; +import com.google.common.util.concurrent.FutureCallback; import meerkat.bulletinboard.SingleServerBulletinBoardClient; import meerkat.protobuf.BulletinBoardAPI.BeginBatchMessage; @@ -13,9 +13,9 @@ public class MultiServerBeginBatchWorker extends MultiServerGenericPostWorker clients, int minServers, BeginBatchMessage payload, int maxRetry, - ClientCallback clientCallback) { + FutureCallback futureCallback) { - super(clients, minServers, payload, maxRetry, clientCallback); + super(clients, minServers, payload, maxRetry, futureCallback); } diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerCloseBatchWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerCloseBatchWorker.java index 56b09c5..300440f 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerCloseBatchWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerCloseBatchWorker.java @@ -1,6 +1,6 @@ package meerkat.bulletinboard.workers.multiserver; -import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; +import com.google.common.util.concurrent.FutureCallback; import meerkat.bulletinboard.SingleServerBulletinBoardClient; import meerkat.protobuf.BulletinBoardAPI.CloseBatchMessage; @@ -13,9 +13,9 @@ public class MultiServerCloseBatchWorker extends MultiServerGenericPostWorker clients, int minServers, CloseBatchMessage payload, int maxRetry, - ClientCallback clientCallback) { + FutureCallback futureCallback) { - super(clients, minServers, payload, maxRetry, clientCallback); + super(clients, minServers, payload, maxRetry, futureCallback); } diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGenericPostWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGenericPostWorker.java index 8b62d4e..4ff96b1 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGenericPostWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGenericPostWorker.java @@ -1,6 +1,7 @@ package meerkat.bulletinboard.workers.multiserver; -import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.FutureCallback; import meerkat.bulletinboard.MultiServerWorker; import meerkat.bulletinboard.SingleServerBulletinBoardClient; import meerkat.comm.CommunicationException; @@ -17,9 +18,9 @@ public abstract class MultiServerGenericPostWorker extends MultiServerWorker< public MultiServerGenericPostWorker(List clients, int minServers, T payload, int maxRetry, - ClientCallback clientCallback) { + FutureCallback futureCallback) { - super(clients, minServers, payload, maxRetry, clientCallback); + super(clients, minServers, payload, maxRetry, futureCallback); } @@ -35,11 +36,6 @@ public abstract class MultiServerGenericPostWorker extends MultiServerWorker< */ public void run() { - WebTarget webTarget; - Response response; - - int count = 0; // Used to count number of servers which contain the required message in a GET_REDUNDANCY request. - // Iterate through servers Iterator clientIterator = getClientIterator(); @@ -56,7 +52,7 @@ public abstract class MultiServerGenericPostWorker extends MultiServerWorker< } @Override - public void handleCallback(Boolean result) { + public void onSuccess(Boolean result) { if (result){ if (minServers.decrementAndGet() <= 0){ succeed(Boolean.TRUE); @@ -65,7 +61,7 @@ public abstract class MultiServerGenericPostWorker extends MultiServerWorker< } @Override - public void handleFailure(Throwable t) { + public void onFailure(Throwable t) { if (maxFailedServers.decrementAndGet() < 0){ fail(t); } diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGenericReadWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGenericReadWorker.java index 6f6b425..68fc020 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGenericReadWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGenericReadWorker.java @@ -1,6 +1,6 @@ package meerkat.bulletinboard.workers.multiserver; -import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; +import com.google.common.util.concurrent.FutureCallback; import meerkat.bulletinboard.MultiServerWorker; import meerkat.bulletinboard.SingleServerBulletinBoardClient; import meerkat.comm.CommunicationException; @@ -18,9 +18,9 @@ public abstract class MultiServerGenericReadWorker extends MultiServerW public MultiServerGenericReadWorker(List clients, int minServers, IN payload, int maxRetry, - ClientCallback clientCallback) { + FutureCallback futureCallback) { - super(clients, true, minServers, payload, maxRetry, clientCallback); // Shuffle clients on creation to balance load + super(clients, true, minServers, payload, maxRetry, futureCallback); // Shuffle clients on creation to balance load clientIterator = getClientIterator(); @@ -41,10 +41,10 @@ public abstract class MultiServerGenericReadWorker extends MultiServerW if (clientIterator.hasNext()) { - // Send request to Server + // Get next server SingleServerBulletinBoardClient client = clientIterator.next(); - // Retrieve answer + // Retrieve answer from server doRead(payload, client); } else { @@ -54,12 +54,12 @@ public abstract class MultiServerGenericReadWorker extends MultiServerW } @Override - public void handleCallback(OUT msg) { + public void onSuccess(OUT msg) { succeed(msg); } @Override - public void handleFailure(Throwable t) { + public void onFailure(Throwable t) { run(); // Retry with next server } diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGetRedundancyWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGetRedundancyWorker.java index 5675cb8..517dbdf 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGetRedundancyWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGetRedundancyWorker.java @@ -1,6 +1,6 @@ package meerkat.bulletinboard.workers.multiserver; -import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; +import com.google.common.util.concurrent.FutureCallback; import meerkat.bulletinboard.MultiServerWorker; import meerkat.bulletinboard.SingleServerBulletinBoardClient; import meerkat.comm.CommunicationException; @@ -20,9 +20,9 @@ public class MultiServerGetRedundancyWorker extends MultiServerWorker clients, int minServers, MessageID payload, int maxRetry, - ClientCallback clientCallback) { + FutureCallback futureCallback) { - super(clients, minServers, payload, maxRetry, clientCallback); // Shuffle clients on creation to balance load + super(clients, minServers, payload, maxRetry, futureCallback); // Shuffle clients on creation to balance load serversContainingMessage = new AtomicInteger(0); totalContactedServers = new AtomicInteger(0); @@ -54,7 +54,7 @@ public class MultiServerGetRedundancyWorker extends MultiServerWorker 0.5) { serversContainingMessage.incrementAndGet(); @@ -67,8 +67,8 @@ public class MultiServerGetRedundancyWorker extends MultiServerWorker clients, int minServers, BatchDataContainer payload, int maxRetry, - ClientCallback clientCallback) { + FutureCallback futureCallback) { - super(clients, minServers, payload, maxRetry, clientCallback); + super(clients, minServers, payload, maxRetry, futureCallback); } diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerPostBatchWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerPostBatchWorker.java index 7c2f586..1b1f3df 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerPostBatchWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerPostBatchWorker.java @@ -1,6 +1,6 @@ package meerkat.bulletinboard.workers.multiserver; -import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; +import com.google.common.util.concurrent.FutureCallback; import meerkat.bulletinboard.CompleteBatch; import meerkat.bulletinboard.SingleServerBulletinBoardClient; @@ -13,9 +13,9 @@ public class MultiServerPostBatchWorker extends MultiServerGenericPostWorker clients, int minServers, CompleteBatch payload, int maxRetry, - ClientCallback clientCallback) { + FutureCallback futureCallback) { - super(clients, minServers, payload, maxRetry, clientCallback); + super(clients, minServers, payload, maxRetry, futureCallback); } diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerPostMessageWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerPostMessageWorker.java index 33f9a3c..6d3d702 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerPostMessageWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerPostMessageWorker.java @@ -1,6 +1,6 @@ package meerkat.bulletinboard.workers.multiserver; -import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; +import com.google.common.util.concurrent.FutureCallback; import meerkat.bulletinboard.SingleServerBulletinBoardClient; import meerkat.protobuf.BulletinBoardAPI.*; @@ -13,9 +13,9 @@ public class MultiServerPostMessageWorker extends MultiServerGenericPostWorker clients, int minServers, BulletinBoardMessage payload, int maxRetry, - ClientCallback clientCallback) { + FutureCallback futureCallback) { - super(clients, minServers, payload, maxRetry, clientCallback); + super(clients, minServers, payload, maxRetry, futureCallback); } diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerReadBatchWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerReadBatchWorker.java index 737c15c..3d40c8a 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerReadBatchWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerReadBatchWorker.java @@ -1,6 +1,6 @@ package meerkat.bulletinboard.workers.multiserver; -import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; +import com.google.common.util.concurrent.FutureCallback; import meerkat.bulletinboard.CompleteBatch; import meerkat.bulletinboard.SingleServerBulletinBoardClient; import meerkat.protobuf.BulletinBoardAPI.BatchSpecificationMessage; @@ -15,9 +15,9 @@ public class MultiServerReadBatchWorker extends MultiServerGenericReadWorker clients, int minServers, BatchSpecificationMessage payload, int maxRetry, - ClientCallback clientCallback) { + FutureCallback futureCallback) { - super(clients, minServers, payload, maxRetry, clientCallback); + super(clients, minServers, payload, maxRetry, futureCallback); } diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerReadMessagesWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerReadMessagesWorker.java index b276eab..980d869 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerReadMessagesWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerReadMessagesWorker.java @@ -1,6 +1,6 @@ package meerkat.bulletinboard.workers.multiserver; -import meerkat.bulletinboard.AsyncBulletinBoardClient.ClientCallback; +import com.google.common.util.concurrent.FutureCallback; import meerkat.bulletinboard.SingleServerBulletinBoardClient; import meerkat.protobuf.BulletinBoardAPI.*; @@ -14,9 +14,9 @@ public class MultiServerReadMessagesWorker extends MultiServerGenericReadWorker< public MultiServerReadMessagesWorker(List clients, int minServers, MessageFilterList payload, int maxRetry, - ClientCallback> clientCallback) { + FutureCallback> futureCallback) { - super(clients, minServers, payload, maxRetry, clientCallback); + super(clients, minServers, payload, maxRetry, futureCallback); } diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerReadBatchWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerReadBatchWorker.java index 61556fc..11fc777 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerReadBatchWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerReadBatchWorker.java @@ -23,7 +23,7 @@ import static meerkat.bulletinboard.BulletinBoardConstants.BATCH_ID_TAG_PREFIX; /** * Created by Arbel Deutsch Peled on 27-Dec-15. */ -public class SingleServerReadBatchWorker extends SingleServerWorker { +public class SingleServerReadBatchWorker extends SingleServerWorker> { public SingleServerReadBatchWorker(String serverAddress, BatchSpecificationMessage payload, int maxRetry) { super(serverAddress, payload, maxRetry); @@ -35,59 +35,13 @@ public class SingleServerReadBatchWorker extends SingleServerWorker call() throws CommunicationException{ Client client = clientLocal.get(); WebTarget webTarget; Response response; - // Set filters for the batch message metadata retrieval - - MessageFilterList messageFilterList = MessageFilterList.newBuilder() - .addFilter(MessageFilter.newBuilder() - .setType(FilterType.TAG) - .setTag(BATCH_ID_TAG_PREFIX + String.valueOf(payload.getBatchId())) - .build()) - .addFilter(MessageFilter.newBuilder() - .setType(FilterType.SIGNER_ID) - .setId(payload.getSignerId()) - .build()) - .build(); - - // Send request to Server - - webTarget = client.target(serverAddress).path(BULLETIN_BOARD_SERVER_PATH).path(READ_MESSAGES_PATH); - response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post( - Entity.entity(messageFilterList, Constants.MEDIATYPE_PROTOBUF)); - - // Retrieve answer - - try { - - // If a BulletinBoardMessageList is returned: the read was successful - BulletinBoardMessage metadata = response.readEntity(BulletinBoardMessageList.class).getMessage(0); - - completeBatch.setBeginBatchMessage(BeginBatchMessage.newBuilder() - .setSignerId(payload.getSignerId()) - .setBatchId(payload.getBatchId()) - .addAllTag(metadata.getMsg().getTagList()) - .build()); - - completeBatch.setSignature(metadata.getSig(0)); - - } catch (ProcessingException | IllegalStateException e) { - - // Read failed - throw new CommunicationException("Could not contact the server"); - - } - finally { - response.close(); - } - // Get the batch data webTarget = client.target(serverAddress).path(BULLETIN_BOARD_SERVER_PATH).path(READ_BATCH_PATH); @@ -98,9 +52,8 @@ public class SingleServerReadBatchWorker extends SingleServerWorker>(){})); + // If a BatchDataList is returned: the read was successful + return response.readEntity(BatchDataList.class).getDataList(); } catch (ProcessingException | IllegalStateException e) { @@ -112,8 +65,6 @@ public class SingleServerReadBatchWorker extends SingleServerWorker thrown; - - protected void genericHandleFailure(Throwable t){ - System.err.println(t.getCause() + " " + t.getMessage()); - thrown.add(t); - jobSemaphore.release(); - } - - private class PostCallback implements ClientCallback{ - - @Override - public void handleCallback(Boolean msg) { - System.err.println("Post operation completed"); - jobSemaphore.release(); - } - - @Override - public void handleFailure(Throwable t) { - genericHandleFailure(t); - } - } - - private class RedundancyCallback implements ClientCallback{ - - private float minRedundancy; - - public RedundancyCallback(float minRedundancy) { - this.minRedundancy = minRedundancy; - } - - @Override - public void handleCallback(Float redundancy) { - System.err.println("Redundancy found is: " + redundancy); - jobSemaphore.release(); - assertThat(redundancy, greaterThanOrEqualTo(minRedundancy)); - } - - @Override - public void handleFailure(Throwable t) { - genericHandleFailure(t); - } - } - - private class ReadCallback implements ClientCallback>{ - - private List expectedMsgList; - - public ReadCallback(List expectedMsgList) { - this.expectedMsgList = expectedMsgList; - } - - @Override - public void handleCallback(List messages) { - - System.err.println(messages); - jobSemaphore.release(); - - BulletinBoardMessageComparator msgComparator = new BulletinBoardMessageComparator(); - - assertThat(messages.size(), is(expectedMsgList.size())); - - Iterator expectedMessageIterator = expectedMsgList.iterator(); - Iterator receivedMessageIterator = messages.iterator(); - - while (expectedMessageIterator.hasNext()) { - assertThat(msgComparator.compare(expectedMessageIterator.next(), receivedMessageIterator.next()), is(0)); - } - - } - - @Override - public void handleFailure(Throwable t) { - genericHandleFailure(t); - } - } - - private AsyncBulletinBoardClient bulletinBoardClient; - - private PostCallback postCallback; - private RedundancyCallback redundancyCallback; - private ReadCallback readCallback; - - private static String PROP_GETTY_URL = "gretty.httpBaseURI"; - private static String DEFAULT_BASE_URL = "http://localhost:8081"; - private static String BASE_URL = System.getProperty(PROP_GETTY_URL, DEFAULT_BASE_URL); - - @Before - public void init(){ - - bulletinBoardClient = new ThreadedBulletinBoardClient(); - - List testDB = new LinkedList(); - testDB.add(BASE_URL); - - bulletinBoardClient.init(BulletinBoardClientParams.newBuilder() - .addBulletinBoardAddress("http://localhost:8081") - .setMinRedundancy((float) 1.0) - .build()); - - postCallback = new PostCallback(); - redundancyCallback = new RedundancyCallback((float) 1.0); - - thrown = new Vector<>(); - jobSemaphore = new Semaphore(0); - - } - - @Test - public void postTest() { - - byte[] b1 = {(byte) 1, (byte) 2, (byte) 3, (byte) 4}; - byte[] b2 = {(byte) 11, (byte) 12, (byte) 13, (byte) 14}; - byte[] b3 = {(byte) 21, (byte) 22, (byte) 23, (byte) 24}; - byte[] b4 = {(byte) 4, (byte) 5, (byte) 100, (byte) -50, (byte) 0}; - - BulletinBoardMessage msg; - - MessageFilterList filterList; - List msgList; - - MessageID messageID; - - Comparator msgComparator = new BulletinBoardMessageComparator(); - - msg = BulletinBoardMessage.newBuilder() - .setMsg(UnsignedBulletinBoardMessage.newBuilder() - .addTag("Signature") - .addTag("Trustee") - .setData(ByteString.copyFrom(b1)) - .build()) - .addSig(Crypto.Signature.newBuilder() - .setType(Crypto.SignatureType.DSA) - .setData(ByteString.copyFrom(b2)) - .setSignerId(ByteString.copyFrom(b3)) - .build()) - .addSig(Crypto.Signature.newBuilder() - .setType(Crypto.SignatureType.ECDSA) - .setData(ByteString.copyFrom(b3)) - .setSignerId(ByteString.copyFrom(b2)) - .build()) - .build(); - - messageID = bulletinBoardClient.postMessage(msg,postCallback); - - try { - jobSemaphore.acquire(); - } catch (InterruptedException e) { - System.err.println(e.getCause() + " " + e.getMessage()); - } - - bulletinBoardClient.getRedundancy(messageID,redundancyCallback); - - filterList = MessageFilterList.newBuilder() - .addFilter( - MessageFilter.newBuilder() - .setType(FilterType.TAG) - .setTag("Signature") - .build() - ) - .addFilter( - MessageFilter.newBuilder() - .setType(FilterType.TAG) - .setTag("Trustee") - .build() - ) - .build(); - - msgList = new LinkedList(); - msgList.add(msg); - - readCallback = new ReadCallback(msgList); - - bulletinBoardClient.readMessages(filterList, readCallback); - try { - jobSemaphore.acquire(2); - } catch (InterruptedException e) { - System.err.println(e.getCause() + " " + e.getMessage()); - } - - bulletinBoardClient.close(); - - if (thrown.size() > 0) { - assert false; - } - - } - -} diff --git a/bulletin-board-client/src/test/java/ThreadedBulletinBoardClientIntegrationTest.java b/bulletin-board-client/src/test/java/ThreadedBulletinBoardClientIntegrationTest.java new file mode 100644 index 0000000..c266086 --- /dev/null +++ b/bulletin-board-client/src/test/java/ThreadedBulletinBoardClientIntegrationTest.java @@ -0,0 +1,541 @@ +import com.google.common.util.concurrent.FutureCallback; +import com.google.protobuf.ByteString; +import meerkat.bulletinboard.AsyncBulletinBoardClient; +import meerkat.bulletinboard.CompleteBatch; +import meerkat.bulletinboard.GenericBatchDigitalSignature; +import meerkat.bulletinboard.ThreadedBulletinBoardClient; +import meerkat.comm.CommunicationException; +import meerkat.crypto.concrete.ECDSASignature; +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Crypto; + +import meerkat.protobuf.Voting.*; +import meerkat.util.BulletinBoardMessageComparator; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.number.OrderingComparison.*; + +import java.io.IOException; +import java.io.InputStream; +import java.security.*; +import java.security.cert.CertificateException; +import java.util.*; +import java.util.concurrent.Semaphore; + +/** + * Created by Arbel Deutsch Peled on 05-Dec-15. + */ +public class ThreadedBulletinBoardClientIntegrationTest { + + // Signature resources + + private GenericBatchDigitalSignature signers[]; + private ByteString[] signerIDs; + + private static String KEYFILE_EXAMPLE = "/certs/enduser-certs/user1-key-with-password-secret.p12"; + private static String KEYFILE_EXAMPLE3 = "/certs/enduser-certs/user3-key-with-password-shh.p12"; + + private static String KEYFILE_PASSWORD1 = "secret"; + private static String KEYFILE_PASSWORD3 = "shh"; + + public static String CERT1_PEM_EXAMPLE = "/certs/enduser-certs/user1.crt"; + public static String CERT3_PEM_EXAMPLE = "/certs/enduser-certs/user3.crt"; + + // Server data + + private static String PROP_GETTY_URL = "gretty.httpBaseURI"; + private static String DEFAULT_BASE_URL = "http://localhost:8081"; + private static String BASE_URL = System.getProperty(PROP_GETTY_URL, DEFAULT_BASE_URL); + + // Client and callbacks + + private AsyncBulletinBoardClient bulletinBoardClient; + + private PostCallback postCallback; + private PostCallback failPostCallback = new PostCallback(true,false); + + private RedundancyCallback redundancyCallback; + private ReadCallback readCallback; + private ReadBatchCallback readBatchCallback; + + // Sync and misc + + private Semaphore jobSemaphore; + private Vector thrown; + private Random random; + + // Constructor + + public ThreadedBulletinBoardClientIntegrationTest(){ + + signers = new GenericBatchDigitalSignature[2]; + signerIDs = new ByteString[signers.length]; + signers[0] = new GenericBatchDigitalSignature(new ECDSASignature()); + signers[1] = new GenericBatchDigitalSignature(new ECDSASignature()); + + InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE); + char[] password = KEYFILE_PASSWORD1.toCharArray(); + + KeyStore.Builder keyStoreBuilder = null; + try { + keyStoreBuilder = signers[0].getPKCS12KeyStoreBuilder(keyStream, password); + + signers[0].loadSigningCertificate(keyStoreBuilder); + + signers[0].loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE)); + + keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE3); + password = KEYFILE_PASSWORD3.toCharArray(); + + keyStoreBuilder = signers[1].getPKCS12KeyStoreBuilder(keyStream, password); + signers[1].loadSigningCertificate(keyStoreBuilder); + + signers[1].loadVerificationCertificates(getClass().getResourceAsStream(CERT3_PEM_EXAMPLE)); + + for (int i = 0 ; i < signers.length ; i++) { + signerIDs[i] = signers[i].getSignerID(); + } + + } catch (IOException e) { + System.err.println("Failed reading from signature file " + e.getMessage()); + fail("Failed reading from signature file " + e.getMessage()); + } catch (CertificateException e) { + System.err.println("Failed reading certificate " + e.getMessage()); + fail("Failed reading certificate " + e.getMessage()); + } catch (KeyStoreException e) { + System.err.println("Failed reading keystore " + e.getMessage()); + fail("Failed reading keystore " + e.getMessage()); + } catch (NoSuchAlgorithmException e) { + System.err.println("Couldn't find signing algorithm " + e.getMessage()); + fail("Couldn't find signing algorithm " + e.getMessage()); + } catch (UnrecoverableKeyException e) { + System.err.println("Couldn't find signing key " + e.getMessage()); + fail("Couldn't find signing key " + e.getMessage()); + } + + } + + // Callback definitions + + protected void genericHandleFailure(Throwable t){ + System.err.println(t.getCause() + " " + t.getMessage()); + thrown.add(t); + jobSemaphore.release(); + } + + private class PostCallback implements FutureCallback{ + + private boolean isAssert; + private boolean assertValue; + + public PostCallback() { + this(false); + } + + public PostCallback(boolean isAssert) { + this(isAssert,true); + } + + public PostCallback(boolean isAssert, boolean assertValue) { + this.isAssert = isAssert; + this.assertValue = assertValue; + } + + @Override + public void onSuccess(Boolean msg) { + System.err.println("Post operation completed"); + jobSemaphore.release(); + //TODO: Change Assert mechanism to exception one + if (isAssert) { + if (assertValue) { + assertThat("Post operation failed", msg, is(Boolean.TRUE)); + } else { + assertThat("Post operation succeeded unexpectedly", msg, is(Boolean.FALSE)); + } + } + } + + @Override + public void onFailure(Throwable t) { + genericHandleFailure(t); + } + } + + private class RedundancyCallback implements FutureCallback{ + + private float minRedundancy; + + public RedundancyCallback(float minRedundancy) { + this.minRedundancy = minRedundancy; + } + + @Override + public void onSuccess(Float redundancy) { + System.err.println("Redundancy found is: " + redundancy); + jobSemaphore.release(); + assertThat(redundancy, greaterThanOrEqualTo(minRedundancy)); + } + + @Override + public void onFailure(Throwable t) { + genericHandleFailure(t); + } + } + + private class ReadCallback implements FutureCallback>{ + + private List expectedMsgList; + + public ReadCallback(List expectedMsgList) { + this.expectedMsgList = expectedMsgList; + } + + @Override + public void onSuccess(List messages) { + + System.err.println(messages); + jobSemaphore.release(); + + BulletinBoardMessageComparator msgComparator = new BulletinBoardMessageComparator(); + + assertThat(messages.size(), is(expectedMsgList.size())); + + Iterator expectedMessageIterator = expectedMsgList.iterator(); + Iterator receivedMessageIterator = messages.iterator(); + + while (expectedMessageIterator.hasNext()) { + assertThat(msgComparator.compare(expectedMessageIterator.next(), receivedMessageIterator.next()), is(0)); + } + + } + + @Override + public void onFailure(Throwable t) { + genericHandleFailure(t); + } + } + + private class ReadBatchCallback implements FutureCallback { + + private CompleteBatch expectedBatch; + + public ReadBatchCallback(CompleteBatch expectedBatch) { + this.expectedBatch = expectedBatch; + } + + @Override + public void onSuccess(CompleteBatch batch) { + + System.err.println(batch); + jobSemaphore.release(); + + assertThat("Batch returned is incorrect", batch, is(equalTo(expectedBatch))); + + } + + @Override + public void onFailure(Throwable t) { + genericHandleFailure(t); + } + } + + // Randomness generators + + private byte randomByte(){ + return (byte) random.nextInt(); + } + + private byte[] randomByteArray(int length) { + + byte[] randomBytes = new byte[length]; + + for (int i = 0; i < length ; i++){ + randomBytes[i] = randomByte(); + } + + return randomBytes; + + } + + private CompleteBatch createRandomBatch(int signer, int batchId, int length) throws SignatureException { + + CompleteBatch completeBatch = new CompleteBatch(); + + // Create data + + completeBatch.setBeginBatchMessage(BeginBatchMessage.newBuilder() + .setSignerId(signerIDs[signer]) + .setBatchId(batchId) + .addTag("Test") + .build()); + + for (int i = 0 ; i < length ; i++){ + + BatchData batchData = BatchData.newBuilder() + .setData(ByteString.copyFrom(randomByteArray(i))) + .build(); + + completeBatch.appendBatchData(batchData); + + } + + signers[signer].updateContent(completeBatch); + + completeBatch.setSignature(signers[signer].sign()); + + return completeBatch; + + } + + // Test methods + + /** + * Takes care of initializing the client and the test resources + */ + @Before + public void init(){ + + bulletinBoardClient = new ThreadedBulletinBoardClient(); + + random = new Random(0); // We use insecure randomness in tests for repeatability + + List testDB = new LinkedList(); + testDB.add(BASE_URL); + + bulletinBoardClient.init(BulletinBoardClientParams.newBuilder() + .addBulletinBoardAddress("http://localhost:8081") + .setMinRedundancy((float) 1.0) + .build()); + + postCallback = new PostCallback(); + redundancyCallback = new RedundancyCallback((float) 1.0); + + thrown = new Vector<>(); + jobSemaphore = new Semaphore(0); + + } + + /** + * Closes the client and makes sure the test fails when an exception occurred in a separate thread + */ + + @After + public void close() { + + bulletinBoardClient.close(); + + if (thrown.size() > 0) { + assert false; + } + + } + + /** + * Tests the standard post, redundancy and read methods + */ + @Test + public void postTest() { + + byte[] b1 = {(byte) 1, (byte) 2, (byte) 3, (byte) 4}; + byte[] b2 = {(byte) 11, (byte) 12, (byte) 13, (byte) 14}; + byte[] b3 = {(byte) 21, (byte) 22, (byte) 23, (byte) 24}; + byte[] b4 = {(byte) 4, (byte) 5, (byte) 100, (byte) -50, (byte) 0}; + + BulletinBoardMessage msg; + + MessageFilterList filterList; + List msgList; + + MessageID messageID; + + Comparator msgComparator = new BulletinBoardMessageComparator(); + + msg = BulletinBoardMessage.newBuilder() + .setMsg(UnsignedBulletinBoardMessage.newBuilder() + .addTag("Signature") + .addTag("Trustee") + .setData(ByteString.copyFrom(b1)) + .build()) + .addSig(Crypto.Signature.newBuilder() + .setType(Crypto.SignatureType.DSA) + .setData(ByteString.copyFrom(b2)) + .setSignerId(ByteString.copyFrom(b3)) + .build()) + .addSig(Crypto.Signature.newBuilder() + .setType(Crypto.SignatureType.ECDSA) + .setData(ByteString.copyFrom(b3)) + .setSignerId(ByteString.copyFrom(b2)) + .build()) + .build(); + + messageID = bulletinBoardClient.postMessage(msg,postCallback); + + try { + jobSemaphore.acquire(); + } catch (InterruptedException e) { + System.err.println(e.getCause() + " " + e.getMessage()); + } + + bulletinBoardClient.getRedundancy(messageID,redundancyCallback); + + filterList = MessageFilterList.newBuilder() + .addFilter( + MessageFilter.newBuilder() + .setType(FilterType.TAG) + .setTag("Signature") + .build() + ) + .addFilter( + MessageFilter.newBuilder() + .setType(FilterType.TAG) + .setTag("Trustee") + .build() + ) + .build(); + + msgList = new LinkedList(); + msgList.add(msg); + + readCallback = new ReadCallback(msgList); + + bulletinBoardClient.readMessages(filterList, readCallback); + try { + jobSemaphore.acquire(2); + } catch (InterruptedException e) { + System.err.println(e.getCause() + " " + e.getMessage()); + } + + } + + /** + * Tests posting a batch by parts + * Also tests not being able to post to a closed batch + * @throws CommunicationException, SignatureException, InterruptedException + */ + @Test + public void testBatchPost() throws CommunicationException, SignatureException, InterruptedException { + + final int SIGNER = 1; + final int BATCH_ID = 100; + final int BATCH_LENGTH = 100; + + CompleteBatch completeBatch = createRandomBatch(SIGNER, BATCH_ID, BATCH_LENGTH); + + // Begin batch + + bulletinBoardClient.beginBatch(completeBatch.getBeginBatchMessage(), postCallback); + + jobSemaphore.acquire(); + + // Post data + + bulletinBoardClient.postBatchData(signerIDs[SIGNER], BATCH_ID, completeBatch.getBatchDataList(), postCallback); + + jobSemaphore.acquire(); + + // Close batch + + CloseBatchMessage closeBatchMessage = CloseBatchMessage.newBuilder() + .setBatchId(BATCH_ID) + .setBatchLength(BATCH_LENGTH) + .setSig(completeBatch.getSignature()) + .build(); + + bulletinBoardClient.closeBatch(closeBatchMessage, postCallback); + + jobSemaphore.acquire(); + + // Attempt to open batch again + + bulletinBoardClient.beginBatch(completeBatch.getBeginBatchMessage(), failPostCallback); + + // Attempt to add batch data + + bulletinBoardClient.postBatchData(signerIDs[SIGNER], BATCH_ID, completeBatch.getBatchDataList(), failPostCallback); + + jobSemaphore.acquire(2); + + // Read batch data + + BatchSpecificationMessage batchSpecificationMessage = + BatchSpecificationMessage.newBuilder() + .setSignerId(signerIDs[SIGNER]) + .setBatchId(BATCH_ID) + .setStartPosition(0) + .build(); + + readBatchCallback = new ReadBatchCallback(completeBatch); + + bulletinBoardClient.readBatch(batchSpecificationMessage, readBatchCallback); + + jobSemaphore.acquire(); + + } + + /** + * Posts a complete batch message + * Checks reading od the message + * @throws CommunicationException, SignatureException, InterruptedException + */ + @Test + public void testCompleteBatchPost() throws CommunicationException, SignatureException, InterruptedException { + + final int SIGNER = 0; + final int BATCH_ID = 101; + final int BATCH_LENGTH = 50; + + // Post batch + + CompleteBatch completeBatch = createRandomBatch(SIGNER, BATCH_ID, BATCH_LENGTH); + + bulletinBoardClient.postBatch(completeBatch,postCallback); + + jobSemaphore.acquire(); + + // Read batch + + BatchSpecificationMessage batchSpecificationMessage = + BatchSpecificationMessage.newBuilder() + .setSignerId(signerIDs[SIGNER]) + .setBatchId(BATCH_ID) + .setStartPosition(0) + .build(); + + readBatchCallback = new ReadBatchCallback(completeBatch); + + bulletinBoardClient.readBatch(batchSpecificationMessage, readBatchCallback); + + jobSemaphore.acquire(); + + } + + /** + * Tests that an unopened batch cannot be closed + * @throws CommunicationException, InterruptedException + */ + @Test + public void testInvalidBatchClose() throws CommunicationException, InterruptedException { + + final int NON_EXISTENT_BATCH_ID = 999; + + CloseBatchMessage closeBatchMessage = + CloseBatchMessage.newBuilder() + .setBatchId(NON_EXISTENT_BATCH_ID) + .setBatchLength(1) + .setSig(Crypto.Signature.getDefaultInstance()) + .build(); + + // Try to close the (unopened) batch; + + bulletinBoardClient.closeBatch(closeBatchMessage, failPostCallback); + + jobSemaphore.acquire(); + + } + +} diff --git a/bulletin-board-server/build.gradle b/bulletin-board-server/build.gradle index 21604d1..59045a2 100644 --- a/bulletin-board-server/build.gradle +++ b/bulletin-board-server/build.gradle @@ -48,7 +48,7 @@ dependencies { // JDBC connections compile 'org.springframework:spring-jdbc:4.2.+' - compile 'org.xerial:sqlite-jdbc:3.7.+' + compile 'org.xerial:sqlite-jdbc:3.8.+' compile 'mysql:mysql-connector-java:5.1.+' compile 'com.h2database:h2:1.0.+' @@ -89,6 +89,11 @@ task h2Test(type: Test) { outputs.upToDateWhen { false } } +task liteTest(type: Test) { + include '**/*SQLite*Test*' + outputs.upToDateWhen { false } +} + task dbTest(type: Test) { include '**/*H2*Test*' include '**/*MySQL*Test*' diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java index 5b4fac9..a6313b6 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java @@ -177,8 +177,9 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ case MSG_ID: return MSG_ID; - case EXACT_ENTRY: // Go through - case MAX_ENTRY: + case EXACT_ENTRY: // Go through + case MAX_ENTRY: // Go through + case MIN_ENTRY: return ENTRY_NUM; case SIGNER_ID: @@ -253,12 +254,13 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ switch (messageFilter.getType()) { - case MSG_ID: // Go through + case MSG_ID: // Go through case SIGNER_ID: return messageFilter.getId().toByteArray(); - case EXACT_ENTRY: // Go through - case MAX_ENTRY: + case EXACT_ENTRY: // Go through + case MAX_ENTRY: // Go through + case MIN_ENTRY: return messageFilter.getEntry(); case TAG: @@ -653,7 +655,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ for (int i=0 ; i < tags.length ; i++) { namedParameters[i] = new MapSqlParameterSource(); - namedParameters[i].addValue(QueryType.CONNECT_BATCH_TAG.getParamName(0),message.getSignerId()); + namedParameters[i].addValue(QueryType.CONNECT_BATCH_TAG.getParamName(0),message.getSignerId().toByteArray()); namedParameters[i].addValue(QueryType.CONNECT_BATCH_TAG.getParamName(1),message.getBatchId()); namedParameters[i].addValue(QueryType.CONNECT_BATCH_TAG.getParamName(2),tags[i]); } @@ -675,7 +677,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ String sql = sqlQueryProvider.getSQLString(QueryType.INSERT_BATCH_DATA); MapSqlParameterSource namedParameters = new MapSqlParameterSource(); - namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(0),batchMessage.getSignerId()); + namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(0),batchMessage.getSignerId().toByteArray()); namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(1),batchMessage.getBatchId()); namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(2),batchMessage.getSerialNum()); namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(3),batchMessage.getData().toByteArray()); @@ -700,7 +702,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ MapSqlParameterSource namedParameters = new MapSqlParameterSource(); - namedParameters.addValue(QueryType.CHECK_BATCH_LENGTH.getParamName(0),signerId); + namedParameters.addValue(QueryType.CHECK_BATCH_LENGTH.getParamName(0),signerId.toByteArray()); namedParameters.addValue(QueryType.CHECK_BATCH_LENGTH.getParamName(1),batchId); List lengthResult = jdbcTemplate.query(sql, namedParameters, new LongMapper()); @@ -733,7 +735,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ sql = sqlQueryProvider.getSQLString(QueryType.GET_BATCH_MESSAGE_DATA); namedParameters = new MapSqlParameterSource(); - namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(0),signerId); + namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(0),signerId.toByteArray()); namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1),batchId); namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(2),0); // Read from the beginning @@ -775,7 +777,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ sql = sqlQueryProvider.getSQLString(QueryType.REMOVE_BATCH_TAGS); namedParameters = new MapSqlParameterSource(); - namedParameters.addValue(QueryType.REMOVE_BATCH_TAGS.getParamName(0), signerId); + namedParameters.addValue(QueryType.REMOVE_BATCH_TAGS.getParamName(0), signerId.toByteArray()); namedParameters.addValue(QueryType.REMOVE_BATCH_TAGS.getParamName(1), batchId); jdbcTemplate.update(sql, namedParameters); @@ -786,7 +788,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ } @Override - public List readBatch(BatchSpecificationMessage message) throws CommunicationException, IllegalArgumentException{ + public BatchDataList readBatch(BatchSpecificationMessage message) throws CommunicationException, IllegalArgumentException{ // Check that batch is closed if (!isBatchClosed(message.getSignerId(), message.getBatchId())) { @@ -796,11 +798,13 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ String sql = sqlQueryProvider.getSQLString(QueryType.GET_BATCH_MESSAGE_DATA); MapSqlParameterSource namedParameters = new MapSqlParameterSource(); - namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(0),message.getSignerId()); + namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(0),message.getSignerId().toByteArray()); namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1),message.getBatchId()); namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(2),message.getStartPosition()); - return jdbcTemplate.query(sql, namedParameters, new BatchDataMapper()); + return BatchDataList.newBuilder() + .addAllData(jdbcTemplate.query(sql, namedParameters, new BatchDataMapper())) + .build(); } @Override diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java index 14bf9e2..659d9c3 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java @@ -134,6 +134,8 @@ public class H2QueryProvider implements BulletinBoardSQLServer.SQLQueryProvider return "MsgTable.EntryNum = :EntryNum" + serialString; case MAX_ENTRY: return "MsgTable.EntryNum <= :EntryNum" + serialString; + case MIN_ENTRY: + return "MsgTable.EntryNum >= :EntryNum" + serialString; case MAX_MESSAGES: return "LIMIT :Limit" + serialString; case MSG_ID: @@ -157,6 +159,7 @@ public class H2QueryProvider implements BulletinBoardSQLServer.SQLQueryProvider switch(filterType) { case EXACT_ENTRY: // Go through case MAX_ENTRY: // Go through + case MIN_ENTRY: // Go through case MAX_MESSAGES: return "INT"; diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java index c8357a3..e3bdef0 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java @@ -151,6 +151,8 @@ public class MySQLQueryProvider implements SQLQueryProvider { return "MsgTable.EntryNum = :EntryNum" + serialString; case MAX_ENTRY: return "MsgTable.EntryNum <= :EntryNum" + serialString; + case MIN_ENTRY: + return "MsgTable.EntryNum >= :EntryNum" + serialString; case MAX_MESSAGES: return "LIMIT :Limit" + serialString; case MSG_ID: @@ -174,6 +176,7 @@ public class MySQLQueryProvider implements SQLQueryProvider { switch(filterType) { case EXACT_ENTRY: // Go through case MAX_ENTRY: // Go through + case MIN_ENTRY: // Go through case MAX_MESSAGES: return "INT"; diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteQueryProvider.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteQueryProvider.java index d796789..b581b87 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteQueryProvider.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteQueryProvider.java @@ -54,6 +54,8 @@ public class SQLiteQueryProvider implements BulletinBoardSQLServer.SQLQueryProvi return "MsgTable.EntryNum = :EntryNum" + serialString; case MAX_ENTRY: return "MsgTable.EntryNum <= :EntryNum" + serialString; + case MIN_ENTRY: + return "MsgTable.EntryNum <= :EntryNum" + serialString; case MAX_MESSAGES: return "LIMIT = :Limit" + serialString; case MSG_ID: @@ -77,6 +79,7 @@ public class SQLiteQueryProvider implements BulletinBoardSQLServer.SQLQueryProvi switch(filterType) { case EXACT_ENTRY: // Go through case MAX_ENTRY: // Go through + case MIN_ENTRY: // Go through case MAX_MESSAGES: return "INTEGER"; diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java index fe3d2fc..766af19 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java @@ -106,6 +106,7 @@ public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextL @Override public BoolMsg beginBatch(BeginBatchMessage message) { try { + init(); return bulletinBoard.beginBatch(message); } catch (CommunicationException e) { System.err.println(e.getMessage()); @@ -120,6 +121,7 @@ public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextL @Override public BoolMsg postBatchMessage(BatchMessage batchMessage) { try { + init(); return bulletinBoard.postBatchMessage(batchMessage); } catch (CommunicationException e) { System.err.println(e.getMessage()); @@ -134,6 +136,7 @@ public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextL @Override public BoolMsg closeBatchMessage(CloseBatchMessage message) { try { + init(); return bulletinBoard.closeBatchMessage(message); } catch (CommunicationException e) { System.err.println(e.getMessage()); @@ -146,8 +149,9 @@ public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextL @Consumes(MEDIATYPE_PROTOBUF) @Produces(MEDIATYPE_PROTOBUF) @Override - public List readBatch(BatchSpecificationMessage message) { + public BatchDataList readBatch(BatchSpecificationMessage message) { try { + init(); return bulletinBoard.readBatch(message); } catch (CommunicationException | IllegalArgumentException e) { System.err.println(e.getMessage()); diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java b/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java index 7732fcb..c6e330c 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java @@ -1,5 +1,6 @@ package meerkat.bulletinboard; +import com.google.common.util.concurrent.FutureCallback; import com.google.protobuf.ByteString; import meerkat.protobuf.BulletinBoardAPI.*; @@ -10,11 +11,6 @@ import java.util.List; */ public interface AsyncBulletinBoardClient extends BulletinBoardClient { - public interface ClientCallback { - void handleCallback(T msg); - void handleFailure(Throwable t); - } - public interface MessageHandler { void handleNewMessages(List messageList); } @@ -25,7 +21,7 @@ public interface AsyncBulletinBoardClient extends BulletinBoardClient { * @param callback is a class containing methods to handle the result of the operation * @return a unique message ID for the message, that can be later used to retrieve the batch */ - public MessageID postMessage(BulletinBoardMessage msg, ClientCallback callback); + public MessageID postMessage(BulletinBoardMessage msg, FutureCallback callback); /** * Perform an end-to-end post of a signed batch message @@ -33,14 +29,14 @@ public interface AsyncBulletinBoardClient extends BulletinBoardClient { * @param callback is a class containing methods to handle the result of the operation * @return a unique identifier for the batch message */ - public MessageID postBatch(CompleteBatch completeBatch, ClientCallback callback); + public MessageID postBatch(CompleteBatch completeBatch, FutureCallback callback); /** * This message informs the server about the existence of a new batch message and supplies it with the tags associated with it * @param beginBatchMessage contains the data required to begin the batch * @param callback is a callback function class for handling results of the operation */ - public void beginBatch(BeginBatchMessage beginBatchMessage, ClientCallback callback); + public void beginBatch(BeginBatchMessage beginBatchMessage, FutureCallback callback); /** * This method posts batch data into an (assumed to be open) batch @@ -54,30 +50,30 @@ public interface AsyncBulletinBoardClient extends BulletinBoardClient { * @param callback is a callback function class for handling results of the operation */ public void postBatchData(byte[] signerId, int batchId, List batchDataList, - int startPosition, ClientCallback callback); + int startPosition, FutureCallback callback); /** * Overloading of the postBatchData method which starts at the first position in the batch */ - public void postBatchData(byte[] signerId, int batchId, List batchDataList, ClientCallback callback); + public void postBatchData(byte[] signerId, int batchId, List batchDataList, FutureCallback callback); /** * Overloading of the postBatchData method which uses ByteString */ public void postBatchData(ByteString signerId, int batchId, List batchDataList, - int startPosition, ClientCallback callback); + int startPosition, FutureCallback callback); /** * Overloading of the postBatchData method which uses ByteString and starts at the first position in the batch */ - public void postBatchData(ByteString signerId, int batchId, List batchDataList, ClientCallback callback); + public void postBatchData(ByteString signerId, int batchId, List batchDataList, FutureCallback callback); /** * Attempts to close a batch message * @param closeBatchMessage contains the data required to close the batch * @param callback is a callback function class for handling results of the operation */ - public void closeBatch(CloseBatchMessage closeBatchMessage, ClientCallback callback); + public void closeBatch(CloseBatchMessage closeBatchMessage, FutureCallback callback); /** * Check how "safe" a given message is in an asynchronous manner @@ -85,7 +81,7 @@ public interface AsyncBulletinBoardClient extends BulletinBoardClient { * @param id is the unique message identifier for retrieval * @param callback is a callback function class for handling results of the operation */ - public void getRedundancy(MessageID id, ClientCallback callback); + public void getRedundancy(MessageID id, FutureCallback callback); /** * Read all messages posted matching the given filter in an asynchronous manner @@ -95,14 +91,14 @@ public interface AsyncBulletinBoardClient extends BulletinBoardClient { * @param filterList return only messages that match the filters (null means no filtering). * @param callback is a callback function class for handling results of the operation */ - public void readMessages(MessageFilterList filterList, ClientCallback> callback); + public void readMessages(MessageFilterList filterList, FutureCallback> callback); /** * Read a given batch message from the bulletin board * @param batchSpecificationMessage contains the data required to specify a single batch instance * @param callback is a callback class for handling the result of the operation */ - public void readBatch(BatchSpecificationMessage batchSpecificationMessage, ClientCallback callback); + public void readBatch(BatchSpecificationMessage batchSpecificationMessage, FutureCallback callback); /** * Subscribes to a notifier that will return any new messages on the server that match the given filters diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java index 70721a7..cbf06ff 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java @@ -75,7 +75,7 @@ public interface BulletinBoardServer{ * @throws CommunicationException on DB connection error * @throws IllegalArgumentException if message does not specify a batch */ - public List readBatch(BatchSpecificationMessage message) throws CommunicationException, IllegalArgumentException; + public BatchDataList readBatch(BatchSpecificationMessage message) throws CommunicationException, IllegalArgumentException; /** * This method closes the connection to the DB diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/CompleteBatch.java b/meerkat-common/src/main/java/meerkat/bulletinboard/CompleteBatch.java index 19c57e3..227c7ca 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/CompleteBatch.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/CompleteBatch.java @@ -2,6 +2,7 @@ package meerkat.bulletinboard; import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.protobuf.Crypto.*; +import meerkat.util.BulletinBoardMessageComparator; import java.util.LinkedList; import java.util.List; @@ -48,6 +49,14 @@ public class CompleteBatch { return signature; } + public CloseBatchMessage getCloseBatchMessage() { + return CloseBatchMessage.newBuilder() + .setBatchId(getBeginBatchMessage().getBatchId()) + .setBatchLength(getBatchDataList().size()) + .setSig(getSignature()) + .build(); + } + public void setBeginBatchMessage(BeginBatchMessage beginBatchMessage) { this.beginBatchMessage = beginBatchMessage; } @@ -64,4 +73,45 @@ public class CompleteBatch { signature = newSignature; } + @Override + public boolean equals(Object other) { + + if (!(other instanceof CompleteBatch)) { + return false; + } + + CompleteBatch otherBatch = (CompleteBatch) other; + + boolean result = true; + + if (beginBatchMessage == null) { + if (otherBatch.getBeginBatchMessage() != null) + return false; + } else { + result = result && beginBatchMessage.equals(otherBatch.getBeginBatchMessage()); + } + + if (batchDataList == null) { + if (otherBatch.getBatchDataList() != null) + return false; + } else { + result = result && batchDataList.equals(otherBatch.getBatchDataList()); + } + + if (signature == null) { + if (otherBatch.getSignature() != null) + return false; + } else { + result = result && signature.equals(otherBatch.getSignature()); + } + + return result; + + } + + @Override + public String toString() { + return "Batch " + beginBatchMessage.getSignerId().toString() + ":" + beginBatchMessage.getBatchId(); + } + } diff --git a/meerkat-common/src/main/java/meerkat/util/BulletinBoardUtils.java b/meerkat-common/src/main/java/meerkat/util/BulletinBoardUtils.java new file mode 100644 index 0000000..b19bab3 --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/util/BulletinBoardUtils.java @@ -0,0 +1,65 @@ +package meerkat.util; + +import meerkat.protobuf.BulletinBoardAPI.*; + +import java.util.LinkedList; +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 16-Feb-16. + */ +public class BulletinBoardUtils { + + /** + * Searches the tags in the message for one that begins with given prefix + * @param message is the message to search + * @param prefix is the given prefix + * @return the tag without the prefix, if found, or null if not found + */ + public static String findTagWithPrefix(BulletinBoardMessage message, String prefix) { + + for (String tag : message.getMsg().getTagList()){ + if (tag.startsWith(prefix)) { + return tag.substring(prefix.length()); + } + } + + return null; + + } + + /** + * Searches the tags in a message for tags that do not contain a given list of prefixes + * @param message is the message to search + * @param prefixes is the list of prefixes + * @return a list of the tags that do *not* contain any of the given prefixes + */ + public static List removePrefixTags(BulletinBoardMessage message, Iterable prefixes) { + + if (prefixes == null) + return message.getMsg().getTagList(); + + List result = new LinkedList<>(); + + for (String tag : message.getMsg().getTagList()){ + + boolean found = false; + + for (String prefix : prefixes){ + if (tag.startsWith(prefix)){ + found = true; + break; + } + } + + if (!found) { + result.add(tag); + } + + } + + return result; + + } + +} diff --git a/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto b/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto index 2ae4068..b86debd 100644 --- a/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto +++ b/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto @@ -50,13 +50,14 @@ enum FilterType { MSG_ID = 0; // Match exact message ID EXACT_ENTRY = 1; // Match exact entry number in database (chronological) MAX_ENTRY = 2; // Find all entries in database up to specified entry number (chronological) - SIGNER_ID = 3; // Find all entries in database that correspond to specific signature (signer) - TAG = 4; // Find all entries in database that have a specific tag + MIN_ENTRY = 3; // Find all entries in database starting from specified entry number (chronological) + SIGNER_ID = 4; // Find all entries in database that correspond to specific signature (signer) + TAG = 5; // Find all entries in database that have a specific tag // NOTE: The MAX_MESSAGES filter must remain the last filter type // This is because the condition it specifies in an SQL statement must come last in the statement // Keeping it last here allows for easily sorting the filters and keeping the code general - MAX_MESSAGES = 5; // Return at most some specified number of messages + MAX_MESSAGES = 6; // Return at most some specified number of messages } message MessageFilter { @@ -98,6 +99,11 @@ message BatchData { bytes data = 1; } +// List of BatchData; Only used for testing +message BatchDataList { + repeated BatchData data = 1; +} + // These messages comprise a batch message message BatchMessage { bytes signerId = 1; // Unique signer identifier From 210cc327ac8ed48ae9cd0fb8f9d8976f8269b9b3 Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Wed, 17 Feb 2016 22:58:20 +0200 Subject: [PATCH 20/49] secure dkg without stage 4 --- .../main/java/Communication/MailHandler.java | 43 +++ .../java/Communication/MessageHandler.java | 14 + .../src/main/java/Communication/Network.java | 70 ++++ .../src/main/java/Communication/User.java | 68 ++++ .../VerifiableSecretSharing.java | 50 ++- ...VerifiableSecretSharingMessageHandler.java | 40 ++ .../main/java/JointFeldmanProtocol/DKG.java | 362 ------------------ .../DistributedKeyGeneration.java | 216 +++++++++++ ...istributedKeyGenerationMessageHandler.java | 161 ++++++++ .../java/JointFeldmanProtocol/Network.java | 124 ------ .../SecureDistributedKeyGeneration.java | 68 ++++ ...istributedKeyGenerationMessageHandler.java | 61 +++ .../LagrangePolynomial.java | 2 +- .../ShamirSecretSharing/Polynomial.java | 14 +- .../ShamirSecretSharing/SecretSharing.java | 50 ++- .../SecretSharingMessageHandler.java | 47 +++ .../VerifiableSecretSharingTest.java | 10 +- .../java/JointFeldmanProtocol/DKGTest.java | 107 ++++-- .../PolynomialTests/AddTest.java | 4 +- .../PolynomialTests/InterpolationTest.java | 4 +- .../PolynomialTests/MulByConstTest.java | 4 +- .../PolynomialTests/MulTest.java | 4 +- .../PolynomialTests/Utils.java | 4 +- .../SecretSharingTest.java | 12 +- .../src/main/proto/meerkat/DKGMessages.proto | 11 +- 25 files changed, 989 insertions(+), 561 deletions(-) create mode 100644 destributed-key-generation/src/main/java/Communication/MailHandler.java create mode 100644 destributed-key-generation/src/main/java/Communication/MessageHandler.java create mode 100644 destributed-key-generation/src/main/java/Communication/Network.java create mode 100644 destributed-key-generation/src/main/java/Communication/User.java create mode 100644 destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingMessageHandler.java delete mode 100644 destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java create mode 100644 destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java create mode 100644 destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMessageHandler.java delete mode 100644 destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java create mode 100644 destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGeneration.java create mode 100644 destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationMessageHandler.java rename destributed-key-generation/src/main/java/{FeldmanVerifiableSecretSharing => }/ShamirSecretSharing/LagrangePolynomial.java (97%) rename destributed-key-generation/src/main/java/{FeldmanVerifiableSecretSharing => }/ShamirSecretSharing/Polynomial.java (89%) rename destributed-key-generation/src/main/java/{FeldmanVerifiableSecretSharing => }/ShamirSecretSharing/SecretSharing.java (64%) create mode 100644 destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharingMessageHandler.java rename destributed-key-generation/src/test/java/{FeldmanVerifiableSecretSharing => }/ShamirSecretSharing/PolynomialTests/AddTest.java (87%) rename destributed-key-generation/src/test/java/{FeldmanVerifiableSecretSharing => }/ShamirSecretSharing/PolynomialTests/InterpolationTest.java (92%) rename destributed-key-generation/src/test/java/{FeldmanVerifiableSecretSharing => }/ShamirSecretSharing/PolynomialTests/MulByConstTest.java (87%) rename destributed-key-generation/src/test/java/{FeldmanVerifiableSecretSharing => }/ShamirSecretSharing/PolynomialTests/MulTest.java (88%) rename destributed-key-generation/src/test/java/{FeldmanVerifiableSecretSharing => }/ShamirSecretSharing/PolynomialTests/Utils.java (76%) rename destributed-key-generation/src/test/java/{FeldmanVerifiableSecretSharing => }/ShamirSecretSharing/SecretSharingTest.java (89%) diff --git a/destributed-key-generation/src/main/java/Communication/MailHandler.java b/destributed-key-generation/src/main/java/Communication/MailHandler.java new file mode 100644 index 0000000..c70032f --- /dev/null +++ b/destributed-key-generation/src/main/java/Communication/MailHandler.java @@ -0,0 +1,43 @@ +package Communication; + +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.protobuf.DKGMessages; + +/** + * Created by Tzlil on 2/14/2016. + */ +public class MailHandler { + + private MessageHandler messageHandler; + + public MailHandler(MessageHandler messageHandler){ + this.messageHandler = messageHandler; + } + + public MessageHandler getMessageHandler(){ + return messageHandler; + } + + public void handel(DKGMessages.Mail mail) throws InvalidProtocolBufferException { + switch (mail.getType()){ + case SECRET: + DKGMessages.SecretMessage secretMessage = DKGMessages.SecretMessage.parseFrom(mail.getMessage()); + messageHandler.handelSecretMessage(mail.getSender(),mail.getDestination()== Network.BROADCAST,secretMessage); + break; + case COMMITMENT: + DKGMessages.CommitmentMessage commitmentMessage = DKGMessages.CommitmentMessage.parseFrom(mail.getMessage()); + messageHandler.handelCommitmentMessage(mail.getSender(),mail.getDestination()== Network.BROADCAST,commitmentMessage); + break; + case DONE: + DKGMessages.DoneMessage doneMessage = DKGMessages.DoneMessage.parseFrom(mail.getMessage()); + messageHandler.handelDoneMessage(mail.getSender(),mail.getDestination()== Network.BROADCAST,doneMessage); + break; + case COMPLAINT: + DKGMessages.ComplaintMessage complaintMessage = DKGMessages.ComplaintMessage.parseFrom(mail.getMessage()); + messageHandler.handelComplaintMessage(mail.getSender(),mail.getDestination()== Network.BROADCAST,complaintMessage); + break; + default: + break; + } + } +} diff --git a/destributed-key-generation/src/main/java/Communication/MessageHandler.java b/destributed-key-generation/src/main/java/Communication/MessageHandler.java new file mode 100644 index 0000000..8d1447e --- /dev/null +++ b/destributed-key-generation/src/main/java/Communication/MessageHandler.java @@ -0,0 +1,14 @@ +package Communication; + +import meerkat.protobuf.DKGMessages; + +/** + * Created by Tzlil on 2/14/2016. + */ +public interface MessageHandler { + void handelComplaintMessage(int sender, boolean isBroadcast,DKGMessages.ComplaintMessage complaintMessage); + void handelDoneMessage(int sender, boolean isBroadcast, DKGMessages.DoneMessage doneMessage); + void handelCommitmentMessage(int sender, boolean isBroadcast,DKGMessages.CommitmentMessage commitmentMessage); + void handelSecretMessage(int sender, boolean isBroadcast,DKGMessages.SecretMessage secretMessage); + void handelDoubleSecretMessage(int sender, boolean isBroadcast,DKGMessages.DoubleSecretMessage doubleSecretMessage); +} diff --git a/destributed-key-generation/src/main/java/Communication/Network.java b/destributed-key-generation/src/main/java/Communication/Network.java new file mode 100644 index 0000000..fb6dca5 --- /dev/null +++ b/destributed-key-generation/src/main/java/Communication/Network.java @@ -0,0 +1,70 @@ +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/7/2016. + * JointFeldamn protocol assumes all parties can communicate throw broadcast chanel + * and private chanel (for each pair) + * this class simulates it + */ +public class Network { + + protected final User[] users; + protected final int n; + protected final Queue availableIDs; + public static final int BROADCAST = 0; + + + public Network(int n) { + this.n = n; + this.users = new User[n]; + this.availableIDs = new ArrayBlockingQueue(n); + for (int id = 1; id <= n; id++){ + availableIDs.add(id); + } + } + + public User connect(MessageHandler messageHandler){ + Integer id = availableIDs.poll(); + if (id == null) + return null; + users[id - 1] = new User(id,this,new MailHandler(messageHandler)); + 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); + } + } + +} diff --git a/destributed-key-generation/src/main/java/Communication/User.java b/destributed-key-generation/src/main/java/Communication/User.java new file mode 100644 index 0000000..e28347c --- /dev/null +++ b/destributed-key-generation/src/main/java/Communication/User.java @@ -0,0 +1,68 @@ +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. + */ +public class User{ + protected final MailHandler mailHandler; + protected final Queue 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(2 * 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 MessageHandler getMessageHandler(){ + return mailHandler.getMessageHandler(); + } + + public int getID() { + return ID; + } + public Thread getReceiverThread(){ + return receiverThread; + } + private class Receiver implements Runnable{ + @Override + public void run() { + while (true){ + if (!mailbox.isEmpty()){ + try { + mailHandler.handel(mailbox.poll()); + } catch (InvalidProtocolBufferException e) { + e.printStackTrace(); + } + }else{ + try { + Thread.sleep(30); + } catch (InterruptedException e) { + // do nothing + } + } + } + } + } + + +} diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java index eb3dc07..796aaa9 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java @@ -1,9 +1,12 @@ package FeldmanVerifiableSecretSharing; -import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; -import FeldmanVerifiableSecretSharing.ShamirSecretSharing.SecretSharing; -import org.bouncycastle.util.Arrays; -import org.factcenter.qilin.primitives.CyclicGroup; +import Communication.Network; +import Communication.User; +import ShamirSecretSharing.Polynomial; +import ShamirSecretSharing.SecretSharing; +import com.google.protobuf.ByteString; +import meerkat.protobuf.DKGMessages; +import java.util.Arrays; import org.factcenter.qilin.primitives.concrete.Zpstar; import java.math.BigInteger; @@ -21,8 +24,7 @@ public class VerifiableSecretSharing extends SecretSharing { protected final Zpstar zpstar; protected final BigInteger g; // public generator of group private final BigInteger y; // y = g ^ x - private final BigInteger[] commitments; - + protected final BigInteger[] commitments; /** * @param p a large prime * @param q a large prime dividing p - 1. @@ -30,8 +32,9 @@ public class VerifiableSecretSharing extends SecretSharing { * the generated group is a subgroup of Zp*. * it must be chosen such that computing discrete logarithms is hard in this group. */ - public VerifiableSecretSharing(int t, int n, BigInteger x, Random random,BigInteger p,BigInteger q,BigInteger g) { - super(t, n, x, random,q); + public VerifiableSecretSharing(int t, int n, BigInteger x, Random random, BigInteger p, BigInteger q, BigInteger g + , User user) { + super(t, n, x, random,q,user); this.g = g; this.zpstar = new Zpstar(p); assert (zpstar.contains(g)); @@ -40,6 +43,11 @@ public class VerifiableSecretSharing extends SecretSharing { this.y = zpstar.multiply(g,x); } + public VerifiableSecretSharing(int t, int n, BigInteger x, Random random, BigInteger p, BigInteger q, BigInteger g + , Network network) { + this(t,n,x,random,p,q,g,network.connect(new VerifiableSecretSharingMessageHandler(t))); + } + /** * @return commitments[i] = g ^ polynomial.coefficients[i] */ @@ -102,6 +110,30 @@ public class VerifiableSecretSharing extends SecretSharing { * @return copy of commitments */ public BigInteger[] getCommitments() { - return Arrays.clone(commitments); + return Arrays.copyOf(commitments,commitments.length); + } + + public DKGMessages.CommitmentMessage[] prepareCommitmentMessages(){ + DKGMessages.CommitmentMessage[] commitmentMessages = new DKGMessages.CommitmentMessage[t + 1]; + for (int k = 0; k <= t ; k ++) { + commitmentMessages[k] = DKGMessages.CommitmentMessage.newBuilder() + .setK(k) + .setCommitment(ByteString.copyFrom(commitments[k].toByteArray())) + .build(); + } + return commitmentMessages; + } + + protected void computeAndSendCommitments(){ + DKGMessages.CommitmentMessage[] commitmentMessages = prepareCommitmentMessages(); + for (int k = 0; k <= t ; k ++){ + user.broadcast(DKGMessages.Mail.Type.COMMITMENT,commitmentMessages[k]); + } + } + + @Override + public void run() { + super.run(); + computeAndSendCommitments(); } } diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingMessageHandler.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingMessageHandler.java new file mode 100644 index 0000000..bfa23e5 --- /dev/null +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingMessageHandler.java @@ -0,0 +1,40 @@ +package FeldmanVerifiableSecretSharing; + +import Communication.Network; +import ShamirSecretSharing.SecretSharingMessageHandler; +import meerkat.protobuf.DKGMessages; + + +import java.math.BigInteger; +import java.util.Arrays; + +/** + * Created by Tzlil on 2/16/2016. + */ +public class VerifiableSecretSharingMessageHandler extends SecretSharingMessageHandler { + + private final BigInteger[] commitments; + + public VerifiableSecretSharingMessageHandler(int t) { + this.commitments = new BigInteger[t + 1]; + } + + public static BigInteger extractCommitment(DKGMessages.CommitmentMessage commitmentMessage){ + return new BigInteger(commitmentMessage.getCommitment().toByteArray()); + } + + @Override + public void handelCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage) { + if(isBroadcast) { // receive in broadcast only + commitments[commitmentMessage.getK()] = extractCommitment(commitmentMessage); + } + } + + public BigInteger[] getCommitments() { + return commitments; + } + + public BigInteger getY(){ + return commitments[0]; + } +} diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java deleted file mode 100644 index 2cbef48..0000000 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java +++ /dev/null @@ -1,362 +0,0 @@ -package JointFeldmanProtocol; - -import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; -import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; -import com.google.protobuf.ByteString; -import com.google.protobuf.InvalidProtocolBufferException; -import org.bouncycastle.util.Arrays; -import meerkat.protobuf.DKGMessages.*; - -import java.math.BigInteger; -import java.util.HashSet; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.Callable; - -/** - * Created by Tzlil on 2/5/2016. - * - * an implementation of a version of Pedersen's distributed key generation protocol - */ -public class DKG extends VerifiableSecretSharing implements Runnable{ - - private final int id; - private final Network.User user; // send and receive messages throw network - - private final BigInteger[] ys; // container for y values that - private final Polynomial.Point[] shares; // shares[i] equivalent to Si,id in terms of the protocol - private final BigInteger[][] commitmentsArray; // commitmentsArray[i] equivalent to Ai in terms of the protocol - private final ComplainState[][] complainStates; // complainStates[i][j] == state of Pj's complaint against Pi - - private final Set QUAL; // set of all non-disqualified parties - private final BigInteger[] commitments; // public verification values - private Polynomial.Point share; // final share of the secrete - private BigInteger y; // final public value - - - public DKG(int t, int n, BigInteger x, Random random, BigInteger p, BigInteger q, BigInteger g,Network network) { - super(t, n, x, random, p, q, g); - - this.commitmentsArray = new BigInteger[n][t + 1]; - this.shares = new Polynomial.Point[n]; - this.user = network.connect(new Handler()); - this.id = user.getID(); - this.complainStates = new ComplainState[n][n]; - this.QUAL = new HashSet(); - this.ys = new BigInteger[n]; - this.commitments = new BigInteger[t + 1]; - - for (int i = 0; i < n; i ++){ - for (int j = 0 ; j < n ; j ++) - complainStates[i][j] = ComplainState.Non; - } - - } - - /** - * use for simulate real distributed protocol - */ - @Override - public void run() { - user.getReceiverThread().start(); - stage1(); - stage2(); - stage3(); - stage4(); - user.getReceiverThread().interrupt(); - } - - /** - * 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. - */ - private void stage1(){ - // for avoiding edge cases, sets commitmentsArray[id - 1] - BigInteger[] commitments = super.getCommitments(); - System.arraycopy(commitments, 0, commitmentsArray[id - 1], 0, commitmentsArray[id - 1].length); - - // broadcasts commitments - CommitmentMessage commitment; - for (int k = 0; k <= t ; k ++){ - commitment = CommitmentMessage.newBuilder() - .setK(k) - .setCommitment(ByteString.copyFrom(commitmentsArray[id - 1][k].toByteArray())) - .build(); - user.broadcast(Mail.Type.COMMITMENT,commitment); - } - - // computes and sends shares - SecretMessage secret; - for (int j = 1; j <= n ; j++ ){ - if(j != id){ - secret = SecretMessage.newBuilder() - .setSecret(getShare(j).asMessage()) - .build(); - user.send(j, Mail.Type.SECRET,secret); - } - else{ - shares[id - 1] = super.getShare(id); - } - } - while (!isStage1Complete()){ - try { - Thread.sleep(300); - } catch (InterruptedException e) { - // do nothing - } - } - } - - /** - * @return true iff all shares and commitments were received - */ - private boolean isStage1Complete(){ - for (int i = 1 ; i <= n ; i++){ - if(shares[i - 1] == null) - return false; - } - - for (int i = 0; i < commitmentsArray.length; i++){ - for (int j = 0; j < commitmentsArray[i].length; j++){ - if(commitmentsArray[i][j] == null) - return false; - } - } - return true; - } - - /** - * @param secret - * @param i - * @return g ^ Sij == verify(j,Ai,zpstar) (mod p) - */ - private boolean isValidSecret(Polynomial.Point secret, int i){ - int j = secret.x.intValue(); - return zpstar.multiply(g,secret.y).equals(verify(j,commitmentsArray[i - 1],zpstar)); - } - - /** - * stage2 according to the protocol - * Pj verifies all the shares he received (using isValidSecret) - * if check fails for an index i, Pj broadcasts a complaint against Pi. - * Pj broadcasts yj value at the end of this stage - */ - private void stage2(){ - ys[id - 1] = super.getY(); - ComplaintMessage complaint; - for (int i = 1; i <= n ; i++ ){ - if(id != i && !isValidSecret(shares[i - 1],i)) { - //message = new Message(Type.Complaint, j) - complaint = ComplaintMessage.newBuilder() - .setId(i) - .build(); - user.broadcast(Mail.Type.COMPLAINT,complaint); - complainStates[i - 1][id - 1] = ComplainState.Waiting; - } - } - //broadcast y after all complaints - YMessage yMessage = YMessage.newBuilder() - .setY(ByteString.copyFrom(super.getY().toByteArray())) - .build(); - user.broadcast(Mail.Type.Y,yMessage); - - while (!isStage2Complete()){ - try { - Thread.sleep(300); - } catch (InterruptedException e) { - // do nothing - } - } - } - - /** - * @return true iff all yi received for i = 1,...,n . - */ - private boolean isStage2Complete() { - for (int j = 1; j <= n ; j++) { - if (j != id && ys[j - 1] == null) - return false; - } - return true; - } - - - /** - * stage3 according to the protocol - * 1. if more than t players complain against a player Pi he is disqualified. - * 2. Pi broadcasts the share Sij for each complaining player Pj. - * 3. if any of the revealed shares fails the verification test, player Pi is disqualified. - * 4. set QUAL to be the set of non-disqualified players. - */ - private void stage3(){ - - // broadcasts Sij for each complaint against Pid - for (int j = 1 ; j <= complainStates[id - 1].length;j++) { - switch (complainStates[id - 1][j - 1]) { - case Waiting: - user.broadcast(Mail.Type.SECRET, SecretMessage.newBuilder() - .setSecret(getShare(j).asMessage()) - .build()); - complainStates[id - 1][j - 1] = ComplainState.NonDisqualified; - break; - default: - break; - } - } - - // wait until there is no complaint waiting for answer - for (int i = 0; i < complainStates.length;i++){ - for (int j = 0 ; j < complainStates[i].length;j++){ - while (complainStates[i][j].equals(ComplainState.Waiting)){ - try { - Thread.sleep(300); - } catch (InterruptedException e) { - // do nothing - } - } - } - } - - // add each non-disqualified player to QUAL - boolean nonDisqualified; - for (int i = 1; i <= complainStates.length;i++){ - nonDisqualified = true; - for (int j = 1 ; j <= complainStates[i - 1].length;j++){ - nonDisqualified &= complainStates[i - 1][j - 1].equals(ComplainState.Disqualified); - } - if(nonDisqualified){ - QUAL.add(i); - } - } - } - - /** - * stage4 according to the protocol - * 1. public value y is computed as y = multiplication of yi mod p for i in QUAL - * 2. public verification values are computed as Ak = multiplication of Aik mod p for i in QUAL for k = 0,...,t - * 3. Pj sets is share of the secret as xj = sum of Sij mod q for i in QUAL - */ - private void stage4(){ - this.y = zpstar.zero(); - for (int i : QUAL) { - this.y = zpstar.add(this.y , ys[i - 1]); - } - BigInteger commitment; - for (int k = 0; k <= t ; k++){ - commitment = zpstar.zero(); - for (int i : QUAL) { - commitment = zpstar.add(commitment,commitmentsArray[i - 1][k]); - } - commitments[k] = commitment; - } - - BigInteger xj = BigInteger.ZERO; - for (int i : QUAL) { - xj = xj.add(shares[i - 1].y); - } - this.share = new Polynomial.Point(BigInteger.valueOf(id) , xj.mod(q)); - } - - @Override - public BigInteger getY() { - return y; - } - - @Override - public BigInteger[] getCommitments() { - return Arrays.clone(commitments); - } - - - - - private enum ComplainState{ - Non, Waiting,Disqualified,NonDisqualified - } - - private class Handler implements Network.MailHandler { - - private Handler() {} - - void handelSecretMessage(Mail mail) throws InvalidProtocolBufferException { - if(shares[mail.getSender() - 1] == null) { - SecretMessage secretMessage = SecretMessage.parseFrom(mail.getMessage()); - Polynomial.Point secret = new Polynomial.Point(secretMessage.getSecret()); - if(mail.getIsPrivate()){ - shares[mail.getSender() - 1] = secret; - }else{ - int i = mail.getSender(); - int j = secret.x.intValue(); - switch (complainStates[i - 1][j - 1]){ - case Waiting: - if(isValidSecret(secret,i)){ - complainStates[i - 1][j - 1] = ComplainState.NonDisqualified; - }else{ - complainStates[i - 1][j - 1] = ComplainState.Disqualified; - } - break; - default: - break; - } - } - } - } - - void handelCommitmentMessage(Mail mail) throws InvalidProtocolBufferException { - if(!mail.getIsPrivate()) { //broadcast only - CommitmentMessage commitmentMessage = CommitmentMessage.parseFrom(mail.getMessage()); - if (commitmentsArray[mail.getSender() - 1][commitmentMessage.getK()] == null) { - BigInteger commitment = new BigInteger(commitmentMessage.getCommitment().toByteArray()); - commitmentsArray[mail.getSender() - 1][commitmentMessage.getK()] = commitment; - } - } - } - - void handelYMessage(Mail mail) throws InvalidProtocolBufferException { - if(!mail.getIsPrivate()) { //broadcast only - if (ys[mail.getSender() - 1] == null) { - YMessage yMessage = YMessage.parseFrom(mail.getMessage()); - BigInteger y = new BigInteger(yMessage.getY().toByteArray()); - ys[mail.getSender() - 1] = y; - } - } - } - - void handelComplaintMessage(Mail mail) throws InvalidProtocolBufferException { - int id = user.getID(); - if(!mail.getIsPrivate()) { //broadcast only - ComplaintMessage complaintMessage = ComplaintMessage.parseFrom(mail.getMessage()); - int i = complaintMessage.getId(); - int j = mail.getSender(); - switch (complainStates[i - 1][j - 1]){ - case Non: - complainStates[i - 1][j - 1] = ComplainState.Waiting; - break; - default: - break; - } - } - } - - @Override - public void handel(Mail mail) throws InvalidProtocolBufferException { - switch (mail.getType()){ - case SECRET: - handelSecretMessage(mail); - break; - case COMMITMENT: - handelCommitmentMessage(mail); - break; - case Y: - handelYMessage(mail); - break; - case COMPLAINT: - handelComplaintMessage(mail); - break; - default: - break; - } - } - } -} diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java new file mode 100644 index 0000000..a9bd311 --- /dev/null +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java @@ -0,0 +1,216 @@ +package JointFeldmanProtocol; + +import Communication.Network; +import Communication.User; +import ShamirSecretSharing.Polynomial; +import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; +import meerkat.protobuf.DKGMessages.*; +import org.factcenter.qilin.primitives.concrete.Zpstar; + +import java.math.BigInteger; +import java.util.HashSet; +import java.util.Random; +import java.util.Set; +import java.util.Arrays; + +/** + * Created by Tzlil on 2/5/2016. + * + * an implementation of a version of Pedersen's distributed key generation protocol + */ +public class DistributedKeyGeneration extends VerifiableSecretSharing implements Runnable{ + + private final int id; + + private final Set QUAL; // set of all non-disqualified parties + private final BigInteger[] finalCommitments; // public verification values + + private Polynomial.Point share; // final share of the secrete + private BigInteger y; // final public value + + private final DistributedKeyGenerationMessageHandler handler; + + public DistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger p, BigInteger q, BigInteger g + , User user) { + super(t, n, zi, random, p, q, g,user); + this.handler = (DistributedKeyGenerationMessageHandler) user.getMessageHandler(); + this.id = user.getID(); + this.QUAL = new HashSet(); + this.finalCommitments = new BigInteger[t + 1]; + Arrays.fill(this.finalCommitments,zpstar.zero()); + } + public DistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger p, BigInteger q, BigInteger g + , Network network) { + this(t,n,zi,random,p,q,g,network.connect(new DistributedKeyGenerationMessageHandler(t,n,g,new Zpstar(p)))); + } + + /** + * use for simulate real distributed protocol + */ + @Override + public void run() { + user.getReceiverThread().start(); + stage1(); + stage2(); + stage3(); + stage4(); + user.getReceiverThread().interrupt(); + } + + /** + * stage1 according to the protocol + * 1. Pi broadcasts Aik for k = 0,...,t. + * 2. Pi computes the shares Sij for j = 1,...,n and sends Sij secretly to Pj. + */ + protected void stage1(){ + super.run(); + while (!handler.isStage1Complete()){ + try { + Thread.sleep(300); + } catch (InterruptedException e) { + // do nothing + } + } + } + + /** + * stage2 according to the protocol + * Pj verifies all the shares he received (using isValidSecret) + * if check fails for an index i, Pj broadcasts a complaint against Pi. + * Pj broadcasts yj value at the end of this stage + */ + private void stage2(){ + ComplaintMessage complaint; + for (int i = 1; i <= n ; i++ ){ + if(id != i && !handler.isValidSecret(i)) { + //message = new Message(Type.Complaint, j) + complaint = ComplaintMessage.newBuilder() + .setId(i) + .build(); + user.broadcast(Mail.Type.COMPLAINT,complaint); + } + } + //broadcast done message after all complaints + DoneMessage doneMessage = DoneMessage.newBuilder().build(); + user.broadcast(Mail.Type.DONE,doneMessage); + + while (!handler.isStage2Complete()){ + try { + Thread.sleep(300); + } catch (InterruptedException e) { + // do nothing + } + } + } + + + + protected void answerComplaint(int j){ + user.broadcast(Mail.Type.SECRET, SecretMessage.newBuilder() + .setSecret(getShare(j).asMessage()) + .build()); + } + /** + * stage3 according to the protocol + * 1. if more than t players complain against a player Pi he is disqualified. + * 2. Pi broadcasts the share Sij for each complaining player Pj. + * 3. if any of the revealed shares fails the verification test, player Pi is disqualified. + * 4. set QUAL to be the set of non-disqualified players. + */ + private void stage3(){ + DistributedKeyGenerationMessageHandler.ComplainState[][] complainStates = handler.getComplainStates(); + // broadcasts Sij for each complaint against Pid + for (int j = 1; j <= complainStates[id - 1].length; j++) { + switch (complainStates[id - 1][j - 1]) { + case Waiting: + answerComplaint(j); + break; + default: + break; + } + } + + // wait until there is no complaint waiting for answer + for (int i = 0; i < complainStates.length; i++){ + for (int j = 0; j < complainStates[i].length; j++){ + while (complainStates[i][j].equals(DistributedKeyGenerationMessageHandler.ComplainState.Waiting)){ + try { + Thread.sleep(300); + } catch (InterruptedException e) { + // do nothing + } + } + } + } + + // add each non-disqualified player to QUAL + boolean nonDisqualified; + int counter; + for (int i = 1; i <= complainStates.length; i++){ + nonDisqualified = true; + counter = 0; + for (int j = 1; j <= complainStates[i - 1].length; j++){ + switch (complainStates[i - 1][j - 1]) { + case Non: + break; + case NonDisqualified: + counter++; + default: + nonDisqualified = false; + } + if(!nonDisqualified) + break; + } + if(nonDisqualified && counter <= t){ + QUAL.add(i); + } + } + } + + /** + * stage4 according to the protocol + * 1. public value y is computed as y = multiplication of yi mod p for i in QUAL + * 2. public verification values are computed as Ak = multiplication of Aik mod p for i in QUAL for k = 0,...,t + * 3. Pj sets is share of the secret as xj = sum of Sij mod q for i in QUAL + */ + private void stage4(){ + this.y = zpstar.zero(); + for (int i : QUAL) { + this.y = zpstar.add(this.y , handler.getY(i)); + } + + BigInteger[] commitments; + + for (int i : QUAL) { + commitments = handler.getCommitments(i); + for (int k = 0; k <= t; k++){ + this.finalCommitments[k] = zpstar.add(this.finalCommitments[k],commitments[k]); + } + } + + BigInteger xj = BigInteger.ZERO; + for (int i : QUAL) { + if( i == id){ + xj = xj.add(super.getShare(i).y); + }else{ + xj = xj.add(handler.getShare(i).y); + } + } + this.share = new Polynomial.Point(BigInteger.valueOf(id) , xj.mod(q)); + } + + @Override + public BigInteger getY() { + return y; + } + + @Override + public BigInteger[] getCommitments() { + return Arrays.copyOf(finalCommitments, finalCommitments.length); + } + + public Polynomial.Point getShare() { + return share; + } + +} diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMessageHandler.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMessageHandler.java new file mode 100644 index 0000000..2314469 --- /dev/null +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMessageHandler.java @@ -0,0 +1,161 @@ +package JointFeldmanProtocol; + +import Communication.MessageHandler; +import Communication.Network; +import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; +import FeldmanVerifiableSecretSharing.VerifiableSecretSharingMessageHandler; +import ShamirSecretSharing.Polynomial; +import ShamirSecretSharing.SecretSharingMessageHandler; +import meerkat.protobuf.DKGMessages; +import org.factcenter.qilin.primitives.concrete.Zpstar; + +import java.math.BigInteger; + +/** + * Created by Tzlil on 2/16/2016. + */ +public class DistributedKeyGenerationMessageHandler implements MessageHandler { + + protected enum ComplainState{ + Non, Waiting,Disqualified,NonDisqualified + } + + protected final VerifiableSecretSharingMessageHandler[] vssHandlers; + protected final ComplainState[][] complainStates; // complainStates[i][j] == state of Pj's complaint against Pi + protected final BigInteger g; + protected final Zpstar zpstar; + protected final int n; + private final boolean[] doneFlags; + + public DistributedKeyGenerationMessageHandler(int t, int n, BigInteger g, Zpstar zpstar) { + this.g = g; + this.zpstar = zpstar; + this.n = n; + this.doneFlags = new boolean[n]; + this.vssHandlers = new VerifiableSecretSharingMessageHandler[n]; + for (int i = 1; i <= n ; i++){ + vssHandlers[i - 1] = new VerifiableSecretSharingMessageHandler(t); + } + this.complainStates = new ComplainState[n][n]; + for (int i = 0; i < n; i ++){ + for (int j = 0 ; j < n ; j ++) + this.complainStates[i][j] = ComplainState.Non; + } + } + + /** + * @return true iff all shares and commitments were received + */ + protected boolean isStage1Complete(){ + for (int i = 1 ; i <= n ; i++){ + if(vssHandlers[i - 1].getShare() == null) + return false; + } + + BigInteger[] commitments; + for (int i = 0; i < vssHandlers.length; i++){ + commitments = vssHandlers[i].getCommitments(); + for (int j = 0; j < commitments.length; j++){ + if(commitments[j] == null) + return false; + } + } + return true; + } + + /** + * @return true iff all flags in doneFlags are true + */ + protected boolean isStage2Complete() { + for (int j = 0; j < n ; j++) { + if(!doneFlags[j]) + return false; + } + return true; + } + + @Override + public void handelComplaintMessage(int sender, boolean isBroadcast, DKGMessages.ComplaintMessage complaintMessage) { + if(isBroadcast){ + int i = complaintMessage.getId(); + int j = sender; + switch (complainStates[i - 1][j - 1]){ + case Non: + complainStates[i - 1][j - 1] = ComplainState.Waiting; + break; + default: + break; + } + } + } + + @Override + public void handelDoneMessage(int sender, boolean isBroadcast, DKGMessages.DoneMessage doneMessage) { + if(isBroadcast) + this.doneFlags[sender - 1] = true; + } + + @Override + public void handelCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage) { + vssHandlers[sender - 1].handelCommitmentMessage(sender, isBroadcast, commitmentMessage); + } + + + /** + * @param secret + * @param i + * @return g ^ Sij == verify(j,Ai,zpstar) (mod p) + */ + private boolean isValidSecret(Polynomial.Point secret, int i){ + int j = secret.x.intValue(); + BigInteger[] commitments = vssHandlers[i - 1].getCommitments(); + return zpstar.multiply(g,secret.y).equals(VerifiableSecretSharing.verify(j,commitments,zpstar)); + } + + protected boolean isValidSecret(int i){ + return isValidSecret(getShare(i),i); + } + + @Override + public void handelSecretMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage) { + vssHandlers[sender - 1].handelSecretMessage(sender, isBroadcast, secretMessage); + if(isBroadcast){ + Polynomial.Point secret = SecretSharingMessageHandler.extractSecret(secretMessage); + int i = sender; + int j = secret.x.intValue(); + switch (complainStates[i - 1][j - 1]){ + case Waiting: + if(isValidSecret(secret,i)){ + complainStates[i - 1][j - 1] = ComplainState.NonDisqualified; + }else{ + complainStates[i - 1][j - 1] = ComplainState.Disqualified; + } + break; + default: + break; + } + } + } + + @Override + public void handelDoubleSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { + // ignore + } + + + protected ComplainState[][] getComplainStates() { + return complainStates; + } + + protected BigInteger getY(int i){ + return vssHandlers[i - 1].getY(); + } + + protected BigInteger[] getCommitments(int i){ + return vssHandlers[i -1].getCommitments(); + } + + protected Polynomial.Point getShare(int i){ + return vssHandlers[i-1].getShare(); + } +} diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java deleted file mode 100644 index 70ab678..0000000 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java +++ /dev/null @@ -1,124 +0,0 @@ -package JointFeldmanProtocol; - -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/7/2016. - * JointFeldamn protocol assumes all parties can communicate throw broadcast chanel - * and private chanel (for each pair) - * this class simulates it - */ -public class Network { - - private final User[] users; - private final int n; - private final Queue availableIDs; - - - public Network(int n) { - this.n = n; - this.users = new User[n]; - this.availableIDs = new ArrayBlockingQueue(n); - for (int id = 1; id <= n; id++){ - availableIDs.add(id); - } - } - - public User connect(MailHandler messageHandler){ - Integer id = availableIDs.poll(); - if (id == null) - return null; - users[id - 1] = new User(id,messageHandler); - return users[id - 1]; - } - - private boolean sendMessage(User sender,int destination,Mail.Type type,Message message){ - if(destination < 1 || destination > n) - return false; - User user = users[destination - 1]; - if (user == null) - return false; - Mail mail = Mail.newBuilder() - .setSender(sender.getID()) - .setDestination(destination) - .setIsPrivate(true) - .setType(type) - .setMessage(message.toByteString()) - .build(); - return user.mailbox.add(mail); - } - - private void sendBroadcast(User sender,Mail.Type type,Message message){ - User user; - int ID = sender.ID; - Mail mail = Mail.newBuilder() - .setSender(sender.getID()) - .setDestination(0) - .setIsPrivate(false) - .setType(type) - .setMessage(message.toByteString()) - .build(); - for (int i = 0 ; i < n ; i++){ - if (i + 1 == ID) { - continue; - } - user = users[i]; - user.mailbox.add(mail); - } - } - - public class User{ - private final MailHandler messageHandler; - private final Queue mailbox; - private final int ID; - private final Thread receiverThread; - public User(int ID, MailHandler messageHandler) { - this.mailbox = new ArrayBlockingQueue(1 << n); - this.ID = ID; - this.messageHandler = messageHandler; - this.receiverThread = new Thread(new Receiver()); - } - - public boolean send(int id, Mail.Type type,Message message){ - return sendMessage(this,id,type,message); - } - public void broadcast(Mail.Type type,Message message){ - sendBroadcast(this,type,message); - } - public int getID() { - return ID; - } - public Thread getReceiverThread(){ - return receiverThread; - } - private class Receiver implements Runnable{ - @Override - public void run() { - while (true){ - if (!mailbox.isEmpty()){ - try { - messageHandler.handel(mailbox.poll()); - } catch (InvalidProtocolBufferException e) { - e.printStackTrace(); - } - }else{ - try { - Thread.sleep(30); - } catch (InterruptedException e) { - // do nothing - } - } - } - } - } - - - } - - public interface MailHandler { - public void handel(Mail mail) throws InvalidProtocolBufferException; - } -} diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGeneration.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGeneration.java new file mode 100644 index 0000000..cf0a429 --- /dev/null +++ b/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGeneration.java @@ -0,0 +1,68 @@ +package SecureDistributedKeyGeneration; + +import Communication.Network; +import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; +import JointFeldmanProtocol.DistributedKeyGeneration; +import com.google.protobuf.ByteString; +import meerkat.protobuf.DKGMessages; +import org.factcenter.qilin.primitives.concrete.Zpstar; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 2/17/2016. + */ +public class SecureDistributedKeyGeneration extends DistributedKeyGeneration { + + VerifiableSecretSharing verifiableSecretSharing; + + public SecureDistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger p, BigInteger q, BigInteger g + ,BigInteger h, Network network) { + super(t, n, zi, random, p, q, g, network.connect(new SecureDistributedKeyGenerationMessageHandler(t,n,g,new Zpstar(p)))); + this.verifiableSecretSharing = new VerifiableSecretSharing(t,n,new BigInteger(q.bitLength(), random).mod(q),random,p,q,h,user); + } + + @Override + protected void computeAndSendSecrets() { + DKGMessages.SecretMessage[] secretMessages1 = prepareSecretMessages(); + DKGMessages.SecretMessage[] secretMessages2 = verifiableSecretSharing.prepareSecretMessages(); + DKGMessages.DoubleSecretMessage doubleSecretMessage; + + for (int j = 1; j <= n ; j++ ){ + doubleSecretMessage = DKGMessages.DoubleSecretMessage.newBuilder() + .setS1(secretMessages1[j - 1]) + .setS1(secretMessages2[j - 1]) + .build(); + user.send(j, DKGMessages.Mail.Type.SECRET,doubleSecretMessage); + } + } + + @Override + public DKGMessages.CommitmentMessage[] prepareCommitmentMessages() { + DKGMessages.CommitmentMessage[] commitmentMessages = new DKGMessages.CommitmentMessage[t + 1]; + BigInteger[] commitments2 = verifiableSecretSharing.getCommitments(); + for (int k = 0; k <= t ; k ++) { + commitmentMessages[k] = DKGMessages.CommitmentMessage.newBuilder() + .setK(k) + .setCommitment(ByteString.copyFrom(zpstar.add(commitments[k],commitments2[k]).toByteArray())) + .build(); + } + return commitmentMessages; + } + + @Override + protected void answerComplaint(int j) { + DKGMessages.SecretMessage secretMessage1 = DKGMessages.SecretMessage.newBuilder() + .setSecret(getShare(j).asMessage()) + .build(); + DKGMessages.SecretMessage secretMessage2 = DKGMessages.SecretMessage.newBuilder() + .setSecret(verifiableSecretSharing.getShare(j).asMessage()) + .build(); + + user.broadcast(DKGMessages.Mail.Type.SECRET, DKGMessages.DoubleSecretMessage.newBuilder() + .setS1(secretMessage1) + .setS2(secretMessage2) + .build()); + } +} diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationMessageHandler.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationMessageHandler.java new file mode 100644 index 0000000..034f89c --- /dev/null +++ b/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationMessageHandler.java @@ -0,0 +1,61 @@ +package SecureDistributedKeyGeneration; + +import Communication.Network; +import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; +import JointFeldmanProtocol.DistributedKeyGenerationMessageHandler; +import ShamirSecretSharing.Polynomial; +import ShamirSecretSharing.SecretSharingMessageHandler; +import meerkat.protobuf.DKGMessages; +import org.factcenter.qilin.primitives.concrete.Zpstar; + +import java.math.BigInteger; + +/** + * Created by Tzlil on 2/17/2016. + */ +public class SecureDistributedKeyGenerationMessageHandler extends DistributedKeyGenerationMessageHandler { + + private final SecretSharingMessageHandler[] ssHandlers; + public SecureDistributedKeyGenerationMessageHandler(int t, int n, BigInteger g, Zpstar zpstar) { + super(t, n, g, zpstar); + this.ssHandlers = new SecretSharingMessageHandler[n]; + } + + private boolean isValidSecret(Polynomial.Point secret1,Polynomial.Point secret2,int i){ + int j = secret1.x.intValue(); + BigInteger[] commitments = vssHandlers[i - 1].getCommitments(); + return zpstar.multiply(g,zpstar.add(secret1.y,secret2.y)).equals(VerifiableSecretSharing.verify(j,commitments,zpstar)); + } + + @Override + protected boolean isValidSecret(int i) { + return isValidSecret(getShare(i),ssHandlers[i - 1].getShare(),i); + } + + + @Override + public void handelDoubleSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { + if(!isBroadcast){ + this.handelSecretMessage(sender,isBroadcast,doubleSecretMessage.getS1()); + ssHandlers[sender - 1].handelSecretMessage(sender,isBroadcast,doubleSecretMessage.getS2()); + }else{ + Polynomial.Point secret1 = SecretSharingMessageHandler.extractSecret(doubleSecretMessage.getS1()); + Polynomial.Point secret2 = SecretSharingMessageHandler.extractSecret(doubleSecretMessage.getS2()); + int i = sender; + int j = secret1.x.intValue(); + switch (complainStates[i - 1][j - 1]){ + case Waiting: + if(isValidSecret(secret1,secret2,i)){ + complainStates[i - 1][j - 1] = ComplainState.NonDisqualified; + }else{ + complainStates[i - 1][j - 1] = ComplainState.Disqualified; + } + break; + default: + break; + } + } + } + + +} diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/LagrangePolynomial.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java similarity index 97% rename from destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/LagrangePolynomial.java rename to destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java index 6754822..d3815ff 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/LagrangePolynomial.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java @@ -1,4 +1,4 @@ -package FeldmanVerifiableSecretSharing.ShamirSecretSharing; +package ShamirSecretSharing; import java.math.BigInteger; diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java similarity index 89% rename from destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java rename to destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java index 2bdf2ad..1c8eb0e 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java @@ -1,4 +1,4 @@ -package FeldmanVerifiableSecretSharing.ShamirSecretSharing; +package ShamirSecretSharing; import com.google.protobuf.ByteString; import meerkat.protobuf.DKGMessages; @@ -9,8 +9,8 @@ import java.math.BigInteger; * Created by Tzlil on 1/27/2016. */ public class Polynomial implements Comparable { - protected static final Polynomial ZERO = new Polynomial(new BigInteger[]{BigInteger.ZERO}); // neutral for add - protected static final Polynomial ONE = new Polynomial(new BigInteger[]{BigInteger.ONE}); // neutral for mul + public static final Polynomial ZERO = new Polynomial(new BigInteger[]{BigInteger.ZERO}); // neutral for add + public static final Polynomial ONE = new Polynomial(new BigInteger[]{BigInteger.ONE}); // neutral for mul private final int degree; private final BigInteger[] coefficients; @@ -45,7 +45,7 @@ public class Polynomial implements Comparable { @Override public String toString() { - return "FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests{" + + return "ShamirSecretSharing.PolynomialTests{" + "degree=" + degree + ", coefficients=" + java.util.Arrays.toString(coefficients) + '}'; @@ -101,7 +101,7 @@ public class Polynomial implements Comparable { /** * @param other - * @return new FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests of degree max(this degree,other degree) s.t for all x in Z + * @return new ShamirSecretSharing.PolynomialTests of degree max(this degree,other degree) s.t for all x in Z * new.image(x) = this.image(x) + other.image(x) */ public Polynomial add(Polynomial other){ @@ -123,7 +123,7 @@ public class Polynomial implements Comparable { /** * @param constant - * @return new FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests of degree this.degree s.t for all x in Z + * @return new ShamirSecretSharing.PolynomialTests of degree this.degree s.t for all x in Z * new.image(x) = constant * this.image(x) */ public Polynomial mul(BigInteger constant){ @@ -138,7 +138,7 @@ public class Polynomial implements Comparable { /** * @param other - * @return new FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests of degree this degree + other degree + 1 s.t for all x in Z + * @return new ShamirSecretSharing.PolynomialTests of degree this degree + other degree + 1 s.t for all x in Z * new.image(x) = this.image(x) * other.image(x) */ public Polynomial mul(Polynomial other){ diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java similarity index 64% rename from destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java rename to destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java index 9e3319d..de6b847 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java @@ -1,6 +1,10 @@ -package FeldmanVerifiableSecretSharing.ShamirSecretSharing; +package ShamirSecretSharing; +import Communication.Network; +import Communication.User; +import meerkat.protobuf.DKGMessages; + import java.math.BigInteger; import java.util.Random; @@ -8,11 +12,12 @@ import java.util.Random; * Created by Tzlil on 1/27/2016. * an implementation of Shamire's secret sharing scheme */ -public class SecretSharing { +public class SecretSharing implements Runnable{ protected final int t; protected final int n; protected final BigInteger q; + protected final User user; // send and receive messages throw network private final Polynomial polynomial; /** @@ -24,11 +29,16 @@ public class SecretSharing { * @param x secret, chosen from Zq * @param random use for generate random polynomial */ - public SecretSharing(int t, int n, BigInteger x, Random random,BigInteger q) { + public SecretSharing(int t, int n, BigInteger x, Random random, BigInteger q, Network network) { + this(t,n,x,random,q,network.connect(new SecretSharingMessageHandler())); + } + + public SecretSharing(int t, int n, BigInteger x, Random random, BigInteger q, User user) { this.q = q; this.t = t; this.n = n; this.polynomial = generateRandomPolynomial(x,random); + this.user = user; } /** @@ -53,18 +63,11 @@ public class SecretSharing { * * @return polynomial.image(i)%q */ - protected final Polynomial.Point getShare(int i){ + public Polynomial.Point getShare(int i){ assert (i > 0 && i <= n); return new Polynomial.Point(BigInteger.valueOf(i), polynomial, q); } - /** - * use for test only - */ - public Polynomial.Point getShareForTest(int i){ - return getShare(i); - } - /** * @param shares - subset of the original shares * @@ -99,8 +102,31 @@ public class SecretSharing { return q; } - protected Polynomial getPolynomial() { + public Polynomial getPolynomial() { return polynomial; } + + public DKGMessages.SecretMessage[] prepareSecretMessages(){ + DKGMessages.SecretMessage[] secretMessages = new DKGMessages.SecretMessage[n]; + for (int j = 1; j <= n ; j++ ){ + secretMessages[j - 1] = DKGMessages.SecretMessage.newBuilder() + .setSecret(getShare(j).asMessage()) + .build(); + } + return secretMessages; + } + + protected void computeAndSendSecrets(){ + DKGMessages.SecretMessage[] secretMessages = prepareSecretMessages(); + for (int j = 1; j <= n ; j++ ){ + user.send(j, DKGMessages.Mail.Type.SECRET,secretMessages[j - 1]); + } + } + + @Override + public void run() { + // computes and sends shares + computeAndSendSecrets(); + } } diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharingMessageHandler.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharingMessageHandler.java new file mode 100644 index 0000000..6230c05 --- /dev/null +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharingMessageHandler.java @@ -0,0 +1,47 @@ +package ShamirSecretSharing; + +import Communication.MessageHandler; +import Communication.Network; +import meerkat.protobuf.DKGMessages; + +/** + * Created by Tzlil on 2/16/2016. + */ +public class SecretSharingMessageHandler implements MessageHandler{ + + private Polynomial.Point share; + + @Override + public void handelComplaintMessage(int sender, boolean isBroadcast, DKGMessages.ComplaintMessage complaintMessage) { + // ignore + } + + @Override + public void handelDoneMessage(int sender, boolean isBroadcast, DKGMessages.DoneMessage doneMessage) { + // ignore + } + + @Override + public void handelCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage) { + // ignore + } + + @Override + public void handelDoubleSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { + // ignore + } + + @Override + public void handelSecretMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage) { + if(!isBroadcast) + this.share = extractSecret(secretMessage); + } + + public static Polynomial.Point extractSecret(DKGMessages.SecretMessage secretMessage){ + return new Polynomial.Point(secretMessage.getSecret()); + } + + public Polynomial.Point getShare() { + return share; + } +} diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java index 8a4f15d..f773237 100644 --- a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java +++ b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java @@ -1,6 +1,7 @@ package FeldmanVerifiableSecretSharing; -import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; +import Communication.Network; +import ShamirSecretSharing.Polynomial; import org.factcenter.qilin.primitives.concrete.Zpstar; import org.junit.Before; import org.junit.Test; @@ -31,11 +32,12 @@ public class VerifiableSecretSharingTest { }while (!g.equals(ZERO) && !zpstar.multiply(g,q).equals(ZERO));// sample from QRZp* int t = 8; int n = 20; - + Network network; verifiableSecretSharingArray = new VerifiableSecretSharing[tests]; for (int i = 0; i < verifiableSecretSharingArray.length; i++){ + network = new Network(n); verifiableSecretSharingArray[i] = new VerifiableSecretSharing(t,n - ,new BigInteger(q.bitLength(),random).mod(q),random,p,q,g); + ,new BigInteger(q.bitLength(),random).mod(q),random,p,q,g,network); } } @@ -47,7 +49,7 @@ public class VerifiableSecretSharingTest { BigInteger[] commitments = verifiableSecretSharing.getCommitments(); BigInteger[] verifications = new BigInteger[n]; for (int i = 1 ; i <= shares.length; i ++){ - shares[i - 1] = verifiableSecretSharing.getShareForTest(i); + shares[i - 1] = verifiableSecretSharing.getShare(i); verifications[i - 1] = VerifiableSecretSharing.verify(i,commitments,zpstar); } BigInteger expected; diff --git a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java index 98e58ed..9171f3d 100644 --- a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java +++ b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java @@ -1,10 +1,16 @@ package JointFeldmanProtocol; +import Communication.Network; +import ShamirSecretSharing.Polynomial; +import ShamirSecretSharing.SecretSharing; +import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; import org.factcenter.qilin.primitives.concrete.Zpstar; import org.junit.Before; import org.junit.Test; import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; import java.util.Random; /** @@ -13,45 +19,98 @@ import java.util.Random; public class DKGTest { - DKG[] dkgs; - Thread[] threads; - int tests = 1 << 10; - Random random; - + DistributedKeyGeneration[][] dkgsArrays; + Thread[][] threadsArrays; + int tests = 10; + BigInteger p = BigInteger.valueOf(2903); + BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); + BigInteger[] secrets; @Before public void settings(){ - BigInteger p = BigInteger.valueOf(2903); - BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); Zpstar zpstar = new Zpstar(p); - random = new Random(); + Random random = new Random(); BigInteger g; + int t = 9; + int n = 20; BigInteger ZERO = zpstar.zero(); - do{ - g = zpstar.sample(random); - }while (!g.equals(ZERO) && !zpstar.multiply(g,q).equals(ZERO));// sample from QRZp* - int t = 8; - int n = 20 - ; - Network network = new Network(n); - dkgs = new DKG[n]; - threads = new Thread[n]; - for (int i = 0 ; i < n ; i++) { - dkgs[i] = new DKG(t, n, new BigInteger(q.bitLength(), random).mod(q), random, p, q, g, network); - threads[i] = new Thread(dkgs[i]); + dkgsArrays = new DistributedKeyGeneration[tests][n]; + threadsArrays = new Thread[tests][n]; + secrets = new BigInteger[tests]; + for (int test = 0; test < tests; test++) { + do { + g = zpstar.sample(random); + } while (!g.equals(ZERO) && !zpstar.multiply(g, q).equals(ZERO));// sample from QRZp* + secrets[test] = BigInteger.ZERO; + Network network = new Network(n); + for (int i = 0; i < n; i++) { + BigInteger secret = new BigInteger(q.bitLength(), random).mod(q); + secrets[test] = secrets[test].add(secret).mod(q); + dkgsArrays[test][i] = new DistributedKeyGeneration(t, n,secret, random, p, q, g, network); + threadsArrays[test][i] = new Thread(dkgsArrays[test][i]); + } } } - @Test - public void DKGTest() throws Exception { - for (int i = 0 ; i < threads.length ; i++){ + public void oneTest(Thread[] threads, DistributedKeyGeneration[] dkgs,BigInteger secret) throws Exception { + for (int i = 0; i < threads.length ; i++){ threads[i].start(); } - for (int i = 0 ; i < threads.length ; i++){ + for (int i = 0; i < threads.length ; i++){ threads[i].join(); } + int t = dkgs[0].getT(); + int n = dkgs[0].getN(); + Zpstar zpstar = dkgs[0].getZpstar(); + BigInteger g = dkgs[0].getGenerator(); + + // got the right public value + assert(zpstar.multiply(g,secret).equals(dkgs[0].getY())); + + // assert all players agreed on the same public value for (int i = 0; i < dkgs.length - 1 ; i++){ assert (dkgs[i].getY().equals(dkgs[i+1].getY())); } + + // assert valid verification values + BigInteger expected,verification; + for (int j = 1; j <= dkgs.length ; j++){ + expected = zpstar.multiply(g, dkgs[j - 1].getShare().y); + verification = VerifiableSecretSharing.verify(j, dkgs[j - 1].getCommitments(),zpstar); + assert (expected.equals(verification)); + } + + + // restore the secret from t + 1 random shares + Polynomial.Point[] shares = new Polynomial.Point[t + 1]; + for (int i = 0 ; i < shares.length; i++){ + shares[i] = dkgs[i].getShare(); + } + //List indexes = new ArrayList(n); + //for (int i = 1 ; i <= n; i ++){ + // indexes.add(i); + //} + //Random random = new Random(); + //int index; + //for (int i = 0 ; i < shares.length ; i++){ + // index = indexes.remove(random.nextInt(indexes.size())); + // shares[i] = dkgs[index - 1].getShare(); + //} + BigInteger calculatedSecret = SecretSharing.getSecrete(shares).mod(q); + + Polynomial polynomial = Polynomial.ZERO; + for (int i = 0 ; i < dkgs.length ; i++){ + polynomial = polynomial.add(dkgs[i].getPolynomial()); + } + + assert (calculatedSecret.equals(secret)); + + } + + @Test + public void secretSharingTest() throws Exception { + for (int i = 0 ; i < dkgsArrays.length; i ++){ + oneTest(threadsArrays[i],dkgsArrays[i],secrets[i]); + } } } diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/AddTest.java b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/AddTest.java similarity index 87% rename from destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/AddTest.java rename to destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/AddTest.java index 1df4fef..288aed1 100644 --- a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/AddTest.java +++ b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/AddTest.java @@ -1,5 +1,5 @@ -package FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests; -import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; +package ShamirSecretSharing.PolynomialTests; +import ShamirSecretSharing.Polynomial; import org.junit.Before; import org.junit.Test; diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/InterpolationTest.java b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/InterpolationTest.java similarity index 92% rename from destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/InterpolationTest.java rename to destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/InterpolationTest.java index 53a50af..b1539cc 100644 --- a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/InterpolationTest.java +++ b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/InterpolationTest.java @@ -1,6 +1,6 @@ -package FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests; +package ShamirSecretSharing.PolynomialTests; -import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; +import ShamirSecretSharing.Polynomial; import org.junit.Before; import org.junit.Test; diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/MulByConstTest.java b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulByConstTest.java similarity index 87% rename from destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/MulByConstTest.java rename to destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulByConstTest.java index 6d9669a..0865058 100644 --- a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/MulByConstTest.java +++ b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulByConstTest.java @@ -1,6 +1,6 @@ -package FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests; +package ShamirSecretSharing.PolynomialTests; -import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; +import ShamirSecretSharing.Polynomial; import org.junit.Before; import org.junit.Test; diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/MulTest.java b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulTest.java similarity index 88% rename from destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/MulTest.java rename to destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulTest.java index fd4d761..418ea00 100644 --- a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/MulTest.java +++ b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulTest.java @@ -1,6 +1,6 @@ -package FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests; +package ShamirSecretSharing.PolynomialTests; -import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; +import ShamirSecretSharing.Polynomial; import org.junit.Before; import org.junit.Test; diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/Utils.java b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/Utils.java similarity index 76% rename from destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/Utils.java rename to destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/Utils.java index 67bd51c..47dca28 100644 --- a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/Utils.java +++ b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/Utils.java @@ -1,6 +1,6 @@ -package FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests; +package ShamirSecretSharing.PolynomialTests; -import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; +import ShamirSecretSharing.Polynomial; import java.math.BigInteger; import java.util.Random; diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharingTest.java b/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java similarity index 89% rename from destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharingTest.java rename to destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java index bc96f7f..02b8898 100644 --- a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharingTest.java +++ b/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java @@ -1,6 +1,7 @@ -package FeldmanVerifiableSecretSharing.ShamirSecretSharing; +package ShamirSecretSharing; -import FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests.Utils; +import Communication.Network; +import Communication.User; import org.factcenter.qilin.primitives.CyclicGroup; import org.factcenter.qilin.primitives.concrete.Zn; import org.junit.Before; @@ -26,14 +27,17 @@ public class SecretSharingTest { public void settings(){ BigInteger p = BigInteger.valueOf(2903); group = new Zn(p); - int t = 10; + int t = 9; int n = 20; random = new Random(); secretSharingArray = new SecretSharing[tests]; secrets = new BigInteger[tests]; + Network network; + for (int i = 0; i < secretSharingArray.length; i++){ secrets[i] = group.sample(random); - secretSharingArray[i] = new SecretSharing(t,n,secrets[i],random,p); + network = new Network(n); + secretSharingArray[i] = new SecretSharing(t,n,secrets[i],random,p,network); } } diff --git a/meerkat-common/src/main/proto/meerkat/DKGMessages.proto b/meerkat-common/src/main/proto/meerkat/DKGMessages.proto index e874f5a..c01b004 100644 --- a/meerkat-common/src/main/proto/meerkat/DKGMessages.proto +++ b/meerkat-common/src/main/proto/meerkat/DKGMessages.proto @@ -8,7 +8,7 @@ message Mail{ enum Type { SECRET = 0; COMMITMENT = 1; - Y = 2; + DONE = 2; COMPLAINT = 3; } int32 sender = 1; @@ -26,14 +26,17 @@ message SecretMessage { Point secret = 1; } +message DoubleSecretMessage{ + SecretMessage s1 = 1; + SecretMessage s2 = 2; +} + message CommitmentMessage{ int32 k = 1; bytes commitment = 2; } -message YMessage{ - bytes y = 1; -} +message DoneMessage{} message ComplaintMessage{ int32 id = 1; From aeb7c13436af18dde9455c82c40221ca0f6ba442 Mon Sep 17 00:00:00 2001 From: Arbel Deutsch Peled Date: Mon, 22 Feb 2016 08:04:01 +0200 Subject: [PATCH 21/49] Made read operations stream the results. Removed dependency on large Protobufs (BulletinBoardMessageList and BatchDataList). Partial implementation of Sync Query. Current version supports only H2 and MySQL (no SQLite support). --- .../bulletinboard/BulletinClientWorker.java | 2 +- .../bulletinboard/MultiServerWorker.java | 4 +- .../SimpleBulletinBoardClient.java | 2 +- .../SingleServerBulletinBoardClient.java | 56 ++-- .../bulletinboard/SingleServerWorker.java | 2 +- .../ThreadedBulletinBoardClient.java | 9 +- .../MultiServerGenericPostWorker.java | 2 - .../MultiServerGenericReadWorker.java | 4 +- .../MultiServerGetRedundancyWorker.java | 6 +- .../SingleServerGenericPostWorker.java | 4 +- .../SingleServerGetRedundancyWorker.java | 4 +- ...dedBulletinBoardClientIntegrationTest.java | 15 +- bulletin-board-server/build.gradle | 4 + .../sqlserver/BulletinBoardSQLServer.java | 265 ++++++++++++++---- .../sqlserver/H2QueryProvider.java | 18 +- .../sqlserver/MySQLQueryProvider.java | 27 +- .../mappers/BatchDataCallbackHandler.java | 32 +++ .../mappers/MessageCallbackHandler.java | 80 ++++++ .../sqlserver/mappers/MessageStubMapper.java | 31 ++ .../webapp/BulletinBoardWebApp.java | 94 ++++++- ...BulletinBoardSQLServerIntegrationTest.java | 38 ++- .../GenericBulletinBoardServerTest.java | 138 ++++++--- meerkat-common/build.gradle | 1 + .../bulletinboard/BulletinBoardConstants.java | 1 + .../bulletinboard/BulletinBoardServer.java | 19 +- .../meerkat/bulletinboard/CompleteBatch.java | 28 ++ .../java/meerkat/comm/MessageInputStream.java | 64 +++++ .../meerkat/comm/MessageOutputStream.java | 24 ++ .../src/main/java/meerkat/comm/Timestamp.java | 7 - .../util/BulletinBoardMessageGenerator.java | 98 +++++++ .../java/meerkat/util/BulletinBoardUtils.java | 42 +++ .../meerkat/util/TimeStampComparator.java | 30 ++ .../main/proto/meerkat/BulletinBoardAPI.proto | 51 +++- .../java/meerkat/comm/MessageStreamTest.java | 98 +++++++ 34 files changed, 1106 insertions(+), 194 deletions(-) create mode 100644 bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/BatchDataCallbackHandler.java create mode 100644 bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/MessageCallbackHandler.java create mode 100644 bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/MessageStubMapper.java create mode 100644 meerkat-common/src/main/java/meerkat/comm/MessageInputStream.java create mode 100644 meerkat-common/src/main/java/meerkat/comm/MessageOutputStream.java delete mode 100644 meerkat-common/src/main/java/meerkat/comm/Timestamp.java create mode 100644 meerkat-common/src/main/java/meerkat/util/BulletinBoardMessageGenerator.java create mode 100644 meerkat-common/src/main/java/meerkat/util/TimeStampComparator.java create mode 100644 meerkat-common/src/test/java/meerkat/comm/MessageStreamTest.java diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java index dba596b..1a4b62f 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java @@ -8,7 +8,7 @@ package meerkat.bulletinboard; */ public abstract class BulletinClientWorker { - protected IN payload; // Payload of the job + protected final IN payload; // Payload of the job private int maxRetry; // Number of retries for this job; set to -1 for infinite retries diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/MultiServerWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/MultiServerWorker.java index 727a922..7347f47 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/MultiServerWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/MultiServerWorker.java @@ -18,7 +18,7 @@ import java.util.concurrent.atomic.AtomicInteger; */ public abstract class MultiServerWorker extends BulletinClientWorker implements Runnable, FutureCallback{ - private List clients; + private final List clients; protected AtomicInteger minServers; // The minimal number of servers the job must be successful on for the job to be completed @@ -26,7 +26,7 @@ public abstract class MultiServerWorker extends BulletinClientWorker futureCallback; + private final FutureCallback futureCallback; /** * Constructor diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java index 8cac04d..633e495 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java @@ -125,7 +125,7 @@ public class SimpleBulletinBoardClient implements BulletinBoardClient{ * If at the operation is successful for some DB: return the results and stop iterating * If no operation is successful: return null (NOT blank list) * @param filterList return only messages that match the filters (null means no filtering). - * @return + * @return the list of Bulletin Board messages that are returned from a server */ @Override public List readMessages(MessageFilterList filterList) { diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java index e6070a5..ea0e93d 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java @@ -6,10 +6,12 @@ import com.google.common.util.concurrent.ListeningScheduledExecutorService; import com.google.common.util.concurrent.MoreExecutors; import com.google.protobuf.ByteString; import meerkat.bulletinboard.workers.singleserver.*; +import meerkat.comm.CommunicationException; import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.protobuf.Voting.BulletinBoardClientParams; import meerkat.util.BulletinBoardUtils; +import javax.ws.rs.NotFoundException; import java.util.Arrays; import java.util.Iterator; import java.util.LinkedList; @@ -31,15 +33,15 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i private final int MAX_RETRIES = 11; - protected ListeningScheduledExecutorService executorService; + private ListeningScheduledExecutorService executorService; protected BatchDigest batchDigest; private long lastServerErrorTime; - protected final long failDelayInMilliseconds; + private final long failDelayInMilliseconds; - protected final long subscriptionIntervalInMilliseconds; + private final long subscriptionIntervalInMilliseconds; /** * Notify the client that a job has failed @@ -86,8 +88,8 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i */ class RetryCallback implements FutureCallback { - private SingleServerWorker worker; - private FutureCallback futureCallback; + private final SingleServerWorker worker; + private final FutureCallback futureCallback; public RetryCallback(SingleServerWorker worker, FutureCallback futureCallback) { this.worker = worker; @@ -128,7 +130,8 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i */ class PostBatchDataListCallback implements FutureCallback { - private FutureCallback callback; + private final FutureCallback callback; + private AtomicInteger batchDataRemaining; private AtomicBoolean aggregatedResult; @@ -168,7 +171,7 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i */ class CompleteBatchReadCallback { - private FutureCallback callback; + private final FutureCallback callback; private List batchDataList; private BulletinBoardMessage batchMessage; @@ -176,7 +179,7 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i private AtomicInteger remainingQueries; private AtomicBoolean failed; - public CompleteBatchReadCallback(FutureCallback callback) { + public CompleteBatchReadCallback(FutureCallback callback) { this.callback = callback; @@ -193,11 +196,16 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i if (remainingQueries.decrementAndGet() == 0){ + String batchIdStr = BulletinBoardUtils.findTagWithPrefix(batchMessage, BulletinBoardConstants.BATCH_ID_TAG_PREFIX); + + if (batchIdStr == null){ + callback.onFailure(new CommunicationException("Server returned invalid message with no Batch ID tag")); + } + BeginBatchMessage beginBatchMessage = BeginBatchMessage.newBuilder() .setSignerId(batchMessage.getSig(0).getSignerId()) - .setBatchId(Integer.parseInt( - BulletinBoardUtils.findTagWithPrefix(batchMessage, BulletinBoardConstants.BATCH_ID_TAG_PREFIX))) + .setBatchId(Integer.parseInt(batchIdStr)) .addAllTag(BulletinBoardUtils.removePrefixTags(batchMessage, Arrays.asList(prefixes))) .build(); callback.onSuccess(new CompleteBatch(beginBatchMessage, batchDataList, batchMessage.getSig(0))); @@ -267,7 +275,7 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i class SubscriptionCallback implements FutureCallback> { private SingleServerReadMessagesWorker worker; - private MessageHandler messageHandler; + private final MessageHandler messageHandler; private MessageFilterList.Builder filterBuilder; @@ -339,7 +347,7 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i // Remove all but first DB address String dbAddress = meerkatDBs.get(0); - meerkatDBs = new LinkedList(); + meerkatDBs = new LinkedList<>(); meerkatDBs.add(dbAddress); } @@ -351,7 +359,7 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i SingleServerPostMessageWorker worker = new SingleServerPostMessageWorker(meerkatDBs.get(0), msg, MAX_RETRIES); // Submit worker and create callback - scheduleWorker(worker, new RetryCallback(worker, callback)); + scheduleWorker(worker, new RetryCallback<>(worker, callback)); // Calculate the correct message ID and return it batchDigest.reset(); @@ -362,8 +370,8 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i private class PostBatchDataCallback implements FutureCallback { - private CompleteBatch completeBatch; - FutureCallback callback; + private final CompleteBatch completeBatch; + private final FutureCallback callback; public PostBatchDataCallback(CompleteBatch completeBatch, FutureCallback callback) { this.completeBatch = completeBatch; @@ -391,8 +399,8 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i private class BeginBatchCallback implements FutureCallback { - private CompleteBatch completeBatch; - FutureCallback callback; + private final CompleteBatch completeBatch; + private final FutureCallback callback; public BeginBatchCallback(CompleteBatch completeBatch, FutureCallback callback) { this.completeBatch = completeBatch; @@ -438,7 +446,7 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i new SingleServerBeginBatchWorker(meerkatDBs.get(0), beginBatchMessage, MAX_RETRIES); // Submit worker and create callback - scheduleWorker(worker, new RetryCallback(worker, callback)); + scheduleWorker(worker, new RetryCallback<>(worker, callback)); } @@ -464,7 +472,7 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i new SingleServerPostBatchWorker(meerkatDBs.get(0), builder.build(), MAX_RETRIES); // Create worker with redundancy 1 and MAX_RETRIES retries - scheduleWorker(worker, new RetryCallback(worker, listCallback)); + scheduleWorker(worker, new RetryCallback<>(worker, listCallback)); // Increment position in batch startPosition++; @@ -502,7 +510,7 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i new SingleServerCloseBatchWorker(meerkatDBs.get(0), closeBatchMessage, MAX_RETRIES); // Submit worker and create callback - scheduleWorker(worker, new RetryCallback(worker, callback)); + scheduleWorker(worker, new RetryCallback<>(worker, callback)); } @@ -513,7 +521,7 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i SingleServerGetRedundancyWorker worker = new SingleServerGetRedundancyWorker(meerkatDBs.get(0), id, 1); // Submit job and create callback - scheduleWorker(worker, new RetryCallback(worker, callback)); + scheduleWorker(worker, new RetryCallback<>(worker, callback)); } @@ -524,7 +532,7 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i SingleServerReadMessagesWorker worker = new SingleServerReadMessagesWorker(meerkatDBs.get(0), filterList, 1); // Submit job and create callback - scheduleWorker(worker, new RetryCallback(worker, callback)); + scheduleWorker(worker, new RetryCallback<>(worker, callback)); } @@ -557,8 +565,8 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i CompleteBatchReadCallback completeBatchReadCallback = new CompleteBatchReadCallback(callback); // Submit jobs with wrapped callbacks - scheduleWorker(messageWorker, new RetryCallback(messageWorker, completeBatchReadCallback.asBulletinBoardMessageListFutureCallback())); - scheduleWorker(batchWorker, new RetryCallback(batchWorker, completeBatchReadCallback.asBatchDataListFutureCallback())); + scheduleWorker(messageWorker, new RetryCallback<>(messageWorker, completeBatchReadCallback.asBulletinBoardMessageListFutureCallback())); + scheduleWorker(batchWorker, new RetryCallback<>(batchWorker, completeBatchReadCallback.asBatchDataListFutureCallback())); } diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerWorker.java index 82ca886..ecebc12 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerWorker.java @@ -25,7 +25,7 @@ public abstract class SingleServerWorker extends BulletinClientWorker clients; + private List clients; - BatchDigest batchDigest; + private BatchDigest batchDigest; private final static int POST_MESSAGE_RETRY_NUM = 3; private final static int READ_MESSAGES_RETRY_NUM = 1; @@ -59,7 +59,7 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple executorService = Executors.newFixedThreadPool(JOBS_THREAD_NUM); - clients = new ArrayList(clientParams.getBulletinBoardAddressCount()); + clients = new ArrayList<>(clientParams.getBulletinBoardAddressCount()); for (String address : clientParams.getBulletinBoardAddressList()){ SingleServerBulletinBoardClient client = @@ -80,7 +80,6 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple * Retry failed DBs * @param msg is the message, * @return the message ID for later retrieval - * @throws CommunicationException */ @Override public MessageID postMessage(BulletinBoardMessage msg, FutureCallback callback){ diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGenericPostWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGenericPostWorker.java index 4ff96b1..8172e14 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGenericPostWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGenericPostWorker.java @@ -31,8 +31,6 @@ public abstract class MultiServerGenericPostWorker extends MultiServerWorker< * It accesses the servers one by one and tries to post the payload to each in turn * The method will only iterate once through the server list * Successful post to a server results in removing the server from the list - * @return The original job, but with a modified server list - * @throws CommunicationException */ public void run() { diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGenericReadWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGenericReadWorker.java index 68fc020..88b4ac1 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGenericReadWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGenericReadWorker.java @@ -14,7 +14,7 @@ import java.util.List; */ public abstract class MultiServerGenericReadWorker extends MultiServerWorker{ - protected Iterator clientIterator; + private final Iterator clientIterator; public MultiServerGenericReadWorker(List clients, int minServers, IN payload, int maxRetry, @@ -32,8 +32,6 @@ public abstract class MultiServerGenericReadWorker extends MultiServerW * This method carries out the actual communication with the servers via HTTP Post * It accesses the servers in a random order until one answers it * Successful retrieval from any server terminates the method and returns the received values; The list is not changed - * @return The original job and the list of messages found in the first server that answered the query - * @throws CommunicationException */ public void run(){ diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGetRedundancyWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGetRedundancyWorker.java index 517dbdf..748916b 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGetRedundancyWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/multiserver/MultiServerGetRedundancyWorker.java @@ -33,8 +33,6 @@ public class MultiServerGetRedundancyWorker extends MultiServerWorker= getClientNumber()){ - succeed(new Float(((float) serversContainingMessage.get()) / ((float) getClientNumber()) )); + succeed(((float) serversContainingMessage.get()) / ((float) getClientNumber())); } } @Override public void onFailure(Throwable t) { - onSuccess(new Float(0.0)); + onSuccess(0.0f); } } diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerGenericPostWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerGenericPostWorker.java index c56af05..621a828 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerGenericPostWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerGenericPostWorker.java @@ -19,7 +19,7 @@ import static meerkat.bulletinboard.BulletinBoardConstants.BULLETIN_BOARD_SERVER */ public class SingleServerGenericPostWorker extends SingleServerWorker { - private String subPath; + private final String subPath; public SingleServerGenericPostWorker(String serverAddress, String subPath, T payload, int maxRetry) { super(serverAddress, payload, maxRetry); @@ -37,7 +37,7 @@ public class SingleServerGenericPostWorker extends SingleServerWorker 0){ // Message exists in the server - return new Float(1.0); + return 1.0f; } else { // Message does not exist in the server - return new Float(0.0); + return 0.0f; } } catch (ProcessingException | IllegalStateException e) { diff --git a/bulletin-board-client/src/test/java/ThreadedBulletinBoardClientIntegrationTest.java b/bulletin-board-client/src/test/java/ThreadedBulletinBoardClientIntegrationTest.java index c266086..dfccebc 100644 --- a/bulletin-board-client/src/test/java/ThreadedBulletinBoardClientIntegrationTest.java +++ b/bulletin-board-client/src/test/java/ThreadedBulletinBoardClientIntegrationTest.java @@ -43,8 +43,8 @@ public class ThreadedBulletinBoardClientIntegrationTest { private static String KEYFILE_PASSWORD1 = "secret"; private static String KEYFILE_PASSWORD3 = "shh"; - public static String CERT1_PEM_EXAMPLE = "/certs/enduser-certs/user1.crt"; - public static String CERT3_PEM_EXAMPLE = "/certs/enduser-certs/user3.crt"; + private static String CERT1_PEM_EXAMPLE = "/certs/enduser-certs/user1.crt"; + private static String CERT3_PEM_EXAMPLE = "/certs/enduser-certs/user3.crt"; // Server data @@ -81,7 +81,7 @@ public class ThreadedBulletinBoardClientIntegrationTest { InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE); char[] password = KEYFILE_PASSWORD1.toCharArray(); - KeyStore.Builder keyStoreBuilder = null; + KeyStore.Builder keyStoreBuilder; try { keyStoreBuilder = signers[0].getPKCS12KeyStoreBuilder(keyStream, password); @@ -304,11 +304,11 @@ public class ThreadedBulletinBoardClientIntegrationTest { random = new Random(0); // We use insecure randomness in tests for repeatability - List testDB = new LinkedList(); + List testDB = new LinkedList<>(); testDB.add(BASE_URL); bulletinBoardClient.init(BulletinBoardClientParams.newBuilder() - .addBulletinBoardAddress("http://localhost:8081") + .addAllBulletinBoardAddress(testDB) .setMinRedundancy((float) 1.0) .build()); @@ -344,7 +344,6 @@ public class ThreadedBulletinBoardClientIntegrationTest { byte[] b1 = {(byte) 1, (byte) 2, (byte) 3, (byte) 4}; byte[] b2 = {(byte) 11, (byte) 12, (byte) 13, (byte) 14}; byte[] b3 = {(byte) 21, (byte) 22, (byte) 23, (byte) 24}; - byte[] b4 = {(byte) 4, (byte) 5, (byte) 100, (byte) -50, (byte) 0}; BulletinBoardMessage msg; @@ -353,8 +352,6 @@ public class ThreadedBulletinBoardClientIntegrationTest { MessageID messageID; - Comparator msgComparator = new BulletinBoardMessageComparator(); - msg = BulletinBoardMessage.newBuilder() .setMsg(UnsignedBulletinBoardMessage.newBuilder() .addTag("Signature") @@ -398,7 +395,7 @@ public class ThreadedBulletinBoardClientIntegrationTest { ) .build(); - msgList = new LinkedList(); + msgList = new LinkedList<>(); msgList.add(msg); readCallback = new ReadCallback(msgList); diff --git a/bulletin-board-server/build.gradle b/bulletin-board-server/build.gradle index 59045a2..8d824e7 100644 --- a/bulletin-board-server/build.gradle +++ b/bulletin-board-server/build.gradle @@ -101,6 +101,10 @@ task dbTest(type: Test) { outputs.upToDateWhen { false } } +task manualIntegration(type: Test) { + include '**/*IntegrationTest*' +} + task integrationTest(type: Test) { include '**/*IntegrationTest*' // debug = true diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java index a6313b6..b4e2949 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java @@ -1,13 +1,9 @@ package meerkat.bulletinboard.sqlserver; -import java.security.InvalidKeyException; -import java.security.SignatureException; -import java.security.cert.CertificateException; import java.sql.*; import java.util.*; -import com.google.protobuf.ByteString; -import com.google.protobuf.ProtocolStringList; +import com.google.protobuf.*; import meerkat.bulletinboard.*; import meerkat.bulletinboard.sqlserver.mappers.*; @@ -15,6 +11,7 @@ import static meerkat.bulletinboard.BulletinBoardConstants.*; import meerkat.comm.CommunicationException; +import meerkat.comm.MessageOutputStream; import meerkat.crypto.concrete.ECDSASignature; import meerkat.crypto.concrete.SHA256Digest; @@ -27,6 +24,8 @@ import static meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer.SQLQueryPro import javax.sql.DataSource; +import meerkat.util.BulletinBoardUtils; +import meerkat.util.TimestampComparator; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.support.GeneratedKeyHolder; @@ -62,8 +61,8 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ ), INSERT_MSG( - new String[] {"MsgId","Msg"}, - new int[] {Types.BLOB, Types.BLOB} + new String[] {"MsgId","TimeStamp","Msg"}, + new int[] {Types.BLOB, Types.TIMESTAMP, Types.BLOB} ), INSERT_NEW_TAG( @@ -91,6 +90,21 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ new int[] {} ), + COUNT_MESSAGES( + new String[] {}, + new int[] {} + ), + + GET_MESSAGE_STUBS( + new String[] {}, + new int[] {} + ), + + GET_LAST_MESSAGE_ENTRY( + new String[] {}, + new int[] {} + ), + GET_BATCH_MESSAGE_ENTRY( new String[] {"SignerId", "BatchId"}, new int[] {Types.BLOB, Types.INTEGER} @@ -161,7 +175,8 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ MSG_ID("MsgId", Types.BLOB), SIGNER_ID("SignerId", Types.BLOB), TAG("Tag", Types.VARCHAR), - LIMIT("Limit", Types.INTEGER); + LIMIT("Limit", Types.INTEGER), + TIMESTAMP("TimeStamp", Types.TIMESTAMP); private FilterTypeParam(String paramName, int paramType) { this.paramName = paramName; @@ -191,6 +206,10 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ case MAX_MESSAGES: return LIMIT; + case BEFORE_TIME: // Go through + case AFTER_TIME: + return TIMESTAMP; + default: return null; } @@ -269,6 +288,10 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ case MAX_MESSAGES: return messageFilter.getMaxMessages(); + case BEFORE_TIME: // Go through + case AFTER_TIME: + return BulletinBoardUtils.toSQLTimestamp(messageFilter.getTimestamp()); + default: // Unsupported filter type return null; } @@ -316,8 +339,6 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ */ private void createSchema() throws SQLException { - final int TIMEOUT = 20; - for (String command : sqlQueryProvider.getSchemaCreationCommands()) { jdbcTemplate.update(command,(Map) null); } @@ -423,7 +444,6 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ // Add message to table if needed and store entry number of message. - sql = sqlQueryProvider.getSQLString(QueryType.FIND_MSG_ID); Map namedParameters = new HashMap(); namedParameters.put(QueryType.FIND_MSG_ID.getParamName(0),msgID); @@ -437,7 +457,9 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ } else{ sql = sqlQueryProvider.getSQLString(QueryType.INSERT_MSG); - namedParameters.put(QueryType.INSERT_MSG.getParamName(1), msg.getMsg().toByteArray()); + + namedParameters.put(QueryType.INSERT_MSG.getParamName(1), BulletinBoardUtils.toSQLTimestamp(msg.getMsg().getTimestamp())); + namedParameters.put(QueryType.INSERT_MSG.getParamName(2), msg.getMsg().toByteArray()); KeyHolder keyHolder = new GeneratedKeyHolder(); jdbcTemplate.update(sql,new MapSqlParameterSource(namedParameters),keyHolder); @@ -504,37 +526,36 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ return postMessage(msg, true); // Perform a post and check the signature for authenticity } - @Override - public BulletinBoardMessageList readMessages(MessageFilterList filterList) throws CommunicationException { - BulletinBoardMessageList.Builder resultListBuilder = BulletinBoardMessageList.newBuilder(); + /** + * This is a container class for and SQL string builder and a MapSqlParameterSource to be used with it + */ + class SQLAndParameters { - // SQL length is roughly 50 characters per filter + 50 for the query itself - StringBuilder sqlBuilder = new StringBuilder(50 * (filterList.getFilterCount() + 1)); + public StringBuilder sql; + public MapSqlParameterSource parameters; - MapSqlParameterSource namedParameters; - int paramNum; + public SQLAndParameters(int numOfFilters) { + sql = new StringBuilder(50 * numOfFilters); + parameters = new MapSqlParameterSource(); + } - MessageMapper messageMapper = new MessageMapper(); - SignatureMapper signatureMapper = new SignatureMapper(); + } + + SQLAndParameters getSQLFromFilters(MessageFilterList filterList) { + + SQLAndParameters result = new SQLAndParameters(filterList.getFilterCount()); List filters = new ArrayList(filterList.getFilterList()); - boolean isFirstFilter = true; - Collections.sort(filters, new FilterTypeComparator()); - // Check if Tag/Signature tables are required for filtering purposes - - sqlBuilder.append(sqlQueryProvider.getSQLString(QueryType.GET_MESSAGES)); - // Add conditions - - namedParameters = new MapSqlParameterSource(); + boolean isFirstFilter = true; if (!filters.isEmpty()) { - sqlBuilder.append(" WHERE "); + result.sql.append(" WHERE "); - for (paramNum = 0 ; paramNum < filters.size() ; paramNum++) { + for (int paramNum = 0 ; paramNum < filters.size() ; paramNum++) { MessageFilter filter = filters.get(paramNum); @@ -542,15 +563,15 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ if (isFirstFilter) { isFirstFilter = false; } else { - sqlBuilder.append(" AND "); + result.sql.append(" AND "); } } - sqlBuilder.append(sqlQueryProvider.getCondition(filter.getType(), paramNum)); + result.sql.append(sqlQueryProvider.getCondition(filter.getType(), paramNum)); FilterTypeParam filterTypeParam = FilterTypeParam.getFilterTypeParamName(filter.getType()); - namedParameters.addValue( + result.parameters.addValue( filterTypeParam.getParamName() + Integer.toString(paramNum), getParam(filter), filterTypeParam.getParamType(), @@ -560,36 +581,56 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ } + return result; + + } + + + /** + * Used to retrieve just basic information about messages to allow calculation of checksum + * @param filterList is a filter list that defines which messages the client is interested in + * @return a list of Bulletin Board Messages that contain just the entry number, timestamp and message ID for each message + * The message ID is returned inside the message data field + */ + protected List readMessageStubs(MessageFilterList filterList) { + + StringBuilder sqlBuilder = new StringBuilder(50 * (filterList.getFilterCount() + 1)); + + sqlBuilder.append(sqlQueryProvider.getSQLString(QueryType.GET_MESSAGE_STUBS)); + + // Get Conditions + + SQLAndParameters sqlAndParameters = getSQLFromFilters(filterList); + + sqlBuilder.append(sqlAndParameters.sql); + // Run query - List msgBuilders = - jdbcTemplate.query(sqlBuilder.toString(), namedParameters, messageMapper); + return jdbcTemplate.query(sqlBuilder.toString(), sqlAndParameters.parameters, new MessageStubMapper()); - // Compile list of messages + } - for (BulletinBoardMessage.Builder msgBuilder : msgBuilders) { - // Retrieve signatures + @Override + public void readMessages(MessageFilterList filterList, MessageOutputStream out) throws CommunicationException { - namedParameters = new MapSqlParameterSource(); - namedParameters.addValue(QueryType.GET_SIGNATURES.getParamName(0), msgBuilder.getEntryNum()); + BulletinBoardMessageList.Builder resultListBuilder = BulletinBoardMessageList.newBuilder(); - List signatures = jdbcTemplate.query( - sqlQueryProvider.getSQLString(QueryType.GET_SIGNATURES), - namedParameters, - signatureMapper); + // SQL length is roughly 50 characters per filter + 50 for the query itself + StringBuilder sqlBuilder = new StringBuilder(50 * (filterList.getFilterCount() + 1)); - // Append signatures - msgBuilder.addAllSig(signatures); + // Check if Tag/Signature tables are required for filtering purposes - // Finalize message and add to message list. + sqlBuilder.append(sqlQueryProvider.getSQLString(QueryType.GET_MESSAGES)); - resultListBuilder.addMessage(msgBuilder.build()); + // Get conditions - } + SQLAndParameters sqlAndParameters = getSQLFromFilters(filterList); + sqlBuilder.append(sqlAndParameters.sql); - //Combine results and return. - return resultListBuilder.build(); + // Run query and stream the output using a MessageCallbackHandler + + jdbcTemplate.query(sqlBuilder.toString(), sqlAndParameters.parameters, new MessageCallbackHandler(jdbcTemplate, sqlQueryProvider, out)); } @@ -625,9 +666,23 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ .build()) .build(); - BulletinBoardMessageList messageList = readMessages(filterList); + // SQL length is roughly 50 characters per filter + 50 for the query itself + StringBuilder sqlBuilder = new StringBuilder(50 * (filterList.getFilterCount() + 1)); - return (messageList.getMessageList().size() > 0); + // Check if Tag/Signature tables are required for filtering purposes + + sqlBuilder.append(sqlQueryProvider.getSQLString(QueryType.COUNT_MESSAGES)); + + // Get conditions + + SQLAndParameters sqlAndParameters = getSQLFromFilters(filterList); + sqlBuilder.append(sqlAndParameters.sql); + + // Run query and stream the output using a MessageCallbackHandler + + List count = jdbcTemplate.query(sqlBuilder.toString(), sqlAndParameters.parameters, new LongMapper()); + + return (count.size() > 0) && (count.get(0) > 0); } @@ -767,6 +822,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ .addTag(BATCH_TAG) .addTag(batchIdToTag(batchId)) .setData(message.getSig().getSignerId()) + .setTimestamp(message.getTimestamp()) .build()) .build(); @@ -788,7 +844,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ } @Override - public BatchDataList readBatch(BatchSpecificationMessage message) throws CommunicationException, IllegalArgumentException{ + public void readBatch(BatchSpecificationMessage message, MessageOutputStream out) throws CommunicationException, IllegalArgumentException{ // Check that batch is closed if (!isBatchClosed(message.getSignerId(), message.getBatchId())) { @@ -802,9 +858,102 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1),message.getBatchId()); namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(2),message.getStartPosition()); - return BatchDataList.newBuilder() - .addAllData(jdbcTemplate.query(sql, namedParameters, new BatchDataMapper())) - .build(); + jdbcTemplate.query(sql, namedParameters, new BatchDataCallbackHandler(out)); + + } + + /** + * Finds the entry number of the last entry in the database + * @return the entry number, or -1 if no entries are found + */ + protected long getLastMessageEntry() { + + String sql = sqlQueryProvider.getSQLString(QueryType.GET_LAST_MESSAGE_ENTRY); + + List resultList = jdbcTemplate.query(sql, new LongMapper()); + + if (resultList.size() <= 0){ + return -1; + } + + return resultList.get(0); + + } + + /** + * Searches for the latest time of sync of the DB relative to a given query and returns the metadata needed to complete the sync + * The checksum up to (and including) each given timestamp is calculated using bitwise XOR on 8-byte sized blocks of the message IDs + * @param syncQuery contains a succinct representation of states to compare to + * @return the current last entry num and latest time of sync if there is one; -1 as last entry and empty timestamp otherwise + * @throws CommunicationException + */ + @Override + public SyncQueryResponse querySync(SyncQuery syncQuery) throws CommunicationException { + + if (syncQuery == null){ + return SyncQueryResponse.newBuilder() + .setLastEntryNum(-1) + .setLastTimeOfSync(com.google.protobuf.Timestamp.getDefaultInstance()) + .build(); + } + + com.google.protobuf.Timestamp lastTimeOfSync = null; + + TimestampComparator timestampComparator = new TimestampComparator(); + + long lastEntryNum = getLastMessageEntry(); + + long checksum = 0; + + Iterator queryIterator = syncQuery.getQueryList().iterator(); + + SingleSyncQuery currentQuery = queryIterator.next(); + + List messageStubs = readMessageStubs(syncQuery.getFilterList()); + + for (BulletinBoardMessage message : messageStubs){ + + // Check for end of current query + if (timestampComparator.compare(message.getMsg().getTimestamp(), currentQuery.getTimeOfSync()) > 0){ + + if (checksum == currentQuery.getChecksum()){ + lastTimeOfSync = currentQuery.getTimeOfSync(); + } else { + break; + } + + if (queryIterator.hasNext()){ + currentQuery = queryIterator.next(); + } else{ + break; + } + + } + + // Advance checksum + + ByteString messageID = message.getMsg().getData(); + + checksum &= messageID.byteAt(0) & messageID.byteAt(1) & messageID.byteAt(2) & messageID.byteAt(3); + + } + + if (checksum == currentQuery.getChecksum()){ + lastTimeOfSync = currentQuery.getTimeOfSync(); + } + + if (lastTimeOfSync == null){ + return SyncQueryResponse.newBuilder() + .setLastEntryNum(-1) + .setLastTimeOfSync(com.google.protobuf.Timestamp.getDefaultInstance()) + .build(); + } else{ + return SyncQueryResponse.newBuilder() + .setLastEntryNum(lastEntryNum) + .setLastTimeOfSync(lastTimeOfSync) + .build(); + } + } @Override diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java index 659d9c3..c390048 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java @@ -51,6 +51,12 @@ public class H2QueryProvider implements BulletinBoardSQLServer.SQLQueryProvider case GET_MESSAGES: return "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable"; + case COUNT_MESSAGES: + return "SELECT COUNT(MsgTable.EntryNum) FROM MsgTable"; + + case GET_MESSAGE_STUBS: + return "SELECT MsgTable.EntryNum, MsgTable.MsgId, MsgTable.ExactTime FROM MsgTable"; + case GET_SIGNATURES: return "SELECT Signature FROM SignatureTable WHERE EntryNum = :EntryNum"; @@ -61,6 +67,9 @@ public class H2QueryProvider implements BulletinBoardSQLServer.SQLQueryProvider return "INSERT INTO TagTable(Tag) SELECT DISTINCT :Tag AS NewTag FROM UtilityTable WHERE" + " NOT EXISTS (SELECT 1 FROM TagTable AS SubTable WHERE SubTable.Tag = :Tag)"; + case GET_LAST_MESSAGE_ENTRY: + return "SELECT MAX(MsgTable.EntryNum) FROM MsgTable"; + case GET_BATCH_MESSAGE_ENTRY: return MessageFormat.format( "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable" @@ -147,6 +156,13 @@ public class H2QueryProvider implements BulletinBoardSQLServer.SQLQueryProvider return "EXISTS (SELECT 1 FROM TagTable" + " INNER JOIN MsgTagTable ON TagTable.TagId = MsgTagTable.TagId" + " WHERE TagTable.Tag = :Tag" + serialString + " AND MsgTagTable.EntryNum = MsgTable.EntryNum)"; + + case BEFORE_TIME: + return "MsgTable.ExactTime <= :TimeStamp"; + + case AFTER_TIME: + return "MsgTable.ExactTime >= :TimeStamp"; + default: throw new IllegalArgumentException("Cannot serve a filter of type " + filterType); } @@ -190,7 +206,7 @@ public class H2QueryProvider implements BulletinBoardSQLServer.SQLQueryProvider public List getSchemaCreationCommands() { List list = new LinkedList(); - list.add("CREATE TABLE IF NOT EXISTS MsgTable (EntryNum INT NOT NULL AUTO_INCREMENT PRIMARY KEY, MsgId TINYBLOB UNIQUE, Msg BLOB)"); + list.add("CREATE TABLE IF NOT EXISTS MsgTable (EntryNum INT NOT NULL AUTO_INCREMENT PRIMARY KEY, MsgId TINYBLOB UNIQUE, ExactTime TIMESTAMP, Msg BLOB)"); list.add("CREATE TABLE IF NOT EXISTS TagTable (TagId INT NOT NULL AUTO_INCREMENT PRIMARY KEY, Tag VARCHAR(50) UNIQUE)"); diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java index e3bdef0..f99114e 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java @@ -62,6 +62,12 @@ public class MySQLQueryProvider implements SQLQueryProvider { case GET_MESSAGES: return "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable"; + case COUNT_MESSAGES: + return "SELECT COUNT(MsgTable.EntryNum) FROM MsgTable"; + + case GET_MESSAGE_STUBS: + return "SELECT MsgTable.EntryNum, MsgTable.MsgId, MsgTable.ExactTime FROM MsgTable"; + case GET_SIGNATURES: return MessageFormat.format( "SELECT Signature FROM SignatureTable WHERE EntryNum = :{0}", @@ -69,15 +75,19 @@ public class MySQLQueryProvider implements SQLQueryProvider { case INSERT_MSG: return MessageFormat.format( - "INSERT INTO MsgTable (MsgId, Msg) VALUES(:{0}, :{1})", + "INSERT INTO MsgTable (MsgId, ExactTime, Msg) VALUES(:{0}, :{1}, :{2})", QueryType.INSERT_MSG.getParamName(0), - QueryType.INSERT_MSG.getParamName(1)); + QueryType.INSERT_MSG.getParamName(1), + QueryType.INSERT_MSG.getParamName(2)); case INSERT_NEW_TAG: return MessageFormat.format( "INSERT IGNORE INTO TagTable(Tag) VALUES (:{0})", QueryType.INSERT_NEW_TAG.getParamName(0)); + case GET_LAST_MESSAGE_ENTRY: + return "SELECT MAX(MsgTable.EntryNum) FROM MsgTable"; + case GET_BATCH_MESSAGE_ENTRY: return MessageFormat.format( "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable" @@ -164,6 +174,13 @@ public class MySQLQueryProvider implements SQLQueryProvider { return "EXISTS (SELECT 1 FROM TagTable" + " INNER JOIN MsgTagTable ON TagTable.TagId = MsgTagTable.TagId" + " WHERE TagTable.Tag = :Tag" + serialString + " AND MsgTagTable.EntryNum = MsgTable.EntryNum)"; + + case BEFORE_TIME: + return "MsgTable.ExactTime <= :TimeStamp"; + + case AFTER_TIME: + return "MsgTable.ExactTime >= :TimeStamp"; + default: throw new IllegalArgumentException("Cannot serve a filter of type " + filterType); } @@ -187,6 +204,10 @@ public class MySQLQueryProvider implements SQLQueryProvider { case TAG: return "VARCHAR"; + case AFTER_TIME: // Go through + case BEFORE_TIME: + return "TIMESTAMP"; + default: throw new IllegalArgumentException("Cannot serve a filter of type " + filterType); } @@ -212,7 +233,7 @@ public class MySQLQueryProvider implements SQLQueryProvider { List list = new LinkedList(); list.add("CREATE TABLE IF NOT EXISTS MsgTable (EntryNum INT NOT NULL AUTO_INCREMENT PRIMARY KEY," - + " MsgId TINYBLOB, Msg BLOB, UNIQUE(MsgId(50)))"); + + " MsgId TINYBLOB, ExactTime TIMESTAMP, Msg BLOB, UNIQUE(MsgId(50)))"); list.add("CREATE TABLE IF NOT EXISTS TagTable (TagId INT NOT NULL AUTO_INCREMENT PRIMARY KEY, Tag VARCHAR(50), UNIQUE(Tag))"); diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/BatchDataCallbackHandler.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/BatchDataCallbackHandler.java new file mode 100644 index 0000000..9ad0dc7 --- /dev/null +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/BatchDataCallbackHandler.java @@ -0,0 +1,32 @@ +package meerkat.bulletinboard.sqlserver.mappers; + +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.comm.MessageOutputStream; +import meerkat.protobuf.BulletinBoardAPI.BatchData; +import org.springframework.jdbc.core.RowCallbackHandler; +import org.springframework.jdbc.core.RowMapper; + +import java.io.IOException; +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * Created by Arbel Deutsch Peled on 19-Dec-15. + */ +public class BatchDataCallbackHandler implements RowCallbackHandler { + + private final MessageOutputStream out; + + public BatchDataCallbackHandler(MessageOutputStream out) { + this.out = out; + } + + @Override + public void processRow(ResultSet rs) throws SQLException { + try { + out.writeMessage(BatchData.parseFrom(rs.getBytes(1))); + } catch (IOException e) { + //TODO: Log + } + } +} diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/MessageCallbackHandler.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/MessageCallbackHandler.java new file mode 100644 index 0000000..bdba241 --- /dev/null +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/MessageCallbackHandler.java @@ -0,0 +1,80 @@ +package meerkat.bulletinboard.sqlserver.mappers; + +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer.*; +import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer.SQLQueryProvider.*; +import meerkat.comm.MessageOutputStream; +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Crypto; +import org.springframework.jdbc.core.RowCallbackHandler; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; + +import java.io.IOException; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 21-Feb-16. + */ +public class MessageCallbackHandler implements RowCallbackHandler { + + NamedParameterJdbcTemplate jdbcTemplate; + SQLQueryProvider sqlQueryProvider; + MessageOutputStream out; + + public MessageCallbackHandler(NamedParameterJdbcTemplate jdbcTemplate, SQLQueryProvider sqlQueryProvider, MessageOutputStream out) { + + this.jdbcTemplate = jdbcTemplate; + this.sqlQueryProvider = sqlQueryProvider; + this.out = out; + + } + + @Override + public void processRow(ResultSet rs) throws SQLException { + + BulletinBoardMessage.Builder result; + + try { + + result = BulletinBoardMessage.newBuilder() + .setEntryNum(rs.getLong(1)) + .setMsg(UnsignedBulletinBoardMessage.parseFrom(rs.getBytes(2))); + + + } catch (InvalidProtocolBufferException e) { + //TODO: log + return; + } + + // Retrieve signatures + + MapSqlParameterSource sqlParameterSource = new MapSqlParameterSource(); + sqlParameterSource.addValue(QueryType.GET_SIGNATURES.getParamName(0), result.getEntryNum()); + + List signatures = jdbcTemplate.query( + sqlQueryProvider.getSQLString(QueryType.GET_SIGNATURES), + sqlParameterSource, + new SignatureMapper()); + + // Append signatures + result.addAllSig(signatures); + + // Finalize message and add to message list. + + try { + + out.writeMessage(result.build()); + + } catch (IOException e) { + + //TODO: log + e.printStackTrace(); + + } + + } + +} diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/MessageStubMapper.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/MessageStubMapper.java new file mode 100644 index 0000000..1f9c459 --- /dev/null +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/MessageStubMapper.java @@ -0,0 +1,31 @@ +package meerkat.bulletinboard.sqlserver.mappers; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; +import meerkat.protobuf.BulletinBoardAPI.UnsignedBulletinBoardMessage; +import meerkat.util.BulletinBoardUtils; +import org.springframework.jdbc.core.RowMapper; + +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * Created by Arbel Deutsch Peled on 11-Dec-15. + */ +public class MessageStubMapper implements RowMapper { + + @Override + public BulletinBoardMessage mapRow(ResultSet rs, int rowNum) throws SQLException { + + return BulletinBoardMessage.newBuilder() + .setEntryNum(rs.getLong(1)) + .setMsg(UnsignedBulletinBoardMessage.newBuilder() + .setData(ByteString.copyFrom(rs.getBytes(2))) + .setTimestamp(BulletinBoardUtils.toTimestampProto(rs.getTimestamp(3))) + .build()) + .build(); + + } + +} diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java index 766af19..2e4782f 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java @@ -3,13 +3,10 @@ package meerkat.bulletinboard.webapp; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; +import javax.ws.rs.*; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.StreamingOutput; import meerkat.bulletinboard.BulletinBoardServer; import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer; @@ -17,12 +14,19 @@ import meerkat.bulletinboard.sqlserver.H2QueryProvider; import meerkat.bulletinboard.sqlserver.MySQLQueryProvider; import meerkat.bulletinboard.sqlserver.SQLiteQueryProvider; import meerkat.comm.CommunicationException; +import meerkat.comm.MessageOutputStream; +import meerkat.protobuf.BulletinBoardAPI; import meerkat.protobuf.BulletinBoardAPI.*; import static meerkat.bulletinboard.BulletinBoardConstants.*; import static meerkat.rest.Constants.*; +import java.io.IOException; +import java.io.OutputStream; import java.util.List; +/** + * An implementation of the BulletinBoardServer which functions as a WebApp + */ @Path(BULLETIN_BOARD_SERVER_PATH) public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextListener{ @@ -88,15 +92,39 @@ public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextL init(); return bulletinBoard.postMessage(msg); } - + + @Override + public void readMessages(MessageFilterList filterList, MessageOutputStream out) throws CommunicationException { + init(); + bulletinBoard.readMessages(filterList, out); + } + + @Path(READ_MESSAGES_PATH) @POST @Consumes(MEDIATYPE_PROTOBUF) - @Produces(MEDIATYPE_PROTOBUF) - @Override - public BulletinBoardMessageList readMessages(MessageFilterList filterList) throws CommunicationException { - init(); - return bulletinBoard.readMessages(filterList); + /** + * Wrapper for the readMessages method which streams the output into the response + */ + public StreamingOutput readMessages(final MessageFilterList filterList) { + + return new StreamingOutput() { + + @Override + public void write(OutputStream output) throws IOException, WebApplicationException { + MessageOutputStream out = new MessageOutputStream<>(output); + + try { + init(); + bulletinBoard.readMessages(filterList, out); + } catch (CommunicationException e) { + //TODO: Log + out.writeMessage(null); + } + } + + }; + } @Path(BEGIN_BATCH_PATH) @@ -144,15 +172,53 @@ public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextL } } + + @Override + public void readBatch(BatchSpecificationMessage message, MessageOutputStream out) { + try { + init(); + bulletinBoard.readBatch(message, out); + } catch (CommunicationException | IllegalArgumentException e) { + System.err.println(e.getMessage()); + } + } + @Path(READ_BATCH_PATH) @POST @Consumes(MEDIATYPE_PROTOBUF) + /** + * Wrapper for the readBatch method which streams the output into the response + */ + public StreamingOutput readBatch(final BatchSpecificationMessage message) { + + return new StreamingOutput() { + + @Override + public void write(OutputStream output) throws IOException, WebApplicationException { + MessageOutputStream out = new MessageOutputStream<>(output); + + try { + init(); + bulletinBoard.readBatch(message, out); + } catch (CommunicationException e) { + //TODO: Log + out.writeMessage(null); + } + } + + }; + + } + + @Path(SYNC_QUERY_PATH) + @POST + @Consumes(MEDIATYPE_PROTOBUF) @Produces(MEDIATYPE_PROTOBUF) @Override - public BatchDataList readBatch(BatchSpecificationMessage message) { - try { + public SyncQueryResponse querySync(SyncQuery syncQuery) throws CommunicationException { + try{ init(); - return bulletinBoard.readBatch(message); + return bulletinBoard.querySync(syncQuery); } catch (CommunicationException | IllegalArgumentException e) { System.err.println(e.getMessage()); return null; diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/BulletinBoardSQLServerIntegrationTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/BulletinBoardSQLServerIntegrationTest.java index 4b8b586..744a086 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/BulletinBoardSQLServerIntegrationTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/BulletinBoardSQLServerIntegrationTest.java @@ -4,6 +4,8 @@ package meerkat.bulletinboard; import com.google.protobuf.ByteString; import com.google.protobuf.TextFormat; +import com.google.protobuf.Timestamp; +import meerkat.comm.MessageInputStream; import meerkat.protobuf.Crypto.*; import meerkat.protobuf.BulletinBoardAPI.*; import static meerkat.bulletinboard.BulletinBoardConstants.*; @@ -18,7 +20,10 @@ import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import java.io.InputStream; +import java.util.List; public class BulletinBoardSQLServerIntegrationTest { @@ -44,6 +49,16 @@ public class BulletinBoardSQLServerIntegrationTest { byte[] b3 = {(byte) 21, (byte) 22, (byte) 23, (byte) 24}; byte[] b4 = {(byte) 4, (byte) 5, (byte) 100, (byte) -50, (byte) 0}; + Timestamp t1 = Timestamp.newBuilder() + .setSeconds(8276482) + .setNanos(4314) + .build(); + + Timestamp t2 = Timestamp.newBuilder() + .setSeconds(987591) + .setNanos(1513) + .build(); + WebTarget webTarget; Response response; BoolMsg bool; @@ -51,7 +66,7 @@ public class BulletinBoardSQLServerIntegrationTest { BulletinBoardMessage msg; MessageFilterList filterList; - BulletinBoardMessageList msgList; + List msgList; // Test writing mechanism @@ -64,6 +79,7 @@ public class BulletinBoardSQLServerIntegrationTest { .addTag("Signature") .addTag("Trustee") .setData(ByteString.copyFrom(b1)) + .setTimestamp(t1) .build()) .addSig(Signature.newBuilder() .setType(SignatureType.DSA) @@ -87,6 +103,7 @@ public class BulletinBoardSQLServerIntegrationTest { .addTag("Vote") .addTag("Trustee") .setData(ByteString.copyFrom(b4)) + .setTimestamp(t2) .build()) .addSig(Signature.newBuilder() .setType(SignatureType.ECDSA) @@ -113,13 +130,20 @@ public class BulletinBoardSQLServerIntegrationTest { ) .build(); - response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(filterList, Constants.MEDIATYPE_PROTOBUF)); - System.err.println(response); - msgList = response.readEntity(BulletinBoardMessageList.class); - System.err.println("List size: " + msgList.getMessageCount()); + InputStream in = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(filterList, Constants.MEDIATYPE_PROTOBUF), InputStream.class); + + MessageInputStream inputStream = + MessageInputStream.MessageInputStreamFactory.createMessageInputStream(in, BulletinBoardMessage.class); + + msgList = inputStream.asList(); + System.err.println("List size: " + msgList.size()); System.err.println("This is the list:"); - System.err.println(TextFormat.printToString(msgList)); - assert msgList.getMessageCount() == 1; + + for (BulletinBoardMessage message : msgList) { + System.err.println(TextFormat.printToString(message)); + } + + assert msgList.size() == 1; } } diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java index 86a32de..e33c739 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java @@ -1,9 +1,12 @@ package meerkat.bulletinboard; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.lang.management.ManagementFactory; import java.lang.management.ThreadMXBean; +import java.lang.reflect.InvocationTargetException; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.KeyStore; @@ -16,17 +19,23 @@ import java.util.*; import com.google.protobuf.ByteString; +import com.google.protobuf.Timestamp; import meerkat.comm.CommunicationException; +import meerkat.comm.MessageInputStream; +import meerkat.comm.MessageOutputStream; +import meerkat.comm.MessageInputStream.MessageInputStreamFactory; import meerkat.crypto.concrete.ECDSASignature; import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.util.BulletinBoardUtils; import static org.junit.Assert.*; import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.MatcherAssert.assertThat; public class GenericBulletinBoardServerTest { protected BulletinBoardServer bulletinBoardServer; - private GenericBatchDigitalSignature signers[]; + private GenericBatchDigitalSignature[] signers; private ByteString[] signerIDs; private Random random; @@ -172,7 +181,8 @@ public class GenericBulletinBoardServerTest { for (i = 1; i <= MESSAGE_NUM; i++) { unsignedMsgBuilder = UnsignedBulletinBoardMessage.newBuilder() - .setData(ByteString.copyFrom(data[i - 1])); + .setData(ByteString.copyFrom(data[i - 1])) + .setTimestamp(BulletinBoardUtils.toTimestampProto()); // Add tags based on bit-representation of message number. @@ -232,28 +242,39 @@ public class GenericBulletinBoardServerTest { System.err.println("Starting to test tag and signature mechanism"); long start = threadBean.getCurrentThreadCpuTime(); - List messages; + List messages = new LinkedList<>(); // Check tag mechanism - + for (int i = 0 ; i < TAG_NUM ; i++){ // Retrieve messages having tag i try { - messages = bulletinBoardServer.readMessages( - MessageFilterList.newBuilder() - .addFilter(MessageFilter.newBuilder() - .setType(FilterType.TAG) - .setTag(tags[i]) - .build() - ) - .build() - ) - .getMessageList(); + MessageFilterList filterList = MessageFilterList.newBuilder() + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.TAG) + .setTag(tags[i]) + .build() + ) + .build(); - } catch (CommunicationException e) { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + bulletinBoardServer.readMessages(filterList, new MessageOutputStream(outputStream)); + + MessageInputStream inputStream = + MessageInputStreamFactory.createMessageInputStream(new ByteArrayInputStream( + outputStream.toByteArray()), + BulletinBoardMessage.class); + + messages = inputStream.asList(); + + } catch (CommunicationException | IOException e) { + fail(e.getMessage()); + return; + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { fail(e.getMessage()); return; } @@ -330,11 +351,26 @@ public class GenericBulletinBoardServerTest { ); try { - messages = bulletinBoardServer.readMessages(filterListBuilder.build()).getMessageList(); + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + bulletinBoardServer.readMessages(filterListBuilder.build(), new MessageOutputStream(outputStream)); + + MessageInputStream inputStream = + MessageInputStreamFactory.createMessageInputStream(new ByteArrayInputStream( + outputStream.toByteArray()), + BulletinBoardMessage.class); + + messages = inputStream.asList(); + } catch (CommunicationException e) { System.err.println("Failed retrieving multi-tag messages from DB: " + e.getMessage()); fail("Failed retrieving multi-tag messages from DB: " + e.getMessage()); return; + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | IOException e) { + System.err.println("Falied to read from stream while retrieving multi-tag messages: " + e.getMessage()); + fail("Falied to read from stream while retrieving multi-tag messages: " + e.getMessage()); + return; } expectedMsgCount /= 2; @@ -361,11 +397,26 @@ public class GenericBulletinBoardServerTest { .build()); try { - messages = bulletinBoardServer.readMessages(filterListBuilder.build()).getMessageList(); + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + bulletinBoardServer.readMessages(filterListBuilder.build(), new MessageOutputStream(outputStream)); + + MessageInputStream inputStream = + MessageInputStreamFactory.createMessageInputStream(new ByteArrayInputStream( + outputStream.toByteArray()), + BulletinBoardMessage.class); + + messages = inputStream.asList(); + } catch (CommunicationException e) { System.err.println("Failed retrieving multi-signature message from DB: " + e.getMessage()); fail("Failed retrieving multi-signature message from DB: " + e.getMessage()); return; + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | IOException e) { + System.err.println("Falied to read from stream while retrieving multi-signature message: " + e.getMessage()); + fail("Falied to read from stream while retrieving multi-signature message: " + e.getMessage()); + return; } assertThat(messages.size(), is(MESSAGE_NUM / 4)); @@ -388,7 +439,10 @@ public class GenericBulletinBoardServerTest { final int BATCH_ID = 100; - CompleteBatch completeBatch = new CompleteBatch(); + CompleteBatch completeBatch = new CompleteBatch(Timestamp.newBuilder() + .setSeconds(978325) + .setNanos(8097234) + .build()); BoolMsg result; // Create data @@ -429,11 +483,7 @@ public class GenericBulletinBoardServerTest { // Close batch - result = bulletinBoardServer.closeBatchMessage(CloseBatchMessage.newBuilder() - .setBatchId(BATCH_ID) - .setBatchLength(1) - .setSig(completeBatch.getSignature()) - .build()); + result = bulletinBoardServer.closeBatchMessage(completeBatch.getCloseBatchMessage()); assertThat("Was not able to close batch", result.getValue(), is(true)); @@ -457,7 +507,10 @@ public class GenericBulletinBoardServerTest { */ public void testPostBatch() throws CommunicationException, SignatureException { - CompleteBatch completeBatch = new CompleteBatch(); + CompleteBatch completeBatch = new CompleteBatch(Timestamp.newBuilder() + .setSeconds(12345) + .setNanos(1111) + .build()); int currentBatch = completeBatches.size(); BoolMsg result; @@ -523,11 +576,7 @@ public class GenericBulletinBoardServerTest { signers[0].updateContent(completeBatch); completeBatch.setSignature(signers[0].sign()); - result = bulletinBoardServer.closeBatchMessage(CloseBatchMessage.newBuilder() - .setBatchId(currentBatch) - .setBatchLength(tempBatchData.length) - .setSig(completeBatch.getSignature()) - .build()); + result = bulletinBoardServer.closeBatchMessage(completeBatch.getCloseBatchMessage()); assertThat("Could not close batch " + currentBatch, result.getValue(), is(true)); @@ -540,17 +589,32 @@ public class GenericBulletinBoardServerTest { for (CompleteBatch completeBatch : completeBatches) { - List batchDataList = - bulletinBoardServer.readBatch(BatchSpecificationMessage.newBuilder() - .setSignerId(completeBatch.getBeginBatchMessage().getSignerId()) - .setBatchId(completeBatch.getBeginBatchMessage().getBatchId()) - .setStartPosition(0) - .build()); + try { - assertThat("Non-matching batch data for batch " + completeBatch.getBeginBatchMessage().getBatchId(), - completeBatch.getBatchDataList().equals(batchDataList), is(true)); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + BatchSpecificationMessage batchSpecificationMessage = + BatchSpecificationMessage.newBuilder() + .setSignerId(completeBatch.getBeginBatchMessage().getSignerId()) + .setBatchId(completeBatch.getBeginBatchMessage().getBatchId()) + .setStartPosition(0) + .build(); + bulletinBoardServer.readBatch(batchSpecificationMessage, new MessageOutputStream(outputStream)); + + MessageInputStream inputStream = + MessageInputStreamFactory.createMessageInputStream(new ByteArrayInputStream( + outputStream.toByteArray()), + BatchData.class); + + List batchDataList = inputStream.asList(); + + assertThat("Non-matching batch data for batch " + completeBatch.getBeginBatchMessage().getBatchId(), + completeBatch.getBatchDataList().equals(batchDataList), is(true)); + + } catch (IOException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + assertThat("Error reading batch data list from input stream", false); + } } diff --git a/meerkat-common/build.gradle b/meerkat-common/build.gradle index 3783531..a9035b0 100644 --- a/meerkat-common/build.gradle +++ b/meerkat-common/build.gradle @@ -39,6 +39,7 @@ version += "${isSnapshot ? '-SNAPSHOT' : ''}" dependencies { // Logging compile 'org.slf4j:slf4j-api:1.7.7' + compile 'javax.ws.rs:javax.ws.rs-api:2.0.+' runtime 'ch.qos.logback:logback-classic:1.1.2' runtime 'ch.qos.logback:logback-core:1.1.2' diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardConstants.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardConstants.java index 6bfc06f..66652f8 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardConstants.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardConstants.java @@ -14,6 +14,7 @@ public interface BulletinBoardConstants { public static final String BEGIN_BATCH_PATH = "/beginbatch"; public static final String POST_BATCH_PATH = "/postbatch"; public static final String CLOSE_BATCH_PATH = "/closebatch"; + public static final String SYNC_QUERY_PATH = "/syncquery"; // Other Constants diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java index cbf06ff..0b279c2 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java @@ -1,9 +1,9 @@ package meerkat.bulletinboard; import meerkat.comm.CommunicationException; +import meerkat.comm.MessageOutputStream; import meerkat.protobuf.BulletinBoardAPI.*; -import java.util.List; /** * Created by Arbel on 07/11/15. @@ -32,10 +32,10 @@ public interface BulletinBoardServer{ /** * Read all messages posted matching the given filter * @param filterList return only messages that match the filters (empty list or null means no filtering) - * @return + * @param out is an output stream into which the matching messages are written * @throws CommunicationException on DB connection error */ - public BulletinBoardMessageList readMessages(MessageFilterList filterList) throws CommunicationException; + public void readMessages(MessageFilterList filterList, MessageOutputStream out) throws CommunicationException; /** * Informs server about a new batch message @@ -71,11 +71,20 @@ public interface BulletinBoardServer{ /** * Reads a batch message from the server (starting with the supplied position) * @param message specifies the signer ID and the batch ID to read as well as an (optional) start position - * @return an ordered list of batch messages starting from the specified start position (if given) or from the beginning (if omitted) + * @param out is a stream of the ordered batch messages starting from the specified start position (if given) or from the beginning (if omitted) * @throws CommunicationException on DB connection error * @throws IllegalArgumentException if message does not specify a batch */ - public BatchDataList readBatch(BatchSpecificationMessage message) throws CommunicationException, IllegalArgumentException; + public void readBatch(BatchSpecificationMessage message, MessageOutputStream out) throws CommunicationException, IllegalArgumentException; + + + /** + * Queries the database for sync status with respect to a given sync query + * @param syncQuery contains a succinct representation of states to compare to + * @return a SyncQueryResponse object containing the representation of the most recent state the database matches + * @throws CommunicationException + */ + public SyncQueryResponse querySync(SyncQuery syncQuery) throws CommunicationException; /** * This method closes the connection to the DB diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/CompleteBatch.java b/meerkat-common/src/main/java/meerkat/bulletinboard/CompleteBatch.java index 227c7ca..14e87e7 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/CompleteBatch.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/CompleteBatch.java @@ -1,5 +1,6 @@ package meerkat.bulletinboard; +import com.google.protobuf.Timestamp; import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.protobuf.Crypto.*; import meerkat.util.BulletinBoardMessageComparator; @@ -17,6 +18,7 @@ public class CompleteBatch { private BeginBatchMessage beginBatchMessage; private List batchDataList; private Signature signature; + private Timestamp timestamp; public CompleteBatch() { batchDataList = new LinkedList(); @@ -37,6 +39,16 @@ public class CompleteBatch { signature = newSignature; } + public CompleteBatch(BeginBatchMessage newBeginBatchMessage, List newDataList, Signature newSignature, Timestamp timestamp) { + this(newBeginBatchMessage, newDataList, newSignature); + this.timestamp = timestamp; + } + + public CompleteBatch(Timestamp timestamp) { + this(); + this.timestamp = timestamp; + } + public BeginBatchMessage getBeginBatchMessage() { return beginBatchMessage; } @@ -49,11 +61,16 @@ public class CompleteBatch { return signature; } + public Timestamp getTimestamp() { + return timestamp; + } + public CloseBatchMessage getCloseBatchMessage() { return CloseBatchMessage.newBuilder() .setBatchId(getBeginBatchMessage().getBatchId()) .setBatchLength(getBatchDataList().size()) .setSig(getSignature()) + .setTimestamp(getTimestamp()) .build(); } @@ -73,6 +90,10 @@ public class CompleteBatch { signature = newSignature; } + public void setTimestamp(Timestamp timestamp) { + this.timestamp = timestamp; + } + @Override public boolean equals(Object other) { @@ -105,6 +126,13 @@ public class CompleteBatch { result = result && signature.equals(otherBatch.getSignature()); } + if (timestamp == null) { + if (otherBatch.getTimestamp() != null) + return false; + } else { + result = result && timestamp.equals(otherBatch.getTimestamp()); + } + return result; } diff --git a/meerkat-common/src/main/java/meerkat/comm/MessageInputStream.java b/meerkat-common/src/main/java/meerkat/comm/MessageInputStream.java new file mode 100644 index 0000000..33deb3f --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/comm/MessageInputStream.java @@ -0,0 +1,64 @@ +package meerkat.comm; + +import com.google.protobuf.Message; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.util.LinkedList; +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 21-Feb-16. + * A input stream of Protobuf messages + */ +public class MessageInputStream{ + + private T.Builder builder; + + private InputStream in; + + MessageInputStream(InputStream in, Class type) throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { + this.in = in; + this.builder = (T.Builder) type.getMethod("newBuilder").invoke(type); + } + + /** + * Factory class for actually creating a MessageInputStream + */ + public static class MessageInputStreamFactory { + + public static MessageInputStream createMessageInputStream(InputStream in, Class type) + throws IOException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { + + return new MessageInputStream<>(in, type); + + } + + } + + public T readMessage() throws IOException{ + + builder.clear(); + builder.mergeDelimitedFrom(in); + return (T) builder.build(); + + } + + public boolean isAvailable() throws IOException { + return (in.available() > 0); + } + + public List asList() throws IOException{ + + List list = new LinkedList<>(); + + while (isAvailable()){ + list.add(readMessage()); + } + + return list; + + } + +} diff --git a/meerkat-common/src/main/java/meerkat/comm/MessageOutputStream.java b/meerkat-common/src/main/java/meerkat/comm/MessageOutputStream.java new file mode 100644 index 0000000..b55bc8e --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/comm/MessageOutputStream.java @@ -0,0 +1,24 @@ +package meerkat.comm; + +import com.google.protobuf.Message; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * Created by Arbel Deutsch Peled on 21-Feb-16. + * An output stream of Protobuf messages + */ +public class MessageOutputStream { + + private OutputStream out; + + public MessageOutputStream(OutputStream out) throws IOException { + this.out = out; + } + + public void writeMessage(T message) throws IOException { + message.writeDelimitedTo(out); + } + +} diff --git a/meerkat-common/src/main/java/meerkat/comm/Timestamp.java b/meerkat-common/src/main/java/meerkat/comm/Timestamp.java deleted file mode 100644 index 6c63854..0000000 --- a/meerkat-common/src/main/java/meerkat/comm/Timestamp.java +++ /dev/null @@ -1,7 +0,0 @@ -package meerkat.comm; - -/** - * Created by talm on 24/10/15. - */ -public class Timestamp { -} diff --git a/meerkat-common/src/main/java/meerkat/util/BulletinBoardMessageGenerator.java b/meerkat-common/src/main/java/meerkat/util/BulletinBoardMessageGenerator.java new file mode 100644 index 0000000..5ca3e0b --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/util/BulletinBoardMessageGenerator.java @@ -0,0 +1,98 @@ +package meerkat.util; + +import com.google.protobuf.ByteString; +import meerkat.crypto.DigitalSignature; +import meerkat.protobuf.BulletinBoardAPI.*; +import com.google.protobuf.Timestamp; + +import java.math.BigInteger; +import java.security.SignatureException; +import java.util.Arrays; +import java.util.Random; + +/** + * Created by Arbel Deutsch Peled on 21-Feb-16. + * This class contains methods used to generate random Bulletin Board Messages + */ +public class BulletinBoardMessageGenerator { + + private Random random; + + public BulletinBoardMessageGenerator(Random random) { + this.random = random; + } + + private byte randomByte(){ + return (byte) random.nextInt(); + } + + private String randomString(){ + return new BigInteger(130, random).toString(32); + } + + /** + * Generates a complete instance of a BulletinBoardMessage + * @param signers contains the (possibly multiple) credentials required to sign the message + * @param timestamp contains the time used in the message + * @param dataSize is the length of the data contained in the message + * @param tagNumber is the number of tags to generate + * @return a random, signed Bulletin Board Message containing random data and tags and the given timestamp + */ + + public BulletinBoardMessage generateRandomMessage(DigitalSignature[] signers, Timestamp timestamp, int dataSize, int tagNumber) + throws SignatureException { + + // Generate random data. + + byte[] data = new byte[dataSize]; + String[] tags = new String[tagNumber]; + + for (int i = 0; i < dataSize; i++) { + data[i] = randomByte(); + } + + for (int i = 0; i < tagNumber; i++) { + tags[i] = randomString(); + } + + UnsignedBulletinBoardMessage unsignedMessage = + UnsignedBulletinBoardMessage.newBuilder() + .setData(ByteString.copyFrom(data)) + .setTimestamp(timestamp) + .addAllTag(Arrays.asList(tags)) + .build(); + + BulletinBoardMessage.Builder messageBuilder = + BulletinBoardMessage.newBuilder() + .setMsg(unsignedMessage); + + for (int i = 0 ; i < signers.length ; i++) { + signers[i].updateContent(unsignedMessage); + messageBuilder.addSig(signers[i].sign()); + } + + return messageBuilder.build(); + + } + + /** + * Generates a complete instance of a BulletinBoardMessage + * @param signers contains the (possibly multiple) credentials required to sign the message + * @param dataSize is the length of the data contained in the message + * @param tagNumber is the number of tags to generate + * @return a random, signed Bulletin Board Message containing random data, tags and timestamp + */ + + public BulletinBoardMessage generateRandomMessage(DigitalSignature[] signers, int dataSize, int tagNumber) + throws SignatureException { + + Timestamp timestamp = Timestamp.newBuilder() + .setSeconds(random.nextLong()) + .setNanos(random.nextInt()) + .build(); + + return generateRandomMessage(signers, timestamp, dataSize, tagNumber); + + } + +} diff --git a/meerkat-common/src/main/java/meerkat/util/BulletinBoardUtils.java b/meerkat-common/src/main/java/meerkat/util/BulletinBoardUtils.java index b19bab3..d8b362c 100644 --- a/meerkat-common/src/main/java/meerkat/util/BulletinBoardUtils.java +++ b/meerkat-common/src/main/java/meerkat/util/BulletinBoardUtils.java @@ -62,4 +62,46 @@ public class BulletinBoardUtils { } + /** + * This method creates a Timestamp Protobuf from a time specification + * @param timeInMillis is the time to encode since the Epoch time in milliseconds + * @return a Timestamp Protobuf encoding of the given time + */ + public static com.google.protobuf.Timestamp toTimestampProto(long timeInMillis) { + + return com.google.protobuf.Timestamp.newBuilder() + .setSeconds(timeInMillis / 1000) + .setNanos((int) ((timeInMillis % 1000) * 1000000)) + .build(); + + } + + /** + * This method creates a Timestamp Protobuf from the current system time + * @return a Timestamp Protobuf encoding of the current system time + */ + public static com.google.protobuf.Timestamp toTimestampProto() { + + return toTimestampProto(System.currentTimeMillis()); + + } + + /** + * This method converts an SQL Timestamp object into a Protobuf Timestamp object + * @param sqlTimestamp is the SQL Timestamp + * @return an equivalent Protobuf Timestamp + */ + public static com.google.protobuf.Timestamp toTimestampProto(java.sql.Timestamp sqlTimestamp) { + return toTimestampProto(sqlTimestamp.getTime()); + } + + /** + * This method converts a Protobuf Timestamp object into an SQL Timestamp object + * @param protoTimestamp is the Protobuf Timestamp + * @return an equivalent SQL Timestamp + */ + public static java.sql.Timestamp toSQLTimestamp(com.google.protobuf.Timestamp protoTimestamp) { + return new java.sql.Timestamp(protoTimestamp.getSeconds() * 1000 + protoTimestamp.getNanos() / 1000000); + } + } diff --git a/meerkat-common/src/main/java/meerkat/util/TimeStampComparator.java b/meerkat-common/src/main/java/meerkat/util/TimeStampComparator.java new file mode 100644 index 0000000..1dc207b --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/util/TimeStampComparator.java @@ -0,0 +1,30 @@ +package meerkat.util; + +import com.google.protobuf.Timestamp; + +import java.util.Comparator; + +/** + * Created by Arbel Deutsch Peled on 20-Feb-16. + */ +public class TimestampComparator implements Comparator { + + @Override + public int compare(Timestamp o1, Timestamp o2) { + + if (o1.getSeconds() != o2.getSeconds()){ + + return o1.getSeconds() > o2.getSeconds() ? 2 : -2; + + } else if (o1.getNanos() != o2.getNanos()){ + + return o1.getNanos() > o2.getNanos() ? 1 : -1; + + } else{ + + return 0; + + } + + } +} diff --git a/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto b/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto index b86debd..fd95503 100644 --- a/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto +++ b/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto @@ -5,6 +5,7 @@ package meerkat; option java_package = "meerkat.protobuf"; import 'meerkat/crypto.proto'; +import 'google/protobuf/timestamp.proto'; message BoolMsg { bool value = 1; @@ -21,11 +22,14 @@ message MessageID { } message UnsignedBulletinBoardMessage { - // Optional tags describing message + // Optional tags describing message; Used for message retrieval repeated string tag = 1; + // Timestamp of the message (as defined by client) + google.protobuf.Timestamp timestamp = 2; + // The actual content of the message - bytes data = 2; + bytes data = 3; } message BulletinBoardMessage { @@ -38,6 +42,7 @@ message BulletinBoardMessage { // Signature of message (and tags), excluding the entry number. repeated meerkat.Signature sig = 3; + } message BulletinBoardMessageList { @@ -53,11 +58,13 @@ enum FilterType { MIN_ENTRY = 3; // Find all entries in database starting from specified entry number (chronological) SIGNER_ID = 4; // Find all entries in database that correspond to specific signature (signer) TAG = 5; // Find all entries in database that have a specific tag + AFTER_TIME = 6; // Find all entries in database that occurred on or after a given timestamp + BEFORE_TIME = 7; // Find all entries in database that occurred on or before a given timestamp // NOTE: The MAX_MESSAGES filter must remain the last filter type // This is because the condition it specifies in an SQL statement must come last in the statement // Keeping it last here allows for easily sorting the filters and keeping the code general - MAX_MESSAGES = 6; // Return at most some specified number of messages + MAX_MESSAGES = 8; // Return at most some specified number of messages } message MessageFilter { @@ -69,6 +76,7 @@ message MessageFilter { int64 entry = 3; string tag = 4; int64 maxMessages = 5; + google.protobuf.Timestamp timestamp = 6; } } @@ -89,9 +97,10 @@ message BeginBatchMessage { // This message is used to finalize and sign a batch transfer to the Bulletin Board Server message CloseBatchMessage { - int32 batchId = 1; // Unique identifier for the batch (unique per signer) - int32 batchLength = 2; // Number of messages in the batch - meerkat.Signature sig = 3; // Signature on the (ordered) batch messages + int32 batchId = 1; // Unique identifier for the batch (unique per signer) + int32 batchLength = 2; // Number of messages in the batch + google.protobuf.Timestamp timestamp = 3; // Timestamp of the batch (as defined by client) + meerkat.Signature sig = 4; // Signature on the (ordered) batch messages } // Container for single batch message data @@ -117,4 +126,34 @@ message BatchSpecificationMessage { bytes signerId = 1; // Unique signer identifier int32 batchId = 2; // Unique identifier for the batch (unique per signer) int32 startPosition = 3; // Position in batch to start reading from +} + +// This message is used to define a single query to the server to ascertain whether or not the server is synched with the client +// up till a specified timestamp +message SingleSyncQuery { + + google.protobuf.Timestamp timeOfSync = 1; + int64 checksum = 2; + +} + +// This message defines a complete server sync query +message SyncQuery { + + MessageFilterList filterList = 1; + + repeated SingleSyncQuery query = 2; + +} + +// This message defines the server's response format to a sync query +message SyncQueryResponse { + + // Serial entry number of current last entry in database + // Set to zero (0) in case no query checksums match + int64 lastEntryNum = 1; + + // Largest value of timestamp for which the checksums match + google.protobuf.Timestamp lastTimeOfSync = 2; + } \ No newline at end of file diff --git a/meerkat-common/src/test/java/meerkat/comm/MessageStreamTest.java b/meerkat-common/src/test/java/meerkat/comm/MessageStreamTest.java new file mode 100644 index 0000000..58dc7c1 --- /dev/null +++ b/meerkat-common/src/test/java/meerkat/comm/MessageStreamTest.java @@ -0,0 +1,98 @@ +package meerkat.comm; + +import com.google.protobuf.*; +import meerkat.comm.MessageInputStream.MessageInputStreamFactory; +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Crypto; +import meerkat.util.BulletinBoardMessageComparator; +import org.junit.Test; + +import java.io.*; +import java.lang.reflect.InvocationTargetException; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.IsEqual.equalTo; + +/** + * Created by Arbel Deutsch Peled on 21-Feb-16. + * Tests for MessageInputStream and MessageOutputStream classes + */ +public class MessageStreamTest { + + @Test + public void testWithBulletinBoardMessages() { + + MessageOutputStream out; + MessageInputStream in; + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + + BulletinBoardMessageComparator comparator = new BulletinBoardMessageComparator(); + + byte[] b1 = {(byte) 1, (byte) 2, (byte) 3, (byte) 4}; + byte[] b2 = {(byte) 11, (byte) 12, (byte) 13, (byte) 14}; + byte[] b3 = {(byte) 21, (byte) 22, (byte) 23, (byte) 24}; + + try { + + out = new MessageOutputStream<>(stream); + + } catch (IOException e) { + + System.err.println(e.getMessage()); + assertThat("Error creating streams: " + e.getMessage(), false); + return; + + } + + + + BulletinBoardMessage message = BulletinBoardMessage.newBuilder() + .setEntryNum(1) + .setMsg(UnsignedBulletinBoardMessage.newBuilder() + .setData(ByteString.copyFrom(b1)) + .addTag("Test") + .addTag("1234") + .setTimestamp(com.google.protobuf.Timestamp.newBuilder() + .setSeconds(19823451) + .setNanos(2134) + .build()) + .build()) + .addSig(Crypto.Signature.newBuilder() + .setSignerId(ByteString.copyFrom(b2)) + .setData(ByteString.copyFrom(b3)) + .build()) + .build(); + + try { + + out.writeMessage(message); + + } catch (IOException e) { + + System.err.println(e.getMessage()); + assertThat("Error writing message: " + e.getMessage(), false); + + } + + try { + + in = MessageInputStreamFactory.createMessageInputStream( + new ByteArrayInputStream(stream.toByteArray()), + BulletinBoardMessage.class); + + assertThat("Retrieved message was not identical to send message", comparator.compare(message, in.readMessage()), is(equalTo(0))); + + } catch (IOException e) { + + System.err.println(e.getMessage()); + assertThat("Error reading message: " + e.getMessage(), false); + + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + System.err.println(e.getMessage()); + assertThat("Error creating input stream " + e.getMessage(), false); + } + + } + +} From 0f7dbe3d50f1d20554d2d9ca7c58888b5943c375 Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Tue, 23 Feb 2016 19:02:49 +0200 Subject: [PATCH 22/49] SDKG tested for non coruppted parties --- .../main/java/Communication/MailHandler.java | 16 +- .../src/main/java/Communication/User.java | 4 +- .../VerifiableSecretSharing.java | 92 ++---- ...VerifiableSecretSharingMessageHandler.java | 40 --- .../DistributedKeyGeneration.java | 242 +++++++-------- ...istributedKeyGenerationMessageHandler.java | 161 ---------- .../DistributedKeyGenerationUserImpl.java | 288 ++++++++++++++++++ .../SecureDistributedKeyGeneration.java | 112 ++++--- ...istributedKeyGenerationMessageHandler.java | 61 ---- ...ecureDistributedKeyGenerationUserImpl.java | 138 +++++++++ .../ShamirSecretSharing/SecretSharing.java | 44 +-- .../SecretSharingMessageHandler.java | 47 --- .../DistributedKeyGenerationUser.java | 13 + .../java/UserInterface/SecretSharingUser.java | 14 + .../VerifiableSecretSharingUser.java | 16 + .../VerifiableSecretSharingTest.java | 9 +- .../java/JointFeldmanProtocol/DKGTest.java | 31 +- .../src/test/java/SDKGTest.java | 113 +++++++ .../SecretSharingTest.java | 8 +- .../src/main/proto/meerkat/DKGMessages.proto | 1 + 20 files changed, 842 insertions(+), 608 deletions(-) delete mode 100644 destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingMessageHandler.java delete mode 100644 destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMessageHandler.java create mode 100644 destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java delete mode 100644 destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationMessageHandler.java create mode 100644 destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationUserImpl.java delete mode 100644 destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharingMessageHandler.java create mode 100644 destributed-key-generation/src/main/java/UserInterface/DistributedKeyGenerationUser.java create mode 100644 destributed-key-generation/src/main/java/UserInterface/SecretSharingUser.java create mode 100644 destributed-key-generation/src/main/java/UserInterface/VerifiableSecretSharingUser.java create mode 100644 destributed-key-generation/src/test/java/SDKGTest.java diff --git a/destributed-key-generation/src/main/java/Communication/MailHandler.java b/destributed-key-generation/src/main/java/Communication/MailHandler.java index c70032f..618ba4f 100644 --- a/destributed-key-generation/src/main/java/Communication/MailHandler.java +++ b/destributed-key-generation/src/main/java/Communication/MailHandler.java @@ -9,14 +9,10 @@ import meerkat.protobuf.DKGMessages; public class MailHandler { private MessageHandler messageHandler; - public MailHandler(MessageHandler messageHandler){ this.messageHandler = messageHandler; } - public MessageHandler getMessageHandler(){ - return messageHandler; - } public void handel(DKGMessages.Mail mail) throws InvalidProtocolBufferException { switch (mail.getType()){ @@ -36,8 +32,20 @@ public class MailHandler { DKGMessages.ComplaintMessage complaintMessage = DKGMessages.ComplaintMessage.parseFrom(mail.getMessage()); messageHandler.handelComplaintMessage(mail.getSender(),mail.getDestination()== Network.BROADCAST,complaintMessage); break; + case DOUBLE: + DKGMessages.DoubleSecretMessage doubleSecretMessage = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage()); + messageHandler.handelDoubleSecretMessage(mail.getSender(),mail.getDestination()== Network.BROADCAST,doubleSecretMessage); default: break; } } + + + public MessageHandler getMessageHandler(){ + return messageHandler; + } + + public void setMessageHandler(MessageHandler messageHandler) { + this.messageHandler = messageHandler; + } } diff --git a/destributed-key-generation/src/main/java/Communication/User.java b/destributed-key-generation/src/main/java/Communication/User.java index e28347c..2de1ba1 100644 --- a/destributed-key-generation/src/main/java/Communication/User.java +++ b/destributed-key-generation/src/main/java/Communication/User.java @@ -33,8 +33,8 @@ public class User{ network.sendBroadcast(this,type,message); } - public MessageHandler getMessageHandler(){ - return mailHandler.getMessageHandler(); + public void setMessageHandler(MessageHandler messageHandler) { + mailHandler.setMessageHandler(messageHandler); } public int getID() { diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java index 796aaa9..51ae86e 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java @@ -1,12 +1,11 @@ package FeldmanVerifiableSecretSharing; -import Communication.Network; -import Communication.User; import ShamirSecretSharing.Polynomial; import ShamirSecretSharing.SecretSharing; -import com.google.protobuf.ByteString; -import meerkat.protobuf.DKGMessages; + import java.util.Arrays; + +import org.factcenter.qilin.primitives.Group; import org.factcenter.qilin.primitives.concrete.Zpstar; import java.math.BigInteger; @@ -21,31 +20,23 @@ import java.util.Random; * */ public class VerifiableSecretSharing extends SecretSharing { - protected final Zpstar zpstar; + protected final Group group; protected final BigInteger g; // public generator of group - private final BigInteger y; // y = g ^ x - protected final BigInteger[] commitments; + protected final BigInteger[] commitmentsArray; /** - * @param p a large prime - * @param q a large prime dividing p - 1. + * @param group + * @param q a large prime dividing group order. * @param g a generator of cyclic group of order q. - * the generated group is a subgroup of Zp*. + * the generated group is a subgroup of the given group. * it must be chosen such that computing discrete logarithms is hard in this group. */ - public VerifiableSecretSharing(int t, int n, BigInteger x, Random random, BigInteger p, BigInteger q, BigInteger g - , User user) { - super(t, n, x, random,q,user); + public VerifiableSecretSharing(int t, int n, BigInteger x, Random random, BigInteger q, BigInteger g + , Group group) { + super(t, n, x, random,q); this.g = g; - this.zpstar = new Zpstar(p); - assert (zpstar.contains(g)); - assert (p.subtract(BigInteger.ONE).mod(q).equals(BigInteger.ZERO)); // assert p - 1 % q == 0 - this.commitments = generateCommitments(); - this.y = zpstar.multiply(g,x); - } - - public VerifiableSecretSharing(int t, int n, BigInteger x, Random random, BigInteger p, BigInteger q, BigInteger g - , Network network) { - this(t,n,x,random,p,q,g,network.connect(new VerifiableSecretSharingMessageHandler(t))); + this.group = group; + assert (this.group.contains(g)); + this.commitmentsArray = generateCommitments(); } /** @@ -57,7 +48,7 @@ public class VerifiableSecretSharing extends SecretSharing { BigInteger[] coefficients = polynomial.getCoefficients(); BigInteger[] commitments = new BigInteger[coefficients.length]; for (int i = 0 ; i < commitments.length;i++){ - commitments[i] = zpstar.multiply(g,coefficients[i]); + commitments[i] = group.multiply(g,coefficients[i]); } return commitments; } @@ -65,16 +56,16 @@ public class VerifiableSecretSharing extends SecretSharing { /** * @param j share holder id * @param commitments - * @param zpstar + * @param group * - * @return product of commitments[j] ^ (i ^ j) == g ^ polynomial(i) + * @return product of commitmentsArray[j] ^ (i ^ j) == g ^ polynomial(i) */ - public static BigInteger verify(int j,BigInteger[] commitments,Zpstar zpstar) { - BigInteger v = zpstar.zero(); + public static BigInteger verify(int j,BigInteger[] commitments,Group group) { + BigInteger v = group.zero(); BigInteger power = BigInteger.ONE; BigInteger J = BigInteger.valueOf(j); for (int k = 0 ; k < commitments.length ; k ++){ - v = zpstar.add(v,zpstar.multiply(commitments[k],power)); + v = group.add(v,group.multiply(commitments[k],power)); power = power.multiply(J); } return v; @@ -91,49 +82,18 @@ public class VerifiableSecretSharing extends SecretSharing { /** * getter - * @return zpstar + * @return group */ - public Zpstar getZpstar(){ - return zpstar; + public Group getGroup(){ + return group; } /** * getter - * @return public value of this + * @return copy of commitmentsArray */ - public BigInteger getY(){ - return y; + public BigInteger[] getCommitmentsArray() { + return Arrays.copyOf(commitmentsArray, commitmentsArray.length); } - /** - * getter - * @return copy of commitments - */ - public BigInteger[] getCommitments() { - return Arrays.copyOf(commitments,commitments.length); - } - - public DKGMessages.CommitmentMessage[] prepareCommitmentMessages(){ - DKGMessages.CommitmentMessage[] commitmentMessages = new DKGMessages.CommitmentMessage[t + 1]; - for (int k = 0; k <= t ; k ++) { - commitmentMessages[k] = DKGMessages.CommitmentMessage.newBuilder() - .setK(k) - .setCommitment(ByteString.copyFrom(commitments[k].toByteArray())) - .build(); - } - return commitmentMessages; - } - - protected void computeAndSendCommitments(){ - DKGMessages.CommitmentMessage[] commitmentMessages = prepareCommitmentMessages(); - for (int k = 0; k <= t ; k ++){ - user.broadcast(DKGMessages.Mail.Type.COMMITMENT,commitmentMessages[k]); - } - } - - @Override - public void run() { - super.run(); - computeAndSendCommitments(); - } } diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingMessageHandler.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingMessageHandler.java deleted file mode 100644 index bfa23e5..0000000 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingMessageHandler.java +++ /dev/null @@ -1,40 +0,0 @@ -package FeldmanVerifiableSecretSharing; - -import Communication.Network; -import ShamirSecretSharing.SecretSharingMessageHandler; -import meerkat.protobuf.DKGMessages; - - -import java.math.BigInteger; -import java.util.Arrays; - -/** - * Created by Tzlil on 2/16/2016. - */ -public class VerifiableSecretSharingMessageHandler extends SecretSharingMessageHandler { - - private final BigInteger[] commitments; - - public VerifiableSecretSharingMessageHandler(int t) { - this.commitments = new BigInteger[t + 1]; - } - - public static BigInteger extractCommitment(DKGMessages.CommitmentMessage commitmentMessage){ - return new BigInteger(commitmentMessage.getCommitment().toByteArray()); - } - - @Override - public void handelCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage) { - if(isBroadcast) { // receive in broadcast only - commitments[commitmentMessage.getK()] = extractCommitment(commitmentMessage); - } - } - - public BigInteger[] getCommitments() { - return commitments; - } - - public BigInteger getY(){ - return commitments[0]; - } -} diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java index a9bd311..bf789f1 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java @@ -1,156 +1,138 @@ package JointFeldmanProtocol; -import Communication.Network; import Communication.User; import ShamirSecretSharing.Polynomial; import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; +import com.google.protobuf.ByteString; import meerkat.protobuf.DKGMessages.*; -import org.factcenter.qilin.primitives.concrete.Zpstar; +import org.factcenter.qilin.primitives.Group; import java.math.BigInteger; +import java.util.Arrays; import java.util.HashSet; import java.util.Random; import java.util.Set; -import java.util.Arrays; /** * Created by Tzlil on 2/5/2016. * * an implementation of a version of Pedersen's distributed key generation protocol */ -public class DistributedKeyGeneration extends VerifiableSecretSharing implements Runnable{ +public class DistributedKeyGeneration extends VerifiableSecretSharing{ - private final int id; + protected final int id; + protected Polynomial.Point[] shares; - private final Set QUAL; // set of all non-disqualified parties - private final BigInteger[] finalCommitments; // public verification values - - private Polynomial.Point share; // final share of the secrete - private BigInteger y; // final public value - - private final DistributedKeyGenerationMessageHandler handler; - - public DistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger p, BigInteger q, BigInteger g - , User user) { - super(t, n, zi, random, p, q, g,user); - this.handler = (DistributedKeyGenerationMessageHandler) user.getMessageHandler(); - this.id = user.getID(); - this.QUAL = new HashSet(); - this.finalCommitments = new BigInteger[t + 1]; - Arrays.fill(this.finalCommitments,zpstar.zero()); - } - public DistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger p, BigInteger q, BigInteger g - , Network network) { - this(t,n,zi,random,p,q,g,network.connect(new DistributedKeyGenerationMessageHandler(t,n,g,new Zpstar(p)))); + public DistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger q, BigInteger g + , Group group, int id) { + super(t, n, zi, random, q, g,group); + this.id = id; + this.shares = null; } /** - * use for simulate real distributed protocol + * stage1.1 according to the protocol + * Pi broadcasts Aik for k = 0,...,t. */ - @Override - public void run() { - user.getReceiverThread().start(); - stage1(); - stage2(); - stage3(); - stage4(); - user.getReceiverThread().interrupt(); + public void broadcastCommitments(User user){ + broadcastCommitments(user,commitmentsArray); + } + + public void broadcastCommitments(User user, BigInteger[] commitments){ + CommitmentMessage commitmentMessage; + for (int k = 0; k <= t ; k++){ + commitmentMessage = CommitmentMessage.newBuilder() + .setCommitment(ByteString.copyFrom(commitments[k].toByteArray())) + .setK(k) + .build(); + user.broadcast(Mail.Type.COMMITMENT, commitmentMessage); + } + } + + public void sendSecret(User user, int j){ + SecretMessage.Point secret = getShare(j).asMessage(); + user.send(j, Mail.Type.DOUBLE,SecretMessage.newBuilder().setSecret(secret).build()); } /** - * stage1 according to the protocol - * 1. Pi broadcasts Aik for k = 0,...,t. - * 2. Pi computes the shares Sij for j = 1,...,n and sends Sij secretly to Pj. + * stage1.2 according to the protocol + * Pi computes the shares Sij for j = 1,...,n and sends Sij secretly to Pj. */ - protected void stage1(){ - super.run(); - while (!handler.isStage1Complete()){ - try { - Thread.sleep(300); - } catch (InterruptedException e) { - // do nothing + public void sendSecrets(User user){ + for (int j = 1; j <= n ; j++){ + if(j != id){ + sendSecret(user,j); } } } + public boolean isValidSecret(int j,BigInteger[] commitments,int i){ + Polynomial.Point secret = shares[j - 1]; + return isValidSecret(secret,commitments,i); + } + + public boolean isValidSecret(Polynomial.Point secret, BigInteger[] commitments, int i){ + BigInteger v = verify(i,commitments,group); + return group.multiply(g,secret.y).equals(v); + } + /** * stage2 according to the protocol * Pj verifies all the shares he received (using isValidSecret) * if check fails for an index i, Pj broadcasts a complaint against Pi. - * Pj broadcasts yj value at the end of this stage */ - private void stage2(){ + public void broadcastComplains(User user, BigInteger[][]commitmentsTable){ ComplaintMessage complaint; - for (int i = 1; i <= n ; i++ ){ - if(id != i && !handler.isValidSecret(i)) { - //message = new Message(Type.Complaint, j) - complaint = ComplaintMessage.newBuilder() - .setId(i) - .build(); - user.broadcast(Mail.Type.COMPLAINT,complaint); - } - } - //broadcast done message after all complaints - DoneMessage doneMessage = DoneMessage.newBuilder().build(); - user.broadcast(Mail.Type.DONE,doneMessage); - - while (!handler.isStage2Complete()){ - try { - Thread.sleep(300); - } catch (InterruptedException e) { - // do nothing + for (int j = 1; j <= n ; j++ ){ + if(j != id) { + if (!isValidSecret(j,commitmentsTable[j - 1],id)) { + //message = new Message(Type.Complaint, j) + complaint = ComplaintMessage.newBuilder() + .setId(j) + .build(); + user.broadcast(Mail.Type.COMPLAINT, complaint); + } } } } - - protected void answerComplaint(int j){ + public void broadcastComplaintAnswer(User user, int j){ user.broadcast(Mail.Type.SECRET, SecretMessage.newBuilder() .setSecret(getShare(j).asMessage()) .build()); } + /** - * stage3 according to the protocol - * 1. if more than t players complain against a player Pi he is disqualified. - * 2. Pi broadcasts the share Sij for each complaining player Pj. - * 3. if any of the revealed shares fails the verification test, player Pi is disqualified. - * 4. set QUAL to be the set of non-disqualified players. + * stage3.1 according to the protocol + * if more than t players complain against a player Pi he is disqualified. */ - private void stage3(){ - DistributedKeyGenerationMessageHandler.ComplainState[][] complainStates = handler.getComplainStates(); - // broadcasts Sij for each complaint against Pid - for (int j = 1; j <= complainStates[id - 1].length; j++) { - switch (complainStates[id - 1][j - 1]) { + public void answerAllComplainingPlayers(User user, DistributedKeyGenerationUserImpl.ComplainState[] complains){ + for (int j = 1; j <= n ; j++) { + switch (complains[j - 1]) { case Waiting: - answerComplaint(j); + broadcastComplaintAnswer(user,j); break; default: break; } } + } - // wait until there is no complaint waiting for answer - for (int i = 0; i < complainStates.length; i++){ - for (int j = 0; j < complainStates[i].length; j++){ - while (complainStates[i][j].equals(DistributedKeyGenerationMessageHandler.ComplainState.Waiting)){ - try { - Thread.sleep(300); - } catch (InterruptedException e) { - // do nothing - } - } - } - } - - // add each non-disqualified player to QUAL + /** + * stage3.2 according to the protocol + * if any of the revealed shares fails the verification test, player Pi is disqualified. + * set QUAL to be the set of non-disqualified players. + */ + public Set calcQUAL(DistributedKeyGenerationUserImpl.ComplainState[][] complains){ + Set QUAL = new HashSet(); boolean nonDisqualified; int counter; - for (int i = 1; i <= complainStates.length; i++){ + for (int i = 1; i <= complains.length; i++){ nonDisqualified = true; counter = 0; - for (int j = 1; j <= complainStates[i - 1].length; j++){ - switch (complainStates[i - 1][j - 1]) { + for (int j = 1; j <= complains[i - 1].length; j++){ + switch (complains[i - 1][j - 1]) { case Non: break; case NonDisqualified: @@ -165,52 +147,54 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing implements QUAL.add(i); } } + return QUAL; } /** - * stage4 according to the protocol - * 1. public value y is computed as y = multiplication of yi mod p for i in QUAL - * 2. public verification values are computed as Ak = multiplication of Aik mod p for i in QUAL for k = 0,...,t - * 3. Pj sets is share of the secret as xj = sum of Sij mod q for i in QUAL + * stage4.1 according to the protocol + * public value y is computed as y = multiplication of yi mod p for i in QUAL */ - private void stage4(){ - this.y = zpstar.zero(); + public BigInteger calcY(BigInteger[] ys,Set QUAL){ + BigInteger y = group.zero(); for (int i : QUAL) { - this.y = zpstar.add(this.y , handler.getY(i)); + y = group.add(y , ys[i - 1]); } - - BigInteger[] commitments; - - for (int i : QUAL) { - commitments = handler.getCommitments(i); - for (int k = 0; k <= t; k++){ - this.finalCommitments[k] = zpstar.add(this.finalCommitments[k],commitments[k]); - } - } - - BigInteger xj = BigInteger.ZERO; - for (int i : QUAL) { - if( i == id){ - xj = xj.add(super.getShare(i).y); - }else{ - xj = xj.add(handler.getShare(i).y); - } - } - this.share = new Polynomial.Point(BigInteger.valueOf(id) , xj.mod(q)); - } - - @Override - public BigInteger getY() { return y; } - @Override - public BigInteger[] getCommitments() { - return Arrays.copyOf(finalCommitments, finalCommitments.length); + /** + * stage4.2 according to the protocol + * public verification values are computed as Ak = multiplication of Aik mod p for i in QUAL for k = 0,...,t + */ + public BigInteger[] calcCommitments(BigInteger[][] commitmentsTable,Set QUAL){ + BigInteger[] commitments = new BigInteger[t + 1]; + Arrays.fill(commitments,group.zero()); + for (int i : QUAL) { + for (int k = 0; k <= t; k++){ + commitments[k] = group.add(commitments[k],commitmentsTable[i - 1][k]); + } + } + return commitments; } - public Polynomial.Point getShare() { - return share; + /** + * stage4.3 according to the protocol + * Pj sets is share of the secret as xj = sum of Sij mod q for i in QUAL + */ + public Polynomial.Point calcShare(Polynomial.Point[] shares,Set QUAL){ + BigInteger xj = BigInteger.ZERO; + for (int i : QUAL) { + xj = xj.add(shares[i - 1].y); + } + return new Polynomial.Point(BigInteger.valueOf(id) , xj.mod(q)); + } + + public int getId() { + return id; + } + + public void setShares(Polynomial.Point[] shares){ + this.shares = shares; } } diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMessageHandler.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMessageHandler.java deleted file mode 100644 index 2314469..0000000 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMessageHandler.java +++ /dev/null @@ -1,161 +0,0 @@ -package JointFeldmanProtocol; - -import Communication.MessageHandler; -import Communication.Network; -import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; -import FeldmanVerifiableSecretSharing.VerifiableSecretSharingMessageHandler; -import ShamirSecretSharing.Polynomial; -import ShamirSecretSharing.SecretSharingMessageHandler; -import meerkat.protobuf.DKGMessages; -import org.factcenter.qilin.primitives.concrete.Zpstar; - -import java.math.BigInteger; - -/** - * Created by Tzlil on 2/16/2016. - */ -public class DistributedKeyGenerationMessageHandler implements MessageHandler { - - protected enum ComplainState{ - Non, Waiting,Disqualified,NonDisqualified - } - - protected final VerifiableSecretSharingMessageHandler[] vssHandlers; - protected final ComplainState[][] complainStates; // complainStates[i][j] == state of Pj's complaint against Pi - protected final BigInteger g; - protected final Zpstar zpstar; - protected final int n; - private final boolean[] doneFlags; - - public DistributedKeyGenerationMessageHandler(int t, int n, BigInteger g, Zpstar zpstar) { - this.g = g; - this.zpstar = zpstar; - this.n = n; - this.doneFlags = new boolean[n]; - this.vssHandlers = new VerifiableSecretSharingMessageHandler[n]; - for (int i = 1; i <= n ; i++){ - vssHandlers[i - 1] = new VerifiableSecretSharingMessageHandler(t); - } - this.complainStates = new ComplainState[n][n]; - for (int i = 0; i < n; i ++){ - for (int j = 0 ; j < n ; j ++) - this.complainStates[i][j] = ComplainState.Non; - } - } - - /** - * @return true iff all shares and commitments were received - */ - protected boolean isStage1Complete(){ - for (int i = 1 ; i <= n ; i++){ - if(vssHandlers[i - 1].getShare() == null) - return false; - } - - BigInteger[] commitments; - for (int i = 0; i < vssHandlers.length; i++){ - commitments = vssHandlers[i].getCommitments(); - for (int j = 0; j < commitments.length; j++){ - if(commitments[j] == null) - return false; - } - } - return true; - } - - /** - * @return true iff all flags in doneFlags are true - */ - protected boolean isStage2Complete() { - for (int j = 0; j < n ; j++) { - if(!doneFlags[j]) - return false; - } - return true; - } - - @Override - public void handelComplaintMessage(int sender, boolean isBroadcast, DKGMessages.ComplaintMessage complaintMessage) { - if(isBroadcast){ - int i = complaintMessage.getId(); - int j = sender; - switch (complainStates[i - 1][j - 1]){ - case Non: - complainStates[i - 1][j - 1] = ComplainState.Waiting; - break; - default: - break; - } - } - } - - @Override - public void handelDoneMessage(int sender, boolean isBroadcast, DKGMessages.DoneMessage doneMessage) { - if(isBroadcast) - this.doneFlags[sender - 1] = true; - } - - @Override - public void handelCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage) { - vssHandlers[sender - 1].handelCommitmentMessage(sender, isBroadcast, commitmentMessage); - } - - - /** - * @param secret - * @param i - * @return g ^ Sij == verify(j,Ai,zpstar) (mod p) - */ - private boolean isValidSecret(Polynomial.Point secret, int i){ - int j = secret.x.intValue(); - BigInteger[] commitments = vssHandlers[i - 1].getCommitments(); - return zpstar.multiply(g,secret.y).equals(VerifiableSecretSharing.verify(j,commitments,zpstar)); - } - - protected boolean isValidSecret(int i){ - return isValidSecret(getShare(i),i); - } - - @Override - public void handelSecretMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage) { - vssHandlers[sender - 1].handelSecretMessage(sender, isBroadcast, secretMessage); - if(isBroadcast){ - Polynomial.Point secret = SecretSharingMessageHandler.extractSecret(secretMessage); - int i = sender; - int j = secret.x.intValue(); - switch (complainStates[i - 1][j - 1]){ - case Waiting: - if(isValidSecret(secret,i)){ - complainStates[i - 1][j - 1] = ComplainState.NonDisqualified; - }else{ - complainStates[i - 1][j - 1] = ComplainState.Disqualified; - } - break; - default: - break; - } - } - } - - @Override - public void handelDoubleSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { - // ignore - } - - - protected ComplainState[][] getComplainStates() { - return complainStates; - } - - protected BigInteger getY(int i){ - return vssHandlers[i - 1].getY(); - } - - protected BigInteger[] getCommitments(int i){ - return vssHandlers[i -1].getCommitments(); - } - - protected Polynomial.Point getShare(int i){ - return vssHandlers[i-1].getShare(); - } -} diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java new file mode 100644 index 0000000..faf0048 --- /dev/null +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java @@ -0,0 +1,288 @@ +package JointFeldmanProtocol; + +import Communication.Network; +import Communication.User; +import ShamirSecretSharing.Polynomial; +import UserInterface.DistributedKeyGenerationUser; +import meerkat.protobuf.DKGMessages; +import org.factcenter.qilin.primitives.Group; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Set; + +/** + * Created by Tzlil on 2/21/2016. + */ +public class DistributedKeyGenerationUserImpl implements DistributedKeyGenerationUser { + protected enum ComplainState{ + Non, Waiting,Disqualified,NonDisqualified + } + + protected final DistributedKeyGeneration dkg; + + protected final BigInteger g; + protected final Group group; + protected final int n; + protected final int t; + protected final int id; + + protected MessageHandler messageHandler; + protected final Polynomial.Point[] shares; + protected final BigInteger[][] commitmentsTable; + protected final boolean[] doneFlags; + protected final User user; + protected final ComplainState[][] complaintsTable; + + protected Set QUAL; // set of all non-disqualified parties + protected BigInteger[] commitments; // public verification values + protected Polynomial.Point share; // final share of the secrete + protected BigInteger y; // final public value + + public DistributedKeyGenerationUserImpl(DistributedKeyGeneration dkg, Network network) { + this.dkg = dkg; + + this.g = dkg.getGenerator(); + this.group = dkg.getGroup(); + this.n = dkg.getN(); + this.t = dkg.getT(); + this.id = dkg.getId(); + + this.messageHandler = new MessageHandler(); + this.shares = new Polynomial.Point[n]; + this.shares[id - 1] = dkg.getShare(id); + this.commitmentsTable = new BigInteger[n][t + 1]; + this.doneFlags = new boolean[n]; + this.user = network.connect(messageHandler); + this.complaintsTable = new ComplainState[n][n]; + for (int i = 0; i < n; i++){ + Arrays.fill(complaintsTable[i],ComplainState.Non); + } + + this.QUAL = null; + this.commitments = null; + this.share = null; + this.y = null; + } + + /** + * stage1 according to the protocol + * 1. Pi broadcasts Aik for k = 0,...,t. + * 2. Pi computes the shares Sij for j = 1,...,n and sends Sij secretly to Pj. + */ + protected void stage1() { + dkg.broadcastCommitments(user); + dkg.sendSecrets(user); + } + + /** + * stage2 according to the protocol + * Pj verifies all the shares he received + * if check fails for an index i, Pj broadcasts a complaint against Pi. + * Pj broadcasts done message at the end of this stage + */ + protected void stage2(){ + dkg.setShares(shares); + dkg.broadcastComplains(user,commitmentsTable); + //broadcast done message after all complaints + DKGMessages.DoneMessage doneMessage = DKGMessages.DoneMessage.newBuilder().build(); + user.broadcast(DKGMessages.Mail.Type.DONE,doneMessage); + } + + /** + * stage3 according to the protocol + * 1. if more than t players complain against a player Pi he is disqualified. + * otherwise Pi broadcasts the share Sij for each complaining player Pj. + * 2. if any of the revealed shares fails the verification test, player Pi is disqualified. + * set QUAL to be the set of non-disqualified players. + */ + protected void stage3(){ + + dkg.answerAllComplainingPlayers(user,complaintsTable[id - 1]); + + // wait until there is no complaint waiting for answer + for (int i = 0; i < complaintsTable.length; i++){ + for (int j = 0; j < complaintsTable[i].length; j++){ + while (complaintsTable[i][j].equals(ComplainState.Waiting)){ + try { + Thread.sleep(300); + } catch (InterruptedException e) { + // do nothing + } + } + } + } + this.QUAL = dkg.calcQUAL(complaintsTable); + } + + /** + * stage4 according to the protocol + * 1. public value y is computed as y = multiplication of yi mod p for i in QUAL + * 2. public verification values are computed as Ak = multiplication of Aik mod p for i in QUAL for k = 0,...,t + * 3. Pj sets is share of the secret as xj = sum of Sij mod q for i in QUAL + */ + protected void stage4(){ + BigInteger[] ys = new BigInteger[n]; + for (int i = 0; i < n; i++){ + ys[i] = commitmentsTable[i][0]; + } + this.y = dkg.calcY(ys,QUAL); + this.commitments = dkg.calcCommitments(commitmentsTable,QUAL); + this.share = dkg.calcShare(shares,QUAL); + } + + @Override + public void run() { + user.getReceiverThread().start(); + stage1(); + while (messageHandler.secretsCounter != n - 1 || messageHandler.commitmentsCounter != n * (t + 1)){ + try { + Thread.sleep(300); + } catch (InterruptedException e) { + // do nothing + } + } + stage2(); + while (messageHandler.doneCounter != n){ + try { + Thread.sleep(300); + } catch (InterruptedException e) { + // do nothing + } + } + stage3(); + stage4(); + user.getReceiverThread().interrupt(); + } + + @Override + public BigInteger[] getCommitments() { + return Arrays.copyOf(commitments, commitments.length); + } + + @Override + public BigInteger getGenerator() { + return g; + } + + @Override + public Group getGroup() { + return group; + } + + @Override + public Polynomial.Point getShare() { + return share; + } + + @Override + public int getID() { + return id; + } + + @Override + public int getN() { + return n; + } + + @Override + public int getT() { + return t; + } + + @Override + public BigInteger getPublicValue() { + return y; + } + + @Override + public Set getQUAL() { + return QUAL; + } + + protected class MessageHandler implements Communication.MessageHandler{ + + public int doneCounter; + public int commitmentsCounter; + public int secretsCounter; + + public MessageHandler() { + this.doneCounter = 0; + this.secretsCounter = 0; + this.commitmentsCounter = 0; + } + + @Override + public void handelComplaintMessage(int sender, boolean isBroadcast, DKGMessages.ComplaintMessage complaintMessage) { + if(isBroadcast) { + int i = sender - 1; + int j = complaintMessage.getId() - 1; + switch (complaintsTable[i][j]) { + case Non: + complaintsTable[i][j] = ComplainState.Waiting; + break; + default: + break; + } + } + } + + @Override + public void handelDoneMessage(int sender, boolean isBroadcast, DKGMessages.DoneMessage doneMessage) { + if(isBroadcast && !doneFlags[sender - 1]) { + doneFlags[sender - 1] = true; + doneCounter++; + } + } + + @Override + public void handelCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage) { + if(isBroadcast){ + int i = sender - 1; + int k = commitmentMessage.getK(); + if(commitmentsTable[i][k] == null){ + commitmentsTable[i][k] = extractCommitment(commitmentMessage); + commitmentsCounter++; + } + } + } + + @Override + public void handelSecretMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage) { + Polynomial.Point secret = extractSecret(secretMessage); + if(!isBroadcast){ + if(shares[sender - 1] == null) { + shares[sender - 1] = secret; + secretsCounter++; + } + }else { + int i = sender; + int j = secret.x.intValue(); + switch (complaintsTable[i - 1][j - 1]){ + case Waiting: + if(dkg.isValidSecret(secret,commitmentsTable[i - 1],j)){ + complaintsTable[i - 1][j - 1] = ComplainState.NonDisqualified; + }else{ + complaintsTable[i - 1][j - 1] = ComplainState.Disqualified; + } + break; + default: + break; + } + } + } + + @Override + public void handelDoubleSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { + + } + + public Polynomial.Point extractSecret(DKGMessages.SecretMessage secretMessage){ + return new Polynomial.Point(secretMessage.getSecret()); + } + + public BigInteger extractCommitment(DKGMessages.CommitmentMessage commitmentMessage){ + return new BigInteger(commitmentMessage.getCommitment().toByteArray()); + } + } +} diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGeneration.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGeneration.java index cf0a429..bd204c8 100644 --- a/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGeneration.java +++ b/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGeneration.java @@ -1,10 +1,13 @@ package SecureDistributedKeyGeneration; import Communication.Network; +import Communication.User; import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; import JointFeldmanProtocol.DistributedKeyGeneration; +import ShamirSecretSharing.Polynomial; import com.google.protobuf.ByteString; import meerkat.protobuf.DKGMessages; +import org.factcenter.qilin.primitives.Group; import org.factcenter.qilin.primitives.concrete.Zpstar; import java.math.BigInteger; @@ -15,54 +18,91 @@ import java.util.Random; */ public class SecureDistributedKeyGeneration extends DistributedKeyGeneration { - VerifiableSecretSharing verifiableSecretSharing; + private VerifiableSecretSharing verifiableSecretSharing; + private final BigInteger h; + private Polynomial.Point[] sharesT; - public SecureDistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger p, BigInteger q, BigInteger g - ,BigInteger h, Network network) { - super(t, n, zi, random, p, q, g, network.connect(new SecureDistributedKeyGenerationMessageHandler(t,n,g,new Zpstar(p)))); - this.verifiableSecretSharing = new VerifiableSecretSharing(t,n,new BigInteger(q.bitLength(), random).mod(q),random,p,q,h,user); + public SecureDistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger q, BigInteger g + , BigInteger h, Group group, int id) { + super(t, n, zi, random, q, g, group, id); + this.h = h; + BigInteger r = new BigInteger(q.bitLength(),random).mod(q); + this.verifiableSecretSharing = new VerifiableSecretSharing(t,n,r,random,q,h,group); } @Override - protected void computeAndSendSecrets() { - DKGMessages.SecretMessage[] secretMessages1 = prepareSecretMessages(); - DKGMessages.SecretMessage[] secretMessages2 = verifiableSecretSharing.prepareSecretMessages(); - DKGMessages.DoubleSecretMessage doubleSecretMessage; + public void sendSecret(User user,int j) { + DKGMessages.SecretMessage.Point secret = getShare(j).asMessage();; + DKGMessages.SecretMessage.Point secretT = verifiableSecretSharing.getShare(j).asMessage();; + DKGMessages.DoubleSecretMessage doubleSecretMessage = DKGMessages.DoubleSecretMessage.newBuilder() + .setS1(DKGMessages.SecretMessage.newBuilder().setSecret(secret).build()) + .setS2(DKGMessages.SecretMessage.newBuilder().setSecret(secretT).build()) + .build(); + user.send(j, DKGMessages.Mail.Type.DOUBLE, doubleSecretMessage); + } - for (int j = 1; j <= n ; j++ ){ - doubleSecretMessage = DKGMessages.DoubleSecretMessage.newBuilder() - .setS1(secretMessages1[j - 1]) - .setS1(secretMessages2[j - 1]) - .build(); - user.send(j, DKGMessages.Mail.Type.SECRET,doubleSecretMessage); + @Override + public boolean isValidSecret(int j, BigInteger[] commitments, int i){ + Polynomial.Point secret = shares[j - 1]; + Polynomial.Point secretT = sharesT[j - 1]; + return isValidSecret(secret,secretT,commitments,i); + } + + public boolean isValidSecret(Polynomial.Point secret,Polynomial.Point secretT, BigInteger[] verificationValues, int i){ + BigInteger v = verify(i,verificationValues,group); + BigInteger exp = group.add(group.multiply(g, secret.y),group.multiply(h, secretT.y)); + return exp.equals(v); + } + + public boolean isValidComplaint(Polynomial.Point secret,Polynomial.Point secretT, BigInteger[] commitments + ,BigInteger[] verificationValues, int i){ + return isValidSecret(secret,secretT,verificationValues,i) && !isValidSecret(secret,commitments,i); + } + + /** + * stage4.3 according to the protocol + * if check fails for index i, Pj + */ + public void broadcastComplaints(User user, BigInteger[][] commitmentsTable, boolean stage4){ + if(!stage4){ + broadcastComplains(user,commitmentsTable); + }else{ + for (int j = 1; j <= n ; j++ ){ + if(j != id) { + if (!isValidSecret(shares[j - 1],commitmentsTable[j - 1],id)) { + broadcastDoubleSecret(user,shares[j - 1],sharesT[j - 1]); + } + } + } } } - @Override - public DKGMessages.CommitmentMessage[] prepareCommitmentMessages() { - DKGMessages.CommitmentMessage[] commitmentMessages = new DKGMessages.CommitmentMessage[t + 1]; - BigInteger[] commitments2 = verifiableSecretSharing.getCommitments(); - for (int k = 0; k <= t ; k ++) { - commitmentMessages[k] = DKGMessages.CommitmentMessage.newBuilder() - .setK(k) - .setCommitment(ByteString.copyFrom(zpstar.add(commitments[k],commitments2[k]).toByteArray())) - .build(); + + public void broadcastVerificationValues(User user){ + BigInteger[] verificationValues = new BigInteger[t + 1]; + BigInteger[] hBaseCommitments = verifiableSecretSharing.getCommitmentsArray(); + for (int k = 0 ; k < verificationValues.length ; k++){ + verificationValues[k] = group.add(commitmentsArray[k],hBaseCommitments[k]); } - return commitmentMessages; + broadcastCommitments(user,verificationValues); + } + + private void broadcastDoubleSecret(User user ,Polynomial.Point secret, Polynomial.Point secretT){ + DKGMessages.SecretMessage.Point secretMessage = secret.asMessage(); + DKGMessages.SecretMessage.Point secretTMessage = secretT.asMessage(); + DKGMessages.DoubleSecretMessage doubleSecretMessage = DKGMessages.DoubleSecretMessage.newBuilder() + .setS1(DKGMessages.SecretMessage.newBuilder().setSecret(secretMessage).build()) + .setS1(DKGMessages.SecretMessage.newBuilder().setSecret(secretTMessage).build()) + .build(); + user.broadcast(DKGMessages.Mail.Type.DOUBLE, doubleSecretMessage); } @Override - protected void answerComplaint(int j) { - DKGMessages.SecretMessage secretMessage1 = DKGMessages.SecretMessage.newBuilder() - .setSecret(getShare(j).asMessage()) - .build(); - DKGMessages.SecretMessage secretMessage2 = DKGMessages.SecretMessage.newBuilder() - .setSecret(verifiableSecretSharing.getShare(j).asMessage()) - .build(); + public void broadcastComplaintAnswer(User user, int j) { + broadcastDoubleSecret(user,getShare(j),verifiableSecretSharing.getShare(j)); + } - user.broadcast(DKGMessages.Mail.Type.SECRET, DKGMessages.DoubleSecretMessage.newBuilder() - .setS1(secretMessage1) - .setS2(secretMessage2) - .build()); + public void setSharesT(Polynomial.Point[] sharesT) { + this.sharesT = sharesT; } } diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationMessageHandler.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationMessageHandler.java deleted file mode 100644 index 034f89c..0000000 --- a/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationMessageHandler.java +++ /dev/null @@ -1,61 +0,0 @@ -package SecureDistributedKeyGeneration; - -import Communication.Network; -import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; -import JointFeldmanProtocol.DistributedKeyGenerationMessageHandler; -import ShamirSecretSharing.Polynomial; -import ShamirSecretSharing.SecretSharingMessageHandler; -import meerkat.protobuf.DKGMessages; -import org.factcenter.qilin.primitives.concrete.Zpstar; - -import java.math.BigInteger; - -/** - * Created by Tzlil on 2/17/2016. - */ -public class SecureDistributedKeyGenerationMessageHandler extends DistributedKeyGenerationMessageHandler { - - private final SecretSharingMessageHandler[] ssHandlers; - public SecureDistributedKeyGenerationMessageHandler(int t, int n, BigInteger g, Zpstar zpstar) { - super(t, n, g, zpstar); - this.ssHandlers = new SecretSharingMessageHandler[n]; - } - - private boolean isValidSecret(Polynomial.Point secret1,Polynomial.Point secret2,int i){ - int j = secret1.x.intValue(); - BigInteger[] commitments = vssHandlers[i - 1].getCommitments(); - return zpstar.multiply(g,zpstar.add(secret1.y,secret2.y)).equals(VerifiableSecretSharing.verify(j,commitments,zpstar)); - } - - @Override - protected boolean isValidSecret(int i) { - return isValidSecret(getShare(i),ssHandlers[i - 1].getShare(),i); - } - - - @Override - public void handelDoubleSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { - if(!isBroadcast){ - this.handelSecretMessage(sender,isBroadcast,doubleSecretMessage.getS1()); - ssHandlers[sender - 1].handelSecretMessage(sender,isBroadcast,doubleSecretMessage.getS2()); - }else{ - Polynomial.Point secret1 = SecretSharingMessageHandler.extractSecret(doubleSecretMessage.getS1()); - Polynomial.Point secret2 = SecretSharingMessageHandler.extractSecret(doubleSecretMessage.getS2()); - int i = sender; - int j = secret1.x.intValue(); - switch (complainStates[i - 1][j - 1]){ - case Waiting: - if(isValidSecret(secret1,secret2,i)){ - complainStates[i - 1][j - 1] = ComplainState.NonDisqualified; - }else{ - complainStates[i - 1][j - 1] = ComplainState.Disqualified; - } - break; - default: - break; - } - } - } - - -} diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationUserImpl.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationUserImpl.java new file mode 100644 index 0000000..02ae13e --- /dev/null +++ b/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationUserImpl.java @@ -0,0 +1,138 @@ +package SecureDistributedKeyGeneration; + +import Communication.Network; +import JointFeldmanProtocol.DistributedKeyGenerationUserImpl; +import ShamirSecretSharing.Polynomial; +import meerkat.protobuf.DKGMessages; + +import java.math.BigInteger; + +/** + * Created by Tzlil on 2/22/2016. + */ +public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenerationUserImpl { + + private final SecureDistributedKeyGeneration sdkg; + + private final Polynomial.Point[] sharesT; + private final BigInteger[][] verificationValuesTable; + + public SecureDistributedKeyGenerationUserImpl(SecureDistributedKeyGeneration sdkg, Network network) { + super(sdkg, network); + this.sdkg = sdkg; + this.sharesT = new Polynomial.Point[n]; + this.verificationValuesTable = new BigInteger[n][t + 1]; + this.messageHandler = new MessageHandler(); + this.user.setMessageHandler(this.messageHandler); + } + + /** + * stage1 according to the protocol + * 1. Pi broadcasts Cik=Aik*Bik for k = 0,...,t. + * 2. Pi computes the shares Sij,Sij' for j = 1,...,n and sends Sij,Sij' secretly to Pj. + */ + @Override + protected void stage1() { + sdkg.broadcastVerificationValues(user); + sdkg.sendSecrets(user); + } + + /** + * stage2 according to the protocol + * Pj verifies all the shares,sharesT he received + * if check fails for an index i, Pj broadcasts a complaint against Pi. + * Pj broadcasts done message at the end of this stage + */ + @Override + protected void stage2(){ + sdkg.setShares(shares); + sdkg.setSharesT(sharesT); + sdkg.broadcastComplains(user,verificationValuesTable); + //broadcast done message after all complaints + DKGMessages.DoneMessage doneMessage = DKGMessages.DoneMessage.newBuilder().build(); + user.broadcast(DKGMessages.Mail.Type.DONE,doneMessage); + } + + private void ys(){ + sdkg.broadcastCommitments(user); + //wait for receive all commitments from all i in QUAL + for (int i:QUAL) { + for(int k = 0; k <= t; k++) { + while (commitmentsTable[i - 1][k] == null) { + try { + Thread.sleep(300); + } catch (InterruptedException e) { + // do nothing + } + } + } + } + sdkg.broadcastComplaints(user,commitmentsTable,true); + //do something with complaints' answers + + } + + @Override + protected void stage4() { + ys(); + super.stage4(); + } + + private class MessageHandler extends DistributedKeyGenerationUserImpl.MessageHandler{ + + final int NumberOfCommitmentsInStage1 = n * (t + 1); + + @Override + public void handelCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage) { + if(isBroadcast){ + if(commitmentsCounter < NumberOfCommitmentsInStage1){ + int i = sender - 1; + int k = commitmentMessage.getK(); + if(verificationValuesTable[i][k] == null){ + verificationValuesTable[i][k] = extractCommitment(commitmentMessage); + commitmentsCounter++; + } + } else{ + super.handelCommitmentMessage(sender,isBroadcast,commitmentMessage); + } + } + } + + @Override + public void handelSecretMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage) { + //there is no secret message in this protocol + } + + @Override + public void handelDoubleSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { + + Polynomial.Point secret = extractSecret(doubleSecretMessage.getS1()); + Polynomial.Point secretT = extractSecret(doubleSecretMessage.getS2()); + if(!isBroadcast){ + if(shares[sender - 1] == null) { + shares[sender - 1] = secret; + sharesT[sender - 1] = secretT; + secretsCounter++; + } + }else { + if(commitmentsCounter <= NumberOfCommitmentsInStage1) { + int i = sender; + int j = secret.x.intValue(); + switch (complaintsTable[i - 1][j - 1]) { + case Waiting: + if (sdkg.isValidSecret(secret,secretT, verificationValuesTable[j - 1], i)) { + complaintsTable[i - 1][j - 1] = ComplainState.NonDisqualified; + } else { + complaintsTable[i - 1][j - 1] = ComplainState.Disqualified; + } + break; + default: + break; + } + }else{ // stage4 + + } + } + } + } +} diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java index de6b847..7dc0bca 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java @@ -12,13 +12,11 @@ import java.util.Random; * Created by Tzlil on 1/27/2016. * an implementation of Shamire's secret sharing scheme */ -public class SecretSharing implements Runnable{ +public class SecretSharing{ protected final int t; protected final int n; protected final BigInteger q; - - protected final User user; // send and receive messages throw network - private final Polynomial polynomial; + protected final Polynomial polynomial; /** * constructor @@ -29,16 +27,11 @@ public class SecretSharing implements Runnable{ * @param x secret, chosen from Zq * @param random use for generate random polynomial */ - public SecretSharing(int t, int n, BigInteger x, Random random, BigInteger q, Network network) { - this(t,n,x,random,q,network.connect(new SecretSharingMessageHandler())); - } - - public SecretSharing(int t, int n, BigInteger x, Random random, BigInteger q, User user) { + public SecretSharing(int t, int n, BigInteger x, Random random, BigInteger q) { this.q = q; this.t = t; this.n = n; this.polynomial = generateRandomPolynomial(x,random); - this.user = user; } /** @@ -73,7 +66,7 @@ public class SecretSharing implements Runnable{ * * @return image of interpolation(shares) at x = 0 */ - public static BigInteger getSecrete(Polynomial.Point[] shares) throws Exception { + public static BigInteger restoreSecrete(Polynomial.Point[] shares) throws Exception { Polynomial polynomial = Polynomial.interpolation(shares); return polynomial.image(BigInteger.ZERO); } @@ -102,31 +95,12 @@ public class SecretSharing implements Runnable{ return q; } - public Polynomial getPolynomial() { + /** + * getter + * @return the polynomial was generated in constructor + */ + public Polynomial getPolynomial() { return polynomial; } - - public DKGMessages.SecretMessage[] prepareSecretMessages(){ - DKGMessages.SecretMessage[] secretMessages = new DKGMessages.SecretMessage[n]; - for (int j = 1; j <= n ; j++ ){ - secretMessages[j - 1] = DKGMessages.SecretMessage.newBuilder() - .setSecret(getShare(j).asMessage()) - .build(); - } - return secretMessages; - } - - protected void computeAndSendSecrets(){ - DKGMessages.SecretMessage[] secretMessages = prepareSecretMessages(); - for (int j = 1; j <= n ; j++ ){ - user.send(j, DKGMessages.Mail.Type.SECRET,secretMessages[j - 1]); - } - } - - @Override - public void run() { - // computes and sends shares - computeAndSendSecrets(); - } } diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharingMessageHandler.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharingMessageHandler.java deleted file mode 100644 index 6230c05..0000000 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharingMessageHandler.java +++ /dev/null @@ -1,47 +0,0 @@ -package ShamirSecretSharing; - -import Communication.MessageHandler; -import Communication.Network; -import meerkat.protobuf.DKGMessages; - -/** - * Created by Tzlil on 2/16/2016. - */ -public class SecretSharingMessageHandler implements MessageHandler{ - - private Polynomial.Point share; - - @Override - public void handelComplaintMessage(int sender, boolean isBroadcast, DKGMessages.ComplaintMessage complaintMessage) { - // ignore - } - - @Override - public void handelDoneMessage(int sender, boolean isBroadcast, DKGMessages.DoneMessage doneMessage) { - // ignore - } - - @Override - public void handelCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage) { - // ignore - } - - @Override - public void handelDoubleSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { - // ignore - } - - @Override - public void handelSecretMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage) { - if(!isBroadcast) - this.share = extractSecret(secretMessage); - } - - public static Polynomial.Point extractSecret(DKGMessages.SecretMessage secretMessage){ - return new Polynomial.Point(secretMessage.getSecret()); - } - - public Polynomial.Point getShare() { - return share; - } -} diff --git a/destributed-key-generation/src/main/java/UserInterface/DistributedKeyGenerationUser.java b/destributed-key-generation/src/main/java/UserInterface/DistributedKeyGenerationUser.java new file mode 100644 index 0000000..d8eb5ef --- /dev/null +++ b/destributed-key-generation/src/main/java/UserInterface/DistributedKeyGenerationUser.java @@ -0,0 +1,13 @@ +package UserInterface; + +import java.math.BigInteger; +import java.util.Set; + +/** + * Created by Tzlil on 2/21/2016. + */ +public interface DistributedKeyGenerationUser extends VerifiableSecretSharingUser { + + BigInteger getPublicValue(); + Set getQUAL(); +} diff --git a/destributed-key-generation/src/main/java/UserInterface/SecretSharingUser.java b/destributed-key-generation/src/main/java/UserInterface/SecretSharingUser.java new file mode 100644 index 0000000..dc4a6e4 --- /dev/null +++ b/destributed-key-generation/src/main/java/UserInterface/SecretSharingUser.java @@ -0,0 +1,14 @@ +package UserInterface; + +import ShamirSecretSharing.Polynomial; + +/** + * Created by Tzlil on 2/21/2016. + */ +public interface SecretSharingUser extends Runnable { + + Polynomial.Point getShare(); + int getID(); + int getN(); + int getT(); +} diff --git a/destributed-key-generation/src/main/java/UserInterface/VerifiableSecretSharingUser.java b/destributed-key-generation/src/main/java/UserInterface/VerifiableSecretSharingUser.java new file mode 100644 index 0000000..79cd404 --- /dev/null +++ b/destributed-key-generation/src/main/java/UserInterface/VerifiableSecretSharingUser.java @@ -0,0 +1,16 @@ +package UserInterface; + +import UserInterface.SecretSharingUser; +import org.factcenter.qilin.primitives.Group; + +import java.math.BigInteger; + +/** + * Created by Tzlil on 2/21/2016. + */ +public interface VerifiableSecretSharingUser extends SecretSharingUser { + + BigInteger[] getCommitments(); + BigInteger getGenerator(); + Group getGroup(); +} diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java index f773237..fff8952 100644 --- a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java +++ b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java @@ -2,6 +2,7 @@ package FeldmanVerifiableSecretSharing; import Communication.Network; import ShamirSecretSharing.Polynomial; +import org.factcenter.qilin.primitives.Group; import org.factcenter.qilin.primitives.concrete.Zpstar; import org.junit.Before; import org.junit.Test; @@ -32,21 +33,19 @@ public class VerifiableSecretSharingTest { }while (!g.equals(ZERO) && !zpstar.multiply(g,q).equals(ZERO));// sample from QRZp* int t = 8; int n = 20; - Network network; verifiableSecretSharingArray = new VerifiableSecretSharing[tests]; for (int i = 0; i < verifiableSecretSharingArray.length; i++){ - network = new Network(n); verifiableSecretSharingArray[i] = new VerifiableSecretSharing(t,n - ,new BigInteger(q.bitLength(),random).mod(q),random,p,q,g,network); + ,new BigInteger(q.bitLength(),random).mod(q),random,q,g,zpstar); } } public void oneTest(VerifiableSecretSharing verifiableSecretSharing) throws Exception { int n = verifiableSecretSharing.getN(); - Zpstar zpstar = verifiableSecretSharing.getZpstar(); + Group zpstar = verifiableSecretSharing.getGroup(); BigInteger g = verifiableSecretSharing.getGenerator(); Polynomial.Point[] shares = new Polynomial.Point[n]; - BigInteger[] commitments = verifiableSecretSharing.getCommitments(); + BigInteger[] commitments = verifiableSecretSharing.getCommitmentsArray(); BigInteger[] verifications = new BigInteger[n]; for (int i = 1 ; i <= shares.length; i ++){ shares[i - 1] = verifiableSecretSharing.getShare(i); diff --git a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java index 9171f3d..4000ec0 100644 --- a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java +++ b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java @@ -4,13 +4,13 @@ import Communication.Network; import ShamirSecretSharing.Polynomial; import ShamirSecretSharing.SecretSharing; import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; +import UserInterface.DistributedKeyGenerationUser; +import org.factcenter.qilin.primitives.Group; import org.factcenter.qilin.primitives.concrete.Zpstar; import org.junit.Before; import org.junit.Test; import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; import java.util.Random; /** @@ -19,7 +19,7 @@ import java.util.Random; public class DKGTest { - DistributedKeyGeneration[][] dkgsArrays; + DistributedKeyGenerationUser[][] dkgsArrays; Thread[][] threadsArrays; int tests = 10; BigInteger p = BigInteger.valueOf(2903); @@ -33,9 +33,10 @@ public class DKGTest { int t = 9; int n = 20; BigInteger ZERO = zpstar.zero(); - dkgsArrays = new DistributedKeyGeneration[tests][n]; + dkgsArrays = new DistributedKeyGenerationUserImpl[tests][n]; threadsArrays = new Thread[tests][n]; secrets = new BigInteger[tests]; + DistributedKeyGeneration dkg; for (int test = 0; test < tests; test++) { do { g = zpstar.sample(random); @@ -45,13 +46,14 @@ public class DKGTest { for (int i = 0; i < n; i++) { BigInteger secret = new BigInteger(q.bitLength(), random).mod(q); secrets[test] = secrets[test].add(secret).mod(q); - dkgsArrays[test][i] = new DistributedKeyGeneration(t, n,secret, random, p, q, g, network); + dkg = new DistributedKeyGeneration(t,n,secret,random,q,g,zpstar,i + 1); + dkgsArrays[test][i] = new DistributedKeyGenerationUserImpl(dkg,network); threadsArrays[test][i] = new Thread(dkgsArrays[test][i]); } } } - public void oneTest(Thread[] threads, DistributedKeyGeneration[] dkgs,BigInteger secret) throws Exception { + public void oneTest(Thread[] threads, DistributedKeyGenerationUser[] dkgs,BigInteger secret) throws Exception { for (int i = 0; i < threads.length ; i++){ threads[i].start(); } @@ -61,15 +63,16 @@ public class DKGTest { int t = dkgs[0].getT(); int n = dkgs[0].getN(); - Zpstar zpstar = dkgs[0].getZpstar(); + Group zpstar = dkgs[0].getGroup(); BigInteger g = dkgs[0].getGenerator(); // got the right public value - assert(zpstar.multiply(g,secret).equals(dkgs[0].getY())); + BigInteger publicValue = dkgs[0].getPublicValue(); + assert(zpstar.multiply(g,secret).equals(publicValue)); // assert all players agreed on the same public value for (int i = 0; i < dkgs.length - 1 ; i++){ - assert (dkgs[i].getY().equals(dkgs[i+1].getY())); + assert (dkgs[i].getPublicValue().equals(dkgs[i+1].getPublicValue())); } // assert valid verification values @@ -96,19 +99,13 @@ public class DKGTest { // index = indexes.remove(random.nextInt(indexes.size())); // shares[i] = dkgs[index - 1].getShare(); //} - BigInteger calculatedSecret = SecretSharing.getSecrete(shares).mod(q); - - Polynomial polynomial = Polynomial.ZERO; - for (int i = 0 ; i < dkgs.length ; i++){ - polynomial = polynomial.add(dkgs[i].getPolynomial()); - } - + BigInteger calculatedSecret = SecretSharing.restoreSecrete(shares).mod(q); assert (calculatedSecret.equals(secret)); } @Test - public void secretSharingTest() throws Exception { + public void DKGTest() throws Exception { for (int i = 0 ; i < dkgsArrays.length; i ++){ oneTest(threadsArrays[i],dkgsArrays[i],secrets[i]); } diff --git a/destributed-key-generation/src/test/java/SDKGTest.java b/destributed-key-generation/src/test/java/SDKGTest.java new file mode 100644 index 0000000..09bfc2e --- /dev/null +++ b/destributed-key-generation/src/test/java/SDKGTest.java @@ -0,0 +1,113 @@ +import Communication.Network; +import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; +import SecureDistributedKeyGeneration.SecureDistributedKeyGeneration; +import SecureDistributedKeyGeneration.SecureDistributedKeyGenerationUserImpl; +import ShamirSecretSharing.Polynomial; +import ShamirSecretSharing.SecretSharing; +import UserInterface.DistributedKeyGenerationUser; +import org.factcenter.qilin.primitives.Group; +import org.factcenter.qilin.primitives.concrete.Zpstar; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 2/23/2016. + */ +public class SDKGTest { + + DistributedKeyGenerationUser[][] sdkgsArrays; + Thread[][] threadsArrays; + int tests = 10; + BigInteger p = BigInteger.valueOf(2903); + BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); + BigInteger[] secrets; + @Before + public void settings(){ + Zpstar zpstar = new Zpstar(p); + Random random = new Random(); + BigInteger g,h; + int t = 9; + int n = 20; + BigInteger ZERO = zpstar.zero(); + sdkgsArrays = new SecureDistributedKeyGenerationUserImpl[tests][n]; + threadsArrays = new Thread[tests][n]; + secrets = new BigInteger[tests]; + SecureDistributedKeyGeneration sdkg; + for (int test = 0; test < tests; test++) { + do { + g = zpstar.sample(random); + } while (!g.equals(ZERO) && !zpstar.multiply(g, q).equals(ZERO));// sample from QRZp* + h = zpstar.multiply(g,BigInteger.valueOf(2)); + secrets[test] = BigInteger.ZERO; + Network network = new Network(n); + for (int i = 0; i < n; i++) { + BigInteger secret = new BigInteger(q.bitLength(), random).mod(q); + secrets[test] = secrets[test].add(secret).mod(q); + sdkg = new SecureDistributedKeyGeneration(t,n,secret,random,q,g,h,zpstar,i + 1); + sdkgsArrays[test][i] = new SecureDistributedKeyGenerationUserImpl(sdkg,network); + threadsArrays[test][i] = new Thread(sdkgsArrays[test][i]); + } + } + } + + public void oneTest(Thread[] threads, DistributedKeyGenerationUser[] dkgs,BigInteger secret) throws Exception { + for (int i = 0; i < threads.length ; i++){ + threads[i].start(); + } + for (int i = 0; i < threads.length ; i++){ + threads[i].join(); + } + int t = dkgs[0].getT(); + int n = dkgs[0].getN(); + + Group zpstar = dkgs[0].getGroup(); + BigInteger g = dkgs[0].getGenerator(); + + // got the right public value + BigInteger publicValue = dkgs[0].getPublicValue(); + assert(zpstar.multiply(g,secret).equals(publicValue)); + + // assert all players agreed on the same public value + for (int i = 0; i < dkgs.length - 1 ; i++){ + assert (dkgs[i].getPublicValue().equals(dkgs[i+1].getPublicValue())); + } + + // assert valid verification values + BigInteger expected,verification; + for (int j = 1; j <= dkgs.length ; j++){ + expected = zpstar.multiply(g, dkgs[j - 1].getShare().y); + verification = VerifiableSecretSharing.verify(j, dkgs[j - 1].getCommitments(),zpstar); + assert (expected.equals(verification)); + } + + + // restore the secret from t + 1 random shares + Polynomial.Point[] shares = new Polynomial.Point[t + 1]; + for (int i = 0 ; i < shares.length; i++){ + shares[i] = dkgs[i].getShare(); + } + //List indexes = new ArrayList(n); + //for (int i = 1 ; i <= n; i ++){ + // indexes.add(i); + //} + //Random random = new Random(); + //int index; + //for (int i = 0 ; i < shares.length ; i++){ + // index = indexes.remove(random.nextInt(indexes.size())); + // shares[i] = dkgs[index - 1].getShare(); + //} + BigInteger calculatedSecret = SecretSharing.restoreSecrete(shares).mod(q); + assert (calculatedSecret.equals(secret)); + + } + + @Test + public void SDKGTest() throws Exception { + for (int i = 0 ; i < sdkgsArrays.length; i ++){ + oneTest(threadsArrays[i],sdkgsArrays[i],secrets[i]); + } + } +} diff --git a/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java b/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java index 02b8898..8c73ee0 100644 --- a/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java +++ b/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java @@ -1,7 +1,6 @@ package ShamirSecretSharing; import Communication.Network; -import Communication.User; import org.factcenter.qilin.primitives.CyclicGroup; import org.factcenter.qilin.primitives.concrete.Zn; import org.junit.Before; @@ -26,18 +25,17 @@ public class SecretSharingTest { @Before public void settings(){ BigInteger p = BigInteger.valueOf(2903); + BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); group = new Zn(p); int t = 9; int n = 20; random = new Random(); secretSharingArray = new SecretSharing[tests]; secrets = new BigInteger[tests]; - Network network; for (int i = 0; i < secretSharingArray.length; i++){ secrets[i] = group.sample(random); - network = new Network(n); - secretSharingArray[i] = new SecretSharing(t,n,secrets[i],random,p,network); + secretSharingArray[i] = new SecretSharing(t,n,secrets[i],random,q); } } @@ -52,7 +50,7 @@ public class SecretSharingTest { for (int i = 0 ; i < shares.length ; i++){ shares[i] = secretSharing.getShare(indexes.remove(random.nextInt(indexes.size()))); } - assert(secret.equals(SecretSharing.getSecrete(shares))); + assert(secret.equals(SecretSharing.restoreSecrete(shares))); } @Test diff --git a/meerkat-common/src/main/proto/meerkat/DKGMessages.proto b/meerkat-common/src/main/proto/meerkat/DKGMessages.proto index c01b004..4fbc4da 100644 --- a/meerkat-common/src/main/proto/meerkat/DKGMessages.proto +++ b/meerkat-common/src/main/proto/meerkat/DKGMessages.proto @@ -10,6 +10,7 @@ message Mail{ COMMITMENT = 1; DONE = 2; COMPLAINT = 3; + DOUBLE = 4; } int32 sender = 1; int32 destination = 2; From 71191e05b9ab8c807d6fcad8487757f5fbd43aca Mon Sep 17 00:00:00 2001 From: Arbel Deutsch Peled Date: Mon, 29 Feb 2016 08:36:35 +0200 Subject: [PATCH 23/49] Added Sync Query tests on Bulletin Board Server --- .../sqlserver/SQLiteQueryProvider.java | 92 +++++++++++++++++++ .../GenericBulletinBoardServerTest.java | 88 +++++++++++++++++- .../MySQLBulletinBoardServerTest.java | 13 +++ .../java/meerkat/comm/MessageInputStream.java | 30 +++++- .../java/meerkat/util/BulletinBoardUtils.java | 2 +- 5 files changed, 219 insertions(+), 6 deletions(-) diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteQueryProvider.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteQueryProvider.java index b581b87..b64412d 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteQueryProvider.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteQueryProvider.java @@ -4,6 +4,7 @@ import meerkat.protobuf.BulletinBoardAPI.*; import org.sqlite.SQLiteDataSource; import javax.sql.DataSource; +import java.text.MessageFormat; import java.util.LinkedList; import java.util.List; @@ -25,19 +26,97 @@ public class SQLiteQueryProvider implements BulletinBoardSQLServer.SQLQueryProvi switch(queryType) { case ADD_SIGNATURE: return "INSERT OR IGNORE INTO SignatureTable (EntryNum, SignerId, Signature) VALUES (:EntryNum,:SignerId,:Signature)"; + case CONNECT_TAG: return "INSERT OR IGNORE INTO MsgTagTable (TagId, EntryNum)" + " SELECT TagTable.TagId, :EntryNum AS EntryNum FROM TagTable WHERE Tag = :Tag"; + case FIND_MSG_ID: return "SELECT EntryNum From MsgTable WHERE MsgId = :MsgId"; + + case FIND_TAG_ID: + return MessageFormat.format( + "SELECT TagId FROM TagTable WHERE Tag = :{0}", + QueryType.FIND_TAG_ID.getParamName(0)); + case GET_MESSAGES: return "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable"; + + case COUNT_MESSAGES: + return "SELECT COUNT(MsgTable.EntryNum) FROM MsgTable"; + + case GET_MESSAGE_STUBS: + return "SELECT MsgTable.EntryNum, MsgTable.MsgId, MsgTable.ExactTime FROM MsgTable"; + case GET_SIGNATURES: return "SELECT Signature FROM SignatureTable WHERE EntryNum = :EntryNum"; + case INSERT_MSG: return "INSERT INTO MsgTable (MsgId, Msg) VALUES(:MsgId,:Msg)"; + case INSERT_NEW_TAG: return "INSERT OR IGNORE INTO TagTable(Tag) VALUES (:Tag)"; + + case GET_LAST_MESSAGE_ENTRY: + return "SELECT MAX(MsgTable.EntryNum) FROM MsgTable"; + + case GET_BATCH_MESSAGE_ENTRY: + return MessageFormat.format( + "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable" + + " INNER JOIN SignatureTable ON MsgTable.EntryNum = SignatureTable.EntryNum" + + " INNER JOIN MsgTagTable ON MsgTable.EntryNum = MsgTagTable.EntryNum" + + " INNER JOIN TagTable ON MsgTagTable.TagId = TagTable.TagId" + + " WHERE SignatureTable.SignerId = :{0}" + + " AND TagTable.Tag = :{1}", + QueryType.GET_BATCH_MESSAGE_ENTRY.getParamName(0), + QueryType.GET_BATCH_MESSAGE_ENTRY.getParamName(1)); + + case GET_BATCH_MESSAGE_DATA: + return MessageFormat.format( + "SELECT Data FROM BatchTable" + + " WHERE SignerId = :{0} AND BatchId = :{1} AND SerialNum >= :{2}" + + " ORDER BY SerialNum ASC", + QueryType.GET_BATCH_MESSAGE_DATA.getParamName(0), + QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1), + QueryType.GET_BATCH_MESSAGE_DATA.getParamName(2)); + + case INSERT_BATCH_DATA: + return MessageFormat.format( + "INSERT INTO BatchTable (SignerId, BatchId, SerialNum, Data)" + + " VALUES (:{0}, :{1}, :{2}, :{3})", + QueryType.INSERT_BATCH_DATA.getParamName(0), + QueryType.INSERT_BATCH_DATA.getParamName(1), + QueryType.INSERT_BATCH_DATA.getParamName(2), + QueryType.INSERT_BATCH_DATA.getParamName(3)); + + case CHECK_BATCH_LENGTH: + return MessageFormat.format( + "SELECT COUNT(Data) AS BatchLength FROM BatchTable" + + " WHERE SignerId = :{0} AND BatchId = :{1}", + QueryType.CHECK_BATCH_LENGTH.getParamName(0), + QueryType.CHECK_BATCH_LENGTH.getParamName(1)); + + case CONNECT_BATCH_TAG: + return MessageFormat.format( + "INSERT INTO BatchTagTable (SignerId, BatchId, TagId) SELECT :{0}, :{1}, TagId FROM TagTable" + + " WHERE Tag = :{2}", + QueryType.CONNECT_BATCH_TAG.getParamName(0), + QueryType.CONNECT_BATCH_TAG.getParamName(1), + QueryType.CONNECT_BATCH_TAG.getParamName(2)); + + case GET_BATCH_TAGS: + return MessageFormat.format( + "SELECT Tag FROM TagTable INNER JOIN BatchTagTable ON TagTable.TagId = BatchTagTable.TagId" + + " WHERE SignerId = :{0} AND BatchId = :{1} ORDER BY Tag ASC", + QueryType.GET_BATCH_TAGS.getParamName(0), + QueryType.GET_BATCH_TAGS.getParamName(1)); + + case REMOVE_BATCH_TAGS: + return MessageFormat.format( + "DELETE FROM BatchTagTable WHERE SignerId = :{0} AND BatchId = :{1}", + QueryType.REMOVE_BATCH_TAGS.getParamName(0), + QueryType.REMOVE_BATCH_TAGS.getParamName(1)); + default: throw new IllegalArgumentException("Cannot serve a query of type " + queryType); } @@ -52,21 +131,34 @@ public class SQLiteQueryProvider implements BulletinBoardSQLServer.SQLQueryProvi switch(filterType) { case EXACT_ENTRY: return "MsgTable.EntryNum = :EntryNum" + serialString; + case MAX_ENTRY: return "MsgTable.EntryNum <= :EntryNum" + serialString; + case MIN_ENTRY: return "MsgTable.EntryNum <= :EntryNum" + serialString; + case MAX_MESSAGES: return "LIMIT = :Limit" + serialString; + case MSG_ID: return "MsgTable.MsgId = :MsgId" + serialString; + case SIGNER_ID: return "EXISTS (SELECT 1 FROM SignatureTable" + " WHERE SignatureTable.SignerId = :SignerId" + serialString + " AND SignatureTable.EntryNum = MsgTable.EntryNum)"; + case TAG: return "EXISTS (SELECT 1 FROM TagTable" + " INNER JOIN MsgTagTable ON TagTable.TagId = MsgTagTable.TagId" + " WHERE TagTable.Tag = :Tag" + serialString + " AND MsgTagTable.EntryNum = MsgTable.EntryNum)"; + + case BEFORE_TIME: + return "MsgTable.ExactTime <= :TimeStamp"; + + case AFTER_TIME: + return "MsgTable.ExactTime >= :TimeStamp"; + default: throw new IllegalArgumentException("Cannot serve a filter of type " + filterType); } diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java index e33c739..1e7921d 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java @@ -24,9 +24,12 @@ import meerkat.comm.CommunicationException; import meerkat.comm.MessageInputStream; import meerkat.comm.MessageOutputStream; import meerkat.comm.MessageInputStream.MessageInputStreamFactory; +import meerkat.crypto.Digest; import meerkat.crypto.concrete.ECDSASignature; +import meerkat.crypto.concrete.SHA256Digest; import meerkat.protobuf.BulletinBoardAPI.*; -import meerkat.util.BulletinBoardUtils; +import meerkat.util.BulletinBoardMessageGenerator; +import org.h2.util.DateTimeUtils; import static org.junit.Assert.*; import static org.hamcrest.CoreMatchers.*; @@ -59,6 +62,10 @@ public class GenericBulletinBoardServerTest { private final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); // Used to time the tests + private BulletinBoardMessageGenerator bulletinBoardMessageGenerator; + + private Digest digest; + /** * @param bulletinBoardServer is an initialized server. * @throws InstantiationException @@ -121,8 +128,12 @@ public class GenericBulletinBoardServerTest { System.err.println("Couldn't find signing key " + e.getMessage()); fail("Couldn't find signing key " + e.getMessage()); } - - random = new Random(0); // We use insecure randomness in tests for repeatability + + // We use insecure randomness in tests for repeatability + random = new Random(0); + bulletinBoardMessageGenerator = new BulletinBoardMessageGenerator(random); + + digest = new SHA256Digest(); long end = threadBean.getCurrentThreadCpuTime(); System.err.println("Finished initializing GenericBulletinBoardServerTest"); @@ -182,7 +193,10 @@ public class GenericBulletinBoardServerTest { for (i = 1; i <= MESSAGE_NUM; i++) { unsignedMsgBuilder = UnsignedBulletinBoardMessage.newBuilder() .setData(ByteString.copyFrom(data[i - 1])) - .setTimestamp(BulletinBoardUtils.toTimestampProto()); + .setTimestamp(Timestamp.newBuilder() + .setSeconds(i) + .setNanos(i) + .build()); // Add tags based on bit-representation of message number. @@ -619,6 +633,72 @@ public class GenericBulletinBoardServerTest { } } + + public void testSyncQuery() + throws SignatureException, CommunicationException, IOException,NoSuchMethodException, IllegalAccessException, InvocationTargetException { + + Timestamp timestamp = Timestamp.newBuilder() + .setSeconds(1) + .setNanos(0) + .build(); + + BulletinBoardMessage newMessage = bulletinBoardMessageGenerator.generateRandomMessage(signers, timestamp, 10, 10); + + BoolMsg result = bulletinBoardServer.postMessage(newMessage); + assertThat("Failed to post message to BB Server", result.getValue(), is(true)); + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + digest.update(newMessage.getMsg()); + + ByteString messageID = ByteString.copyFrom(digest.digest()); + + MessageFilterList filterList = MessageFilterList.newBuilder() + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.MSG_ID) + .setId(messageID) + .build()) + .build(); + + bulletinBoardServer.readMessages(filterList, new MessageOutputStream(outputStream)); + + MessageInputStream inputStream = + MessageInputStreamFactory.createMessageInputStream(new ByteArrayInputStream( + outputStream.toByteArray()), + BulletinBoardMessage.class); + + long lastEntry = inputStream.asList().get(0).getEntryNum(); + + SyncQuery syncQuery = SyncQuery.newBuilder() + .setFilterList(MessageFilterList.getDefaultInstance()) + .addQuery(SingleSyncQuery.newBuilder() + .setChecksum(2) + .setTimeOfSync(Timestamp.newBuilder() + .setSeconds(2) + .setNanos(0) + .build()) + .build()) + .build(); + + SyncQueryResponse queryResponse = bulletinBoardServer.querySync(syncQuery); + + assertThat("Sync query replies with positive sync when no sync was expected", queryResponse.getLastEntryNum(), is(equalTo(-1l))); + + syncQuery = SyncQuery.newBuilder() + .setFilterList(MessageFilterList.getDefaultInstance()) + .addQuery(SingleSyncQuery.newBuilder() + .setChecksum(messageID.byteAt(0) & messageID.byteAt(1) & messageID.byteAt(2) & messageID.byteAt(3)) + .setTimeOfSync(timestamp) + .build()) + .build(); + + queryResponse = bulletinBoardServer.querySync(syncQuery); + + assertThat("Sync query reply contained wrong last entry number", lastEntry, is(equalTo(queryResponse.getLastEntryNum()))); + + assertThat("Sync query reply contained wrong timestamp", timestamp, is(equalTo(queryResponse.getLastTimeOfSync()))); + + } public void close(){ signers[0].clearSigningKey(); diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/MySQLBulletinBoardServerTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/MySQLBulletinBoardServerTest.java index 42c11f7..273a53f 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/MySQLBulletinBoardServerTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/MySQLBulletinBoardServerTest.java @@ -8,8 +8,11 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +import java.io.IOException; import java.lang.management.ManagementFactory; import java.lang.management.ThreadMXBean; +import java.lang.reflect.InvocationTargetException; +import java.security.SignatureException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; @@ -144,6 +147,16 @@ public class MySQLBulletinBoardServerTest { } + @Test + public void testSyncQuery() { + try { + serverTest.testSyncQuery(); + } catch (Exception e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + } + @After public void close() { System.err.println("Starting to close MySQLBulletinBoardServerTest"); diff --git a/meerkat-common/src/main/java/meerkat/comm/MessageInputStream.java b/meerkat-common/src/main/java/meerkat/comm/MessageInputStream.java index 33deb3f..dc637d9 100644 --- a/meerkat-common/src/main/java/meerkat/comm/MessageInputStream.java +++ b/meerkat-common/src/main/java/meerkat/comm/MessageInputStream.java @@ -5,6 +5,7 @@ import com.google.protobuf.Message; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; +import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -12,7 +13,7 @@ import java.util.List; * Created by Arbel Deutsch Peled on 21-Feb-16. * A input stream of Protobuf messages */ -public class MessageInputStream{ +public class MessageInputStream implements Iterable{ private T.Builder builder; @@ -23,6 +24,33 @@ public class MessageInputStream{ this.builder = (T.Builder) type.getMethod("newBuilder").invoke(type); } + @Override + public Iterator iterator() { + + return new Iterator() { + + @Override + public boolean hasNext() { + try { + return isAvailable(); + } catch (IOException e) { + return false; + } + } + + @Override + public T next() { + try { + return readMessage(); + } catch (IOException e) { + return null; + } + } + + }; + + } + /** * Factory class for actually creating a MessageInputStream */ diff --git a/meerkat-common/src/main/java/meerkat/util/BulletinBoardUtils.java b/meerkat-common/src/main/java/meerkat/util/BulletinBoardUtils.java index d8b362c..8793b2d 100644 --- a/meerkat-common/src/main/java/meerkat/util/BulletinBoardUtils.java +++ b/meerkat-common/src/main/java/meerkat/util/BulletinBoardUtils.java @@ -80,7 +80,7 @@ public class BulletinBoardUtils { * This method creates a Timestamp Protobuf from the current system time * @return a Timestamp Protobuf encoding of the current system time */ - public static com.google.protobuf.Timestamp toTimestampProto() { + public static com.google.protobuf.Timestamp getCurrentTimestampProto() { return toTimestampProto(System.currentTimeMillis()); From 1cf14a60a805a17ebcc795d64a990317c4b414a3 Mon Sep 17 00:00:00 2001 From: Arbel Deutsch Peled Date: Tue, 1 Mar 2016 13:56:18 +0200 Subject: [PATCH 24/49] Bulletin Board Client support for streaming and Timestamps Created standard Checksum interface and implementation for Sync Query mechanism Added the Timestamp into the Batch Digest and Signature logic --- .../SingleServerBulletinBoardClient.java | 6 +- .../SingleServerReadBatchWorker.java | 30 ++-- .../SingleServerReadMessagesWorker.java | 32 +++-- ...dedBulletinBoardClientIntegrationTest.java | 20 ++- .../sqlserver/BulletinBoardSQLServer.java | 20 +-- .../GenericBulletinBoardServerTest.java | 4 +- .../java/meerkat/bulletinboard/Checksum.java | 122 ++++++++++++++++ .../bulletinboard/GenericBatchDigest.java | 2 + .../GenericBatchDigitalSignature.java | 3 + .../meerkat/bulletinboard/SimpleChecksum.java | 131 ++++++++++++++++++ .../java/meerkat/comm/MessageInputStream.java | 6 + .../meerkat/comm/MessageOutputStream.java | 4 + 12 files changed, 342 insertions(+), 38 deletions(-) create mode 100644 meerkat-common/src/main/java/meerkat/bulletinboard/Checksum.java create mode 100644 meerkat-common/src/main/java/meerkat/bulletinboard/SimpleChecksum.java diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java index ea0e93d..24cd6bf 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java @@ -381,11 +381,7 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i @Override public void onSuccess(Boolean msg) { closeBatch( - CloseBatchMessage.newBuilder() - .setBatchId(completeBatch.getBeginBatchMessage().getBatchId()) - .setSig(completeBatch.getSignature()) - .setBatchLength(completeBatch.getBatchDataList().size()) - .build(), + completeBatch.getCloseBatchMessage(), callback ); } diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerReadBatchWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerReadBatchWorker.java index 11fc777..57b336e 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerReadBatchWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerReadBatchWorker.java @@ -3,6 +3,7 @@ package meerkat.bulletinboard.workers.singleserver; import meerkat.bulletinboard.CompleteBatch; import meerkat.bulletinboard.SingleServerWorker; import meerkat.comm.CommunicationException; +import meerkat.comm.MessageInputStream; import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.rest.Constants; @@ -12,6 +13,9 @@ import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.GenericType; import javax.ws.rs.core.Response; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; import java.util.List; import static meerkat.bulletinboard.BulletinBoardConstants.BULLETIN_BOARD_SERVER_PATH; @@ -40,29 +44,33 @@ public class SingleServerReadBatchWorker extends SingleServerWorker inputStream = null; try { - // If a BatchDataList is returned: the read was successful - return response.readEntity(BatchDataList.class).getDataList(); + inputStream = MessageInputStream.MessageInputStreamFactory.createMessageInputStream(in, BatchData.class); - } catch (ProcessingException | IllegalStateException e) { + return inputStream.asList(); + + } catch (IOException | InvocationTargetException e) { // Read failed - throw new CommunicationException("Could not contact the server"); + throw new CommunicationException("Could not contact the server or server returned illegal result"); - } - finally { - response.close(); + } catch (NoSuchMethodException | IllegalAccessException e) { + + throw new CommunicationException("MessageInputStream error"); + + } finally { + try { + inputStream.close(); + } catch (IOException ignored) {} } } diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerReadMessagesWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerReadMessagesWorker.java index 6c09bcc..d8525ab 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerReadMessagesWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerReadMessagesWorker.java @@ -2,6 +2,8 @@ package meerkat.bulletinboard.workers.singleserver; import meerkat.bulletinboard.SingleServerWorker; import meerkat.comm.CommunicationException; +import meerkat.comm.MessageInputStream; +import meerkat.protobuf.BulletinBoardAPI; import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessageList; import meerkat.protobuf.BulletinBoardAPI.MessageFilterList; import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; @@ -13,6 +15,9 @@ import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.Response; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; import java.util.List; import static meerkat.bulletinboard.BulletinBoardConstants.BULLETIN_BOARD_SERVER_PATH; @@ -38,30 +43,33 @@ public class SingleServerReadMessagesWorker extends SingleServerWorker inputStream = null; try { - // If a BulletinBoardMessageList is returned: the read was successful - return response.readEntity(BulletinBoardMessageList.class).getMessageList(); + inputStream = MessageInputStream.MessageInputStreamFactory.createMessageInputStream(in, BulletinBoardMessage.class); - } catch (ProcessingException | IllegalStateException e) { + return inputStream.asList(); + + } catch (IOException | InvocationTargetException e) { // Read failed - throw new CommunicationException("Could not contact the server"); + throw new CommunicationException("Could not contact the server or server returned illegal result"); - } - finally { - response.close(); - } + } catch (NoSuchMethodException | IllegalAccessException e) { + throw new CommunicationException("MessageInputStream error"); + + } finally { + try { + inputStream.close(); + } catch (IOException ignored) {} + } } diff --git a/bulletin-board-client/src/test/java/ThreadedBulletinBoardClientIntegrationTest.java b/bulletin-board-client/src/test/java/ThreadedBulletinBoardClientIntegrationTest.java index dfccebc..59aa615 100644 --- a/bulletin-board-client/src/test/java/ThreadedBulletinBoardClientIntegrationTest.java +++ b/bulletin-board-client/src/test/java/ThreadedBulletinBoardClientIntegrationTest.java @@ -1,5 +1,6 @@ import com.google.common.util.concurrent.FutureCallback; -import com.google.protobuf.ByteString; +import com.google.protobuf.*; +import com.google.protobuf.Timestamp; import meerkat.bulletinboard.AsyncBulletinBoardClient; import meerkat.bulletinboard.CompleteBatch; import meerkat.bulletinboard.GenericBatchDigitalSignature; @@ -284,6 +285,11 @@ public class ThreadedBulletinBoardClientIntegrationTest { } + completeBatch.setTimestamp(Timestamp.newBuilder() + .setSeconds(Math.abs(90)) + .setNanos(50) + .build()); + signers[signer].updateContent(completeBatch); completeBatch.setSignature(signers[signer].sign()); @@ -357,6 +363,10 @@ public class ThreadedBulletinBoardClientIntegrationTest { .addTag("Signature") .addTag("Trustee") .setData(ByteString.copyFrom(b1)) + .setTimestamp(Timestamp.newBuilder() + .setSeconds(20) + .setNanos(30) + .build()) .build()) .addSig(Crypto.Signature.newBuilder() .setType(Crypto.SignatureType.DSA) @@ -440,6 +450,10 @@ public class ThreadedBulletinBoardClientIntegrationTest { CloseBatchMessage closeBatchMessage = CloseBatchMessage.newBuilder() .setBatchId(BATCH_ID) .setBatchLength(BATCH_LENGTH) + .setTimestamp(Timestamp.newBuilder() + .setSeconds(50) + .setNanos(80) + .build()) .setSig(completeBatch.getSignature()) .build(); @@ -525,6 +539,10 @@ public class ThreadedBulletinBoardClientIntegrationTest { .setBatchId(NON_EXISTENT_BATCH_ID) .setBatchLength(1) .setSig(Crypto.Signature.getDefaultInstance()) + .setTimestamp(Timestamp.newBuilder() + .setSeconds(9) + .setNanos(12) + .build()) .build(); // Try to close the (unopened) batch; diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java index b4e2949..c7bcf57 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java @@ -446,9 +446,10 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ sql = sqlQueryProvider.getSQLString(QueryType.FIND_MSG_ID); Map namedParameters = new HashMap(); + namedParameters.put(QueryType.FIND_MSG_ID.getParamName(0),msgID); - List entryNums = jdbcTemplate.query(sql, new MapSqlParameterSource(namedParameters), new LongMapper()); + List entryNums = jdbcTemplate.query(sql, namedParameters, new LongMapper()); if (entryNums.size() > 0){ @@ -462,7 +463,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ namedParameters.put(QueryType.INSERT_MSG.getParamName(2), msg.getMsg().toByteArray()); KeyHolder keyHolder = new GeneratedKeyHolder(); - jdbcTemplate.update(sql,new MapSqlParameterSource(namedParameters),keyHolder); + jdbcTemplate.update(sql, new MapSqlParameterSource(namedParameters), keyHolder); entryNum = keyHolder.getKey().longValue(); @@ -785,6 +786,9 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ .build() ); + // Add timestamp to CompleteBatch + completeBatch.setTimestamp(message.getTimestamp()); + // Add actual batch data to CompleteBatch sql = sqlQueryProvider.getSQLString(QueryType.GET_BATCH_MESSAGE_DATA); @@ -903,20 +907,20 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ long lastEntryNum = getLastMessageEntry(); - long checksum = 0; - Iterator queryIterator = syncQuery.getQueryList().iterator(); SingleSyncQuery currentQuery = queryIterator.next(); List messageStubs = readMessageStubs(syncQuery.getFilterList()); + Checksum checksum = new SimpleChecksum(); + for (BulletinBoardMessage message : messageStubs){ // Check for end of current query if (timestampComparator.compare(message.getMsg().getTimestamp(), currentQuery.getTimeOfSync()) > 0){ - if (checksum == currentQuery.getChecksum()){ + if (checksum.getChecksum() == currentQuery.getChecksum()){ lastTimeOfSync = currentQuery.getTimeOfSync(); } else { break; @@ -932,13 +936,13 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ // Advance checksum - ByteString messageID = message.getMsg().getData(); + ByteString messageID = message.getMsg().getData(); // The data field contains the message ID - checksum &= messageID.byteAt(0) & messageID.byteAt(1) & messageID.byteAt(2) & messageID.byteAt(3); + checksum.update(messageID); } - if (checksum == currentQuery.getChecksum()){ + if (checksum.getChecksum() == currentQuery.getChecksum()){ lastTimeOfSync = currentQuery.getTimeOfSync(); } diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java index 1e7921d..affb1a3 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java @@ -637,6 +637,8 @@ public class GenericBulletinBoardServerTest { public void testSyncQuery() throws SignatureException, CommunicationException, IOException,NoSuchMethodException, IllegalAccessException, InvocationTargetException { + Checksum checksum = new SimpleChecksum(); + Timestamp timestamp = Timestamp.newBuilder() .setSeconds(1) .setNanos(0) @@ -687,7 +689,7 @@ public class GenericBulletinBoardServerTest { syncQuery = SyncQuery.newBuilder() .setFilterList(MessageFilterList.getDefaultInstance()) .addQuery(SingleSyncQuery.newBuilder() - .setChecksum(messageID.byteAt(0) & messageID.byteAt(1) & messageID.byteAt(2) & messageID.byteAt(3)) + .setChecksum(checksum.getChecksum(messageID)) .setTimeOfSync(timestamp) .build()) .build(); diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/Checksum.java b/meerkat-common/src/main/java/meerkat/bulletinboard/Checksum.java new file mode 100644 index 0000000..b8ddb0b --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/Checksum.java @@ -0,0 +1,122 @@ +package meerkat.bulletinboard; + +import com.google.protobuf.ByteString; +import meerkat.crypto.Digest; +import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; +import meerkat.protobuf.BulletinBoardAPI.MessageID; + +import java.util.Collection; + +/** + * Created by Arbel Deutsch Peled on 01-Mar-16. + * This interface is used to create checksums of Bulletin Board messages IDs + * This is useful in comparing database states + */ +public interface Checksum { + + /** + * Sets the Digest method which is used in creating message IDs from the messages themselves + * This method must be called with an initialized Digest before calling any methods that receive a parameter of type BulletinBoardMessage + * @param digest is the Digest that will be used to create message IDs from Bulletin Board Messages + */ + public void setDigest(Digest digest); + + /** + * Used to reset the current checksum state + */ + public void reset(); + + /** + * Update the current checksum with the given ID + * @param messageID is the message ID to be added + */ + public void update(MessageID messageID); + + /** + * Update the current checksum with the given collection of IDs + * @param messageIDs contains the message IDs + */ + public void update(Collection messageIDs); + + /** + * Update the current checksum with the given ID + * @param messageID is the message ID to be added + */ + public void update(ByteString messageID); + + /** + * Update the current checksum with the given ID + * @param messageID is the message ID to be added + */ + public void update(byte[] messageID); + + /** + * Update the current checksum with the message ID of the given message + * @param bulletinBoardMessage is the message whose ID should be added to the checksum + * @throws IllegalStateException if a Digest has not been set before calling this method + */ + public void digestAndUpdate(BulletinBoardMessage bulletinBoardMessage) throws IllegalStateException; + + + /** + * Update the current checksum with the message IDs of the given messages + * @param bulletinBoardMessages contains the messages whose IDs should be added to the checksum + * @throws IllegalStateException if a Digest has not been set before calling this method + */ + public void digestAndUpdate(Collection bulletinBoardMessages) throws IllegalStateException; + + /** + * Returns the current checksum without changing the checksum state + * @return the current checksum + */ + public long getChecksum(); + + /** + * Updates the current checksum with the given ID and returns the resulting checksum + * The checksum is not reset afterwards + * @param messageID is the message ID to be added + * @return the updated checksum + */ + public long getChecksum(MessageID messageID); + + /** + * Updates the current checksum with the given ID and returns the resulting checksum + * The checksum is not reset afterwards + * @param messageID is the message ID to be added + * @return the updated checksum + */ + public long getChecksum(ByteString messageID); + + /** + * Updates the current checksum with the given ID and returns the resulting checksum + * The checksum is not reset afterwards + * @param messageID is the message ID to be added + * @return the updated checksum + */ + public long getChecksum(byte[] messageID); + + /** + * Updates the current checksum with the given IDs and returns the resulting checksum + * The checksum is not reset afterwards + * @param messageIDs contains the message IDs to be added + * @return the updated checksum + */ + public long getChecksum(Collection messageIDs); + + /** + * Updates the current checksum with the message ID of the given message + * The checksum is not reset afterwards + * @param bulletinBoardMessage is the message whose ID should be added to the checksum + * @return the updated checksum + */ + public long digestAndGetChecksum(BulletinBoardMessage bulletinBoardMessage) throws IllegalStateException; + + /** + * Updates the current checksum with the message IDs of the given messages + * The checksum is not reset afterwards + * @param bulletinBoardMessages contains the messages whose IDs should be added to the checksum + * @return the updated checksum + */ + public long digestAndGetChecksum(Collection bulletinBoardMessages) throws IllegalStateException; + +} diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigest.java b/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigest.java index 4f25f59..852bb24 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigest.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigest.java @@ -29,6 +29,8 @@ public class GenericBatchDigest implements BatchDigest{ update(batchData); } + update(completeBatch.getTimestamp()); + } @Override diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigitalSignature.java b/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigitalSignature.java index 7174b42..7327b8e 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigitalSignature.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/GenericBatchDigitalSignature.java @@ -32,10 +32,13 @@ public class GenericBatchDigitalSignature implements BatchDigitalSignature{ public void updateContent(CompleteBatch completeBatch) throws SignatureException { digitalSignature.updateContent(completeBatch.getBeginBatchMessage()); + for (BatchData batchData : completeBatch.getBatchDataList()) { digitalSignature.updateContent(batchData); } + digitalSignature.updateContent(completeBatch.getTimestamp()); + } @Override diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/SimpleChecksum.java b/meerkat-common/src/main/java/meerkat/bulletinboard/SimpleChecksum.java new file mode 100644 index 0000000..90d7ae5 --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/SimpleChecksum.java @@ -0,0 +1,131 @@ +package meerkat.bulletinboard; + +import com.google.protobuf.ByteString; +import meerkat.crypto.Digest; +import meerkat.protobuf.BulletinBoardAPI.MessageID; +import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; + +import java.util.Collection; + +/** + * Created by Arbel Deutsch Peled on 01-Mar-16. + * Implementation of Checksum via bitwise XOR of the bytes of message IDs + */ +public class SimpleChecksum implements Checksum{ + + private Digest digest; + private long checksum; + + public SimpleChecksum() { + digest = null; + reset(); + } + + @Override + public void setDigest(Digest digest) { + this.digest = digest; + } + + @Override + public void reset() { + checksum = 0; + } + + @Override + public void update(MessageID messageID) { + ByteString messageIDByteString = messageID.getID(); + update(messageIDByteString); + } + + @Override + public void update(Collection messageIDs) { + + for (MessageID messageID : messageIDs){ + update(messageID); + } + + } + + @Override + public void update(ByteString messageID) { + for (int i = 0 ; i < messageID.size() ; i++){ + checksum &= messageID.byteAt(i); + } + } + + @Override + public void update(byte[] messageID) { + for (int i = 0 ; i < messageID.length ; i++){ + checksum &= messageID[i]; + } + } + + private void checkDigest() throws IllegalStateException { + + if (digest == null){ + throw new IllegalStateException("Digest method not set. Use setDigest method before calling digestAndUpdate."); + } + + } + + @Override + public void digestAndUpdate(BulletinBoardMessage bulletinBoardMessage) throws IllegalStateException { + + checkDigest(); + + digest.reset(); + digest.update(bulletinBoardMessage); + update(digest.digest()); + + } + + @Override + public void digestAndUpdate(Collection bulletinBoardMessages) throws IllegalStateException { + + for (BulletinBoardMessage bulletinBoardMessage : bulletinBoardMessages){ + digestAndUpdate(bulletinBoardMessage); + } + + } + + @Override + public long getChecksum() { + return checksum; + } + + @Override + public long getChecksum(MessageID messageID) { + update(messageID); + return getChecksum(); + } + + @Override + public long getChecksum(ByteString messageID) { + update(messageID); + return getChecksum(); + } + + @Override + public long getChecksum(byte[] messageID) { + update(messageID); + return getChecksum(); + } + + @Override + public long getChecksum(Collection messageIDs) { + update(messageIDs); + return getChecksum(); + } + + @Override + public long digestAndGetChecksum(BulletinBoardMessage bulletinBoardMessage) throws IllegalStateException { + digestAndUpdate(bulletinBoardMessage); + return getChecksum(); + } + + @Override + public long digestAndGetChecksum(Collection bulletinBoardMessages) throws IllegalStateException { + digestAndUpdate(bulletinBoardMessages); + return getChecksum(); + } +} diff --git a/meerkat-common/src/main/java/meerkat/comm/MessageInputStream.java b/meerkat-common/src/main/java/meerkat/comm/MessageInputStream.java index dc637d9..b1e5255 100644 --- a/meerkat-common/src/main/java/meerkat/comm/MessageInputStream.java +++ b/meerkat-common/src/main/java/meerkat/comm/MessageInputStream.java @@ -89,4 +89,10 @@ public class MessageInputStream implements Iterable{ } + public void close() throws IOException { + + in.close(); + + } + } diff --git a/meerkat-common/src/main/java/meerkat/comm/MessageOutputStream.java b/meerkat-common/src/main/java/meerkat/comm/MessageOutputStream.java index b55bc8e..f72c04c 100644 --- a/meerkat-common/src/main/java/meerkat/comm/MessageOutputStream.java +++ b/meerkat-common/src/main/java/meerkat/comm/MessageOutputStream.java @@ -21,4 +21,8 @@ public class MessageOutputStream { message.writeDelimitedTo(out); } + public void close() throws IOException { + out.close(); + } + } From cc7e138a4303b7df7cee4a244f78e669d92e265e Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Tue, 1 Mar 2016 16:49:55 +0200 Subject: [PATCH 25/49] redesigned mail handler --- .../main/java/Communication/MailHandler.java | 43 +-- .../java/Communication/MessageHandler.java | 12 +- .../src/main/java/Communication/Network.java | 4 +- .../src/main/java/Communication/User.java | 10 +- .../VerifiableSecretSharing.java | 2 +- .../DistributedKeyGeneration.java | 39 +-- .../DistributedKeyGenerationMailHandler.java | 46 ++++ .../DistributedKeyGenerationUserImpl.java | 130 +++++---- ...ecureDistributedKeyGenerationUserImpl.java | 138 ---------- .../SecureDistributedKeyGeneration.java | 63 ++--- ...reDistributedKeyGenerationMailHandler.java | 60 +++++ ...ecureDistributedKeyGenerationUserImpl.java | 247 ++++++++++++++++++ .../java/ShamirSecretSharing/Polynomial.java | 17 -- .../ShamirSecretSharing/SecretSharing.java | 2 +- .../java/JointFeldmanProtocol/DKGTest.java | 2 +- .../src/test/java/SDKGTest.java | 6 +- .../SecretSharingTest.java | 3 +- .../src/main/proto/meerkat/DKGMessages.proto | 25 +- 18 files changed, 546 insertions(+), 303 deletions(-) create mode 100644 destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMailHandler.java delete mode 100644 destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationUserImpl.java rename destributed-key-generation/src/main/java/{SecureDistributedKeyGeneration => SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem}/SecureDistributedKeyGeneration.java (53%) create mode 100644 destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationMailHandler.java create mode 100644 destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationUserImpl.java diff --git a/destributed-key-generation/src/main/java/Communication/MailHandler.java b/destributed-key-generation/src/main/java/Communication/MailHandler.java index 618ba4f..13bd347 100644 --- a/destributed-key-generation/src/main/java/Communication/MailHandler.java +++ b/destributed-key-generation/src/main/java/Communication/MailHandler.java @@ -1,50 +1,53 @@ package Communication; import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; import meerkat.protobuf.DKGMessages; /** * Created by Tzlil on 2/14/2016. */ -public class MailHandler { +public abstract class MailHandler { private MessageHandler messageHandler; public MailHandler(MessageHandler messageHandler){ this.messageHandler = messageHandler; } + public abstract Message extractMessage(DKGMessages.Mail mail); - public void handel(DKGMessages.Mail mail) throws InvalidProtocolBufferException { - switch (mail.getType()){ + public void handel(DKGMessages.Mail mail){ + + Message message = extractMessage(mail); + if (message == null) + return; + + switch (mail.getType()) { case SECRET: - DKGMessages.SecretMessage secretMessage = DKGMessages.SecretMessage.parseFrom(mail.getMessage()); - messageHandler.handelSecretMessage(mail.getSender(),mail.getDestination()== Network.BROADCAST,secretMessage); + messageHandler.handelSecretMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST + , message); break; case COMMITMENT: - DKGMessages.CommitmentMessage commitmentMessage = DKGMessages.CommitmentMessage.parseFrom(mail.getMessage()); - messageHandler.handelCommitmentMessage(mail.getSender(),mail.getDestination()== Network.BROADCAST,commitmentMessage); + messageHandler.handelCommitmentMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST + , message); break; case DONE: - DKGMessages.DoneMessage doneMessage = DKGMessages.DoneMessage.parseFrom(mail.getMessage()); - messageHandler.handelDoneMessage(mail.getSender(),mail.getDestination()== Network.BROADCAST,doneMessage); + messageHandler.handelDoneMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST + , message); break; case COMPLAINT: - DKGMessages.ComplaintMessage complaintMessage = DKGMessages.ComplaintMessage.parseFrom(mail.getMessage()); - messageHandler.handelComplaintMessage(mail.getSender(),mail.getDestination()== Network.BROADCAST,complaintMessage); + messageHandler.handelComplaintMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST + , message); break; - case DOUBLE: - DKGMessages.DoubleSecretMessage doubleSecretMessage = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage()); - messageHandler.handelDoubleSecretMessage(mail.getSender(),mail.getDestination()== Network.BROADCAST,doubleSecretMessage); + case ANSWER: + messageHandler.handelAnswerMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST + , message); default: break; } + + } - - - public MessageHandler getMessageHandler(){ - return messageHandler; - } - public void setMessageHandler(MessageHandler messageHandler) { this.messageHandler = messageHandler; } diff --git a/destributed-key-generation/src/main/java/Communication/MessageHandler.java b/destributed-key-generation/src/main/java/Communication/MessageHandler.java index 8d1447e..a12a600 100644 --- a/destributed-key-generation/src/main/java/Communication/MessageHandler.java +++ b/destributed-key-generation/src/main/java/Communication/MessageHandler.java @@ -1,14 +1,14 @@ package Communication; -import meerkat.protobuf.DKGMessages; +import com.google.protobuf.Message; /** * Created by Tzlil on 2/14/2016. */ public interface MessageHandler { - void handelComplaintMessage(int sender, boolean isBroadcast,DKGMessages.ComplaintMessage complaintMessage); - void handelDoneMessage(int sender, boolean isBroadcast, DKGMessages.DoneMessage doneMessage); - void handelCommitmentMessage(int sender, boolean isBroadcast,DKGMessages.CommitmentMessage commitmentMessage); - void handelSecretMessage(int sender, boolean isBroadcast,DKGMessages.SecretMessage secretMessage); - void handelDoubleSecretMessage(int sender, boolean isBroadcast,DKGMessages.DoubleSecretMessage doubleSecretMessage); + void handelSecretMessage(int sender, boolean isBroadcast, Message message); + void handelCommitmentMessage(int sender, boolean isBroadcast, Message message); + void handelComplaintMessage(int sender, boolean isBroadcast, Message message); + void handelDoneMessage(int sender, boolean isBroadcast, Message message); //will be remove + void handelAnswerMessage(int sender, boolean isBroadcast, Message message); } diff --git a/destributed-key-generation/src/main/java/Communication/Network.java b/destributed-key-generation/src/main/java/Communication/Network.java index fb6dca5..af7e5d6 100644 --- a/destributed-key-generation/src/main/java/Communication/Network.java +++ b/destributed-key-generation/src/main/java/Communication/Network.java @@ -28,11 +28,11 @@ public class Network { } } - public User connect(MessageHandler messageHandler){ + public User connect(MailHandler mailHandler){ Integer id = availableIDs.poll(); if (id == null) return null; - users[id - 1] = new User(id,this,new MailHandler(messageHandler)); + users[id - 1] = new User(id,this,mailHandler); return users[id - 1]; } diff --git a/destributed-key-generation/src/main/java/Communication/User.java b/destributed-key-generation/src/main/java/Communication/User.java index 2de1ba1..3851b4d 100644 --- a/destributed-key-generation/src/main/java/Communication/User.java +++ b/destributed-key-generation/src/main/java/Communication/User.java @@ -32,7 +32,9 @@ public class User{ 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); } @@ -48,11 +50,7 @@ public class User{ public void run() { while (true){ if (!mailbox.isEmpty()){ - try { - mailHandler.handel(mailbox.poll()); - } catch (InvalidProtocolBufferException e) { - e.printStackTrace(); - } + mailHandler.handel(mailbox.poll()); }else{ try { Thread.sleep(30); diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java index 51ae86e..521714d 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java @@ -58,7 +58,7 @@ public class VerifiableSecretSharing extends SecretSharing { * @param commitments * @param group * - * @return product of commitmentsArray[j] ^ (i ^ j) == g ^ polynomial(i) + * @return product of Aik ^ (j ^ k) == g ^ polynomial(i) */ public static BigInteger verify(int j,BigInteger[] commitments,Group group) { BigInteger v = group.zero(); diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java index bf789f1..b52a728 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java @@ -50,8 +50,13 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing{ } public void sendSecret(User user, int j){ - SecretMessage.Point secret = getShare(j).asMessage(); - user.send(j, Mail.Type.DOUBLE,SecretMessage.newBuilder().setSecret(secret).build()); + ByteString secret = ByteString.copyFrom(getShare(j).y.toByteArray()); + user.send(j, Mail.Type.SECRET, + SecretMessage.newBuilder() + .setI(id) + .setJ(j) + .setSecret(secret) + .build()); } /** @@ -66,13 +71,13 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing{ } } - public boolean isValidSecret(int j,BigInteger[] commitments,int i){ - Polynomial.Point secret = shares[j - 1]; - return isValidSecret(secret,commitments,i); + public boolean isValidSecret(int i,BigInteger[] commitments,int j){ + Polynomial.Point secret = shares[i - 1]; + return isValidSecret(secret,commitments,j); } - public boolean isValidSecret(Polynomial.Point secret, BigInteger[] commitments, int i){ - BigInteger v = verify(i,commitments,group); + public boolean isValidSecret(Polynomial.Point secret, BigInteger[] commitments, int j){ + BigInteger v = verify(j,commitments,group); return group.multiply(g,secret.y).equals(v); } @@ -83,12 +88,12 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing{ */ public void broadcastComplains(User user, BigInteger[][]commitmentsTable){ ComplaintMessage complaint; - for (int j = 1; j <= n ; j++ ){ - if(j != id) { - if (!isValidSecret(j,commitmentsTable[j - 1],id)) { + for (int i = 1; i <= n ; i++ ){ + if(i != id) { + if (!isValidSecret(i,commitmentsTable[i - 1],id)) { //message = new Message(Type.Complaint, j) complaint = ComplaintMessage.newBuilder() - .setId(j) + .setId(i) .build(); user.broadcast(Mail.Type.COMPLAINT, complaint); } @@ -98,8 +103,10 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing{ public void broadcastComplaintAnswer(User user, int j){ - user.broadcast(Mail.Type.SECRET, SecretMessage.newBuilder() - .setSecret(getShare(j).asMessage()) + user.broadcast(Mail.Type.ANSWER, SecretMessage.newBuilder() + .setI(id) + .setJ(j) + .setSecret(ByteString.copyFrom(getShare(j).y.toByteArray())) .build()); } @@ -108,10 +115,10 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing{ * if more than t players complain against a player Pi he is disqualified. */ public void answerAllComplainingPlayers(User user, DistributedKeyGenerationUserImpl.ComplainState[] complains){ - for (int j = 1; j <= n ; j++) { - switch (complains[j - 1]) { + for (int i = 1; i <= n ; i++) { + switch (complains[i - 1]) { case Waiting: - broadcastComplaintAnswer(user,j); + broadcastComplaintAnswer(user,i); break; default: break; diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMailHandler.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMailHandler.java new file mode 100644 index 0000000..bc2c63e --- /dev/null +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMailHandler.java @@ -0,0 +1,46 @@ +package JointFeldmanProtocol; + +import Communication.MailHandler; +import Communication.MessageHandler; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; +import meerkat.protobuf.DKGMessages; + +/** + * Created by Tzlil on 2/29/2016. + */ +public class DistributedKeyGenerationMailHandler extends MailHandler { + + public DistributedKeyGenerationMailHandler(MessageHandler messageHandler) { + super(messageHandler); + } + + @Override + public Message extractMessage(DKGMessages.Mail mail) { + try { + Message message; + switch (mail.getType()) { + case SECRET: + message = DKGMessages.SecretMessage.parseFrom(mail.getMessage()); + break; + case COMMITMENT: + message = DKGMessages.CommitmentMessage.parseFrom(mail.getMessage()); + break; + case COMPLAINT: + message = DKGMessages.ComplaintMessage.parseFrom(mail.getMessage()); + break; + case DONE: + message = DKGMessages.DoneMessage.parseFrom(mail.getMessage()); + break; + case ANSWER: + message = DKGMessages.SecretMessage.parseFrom(mail.getMessage()); + break; + default: + return null; + } + return message; + } catch (InvalidProtocolBufferException e) { + return null; + } + } +} diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java index faf0048..43958b2 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java @@ -1,9 +1,12 @@ package JointFeldmanProtocol; +import Communication.MailHandler; import Communication.Network; import Communication.User; import ShamirSecretSharing.Polynomial; import UserInterface.DistributedKeyGenerationUser; +import com.google.protobuf.ByteString; +import com.google.protobuf.Message; import meerkat.protobuf.DKGMessages; import org.factcenter.qilin.primitives.Group; @@ -39,7 +42,10 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio protected Polynomial.Point share; // final share of the secrete protected BigInteger y; // final public value - public DistributedKeyGenerationUserImpl(DistributedKeyGeneration dkg, Network network) { + public DistributedKeyGenerationUserImpl(DistributedKeyGeneration dkg, Network network){ + this(dkg,network,new DistributedKeyGenerationMailHandler(null)); + } + public DistributedKeyGenerationUserImpl(DistributedKeyGeneration dkg, Network network, MailHandler mailHandler) { this.dkg = dkg; this.g = dkg.getGenerator(); @@ -49,11 +55,12 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio this.id = dkg.getId(); this.messageHandler = new MessageHandler(); + mailHandler.setMessageHandler(this.messageHandler); + this.user = network.connect(mailHandler); this.shares = new Polynomial.Point[n]; this.shares[id - 1] = dkg.getShare(id); this.commitmentsTable = new BigInteger[n][t + 1]; this.doneFlags = new boolean[n]; - this.user = network.connect(messageHandler); this.complaintsTable = new ComplainState[n][n]; for (int i = 0; i < n; i++){ Arrays.fill(complaintsTable[i],ComplainState.Non); @@ -212,75 +219,100 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio this.commitmentsCounter = 0; } - @Override - public void handelComplaintMessage(int sender, boolean isBroadcast, DKGMessages.ComplaintMessage complaintMessage) { - if(isBroadcast) { - int i = sender - 1; - int j = complaintMessage.getId() - 1; - switch (complaintsTable[i][j]) { - case Non: - complaintsTable[i][j] = ComplainState.Waiting; - break; - default: - break; - } - } + protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, DKGMessages.ComplaintMessage complaintMessage){ + int i = sender; + int j = complaintMessage.getId(); + return isBroadcast && complaintsTable[i - 1][j - 1].equals( ComplainState.Non); } @Override - public void handelDoneMessage(int sender, boolean isBroadcast, DKGMessages.DoneMessage doneMessage) { - if(isBroadcast && !doneFlags[sender - 1]) { + public void handelComplaintMessage(int sender, boolean isBroadcast, Message message) { + DKGMessages.ComplaintMessage complaintMessage = (DKGMessages.ComplaintMessage)message; + if(isValidComplaintMessage(sender,isBroadcast,complaintMessage)){ + int i = sender; + int j = complaintMessage.getId(); + complaintsTable[i - 1][j - 1] = ComplainState.Waiting; + } + } + + protected boolean isValidDoneMessage(int sender, boolean isBroadcast){ + return isBroadcast && !doneFlags[sender - 1]; + } + + @Override + public void handelDoneMessage(int sender, boolean isBroadcast,Message message) { + if(isValidDoneMessage(sender,isBroadcast)) { doneFlags[sender - 1] = true; doneCounter++; } } + protected boolean isValidCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage){ + int i = sender - 1; + int k = commitmentMessage.getK(); + return isBroadcast && commitmentsTable[i][k] == null; + } + @Override - public void handelCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage) { - if(isBroadcast){ + public void handelCommitmentMessage(int sender, boolean isBroadcast, Message message) { + DKGMessages.CommitmentMessage commitmentMessage = (DKGMessages.CommitmentMessage) message; + if(isValidCommitmentMessage(sender,isBroadcast,commitmentMessage)){ int i = sender - 1; int k = commitmentMessage.getK(); - if(commitmentsTable[i][k] == null){ - commitmentsTable[i][k] = extractCommitment(commitmentMessage); - commitmentsCounter++; - } + commitmentsTable[i][k] = extractCommitment(commitmentMessage); + commitmentsCounter++; } } + protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage){ + int i = secretMessage.getI(); + int j = secretMessage.getJ(); + if(sender != i || isBroadcast) + return false; + else + return shares[i - 1] == null && j == id; + + } + @Override - public void handelSecretMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage) { - Polynomial.Point secret = extractSecret(secretMessage); - if(!isBroadcast){ - if(shares[sender - 1] == null) { - shares[sender - 1] = secret; - secretsCounter++; - } - }else { - int i = sender; - int j = secret.x.intValue(); - switch (complaintsTable[i - 1][j - 1]){ - case Waiting: - if(dkg.isValidSecret(secret,commitmentsTable[i - 1],j)){ - complaintsTable[i - 1][j - 1] = ComplainState.NonDisqualified; - }else{ - complaintsTable[i - 1][j - 1] = ComplainState.Disqualified; - } - break; - default: - break; - } + public void handelSecretMessage(int sender, boolean isBroadcast, Message message) { + DKGMessages.SecretMessage secretMessage = (DKGMessages.SecretMessage) message; + if(isValidSecretMessage(sender,isBroadcast,secretMessage)) { + int i = secretMessage.getI(); + Polynomial.Point secret = extractSecret(i,secretMessage.getSecret()); + shares[i - 1] = secret; + secretsCounter++; } } + protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage){ + int i = secretMessage.getI(); + int j = secretMessage.getJ(); + if(sender != i || !isBroadcast) + return false; + else + return j >= 1 && j <= n && complaintsTable[i - 1][j - 1].equals(ComplainState.Waiting); + } + @Override - public void handelDoubleSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { - + public void handelAnswerMessage(int sender, boolean isBroadcast, Message message) { + DKGMessages.SecretMessage secretMessage = (DKGMessages.SecretMessage) message; + if(isValidAnswerMessage(sender,isBroadcast,secretMessage)) { + int i = secretMessage.getI(); + int j = secretMessage.getJ(); + Polynomial.Point secret = extractSecret(i,secretMessage.getSecret()); + if (dkg.isValidSecret(secret, commitmentsTable[i - 1], j)) + complaintsTable[i - 1][j - 1] = ComplainState.NonDisqualified; + else + complaintsTable[i - 1][j - 1] = ComplainState.Disqualified; + } } - public Polynomial.Point extractSecret(DKGMessages.SecretMessage secretMessage){ - return new Polynomial.Point(secretMessage.getSecret()); + public Polynomial.Point extractSecret(int i, ByteString secret){ + BigInteger x = BigInteger.valueOf(i); + BigInteger y = new BigInteger(secret.toByteArray()); + return new Polynomial.Point(x,y); } - public BigInteger extractCommitment(DKGMessages.CommitmentMessage commitmentMessage){ return new BigInteger(commitmentMessage.getCommitment().toByteArray()); } diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationUserImpl.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationUserImpl.java deleted file mode 100644 index 02ae13e..0000000 --- a/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGenerationUserImpl.java +++ /dev/null @@ -1,138 +0,0 @@ -package SecureDistributedKeyGeneration; - -import Communication.Network; -import JointFeldmanProtocol.DistributedKeyGenerationUserImpl; -import ShamirSecretSharing.Polynomial; -import meerkat.protobuf.DKGMessages; - -import java.math.BigInteger; - -/** - * Created by Tzlil on 2/22/2016. - */ -public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenerationUserImpl { - - private final SecureDistributedKeyGeneration sdkg; - - private final Polynomial.Point[] sharesT; - private final BigInteger[][] verificationValuesTable; - - public SecureDistributedKeyGenerationUserImpl(SecureDistributedKeyGeneration sdkg, Network network) { - super(sdkg, network); - this.sdkg = sdkg; - this.sharesT = new Polynomial.Point[n]; - this.verificationValuesTable = new BigInteger[n][t + 1]; - this.messageHandler = new MessageHandler(); - this.user.setMessageHandler(this.messageHandler); - } - - /** - * stage1 according to the protocol - * 1. Pi broadcasts Cik=Aik*Bik for k = 0,...,t. - * 2. Pi computes the shares Sij,Sij' for j = 1,...,n and sends Sij,Sij' secretly to Pj. - */ - @Override - protected void stage1() { - sdkg.broadcastVerificationValues(user); - sdkg.sendSecrets(user); - } - - /** - * stage2 according to the protocol - * Pj verifies all the shares,sharesT he received - * if check fails for an index i, Pj broadcasts a complaint against Pi. - * Pj broadcasts done message at the end of this stage - */ - @Override - protected void stage2(){ - sdkg.setShares(shares); - sdkg.setSharesT(sharesT); - sdkg.broadcastComplains(user,verificationValuesTable); - //broadcast done message after all complaints - DKGMessages.DoneMessage doneMessage = DKGMessages.DoneMessage.newBuilder().build(); - user.broadcast(DKGMessages.Mail.Type.DONE,doneMessage); - } - - private void ys(){ - sdkg.broadcastCommitments(user); - //wait for receive all commitments from all i in QUAL - for (int i:QUAL) { - for(int k = 0; k <= t; k++) { - while (commitmentsTable[i - 1][k] == null) { - try { - Thread.sleep(300); - } catch (InterruptedException e) { - // do nothing - } - } - } - } - sdkg.broadcastComplaints(user,commitmentsTable,true); - //do something with complaints' answers - - } - - @Override - protected void stage4() { - ys(); - super.stage4(); - } - - private class MessageHandler extends DistributedKeyGenerationUserImpl.MessageHandler{ - - final int NumberOfCommitmentsInStage1 = n * (t + 1); - - @Override - public void handelCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage) { - if(isBroadcast){ - if(commitmentsCounter < NumberOfCommitmentsInStage1){ - int i = sender - 1; - int k = commitmentMessage.getK(); - if(verificationValuesTable[i][k] == null){ - verificationValuesTable[i][k] = extractCommitment(commitmentMessage); - commitmentsCounter++; - } - } else{ - super.handelCommitmentMessage(sender,isBroadcast,commitmentMessage); - } - } - } - - @Override - public void handelSecretMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage) { - //there is no secret message in this protocol - } - - @Override - public void handelDoubleSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { - - Polynomial.Point secret = extractSecret(doubleSecretMessage.getS1()); - Polynomial.Point secretT = extractSecret(doubleSecretMessage.getS2()); - if(!isBroadcast){ - if(shares[sender - 1] == null) { - shares[sender - 1] = secret; - sharesT[sender - 1] = secretT; - secretsCounter++; - } - }else { - if(commitmentsCounter <= NumberOfCommitmentsInStage1) { - int i = sender; - int j = secret.x.intValue(); - switch (complaintsTable[i - 1][j - 1]) { - case Waiting: - if (sdkg.isValidSecret(secret,secretT, verificationValuesTable[j - 1], i)) { - complaintsTable[i - 1][j - 1] = ComplainState.NonDisqualified; - } else { - complaintsTable[i - 1][j - 1] = ComplainState.Disqualified; - } - break; - default: - break; - } - }else{ // stage4 - - } - } - } - } -} diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGeneration.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGeneration.java similarity index 53% rename from destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGeneration.java rename to destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGeneration.java index bd204c8..05e892e 100644 --- a/destributed-key-generation/src/main/java/SecureDistributedKeyGeneration/SecureDistributedKeyGeneration.java +++ b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGeneration.java @@ -1,6 +1,5 @@ -package SecureDistributedKeyGeneration; +package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; -import Communication.Network; import Communication.User; import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; import JointFeldmanProtocol.DistributedKeyGeneration; @@ -8,7 +7,6 @@ import ShamirSecretSharing.Polynomial; import com.google.protobuf.ByteString; import meerkat.protobuf.DKGMessages; import org.factcenter.qilin.primitives.Group; -import org.factcenter.qilin.primitives.concrete.Zpstar; import java.math.BigInteger; import java.util.Random; @@ -32,31 +30,34 @@ public class SecureDistributedKeyGeneration extends DistributedKeyGeneration { @Override public void sendSecret(User user,int j) { - DKGMessages.SecretMessage.Point secret = getShare(j).asMessage();; - DKGMessages.SecretMessage.Point secretT = verifiableSecretSharing.getShare(j).asMessage();; - DKGMessages.DoubleSecretMessage doubleSecretMessage = DKGMessages.DoubleSecretMessage.newBuilder() - .setS1(DKGMessages.SecretMessage.newBuilder().setSecret(secret).build()) - .setS2(DKGMessages.SecretMessage.newBuilder().setSecret(secretT).build()) - .build(); - user.send(j, DKGMessages.Mail.Type.DOUBLE, doubleSecretMessage); + Polynomial.Point secret = getShare(j); + Polynomial.Point secretT = verifiableSecretSharing.getShare(j); + DKGMessages.DoubleSecretMessage doubleSecretMessage = doubleSecretMessage(id,j,secret,secretT); + user.send(j, DKGMessages.Mail.Type.SECRET, doubleSecretMessage); } @Override - public boolean isValidSecret(int j, BigInteger[] commitments, int i){ - Polynomial.Point secret = shares[j - 1]; - Polynomial.Point secretT = sharesT[j - 1]; - return isValidSecret(secret,secretT,commitments,i); + public boolean isValidSecret(int i, BigInteger[] commitments, int j){ + Polynomial.Point secret = shares[i - 1]; + Polynomial.Point secretT = sharesT[i - 1]; + return isValidSecret(secret,secretT,commitments, j); } - public boolean isValidSecret(Polynomial.Point secret,Polynomial.Point secretT, BigInteger[] verificationValues, int i){ - BigInteger v = verify(i,verificationValues,group); + public boolean isValidSecret(Polynomial.Point secret,Polynomial.Point secretT, BigInteger[] verificationValues, int j){ + BigInteger v = verify(j,verificationValues,group); BigInteger exp = group.add(group.multiply(g, secret.y),group.multiply(h, secretT.y)); return exp.equals(v); } - public boolean isValidComplaint(Polynomial.Point secret,Polynomial.Point secretT, BigInteger[] commitments - ,BigInteger[] verificationValues, int i){ - return isValidSecret(secret,secretT,verificationValues,i) && !isValidSecret(secret,commitments,i); + + public void broadcastComplaint(User user,Polynomial.Point secret,Polynomial.Point secretT,int i){ + DKGMessages.DoubleSecretMessage complaint = doubleSecretMessage(i,id,secret,secretT); + user.broadcast(DKGMessages.Mail.Type.COMPLAINT,complaint); + } + + public void broadcastAnswer(User user,Polynomial.Point secret,Polynomial.Point secretT,int i){ + DKGMessages.DoubleSecretMessage complaint = doubleSecretMessage(i,id,secret,secretT); + user.broadcast(DKGMessages.Mail.Type.ANSWER,complaint); } /** @@ -67,10 +68,10 @@ public class SecureDistributedKeyGeneration extends DistributedKeyGeneration { if(!stage4){ broadcastComplains(user,commitmentsTable); }else{ - for (int j = 1; j <= n ; j++ ){ - if(j != id) { - if (!isValidSecret(shares[j - 1],commitmentsTable[j - 1],id)) { - broadcastDoubleSecret(user,shares[j - 1],sharesT[j - 1]); + for (int i = 1; i <= n ; i++ ){ + if(i != id) { + if (!isValidSecret(shares[i - 1],commitmentsTable[i - 1],id)) { + broadcastComplaint(user,shares[i - 1],sharesT[i - 1],i); } } } @@ -87,19 +88,21 @@ public class SecureDistributedKeyGeneration extends DistributedKeyGeneration { broadcastCommitments(user,verificationValues); } - private void broadcastDoubleSecret(User user ,Polynomial.Point secret, Polynomial.Point secretT){ - DKGMessages.SecretMessage.Point secretMessage = secret.asMessage(); - DKGMessages.SecretMessage.Point secretTMessage = secretT.asMessage(); + private DKGMessages.DoubleSecretMessage doubleSecretMessage(int i,int j,Polynomial.Point secret, Polynomial.Point secretT){ DKGMessages.DoubleSecretMessage doubleSecretMessage = DKGMessages.DoubleSecretMessage.newBuilder() - .setS1(DKGMessages.SecretMessage.newBuilder().setSecret(secretMessage).build()) - .setS1(DKGMessages.SecretMessage.newBuilder().setSecret(secretTMessage).build()) + .setI(i) + .setJ(j) + .setSecret(ByteString.copyFrom(secret.y.toByteArray())) + .setSecretT(ByteString.copyFrom(secretT.y.toByteArray())) .build(); - user.broadcast(DKGMessages.Mail.Type.DOUBLE, doubleSecretMessage); + return doubleSecretMessage; } @Override public void broadcastComplaintAnswer(User user, int j) { - broadcastDoubleSecret(user,getShare(j),verifiableSecretSharing.getShare(j)); + DKGMessages.DoubleSecretMessage answer = doubleSecretMessage(id,j,getShare(j) + ,verifiableSecretSharing.getShare(j)); + user.broadcast(DKGMessages.Mail.Type.ANSWER,answer); } public void setSharesT(Polynomial.Point[] sharesT) { diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationMailHandler.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationMailHandler.java new file mode 100644 index 0000000..2f60c6d --- /dev/null +++ b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationMailHandler.java @@ -0,0 +1,60 @@ +package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; + +import Communication.MailHandler; +import Communication.MessageHandler; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; +import meerkat.protobuf.DKGMessages; + +/** + * Created by Tzlil on 2/29/2016. + */ +public class SecureDistributedKeyGenerationMailHandler extends MailHandler { + + private boolean isStage4; + + public SecureDistributedKeyGenerationMailHandler(MessageHandler messageHandler) { + super(messageHandler); + this.isStage4 = false; + } + + @Override + public Message extractMessage(DKGMessages.Mail mail) { + try { + Message message; + switch (mail.getType()) { + case SECRET: + message = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage()); + break; + case COMMITMENT: + message = DKGMessages.CommitmentMessage.parseFrom(mail.getMessage()); + break; + case COMPLAINT: + if(isStage4) + message = DKGMessages.ComplaintMessage.parseFrom(mail.getMessage()); + else + message = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage()); + break; + case DONE: + message = DKGMessages.DoneMessage.parseFrom(mail.getMessage()); + break; + case ANSWER: + message = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage()); + break; + default: + return null; + } + return message; + } catch (InvalidProtocolBufferException e) { + return null; + } + } + + public boolean isStage4() { + return isStage4; + } + + public void setStage4(boolean stage4) { + isStage4 = stage4; + } +} diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationUserImpl.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationUserImpl.java new file mode 100644 index 0000000..e8fcf9d --- /dev/null +++ b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationUserImpl.java @@ -0,0 +1,247 @@ +package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; + +import Communication.Network; +import JointFeldmanProtocol.DistributedKeyGenerationUserImpl; +import ShamirSecretSharing.Polynomial; +import ShamirSecretSharing.SecretSharing; +import com.google.protobuf.Message; +import meerkat.protobuf.DKGMessages; + +import java.math.BigInteger; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Set; + +/** + * Created by Tzlil on 2/22/2016. + */ +public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenerationUserImpl { + + private final SecureDistributedKeyGeneration sdkg; + private final Polynomial.Point[] sharesT; + private final BigInteger[][] verificationValuesTable; + private final Hashtable> ysRestoreShares; + + public SecureDistributedKeyGenerationUserImpl(SecureDistributedKeyGeneration sdkg, Network network) { + super(sdkg, network,new SecureDistributedKeyGenerationMailHandler(null)); + this.sdkg = sdkg; + this.sharesT = new Polynomial.Point[n]; + this.verificationValuesTable = new BigInteger[n][t + 1]; + this.ysRestoreShares = new Hashtable>(); + this.messageHandler = new MessageHandler(); + this.user.setMessageHandler(this.messageHandler); + } + + /** + * stage1 according to the protocol + * 1. Pi broadcasts Cik=Aik*Bik for k = 0,...,t. + * 2. Pi computes the shares Sij,Sij' for j = 1,...,n and sends Sij,Sij' secretly to Pj. + */ + @Override + protected void stage1() { + sdkg.broadcastVerificationValues(user); + sdkg.sendSecrets(user); + } + + /** + * stage2 according to the protocol + * Pj verifies all the shares,sharesT he received + * if check fails for an index i, Pj broadcasts a complaint against Pi. + * Pj broadcasts done message at the end of this stage + */ + @Override + protected void stage2(){ + sdkg.setShares(shares); + sdkg.setSharesT(sharesT); + sdkg.broadcastComplains(user,verificationValuesTable); + //broadcast done message after all complaints + DKGMessages.DoneMessage doneMessage = DKGMessages.DoneMessage.newBuilder().build(); + user.broadcast(DKGMessages.Mail.Type.DONE,doneMessage); + } + + private void ys(){ + sdkg.broadcastCommitments(user); + //wait for receive all commitments from all i in QUAL + for (int i:QUAL) { + for(int k = 0; k <= t; k++) { + while (commitmentsTable[i - 1][k] == null) { + try { + Thread.sleep(300); + } catch (InterruptedException e) { + // do nothing + } + } + } + } + sdkg.broadcastComplaints(user,commitmentsTable,true); + //broadcast done message after all complaints + DKGMessages.DoneMessage doneMessage = DKGMessages.DoneMessage.newBuilder().build(); + user.broadcast(DKGMessages.Mail.Type.DONE,doneMessage); + + for (int i:QUAL) { + while (doneFlags[i - 1]) { + try { + Thread.sleep(300); + } catch (InterruptedException e) { + // do nothing + } + } + } + BigInteger secret; + for (Integer i: ysRestoreShares.keySet()) { + try { + secret = SecretSharing.restoreSecret((Polynomial.Point[])ysRestoreShares.get(i).toArray()); + //ToDo use restored secret... + } catch (Exception e) { + // + } + } + } + + @Override + protected void stage4() { + isStage4 = true; + ((SecureDistributedKeyGenerationMailHandler)user.getMailHandler()).setStage4(true); + ys(); + super.stage4(); + } + boolean isStage4 = false; + private class MessageHandler extends DistributedKeyGenerationUserImpl.MessageHandler{ + + final int NumberOfCommitmentsInStage1 = n * (t + 1); + + @Override + protected boolean isValidCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage) { + if(commitmentsCounter < NumberOfCommitmentsInStage1) { + int i = sender - 1; + int k = commitmentMessage.getK(); + return isBroadcast && verificationValuesTable[i][k] == null; + }else { + return super.isValidCommitmentMessage(sender, isBroadcast, commitmentMessage); + } + } + + @Override + public void handelCommitmentMessage(int sender, boolean isBroadcast, Message message) { + DKGMessages.CommitmentMessage commitmentMessage = ( DKGMessages.CommitmentMessage)message; + if(commitmentsCounter < NumberOfCommitmentsInStage1) { + if(isValidCommitmentMessage(sender,isBroadcast,commitmentMessage)) { + int i = sender - 1; + int k = commitmentMessage.getK(); + verificationValuesTable[i][k] = extractCommitment(commitmentMessage); + commitmentsCounter++; + } + } + else{ + super.handelCommitmentMessage(sender,isBroadcast,commitmentMessage); + } + } + + protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { + DKGMessages.SecretMessage secretMessage = DKGMessages.SecretMessage.newBuilder() + .setI(doubleSecretMessage.getI()) + .setJ(doubleSecretMessage.getJ()) + .setSecret(doubleSecretMessage.getSecret()) + .build(); + return super.isValidSecretMessage(sender,isBroadcast,secretMessage); + } + + @Override + public void handelSecretMessage(int sender, boolean isBroadcast, Message message) { + DKGMessages.DoubleSecretMessage doubleSecretMessage = (DKGMessages.DoubleSecretMessage)message; + if (isValidSecretMessage(sender,isBroadcast,doubleSecretMessage)) { + int i = doubleSecretMessage.getI(); + + Polynomial.Point secret = extractSecret(i, doubleSecretMessage.getSecret()); + Polynomial.Point secretT = extractSecret(i, doubleSecretMessage.getSecretT()); + shares[i - 1] = secret; + sharesT[i - 1] = secretT; + secretsCounter++; + } + } + 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()) + .build(); + return super.isValidAnswerMessage(sender, isBroadcast, secretMessage); + }else{ + int i = doubleSecretMessage.getI(); + int j = doubleSecretMessage.getJ(); + return isBroadcast && j == sender && QUAL.contains(i) && QUAL.contains(j)&& ysRestoreShares.containsKey(i); + } + } + + @Override + public void handelAnswerMessage(int sender, boolean isBroadcast, Message message) { + DKGMessages.DoubleSecretMessage doubleSecretMessage = (DKGMessages.DoubleSecretMessage)message; + if(isValidAnswerMessage(sender,isBroadcast,doubleSecretMessage)) { + int i = doubleSecretMessage.getI(); + int j = doubleSecretMessage.getJ(); + Polynomial.Point secret = extractSecret(i, doubleSecretMessage.getSecret()); + Polynomial.Point secretT = extractSecret(i, doubleSecretMessage.getSecretT()); + if (!isStage4) { + if (sdkg.isValidSecret(secret, secretT, verificationValuesTable[j - 1], i)) { + complaintsTable[i - 1][j - 1] = ComplainState.NonDisqualified; + } else { + complaintsTable[i - 1][j - 1] = ComplainState.Disqualified; + } + } else { + if (ysRestoreShares.get(i).add(secret) && sender != id) { + sdkg.broadcastAnswer(user, secret, secretT, i); + } + } + } + } + + @Override + protected boolean isValidDoneMessage(int sender, boolean isBroadcast) { + if(doneCounter < n) { + return super.isValidDoneMessage(sender, isBroadcast); + }else{ + return isBroadcast && doneFlags[sender - 1]; + } + } + + @Override + public void handelDoneMessage(int sender, boolean isBroadcast, Message message) { + if(doneCounter < n) + super.handelDoneMessage(sender, isBroadcast, message); + else{ + if(isValidDoneMessage(sender,isBroadcast)) { + doneFlags[sender - 1] = false; + } + } + } + + protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, + DKGMessages.DoubleSecretMessage ysComplaintMessage){ + int i = ysComplaintMessage.getI(); + int j = ysComplaintMessage.getJ(); + return isBroadcast && j == sender && QUAL.contains(i) && QUAL.contains(j)&&!ysRestoreShares.containsKey(i); + } + + @Override + public void handelComplaintMessage(int sender, boolean isBroadcast, Message message) { + if(!isStage4) { + super.handelComplaintMessage(sender, isBroadcast, message); + }else { + DKGMessages.DoubleSecretMessage ysComplaintMessage =(DKGMessages.DoubleSecretMessage)message; + if (isValidComplaintMessage(sender,isBroadcast,ysComplaintMessage)) { + int i = ysComplaintMessage.getI(); + int j = ysComplaintMessage.getJ(); + Polynomial.Point secret = extractSecret(i,ysComplaintMessage.getSecret()); + Polynomial.Point secretT = extractSecret(i,ysComplaintMessage.getSecretT()); + if (sdkg.isValidSecret(secret, secretT, verificationValuesTable[i - 1], j) + && !sdkg.isValidSecret(secret, commitmentsTable[i - 1], j)) { + ysRestoreShares.put(i, new HashSet()); + ysRestoreShares.get(i).add(secret); + sdkg.broadcastAnswer(user, secret, secretT, i); + } + } + } + } + } +} diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java index 1c8eb0e..cf8719f 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java @@ -199,15 +199,6 @@ public class Polynomial implements Comparable { this.y = polynomial.image(x); } - /** - * constructor - restore point from message - * @param pointMessage - */ - public Point(DKGMessages.SecretMessage.Point pointMessage) { - this.x = new BigInteger(pointMessage.getX().toByteArray()); - this.y = new BigInteger(pointMessage.getY().toByteArray()); - } - /** * constructor * @param x @@ -217,14 +208,6 @@ public class Polynomial implements Comparable { this.x = x; this.y = y; } - - public DKGMessages.SecretMessage.Point asMessage(){ - return DKGMessages.SecretMessage.Point.newBuilder() - .setX(ByteString.copyFrom(x.toByteArray())) - .setY(ByteString.copyFrom(y.toByteArray())) - .build(); - } - } } diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java index 7dc0bca..7b6133f 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java @@ -66,7 +66,7 @@ public class SecretSharing{ * * @return image of interpolation(shares) at x = 0 */ - public static BigInteger restoreSecrete(Polynomial.Point[] shares) throws Exception { + public static BigInteger restoreSecret(Polynomial.Point[] shares) throws Exception { Polynomial polynomial = Polynomial.interpolation(shares); return polynomial.image(BigInteger.ZERO); } diff --git a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java index 4000ec0..066daff 100644 --- a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java +++ b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java @@ -99,7 +99,7 @@ public class DKGTest { // index = indexes.remove(random.nextInt(indexes.size())); // shares[i] = dkgs[index - 1].getShare(); //} - BigInteger calculatedSecret = SecretSharing.restoreSecrete(shares).mod(q); + BigInteger calculatedSecret = SecretSharing.restoreSecret(shares).mod(q); assert (calculatedSecret.equals(secret)); } diff --git a/destributed-key-generation/src/test/java/SDKGTest.java b/destributed-key-generation/src/test/java/SDKGTest.java index 09bfc2e..e295099 100644 --- a/destributed-key-generation/src/test/java/SDKGTest.java +++ b/destributed-key-generation/src/test/java/SDKGTest.java @@ -1,7 +1,7 @@ import Communication.Network; import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; -import SecureDistributedKeyGeneration.SecureDistributedKeyGeneration; -import SecureDistributedKeyGeneration.SecureDistributedKeyGenerationUserImpl; +import SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem.SecureDistributedKeyGeneration; +import SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem.SecureDistributedKeyGenerationUserImpl; import ShamirSecretSharing.Polynomial; import ShamirSecretSharing.SecretSharing; import UserInterface.DistributedKeyGenerationUser; @@ -99,7 +99,7 @@ public class SDKGTest { // index = indexes.remove(random.nextInt(indexes.size())); // shares[i] = dkgs[index - 1].getShare(); //} - BigInteger calculatedSecret = SecretSharing.restoreSecrete(shares).mod(q); + BigInteger calculatedSecret = SecretSharing.restoreSecret(shares).mod(q); assert (calculatedSecret.equals(secret)); } diff --git a/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java b/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java index 8c73ee0..14aa387 100644 --- a/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java +++ b/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java @@ -1,6 +1,5 @@ package ShamirSecretSharing; -import Communication.Network; import org.factcenter.qilin.primitives.CyclicGroup; import org.factcenter.qilin.primitives.concrete.Zn; import org.junit.Before; @@ -50,7 +49,7 @@ public class SecretSharingTest { for (int i = 0 ; i < shares.length ; i++){ shares[i] = secretSharing.getShare(indexes.remove(random.nextInt(indexes.size()))); } - assert(secret.equals(SecretSharing.restoreSecrete(shares))); + assert(secret.equals(SecretSharing.restoreSecret(shares))); } @Test diff --git a/meerkat-common/src/main/proto/meerkat/DKGMessages.proto b/meerkat-common/src/main/proto/meerkat/DKGMessages.proto index 4fbc4da..70d5808 100644 --- a/meerkat-common/src/main/proto/meerkat/DKGMessages.proto +++ b/meerkat-common/src/main/proto/meerkat/DKGMessages.proto @@ -8,9 +8,12 @@ message Mail{ enum Type { SECRET = 0; COMMITMENT = 1; - DONE = 2; - COMPLAINT = 3; - DOUBLE = 4; + COMPLAINT = 2; + DONE = 3; + ANSWER = 4; + YCOMMITMENT = 5; + YCOMPLAINT = 6; + YANSWER = 7; } int32 sender = 1; int32 destination = 2; @@ -20,16 +23,16 @@ message Mail{ } message SecretMessage { - message Point{ - bytes x = 1; - bytes y = 2; - } - Point secret = 1; + int32 i = 1; + int32 j = 2; + bytes secret = 3; } message DoubleSecretMessage{ - SecretMessage s1 = 1; - SecretMessage s2 = 2; + int32 i = 1; + int32 j = 2; + bytes secret = 3; + bytes secretT = 4; } message CommitmentMessage{ @@ -41,4 +44,4 @@ message DoneMessage{} message ComplaintMessage{ int32 id = 1; -} \ No newline at end of file +} From e4a33af4d4dce07c7de88cca6cbd869fd626ce0f Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Fri, 18 Mar 2016 14:20:47 +0200 Subject: [PATCH 26/49] abort message --- .../src/main/java/Arithmetics/Arithmetic.java | 14 ++ .../src/main/java/Arithmetics/Fp.java | 53 ++++++ .../src/main/java/Arithmetics/Z.java | 29 ++++ .../main/java/Communication/MailHandler.java | 5 + .../java/Communication/MessageHandler.java | 1 + .../src/main/java/Communication/User.java | 2 +- .../DistributedKeyGeneration.java | 116 ++++++++----- .../DistributedKeyGenerationMailHandler.java | 7 +- .../DistributedKeyGenerationParty.java | 28 ++++ .../DistributedKeyGenerationUserImpl.java | 149 ++++++++--------- .../SecureDistributedKeyGeneration.java | 54 +++++-- ...reDistributedKeyGenerationMailHandler.java | 7 +- .../SecureDistributedKeyGenerationParty.java | 25 +++ ...ecureDistributedKeyGenerationUserImpl.java | 153 +++++++++--------- .../java/ShamirSecretSharing/Polynomial.java | 73 +++++---- .../ShamirSecretSharing/SecretSharing.java | 21 ++- .../java/JointFeldmanProtocol/DKGTest.java | 65 ++++---- .../DKGUserImplAbort.java | 63 ++++++++ .../src/test/java/SDKGTest.java | 67 ++++---- .../src/test/java/SDKGUserImplAbort.java | 62 +++++++ .../PolynomialTests/InterpolationTest.java | 19 ++- .../PolynomialTests/Utils.java | 9 ++ .../SecretSharingTest.java | 3 +- .../src/main/proto/meerkat/DKGMessages.proto | 5 +- 24 files changed, 705 insertions(+), 325 deletions(-) create mode 100644 destributed-key-generation/src/main/java/Arithmetics/Arithmetic.java create mode 100644 destributed-key-generation/src/main/java/Arithmetics/Fp.java create mode 100644 destributed-key-generation/src/main/java/Arithmetics/Z.java create mode 100644 destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationParty.java create mode 100644 destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationParty.java create mode 100644 destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGUserImplAbort.java create mode 100644 destributed-key-generation/src/test/java/SDKGUserImplAbort.java diff --git a/destributed-key-generation/src/main/java/Arithmetics/Arithmetic.java b/destributed-key-generation/src/main/java/Arithmetics/Arithmetic.java new file mode 100644 index 0000000..bd9920a --- /dev/null +++ b/destributed-key-generation/src/main/java/Arithmetics/Arithmetic.java @@ -0,0 +1,14 @@ +package Arithmetics; + +import java.math.BigInteger; + +/** + * Created by Tzlil on 3/17/2016. + */ +public interface Arithmetic { + BigInteger add(T a,T b); + BigInteger sub(T a,T b); + BigInteger mul(T a,T b); + BigInteger div(T a,T b); + +} diff --git a/destributed-key-generation/src/main/java/Arithmetics/Fp.java b/destributed-key-generation/src/main/java/Arithmetics/Fp.java new file mode 100644 index 0000000..545dd8b --- /dev/null +++ b/destributed-key-generation/src/main/java/Arithmetics/Fp.java @@ -0,0 +1,53 @@ +package Arithmetics; + +import java.math.BigInteger; + +/** + * Created by Tzlil on 3/17/2016. + */ +public class Fp implements Arithmetic { + public final BigInteger p; + + public Fp(BigInteger p) { + this.p = p; + } + + @Override + public BigInteger add(BigInteger a,BigInteger b){ + return a.add(b).mod(p); + } + + @Override + public BigInteger sub(BigInteger a,BigInteger b){ + return a.add(p).subtract(b).mod(p); + } + + @Override + public BigInteger mul(BigInteger a,BigInteger b){ + return a.multiply(b).mod(p); + } + + @Override + public BigInteger div(BigInteger a,BigInteger b){ + return mul(a,inv(b)); + } + + public BigInteger pow(BigInteger b,BigInteger e){ + if (e.compareTo(BigInteger.ZERO) < 0 ) { + return pow(inv(b), e.negate()); + } + BigInteger result = BigInteger.ONE; + while (e.compareTo(BigInteger.ZERO) > 0) { + if (e.testBit(0)) { + result = mul(result, b); + } + e = e.shiftRight(1); + b = mul(b, b); + } + return result; + } + + public BigInteger inv(BigInteger a){ + return pow(a,p.subtract(BigInteger.valueOf(2))); + } +} diff --git a/destributed-key-generation/src/main/java/Arithmetics/Z.java b/destributed-key-generation/src/main/java/Arithmetics/Z.java new file mode 100644 index 0000000..9523ead --- /dev/null +++ b/destributed-key-generation/src/main/java/Arithmetics/Z.java @@ -0,0 +1,29 @@ +package Arithmetics; + +import java.math.BigInteger; + +/** + * Created by Tzlil on 3/17/2016. + */ +public class Z implements Arithmetic { + + @Override + public BigInteger add(BigInteger a, BigInteger b) { + return a.add(b); + } + + @Override + public BigInteger sub(BigInteger a, BigInteger b) { + return a.subtract(b); + } + + @Override + public BigInteger mul(BigInteger a, BigInteger b) { + return a.multiply(b); + } + + @Override + public BigInteger div(BigInteger a, BigInteger b) { + return a.divide(b); + } +} diff --git a/destributed-key-generation/src/main/java/Communication/MailHandler.java b/destributed-key-generation/src/main/java/Communication/MailHandler.java index 13bd347..fbb0522 100644 --- a/destributed-key-generation/src/main/java/Communication/MailHandler.java +++ b/destributed-key-generation/src/main/java/Communication/MailHandler.java @@ -42,6 +42,11 @@ public abstract class MailHandler { case ANSWER: messageHandler.handelAnswerMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST , message); + break; + case ABORT: + messageHandler.handelAbortMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST + , message); + break; default: break; } diff --git a/destributed-key-generation/src/main/java/Communication/MessageHandler.java b/destributed-key-generation/src/main/java/Communication/MessageHandler.java index a12a600..2d68be4 100644 --- a/destributed-key-generation/src/main/java/Communication/MessageHandler.java +++ b/destributed-key-generation/src/main/java/Communication/MessageHandler.java @@ -11,4 +11,5 @@ public interface MessageHandler { void handelComplaintMessage(int sender, boolean isBroadcast, Message message); void handelDoneMessage(int sender, boolean isBroadcast, Message message); //will be remove void handelAnswerMessage(int sender, boolean isBroadcast, Message message); + void handelAbortMessage(int sender, boolean isBroadcast, Message message); } diff --git a/destributed-key-generation/src/main/java/Communication/User.java b/destributed-key-generation/src/main/java/Communication/User.java index 3851b4d..2077d6e 100644 --- a/destributed-key-generation/src/main/java/Communication/User.java +++ b/destributed-key-generation/src/main/java/Communication/User.java @@ -18,7 +18,7 @@ public class User{ private final Network network; protected User(int ID, Network network, MailHandler mailHandler) { - this.mailbox = new ArrayBlockingQueue(2 * network.n * network.n); + this.mailbox = new ArrayBlockingQueue( network.n * network.n * network.n); this.ID = ID; this.mailHandler = mailHandler; this.receiverThread = new Thread(new Receiver()); diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java index b52a728..99feec6 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java @@ -1,10 +1,10 @@ package JointFeldmanProtocol; import Communication.User; -import ShamirSecretSharing.Polynomial; import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; +import ShamirSecretSharing.Polynomial; import com.google.protobuf.ByteString; -import meerkat.protobuf.DKGMessages.*; +import meerkat.protobuf.DKGMessages; import org.factcenter.qilin.primitives.Group; import java.math.BigInteger; @@ -14,20 +14,31 @@ import java.util.Random; import java.util.Set; /** - * Created by Tzlil on 2/5/2016. - * - * an implementation of a version of Pedersen's distributed key generation protocol + * Created by Tzlil on 3/14/2016. */ -public class DistributedKeyGeneration extends VerifiableSecretSharing{ - +public class DistributedKeyGeneration extends VerifiableSecretSharing { + public enum ComplainState{ + Non, Waiting,Disqualified,NonDisqualified + } protected final int id; - protected Polynomial.Point[] shares; + private DistributedKeyGenerationParty[] parties; + public DistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger q, BigInteger g , Group group, int id) { super(t, n, zi, random, q, g,group); this.id = id; - this.shares = null; + this.parties = new DistributedKeyGenerationParty[n]; + for (int i = 1; i <= n ; i++){ + this.parties[i - 1] = new DistributedKeyGenerationParty(i,n,t); + } + } + + protected void setParties(DistributedKeyGenerationParty[] parties){ + this.parties = parties; + } + protected DistributedKeyGenerationParty[] getParties(){ + return parties; } /** @@ -39,20 +50,20 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing{ } public void broadcastCommitments(User user, BigInteger[] commitments){ - CommitmentMessage commitmentMessage; + DKGMessages.CommitmentMessage commitmentMessage; for (int k = 0; k <= t ; k++){ - commitmentMessage = CommitmentMessage.newBuilder() + commitmentMessage = DKGMessages.CommitmentMessage.newBuilder() .setCommitment(ByteString.copyFrom(commitments[k].toByteArray())) .setK(k) .build(); - user.broadcast(Mail.Type.COMMITMENT, commitmentMessage); + user.broadcast(DKGMessages.Mail.Type.COMMITMENT, commitmentMessage); } } public void sendSecret(User user, int j){ ByteString secret = ByteString.copyFrom(getShare(j).y.toByteArray()); - user.send(j, Mail.Type.SECRET, - SecretMessage.newBuilder() + user.send(j, DKGMessages.Mail.Type.SECRET, + DKGMessages.SecretMessage.newBuilder() .setI(id) .setJ(j) .setSecret(secret) @@ -71,9 +82,9 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing{ } } - public boolean isValidSecret(int i,BigInteger[] commitments,int j){ - Polynomial.Point secret = shares[i - 1]; - return isValidSecret(secret,commitments,j); + public boolean isValidSecret(int i){ + DistributedKeyGenerationParty party = parties[i - 1]; + return isValidSecret(party.share,party.commitments,id); } public boolean isValidSecret(Polynomial.Point secret, BigInteger[] commitments, int j){ @@ -86,24 +97,29 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing{ * Pj verifies all the shares he received (using isValidSecret) * if check fails for an index i, Pj broadcasts a complaint against Pi. */ - public void broadcastComplains(User user, BigInteger[][]commitmentsTable){ - ComplaintMessage complaint; + public void broadcastComplains(User user){ + DKGMessages.IDMessage complaint; for (int i = 1; i <= n ; i++ ){ - if(i != id) { - if (!isValidSecret(i,commitmentsTable[i - 1],id)) { - //message = new Message(Type.Complaint, j) - complaint = ComplaintMessage.newBuilder() - .setId(i) - .build(); - user.broadcast(Mail.Type.COMPLAINT, complaint); - } + if(i != id && !parties[i - 1].aborted) { + sendComplain(user,i); } } } + protected void sendComplain(User user,int i){ + DKGMessages.IDMessage complaint; + if (!isValidSecret(i)) { + //message = new Message(Type.Complaint, j) + complaint = DKGMessages.IDMessage.newBuilder() + .setId(i) + .build(); + user.broadcast(DKGMessages.Mail.Type.COMPLAINT, complaint); + } + } + public void broadcastComplaintAnswer(User user, int j){ - user.broadcast(Mail.Type.ANSWER, SecretMessage.newBuilder() + user.broadcast(DKGMessages.Mail.Type.ANSWER, DKGMessages.SecretMessage.newBuilder() .setI(id) .setJ(j) .setSecret(ByteString.copyFrom(getShare(j).y.toByteArray())) @@ -114,7 +130,8 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing{ * stage3.1 according to the protocol * if more than t players complain against a player Pi he is disqualified. */ - public void answerAllComplainingPlayers(User user, DistributedKeyGenerationUserImpl.ComplainState[] complains){ + public void answerAllComplainingPlayers(User user){ + ComplainState[] complains = parties[id - 1].complaints; for (int i = 1; i <= n ; i++) { switch (complains[i - 1]) { case Waiting: @@ -126,20 +143,35 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing{ } } + protected boolean isPartyCompletedStage1(int i){ + if(parties[i - 1].aborted){ + if(parties[i - 1].share == null){ + return false; + } + for (int k = 0; k <= t ; k++){ + if(parties[i - 1].commitments[k] == null){ + return false; + } + } + } + return true; + } + /** * stage3.2 according to the protocol * if any of the revealed shares fails the verification test, player Pi is disqualified. * set QUAL to be the set of non-disqualified players. */ - public Set calcQUAL(DistributedKeyGenerationUserImpl.ComplainState[][] complains){ + public Set calcQUAL(){ Set QUAL = new HashSet(); boolean nonDisqualified; int counter; - for (int i = 1; i <= complains.length; i++){ + for (int i = 1; i <= n; i++){ + ComplainState[] complains = parties[i - 1].complaints; nonDisqualified = true; counter = 0; - for (int j = 1; j <= complains[i - 1].length; j++){ - switch (complains[i - 1][j - 1]) { + for (int j = 1; j <= n; j++){ + switch (complains[j - 1]) { case Non: break; case NonDisqualified: @@ -150,7 +182,7 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing{ if(!nonDisqualified) break; } - if(nonDisqualified && counter <= t){ + if(nonDisqualified && counter <= t && isPartyCompletedStage1(i)){ QUAL.add(i); } } @@ -161,10 +193,10 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing{ * stage4.1 according to the protocol * public value y is computed as y = multiplication of yi mod p for i in QUAL */ - public BigInteger calcY(BigInteger[] ys,Set QUAL){ + public BigInteger calcY(Set QUAL){ BigInteger y = group.zero(); for (int i : QUAL) { - y = group.add(y , ys[i - 1]); + y = group.add(y , parties[i - 1].commitments[0]); } return y; } @@ -173,12 +205,12 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing{ * stage4.2 according to the protocol * public verification values are computed as Ak = multiplication of Aik mod p for i in QUAL for k = 0,...,t */ - public BigInteger[] calcCommitments(BigInteger[][] commitmentsTable,Set QUAL){ + public BigInteger[] calcCommitments(Set QUAL){ BigInteger[] commitments = new BigInteger[t + 1]; Arrays.fill(commitments,group.zero()); for (int i : QUAL) { for (int k = 0; k <= t; k++){ - commitments[k] = group.add(commitments[k],commitmentsTable[i - 1][k]); + commitments[k] = group.add(commitments[k], parties[i - 1].commitments[k]); } } return commitments; @@ -188,10 +220,10 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing{ * stage4.3 according to the protocol * Pj sets is share of the secret as xj = sum of Sij mod q for i in QUAL */ - public Polynomial.Point calcShare(Polynomial.Point[] shares,Set QUAL){ + public Polynomial.Point calcShare(Set QUAL){ BigInteger xj = BigInteger.ZERO; for (int i : QUAL) { - xj = xj.add(shares[i - 1].y); + xj = xj.add(parties[i - 1].share.y); } return new Polynomial.Point(BigInteger.valueOf(id) , xj.mod(q)); } @@ -200,8 +232,4 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing{ return id; } - public void setShares(Polynomial.Point[] shares){ - this.shares = shares; - } - } diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMailHandler.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMailHandler.java index bc2c63e..fe141f2 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMailHandler.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMailHandler.java @@ -27,14 +27,17 @@ public class DistributedKeyGenerationMailHandler extends MailHandler { message = DKGMessages.CommitmentMessage.parseFrom(mail.getMessage()); break; case COMPLAINT: - message = DKGMessages.ComplaintMessage.parseFrom(mail.getMessage()); + message = DKGMessages.IDMessage.parseFrom(mail.getMessage()); break; case DONE: - message = DKGMessages.DoneMessage.parseFrom(mail.getMessage()); + message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); break; case ANSWER: message = DKGMessages.SecretMessage.parseFrom(mail.getMessage()); break; + case ABORT: + message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); + break; default: return null; } diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationParty.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationParty.java new file mode 100644 index 0000000..617ea08 --- /dev/null +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationParty.java @@ -0,0 +1,28 @@ +package JointFeldmanProtocol; + +import ShamirSecretSharing.Polynomial; + +import java.math.BigInteger; +import java.util.Arrays; + +/** + * Created by Tzlil on 3/14/2016. + */ +public class DistributedKeyGenerationParty { + public final int id; + public Polynomial.Point share; + public BigInteger[] commitments; + public boolean doneFlag; + public DistributedKeyGeneration.ComplainState[] complaints; + public boolean aborted; + + public DistributedKeyGenerationParty(int id, int n, int t) { + this.id = id; + this.share = null; + this.doneFlag = false; + this.complaints = new DistributedKeyGeneration.ComplainState[n]; + Arrays.fill(this.complaints, DistributedKeyGeneration.ComplainState.Non); + this.commitments = new BigInteger[t + 1]; + this.aborted = false; + } +} diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java index 43958b2..f633258 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java @@ -13,14 +13,12 @@ import org.factcenter.qilin.primitives.Group; import java.math.BigInteger; import java.util.Arrays; import java.util.Set; +import JointFeldmanProtocol.DistributedKeyGeneration.ComplainState; /** - * Created by Tzlil on 2/21/2016. + * Created by Tzlil on 3/14/2016. */ public class DistributedKeyGenerationUserImpl implements DistributedKeyGenerationUser { - protected enum ComplainState{ - Non, Waiting,Disqualified,NonDisqualified - } protected final DistributedKeyGeneration dkg; @@ -31,12 +29,8 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio protected final int id; protected MessageHandler messageHandler; - protected final Polynomial.Point[] shares; - protected final BigInteger[][] commitmentsTable; - protected final boolean[] doneFlags; protected final User user; - protected final ComplainState[][] complaintsTable; - + protected final DistributedKeyGenerationParty[] parties; protected Set QUAL; // set of all non-disqualified parties protected BigInteger[] commitments; // public verification values protected Polynomial.Point share; // final share of the secrete @@ -57,14 +51,9 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio this.messageHandler = new MessageHandler(); mailHandler.setMessageHandler(this.messageHandler); this.user = network.connect(mailHandler); - this.shares = new Polynomial.Point[n]; - this.shares[id - 1] = dkg.getShare(id); - this.commitmentsTable = new BigInteger[n][t + 1]; - this.doneFlags = new boolean[n]; - this.complaintsTable = new ComplainState[n][n]; - for (int i = 0; i < n; i++){ - Arrays.fill(complaintsTable[i],ComplainState.Non); - } + this.parties = dkg.getParties(); + + this.parties[id - 1].share = dkg.getShare(id); this.QUAL = null; this.commitments = null; @@ -89,10 +78,15 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio * Pj broadcasts done message at the end of this stage */ protected void stage2(){ - dkg.setShares(shares); - dkg.broadcastComplains(user,commitmentsTable); + Polynomial.Point[] shares = new Polynomial.Point[n]; + BigInteger[][] commitmentsTable = new BigInteger[n][]; + for (int i = 0 ; i < n ; i++){ + shares[i] = parties[i].share; + commitmentsTable[i] = parties[i].commitments; + } + dkg.broadcastComplains(user); //broadcast done message after all complaints - DKGMessages.DoneMessage doneMessage = DKGMessages.DoneMessage.newBuilder().build(); + DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build(); user.broadcast(DKGMessages.Mail.Type.DONE,doneMessage); } @@ -104,13 +98,12 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio * set QUAL to be the set of non-disqualified players. */ protected void stage3(){ - - dkg.answerAllComplainingPlayers(user,complaintsTable[id - 1]); + dkg.answerAllComplainingPlayers(user); // wait until there is no complaint waiting for answer - for (int i = 0; i < complaintsTable.length; i++){ - for (int j = 0; j < complaintsTable[i].length; j++){ - while (complaintsTable[i][j].equals(ComplainState.Waiting)){ + for (int i = 0; i < n; i++){ + for (int j = 0; j < n; j++){ + while (parties[i].complaints[j].equals(ComplainState.Waiting) && !parties[i].aborted){ try { Thread.sleep(300); } catch (InterruptedException e) { @@ -119,7 +112,7 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio } } } - this.QUAL = dkg.calcQUAL(complaintsTable); + this.QUAL = dkg.calcQUAL(); } /** @@ -129,34 +122,51 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio * 3. Pj sets is share of the secret as xj = sum of Sij mod q for i in QUAL */ protected void stage4(){ - BigInteger[] ys = new BigInteger[n]; - for (int i = 0; i < n; i++){ - ys[i] = commitmentsTable[i][0]; + this.y = dkg.calcY(QUAL); + this.commitments = dkg.calcCommitments(QUAL); + this.share = dkg.calcShare(QUAL); + } + + protected void endOfStage1(){ + for (int i = 0 ; i < n ; i++){ + while (parties[i].share == null && !parties[i].aborted){ + try { + Thread.sleep(300); + } catch (InterruptedException e) { + // do nothing + } + } + } + + for (int i = 0 ; i < n ; i++){ + for (int k = 0 ; k <= t ; k++) { + while (parties[i].commitments[k] == null && !parties[i].aborted) { + try { + Thread.sleep(300); + } catch (InterruptedException e) { + // do nothing + } + } + } } - this.y = dkg.calcY(ys,QUAL); - this.commitments = dkg.calcCommitments(commitmentsTable,QUAL); - this.share = dkg.calcShare(shares,QUAL); } @Override public void run() { user.getReceiverThread().start(); stage1(); - while (messageHandler.secretsCounter != n - 1 || messageHandler.commitmentsCounter != n * (t + 1)){ - try { - Thread.sleep(300); - } catch (InterruptedException e) { - // do nothing - } - } + endOfStage1(); stage2(); - while (messageHandler.doneCounter != n){ - try { - Thread.sleep(300); - } catch (InterruptedException e) { - // do nothing + for (int i = 0 ; i < n ; i++){ + while (!parties[i].doneFlag && !parties[i].aborted){ + try { + Thread.sleep(300); + } catch (InterruptedException e) { + // do nothing + } } } + stage3(); stage4(); user.getReceiverThread().interrupt(); @@ -208,49 +218,37 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio } protected class MessageHandler implements Communication.MessageHandler{ - - public int doneCounter; - public int commitmentsCounter; - public int secretsCounter; - - public MessageHandler() { - this.doneCounter = 0; - this.secretsCounter = 0; - this.commitmentsCounter = 0; - } - - protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, DKGMessages.ComplaintMessage complaintMessage){ + protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, DKGMessages.IDMessage complaintMessage){ int i = sender; int j = complaintMessage.getId(); - return isBroadcast && complaintsTable[i - 1][j - 1].equals( ComplainState.Non); + return isBroadcast && parties[i - 1].complaints[j - 1].equals( ComplainState.Non); } @Override public void handelComplaintMessage(int sender, boolean isBroadcast, Message message) { - DKGMessages.ComplaintMessage complaintMessage = (DKGMessages.ComplaintMessage)message; + DKGMessages.IDMessage complaintMessage = (DKGMessages.IDMessage)message; if(isValidComplaintMessage(sender,isBroadcast,complaintMessage)){ int i = sender; int j = complaintMessage.getId(); - complaintsTable[i - 1][j - 1] = ComplainState.Waiting; + parties[i - 1].complaints[j - 1] = ComplainState.Waiting; } } protected boolean isValidDoneMessage(int sender, boolean isBroadcast){ - return isBroadcast && !doneFlags[sender - 1]; + return isBroadcast && !parties[sender - 1].doneFlag; } @Override public void handelDoneMessage(int sender, boolean isBroadcast,Message message) { if(isValidDoneMessage(sender,isBroadcast)) { - doneFlags[sender - 1] = true; - doneCounter++; + parties[sender - 1].doneFlag = true; } } protected boolean isValidCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage){ int i = sender - 1; int k = commitmentMessage.getK(); - return isBroadcast && commitmentsTable[i][k] == null; + return isBroadcast && parties[i].commitments[k] == null; } @Override @@ -259,8 +257,7 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio if(isValidCommitmentMessage(sender,isBroadcast,commitmentMessage)){ int i = sender - 1; int k = commitmentMessage.getK(); - commitmentsTable[i][k] = extractCommitment(commitmentMessage); - commitmentsCounter++; + parties[i].commitments[k] = extractCommitment(commitmentMessage); } } @@ -270,7 +267,7 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio if(sender != i || isBroadcast) return false; else - return shares[i - 1] == null && j == id; + return parties[i - 1].share == null && j == id; } @@ -279,9 +276,8 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio DKGMessages.SecretMessage secretMessage = (DKGMessages.SecretMessage) message; if(isValidSecretMessage(sender,isBroadcast,secretMessage)) { int i = secretMessage.getI(); - Polynomial.Point secret = extractSecret(i,secretMessage.getSecret()); - shares[i - 1] = secret; - secretsCounter++; + Polynomial.Point secret = extractSecret(id,secretMessage.getSecret()); + parties[i - 1].share = secret; } } @@ -291,7 +287,7 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio if(sender != i || !isBroadcast) return false; else - return j >= 1 && j <= n && complaintsTable[i - 1][j - 1].equals(ComplainState.Waiting); + return j >= 1 && j <= n && parties[i - 1].complaints[j - 1].equals(ComplainState.Waiting); } @Override @@ -300,14 +296,19 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio if(isValidAnswerMessage(sender,isBroadcast,secretMessage)) { int i = secretMessage.getI(); int j = secretMessage.getJ(); - Polynomial.Point secret = extractSecret(i,secretMessage.getSecret()); - if (dkg.isValidSecret(secret, commitmentsTable[i - 1], j)) - complaintsTable[i - 1][j - 1] = ComplainState.NonDisqualified; + Polynomial.Point secret = extractSecret(j,secretMessage.getSecret()); + if (dkg.isValidSecret(secret, parties[i - 1].commitments, j)) + parties[i - 1].complaints[j - 1] = ComplainState.NonDisqualified; else - complaintsTable[i - 1][j - 1] = ComplainState.Disqualified; + parties[i - 1].complaints[j - 1] = ComplainState.Disqualified; } } + @Override + public void handelAbortMessage(int sender, boolean isBroadcast, Message message) { + parties[sender - 1].aborted = true; + } + public Polynomial.Point extractSecret(int i, ByteString secret){ BigInteger x = BigInteger.valueOf(i); BigInteger y = new BigInteger(secret.toByteArray()); diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGeneration.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGeneration.java index 05e892e..4a05125 100644 --- a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGeneration.java +++ b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGeneration.java @@ -12,13 +12,13 @@ import java.math.BigInteger; import java.util.Random; /** - * Created by Tzlil on 2/17/2016. + * Created by Tzlil on 3/16/2016. */ public class SecureDistributedKeyGeneration extends DistributedKeyGeneration { private VerifiableSecretSharing verifiableSecretSharing; private final BigInteger h; - private Polynomial.Point[] sharesT; + private SecureDistributedKeyGenerationParty[] parties; public SecureDistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger q, BigInteger g , BigInteger h, Group group, int id) { @@ -26,10 +26,34 @@ public class SecureDistributedKeyGeneration extends DistributedKeyGeneration { this.h = h; BigInteger r = new BigInteger(q.bitLength(),random).mod(q); this.verifiableSecretSharing = 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); + } + setParties(parties); + } + + protected SecureDistributedKeyGenerationParty[] getParties(){ + return parties; } @Override - public void sendSecret(User user,int j) { + protected boolean isPartyCompletedStage1(int i){ + if(parties[i - 1].aborted){ + if(parties[i - 1].share == null){ + return false; + } + for (int k = 0; k <= t ; k++){ + if(parties[i - 1].verifiableValues[k] == null){ + return false; + } + } + } + return true; + } + + @Override + public void sendSecret(User user, int j) { Polynomial.Point secret = getShare(j); Polynomial.Point secretT = verifiableSecretSharing.getShare(j); DKGMessages.DoubleSecretMessage doubleSecretMessage = doubleSecretMessage(id,j,secret,secretT); @@ -37,10 +61,9 @@ public class SecureDistributedKeyGeneration extends DistributedKeyGeneration { } @Override - public boolean isValidSecret(int i, BigInteger[] commitments, int j){ - Polynomial.Point secret = shares[i - 1]; - Polynomial.Point secretT = sharesT[i - 1]; - return isValidSecret(secret,secretT,commitments, j); + public boolean isValidSecret(int i){ + SecureDistributedKeyGenerationParty party = parties[i - 1]; + return isValidSecret(party.share,party.shareT,party.verifiableValues, id); } public boolean isValidSecret(Polynomial.Point secret,Polynomial.Point secretT, BigInteger[] verificationValues, int j){ @@ -49,7 +72,6 @@ public class SecureDistributedKeyGeneration extends DistributedKeyGeneration { return exp.equals(v); } - public void broadcastComplaint(User user,Polynomial.Point secret,Polynomial.Point secretT,int i){ DKGMessages.DoubleSecretMessage complaint = doubleSecretMessage(i,id,secret,secretT); user.broadcast(DKGMessages.Mail.Type.COMPLAINT,complaint); @@ -64,14 +86,16 @@ public class SecureDistributedKeyGeneration extends DistributedKeyGeneration { * stage4.3 according to the protocol * if check fails for index i, Pj */ - public void broadcastComplaints(User user, BigInteger[][] commitmentsTable, boolean stage4){ + public void broadcastComplaints(User user, boolean stage4){ if(!stage4){ - broadcastComplains(user,commitmentsTable); + super.broadcastComplains(user); }else{ + SecureDistributedKeyGenerationParty party; for (int i = 1; i <= n ; i++ ){ - if(i != id) { - if (!isValidSecret(shares[i - 1],commitmentsTable[i - 1],id)) { - broadcastComplaint(user,shares[i - 1],sharesT[i - 1],i); + party = parties[i - 1]; + if(i != id && !party.aborted) { + if (!super.isValidSecret(party.share,party.commitments,id)) { + broadcastComplaint(user,party.share,party.shareT,i); } } } @@ -104,8 +128,4 @@ public class SecureDistributedKeyGeneration extends DistributedKeyGeneration { ,verifiableSecretSharing.getShare(j)); user.broadcast(DKGMessages.Mail.Type.ANSWER,answer); } - - public void setSharesT(Polynomial.Point[] sharesT) { - this.sharesT = sharesT; - } } diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationMailHandler.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationMailHandler.java index 2f60c6d..bad5d07 100644 --- a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationMailHandler.java +++ b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationMailHandler.java @@ -31,16 +31,19 @@ public class SecureDistributedKeyGenerationMailHandler extends MailHandler { break; case COMPLAINT: if(isStage4) - message = DKGMessages.ComplaintMessage.parseFrom(mail.getMessage()); + message = DKGMessages.IDMessage.parseFrom(mail.getMessage()); else message = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage()); break; case DONE: - message = DKGMessages.DoneMessage.parseFrom(mail.getMessage()); + message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); break; case ANSWER: message = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage()); break; + case ABORT: + message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); + break; default: return null; } diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationParty.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationParty.java new file mode 100644 index 0000000..3d933a9 --- /dev/null +++ b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationParty.java @@ -0,0 +1,25 @@ +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. + */ +public class SecureDistributedKeyGenerationParty extends DistributedKeyGenerationParty { + + + public Polynomial.Point shareT; + public BigInteger[] verifiableValues; + public Set restoreSharesSet; + public SecureDistributedKeyGenerationParty(int id, int n, int t) { + super(id, n, t); + this.shareT = null; + this.verifiableValues = new BigInteger[t + 1]; + this.restoreSharesSet = new HashSet(); + } +} diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationUserImpl.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationUserImpl.java index e8fcf9d..778a5d2 100644 --- a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationUserImpl.java +++ b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationUserImpl.java @@ -1,6 +1,9 @@ package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; +import Arithmetics.Arithmetic; +import Arithmetics.Fp; import Communication.Network; +import JointFeldmanProtocol.DistributedKeyGeneration; import JointFeldmanProtocol.DistributedKeyGenerationUserImpl; import ShamirSecretSharing.Polynomial; import ShamirSecretSharing.SecretSharing; @@ -8,28 +11,23 @@ import com.google.protobuf.Message; import meerkat.protobuf.DKGMessages; import java.math.BigInteger; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.Set; /** - * Created by Tzlil on 2/22/2016. + * Created by Tzlil on 3/16/2016. */ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenerationUserImpl { private final SecureDistributedKeyGeneration sdkg; - private final Polynomial.Point[] sharesT; - private final BigInteger[][] verificationValuesTable; - private final Hashtable> ysRestoreShares; + private SecureDistributedKeyGenerationParty[] parties; + private Arithmetic arithmetic; public SecureDistributedKeyGenerationUserImpl(SecureDistributedKeyGeneration sdkg, Network network) { super(sdkg, network,new SecureDistributedKeyGenerationMailHandler(null)); this.sdkg = sdkg; - this.sharesT = new Polynomial.Point[n]; - this.verificationValuesTable = new BigInteger[n][t + 1]; - this.ysRestoreShares = new Hashtable>(); this.messageHandler = new MessageHandler(); this.user.setMessageHandler(this.messageHandler); + this.parties = sdkg.getParties(); + this.arithmetic = new Fp(sdkg.getQ()); } /** @@ -43,6 +41,17 @@ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenera sdkg.sendSecrets(user); } + @Override + protected void endOfStage1(){ + super.endOfStage1(); + BigInteger[] 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 @@ -51,11 +60,10 @@ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenera */ @Override protected void stage2(){ - sdkg.setShares(shares); - sdkg.setSharesT(sharesT); - sdkg.broadcastComplains(user,verificationValuesTable); + sdkg.broadcastComplains(user); //broadcast done message after all complaints - DKGMessages.DoneMessage doneMessage = DKGMessages.DoneMessage.newBuilder().build(); + DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build(); + isVerificationValue = false; user.broadcast(DKGMessages.Mail.Type.DONE,doneMessage); } @@ -64,7 +72,7 @@ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenera //wait for receive all commitments from all i in QUAL for (int i:QUAL) { for(int k = 0; k <= t; k++) { - while (commitmentsTable[i - 1][k] == null) { + while (parties[i - 1].commitments[k] == null && !parties[i - 1].aborted) { try { Thread.sleep(300); } catch (InterruptedException e) { @@ -73,13 +81,13 @@ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenera } } } - sdkg.broadcastComplaints(user,commitmentsTable,true); + sdkg.broadcastComplaints(user,true); //broadcast done message after all complaints - DKGMessages.DoneMessage doneMessage = DKGMessages.DoneMessage.newBuilder().build(); + DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build(); user.broadcast(DKGMessages.Mail.Type.DONE,doneMessage); for (int i:QUAL) { - while (doneFlags[i - 1]) { + while (parties[i - 1].doneFlag && !parties[i - 1].aborted) { try { Thread.sleep(300); } catch (InterruptedException e) { @@ -87,11 +95,40 @@ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenera } } } - BigInteger secret; - for (Integer i: ysRestoreShares.keySet()) { + + int counter = 0; + for (int i:QUAL) { + if(parties[i - 1].aborted){ + counter++; + sdkg.broadcastAnswer(user, parties[i - 1].share, parties[i - 1].shareT, i); + } + } + for (int i:QUAL) { + if(parties[i - 1].aborted){ + while (parties[i - 1].restoreSharesSet.size() < n - counter) { + try { + Thread.sleep(300); + } catch (InterruptedException e) { + // do nothing + } + } + } + } + + for (int i = 0; i < n ; i++) { + if(parties[i].restoreSharesSet.isEmpty()){ + continue; + } try { - secret = SecretSharing.restoreSecret((Polynomial.Point[])ysRestoreShares.get(i).toArray()); - //ToDo use restored secret... + Polynomial.Point[] shares = new Polynomial.Point[parties[i].restoreSharesSet.size()]; + parties[i].restoreSharesSet.toArray(shares); + Polynomial polynomial = SecretSharing.restorePolynomial(shares,arithmetic); + BigInteger[] coefficients = polynomial.getCoefficients(); + for (int k = 0 ; k <= t; k++){ + parties[i].commitments[k] = group.multiply(g,coefficients[k]); + } + parties[i].share = new Polynomial.Point(BigInteger.valueOf(id),polynomial); + } catch (Exception e) { // } @@ -106,37 +143,9 @@ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenera super.stage4(); } boolean isStage4 = false; + boolean isVerificationValue = true; private class MessageHandler extends DistributedKeyGenerationUserImpl.MessageHandler{ - final int NumberOfCommitmentsInStage1 = n * (t + 1); - - @Override - protected boolean isValidCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage) { - if(commitmentsCounter < NumberOfCommitmentsInStage1) { - int i = sender - 1; - int k = commitmentMessage.getK(); - return isBroadcast && verificationValuesTable[i][k] == null; - }else { - return super.isValidCommitmentMessage(sender, isBroadcast, commitmentMessage); - } - } - - @Override - public void handelCommitmentMessage(int sender, boolean isBroadcast, Message message) { - DKGMessages.CommitmentMessage commitmentMessage = ( DKGMessages.CommitmentMessage)message; - if(commitmentsCounter < NumberOfCommitmentsInStage1) { - if(isValidCommitmentMessage(sender,isBroadcast,commitmentMessage)) { - int i = sender - 1; - int k = commitmentMessage.getK(); - verificationValuesTable[i][k] = extractCommitment(commitmentMessage); - commitmentsCounter++; - } - } - else{ - super.handelCommitmentMessage(sender,isBroadcast,commitmentMessage); - } - } - protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { DKGMessages.SecretMessage secretMessage = DKGMessages.SecretMessage.newBuilder() .setI(doubleSecretMessage.getI()) @@ -152,11 +161,8 @@ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenera if (isValidSecretMessage(sender,isBroadcast,doubleSecretMessage)) { int i = doubleSecretMessage.getI(); - Polynomial.Point secret = extractSecret(i, doubleSecretMessage.getSecret()); - Polynomial.Point secretT = extractSecret(i, doubleSecretMessage.getSecretT()); - shares[i - 1] = secret; - sharesT[i - 1] = secretT; - secretsCounter++; + parties[i - 1].share = extractSecret(id, doubleSecretMessage.getSecret()); + parties[i - 1].shareT = extractSecret(id, doubleSecretMessage.getSecretT()); } } protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { @@ -170,7 +176,7 @@ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenera }else{ int i = doubleSecretMessage.getI(); int j = doubleSecretMessage.getJ(); - return isBroadcast && j == sender && QUAL.contains(i) && QUAL.contains(j)&& ysRestoreShares.containsKey(i); + return isBroadcast && j == sender && QUAL.contains(i) && QUAL.contains(j); } } @@ -180,38 +186,36 @@ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenera if(isValidAnswerMessage(sender,isBroadcast,doubleSecretMessage)) { int i = doubleSecretMessage.getI(); int j = doubleSecretMessage.getJ(); - Polynomial.Point secret = extractSecret(i, doubleSecretMessage.getSecret()); - Polynomial.Point secretT = extractSecret(i, doubleSecretMessage.getSecretT()); + Polynomial.Point secret = extractSecret(j, doubleSecretMessage.getSecret()); + Polynomial.Point secretT = extractSecret(j, doubleSecretMessage.getSecretT()); if (!isStage4) { - if (sdkg.isValidSecret(secret, secretT, verificationValuesTable[j - 1], i)) { - complaintsTable[i - 1][j - 1] = ComplainState.NonDisqualified; + if (sdkg.isValidSecret(secret, secretT, parties[j - 1].verifiableValues, i)) { + parties[i - 1].complaints[j - 1] = DistributedKeyGeneration.ComplainState.NonDisqualified; } else { - complaintsTable[i - 1][j - 1] = ComplainState.Disqualified; + parties[i - 1].complaints[j - 1] = DistributedKeyGeneration.ComplainState.Disqualified; } } else { - if (ysRestoreShares.get(i).add(secret) && sender != id) { - sdkg.broadcastAnswer(user, secret, secretT, i); - } + parties[i - 1].restoreSharesSet.add(secret); } } } @Override protected boolean isValidDoneMessage(int sender, boolean isBroadcast) { - if(doneCounter < n) { + if(!isStage4) { return super.isValidDoneMessage(sender, isBroadcast); }else{ - return isBroadcast && doneFlags[sender - 1]; + return isBroadcast && parties[sender - 1].doneFlag; } } @Override public void handelDoneMessage(int sender, boolean isBroadcast, Message message) { - if(doneCounter < n) + if(!isStage4) super.handelDoneMessage(sender, isBroadcast, message); else{ if(isValidDoneMessage(sender,isBroadcast)) { - doneFlags[sender - 1] = false; + parties[sender - 1].doneFlag = false; } } } @@ -220,9 +224,11 @@ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenera DKGMessages.DoubleSecretMessage ysComplaintMessage){ int i = ysComplaintMessage.getI(); int j = ysComplaintMessage.getJ(); - return isBroadcast && j == sender && QUAL.contains(i) && QUAL.contains(j)&&!ysRestoreShares.containsKey(i); + return isBroadcast && j == sender && QUAL.contains(i) && QUAL.contains(j); } + + @Override public void handelComplaintMessage(int sender, boolean isBroadcast, Message message) { if(!isStage4) { @@ -234,10 +240,9 @@ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenera int j = ysComplaintMessage.getJ(); Polynomial.Point secret = extractSecret(i,ysComplaintMessage.getSecret()); Polynomial.Point secretT = extractSecret(i,ysComplaintMessage.getSecretT()); - if (sdkg.isValidSecret(secret, secretT, verificationValuesTable[i - 1], j) - && !sdkg.isValidSecret(secret, commitmentsTable[i - 1], j)) { - ysRestoreShares.put(i, new HashSet()); - ysRestoreShares.get(i).add(secret); + if (sdkg.isValidSecret(secret, secretT, parties[i - 1].commitments, j) + && !sdkg.isValidSecret(secret,parties[i - 1].commitments, j)) { + parties[i - 1].restoreSharesSet.add(secret); sdkg.broadcastAnswer(user, secret, secretT, i); } } diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java index cf8719f..119cf61 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java @@ -1,18 +1,19 @@ package ShamirSecretSharing; -import com.google.protobuf.ByteString; -import meerkat.protobuf.DKGMessages; -import org.bouncycastle.util.Arrays; +import Arithmetics.Arithmetic; +import Arithmetics.Z; + import java.math.BigInteger; +import java.util.Arrays; /** * Created by Tzlil on 1/27/2016. */ public class Polynomial implements Comparable { - public static final Polynomial ZERO = new Polynomial(new BigInteger[]{BigInteger.ZERO}); // neutral for add - public static final Polynomial ONE = new Polynomial(new BigInteger[]{BigInteger.ONE}); // neutral for mul + public static final Polynomial ONE = new Polynomial(new BigInteger[]{BigInteger.ONE}); private final int degree; private final BigInteger[] coefficients; + private final Arithmetic arithmetic; /** * constructor @@ -20,12 +21,17 @@ public class Polynomial implements Comparable { * degree set as max index such that coefficients[degree] not equals zero */ public Polynomial(BigInteger[] coefficients) { + this(coefficients,new Z()); + } + + public Polynomial(BigInteger[] coefficients,Arithmetic arithmetic) { int d = coefficients.length - 1; while (d > 0 && coefficients[d].equals(BigInteger.ZERO)){ d--; } this.degree = d; this.coefficients = coefficients; + this.arithmetic = arithmetic; } @@ -60,7 +66,7 @@ public class Polynomial implements Comparable { BigInteger result = BigInteger.ZERO; BigInteger power = BigInteger.ONE; for(int i = 0 ; i <= degree ; i++){ - result = result.add(coefficients[i].multiply(power)); + result = arithmetic.add(result,arithmetic.mul(coefficients[i],power)); power = power.multiply(x); } return result; @@ -70,19 +76,18 @@ public class Polynomial implements Comparable { * @param points * @return polynomial of minimal degree which goes through all points */ - public static Polynomial interpolation(Point[] points) throws Exception { + public static Polynomial interpolation(Point[] points, Arithmetic arithmetic) throws Exception { LagrangePolynomial[] l = LagrangePolynomial.lagrangePolynomials(points); - // product = product of l[i].divisor BigInteger product = BigInteger.ONE; for (int i = 0; i < l.length;i++){ - product = product.multiply(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 BigInteger[] factors = new BigInteger[l.length]; for (int i = 0; i < l.length;i++){ - factors[i] = product.divide(l[i].divisor); + factors[i] = arithmetic.div(product,l[i].divisor); } int degree = l[0].polynomial.degree; @@ -92,11 +97,13 @@ public class Polynomial implements Comparable { for (int j = 0; j < coefficients.length;j++){ coefficients[j] = BigInteger.ZERO; for (int i = 0; i < l.length; i++){ - coefficients[j] = coefficients[j].add(l[i].image.multiply(factors[i]).multiply(l[i].polynomial.coefficients[j])); + BigInteger current = arithmetic.mul(l[i].image,factors[i]); + current = arithmetic.mul(current,l[i].polynomial.coefficients[j]); + coefficients[j] = arithmetic.add(coefficients[j],current); } - coefficients[j] = coefficients[j].divide(product); + coefficients[j] = arithmetic.div(coefficients[j],product); } - return new Polynomial(coefficients); + return new Polynomial(coefficients,arithmetic); } /** @@ -116,14 +123,14 @@ public class Polynomial implements Comparable { BigInteger[] coefficients = bigger.getCoefficients(); for (int i = 0; i <= smaller.degree ; i++){ - coefficients[i] = smaller.coefficients[i].add(bigger.coefficients[i]); + coefficients[i] = arithmetic.add(smaller.coefficients[i],bigger.coefficients[i]); } - return new Polynomial(coefficients); + return new Polynomial(coefficients,other.arithmetic); } /** * @param constant - * @return new ShamirSecretSharing.PolynomialTests of degree this.degree s.t for all x in Z + * @return new Polynomial of degree this.degree s.t for all x in Z * new.image(x) = constant * this.image(x) */ public Polynomial mul(BigInteger constant){ @@ -131,27 +138,27 @@ public class Polynomial implements Comparable { BigInteger[] coefficients = this.getCoefficients(); for (int i = 0; i <= this.degree ; i++){ - coefficients[i] = constant.multiply(coefficients[i]); + coefficients[i] = arithmetic.mul(constant,coefficients[i]); } - return new Polynomial(coefficients); + return new Polynomial(coefficients,arithmetic); } /** * @param other - * @return new ShamirSecretSharing.PolynomialTests 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 in Z * new.image(x) = this.image(x) * other.image(x) */ public Polynomial mul(Polynomial other){ BigInteger[] coefficients = new BigInteger[this.degree + other.degree + 1]; - java.util.Arrays.fill(coefficients,BigInteger.ZERO); + Arrays.fill(coefficients,BigInteger.ZERO); for (int i = 0; i <= this.degree ; i++){ for (int j = 0; j <= other.degree; j++){ - coefficients[i+j] = coefficients[i+j].add(this.coefficients[i].multiply(other.coefficients[j])); + coefficients[i+j] = arithmetic.add(coefficients[i+j],arithmetic.mul(this.coefficients[i],other.coefficients[j])); } } - return new Polynomial(coefficients); + return new Polynomial(coefficients,arithmetic); } @@ -159,7 +166,7 @@ public class Polynomial implements Comparable { * @return copy of coefficients */ public BigInteger[] getCoefficients() { - return Arrays.clone(coefficients); + return Arrays.copyOf(coefficients,coefficients.length); } /** getter @@ -187,18 +194,6 @@ public class Polynomial implements Comparable { this.y = polynomial.image(x); } - /** - * constructor - * @param x - * @param p - * @param polynomial y = polynomial.image(x) % q - * - */ - public Point(BigInteger x, Polynomial polynomial,BigInteger p) { - this.x = x; - this.y = polynomial.image(x); - } - /** * constructor * @param x @@ -208,6 +203,14 @@ public class Polynomial implements Comparable { this.x = x; this.y = y; } + + @Override + public boolean equals(Object obj) { + if(!super.equals(obj)) + return false; + Point other = (Point)obj; + return this.x.equals(other.x) && this.y.equals(other.y); + } } } diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java index 7b6133f..cdd631d 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java @@ -1,9 +1,6 @@ package ShamirSecretSharing; - -import Communication.Network; -import Communication.User; -import meerkat.protobuf.DKGMessages; +import Arithmetics.Arithmetic; import java.math.BigInteger; import java.util.Random; @@ -58,7 +55,7 @@ public class SecretSharing{ */ public Polynomial.Point getShare(int i){ assert (i > 0 && i <= n); - return new Polynomial.Point(BigInteger.valueOf(i), polynomial, q); + return new Polynomial.Point(BigInteger.valueOf(i), polynomial); } /** @@ -66,9 +63,17 @@ public class SecretSharing{ * * @return image of interpolation(shares) at x = 0 */ - public static BigInteger restoreSecret(Polynomial.Point[] shares) throws Exception { - Polynomial polynomial = Polynomial.interpolation(shares); - return polynomial.image(BigInteger.ZERO); + public static BigInteger restoreSecret(Polynomial.Point[] shares,Arithmetic arithmetic) throws Exception { + return restorePolynomial(shares,arithmetic).image(BigInteger.ZERO); + } + + /** + * @param shares - subset of the original shares + * + * @return interpolation(shares) + */ + public static Polynomial restorePolynomial(Polynomial.Point[] shares,Arithmetic arithmetic) throws Exception { + return Polynomial.interpolation(shares,arithmetic); } /** diff --git a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java index 066daff..b74f258 100644 --- a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java +++ b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java @@ -1,5 +1,6 @@ package JointFeldmanProtocol; +import Arithmetics.Z; import Communication.Network; import ShamirSecretSharing.Polynomial; import ShamirSecretSharing.SecretSharing; @@ -11,7 +12,7 @@ import org.junit.Before; import org.junit.Test; import java.math.BigInteger; -import java.util.Random; +import java.util.*; /** * Created by Tzlil on 2/9/2016. @@ -25,6 +26,7 @@ public class DKGTest { BigInteger p = BigInteger.valueOf(2903); BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); BigInteger[] secrets; + Set QUAL = new HashSet(); @Before public void settings(){ Zpstar zpstar = new Zpstar(p); @@ -37,18 +39,28 @@ public class DKGTest { threadsArrays = new Thread[tests][n]; secrets = new BigInteger[tests]; DistributedKeyGeneration dkg; + int abortedStage = 2; for (int test = 0; test < tests; test++) { do { g = zpstar.sample(random); } while (!g.equals(ZERO) && !zpstar.multiply(g, q).equals(ZERO));// sample from QRZp* secrets[test] = BigInteger.ZERO; Network network = new Network(n); - for (int i = 0; i < n; i++) { + for (int i = 1; i <= n; i++) { BigInteger secret = new BigInteger(q.bitLength(), random).mod(q); - secrets[test] = secrets[test].add(secret).mod(q); - dkg = new DistributedKeyGeneration(t,n,secret,random,q,g,zpstar,i + 1); - dkgsArrays[test][i] = new DistributedKeyGenerationUserImpl(dkg,network); - threadsArrays[test][i] = new Thread(dkgsArrays[test][i]); + dkg = new DistributedKeyGeneration(t,n,secret,random,q,g,zpstar,i); + + if(i == n) { + dkgsArrays[test][i - 1] = new DKGUserImplAbort(dkg, network, abortedStage); + } + else { + dkgsArrays[test][i - 1] = new DistributedKeyGenerationUserImpl(dkg, network); + QUAL.add(i); + } + if (abortedStage > 1 || (abortedStage == 1 && i != n)){ + secrets[test] = secrets[test].add(secret).mod(q); + } + threadsArrays[test][i - 1] = new Thread(dkgsArrays[test][i - 1]); } } } @@ -67,39 +79,32 @@ public class DKGTest { BigInteger g = dkgs[0].getGenerator(); // got the right public value - BigInteger publicValue = dkgs[0].getPublicValue(); - assert(zpstar.multiply(g,secret).equals(publicValue)); - - // assert all players agreed on the same public value - for (int i = 0; i < dkgs.length - 1 ; i++){ - assert (dkgs[i].getPublicValue().equals(dkgs[i+1].getPublicValue())); + BigInteger publicValue = zpstar.multiply(g,secret); + for (int i: QUAL){ + if(i != n) + assert (dkgs[i - 1].getPublicValue().equals(publicValue)); } // assert valid verification values BigInteger expected,verification; - for (int j = 1; j <= dkgs.length ; j++){ - expected = zpstar.multiply(g, dkgs[j - 1].getShare().y); - verification = VerifiableSecretSharing.verify(j, dkgs[j - 1].getCommitments(),zpstar); + for (int i: QUAL){ + expected = zpstar.multiply(g, dkgs[i - 1].getShare().y); + verification = VerifiableSecretSharing.verify(i, dkgs[i - 1].getCommitments(),zpstar); assert (expected.equals(verification)); } - // restore the secret from t + 1 random shares - Polynomial.Point[] shares = new Polynomial.Point[t + 1]; - for (int i = 0 ; i < shares.length; i++){ - shares[i] = dkgs[i].getShare(); + // restore the secret from shares + ArrayList sharesList = new ArrayList(); + Polynomial.Point[] shares = new Polynomial.Point[QUAL.size()]; + for(int i : QUAL){ + sharesList.add(dkgs[i - 1].getShare()); } - //List indexes = new ArrayList(n); - //for (int i = 1 ; i <= n; i ++){ - // indexes.add(i); - //} - //Random random = new Random(); - //int index; - //for (int i = 0 ; i < shares.length ; i++){ - // index = indexes.remove(random.nextInt(indexes.size())); - // shares[i] = dkgs[index - 1].getShare(); - //} - BigInteger calculatedSecret = SecretSharing.restoreSecret(shares).mod(q); + for (int i = 0; i < shares.length; i ++){ + shares[i] = sharesList.get(i); + } + + BigInteger calculatedSecret = SecretSharing.restoreSecret(shares,new Z()).mod(q); assert (calculatedSecret.equals(secret)); } diff --git a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGUserImplAbort.java b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGUserImplAbort.java new file mode 100644 index 0000000..39f211a --- /dev/null +++ b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGUserImplAbort.java @@ -0,0 +1,63 @@ +package JointFeldmanProtocol; + +import Communication.Network; +import meerkat.protobuf.DKGMessages; + +/** + * Created by Tzlil on 3/14/2016. + */ +public class DKGUserImplAbort extends DistributedKeyGenerationUserImpl { + + final int abortStage; + int stage; + public DKGUserImplAbort(DistributedKeyGeneration dkg, Network network, int abortStage) { + super(dkg, network); + this.abortStage = abortStage;// 1 - 2 + this.stage = 1; + } + + + private void sendAbort(){ + user.broadcast(DKGMessages.Mail.Type.ABORT,DKGMessages.EmptyMessage.getDefaultInstance()); + } + + @Override + protected void stage1() { + if(stage < abortStage) + super.stage1(); + else if(stage == abortStage){ + sendAbort(); + } + stage++; + } + + @Override + protected void stage2() { + if(stage < abortStage) + super.stage2(); + else if(stage == abortStage){ + sendAbort(); + } + stage++; + } + + @Override + protected void stage3() { + if(stage < abortStage) + super.stage3(); + else if(stage == abortStage){ + sendAbort(); + } + stage++; + } + + @Override + protected void stage4() { + if(stage < abortStage) + super.stage4(); + else if(stage == abortStage){ + sendAbort(); + } + stage++; + } +} diff --git a/destributed-key-generation/src/test/java/SDKGTest.java b/destributed-key-generation/src/test/java/SDKGTest.java index e295099..5866063 100644 --- a/destributed-key-generation/src/test/java/SDKGTest.java +++ b/destributed-key-generation/src/test/java/SDKGTest.java @@ -1,3 +1,4 @@ +import Arithmetics.Z; import Communication.Network; import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; import SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem.SecureDistributedKeyGeneration; @@ -11,7 +12,10 @@ import org.junit.Before; import org.junit.Test; import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashSet; import java.util.Random; +import java.util.Set; /** * Created by Tzlil on 2/23/2016. @@ -24,6 +28,9 @@ public class SDKGTest { BigInteger p = BigInteger.valueOf(2903); BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); BigInteger[] secrets; + + Set QUAL = new HashSet(); + @Before public void settings(){ Zpstar zpstar = new Zpstar(p); @@ -43,16 +50,26 @@ public class SDKGTest { h = zpstar.multiply(g,BigInteger.valueOf(2)); secrets[test] = BigInteger.ZERO; Network network = new Network(n); - for (int i = 0; i < n; i++) { + int abortedStage = 2; + for (int i = 1; i <= n; i++) { BigInteger secret = new BigInteger(q.bitLength(), random).mod(q); - secrets[test] = secrets[test].add(secret).mod(q); - sdkg = new SecureDistributedKeyGeneration(t,n,secret,random,q,g,h,zpstar,i + 1); - sdkgsArrays[test][i] = new SecureDistributedKeyGenerationUserImpl(sdkg,network); - threadsArrays[test][i] = new Thread(sdkgsArrays[test][i]); + sdkg = new SecureDistributedKeyGeneration(t,n,secret,random,q,g,h,zpstar,i); + if(i == n) { + sdkgsArrays[test][i - 1] = new SDKGUserImplAbort(sdkg, network, abortedStage); + } + else { + sdkgsArrays[test][i - 1] = new SecureDistributedKeyGenerationUserImpl(sdkg, network); + QUAL.add(i); + } + if (abortedStage > 1 || (abortedStage == 1 && i != n)){ + secrets[test] = secrets[test].add(secret).mod(q); + } + threadsArrays[test][i - 1] = new Thread(sdkgsArrays[test][i - 1]); } } } + public void oneTest(Thread[] threads, DistributedKeyGenerationUser[] dkgs,BigInteger secret) throws Exception { for (int i = 0; i < threads.length ; i++){ threads[i].start(); @@ -67,39 +84,31 @@ public class SDKGTest { BigInteger g = dkgs[0].getGenerator(); // got the right public value - BigInteger publicValue = dkgs[0].getPublicValue(); - assert(zpstar.multiply(g,secret).equals(publicValue)); - - // assert all players agreed on the same public value - for (int i = 0; i < dkgs.length - 1 ; i++){ - assert (dkgs[i].getPublicValue().equals(dkgs[i+1].getPublicValue())); + BigInteger publicValue = zpstar.multiply(g,secret); + for (int i: QUAL){ + assert (dkgs[i - 1].getPublicValue().equals(publicValue)); } // assert valid verification values BigInteger expected,verification; - for (int j = 1; j <= dkgs.length ; j++){ - expected = zpstar.multiply(g, dkgs[j - 1].getShare().y); - verification = VerifiableSecretSharing.verify(j, dkgs[j - 1].getCommitments(),zpstar); + for (int i: QUAL){ + expected = zpstar.multiply(g, dkgs[i - 1].getShare().y); + verification = VerifiableSecretSharing.verify(i, dkgs[i - 1].getCommitments(),zpstar); assert (expected.equals(verification)); } - // restore the secret from t + 1 random shares - Polynomial.Point[] shares = new Polynomial.Point[t + 1]; - for (int i = 0 ; i < shares.length; i++){ - shares[i] = dkgs[i].getShare(); + // restore the secret from shares + ArrayList sharesList = new ArrayList(); + Polynomial.Point[] shares = new Polynomial.Point[QUAL.size()]; + for(int i : QUAL){ + sharesList.add(dkgs[i - 1].getShare()); } - //List indexes = new ArrayList(n); - //for (int i = 1 ; i <= n; i ++){ - // indexes.add(i); - //} - //Random random = new Random(); - //int index; - //for (int i = 0 ; i < shares.length ; i++){ - // index = indexes.remove(random.nextInt(indexes.size())); - // shares[i] = dkgs[index - 1].getShare(); - //} - BigInteger calculatedSecret = SecretSharing.restoreSecret(shares).mod(q); + for (int i = 0; i < shares.length; i ++){ + shares[i] = sharesList.get(i); + } + + BigInteger calculatedSecret = SecretSharing.restoreSecret(shares,new Z()).mod(q); assert (calculatedSecret.equals(secret)); } diff --git a/destributed-key-generation/src/test/java/SDKGUserImplAbort.java b/destributed-key-generation/src/test/java/SDKGUserImplAbort.java new file mode 100644 index 0000000..bc30eb5 --- /dev/null +++ b/destributed-key-generation/src/test/java/SDKGUserImplAbort.java @@ -0,0 +1,62 @@ +import Communication.Network; +import SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem.SecureDistributedKeyGeneration; +import SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem.SecureDistributedKeyGenerationUserImpl; +import meerkat.protobuf.DKGMessages; + +/** + * Created by Tzlil on 3/14/2016. + */ +public class SDKGUserImplAbort extends SecureDistributedKeyGenerationUserImpl { + + final int abortStage; + int stage; + public SDKGUserImplAbort(SecureDistributedKeyGeneration sdkg, Network network, int abortStage) { + super(sdkg, network); + this.abortStage = abortStage;// 1 - 4 + this.stage = 1; + } + + private void sendAbort(){ + user.broadcast(DKGMessages.Mail.Type.ABORT,DKGMessages.EmptyMessage.getDefaultInstance()); + } + + @Override + protected void stage1() { + if(stage < abortStage) + super.stage1(); + else if(stage == abortStage){ + sendAbort(); + } + stage++; + } + + @Override + protected void stage2() { + if(stage < abortStage) + super.stage2(); + else if(stage == abortStage){ + sendAbort(); + } + stage++; + } + + @Override + protected void stage3() { + if(stage < abortStage) + super.stage3(); + else if(stage == abortStage){ + sendAbort(); + } + stage++; + } + + @Override + protected void stage4() { + if(stage < abortStage) + super.stage4(); + else if(stage == abortStage){ + sendAbort(); + } + stage++; + } +} diff --git a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/InterpolationTest.java b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/InterpolationTest.java index b1539cc..2f5ba39 100644 --- a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/InterpolationTest.java +++ b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/InterpolationTest.java @@ -1,5 +1,8 @@ package ShamirSecretSharing.PolynomialTests; +import Arithmetics.Arithmetic; +import Arithmetics.Fp; +import Arithmetics.Z; import ShamirSecretSharing.Polynomial; import org.junit.Before; import org.junit.Test; @@ -19,35 +22,39 @@ public class InterpolationTest { int bits = 128; Random random; Polynomial.Point[][] pointsArrays; + Arithmetic arithmetic; + BigInteger p = BigInteger.valueOf(2903); + @Before public void settings(){ random = new Random(); polynomials = new Polynomial[tests]; pointsArrays = new Polynomial.Point[tests][]; for (int i = 0; i < polynomials.length; i++){ - polynomials[i] = Utils.generateRandomPolynomial(random.nextInt(maxDegree),bits,random); + polynomials[i] = Utils.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,p); pointsArrays[i] = randomPoints(polynomials[i]); } + arithmetic = new Fp(p); } - public Polynomial.Point[] randomPoints(Polynomial p){ - Polynomial.Point[] points = new Polynomial.Point[p.getDegree() + 1]; + public Polynomial.Point[] randomPoints(Polynomial polynomial){ + Polynomial.Point[] points = new Polynomial.Point[polynomial.getDegree() + 1]; BigInteger x; Set set = new HashSet(); for (int i = 0; i < points.length; i++){ - x = new BigInteger(bits,random); + x = new BigInteger(bits,random).mod(p); if(set.contains(x)){ i--; continue; } set.add(x); - points[i] = new Polynomial.Point(x,p); + points[i] = new Polynomial.Point(x,polynomial); } return points; } public void oneTest(Polynomial p, Polynomial.Point[] points) throws Exception { - Polynomial interpolation = Polynomial.interpolation(points); + Polynomial interpolation = Polynomial.interpolation(points,arithmetic); assert (p.compareTo(interpolation) == 0); } diff --git a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/Utils.java b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/Utils.java index 47dca28..8ec057a 100644 --- a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/Utils.java +++ b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/Utils.java @@ -1,5 +1,6 @@ package ShamirSecretSharing.PolynomialTests; +import Arithmetics.Fp; import ShamirSecretSharing.Polynomial; import java.math.BigInteger; @@ -18,4 +19,12 @@ public class Utils { } return new Polynomial(coefficients); } + + public static Polynomial generateRandomPolynomial(int degree,int bits,Random random,BigInteger p) { + BigInteger[] coefficients = generateRandomPolynomial(degree,bits,random).getCoefficients(); + for (int i = 0; i Date: Mon, 21 Mar 2016 20:32:57 +0200 Subject: [PATCH 27/49] Local Client for testing (without subscription yet) Partial implementation of subscriptions. Some bug fixes. --- .../SimpleBulletinBoardClient.java | 35 ++ .../SingleServerBulletinBoardClient.java | 51 +- .../ThreadedBulletinBoardClient.java | 11 +- .../SingleServerGetRedundancyWorker.java | 24 +- ...dedBulletinBoardClientIntegrationTest.java | 556 ------------------ .../LocalBulletinBoardClientTest.java | 107 ++++ .../sqlserver/BulletinBoardSQLServer.java | 96 ++- .../mappers/MessageCallbackHandler.java | 6 +- .../mappers/MessageStubCallbackHandler.java | 59 ++ .../webapp/BulletinBoardWebApp.java | 17 +- .../AsyncBulletinBoardClient.java | 13 +- .../bulletinboard/BulletinBoardClient.java | 15 +- .../bulletinboard/BulletinBoardConstants.java | 1 + .../bulletinboard/BulletinBoardServer.java | 11 +- .../BulletinBoardSubscriber.java | 32 + .../BulletinBoardSynchronizer.java | 22 + .../meerkat/bulletinboard/CompleteBatch.java | 5 + .../SubscriptionAsyncBulletinBoardClient.java | 7 + .../main/proto/meerkat/BulletinBoardAPI.proto | 12 + 19 files changed, 474 insertions(+), 606 deletions(-) delete mode 100644 bulletin-board-client/src/test/java/ThreadedBulletinBoardClientIntegrationTest.java create mode 100644 bulletin-board-client/src/test/java/meerkat/bulletinboard/LocalBulletinBoardClientTest.java create mode 100644 bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/MessageStubCallbackHandler.java create mode 100644 meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardSubscriber.java create mode 100644 meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardSynchronizer.java create mode 100644 meerkat-common/src/main/java/meerkat/bulletinboard/SubscriptionAsyncBulletinBoardClient.java diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java index 633e495..2ed113a 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java @@ -1,13 +1,21 @@ package meerkat.bulletinboard; import com.google.protobuf.ByteString; +import com.google.protobuf.Timestamp; import meerkat.comm.CommunicationException; +import meerkat.comm.MessageInputStream; import meerkat.crypto.Digest; import meerkat.crypto.concrete.SHA256Digest; +import meerkat.protobuf.BulletinBoardAPI; import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.protobuf.Voting.*; import meerkat.rest.*; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.util.Collection; +import java.util.Iterator; import java.util.List; import javax.ws.rs.client.Client; @@ -129,6 +137,7 @@ public class SimpleBulletinBoardClient implements BulletinBoardClient{ */ @Override public List readMessages(MessageFilterList filterList) { + WebTarget webTarget; Response response; BulletinBoardMessageList messageList; @@ -139,6 +148,7 @@ public class SimpleBulletinBoardClient implements BulletinBoardClient{ } for (String db : meerkatDBs) { + try { webTarget = client.target(db).path(BULLETIN_BOARD_SERVER_PATH).path(READ_MESSAGES_PATH); @@ -151,9 +161,34 @@ public class SimpleBulletinBoardClient implements BulletinBoardClient{ } } catch (Exception e) {} + } return null; + + } + + @Override + public SyncQuery generateSyncQuery(GenerateSyncQueryParams generateSyncQueryParams) throws CommunicationException { + + WebTarget webTarget; + Response response; + + for (String db : meerkatDBs) { + + try { + webTarget = client.target(db).path(BULLETIN_BOARD_SERVER_PATH).path(GENERATE_SYNC_QUERY_PATH); + + response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(generateSyncQueryParams, Constants.MEDIATYPE_PROTOBUF)); + + return response.readEntity(SyncQuery.class); + + } catch (Exception e) {} + + } + + throw new CommunicationException("Could not contact any server"); + } public void close() { diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java index 24cd6bf..34531cf 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java @@ -7,6 +7,7 @@ import com.google.common.util.concurrent.MoreExecutors; import com.google.protobuf.ByteString; import meerkat.bulletinboard.workers.singleserver.*; import meerkat.comm.CommunicationException; +import meerkat.protobuf.BulletinBoardAPI; import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.protobuf.Voting.BulletinBoardClientParams; import meerkat.util.BulletinBoardUtils; @@ -29,7 +30,7 @@ import java.util.concurrent.atomic.AtomicInteger; * If the list of servers contains more than one server: the server actually used is the first one * The class further implements a delayed access to the server after a communication error occurs */ -public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient implements AsyncBulletinBoardClient { +public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient implements SubscriptionAsyncBulletinBoardClient { private final int MAX_RETRIES = 11; @@ -275,13 +276,13 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i class SubscriptionCallback implements FutureCallback> { private SingleServerReadMessagesWorker worker; - private final MessageHandler messageHandler; + private final FutureCallback> callback; private MessageFilterList.Builder filterBuilder; - public SubscriptionCallback(SingleServerReadMessagesWorker worker, MessageHandler messageHandler) { + public SubscriptionCallback(SingleServerReadMessagesWorker worker, FutureCallback> callback) { this.worker = worker; - this.messageHandler = messageHandler; + this.callback = callback; filterBuilder = worker.getPayload().toBuilder(); } @@ -290,7 +291,7 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i public void onSuccess(List result) { // Report new messages to user - messageHandler.handleNewMessages(result); + callback.onSuccess(result); // Remove last filter from list (MIN_ENTRY one) filterBuilder.removeFilter(filterBuilder.getFilterCount() - 1); @@ -315,14 +316,16 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i // Notify client about failure fail(); - // Reschedule exact same task - scheduleWorker(worker, this); + // Notify caller about failure and terminate subscription + callback.onFailure(t); } } - public SingleServerBulletinBoardClient(int threadPoolSize, long failDelayInMilliseconds, long subscriptionIntervalInMilliseconds) { + public SingleServerBulletinBoardClient(ListeningScheduledExecutorService executorService, + long failDelayInMilliseconds, + long subscriptionIntervalInMilliseconds) { - executorService = MoreExecutors.listeningDecorator(Executors.newScheduledThreadPool(threadPoolSize)); + this.executorService = executorService; this.failDelayInMilliseconds = failDelayInMilliseconds; this.subscriptionIntervalInMilliseconds = subscriptionIntervalInMilliseconds; @@ -332,6 +335,14 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i } + public SingleServerBulletinBoardClient(int threadPoolSize, long failDelayInMilliseconds, long subscriptionIntervalInMilliseconds) { + + this(MoreExecutors.listeningDecorator(Executors.newScheduledThreadPool(threadPoolSize)), + failDelayInMilliseconds, + subscriptionIntervalInMilliseconds); + + } + /** * Stores database location, initializes the web Client and * @param clientParams contains the data needed to access the DBs @@ -567,8 +578,16 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i } @Override - public void subscribe(MessageFilterList filterList, MessageHandler messageHandler) { + public void querySync(SyncQuery syncQuery, FutureCallback callback) { + SingleServerQuerySyncWorker worker = new SingleServerQuerySyncWorker(meerkatDBs.get(0), syncQuery, MAX_RETRIES); + + scheduleWorker(worker, new RetryCallback<>(worker, callback)); + + } + + @Override + public void subscribe(MessageFilterList filterList, long startEntry, FutureCallback> callback) { // Remove all existing MIN_ENTRY filters and create new one that starts at 0 MessageFilterList.Builder filterListBuilder = filterList.toBuilder(); @@ -583,15 +602,19 @@ public class SingleServerBulletinBoardClient extends SimpleBulletinBoardClient i } filterListBuilder.addFilter(MessageFilter.newBuilder() .setType(FilterType.MIN_ENTRY) - .setEntry(0) + .setEntry(startEntry) .build()); // Create job with no retries - SingleServerReadMessagesWorker worker = new SingleServerReadMessagesWorker(meerkatDBs.get(0), filterListBuilder.build(), 1); + SingleServerReadMessagesWorker worker = new SingleServerReadMessagesWorker(meerkatDBs.get(0), filterListBuilder.build(), MAX_RETRIES); - // Submit job and create callback - scheduleWorker(worker, new SubscriptionCallback(worker, messageHandler)); + // Submit job and create callback that retries on failure and handles repeated subscription + scheduleWorker(worker, new RetryCallback<>(worker, new SubscriptionCallback(worker, callback))); + } + @Override + public void subscribe(MessageFilterList filterList, FutureCallback> callback) { + subscribe(filterList, 0, callback); } @Override diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java index d8f66f2..52e28e0 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java @@ -5,6 +5,7 @@ import com.google.protobuf.ByteString; import meerkat.bulletinboard.workers.multiserver.*; import meerkat.comm.CommunicationException; +import meerkat.protobuf.BulletinBoardAPI; import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.protobuf.Voting.*; @@ -55,7 +56,7 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple batchDigest = new GenericBatchDigest(digest); - minAbsoluteRedundancy = (int) (clientParams.getMinRedundancy() * clientParams.getBulletinBoardAddressCount()); + minAbsoluteRedundancy = (int) (clientParams.getMinRedundancy() * (float) clientParams.getBulletinBoardAddressCount()); executorService = Executors.newFixedThreadPool(JOBS_THREAD_NUM); @@ -223,9 +224,13 @@ public class ThreadedBulletinBoardClient extends SimpleBulletinBoardClient imple } + /** + * This method is not supported by this class! + * This is because it has no meaning when considering more than one server without knowing which server will be contacted + */ @Override - public void subscribe(MessageFilterList filterList, MessageHandler messageHandler) { - // TODO: Implement + public void querySync(SyncQuery syncQuery, FutureCallback callback) { + callback.onFailure(new IllegalAccessError("querySync is not supported by this class")); } @Override diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerGetRedundancyWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerGetRedundancyWorker.java index 10517f7..0401a76 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerGetRedundancyWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerGetRedundancyWorker.java @@ -2,6 +2,7 @@ package meerkat.bulletinboard.workers.singleserver; import meerkat.bulletinboard.SingleServerWorker; import meerkat.comm.CommunicationException; +import meerkat.comm.MessageInputStream; import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.rest.Constants; @@ -11,6 +12,10 @@ import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.Response; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; + import static meerkat.bulletinboard.BulletinBoardConstants.BULLETIN_BOARD_SERVER_PATH; import static meerkat.bulletinboard.BulletinBoardConstants.READ_MESSAGES_PATH; @@ -45,17 +50,19 @@ public class SingleServerGetRedundancyWorker extends SingleServerWorker inputStream = null; // Retrieve answer try { - // If a BulletinBoardMessageList is returned: the read was successful - BulletinBoardMessageList msgList = response.readEntity(BulletinBoardMessageList.class); + inputStream = MessageInputStream.MessageInputStreamFactory.createMessageInputStream(in, BulletinBoardMessage.class); - if (msgList.getMessageList().size() > 0){ + if (inputStream.asList().size() > 0){ // Message exists in the server return 1.0f; } @@ -64,14 +71,15 @@ public class SingleServerGetRedundancyWorker extends SingleServerWorker thrown; - private Random random; - - // Constructor - - public ThreadedBulletinBoardClientIntegrationTest(){ - - signers = new GenericBatchDigitalSignature[2]; - signerIDs = new ByteString[signers.length]; - signers[0] = new GenericBatchDigitalSignature(new ECDSASignature()); - signers[1] = new GenericBatchDigitalSignature(new ECDSASignature()); - - InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE); - char[] password = KEYFILE_PASSWORD1.toCharArray(); - - KeyStore.Builder keyStoreBuilder; - try { - keyStoreBuilder = signers[0].getPKCS12KeyStoreBuilder(keyStream, password); - - signers[0].loadSigningCertificate(keyStoreBuilder); - - signers[0].loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE)); - - keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE3); - password = KEYFILE_PASSWORD3.toCharArray(); - - keyStoreBuilder = signers[1].getPKCS12KeyStoreBuilder(keyStream, password); - signers[1].loadSigningCertificate(keyStoreBuilder); - - signers[1].loadVerificationCertificates(getClass().getResourceAsStream(CERT3_PEM_EXAMPLE)); - - for (int i = 0 ; i < signers.length ; i++) { - signerIDs[i] = signers[i].getSignerID(); - } - - } catch (IOException e) { - System.err.println("Failed reading from signature file " + e.getMessage()); - fail("Failed reading from signature file " + e.getMessage()); - } catch (CertificateException e) { - System.err.println("Failed reading certificate " + e.getMessage()); - fail("Failed reading certificate " + e.getMessage()); - } catch (KeyStoreException e) { - System.err.println("Failed reading keystore " + e.getMessage()); - fail("Failed reading keystore " + e.getMessage()); - } catch (NoSuchAlgorithmException e) { - System.err.println("Couldn't find signing algorithm " + e.getMessage()); - fail("Couldn't find signing algorithm " + e.getMessage()); - } catch (UnrecoverableKeyException e) { - System.err.println("Couldn't find signing key " + e.getMessage()); - fail("Couldn't find signing key " + e.getMessage()); - } - - } - - // Callback definitions - - protected void genericHandleFailure(Throwable t){ - System.err.println(t.getCause() + " " + t.getMessage()); - thrown.add(t); - jobSemaphore.release(); - } - - private class PostCallback implements FutureCallback{ - - private boolean isAssert; - private boolean assertValue; - - public PostCallback() { - this(false); - } - - public PostCallback(boolean isAssert) { - this(isAssert,true); - } - - public PostCallback(boolean isAssert, boolean assertValue) { - this.isAssert = isAssert; - this.assertValue = assertValue; - } - - @Override - public void onSuccess(Boolean msg) { - System.err.println("Post operation completed"); - jobSemaphore.release(); - //TODO: Change Assert mechanism to exception one - if (isAssert) { - if (assertValue) { - assertThat("Post operation failed", msg, is(Boolean.TRUE)); - } else { - assertThat("Post operation succeeded unexpectedly", msg, is(Boolean.FALSE)); - } - } - } - - @Override - public void onFailure(Throwable t) { - genericHandleFailure(t); - } - } - - private class RedundancyCallback implements FutureCallback{ - - private float minRedundancy; - - public RedundancyCallback(float minRedundancy) { - this.minRedundancy = minRedundancy; - } - - @Override - public void onSuccess(Float redundancy) { - System.err.println("Redundancy found is: " + redundancy); - jobSemaphore.release(); - assertThat(redundancy, greaterThanOrEqualTo(minRedundancy)); - } - - @Override - public void onFailure(Throwable t) { - genericHandleFailure(t); - } - } - - private class ReadCallback implements FutureCallback>{ - - private List expectedMsgList; - - public ReadCallback(List expectedMsgList) { - this.expectedMsgList = expectedMsgList; - } - - @Override - public void onSuccess(List messages) { - - System.err.println(messages); - jobSemaphore.release(); - - BulletinBoardMessageComparator msgComparator = new BulletinBoardMessageComparator(); - - assertThat(messages.size(), is(expectedMsgList.size())); - - Iterator expectedMessageIterator = expectedMsgList.iterator(); - Iterator receivedMessageIterator = messages.iterator(); - - while (expectedMessageIterator.hasNext()) { - assertThat(msgComparator.compare(expectedMessageIterator.next(), receivedMessageIterator.next()), is(0)); - } - - } - - @Override - public void onFailure(Throwable t) { - genericHandleFailure(t); - } - } - - private class ReadBatchCallback implements FutureCallback { - - private CompleteBatch expectedBatch; - - public ReadBatchCallback(CompleteBatch expectedBatch) { - this.expectedBatch = expectedBatch; - } - - @Override - public void onSuccess(CompleteBatch batch) { - - System.err.println(batch); - jobSemaphore.release(); - - assertThat("Batch returned is incorrect", batch, is(equalTo(expectedBatch))); - - } - - @Override - public void onFailure(Throwable t) { - genericHandleFailure(t); - } - } - - // Randomness generators - - private byte randomByte(){ - return (byte) random.nextInt(); - } - - private byte[] randomByteArray(int length) { - - byte[] randomBytes = new byte[length]; - - for (int i = 0; i < length ; i++){ - randomBytes[i] = randomByte(); - } - - return randomBytes; - - } - - private CompleteBatch createRandomBatch(int signer, int batchId, int length) throws SignatureException { - - CompleteBatch completeBatch = new CompleteBatch(); - - // Create data - - completeBatch.setBeginBatchMessage(BeginBatchMessage.newBuilder() - .setSignerId(signerIDs[signer]) - .setBatchId(batchId) - .addTag("Test") - .build()); - - for (int i = 0 ; i < length ; i++){ - - BatchData batchData = BatchData.newBuilder() - .setData(ByteString.copyFrom(randomByteArray(i))) - .build(); - - completeBatch.appendBatchData(batchData); - - } - - completeBatch.setTimestamp(Timestamp.newBuilder() - .setSeconds(Math.abs(90)) - .setNanos(50) - .build()); - - signers[signer].updateContent(completeBatch); - - completeBatch.setSignature(signers[signer].sign()); - - return completeBatch; - - } - - // Test methods - - /** - * Takes care of initializing the client and the test resources - */ - @Before - public void init(){ - - bulletinBoardClient = new ThreadedBulletinBoardClient(); - - random = new Random(0); // We use insecure randomness in tests for repeatability - - List testDB = new LinkedList<>(); - testDB.add(BASE_URL); - - bulletinBoardClient.init(BulletinBoardClientParams.newBuilder() - .addAllBulletinBoardAddress(testDB) - .setMinRedundancy((float) 1.0) - .build()); - - postCallback = new PostCallback(); - redundancyCallback = new RedundancyCallback((float) 1.0); - - thrown = new Vector<>(); - jobSemaphore = new Semaphore(0); - - } - - /** - * Closes the client and makes sure the test fails when an exception occurred in a separate thread - */ - - @After - public void close() { - - bulletinBoardClient.close(); - - if (thrown.size() > 0) { - assert false; - } - - } - - /** - * Tests the standard post, redundancy and read methods - */ - @Test - public void postTest() { - - byte[] b1 = {(byte) 1, (byte) 2, (byte) 3, (byte) 4}; - byte[] b2 = {(byte) 11, (byte) 12, (byte) 13, (byte) 14}; - byte[] b3 = {(byte) 21, (byte) 22, (byte) 23, (byte) 24}; - - BulletinBoardMessage msg; - - MessageFilterList filterList; - List msgList; - - MessageID messageID; - - msg = BulletinBoardMessage.newBuilder() - .setMsg(UnsignedBulletinBoardMessage.newBuilder() - .addTag("Signature") - .addTag("Trustee") - .setData(ByteString.copyFrom(b1)) - .setTimestamp(Timestamp.newBuilder() - .setSeconds(20) - .setNanos(30) - .build()) - .build()) - .addSig(Crypto.Signature.newBuilder() - .setType(Crypto.SignatureType.DSA) - .setData(ByteString.copyFrom(b2)) - .setSignerId(ByteString.copyFrom(b3)) - .build()) - .addSig(Crypto.Signature.newBuilder() - .setType(Crypto.SignatureType.ECDSA) - .setData(ByteString.copyFrom(b3)) - .setSignerId(ByteString.copyFrom(b2)) - .build()) - .build(); - - messageID = bulletinBoardClient.postMessage(msg,postCallback); - - try { - jobSemaphore.acquire(); - } catch (InterruptedException e) { - System.err.println(e.getCause() + " " + e.getMessage()); - } - - bulletinBoardClient.getRedundancy(messageID,redundancyCallback); - - filterList = MessageFilterList.newBuilder() - .addFilter( - MessageFilter.newBuilder() - .setType(FilterType.TAG) - .setTag("Signature") - .build() - ) - .addFilter( - MessageFilter.newBuilder() - .setType(FilterType.TAG) - .setTag("Trustee") - .build() - ) - .build(); - - msgList = new LinkedList<>(); - msgList.add(msg); - - readCallback = new ReadCallback(msgList); - - bulletinBoardClient.readMessages(filterList, readCallback); - try { - jobSemaphore.acquire(2); - } catch (InterruptedException e) { - System.err.println(e.getCause() + " " + e.getMessage()); - } - - } - - /** - * Tests posting a batch by parts - * Also tests not being able to post to a closed batch - * @throws CommunicationException, SignatureException, InterruptedException - */ - @Test - public void testBatchPost() throws CommunicationException, SignatureException, InterruptedException { - - final int SIGNER = 1; - final int BATCH_ID = 100; - final int BATCH_LENGTH = 100; - - CompleteBatch completeBatch = createRandomBatch(SIGNER, BATCH_ID, BATCH_LENGTH); - - // Begin batch - - bulletinBoardClient.beginBatch(completeBatch.getBeginBatchMessage(), postCallback); - - jobSemaphore.acquire(); - - // Post data - - bulletinBoardClient.postBatchData(signerIDs[SIGNER], BATCH_ID, completeBatch.getBatchDataList(), postCallback); - - jobSemaphore.acquire(); - - // Close batch - - CloseBatchMessage closeBatchMessage = CloseBatchMessage.newBuilder() - .setBatchId(BATCH_ID) - .setBatchLength(BATCH_LENGTH) - .setTimestamp(Timestamp.newBuilder() - .setSeconds(50) - .setNanos(80) - .build()) - .setSig(completeBatch.getSignature()) - .build(); - - bulletinBoardClient.closeBatch(closeBatchMessage, postCallback); - - jobSemaphore.acquire(); - - // Attempt to open batch again - - bulletinBoardClient.beginBatch(completeBatch.getBeginBatchMessage(), failPostCallback); - - // Attempt to add batch data - - bulletinBoardClient.postBatchData(signerIDs[SIGNER], BATCH_ID, completeBatch.getBatchDataList(), failPostCallback); - - jobSemaphore.acquire(2); - - // Read batch data - - BatchSpecificationMessage batchSpecificationMessage = - BatchSpecificationMessage.newBuilder() - .setSignerId(signerIDs[SIGNER]) - .setBatchId(BATCH_ID) - .setStartPosition(0) - .build(); - - readBatchCallback = new ReadBatchCallback(completeBatch); - - bulletinBoardClient.readBatch(batchSpecificationMessage, readBatchCallback); - - jobSemaphore.acquire(); - - } - - /** - * Posts a complete batch message - * Checks reading od the message - * @throws CommunicationException, SignatureException, InterruptedException - */ - @Test - public void testCompleteBatchPost() throws CommunicationException, SignatureException, InterruptedException { - - final int SIGNER = 0; - final int BATCH_ID = 101; - final int BATCH_LENGTH = 50; - - // Post batch - - CompleteBatch completeBatch = createRandomBatch(SIGNER, BATCH_ID, BATCH_LENGTH); - - bulletinBoardClient.postBatch(completeBatch,postCallback); - - jobSemaphore.acquire(); - - // Read batch - - BatchSpecificationMessage batchSpecificationMessage = - BatchSpecificationMessage.newBuilder() - .setSignerId(signerIDs[SIGNER]) - .setBatchId(BATCH_ID) - .setStartPosition(0) - .build(); - - readBatchCallback = new ReadBatchCallback(completeBatch); - - bulletinBoardClient.readBatch(batchSpecificationMessage, readBatchCallback); - - jobSemaphore.acquire(); - - } - - /** - * Tests that an unopened batch cannot be closed - * @throws CommunicationException, InterruptedException - */ - @Test - public void testInvalidBatchClose() throws CommunicationException, InterruptedException { - - final int NON_EXISTENT_BATCH_ID = 999; - - CloseBatchMessage closeBatchMessage = - CloseBatchMessage.newBuilder() - .setBatchId(NON_EXISTENT_BATCH_ID) - .setBatchLength(1) - .setSig(Crypto.Signature.getDefaultInstance()) - .setTimestamp(Timestamp.newBuilder() - .setSeconds(9) - .setNanos(12) - .build()) - .build(); - - // Try to close the (unopened) batch; - - bulletinBoardClient.closeBatch(closeBatchMessage, failPostCallback); - - jobSemaphore.acquire(); - - } - -} diff --git a/bulletin-board-client/src/test/java/meerkat/bulletinboard/LocalBulletinBoardClientTest.java b/bulletin-board-client/src/test/java/meerkat/bulletinboard/LocalBulletinBoardClientTest.java new file mode 100644 index 0000000..2e0e0af --- /dev/null +++ b/bulletin-board-client/src/test/java/meerkat/bulletinboard/LocalBulletinBoardClientTest.java @@ -0,0 +1,107 @@ +package meerkat.bulletinboard; + +import meerkat.bulletinboard.sqlserver.*; +import meerkat.comm.CommunicationException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.security.SignatureException; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.List; + +import static org.junit.Assert.fail; + +/** + * Created by Arbel Deutsch Peled on 05-Dec-15. + */ +public class LocalBulletinBoardClientTest { + + private static final int THREAD_NUM = 3; + private static final String DB_NAME = "TestDB"; + + // Tester + private GenericBulletinBoardClientTester clientTest; + + public LocalBulletinBoardClientTest() throws CommunicationException { + + H2QueryProvider queryProvider = new H2QueryProvider(DB_NAME) ; + + try { + + Connection conn = queryProvider.getDataSource().getConnection(); + Statement stmt = conn.createStatement(); + + List deletionQueries = queryProvider.getSchemaDeletionCommands(); + + for (String deletionQuery : deletionQueries) { + stmt.execute(deletionQuery); + } + + } catch (SQLException e) { + System.err.println(e.getMessage()); + throw new CommunicationException(e.getCause() + " " + e.getMessage()); + } + + BulletinBoardServer server = new BulletinBoardSQLServer(queryProvider); + server.init(DB_NAME); + + LocalBulletinBoardClient client = new LocalBulletinBoardClient(server, THREAD_NUM); + + clientTest = new GenericBulletinBoardClientTester(client); + + } + + // Test methods + + /** + * Takes care of initializing the client and the test resources + */ + @Before + public void init(){ + + clientTest.init(); + + } + + /** + * Closes the client and makes sure the test fails when an exception occurred in a separate thread + */ + + @After + public void close() { + + clientTest.close(); + + } + + @Test + public void postTest() { + + clientTest.postTest(); + + } + + @Test + public void testBatchPost() throws CommunicationException, SignatureException, InterruptedException { + + clientTest.testBatchPost(); + } + + @Test + public void testCompleteBatchPost() throws CommunicationException, SignatureException, InterruptedException { + + clientTest.testCompleteBatchPost(); + + } + + @Test + public void testInvalidBatchClose() throws CommunicationException, InterruptedException { + + clientTest.testInvalidBatchClose(); + + } + +} diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java index c7bcf57..ab82ab1 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java @@ -5,6 +5,7 @@ import java.util.*; import com.google.protobuf.*; +import com.google.protobuf.Timestamp; import meerkat.bulletinboard.*; import meerkat.bulletinboard.sqlserver.mappers.*; import static meerkat.bulletinboard.BulletinBoardConstants.*; @@ -26,6 +27,7 @@ import javax.sql.DataSource; import meerkat.util.BulletinBoardUtils; import meerkat.util.TimestampComparator; +import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.support.GeneratedKeyHolder; @@ -586,14 +588,12 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ } - /** - * Used to retrieve just basic information about messages to allow calculation of checksum + * Private implementation of the message stub reader for returning result as a list * @param filterList is a filter list that defines which messages the client is interested in - * @return a list of Bulletin Board Messages that contain just the entry number, timestamp and message ID for each message - * The message ID is returned inside the message data field + * @return the requested list of message stubs */ - protected List readMessageStubs(MessageFilterList filterList) { + private List readMessageStubs(MessageFilterList filterList) { StringBuilder sqlBuilder = new StringBuilder(50 * (filterList.getFilterCount() + 1)); @@ -635,6 +635,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ } + /** * This method returns a string representation of the tag associated with a batch ID * @param batchId is the given batch ID @@ -644,6 +645,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ return BATCH_ID_TAG_PREFIX + Integer.toString(batchId); } + /** * This method checks if a specified batch exists and is already closed * @param signerId is the ID of the publisher of the batch @@ -687,6 +689,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ } + @Override public BoolMsg beginBatch(BeginBatchMessage message) throws CommunicationException { @@ -719,8 +722,10 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ jdbcTemplate.batchUpdate(sql,namedParameters); return BoolMsg.newBuilder().setValue(true).build(); + } + @Override public BoolMsg postBatchMessage(BatchMessage batchMessage) throws CommunicationException{ @@ -744,6 +749,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ } + @Override public BoolMsg closeBatchMessage(CloseBatchMessage message) throws CommunicationException { @@ -767,13 +773,12 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ return BoolMsg.newBuilder().setValue(false).build(); } - // Get Tags and add them to CompleteBatch sql = sqlQueryProvider.getSQLString(QueryType.GET_BATCH_TAGS); namedParameters = new MapSqlParameterSource(); - namedParameters.addValue(QueryType.GET_BATCH_TAGS.getParamName(0),signerId); + namedParameters.addValue(QueryType.GET_BATCH_TAGS.getParamName(0),signerId.toByteArray()); namedParameters.addValue(QueryType.GET_BATCH_TAGS.getParamName(1),batchId); List tags = jdbcTemplate.query(sql, namedParameters, new StringMapper()); @@ -847,6 +852,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ return BoolMsg.newBuilder().setValue(true).build(); } + @Override public void readBatch(BatchSpecificationMessage message, MessageOutputStream out) throws CommunicationException, IllegalArgumentException{ @@ -866,6 +872,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ } + /** * Finds the entry number of the last entry in the database * @return the entry number, or -1 if no entries are found @@ -884,10 +891,80 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ } + @Override + public SyncQuery generateSyncQuery(GenerateSyncQueryParams generateSyncQueryParams) { + + if (generateSyncQueryParams == null + || !generateSyncQueryParams.hasFilterList() + || generateSyncQueryParams.getFilterList().getFilterCount() <= 0 + || generateSyncQueryParams.getBreakpointListCount() <= 0){ + + return SyncQuery.getDefaultInstance(); + + } + + List messages = readMessageStubs(generateSyncQueryParams.getFilterList()); + + if (messages.size() <= 0){ + return SyncQuery.newBuilder().build(); + } + + SyncQuery.Builder resultBuilder = SyncQuery.newBuilder(); + + Iterator messageIterator = messages.iterator(); + Iterator breakpointIterator = generateSyncQueryParams.getBreakpointListList().iterator(); + + Checksum checksum = new SimpleChecksum(); + checksum.setDigest(new SHA256Digest()); + + Timestamp lastTimestamp = Timestamp.getDefaultInstance(); + BulletinBoardMessage message = messageIterator.next(); + long currentMessageNum = 1; + + boolean checksumChanged = true; + + while (breakpointIterator.hasNext()){ + + Float breakpoint = breakpointIterator.next(); + + // Continue while breakpoint not reached, or it has been reached but no new timestamp has been encountered since + while ( messageIterator.hasNext() + && ((float) currentMessageNum / (float) messages.size() <= breakpoint) + || ((float) currentMessageNum / (float) messages.size() > breakpoint + && lastTimestamp.equals(message.getMsg().getTimestamp()))){ + + checksumChanged = true; + + checksum.update(message.getMsg().getData()); + + lastTimestamp = message.getMsg().getTimestamp(); + message = messageIterator.next(); + + } + + if (checksumChanged) { + + checksum.update(message.getMsg().getData()); + resultBuilder.addQuery(SingleSyncQuery.newBuilder() + .setTimeOfSync(message.getMsg().getTimestamp()) + .setChecksum(checksum.getChecksum()) + .build()); + + } + + checksumChanged = false; + + } + + return resultBuilder.build(); + + } + + /** * Searches for the latest time of sync of the DB relative to a given query and returns the metadata needed to complete the sync - * The checksum up to (and including) each given timestamp is calculated using bitwise XOR on 8-byte sized blocks of the message IDs - * @param syncQuery contains a succinct representation of states to compare to + * The checksum up to (and including) each given timestamp is calculated using an instance of SimpleChecksum + * @param syncQuery contains a succinct representation of states to compare against * @return the current last entry num and latest time of sync if there is one; -1 as last entry and empty timestamp otherwise * @throws CommunicationException */ @@ -960,6 +1037,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ } + @Override public void close() {} diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/MessageCallbackHandler.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/MessageCallbackHandler.java index bdba241..71ba742 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/MessageCallbackHandler.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/MessageCallbackHandler.java @@ -20,9 +20,9 @@ import java.util.List; */ public class MessageCallbackHandler implements RowCallbackHandler { - NamedParameterJdbcTemplate jdbcTemplate; - SQLQueryProvider sqlQueryProvider; - MessageOutputStream out; + private final NamedParameterJdbcTemplate jdbcTemplate; + private final SQLQueryProvider sqlQueryProvider; + private final MessageOutputStream out; public MessageCallbackHandler(NamedParameterJdbcTemplate jdbcTemplate, SQLQueryProvider sqlQueryProvider, MessageOutputStream out) { diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/MessageStubCallbackHandler.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/MessageStubCallbackHandler.java new file mode 100644 index 0000000..f81cc76 --- /dev/null +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/MessageStubCallbackHandler.java @@ -0,0 +1,59 @@ +package meerkat.bulletinboard.sqlserver.mappers; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer.SQLQueryProvider.QueryType; +import meerkat.comm.MessageOutputStream; +import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; +import meerkat.protobuf.BulletinBoardAPI.UnsignedBulletinBoardMessage; +import meerkat.protobuf.Crypto; +import meerkat.util.BulletinBoardUtils; +import org.springframework.jdbc.core.RowCallbackHandler; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; + +import java.io.IOException; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 21-Feb-16. + */ +public class MessageStubCallbackHandler implements RowCallbackHandler { + + private final MessageOutputStream out; + + public MessageStubCallbackHandler(MessageOutputStream out) { + + this.out = out; + + } + + @Override + public void processRow(ResultSet rs) throws SQLException { + + BulletinBoardMessage result; + + result = BulletinBoardMessage.newBuilder() + .setEntryNum(rs.getLong(1)) + .setMsg(UnsignedBulletinBoardMessage.newBuilder() + .setData(ByteString.copyFrom(rs.getBytes(2))) + .setTimestamp(BulletinBoardUtils.toTimestampProto(rs.getTimestamp(3))) + .build()) + .build(); + + try { + + out.writeMessage(result); + + } catch (IOException e) { + + //TODO: log + e.printStackTrace(); + + } + + } + +} diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java index 2e4782f..7c0f7fa 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java @@ -22,7 +22,7 @@ import static meerkat.rest.Constants.*; import java.io.IOException; import java.io.OutputStream; -import java.util.List; +import java.util.Collection; /** * An implementation of the BulletinBoardServer which functions as a WebApp @@ -183,6 +183,21 @@ public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextL } } + @Path(GENERATE_SYNC_QUERY_PATH) + @POST + @Consumes(MEDIATYPE_PROTOBUF) + @Produces(MEDIATYPE_PROTOBUF) + @Override + public SyncQuery generateSyncQuery(GenerateSyncQueryParams generateSyncQueryParams) throws CommunicationException { + try { + init(); + return bulletinBoard.generateSyncQuery(generateSyncQueryParams); + } catch (CommunicationException | IllegalArgumentException e) { + System.err.println(e.getMessage()); + return null; + } + } + @Path(READ_BATCH_PATH) @POST @Consumes(MEDIATYPE_PROTOBUF) diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java b/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java index c6e330c..d74c1ea 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/AsyncBulletinBoardClient.java @@ -11,10 +11,6 @@ import java.util.List; */ public interface AsyncBulletinBoardClient extends BulletinBoardClient { - public interface MessageHandler { - void handleNewMessages(List messageList); - } - /** * Post a message to the bulletin board in an asynchronous manner * @param msg is the message to be posted @@ -100,11 +96,12 @@ public interface AsyncBulletinBoardClient extends BulletinBoardClient { */ public void readBatch(BatchSpecificationMessage batchSpecificationMessage, FutureCallback callback); + /** - * Subscribes to a notifier that will return any new messages on the server that match the given filters - * @param filterList defines the set of filters for message retrieval - * @param messageHandler defines the handler for new messages received + * Perform a Sync Query on the bulletin board + * @param syncQuery defines the query + * @param callback is a callback for handling the result of the query */ - public void subscribe(MessageFilterList filterList, MessageHandler messageHandler); + public void querySync(SyncQuery syncQuery, FutureCallback callback); } diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardClient.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardClient.java index 2f5a3df..245eddf 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardClient.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardClient.java @@ -5,6 +5,7 @@ import meerkat.protobuf.Voting.*; import static meerkat.protobuf.BulletinBoardAPI.*; +import java.util.Collection; import java.util.List; /** @@ -26,8 +27,6 @@ public interface BulletinBoardClient { */ MessageID postMessage(BulletinBoardMessage msg) throws CommunicationException; - - /** * Check how "safe" a given message is in a synchronous manner * @param id is the unique message identifier for retrieval @@ -40,11 +39,21 @@ public interface BulletinBoardClient { * Note that if messages haven't been "fully posted", this might return a different * set of messages in different calls. However, messages that are fully posted * are guaranteed to be included. - * @param filterList return only messages that match the filters (null means no filtering). + * @param filterList return only messages that match the filters (null means no filtering) * @return the list of messages */ List readMessages(MessageFilterList filterList); + /** + * Create a SyncQuery to test against that corresponds with the current server state for a specific filter list + * Should only be called on instances for which the actual server contacted is known (i.e. there is only one server) + * @param GenerateSyncQueryParams defines the required information needed to generate the query + * These are represented as fractions of the total number of relevant messages + * @return The generated SyncQuery + * @throws CommunicationException when no DB can be contacted + */ + SyncQuery generateSyncQuery(GenerateSyncQueryParams GenerateSyncQueryParams) throws CommunicationException; + /** * Closes all connections, if any. * This is done in a synchronous (blocking) way. diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardConstants.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardConstants.java index 66652f8..9ddee90 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardConstants.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardConstants.java @@ -8,6 +8,7 @@ public interface BulletinBoardConstants { // Relative addresses for Bulletin Board operations public static final String BULLETIN_BOARD_SERVER_PATH = "/bbserver"; + public static final String GENERATE_SYNC_QUERY_PATH = "/generatesyncquery"; public static final String READ_MESSAGES_PATH = "/readmessages"; public static final String READ_BATCH_PATH = "/readbatch"; public static final String POST_MESSAGE_PATH = "/postmessage"; diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java index 0b279c2..e458dbc 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java @@ -4,6 +4,8 @@ import meerkat.comm.CommunicationException; import meerkat.comm.MessageOutputStream; import meerkat.protobuf.BulletinBoardAPI.*; +import java.util.Collection; + /** * Created by Arbel on 07/11/15. @@ -28,7 +30,7 @@ public interface BulletinBoardServer{ * @throws CommunicationException on DB connection error */ public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException; - + /** * Read all messages posted matching the given filter * @param filterList return only messages that match the filters (empty list or null means no filtering) @@ -77,6 +79,13 @@ public interface BulletinBoardServer{ */ public void readBatch(BatchSpecificationMessage message, MessageOutputStream out) throws CommunicationException, IllegalArgumentException; + /** + * Create a SyncQuery to test against that corresponds with the current server state for a specific filter list + * @param generateSyncQueryParams defines the information needed to generate the query + * @return The generated SyncQuery + * @throws CommunicationException on DB connection error + */ + SyncQuery generateSyncQuery(GenerateSyncQueryParams generateSyncQueryParams) throws CommunicationException; /** * Queries the database for sync status with respect to a given sync query diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardSubscriber.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardSubscriber.java new file mode 100644 index 0000000..85eb2cc --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardSubscriber.java @@ -0,0 +1,32 @@ +package meerkat.bulletinboard; + +import com.google.common.util.concurrent.FutureCallback; +import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; +import meerkat.protobuf.BulletinBoardAPI.MessageFilterList; + +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 03-Mar-16. + * This interface defines the behaviour required from a subscription service to Bulletin Board messages + */ +public interface BulletinBoardSubscriber { + + /** + * Subscribes to a notifier that will return any new messages on the server that match the given filters + * In case of communication error: the subscription is terminated + * @param filterList defines the set of filters for message retrieval + * @param callback defines how to handle new messages received and/or a failures in communication + */ + public void subscribe(MessageFilterList filterList, FutureCallback> callback); + + /** + * Subscribes to a notifier that will return any new messages on the server that match the given filters + * In case of communication error: the subscription is terminated + * @param filterList defines the set of filters for message retrieval + * @param startEntry defines the first entry number to consider + * @param callback defines how to handle new messages received and/or a failures in communication + */ + public void subscribe(MessageFilterList filterList, long startEntry, FutureCallback> callback); + +} diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardSynchronizer.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardSynchronizer.java new file mode 100644 index 0000000..4b07225 --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardSynchronizer.java @@ -0,0 +1,22 @@ +package meerkat.bulletinboard; + +/** + * Created by Arbel Deutsch Peled on 08-Mar-16. + * This interface defines the behaviour of a bulletin board synchronizer + * This is used to make sure that data in a specific instance of a bulletin board server is duplicated to a sufficient percentage of the other servers + */ +public interface BulletinBoardSynchronizer extends Runnable{ + + /** + * + * @param localClient is a client for the local DB instance + * @param remoteClient is a client for the remote DBs + * @param minRedundancy + */ + public void init(BulletinBoardClient localClient, AsyncBulletinBoardClient remoteClient, float minRedundancy); + + @Override + public void run(); + + +} diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/CompleteBatch.java b/meerkat-common/src/main/java/meerkat/bulletinboard/CompleteBatch.java index 14e87e7..649fd8b 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/CompleteBatch.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/CompleteBatch.java @@ -139,7 +139,12 @@ public class CompleteBatch { @Override public String toString() { + + if (beginBatchMessage == null || beginBatchMessage.getSignerId() == null) + return "Unspecified batch " + super.toString(); + return "Batch " + beginBatchMessage.getSignerId().toString() + ":" + beginBatchMessage.getBatchId(); + } } diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/SubscriptionAsyncBulletinBoardClient.java b/meerkat-common/src/main/java/meerkat/bulletinboard/SubscriptionAsyncBulletinBoardClient.java new file mode 100644 index 0000000..b07e655 --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/SubscriptionAsyncBulletinBoardClient.java @@ -0,0 +1,7 @@ +package meerkat.bulletinboard; + +/** + * Created by Arbel Deutsch Peled on 03-Mar-16. + */ +public interface SubscriptionAsyncBulletinBoardClient extends AsyncBulletinBoardClient, BulletinBoardSubscriber { +} diff --git a/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto b/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto index fd95503..1136e16 100644 --- a/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto +++ b/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto @@ -146,6 +146,18 @@ message SyncQuery { } +// This message defines the required information for generation of a SyncQuery instance by the server +message GenerateSyncQueryParams { + + // Defines the set of messages required + MessageFilterList filterList = 1; + + // Defines the locations in the list of messages to calculate single sync queries for + // The values should be between 0.0 and 1.0 and define the location in fractions of the size of the message set + repeated float breakpointList = 2; + +} + // This message defines the server's response format to a sync query message SyncQueryResponse { From 5f45c1f6d6e088b3743f9560dae2dc863cdf5d59 Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Tue, 22 Mar 2016 00:49:21 +0200 Subject: [PATCH 28/49] tested with malicious users --- .../src/main/java/Communication/Network.java | 13 +- .../DistributedKeyGenerationUserImpl.java | 4 +- .../ShamirSecretSharing/SecretSharing.java | 3 +- .../JointFeldmanProtocol/DKGDeepTest.java | 174 ++++++++++++++++++ .../DKGMaliciousUserImpl.java | 72 ++++++++ .../java/JointFeldmanProtocol/DKGTest.java | 10 +- .../SDKGTest.java | 11 +- .../SDKGUserImplAbort.java | 2 + 8 files changed, 275 insertions(+), 14 deletions(-) create mode 100644 destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGDeepTest.java create mode 100644 destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGMaliciousUserImpl.java rename destributed-key-generation/src/test/java/{ => SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem}/SDKGTest.java (94%) rename destributed-key-generation/src/test/java/{ => SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem}/SDKGUserImplAbort.java (95%) diff --git a/destributed-key-generation/src/main/java/Communication/Network.java b/destributed-key-generation/src/main/java/Communication/Network.java index af7e5d6..ca53991 100644 --- a/destributed-key-generation/src/main/java/Communication/Network.java +++ b/destributed-key-generation/src/main/java/Communication/Network.java @@ -3,7 +3,10 @@ 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. @@ -15,23 +18,23 @@ public class Network { protected final User[] users; protected final int n; - protected final Queue availableIDs; + protected final Set availableIDs; public static final int BROADCAST = 0; public Network(int n) { this.n = n; this.users = new User[n]; - this.availableIDs = new ArrayBlockingQueue(n); + this.availableIDs = new HashSet(); for (int id = 1; id <= n; id++){ availableIDs.add(id); } } - public User connect(MailHandler mailHandler){ - Integer id = availableIDs.poll(); - if (id == null) + 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]; } diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java index f633258..578b1e5 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java @@ -50,7 +50,7 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio this.messageHandler = new MessageHandler(); mailHandler.setMessageHandler(this.messageHandler); - this.user = network.connect(mailHandler); + this.user = network.connect(mailHandler,dkg.getId()); this.parties = dkg.getParties(); this.parties[id - 1].share = dkg.getShare(id); @@ -230,7 +230,7 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio if(isValidComplaintMessage(sender,isBroadcast,complaintMessage)){ int i = sender; int j = complaintMessage.getId(); - parties[i - 1].complaints[j - 1] = ComplainState.Waiting; + parties[j - 1].complaints[i - 1] = ComplainState.Waiting; } } diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java index cdd631d..877d272 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java @@ -1,6 +1,7 @@ package ShamirSecretSharing; import Arithmetics.Arithmetic; +import Arithmetics.Fp; import java.math.BigInteger; import java.util.Random; @@ -45,7 +46,7 @@ public class SecretSharing{ for (int i = 1 ; i <= t; i++ ){ coefficients[i] = new BigInteger(bits,random).mod(q); } - return new Polynomial(coefficients); + return new Polynomial(coefficients,new Fp(q)); } /** diff --git a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGDeepTest.java b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGDeepTest.java new file mode 100644 index 0000000..a50c75c --- /dev/null +++ b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGDeepTest.java @@ -0,0 +1,174 @@ +package JointFeldmanProtocol; + +import Arithmetics.Arithmetic; +import Arithmetics.Fp; +import Communication.Network; +import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; +import ShamirSecretSharing.Polynomial; +import ShamirSecretSharing.SecretSharing; +import UserInterface.DistributedKeyGenerationUser; +import org.factcenter.qilin.primitives.Group; +import org.factcenter.qilin.primitives.concrete.Zpstar; +import org.junit.Before; +import org.junit.Test; + +import java.lang.reflect.Array; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Random; +import java.util.Set; + +/** + * Created by Tzlil on 3/21/2016. + */ +public class DKGDeepTest { + + int tests = 10; + BigInteger p = BigInteger.valueOf(2903); + BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); + Group group = new Zpstar(p); + Arithmetic arithmetic = new Fp(q); + int t = 9; + int n = 20; + + Testable[] testables; + + @Before + public void settings(){ + testables = new Testable[n]; + 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++){ + testable.threads[i].start(); + } + 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.QUAL){ + if(!testable.aborted.contains(i)) + assert (testable.dkgs[i - 1].getPublicValue().equals(publicValue)); + } + + // assert valid verification values + BigInteger expected,verification; + for (int i: testable.QUAL){ + if(!testable.aborted.contains(i)) { + expected = group.multiply(testable.g, testable.dkgs[i - 1].getShare().y); + verification = VerifiableSecretSharing.verify(i, testable.dkgs[i - 1].getCommitments(), group); + assert (expected.equals(verification)); + } + } + + + // restore the secret from shares + ArrayList sharesList = new ArrayList(); + + for(int i : testable.QUAL){ + if(!testable.aborted.contains(i)) + sharesList.add(testable.dkgs[i - 1].getShare()); + } + Polynomial.Point[] shares = new Polynomial.Point[sharesList.size()]; + for (int i = 0; i < shares.length; i ++){ + shares[i] = sharesList.get(i); + } + + BigInteger calculatedSecret = SecretSharing.restoreSecret(shares,arithmetic); + assert (calculatedSecret.equals(testable.secret)); + } + + @Test + public void test() throws Exception { + for (int i = 0; i < tests; i++){ + oneTest(i); + } + } + + class Testable{ + Set QUAL; + Set aborted; + Set malicious; + DistributedKeyGenerationUser[] dkgs; + Thread[] threads; + BigInteger g; + BigInteger secret; + public Testable(Random random) { + + this.dkgs = new DistributedKeyGenerationUserImpl[n]; + this.QUAL = new HashSet(); + this.aborted = new HashSet(); + this.malicious = new HashSet(); + this.threads = new Thread[n]; + this.g = sampleGenerator(random); + ArrayList ids = new ArrayList(); + for (int id = 1; id<= n ; id++){ + ids.add(id); + } + Network network = new Network(n); + int id; + BigInteger s; + DistributedKeyGeneration dkg; + this.secret = BigInteger.ZERO; + while (!ids.isEmpty()) { + id = ids.remove(random.nextInt(ids.size())); + s = randomIntModQ(random); + dkg = new DistributedKeyGeneration(t, n, s, random, q, g, group, id); + dkgs[id - 1] = randomDKGUser(id,network,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) { + QUAL.add(id); + return new DistributedKeyGenerationUserImpl(dkg,network); + }else{ + int type = random.nextInt(3); + switch (type){ + case 0:// regular + QUAL.add(id); + return new DistributedKeyGenerationUserImpl(dkg,network); + case 1:// abort + int abortStage = random.nextInt(2) + 1; // 1 or 2 + aborted.add(id); + if (abortStage == 2){ + QUAL.add(id); + } + return new DKGUserImplAbort(dkg,network,abortStage); + case 2:// malicious + malicious.add(id); + return new DKGMaliciousUserImpl(dkg,network,random); + default: + return null; + } + } + } + + public BigInteger sampleGenerator(Random random){ + BigInteger ZERO = group.zero(); + BigInteger g; + do { + g = group.sample(random); + } while (!g.equals(ZERO) && !group.multiply(g, q).equals(ZERO)); + return g; + } + + public BigInteger randomIntModQ(Random random){ + return new BigInteger(q.bitLength(), random).mod(q); + } + + + } +} diff --git a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGMaliciousUserImpl.java b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGMaliciousUserImpl.java new file mode 100644 index 0000000..e3261f8 --- /dev/null +++ b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGMaliciousUserImpl.java @@ -0,0 +1,72 @@ +package JointFeldmanProtocol; + +import Communication.MailHandler; +import Communication.Network; + +import java.math.BigInteger; +import java.util.*; + +/** + * Created by Tzlil on 3/21/2016. + */ +public class DKGMaliciousUserImpl extends DistributedKeyGenerationUserImpl { + + private final DistributedKeyGeneration maliciousDkg; + private final Set falls; + public DKGMaliciousUserImpl(DistributedKeyGeneration dkg, Network network, Random random) { + super(dkg, network); + this.falls = selectFalls(random); + this.maliciousDkg = new DistributedKeyGeneration(t,n,randomInt(random),random,dkg.getQ(),g,group,id); + maliciousDkg.setParties(parties); + } + + public Set selectFalls(Random random){ + ArrayList ids = new ArrayList(); + for (int i = 1; i<= n ; i++){ + if(i!=id) { + ids.add(i); + } + } + Set falls = new HashSet(); + int fallsSize = random.nextInt(ids.size()) + 1;// 1 - (n-1) + while (falls.size() < fallsSize){ + falls.add(ids.remove(random.nextInt(ids.size()))); + } + return falls; + } + + @Override + public void stage1() { + dkg.broadcastCommitments(user); + sendSecrets(); //insteadof dkg.sendSecrets(user); + } + + @Override + public void stage3() { + maliciousDkg.answerAllComplainingPlayers(user); + } + + @Override + public void stage4(){ + // do nothing + } + + private BigInteger randomInt(Random random){ + BigInteger q = dkg.getQ(); + return new BigInteger(q.bitLength(), random).mod(q); + } + + private void sendSecrets(){ + for (int j = 1; j <= n ; j++){ + if(j != id){ + if(falls.contains(j)){ + maliciousDkg.sendSecret(user,j); + }else { + dkg.sendSecret(user, j); + } + } + } + } + + +} diff --git a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java index b74f258..b50c46e 100644 --- a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java +++ b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java @@ -1,5 +1,7 @@ package JointFeldmanProtocol; +import Arithmetics.Arithmetic; +import Arithmetics.Fp; import Arithmetics.Z; import Communication.Network; import ShamirSecretSharing.Polynomial; @@ -27,10 +29,12 @@ public class DKGTest { BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); BigInteger[] secrets; Set QUAL = new HashSet(); + Arithmetic arithmetic; @Before public void settings(){ Zpstar zpstar = new Zpstar(p); Random random = new Random(); + arithmetic = new Fp(q); BigInteger g; int t = 9; int n = 20; @@ -39,7 +43,7 @@ public class DKGTest { threadsArrays = new Thread[tests][n]; secrets = new BigInteger[tests]; DistributedKeyGeneration dkg; - int abortedStage = 2; + int abortedStage = 1; for (int test = 0; test < tests; test++) { do { g = zpstar.sample(random); @@ -51,7 +55,7 @@ public class DKGTest { dkg = new DistributedKeyGeneration(t,n,secret,random,q,g,zpstar,i); if(i == n) { - dkgsArrays[test][i - 1] = new DKGUserImplAbort(dkg, network, abortedStage); + dkgsArrays[test][i - 1] = new DKGMaliciousUserImpl(dkg,network,random);//new DKGUserImplAbort(dkg, network, abortedStage); } else { dkgsArrays[test][i - 1] = new DistributedKeyGenerationUserImpl(dkg, network); @@ -104,7 +108,7 @@ public class DKGTest { shares[i] = sharesList.get(i); } - BigInteger calculatedSecret = SecretSharing.restoreSecret(shares,new Z()).mod(q); + BigInteger calculatedSecret = SecretSharing.restoreSecret(shares,arithmetic); assert (calculatedSecret.equals(secret)); } diff --git a/destributed-key-generation/src/test/java/SDKGTest.java b/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGTest.java similarity index 94% rename from destributed-key-generation/src/test/java/SDKGTest.java rename to destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGTest.java index 5866063..107f87c 100644 --- a/destributed-key-generation/src/test/java/SDKGTest.java +++ b/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGTest.java @@ -1,8 +1,10 @@ +package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; + +import Arithmetics.Arithmetic; +import Arithmetics.Fp; import Arithmetics.Z; import Communication.Network; import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; -import SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem.SecureDistributedKeyGeneration; -import SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem.SecureDistributedKeyGenerationUserImpl; import ShamirSecretSharing.Polynomial; import ShamirSecretSharing.SecretSharing; import UserInterface.DistributedKeyGenerationUser; @@ -31,10 +33,13 @@ public class SDKGTest { Set QUAL = new HashSet(); + Arithmetic arithmetic; + @Before public void settings(){ Zpstar zpstar = new Zpstar(p); Random random = new Random(); + arithmetic = new Fp(q); BigInteger g,h; int t = 9; int n = 20; @@ -108,7 +113,7 @@ public class SDKGTest { shares[i] = sharesList.get(i); } - BigInteger calculatedSecret = SecretSharing.restoreSecret(shares,new Z()).mod(q); + BigInteger calculatedSecret = SecretSharing.restoreSecret(shares,arithmetic); assert (calculatedSecret.equals(secret)); } diff --git a/destributed-key-generation/src/test/java/SDKGUserImplAbort.java b/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGUserImplAbort.java similarity index 95% rename from destributed-key-generation/src/test/java/SDKGUserImplAbort.java rename to destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGUserImplAbort.java index bc30eb5..fc777d3 100644 --- a/destributed-key-generation/src/test/java/SDKGUserImplAbort.java +++ b/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGUserImplAbort.java @@ -1,3 +1,5 @@ +package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; + import Communication.Network; import SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem.SecureDistributedKeyGeneration; import SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem.SecureDistributedKeyGenerationUserImpl; From e56312d38bae20ae1a02726f23eeef9d222eb02b Mon Sep 17 00:00:00 2001 From: Arbel Deutsch Peled Date: Tue, 22 Mar 2016 10:16:46 +0200 Subject: [PATCH 29/49] Local Client supports subsrciptions --- .../GenericSubscriptionClientTester.java | 231 ++++++++++++++++++ .../LocalBulletinBoardClientTest.java | 17 +- .../sqlserver/H2QueryProvider.java | 9 +- .../util/BulletinBoardMessageGenerator.java | 34 ++- 4 files changed, 279 insertions(+), 12 deletions(-) create mode 100644 bulletin-board-client/src/test/java/meerkat/bulletinboard/GenericSubscriptionClientTester.java diff --git a/bulletin-board-client/src/test/java/meerkat/bulletinboard/GenericSubscriptionClientTester.java b/bulletin-board-client/src/test/java/meerkat/bulletinboard/GenericSubscriptionClientTester.java new file mode 100644 index 0000000..a91f8d6 --- /dev/null +++ b/bulletin-board-client/src/test/java/meerkat/bulletinboard/GenericSubscriptionClientTester.java @@ -0,0 +1,231 @@ +package meerkat.bulletinboard; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.protobuf.ByteString; +import com.google.protobuf.Timestamp; +import meerkat.comm.CommunicationException; +import meerkat.crypto.concrete.ECDSASignature; +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.util.BulletinBoardMessageComparator; +import meerkat.util.BulletinBoardMessageGenerator; + +import java.io.IOException; +import java.io.InputStream; +import java.security.*; +import java.security.cert.CertificateException; +import java.util.*; +import java.util.concurrent.Semaphore; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.startsWith; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; + +/** + * Created by Arbel Deutsch Peled on 22-Mar-16. + */ +public class GenericSubscriptionClientTester { + + private GenericBatchDigitalSignature signers[]; + private ByteString[] signerIDs; + + private static String KEYFILE_EXAMPLE = "/certs/enduser-certs/user1-key-with-password-secret.p12"; + private static String KEYFILE_EXAMPLE3 = "/certs/enduser-certs/user3-key-with-password-shh.p12"; + + private static String KEYFILE_PASSWORD1 = "secret"; + private static String KEYFILE_PASSWORD3 = "shh"; + + private static String CERT1_PEM_EXAMPLE = "/certs/enduser-certs/user1.crt"; + private static String CERT3_PEM_EXAMPLE = "/certs/enduser-certs/user3.crt"; + + private SubscriptionAsyncBulletinBoardClient bulletinBoardClient; + + private Random random; + private BulletinBoardMessageGenerator generator; + + private Semaphore jobSemaphore; + private Vector thrown; + + public GenericSubscriptionClientTester(SubscriptionAsyncBulletinBoardClient bulletinBoardClient){ + + this.bulletinBoardClient = bulletinBoardClient; + + signers = new GenericBatchDigitalSignature[2]; + signerIDs = new ByteString[signers.length]; + signers[0] = new GenericBatchDigitalSignature(new ECDSASignature()); + signers[1] = new GenericBatchDigitalSignature(new ECDSASignature()); + + InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE); + char[] password = KEYFILE_PASSWORD1.toCharArray(); + + KeyStore.Builder keyStoreBuilder; + try { + keyStoreBuilder = signers[0].getPKCS12KeyStoreBuilder(keyStream, password); + + signers[0].loadSigningCertificate(keyStoreBuilder); + + signers[0].loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE)); + + keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE3); + password = KEYFILE_PASSWORD3.toCharArray(); + + keyStoreBuilder = signers[1].getPKCS12KeyStoreBuilder(keyStream, password); + signers[1].loadSigningCertificate(keyStoreBuilder); + + signers[1].loadVerificationCertificates(getClass().getResourceAsStream(CERT3_PEM_EXAMPLE)); + + for (int i = 0 ; i < signers.length ; i++) { + signerIDs[i] = signers[i].getSignerID(); + } + + } catch (IOException e) { + System.err.println("Failed reading from signature file " + e.getMessage()); + fail("Failed reading from signature file " + e.getMessage()); + } catch (CertificateException e) { + System.err.println("Failed reading certificate " + e.getMessage()); + fail("Failed reading certificate " + e.getMessage()); + } catch (KeyStoreException e) { + System.err.println("Failed reading keystore " + e.getMessage()); + fail("Failed reading keystore " + e.getMessage()); + } catch (NoSuchAlgorithmException e) { + System.err.println("Couldn't find signing algorithm " + e.getMessage()); + fail("Couldn't find signing algorithm " + e.getMessage()); + } catch (UnrecoverableKeyException e) { + System.err.println("Couldn't find signing key " + e.getMessage()); + fail("Couldn't find signing key " + e.getMessage()); + } + + } + + /** + * Takes care of initializing the client and the test resources + */ + public void init(){ + + random = new Random(0); // We use insecure randomness in tests for repeatability + generator = new BulletinBoardMessageGenerator(random); + + thrown = new Vector<>(); + jobSemaphore = new Semaphore(0); + + } + + /** + * Closes the client and makes sure the test fails when an exception occurred in a separate thread + */ + + public void close() { + + if (thrown.size() > 0) { + assert false; + } + + } + + private class SubscriptionCallback implements FutureCallback>{ + + private int stage; + private final List> expectedMessages; + private final List messagesToPost; + private final BulletinBoardMessageComparator comparator; + + public SubscriptionCallback(List> expectedMessages, List messagesToPost) { + + this.expectedMessages = expectedMessages; + this.messagesToPost = messagesToPost; + this.stage = 0; + this.comparator = new BulletinBoardMessageComparator(); + + } + + @Override + public void onSuccess(List result) { + + if (stage >= expectedMessages.size()) + return; + + // Check for consistency + + List expectedMsgList = expectedMessages.get(stage); + + if (expectedMsgList.size() != result.size()){ + onFailure(new AssertionError("Received wrong number of messages")); + return; + } + + Iterator expectedMessageIterator = expectedMsgList.iterator(); + Iterator receivedMessageIterator = result.iterator(); + + while (expectedMessageIterator.hasNext()) { + if(comparator.compare(expectedMessageIterator.next(), receivedMessageIterator.next()) != 0){ + onFailure(new AssertionError("Received unexpected message")); + return; + } + } + + // Post new message + try { + if (stage < messagesToPost.size()) { + bulletinBoardClient.postMessage(messagesToPost.get(stage)); + } + } catch (CommunicationException e) { + onFailure(e); + return; + } + + stage++; + jobSemaphore.release(); + } + + @Override + public void onFailure(Throwable t) { + System.err.println(t.getCause() + " " + t.getMessage()); + thrown.add(t); + jobSemaphore.release(expectedMessages.size()); + stage = expectedMessages.size(); + } + } + + public void subscriptionTest() throws SignatureException, CommunicationException { + + final int FIRST_POST_ID = 201; + final int SECOND_POST_ID = 202; + final String COMMON_TAG = "SUBSCRIPTION_TEST"; + + List tags = new LinkedList<>(); + tags.add(COMMON_TAG); + + BulletinBoardMessage msg1 = generator.generateRandomMessage(signers, Timestamp.newBuilder().setSeconds(1000).setNanos(900).build(), 10, 4, tags); + BulletinBoardMessage msg2 = generator.generateRandomMessage(signers, Timestamp.newBuilder().setSeconds(800).setNanos(300).build(), 10, 4); + BulletinBoardMessage msg3 = generator.generateRandomMessage(signers, Timestamp.newBuilder().setSeconds(2000).setNanos(0).build(), 10, 4, tags); + + MessageFilterList filterList = MessageFilterList.newBuilder() + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.TAG) + .setTag(COMMON_TAG) + .build()) + .build(); + + List> expectedMessages = new ArrayList<>(3); + expectedMessages.add(new LinkedList()); + expectedMessages.add(new LinkedList()); + expectedMessages.add(new LinkedList()); + expectedMessages.get(0).add(msg1); + expectedMessages.get(2).add(msg3); + + List messagesToPost = new ArrayList<>(2); + messagesToPost.add(msg2); + messagesToPost.add(msg3); + + bulletinBoardClient.postMessage(msg1); + bulletinBoardClient.subscribe(filterList, new SubscriptionCallback(expectedMessages, messagesToPost)); + + try { + jobSemaphore.acquire(3); + } catch (InterruptedException e) { + System.err.println(e.getCause() + " " + e.getMessage()); + } + + } + +} diff --git a/bulletin-board-client/src/test/java/meerkat/bulletinboard/LocalBulletinBoardClientTest.java b/bulletin-board-client/src/test/java/meerkat/bulletinboard/LocalBulletinBoardClientTest.java index 2e0e0af..d2039ae 100644 --- a/bulletin-board-client/src/test/java/meerkat/bulletinboard/LocalBulletinBoardClientTest.java +++ b/bulletin-board-client/src/test/java/meerkat/bulletinboard/LocalBulletinBoardClientTest.java @@ -22,8 +22,11 @@ public class LocalBulletinBoardClientTest { private static final int THREAD_NUM = 3; private static final String DB_NAME = "TestDB"; - // Tester + private static final int SUBSRCIPTION_DELAY = 3000; + + // Testers private GenericBulletinBoardClientTester clientTest; + private GenericSubscriptionClientTester subscriptionTester; public LocalBulletinBoardClientTest() throws CommunicationException { @@ -48,8 +51,8 @@ public class LocalBulletinBoardClientTest { BulletinBoardServer server = new BulletinBoardSQLServer(queryProvider); server.init(DB_NAME); - LocalBulletinBoardClient client = new LocalBulletinBoardClient(server, THREAD_NUM); - + LocalBulletinBoardClient client = new LocalBulletinBoardClient(server, THREAD_NUM, SUBSRCIPTION_DELAY); + subscriptionTester = new GenericSubscriptionClientTester(client); clientTest = new GenericBulletinBoardClientTester(client); } @@ -104,4 +107,12 @@ public class LocalBulletinBoardClientTest { } + @Test + public void testSubscription() throws SignatureException, CommunicationException { + subscriptionTester.init(); + subscriptionTester.subscriptionTest(); + subscriptionTester.close(); + + } + } diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java index c390048..a54c2ff 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java @@ -158,10 +158,10 @@ public class H2QueryProvider implements BulletinBoardSQLServer.SQLQueryProvider + " WHERE TagTable.Tag = :Tag" + serialString + " AND MsgTagTable.EntryNum = MsgTable.EntryNum)"; case BEFORE_TIME: - return "MsgTable.ExactTime <= :TimeStamp"; + return "MsgTable.ExactTime <= :TimeStamp" + serialString; case AFTER_TIME: - return "MsgTable.ExactTime >= :TimeStamp"; + return "MsgTable.ExactTime >= :TimeStamp" + serialString; default: throw new IllegalArgumentException("Cannot serve a filter of type " + filterType); @@ -186,6 +186,11 @@ public class H2QueryProvider implements BulletinBoardSQLServer.SQLQueryProvider case TAG: return "VARCHAR"; + case AFTER_TIME: // Go through + case BEFORE_TIME: + return "TIMESTAMP"; + + default: throw new IllegalArgumentException("Cannot serve a filter of type " + filterType); } diff --git a/meerkat-common/src/main/java/meerkat/util/BulletinBoardMessageGenerator.java b/meerkat-common/src/main/java/meerkat/util/BulletinBoardMessageGenerator.java index 5ca3e0b..dff562e 100644 --- a/meerkat-common/src/main/java/meerkat/util/BulletinBoardMessageGenerator.java +++ b/meerkat-common/src/main/java/meerkat/util/BulletinBoardMessageGenerator.java @@ -8,6 +8,8 @@ import com.google.protobuf.Timestamp; import java.math.BigInteger; import java.security.SignatureException; import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; import java.util.Random; /** @@ -36,35 +38,36 @@ public class BulletinBoardMessageGenerator { * @param timestamp contains the time used in the message * @param dataSize is the length of the data contained in the message * @param tagNumber is the number of tags to generate + * @param tags is a list of initial tags (on top of which more will be added according to the method input) * @return a random, signed Bulletin Board Message containing random data and tags and the given timestamp */ - - public BulletinBoardMessage generateRandomMessage(DigitalSignature[] signers, Timestamp timestamp, int dataSize, int tagNumber) - throws SignatureException { + public BulletinBoardMessage generateRandomMessage(DigitalSignature[] signers, Timestamp timestamp, int dataSize, int tagNumber, List tags) + throws SignatureException{ // Generate random data. byte[] data = new byte[dataSize]; - String[] tags = new String[tagNumber]; + String[] newTags = new String[tagNumber]; for (int i = 0; i < dataSize; i++) { data[i] = randomByte(); } for (int i = 0; i < tagNumber; i++) { - tags[i] = randomString(); + newTags[i] = randomString(); } UnsignedBulletinBoardMessage unsignedMessage = UnsignedBulletinBoardMessage.newBuilder() .setData(ByteString.copyFrom(data)) .setTimestamp(timestamp) - .addAllTag(Arrays.asList(tags)) + .addAllTag(tags) + .addAllTag(Arrays.asList(newTags)) .build(); BulletinBoardMessage.Builder messageBuilder = BulletinBoardMessage.newBuilder() - .setMsg(unsignedMessage); + .setMsg(unsignedMessage); for (int i = 0 ; i < signers.length ; i++) { signers[i].updateContent(unsignedMessage); @@ -75,6 +78,23 @@ public class BulletinBoardMessageGenerator { } + /** + * Generates a complete instance of a BulletinBoardMessage + * @param signers contains the (possibly multiple) credentials required to sign the message + * @param timestamp contains the time used in the message + * @param dataSize is the length of the data contained in the message + * @param tagNumber is the number of tags to generate + * @return a random, signed Bulletin Board Message containing random data and tags and the given timestamp + */ + + public BulletinBoardMessage generateRandomMessage(DigitalSignature[] signers, Timestamp timestamp, int dataSize, int tagNumber) + throws SignatureException { + + List tags = new LinkedList<>(); + return generateRandomMessage(signers, timestamp, dataSize, tagNumber, tags); + + } + /** * Generates a complete instance of a BulletinBoardMessage * @param signers contains the (possibly multiple) credentials required to sign the message From 49c1e2c17856e674d9fb06a2d298117537b39ed9 Mon Sep 17 00:00:00 2001 From: Arbel Deutsch Peled Date: Sun, 27 Mar 2016 20:11:09 +0300 Subject: [PATCH 30/49] Added missing files to version control --- bulletin-board-client/build.gradle | 242 ++++++++ .../CachedBulletinBoardClient.java | 168 ++++++ .../LocalBulletinBoardClient.java | 531 ++++++++++++++++++ .../ThreadedBulletinBoardSubscriber.java | 272 +++++++++ .../GenericBulletinBoardClientTester.java | 519 +++++++++++++++++ ...dedBulletinBoardClientIntegrationTest.java | 95 ++++ 6 files changed, 1827 insertions(+) create mode 100644 bulletin-board-client/build.gradle create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/CachedBulletinBoardClient.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/LocalBulletinBoardClient.java create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardSubscriber.java create mode 100644 bulletin-board-client/src/test/java/meerkat/bulletinboard/GenericBulletinBoardClientTester.java create mode 100644 bulletin-board-client/src/test/java/meerkat/bulletinboard/ThreadedBulletinBoardClientIntegrationTest.java diff --git a/bulletin-board-client/build.gradle b/bulletin-board-client/build.gradle new file mode 100644 index 0000000..8fdeba0 --- /dev/null +++ b/bulletin-board-client/build.gradle @@ -0,0 +1,242 @@ + +plugins { + id "us.kirchmeier.capsule" version "1.0.1" + id 'com.google.protobuf' version '0.7.0' +} + +apply plugin: 'java' +apply plugin: 'com.google.protobuf' +apply plugin: 'eclipse' +apply plugin: 'idea' + +apply plugin: 'maven-publish' + +// Is this a snapshot version? +ext { isSnapshot = false } + +ext { + groupId = 'org.factcenter.meerkat' + nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/" + + // Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing) + // Should be set in ${HOME}/.gradle/gradle.properties + nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : "" + nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : "" +} + +description = "Meerkat Voting Common Library" + +// Your project version +version = "0.0" + +version += "${isSnapshot ? '-SNAPSHOT' : ''}" + + +dependencies { + + // Meerkat common + compile project(':meerkat-common') + compile project(':restful-api-common') + + // Jersey for RESTful API + compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.22.+' + compile 'org.xerial:sqlite-jdbc:3.7.+' + + // Logging + compile 'org.slf4j:slf4j-api:1.7.7' + runtime 'ch.qos.logback:logback-classic:1.1.2' + runtime 'ch.qos.logback:logback-core:1.1.2' + + // Google protobufs + compile 'com.google.protobuf:protobuf-java:3.+' + + // Crypto + compile 'org.factcenter.qilin:qilin:1.1+' + compile 'org.bouncycastle:bcprov-jdk15on:1.53' + compile 'org.bouncycastle:bcpkix-jdk15on:1.53' + + // Depend on test resources from meerkat-common + testCompile project(path: ':meerkat-common', configuration: 'testOutput') + + // Depend on server compilation for the non-integration tests + testCompile project(path: ':bulletin-board-server') + + testCompile 'junit:junit:4.+' + testCompile 'org.hamcrest:hamcrest-all:1.3' + + runtime 'org.codehaus.groovy:groovy:2.4.+' +} + +test { + exclude '**/*IntegrationTest*' + outputs.upToDateWhen { false } +} + +task integrationTest(type: Test) { + include '**/*IntegrationTest*' +// debug = true + outputs.upToDateWhen { false } + +} + +/*==== You probably don't have to edit below this line =======*/ + + +// Setup test configuration that can appear as a dependency in +// other subprojects +configurations { + testOutput.extendsFrom (testCompile) +} + +task testJar(type: Jar, dependsOn: testClasses) { + classifier = 'tests' + from sourceSets.test.output +} + +artifacts { + testOutput testJar +} + + + +// The run task added by the application plugin +// is also of type JavaExec. +tasks.withType(JavaExec) { + // Assign all Java system properties from + // the command line to the JavaExec task. + systemProperties System.properties +} + + +protobuf { + // Configure the protoc executable + protoc { + // Download from repositories + artifact = 'com.google.protobuf:protoc:3.+' + } +} + +idea { + module { + project.sourceSets.each { sourceSet -> + + def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java" + + // add protobuf generated sources to generated source dir. + if ("test".equals(sourceSet.name)) { + testSourceDirs += file(srcDir) + } else { + sourceDirs += file(srcDir) + } + generatedSourceDirs += file(srcDir) + + } + + // Don't exclude build directory + excludeDirs -= file(buildDir) + } +} + +/*=================================== + * "Fat" Build targets + *===================================*/ + +if (project.hasProperty('mainClassName') && (mainClassName != null)) { + + task mavenCapsule(type: MavenCapsule) { + description = "Generate a capsule jar that automatically downloads and caches dependencies when run." + applicationClass mainClassName + destinationDir = buildDir + } + + task fatCapsule(type: FatCapsule) { + description = "Generate a single capsule jar containing everything. Use -Pfatmain=... to override main class" + + destinationDir = buildDir + + def fatMain = hasProperty('fatmain') ? fatmain : mainClassName + + applicationClass fatMain + + def testJar = hasProperty('test') + + if (hasProperty('fatmain')) { + appendix = "fat-${fatMain}" + } else { + appendix = "fat" + } + + if (testJar) { + from sourceSets.test.output + } + } + +} + +/*=================================== + * Repositories + *===================================*/ + +repositories { + + mavenLocal(); + + // Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral) + maven { + url nexusRepository + + if (isSnapshot) { + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } + + // Use 'maven central' for other dependencies. + mavenCentral() +} + +task "info" << { + println "Project: ${project.name}" + println "Description: ${project.description}" + println "--------------------------" + println "GroupId: $groupId" + println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})" + println "" +} +info.description 'Print some information about project parameters' + + +/*=================================== + * Publishing + *===================================*/ + +publishing { + publications { + mavenJava(MavenPublication) { + groupId project.groupId + pom.withXml { + asNode().appendNode('description', project.description) + } + from project.components.java + + } + } + repositories { + maven { + url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}" + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } +} + + + diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/CachedBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/CachedBulletinBoardClient.java new file mode 100644 index 0000000..96ba76d --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/CachedBulletinBoardClient.java @@ -0,0 +1,168 @@ +package meerkat.bulletinboard; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.ListeningScheduledExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.protobuf.ByteString; +import meerkat.comm.CommunicationException; +import meerkat.protobuf.BulletinBoardAPI; +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Voting.*; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.Executors; + +/** + * Created by Arbel Deutsch Peled on 03-Mar-16. + * This is a full-fledged implementation of a Bulletin Board Client + * It provides asynchronous access to several remote servers, as well as a local cache + * Read/write operations are performed on the local server + * After any read is carried out, a subscription is made for the specific query to make sure the local DB will be updated + * The database also employs a synchronizer which makes sure local data is sent to the remote servers + */ +public class CachedBulletinBoardClient implements SubscriptionAsyncBulletinBoardClient { + + private final BulletinBoardClient localClient; + private AsyncBulletinBoardClient remoteClient; + private BulletinBoardSubscriber subscriber; + + private final int threadPoolSize; + private final long failDelayInMilliseconds; + private final long subscriptionIntervalInMilliseconds; + + public CachedBulletinBoardClient(BulletinBoardClient localClient, + int threadPoolSize, + long failDelayInMilliseconds, + long subscriptionIntervalInMilliseconds) + throws IllegalAccessException, InstantiationException { + + this.localClient = localClient; + this.threadPoolSize = threadPoolSize; + this.failDelayInMilliseconds = failDelayInMilliseconds; + this.subscriptionIntervalInMilliseconds = subscriptionIntervalInMilliseconds; + + remoteClient = new ThreadedBulletinBoardClient(); + + } + + @Override + public MessageID postMessage(BulletinBoardMessage msg, FutureCallback callback) { + return null; + } + + @Override + public MessageID postBatch(CompleteBatch completeBatch, FutureCallback callback) { + return null; + } + + @Override + public void beginBatch(BeginBatchMessage beginBatchMessage, FutureCallback callback) { + + } + + @Override + public void postBatchData(byte[] signerId, int batchId, List batchDataList, int startPosition, FutureCallback callback) { + + } + + @Override + public void postBatchData(byte[] signerId, int batchId, List batchDataList, FutureCallback callback) { + + } + + @Override + public void postBatchData(ByteString signerId, int batchId, List batchDataList, int startPosition, FutureCallback callback) { + + } + + @Override + public void postBatchData(ByteString signerId, int batchId, List batchDataList, FutureCallback callback) { + + } + + @Override + public void closeBatch(CloseBatchMessage closeBatchMessage, FutureCallback callback) { + + } + + @Override + public void getRedundancy(MessageID id, FutureCallback callback) { + + } + + @Override + public void readMessages(MessageFilterList filterList, FutureCallback> callback) { + + } + + @Override + public void readBatch(BatchSpecificationMessage batchSpecificationMessage, FutureCallback callback) { + + } + + @Override + public void querySync(SyncQuery syncQuery, FutureCallback callback) { + + } + + @Override + public void init(BulletinBoardClientParams clientParams) { + + remoteClient.init(clientParams); + + ListeningScheduledExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newScheduledThreadPool(threadPoolSize)); + + List subscriberClients = new ArrayList<>(clientParams.getBulletinBoardAddressCount()); + + for (String address : clientParams.getBulletinBoardAddressList()){ + + SubscriptionAsyncBulletinBoardClient newClient = + new SingleServerBulletinBoardClient(executorService, failDelayInMilliseconds, subscriptionIntervalInMilliseconds); + + newClient.init(clientParams.toBuilder().clearBulletinBoardAddress().addBulletinBoardAddress(address).build()); + + subscriberClients.add(newClient); + + } + + subscriber = new ThreadedBulletinBoardSubscriber(subscriberClients, localClient); + + } + + @Override + public MessageID postMessage(BulletinBoardMessage msg) throws CommunicationException { + return null; + } + + @Override + public float getRedundancy(MessageID id) { + return 0; + } + + @Override + public List readMessages(MessageFilterList filterList) { + return null; + } + + @Override + public SyncQuery generateSyncQuery(GenerateSyncQueryParams GenerateSyncQueryParams) throws CommunicationException { + return null; + } + + @Override + public void close() { + + } + + @Override + public void subscribe(MessageFilterList filterList, FutureCallback> callback) { + + } + + @Override + public void subscribe(MessageFilterList filterList, long startEntry, FutureCallback> callback) { + + } +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/LocalBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/LocalBulletinBoardClient.java new file mode 100644 index 0000000..df3e196 --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/LocalBulletinBoardClient.java @@ -0,0 +1,531 @@ +package meerkat.bulletinboard; + +import com.google.common.util.concurrent.*; +import com.google.protobuf.ByteString; +import meerkat.comm.CommunicationException; +import meerkat.comm.MessageInputStream; +import meerkat.comm.MessageInputStream.MessageInputStreamFactory; +import meerkat.comm.MessageOutputStream; +import meerkat.crypto.concrete.SHA256Digest; +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Voting.*; +import meerkat.util.BulletinBoardUtils; + +import javax.ws.rs.NotFoundException; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * Created by Arbel Deutsch Peled on 15-Mar-16. + * This client is to be used mainly for testing. + * It wraps a BulletinBoardServer in an asynchronous client. + * This means the access to the server is direct (via method calls) instead of through a TCP connection. + * The client implements both synchronous and asynchronous method calls, but calls to the server itself are performed synchronously. + */ +public class LocalBulletinBoardClient implements SubscriptionAsyncBulletinBoardClient{ + + private final BulletinBoardServer server; + private final ListeningScheduledExecutorService executorService; + private final BatchDigest digest; + private final int subsrciptionDelay; + + /** + * Initializes an instance of the client + * @param server an initialized Bulletin Board Server instance which will perform the actual processing of the requests + * @param threadNum is the number of concurrent threads to allocate for the client + * @param subscriptionDelay is the required delay between subscription calls in milliseconds + */ + public LocalBulletinBoardClient(BulletinBoardServer server, int threadNum, int subscriptionDelay) { + this.server = server; + this.executorService = MoreExecutors.listeningDecorator(Executors.newScheduledThreadPool(threadNum)); + this.digest = new GenericBatchDigest(new SHA256Digest()); + this.subsrciptionDelay = subscriptionDelay; + } + + private class MessagePoster implements Callable { + + private final BulletinBoardMessage msg; + + public MessagePoster(BulletinBoardMessage msg) { + this.msg = msg; + } + + + @Override + public Boolean call() throws Exception { + return server.postMessage(msg).getValue(); + } + + } + + @Override + public MessageID postMessage(BulletinBoardMessage msg, FutureCallback callback) { + + Futures.addCallback(executorService.submit(new MessagePoster(msg)), callback); + + digest.update(msg.getMsg()); + return digest.digestAsMessageID(); + + } + + private class CompleteBatchPoster implements Callable { + + private final CompleteBatch completeBatch; + + public CompleteBatchPoster(CompleteBatch completeBatch) { + this.completeBatch = completeBatch; + } + + + @Override + public Boolean call() throws Exception { + + if (!server.beginBatch(completeBatch.getBeginBatchMessage()).getValue()) + return false; + + int i=0; + for (BatchData data : completeBatch.getBatchDataList()){ + + BatchMessage message = BatchMessage.newBuilder() + .setSignerId(completeBatch.getSignature().getSignerId()) + .setBatchId(completeBatch.getBeginBatchMessage().getBatchId()) + .setSerialNum(i) + .setData(data) + .build(); + + if (!server.postBatchMessage(message).getValue()) + return false; + + i++; + } + + return server.closeBatchMessage(completeBatch.getCloseBatchMessage()).getValue(); + } + + } + + @Override + public MessageID postBatch(CompleteBatch completeBatch, FutureCallback callback) { + + Futures.addCallback(executorService.schedule(new CompleteBatchPoster(completeBatch), subsrciptionDelay, TimeUnit.MILLISECONDS), callback); + + digest.update(completeBatch); + return digest.digestAsMessageID(); + + } + + private class BatchBeginner implements Callable { + + private final BeginBatchMessage msg; + + public BatchBeginner(BeginBatchMessage msg) { + this.msg = msg; + } + + + @Override + public Boolean call() throws Exception { + return server.beginBatch(msg).getValue(); + } + + } + + @Override + public void beginBatch(BeginBatchMessage beginBatchMessage, FutureCallback callback) { + Futures.addCallback(executorService.submit(new BatchBeginner(beginBatchMessage)), callback); + } + + private class BatchDataPoster implements Callable { + + private final ByteString signerId; + private final int batchId; + private final List batchDataList; + private final int startPosition; + + public BatchDataPoster(ByteString signerId, int batchId, List batchDataList, int startPosition) { + this.signerId = signerId; + this.batchId = batchId; + this.batchDataList = batchDataList; + this.startPosition = startPosition; + } + + + @Override + public Boolean call() throws Exception { + + BatchMessage.Builder msgBuilder = BatchMessage.newBuilder() + .setSignerId(signerId) + .setBatchId(batchId); + + int i = startPosition; + for (BatchData data : batchDataList){ + + msgBuilder.setSerialNum(i) + .setData(data); + + if (!server.postBatchMessage(msgBuilder.build()).getValue()) + return false; + + i++; + + } + + return true; + + } + + } + + @Override + public void postBatchData(byte[] signerId, int batchId, List batchDataList, int startPosition, FutureCallback callback) { + postBatchData(ByteString.copyFrom(signerId), batchId, batchDataList, startPosition, callback); + } + + @Override + public void postBatchData(byte[] signerId, int batchId, List batchDataList, FutureCallback callback) { + postBatchData(signerId, batchId, batchDataList, 0, callback); + } + + @Override + public void postBatchData(ByteString signerId, int batchId, List batchDataList, int startPosition, FutureCallback callback) { + Futures.addCallback(executorService.submit(new BatchDataPoster(signerId, batchId, batchDataList, startPosition)), callback); + } + + @Override + public void postBatchData(ByteString signerId, int batchId, List batchDataList, FutureCallback callback) { + postBatchData(signerId, batchId, batchDataList, 0, callback); + } + + private class BatchCloser implements Callable { + + private final CloseBatchMessage msg; + + public BatchCloser(CloseBatchMessage msg) { + this.msg = msg; + } + + + @Override + public Boolean call() throws Exception { + return server.closeBatchMessage(msg).getValue(); + } + + } + + @Override + public void closeBatch(CloseBatchMessage closeBatchMessage, FutureCallback callback) { + Futures.addCallback(executorService.submit(new BatchCloser(closeBatchMessage)), callback); + } + + private class RedundancyGetter implements Callable { + + private final MessageID msgId; + + public RedundancyGetter(MessageID msgId) { + this.msgId = msgId; + } + + + @Override + public Float call() throws Exception { + + MessageFilterList filterList = MessageFilterList.newBuilder() + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.MSG_ID) + .setId(msgId.getID()) + .build()) + .build(); + + ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream(); + MessageOutputStream outputStream = new MessageOutputStream<>(byteOutputStream); + server.readMessages(filterList,outputStream); + + MessageInputStream inputStream = + MessageInputStreamFactory.createMessageInputStream( + new ByteArrayInputStream(byteOutputStream.toByteArray()), + BulletinBoardMessage.class); + + if (inputStream.isAvailable()) + return 1.0f; + else + return 0.0f; + + } + + } + + @Override + public void getRedundancy(MessageID id, FutureCallback callback) { + Futures.addCallback(executorService.submit(new RedundancyGetter(id)), callback); + } + + private class MessageReader implements Callable> { + + private final MessageFilterList filterList; + + public MessageReader(MessageFilterList filterList) { + this.filterList = filterList; + } + + + @Override + public List call() throws Exception { + + ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream(); + MessageOutputStream outputStream = new MessageOutputStream<>(byteOutputStream); + server.readMessages(filterList, outputStream); + + MessageInputStream inputStream = + MessageInputStreamFactory.createMessageInputStream( + new ByteArrayInputStream(byteOutputStream.toByteArray()), + BulletinBoardMessage.class); + + return inputStream.asList(); + + } + + } + + @Override + public void readMessages(MessageFilterList filterList, FutureCallback> callback) { + Futures.addCallback(executorService.submit(new MessageReader(filterList)), callback); + } + + class SubscriptionCallback implements FutureCallback> { + + private MessageFilterList filterList; + private final FutureCallback> callback; + + public SubscriptionCallback(MessageFilterList filterList, FutureCallback> callback) { + this.filterList = filterList; + this.callback = callback; + } + + @Override + public void onSuccess(List result) { + + // Report new messages to user + callback.onSuccess(result); + + MessageFilterList.Builder filterBuilder = filterList.toBuilder(); + + // If any new messages arrived: update the MIN_ENTRY condition + if (result.size() > 0) { + + // Remove last filter from list (MIN_ENTRY one) + filterBuilder.removeFilter(filterBuilder.getFilterCount() - 1); + + // Add updated MIN_ENTRY filter (entry number is successor of last received entry's number) + filterBuilder.addFilter(MessageFilter.newBuilder() + .setType(FilterType.MIN_ENTRY) + .setEntry(result.get(result.size() - 1).getEntryNum() + 1) + .build()); + + } + + filterList = filterBuilder.build(); + + // Reschedule job + Futures.addCallback(executorService.submit(new MessageReader(filterList)), this); + + } + + @Override + public void onFailure(Throwable t) { + + // Notify caller about failure and terminate subscription + callback.onFailure(t); + + } + } + + @Override + public void subscribe(MessageFilterList filterList, long startEntry, FutureCallback> callback) { + + MessageFilterList subscriptionFilterList = + filterList.toBuilder() + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.MIN_ENTRY) + .setEntry(startEntry) + .build()) + .build(); + + Futures.addCallback(executorService.submit(new MessageReader(subscriptionFilterList)), new SubscriptionCallback(subscriptionFilterList, callback)); + + } + + @Override + public void subscribe(MessageFilterList filterList, FutureCallback> callback) { + subscribe(filterList, 0, callback); + } + + private class CompleteBatchReader implements Callable { + + private final BatchSpecificationMessage batchSpecificationMessage; + + public CompleteBatchReader(BatchSpecificationMessage batchSpecificationMessage) { + this.batchSpecificationMessage = batchSpecificationMessage; + } + + + @Override + public CompleteBatch call() throws Exception { + + final String[] TAGS_TO_REMOVE = {BulletinBoardConstants.BATCH_TAG, BulletinBoardConstants.BATCH_ID_TAG_PREFIX}; + + CompleteBatch completeBatch = new CompleteBatch(BeginBatchMessage.newBuilder() + .setSignerId(batchSpecificationMessage.getSignerId()) + .setBatchId(batchSpecificationMessage.getBatchId()) + .build()); + + ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream(); + MessageOutputStream batchOutputStream = new MessageOutputStream<>(byteOutputStream); + server.readBatch(batchSpecificationMessage,batchOutputStream); + + MessageInputStream batchInputStream = + MessageInputStreamFactory.createMessageInputStream( + new ByteArrayInputStream(byteOutputStream.toByteArray()), + BatchData.class); + + completeBatch.appendBatchData(batchInputStream.asList()); + + MessageFilterList filterList = MessageFilterList.newBuilder() + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.TAG) + .setTag(BulletinBoardConstants.BATCH_TAG) + .build()) + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.TAG) + .setTag(BulletinBoardConstants.BATCH_ID_TAG_PREFIX + completeBatch.getBeginBatchMessage().getBatchId()) + .build()) + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.SIGNER_ID) + .setId(completeBatch.getBeginBatchMessage().getSignerId()) + .build()) + .build(); + + byteOutputStream = new ByteArrayOutputStream(); + MessageOutputStream messageOutputStream = new MessageOutputStream<>(byteOutputStream); + server.readMessages(filterList,messageOutputStream); + + MessageInputStream messageInputStream = + MessageInputStreamFactory.createMessageInputStream( + new ByteArrayInputStream(byteOutputStream.toByteArray()), + BulletinBoardMessage.class); + + if (!messageInputStream.isAvailable()) + throw new NotFoundException("Batch does not exist"); + + BulletinBoardMessage message = messageInputStream.readMessage(); + + completeBatch.setBeginBatchMessage(BeginBatchMessage.newBuilder() + .addAllTag(BulletinBoardUtils.removePrefixTags(message, Arrays.asList(TAGS_TO_REMOVE))) + .setSignerId(message.getSig(0).getSignerId()) + .setBatchId(Integer.parseInt(BulletinBoardUtils.findTagWithPrefix(message, BulletinBoardConstants.BATCH_ID_TAG_PREFIX))) + .build()); + + completeBatch.setSignature(message.getSig(0)); + completeBatch.setTimestamp(message.getMsg().getTimestamp()); + + return completeBatch; + + } + + } + + @Override + public void readBatch(BatchSpecificationMessage batchSpecificationMessage, FutureCallback callback) { + Futures.addCallback(executorService.submit(new CompleteBatchReader(batchSpecificationMessage)), callback); + } + + private class SyncQueryHandler implements Callable { + + private final SyncQuery syncQuery; + + public SyncQueryHandler(SyncQuery syncQuery) { + this.syncQuery = syncQuery; + } + + + @Override + public SyncQueryResponse call() throws Exception { + return server.querySync(syncQuery); + } + + } + + @Override + public void querySync(SyncQuery syncQuery, FutureCallback callback) { + Futures.addCallback(executorService.submit(new SyncQueryHandler(syncQuery)), callback); + } + + /** + * This method is a stub, since the implementation only considers one server, and that is given in the constructor + * @param ignored is ignored + */ + @Override + public void init(BulletinBoardClientParams ignored) {} + + @Override + public MessageID postMessage(BulletinBoardMessage msg) throws CommunicationException { + + try { + + MessagePoster poster = new MessagePoster(msg); + poster.call(); + + digest.update(msg); + return digest.digestAsMessageID(); + + } catch (Exception e) { + return null; + } + + } + + @Override + public float getRedundancy(MessageID id) { + + try { + + RedundancyGetter getter = new RedundancyGetter(id); + return getter.call(); + + } catch (Exception e) { + return -1.0f; + } + + } + + @Override + public List readMessages(MessageFilterList filterList) { + + try { + + MessageReader reader = new MessageReader(filterList); + return reader.call(); + + } catch (Exception e){ + return null; + } + + } + + @Override + public SyncQuery generateSyncQuery(GenerateSyncQueryParams GenerateSyncQueryParams) throws CommunicationException { + return server.generateSyncQuery(GenerateSyncQueryParams); + } + + @Override + public void close() { + try { + server.close(); + } catch (CommunicationException ignored) {} + } + +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardSubscriber.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardSubscriber.java new file mode 100644 index 0000000..cf8d47d --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardSubscriber.java @@ -0,0 +1,272 @@ +package meerkat.bulletinboard; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.protobuf.Timestamp; +import meerkat.comm.CommunicationException; +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.util.BulletinBoardUtils; + +import static meerkat.protobuf.BulletinBoardAPI.FilterType.*; + +import java.sql.Time; +import java.util.*; +import java.util.concurrent.Semaphore; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Created by Arbel Deutsch Peled on 03-Mar-16. + * A multi-server implementation of the {@link BulletinBoardSubscriber} + */ +public class ThreadedBulletinBoardSubscriber implements BulletinBoardSubscriber { + + protected final Collection clients; + protected final BulletinBoardClient localClient; + + protected Iterator clientIterator; + protected SubscriptionAsyncBulletinBoardClient currentClient; + + private long lastServerSwitchTime; + + private AtomicBoolean isSyncInProgress; + private Semaphore rescheduleSemaphore; + + private static final Float[] BREAKPOINTS = {0.5f, 0.75f, 0.9f, 0.95f, 0.99f, 0.999f}; + + public ThreadedBulletinBoardSubscriber(Collection clients, BulletinBoardClient localClient) { + + this.clients = clients; + this.localClient = localClient; + + lastServerSwitchTime = System.currentTimeMillis(); + + clientIterator = clients.iterator(); + currentClient = clientIterator.next(); + + isSyncInProgress = new AtomicBoolean(false); + rescheduleSemaphore = new Semaphore(1); + + } + + /** + * Moves to next client and performs resync with it + */ + private void nextClient() { + + try { + + rescheduleSemaphore.acquire(); + + if (!clientIterator.hasNext()){ + clientIterator = clients.iterator(); + } + + currentClient = clientIterator.next(); + + lastServerSwitchTime = System.currentTimeMillis(); + + isSyncInProgress.set(false); + + rescheduleSemaphore.release(); + + } catch (InterruptedException e) { + // TODO: log + // Do not change client + } + + } + + private abstract class SubscriberCallback implements FutureCallback { + + protected final MessageFilterList filterList; + protected final FutureCallback> callback; + private final long invocationTime; + + public SubscriberCallback(MessageFilterList filterList, FutureCallback> callback) { + + this.filterList = filterList; + this.callback = callback; + this.invocationTime = System.currentTimeMillis(); + + } + + /** + * Handles resyncing process for the given subscription after a server is switched + * Specifically: generates a sync query from the local database and uses it to query the current server + */ + private void reSync() { + + SyncQuery syncQuery = null; + try { + + syncQuery = localClient.generateSyncQuery(GenerateSyncQueryParams.newBuilder() + .setFilterList(filterList) + .addAllBreakpointList(Arrays.asList(BREAKPOINTS)) + .build()); + + } catch (CommunicationException e) { + + // Handle failure in standard way + onFailure(e); + + } + + currentClient.querySync(syncQuery, new SyncQueryCallback(filterList, callback)); + + } + + /** + * Reschedules the subscription + */ + private void reschedule() { + + try { + + rescheduleSemaphore.acquire(); + + reSync(); + + rescheduleSemaphore.release(); + + + } catch (InterruptedException e) { + + //TODO: log + + callback.onFailure(e); // Hard error: Cannot guarantee subscription safety + + } + + } + + @Override + public void onFailure(Throwable t) { + + // If server failure is not already known: switch to next client and resync + if (invocationTime > lastServerSwitchTime){ + + // Make sure only what thread switches the client + if (isSyncInProgress.compareAndSet(false, true)){ + nextClient(); + } + + } + + reschedule(); + + } + + } + + /** + * Provides handling logic for resync query callback operation + * Receives a SyncQueryResponse and reads the missing data (starting from the received timestamp) if needed + */ + protected class SyncQueryCallback extends SubscriberCallback { + + public SyncQueryCallback (MessageFilterList filterList, FutureCallback> callback) { + + super(filterList, callback); + + } + + @Override + public void onSuccess(SyncQueryResponse result) { + + final Timestamp DEFAULT_TIME = BulletinBoardUtils.toTimestampProto(946728000); // Year 2000 + + // Read required messages according to received Timestamp + + Timestamp syncTimestamp; + + if (result.hasLastTimeOfSync()) { + syncTimestamp = result.getLastTimeOfSync(); // Use returned time of sync + } else { + syncTimestamp = DEFAULT_TIME; // Get all messages + } + + MessageFilterList timestampedFilterList = filterList.toBuilder() + .removeFilter(filterList.getFilterCount()-1) // Remove MIN_ENTRY filter + .addFilter(MessageFilter.newBuilder() // Add timestamp filter + .setType(AFTER_TIME) + .setTimestamp(syncTimestamp) + .build()) + .build(); + + currentClient.readMessages(timestampedFilterList, new ReSyncCallback(filterList, callback, result.getLastEntryNum())); + + } + + } + + /** + * Provides handling logic for callback of resyncing process + * Receives the missing messages, handles them and resubscribes + */ + protected class ReSyncCallback extends SubscriberCallback> { + + private long minEntry; + + public ReSyncCallback (MessageFilterList filterList, FutureCallback> callback, long minEntry) { + + super(filterList, callback); + + this.minEntry = minEntry; + + } + + @Override + public void onSuccess(List result) { + + // Propagate result to caller + callback.onSuccess(result); + + // Renew subscription + + MessageFilterList newFilterList = filterList.toBuilder() + .removeFilter(filterList.getFilterCount()-1) // Remove current MIN_ENTRY filter + .addFilter(MessageFilter.newBuilder() // Add new MIN_ENTRY filter for current server + .setType(MIN_ENTRY) + .setEntry(minEntry) + .build()) + .build(); + + currentClient.subscribe(newFilterList, callback); + + } + + } + + /** + * Provides the handling logic for results and failures of main subscription (while there are no errors) + */ + protected class SubscriptionCallback extends SubscriberCallback> { + + public SubscriptionCallback(MessageFilterList filterList, FutureCallback> callback){ + super(filterList, callback); + } + + + @Override + public void onSuccess(List result) { + + // Propagate result to caller + callback.onSuccess(result); + + } + + } + + @Override + public void subscribe(MessageFilterList filterList, long startEntry, FutureCallback> callback) { + + currentClient.subscribe(filterList, startEntry, new SubscriptionCallback(filterList, callback)); + + } + + @Override + public void subscribe(MessageFilterList filterList, FutureCallback> callback) { + subscribe(filterList, 0, callback); + } + + +} diff --git a/bulletin-board-client/src/test/java/meerkat/bulletinboard/GenericBulletinBoardClientTester.java b/bulletin-board-client/src/test/java/meerkat/bulletinboard/GenericBulletinBoardClientTester.java new file mode 100644 index 0000000..88fb22c --- /dev/null +++ b/bulletin-board-client/src/test/java/meerkat/bulletinboard/GenericBulletinBoardClientTester.java @@ -0,0 +1,519 @@ +package meerkat.bulletinboard; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.protobuf.ByteString; +import com.google.protobuf.Timestamp; +import meerkat.comm.CommunicationException; +import meerkat.crypto.concrete.ECDSASignature; +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Crypto; +import meerkat.util.BulletinBoardMessageComparator; +import meerkat.util.BulletinBoardMessageGenerator; + +import java.io.IOException; +import java.io.InputStream; +import java.security.*; +import java.security.cert.CertificateException; +import java.util.*; +import java.util.concurrent.Semaphore; + +import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.number.OrderingComparison.greaterThanOrEqualTo; +import static org.junit.Assert.*; + +/** + * Created by Arbel Deutsch Peled on 05-Dec-15. + */ +public class GenericBulletinBoardClientTester { + + // Signature resources + + private GenericBatchDigitalSignature signers[]; + private ByteString[] signerIDs; + + private static String KEYFILE_EXAMPLE = "/certs/enduser-certs/user1-key-with-password-secret.p12"; + private static String KEYFILE_EXAMPLE3 = "/certs/enduser-certs/user3-key-with-password-shh.p12"; + + private static String KEYFILE_PASSWORD1 = "secret"; + private static String KEYFILE_PASSWORD3 = "shh"; + + private static String CERT1_PEM_EXAMPLE = "/certs/enduser-certs/user1.crt"; + private static String CERT3_PEM_EXAMPLE = "/certs/enduser-certs/user3.crt"; + + // Client and callbacks + + private AsyncBulletinBoardClient bulletinBoardClient; + + private PostCallback postCallback; + private PostCallback failPostCallback = new PostCallback(true,false); + + private RedundancyCallback redundancyCallback; + private ReadCallback readCallback; + private ReadBatchCallback readBatchCallback; + + // Sync and misc + + private Semaphore jobSemaphore; + private Vector thrown; + private Random random; + + // Constructor + + public GenericBulletinBoardClientTester(AsyncBulletinBoardClient bulletinBoardClient){ + + this.bulletinBoardClient = bulletinBoardClient; + + signers = new GenericBatchDigitalSignature[2]; + signerIDs = new ByteString[signers.length]; + signers[0] = new GenericBatchDigitalSignature(new ECDSASignature()); + signers[1] = new GenericBatchDigitalSignature(new ECDSASignature()); + + InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE); + char[] password = KEYFILE_PASSWORD1.toCharArray(); + + KeyStore.Builder keyStoreBuilder; + try { + keyStoreBuilder = signers[0].getPKCS12KeyStoreBuilder(keyStream, password); + + signers[0].loadSigningCertificate(keyStoreBuilder); + + signers[0].loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE)); + + keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE3); + password = KEYFILE_PASSWORD3.toCharArray(); + + keyStoreBuilder = signers[1].getPKCS12KeyStoreBuilder(keyStream, password); + signers[1].loadSigningCertificate(keyStoreBuilder); + + signers[1].loadVerificationCertificates(getClass().getResourceAsStream(CERT3_PEM_EXAMPLE)); + + for (int i = 0 ; i < signers.length ; i++) { + signerIDs[i] = signers[i].getSignerID(); + } + + } catch (IOException e) { + System.err.println("Failed reading from signature file " + e.getMessage()); + fail("Failed reading from signature file " + e.getMessage()); + } catch (CertificateException e) { + System.err.println("Failed reading certificate " + e.getMessage()); + fail("Failed reading certificate " + e.getMessage()); + } catch (KeyStoreException e) { + System.err.println("Failed reading keystore " + e.getMessage()); + fail("Failed reading keystore " + e.getMessage()); + } catch (NoSuchAlgorithmException e) { + System.err.println("Couldn't find signing algorithm " + e.getMessage()); + fail("Couldn't find signing algorithm " + e.getMessage()); + } catch (UnrecoverableKeyException e) { + System.err.println("Couldn't find signing key " + e.getMessage()); + fail("Couldn't find signing key " + e.getMessage()); + } + + } + + // Callback definitions + + protected void genericHandleFailure(Throwable t){ + System.err.println(t.getCause() + " " + t.getMessage()); + thrown.add(t); + jobSemaphore.release(); + } + + private class PostCallback implements FutureCallback{ + + private boolean isAssert; + private boolean assertValue; + + public PostCallback() { + this(false); + } + + public PostCallback(boolean isAssert) { + this(isAssert,true); + } + + public PostCallback(boolean isAssert, boolean assertValue) { + this.isAssert = isAssert; + this.assertValue = assertValue; + } + + @Override + public void onSuccess(Boolean msg) { + System.err.println("Post operation completed"); + jobSemaphore.release(); + //TODO: Change Assert mechanism to exception one + if (isAssert) { + if (assertValue) { + assertThat("Post operation failed", msg, is(Boolean.TRUE)); + } else { + assertThat("Post operation succeeded unexpectedly", msg, is(Boolean.FALSE)); + } + } + } + + @Override + public void onFailure(Throwable t) { + genericHandleFailure(t); + } + } + + private class RedundancyCallback implements FutureCallback{ + + private float minRedundancy; + + public RedundancyCallback(float minRedundancy) { + this.minRedundancy = minRedundancy; + } + + @Override + public void onSuccess(Float redundancy) { + System.err.println("Redundancy found is: " + redundancy); + jobSemaphore.release(); + assertThat(redundancy, greaterThanOrEqualTo(minRedundancy)); + } + + @Override + public void onFailure(Throwable t) { + genericHandleFailure(t); + } + } + + private class ReadCallback implements FutureCallback>{ + + private List expectedMsgList; + + public ReadCallback(List expectedMsgList) { + this.expectedMsgList = expectedMsgList; + } + + @Override + public void onSuccess(List messages) { + + System.err.println(messages); + jobSemaphore.release(); + + BulletinBoardMessageComparator msgComparator = new BulletinBoardMessageComparator(); + + assertThat(messages.size(), is(expectedMsgList.size())); + + Iterator expectedMessageIterator = expectedMsgList.iterator(); + Iterator receivedMessageIterator = messages.iterator(); + + while (expectedMessageIterator.hasNext()) { + assertThat(msgComparator.compare(expectedMessageIterator.next(), receivedMessageIterator.next()), is(0)); + } + + } + + @Override + public void onFailure(Throwable t) { + genericHandleFailure(t); + } + } + + private class ReadBatchCallback implements FutureCallback { + + private CompleteBatch expectedBatch; + + public ReadBatchCallback(CompleteBatch expectedBatch) { + this.expectedBatch = expectedBatch; + } + + @Override + public void onSuccess(CompleteBatch batch) { + + System.err.println(batch); + jobSemaphore.release(); + + assertThat("Batch returned is incorrect", batch, is(equalTo(expectedBatch))); + + } + + @Override + public void onFailure(Throwable t) { + genericHandleFailure(t); + } + } + + // Randomness generators + + private byte randomByte(){ + return (byte) random.nextInt(); + } + + private byte[] randomByteArray(int length) { + + byte[] randomBytes = new byte[length]; + + for (int i = 0; i < length ; i++){ + randomBytes[i] = randomByte(); + } + + return randomBytes; + + } + + private CompleteBatch createRandomBatch(int signer, int batchId, int length) throws SignatureException { + + CompleteBatch completeBatch = new CompleteBatch(); + + // Create data + + completeBatch.setBeginBatchMessage(BeginBatchMessage.newBuilder() + .setSignerId(signerIDs[signer]) + .setBatchId(batchId) + .addTag("Test") + .build()); + + for (int i = 0 ; i < length ; i++){ + + BatchData batchData = BatchData.newBuilder() + .setData(ByteString.copyFrom(randomByteArray(i))) + .build(); + + completeBatch.appendBatchData(batchData); + + } + + completeBatch.setTimestamp(Timestamp.newBuilder() + .setSeconds(Math.abs(90)) + .setNanos(50) + .build()); + + signers[signer].updateContent(completeBatch); + + completeBatch.setSignature(signers[signer].sign()); + + return completeBatch; + + } + + // Test methods + + /** + * Takes care of initializing the client and the test resources + */ + public void init(){ + + random = new Random(0); // We use insecure randomness in tests for repeatability + + postCallback = new PostCallback(); + redundancyCallback = new RedundancyCallback((float) 1.0); + + thrown = new Vector<>(); + jobSemaphore = new Semaphore(0); + + } + + /** + * Closes the client and makes sure the test fails when an exception occurred in a separate thread + */ + + public void close() { + + if (thrown.size() > 0) { + assert false; + } + + } + + /** + * Tests the standard post, redundancy and read methods + */ + public void postTest() { + + byte[] b1 = {(byte) 1, (byte) 2, (byte) 3, (byte) 4}; + byte[] b2 = {(byte) 11, (byte) 12, (byte) 13, (byte) 14}; + byte[] b3 = {(byte) 21, (byte) 22, (byte) 23, (byte) 24}; + + BulletinBoardMessage msg; + + MessageFilterList filterList; + List msgList; + + MessageID messageID; + + msg = BulletinBoardMessage.newBuilder() + .setMsg(UnsignedBulletinBoardMessage.newBuilder() + .addTag("Signature") + .addTag("Trustee") + .setData(ByteString.copyFrom(b1)) + .setTimestamp(Timestamp.newBuilder() + .setSeconds(20) + .setNanos(30) + .build()) + .build()) + .addSig(Crypto.Signature.newBuilder() + .setType(Crypto.SignatureType.DSA) + .setData(ByteString.copyFrom(b2)) + .setSignerId(ByteString.copyFrom(b3)) + .build()) + .addSig(Crypto.Signature.newBuilder() + .setType(Crypto.SignatureType.ECDSA) + .setData(ByteString.copyFrom(b3)) + .setSignerId(ByteString.copyFrom(b2)) + .build()) + .build(); + + messageID = bulletinBoardClient.postMessage(msg,postCallback); + + try { + jobSemaphore.acquire(); + } catch (InterruptedException e) { + System.err.println(e.getCause() + " " + e.getMessage()); + } + + bulletinBoardClient.getRedundancy(messageID,redundancyCallback); + + filterList = MessageFilterList.newBuilder() + .addFilter( + MessageFilter.newBuilder() + .setType(FilterType.TAG) + .setTag("Signature") + .build() + ) + .addFilter( + MessageFilter.newBuilder() + .setType(FilterType.TAG) + .setTag("Trustee") + .build() + ) + .build(); + + msgList = new LinkedList<>(); + msgList.add(msg); + + readCallback = new ReadCallback(msgList); + + bulletinBoardClient.readMessages(filterList, readCallback); + try { + jobSemaphore.acquire(2); + } catch (InterruptedException e) { + System.err.println(e.getCause() + " " + e.getMessage()); + } + + } + + /** + * Tests posting a batch by parts + * Also tests not being able to post to a closed batch + * @throws CommunicationException, SignatureException, InterruptedException + */ + public void testBatchPost() throws CommunicationException, SignatureException, InterruptedException { + + final int SIGNER = 1; + final int BATCH_ID = 100; + final int BATCH_LENGTH = 100; + + CompleteBatch completeBatch = createRandomBatch(SIGNER, BATCH_ID, BATCH_LENGTH); + + // Begin batch + + bulletinBoardClient.beginBatch(completeBatch.getBeginBatchMessage(), postCallback); + + jobSemaphore.acquire(); + + // Post data + + bulletinBoardClient.postBatchData(signerIDs[SIGNER], BATCH_ID, completeBatch.getBatchDataList(), postCallback); + + jobSemaphore.acquire(); + + // Close batch + + CloseBatchMessage closeBatchMessage = completeBatch.getCloseBatchMessage(); + + bulletinBoardClient.closeBatch(closeBatchMessage, postCallback); + + jobSemaphore.acquire(); + + // Attempt to open batch again + + bulletinBoardClient.beginBatch(completeBatch.getBeginBatchMessage(), failPostCallback); + + // Attempt to add batch data + + bulletinBoardClient.postBatchData(signerIDs[SIGNER], BATCH_ID, completeBatch.getBatchDataList(), failPostCallback); + + jobSemaphore.acquire(2); + + // Read batch data + + BatchSpecificationMessage batchSpecificationMessage = + BatchSpecificationMessage.newBuilder() + .setSignerId(signerIDs[SIGNER]) + .setBatchId(BATCH_ID) + .setStartPosition(0) + .build(); + + readBatchCallback = new ReadBatchCallback(completeBatch); + + bulletinBoardClient.readBatch(batchSpecificationMessage, readBatchCallback); + + jobSemaphore.acquire(); + + } + + /** + * Posts a complete batch message + * Checks reading of the message + * @throws CommunicationException, SignatureException, InterruptedException + */ + public void testCompleteBatchPost() throws CommunicationException, SignatureException, InterruptedException { + + final int SIGNER = 0; + final int BATCH_ID = 101; + final int BATCH_LENGTH = 50; + + // Post batch + + CompleteBatch completeBatch = createRandomBatch(SIGNER, BATCH_ID, BATCH_LENGTH); + + bulletinBoardClient.postBatch(completeBatch,postCallback); + + jobSemaphore.acquire(); + + // Read batch + + BatchSpecificationMessage batchSpecificationMessage = + BatchSpecificationMessage.newBuilder() + .setSignerId(signerIDs[SIGNER]) + .setBatchId(BATCH_ID) + .setStartPosition(0) + .build(); + + readBatchCallback = new ReadBatchCallback(completeBatch); + + bulletinBoardClient.readBatch(batchSpecificationMessage, readBatchCallback); + + jobSemaphore.acquire(); + + } + + /** + * Tests that an unopened batch cannot be closed + * @throws CommunicationException, InterruptedException + */ + public void testInvalidBatchClose() throws CommunicationException, InterruptedException { + + final int NON_EXISTENT_BATCH_ID = 999; + + CloseBatchMessage closeBatchMessage = + CloseBatchMessage.newBuilder() + .setBatchId(NON_EXISTENT_BATCH_ID) + .setBatchLength(1) + .setSig(Crypto.Signature.getDefaultInstance()) + .setTimestamp(Timestamp.newBuilder() + .setSeconds(9) + .setNanos(12) + .build()) + .build(); + + // Try to close the (unopened) batch; + + bulletinBoardClient.closeBatch(closeBatchMessage, failPostCallback); + + jobSemaphore.acquire(); + + } + +} diff --git a/bulletin-board-client/src/test/java/meerkat/bulletinboard/ThreadedBulletinBoardClientIntegrationTest.java b/bulletin-board-client/src/test/java/meerkat/bulletinboard/ThreadedBulletinBoardClientIntegrationTest.java new file mode 100644 index 0000000..b69cf72 --- /dev/null +++ b/bulletin-board-client/src/test/java/meerkat/bulletinboard/ThreadedBulletinBoardClientIntegrationTest.java @@ -0,0 +1,95 @@ +package meerkat.bulletinboard; + +import meerkat.comm.CommunicationException; + +import meerkat.protobuf.Voting.*; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.security.SignatureException; +import java.util.LinkedList; +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 05-Dec-15. + */ +public class ThreadedBulletinBoardClientIntegrationTest { + + // Server data + + private static String PROP_GETTY_URL = "gretty.httpBaseURI"; + private static String DEFAULT_BASE_URL = "http://localhost:8081"; + private static String BASE_URL = System.getProperty(PROP_GETTY_URL, DEFAULT_BASE_URL); + + // Tester + private GenericBulletinBoardClientTester clientTest; + + public ThreadedBulletinBoardClientIntegrationTest(){ + + ThreadedBulletinBoardClient client = new ThreadedBulletinBoardClient(); + + List testDB = new LinkedList<>(); + testDB.add(BASE_URL); + + client.init(BulletinBoardClientParams.newBuilder() + .addAllBulletinBoardAddress(testDB) + .setMinRedundancy((float) 1.0) + .build()); + + clientTest = new GenericBulletinBoardClientTester(client); + + } + + // Test methods + + /** + * Takes care of initializing the client and the test resources + */ + @Before + public void init(){ + + clientTest.init(); + + } + + /** + * Closes the client and makes sure the test fails when an exception occurred in a separate thread + */ + + @After + public void close() { + + clientTest.close(); + + } + + @Test + public void postTest() { + + clientTest.postTest(); + + } + + @Test + public void testBatchPost() throws CommunicationException, SignatureException, InterruptedException { + + clientTest.testBatchPost(); + } + + @Test + public void testCompleteBatchPost() throws CommunicationException, SignatureException, InterruptedException { + + clientTest.testCompleteBatchPost(); + + } + + @Test + public void testInvalidBatchClose() throws CommunicationException, InterruptedException { + + clientTest.testInvalidBatchClose(); + + } + +} From 5670739e494d78a2de14ff80bba8e5a6b9bbe899 Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Wed, 30 Mar 2016 12:44:04 +0300 Subject: [PATCH 31/49] tested version --- .../src/main/java/Arithmetics/Fp.java | 27 +-- .../java/Communication/MessageHandler.java | 2 +- .../src/main/java/Communication/Network.java | 2 +- .../VerifiableSecretSharing.java | 5 +- .../DistributedKeyGeneration.java | 70 +++--- .../DistributedKeyGenerationParty.java | 9 +- .../DistributedKeyGenerationUserImpl.java | 221 +++++++++++------- .../SecureDistributedKeyGeneration.java | 78 ++++--- ...reDistributedKeyGenerationMailHandler.java | 2 +- .../SecureDistributedKeyGenerationParty.java | 8 +- ...ecureDistributedKeyGenerationUserImpl.java | 142 +++++++---- .../LagrangePolynomial.java | 18 +- .../java/ShamirSecretSharing/Polynomial.java | 27 +-- .../ShamirSecretSharing/SecretSharing.java | 4 +- .../JointFeldmanProtocol/DKGDeepTest.java | 174 -------------- .../DKGMaliciousUserImpl.java | 36 +-- .../java/JointFeldmanProtocol/DKGTest.java | 193 +++++++++------ .../SDKGMaliciousUserImpl.java | 64 +++++ .../SDKGTest.java | 191 +++++++++------ .../SDKGUserImplAbort.java | 11 +- .../PolynomialTests/AddTest.java | 6 +- .../PolynomialTests/InterpolationTest.java | 7 +- .../PolynomialTests/MulByConstTest.java | 4 +- .../PolynomialTests/MulTest.java | 6 +- .../SecretSharingTest.java | 3 +- .../GenerateRandomPolynomial.java} | 11 +- .../test/java/Utils/GenerateRandomPrime.java | 32 +++ 27 files changed, 745 insertions(+), 608 deletions(-) delete mode 100644 destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGDeepTest.java create mode 100644 destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGMaliciousUserImpl.java rename destributed-key-generation/src/test/java/{ShamirSecretSharing/PolynomialTests/Utils.java => Utils/GenerateRandomPolynomial.java} (75%) create mode 100644 destributed-key-generation/src/test/java/Utils/GenerateRandomPrime.java diff --git a/destributed-key-generation/src/main/java/Arithmetics/Fp.java b/destributed-key-generation/src/main/java/Arithmetics/Fp.java index 545dd8b..db2d6da 100644 --- a/destributed-key-generation/src/main/java/Arithmetics/Fp.java +++ b/destributed-key-generation/src/main/java/Arithmetics/Fp.java @@ -1,5 +1,7 @@ package Arithmetics; +import org.factcenter.qilin.primitives.concrete.Zpstar; + import java.math.BigInteger; /** @@ -7,9 +9,11 @@ import java.math.BigInteger; */ public class Fp implements Arithmetic { public final BigInteger p; + private final Zpstar zp; public Fp(BigInteger p) { this.p = p; + this.zp = new Zpstar(p); } @Override @@ -24,30 +28,11 @@ public class Fp implements Arithmetic { @Override public BigInteger mul(BigInteger a,BigInteger b){ - return a.multiply(b).mod(p); + return zp.add(a,b); } @Override public BigInteger div(BigInteger a,BigInteger b){ - return mul(a,inv(b)); - } - - public BigInteger pow(BigInteger b,BigInteger e){ - if (e.compareTo(BigInteger.ZERO) < 0 ) { - return pow(inv(b), e.negate()); - } - BigInteger result = BigInteger.ONE; - while (e.compareTo(BigInteger.ZERO) > 0) { - if (e.testBit(0)) { - result = mul(result, b); - } - e = e.shiftRight(1); - b = mul(b, b); - } - return result; - } - - public BigInteger inv(BigInteger a){ - return pow(a,p.subtract(BigInteger.valueOf(2))); + return mul(a,zp.negate(b)); } } diff --git a/destributed-key-generation/src/main/java/Communication/MessageHandler.java b/destributed-key-generation/src/main/java/Communication/MessageHandler.java index 2d68be4..8cedf4e 100644 --- a/destributed-key-generation/src/main/java/Communication/MessageHandler.java +++ b/destributed-key-generation/src/main/java/Communication/MessageHandler.java @@ -9,7 +9,7 @@ public interface MessageHandler { void handelSecretMessage(int sender, boolean isBroadcast, Message message); void handelCommitmentMessage(int sender, boolean isBroadcast, Message message); void handelComplaintMessage(int sender, boolean isBroadcast, Message message); - void handelDoneMessage(int sender, boolean isBroadcast, Message message); //will be remove + void handelDoneMessage(int sender, boolean isBroadcast, Message message); void handelAnswerMessage(int sender, boolean isBroadcast, Message message); void handelAbortMessage(int sender, boolean isBroadcast, Message message); } diff --git a/destributed-key-generation/src/main/java/Communication/Network.java b/destributed-key-generation/src/main/java/Communication/Network.java index ca53991..541179e 100644 --- a/destributed-key-generation/src/main/java/Communication/Network.java +++ b/destributed-key-generation/src/main/java/Communication/Network.java @@ -10,7 +10,7 @@ import java.util.Set; import java.util.concurrent.ArrayBlockingQueue; /** * Created by Tzlil on 2/7/2016. - * JointFeldamn protocol assumes all parties can communicate throw broadcast chanel + * Joint Feldamn protocol assumes all parties can communicate throw broadcast chanel * and private chanel (for each pair) * this class simulates it */ diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java index 521714d..4573c57 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java @@ -3,11 +3,8 @@ package FeldmanVerifiableSecretSharing; import ShamirSecretSharing.Polynomial; import ShamirSecretSharing.SecretSharing; -import java.util.Arrays; - import org.factcenter.qilin.primitives.Group; -import org.factcenter.qilin.primitives.concrete.Zpstar; - +import java.util.Arrays; import java.math.BigInteger; import java.util.Random; diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java index 99feec6..d9ae852 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java @@ -17,7 +17,7 @@ import java.util.Set; * Created by Tzlil on 3/14/2016. */ public class DistributedKeyGeneration extends VerifiableSecretSharing { - public enum ComplainState{ + public enum ComplaintState { Non, Waiting,Disqualified,NonDisqualified } protected final int id; @@ -32,6 +32,7 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing { for (int i = 1; i <= n ; i++){ this.parties[i - 1] = new DistributedKeyGenerationParty(i,n,t); } + this.parties[id - 1].share = getShare(id); } protected void setParties(DistributedKeyGenerationParty[] parties){ @@ -87,9 +88,21 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing { return isValidSecret(party.share,party.commitments,id); } + /** + * + * @param secret + * @param commitments + * @param j + * @return verify(j,commitments,group) == g ^ secret.y mod q + */ public boolean isValidSecret(Polynomial.Point secret, BigInteger[] commitments, int j){ - BigInteger v = verify(j,commitments,group); - return group.multiply(g,secret.y).equals(v); + try{ + BigInteger v = verify(j,commitments,group); + return group.multiply(g,secret.y).equals(v); + } + catch (NullPointerException e){ + return false; + } } /** @@ -97,27 +110,22 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing { * Pj verifies all the shares he received (using isValidSecret) * if check fails for an index i, Pj broadcasts a complaint against Pi. */ - public void broadcastComplains(User user){ - DKGMessages.IDMessage complaint; + public void broadcastComplaints(User user){ for (int i = 1; i <= n ; i++ ){ - if(i != id && !parties[i - 1].aborted) { - sendComplain(user,i); + if(i != id && !isValidSecret(i)) { + broadcastComplaint(user,i); } } } - protected void sendComplain(User user,int i){ - DKGMessages.IDMessage complaint; - if (!isValidSecret(i)) { - //message = new Message(Type.Complaint, j) - complaint = DKGMessages.IDMessage.newBuilder() - .setId(i) - .build(); - user.broadcast(DKGMessages.Mail.Type.COMPLAINT, complaint); - } + 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); } - public void broadcastComplaintAnswer(User user, int j){ user.broadcast(DKGMessages.Mail.Type.ANSWER, DKGMessages.SecretMessage.newBuilder() .setI(id) @@ -131,9 +139,9 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing { * if more than t players complain against a player Pi he is disqualified. */ public void answerAllComplainingPlayers(User user){ - ComplainState[] complains = parties[id - 1].complaints; + ComplaintState[] complaints = parties[id - 1].complaints; for (int i = 1; i <= n ; i++) { - switch (complains[i - 1]) { + switch (complaints[i - 1]) { case Waiting: broadcastComplaintAnswer(user,i); break; @@ -143,20 +151,6 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing { } } - protected boolean isPartyCompletedStage1(int i){ - if(parties[i - 1].aborted){ - if(parties[i - 1].share == null){ - return false; - } - for (int k = 0; k <= t ; k++){ - if(parties[i - 1].commitments[k] == null){ - return false; - } - } - } - return true; - } - /** * stage3.2 according to the protocol * if any of the revealed shares fails the verification test, player Pi is disqualified. @@ -167,11 +161,11 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing { boolean nonDisqualified; int counter; for (int i = 1; i <= n; i++){ - ComplainState[] complains = parties[i - 1].complaints; + ComplaintState[] complaints = parties[i - 1].complaints; nonDisqualified = true; counter = 0; for (int j = 1; j <= n; j++){ - switch (complains[j - 1]) { + switch (complaints[j - 1]) { case Non: break; case NonDisqualified: @@ -182,7 +176,7 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing { if(!nonDisqualified) break; } - if(nonDisqualified && counter <= t && isPartyCompletedStage1(i)){ + if(nonDisqualified && counter <= t){ QUAL.add(i); } } @@ -228,6 +222,10 @@ public class DistributedKeyGeneration extends VerifiableSecretSharing { return new Polynomial.Point(BigInteger.valueOf(id) , xj.mod(q)); } + /** + * getter + * @return id + */ public int getId() { return id; } diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationParty.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationParty.java index 617ea08..878ab66 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationParty.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationParty.java @@ -7,21 +7,24 @@ import java.util.Arrays; /** * Created by Tzlil on 3/14/2016. + * + * contains all relevant information on specific party during + * the run of Joint Feldamn protocol */ public class DistributedKeyGenerationParty { public final int id; public Polynomial.Point share; public BigInteger[] commitments; public boolean doneFlag; - public DistributedKeyGeneration.ComplainState[] complaints; + public DistributedKeyGeneration.ComplaintState[] complaints; public boolean aborted; public DistributedKeyGenerationParty(int id, int n, int t) { this.id = id; this.share = null; this.doneFlag = false; - this.complaints = new DistributedKeyGeneration.ComplainState[n]; - Arrays.fill(this.complaints, DistributedKeyGeneration.ComplainState.Non); + this.complaints = new DistributedKeyGeneration.ComplaintState[n]; + Arrays.fill(this.complaints, DistributedKeyGeneration.ComplaintState.Non); this.commitments = new BigInteger[t + 1]; this.aborted = false; } diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java index 578b1e5..6287526 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java @@ -13,13 +13,15 @@ import org.factcenter.qilin.primitives.Group; import java.math.BigInteger; import java.util.Arrays; import java.util.Set; -import JointFeldmanProtocol.DistributedKeyGeneration.ComplainState; +import JointFeldmanProtocol.DistributedKeyGeneration.ComplaintState; /** * Created by Tzlil on 3/14/2016. */ public class DistributedKeyGenerationUserImpl implements DistributedKeyGenerationUser { + protected final static int SleepTime = 300; + protected final DistributedKeyGeneration dkg; protected final BigInteger g; @@ -52,9 +54,6 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio mailHandler.setMessageHandler(this.messageHandler); this.user = network.connect(mailHandler,dkg.getId()); this.parties = dkg.getParties(); - - this.parties[id - 1].share = dkg.getShare(id); - this.QUAL = null; this.commitments = null; this.share = null; @@ -71,6 +70,31 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio dkg.sendSecrets(user); } + protected void waitUntilStageOneCompleted(){ + // all parties send their share or aborted + for (int i = 0 ; i < n ; i++){ + while (parties[i].share == null && !parties[i].aborted){ + try { + Thread.sleep(SleepTime); + } 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 { + Thread.sleep(SleepTime); + } catch (InterruptedException e) { + // do nothing + } + } + } + } + } + /** * stage2 according to the protocol * Pj verifies all the shares he received @@ -78,18 +102,26 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio * Pj broadcasts done message at the end of this stage */ protected void stage2(){ - Polynomial.Point[] shares = new Polynomial.Point[n]; - BigInteger[][] commitmentsTable = new BigInteger[n][]; - for (int i = 0 ; i < n ; i++){ - shares[i] = parties[i].share; - commitmentsTable[i] = parties[i].commitments; - } - dkg.broadcastComplains(user); + dkg.broadcastComplaints(user); //broadcast done message after all complaints DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build(); user.broadcast(DKGMessages.Mail.Type.DONE,doneMessage); } + + protected void waitUntilStageTwoCompleted(){ + // all parties done or aborted + for (int i = 0 ; i < n ; i++){ + while (!parties[i].doneFlag && !parties[i].aborted){ + try { + Thread.sleep(SleepTime); + } catch (InterruptedException e) { + // do nothing + } + } + } + } + /** * stage3 according to the protocol * 1. if more than t players complain against a player Pi he is disqualified. @@ -99,13 +131,12 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio */ protected void stage3(){ dkg.answerAllComplainingPlayers(user); - // wait until there is no complaint waiting for answer for (int i = 0; i < n; i++){ for (int j = 0; j < n; j++){ - while (parties[i].complaints[j].equals(ComplainState.Waiting) && !parties[i].aborted){ + while (parties[i].complaints[j].equals(ComplaintState.Waiting) && !parties[i].aborted){ try { - Thread.sleep(300); + Thread.sleep(SleepTime); } catch (InterruptedException e) { // do nothing } @@ -127,49 +158,23 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio this.share = dkg.calcShare(QUAL); } - protected void endOfStage1(){ - for (int i = 0 ; i < n ; i++){ - while (parties[i].share == null && !parties[i].aborted){ - try { - Thread.sleep(300); - } catch (InterruptedException e) { - // do nothing - } - } - } - - for (int i = 0 ; i < n ; i++){ - for (int k = 0 ; k <= t ; k++) { - while (parties[i].commitments[k] == null && !parties[i].aborted) { - try { - Thread.sleep(300); - } catch (InterruptedException e) { - // do nothing - } - } - } - } + protected void startReceiver(){ + user.getReceiverThread().start(); + } + protected void stopReceiver(){ + user.getReceiverThread().interrupt(); } @Override public void run() { - user.getReceiverThread().start(); + startReceiver(); stage1(); - endOfStage1(); + waitUntilStageOneCompleted(); stage2(); - for (int i = 0 ; i < n ; i++){ - while (!parties[i].doneFlag && !parties[i].aborted){ - try { - Thread.sleep(300); - } catch (InterruptedException e) { - // do nothing - } - } - } - + waitUntilStageTwoCompleted(); stage3(); stage4(); - user.getReceiverThread().interrupt(); + stopReceiver(); } @Override @@ -217,40 +222,23 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio return QUAL; } + protected class MessageHandler implements Communication.MessageHandler{ - protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, DKGMessages.IDMessage complaintMessage){ - int i = sender; - int j = complaintMessage.getId(); - return isBroadcast && parties[i - 1].complaints[j - 1].equals( ComplainState.Non); - } - - @Override - public void handelComplaintMessage(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] = ComplainState.Waiting; - } - } - - protected boolean isValidDoneMessage(int sender, boolean isBroadcast){ - return isBroadcast && !parties[sender - 1].doneFlag; - } - - @Override - public void handelDoneMessage(int sender, boolean isBroadcast,Message message) { - if(isValidDoneMessage(sender,isBroadcast)) { - parties[sender - 1].doneFlag = true; - } - } + /** + * commitment message is valid if: + * 1. it was received in broadcast chanel + * 2. the sender didn't sent this commitment before + */ protected boolean isValidCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage){ int i = sender - 1; int k = commitmentMessage.getK(); return isBroadcast && parties[i].commitments[k] == null; } + /** + * saves the commitment + */ @Override public void handelCommitmentMessage(int sender, boolean isBroadcast, Message message) { DKGMessages.CommitmentMessage commitmentMessage = (DKGMessages.CommitmentMessage) message; @@ -261,6 +249,13 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio } } + /** + * 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 + * 4. secret.j == id + */ protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage){ int i = secretMessage.getI(); int j = secretMessage.getJ(); @@ -271,6 +266,9 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio } + /** + * saves the secret + */ @Override public void handelSecretMessage(int sender, boolean isBroadcast, Message message) { DKGMessages.SecretMessage secretMessage = (DKGMessages.SecretMessage) message; @@ -281,15 +279,70 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio } } + /** + * 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; + } + + /** + * marks that the sender was finished sending all his complaints + */ + @Override + public void handelDoneMessage(int sender, boolean isBroadcast,Message message) { + if(isValidDoneMessage(sender,isBroadcast)) { + parties[sender - 1].doneFlag = true; + } + } + + /** + * complaint message is valid if: + * 1. it was received in broadcast chanel + * 2. the sender didn't complained against id before + */ + protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, DKGMessages.IDMessage complaintMessage){ + int i = sender; + int j = complaintMessage.getId(); + return isBroadcast && parties[i - 1].complaints[j - 1].equals( ComplaintState.Non); + } + + /** + * marks that the sender was complained against id + */ + @Override + public void handelComplaintMessage(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; + } + } + + /** + * answer message is valid if: + * 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 + */ protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage){ int i = secretMessage.getI(); int j = secretMessage.getJ(); if(sender != i || !isBroadcast) return false; else - return j >= 1 && j <= n && parties[i - 1].complaints[j - 1].equals(ComplainState.Waiting); + 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 handelAnswerMessage(int sender, boolean isBroadcast, Message message) { DKGMessages.SecretMessage secretMessage = (DKGMessages.SecretMessage) message; @@ -297,13 +350,20 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio int i = secretMessage.getI(); 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] = ComplainState.NonDisqualified; - else - parties[i - 1].complaints[j - 1] = ComplainState.Disqualified; + if (dkg.isValidSecret(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; + } } } + /** + * marks that the sender was aborted + */ @Override public void handelAbortMessage(int sender, boolean isBroadcast, Message message) { parties[sender - 1].aborted = true; @@ -314,6 +374,7 @@ public class DistributedKeyGenerationUserImpl implements DistributedKeyGeneratio BigInteger y = new BigInteger(secret.toByteArray()); return new Polynomial.Point(x,y); } + public BigInteger extractCommitment(DKGMessages.CommitmentMessage commitmentMessage){ return new BigInteger(commitmentMessage.getCommitment().toByteArray()); } diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGeneration.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGeneration.java index 4a05125..92c29f3 100644 --- a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGeneration.java +++ b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGeneration.java @@ -10,6 +10,7 @@ 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. @@ -30,28 +31,21 @@ public class SecureDistributedKeyGeneration extends DistributedKeyGeneration { for (int i = 1; i <= n ; i++){ this.parties[i - 1] = new SecureDistributedKeyGenerationParty(i,n,t); } - setParties(parties); + this.parties[id - 1].share = getShare(id); + this.parties[id - 1].shareT = verifiableSecretSharing.getShare(id); + super.setParties(parties); } protected SecureDistributedKeyGenerationParty[] getParties(){ return parties; } - @Override - protected boolean isPartyCompletedStage1(int i){ - if(parties[i - 1].aborted){ - if(parties[i - 1].share == null){ - return false; - } - for (int k = 0; k <= t ; k++){ - if(parties[i - 1].verifiableValues[k] == null){ - return false; - } - } - } - return true; + protected void setParties(SecureDistributedKeyGenerationParty[] parties) { + super.setParties(parties); + this.parties = parties; } + @Override public void sendSecret(User user, int j) { Polynomial.Point secret = getShare(j); @@ -60,49 +54,52 @@ public class SecureDistributedKeyGeneration extends DistributedKeyGeneration { user.send(j, DKGMessages.Mail.Type.SECRET, doubleSecretMessage); } + @Override public boolean isValidSecret(int i){ SecureDistributedKeyGenerationParty party = parties[i - 1]; - return isValidSecret(party.share,party.shareT,party.verifiableValues, id); + return isValidSecret(party.share, party.shareT, party.verifiableValues, id); } + /** + * @param secret + * @param secretT + * @param verificationValues + * @param j + * @return verify(j,verificationValues,group) == (g ^ secret.y) * (h ^ secretT.y) mod q + */ public boolean isValidSecret(Polynomial.Point secret,Polynomial.Point secretT, BigInteger[] verificationValues, int j){ - BigInteger v = verify(j,verificationValues,group); - BigInteger exp = group.add(group.multiply(g, secret.y),group.multiply(h, secretT.y)); - return exp.equals(v); + try { + BigInteger v = verify(j, verificationValues, group); + BigInteger exp = group.add(group.multiply(g, secret.y), group.multiply(h, secretT.y)); + return exp.equals(v); + } + catch (NullPointerException e){ + return false; + } } - public void broadcastComplaint(User user,Polynomial.Point secret,Polynomial.Point secretT,int i){ + private void broadcastComplaint(User user,Polynomial.Point secret,Polynomial.Point secretT,int i){ DKGMessages.DoubleSecretMessage complaint = doubleSecretMessage(i,id,secret,secretT); user.broadcast(DKGMessages.Mail.Type.COMPLAINT,complaint); } - public void broadcastAnswer(User user,Polynomial.Point secret,Polynomial.Point secretT,int i){ - DKGMessages.DoubleSecretMessage complaint = doubleSecretMessage(i,id,secret,secretT); - user.broadcast(DKGMessages.Mail.Type.ANSWER,complaint); - } - /** * stage4.3 according to the protocol * if check fails for index i, Pj */ - public void broadcastComplaints(User user, boolean stage4){ - if(!stage4){ - super.broadcastComplains(user); - }else{ - SecureDistributedKeyGenerationParty party; - for (int i = 1; i <= n ; i++ ){ - party = parties[i - 1]; - if(i != id && !party.aborted) { - if (!super.isValidSecret(party.share,party.commitments,id)) { - broadcastComplaint(user,party.share,party.shareT,i); - } + public void broadcastComplaints(User user, Set 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 = verifiableSecretSharing.getCommitmentsArray(); @@ -128,4 +125,13 @@ public class SecureDistributedKeyGeneration extends DistributedKeyGeneration { ,verifiableSecretSharing.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 = doubleSecretMessage(i,id,secret,secretT); + user.broadcast(DKGMessages.Mail.Type.ANSWER,complaint); + } + + public BigInteger getH() { + return h; + } } diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationMailHandler.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationMailHandler.java index bad5d07..9b4752e 100644 --- a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationMailHandler.java +++ b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationMailHandler.java @@ -30,7 +30,7 @@ public class SecureDistributedKeyGenerationMailHandler extends MailHandler { message = DKGMessages.CommitmentMessage.parseFrom(mail.getMessage()); break; case COMPLAINT: - if(isStage4) + if(!isStage4) message = DKGMessages.IDMessage.parseFrom(mail.getMessage()); else message = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage()); diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationParty.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationParty.java index 3d933a9..ea36136 100644 --- a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationParty.java +++ b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationParty.java @@ -9,16 +9,20 @@ 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 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(); } diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationUserImpl.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationUserImpl.java index 778a5d2..66751eb 100644 --- a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationUserImpl.java +++ b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationUserImpl.java @@ -17,9 +17,10 @@ import java.math.BigInteger; */ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenerationUserImpl { - private final SecureDistributedKeyGeneration sdkg; - private SecureDistributedKeyGenerationParty[] parties; + protected SecureDistributedKeyGenerationParty[] parties; + protected final SecureDistributedKeyGeneration sdkg; private Arithmetic arithmetic; + private boolean isStage4; public SecureDistributedKeyGenerationUserImpl(SecureDistributedKeyGeneration sdkg, Network network) { super(sdkg, network,new SecureDistributedKeyGenerationMailHandler(null)); @@ -28,6 +29,7 @@ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenera this.user.setMessageHandler(this.messageHandler); this.parties = sdkg.getParties(); this.arithmetic = new Fp(sdkg.getQ()); + this.isStage4 = false; } /** @@ -42,8 +44,9 @@ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenera } @Override - protected void endOfStage1(){ - super.endOfStage1(); + protected void waitUntilStageOneCompleted(){ + super.waitUntilStageOneCompleted(); + // save the received commitments as verification values BigInteger[] temp; for (int i = 0 ; i < n; i++){ temp = parties[i].verifiableValues; @@ -60,54 +63,54 @@ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenera */ @Override protected void stage2(){ - sdkg.broadcastComplains(user); + sdkg.broadcastComplaints(user); //broadcast done message after all complaints DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build(); - isVerificationValue = false; user.broadcast(DKGMessages.Mail.Type.DONE,doneMessage); } private void ys(){ sdkg.broadcastCommitments(user); - //wait for receive all commitments from all i in QUAL + // wait until all parties in QUAL broadcast their commitments or aborted for (int i:QUAL) { for(int k = 0; k <= t; k++) { while (parties[i - 1].commitments[k] == null && !parties[i - 1].aborted) { try { - Thread.sleep(300); + Thread.sleep(SleepTime); } catch (InterruptedException e) { // do nothing } } } } - sdkg.broadcastComplaints(user,true); + sdkg.broadcastComplaints(user,QUAL); //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) { - while (parties[i - 1].doneFlag && !parties[i - 1].aborted) { + while (!parties[i - 1].ysDoneFlag && !parties[i - 1].aborted) { try { - Thread.sleep(300); + Thread.sleep(SleepTime); } catch (InterruptedException e) { // do nothing } } } - int counter = 0; + // broadcast i private secret foreach i in QUAL that aborted for (int i:QUAL) { if(parties[i - 1].aborted){ - counter++; 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){ - while (parties[i - 1].restoreSharesSet.size() < n - counter) { + while (parties[i - 1].restoreSharesSet.size() <= t) { try { - Thread.sleep(300); + Thread.sleep(SleepTime); } catch (InterruptedException e) { // do nothing } @@ -115,37 +118,50 @@ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenera } } + // restore necessary information for (int i = 0; i < n ; i++) { if(parties[i].restoreSharesSet.isEmpty()){ continue; } - try { - Polynomial.Point[] shares = new Polynomial.Point[parties[i].restoreSharesSet.size()]; - parties[i].restoreSharesSet.toArray(shares); - Polynomial polynomial = SecretSharing.restorePolynomial(shares,arithmetic); - BigInteger[] coefficients = polynomial.getCoefficients(); - for (int k = 0 ; k <= t; k++){ - parties[i].commitments[k] = group.multiply(g,coefficients[k]); + 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; } - parties[i].share = new Polynomial.Point(BigInteger.valueOf(id),polynomial); - - } catch (Exception e) { - // } + Polynomial polynomial = SecretSharing.restorePolynomial(shares,arithmetic); + BigInteger[] coefficients = polynomial.getCoefficients(); + for (int k = 0 ; k <= t; k++){ + parties[i].commitments[k] = group.multiply(g,coefficients[k]); + } + parties[i].share = new Polynomial.Point(BigInteger.valueOf(id),polynomial); } } + /** + * notifies mail handler that stage 4 was started + */ + protected void setStage4(){ + this.isStage4 = true; + SecureDistributedKeyGenerationMailHandler handler = + (SecureDistributedKeyGenerationMailHandler)user.getMailHandler(); + handler.setStage4(true); + } + @Override protected void stage4() { - isStage4 = true; - ((SecureDistributedKeyGenerationMailHandler)user.getMailHandler()).setStage4(true); + setStage4(); ys(); super.stage4(); } - boolean isStage4 = false; - boolean isVerificationValue = true; + private class MessageHandler extends DistributedKeyGenerationUserImpl.MessageHandler{ + /** + * as in super, with extension to double secret message + */ protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { DKGMessages.SecretMessage secretMessage = DKGMessages.SecretMessage.newBuilder() .setI(doubleSecretMessage.getI()) @@ -155,16 +171,26 @@ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenera return super.isValidSecretMessage(sender,isBroadcast,secretMessage); } + /** + * as in super, with extension to double secret message + */ @Override public void handelSecretMessage(int sender, boolean isBroadcast, Message message) { DKGMessages.DoubleSecretMessage doubleSecretMessage = (DKGMessages.DoubleSecretMessage)message; 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()); } } + + /** + * if !isStage4 as super, with extension to double secret message + * else answer message is valid if: + * 1. it was received in broadcast chanel + * 2. secret.j == sender + * 3. QUAL contains i and j + */ protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { if(!isStage4) { DKGMessages.SecretMessage secretMessage = DKGMessages.SecretMessage.newBuilder() @@ -176,10 +202,15 @@ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenera }else{ int i = doubleSecretMessage.getI(); int j = doubleSecretMessage.getJ(); - return isBroadcast && j == sender && QUAL.contains(i) && QUAL.contains(j); + return isBroadcast && j == sender && parties[i -1].aborted && !parties[j - 1].aborted + && QUAL.contains(i) && QUAL.contains(j); } } + /** + * if !isStage4 as super, with extension to double secret message + * else saves secret + */ @Override public void handelAnswerMessage(int sender, boolean isBroadcast, Message message) { DKGMessages.DoubleSecretMessage doubleSecretMessage = (DKGMessages.DoubleSecretMessage)message; @@ -190,9 +221,14 @@ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenera Polynomial.Point secretT = extractSecret(j, doubleSecretMessage.getSecretT()); if (!isStage4) { if (sdkg.isValidSecret(secret, secretT, parties[j - 1].verifiableValues, i)) { - parties[i - 1].complaints[j - 1] = DistributedKeyGeneration.ComplainState.NonDisqualified; + parties[i - 1].complaints[j - 1] = DistributedKeyGeneration.ComplaintState.NonDisqualified; + } else { - parties[i - 1].complaints[j - 1] = DistributedKeyGeneration.ComplainState.Disqualified; + parties[i - 1].complaints[j - 1] = DistributedKeyGeneration.ComplaintState.Disqualified; + } + if(j == id){ + parties[i - 1].share = secret; + parties[i - 1].shareT = secretT; } } else { parties[i - 1].restoreSharesSet.add(secret); @@ -200,35 +236,52 @@ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenera } } + /** + * as in super with respect to protocol stage + */ @Override protected boolean isValidDoneMessage(int sender, boolean isBroadcast) { if(!isStage4) { return super.isValidDoneMessage(sender, isBroadcast); }else{ - return isBroadcast && parties[sender - 1].doneFlag; + return isBroadcast && !parties[sender - 1].ysDoneFlag; } } + /** + * as in super with respect to protocol state + */ @Override public void handelDoneMessage(int sender, boolean isBroadcast, Message message) { if(!isStage4) super.handelDoneMessage(sender, isBroadcast, message); else{ if(isValidDoneMessage(sender,isBroadcast)) { - parties[sender - 1].doneFlag = false; + parties[sender - 1].ysDoneFlag = true; } } } + /** + * use only in stage4 + * complaint message is valid if: + * 1. it was received in broadcast chanel + * 2. secret.j == sender + * 3. QUAL contains i and j + */ protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, - DKGMessages.DoubleSecretMessage ysComplaintMessage){ - int i = ysComplaintMessage.getI(); - int j = ysComplaintMessage.getJ(); + DKGMessages.DoubleSecretMessage complaintMessage){ + int i = complaintMessage.getI(); + int j = complaintMessage.getJ(); 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 + * marks i as aborted + */ @Override public void handelComplaintMessage(int sender, boolean isBroadcast, Message message) { if(!isStage4) { @@ -240,10 +293,9 @@ public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenera int j = ysComplaintMessage.getJ(); Polynomial.Point secret = extractSecret(i,ysComplaintMessage.getSecret()); Polynomial.Point secretT = extractSecret(i,ysComplaintMessage.getSecretT()); - if (sdkg.isValidSecret(secret, secretT, parties[i - 1].commitments, j) - && !sdkg.isValidSecret(secret,parties[i - 1].commitments, j)) { - parties[i - 1].restoreSharesSet.add(secret); - sdkg.broadcastAnswer(user, secret, secretT, i); + if (sdkg.isValidSecret(secret, secretT, parties[i - 1].verifiableValues, j) + && !dkg.isValidSecret(secret,parties[i - 1].commitments, j)) { + parties[i - 1].aborted = true; } } } diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java index d3815ff..6fd93ce 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java @@ -1,5 +1,7 @@ package ShamirSecretSharing; +import Arithmetics.Arithmetic; + import java.math.BigInteger; /** @@ -34,29 +36,29 @@ class LagrangePolynomial{ * static method * @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 - * - * @throws Exception there exists i != j s.t points[i].x == points[j].x + * @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. */ - public static LagrangePolynomial[] lagrangePolynomials(Polynomial.Point[] points) throws Exception { + public static LagrangePolynomial[] lagrangePolynomials(Polynomial.Point[] points,Arithmetic arithmetic) { + Polynomial one = new Polynomial(new BigInteger[]{BigInteger.ONE},arithmetic); LagrangePolynomial[] lagrangePolynomials = new LagrangePolynomial[points.length]; Polynomial[] factors = new Polynomial[points.length]; for (int i = 0 ; i < factors.length ; i++){ - factors[i] = new Polynomial(new BigInteger[]{BigInteger.ZERO.subtract(points[i].x),BigInteger.ONE}); // X - Xi + factors[i] = new Polynomial(new BigInteger[]{points[i].x.negate(),BigInteger.ONE},arithmetic); // X - Xi } Polynomial product; BigInteger divisor; for(int i = 0; i < points.length; i ++) { - product = Polynomial.ONE; + product = one; divisor = BigInteger.ONE; for (int j = 0; j < points.length; j++) { if (i != j) { - divisor = divisor.multiply(points[i].x.subtract(points[j].x)); + divisor = arithmetic.mul(divisor,arithmetic.sub(points[i].x,points[j].x)); product = product.mul(factors[j]); } } if(divisor.equals(BigInteger.ZERO)) - throw new Exception(); + return null; lagrangePolynomials[i] = new LagrangePolynomial(product,points[i].y,divisor); } return lagrangePolynomials; diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java index 119cf61..ac7fc79 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java @@ -1,7 +1,6 @@ package ShamirSecretSharing; import Arithmetics.Arithmetic; -import Arithmetics.Z; import java.math.BigInteger; import java.util.Arrays; @@ -10,7 +9,6 @@ import java.util.Arrays; * Created by Tzlil on 1/27/2016. */ public class Polynomial implements Comparable { - public static final Polynomial ONE = new Polynomial(new BigInteger[]{BigInteger.ONE}); private final int degree; private final BigInteger[] coefficients; private final Arithmetic arithmetic; @@ -18,12 +16,9 @@ public class Polynomial implements Comparable { /** * constructor * @param coefficients + * @param arithmetic * degree set as max index such that coefficients[degree] not equals zero */ - public Polynomial(BigInteger[] coefficients) { - this(coefficients,new Z()); - } - public Polynomial(BigInteger[] coefficients,Arithmetic arithmetic) { int d = coefficients.length - 1; while (d > 0 && coefficients[d].equals(BigInteger.ZERO)){ @@ -34,7 +29,9 @@ public class Polynomial implements Comparable { this.arithmetic = arithmetic; } - + /* + * use for tests + */ @Override public int compareTo(Polynomial other) { if (this.degree != other.degree) @@ -49,15 +46,6 @@ public class Polynomial implements Comparable { return 0; } - @Override - public String toString() { - return "ShamirSecretSharing.PolynomialTests{" + - "degree=" + degree + - ", coefficients=" + java.util.Arrays.toString(coefficients) + - '}'; - } - - /** * @param x * @return sum of coefficients[i] * (x ^ i) @@ -76,8 +64,11 @@ public class Polynomial implements Comparable { * @param points * @return polynomial of minimal degree which goes through all points */ - public static Polynomial interpolation(Point[] points, Arithmetic arithmetic) throws Exception { - LagrangePolynomial[] l = LagrangePolynomial.lagrangePolynomials(points); + public static Polynomial interpolation(Point[] points, Arithmetic arithmetic) { + LagrangePolynomial[] l = LagrangePolynomial.lagrangePolynomials(points,arithmetic); + if (l == null){ + return null; + } // product = product of l[i].divisor BigInteger product = BigInteger.ONE; for (int i = 0; i < l.length;i++){ diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java index 877d272..0f424f9 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java @@ -4,6 +4,7 @@ import Arithmetics.Arithmetic; import Arithmetics.Fp; import java.math.BigInteger; +import java.util.Collection; import java.util.Random; /** @@ -67,13 +68,12 @@ public class SecretSharing{ public static BigInteger restoreSecret(Polynomial.Point[] shares,Arithmetic arithmetic) throws Exception { return restorePolynomial(shares,arithmetic).image(BigInteger.ZERO); } - /** * @param shares - subset of the original shares * * @return interpolation(shares) */ - public static Polynomial restorePolynomial(Polynomial.Point[] shares,Arithmetic arithmetic) throws Exception { + public static Polynomial restorePolynomial(Polynomial.Point[] shares,Arithmetic arithmetic) { return Polynomial.interpolation(shares,arithmetic); } diff --git a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGDeepTest.java b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGDeepTest.java deleted file mode 100644 index a50c75c..0000000 --- a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGDeepTest.java +++ /dev/null @@ -1,174 +0,0 @@ -package JointFeldmanProtocol; - -import Arithmetics.Arithmetic; -import Arithmetics.Fp; -import Communication.Network; -import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; -import ShamirSecretSharing.Polynomial; -import ShamirSecretSharing.SecretSharing; -import UserInterface.DistributedKeyGenerationUser; -import org.factcenter.qilin.primitives.Group; -import org.factcenter.qilin.primitives.concrete.Zpstar; -import org.junit.Before; -import org.junit.Test; - -import java.lang.reflect.Array; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Random; -import java.util.Set; - -/** - * Created by Tzlil on 3/21/2016. - */ -public class DKGDeepTest { - - int tests = 10; - BigInteger p = BigInteger.valueOf(2903); - BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); - Group group = new Zpstar(p); - Arithmetic arithmetic = new Fp(q); - int t = 9; - int n = 20; - - Testable[] testables; - - @Before - public void settings(){ - testables = new Testable[n]; - 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++){ - testable.threads[i].start(); - } - 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.QUAL){ - if(!testable.aborted.contains(i)) - assert (testable.dkgs[i - 1].getPublicValue().equals(publicValue)); - } - - // assert valid verification values - BigInteger expected,verification; - for (int i: testable.QUAL){ - if(!testable.aborted.contains(i)) { - expected = group.multiply(testable.g, testable.dkgs[i - 1].getShare().y); - verification = VerifiableSecretSharing.verify(i, testable.dkgs[i - 1].getCommitments(), group); - assert (expected.equals(verification)); - } - } - - - // restore the secret from shares - ArrayList sharesList = new ArrayList(); - - for(int i : testable.QUAL){ - if(!testable.aborted.contains(i)) - sharesList.add(testable.dkgs[i - 1].getShare()); - } - Polynomial.Point[] shares = new Polynomial.Point[sharesList.size()]; - for (int i = 0; i < shares.length; i ++){ - shares[i] = sharesList.get(i); - } - - BigInteger calculatedSecret = SecretSharing.restoreSecret(shares,arithmetic); - assert (calculatedSecret.equals(testable.secret)); - } - - @Test - public void test() throws Exception { - for (int i = 0; i < tests; i++){ - oneTest(i); - } - } - - class Testable{ - Set QUAL; - Set aborted; - Set malicious; - DistributedKeyGenerationUser[] dkgs; - Thread[] threads; - BigInteger g; - BigInteger secret; - public Testable(Random random) { - - this.dkgs = new DistributedKeyGenerationUserImpl[n]; - this.QUAL = new HashSet(); - this.aborted = new HashSet(); - this.malicious = new HashSet(); - this.threads = new Thread[n]; - this.g = sampleGenerator(random); - ArrayList ids = new ArrayList(); - for (int id = 1; id<= n ; id++){ - ids.add(id); - } - Network network = new Network(n); - int id; - BigInteger s; - DistributedKeyGeneration dkg; - this.secret = BigInteger.ZERO; - while (!ids.isEmpty()) { - id = ids.remove(random.nextInt(ids.size())); - s = randomIntModQ(random); - dkg = new DistributedKeyGeneration(t, n, s, random, q, g, group, id); - dkgs[id - 1] = randomDKGUser(id,network,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) { - QUAL.add(id); - return new DistributedKeyGenerationUserImpl(dkg,network); - }else{ - int type = random.nextInt(3); - switch (type){ - case 0:// regular - QUAL.add(id); - return new DistributedKeyGenerationUserImpl(dkg,network); - case 1:// abort - int abortStage = random.nextInt(2) + 1; // 1 or 2 - aborted.add(id); - if (abortStage == 2){ - QUAL.add(id); - } - return new DKGUserImplAbort(dkg,network,abortStage); - case 2:// malicious - malicious.add(id); - return new DKGMaliciousUserImpl(dkg,network,random); - default: - return null; - } - } - } - - public BigInteger sampleGenerator(Random random){ - BigInteger ZERO = group.zero(); - BigInteger g; - do { - g = group.sample(random); - } while (!g.equals(ZERO) && !group.multiply(g, q).equals(ZERO)); - return g; - } - - public BigInteger randomIntModQ(Random random){ - return new BigInteger(q.bitLength(), random).mod(q); - } - - - } -} diff --git a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGMaliciousUserImpl.java b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGMaliciousUserImpl.java index e3261f8..ad4aa4d 100644 --- a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGMaliciousUserImpl.java +++ b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGMaliciousUserImpl.java @@ -13,28 +13,33 @@ public class DKGMaliciousUserImpl extends DistributedKeyGenerationUserImpl { private final DistributedKeyGeneration maliciousDkg; private final Set falls; - public DKGMaliciousUserImpl(DistributedKeyGeneration dkg, Network network, Random random) { + public DKGMaliciousUserImpl(DistributedKeyGeneration dkg,DistributedKeyGeneration maliciousDKG, Network network,Set falls) { super(dkg, network); - this.falls = selectFalls(random); - this.maliciousDkg = new DistributedKeyGeneration(t,n,randomInt(random),random,dkg.getQ(),g,group,id); - maliciousDkg.setParties(parties); + this.falls = falls; + this.maliciousDkg = maliciousDKG; + maliciousDKG.setParties(parties); } - public Set selectFalls(Random random){ - ArrayList ids = new ArrayList(); - for (int i = 1; i<= n ; i++){ - if(i!=id) { - ids.add(i); - } - } + public static Set selectFallsRandomly(Set ids, Random random){ Set falls = new HashSet(); - int fallsSize = random.nextInt(ids.size()) + 1;// 1 - (n-1) + ArrayList idsList = new ArrayList(); + for (int id : ids){ + idsList.add(id); + } + int fallsSize = random.nextInt(idsList.size()) + 1;// 1 - (n-1) while (falls.size() < fallsSize){ - falls.add(ids.remove(random.nextInt(ids.size()))); + falls.add(idsList.remove(random.nextInt(idsList.size()))); } return falls; } + public static DistributedKeyGeneration generateMaliciousDKG(DistributedKeyGeneration dkg,Random random){ + BigInteger q = dkg.getQ(); + BigInteger zi = new BigInteger(q.bitLength(), random).mod(q); + return new DistributedKeyGeneration(dkg.getT(),dkg.getN(),zi,random,dkg.getQ() + ,dkg.getGenerator(),dkg.getGroup(),dkg.getId()); + } + @Override public void stage1() { dkg.broadcastCommitments(user); @@ -51,11 +56,6 @@ public class DKGMaliciousUserImpl extends DistributedKeyGenerationUserImpl { // do nothing } - private BigInteger randomInt(Random random){ - BigInteger q = dkg.getQ(); - return new BigInteger(q.bitLength(), random).mod(q); - } - private void sendSecrets(){ for (int j = 1; j <= n ; j++){ if(j != id){ diff --git a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java index b50c46e..624aeeb 100644 --- a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java +++ b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java @@ -2,121 +2,174 @@ package JointFeldmanProtocol; import Arithmetics.Arithmetic; import Arithmetics.Fp; -import Arithmetics.Z; import Communication.Network; +import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; import ShamirSecretSharing.Polynomial; import ShamirSecretSharing.SecretSharing; -import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; import UserInterface.DistributedKeyGenerationUser; +import Utils.GenerateRandomPrime; import org.factcenter.qilin.primitives.Group; import org.factcenter.qilin.primitives.concrete.Zpstar; import org.junit.Before; import org.junit.Test; import java.math.BigInteger; -import java.util.*; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Random; +import java.util.Set; /** - * Created by Tzlil on 2/9/2016. + * Created by Tzlil on 3/21/2016. */ public class DKGTest { - - DistributedKeyGenerationUser[][] dkgsArrays; - Thread[][] threadsArrays; int tests = 10; - BigInteger p = BigInteger.valueOf(2903); + BigInteger p = GenerateRandomPrime.SafePrime100Bits; BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); - BigInteger[] secrets; - Set QUAL = new HashSet(); - Arithmetic arithmetic; + Group group = new Zpstar(p); + Arithmetic arithmetic = new Fp(q); + int t = 9; + int n = 20; + + Testable[] testables; + @Before public void settings(){ - Zpstar zpstar = new Zpstar(p); - Random random = new Random(); - arithmetic = new Fp(q); - BigInteger g; - int t = 9; - int n = 20; - BigInteger ZERO = zpstar.zero(); - dkgsArrays = new DistributedKeyGenerationUserImpl[tests][n]; - threadsArrays = new Thread[tests][n]; - secrets = new BigInteger[tests]; - DistributedKeyGeneration dkg; - int abortedStage = 1; - for (int test = 0; test < tests; test++) { - do { - g = zpstar.sample(random); - } while (!g.equals(ZERO) && !zpstar.multiply(g, q).equals(ZERO));// sample from QRZp* - secrets[test] = BigInteger.ZERO; - Network network = new Network(n); - for (int i = 1; i <= n; i++) { - BigInteger secret = new BigInteger(q.bitLength(), random).mod(q); - dkg = new DistributedKeyGeneration(t,n,secret,random,q,g,zpstar,i); - - if(i == n) { - dkgsArrays[test][i - 1] = new DKGMaliciousUserImpl(dkg,network,random);//new DKGUserImplAbort(dkg, network, abortedStage); - } - else { - dkgsArrays[test][i - 1] = new DistributedKeyGenerationUserImpl(dkg, network); - QUAL.add(i); - } - if (abortedStage > 1 || (abortedStage == 1 && i != n)){ - secrets[test] = secrets[test].add(secret).mod(q); - } - threadsArrays[test][i - 1] = new Thread(dkgsArrays[test][i - 1]); - } + testables = new Testable[tests]; + for (int i = 0; i < tests; i++){ + testables[i] = new Testable(new Random()); } } - public void oneTest(Thread[] threads, DistributedKeyGenerationUser[] dkgs,BigInteger secret) throws Exception { - for (int i = 0; i < threads.length ; i++){ - threads[i].start(); + public void oneTest(int test) throws Exception { + Testable testable = testables[test]; + for (int i = 0; i < testable.threads.length ; i++){ + testable.threads[i].start(); } - for (int i = 0; i < threads.length ; i++){ - threads[i].join(); + for (int i = 0; i < testable.threads.length ; i++){ + testable.threads[i].join(); } - int t = dkgs[0].getT(); - int n = dkgs[0].getN(); - - Group zpstar = dkgs[0].getGroup(); - BigInteger g = dkgs[0].getGenerator(); // got the right public value - BigInteger publicValue = zpstar.multiply(g,secret); - for (int i: QUAL){ - if(i != n) - assert (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: QUAL){ - expected = zpstar.multiply(g, dkgs[i - 1].getShare().y); - verification = VerifiableSecretSharing.verify(i, dkgs[i - 1].getCommitments(),zpstar); + for (int i: testable.valids){ + expected = group.multiply(testable.g, testable.dkgs[i - 1].getShare().y); + verification = VerifiableSecretSharing.verify(i, testable.dkgs[i - 1].getCommitments(), group); assert (expected.equals(verification)); } // restore the secret from shares ArrayList sharesList = new ArrayList(); - Polynomial.Point[] shares = new Polynomial.Point[QUAL.size()]; - for(int i : QUAL){ - sharesList.add(dkgs[i - 1].getShare()); + + for (int i: testable.valids){ + sharesList.add(testable.dkgs[i - 1].getShare()); } + Polynomial.Point[] shares = new Polynomial.Point[sharesList.size()]; for (int i = 0; i < shares.length; i ++){ shares[i] = sharesList.get(i); } BigInteger calculatedSecret = SecretSharing.restoreSecret(shares,arithmetic); - assert (calculatedSecret.equals(secret)); - + assert (calculatedSecret.equals(testable.secret)); } @Test - public void DKGTest() throws Exception { - for (int i = 0 ; i < dkgsArrays.length; i ++){ - oneTest(threadsArrays[i],dkgsArrays[i],secrets[i]); + public void test() throws Exception { + for (int i = 0; i < tests; i++){ + oneTest(i); } } + + class Testable{ + Set valids; + Set QUAL; + Set aborted; + Set malicious; + DistributedKeyGenerationUser[] dkgs; + Thread[] threads; + BigInteger g; + BigInteger secret; + + public Testable(Random random) { + this.dkgs = new DistributedKeyGenerationUserImpl[n]; + this.valids = new HashSet(); + this.QUAL = new HashSet(); + this.aborted = new HashSet(); + this.malicious = new HashSet(); + this.threads = new Thread[n]; + this.g = sampleGenerator(random); + ArrayList ids = new ArrayList(); + for (int id = 1; id<= n ; id++){ + ids.add(id); + } + Network network = new Network(n); + int id; + BigInteger s; + DistributedKeyGeneration dkg; + this.secret = BigInteger.ZERO; + while (!ids.isEmpty()) { + id = ids.remove(random.nextInt(ids.size())); + s = randomIntModQ(random); + dkg = new DistributedKeyGeneration(t, n, s, random, q, g, group, id); + dkgs[id - 1] = randomDKGUser(id,network,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); + }else{ + int type = random.nextInt(3); + switch (type){ + case 0:// regular + valids.add(id); + QUAL.add(id); + return new DistributedKeyGenerationUserImpl(dkg,network); + case 1:// abort + int abortStage = random.nextInt(2) + 1; // 1 or 2 + aborted.add(id); + if (abortStage == 2){ + QUAL.add(id); + } + return new DKGUserImplAbort(dkg,network,abortStage); + case 2:// malicious + malicious.add(id); + Set falls = DKGMaliciousUserImpl.selectFallsRandomly(valids,random); + DistributedKeyGeneration maliciousDKG = DKGMaliciousUserImpl.generateMaliciousDKG(dkg,random); + return new DKGMaliciousUserImpl(dkg,maliciousDKG,network,falls); + default: + return null; + } + } + } + + public BigInteger sampleGenerator(Random random){ + BigInteger ZERO = group.zero(); + BigInteger g; + do { + g = group.sample(random); + } while (!g.equals(ZERO) && !group.multiply(g, q).equals(ZERO)); + return g; + } + + public BigInteger randomIntModQ(Random random){ + return new BigInteger(q.bitLength(), random).mod(q); + } + + } } diff --git a/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGMaliciousUserImpl.java b/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGMaliciousUserImpl.java new file mode 100644 index 0000000..9240dea --- /dev/null +++ b/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGMaliciousUserImpl.java @@ -0,0 +1,64 @@ +package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; + +import Communication.Network; +import JointFeldmanProtocol.DistributedKeyGeneration; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Random; +import java.util.Set; + +/** + * Created by Tzlil on 3/29/2016. + */ +public class SDKGMaliciousUserImpl extends SecureDistributedKeyGenerationUserImpl { + + private final DistributedKeyGeneration maliciousSDKG; + private final Set falls; + public SDKGMaliciousUserImpl(SecureDistributedKeyGeneration sdkg,SecureDistributedKeyGeneration maliciousSDKG + , Network network,Set falls) { + super(sdkg, network); + this.falls = falls; + this.maliciousSDKG = maliciousSDKG; + maliciousSDKG.setParties(parties); + } + + public static SecureDistributedKeyGeneration generateMaliciousSDKG(SecureDistributedKeyGeneration sdkg,Random random){ + BigInteger q = sdkg.getQ(); + BigInteger zi = new BigInteger(q.bitLength(), random).mod(q); + return new SecureDistributedKeyGeneration(sdkg.getT(),sdkg.getN(),zi,random,sdkg.getQ() + ,sdkg.getGenerator(),sdkg.getH(),sdkg.getGroup(),sdkg.getId()); + } + + @Override + public void stage1() { + sdkg.broadcastVerificationValues(user); + //sdkg.sendSecrets(user); + sendSecrets(); //insteadof dkg.sendSecrets(user); + } + + @Override + public void stage3() { + stopReceiver(); + maliciousSDKG.answerAllComplainingPlayers(user); + } + + @Override + public void stage4(){ + //do nothing + } + + private void sendSecrets(){ + for (int j = 1; j <= n ; j++){ + if(j != id){ + if(falls.contains(j)){ + maliciousSDKG.sendSecret(user,j); + }else { + sdkg.sendSecret(user, j); + } + } + } + } + +} diff --git a/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGTest.java b/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGTest.java index 107f87c..1b1b261 100644 --- a/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGTest.java +++ b/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGTest.java @@ -2,12 +2,16 @@ package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; import Arithmetics.Arithmetic; import Arithmetics.Fp; -import Arithmetics.Z; import Communication.Network; import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; +import JointFeldmanProtocol.DKGMaliciousUserImpl; +import JointFeldmanProtocol.DKGUserImplAbort; +import JointFeldmanProtocol.DistributedKeyGeneration; +import JointFeldmanProtocol.DistributedKeyGenerationUserImpl; import ShamirSecretSharing.Polynomial; import ShamirSecretSharing.SecretSharing; import UserInterface.DistributedKeyGenerationUser; +import Utils.GenerateRandomPrime; import org.factcenter.qilin.primitives.Group; import org.factcenter.qilin.primitives.concrete.Zpstar; import org.junit.Before; @@ -20,108 +24,157 @@ import java.util.Random; import java.util.Set; /** - * Created by Tzlil on 2/23/2016. + * Created by Tzlil on 3/29/2016. */ public class SDKGTest { - DistributedKeyGenerationUser[][] sdkgsArrays; - Thread[][] threadsArrays; int tests = 10; - BigInteger p = BigInteger.valueOf(2903); + BigInteger p = GenerateRandomPrime.SafePrime100Bits; BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); - BigInteger[] secrets; - - Set QUAL = new HashSet(); - - Arithmetic arithmetic; + Group group = new Zpstar(p); + Arithmetic arithmetic = new Fp(q); + int t = 9; + int n = 20; + Testable[] testables; @Before public void settings(){ - Zpstar zpstar = new Zpstar(p); - Random random = new Random(); - arithmetic = new Fp(q); - BigInteger g,h; - int t = 9; - int n = 20; - BigInteger ZERO = zpstar.zero(); - sdkgsArrays = new SecureDistributedKeyGenerationUserImpl[tests][n]; - threadsArrays = new Thread[tests][n]; - secrets = new BigInteger[tests]; - SecureDistributedKeyGeneration sdkg; - for (int test = 0; test < tests; test++) { - do { - g = zpstar.sample(random); - } while (!g.equals(ZERO) && !zpstar.multiply(g, q).equals(ZERO));// sample from QRZp* - h = zpstar.multiply(g,BigInteger.valueOf(2)); - secrets[test] = BigInteger.ZERO; - Network network = new Network(n); - int abortedStage = 2; - for (int i = 1; i <= n; i++) { - BigInteger secret = new BigInteger(q.bitLength(), random).mod(q); - sdkg = new SecureDistributedKeyGeneration(t,n,secret,random,q,g,h,zpstar,i); - if(i == n) { - sdkgsArrays[test][i - 1] = new SDKGUserImplAbort(sdkg, network, abortedStage); - } - else { - sdkgsArrays[test][i - 1] = new SecureDistributedKeyGenerationUserImpl(sdkg, network); - QUAL.add(i); - } - if (abortedStage > 1 || (abortedStage == 1 && i != n)){ - secrets[test] = secrets[test].add(secret).mod(q); - } - threadsArrays[test][i - 1] = new Thread(sdkgsArrays[test][i - 1]); - } + testables = new Testable[tests]; + for (int i = 0; i < tests; i++){ + testables[i] = new Testable(new Random()); } } - - public void oneTest(Thread[] threads, DistributedKeyGenerationUser[] dkgs,BigInteger secret) throws Exception { - for (int i = 0; i < threads.length ; i++){ - threads[i].start(); + public void oneTest(int test) throws Exception { + Testable testable = testables[test]; + for (int i = 0; i < testable.threads.length ; i++){ + testable.threads[i].start(); } - for (int i = 0; i < threads.length ; i++){ - threads[i].join(); + for (int i = 0; i < testable.threads.length ; i++){ + testable.threads[i].join(); } - int t = dkgs[0].getT(); - int n = dkgs[0].getN(); - - Group zpstar = dkgs[0].getGroup(); - BigInteger g = dkgs[0].getGenerator(); // got the right public value - BigInteger publicValue = zpstar.multiply(g,secret); - for (int i: QUAL){ - assert (dkgs[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: QUAL){ - expected = zpstar.multiply(g, dkgs[i - 1].getShare().y); - verification = VerifiableSecretSharing.verify(i, dkgs[i - 1].getCommitments(),zpstar); + for (int i: testable.valids){ + expected = group.multiply(testable.g, testable.sdkgs[i - 1].getShare().y); + verification = VerifiableSecretSharing.verify(i, testable.sdkgs[i - 1].getCommitments(), group); assert (expected.equals(verification)); } // restore the secret from shares ArrayList sharesList = new ArrayList(); - Polynomial.Point[] shares = new Polynomial.Point[QUAL.size()]; - for(int i : QUAL){ - sharesList.add(dkgs[i - 1].getShare()); + + for (int i: testable.valids){ + sharesList.add(testable.sdkgs[i - 1].getShare()); } + Polynomial.Point[] shares = new Polynomial.Point[sharesList.size()]; for (int i = 0; i < shares.length; i ++){ shares[i] = sharesList.get(i); } BigInteger calculatedSecret = SecretSharing.restoreSecret(shares,arithmetic); - assert (calculatedSecret.equals(secret)); - + assert (calculatedSecret.equals(testable.secret)); } @Test - public void SDKGTest() throws Exception { - for (int i = 0 ; i < sdkgsArrays.length; i ++){ - oneTest(threadsArrays[i],sdkgsArrays[i],secrets[i]); + public void test() throws Exception { + for (int i = 0; i < tests; i++){ + oneTest(i); } } + + class Testable{ + Set valids; + Set QUAL; + Set aborted; + Set malicious; + DistributedKeyGenerationUser[] sdkgs; + Thread[] threads; + BigInteger g; + BigInteger h; + BigInteger secret; + + public Testable(Random random) { + this.sdkgs = new SecureDistributedKeyGenerationUserImpl[n]; + this.valids = new HashSet(); + this.QUAL = new HashSet(); + this.aborted = new HashSet(); + this.malicious = new HashSet(); + this.threads = new Thread[n]; + this.g = sampleGenerator(random); + this.h = group.multiply(g,randomIntModQ(random)); + ArrayList ids = new ArrayList(); + for (int id = 1; id<= n ; id++){ + ids.add(id); + } + Network network = new Network(n); + int id; + BigInteger s; + SecureDistributedKeyGeneration sdkg; + this.secret = BigInteger.ZERO; + while (!ids.isEmpty()) { + id = ids.remove(random.nextInt(ids.size())); + s = randomIntModQ(random); + sdkg = new SecureDistributedKeyGeneration(t, n, s, random, q, g , h, group, id); + sdkgs[id - 1] = randomSDKGUser(id,network,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); + }else{ + int type = random.nextInt(3); + switch (type){ + case 0:// regular + valids.add(id); + QUAL.add(id); + return new SecureDistributedKeyGenerationUserImpl(sdkg,network); + case 1:// abort + int abortStage = random.nextInt(3) + 1; // 1 or 2 or 3 + aborted.add(id); + if (abortStage > 1){ + QUAL.add(id); + } + return new SDKGUserImplAbort(sdkg,network,abortStage); + case 2:// malicious + malicious.add(id); + Set falls = DKGMaliciousUserImpl.selectFallsRandomly(valids,random); + SecureDistributedKeyGeneration maliciousSDKG = SDKGMaliciousUserImpl.generateMaliciousSDKG(sdkg,random); + return new SDKGMaliciousUserImpl(sdkg,maliciousSDKG,network,falls); + default: + return null; + } + } + } + + public BigInteger sampleGenerator(Random random){ + BigInteger ZERO = group.zero(); + BigInteger g; + do { + g = group.sample(random); + } while (!g.equals(ZERO) && !group.multiply(g, q).equals(ZERO)); + return g; + } + + public BigInteger randomIntModQ(Random random){ + return new BigInteger(q.bitLength(), random).mod(q); + } + + } } diff --git a/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGUserImplAbort.java b/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGUserImplAbort.java index fc777d3..c2a6fbe 100644 --- a/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGUserImplAbort.java +++ b/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGUserImplAbort.java @@ -18,7 +18,8 @@ public class SDKGUserImplAbort extends SecureDistributedKeyGenerationUserImpl { this.stage = 1; } - private void sendAbort(){ + private void abort(){ + stopReceiver(); user.broadcast(DKGMessages.Mail.Type.ABORT,DKGMessages.EmptyMessage.getDefaultInstance()); } @@ -27,7 +28,7 @@ public class SDKGUserImplAbort extends SecureDistributedKeyGenerationUserImpl { if(stage < abortStage) super.stage1(); else if(stage == abortStage){ - sendAbort(); + abort(); } stage++; } @@ -37,7 +38,7 @@ public class SDKGUserImplAbort extends SecureDistributedKeyGenerationUserImpl { if(stage < abortStage) super.stage2(); else if(stage == abortStage){ - sendAbort(); + abort(); } stage++; } @@ -47,7 +48,7 @@ public class SDKGUserImplAbort extends SecureDistributedKeyGenerationUserImpl { if(stage < abortStage) super.stage3(); else if(stage == abortStage){ - sendAbort(); + abort(); } stage++; } @@ -57,7 +58,7 @@ public class SDKGUserImplAbort extends SecureDistributedKeyGenerationUserImpl { if(stage < abortStage) super.stage4(); else if(stage == abortStage){ - sendAbort(); + abort(); } stage++; } diff --git a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/AddTest.java b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/AddTest.java index 288aed1..fe4e602 100644 --- a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/AddTest.java +++ b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/AddTest.java @@ -1,4 +1,6 @@ package ShamirSecretSharing.PolynomialTests; +import Arithmetics.Z; +import Utils.GenerateRandomPolynomial; import ShamirSecretSharing.Polynomial; import org.junit.Before; import org.junit.Test; @@ -24,8 +26,8 @@ public class AddTest { arr1 = new Polynomial[tests]; arr2 = new Polynomial[tests]; for (int i = 0; i < arr1.length; i++){ - arr1[i] = Utils.generateRandomPolynomial(random.nextInt(maxDegree),bits,random); - arr2[i] = Utils.generateRandomPolynomial(random.nextInt(maxDegree),bits,random); + arr1[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,new Z()); + arr2[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,new Z()); } } diff --git a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/InterpolationTest.java b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/InterpolationTest.java index 2f5ba39..97f1b8d 100644 --- a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/InterpolationTest.java +++ b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/InterpolationTest.java @@ -2,8 +2,9 @@ package ShamirSecretSharing.PolynomialTests; import Arithmetics.Arithmetic; import Arithmetics.Fp; -import Arithmetics.Z; +import Utils.GenerateRandomPolynomial; import ShamirSecretSharing.Polynomial; +import Utils.GenerateRandomPrime; import org.junit.Before; import org.junit.Test; @@ -23,7 +24,7 @@ public class InterpolationTest { Random random; Polynomial.Point[][] pointsArrays; Arithmetic arithmetic; - BigInteger p = BigInteger.valueOf(2903); + BigInteger p = GenerateRandomPrime.SafePrime100Bits; @Before public void settings(){ @@ -31,7 +32,7 @@ public class InterpolationTest { polynomials = new Polynomial[tests]; pointsArrays = new Polynomial.Point[tests][]; for (int i = 0; i < polynomials.length; i++){ - polynomials[i] = Utils.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,p); + polynomials[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,p); pointsArrays[i] = randomPoints(polynomials[i]); } arithmetic = new Fp(p); diff --git a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulByConstTest.java b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulByConstTest.java index 0865058..3a3bf1a 100644 --- a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulByConstTest.java +++ b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulByConstTest.java @@ -1,5 +1,7 @@ package ShamirSecretSharing.PolynomialTests; +import Arithmetics.Z; +import Utils.GenerateRandomPolynomial; import ShamirSecretSharing.Polynomial; import org.junit.Before; import org.junit.Test; @@ -26,7 +28,7 @@ public class MulByConstTest { arr1 = new Polynomial[tests]; arr2 = new BigInteger[tests]; for (int i = 0; i < arr1.length; i++){ - arr1[i] = Utils.generateRandomPolynomial(random.nextInt(maxDegree),bits,random); + arr1[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,new Z()); arr2[i] = new BigInteger(bits,random); } } diff --git a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulTest.java b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulTest.java index 418ea00..a7dd365 100644 --- a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulTest.java +++ b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulTest.java @@ -1,5 +1,7 @@ package ShamirSecretSharing.PolynomialTests; +import Arithmetics.Z; +import Utils.GenerateRandomPolynomial; import ShamirSecretSharing.Polynomial; import org.junit.Before; import org.junit.Test; @@ -26,8 +28,8 @@ public class MulTest { arr1 = new Polynomial[tests]; arr2 = new Polynomial[tests]; for (int i = 0; i < arr1.length; i++){ - arr1[i] = Utils.generateRandomPolynomial(random.nextInt(maxDegree),bits,random); - arr2[i] = Utils.generateRandomPolynomial(random.nextInt(maxDegree),bits,random); + arr1[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,new Z()); + arr2[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,new Z()); } } diff --git a/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java b/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java index 042c06a..a74148f 100644 --- a/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java +++ b/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java @@ -1,6 +1,7 @@ package ShamirSecretSharing; import Arithmetics.Z; +import Utils.GenerateRandomPrime; import org.factcenter.qilin.primitives.CyclicGroup; import org.factcenter.qilin.primitives.concrete.Zn; import org.junit.Before; @@ -24,7 +25,7 @@ public class SecretSharingTest { @Before public void settings(){ - BigInteger p = BigInteger.valueOf(2903); + BigInteger p = GenerateRandomPrime.SafePrime100Bits; BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); group = new Zn(p); int t = 9; diff --git a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/Utils.java b/destributed-key-generation/src/test/java/Utils/GenerateRandomPolynomial.java similarity index 75% rename from destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/Utils.java rename to destributed-key-generation/src/test/java/Utils/GenerateRandomPolynomial.java index 8ec057a..d59d051 100644 --- a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/Utils.java +++ b/destributed-key-generation/src/test/java/Utils/GenerateRandomPolynomial.java @@ -1,5 +1,6 @@ -package ShamirSecretSharing.PolynomialTests; +package Utils; +import Arithmetics.Arithmetic; import Arithmetics.Fp; import ShamirSecretSharing.Polynomial; @@ -9,19 +10,19 @@ import java.util.Random; /** * Created by Tzlil on 1/27/2016. */ -public class Utils { +public class GenerateRandomPolynomial { - public static Polynomial generateRandomPolynomial(int degree,int bits,Random random) { + public static Polynomial generateRandomPolynomial(int degree, int bits, Random random,Arithmetic arithmetic) { BigInteger[] coefficients = new BigInteger[degree + 1]; for (int i = 0 ; i <= degree; i++ ){ coefficients[i] = new BigInteger(bits,random); // sample from Zp [0,... q-1] } - return new Polynomial(coefficients); + return new Polynomial(coefficients,arithmetic); } public static Polynomial generateRandomPolynomial(int degree,int bits,Random random,BigInteger p) { - BigInteger[] coefficients = generateRandomPolynomial(degree,bits,random).getCoefficients(); + BigInteger[] coefficients = generateRandomPolynomial(degree,bits,random,new Fp(p)).getCoefficients(); for (int i = 0; i Date: Tue, 5 Apr 2016 15:36:00 +0300 Subject: [PATCH 32/49] Code review comments and channges --- .gitignore | 32 +- build.gradle | 20 +- build.gradle-template | 440 ++++---- .../bulletinboard/BulletinClientJob.java | 162 +-- .../BulletinClientJobResult.java | 58 +- .../bulletinboard/BulletinClientWorker.java | 434 ++++---- .../SimpleBulletinBoardClient.java | 322 +++--- .../ThreadedBulletinBoardClient.java | 262 ++--- .../callbacks/ClientFutureCallback.java | 50 +- .../GetRedundancyFutureCallback.java | 76 +- .../callbacks/PostMessageFutureCallback.java | 92 +- .../callbacks/ReadMessagesFutureCallback.java | 76 +- .../BulletinBoardClientIntegrationTest.java | 428 ++++---- bulletin-board-server/.gitignore | 2 +- bulletin-board-server/build.gradle | 482 ++++----- bulletin-board-server/gradle-app.setting | 58 +- .../bulletinboard/service/HelloProtoBuf.java | 60 +- .../sqlserver/BulletinBoardSQLServer.java | 968 +++++++++--------- .../sqlserver/H2QueryProvider.java | 328 +++--- .../sqlserver/MySQLQueryProvider.java | 296 +++--- .../sqlserver/SQLiteQueryProvider.java | 246 ++--- .../sqlserver/mappers/EntryNumMapper.java | 36 +- .../sqlserver/mappers/MessageMapper.java | 64 +- .../sqlserver/mappers/SignatureMapper.java | 56 +- .../webapp/BulletinBoardWebApp.java | 248 ++--- .../webapp/HelloProtoWebApp.java | 100 +- .../proto/meerkat/bulletin_board_server.proto | 16 +- .../src/main/webapp/META-INF/jetty-env.xml | 22 +- .../src/main/webapp/WEB-INF/web.xml | 76 +- ...BulletinBoardSQLServerIntegrationTest.java | 248 ++--- .../GenericBulletinBoardServerTest.java | 782 +++++++------- .../H2BulletinBoardServerTest.java | 244 ++--- .../HelloProtoIntegrationTest.java | 84 +- .../MySQLBulletinBoardServerTest.java | 252 ++--- .../SQLiteBulletinBoardServerTest.java | 212 ++-- destributed-key-generation/build.gradle | 440 ++++---- .../src/main/java/Arithmetics/Arithmetic.java | 32 +- .../src/main/java/Arithmetics/Fp.java | 76 +- .../src/main/java/Arithmetics/Z.java | 58 +- .../src/main/java/Communication/Channel.java | 28 + .../main/java/Communication/MailHandler.java | 117 ++- .../java/Communication/MessageHandler.java | 30 +- .../src/main/java/Communication/Network.java | 148 +-- .../src/main/java/Communication/User.java | 140 +-- .../VerifiableSecretSharing.java | 198 ++-- .../DistributedKeyGeneration.java | 513 +++++----- .../DistributedKeyGenerationMailHandler.java | 98 +- .../DistributedKeyGenerationParty.java | 63 +- .../DistributedKeyGenerationUserImpl.java | 775 +++++++------- .../SecureDistributedKeyGeneration.java | 278 ++--- ...reDistributedKeyGenerationMailHandler.java | 126 +-- .../SecureDistributedKeyGenerationParty.java | 58 +- ...ecureDistributedKeyGenerationUserImpl.java | 611 +++++------ .../LagrangePolynomial.java | 132 +-- .../java/ShamirSecretSharing/Polynomial.java | 415 ++++---- .../ShamirSecretSharing/SecretSharing.java | 223 ++-- .../DistributedKeyGenerationUser.java | 26 +- .../java/UserInterface/SecretSharingUser.java | 28 +- .../VerifiableSecretSharingUser.java | 32 +- .../VerifiableSecretSharingTest.java | 135 ++- .../DKGMaliciousUserImpl.java | 144 +-- .../java/JointFeldmanProtocol/DKGTest.java | 350 +++---- .../DKGUserImplAbort.java | 126 +-- .../SDKGMaliciousUserImpl.java | 125 ++- .../SDKGTest.java | 357 ++++--- .../SDKGUserImplAbort.java | 130 +-- .../PolynomialTests/AddTest.java | 92 +- .../PolynomialTests/InterpolationTest.java | 136 +-- .../PolynomialTests/MulByConstTest.java | 96 +- .../PolynomialTests/MulTest.java | 96 +- .../SecretSharingTest.java | 126 +-- .../java/Utils/GenerateRandomPolynomial.java | 62 +- .../test/java/Utils/GenerateRandomPrime.java | 64 +- gradle/wrapper/gradle-wrapper.properties | 12 +- meerkat-common/.gitignore | 2 +- meerkat-common/build.gradle | 436 ++++---- meerkat-common/src/main/java/Demo.java | 58 +- .../bulletinboard/BulletinBoardClient.java | 108 +- .../bulletinboard/BulletinBoardServer.java | 84 +- .../meerkat/comm/CommunicationException.java | 72 +- .../src/main/java/meerkat/comm/Timestamp.java | 14 +- .../src/main/java/meerkat/crypto/Digest.java | 76 +- .../java/meerkat/crypto/DigitalSignature.java | 192 ++-- .../main/java/meerkat/crypto/Encryption.java | 80 +- .../concrete/ECDSADeterministicSignature.java | 268 ++--- .../crypto/concrete/ECDSASignature.java | 644 ++++++------ .../crypto/concrete/ECElGamalEncryption.java | 270 ++--- .../crypto/concrete/GlobalCryptoSetup.java | 86 +- .../meerkat/crypto/concrete/SHA256Digest.java | 192 ++-- .../mixnet/Mix2ZeroKnowledgeProver.java | 36 +- .../mixnet/Mix2ZeroKnowledgeVerifier.java | 46 +- .../java/meerkat/crypto/mixnet/Mixer.java | 22 +- .../java/meerkat/crypto/mixnet/Trustee.java | 14 +- .../java/meerkat/crypto/mixnet/Verifier.java | 14 +- .../java/meerkat/logging/LogVerifier.java | 14 +- .../src/main/java/meerkat/logging/Logger.java | 14 +- .../util/BulletinBoardMessageComparator.java | 98 +- .../src/main/java/meerkat/util/Hex.java | 52 +- .../main/java/meerkat/voting/VotingBooth.java | 140 +-- .../main/proto/meerkat/BulletinBoardAPI.proto | 158 +-- .../src/main/proto/meerkat/DKGMessages.proto | 96 +- .../main/proto/meerkat/concrete_crypto.proto | 42 +- .../src/main/proto/meerkat/crypto.proto | 108 +- .../src/main/proto/meerkat/mixing.proto | 22 +- .../src/main/proto/meerkat/voting.proto | 180 ++-- .../src/main/resources/logback.groovy | 92 +- .../ECDSADeterministicSignatureTest.java | 100 +- .../crypto/concrete/ECDSASignatureTest.java | 440 ++++---- .../concrete/ECElGamalEncryptionTest.java | 244 ++--- .../crypto/concrete/ECElGamalUtils.java | 178 ++-- .../src/test/resources/certs/README.md | 12 +- .../user1-key-with-password-secret.pem | 16 +- .../certs/enduser-certs/user1-key.pem | 10 +- .../certs/enduser-certs/user1-pubkey.pem | 8 +- .../resources/certs/enduser-certs/user1.crt | 38 +- .../resources/certs/enduser-certs/user1.csr | 18 +- .../certs/enduser-certs/user2-key.pem | 10 +- .../certs/enduser-certs/user2-pubkey.pem | 8 +- .../resources/certs/enduser-certs/user2.crt | 38 +- .../resources/certs/enduser-certs/user2.csr | 18 +- .../certs/intermediate-ca-1/1000.pem | 38 +- .../certs/intermediate-ca-1/1001.pem | 38 +- .../certs/intermediate-ca-1/certindex | 4 +- .../certs/intermediate-ca-1/certindex.attr | 2 +- .../intermediate-ca-1/certindex.attr.old | 2 +- .../certs/intermediate-ca-1/certindex.old | 2 +- .../certs/intermediate-ca-1/certserial | 2 +- .../certs/intermediate-ca-1/certserial.old | 2 +- .../certs/intermediate-ca-1/crlnumber | 2 +- .../intermediate-ca-1-private-key.pem | 10 +- .../intermediate-ca-1/intermediate-ca-1.crt | 42 +- .../intermediate-ca-1/intermediate-ca-1.csr | 20 +- .../openssl-intermediate-ca.conf | 92 +- .../src/test/resources/certs/root-ca/1000.pem | 42 +- .../test/resources/certs/root-ca/certindex | 2 +- .../resources/certs/root-ca/certindex.attr | 2 +- .../test/resources/certs/root-ca/certserial | 2 +- .../resources/certs/root-ca/certserial.old | 2 +- .../test/resources/certs/root-ca/crlnumber | 2 +- .../resources/certs/root-ca/openssl-ca.conf | 122 +-- ...ot-ca-private-key-with-password-secret.pem | 16 +- .../certs/root-ca/root-ca-private-key.pem | 10 +- .../test/resources/certs/root-ca/root-ca.crt | 34 +- .../src/test/resources/certs/secp256k1.pem | 6 +- polling-station/build.gradle | 388 +++---- restful-api-common/.gitignore | 2 +- restful-api-common/build.gradle | 320 +++--- .../src/main/java/meerkat/rest/Constants.java | 24 +- .../rest/ProtobufMessageBodyReader.java | 82 +- .../rest/ProtobufMessageBodyWriter.java | 82 +- settings.gradle | 16 +- voting-booth/build.gradle | 386 +++---- 152 files changed, 10399 insertions(+), 10293 deletions(-) create mode 100644 destributed-key-generation/src/main/java/Communication/Channel.java diff --git a/.gitignore b/.gitignore index 6339218..6c07527 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,16 @@ -.gradle -.idea -build -bin -.settings -.classpath -.project -out -*.iml -*.ipr -*.iws -**/*.swp -*.prefs -*.project -*.classpath -bulletin-board-server/local-instances/meerkat.db +.gradle +.idea +build +bin +.settings +.classpath +.project +out +*.iml +*.ipr +*.iws +**/*.swp +*.prefs +*.project +*.classpath +bulletin-board-server/local-instances/meerkat.db diff --git a/build.gradle b/build.gradle index 9f070e3..e3f1a0c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,10 +1,10 @@ - -subprojects { proj -> - proj.afterEvaluate { - // Used to generate initial maven-dir layout - task "create-dirs" { description = "Create default maven directory structure" } << { - sourceSets*.java.srcDirs*.each { it.mkdirs() } - sourceSets*.resources.srcDirs*.each { it.mkdirs() } - } - } -} + +subprojects { proj -> + proj.afterEvaluate { + // Used to generate initial maven-dir layout + task "create-dirs" { description = "Create default maven directory structure" } << { + sourceSets*.java.srcDirs*.each { it.mkdirs() } + sourceSets*.resources.srcDirs*.each { it.mkdirs() } + } + } +} diff --git a/build.gradle-template b/build.gradle-template index 60ec7c9..074667f 100644 --- a/build.gradle-template +++ b/build.gradle-template @@ -1,220 +1,220 @@ - -plugins { - id "us.kirchmeier.capsule" version "1.0.1" - id 'com.google.protobuf' version '0.7.0' -} - -apply plugin: 'java' -apply plugin: 'eclipse' -apply plugin: 'idea' - -apply plugin: 'maven-publish' - -// Uncomment the lines below to define an application -// (this will also allow you to build a "fatCapsule" which includes -// the entire application, including all dependencies in a single jar) -//apply plugin: 'application' -//mainClassName='your.main.ApplicationClass' - -// Is this a snapshot version? -ext { isSnapshot = false } - -ext { - groupId = 'org.factcenter.meerkat' - nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/" - - // Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing) - // Should be set in ${HOME}/.gradle/gradle.properties - nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : "" - nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : "" -} - -description = "TODO: Add a description" - -// Your project version -version = "0.0" - -version += "${isSnapshot ? '-SNAPSHOT' : ''}" - - -dependencies { - // Meerkat common - compile project(':meerkat-common') - - // Logging - compile 'org.slf4j:slf4j-api:1.7.7' - runtime 'ch.qos.logback:logback-classic:1.1.2' - runtime 'ch.qos.logback:logback-core:1.1.2' - - // Google protobufs - compile 'com.google.protobuf:protobuf-java:3.+' - - testCompile 'junit:junit:4.+' - - runtime 'org.codehaus.groovy:groovy:2.4.+' -} - - -/*==== You probably don't have to edit below this line =======*/ - -// Setup test configuration that can appear as a dependency in -// other subprojects -configurations { - testOutput.extendsFrom (testCompile) -} - -task testJar(type: Jar, dependsOn: testClasses) { - classifier = 'tests' - from sourceSets.test.output -} - -artifacts { - testOutput testJar -} - -// The run task added by the application plugin -// is also of type JavaExec. -tasks.withType(JavaExec) { - // Assign all Java system properties from - // the command line to the JavaExec task. - systemProperties System.properties -} - - -protobuf { - // Configure the protoc executable - protoc { - // Download from repositories - artifact = 'com.google.protobuf:protoc:3.+' - } -} - - -idea { - module { - project.sourceSets.each { sourceSet -> - - def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java" - - println "Adding $srcDir" - // add protobuf generated sources to generated source dir. - if ("test".equals(sourceSet.name)) { - testSourceDirs += file(srcDir) - } else { - sourceDirs += file(srcDir) - } - generatedSourceDirs += file(srcDir) - - } - - // Don't exclude build directory - excludeDirs -= file(buildDir) - } -} - - -/*=================================== - * "Fat" Build targets - *===================================*/ - - -if (project.hasProperty('mainClassName') && (mainClassName != null)) { - - task mavenCapsule(type: MavenCapsule) { - description = "Generate a capsule jar that automatically downloads and caches dependencies when run." - applicationClass mainClassName - destinationDir = buildDir - } - - task fatCapsule(type: FatCapsule) { - description = "Generate a single capsule jar containing everything. Use -Pfatmain=... to override main class" - - destinationDir = buildDir - - def fatMain = hasProperty('fatmain') ? fatmain : mainClassName - - applicationClass fatMain - - def testJar = hasProperty('test') - - if (hasProperty('fatmain')) { - appendix = "fat-${fatMain}" - } else { - appendix = "fat" - } - - if (testJar) { - from sourceSets.test.output - } - } -} - - -/*=================================== - * Repositories - *===================================*/ - -repositories { - - // Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral) - maven { - url nexusRepository - - if (isSnapshot) { - credentials { username - password - - username nexusUser - password nexusPassword - } - } - } - - // Use local maven repository - mavenLocal() - - // Use 'maven central' for other dependencies. - mavenCentral() -} - -task "info" << { - println "Project: ${project.name}" -println "Description: ${project.description}" - println "--------------------------" - println "GroupId: $groupId" - println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})" - println "" -} -info.description 'Print some information about project parameters' - - -/*=================================== - * Publishing - *===================================*/ - -publishing { - publications { - mavenJava(MavenPublication) { - groupId project.groupId - pom.withXml { - asNode().appendNode('description', project.description) - } - from project.components.java - - } - } - repositories { - maven { - url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}" - credentials { username - password - - username nexusUser - password nexusPassword - } - } - } -} - - - + +plugins { + id "us.kirchmeier.capsule" version "1.0.1" + id 'com.google.protobuf' version '0.7.0' +} + +apply plugin: 'java' +apply plugin: 'eclipse' +apply plugin: 'idea' + +apply plugin: 'maven-publish' + +// Uncomment the lines below to define an application +// (this will also allow you to build a "fatCapsule" which includes +// the entire application, including all dependencies in a single jar) +//apply plugin: 'application' +//mainClassName='your.main.ApplicationClass' + +// Is this a snapshot version? +ext { isSnapshot = false } + +ext { + groupId = 'org.factcenter.meerkat' + nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/" + + // Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing) + // Should be set in ${HOME}/.gradle/gradle.properties + nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : "" + nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : "" +} + +description = "TODO: Add a description" + +// Your project version +version = "0.0" + +version += "${isSnapshot ? '-SNAPSHOT' : ''}" + + +dependencies { + // Meerkat common + compile project(':meerkat-common') + + // Logging + compile 'org.slf4j:slf4j-api:1.7.7' + runtime 'ch.qos.logback:logback-classic:1.1.2' + runtime 'ch.qos.logback:logback-core:1.1.2' + + // Google protobufs + compile 'com.google.protobuf:protobuf-java:3.+' + + testCompile 'junit:junit:4.+' + + runtime 'org.codehaus.groovy:groovy:2.4.+' +} + + +/*==== You probably don't have to edit below this line =======*/ + +// Setup test configuration that can appear as a dependency in +// other subprojects +configurations { + testOutput.extendsFrom (testCompile) +} + +task testJar(type: Jar, dependsOn: testClasses) { + classifier = 'tests' + from sourceSets.test.output +} + +artifacts { + testOutput testJar +} + +// The run task added by the application plugin +// is also of type JavaExec. +tasks.withType(JavaExec) { + // Assign all Java system properties from + // the command line to the JavaExec task. + systemProperties System.properties +} + + +protobuf { + // Configure the protoc executable + protoc { + // Download from repositories + artifact = 'com.google.protobuf:protoc:3.+' + } +} + + +idea { + module { + project.sourceSets.each { sourceSet -> + + def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java" + + println "Adding $srcDir" + // add protobuf generated sources to generated source dir. + if ("test".equals(sourceSet.name)) { + testSourceDirs += file(srcDir) + } else { + sourceDirs += file(srcDir) + } + generatedSourceDirs += file(srcDir) + + } + + // Don't exclude build directory + excludeDirs -= file(buildDir) + } +} + + +/*=================================== + * "Fat" Build targets + *===================================*/ + + +if (project.hasProperty('mainClassName') && (mainClassName != null)) { + + task mavenCapsule(type: MavenCapsule) { + description = "Generate a capsule jar that automatically downloads and caches dependencies when run." + applicationClass mainClassName + destinationDir = buildDir + } + + task fatCapsule(type: FatCapsule) { + description = "Generate a single capsule jar containing everything. Use -Pfatmain=... to override main class" + + destinationDir = buildDir + + def fatMain = hasProperty('fatmain') ? fatmain : mainClassName + + applicationClass fatMain + + def testJar = hasProperty('test') + + if (hasProperty('fatmain')) { + appendix = "fat-${fatMain}" + } else { + appendix = "fat" + } + + if (testJar) { + from sourceSets.test.output + } + } +} + + +/*=================================== + * Repositories + *===================================*/ + +repositories { + + // Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral) + maven { + url nexusRepository + + if (isSnapshot) { + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } + + // Use local maven repository + mavenLocal() + + // Use 'maven central' for other dependencies. + mavenCentral() +} + +task "info" << { + println "Project: ${project.name}" +println "Description: ${project.description}" + println "--------------------------" + println "GroupId: $groupId" + println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})" + println "" +} +info.description 'Print some information about project parameters' + + +/*=================================== + * Publishing + *===================================*/ + +publishing { + publications { + mavenJava(MavenPublication) { + groupId project.groupId + pom.withXml { + asNode().appendNode('description', project.description) + } + from project.components.java + + } + } + repositories { + maven { + url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}" + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } +} + + + diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientJob.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientJob.java index aca98d4..175cd91 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientJob.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientJob.java @@ -1,82 +1,82 @@ -package meerkat.bulletinboard; - -import com.google.protobuf.Message; - -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -/** - * Created by Arbel Deutsch Peled on 09-Dec-15. - * - * This class specifies the job that is required of a Bulletin Board Client Worker - */ -public class BulletinClientJob { - - public static enum JobType{ - POST_MESSAGE, // Post a message to servers - READ_MESSAGES, // Read messages according to some given filter (any server will do) - GET_REDUNDANCY // Check the redundancy of a specific message in the databases - } - - private List serverAddresses; - - private int minServers; // The minimal number of servers the job must be successful on for the job to be completed - - private final JobType jobType; - - private final Message payload; // The information associated with the job type - - private int maxRetry; // Number of retries for this job; set to -1 for infinite retries - - public BulletinClientJob(List serverAddresses, int minServers, JobType jobType, Message payload, int maxRetry) { - this.serverAddresses = serverAddresses; - this.minServers = minServers; - this.jobType = jobType; - this.payload = payload; - this.maxRetry = maxRetry; - } - - public void updateServerAddresses(List newServerAdresses) { - this.serverAddresses = newServerAdresses; - } - - public List getServerAddresses() { - return serverAddresses; - } - - public int getMinServers() { - return minServers; - } - - public JobType getJobType() { - return jobType; - } - - public Message getPayload() { - return payload; - } - - public int getMaxRetry() { - return maxRetry; - } - - public void shuffleAddresses() { - Collections.shuffle(serverAddresses); - } - - public void decMinServers(){ - minServers--; - } - - public void decMaxRetry(){ - if (maxRetry > 0) { - maxRetry--; - } - } - - public boolean isRetry(){ - return (maxRetry != 0); - } - +package meerkat.bulletinboard; + +import com.google.protobuf.Message; + +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 09-Dec-15. + * + * This class specifies the job that is required of a Bulletin Board Client Worker + */ +public class BulletinClientJob { + + public static enum JobType{ + POST_MESSAGE, // Post a message to servers + READ_MESSAGES, // Read messages according to some given filter (any server will do) + GET_REDUNDANCY // Check the redundancy of a specific message in the databases + } + + private List serverAddresses; + + private int minServers; // The minimal number of servers the job must be successful on for the job to be completed + + private final JobType jobType; + + private final Message payload; // The information associated with the job type + + private int maxRetry; // Number of retries for this job; set to -1 for infinite retries + + public BulletinClientJob(List serverAddresses, int minServers, JobType jobType, Message payload, int maxRetry) { + this.serverAddresses = serverAddresses; + this.minServers = minServers; + this.jobType = jobType; + this.payload = payload; + this.maxRetry = maxRetry; + } + + public void updateServerAddresses(List newServerAdresses) { + this.serverAddresses = newServerAdresses; + } + + public List getServerAddresses() { + return serverAddresses; + } + + public int getMinServers() { + return minServers; + } + + public JobType getJobType() { + return jobType; + } + + public Message getPayload() { + return payload; + } + + public int getMaxRetry() { + return maxRetry; + } + + public void shuffleAddresses() { + Collections.shuffle(serverAddresses); + } + + public void decMinServers(){ + minServers--; + } + + public void decMaxRetry(){ + if (maxRetry > 0) { + maxRetry--; + } + } + + public boolean isRetry(){ + return (maxRetry != 0); + } + } \ No newline at end of file diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientJobResult.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientJobResult.java index be0501b..6a3998f 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientJobResult.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientJobResult.java @@ -1,29 +1,29 @@ -package meerkat.bulletinboard; - -import com.google.protobuf.Message; - -/** - * Created by Arbel Deutsch Peled on 09-Dec-15. - * - * This class contains the end status and result of a Bulletin Board Client Job. - */ -public final class BulletinClientJobResult { - - private final BulletinClientJob job; // Stores the job the result refers to - - private final Message result; // The result of the job; valid only if success==true - - public BulletinClientJobResult(BulletinClientJob job, Message result) { - this.job = job; - this.result = result; - } - - public BulletinClientJob getJob() { - return job; - } - - public Message getResult() { - return result; - } - -} +package meerkat.bulletinboard; + +import com.google.protobuf.Message; + +/** + * Created by Arbel Deutsch Peled on 09-Dec-15. + * + * This class contains the end status and result of a Bulletin Board Client Job. + */ +public final class BulletinClientJobResult { + + private final BulletinClientJob job; // Stores the job the result refers to + + private final Message result; // The result of the job; valid only if success==true + + public BulletinClientJobResult(BulletinClientJob job, Message result) { + this.job = job; + this.result = result; + } + + public BulletinClientJob getJob() { + return job; + } + + public Message getResult() { + return result; + } + +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java index 51599d5..1d0d741 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java @@ -1,217 +1,217 @@ -package meerkat.bulletinboard; - -import com.google.protobuf.Message; -import meerkat.comm.CommunicationException; -import meerkat.crypto.Digest; -import meerkat.crypto.concrete.SHA256Digest; -import meerkat.protobuf.BulletinBoardAPI.*; -import meerkat.rest.Constants; -import meerkat.rest.ProtobufMessageBodyReader; -import meerkat.rest.ProtobufMessageBodyWriter; - -import javax.ws.rs.ProcessingException; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.Response; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.Callable; - -/** - * Created by Arbel Deutsch Peled on 09-Dec-15. - * - * This class implements the actual communication with the Bulletin Board Servers. - * It is meant to be used in a multi-threaded environment. - */ -//TODO: Maybe make this abstract and inherit from it. -public class BulletinClientWorker implements Callable { - - private final BulletinClientJob job; // The requested job to be handled - - public BulletinClientWorker(BulletinClientJob job){ - this.job = job; - } - - // This resource enabled creation of a single Client per thread. - private static final ThreadLocal clientLocal = - new ThreadLocal () { - @Override protected Client initialValue() { - Client client; - client = ClientBuilder.newClient(); - client.register(ProtobufMessageBodyReader.class); - client.register(ProtobufMessageBodyWriter.class); - - return client; - } - }; - - // This resource enables creation of a single Digest per thread. - private static final ThreadLocal digestLocal = - new ThreadLocal () { - @Override protected Digest initialValue() { - Digest digest; - digest = new SHA256Digest(); //TODO: Make this generic. - - return digest; - } - }; - - /** - * This method carries out the actual communication with the servers via HTTP Post - * It accesses the servers according to the job it received and updates said job as it goes - * The method will only iterate once through the server list, removing servers from the list when they are no longer required - * In a POST_MESSAGE job: successful post to a server results in removing the server from the list - * In a GET_REDUNDANCY job: no server is removed from the list and the (absolute) number of servers in which the message was found is returned - * In a READ_MESSAGES job: successful retrieval from any server terminates the method and returns the received values; The list is not changed - * @return The original job, modified to fit the current state and the required output (if any) of the operation - * @throws IllegalArgumentException - * @throws CommunicationException - */ - public BulletinClientJobResult call() throws IllegalArgumentException, CommunicationException{ - - Client client = clientLocal.get(); - Digest digest = digestLocal.get(); - - WebTarget webTarget; - Response response; - - String requestPath; - Message msg; - - List serverAddresses = new LinkedList(job.getServerAddresses()); - - Message payload = job.getPayload(); - - BulletinBoardMessageList msgList; - - int count = 0; // Used to count number of servers which contain the required message in a GET_REDUNDANCY request. - - job.shuffleAddresses(); // This is done to randomize the order of access to servers primarily for READ operations - - // Prepare the request. - switch(job.getJobType()) { - - case POST_MESSAGE: - // Make sure the payload is a BulletinBoardMessage - if (!(payload instanceof BulletinBoardMessage)) { - throw new IllegalArgumentException("Cannot post an object that is not an instance of BulletinBoardMessage"); - } - - msg = payload; - requestPath = Constants.POST_MESSAGE_PATH; - break; - - case READ_MESSAGES: - // Make sure the payload is a MessageFilterList - if (!(payload instanceof MessageFilterList)) { - throw new IllegalArgumentException("Read failed: an instance of MessageFilterList is required as payload for a READ_MESSAGES operation"); - } - - msg = payload; - requestPath = Constants.READ_MESSAGES_PATH; - break; - - case GET_REDUNDANCY: - // Make sure the payload is a MessageId - if (!(payload instanceof MessageID)) { - throw new IllegalArgumentException("Cannot search for an object that is not an instance of MessageID"); - } - - requestPath = Constants.READ_MESSAGES_PATH; - - msg = MessageFilterList.newBuilder() - .addFilter(MessageFilter.newBuilder() - .setType(FilterType.MSG_ID) - .setId(((MessageID) payload).getID()) - .build() - ).build(); - - break; - - default: - throw new IllegalArgumentException("Unsupported job type"); - - } - - // Iterate through servers - - Iterator addressIterator = serverAddresses.iterator(); - - while (addressIterator.hasNext()) { - - // Send request to Server - String address = addressIterator.next(); - webTarget = client.target(address).path(Constants.BULLETIN_BOARD_SERVER_PATH).path(requestPath); - response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(msg, Constants.MEDIATYPE_PROTOBUF)); - - // Retrieve answer - switch(job.getJobType()) { - - case POST_MESSAGE: - try { - - response.readEntity(BoolMsg.class); // If a BoolMsg entity is returned: the post was successful - addressIterator.remove(); // Post to this server succeeded: remove server from list - job.decMinServers(); - - } catch (ProcessingException | IllegalStateException e) {} // Post to this server failed: retry next time - finally { - response.close(); - } - break; - - case GET_REDUNDANCY: - try { - msgList = response.readEntity(BulletinBoardMessageList.class); // If a BulletinBoardMessageList is returned: the read was successful - - if (msgList.getMessageList().size() > 0){ // Message was found in the server. - count++; - } - } catch (ProcessingException | IllegalStateException e) {} // Read failed: try with next server - finally { - response.close(); - } - break; - - case READ_MESSAGES: - try { - msgList = response.readEntity(BulletinBoardMessageList.class); // If a BulletinBoardMessageList is returned: the read was successful - return new BulletinClientJobResult(job, msgList); // Return the result - } catch (ProcessingException | IllegalStateException e) {} // Read failed: try with next server - finally { - response.close(); - } - break; - - } - - } - - // Return result (if haven't done so yet) - switch(job.getJobType()) { - - case POST_MESSAGE: - // The job now contains the information required to ascertain whether enough server posts have succeeded - // It will also contain the list of servers in which the post was not successful - job.updateServerAddresses(serverAddresses); - return new BulletinClientJobResult(job, null); - - case GET_REDUNDANCY: - // Return the number of servers in which the message was found - // The job now contains the list of these servers - return new BulletinClientJobResult(job, IntMsg.newBuilder().setValue(count).build()); - - case READ_MESSAGES: - // A successful operation would have already returned an output - // Therefore: no server access was successful - throw new CommunicationException("Could not access any server"); - - default: // This is required for successful compilation - throw new IllegalArgumentException("Unsupported job type"); - - } - } -} +package meerkat.bulletinboard; + +import com.google.protobuf.Message; +import meerkat.comm.CommunicationException; +import meerkat.crypto.Digest; +import meerkat.crypto.concrete.SHA256Digest; +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.rest.Constants; +import meerkat.rest.ProtobufMessageBodyReader; +import meerkat.rest.ProtobufMessageBodyWriter; + +import javax.ws.rs.ProcessingException; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Response; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.Callable; + +/** + * Created by Arbel Deutsch Peled on 09-Dec-15. + * + * This class implements the actual communication with the Bulletin Board Servers. + * It is meant to be used in a multi-threaded environment. + */ +//TODO: Maybe make this abstract and inherit from it. +public class BulletinClientWorker implements Callable { + + private final BulletinClientJob job; // The requested job to be handled + + public BulletinClientWorker(BulletinClientJob job){ + this.job = job; + } + + // This resource enabled creation of a single Client per thread. + private static final ThreadLocal clientLocal = + new ThreadLocal () { + @Override protected Client initialValue() { + Client client; + client = ClientBuilder.newClient(); + client.register(ProtobufMessageBodyReader.class); + client.register(ProtobufMessageBodyWriter.class); + + return client; + } + }; + + // This resource enables creation of a single Digest per thread. + private static final ThreadLocal digestLocal = + new ThreadLocal () { + @Override protected Digest initialValue() { + Digest digest; + digest = new SHA256Digest(); //TODO: Make this generic. + + return digest; + } + }; + + /** + * This method carries out the actual communication with the servers via HTTP Post + * It accesses the servers according to the job it received and updates said job as it goes + * The method will only iterate once through the server list, removing servers from the list when they are no longer required + * In a POST_MESSAGE job: successful post to a server results in removing the server from the list + * In a GET_REDUNDANCY job: no server is removed from the list and the (absolute) number of servers in which the message was found is returned + * In a READ_MESSAGES job: successful retrieval from any server terminates the method and returns the received values; The list is not changed + * @return The original job, modified to fit the current state and the required output (if any) of the operation + * @throws IllegalArgumentException + * @throws CommunicationException + */ + public BulletinClientJobResult call() throws IllegalArgumentException, CommunicationException{ + + Client client = clientLocal.get(); + Digest digest = digestLocal.get(); + + WebTarget webTarget; + Response response; + + String requestPath; + Message msg; + + List serverAddresses = new LinkedList(job.getServerAddresses()); + + Message payload = job.getPayload(); + + BulletinBoardMessageList msgList; + + int count = 0; // Used to count number of servers which contain the required message in a GET_REDUNDANCY request. + + job.shuffleAddresses(); // This is done to randomize the order of access to servers primarily for READ operations + + // Prepare the request. + switch(job.getJobType()) { + + case POST_MESSAGE: + // Make sure the payload is a BulletinBoardMessage + if (!(payload instanceof BulletinBoardMessage)) { + throw new IllegalArgumentException("Cannot post an object that is not an instance of BulletinBoardMessage"); + } + + msg = payload; + requestPath = Constants.POST_MESSAGE_PATH; + break; + + case READ_MESSAGES: + // Make sure the payload is a MessageFilterList + if (!(payload instanceof MessageFilterList)) { + throw new IllegalArgumentException("Read failed: an instance of MessageFilterList is required as payload for a READ_MESSAGES operation"); + } + + msg = payload; + requestPath = Constants.READ_MESSAGES_PATH; + break; + + case GET_REDUNDANCY: + // Make sure the payload is a MessageId + if (!(payload instanceof MessageID)) { + throw new IllegalArgumentException("Cannot search for an object that is not an instance of MessageID"); + } + + requestPath = Constants.READ_MESSAGES_PATH; + + msg = MessageFilterList.newBuilder() + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.MSG_ID) + .setId(((MessageID) payload).getID()) + .build() + ).build(); + + break; + + default: + throw new IllegalArgumentException("Unsupported job type"); + + } + + // Iterate through servers + + Iterator addressIterator = serverAddresses.iterator(); + + while (addressIterator.hasNext()) { + + // Send request to Server + String address = addressIterator.next(); + webTarget = client.target(address).path(Constants.BULLETIN_BOARD_SERVER_PATH).path(requestPath); + response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(msg, Constants.MEDIATYPE_PROTOBUF)); + + // Retrieve answer + switch(job.getJobType()) { + + case POST_MESSAGE: + try { + + response.readEntity(BoolMsg.class); // If a BoolMsg entity is returned: the post was successful + addressIterator.remove(); // Post to this server succeeded: remove server from list + job.decMinServers(); + + } catch (ProcessingException | IllegalStateException e) {} // Post to this server failed: retry next time + finally { + response.close(); + } + break; + + case GET_REDUNDANCY: + try { + msgList = response.readEntity(BulletinBoardMessageList.class); // If a BulletinBoardMessageList is returned: the read was successful + + if (msgList.getMessageList().size() > 0){ // Message was found in the server. + count++; + } + } catch (ProcessingException | IllegalStateException e) {} // Read failed: try with next server + finally { + response.close(); + } + break; + + case READ_MESSAGES: + try { + msgList = response.readEntity(BulletinBoardMessageList.class); // If a BulletinBoardMessageList is returned: the read was successful + return new BulletinClientJobResult(job, msgList); // Return the result + } catch (ProcessingException | IllegalStateException e) {} // Read failed: try with next server + finally { + response.close(); + } + break; + + } + + } + + // Return result (if haven't done so yet) + switch(job.getJobType()) { + + case POST_MESSAGE: + // The job now contains the information required to ascertain whether enough server posts have succeeded + // It will also contain the list of servers in which the post was not successful + job.updateServerAddresses(serverAddresses); + return new BulletinClientJobResult(job, null); + + case GET_REDUNDANCY: + // Return the number of servers in which the message was found + // The job now contains the list of these servers + return new BulletinClientJobResult(job, IntMsg.newBuilder().setValue(count).build()); + + case READ_MESSAGES: + // A successful operation would have already returned an output + // Therefore: no server access was successful + throw new CommunicationException("Could not access any server"); + + default: // This is required for successful compilation + throw new IllegalArgumentException("Unsupported job type"); + + } + } +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java index f340cae..9d3f24a 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java @@ -1,161 +1,161 @@ -package meerkat.bulletinboard; - -import com.google.protobuf.ByteString; -import meerkat.comm.CommunicationException; -import meerkat.crypto.Digest; -import meerkat.crypto.concrete.SHA256Digest; -import meerkat.protobuf.BulletinBoardAPI.*; -import meerkat.protobuf.Voting; -import meerkat.protobuf.Voting.BulletinBoardClientParams; -import meerkat.rest.*; - -import java.util.List; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.Response; - -/** - * Created by Arbel Deutsch Peled on 05-Dec-15. - */ -public class SimpleBulletinBoardClient{ //implements BulletinBoardClient { - - private List meerkatDBs; - - private Client client; - - private Digest digest; - - /** - * Stores database locations and initializes the web Client - * @param clientParams contains the data needed to access the DBs - */ -// @Override - public void init(Voting.BulletinBoardClientParams clientParams) { - - meerkatDBs = clientParams.getBulletinBoardAddressList(); - - client = ClientBuilder.newClient(); - client.register(ProtobufMessageBodyReader.class); - client.register(ProtobufMessageBodyWriter.class); - - digest = new SHA256Digest(); - - } - - /** - * Post message to all DBs - * Make only one try per DB. - * @param msg is the message, - * @return the message ID for later retrieval - * @throws CommunicationException - */ -// @Override - public MessageID postMessage(BulletinBoardMessage msg) throws CommunicationException { - - WebTarget webTarget; - Response response; - - // Post message to all databases - try { - for (String db : meerkatDBs) { - webTarget = client.target(db).path(Constants.BULLETIN_BOARD_SERVER_PATH).path(Constants.POST_MESSAGE_PATH); - response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(msg, Constants.MEDIATYPE_PROTOBUF)); - - // Only consider valid responses - if (response.getStatusInfo() == Response.Status.OK - || response.getStatusInfo() == Response.Status.CREATED) { - response.readEntity(BoolMsg.class).getValue(); - } - } - } catch (Exception e) { // Occurs only when server replies with valid status but invalid data - throw new CommunicationException("Error accessing database: " + e.getMessage()); - } - - // Calculate the correct message ID and return it - digest.reset(); - digest.update(msg.getMsg()); - return MessageID.newBuilder().setID(ByteString.copyFrom(digest.digest())).build(); - } - - /** - * Access each database and search for a given message ID - * Return the number of databases in which the message was found - * Only try once per DB - * Ignore communication exceptions in specific databases - * @param id is the requested message ID - * @return the number of DBs in which retrieval was successful - */ -// @Override - public float getRedundancy(MessageID id) { - WebTarget webTarget; - Response response; - - MessageFilterList filterList = MessageFilterList.newBuilder() - .addFilter(MessageFilter.newBuilder() - .setType(FilterType.MSG_ID) - .setId(id.getID()) - .build()) - .build(); - - float count = 0; - - for (String db : meerkatDBs) { - try { - webTarget = client.target(db).path(Constants.BULLETIN_BOARD_SERVER_PATH).path(Constants.READ_MESSAGES_PATH); - - response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(filterList, Constants.MEDIATYPE_PROTOBUF)); - - if (response.readEntity(BulletinBoardMessageList.class).getMessageCount() > 0){ - count++; - } - - } catch (Exception e) {} - } - - return count / ((float) meerkatDBs.size()); - } - - /** - * Go through the DBs and try to retrieve messages according to the specified filter - * If at the operation is successful for some DB: return the results and stop iterating - * If no operation is successful: return null (NOT blank list) - * @param filterList return only messages that match the filters (null means no filtering). - * @return - */ -// @Override - public List readMessages(MessageFilterList filterList) { - WebTarget webTarget; - Response response; - BulletinBoardMessageList messageList; - - // Replace null filter list with blank one. - if (filterList == null){ - filterList = MessageFilterList.newBuilder().build(); - } - - for (String db : meerkatDBs) { - try { - webTarget = client.target(db).path(Constants.BULLETIN_BOARD_SERVER_PATH).path(Constants.READ_MESSAGES_PATH); - - response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(filterList, Constants.MEDIATYPE_PROTOBUF)); - - messageList = response.readEntity(BulletinBoardMessageList.class); - - if (messageList != null){ - return messageList.getMessageList(); - } - - } catch (Exception e) {} - } - - return null; - } - -// @Override -// public void registerNewMessageCallback(MessageCallback callback, MessageFilterList filterList) { -// callback.handleNewMessage(readMessages(filterList)); -// } -} +package meerkat.bulletinboard; + +import com.google.protobuf.ByteString; +import meerkat.comm.CommunicationException; +import meerkat.crypto.Digest; +import meerkat.crypto.concrete.SHA256Digest; +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Voting; +import meerkat.protobuf.Voting.BulletinBoardClientParams; +import meerkat.rest.*; + +import java.util.List; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Response; + +/** + * Created by Arbel Deutsch Peled on 05-Dec-15. + */ +public class SimpleBulletinBoardClient{ //implements BulletinBoardClient { + + private List meerkatDBs; + + private Client client; + + private Digest digest; + + /** + * Stores database locations and initializes the web Client + * @param clientParams contains the data needed to access the DBs + */ +// @Override + public void init(Voting.BulletinBoardClientParams clientParams) { + + meerkatDBs = clientParams.getBulletinBoardAddressList(); + + client = ClientBuilder.newClient(); + client.register(ProtobufMessageBodyReader.class); + client.register(ProtobufMessageBodyWriter.class); + + digest = new SHA256Digest(); + + } + + /** + * Post message to all DBs + * Make only one try per DB. + * @param msg is the message, + * @return the message ID for later retrieval + * @throws CommunicationException + */ +// @Override + public MessageID postMessage(BulletinBoardMessage msg) throws CommunicationException { + + WebTarget webTarget; + Response response; + + // Post message to all databases + try { + for (String db : meerkatDBs) { + webTarget = client.target(db).path(Constants.BULLETIN_BOARD_SERVER_PATH).path(Constants.POST_MESSAGE_PATH); + response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(msg, Constants.MEDIATYPE_PROTOBUF)); + + // Only consider valid responses + if (response.getStatusInfo() == Response.Status.OK + || response.getStatusInfo() == Response.Status.CREATED) { + response.readEntity(BoolMsg.class).getValue(); + } + } + } catch (Exception e) { // Occurs only when server replies with valid status but invalid data + throw new CommunicationException("Error accessing database: " + e.getMessage()); + } + + // Calculate the correct message ID and return it + digest.reset(); + digest.update(msg.getMsg()); + return MessageID.newBuilder().setID(ByteString.copyFrom(digest.digest())).build(); + } + + /** + * Access each database and search for a given message ID + * Return the number of databases in which the message was found + * Only try once per DB + * Ignore communication exceptions in specific databases + * @param id is the requested message ID + * @return the number of DBs in which retrieval was successful + */ +// @Override + public float getRedundancy(MessageID id) { + WebTarget webTarget; + Response response; + + MessageFilterList filterList = MessageFilterList.newBuilder() + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.MSG_ID) + .setId(id.getID()) + .build()) + .build(); + + float count = 0; + + for (String db : meerkatDBs) { + try { + webTarget = client.target(db).path(Constants.BULLETIN_BOARD_SERVER_PATH).path(Constants.READ_MESSAGES_PATH); + + response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(filterList, Constants.MEDIATYPE_PROTOBUF)); + + if (response.readEntity(BulletinBoardMessageList.class).getMessageCount() > 0){ + count++; + } + + } catch (Exception e) {} + } + + return count / ((float) meerkatDBs.size()); + } + + /** + * Go through the DBs and try to retrieve messages according to the specified filter + * If at the operation is successful for some DB: return the results and stop iterating + * If no operation is successful: return null (NOT blank list) + * @param filterList return only messages that match the filters (null means no filtering). + * @return + */ +// @Override + public List readMessages(MessageFilterList filterList) { + WebTarget webTarget; + Response response; + BulletinBoardMessageList messageList; + + // Replace null filter list with blank one. + if (filterList == null){ + filterList = MessageFilterList.newBuilder().build(); + } + + for (String db : meerkatDBs) { + try { + webTarget = client.target(db).path(Constants.BULLETIN_BOARD_SERVER_PATH).path(Constants.READ_MESSAGES_PATH); + + response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(filterList, Constants.MEDIATYPE_PROTOBUF)); + + messageList = response.readEntity(BulletinBoardMessageList.class); + + if (messageList != null){ + return messageList.getMessageList(); + } + + } catch (Exception e) {} + } + + return null; + } + +// @Override +// public void registerNewMessageCallback(MessageCallback callback, MessageFilterList filterList) { +// callback.handleNewMessage(readMessages(filterList)); +// } +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java index bb46c32..81513f8 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java @@ -1,131 +1,131 @@ -package meerkat.bulletinboard; - -import com.google.common.util.concurrent.*; -import com.google.protobuf.ByteString; -import meerkat.bulletinboard.callbacks.GetRedundancyFutureCallback; -import meerkat.bulletinboard.callbacks.PostMessageFutureCallback; -import meerkat.bulletinboard.callbacks.ReadMessagesFutureCallback; -import meerkat.comm.CommunicationException; -import meerkat.crypto.Digest; -import meerkat.crypto.concrete.SHA256Digest; -import meerkat.protobuf.BulletinBoardAPI.*; -import meerkat.protobuf.Voting; - -import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -/** - * Created by Arbel Deutsch Peled on 05-Dec-15. - * Thread-based implementation of a Bulletin Board Client. - * Features: - * 1. Handles tasks concurrently. - * 2. Retries submitting - */ -public class ThreadedBulletinBoardClient implements BulletinBoardClient { - - private final static int THREAD_NUM = 10; - ListeningExecutorService listeningExecutor; - - private Digest digest; - - private List meerkatDBs; - private String postSubAddress; - private String readSubAddress; - - private final static int READ_MESSAGES_RETRY_NUM = 1; - - private int minAbsoluteRedundancy; - - /** - * Stores database locations and initializes the web Client - * Stores the required minimum redundancy. - * Starts the Thread Pool. - * @param clientParams contains the required information - */ - @Override - public void init(Voting.BulletinBoardClientParams clientParams) { - - meerkatDBs = clientParams.getBulletinBoardAddressList(); - - minAbsoluteRedundancy = (int) (clientParams.getMinRedundancy() * meerkatDBs.size()); - - listeningExecutor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(THREAD_NUM)); - - digest = new SHA256Digest(); - - } - - /** - * Post message to all DBs - * Retry failed DBs - * @param msg is the message, - * @return the message ID for later retrieval - * @throws CommunicationException - */ - @Override - public MessageID postMessage(BulletinBoardMessage msg, ClientCallback callback){ - - // Create job - BulletinClientJob job = new BulletinClientJob(meerkatDBs, minAbsoluteRedundancy, BulletinClientJob.JobType.POST_MESSAGE, msg, -1); - - // Submit job and create callback - Futures.addCallback(listeningExecutor.submit(new BulletinClientWorker(job)), new PostMessageFutureCallback(listeningExecutor, callback)); - - // Calculate the correct message ID and return it - digest.reset(); - digest.update(msg.getMsg()); - return MessageID.newBuilder().setID(ByteString.copyFrom(digest.digest())).build(); - } - - /** - * Access each database and search for a given message ID - * Return the number of databases in which the message was found - * Only try once per DB - * Ignore communication exceptions in specific databases - * @param id is the requested message ID - * @return the number of DBs in which retrieval was successful - */ - @Override - public void getRedundancy(MessageID id, ClientCallback callback) { - - // Create job - BulletinClientJob job = new BulletinClientJob(meerkatDBs, minAbsoluteRedundancy, BulletinClientJob.JobType.GET_REDUNDANCY, id, 1); - - // Submit job and create callback - Futures.addCallback(listeningExecutor.submit(new BulletinClientWorker(job)), new GetRedundancyFutureCallback(listeningExecutor, callback)); - - } - - /** - * Go through the DBs and try to retrieve messages according to the specified filter - * If at the operation is successful for some DB: return the results and stop iterating - * If no operation is successful: return null (NOT blank list) - * @param filterList return only messages that match the filters (null means no filtering). - * @return - */ - @Override - public void readMessages(MessageFilterList filterList, ClientCallback> callback) { - - // Create job - BulletinClientJob job = new BulletinClientJob(meerkatDBs, minAbsoluteRedundancy, BulletinClientJob.JobType.READ_MESSAGES, - filterList, READ_MESSAGES_RETRY_NUM); - - // Submit job and create callback - Futures.addCallback(listeningExecutor.submit(new BulletinClientWorker(job)), new ReadMessagesFutureCallback(listeningExecutor, callback)); - - } - - @Override - public void close() { - try { - listeningExecutor.shutdown(); - while (! listeningExecutor.isShutdown()) { - listeningExecutor.awaitTermination(10, TimeUnit.SECONDS); - } - } catch (InterruptedException e) { - System.err.println(e.getCause() + " " + e.getMessage()); - } - } - -} +package meerkat.bulletinboard; + +import com.google.common.util.concurrent.*; +import com.google.protobuf.ByteString; +import meerkat.bulletinboard.callbacks.GetRedundancyFutureCallback; +import meerkat.bulletinboard.callbacks.PostMessageFutureCallback; +import meerkat.bulletinboard.callbacks.ReadMessagesFutureCallback; +import meerkat.comm.CommunicationException; +import meerkat.crypto.Digest; +import meerkat.crypto.concrete.SHA256Digest; +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Voting; + +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * Created by Arbel Deutsch Peled on 05-Dec-15. + * Thread-based implementation of a Bulletin Board Client. + * Features: + * 1. Handles tasks concurrently. + * 2. Retries submitting + */ +public class ThreadedBulletinBoardClient implements BulletinBoardClient { + + private final static int THREAD_NUM = 10; + ListeningExecutorService listeningExecutor; + + private Digest digest; + + private List meerkatDBs; + private String postSubAddress; + private String readSubAddress; + + private final static int READ_MESSAGES_RETRY_NUM = 1; + + private int minAbsoluteRedundancy; + + /** + * Stores database locations and initializes the web Client + * Stores the required minimum redundancy. + * Starts the Thread Pool. + * @param clientParams contains the required information + */ + @Override + public void init(Voting.BulletinBoardClientParams clientParams) { + + meerkatDBs = clientParams.getBulletinBoardAddressList(); + + minAbsoluteRedundancy = (int) (clientParams.getMinRedundancy() * meerkatDBs.size()); + + listeningExecutor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(THREAD_NUM)); + + digest = new SHA256Digest(); + + } + + /** + * Post message to all DBs + * Retry failed DBs + * @param msg is the message, + * @return the message ID for later retrieval + * @throws CommunicationException + */ + @Override + public MessageID postMessage(BulletinBoardMessage msg, ClientCallback callback){ + + // Create job + BulletinClientJob job = new BulletinClientJob(meerkatDBs, minAbsoluteRedundancy, BulletinClientJob.JobType.POST_MESSAGE, msg, -1); + + // Submit job and create callback + Futures.addCallback(listeningExecutor.submit(new BulletinClientWorker(job)), new PostMessageFutureCallback(listeningExecutor, callback)); + + // Calculate the correct message ID and return it + digest.reset(); + digest.update(msg.getMsg()); + return MessageID.newBuilder().setID(ByteString.copyFrom(digest.digest())).build(); + } + + /** + * Access each database and search for a given message ID + * Return the number of databases in which the message was found + * Only try once per DB + * Ignore communication exceptions in specific databases + * @param id is the requested message ID + * @return the number of DBs in which retrieval was successful + */ + @Override + public void getRedundancy(MessageID id, ClientCallback callback) { + + // Create job + BulletinClientJob job = new BulletinClientJob(meerkatDBs, minAbsoluteRedundancy, BulletinClientJob.JobType.GET_REDUNDANCY, id, 1); + + // Submit job and create callback + Futures.addCallback(listeningExecutor.submit(new BulletinClientWorker(job)), new GetRedundancyFutureCallback(listeningExecutor, callback)); + + } + + /** + * Go through the DBs and try to retrieve messages according to the specified filter + * If at the operation is successful for some DB: return the results and stop iterating + * If no operation is successful: return null (NOT blank list) + * @param filterList return only messages that match the filters (null means no filtering). + * @return + */ + @Override + public void readMessages(MessageFilterList filterList, ClientCallback> callback) { + + // Create job + BulletinClientJob job = new BulletinClientJob(meerkatDBs, minAbsoluteRedundancy, BulletinClientJob.JobType.READ_MESSAGES, + filterList, READ_MESSAGES_RETRY_NUM); + + // Submit job and create callback + Futures.addCallback(listeningExecutor.submit(new BulletinClientWorker(job)), new ReadMessagesFutureCallback(listeningExecutor, callback)); + + } + + @Override + public void close() { + try { + listeningExecutor.shutdown(); + while (! listeningExecutor.isShutdown()) { + listeningExecutor.awaitTermination(10, TimeUnit.SECONDS); + } + } catch (InterruptedException e) { + System.err.println(e.getCause() + " " + e.getMessage()); + } + } + +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ClientFutureCallback.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ClientFutureCallback.java index 7c5b7b0..d682b38 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ClientFutureCallback.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ClientFutureCallback.java @@ -1,25 +1,25 @@ -package meerkat.bulletinboard.callbacks; - -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListeningExecutorService; -import meerkat.bulletinboard.BulletinClientJob; -import meerkat.bulletinboard.BulletinClientJobResult; -import meerkat.bulletinboard.BulletinClientWorker; -import meerkat.protobuf.BulletinBoardAPI; - -import java.util.List; - -/** - * This is a future callback used to listen to workers and run on job finish - * Depending on the type of job and the finishing status of the worker: a decision is made whether to retry or return an error - */ -public abstract class ClientFutureCallback implements FutureCallback { - - protected ListeningExecutorService listeningExecutor; - - ClientFutureCallback(ListeningExecutorService listeningExecutor) { - this.listeningExecutor = listeningExecutor; - } - -} +package meerkat.bulletinboard.callbacks; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListeningExecutorService; +import meerkat.bulletinboard.BulletinClientJob; +import meerkat.bulletinboard.BulletinClientJobResult; +import meerkat.bulletinboard.BulletinClientWorker; +import meerkat.protobuf.BulletinBoardAPI; + +import java.util.List; + +/** + * This is a future callback used to listen to workers and run on job finish + * Depending on the type of job and the finishing status of the worker: a decision is made whether to retry or return an error + */ +public abstract class ClientFutureCallback implements FutureCallback { + + protected ListeningExecutorService listeningExecutor; + + ClientFutureCallback(ListeningExecutorService listeningExecutor) { + this.listeningExecutor = listeningExecutor; + } + +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/GetRedundancyFutureCallback.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/GetRedundancyFutureCallback.java index 518ed77..c083623 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/GetRedundancyFutureCallback.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/GetRedundancyFutureCallback.java @@ -1,38 +1,38 @@ -package meerkat.bulletinboard.callbacks; - -import com.google.common.util.concurrent.ListeningExecutorService; -import meerkat.bulletinboard.BulletinBoardClient; -import meerkat.bulletinboard.BulletinClientJobResult; -import meerkat.protobuf.BulletinBoardAPI.*; - -import java.util.List; - -/** - * This is a future callback used to listen to workers and run on job finish - * Depending on the type of job and the finishing status of the worker: a decision is made whether to retry or return an error - */ -public class GetRedundancyFutureCallback extends ClientFutureCallback { - - private BulletinBoardClient.ClientCallback callback; - - public GetRedundancyFutureCallback(ListeningExecutorService listeningExecutor, - BulletinBoardClient.ClientCallback callback) { - super(listeningExecutor); - this.callback = callback; - } - - @Override - public void onSuccess(BulletinClientJobResult result) { - - int absoluteRedundancy = ((IntMsg) result.getResult()).getValue(); - int totalServers = result.getJob().getServerAddresses().size(); - - callback.handleCallback( ((float) absoluteRedundancy) / ((float) totalServers) ); - - } - - @Override - public void onFailure(Throwable t) { - callback.handleFailure(t); - } -} +package meerkat.bulletinboard.callbacks; + +import com.google.common.util.concurrent.ListeningExecutorService; +import meerkat.bulletinboard.BulletinBoardClient; +import meerkat.bulletinboard.BulletinClientJobResult; +import meerkat.protobuf.BulletinBoardAPI.*; + +import java.util.List; + +/** + * This is a future callback used to listen to workers and run on job finish + * Depending on the type of job and the finishing status of the worker: a decision is made whether to retry or return an error + */ +public class GetRedundancyFutureCallback extends ClientFutureCallback { + + private BulletinBoardClient.ClientCallback callback; + + public GetRedundancyFutureCallback(ListeningExecutorService listeningExecutor, + BulletinBoardClient.ClientCallback callback) { + super(listeningExecutor); + this.callback = callback; + } + + @Override + public void onSuccess(BulletinClientJobResult result) { + + int absoluteRedundancy = ((IntMsg) result.getResult()).getValue(); + int totalServers = result.getJob().getServerAddresses().size(); + + callback.handleCallback( ((float) absoluteRedundancy) / ((float) totalServers) ); + + } + + @Override + public void onFailure(Throwable t) { + callback.handleFailure(t); + } +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/PostMessageFutureCallback.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/PostMessageFutureCallback.java index 221ae1a..71f8ee7 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/PostMessageFutureCallback.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/PostMessageFutureCallback.java @@ -1,46 +1,46 @@ -package meerkat.bulletinboard.callbacks; - -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListeningExecutorService; -import meerkat.bulletinboard.BulletinBoardClient; -import meerkat.bulletinboard.BulletinClientJob; -import meerkat.bulletinboard.BulletinClientJobResult; -import meerkat.bulletinboard.BulletinClientWorker; -import meerkat.protobuf.BulletinBoardAPI; - -import java.util.List; - -/** - * This is a future callback used to listen to workers and run on job finish - * Depending on the type of job and the finishing status of the worker: a decision is made whether to retry or return an error - */ -public class PostMessageFutureCallback extends ClientFutureCallback { - - private BulletinBoardClient.ClientCallback callback; - - public PostMessageFutureCallback(ListeningExecutorService listeningExecutor, - BulletinBoardClient.ClientCallback callback) { - super(listeningExecutor); - this.callback = callback; - } - - @Override - public void onSuccess(BulletinClientJobResult result) { - - BulletinClientJob job = result.getJob(); - - job.decMaxRetry(); - - // If redundancy is below threshold: retry - if (job.getMinServers() > 0 && job.isRetry()) { - Futures.addCallback(listeningExecutor.submit(new BulletinClientWorker(job)), this); - } - - callback.handleCallback(null); - } - - @Override - public void onFailure(Throwable t) { - callback.handleFailure(t); - } -} +package meerkat.bulletinboard.callbacks; + +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListeningExecutorService; +import meerkat.bulletinboard.BulletinBoardClient; +import meerkat.bulletinboard.BulletinClientJob; +import meerkat.bulletinboard.BulletinClientJobResult; +import meerkat.bulletinboard.BulletinClientWorker; +import meerkat.protobuf.BulletinBoardAPI; + +import java.util.List; + +/** + * This is a future callback used to listen to workers and run on job finish + * Depending on the type of job and the finishing status of the worker: a decision is made whether to retry or return an error + */ +public class PostMessageFutureCallback extends ClientFutureCallback { + + private BulletinBoardClient.ClientCallback callback; + + public PostMessageFutureCallback(ListeningExecutorService listeningExecutor, + BulletinBoardClient.ClientCallback callback) { + super(listeningExecutor); + this.callback = callback; + } + + @Override + public void onSuccess(BulletinClientJobResult result) { + + BulletinClientJob job = result.getJob(); + + job.decMaxRetry(); + + // If redundancy is below threshold: retry + if (job.getMinServers() > 0 && job.isRetry()) { + Futures.addCallback(listeningExecutor.submit(new BulletinClientWorker(job)), this); + } + + callback.handleCallback(null); + } + + @Override + public void onFailure(Throwable t) { + callback.handleFailure(t); + } +} diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ReadMessagesFutureCallback.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ReadMessagesFutureCallback.java index 4c43ba2..fe321a4 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ReadMessagesFutureCallback.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/callbacks/ReadMessagesFutureCallback.java @@ -1,38 +1,38 @@ -package meerkat.bulletinboard.callbacks; - -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListeningExecutorService; -import meerkat.bulletinboard.BulletinBoardClient; -import meerkat.bulletinboard.BulletinClientJob; -import meerkat.bulletinboard.BulletinClientJobResult; -import meerkat.bulletinboard.BulletinClientWorker; -import meerkat.protobuf.BulletinBoardAPI; - -import java.util.List; - -/** - * This is a future callback used to listen to workers and run on job finish - * Depending on the type of job and the finishing status of the worker: a decision is made whether to retry or return an error - */ -public class ReadMessagesFutureCallback extends ClientFutureCallback { - - private BulletinBoardClient.ClientCallback> callback; - - public ReadMessagesFutureCallback(ListeningExecutorService listeningExecutor, - BulletinBoardClient.ClientCallback> callback) { - super(listeningExecutor); - this.callback = callback; - } - - @Override - public void onSuccess(BulletinClientJobResult result) { - - callback.handleCallback(((BulletinBoardAPI.BulletinBoardMessageList) result.getResult()).getMessageList()); - - } - - @Override - public void onFailure(Throwable t) { - callback.handleFailure(t); - } -} +package meerkat.bulletinboard.callbacks; + +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListeningExecutorService; +import meerkat.bulletinboard.BulletinBoardClient; +import meerkat.bulletinboard.BulletinClientJob; +import meerkat.bulletinboard.BulletinClientJobResult; +import meerkat.bulletinboard.BulletinClientWorker; +import meerkat.protobuf.BulletinBoardAPI; + +import java.util.List; + +/** + * This is a future callback used to listen to workers and run on job finish + * Depending on the type of job and the finishing status of the worker: a decision is made whether to retry or return an error + */ +public class ReadMessagesFutureCallback extends ClientFutureCallback { + + private BulletinBoardClient.ClientCallback> callback; + + public ReadMessagesFutureCallback(ListeningExecutorService listeningExecutor, + BulletinBoardClient.ClientCallback> callback) { + super(listeningExecutor); + this.callback = callback; + } + + @Override + public void onSuccess(BulletinClientJobResult result) { + + callback.handleCallback(((BulletinBoardAPI.BulletinBoardMessageList) result.getResult()).getMessageList()); + + } + + @Override + public void onFailure(Throwable t) { + callback.handleFailure(t); + } +} diff --git a/bulletin-board-client/src/test/java/BulletinBoardClientIntegrationTest.java b/bulletin-board-client/src/test/java/BulletinBoardClientIntegrationTest.java index dda76c7..b993f1f 100644 --- a/bulletin-board-client/src/test/java/BulletinBoardClientIntegrationTest.java +++ b/bulletin-board-client/src/test/java/BulletinBoardClientIntegrationTest.java @@ -1,214 +1,214 @@ -import com.google.protobuf.ByteString; -import meerkat.bulletinboard.BulletinBoardClient; -import meerkat.bulletinboard.BulletinBoardClient.ClientCallback; -import meerkat.bulletinboard.ThreadedBulletinBoardClient; -import meerkat.protobuf.BulletinBoardAPI.*; -import meerkat.protobuf.Crypto; - -import meerkat.protobuf.Voting.*; -import meerkat.util.BulletinBoardMessageComparator; - -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.*; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.number.OrderingComparison.*; - -import java.util.*; -import java.util.concurrent.Semaphore; - -/** - * Created by Arbel Deutsch Peled on 05-Dec-15. - */ -public class BulletinBoardClientIntegrationTest { - - Semaphore jobSemaphore; - Vector thrown; - - private class PostCallback implements ClientCallback{ - - @Override - public void handleCallback(Object msg) { - System.err.println("Post operation completed"); - jobSemaphore.release(); - } - - @Override - public void handleFailure(Throwable t) { - thrown.add(t); - jobSemaphore.release(); - } - } - - private class RedundancyCallback implements ClientCallback{ - - private float minRedundancy; - - public RedundancyCallback(float minRedundancy) { - this.minRedundancy = minRedundancy; - } - - @Override - public void handleCallback(Float redundancy) { - System.err.println("Redundancy found is: " + redundancy); - jobSemaphore.release(); - assertThat(redundancy, greaterThanOrEqualTo(minRedundancy)); - } - - @Override - public void handleFailure(Throwable t) { - thrown.add(t); - jobSemaphore.release(); - } - } - - private class ReadCallback implements ClientCallback>{ - - private List expectedMsgList; - - public ReadCallback(List expectedMsgList) { - this.expectedMsgList = expectedMsgList; - } - - @Override - public void handleCallback(List messages) { - - System.err.println(messages); - jobSemaphore.release(); - - BulletinBoardMessageComparator msgComparator = new BulletinBoardMessageComparator(); - - assertThat(messages.size(), is(expectedMsgList.size())); - - Iterator expectedMessageIterator = expectedMsgList.iterator(); - Iterator receivedMessageIterator = messages.iterator(); - - while (expectedMessageIterator.hasNext()) { - assertThat(msgComparator.compare(expectedMessageIterator.next(), receivedMessageIterator.next()), is(0)); - } - - } - - @Override - public void handleFailure(Throwable t) { - thrown.add(t); - jobSemaphore.release(); - } - } - - private BulletinBoardClient bulletinBoardClient; - - private PostCallback postCallback; - private RedundancyCallback redundancyCallback; - private ReadCallback readCallback; - - private static String PROP_GETTY_URL = "gretty.httpBaseURI"; - private static String DEFAULT_BASE_URL = "http://localhost:8081"; - private static String BASE_URL = System.getProperty(PROP_GETTY_URL, DEFAULT_BASE_URL); - - @Before - public void init(){ - - bulletinBoardClient = new ThreadedBulletinBoardClient(); - - List testDB = new LinkedList(); - testDB.add(BASE_URL); - - bulletinBoardClient.init(BulletinBoardClientParams.newBuilder() - .addBulletinBoardAddress("http://localhost:8081") - .setMinRedundancy((float) 1.0) - .build()); - - postCallback = new PostCallback(); - redundancyCallback = new RedundancyCallback((float) 1.0); - - thrown = new Vector<>(); - jobSemaphore = new Semaphore(0); - - } - - @Test - public void postTest() { - - byte[] b1 = {(byte) 1, (byte) 2, (byte) 3, (byte) 4}; - byte[] b2 = {(byte) 11, (byte) 12, (byte) 13, (byte) 14}; - byte[] b3 = {(byte) 21, (byte) 22, (byte) 23, (byte) 24}; - byte[] b4 = {(byte) 4, (byte) 5, (byte) 100, (byte) -50, (byte) 0}; - - BulletinBoardMessage msg; - - MessageFilterList filterList; - List msgList; - - MessageID messageID; - - Comparator msgComparator = new BulletinBoardMessageComparator(); - - msg = BulletinBoardMessage.newBuilder() - .setMsg(UnsignedBulletinBoardMessage.newBuilder() - .addTag("Signature") - .addTag("Trustee") - .setData(ByteString.copyFrom(b1)) - .build()) - .addSig(Crypto.Signature.newBuilder() - .setType(Crypto.SignatureType.DSA) - .setData(ByteString.copyFrom(b2)) - .setSignerId(ByteString.copyFrom(b3)) - .build()) - .addSig(Crypto.Signature.newBuilder() - .setType(Crypto.SignatureType.ECDSA) - .setData(ByteString.copyFrom(b3)) - .setSignerId(ByteString.copyFrom(b2)) - .build()) - .build(); - - messageID = bulletinBoardClient.postMessage(msg,postCallback); - - try { - jobSemaphore.acquire(); - } catch (InterruptedException e) { - System.err.println(e.getCause() + " " + e.getMessage()); - } - - bulletinBoardClient.getRedundancy(messageID,redundancyCallback); - - filterList = MessageFilterList.newBuilder() - .addFilter( - MessageFilter.newBuilder() - .setType(FilterType.TAG) - .setTag("Signature") - .build() - ) - .addFilter( - MessageFilter.newBuilder() - .setType(FilterType.TAG) - .setTag("Trustee") - .build() - ) - .build(); - - msgList = new LinkedList(); - msgList.add(msg); - - readCallback = new ReadCallback(msgList); - - bulletinBoardClient.readMessages(filterList, readCallback); - try { - jobSemaphore.acquire(2); - } catch (InterruptedException e) { - System.err.println(e.getCause() + " " + e.getMessage()); - } - - bulletinBoardClient.close(); - - for (Throwable t : thrown) { - System.err.println(t.getMessage()); - } - if (thrown.size() > 0) { - assert false; - } - - } - -} +import com.google.protobuf.ByteString; +import meerkat.bulletinboard.BulletinBoardClient; +import meerkat.bulletinboard.BulletinBoardClient.ClientCallback; +import meerkat.bulletinboard.ThreadedBulletinBoardClient; +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Crypto; + +import meerkat.protobuf.Voting.*; +import meerkat.util.BulletinBoardMessageComparator; + +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.number.OrderingComparison.*; + +import java.util.*; +import java.util.concurrent.Semaphore; + +/** + * Created by Arbel Deutsch Peled on 05-Dec-15. + */ +public class BulletinBoardClientIntegrationTest { + + Semaphore jobSemaphore; + Vector thrown; + + private class PostCallback implements ClientCallback{ + + @Override + public void handleCallback(Object msg) { + System.err.println("Post operation completed"); + jobSemaphore.release(); + } + + @Override + public void handleFailure(Throwable t) { + thrown.add(t); + jobSemaphore.release(); + } + } + + private class RedundancyCallback implements ClientCallback{ + + private float minRedundancy; + + public RedundancyCallback(float minRedundancy) { + this.minRedundancy = minRedundancy; + } + + @Override + public void handleCallback(Float redundancy) { + System.err.println("Redundancy found is: " + redundancy); + jobSemaphore.release(); + assertThat(redundancy, greaterThanOrEqualTo(minRedundancy)); + } + + @Override + public void handleFailure(Throwable t) { + thrown.add(t); + jobSemaphore.release(); + } + } + + private class ReadCallback implements ClientCallback>{ + + private List expectedMsgList; + + public ReadCallback(List expectedMsgList) { + this.expectedMsgList = expectedMsgList; + } + + @Override + public void handleCallback(List messages) { + + System.err.println(messages); + jobSemaphore.release(); + + BulletinBoardMessageComparator msgComparator = new BulletinBoardMessageComparator(); + + assertThat(messages.size(), is(expectedMsgList.size())); + + Iterator expectedMessageIterator = expectedMsgList.iterator(); + Iterator receivedMessageIterator = messages.iterator(); + + while (expectedMessageIterator.hasNext()) { + assertThat(msgComparator.compare(expectedMessageIterator.next(), receivedMessageIterator.next()), is(0)); + } + + } + + @Override + public void handleFailure(Throwable t) { + thrown.add(t); + jobSemaphore.release(); + } + } + + private BulletinBoardClient bulletinBoardClient; + + private PostCallback postCallback; + private RedundancyCallback redundancyCallback; + private ReadCallback readCallback; + + private static String PROP_GETTY_URL = "gretty.httpBaseURI"; + private static String DEFAULT_BASE_URL = "http://localhost:8081"; + private static String BASE_URL = System.getProperty(PROP_GETTY_URL, DEFAULT_BASE_URL); + + @Before + public void init(){ + + bulletinBoardClient = new ThreadedBulletinBoardClient(); + + List testDB = new LinkedList(); + testDB.add(BASE_URL); + + bulletinBoardClient.init(BulletinBoardClientParams.newBuilder() + .addBulletinBoardAddress("http://localhost:8081") + .setMinRedundancy((float) 1.0) + .build()); + + postCallback = new PostCallback(); + redundancyCallback = new RedundancyCallback((float) 1.0); + + thrown = new Vector<>(); + jobSemaphore = new Semaphore(0); + + } + + @Test + public void postTest() { + + byte[] b1 = {(byte) 1, (byte) 2, (byte) 3, (byte) 4}; + byte[] b2 = {(byte) 11, (byte) 12, (byte) 13, (byte) 14}; + byte[] b3 = {(byte) 21, (byte) 22, (byte) 23, (byte) 24}; + byte[] b4 = {(byte) 4, (byte) 5, (byte) 100, (byte) -50, (byte) 0}; + + BulletinBoardMessage msg; + + MessageFilterList filterList; + List msgList; + + MessageID messageID; + + Comparator msgComparator = new BulletinBoardMessageComparator(); + + msg = BulletinBoardMessage.newBuilder() + .setMsg(UnsignedBulletinBoardMessage.newBuilder() + .addTag("Signature") + .addTag("Trustee") + .setData(ByteString.copyFrom(b1)) + .build()) + .addSig(Crypto.Signature.newBuilder() + .setType(Crypto.SignatureType.DSA) + .setData(ByteString.copyFrom(b2)) + .setSignerId(ByteString.copyFrom(b3)) + .build()) + .addSig(Crypto.Signature.newBuilder() + .setType(Crypto.SignatureType.ECDSA) + .setData(ByteString.copyFrom(b3)) + .setSignerId(ByteString.copyFrom(b2)) + .build()) + .build(); + + messageID = bulletinBoardClient.postMessage(msg,postCallback); + + try { + jobSemaphore.acquire(); + } catch (InterruptedException e) { + System.err.println(e.getCause() + " " + e.getMessage()); + } + + bulletinBoardClient.getRedundancy(messageID,redundancyCallback); + + filterList = MessageFilterList.newBuilder() + .addFilter( + MessageFilter.newBuilder() + .setType(FilterType.TAG) + .setTag("Signature") + .build() + ) + .addFilter( + MessageFilter.newBuilder() + .setType(FilterType.TAG) + .setTag("Trustee") + .build() + ) + .build(); + + msgList = new LinkedList(); + msgList.add(msg); + + readCallback = new ReadCallback(msgList); + + bulletinBoardClient.readMessages(filterList, readCallback); + try { + jobSemaphore.acquire(2); + } catch (InterruptedException e) { + System.err.println(e.getCause() + " " + e.getMessage()); + } + + bulletinBoardClient.close(); + + for (Throwable t : thrown) { + System.err.println(t.getMessage()); + } + if (thrown.size() > 0) { + assert false; + } + + } + +} diff --git a/bulletin-board-server/.gitignore b/bulletin-board-server/.gitignore index ae3c172..3e2fcc7 100644 --- a/bulletin-board-server/.gitignore +++ b/bulletin-board-server/.gitignore @@ -1 +1 @@ -/bin/ +/bin/ diff --git a/bulletin-board-server/build.gradle b/bulletin-board-server/build.gradle index 0bc5452..772fb14 100644 --- a/bulletin-board-server/build.gradle +++ b/bulletin-board-server/build.gradle @@ -1,241 +1,241 @@ - -plugins { - id "us.kirchmeier.capsule" version "1.0.1" - id 'com.google.protobuf' version '0.7.0' - id 'org.akhikhl.gretty' version "1.2.4" -} - -apply plugin: 'org.akhikhl.gretty' -apply plugin: 'java' -apply plugin: 'eclipse' -apply plugin: 'idea' - -//apply plugin: 'application' - -//apply plugin: 'jetty' -//mainClassName = 'SQLiteIntegrationTest' - -apply plugin: 'maven-publish' - -// Is this a snapshot version? -ext { isSnapshot = false } - -ext { - groupId = 'org.factcenter.meerkat' - nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/" - - // Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing) - // Should be set in ${HOME}/.gradle/gradle.properties - nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : "" - nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : "" -} - -description = "Bulletin-board server web application" - -// Your project version -version = "0.0.1" - -version += "${isSnapshot ? '-SNAPSHOT' : ''}" - - -dependencies { - // Meerkat common - compile project(':meerkat-common') - compile project(':restful-api-common') - - // Jersey for RESTful API - compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.22.+' - - // JDBC connections - compile 'org.springframework:spring-jdbc:4.2.+' - compile 'org.xerial:sqlite-jdbc:3.7.+' - compile 'mysql:mysql-connector-java:5.1.+' - compile 'com.h2database:h2:1.0.+' - - // Servlets - compile 'javax.servlet:javax.servlet-api:3.0.+' - - // Logging - compile 'org.slf4j:slf4j-api:1.7.7' - runtime 'ch.qos.logback:logback-classic:1.1.2' - runtime 'ch.qos.logback:logback-core:1.1.2' - - // Google protobufs - compile 'com.google.protobuf:protobuf-java:3.+' - - // Depend on test resources from meerkat-common - testCompile project(path: ':meerkat-common', configuration: 'testOutput') - - testCompile 'junit:junit:4.+' - - runtime 'org.codehaus.groovy:groovy:2.4.+' -} - - -test { - exclude '**/*SQLite*Test*' - exclude '**/*H2*Test*' - exclude '**/*MySQL*Test*' - exclude '**/*IntegrationTest*' -} - -task dbTest(type: Test) { - include '**/*H2*Test*' - include '**/*MySql*Test' -} - -task integrationTest(type: Test) { - include '**/*IntegrationTest*' -// debug = true - outputs.upToDateWhen { false } - -} - -gretty { - httpPort = 8081 - contextPath = '/' - integrationTestTask = 'integrationTest' - loggingLevel = 'TRACE' - debugPort = 5006 -} - - - -/*==== You probably don't have to edit below this line =======*/ - -protobuf { - // Configure the protoc executable - protoc { - // Download from repositories - artifact = 'com.google.protobuf:protoc:3.+' - } -} - - -idea { - module { - project.sourceSets.each { sourceSet -> - - def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java" - - // add protobuf generated sources to generated source dir. - if ("test".equals(sourceSet.name)) { - testSourceDirs += file(srcDir) - } else { - sourceDirs += file(srcDir) - } - generatedSourceDirs += file(srcDir) - - } - - // Don't exclude build directory - excludeDirs -= file(buildDir) - } -} - - -/*=================================== - * "Fat" Build targets - *===================================*/ - -if (project.hasProperty('mainClassName') && (mainClassName != null)) { - - task mavenCapsule(type: MavenCapsule) { - description = "Generate a capsule jar that automatically downloads and caches dependencies when run." - applicationClass mainClassName - destinationDir = buildDir - } - - task fatCapsule(type: FatCapsule) { - description = "Generate a single capsule jar containing everything. Use -Pfatmain=... to override main class" - - destinationDir = buildDir - - def fatMain = hasProperty('fatmain') ? fatmain : mainClassName - - applicationClass fatMain - - def testJar = hasProperty('test') - - if (hasProperty('fatmain')) { - appendix = "fat-${fatMain}" - } else { - appendix = "fat" - } - - if (testJar) { - from sourceSets.test.output - } - } -} - -/*=================================== - * Repositories - *===================================*/ - -repositories { - - // Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral) - maven { - url nexusRepository - - if (isSnapshot) { - credentials { username - password - - username nexusUser - password nexusPassword - } - } - } - - // Use local maven repository - mavenLocal() - - jcenter() - - // Use 'maven central' for other dependencies. - mavenCentral() -} - -task "info" << { - println "Project: ${project.name}" -println "Description: ${project.description}" - println "--------------------------" - println "GroupId: $groupId" - println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})" - println "" -} -info.description 'Print some information about project parameters' - - -/*=================================== - * Publishing - *===================================*/ - -publishing { - publications { - mavenJava(MavenPublication) { - groupId project.groupId - pom.withXml { - asNode().appendNode('description', project.description) - } - from project.components.java - - } - } - repositories { - maven { - url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}" - credentials { username - password - - username nexusUser - password nexusPassword - } - } - } -} - - - + +plugins { + id "us.kirchmeier.capsule" version "1.0.1" + id 'com.google.protobuf' version '0.7.0' + id 'org.akhikhl.gretty' version "1.2.4" +} + +apply plugin: 'org.akhikhl.gretty' +apply plugin: 'java' +apply plugin: 'eclipse' +apply plugin: 'idea' + +//apply plugin: 'application' + +//apply plugin: 'jetty' +//mainClassName = 'SQLiteIntegrationTest' + +apply plugin: 'maven-publish' + +// Is this a snapshot version? +ext { isSnapshot = false } + +ext { + groupId = 'org.factcenter.meerkat' + nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/" + + // Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing) + // Should be set in ${HOME}/.gradle/gradle.properties + nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : "" + nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : "" +} + +description = "Bulletin-board server web application" + +// Your project version +version = "0.0.1" + +version += "${isSnapshot ? '-SNAPSHOT' : ''}" + + +dependencies { + // Meerkat common + compile project(':meerkat-common') + compile project(':restful-api-common') + + // Jersey for RESTful API + compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.22.+' + + // JDBC connections + compile 'org.springframework:spring-jdbc:4.2.+' + compile 'org.xerial:sqlite-jdbc:3.7.+' + compile 'mysql:mysql-connector-java:5.1.+' + compile 'com.h2database:h2:1.0.+' + + // Servlets + compile 'javax.servlet:javax.servlet-api:3.0.+' + + // Logging + compile 'org.slf4j:slf4j-api:1.7.7' + runtime 'ch.qos.logback:logback-classic:1.1.2' + runtime 'ch.qos.logback:logback-core:1.1.2' + + // Google protobufs + compile 'com.google.protobuf:protobuf-java:3.+' + + // Depend on test resources from meerkat-common + testCompile project(path: ':meerkat-common', configuration: 'testOutput') + + testCompile 'junit:junit:4.+' + + runtime 'org.codehaus.groovy:groovy:2.4.+' +} + + +test { + exclude '**/*SQLite*Test*' + exclude '**/*H2*Test*' + exclude '**/*MySQL*Test*' + exclude '**/*IntegrationTest*' +} + +task dbTest(type: Test) { + include '**/*H2*Test*' + include '**/*MySql*Test' +} + +task integrationTest(type: Test) { + include '**/*IntegrationTest*' +// debug = true + outputs.upToDateWhen { false } + +} + +gretty { + httpPort = 8081 + contextPath = '/' + integrationTestTask = 'integrationTest' + loggingLevel = 'TRACE' + debugPort = 5006 +} + + + +/*==== You probably don't have to edit below this line =======*/ + +protobuf { + // Configure the protoc executable + protoc { + // Download from repositories + artifact = 'com.google.protobuf:protoc:3.+' + } +} + + +idea { + module { + project.sourceSets.each { sourceSet -> + + def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java" + + // add protobuf generated sources to generated source dir. + if ("test".equals(sourceSet.name)) { + testSourceDirs += file(srcDir) + } else { + sourceDirs += file(srcDir) + } + generatedSourceDirs += file(srcDir) + + } + + // Don't exclude build directory + excludeDirs -= file(buildDir) + } +} + + +/*=================================== + * "Fat" Build targets + *===================================*/ + +if (project.hasProperty('mainClassName') && (mainClassName != null)) { + + task mavenCapsule(type: MavenCapsule) { + description = "Generate a capsule jar that automatically downloads and caches dependencies when run." + applicationClass mainClassName + destinationDir = buildDir + } + + task fatCapsule(type: FatCapsule) { + description = "Generate a single capsule jar containing everything. Use -Pfatmain=... to override main class" + + destinationDir = buildDir + + def fatMain = hasProperty('fatmain') ? fatmain : mainClassName + + applicationClass fatMain + + def testJar = hasProperty('test') + + if (hasProperty('fatmain')) { + appendix = "fat-${fatMain}" + } else { + appendix = "fat" + } + + if (testJar) { + from sourceSets.test.output + } + } +} + +/*=================================== + * Repositories + *===================================*/ + +repositories { + + // Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral) + maven { + url nexusRepository + + if (isSnapshot) { + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } + + // Use local maven repository + mavenLocal() + + jcenter() + + // Use 'maven central' for other dependencies. + mavenCentral() +} + +task "info" << { + println "Project: ${project.name}" +println "Description: ${project.description}" + println "--------------------------" + println "GroupId: $groupId" + println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})" + println "" +} +info.description 'Print some information about project parameters' + + +/*=================================== + * Publishing + *===================================*/ + +publishing { + publications { + mavenJava(MavenPublication) { + groupId project.groupId + pom.withXml { + asNode().appendNode('description', project.description) + } + from project.components.java + + } + } + repositories { + maven { + url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}" + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } +} + + + diff --git a/bulletin-board-server/gradle-app.setting b/bulletin-board-server/gradle-app.setting index b0bad25..21226bc 100644 --- a/bulletin-board-server/gradle-app.setting +++ b/bulletin-board-server/gradle-app.setting @@ -1,29 +1,29 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/service/HelloProtoBuf.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/service/HelloProtoBuf.java index 772e7dd..c1f5de8 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/service/HelloProtoBuf.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/service/HelloProtoBuf.java @@ -1,30 +1,30 @@ -package meerkat.bulletinboard.service; - -import com.google.protobuf.ByteString; -import com.google.protobuf.Message; -import meerkat.protobuf.Crypto; -import meerkat.protobuf.BulletinBoardAPI.*; - -import java.util.Arrays; -import java.util.List; - -/** - * Created by talm on 10/11/15. - */ -public class HelloProtoBuf { - public Message sayHello() { - BulletinBoardMessage.Builder msg = BulletinBoardMessage.newBuilder(); - - UnsignedBulletinBoardMessage.Builder unsigned = UnsignedBulletinBoardMessage.newBuilder(); - unsigned.setData(ByteString.copyFromUtf8("Hello World!")); - List tags = Arrays.asList("Greetings", "FirstPrograms"); - unsigned.addAllTag(tags); - msg.setMsg(unsigned); - - Crypto.Signature.Builder sig = Crypto.Signature.newBuilder(); - sig.setData(ByteString.copyFromUtf8("deadbeef")); - msg.addSig(sig); - - return msg.build(); - } -} +package meerkat.bulletinboard.service; + +import com.google.protobuf.ByteString; +import com.google.protobuf.Message; +import meerkat.protobuf.Crypto; +import meerkat.protobuf.BulletinBoardAPI.*; + +import java.util.Arrays; +import java.util.List; + +/** + * Created by talm on 10/11/15. + */ +public class HelloProtoBuf { + public Message sayHello() { + BulletinBoardMessage.Builder msg = BulletinBoardMessage.newBuilder(); + + UnsignedBulletinBoardMessage.Builder unsigned = UnsignedBulletinBoardMessage.newBuilder(); + unsigned.setData(ByteString.copyFromUtf8("Hello World!")); + List tags = Arrays.asList("Greetings", "FirstPrograms"); + unsigned.addAllTag(tags); + msg.setMsg(unsigned); + + Crypto.Signature.Builder sig = Crypto.Signature.newBuilder(); + sig.setData(ByteString.copyFromUtf8("deadbeef")); + msg.addSig(sig); + + return msg.build(); + } +} diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java index 52bf42b..8402e55 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java @@ -1,484 +1,484 @@ -package meerkat.bulletinboard.sqlserver; - -import java.sql.*; -import java.util.*; - -import com.google.protobuf.ProtocolStringList; - -import meerkat.bulletinboard.BulletinBoardServer; -import meerkat.bulletinboard.sqlserver.mappers.EntryNumMapper; -import meerkat.bulletinboard.sqlserver.mappers.MessageMapper; -import meerkat.bulletinboard.sqlserver.mappers.SignatureMapper; -import meerkat.comm.CommunicationException; -import meerkat.protobuf.BulletinBoardAPI.*; -import meerkat.protobuf.Crypto.Signature; -import meerkat.protobuf.Crypto.SignatureVerificationKey; -import meerkat.crypto.Digest; -import meerkat.crypto.concrete.SHA256Digest; - -import javax.sql.DataSource; - -import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; -import org.springframework.jdbc.support.GeneratedKeyHolder; -import org.springframework.jdbc.support.KeyHolder; - -/** - * This is a generic SQL implementation of the BulletinBoardServer API. - */ -public class BulletinBoardSQLServer implements BulletinBoardServer{ - - /** - * This interface provides the required implementation-specific data to enable an access to an actual SQL server. - * It accounts for differences in languages between SQL DB types and for the different addresses needed to access them. - */ - public interface SQLQueryProvider { - - /** - * Allowed query types. - * Note that each query returned has to comply with the parameter names specified ny getParamNames - */ - public static enum QueryType { - - FIND_MSG_ID(new String[] {"MsgId"}), - INSERT_MSG(new String[] {"MsgId","Msg"}), - INSERT_NEW_TAG(new String[] {"Tag"}), - CONNECT_TAG(new String[] {"EntryNum","Tag"}), - ADD_SIGNATURE(new String[] {"EntryNum","SignerId","Signature"}), - GET_SIGNATURES(new String[] {"EntryNum"}), - GET_MESSAGES(new String[] {}); - - private String[] paramNames; - - private QueryType(String[] paramNames) { - this.paramNames = paramNames; - } - - public String[] getParamNames() { - return paramNames; - } - - } - - /** - * This enum provides the standard translation between a filter type and the corresponding parameter name in the SQL query - */ - public static enum FilterTypeParam { - - ENTRY_NUM("EntryNum", Types.INTEGER), - MSG_ID("MsgId", Types.BLOB), - SIGNER_ID("SignerId", Types.BLOB), - TAG("Tag", Types.VARCHAR), - LIMIT("Limit", Types.INTEGER); - - private FilterTypeParam(String paramName, int paramType) { - this.paramName = paramName; - this.paramType = paramType; - } - - private String paramName; - private int paramType; - - public static FilterTypeParam getFilterTypeParamName(FilterType filterType) { - switch (filterType) { - - case MSG_ID: - return MSG_ID; - - case EXACT_ENTRY: // Go through - case MAX_ENTRY: - return ENTRY_NUM; - - case SIGNER_ID: - return SIGNER_ID; - - case TAG: - return TAG; - - case MAX_MESSAGES: - return LIMIT; - - default: - return null; - } - } - - public String getParamName() { - return paramName; - } - - public int getParamType() { - return paramType; - } - } - - /** - * This function translates a QueryType into an actual SQL query. - * @param queryType is the type of query requested - * @return a string representation of the query for the specific type of SQL database implemented. - */ - public String getSQLString(QueryType queryType) throws IllegalArgumentException; - - /** - * Used to retrieve a condition to add to an SQL statement that will make the result comply with the filter type - * @param filterType is the filter type - * @param serialNum is a unique number used to identify the condition variables from other condition instances - * @return The SQL string for the condition - * @throws IllegalArgumentException if the filter type used is not supported - */ - public String getCondition(FilterType filterType, int serialNum) throws IllegalArgumentException; - - public String getConditionParamTypeName(FilterType filterType) throws IllegalArgumentException; - - /** - * @return the string needed in order to connect to the DB. - */ - public DataSource getDataSource(); - - /** - * This is used to get a list of queries that together create the schema needed for the DB. - * Note that these queries should not assume anything about the current state of the DB. - * In particular: they should not erase any existing tables and/or entries. - * @return The list of queries. - */ - public List getSchemaCreationCommands(); - - /** - * This is used to get a list of queries that together delete the schema needed for the DB. - * This is useful primarily for tests, in which we want to make sure we start with a clean DB. - * @return The list of queries. - */ - public List getSchemaDeletionCommands(); - - } - - private Object getParam(MessageFilter messageFilter) { - - switch (messageFilter.getType()) { - - case MSG_ID: // Go through - case SIGNER_ID: - return messageFilter.getId().toByteArray(); - - case EXACT_ENTRY: // Go through - case MAX_ENTRY: - return messageFilter.getEntry(); - - case TAG: - return messageFilter.getTag(); - - case MAX_MESSAGES: - return messageFilter.getMaxMessages(); - - default: - return null; - } - - } - - /** - * This class implements a comparator for the MessageFilter class - * The comparison is done solely by comparing the type of the filter - * This is used to sort the filters by type - */ - public class FilterTypeComparator implements Comparator { - - @Override - public int compare(MessageFilter filter1, MessageFilter filter2) { - return filter1.getTypeValue() - filter2.getTypeValue(); - } - } - - protected SQLQueryProvider sqlQueryProvider; - - protected NamedParameterJdbcTemplate jdbcTemplate; - - protected Digest digest; - - protected List trusteeSignatureVerificationArray; - protected int minTrusteeSignatures; - - protected List> pollingCommitteeSignatureVerificationKeyArray; - protected int minCommiteeSignatures; - - /** - * This constructor sets the type of SQL language in use. - * @param sqlQueryProvider is the provider of the SQL query strings required for actual operation of the server. - */ - public BulletinBoardSQLServer(SQLQueryProvider sqlQueryProvider) { - this.sqlQueryProvider = sqlQueryProvider; - } - - /** - * This method creates the schema in the given DB to prepare for future transactions - * It does not assume anything about the current state of the database - * @throws SQLException - */ - private void createSchema() throws SQLException { - - final int TIMEOUT = 20; - - for (String command : sqlQueryProvider.getSchemaCreationCommands()) { - jdbcTemplate.update(command,(Map) null); - } - - } - - /** - * This method initializes the signatures, connects to the DB and creates the schema (if required). - */ - @Override - public void init(String meerkatDB) throws CommunicationException { - // TODO write signature reading part. - - digest = new SHA256Digest(); - - jdbcTemplate = new NamedParameterJdbcTemplate(sqlQueryProvider.getDataSource()); - - try { - createSchema(); - } catch (SQLException e) { - throw new CommunicationException("Couldn't create schema " + e.getMessage()); - } - - } - - /** - * This method verifies the authenticity of the received message based on - * the stored signatures. - * - * @param msg - * is the message to authenticate (containing the signature). - * @return TRUE if the message is authenticated and FALSE otherwise. - */ - private boolean verifyMessage(BulletinBoardMessage msg) { - //TODO: Replace with actual verification. - return true; - } - - /** - * This procedure makes sure that all tags in the given list have an entry in the tags table. - * @param tags - */ - protected void insertNewTags(String[] tags) throws SQLException { - - String sql; - - sql = sqlQueryProvider.getSQLString(SQLQueryProvider.QueryType.INSERT_NEW_TAG); - Map namedParameters[] = new HashMap[tags.length]; - - for (int i = 0 ; i < tags.length ; i++){ - namedParameters[i] = new HashMap(); - namedParameters[i].put("Tag", tags[i]); - } - - jdbcTemplate.batchUpdate(sql, namedParameters); - - } - - /** - * This procedure is used to convert a boolean to a BoolMsg. - * @param b is the boolean to convert. - * @return a ProtoBuf message with boolean payload. - */ - private BoolMsg boolToBoolMsg(boolean b){ - return BoolMsg.newBuilder() - .setValue(b) - .build(); - } - - @Override - public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException { - - if (!verifyMessage(msg)) { - return boolToBoolMsg(false); - } - - String sql; - Map[] namedParameterArray; - - byte[] msgID; - long entryNum; - - ProtocolStringList tagList; - String[] tags; - - List signatureList; - Signature[] signatures; - - // Calculate message ID (depending only on the the unsigned message) - - digest.reset(); - digest.update(msg.getMsg()); - - msgID = digest.digest(); - - // Add message to table if needed and store entry number of message. - - - sql = sqlQueryProvider.getSQLString(SQLQueryProvider.QueryType.FIND_MSG_ID); - Map namedParameters = new HashMap(); - namedParameters.put("MsgId",msgID); - - List entryNums = jdbcTemplate.query(sql, new MapSqlParameterSource(namedParameters), new EntryNumMapper()); - - if (entryNums.size() > 0){ - - entryNum = entryNums.get(0); - - } else{ - - sql = sqlQueryProvider.getSQLString(SQLQueryProvider.QueryType.INSERT_MSG); - namedParameters.put("Msg", msg.getMsg().toByteArray()); - - KeyHolder keyHolder = new GeneratedKeyHolder(); - jdbcTemplate.update(sql,new MapSqlParameterSource(namedParameters),keyHolder); - - entryNum = keyHolder.getKey().longValue(); - - } - - // Retrieve tags and store new ones in tag table. - - try { - - tagList = msg.getMsg().getTagList(); - tags = new String[tagList.size()]; - tags = tagList.toArray(tags); - - insertNewTags(tags); - - } catch (SQLException e) { - throw new CommunicationException(e.getMessage()); - } - - // Connect message to tags. - - sql = sqlQueryProvider.getSQLString(SQLQueryProvider.QueryType.CONNECT_TAG); - - namedParameterArray = new HashMap[tags.length]; - - for (int i = 0 ; i < tags.length ; i++) { - namedParameterArray[i] = new HashMap(); - namedParameterArray[i].put("EntryNum", entryNum); - namedParameterArray[i].put("Tag", tags[i]); - } - - jdbcTemplate.batchUpdate(sql, namedParameterArray); - - // Retrieve signatures. - - signatureList = msg.getSigList(); - signatures = new Signature[signatureList.size()]; - signatures = signatureList.toArray(signatures); - - // Connect message to signatures. - - sql = sqlQueryProvider.getSQLString(SQLQueryProvider.QueryType.ADD_SIGNATURE); - - namedParameterArray = new HashMap[signatures.length]; - - for (int i = 0 ; i < signatures.length ; i++) { - namedParameterArray[i] = new HashMap(); - namedParameterArray[i].put("EntryNum", entryNum); - namedParameterArray[i].put("SignerId", signatures[i].getSignerId().toByteArray()); - namedParameterArray[i].put("Signature", signatures[i].toByteArray()); - } - - jdbcTemplate.batchUpdate(sql,namedParameterArray); - - return boolToBoolMsg(true); - } - - @Override - public BulletinBoardMessageList readMessages(MessageFilterList filterList) throws CommunicationException { - - BulletinBoardMessageList.Builder resultListBuilder = BulletinBoardMessageList.newBuilder(); - - // SQL length is roughly 50 characters per filter + 50 for the query itself - StringBuilder sqlBuilder = new StringBuilder(50 * (filterList.getFilterCount() + 1)); - - MapSqlParameterSource namedParameters; - int paramNum; - - MessageMapper messageMapper = new MessageMapper(); - SignatureMapper signatureMapper = new SignatureMapper(); - - List filters = new ArrayList(filterList.getFilterList()); - - boolean isFirstFilter = true; - - Collections.sort(filters, new FilterTypeComparator()); - - // Check if Tag/Signature tables are required for filtering purposes - - sqlBuilder.append(sqlQueryProvider.getSQLString(SQLQueryProvider.QueryType.GET_MESSAGES)); - // Add conditions - - namedParameters = new MapSqlParameterSource(); - - if (!filters.isEmpty()) { - sqlBuilder.append(" WHERE "); - - for (paramNum = 0 ; paramNum < filters.size() ; paramNum++) { - - MessageFilter filter = filters.get(paramNum); - - if (filter.getType().getNumber() != FilterType.MAX_MESSAGES_VALUE) { - if (isFirstFilter) { - isFirstFilter = false; - } else { - sqlBuilder.append(" AND "); - } - } - - sqlBuilder.append(sqlQueryProvider.getCondition(filter.getType(), paramNum)); - - SQLQueryProvider.FilterTypeParam filterTypeParam = SQLQueryProvider.FilterTypeParam.getFilterTypeParamName(filter.getType()); - - namedParameters.addValue( - filterTypeParam.getParamName() + Integer.toString(paramNum), - getParam(filter), - filterTypeParam.getParamType(), - sqlQueryProvider.getConditionParamTypeName(filter.getType())); - - } - - } - - // Run query - - List msgBuilders = jdbcTemplate.query(sqlBuilder.toString(), namedParameters, messageMapper); - - // Compile list of messages - - for (BulletinBoardMessage.Builder msgBuilder : msgBuilders) { - - // Retrieve signatures - - namedParameters = new MapSqlParameterSource(); - namedParameters.addValue("EntryNum", msgBuilder.getEntryNum()); - - List signatures = jdbcTemplate.query( - sqlQueryProvider.getSQLString(SQLQueryProvider.QueryType.GET_SIGNATURES), - namedParameters, - signatureMapper); - - // Append signatures - msgBuilder.addAllSig(signatures); - - // Finalize message and add to message list. - - resultListBuilder.addMessage(msgBuilder.build()); - - } - - //Combine results and return. - return resultListBuilder.build(); - - } - - @Override - public void close() {} - -} +package meerkat.bulletinboard.sqlserver; + +import java.sql.*; +import java.util.*; + +import com.google.protobuf.ProtocolStringList; + +import meerkat.bulletinboard.BulletinBoardServer; +import meerkat.bulletinboard.sqlserver.mappers.EntryNumMapper; +import meerkat.bulletinboard.sqlserver.mappers.MessageMapper; +import meerkat.bulletinboard.sqlserver.mappers.SignatureMapper; +import meerkat.comm.CommunicationException; +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Crypto.Signature; +import meerkat.protobuf.Crypto.SignatureVerificationKey; +import meerkat.crypto.Digest; +import meerkat.crypto.concrete.SHA256Digest; + +import javax.sql.DataSource; + +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; + +/** + * This is a generic SQL implementation of the BulletinBoardServer API. + */ +public class BulletinBoardSQLServer implements BulletinBoardServer{ + + /** + * This interface provides the required implementation-specific data to enable an access to an actual SQL server. + * It accounts for differences in languages between SQL DB types and for the different addresses needed to access them. + */ + public interface SQLQueryProvider { + + /** + * Allowed query types. + * Note that each query returned has to comply with the parameter names specified ny getParamNames + */ + public static enum QueryType { + + FIND_MSG_ID(new String[] {"MsgId"}), + INSERT_MSG(new String[] {"MsgId","Msg"}), + INSERT_NEW_TAG(new String[] {"Tag"}), + CONNECT_TAG(new String[] {"EntryNum","Tag"}), + ADD_SIGNATURE(new String[] {"EntryNum","SignerId","Signature"}), + GET_SIGNATURES(new String[] {"EntryNum"}), + GET_MESSAGES(new String[] {}); + + private String[] paramNames; + + private QueryType(String[] paramNames) { + this.paramNames = paramNames; + } + + public String[] getParamNames() { + return paramNames; + } + + } + + /** + * This enum provides the standard translation between a filter type and the corresponding parameter name in the SQL query + */ + public static enum FilterTypeParam { + + ENTRY_NUM("EntryNum", Types.INTEGER), + MSG_ID("MsgId", Types.BLOB), + SIGNER_ID("SignerId", Types.BLOB), + TAG("Tag", Types.VARCHAR), + LIMIT("Limit", Types.INTEGER); + + private FilterTypeParam(String paramName, int paramType) { + this.paramName = paramName; + this.paramType = paramType; + } + + private String paramName; + private int paramType; + + public static FilterTypeParam getFilterTypeParamName(FilterType filterType) { + switch (filterType) { + + case MSG_ID: + return MSG_ID; + + case EXACT_ENTRY: // Go through + case MAX_ENTRY: + return ENTRY_NUM; + + case SIGNER_ID: + return SIGNER_ID; + + case TAG: + return TAG; + + case MAX_MESSAGES: + return LIMIT; + + default: + return null; + } + } + + public String getParamName() { + return paramName; + } + + public int getParamType() { + return paramType; + } + } + + /** + * This function translates a QueryType into an actual SQL query. + * @param queryType is the type of query requested + * @return a string representation of the query for the specific type of SQL database implemented. + */ + public String getSQLString(QueryType queryType) throws IllegalArgumentException; + + /** + * Used to retrieve a condition to add to an SQL statement that will make the result comply with the filter type + * @param filterType is the filter type + * @param serialNum is a unique number used to identify the condition variables from other condition instances + * @return The SQL string for the condition + * @throws IllegalArgumentException if the filter type used is not supported + */ + public String getCondition(FilterType filterType, int serialNum) throws IllegalArgumentException; + + public String getConditionParamTypeName(FilterType filterType) throws IllegalArgumentException; + + /** + * @return the string needed in order to connect to the DB. + */ + public DataSource getDataSource(); + + /** + * This is used to get a list of queries that together create the schema needed for the DB. + * Note that these queries should not assume anything about the current state of the DB. + * In particular: they should not erase any existing tables and/or entries. + * @return The list of queries. + */ + public List getSchemaCreationCommands(); + + /** + * This is used to get a list of queries that together delete the schema needed for the DB. + * This is useful primarily for tests, in which we want to make sure we start with a clean DB. + * @return The list of queries. + */ + public List getSchemaDeletionCommands(); + + } + + private Object getParam(MessageFilter messageFilter) { + + switch (messageFilter.getType()) { + + case MSG_ID: // Go through + case SIGNER_ID: + return messageFilter.getId().toByteArray(); + + case EXACT_ENTRY: // Go through + case MAX_ENTRY: + return messageFilter.getEntry(); + + case TAG: + return messageFilter.getTag(); + + case MAX_MESSAGES: + return messageFilter.getMaxMessages(); + + default: + return null; + } + + } + + /** + * This class implements a comparator for the MessageFilter class + * The comparison is done solely by comparing the type of the filter + * This is used to sort the filters by type + */ + public class FilterTypeComparator implements Comparator { + + @Override + public int compare(MessageFilter filter1, MessageFilter filter2) { + return filter1.getTypeValue() - filter2.getTypeValue(); + } + } + + protected SQLQueryProvider sqlQueryProvider; + + protected NamedParameterJdbcTemplate jdbcTemplate; + + protected Digest digest; + + protected List trusteeSignatureVerificationArray; + protected int minTrusteeSignatures; + + protected List> pollingCommitteeSignatureVerificationKeyArray; + protected int minCommiteeSignatures; + + /** + * This constructor sets the type of SQL language in use. + * @param sqlQueryProvider is the provider of the SQL query strings required for actual operation of the server. + */ + public BulletinBoardSQLServer(SQLQueryProvider sqlQueryProvider) { + this.sqlQueryProvider = sqlQueryProvider; + } + + /** + * This method creates the schema in the given DB to prepare for future transactions + * It does not assume anything about the current state of the database + * @throws SQLException + */ + private void createSchema() throws SQLException { + + final int TIMEOUT = 20; + + for (String command : sqlQueryProvider.getSchemaCreationCommands()) { + jdbcTemplate.update(command,(Map) null); + } + + } + + /** + * This method initializes the signatures, connects to the DB and creates the schema (if required). + */ + @Override + public void init(String meerkatDB) throws CommunicationException { + // TODO write signature reading part. + + digest = new SHA256Digest(); + + jdbcTemplate = new NamedParameterJdbcTemplate(sqlQueryProvider.getDataSource()); + + try { + createSchema(); + } catch (SQLException e) { + throw new CommunicationException("Couldn't create schema " + e.getMessage()); + } + + } + + /** + * This method verifies the authenticity of the received message based on + * the stored signatures. + * + * @param msg + * is the message to authenticate (containing the signature). + * @return TRUE if the message is authenticated and FALSE otherwise. + */ + private boolean verifyMessage(BulletinBoardMessage msg) { + //TODO: Replace with actual verification. + return true; + } + + /** + * This procedure makes sure that all tags in the given list have an entry in the tags table. + * @param tags + */ + protected void insertNewTags(String[] tags) throws SQLException { + + String sql; + + sql = sqlQueryProvider.getSQLString(SQLQueryProvider.QueryType.INSERT_NEW_TAG); + Map namedParameters[] = new HashMap[tags.length]; + + for (int i = 0 ; i < tags.length ; i++){ + namedParameters[i] = new HashMap(); + namedParameters[i].put("Tag", tags[i]); + } + + jdbcTemplate.batchUpdate(sql, namedParameters); + + } + + /** + * This procedure is used to convert a boolean to a BoolMsg. + * @param b is the boolean to convert. + * @return a ProtoBuf message with boolean payload. + */ + private BoolMsg boolToBoolMsg(boolean b){ + return BoolMsg.newBuilder() + .setValue(b) + .build(); + } + + @Override + public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException { + + if (!verifyMessage(msg)) { + return boolToBoolMsg(false); + } + + String sql; + Map[] namedParameterArray; + + byte[] msgID; + long entryNum; + + ProtocolStringList tagList; + String[] tags; + + List signatureList; + Signature[] signatures; + + // Calculate message ID (depending only on the the unsigned message) + + digest.reset(); + digest.update(msg.getMsg()); + + msgID = digest.digest(); + + // Add message to table if needed and store entry number of message. + + + sql = sqlQueryProvider.getSQLString(SQLQueryProvider.QueryType.FIND_MSG_ID); + Map namedParameters = new HashMap(); + namedParameters.put("MsgId",msgID); + + List entryNums = jdbcTemplate.query(sql, new MapSqlParameterSource(namedParameters), new EntryNumMapper()); + + if (entryNums.size() > 0){ + + entryNum = entryNums.get(0); + + } else{ + + sql = sqlQueryProvider.getSQLString(SQLQueryProvider.QueryType.INSERT_MSG); + namedParameters.put("Msg", msg.getMsg().toByteArray()); + + KeyHolder keyHolder = new GeneratedKeyHolder(); + jdbcTemplate.update(sql,new MapSqlParameterSource(namedParameters),keyHolder); + + entryNum = keyHolder.getKey().longValue(); + + } + + // Retrieve tags and store new ones in tag table. + + try { + + tagList = msg.getMsg().getTagList(); + tags = new String[tagList.size()]; + tags = tagList.toArray(tags); + + insertNewTags(tags); + + } catch (SQLException e) { + throw new CommunicationException(e.getMessage()); + } + + // Connect message to tags. + + sql = sqlQueryProvider.getSQLString(SQLQueryProvider.QueryType.CONNECT_TAG); + + namedParameterArray = new HashMap[tags.length]; + + for (int i = 0 ; i < tags.length ; i++) { + namedParameterArray[i] = new HashMap(); + namedParameterArray[i].put("EntryNum", entryNum); + namedParameterArray[i].put("Tag", tags[i]); + } + + jdbcTemplate.batchUpdate(sql, namedParameterArray); + + // Retrieve signatures. + + signatureList = msg.getSigList(); + signatures = new Signature[signatureList.size()]; + signatures = signatureList.toArray(signatures); + + // Connect message to signatures. + + sql = sqlQueryProvider.getSQLString(SQLQueryProvider.QueryType.ADD_SIGNATURE); + + namedParameterArray = new HashMap[signatures.length]; + + for (int i = 0 ; i < signatures.length ; i++) { + namedParameterArray[i] = new HashMap(); + namedParameterArray[i].put("EntryNum", entryNum); + namedParameterArray[i].put("SignerId", signatures[i].getSignerId().toByteArray()); + namedParameterArray[i].put("Signature", signatures[i].toByteArray()); + } + + jdbcTemplate.batchUpdate(sql,namedParameterArray); + + return boolToBoolMsg(true); + } + + @Override + public BulletinBoardMessageList readMessages(MessageFilterList filterList) throws CommunicationException { + + BulletinBoardMessageList.Builder resultListBuilder = BulletinBoardMessageList.newBuilder(); + + // SQL length is roughly 50 characters per filter + 50 for the query itself + StringBuilder sqlBuilder = new StringBuilder(50 * (filterList.getFilterCount() + 1)); + + MapSqlParameterSource namedParameters; + int paramNum; + + MessageMapper messageMapper = new MessageMapper(); + SignatureMapper signatureMapper = new SignatureMapper(); + + List filters = new ArrayList(filterList.getFilterList()); + + boolean isFirstFilter = true; + + Collections.sort(filters, new FilterTypeComparator()); + + // Check if Tag/Signature tables are required for filtering purposes + + sqlBuilder.append(sqlQueryProvider.getSQLString(SQLQueryProvider.QueryType.GET_MESSAGES)); + // Add conditions + + namedParameters = new MapSqlParameterSource(); + + if (!filters.isEmpty()) { + sqlBuilder.append(" WHERE "); + + for (paramNum = 0 ; paramNum < filters.size() ; paramNum++) { + + MessageFilter filter = filters.get(paramNum); + + if (filter.getType().getNumber() != FilterType.MAX_MESSAGES_VALUE) { + if (isFirstFilter) { + isFirstFilter = false; + } else { + sqlBuilder.append(" AND "); + } + } + + sqlBuilder.append(sqlQueryProvider.getCondition(filter.getType(), paramNum)); + + SQLQueryProvider.FilterTypeParam filterTypeParam = SQLQueryProvider.FilterTypeParam.getFilterTypeParamName(filter.getType()); + + namedParameters.addValue( + filterTypeParam.getParamName() + Integer.toString(paramNum), + getParam(filter), + filterTypeParam.getParamType(), + sqlQueryProvider.getConditionParamTypeName(filter.getType())); + + } + + } + + // Run query + + List msgBuilders = jdbcTemplate.query(sqlBuilder.toString(), namedParameters, messageMapper); + + // Compile list of messages + + for (BulletinBoardMessage.Builder msgBuilder : msgBuilders) { + + // Retrieve signatures + + namedParameters = new MapSqlParameterSource(); + namedParameters.addValue("EntryNum", msgBuilder.getEntryNum()); + + List signatures = jdbcTemplate.query( + sqlQueryProvider.getSQLString(SQLQueryProvider.QueryType.GET_SIGNATURES), + namedParameters, + signatureMapper); + + // Append signatures + msgBuilder.addAllSig(signatures); + + // Finalize message and add to message list. + + resultListBuilder.addMessage(msgBuilder.build()); + + } + + //Combine results and return. + return resultListBuilder.build(); + + } + + @Override + public void close() {} + +} diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java index fa2b146..11dcefe 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java @@ -1,164 +1,164 @@ -package meerkat.bulletinboard.sqlserver; - -import meerkat.protobuf.BulletinBoardAPI.FilterType; -import org.h2.jdbcx.JdbcDataSource; -import javax.naming.Context; -import javax.naming.InitialContext; - -import javax.naming.NamingException; -import javax.sql.DataSource; -import java.util.LinkedList; -import java.util.List; - -/** - * Created by Arbel Deutsch Peled on 09-Dec-15. - */ - -public class H2QueryProvider implements BulletinBoardSQLServer.SQLQueryProvider { - - private String dbName; - - public H2QueryProvider(String dbName) { - this.dbName = dbName; - } - - - @Override - public String getSQLString(QueryType queryType) throws IllegalArgumentException{ - - switch(queryType) { - case ADD_SIGNATURE: - return "INSERT INTO SignatureTable (EntryNum, SignerId, Signature)" - + " SELECT DISTINCT :EntryNum AS Entry, :SignerId AS Id, :Signature AS Sig FROM UtilityTable AS Temp" - + " WHERE NOT EXISTS" - + " (SELECT 1 FROM SignatureTable AS SubTable WHERE SubTable.SignerId = :SignerId AND SubTable.EntryNum = :EntryNum)"; - - case CONNECT_TAG: - return "INSERT INTO MsgTagTable (TagId, EntryNum)" - + " SELECT DISTINCT TagTable.TagId, :EntryNum AS NewEntry FROM TagTable WHERE Tag = :Tag" - + " AND NOT EXISTS (SELECT 1 FROM MsgTagTable AS SubTable WHERE SubTable.TagId = TagTable.TagId" - + " AND SubTable.EntryNum = :EntryNum)"; - - case FIND_MSG_ID: - return "SELECT EntryNum From MsgTable WHERE MsgId = :MsgId"; - - case GET_MESSAGES: - return "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable"; - - case GET_SIGNATURES: - return "SELECT Signature FROM SignatureTable WHERE EntryNum = :EntryNum"; - - case INSERT_MSG: - return "INSERT INTO MsgTable (MsgId, Msg) VALUES(:MsgId,:Msg)"; - - case INSERT_NEW_TAG: - return "INSERT INTO TagTable(Tag) SELECT DISTINCT :Tag AS NewTag FROM UtilityTable WHERE" - + " NOT EXISTS (SELECT 1 FROM TagTable AS SubTable WHERE SubTable.Tag = :Tag)"; - - default: - throw new IllegalArgumentException("Cannot serve a query of type " + queryType); - } - - } - - @Override - public String getCondition(FilterType filterType, int serialNum) throws IllegalArgumentException { - - String serialString = Integer.toString(serialNum); - - switch(filterType) { - case EXACT_ENTRY: - return "MsgTable.EntryNum = :EntryNum" + serialString; - case MAX_ENTRY: - return "MsgTable.EntryNum <= :EntryNum" + serialString; - case MAX_MESSAGES: - return "LIMIT :Limit" + serialString; - case MSG_ID: - return "MsgTable.MsgId = MsgId" + serialString; - case SIGNER_ID: - return "EXISTS (SELECT 1 FROM SignatureTable" - + " WHERE SignatureTable.SignerId = :SignerId" + serialString + " AND SignatureTable.EntryNum = MsgTable.EntryNum)"; - case TAG: - return "EXISTS (SELECT 1 FROM TagTable" - + " INNER JOIN MsgTagTable ON TagTable.TagId = MsgTagTable.TagId" - + " WHERE TagTable.Tag = :Tag" + serialString + " AND MsgTagTable.EntryNum = MsgTable.EntryNum)"; - default: - throw new IllegalArgumentException("Cannot serve a filter of type " + filterType); - } - - } - - @Override - public String getConditionParamTypeName(FilterType filterType) throws IllegalArgumentException { - - switch(filterType) { - case EXACT_ENTRY: // Go through - case MAX_ENTRY: // Go through - case MAX_MESSAGES: - return "INT"; - - case MSG_ID: // Go through - case SIGNER_ID: - return "TINYBLOB"; - - case TAG: - return "VARCHAR"; - - default: - throw new IllegalArgumentException("Cannot serve a filter of type " + filterType); - } - - } - - @Override - public DataSource getDataSource() { - - JdbcDataSource dataSource = new JdbcDataSource(); - dataSource.setURL("jdbc:h2:~/" + dbName); - - return dataSource; - } - - - @Override - public List getSchemaCreationCommands() { - List list = new LinkedList(); - - list.add("CREATE TABLE IF NOT EXISTS MsgTable (EntryNum INT NOT NULL AUTO_INCREMENT PRIMARY KEY, MsgId TINYBLOB UNIQUE, Msg BLOB)"); - - list.add("CREATE TABLE IF NOT EXISTS TagTable (TagId INT NOT NULL AUTO_INCREMENT PRIMARY KEY, Tag VARCHAR(50) UNIQUE)"); - - list.add("CREATE TABLE IF NOT EXISTS MsgTagTable (EntryNum INT, TagId INT," - + " FOREIGN KEY (EntryNum) REFERENCES MsgTable(EntryNum)," - + " FOREIGN KEY (TagId) REFERENCES TagTable(TagId)," - + " UNIQUE (EntryNum, TagID))"); - - list.add("CREATE TABLE IF NOT EXISTS SignatureTable (EntryNum INT, SignerId TINYBLOB, Signature TINYBLOB UNIQUE," - + " FOREIGN KEY (EntryNum) REFERENCES MsgTable(EntryNum))"); - - list.add("CREATE INDEX IF NOT EXISTS SignerIndex ON SignatureTable(SignerId)"); - list.add("CREATE UNIQUE INDEX IF NOT EXISTS SignerIndex ON SignatureTable(SignerId, EntryNum)"); - - // This is used to create a simple table with one entry. - // It is used for implementing a workaround for the missing INSERT IGNORE syntax - list.add("CREATE TABLE IF NOT EXISTS UtilityTable (Entry INT)"); - list.add("INSERT INTO UtilityTable (Entry) VALUES (1)"); - - return list; - } - - @Override - public List getSchemaDeletionCommands() { - List list = new LinkedList(); - - list.add("DROP TABLE IF EXISTS UtilityTable"); - list.add("DROP INDEX IF EXISTS SignerIdIndex"); - list.add("DROP TABLE IF EXISTS MsgTagTable"); - list.add("DROP TABLE IF EXISTS SignatureTable"); - list.add("DROP TABLE IF EXISTS TagTable"); - list.add("DROP TABLE IF EXISTS MsgTable"); - - return list; - } - -} +package meerkat.bulletinboard.sqlserver; + +import meerkat.protobuf.BulletinBoardAPI.FilterType; +import org.h2.jdbcx.JdbcDataSource; +import javax.naming.Context; +import javax.naming.InitialContext; + +import javax.naming.NamingException; +import javax.sql.DataSource; +import java.util.LinkedList; +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 09-Dec-15. + */ + +public class H2QueryProvider implements BulletinBoardSQLServer.SQLQueryProvider { + + private String dbName; + + public H2QueryProvider(String dbName) { + this.dbName = dbName; + } + + + @Override + public String getSQLString(QueryType queryType) throws IllegalArgumentException{ + + switch(queryType) { + case ADD_SIGNATURE: + return "INSERT INTO SignatureTable (EntryNum, SignerId, Signature)" + + " SELECT DISTINCT :EntryNum AS Entry, :SignerId AS Id, :Signature AS Sig FROM UtilityTable AS Temp" + + " WHERE NOT EXISTS" + + " (SELECT 1 FROM SignatureTable AS SubTable WHERE SubTable.SignerId = :SignerId AND SubTable.EntryNum = :EntryNum)"; + + case CONNECT_TAG: + return "INSERT INTO MsgTagTable (TagId, EntryNum)" + + " SELECT DISTINCT TagTable.TagId, :EntryNum AS NewEntry FROM TagTable WHERE Tag = :Tag" + + " AND NOT EXISTS (SELECT 1 FROM MsgTagTable AS SubTable WHERE SubTable.TagId = TagTable.TagId" + + " AND SubTable.EntryNum = :EntryNum)"; + + case FIND_MSG_ID: + return "SELECT EntryNum From MsgTable WHERE MsgId = :MsgId"; + + case GET_MESSAGES: + return "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable"; + + case GET_SIGNATURES: + return "SELECT Signature FROM SignatureTable WHERE EntryNum = :EntryNum"; + + case INSERT_MSG: + return "INSERT INTO MsgTable (MsgId, Msg) VALUES(:MsgId,:Msg)"; + + case INSERT_NEW_TAG: + return "INSERT INTO TagTable(Tag) SELECT DISTINCT :Tag AS NewTag FROM UtilityTable WHERE" + + " NOT EXISTS (SELECT 1 FROM TagTable AS SubTable WHERE SubTable.Tag = :Tag)"; + + default: + throw new IllegalArgumentException("Cannot serve a query of type " + queryType); + } + + } + + @Override + public String getCondition(FilterType filterType, int serialNum) throws IllegalArgumentException { + + String serialString = Integer.toString(serialNum); + + switch(filterType) { + case EXACT_ENTRY: + return "MsgTable.EntryNum = :EntryNum" + serialString; + case MAX_ENTRY: + return "MsgTable.EntryNum <= :EntryNum" + serialString; + case MAX_MESSAGES: + return "LIMIT :Limit" + serialString; + case MSG_ID: + return "MsgTable.MsgId = MsgId" + serialString; + case SIGNER_ID: + return "EXISTS (SELECT 1 FROM SignatureTable" + + " WHERE SignatureTable.SignerId = :SignerId" + serialString + " AND SignatureTable.EntryNum = MsgTable.EntryNum)"; + case TAG: + return "EXISTS (SELECT 1 FROM TagTable" + + " INNER JOIN MsgTagTable ON TagTable.TagId = MsgTagTable.TagId" + + " WHERE TagTable.Tag = :Tag" + serialString + " AND MsgTagTable.EntryNum = MsgTable.EntryNum)"; + default: + throw new IllegalArgumentException("Cannot serve a filter of type " + filterType); + } + + } + + @Override + public String getConditionParamTypeName(FilterType filterType) throws IllegalArgumentException { + + switch(filterType) { + case EXACT_ENTRY: // Go through + case MAX_ENTRY: // Go through + case MAX_MESSAGES: + return "INT"; + + case MSG_ID: // Go through + case SIGNER_ID: + return "TINYBLOB"; + + case TAG: + return "VARCHAR"; + + default: + throw new IllegalArgumentException("Cannot serve a filter of type " + filterType); + } + + } + + @Override + public DataSource getDataSource() { + + JdbcDataSource dataSource = new JdbcDataSource(); + dataSource.setURL("jdbc:h2:~/" + dbName); + + return dataSource; + } + + + @Override + public List getSchemaCreationCommands() { + List list = new LinkedList(); + + list.add("CREATE TABLE IF NOT EXISTS MsgTable (EntryNum INT NOT NULL AUTO_INCREMENT PRIMARY KEY, MsgId TINYBLOB UNIQUE, Msg BLOB)"); + + list.add("CREATE TABLE IF NOT EXISTS TagTable (TagId INT NOT NULL AUTO_INCREMENT PRIMARY KEY, Tag VARCHAR(50) UNIQUE)"); + + list.add("CREATE TABLE IF NOT EXISTS MsgTagTable (EntryNum INT, TagId INT," + + " FOREIGN KEY (EntryNum) REFERENCES MsgTable(EntryNum)," + + " FOREIGN KEY (TagId) REFERENCES TagTable(TagId)," + + " UNIQUE (EntryNum, TagID))"); + + list.add("CREATE TABLE IF NOT EXISTS SignatureTable (EntryNum INT, SignerId TINYBLOB, Signature TINYBLOB UNIQUE," + + " FOREIGN KEY (EntryNum) REFERENCES MsgTable(EntryNum))"); + + list.add("CREATE INDEX IF NOT EXISTS SignerIndex ON SignatureTable(SignerId)"); + list.add("CREATE UNIQUE INDEX IF NOT EXISTS SignerIndex ON SignatureTable(SignerId, EntryNum)"); + + // This is used to create a simple table with one entry. + // It is used for implementing a workaround for the missing INSERT IGNORE syntax + list.add("CREATE TABLE IF NOT EXISTS UtilityTable (Entry INT)"); + list.add("INSERT INTO UtilityTable (Entry) VALUES (1)"); + + return list; + } + + @Override + public List getSchemaDeletionCommands() { + List list = new LinkedList(); + + list.add("DROP TABLE IF EXISTS UtilityTable"); + list.add("DROP INDEX IF EXISTS SignerIdIndex"); + list.add("DROP TABLE IF EXISTS MsgTagTable"); + list.add("DROP TABLE IF EXISTS SignatureTable"); + list.add("DROP TABLE IF EXISTS TagTable"); + list.add("DROP TABLE IF EXISTS MsgTable"); + + return list; + } + +} diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java index c00c044..53d9829 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java @@ -1,148 +1,148 @@ -package meerkat.bulletinboard.sqlserver; - -import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; -import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer.SQLQueryProvider; -import meerkat.protobuf.BulletinBoardAPI.FilterType; - -import javax.sql.DataSource; -import java.util.LinkedList; -import java.util.List; - -/** - * Created by Arbel Deutsch Peled on 09-Dec-15. - */ - -public class MySQLQueryProvider implements SQLQueryProvider { - - private String dbAddress; - private int dbPort; - private String dbName; - private String username; - private String password; - - public MySQLQueryProvider(String dbAddress, int dbPort, String dbName, String username, String password) { - this.dbAddress = dbAddress; - this.dbPort = dbPort; - this.dbName = dbName; - this.username = username; - this.password = password; - } - - @Override - public String getSQLString(QueryType queryType) throws IllegalArgumentException{ - - switch(queryType) { - case ADD_SIGNATURE: - return "INSERT IGNORE INTO SignatureTable (EntryNum, SignerId, Signature) VALUES (:EntryNum, :SignerId, :Signature)"; - case CONNECT_TAG: - return "INSERT IGNORE INTO MsgTagTable (TagId, EntryNum)" - + " SELECT TagTable.TagId, :EntryNum AS EntryNum FROM TagTable WHERE Tag = :Tag"; - case FIND_MSG_ID: - return "SELECT EntryNum From MsgTable WHERE MsgId = :MsgId"; - case GET_MESSAGES: - return "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable"; - case GET_SIGNATURES: - return "SELECT Signature FROM SignatureTable WHERE EntryNum = :EntryNum"; - case INSERT_MSG: - return "INSERT INTO MsgTable (MsgId, Msg) VALUES(:MsgId, :Msg)"; - case INSERT_NEW_TAG: - return "INSERT IGNORE INTO TagTable(Tag) VALUES (:Tag)"; - default: - throw new IllegalArgumentException("Cannot serve a query of type " + queryType); - } - - } - - @Override - public String getCondition(FilterType filterType, int serialNum) throws IllegalArgumentException { - - String serialString = Integer.toString(serialNum); - - switch(filterType) { - case EXACT_ENTRY: - return "MsgTable.EntryNum = :EntryNum" + serialString; - case MAX_ENTRY: - return "MsgTable.EntryNum <= :EntryNum" + serialString; - case MAX_MESSAGES: - return "LIMIT :Limit" + serialString; - case MSG_ID: - return "MsgTable.MsgId = :MsgId" + serialString; - case SIGNER_ID: - return "EXISTS (SELECT 1 FROM SignatureTable" - + " WHERE SignatureTable.SignerId = :SignerId" + serialString + " AND SignatureTable.EntryNum = MsgTable.EntryNum)"; - case TAG: - return "EXISTS (SELECT 1 FROM TagTable" - + " INNER JOIN MsgTagTable ON TagTable.TagId = MsgTagTable.TagId" - + " WHERE TagTable.Tag = :Tag" + serialString + " AND MsgTagTable.EntryNum = MsgTable.EntryNum)"; - default: - throw new IllegalArgumentException("Cannot serve a filter of type " + filterType); - } - - } - - @Override - public String getConditionParamTypeName(FilterType filterType) throws IllegalArgumentException { - - switch(filterType) { - case EXACT_ENTRY: // Go through - case MAX_ENTRY: // Go through - case MAX_MESSAGES: - return "INT"; - - case MSG_ID: // Go through - case SIGNER_ID: - return "TINYBLOB"; - - case TAG: - return "VARCHAR"; - - default: - throw new IllegalArgumentException("Cannot serve a filter of type " + filterType); - } - - } - - @Override - public DataSource getDataSource() { - MysqlDataSource dataSource = new MysqlDataSource(); - - dataSource.setServerName(dbAddress); - dataSource.setPort(dbPort); - dataSource.setDatabaseName(dbName); - dataSource.setUser(username); - dataSource.setPassword(password); - - return dataSource; - } - - @Override - public List getSchemaCreationCommands() { - List list = new LinkedList(); - - list.add("CREATE TABLE IF NOT EXISTS MsgTable (EntryNum INT NOT NULL AUTO_INCREMENT PRIMARY KEY, MsgId TINYBLOB, Msg BLOB, UNIQUE(MsgId(50)))"); - - list.add("CREATE TABLE IF NOT EXISTS TagTable (TagId INT NOT NULL AUTO_INCREMENT PRIMARY KEY, Tag VARCHAR(50), UNIQUE(Tag))"); - - list.add("CREATE TABLE IF NOT EXISTS MsgTagTable (EntryNum INT, TagId INT," - + " CONSTRAINT FOREIGN KEY (EntryNum) REFERENCES MsgTable(EntryNum)," - + " CONSTRAINT FOREIGN KEY (TagId) REFERENCES TagTable(TagId)," - + " CONSTRAINT UNIQUE (EntryNum, TagID))"); - - list.add("CREATE TABLE IF NOT EXISTS SignatureTable (EntryNum INT, SignerId TINYBLOB, Signature TINYBLOB," - + " INDEX(SignerId(32)), CONSTRAINT Uni UNIQUE(SignerId(32), EntryNum), CONSTRAINT FOREIGN KEY (EntryNum) REFERENCES MsgTable(EntryNum))"); - - return list; - } - - @Override - public List getSchemaDeletionCommands() { - List list = new LinkedList(); - - list.add("DROP TABLE IF EXISTS MsgTagTable"); - list.add("DROP TABLE IF EXISTS SignatureTable"); - list.add("DROP TABLE IF EXISTS TagTable"); - list.add("DROP TABLE IF EXISTS MsgTable"); - - return list; - } -} +package meerkat.bulletinboard.sqlserver; + +import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; +import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer.SQLQueryProvider; +import meerkat.protobuf.BulletinBoardAPI.FilterType; + +import javax.sql.DataSource; +import java.util.LinkedList; +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 09-Dec-15. + */ + +public class MySQLQueryProvider implements SQLQueryProvider { + + private String dbAddress; + private int dbPort; + private String dbName; + private String username; + private String password; + + public MySQLQueryProvider(String dbAddress, int dbPort, String dbName, String username, String password) { + this.dbAddress = dbAddress; + this.dbPort = dbPort; + this.dbName = dbName; + this.username = username; + this.password = password; + } + + @Override + public String getSQLString(QueryType queryType) throws IllegalArgumentException{ + + switch(queryType) { + case ADD_SIGNATURE: + return "INSERT IGNORE INTO SignatureTable (EntryNum, SignerId, Signature) VALUES (:EntryNum, :SignerId, :Signature)"; + case CONNECT_TAG: + return "INSERT IGNORE INTO MsgTagTable (TagId, EntryNum)" + + " SELECT TagTable.TagId, :EntryNum AS EntryNum FROM TagTable WHERE Tag = :Tag"; + case FIND_MSG_ID: + return "SELECT EntryNum From MsgTable WHERE MsgId = :MsgId"; + case GET_MESSAGES: + return "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable"; + case GET_SIGNATURES: + return "SELECT Signature FROM SignatureTable WHERE EntryNum = :EntryNum"; + case INSERT_MSG: + return "INSERT INTO MsgTable (MsgId, Msg) VALUES(:MsgId, :Msg)"; + case INSERT_NEW_TAG: + return "INSERT IGNORE INTO TagTable(Tag) VALUES (:Tag)"; + default: + throw new IllegalArgumentException("Cannot serve a query of type " + queryType); + } + + } + + @Override + public String getCondition(FilterType filterType, int serialNum) throws IllegalArgumentException { + + String serialString = Integer.toString(serialNum); + + switch(filterType) { + case EXACT_ENTRY: + return "MsgTable.EntryNum = :EntryNum" + serialString; + case MAX_ENTRY: + return "MsgTable.EntryNum <= :EntryNum" + serialString; + case MAX_MESSAGES: + return "LIMIT :Limit" + serialString; + case MSG_ID: + return "MsgTable.MsgId = :MsgId" + serialString; + case SIGNER_ID: + return "EXISTS (SELECT 1 FROM SignatureTable" + + " WHERE SignatureTable.SignerId = :SignerId" + serialString + " AND SignatureTable.EntryNum = MsgTable.EntryNum)"; + case TAG: + return "EXISTS (SELECT 1 FROM TagTable" + + " INNER JOIN MsgTagTable ON TagTable.TagId = MsgTagTable.TagId" + + " WHERE TagTable.Tag = :Tag" + serialString + " AND MsgTagTable.EntryNum = MsgTable.EntryNum)"; + default: + throw new IllegalArgumentException("Cannot serve a filter of type " + filterType); + } + + } + + @Override + public String getConditionParamTypeName(FilterType filterType) throws IllegalArgumentException { + + switch(filterType) { + case EXACT_ENTRY: // Go through + case MAX_ENTRY: // Go through + case MAX_MESSAGES: + return "INT"; + + case MSG_ID: // Go through + case SIGNER_ID: + return "TINYBLOB"; + + case TAG: + return "VARCHAR"; + + default: + throw new IllegalArgumentException("Cannot serve a filter of type " + filterType); + } + + } + + @Override + public DataSource getDataSource() { + MysqlDataSource dataSource = new MysqlDataSource(); + + dataSource.setServerName(dbAddress); + dataSource.setPort(dbPort); + dataSource.setDatabaseName(dbName); + dataSource.setUser(username); + dataSource.setPassword(password); + + return dataSource; + } + + @Override + public List getSchemaCreationCommands() { + List list = new LinkedList(); + + list.add("CREATE TABLE IF NOT EXISTS MsgTable (EntryNum INT NOT NULL AUTO_INCREMENT PRIMARY KEY, MsgId TINYBLOB, Msg BLOB, UNIQUE(MsgId(50)))"); + + list.add("CREATE TABLE IF NOT EXISTS TagTable (TagId INT NOT NULL AUTO_INCREMENT PRIMARY KEY, Tag VARCHAR(50), UNIQUE(Tag))"); + + list.add("CREATE TABLE IF NOT EXISTS MsgTagTable (EntryNum INT, TagId INT," + + " CONSTRAINT FOREIGN KEY (EntryNum) REFERENCES MsgTable(EntryNum)," + + " CONSTRAINT FOREIGN KEY (TagId) REFERENCES TagTable(TagId)," + + " CONSTRAINT UNIQUE (EntryNum, TagID))"); + + list.add("CREATE TABLE IF NOT EXISTS SignatureTable (EntryNum INT, SignerId TINYBLOB, Signature TINYBLOB," + + " INDEX(SignerId(32)), CONSTRAINT Uni UNIQUE(SignerId(32), EntryNum), CONSTRAINT FOREIGN KEY (EntryNum) REFERENCES MsgTable(EntryNum))"); + + return list; + } + + @Override + public List getSchemaDeletionCommands() { + List list = new LinkedList(); + + list.add("DROP TABLE IF EXISTS MsgTagTable"); + list.add("DROP TABLE IF EXISTS SignatureTable"); + list.add("DROP TABLE IF EXISTS TagTable"); + list.add("DROP TABLE IF EXISTS MsgTable"); + + return list; + } +} diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteQueryProvider.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteQueryProvider.java index 945ae47..089bdd2 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteQueryProvider.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/SQLiteQueryProvider.java @@ -1,123 +1,123 @@ -package meerkat.bulletinboard.sqlserver; - -import meerkat.protobuf.BulletinBoardAPI.*; -import org.sqlite.SQLiteDataSource; - -import javax.sql.DataSource; -import java.util.LinkedList; -import java.util.List; - -/** - * Created by Arbel Deutsch Peled on 09-Dec-15. - */ - -public class SQLiteQueryProvider implements BulletinBoardSQLServer.SQLQueryProvider { - - String dbName; - - public SQLiteQueryProvider(String dbName) { - this.dbName = dbName; - } - - @Override - public String getSQLString(QueryType queryType) throws IllegalArgumentException{ - - switch(queryType) { - case ADD_SIGNATURE: - return "INSERT OR IGNORE INTO SignatureTable (EntryNum, SignerId, Signature) VALUES (:EntryNum,:SignerId,:Signature)"; - case CONNECT_TAG: - return "INSERT OR IGNORE INTO MsgTagTable (TagId, EntryNum)" - + " SELECT TagTable.TagId, :EntryNum AS EntryNum FROM TagTable WHERE Tag = :Tag"; - case FIND_MSG_ID: - return "SELECT EntryNum From MsgTable WHERE MsgId = :MsgId"; - case GET_MESSAGES: - return "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable"; - case GET_SIGNATURES: - return "SELECT Signature FROM SignatureTable WHERE EntryNum = :EntryNum"; - case INSERT_MSG: - return "INSERT INTO MsgTable (MsgId, Msg) VALUES(:MsgId,:Msg)"; - case INSERT_NEW_TAG: - return "INSERT OR IGNORE INTO TagTable(Tag) VALUES (:Tag)"; - default: - throw new IllegalArgumentException("Cannot serve a query of type " + queryType); - } - - } - - @Override - public String getCondition(FilterType filterType, int serialNum) throws IllegalArgumentException { - - String serialString = Integer.toString(serialNum); - - switch(filterType) { - case EXACT_ENTRY: - return "MsgTable.EntryNum = :EntryNum" + serialString; - case MAX_ENTRY: - return "MsgTable.EntryNum <= :EntryNum" + serialString; - case MAX_MESSAGES: - return "LIMIT = :Limit" + serialString; - case MSG_ID: - return "MsgTable.MsgId = :MsgId" + serialString; - case SIGNER_ID: - return "EXISTS (SELECT 1 FROM SignatureTable" - + " WHERE SignatureTable.SignerId = :SignerId" + serialString + " AND SignatureTable.EntryNum = MsgTable.EntryNum)"; - case TAG: - return "EXISTS (SELECT 1 FROM TagTable" - + " INNER JOIN MsgTagTable ON TagTable.TagId = MsgTagTable.TagId" - + " WHERE TagTable.Tag = :Tag" + serialString + " AND MsgTagTable.EntryNum = MsgTable.EntryNum)"; - default: - throw new IllegalArgumentException("Cannot serve a filter of type " + filterType); - } - - } - - @Override - public String getConditionParamTypeName(FilterType filterType) throws IllegalArgumentException { - return null; //TODO: write this. - } - - @Override - public DataSource getDataSource() { - // TODO: Fix this - SQLiteDataSource dataSource = new SQLiteDataSource(); - dataSource.setUrl("jdbc:sqlite:" + dbName); - dataSource.setDatabaseName("meerkat"); //TODO: Make generic - - return dataSource; - } - - - @Override - public List getSchemaCreationCommands() { - List list = new LinkedList(); - - list.add("CREATE TABLE IF NOT EXISTS MsgTable (EntryNum INTEGER PRIMARY KEY, MsgId BLOB UNIQUE, Msg BLOB)"); - - list.add("CREATE TABLE IF NOT EXISTS TagTable (TagId INTEGER PRIMARY KEY, Tag varchar(50) UNIQUE)"); - list.add("CREATE TABLE IF NOT EXISTS MsgTagTable (EntryNum BLOB, TagId INTEGER, FOREIGN KEY (EntryNum)" - + " REFERENCES MsgTable(EntryNum), FOREIGN KEY (TagId) REFERENCES TagTable(TagId), UNIQUE (EntryNum, TagID))"); - - list.add("CREATE TABLE IF NOT EXISTS SignatureTable (EntryNum INTEGER, SignerId BLOB, Signature BLOB," - + " FOREIGN KEY (EntryNum) REFERENCES MsgTable(EntryNum))"); - - list.add("CREATE INDEX IF NOT EXISTS SignerIndex ON SignatureTable(SignerId)"); - list.add("CREATE UNIQUE INDEX IF NOT EXISTS SignerIndex ON SignatureTable(SignerId, EntryNum)"); - - return list; - } - - @Override - public List getSchemaDeletionCommands() { - List list = new LinkedList(); - - list.add("DROP TABLE IF EXISTS MsgTagTable"); - - list.add("DROP INDEX IF EXISTS SignerIndex"); - list.add("DROP TABLE IF EXISTS SignatureTable"); - - list.add("DROP TABLE IF EXISTS TagTable"); - list.add("DROP TABLE IF EXISTS MsgTable"); - - return list; - } -} +package meerkat.bulletinboard.sqlserver; + +import meerkat.protobuf.BulletinBoardAPI.*; +import org.sqlite.SQLiteDataSource; + +import javax.sql.DataSource; +import java.util.LinkedList; +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 09-Dec-15. + */ + +public class SQLiteQueryProvider implements BulletinBoardSQLServer.SQLQueryProvider { + + String dbName; + + public SQLiteQueryProvider(String dbName) { + this.dbName = dbName; + } + + @Override + public String getSQLString(QueryType queryType) throws IllegalArgumentException{ + + switch(queryType) { + case ADD_SIGNATURE: + return "INSERT OR IGNORE INTO SignatureTable (EntryNum, SignerId, Signature) VALUES (:EntryNum,:SignerId,:Signature)"; + case CONNECT_TAG: + return "INSERT OR IGNORE INTO MsgTagTable (TagId, EntryNum)" + + " SELECT TagTable.TagId, :EntryNum AS EntryNum FROM TagTable WHERE Tag = :Tag"; + case FIND_MSG_ID: + return "SELECT EntryNum From MsgTable WHERE MsgId = :MsgId"; + case GET_MESSAGES: + return "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable"; + case GET_SIGNATURES: + return "SELECT Signature FROM SignatureTable WHERE EntryNum = :EntryNum"; + case INSERT_MSG: + return "INSERT INTO MsgTable (MsgId, Msg) VALUES(:MsgId,:Msg)"; + case INSERT_NEW_TAG: + return "INSERT OR IGNORE INTO TagTable(Tag) VALUES (:Tag)"; + default: + throw new IllegalArgumentException("Cannot serve a query of type " + queryType); + } + + } + + @Override + public String getCondition(FilterType filterType, int serialNum) throws IllegalArgumentException { + + String serialString = Integer.toString(serialNum); + + switch(filterType) { + case EXACT_ENTRY: + return "MsgTable.EntryNum = :EntryNum" + serialString; + case MAX_ENTRY: + return "MsgTable.EntryNum <= :EntryNum" + serialString; + case MAX_MESSAGES: + return "LIMIT = :Limit" + serialString; + case MSG_ID: + return "MsgTable.MsgId = :MsgId" + serialString; + case SIGNER_ID: + return "EXISTS (SELECT 1 FROM SignatureTable" + + " WHERE SignatureTable.SignerId = :SignerId" + serialString + " AND SignatureTable.EntryNum = MsgTable.EntryNum)"; + case TAG: + return "EXISTS (SELECT 1 FROM TagTable" + + " INNER JOIN MsgTagTable ON TagTable.TagId = MsgTagTable.TagId" + + " WHERE TagTable.Tag = :Tag" + serialString + " AND MsgTagTable.EntryNum = MsgTable.EntryNum)"; + default: + throw new IllegalArgumentException("Cannot serve a filter of type " + filterType); + } + + } + + @Override + public String getConditionParamTypeName(FilterType filterType) throws IllegalArgumentException { + return null; //TODO: write this. + } + + @Override + public DataSource getDataSource() { + // TODO: Fix this + SQLiteDataSource dataSource = new SQLiteDataSource(); + dataSource.setUrl("jdbc:sqlite:" + dbName); + dataSource.setDatabaseName("meerkat"); //TODO: Make generic + + return dataSource; + } + + + @Override + public List getSchemaCreationCommands() { + List list = new LinkedList(); + + list.add("CREATE TABLE IF NOT EXISTS MsgTable (EntryNum INTEGER PRIMARY KEY, MsgId BLOB UNIQUE, Msg BLOB)"); + + list.add("CREATE TABLE IF NOT EXISTS TagTable (TagId INTEGER PRIMARY KEY, Tag varchar(50) UNIQUE)"); + list.add("CREATE TABLE IF NOT EXISTS MsgTagTable (EntryNum BLOB, TagId INTEGER, FOREIGN KEY (EntryNum)" + + " REFERENCES MsgTable(EntryNum), FOREIGN KEY (TagId) REFERENCES TagTable(TagId), UNIQUE (EntryNum, TagID))"); + + list.add("CREATE TABLE IF NOT EXISTS SignatureTable (EntryNum INTEGER, SignerId BLOB, Signature BLOB," + + " FOREIGN KEY (EntryNum) REFERENCES MsgTable(EntryNum))"); + + list.add("CREATE INDEX IF NOT EXISTS SignerIndex ON SignatureTable(SignerId)"); + list.add("CREATE UNIQUE INDEX IF NOT EXISTS SignerIndex ON SignatureTable(SignerId, EntryNum)"); + + return list; + } + + @Override + public List getSchemaDeletionCommands() { + List list = new LinkedList(); + + list.add("DROP TABLE IF EXISTS MsgTagTable"); + + list.add("DROP INDEX IF EXISTS SignerIndex"); + list.add("DROP TABLE IF EXISTS SignatureTable"); + + list.add("DROP TABLE IF EXISTS TagTable"); + list.add("DROP TABLE IF EXISTS MsgTable"); + + return list; + } +} diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/EntryNumMapper.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/EntryNumMapper.java index 478c39e..68addbc 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/EntryNumMapper.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/EntryNumMapper.java @@ -1,18 +1,18 @@ -package meerkat.bulletinboard.sqlserver.mappers; - -import meerkat.protobuf.BulletinBoardAPI.MessageID; -import org.springframework.jdbc.core.RowMapper; - -import java.sql.ResultSet; -import java.sql.SQLException; - -/** - * Created by Arbel Deutsch Peled on 11-Dec-15. - */ -public class EntryNumMapper implements RowMapper { - - @Override - public Long mapRow(ResultSet rs, int rowNum) throws SQLException { - return rs.getLong(1); - } -} +package meerkat.bulletinboard.sqlserver.mappers; + +import meerkat.protobuf.BulletinBoardAPI.MessageID; +import org.springframework.jdbc.core.RowMapper; + +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * Created by Arbel Deutsch Peled on 11-Dec-15. + */ +public class EntryNumMapper implements RowMapper { + + @Override + public Long mapRow(ResultSet rs, int rowNum) throws SQLException { + return rs.getLong(1); + } +} diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/MessageMapper.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/MessageMapper.java index fdc1fa8..d1584aa 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/MessageMapper.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/MessageMapper.java @@ -1,32 +1,32 @@ -package meerkat.bulletinboard.sqlserver.mappers; - -import com.google.protobuf.InvalidProtocolBufferException; -import meerkat.protobuf.BulletinBoardAPI.UnsignedBulletinBoardMessage; -import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; -import org.springframework.jdbc.core.RowMapper; - -import java.sql.ResultSet; -import java.sql.SQLException; - -/** - * Created by Arbel Deutsch Peled on 11-Dec-15. - */ -public class MessageMapper implements RowMapper { - - @Override - public BulletinBoardMessage.Builder mapRow(ResultSet rs, int rowNum) throws SQLException { - - BulletinBoardMessage.Builder builder = BulletinBoardMessage.newBuilder(); - - try { - builder.setEntryNum(rs.getLong(1)) - .setMsg(UnsignedBulletinBoardMessage.parseFrom(rs.getBytes(2))); - - } catch (InvalidProtocolBufferException e) { - throw new SQLException(e.getMessage(), e); - } - - return builder; - } - -} +package meerkat.bulletinboard.sqlserver.mappers; + +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.protobuf.BulletinBoardAPI.UnsignedBulletinBoardMessage; +import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; +import org.springframework.jdbc.core.RowMapper; + +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * Created by Arbel Deutsch Peled on 11-Dec-15. + */ +public class MessageMapper implements RowMapper { + + @Override + public BulletinBoardMessage.Builder mapRow(ResultSet rs, int rowNum) throws SQLException { + + BulletinBoardMessage.Builder builder = BulletinBoardMessage.newBuilder(); + + try { + builder.setEntryNum(rs.getLong(1)) + .setMsg(UnsignedBulletinBoardMessage.parseFrom(rs.getBytes(2))); + + } catch (InvalidProtocolBufferException e) { + throw new SQLException(e.getMessage(), e); + } + + return builder; + } + +} diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/SignatureMapper.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/SignatureMapper.java index 60015c1..95ff087 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/SignatureMapper.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/mappers/SignatureMapper.java @@ -1,28 +1,28 @@ -package meerkat.bulletinboard.sqlserver.mappers; - -import com.google.protobuf.InvalidProtocolBufferException; -import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; -import meerkat.protobuf.BulletinBoardAPI.UnsignedBulletinBoardMessage; -import meerkat.protobuf.Crypto.Signature; -import org.springframework.jdbc.core.RowMapper; - -import java.sql.ResultSet; -import java.sql.SQLException; - -/** - * Created by Arbel Deutsch Peled on 11-Dec-15. - */ -public class SignatureMapper implements RowMapper { - - @Override - public Signature mapRow(ResultSet rs, int rowNum) throws SQLException { - - try { - return Signature.parseFrom(rs.getBytes(1)); - } catch (InvalidProtocolBufferException e) { - throw new SQLException(e.getMessage(), e); - } - - } - -} +package meerkat.bulletinboard.sqlserver.mappers; + +import com.google.protobuf.InvalidProtocolBufferException; +import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; +import meerkat.protobuf.BulletinBoardAPI.UnsignedBulletinBoardMessage; +import meerkat.protobuf.Crypto.Signature; +import org.springframework.jdbc.core.RowMapper; + +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * Created by Arbel Deutsch Peled on 11-Dec-15. + */ +public class SignatureMapper implements RowMapper { + + @Override + public Signature mapRow(ResultSet rs, int rowNum) throws SQLException { + + try { + return Signature.parseFrom(rs.getBytes(1)); + } catch (InvalidProtocolBufferException e) { + throw new SQLException(e.getMessage(), e); + } + + } + +} diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java index b3fc03c..1ab4a62 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java @@ -1,124 +1,124 @@ -package meerkat.bulletinboard.webapp; - -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; - -import meerkat.bulletinboard.BulletinBoardServer; -import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer; -import meerkat.bulletinboard.sqlserver.H2QueryProvider; -import meerkat.bulletinboard.sqlserver.MySQLQueryProvider; -import meerkat.bulletinboard.sqlserver.SQLiteQueryProvider; -import meerkat.comm.CommunicationException; -import meerkat.protobuf.BulletinBoardAPI.BoolMsg; -import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; -import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessageList; -import meerkat.protobuf.BulletinBoardAPI.MessageFilterList; -import meerkat.rest.Constants; - -@Path(Constants.BULLETIN_BOARD_SERVER_PATH) -public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextListener{ - - private static final String BULLETIN_BOARD_ATTRIBUTE_NAME = "bulletinBoard"; - - @Context ServletContext servletContext; - - BulletinBoardServer bulletinBoard; - - /** - * This is the servlet init method. - */ - public void init(){ - bulletinBoard = (BulletinBoardServer) servletContext.getAttribute(BULLETIN_BOARD_ATTRIBUTE_NAME); - } - - /** - * This is the BulletinBoard init method. - */ - @Override - public void init(String meerkatDB) throws CommunicationException { - bulletinBoard.init(meerkatDB); - } - - @Override - public void contextInitialized(ServletContextEvent servletContextEvent) { - ServletContext servletContext = servletContextEvent.getServletContext(); - String dbType = servletContext.getInitParameter("dbType"); - String dbName = servletContext.getInitParameter("dbName"); - - if ("SQLite".equals(dbType)){ - - bulletinBoard = new BulletinBoardSQLServer(new SQLiteQueryProvider(dbName)); - - } else if ("H2".equals(dbType)) { - - bulletinBoard = new BulletinBoardSQLServer(new H2QueryProvider(dbName)); - - } else if ("MySQL".equals(dbType)) { - - String dbAddress = servletContext.getInitParameter("dbAddress"); - int dbPort = Integer.parseInt(servletContext.getInitParameter("dbPort")); - String username = servletContext.getInitParameter("username"); - String password = servletContext.getInitParameter("password"); - - bulletinBoard = new BulletinBoardSQLServer(new MySQLQueryProvider(dbAddress,dbPort,dbName,username,password)); - } - - try { - init(dbName); - servletContext.setAttribute(BULLETIN_BOARD_ATTRIBUTE_NAME, bulletinBoard); - } catch (CommunicationException e) { - System.err.println(e.getMessage()); - } - } - - @Path(Constants.POST_MESSAGE_PATH) - @POST - @Consumes(Constants.MEDIATYPE_PROTOBUF) - @Produces(Constants.MEDIATYPE_PROTOBUF) - @Override - public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException { - init(); - return bulletinBoard.postMessage(msg); - } - - @Path(Constants.READ_MESSAGES_PATH) - @POST - @Consumes(Constants.MEDIATYPE_PROTOBUF) - @Produces(Constants.MEDIATYPE_PROTOBUF) - @Override - public BulletinBoardMessageList readMessages(MessageFilterList filterList) throws CommunicationException { - init(); - return bulletinBoard.readMessages(filterList); - } - - @Override - public void close(){ - try { - bulletinBoard.close(); - } catch (CommunicationException e) { - System.err.println(e.getMessage()); - } - } - - @GET - @Produces(MediaType.TEXT_PLAIN) - public String test() { - return "This BulletinBoard is up and running!\n Please consult the API documents to perform queries."; - } - - @Override - public void contextDestroyed(ServletContextEvent servletContextEvent) { - ServletContext servletContext = servletContextEvent.getServletContext(); - bulletinBoard = (BulletinBoardServer) servletContext.getAttribute(BULLETIN_BOARD_ATTRIBUTE_NAME); - close(); - } - -} +package meerkat.bulletinboard.webapp; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; + +import meerkat.bulletinboard.BulletinBoardServer; +import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer; +import meerkat.bulletinboard.sqlserver.H2QueryProvider; +import meerkat.bulletinboard.sqlserver.MySQLQueryProvider; +import meerkat.bulletinboard.sqlserver.SQLiteQueryProvider; +import meerkat.comm.CommunicationException; +import meerkat.protobuf.BulletinBoardAPI.BoolMsg; +import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; +import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessageList; +import meerkat.protobuf.BulletinBoardAPI.MessageFilterList; +import meerkat.rest.Constants; + +@Path(Constants.BULLETIN_BOARD_SERVER_PATH) +public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextListener{ + + private static final String BULLETIN_BOARD_ATTRIBUTE_NAME = "bulletinBoard"; + + @Context ServletContext servletContext; + + BulletinBoardServer bulletinBoard; + + /** + * This is the servlet init method. + */ + public void init(){ + bulletinBoard = (BulletinBoardServer) servletContext.getAttribute(BULLETIN_BOARD_ATTRIBUTE_NAME); + } + + /** + * This is the BulletinBoard init method. + */ + @Override + public void init(String meerkatDB) throws CommunicationException { + bulletinBoard.init(meerkatDB); + } + + @Override + public void contextInitialized(ServletContextEvent servletContextEvent) { + ServletContext servletContext = servletContextEvent.getServletContext(); + String dbType = servletContext.getInitParameter("dbType"); + String dbName = servletContext.getInitParameter("dbName"); + + if ("SQLite".equals(dbType)){ + + bulletinBoard = new BulletinBoardSQLServer(new SQLiteQueryProvider(dbName)); + + } else if ("H2".equals(dbType)) { + + bulletinBoard = new BulletinBoardSQLServer(new H2QueryProvider(dbName)); + + } else if ("MySQL".equals(dbType)) { + + String dbAddress = servletContext.getInitParameter("dbAddress"); + int dbPort = Integer.parseInt(servletContext.getInitParameter("dbPort")); + String username = servletContext.getInitParameter("username"); + String password = servletContext.getInitParameter("password"); + + bulletinBoard = new BulletinBoardSQLServer(new MySQLQueryProvider(dbAddress,dbPort,dbName,username,password)); + } + + try { + init(dbName); + servletContext.setAttribute(BULLETIN_BOARD_ATTRIBUTE_NAME, bulletinBoard); + } catch (CommunicationException e) { + System.err.println(e.getMessage()); + } + } + + @Path(Constants.POST_MESSAGE_PATH) + @POST + @Consumes(Constants.MEDIATYPE_PROTOBUF) + @Produces(Constants.MEDIATYPE_PROTOBUF) + @Override + public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException { + init(); + return bulletinBoard.postMessage(msg); + } + + @Path(Constants.READ_MESSAGES_PATH) + @POST + @Consumes(Constants.MEDIATYPE_PROTOBUF) + @Produces(Constants.MEDIATYPE_PROTOBUF) + @Override + public BulletinBoardMessageList readMessages(MessageFilterList filterList) throws CommunicationException { + init(); + return bulletinBoard.readMessages(filterList); + } + + @Override + public void close(){ + try { + bulletinBoard.close(); + } catch (CommunicationException e) { + System.err.println(e.getMessage()); + } + } + + @GET + @Produces(MediaType.TEXT_PLAIN) + public String test() { + return "This BulletinBoard is up and running!\n Please consult the API documents to perform queries."; + } + + @Override + public void contextDestroyed(ServletContextEvent servletContextEvent) { + ServletContext servletContext = servletContextEvent.getServletContext(); + bulletinBoard = (BulletinBoardServer) servletContext.getAttribute(BULLETIN_BOARD_ATTRIBUTE_NAME); + close(); + } + +} diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/HelloProtoWebApp.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/HelloProtoWebApp.java index bf748c5..469fba9 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/HelloProtoWebApp.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/HelloProtoWebApp.java @@ -1,50 +1,50 @@ -package meerkat.bulletinboard.webapp; - -import com.google.protobuf.ByteString; -import com.google.protobuf.Message; -import meerkat.bulletinboard.service.HelloProtoBuf; -import meerkat.protobuf.Crypto.*; -import meerkat.protobuf.BulletinBoardAPI.*; -import meerkat.rest.Constants; - -import javax.annotation.PostConstruct; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; - -@Path("/proto") -public class HelloProtoWebApp { - private HelloProtoBuf helloProtoBuf; - - @PostConstruct - public void init() { - helloProtoBuf = new HelloProtoBuf(); - } - - @GET - @Produces(Constants.MEDIATYPE_PROTOBUF) - public Message hello() { - byte[] b1 = { (byte) 1, (byte) 2, (byte) 3, (byte) 4 }; - byte[] b2 = { (byte) 11, (byte) 12, (byte) 13, (byte) 14 }; - byte[] b3 = {(byte) 21, (byte)22, (byte) 23, (byte) 24}; - - Message msg; - - if (helloProtoBuf != null) { - msg = helloProtoBuf.sayHello(); - } else { - msg = BulletinBoardMessage.newBuilder() - .setMsg(UnsignedBulletinBoardMessage.newBuilder() - .addTag("Signature") - .addTag("Trustee") - .setData(ByteString.copyFrom(b1)).build()) - .addSig(Signature.newBuilder() - .setType(SignatureType.DSA) - .setData(ByteString.copyFrom(b2)) - .setSignerId(ByteString.copyFrom(b3)).build()) - .build(); - } - - return msg; - } -} +package meerkat.bulletinboard.webapp; + +import com.google.protobuf.ByteString; +import com.google.protobuf.Message; +import meerkat.bulletinboard.service.HelloProtoBuf; +import meerkat.protobuf.Crypto.*; +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.rest.Constants; + +import javax.annotation.PostConstruct; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +@Path("/proto") +public class HelloProtoWebApp { + private HelloProtoBuf helloProtoBuf; + + @PostConstruct + public void init() { + helloProtoBuf = new HelloProtoBuf(); + } + + @GET + @Produces(Constants.MEDIATYPE_PROTOBUF) + public Message hello() { + byte[] b1 = { (byte) 1, (byte) 2, (byte) 3, (byte) 4 }; + byte[] b2 = { (byte) 11, (byte) 12, (byte) 13, (byte) 14 }; + byte[] b3 = {(byte) 21, (byte)22, (byte) 23, (byte) 24}; + + Message msg; + + if (helloProtoBuf != null) { + msg = helloProtoBuf.sayHello(); + } else { + msg = BulletinBoardMessage.newBuilder() + .setMsg(UnsignedBulletinBoardMessage.newBuilder() + .addTag("Signature") + .addTag("Trustee") + .setData(ByteString.copyFrom(b1)).build()) + .addSig(Signature.newBuilder() + .setType(SignatureType.DSA) + .setData(ByteString.copyFrom(b2)) + .setSignerId(ByteString.copyFrom(b3)).build()) + .build(); + } + + return msg; + } +} diff --git a/bulletin-board-server/src/main/proto/meerkat/bulletin_board_server.proto b/bulletin-board-server/src/main/proto/meerkat/bulletin_board_server.proto index e31485b..c284302 100644 --- a/bulletin-board-server/src/main/proto/meerkat/bulletin_board_server.proto +++ b/bulletin-board-server/src/main/proto/meerkat/bulletin_board_server.proto @@ -1,9 +1,9 @@ -syntax = "proto3"; - -package meerkat; - -option java_package = "meerkat.protobuf"; - -message Boolean { - bool value = 1; +syntax = "proto3"; + +package meerkat; + +option java_package = "meerkat.protobuf"; + +message Boolean { + bool value = 1; } \ No newline at end of file diff --git a/bulletin-board-server/src/main/webapp/META-INF/jetty-env.xml b/bulletin-board-server/src/main/webapp/META-INF/jetty-env.xml index c4d368f..07c1470 100644 --- a/bulletin-board-server/src/main/webapp/META-INF/jetty-env.xml +++ b/bulletin-board-server/src/main/webapp/META-INF/jetty-env.xml @@ -1,12 +1,12 @@ - - - - - org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern - none - - - org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern - none - + + + + + org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern + none + + + org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern + none + \ No newline at end of file diff --git a/bulletin-board-server/src/main/webapp/WEB-INF/web.xml b/bulletin-board-server/src/main/webapp/WEB-INF/web.xml index 2198c07..7e91168 100644 --- a/bulletin-board-server/src/main/webapp/WEB-INF/web.xml +++ b/bulletin-board-server/src/main/webapp/WEB-INF/web.xml @@ -1,38 +1,38 @@ - - - Jersey Hello World - - org.glassfish.jersey.servlet.ServletContainer - - - jersey.config.server.provider.packages - meerkat - - 1 - - - Jersey Hello World - /* - - - dbAddress - localhost - - dbPort - 3306 - - dbName - meerkat - - username - arbel - - password - mypass - - dbType - SQLite - - meerkat.bulletinboard.webapp.BulletinBoardWebApp - - + + + Jersey Hello World + + org.glassfish.jersey.servlet.ServletContainer + + + jersey.config.server.provider.packages + meerkat + + 1 + + + Jersey Hello World + /* + + + dbAddress + localhost + + dbPort + 3306 + + dbName + meerkat + + username + arbel + + password + mypass + + dbType + SQLite + + meerkat.bulletinboard.webapp.BulletinBoardWebApp + + diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/BulletinBoardSQLServerIntegrationTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/BulletinBoardSQLServerIntegrationTest.java index 838adcc..eb3465b 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/BulletinBoardSQLServerIntegrationTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/BulletinBoardSQLServerIntegrationTest.java @@ -1,124 +1,124 @@ -package meerkat.bulletinboard; - - -import com.google.protobuf.ByteString; -import com.google.protobuf.TextFormat; - -import meerkat.protobuf.Crypto.*; -import meerkat.protobuf.BulletinBoardAPI.*; -import meerkat.rest.Constants; -import meerkat.rest.ProtobufMessageBodyReader; -import meerkat.rest.ProtobufMessageBodyWriter; - -import org.junit.Before; -import org.junit.Test; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.Response; - -public class BulletinBoardSQLServerIntegrationTest { - - private static String PROP_GETTY_URL = "gretty.httpBaseURI"; - private static String DEFAULT_BASE_URL = "http://localhost:8081"; - private static String BASE_URL = System.getProperty(PROP_GETTY_URL, DEFAULT_BASE_URL); - - Client client; - - @Before - public void setup() throws Exception { - System.err.println("Registering client"); - client = ClientBuilder.newClient(); - client.register(ProtobufMessageBodyReader.class); - client.register(ProtobufMessageBodyWriter.class); - - } - - @Test - public void testPost() throws Exception { - byte[] b1 = {(byte) 1, (byte) 2, (byte) 3, (byte) 4}; - byte[] b2 = {(byte) 11, (byte) 12, (byte) 13, (byte) 14}; - byte[] b3 = {(byte) 21, (byte) 22, (byte) 23, (byte) 24}; - byte[] b4 = {(byte) 4, (byte) 5, (byte) 100, (byte) -50, (byte) 0}; - - WebTarget webTarget; - Response response; - BoolMsg bool; - - BulletinBoardMessage msg; - - MessageFilterList filterList; - BulletinBoardMessageList msgList; - - // Test writing mechanism - - System.err.println("******** Testing: " + Constants.POST_MESSAGE_PATH); - webTarget = client.target(BASE_URL).path(Constants.BULLETIN_BOARD_SERVER_PATH).path(Constants.POST_MESSAGE_PATH); - System.err.println(webTarget.getUri()); - - msg = BulletinBoardMessage.newBuilder() - .setMsg(UnsignedBulletinBoardMessage.newBuilder() - .addTag("Signature") - .addTag("Trustee") - .setData(ByteString.copyFrom(b1)) - .build()) - .addSig(Signature.newBuilder() - .setType(SignatureType.DSA) - .setData(ByteString.copyFrom(b2)) - .setSignerId(ByteString.copyFrom(b3)) - .build()) - .addSig(Signature.newBuilder() - .setType(SignatureType.ECDSA) - .setData(ByteString.copyFrom(b3)) - .setSignerId(ByteString.copyFrom(b2)) - .build()) - .build(); - - response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(msg, Constants.MEDIATYPE_PROTOBUF)); - System.err.println(response); - bool = response.readEntity(BoolMsg.class); - assert bool.getValue(); - - msg = BulletinBoardMessage.newBuilder() - .setMsg(UnsignedBulletinBoardMessage.newBuilder() - .addTag("Vote") - .addTag("Trustee") - .setData(ByteString.copyFrom(b4)) - .build()) - .addSig(Signature.newBuilder() - .setType(SignatureType.ECDSA) - .setData(ByteString.copyFrom(b4)) - .setSignerId(ByteString.copyFrom(b2)) - .build()) - .build(); - - response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(msg, Constants.MEDIATYPE_PROTOBUF)); - System.err.println(response); - bool = response.readEntity(BoolMsg.class); - assert bool.getValue(); - - // Test reading mechanism - - System.err.println("******** Testing: " + Constants.READ_MESSAGES_PATH); - webTarget = client.target(BASE_URL).path(Constants.BULLETIN_BOARD_SERVER_PATH).path(Constants.READ_MESSAGES_PATH); - filterList = MessageFilterList.newBuilder() - .addFilter( - MessageFilter.newBuilder() - .setType(FilterType.TAG) - .setTag("Vote") - .build() - ) - .build(); - - response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(filterList, Constants.MEDIATYPE_PROTOBUF)); - System.err.println(response); - msgList = response.readEntity(BulletinBoardMessageList.class); - System.err.println("List size: " + msgList.getMessageCount()); - System.err.println("This is the list:"); - System.err.println(TextFormat.printToString(msgList)); - assert msgList.getMessageCount() == 1; - } - -} +package meerkat.bulletinboard; + + +import com.google.protobuf.ByteString; +import com.google.protobuf.TextFormat; + +import meerkat.protobuf.Crypto.*; +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.rest.Constants; +import meerkat.rest.ProtobufMessageBodyReader; +import meerkat.rest.ProtobufMessageBodyWriter; + +import org.junit.Before; +import org.junit.Test; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Response; + +public class BulletinBoardSQLServerIntegrationTest { + + private static String PROP_GETTY_URL = "gretty.httpBaseURI"; + private static String DEFAULT_BASE_URL = "http://localhost:8081"; + private static String BASE_URL = System.getProperty(PROP_GETTY_URL, DEFAULT_BASE_URL); + + Client client; + + @Before + public void setup() throws Exception { + System.err.println("Registering client"); + client = ClientBuilder.newClient(); + client.register(ProtobufMessageBodyReader.class); + client.register(ProtobufMessageBodyWriter.class); + + } + + @Test + public void testPost() throws Exception { + byte[] b1 = {(byte) 1, (byte) 2, (byte) 3, (byte) 4}; + byte[] b2 = {(byte) 11, (byte) 12, (byte) 13, (byte) 14}; + byte[] b3 = {(byte) 21, (byte) 22, (byte) 23, (byte) 24}; + byte[] b4 = {(byte) 4, (byte) 5, (byte) 100, (byte) -50, (byte) 0}; + + WebTarget webTarget; + Response response; + BoolMsg bool; + + BulletinBoardMessage msg; + + MessageFilterList filterList; + BulletinBoardMessageList msgList; + + // Test writing mechanism + + System.err.println("******** Testing: " + Constants.POST_MESSAGE_PATH); + webTarget = client.target(BASE_URL).path(Constants.BULLETIN_BOARD_SERVER_PATH).path(Constants.POST_MESSAGE_PATH); + System.err.println(webTarget.getUri()); + + msg = BulletinBoardMessage.newBuilder() + .setMsg(UnsignedBulletinBoardMessage.newBuilder() + .addTag("Signature") + .addTag("Trustee") + .setData(ByteString.copyFrom(b1)) + .build()) + .addSig(Signature.newBuilder() + .setType(SignatureType.DSA) + .setData(ByteString.copyFrom(b2)) + .setSignerId(ByteString.copyFrom(b3)) + .build()) + .addSig(Signature.newBuilder() + .setType(SignatureType.ECDSA) + .setData(ByteString.copyFrom(b3)) + .setSignerId(ByteString.copyFrom(b2)) + .build()) + .build(); + + response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(msg, Constants.MEDIATYPE_PROTOBUF)); + System.err.println(response); + bool = response.readEntity(BoolMsg.class); + assert bool.getValue(); + + msg = BulletinBoardMessage.newBuilder() + .setMsg(UnsignedBulletinBoardMessage.newBuilder() + .addTag("Vote") + .addTag("Trustee") + .setData(ByteString.copyFrom(b4)) + .build()) + .addSig(Signature.newBuilder() + .setType(SignatureType.ECDSA) + .setData(ByteString.copyFrom(b4)) + .setSignerId(ByteString.copyFrom(b2)) + .build()) + .build(); + + response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(msg, Constants.MEDIATYPE_PROTOBUF)); + System.err.println(response); + bool = response.readEntity(BoolMsg.class); + assert bool.getValue(); + + // Test reading mechanism + + System.err.println("******** Testing: " + Constants.READ_MESSAGES_PATH); + webTarget = client.target(BASE_URL).path(Constants.BULLETIN_BOARD_SERVER_PATH).path(Constants.READ_MESSAGES_PATH); + filterList = MessageFilterList.newBuilder() + .addFilter( + MessageFilter.newBuilder() + .setType(FilterType.TAG) + .setTag("Vote") + .build() + ) + .build(); + + response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(filterList, Constants.MEDIATYPE_PROTOBUF)); + System.err.println(response); + msgList = response.readEntity(BulletinBoardMessageList.class); + System.err.println("List size: " + msgList.getMessageCount()); + System.err.println("This is the list:"); + System.err.println(TextFormat.printToString(msgList)); + assert msgList.getMessageCount() == 1; + } + +} diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java index 4799e0d..1c5e3c5 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java @@ -1,391 +1,391 @@ -package meerkat.bulletinboard; - -import java.io.IOException; -import java.io.InputStream; -import java.lang.management.ManagementFactory; -import java.lang.management.ThreadMXBean; -import java.math.BigInteger; -import java.security.InvalidKeyException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.SignatureException; -import java.security.UnrecoverableKeyException; -import java.security.cert.CertificateException; -import java.util.List; -import java.util.Random; - -import com.google.protobuf.ByteString; - -import meerkat.comm.CommunicationException; -import meerkat.crypto.concrete.ECDSASignature; -import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; -import meerkat.protobuf.BulletinBoardAPI.FilterType; -import meerkat.protobuf.BulletinBoardAPI.MessageFilter; -import meerkat.protobuf.BulletinBoardAPI.MessageFilterList; -import meerkat.protobuf.BulletinBoardAPI.UnsignedBulletinBoardMessage; - -import static org.junit.Assert.*; -import static org.hamcrest.CoreMatchers.*; - -public class GenericBulletinBoardServerTest { - - protected BulletinBoardServer bulletinBoardServer; - private ECDSASignature signers[]; - private ByteString[] signerIDs; - - private Random random; - - private static String KEYFILE_EXAMPLE = "/certs/enduser-certs/user1-key-with-password-secret.p12"; - private static String KEYFILE_EXAMPLE3 = "/certs/enduser-certs/user3-key-with-password-shh.p12"; - - private static String KEYFILE_PASSWORD1 = "secret"; - private static String KEYFILE_PASSWORD3 = "shh"; - - public static String CERT1_PEM_EXAMPLE = "/certs/enduser-certs/user1.crt"; - public static String CERT3_PEM_EXAMPLE = "/certs/enduser-certs/user3.crt"; - - private final int TAG_NUM = 5; // Number of tags. - private final int MESSAGE_NUM = 32; // Number of messages (2^TAG_NUM). - - private String[] tags; - private byte[][] data; - - private final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); // Used to time the tests - - /** - * @param bulletinBoardServer is an initialized server. - * @throws InstantiationException - * @throws IllegalAccessException - * @throws CertificateException - * @throws KeyStoreException - * @throws NoSuchAlgorithmException - * @throws IOException - * @throws UnrecoverableKeyException - * @throws CommunicationException - */ - public void init(BulletinBoardServer bulletinBoardServer) { - - System.err.println("Starting to initialize GenericBulletinBoardServerTest"); - long start = threadBean.getCurrentThreadCpuTime(); - - this.bulletinBoardServer = bulletinBoardServer; - - signers = new ECDSASignature[2]; - signerIDs = new ByteString[signers.length]; - signers[0] = new ECDSASignature(); - signers[1] = new ECDSASignature(); - - InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE); - char[] password = KEYFILE_PASSWORD1.toCharArray(); - - KeyStore.Builder keyStoreBuilder = null; - try { - keyStoreBuilder = signers[0].getPKCS12KeyStoreBuilder(keyStream, password); - - signers[0].loadSigningCertificate(keyStoreBuilder); - - signers[0].loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE)); - - keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE3); - password = KEYFILE_PASSWORD3.toCharArray(); - - keyStoreBuilder = signers[1].getPKCS12KeyStoreBuilder(keyStream, password); - signers[1].loadSigningCertificate(keyStoreBuilder); - - signers[1].loadVerificationCertificates(getClass().getResourceAsStream(CERT3_PEM_EXAMPLE)); - - for (int i = 0 ; i < signers.length ; i++) { - signerIDs[i] = signers[i].getSignerID(); - } - - } catch (IOException e) { - System.err.println("Failed reading from signature file " + e.getMessage()); - fail("Failed reading from signature file " + e.getMessage()); - } catch (CertificateException e) { - System.err.println("Failed reading certificate " + e.getMessage()); - fail("Failed reading certificate " + e.getMessage()); - } catch (KeyStoreException e) { - System.err.println("Failed reading keystore " + e.getMessage()); - fail("Failed reading keystore " + e.getMessage()); - } catch (NoSuchAlgorithmException e) { - System.err.println("Couldn't find signing algorithm " + e.getMessage()); - fail("Couldn't find signing algorithm " + e.getMessage()); - } catch (UnrecoverableKeyException e) { - System.err.println("Couldn't find signing key " + e.getMessage()); - fail("Couldn't find signing key " + e.getMessage()); - } - - random = new Random(0); // We use insecure randomness in tests for repeatability - - long end = threadBean.getCurrentThreadCpuTime(); - System.err.println("Finished initializing GenericBulletinBoardServerTest"); - System.err.println("Time of operation: " + (end - start)); - } - - private byte randomByte(){ - return (byte) random.nextInt(); - } - - private String randomString(){ - return new BigInteger(130, random).toString(32); - } - - /** - * Tests writing of several messages with multiple tags and signatures. - * @throws CommunicationException - * @throws SignatureException - * @throws InvalidKeyException - * @throws CertificateException - * @throws IOException - */ - public void testInsert() { - - System.err.println("Starting to insert messages to DB"); - long start = threadBean.getCurrentThreadCpuTime(); - - final int BYTES_PER_MESSAGE_DATA = 50; // Message size. - - tags = new String[TAG_NUM]; - data = new byte[MESSAGE_NUM][BYTES_PER_MESSAGE_DATA]; - - UnsignedBulletinBoardMessage.Builder unsignedMsgBuilder; - BulletinBoardMessage.Builder msgBuilder; - - int i, j; - - // Generate random data. - - for (i = 1; i <= MESSAGE_NUM; i++) { - for (j = 0; j < BYTES_PER_MESSAGE_DATA; j++) { - data[i - 1][j] = randomByte(); - } - } - - for (i = 0; i < TAG_NUM; i++) { - tags[i] = randomString(); - } - - // Build messages. - - for (i = 1; i <= MESSAGE_NUM; i++) { - unsignedMsgBuilder = UnsignedBulletinBoardMessage.newBuilder() - .setData(ByteString.copyFrom(data[i - 1])); - - // Add tags based on bit-representation of message number. - - int copyI = i; - for (j = 0; j < TAG_NUM; j++) { - if (copyI % 2 == 1) { - unsignedMsgBuilder.addTag(tags[j]); - } - - copyI >>>= 1; - } - - // Build message. - - msgBuilder = BulletinBoardMessage.newBuilder() - .setMsg(unsignedMsgBuilder.build()); - - // Add signatures. - - try { - - if (i % 2 == 1) { - signers[0].updateContent(msgBuilder.getMsg()); - msgBuilder.addSig(signers[0].sign()); - - if (i % 4 == 1) { - signers[1].updateContent(msgBuilder.getMsg()); - msgBuilder.addSig(signers[1].sign()); - } - } - - } catch (SignatureException e) { - fail(e.getMessage()); - } - - // Post message. - - try { - bulletinBoardServer.postMessage(msgBuilder.build()); - } catch (CommunicationException e) { - fail(e.getMessage()); - } - } - - long end = threadBean.getCurrentThreadCpuTime(); - System.err.println("Finished inserting messages to DB"); - System.err.println("Time of operation: " + (end - start)); - - } - - /** - * Tests retrieval of messages written in {@Link #testInsert()} - * Only queries using one tag filter - */ - public void testSimpleTagAndSignature(){ - - System.err.println("Starting to test tag and signature mechanism"); - long start = threadBean.getCurrentThreadCpuTime(); - - List messages; - - // Check tag mechanism - - for (int i = 0 ; i < TAG_NUM ; i++){ - - // Retrieve messages having tag i - - try { - - messages = bulletinBoardServer.readMessages( - MessageFilterList.newBuilder() - .addFilter(MessageFilter.newBuilder() - .setType(FilterType.TAG) - .setTag(tags[i]) - .build() - ) - .build() - ) - .getMessageList(); - - } catch (CommunicationException e) { - fail(e.getMessage()); - return; - } - - // Assert that the number of retrieved messages is correct. - - assertThat(messages.size(), is(MESSAGE_NUM / 2)); - - // Assert the identity of the messages. - - for (BulletinBoardMessage msg : messages){ - - // Assert serial number and raw data. - - assertThat((msg.getEntryNum() >>> i) % 2 , is((long) 1)); - assertThat(msg.getMsg().getData().toByteArray(), is(data[(int) msg.getEntryNum() - 1])); - - // Assert signatures. - - try { - - if (msg.getEntryNum() % 2 == 1) { - signers[0].initVerify(msg.getSig(0)); - signers[0].updateContent(msg.getMsg()); - assertTrue("Signature did not verify!", signers[0].verify()); - - if (msg.getEntryNum() % 4 == 1) { - signers[1].initVerify(msg.getSig(1)); - signers[1].updateContent(msg.getMsg()); - assertTrue("Signature did not verify!", signers[1].verify()); - - assertThat(msg.getSigCount(), is(2)); - } else { - assertThat(msg.getSigCount(), is(1)); - } - } else { - assertThat(msg.getSigCount(), is(0)); - } - } catch (Exception e) { - fail(e.getMessage()); - } - } - - } - - long end = threadBean.getCurrentThreadCpuTime(); - System.err.println("Finished testing tag and signature mechanism"); - System.err.println("Time of operation: " + (end - start)); - - } - - /** - * Tests retrieval of messages written in {@Link #testInsert()} using multiple tags/signature filters. - */ - public void testEnhancedTagsAndSignatures(){ - - System.err.println("Starting to test multiple tags and signatures"); - long start = threadBean.getCurrentThreadCpuTime(); - - List messages; - MessageFilterList.Builder filterListBuilder = MessageFilterList.newBuilder(); - - int expectedMsgCount = MESSAGE_NUM; - - // Check multiple tag filters. - - for (int i = 0 ; i < TAG_NUM ; i++) { - - filterListBuilder.addFilter( - MessageFilter.newBuilder() - .setType(FilterType.TAG) - .setTag(tags[i]) - .build() - ); - - try { - messages = bulletinBoardServer.readMessages(filterListBuilder.build()).getMessageList(); - } catch (CommunicationException e) { - System.err.println("Failed retrieving multi-tag messages from DB: " + e.getMessage()); - fail("Failed retrieving multi-tag messages from DB: " + e.getMessage()); - return; - } - - expectedMsgCount /= 2; - - assertThat(messages.size(), is(expectedMsgCount)); - - for (BulletinBoardMessage msg : messages) { - for (int j = 0 ; j <= i ; j++) { - assertThat((msg.getEntryNum() >>> j) % 2, is((long) 1)); - } - } - } - - // Check multiple signature filters. - - filterListBuilder = MessageFilterList.newBuilder() - .addFilter(MessageFilter.newBuilder() - .setType(FilterType.SIGNER_ID) - .setId(signerIDs[0]) - .build()) - .addFilter(MessageFilter.newBuilder() - .setType(FilterType.SIGNER_ID) - .setId(signerIDs[1]) - .build()); - - try { - messages = bulletinBoardServer.readMessages(filterListBuilder.build()).getMessageList(); - } catch (CommunicationException e) { - System.err.println("Failed retrieving multi-signature message from DB: " + e.getMessage()); - fail("Failed retrieving multi-signature message from DB: " + e.getMessage()); - return; - } - - assertThat(messages.size(), is(MESSAGE_NUM / 4)); - - for (BulletinBoardMessage message : messages) { - assertThat(message.getEntryNum() % 4, is((long) 1)); - } - - long end = threadBean.getCurrentThreadCpuTime(); - System.err.println("Finished testing multiple tags and signatures"); - System.err.println("Time of operation: " + (end - start)); - - } - - public void close(){ - signers[0].clearSigningKey(); - signers[1].clearSigningKey(); - try { - bulletinBoardServer.close(); - } catch (CommunicationException e) { - System.err.println("Error closing server " + e.getMessage()); - fail("Error closing server " + e.getMessage()); - } - } -} +package meerkat.bulletinboard; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadMXBean; +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.SignatureException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.util.List; +import java.util.Random; + +import com.google.protobuf.ByteString; + +import meerkat.comm.CommunicationException; +import meerkat.crypto.concrete.ECDSASignature; +import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; +import meerkat.protobuf.BulletinBoardAPI.FilterType; +import meerkat.protobuf.BulletinBoardAPI.MessageFilter; +import meerkat.protobuf.BulletinBoardAPI.MessageFilterList; +import meerkat.protobuf.BulletinBoardAPI.UnsignedBulletinBoardMessage; + +import static org.junit.Assert.*; +import static org.hamcrest.CoreMatchers.*; + +public class GenericBulletinBoardServerTest { + + protected BulletinBoardServer bulletinBoardServer; + private ECDSASignature signers[]; + private ByteString[] signerIDs; + + private Random random; + + private static String KEYFILE_EXAMPLE = "/certs/enduser-certs/user1-key-with-password-secret.p12"; + private static String KEYFILE_EXAMPLE3 = "/certs/enduser-certs/user3-key-with-password-shh.p12"; + + private static String KEYFILE_PASSWORD1 = "secret"; + private static String KEYFILE_PASSWORD3 = "shh"; + + public static String CERT1_PEM_EXAMPLE = "/certs/enduser-certs/user1.crt"; + public static String CERT3_PEM_EXAMPLE = "/certs/enduser-certs/user3.crt"; + + private final int TAG_NUM = 5; // Number of tags. + private final int MESSAGE_NUM = 32; // Number of messages (2^TAG_NUM). + + private String[] tags; + private byte[][] data; + + private final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); // Used to time the tests + + /** + * @param bulletinBoardServer is an initialized server. + * @throws InstantiationException + * @throws IllegalAccessException + * @throws CertificateException + * @throws KeyStoreException + * @throws NoSuchAlgorithmException + * @throws IOException + * @throws UnrecoverableKeyException + * @throws CommunicationException + */ + public void init(BulletinBoardServer bulletinBoardServer) { + + System.err.println("Starting to initialize GenericBulletinBoardServerTest"); + long start = threadBean.getCurrentThreadCpuTime(); + + this.bulletinBoardServer = bulletinBoardServer; + + signers = new ECDSASignature[2]; + signerIDs = new ByteString[signers.length]; + signers[0] = new ECDSASignature(); + signers[1] = new ECDSASignature(); + + InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE); + char[] password = KEYFILE_PASSWORD1.toCharArray(); + + KeyStore.Builder keyStoreBuilder = null; + try { + keyStoreBuilder = signers[0].getPKCS12KeyStoreBuilder(keyStream, password); + + signers[0].loadSigningCertificate(keyStoreBuilder); + + signers[0].loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE)); + + keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE3); + password = KEYFILE_PASSWORD3.toCharArray(); + + keyStoreBuilder = signers[1].getPKCS12KeyStoreBuilder(keyStream, password); + signers[1].loadSigningCertificate(keyStoreBuilder); + + signers[1].loadVerificationCertificates(getClass().getResourceAsStream(CERT3_PEM_EXAMPLE)); + + for (int i = 0 ; i < signers.length ; i++) { + signerIDs[i] = signers[i].getSignerID(); + } + + } catch (IOException e) { + System.err.println("Failed reading from signature file " + e.getMessage()); + fail("Failed reading from signature file " + e.getMessage()); + } catch (CertificateException e) { + System.err.println("Failed reading certificate " + e.getMessage()); + fail("Failed reading certificate " + e.getMessage()); + } catch (KeyStoreException e) { + System.err.println("Failed reading keystore " + e.getMessage()); + fail("Failed reading keystore " + e.getMessage()); + } catch (NoSuchAlgorithmException e) { + System.err.println("Couldn't find signing algorithm " + e.getMessage()); + fail("Couldn't find signing algorithm " + e.getMessage()); + } catch (UnrecoverableKeyException e) { + System.err.println("Couldn't find signing key " + e.getMessage()); + fail("Couldn't find signing key " + e.getMessage()); + } + + random = new Random(0); // We use insecure randomness in tests for repeatability + + long end = threadBean.getCurrentThreadCpuTime(); + System.err.println("Finished initializing GenericBulletinBoardServerTest"); + System.err.println("Time of operation: " + (end - start)); + } + + private byte randomByte(){ + return (byte) random.nextInt(); + } + + private String randomString(){ + return new BigInteger(130, random).toString(32); + } + + /** + * Tests writing of several messages with multiple tags and signatures. + * @throws CommunicationException + * @throws SignatureException + * @throws InvalidKeyException + * @throws CertificateException + * @throws IOException + */ + public void testInsert() { + + System.err.println("Starting to insert messages to DB"); + long start = threadBean.getCurrentThreadCpuTime(); + + final int BYTES_PER_MESSAGE_DATA = 50; // Message size. + + tags = new String[TAG_NUM]; + data = new byte[MESSAGE_NUM][BYTES_PER_MESSAGE_DATA]; + + UnsignedBulletinBoardMessage.Builder unsignedMsgBuilder; + BulletinBoardMessage.Builder msgBuilder; + + int i, j; + + // Generate random data. + + for (i = 1; i <= MESSAGE_NUM; i++) { + for (j = 0; j < BYTES_PER_MESSAGE_DATA; j++) { + data[i - 1][j] = randomByte(); + } + } + + for (i = 0; i < TAG_NUM; i++) { + tags[i] = randomString(); + } + + // Build messages. + + for (i = 1; i <= MESSAGE_NUM; i++) { + unsignedMsgBuilder = UnsignedBulletinBoardMessage.newBuilder() + .setData(ByteString.copyFrom(data[i - 1])); + + // Add tags based on bit-representation of message number. + + int copyI = i; + for (j = 0; j < TAG_NUM; j++) { + if (copyI % 2 == 1) { + unsignedMsgBuilder.addTag(tags[j]); + } + + copyI >>>= 1; + } + + // Build message. + + msgBuilder = BulletinBoardMessage.newBuilder() + .setMsg(unsignedMsgBuilder.build()); + + // Add signatures. + + try { + + if (i % 2 == 1) { + signers[0].updateContent(msgBuilder.getMsg()); + msgBuilder.addSig(signers[0].sign()); + + if (i % 4 == 1) { + signers[1].updateContent(msgBuilder.getMsg()); + msgBuilder.addSig(signers[1].sign()); + } + } + + } catch (SignatureException e) { + fail(e.getMessage()); + } + + // Post message. + + try { + bulletinBoardServer.postMessage(msgBuilder.build()); + } catch (CommunicationException e) { + fail(e.getMessage()); + } + } + + long end = threadBean.getCurrentThreadCpuTime(); + System.err.println("Finished inserting messages to DB"); + System.err.println("Time of operation: " + (end - start)); + + } + + /** + * Tests retrieval of messages written in {@Link #testInsert()} + * Only queries using one tag filter + */ + public void testSimpleTagAndSignature(){ + + System.err.println("Starting to test tag and signature mechanism"); + long start = threadBean.getCurrentThreadCpuTime(); + + List messages; + + // Check tag mechanism + + for (int i = 0 ; i < TAG_NUM ; i++){ + + // Retrieve messages having tag i + + try { + + messages = bulletinBoardServer.readMessages( + MessageFilterList.newBuilder() + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.TAG) + .setTag(tags[i]) + .build() + ) + .build() + ) + .getMessageList(); + + } catch (CommunicationException e) { + fail(e.getMessage()); + return; + } + + // Assert that the number of retrieved messages is correct. + + assertThat(messages.size(), is(MESSAGE_NUM / 2)); + + // Assert the identity of the messages. + + for (BulletinBoardMessage msg : messages){ + + // Assert serial number and raw data. + + assertThat((msg.getEntryNum() >>> i) % 2 , is((long) 1)); + assertThat(msg.getMsg().getData().toByteArray(), is(data[(int) msg.getEntryNum() - 1])); + + // Assert signatures. + + try { + + if (msg.getEntryNum() % 2 == 1) { + signers[0].initVerify(msg.getSig(0)); + signers[0].updateContent(msg.getMsg()); + assertTrue("Signature did not verify!", signers[0].verify()); + + if (msg.getEntryNum() % 4 == 1) { + signers[1].initVerify(msg.getSig(1)); + signers[1].updateContent(msg.getMsg()); + assertTrue("Signature did not verify!", signers[1].verify()); + + assertThat(msg.getSigCount(), is(2)); + } else { + assertThat(msg.getSigCount(), is(1)); + } + } else { + assertThat(msg.getSigCount(), is(0)); + } + } catch (Exception e) { + fail(e.getMessage()); + } + } + + } + + long end = threadBean.getCurrentThreadCpuTime(); + System.err.println("Finished testing tag and signature mechanism"); + System.err.println("Time of operation: " + (end - start)); + + } + + /** + * Tests retrieval of messages written in {@Link #testInsert()} using multiple tags/signature filters. + */ + public void testEnhancedTagsAndSignatures(){ + + System.err.println("Starting to test multiple tags and signatures"); + long start = threadBean.getCurrentThreadCpuTime(); + + List messages; + MessageFilterList.Builder filterListBuilder = MessageFilterList.newBuilder(); + + int expectedMsgCount = MESSAGE_NUM; + + // Check multiple tag filters. + + for (int i = 0 ; i < TAG_NUM ; i++) { + + filterListBuilder.addFilter( + MessageFilter.newBuilder() + .setType(FilterType.TAG) + .setTag(tags[i]) + .build() + ); + + try { + messages = bulletinBoardServer.readMessages(filterListBuilder.build()).getMessageList(); + } catch (CommunicationException e) { + System.err.println("Failed retrieving multi-tag messages from DB: " + e.getMessage()); + fail("Failed retrieving multi-tag messages from DB: " + e.getMessage()); + return; + } + + expectedMsgCount /= 2; + + assertThat(messages.size(), is(expectedMsgCount)); + + for (BulletinBoardMessage msg : messages) { + for (int j = 0 ; j <= i ; j++) { + assertThat((msg.getEntryNum() >>> j) % 2, is((long) 1)); + } + } + } + + // Check multiple signature filters. + + filterListBuilder = MessageFilterList.newBuilder() + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.SIGNER_ID) + .setId(signerIDs[0]) + .build()) + .addFilter(MessageFilter.newBuilder() + .setType(FilterType.SIGNER_ID) + .setId(signerIDs[1]) + .build()); + + try { + messages = bulletinBoardServer.readMessages(filterListBuilder.build()).getMessageList(); + } catch (CommunicationException e) { + System.err.println("Failed retrieving multi-signature message from DB: " + e.getMessage()); + fail("Failed retrieving multi-signature message from DB: " + e.getMessage()); + return; + } + + assertThat(messages.size(), is(MESSAGE_NUM / 4)); + + for (BulletinBoardMessage message : messages) { + assertThat(message.getEntryNum() % 4, is((long) 1)); + } + + long end = threadBean.getCurrentThreadCpuTime(); + System.err.println("Finished testing multiple tags and signatures"); + System.err.println("Time of operation: " + (end - start)); + + } + + public void close(){ + signers[0].clearSigningKey(); + signers[1].clearSigningKey(); + try { + bulletinBoardServer.close(); + } catch (CommunicationException e) { + System.err.println("Error closing server " + e.getMessage()); + fail("Error closing server " + e.getMessage()); + } + } +} diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/H2BulletinBoardServerTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/H2BulletinBoardServerTest.java index ef19310..2792b7a 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/H2BulletinBoardServerTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/H2BulletinBoardServerTest.java @@ -1,122 +1,122 @@ -package meerkat.bulletinboard; - -import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer; -import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer.SQLQueryProvider; -import meerkat.bulletinboard.sqlserver.H2QueryProvider; -import meerkat.comm.CommunicationException; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.Result; - -import java.lang.management.ManagementFactory; -import java.lang.management.ThreadMXBean; -import java.sql.*; -import java.util.List; - -import static org.junit.Assert.fail; - -/** - * Created by Arbel Deutsch Peled on 07-Dec-15. - */ -public class H2BulletinBoardServerTest { - - private final String dbName = "meerkatTest"; - - private GenericBulletinBoardServerTest serverTest; - - private SQLQueryProvider queryProvider; - - private final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); // Used to time the tests - - @Before - public void init(){ - - System.err.println("Starting to initialize H2BulletinBoardServerTest"); - long start = threadBean.getCurrentThreadCpuTime(); - - queryProvider = new H2QueryProvider(dbName); - - try { - - Connection conn = queryProvider.getDataSource().getConnection(); - Statement stmt = conn.createStatement(); - - List deletionQueries = queryProvider.getSchemaDeletionCommands(); - - for (String deletionQuery : deletionQueries) { - stmt.execute(deletionQuery); - } - - } catch (SQLException e) { - System.err.println(e.getMessage()); - fail(e.getMessage()); - } - - BulletinBoardServer bulletinBoardServer = new BulletinBoardSQLServer(queryProvider); - try { - bulletinBoardServer.init(""); - - } catch (CommunicationException e) { - System.err.println(e.getMessage()); - fail(e.getMessage()); - return; - } - - serverTest = new GenericBulletinBoardServerTest(); - try { - serverTest.init(bulletinBoardServer); - } catch (Exception e) { - System.err.println(e.getMessage()); - fail(e.getMessage()); - } - - long end = threadBean.getCurrentThreadCpuTime(); - System.err.println("Finished initializing H2BulletinBoardServerTest"); - System.err.println("Time of operation: " + (end - start)); - } - - @Test - public void bulkTest() { - System.err.println("Starting bulkTest of H2BulletinBoardServerTest"); - long start = threadBean.getCurrentThreadCpuTime(); - - try { - serverTest.testInsert(); - } catch (Exception e) { - System.err.println(e.getMessage()); - fail(e.getMessage()); - } - - try{ - serverTest.testSimpleTagAndSignature(); - } catch (Exception e) { - System.err.println(e.getMessage()); - fail(e.getMessage()); - } - - try{ - serverTest.testEnhancedTagsAndSignatures(); - } catch (Exception e) { - System.err.println(e.getMessage()); - fail(e.getMessage()); - } - - long end = threadBean.getCurrentThreadCpuTime(); - System.err.println("Finished bulkTest of H2BulletinBoardServerTest"); - System.err.println("Time of operation: " + (end - start)); - } - - @After - public void close() { - System.err.println("Starting to close H2BulletinBoardServerTest"); - long start = threadBean.getCurrentThreadCpuTime(); - - serverTest.close(); - - long end = threadBean.getCurrentThreadCpuTime(); - System.err.println("Finished closing H2BulletinBoardServerTest"); - System.err.println("Time of operation: " + (end - start)); - } - -} +package meerkat.bulletinboard; + +import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer; +import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer.SQLQueryProvider; +import meerkat.bulletinboard.sqlserver.H2QueryProvider; +import meerkat.comm.CommunicationException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.Result; + +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadMXBean; +import java.sql.*; +import java.util.List; + +import static org.junit.Assert.fail; + +/** + * Created by Arbel Deutsch Peled on 07-Dec-15. + */ +public class H2BulletinBoardServerTest { + + private final String dbName = "meerkatTest"; + + private GenericBulletinBoardServerTest serverTest; + + private SQLQueryProvider queryProvider; + + private final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); // Used to time the tests + + @Before + public void init(){ + + System.err.println("Starting to initialize H2BulletinBoardServerTest"); + long start = threadBean.getCurrentThreadCpuTime(); + + queryProvider = new H2QueryProvider(dbName); + + try { + + Connection conn = queryProvider.getDataSource().getConnection(); + Statement stmt = conn.createStatement(); + + List deletionQueries = queryProvider.getSchemaDeletionCommands(); + + for (String deletionQuery : deletionQueries) { + stmt.execute(deletionQuery); + } + + } catch (SQLException e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + + BulletinBoardServer bulletinBoardServer = new BulletinBoardSQLServer(queryProvider); + try { + bulletinBoardServer.init(""); + + } catch (CommunicationException e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + return; + } + + serverTest = new GenericBulletinBoardServerTest(); + try { + serverTest.init(bulletinBoardServer); + } catch (Exception e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + + long end = threadBean.getCurrentThreadCpuTime(); + System.err.println("Finished initializing H2BulletinBoardServerTest"); + System.err.println("Time of operation: " + (end - start)); + } + + @Test + public void bulkTest() { + System.err.println("Starting bulkTest of H2BulletinBoardServerTest"); + long start = threadBean.getCurrentThreadCpuTime(); + + try { + serverTest.testInsert(); + } catch (Exception e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + + try{ + serverTest.testSimpleTagAndSignature(); + } catch (Exception e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + + try{ + serverTest.testEnhancedTagsAndSignatures(); + } catch (Exception e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + + long end = threadBean.getCurrentThreadCpuTime(); + System.err.println("Finished bulkTest of H2BulletinBoardServerTest"); + System.err.println("Time of operation: " + (end - start)); + } + + @After + public void close() { + System.err.println("Starting to close H2BulletinBoardServerTest"); + long start = threadBean.getCurrentThreadCpuTime(); + + serverTest.close(); + + long end = threadBean.getCurrentThreadCpuTime(); + System.err.println("Finished closing H2BulletinBoardServerTest"); + System.err.println("Time of operation: " + (end - start)); + } + +} diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/HelloProtoIntegrationTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/HelloProtoIntegrationTest.java index c7b16df..a0c3653 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/HelloProtoIntegrationTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/HelloProtoIntegrationTest.java @@ -1,42 +1,42 @@ -package meerkat.bulletinboard; - -import meerkat.protobuf.BulletinBoardAPI.*; -import meerkat.rest.Constants; -import meerkat.rest.ProtobufMessageBodyReader; -import meerkat.rest.ProtobufMessageBodyWriter; -import org.junit.Test; - -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.WebTarget; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; - -/** - * Created by talm on 10/11/15. - */ -public class HelloProtoIntegrationTest { - private static String PROP_GETTY_URL = "gretty.httpBaseURI"; - private static String DEFAULT_BASE_URL = "http://localhost:8081/"; - private static String BASE_URL = System.getProperty(PROP_GETTY_URL, DEFAULT_BASE_URL); - private static String HELLO_URL = "proto"; - - @Test - public void testHello() throws Exception { - Client client = ClientBuilder.newClient(); - client.register(ProtobufMessageBodyReader.class); - client.register(ProtobufMessageBodyWriter.class); - - WebTarget webTarget = client.target(BASE_URL).path(HELLO_URL); - BulletinBoardMessage response = webTarget.request(Constants.MEDIATYPE_PROTOBUF) - .get(BulletinBoardMessage.class); - - System.out.println(response.getMsg().getData()); - - assertThat(response.getMsg().getData().toStringUtf8(), is("Hello World!")); - assertThat(response.getMsg().getTagCount(), is(2)); - assertThat(response.getMsg().getTag(0), is("Greetings")); - assertThat(response.getMsg().getTag(1), is("FirstPrograms")); - } -} +package meerkat.bulletinboard; + +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.rest.Constants; +import meerkat.rest.ProtobufMessageBodyReader; +import meerkat.rest.ProtobufMessageBodyWriter; +import org.junit.Test; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.WebTarget; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +/** + * Created by talm on 10/11/15. + */ +public class HelloProtoIntegrationTest { + private static String PROP_GETTY_URL = "gretty.httpBaseURI"; + private static String DEFAULT_BASE_URL = "http://localhost:8081/"; + private static String BASE_URL = System.getProperty(PROP_GETTY_URL, DEFAULT_BASE_URL); + private static String HELLO_URL = "proto"; + + @Test + public void testHello() throws Exception { + Client client = ClientBuilder.newClient(); + client.register(ProtobufMessageBodyReader.class); + client.register(ProtobufMessageBodyWriter.class); + + WebTarget webTarget = client.target(BASE_URL).path(HELLO_URL); + BulletinBoardMessage response = webTarget.request(Constants.MEDIATYPE_PROTOBUF) + .get(BulletinBoardMessage.class); + + System.out.println(response.getMsg().getData()); + + assertThat(response.getMsg().getData().toStringUtf8(), is("Hello World!")); + assertThat(response.getMsg().getTagCount(), is(2)); + assertThat(response.getMsg().getTag(0), is("Greetings")); + assertThat(response.getMsg().getTag(1), is("FirstPrograms")); + } +} diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/MySQLBulletinBoardServerTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/MySQLBulletinBoardServerTest.java index e473931..20e3f58 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/MySQLBulletinBoardServerTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/MySQLBulletinBoardServerTest.java @@ -1,126 +1,126 @@ -package meerkat.bulletinboard; - -import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer; -import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer.SQLQueryProvider; -import meerkat.bulletinboard.sqlserver.MySQLQueryProvider; -import meerkat.comm.CommunicationException; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.lang.management.ManagementFactory; -import java.lang.management.ThreadMXBean; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.List; - -import static org.junit.Assert.fail; - -/** - * Created by Arbel Deutsch Peled on 07-Dec-15. - */ -public class MySQLBulletinBoardServerTest { - - private final String dbAddress = "localhost"; - private final int dbPort = 3306; - private final String dbName = "meerkat"; - private final String username = "arbel"; - private final String password = "mypass"; - - private GenericBulletinBoardServerTest serverTest; - - private final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); // Used to time the tests - - @Before - public void init(){ - - System.err.println("Starting to initialize MySQLBulletinBoardServerTest"); - long start = threadBean.getCurrentThreadCpuTime(); - - SQLQueryProvider queryProvider = new MySQLQueryProvider(dbAddress,dbPort,dbName,username,password); - - try { - - Connection conn = queryProvider.getDataSource().getConnection(); - Statement stmt = conn.createStatement(); - - List deletionQueries = queryProvider.getSchemaDeletionCommands(); - - for (String deletionQuery : deletionQueries) { - stmt.execute(deletionQuery); - } - - } catch (SQLException e) { - System.err.println(e.getMessage()); - fail(e.getMessage()); - } - - BulletinBoardServer bulletinBoardServer = new BulletinBoardSQLServer(queryProvider); - try { - bulletinBoardServer.init(""); - - } catch (CommunicationException e) { - System.err.println(e.getMessage()); - fail(e.getMessage()); - return; - } - - serverTest = new GenericBulletinBoardServerTest(); - try { - serverTest.init(bulletinBoardServer); - } catch (Exception e) { - System.err.println(e.getMessage()); - fail(e.getMessage()); - } - - long end = threadBean.getCurrentThreadCpuTime(); - System.err.println("Finished initializing MySQLBulletinBoardServerTest"); - System.err.println("Time of operation: " + (end - start)); - } - - @Test - public void bulkTest() { - System.err.println("Starting bulkTest of MySQLBulletinBoardServerTest"); - long start = threadBean.getCurrentThreadCpuTime(); - - try { - serverTest.testInsert(); - } catch (Exception e) { - System.err.println(e.getMessage()); - fail(e.getMessage()); - } - - try{ - serverTest.testSimpleTagAndSignature(); - } catch (Exception e) { - System.err.println(e.getMessage()); - fail(e.getMessage()); - } - - try{ - serverTest.testEnhancedTagsAndSignatures(); - } catch (Exception e) { - System.err.println(e.getMessage()); - fail(e.getMessage()); - } - - long end = threadBean.getCurrentThreadCpuTime(); - System.err.println("Finished bulkTest of MySQLBulletinBoardServerTest"); - System.err.println("Time of operation: " + (end - start)); - } - - @After - public void close() { - System.err.println("Starting to close MySQLBulletinBoardServerTest"); - long start = threadBean.getCurrentThreadCpuTime(); - - serverTest.close(); - - long end = threadBean.getCurrentThreadCpuTime(); - System.err.println("Finished closing MySQLBulletinBoardServerTest"); - System.err.println("Time of operation: " + (end - start)); - } - -} +package meerkat.bulletinboard; + +import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer; +import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer.SQLQueryProvider; +import meerkat.bulletinboard.sqlserver.MySQLQueryProvider; +import meerkat.comm.CommunicationException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadMXBean; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.List; + +import static org.junit.Assert.fail; + +/** + * Created by Arbel Deutsch Peled on 07-Dec-15. + */ +public class MySQLBulletinBoardServerTest { + + private final String dbAddress = "localhost"; + private final int dbPort = 3306; + private final String dbName = "meerkat"; + private final String username = "arbel"; + private final String password = "mypass"; + + private GenericBulletinBoardServerTest serverTest; + + private final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); // Used to time the tests + + @Before + public void init(){ + + System.err.println("Starting to initialize MySQLBulletinBoardServerTest"); + long start = threadBean.getCurrentThreadCpuTime(); + + SQLQueryProvider queryProvider = new MySQLQueryProvider(dbAddress,dbPort,dbName,username,password); + + try { + + Connection conn = queryProvider.getDataSource().getConnection(); + Statement stmt = conn.createStatement(); + + List deletionQueries = queryProvider.getSchemaDeletionCommands(); + + for (String deletionQuery : deletionQueries) { + stmt.execute(deletionQuery); + } + + } catch (SQLException e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + + BulletinBoardServer bulletinBoardServer = new BulletinBoardSQLServer(queryProvider); + try { + bulletinBoardServer.init(""); + + } catch (CommunicationException e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + return; + } + + serverTest = new GenericBulletinBoardServerTest(); + try { + serverTest.init(bulletinBoardServer); + } catch (Exception e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + + long end = threadBean.getCurrentThreadCpuTime(); + System.err.println("Finished initializing MySQLBulletinBoardServerTest"); + System.err.println("Time of operation: " + (end - start)); + } + + @Test + public void bulkTest() { + System.err.println("Starting bulkTest of MySQLBulletinBoardServerTest"); + long start = threadBean.getCurrentThreadCpuTime(); + + try { + serverTest.testInsert(); + } catch (Exception e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + + try{ + serverTest.testSimpleTagAndSignature(); + } catch (Exception e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + + try{ + serverTest.testEnhancedTagsAndSignatures(); + } catch (Exception e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + + long end = threadBean.getCurrentThreadCpuTime(); + System.err.println("Finished bulkTest of MySQLBulletinBoardServerTest"); + System.err.println("Time of operation: " + (end - start)); + } + + @After + public void close() { + System.err.println("Starting to close MySQLBulletinBoardServerTest"); + long start = threadBean.getCurrentThreadCpuTime(); + + serverTest.close(); + + long end = threadBean.getCurrentThreadCpuTime(); + System.err.println("Finished closing MySQLBulletinBoardServerTest"); + System.err.println("Time of operation: " + (end - start)); + } + +} diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/SQLiteBulletinBoardServerTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/SQLiteBulletinBoardServerTest.java index 1d7aae0..cbbd6f9 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/SQLiteBulletinBoardServerTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/SQLiteBulletinBoardServerTest.java @@ -1,106 +1,106 @@ -package meerkat.bulletinboard; - -import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer; -import meerkat.bulletinboard.sqlserver.SQLiteQueryProvider; -import meerkat.comm.CommunicationException; -import meerkat.protobuf.*; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.File; -import java.io.IOException; -import java.lang.management.ManagementFactory; -import java.lang.management.ThreadMXBean; -import java.security.*; -import java.security.cert.CertificateException; - -import static org.junit.Assert.fail; - -/** - * Created by Arbel Deutsch Peled on 07-Dec-15. - */ -public class SQLiteBulletinBoardServerTest{ - - private String testFilename = "SQLiteDBTest.db"; - - private GenericBulletinBoardServerTest serverTest; - - private final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); // Used to time the tests - - @Before - public void init(){ - - System.err.println("Starting to initialize SQLiteBulletinBoardServerTest"); - long start = threadBean.getCurrentThreadCpuTime(); - - File old = new File(testFilename); - old.delete(); - - BulletinBoardServer bulletinBoardServer = new BulletinBoardSQLServer(new SQLiteQueryProvider(testFilename)); - try { - bulletinBoardServer.init(""); - - } catch (CommunicationException e) { - System.err.println(e.getMessage()); - fail(e.getMessage()); - return; - } - - serverTest = new GenericBulletinBoardServerTest(); - try { - serverTest.init(bulletinBoardServer); - } catch (Exception e) { - System.err.println(e.getMessage()); - fail(e.getMessage()); - } - - long end = threadBean.getCurrentThreadCpuTime(); - System.err.println("Finished initializing SQLiteBulletinBoardServerTest"); - System.err.println("Time of operation: " + (end - start)); - } - - @Test - public void bulkTest() { - System.err.println("Starting bulkTest of SQLiteBulletinBoardServerTest"); - long start = threadBean.getCurrentThreadCpuTime(); - - try { - serverTest.testInsert(); - } catch (Exception e) { - System.err.println(e.getMessage()); - fail(e.getMessage()); - } - - try{ - serverTest.testSimpleTagAndSignature(); - } catch (Exception e) { - System.err.println(e.getMessage()); - fail(e.getMessage()); - } - - try{ - serverTest.testEnhancedTagsAndSignatures(); - } catch (Exception e) { - System.err.println(e.getMessage()); - fail(e.getMessage()); - } - - long end = threadBean.getCurrentThreadCpuTime(); - System.err.println("Finished bulkTest of SQLiteBulletinBoardServerTest"); - System.err.println("Time of operation: " + (end - start)); - } - - @After - public void close() { - System.err.println("Starting to close SQLiteBulletinBoardServerTest"); - long start = threadBean.getCurrentThreadCpuTime(); - - serverTest.close(); - - long end = threadBean.getCurrentThreadCpuTime(); - System.err.println("Finished closing SQLiteBulletinBoardServerTest"); - System.err.println("Time of operation: " + (end - start)); - } - -} +package meerkat.bulletinboard; + +import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer; +import meerkat.bulletinboard.sqlserver.SQLiteQueryProvider; +import meerkat.comm.CommunicationException; +import meerkat.protobuf.*; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadMXBean; +import java.security.*; +import java.security.cert.CertificateException; + +import static org.junit.Assert.fail; + +/** + * Created by Arbel Deutsch Peled on 07-Dec-15. + */ +public class SQLiteBulletinBoardServerTest{ + + private String testFilename = "SQLiteDBTest.db"; + + private GenericBulletinBoardServerTest serverTest; + + private final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); // Used to time the tests + + @Before + public void init(){ + + System.err.println("Starting to initialize SQLiteBulletinBoardServerTest"); + long start = threadBean.getCurrentThreadCpuTime(); + + File old = new File(testFilename); + old.delete(); + + BulletinBoardServer bulletinBoardServer = new BulletinBoardSQLServer(new SQLiteQueryProvider(testFilename)); + try { + bulletinBoardServer.init(""); + + } catch (CommunicationException e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + return; + } + + serverTest = new GenericBulletinBoardServerTest(); + try { + serverTest.init(bulletinBoardServer); + } catch (Exception e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + + long end = threadBean.getCurrentThreadCpuTime(); + System.err.println("Finished initializing SQLiteBulletinBoardServerTest"); + System.err.println("Time of operation: " + (end - start)); + } + + @Test + public void bulkTest() { + System.err.println("Starting bulkTest of SQLiteBulletinBoardServerTest"); + long start = threadBean.getCurrentThreadCpuTime(); + + try { + serverTest.testInsert(); + } catch (Exception e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + + try{ + serverTest.testSimpleTagAndSignature(); + } catch (Exception e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + + try{ + serverTest.testEnhancedTagsAndSignatures(); + } catch (Exception e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + + long end = threadBean.getCurrentThreadCpuTime(); + System.err.println("Finished bulkTest of SQLiteBulletinBoardServerTest"); + System.err.println("Time of operation: " + (end - start)); + } + + @After + public void close() { + System.err.println("Starting to close SQLiteBulletinBoardServerTest"); + long start = threadBean.getCurrentThreadCpuTime(); + + serverTest.close(); + + long end = threadBean.getCurrentThreadCpuTime(); + System.err.println("Finished closing SQLiteBulletinBoardServerTest"); + System.err.println("Time of operation: " + (end - start)); + } + +} diff --git a/destributed-key-generation/build.gradle b/destributed-key-generation/build.gradle index 60ec7c9..074667f 100644 --- a/destributed-key-generation/build.gradle +++ b/destributed-key-generation/build.gradle @@ -1,220 +1,220 @@ - -plugins { - id "us.kirchmeier.capsule" version "1.0.1" - id 'com.google.protobuf' version '0.7.0' -} - -apply plugin: 'java' -apply plugin: 'eclipse' -apply plugin: 'idea' - -apply plugin: 'maven-publish' - -// Uncomment the lines below to define an application -// (this will also allow you to build a "fatCapsule" which includes -// the entire application, including all dependencies in a single jar) -//apply plugin: 'application' -//mainClassName='your.main.ApplicationClass' - -// Is this a snapshot version? -ext { isSnapshot = false } - -ext { - groupId = 'org.factcenter.meerkat' - nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/" - - // Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing) - // Should be set in ${HOME}/.gradle/gradle.properties - nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : "" - nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : "" -} - -description = "TODO: Add a description" - -// Your project version -version = "0.0" - -version += "${isSnapshot ? '-SNAPSHOT' : ''}" - - -dependencies { - // Meerkat common - compile project(':meerkat-common') - - // Logging - compile 'org.slf4j:slf4j-api:1.7.7' - runtime 'ch.qos.logback:logback-classic:1.1.2' - runtime 'ch.qos.logback:logback-core:1.1.2' - - // Google protobufs - compile 'com.google.protobuf:protobuf-java:3.+' - - testCompile 'junit:junit:4.+' - - runtime 'org.codehaus.groovy:groovy:2.4.+' -} - - -/*==== You probably don't have to edit below this line =======*/ - -// Setup test configuration that can appear as a dependency in -// other subprojects -configurations { - testOutput.extendsFrom (testCompile) -} - -task testJar(type: Jar, dependsOn: testClasses) { - classifier = 'tests' - from sourceSets.test.output -} - -artifacts { - testOutput testJar -} - -// The run task added by the application plugin -// is also of type JavaExec. -tasks.withType(JavaExec) { - // Assign all Java system properties from - // the command line to the JavaExec task. - systemProperties System.properties -} - - -protobuf { - // Configure the protoc executable - protoc { - // Download from repositories - artifact = 'com.google.protobuf:protoc:3.+' - } -} - - -idea { - module { - project.sourceSets.each { sourceSet -> - - def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java" - - println "Adding $srcDir" - // add protobuf generated sources to generated source dir. - if ("test".equals(sourceSet.name)) { - testSourceDirs += file(srcDir) - } else { - sourceDirs += file(srcDir) - } - generatedSourceDirs += file(srcDir) - - } - - // Don't exclude build directory - excludeDirs -= file(buildDir) - } -} - - -/*=================================== - * "Fat" Build targets - *===================================*/ - - -if (project.hasProperty('mainClassName') && (mainClassName != null)) { - - task mavenCapsule(type: MavenCapsule) { - description = "Generate a capsule jar that automatically downloads and caches dependencies when run." - applicationClass mainClassName - destinationDir = buildDir - } - - task fatCapsule(type: FatCapsule) { - description = "Generate a single capsule jar containing everything. Use -Pfatmain=... to override main class" - - destinationDir = buildDir - - def fatMain = hasProperty('fatmain') ? fatmain : mainClassName - - applicationClass fatMain - - def testJar = hasProperty('test') - - if (hasProperty('fatmain')) { - appendix = "fat-${fatMain}" - } else { - appendix = "fat" - } - - if (testJar) { - from sourceSets.test.output - } - } -} - - -/*=================================== - * Repositories - *===================================*/ - -repositories { - - // Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral) - maven { - url nexusRepository - - if (isSnapshot) { - credentials { username - password - - username nexusUser - password nexusPassword - } - } - } - - // Use local maven repository - mavenLocal() - - // Use 'maven central' for other dependencies. - mavenCentral() -} - -task "info" << { - println "Project: ${project.name}" -println "Description: ${project.description}" - println "--------------------------" - println "GroupId: $groupId" - println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})" - println "" -} -info.description 'Print some information about project parameters' - - -/*=================================== - * Publishing - *===================================*/ - -publishing { - publications { - mavenJava(MavenPublication) { - groupId project.groupId - pom.withXml { - asNode().appendNode('description', project.description) - } - from project.components.java - - } - } - repositories { - maven { - url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}" - credentials { username - password - - username nexusUser - password nexusPassword - } - } - } -} - - - + +plugins { + id "us.kirchmeier.capsule" version "1.0.1" + id 'com.google.protobuf' version '0.7.0' +} + +apply plugin: 'java' +apply plugin: 'eclipse' +apply plugin: 'idea' + +apply plugin: 'maven-publish' + +// Uncomment the lines below to define an application +// (this will also allow you to build a "fatCapsule" which includes +// the entire application, including all dependencies in a single jar) +//apply plugin: 'application' +//mainClassName='your.main.ApplicationClass' + +// Is this a snapshot version? +ext { isSnapshot = false } + +ext { + groupId = 'org.factcenter.meerkat' + nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/" + + // Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing) + // Should be set in ${HOME}/.gradle/gradle.properties + nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : "" + nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : "" +} + +description = "TODO: Add a description" + +// Your project version +version = "0.0" + +version += "${isSnapshot ? '-SNAPSHOT' : ''}" + + +dependencies { + // Meerkat common + compile project(':meerkat-common') + + // Logging + compile 'org.slf4j:slf4j-api:1.7.7' + runtime 'ch.qos.logback:logback-classic:1.1.2' + runtime 'ch.qos.logback:logback-core:1.1.2' + + // Google protobufs + compile 'com.google.protobuf:protobuf-java:3.+' + + testCompile 'junit:junit:4.+' + + runtime 'org.codehaus.groovy:groovy:2.4.+' +} + + +/*==== You probably don't have to edit below this line =======*/ + +// Setup test configuration that can appear as a dependency in +// other subprojects +configurations { + testOutput.extendsFrom (testCompile) +} + +task testJar(type: Jar, dependsOn: testClasses) { + classifier = 'tests' + from sourceSets.test.output +} + +artifacts { + testOutput testJar +} + +// The run task added by the application plugin +// is also of type JavaExec. +tasks.withType(JavaExec) { + // Assign all Java system properties from + // the command line to the JavaExec task. + systemProperties System.properties +} + + +protobuf { + // Configure the protoc executable + protoc { + // Download from repositories + artifact = 'com.google.protobuf:protoc:3.+' + } +} + + +idea { + module { + project.sourceSets.each { sourceSet -> + + def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java" + + println "Adding $srcDir" + // add protobuf generated sources to generated source dir. + if ("test".equals(sourceSet.name)) { + testSourceDirs += file(srcDir) + } else { + sourceDirs += file(srcDir) + } + generatedSourceDirs += file(srcDir) + + } + + // Don't exclude build directory + excludeDirs -= file(buildDir) + } +} + + +/*=================================== + * "Fat" Build targets + *===================================*/ + + +if (project.hasProperty('mainClassName') && (mainClassName != null)) { + + task mavenCapsule(type: MavenCapsule) { + description = "Generate a capsule jar that automatically downloads and caches dependencies when run." + applicationClass mainClassName + destinationDir = buildDir + } + + task fatCapsule(type: FatCapsule) { + description = "Generate a single capsule jar containing everything. Use -Pfatmain=... to override main class" + + destinationDir = buildDir + + def fatMain = hasProperty('fatmain') ? fatmain : mainClassName + + applicationClass fatMain + + def testJar = hasProperty('test') + + if (hasProperty('fatmain')) { + appendix = "fat-${fatMain}" + } else { + appendix = "fat" + } + + if (testJar) { + from sourceSets.test.output + } + } +} + + +/*=================================== + * Repositories + *===================================*/ + +repositories { + + // Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral) + maven { + url nexusRepository + + if (isSnapshot) { + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } + + // Use local maven repository + mavenLocal() + + // Use 'maven central' for other dependencies. + mavenCentral() +} + +task "info" << { + println "Project: ${project.name}" +println "Description: ${project.description}" + println "--------------------------" + println "GroupId: $groupId" + println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})" + println "" +} +info.description 'Print some information about project parameters' + + +/*=================================== + * Publishing + *===================================*/ + +publishing { + publications { + mavenJava(MavenPublication) { + groupId project.groupId + pom.withXml { + asNode().appendNode('description', project.description) + } + from project.components.java + + } + } + repositories { + maven { + url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}" + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } +} + + + diff --git a/destributed-key-generation/src/main/java/Arithmetics/Arithmetic.java b/destributed-key-generation/src/main/java/Arithmetics/Arithmetic.java index bd9920a..979ea60 100644 --- a/destributed-key-generation/src/main/java/Arithmetics/Arithmetic.java +++ b/destributed-key-generation/src/main/java/Arithmetics/Arithmetic.java @@ -1,14 +1,18 @@ -package Arithmetics; - -import java.math.BigInteger; - -/** - * Created by Tzlil on 3/17/2016. - */ -public interface Arithmetic { - BigInteger add(T a,T b); - BigInteger sub(T a,T b); - BigInteger mul(T a,T b); - BigInteger div(T a,T b); - -} +package Arithmetics; + +/** + * Created by Tzlil on 3/17/2016. + */ +public interface Arithmetic { + /** + * + * @param a + * @param b + * @return + */ + T add(T a, T b); + T sub(T a, T b); + T mul(T a, T b); + T div(T a, T b); + +} diff --git a/destributed-key-generation/src/main/java/Arithmetics/Fp.java b/destributed-key-generation/src/main/java/Arithmetics/Fp.java index db2d6da..0525d08 100644 --- a/destributed-key-generation/src/main/java/Arithmetics/Fp.java +++ b/destributed-key-generation/src/main/java/Arithmetics/Fp.java @@ -1,38 +1,38 @@ -package Arithmetics; - -import org.factcenter.qilin.primitives.concrete.Zpstar; - -import java.math.BigInteger; - -/** - * Created by Tzlil on 3/17/2016. - */ -public class Fp implements Arithmetic { - public final BigInteger p; - private final Zpstar zp; - - public Fp(BigInteger p) { - this.p = p; - this.zp = new Zpstar(p); - } - - @Override - public BigInteger add(BigInteger a,BigInteger b){ - return a.add(b).mod(p); - } - - @Override - public BigInteger sub(BigInteger a,BigInteger b){ - return a.add(p).subtract(b).mod(p); - } - - @Override - public BigInteger mul(BigInteger a,BigInteger b){ - return zp.add(a,b); - } - - @Override - public BigInteger div(BigInteger a,BigInteger b){ - return mul(a,zp.negate(b)); - } -} +package Arithmetics; + +import org.factcenter.qilin.primitives.concrete.Zpstar; + +import java.math.BigInteger; + +/** + * Created by Tzlil on 3/17/2016. + */ +public class Fp implements Arithmetic { + public final BigInteger p; + private final Zpstar zp; + + public Fp(BigInteger p) { + this.p = p; + this.zp = new Zpstar(p); + } + + @Override + public BigInteger add(BigInteger a, BigInteger b){ + return a.add(b).mod(p); + } + + @Override + public BigInteger sub(BigInteger a, BigInteger b){ + return a.add(p).subtract(b).mod(p); + } + + @Override + public BigInteger mul(BigInteger a, BigInteger b){ + return zp.add(a,b); + } + + @Override + public BigInteger div(BigInteger a, BigInteger b){ + return mul(a,zp.negate(b)); + } +} diff --git a/destributed-key-generation/src/main/java/Arithmetics/Z.java b/destributed-key-generation/src/main/java/Arithmetics/Z.java index 9523ead..acf486d 100644 --- a/destributed-key-generation/src/main/java/Arithmetics/Z.java +++ b/destributed-key-generation/src/main/java/Arithmetics/Z.java @@ -1,29 +1,29 @@ -package Arithmetics; - -import java.math.BigInteger; - -/** - * Created by Tzlil on 3/17/2016. - */ -public class Z implements Arithmetic { - - @Override - public BigInteger add(BigInteger a, BigInteger b) { - return a.add(b); - } - - @Override - public BigInteger sub(BigInteger a, BigInteger b) { - return a.subtract(b); - } - - @Override - public BigInteger mul(BigInteger a, BigInteger b) { - return a.multiply(b); - } - - @Override - public BigInteger div(BigInteger a, BigInteger b) { - return a.divide(b); - } -} +package Arithmetics; + +import java.math.BigInteger; + +/** + * Created by Tzlil on 3/17/2016. + */ +public class Z implements Arithmetic { + + @Override + public BigInteger add(BigInteger a, BigInteger b) { + return a.add(b); + } + + @Override + public BigInteger sub(BigInteger a, BigInteger b) { + return a.subtract(b); + } + + @Override + public BigInteger mul(BigInteger a, BigInteger b) { + return a.multiply(b); + } + + @Override + public BigInteger div(BigInteger a, BigInteger b) { + return a.divide(b); + } +} diff --git a/destributed-key-generation/src/main/java/Communication/Channel.java b/destributed-key-generation/src/main/java/Communication/Channel.java new file mode 100644 index 0000000..cedb213 --- /dev/null +++ b/destributed-key-generation/src/main/java/Communication/Channel.java @@ -0,0 +1,28 @@ +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 Channel thread, so no long processing should +// * occur in the callback method. +// * @param callback +// */ +// public void registerReceiverCallback(ReceiverCallback callback); +//} diff --git a/destributed-key-generation/src/main/java/Communication/MailHandler.java b/destributed-key-generation/src/main/java/Communication/MailHandler.java index fbb0522..23fd840 100644 --- a/destributed-key-generation/src/main/java/Communication/MailHandler.java +++ b/destributed-key-generation/src/main/java/Communication/MailHandler.java @@ -1,59 +1,58 @@ -package Communication; - -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Message; -import meerkat.protobuf.DKGMessages; - -/** - * Created by Tzlil on 2/14/2016. - */ -public abstract class MailHandler { - - private MessageHandler messageHandler; - public MailHandler(MessageHandler messageHandler){ - this.messageHandler = messageHandler; - } - - public abstract Message extractMessage(DKGMessages.Mail mail); - - public void handel(DKGMessages.Mail mail){ - - Message message = extractMessage(mail); - if (message == null) - return; - - switch (mail.getType()) { - case SECRET: - messageHandler.handelSecretMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST - , message); - break; - case COMMITMENT: - messageHandler.handelCommitmentMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST - , message); - break; - case DONE: - messageHandler.handelDoneMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST - , message); - break; - case COMPLAINT: - messageHandler.handelComplaintMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST - , message); - break; - case ANSWER: - messageHandler.handelAnswerMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST - , message); - break; - case ABORT: - messageHandler.handelAbortMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST - , message); - break; - default: - break; - } - - - } - public void setMessageHandler(MessageHandler messageHandler) { - this.messageHandler = messageHandler; - } -} +package Communication; + +import com.google.protobuf.Message; +import meerkat.protobuf.DKGMessages; + +/** + * Created by Tzlil on 2/14/2016. + */ +public abstract class MailHandler { + + private MessageHandler messageHandler; + public MailHandler(MessageHandler messageHandler){ + this.messageHandler = messageHandler; + } + + public abstract Message extractMessage(DKGMessages.Mail mail); + + public void handel(DKGMessages.Mail mail){ + + Message message = extractMessage(mail); + if (message == null) + return; + + switch (mail.getType()) { + case SECRET: + messageHandler.handleSecretMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST + , message); + break; + case COMMITMENT: + messageHandler.handleCommitmentMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST + , message); + break; + case DONE: + messageHandler.handleDoneMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST + , message); + break; + case COMPLAINT: + messageHandler.handleComplaintMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST + , message); + break; + case ANSWER: + messageHandler.handleAnswerMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST + , message); + break; + case ABORT: + messageHandler.handleAbortMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST + , message); + break; + default: + break; + } + + + } + public void setMessageHandler(MessageHandler messageHandler) { + this.messageHandler = messageHandler; + } +} diff --git a/destributed-key-generation/src/main/java/Communication/MessageHandler.java b/destributed-key-generation/src/main/java/Communication/MessageHandler.java index 8cedf4e..2bbf3c4 100644 --- a/destributed-key-generation/src/main/java/Communication/MessageHandler.java +++ b/destributed-key-generation/src/main/java/Communication/MessageHandler.java @@ -1,15 +1,15 @@ -package Communication; - -import com.google.protobuf.Message; - -/** - * Created by Tzlil on 2/14/2016. - */ -public interface MessageHandler { - void handelSecretMessage(int sender, boolean isBroadcast, Message message); - void handelCommitmentMessage(int sender, boolean isBroadcast, Message message); - void handelComplaintMessage(int sender, boolean isBroadcast, Message message); - void handelDoneMessage(int sender, boolean isBroadcast, Message message); - void handelAnswerMessage(int sender, boolean isBroadcast, Message message); - void handelAbortMessage(int sender, boolean isBroadcast, Message message); -} +package Communication; + +import com.google.protobuf.Message; + +/** + * Created by Tzlil on 2/14/2016. + */ +public interface MessageHandler { + void handleSecretMessage(int sender, boolean isBroadcast, Message message); + void handleCommitmentMessage(int sender, boolean isBroadcast, Message message); + void handleComplaintMessage(int sender, boolean isBroadcast, Message message); + void handleDoneMessage(int sender, boolean isBroadcast, Message message); + void handleAnswerMessage(int sender, boolean isBroadcast, Message message); + void handleAbortMessage(int sender, boolean isBroadcast, Message message); +} diff --git a/destributed-key-generation/src/main/java/Communication/Network.java b/destributed-key-generation/src/main/java/Communication/Network.java index 541179e..8de25b3 100644 --- a/destributed-key-generation/src/main/java/Communication/Network.java +++ b/destributed-key-generation/src/main/java/Communication/Network.java @@ -1,73 +1,75 @@ -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 chanel - * and private chanel (for each pair) - * this class simulates it - */ -public class Network { - - protected final User[] users; - protected final int n; - protected final Set availableIDs; - public static final int BROADCAST = 0; - - - public Network(int n) { - this.n = n; - this.users = new User[n]; - this.availableIDs = new HashSet(); - 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); - } - } - -} +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 availableIDs; + public static final int BROADCAST = 0; + + + public Network(int n) { + this.n = n; + this.users = new User[n]; + this.availableIDs = new HashSet(); + 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); + } + } + +} diff --git a/destributed-key-generation/src/main/java/Communication/User.java b/destributed-key-generation/src/main/java/Communication/User.java index 2077d6e..1eb6e4a 100644 --- a/destributed-key-generation/src/main/java/Communication/User.java +++ b/destributed-key-generation/src/main/java/Communication/User.java @@ -1,66 +1,74 @@ -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. - */ -public class User{ - protected final MailHandler mailHandler; - protected final Queue 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( 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 - } - } - } - } - } - - -} +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 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( 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 + } + } + } + } + } + + +} diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java index 4573c57..7b5b7ad 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java @@ -1,96 +1,102 @@ -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. - * - */ -public class VerifiableSecretSharing extends SecretSharing { - protected final Group 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 group) { - super(t, n, x, random,q); - this.g = g; - this.group = group; - assert (this.group.contains(g)); - this.commitmentsArray = generateCommitments(); - } - - /** - * @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; - } - - /** - * @param j share holder id - * @param commitments - * @param group - * - * @return product of Aik ^ (j ^ k) == g ^ polynomial(i) - */ - public static BigInteger verify(int j,BigInteger[] commitments,Group group) { - BigInteger v = group.zero(); - BigInteger power = BigInteger.ONE; - BigInteger J = BigInteger.valueOf(j); - for (int k = 0 ; k < commitments.length ; k ++){ - v = group.add(v,group.multiply(commitments[k],power)); - power = power.multiply(J); - } - return v; - } - - - /** - * getter - * @return generator of group - */ - public BigInteger getGenerator() { - return g; - } - - /** - * getter - * @return group - */ - public Group getGroup(){ - return group; - } - - /** - * getter - * @return copy of commitmentsArray - */ - public BigInteger[] getCommitmentsArray() { - return Arrays.copyOf(commitmentsArray, commitmentsArray.length); - } - -} +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 rather than fix to biginteger (allow using EC groups for better comm. complexity) +public class VerifiableSecretSharing extends SecretSharing { + protected final Group 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 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 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 getGroup(){ + return group; + } + + /** + * getter + * @return copy of commitmentsArray + */ + public BigInteger[] getCommitmentsArray() { + return Arrays.copyOf(commitmentsArray, commitmentsArray.length); + } + +} diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java index d9ae852..a60fd33 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java @@ -1,233 +1,280 @@ -package JointFeldmanProtocol; - -import Communication.User; -import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; -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.Arrays; -import java.util.HashSet; -import java.util.Random; -import java.util.Set; - -/** - * Created by Tzlil on 3/14/2016. - */ -public class DistributedKeyGeneration extends VerifiableSecretSharing { - public enum ComplaintState { - Non, Waiting,Disqualified,NonDisqualified - } - protected final int id; - private DistributedKeyGenerationParty[] parties; - - - public DistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger q, BigInteger g - , Group group, int id) { - super(t, n, zi, random, q, g,group); - this.id = id; - this.parties = new DistributedKeyGenerationParty[n]; - for (int i = 1; i <= n ; i++){ - this.parties[i - 1] = new DistributedKeyGenerationParty(i,n,t); - } - this.parties[id - 1].share = getShare(id); - } - - protected void setParties(DistributedKeyGenerationParty[] parties){ - this.parties = parties; - } - protected DistributedKeyGenerationParty[] getParties(){ - return parties; - } - - /** - * stage1.1 according to the protocol - * Pi broadcasts Aik for k = 0,...,t. - */ - public void broadcastCommitments(User user){ - broadcastCommitments(user,commitmentsArray); - } - - public void broadcastCommitments(User user, BigInteger[] commitments){ - DKGMessages.CommitmentMessage commitmentMessage; - for (int k = 0; k <= t ; k++){ - commitmentMessage = DKGMessages.CommitmentMessage.newBuilder() - .setCommitment(ByteString.copyFrom(commitments[k].toByteArray())) - .setK(k) - .build(); - user.broadcast(DKGMessages.Mail.Type.COMMITMENT, commitmentMessage); - } - } - - public void sendSecret(User user, int j){ - ByteString secret = ByteString.copyFrom(getShare(j).y.toByteArray()); - user.send(j, DKGMessages.Mail.Type.SECRET, - DKGMessages.SecretMessage.newBuilder() - .setI(id) - .setJ(j) - .setSecret(secret) - .build()); - } - - /** - * stage1.2 according to the protocol - * Pi computes the shares Sij for j = 1,...,n and sends Sij secretly to Pj. - */ - public void sendSecrets(User user){ - for (int j = 1; j <= n ; j++){ - if(j != id){ - sendSecret(user,j); - } - } - } - - public boolean isValidSecret(int i){ - DistributedKeyGenerationParty party = parties[i - 1]; - return isValidSecret(party.share,party.commitments,id); - } - - /** - * - * @param secret - * @param commitments - * @param j - * @return verify(j,commitments,group) == g ^ secret.y mod q - */ - public boolean isValidSecret(Polynomial.Point secret, BigInteger[] commitments, int j){ - try{ - BigInteger v = verify(j,commitments,group); - return group.multiply(g,secret.y).equals(v); - } - catch (NullPointerException e){ - return false; - } - } - - /** - * stage2 according to the protocol - * Pj verifies all the shares he received (using isValidSecret) - * if check fails for an index i, Pj broadcasts a complaint against Pi. - */ - public void broadcastComplaints(User user){ - for (int i = 1; i <= n ; i++ ){ - if(i != id && !isValidSecret(i)) { - broadcastComplaint(user,i); - } - } - } - - 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); - } - - public void broadcastComplaintAnswer(User user, int j){ - user.broadcast(DKGMessages.Mail.Type.ANSWER, DKGMessages.SecretMessage.newBuilder() - .setI(id) - .setJ(j) - .setSecret(ByteString.copyFrom(getShare(j).y.toByteArray())) - .build()); - } - - /** - * stage3.1 according to the protocol - * if more than t players complain against a player Pi he is disqualified. - */ - public void answerAllComplainingPlayers(User user){ - ComplaintState[] complaints = parties[id - 1].complaints; - for (int i = 1; i <= n ; i++) { - switch (complaints[i - 1]) { - case Waiting: - broadcastComplaintAnswer(user,i); - break; - default: - break; - } - } - } - - /** - * stage3.2 according to the protocol - * if any of the revealed shares fails the verification test, player Pi is disqualified. - * set QUAL to be the set of non-disqualified players. - */ - public Set calcQUAL(){ - Set QUAL = new HashSet(); - boolean nonDisqualified; - int counter; - for (int i = 1; i <= n; i++){ - ComplaintState[] complaints = parties[i - 1].complaints; - nonDisqualified = true; - counter = 0; - for (int j = 1; j <= n; j++){ - switch (complaints[j - 1]) { - case Non: - break; - case NonDisqualified: - counter++; - default: - nonDisqualified = false; - } - if(!nonDisqualified) - break; - } - if(nonDisqualified && counter <= t){ - QUAL.add(i); - } - } - return QUAL; - } - - /** - * stage4.1 according to the protocol - * public value y is computed as y = multiplication of yi mod p for i in QUAL - */ - public BigInteger calcY(Set QUAL){ - BigInteger y = group.zero(); - for (int i : QUAL) { - y = group.add(y , parties[i - 1].commitments[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 BigInteger[] calcCommitments(Set QUAL){ - BigInteger[] commitments = new BigInteger[t + 1]; - Arrays.fill(commitments,group.zero()); - for (int i : QUAL) { - for (int k = 0; k <= t; k++){ - commitments[k] = group.add(commitments[k], parties[i - 1].commitments[k]); - } - } - return commitments; - } - - /** - * stage4.3 according to the protocol - * Pj sets is share of the secret as xj = sum of Sij mod q for i in QUAL - */ - public Polynomial.Point calcShare(Set 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)); - } - - /** - * getter - * @return id - */ - public int getId() { - return id; - } - -} +package JointFeldmanProtocol; + +import Communication.User; +import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; +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.Arrays; +import java.util.HashSet; +import java.util.Random; +import java.util.Set; + +/** + * Created by Tzlil on 3/14/2016. + */ +// TODO: Lots of comments... +// TODO: User Channel instead of User +public class DistributedKeyGeneration extends VerifiableSecretSharing { + public enum ComplaintState { + /** + * No complaints, no response required at this point. + */ + OK, + + /** + * Party received complaint, waiting for response from party + */ + Waiting, + + /** + * Party gave invalid answer to conplaint. + */ + Disqualified, + + /** + * Party received complaint, gave valid answer. + */ + NonDisqualified + } + + /** + * My share id. + */ + protected final int id; + + /** + * All parties participating in key generation. + * parties[id-1] has my info. + */ + private DistributedKeyGenerationParty[] parties; + + + // TODO: Copy comment + public DistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger q, BigInteger g + , Group group, int id) { + super(t, n, zi, random, q, g,group); + this.id = id; + this.parties = new DistributedKeyGenerationParty[n]; + for (int i = 1; i <= n ; i++){ + this.parties[i - 1] = new DistributedKeyGenerationParty(i,n,t); + } + this.parties[id - 1].share = getShare(id); + } + + protected void setParties(DistributedKeyGenerationParty[] parties){ + this.parties = parties; + } + + protected DistributedKeyGenerationParty[] getParties(){ + return parties; + } + + /** + * stage1.1 according to the protocol + * Pi broadcasts Aik for k = 0,...,t. + */ + public void broadcastCommitments(User user){ + broadcastCommitments(user,commitmentsArray); + } + + public void broadcastCommitments(User user, BigInteger[] commitments){ + DKGMessages.CommitmentMessage commitmentMessage; + for (int k = 0; k <= t ; k++){ + commitmentMessage = DKGMessages.CommitmentMessage.newBuilder() + .setCommitment(ByteString.copyFrom(commitments[k].toByteArray())) + .setK(k) + .build(); + user.broadcast(DKGMessages.Mail.Type.COMMITMENT, commitmentMessage); + } + } + + /** + * Send user j her secret share (of my polynomial) + * @param user + * @param j + */ + public void sendSecret(User user, int j){ + ByteString secret = ByteString.copyFrom(getShare(j).y.toByteArray()); + user.send(j, DKGMessages.Mail.Type.SECRET, + DKGMessages.SecretMessage.newBuilder() + .setI(id) + .setJ(j) + .setSecret(secret) + .build()); + } + + /** + * stage1.2 according to the protocol + * Pi computes the shares Sij for j = 1,...,n and sends Sij secretly to Pj. + */ + public void sendSecrets(User user){ + for (int j = 1; j <= n ; j++){ + if(j != id){ + sendSecret(user,j); + } + } + } + + /** + * TODO: comment + * @param i + * @return + */ + public boolean isValidSecret(int i){ + DistributedKeyGenerationParty party = parties[i - 1]; + return isValidSecret(party.share,party.commitments,id); + } + + /** + * TODO: Move to VerifiableSecretSharing + * @param secret + * @param commitments + * @param j + * @return computeVerificationValue(j,commitments,group) == g ^ secret.y mod q + */ + public boolean isValidSecret(Polynomial.Point secret, BigInteger[] commitments, int j){ + try{ + BigInteger v = computeVerificationValue(j,commitments,group); + return group.multiply(g,secret.y).equals(v); + } + catch (NullPointerException e){ + return false; + } + } + + /** + * 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. + */ + public void broadcastComplaints(User user){ + for (int i = 1; i <= n ; i++ ){ + if(i != id && !isValidSecret(i)) { + broadcastComplaint(user,i); + } + } + } + + 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); + } + + public void broadcastComplaintAnswer(User user, int j){ + user.broadcast(DKGMessages.Mail.Type.ANSWER, DKGMessages.SecretMessage.newBuilder() + .setI(id) + .setJ(j) + .setSecret(ByteString.copyFrom(getShare(j).y.toByteArray())) + .build()); + } + + /** + * stage3.1 according to the protocol + * if more than t players complain against a player Pi he is disqualified. + */ + public void answerAllComplainingPlayers(User user){ + ComplaintState[] complaints = parties[id - 1].complaints; + for (int i = 1; i <= n ; i++) { + switch (complaints[i - 1]) { + case Waiting: + broadcastComplaintAnswer(user,i); + break; + default: + break; + } + } + } + + /** + * stage3.2 according to the protocol + * if any of the revealed shares fails the verification test, player Pi is disqualified. + * set QUAL to be the set of non-disqualified players. + */ + public Set calcQUAL(){ + Set QUAL = new HashSet(); + boolean nonDisqualified; + int counter; + for (int i = 1; i <= n; i++){ + ComplaintState[] complaints = parties[i - 1].complaints; + nonDisqualified = true; + counter = 0; + for (int j = 1; j <= n; j++){ + switch (complaints[j - 1]) { + case OK: + break; + case NonDisqualified: + // TODO: Add test for false complaint + counter++; + break; + default: + nonDisqualified = false; + break; + } + if(!nonDisqualified) + break; + } + if(nonDisqualified && counter <= t){ + QUAL.add(i); + } + } + return QUAL; + } + + /** + * 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 BigInteger calcY(Set QUAL){ + BigInteger y = group.zero(); + for (int i : QUAL) { + y = group.add(y , parties[i - 1].commitments[0]); + } + return y; + } + + /** + * 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 + */ + public BigInteger[] calcCommitments(Set QUAL){ + BigInteger[] commitments = new BigInteger[t + 1]; + Arrays.fill(commitments,group.zero()); + for (int i : QUAL) { + for (int k = 0; k <= t; k++){ + commitments[k] = group.add(commitments[k], parties[i - 1].commitments[k]); + } + } + return commitments; + } + + /** + * TODO: better comment. + * stage4.3 according to the protocol + * Pj sets is share of the secret as xj = sum of Sij mod q for i in QUAL + */ + public Polynomial.Point calcShare(Set 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)); + } + + /** + * getter + * @return id + */ + public int getId() { + return id; + } + +} diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMailHandler.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMailHandler.java index fe141f2..f33959f 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMailHandler.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMailHandler.java @@ -1,49 +1,49 @@ -package JointFeldmanProtocol; - -import Communication.MailHandler; -import Communication.MessageHandler; -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Message; -import meerkat.protobuf.DKGMessages; - -/** - * Created by Tzlil on 2/29/2016. - */ -public class DistributedKeyGenerationMailHandler extends MailHandler { - - public DistributedKeyGenerationMailHandler(MessageHandler messageHandler) { - super(messageHandler); - } - - @Override - public Message extractMessage(DKGMessages.Mail mail) { - try { - Message message; - switch (mail.getType()) { - case SECRET: - message = DKGMessages.SecretMessage.parseFrom(mail.getMessage()); - break; - case COMMITMENT: - message = DKGMessages.CommitmentMessage.parseFrom(mail.getMessage()); - break; - case COMPLAINT: - message = DKGMessages.IDMessage.parseFrom(mail.getMessage()); - break; - case DONE: - message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); - break; - case ANSWER: - message = DKGMessages.SecretMessage.parseFrom(mail.getMessage()); - break; - case ABORT: - message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); - break; - default: - return null; - } - return message; - } catch (InvalidProtocolBufferException e) { - return null; - } - } -} +package JointFeldmanProtocol; + +import Communication.MailHandler; +import Communication.MessageHandler; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; +import meerkat.protobuf.DKGMessages; + +/** + * Created by Tzlil on 2/29/2016. + */ +public class DistributedKeyGenerationMailHandler extends MailHandler { + + public DistributedKeyGenerationMailHandler(MessageHandler messageHandler) { + super(messageHandler); + } + + @Override + public Message extractMessage(DKGMessages.Mail mail) { + try { + Message message; + switch (mail.getType()) { + case SECRET: + message = DKGMessages.SecretMessage.parseFrom(mail.getMessage()); + break; + case COMMITMENT: + message = DKGMessages.CommitmentMessage.parseFrom(mail.getMessage()); + break; + case COMPLAINT: + message = DKGMessages.IDMessage.parseFrom(mail.getMessage()); + break; + case DONE: + message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); + break; + case ANSWER: + message = DKGMessages.SecretMessage.parseFrom(mail.getMessage()); + break; + case ABORT: + message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); + break; + default: + return null; + } + return message; + } catch (InvalidProtocolBufferException e) { + return null; + } + } +} diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationParty.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationParty.java index 878ab66..59ef1ea 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationParty.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationParty.java @@ -1,31 +1,32 @@ -package JointFeldmanProtocol; - -import ShamirSecretSharing.Polynomial; - -import java.math.BigInteger; -import java.util.Arrays; - -/** - * Created by Tzlil on 3/14/2016. - * - * contains all relevant information on specific party during - * the run of Joint Feldamn protocol - */ -public class DistributedKeyGenerationParty { - public final int id; - public Polynomial.Point share; - public BigInteger[] commitments; - public boolean doneFlag; - public DistributedKeyGeneration.ComplaintState[] complaints; - public boolean aborted; - - public DistributedKeyGenerationParty(int id, int n, int t) { - this.id = id; - this.share = null; - this.doneFlag = false; - this.complaints = new DistributedKeyGeneration.ComplaintState[n]; - Arrays.fill(this.complaints, DistributedKeyGeneration.ComplaintState.Non); - this.commitments = new BigInteger[t + 1]; - this.aborted = false; - } -} +package JointFeldmanProtocol; + +import ShamirSecretSharing.Polynomial; + +import java.math.BigInteger; +import java.util.Arrays; + +/** + * Created by Tzlil on 3/14/2016. + * + * contains all relevant information on specific party during + * the run of Joint Feldamn protocol + */ +// TODO: comments for every field. +public class DistributedKeyGenerationParty { + public final int id; + public Polynomial.Point share; + public BigInteger[] commitments; + public boolean doneFlag; + public DistributedKeyGeneration.ComplaintState[] complaints; + public boolean aborted; + + public DistributedKeyGenerationParty(int id, int n, int t) { + this.id = id; + this.share = null; + this.doneFlag = false; + this.complaints = new DistributedKeyGeneration.ComplaintState[n]; + Arrays.fill(this.complaints, DistributedKeyGeneration.ComplaintState.OK); + this.commitments = new BigInteger[t + 1]; + this.aborted = false; + } +} diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java index 6287526..6198f97 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java @@ -1,382 +1,393 @@ -package JointFeldmanProtocol; - -import Communication.MailHandler; -import Communication.Network; -import Communication.User; -import ShamirSecretSharing.Polynomial; -import UserInterface.DistributedKeyGenerationUser; -import com.google.protobuf.ByteString; -import com.google.protobuf.Message; -import meerkat.protobuf.DKGMessages; -import org.factcenter.qilin.primitives.Group; - -import java.math.BigInteger; -import java.util.Arrays; -import java.util.Set; -import JointFeldmanProtocol.DistributedKeyGeneration.ComplaintState; - -/** - * Created by Tzlil on 3/14/2016. - */ -public class DistributedKeyGenerationUserImpl implements DistributedKeyGenerationUser { - - protected final static int SleepTime = 300; - - protected final DistributedKeyGeneration dkg; - - protected final BigInteger g; - protected final Group group; - protected final int n; - protected final int t; - protected final int id; - - protected MessageHandler messageHandler; - protected final User user; - protected final DistributedKeyGenerationParty[] parties; - protected Set QUAL; // set of all non-disqualified parties - protected BigInteger[] commitments; // public verification values - protected Polynomial.Point share; // final share of the secrete - protected BigInteger y; // final public value - - public DistributedKeyGenerationUserImpl(DistributedKeyGeneration dkg, Network network){ - this(dkg,network,new DistributedKeyGenerationMailHandler(null)); - } - public DistributedKeyGenerationUserImpl(DistributedKeyGeneration dkg, Network network, MailHandler mailHandler) { - this.dkg = dkg; - - this.g = dkg.getGenerator(); - this.group = dkg.getGroup(); - this.n = dkg.getN(); - this.t = dkg.getT(); - this.id = dkg.getId(); - - this.messageHandler = new MessageHandler(); - mailHandler.setMessageHandler(this.messageHandler); - this.user = network.connect(mailHandler,dkg.getId()); - this.parties = dkg.getParties(); - this.QUAL = null; - this.commitments = null; - this.share = null; - this.y = null; - } - - /** - * stage1 according to the protocol - * 1. Pi broadcasts Aik for k = 0,...,t. - * 2. Pi computes the shares Sij for j = 1,...,n and sends Sij secretly to Pj. - */ - protected void stage1() { - dkg.broadcastCommitments(user); - dkg.sendSecrets(user); - } - - protected void waitUntilStageOneCompleted(){ - // all parties send their share or aborted - for (int i = 0 ; i < n ; i++){ - while (parties[i].share == null && !parties[i].aborted){ - try { - Thread.sleep(SleepTime); - } 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 { - Thread.sleep(SleepTime); - } 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); - //broadcast done message after all complaints - DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build(); - user.broadcast(DKGMessages.Mail.Type.DONE,doneMessage); - } - - - protected void waitUntilStageTwoCompleted(){ - // all parties done or aborted - for (int i = 0 ; i < n ; i++){ - while (!parties[i].doneFlag && !parties[i].aborted){ - try { - Thread.sleep(SleepTime); - } catch (InterruptedException e) { - // do nothing - } - } - } - } - - /** - * stage3 according to the protocol - * 1. if more than t players complain against a player Pi he is disqualified. - * otherwise Pi broadcasts the share Sij for each complaining player Pj. - * 2. if any of the revealed shares fails the verification test, player Pi is disqualified. - * set QUAL to be the set of non-disqualified players. - */ - protected void stage3(){ - dkg.answerAllComplainingPlayers(user); - // wait until there is no complaint waiting for answer - for (int i = 0; i < n; i++){ - for (int j = 0; j < n; j++){ - while (parties[i].complaints[j].equals(ComplaintState.Waiting) && !parties[i].aborted){ - try { - Thread.sleep(SleepTime); - } catch (InterruptedException e) { - // do nothing - } - } - } - } - this.QUAL = dkg.calcQUAL(); - } - - /** - * stage4 according to the protocol - * 1. public value y is computed as y = multiplication of yi mod p for i in QUAL - * 2. public verification values are computed as Ak = multiplication of Aik mod p for i in QUAL for k = 0,...,t - * 3. Pj sets is share of the secret as xj = sum of Sij mod q for i in QUAL - */ - protected void stage4(){ - this.y = dkg.calcY(QUAL); - this.commitments = dkg.calcCommitments(QUAL); - this.share = dkg.calcShare(QUAL); - } - - protected void startReceiver(){ - user.getReceiverThread().start(); - } - protected void stopReceiver(){ - user.getReceiverThread().interrupt(); - } - - @Override - public void run() { - startReceiver(); - stage1(); - waitUntilStageOneCompleted(); - stage2(); - waitUntilStageTwoCompleted(); - stage3(); - stage4(); - stopReceiver(); - } - - @Override - public BigInteger[] getCommitments() { - return Arrays.copyOf(commitments, commitments.length); - } - - @Override - public BigInteger getGenerator() { - return g; - } - - @Override - public Group getGroup() { - return group; - } - - @Override - public Polynomial.Point getShare() { - return share; - } - - @Override - public int getID() { - return id; - } - - @Override - public int getN() { - return n; - } - - @Override - public int getT() { - return t; - } - - @Override - public BigInteger getPublicValue() { - return y; - } - - @Override - public Set getQUAL() { - return QUAL; - } - - - protected class MessageHandler implements Communication.MessageHandler{ - - /** - * commitment message is valid if: - * 1. it was received in broadcast chanel - * 2. the sender didn't sent this commitment before - */ - protected boolean isValidCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage){ - int i = sender - 1; - int k = commitmentMessage.getK(); - return isBroadcast && parties[i].commitments[k] == null; - } - - /** - * saves the commitment - */ - @Override - public void handelCommitmentMessage(int sender, boolean isBroadcast, Message message) { - DKGMessages.CommitmentMessage commitmentMessage = (DKGMessages.CommitmentMessage) message; - if(isValidCommitmentMessage(sender,isBroadcast,commitmentMessage)){ - int i = sender - 1; - int k = commitmentMessage.getK(); - parties[i].commitments[k] = extractCommitment(commitmentMessage); - } - } - - /** - * 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 - * 4. secret.j == id - */ - protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage){ - int i = secretMessage.getI(); - int j = secretMessage.getJ(); - if(sender != i || isBroadcast) - return false; - else - return parties[i - 1].share == null && j == id; - - } - - /** - * saves the secret - */ - @Override - public void handelSecretMessage(int sender, boolean isBroadcast, Message message) { - DKGMessages.SecretMessage secretMessage = (DKGMessages.SecretMessage) message; - if(isValidSecretMessage(sender,isBroadcast,secretMessage)) { - int i = secretMessage.getI(); - Polynomial.Point secret = extractSecret(id,secretMessage.getSecret()); - parties[i - 1].share = secret; - } - } - - /** - * 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; - } - - /** - * marks that the sender was finished sending all his complaints - */ - @Override - public void handelDoneMessage(int sender, boolean isBroadcast,Message message) { - if(isValidDoneMessage(sender,isBroadcast)) { - parties[sender - 1].doneFlag = true; - } - } - - /** - * complaint message is valid if: - * 1. it was received in broadcast chanel - * 2. the sender didn't complained against id before - */ - protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, DKGMessages.IDMessage complaintMessage){ - int i = sender; - int j = complaintMessage.getId(); - return isBroadcast && parties[i - 1].complaints[j - 1].equals( ComplaintState.Non); - } - - /** - * marks that the sender was complained against id - */ - @Override - public void handelComplaintMessage(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; - } - } - - /** - * answer message is valid if: - * 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 - */ - protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage){ - int i = secretMessage.getI(); - int j = secretMessage.getJ(); - 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 handelAnswerMessage(int sender, boolean isBroadcast, Message message) { - DKGMessages.SecretMessage secretMessage = (DKGMessages.SecretMessage) message; - if(isValidAnswerMessage(sender,isBroadcast,secretMessage)) { - int i = secretMessage.getI(); - 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; - } else { - parties[i - 1].complaints[j - 1] = ComplaintState.Disqualified; - } - if(j == id){ - parties[i - 1].share = secret; - } - } - } - - /** - * marks that the sender was aborted - */ - @Override - public void handelAbortMessage(int sender, boolean isBroadcast, Message message) { - parties[sender - 1].aborted = true; - } - - public Polynomial.Point extractSecret(int i, ByteString secret){ - BigInteger x = BigInteger.valueOf(i); - BigInteger y = new BigInteger(secret.toByteArray()); - return new Polynomial.Point(x,y); - } - - public BigInteger extractCommitment(DKGMessages.CommitmentMessage commitmentMessage){ - return new BigInteger(commitmentMessage.getCommitment().toByteArray()); - } - } -} +package JointFeldmanProtocol; + +import Communication.MailHandler; +import Communication.Network; +import Communication.User; +import ShamirSecretSharing.Polynomial; +import UserInterface.DistributedKeyGenerationUser; +import com.google.protobuf.ByteString; +import com.google.protobuf.Message; +import meerkat.protobuf.DKGMessages; +import org.factcenter.qilin.primitives.Group; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Set; +import JointFeldmanProtocol.DistributedKeyGeneration.ComplaintState; + +/** + * Created by Tzlil on 3/14/2016. + * TODO: Comments + * TODO: Replace polling with monitors/wait/notify (remember synchronization) + */ +public class DistributedKeyGenerationUserImpl implements DistributedKeyGenerationUser { + + // TODO: remove + protected final static int SleepTime = 300; + + protected final DistributedKeyGeneration dkg; + + protected final BigInteger g; + protected final Group group; + protected final int n; + protected final int t; + protected final int id; + + protected MessageHandler messageHandler; + protected final User user; + protected final DistributedKeyGenerationParty[] parties; + protected Set QUAL; // set of all non-disqualified parties + protected BigInteger[] commitments; // public verification values + protected Polynomial.Point share; // final share of the secrete + protected BigInteger y; // final public value + + public DistributedKeyGenerationUserImpl(DistributedKeyGeneration dkg, Network network){ + this(dkg,network,new DistributedKeyGenerationMailHandler(null)); + } + public DistributedKeyGenerationUserImpl(DistributedKeyGeneration dkg, Network network, MailHandler mailHandler) { + this.dkg = dkg; + + this.g = dkg.getGenerator(); + this.group = dkg.getGroup(); + this.n = dkg.getN(); + this.t = dkg.getT(); + this.id = dkg.getId(); + + this.messageHandler = new MessageHandler(); + mailHandler.setMessageHandler(this.messageHandler); + this.user = network.connect(mailHandler,dkg.getId()); + this.parties = dkg.getParties(); + this.QUAL = null; + this.commitments = null; + this.share = null; + this.y = null; + } + + /** + * stage1 according to the protocol + * 1. Pi broadcasts Aik for k = 0,...,t. + * 2. Pi computes the shares Sij for j = 1,...,n and sends Sij secretly to Pj. + */ + protected void stage1() { + dkg.broadcastCommitments(user); + dkg.sendSecrets(user); + } + + + protected void waitUntilStageOneCompleted(){ + // all parties send their share or aborted + for (int i = 0 ; i < n ; i++){ + while (parties[i].share == null && !parties[i].aborted){ + try { + Thread.sleep(SleepTime); + } 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 { + Thread.sleep(SleepTime); + } 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); + //broadcast done message after all complaints + DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build(); + user.broadcast(DKGMessages.Mail.Type.DONE,doneMessage); + } + + + protected void waitUntilStageTwoCompleted(){ + // all parties done or aborted + for (int i = 0 ; i < n ; i++){ + while (!parties[i].doneFlag && !parties[i].aborted){ + try { + Thread.sleep(SleepTime); + } catch (InterruptedException e) { + // do nothing + } + } + } + } + + /** + * stage3 according to the protocol + * 1. if more than t players complain against a player Pi he is disqualified. + * otherwise Pi broadcasts the share Sij for each complaining player Pj. + * 2. if any of the revealed shares fails the verification test, player Pi is disqualified. + * set QUAL to be the set of non-disqualified players. + */ + protected void stage3(){ + dkg.answerAllComplainingPlayers(user); + // wait until there is no complaint waiting for answer + for (int i = 0; i < n; i++){ + for (int j = 0; j < n; j++){ + while (parties[i].complaints[j].equals(ComplaintState.Waiting) && !parties[i].aborted){ + try { + Thread.sleep(SleepTime); + } catch (InterruptedException e) { + // do nothing + } + } + } + } + this.QUAL = dkg.calcQUAL(); + } + + /** + * stage4 according to the protocol + * 1. public value y is computed as y = multiplication of yi mod p for i in QUAL + * 2. public verification values are computed as Ak = multiplication of Aik mod p for i in QUAL for k = 0,...,t + * 3. Pj sets is share of the secret as xj = sum of Sij mod q for i in QUAL + */ + protected void stage4(){ + this.y = dkg.calcY(QUAL); + this.commitments = dkg.calcCommitments(QUAL); + this.share = dkg.calcShare(QUAL); + } + + protected void startReceiver(){ + user.getReceiverThread().start(); + } + protected void stopReceiver(){ + user.getReceiverThread().interrupt(); + } + + @Override + public void run() { + startReceiver(); + stage1(); + waitUntilStageOneCompleted(); + stage2(); + waitUntilStageTwoCompleted(); + stage3(); + stage4(); + stopReceiver(); + } + + /** + * Request the current run loop to exit gracefully + */ + public void stop() { + // TODO: implement + } + + @Override + public BigInteger[] getCommitments() { + return Arrays.copyOf(commitments, commitments.length); + } + + @Override + public BigInteger getGenerator() { + return g; + } + + @Override + public Group getGroup() { + return group; + } + + @Override + public Polynomial.Point getShare() { + return share; + } + + @Override + public int getID() { + return id; + } + + @Override + public int getN() { + return n; + } + + @Override + public int getT() { + return t; + } + + @Override + public BigInteger getPublicValue() { + return y; + } + + @Override + public Set getQUAL() { + return QUAL; + } + + + protected class MessageHandler implements Communication.MessageHandler{ + + /** + * commitment message is valid if: + * 1. it was received in broadcast chanel + * 2. the sender didn't sent this commitment before + */ + protected boolean isValidCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage){ + int i = sender - 1; + int k = commitmentMessage.getK(); + return isBroadcast && parties[i].commitments[k] == null; + } + + /** + * saves the commitment + */ + @Override + public void handleCommitmentMessage(int sender, boolean isBroadcast, Message message) { + DKGMessages.CommitmentMessage commitmentMessage = (DKGMessages.CommitmentMessage) message; + if(isValidCommitmentMessage(sender,isBroadcast,commitmentMessage)){ + int i = sender - 1; + int k = commitmentMessage.getK(); + parties[i].commitments[k] = extractCommitment(commitmentMessage); + } + } + + /** + * 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 + * 4. secret.j == id + */ + protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage){ + int i = secretMessage.getI(); + int j = secretMessage.getJ(); + if(sender != i || isBroadcast) + return false; + else + return parties[i - 1].share == null && j == id; + + } + + /** + * saves the secret + */ + @Override + public void handleSecretMessage(int sender, boolean isBroadcast, Message message) { + DKGMessages.SecretMessage secretMessage = (DKGMessages.SecretMessage) message; + if(isValidSecretMessage(sender,isBroadcast,secretMessage)) { + int i = secretMessage.getI(); + Polynomial.Point secret = extractSecret(id,secretMessage.getSecret()); + parties[i - 1].share = secret; + } + } + + /** + * 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; + } + + /** + * marks that the sender was finished sending all his complaints + */ + @Override + public void handleDoneMessage(int sender, boolean isBroadcast, Message message) { + if(isValidDoneMessage(sender,isBroadcast)) { + parties[sender - 1].doneFlag = true; + } + } + + /** + * complaint message is valid if: + * 1. it was received in broadcast chanel + * 2. the sender didn't complained against id before + */ + protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, DKGMessages.IDMessage complaintMessage){ + int i = sender; + int j = complaintMessage.getId(); + return isBroadcast && parties[i - 1].complaints[j - 1].equals( ComplaintState.OK); + } + + /** + * marks that the sender was complained against id + */ + @Override + 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; + } + } + + /** + * answer message is valid if: + * 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 + */ + protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage){ + int i = secretMessage.getI(); + int j = secretMessage.getJ(); + 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.SecretMessage secretMessage = (DKGMessages.SecretMessage) message; + if(isValidAnswerMessage(sender,isBroadcast,secretMessage)) { + int i = secretMessage.getI(); + 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; + } else { + parties[i - 1].complaints[j - 1] = ComplaintState.Disqualified; + } + if(j == id){ + parties[i - 1].share = secret; + } + } + } + + /** + * marks that the sender was aborted + */ + @Override + public void handleAbortMessage(int sender, boolean isBroadcast, Message message) { + parties[sender - 1].aborted = true; + } + + public Polynomial.Point extractSecret(int i, ByteString secret){ + BigInteger x = BigInteger.valueOf(i); + BigInteger y = new BigInteger(secret.toByteArray()); + return new Polynomial.Point(x,y); + } + + public BigInteger extractCommitment(DKGMessages.CommitmentMessage commitmentMessage){ + return new BigInteger(commitmentMessage.getCommitment().toByteArray()); + } + } +} diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGeneration.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGeneration.java index 92c29f3..9aefeb5 100644 --- a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGeneration.java +++ b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGeneration.java @@ -1,137 +1,141 @@ -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. - */ -public class SecureDistributedKeyGeneration extends DistributedKeyGeneration { - - private VerifiableSecretSharing verifiableSecretSharing; - private final BigInteger h; - private SecureDistributedKeyGenerationParty[] parties; - - public SecureDistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger q, BigInteger g - , BigInteger h, Group group, int id) { - super(t, n, zi, random, q, g, group, id); - this.h = h; - BigInteger r = new BigInteger(q.bitLength(),random).mod(q); - this.verifiableSecretSharing = new VerifiableSecretSharing(t,n,r,random,q,h,group); - 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 = verifiableSecretSharing.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 = verifiableSecretSharing.getShare(j); - DKGMessages.DoubleSecretMessage doubleSecretMessage = doubleSecretMessage(id,j,secret,secretT); - user.send(j, DKGMessages.Mail.Type.SECRET, doubleSecretMessage); - } - - - @Override - public boolean isValidSecret(int i){ - SecureDistributedKeyGenerationParty party = parties[i - 1]; - return isValidSecret(party.share, party.shareT, party.verifiableValues, id); - } - - /** - * @param secret - * @param secretT - * @param verificationValues - * @param j - * @return verify(j,verificationValues,group) == (g ^ secret.y) * (h ^ secretT.y) mod q - */ - public boolean isValidSecret(Polynomial.Point secret,Polynomial.Point secretT, BigInteger[] verificationValues, int j){ - try { - BigInteger v = verify(j, verificationValues, group); - BigInteger exp = group.add(group.multiply(g, secret.y), group.multiply(h, secretT.y)); - return exp.equals(v); - } - catch (NullPointerException e){ - return false; - } - } - - private void broadcastComplaint(User user,Polynomial.Point secret,Polynomial.Point secretT,int i){ - DKGMessages.DoubleSecretMessage complaint = doubleSecretMessage(i,id,secret,secretT); - user.broadcast(DKGMessages.Mail.Type.COMPLAINT,complaint); - } - - /** - * stage4.3 according to the protocol - * if check fails for index i, Pj - */ - public void broadcastComplaints(User user, Set 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 = verifiableSecretSharing.getCommitmentsArray(); - for (int k = 0 ; k < verificationValues.length ; k++){ - verificationValues[k] = group.add(commitmentsArray[k],hBaseCommitments[k]); - } - broadcastCommitments(user,verificationValues); - } - - private DKGMessages.DoubleSecretMessage doubleSecretMessage(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 = doubleSecretMessage(id,j,getShare(j) - ,verifiableSecretSharing.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 = doubleSecretMessage(i,id,secret,secretT); - user.broadcast(DKGMessages.Mail.Type.ANSWER,complaint); - } - - public BigInteger getH() { - return h; - } -} +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 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 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; + } +} diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationMailHandler.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationMailHandler.java index 9b4752e..92dba85 100644 --- a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationMailHandler.java +++ b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationMailHandler.java @@ -1,63 +1,63 @@ -package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; - -import Communication.MailHandler; -import Communication.MessageHandler; -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Message; -import meerkat.protobuf.DKGMessages; - -/** - * Created by Tzlil on 2/29/2016. - */ -public class SecureDistributedKeyGenerationMailHandler extends MailHandler { - - private boolean isStage4; - - public SecureDistributedKeyGenerationMailHandler(MessageHandler messageHandler) { - super(messageHandler); - this.isStage4 = false; - } - - @Override - public Message extractMessage(DKGMessages.Mail mail) { - try { - Message message; - switch (mail.getType()) { - case SECRET: - message = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage()); - break; - case COMMITMENT: - message = DKGMessages.CommitmentMessage.parseFrom(mail.getMessage()); - break; - case COMPLAINT: - if(!isStage4) - message = DKGMessages.IDMessage.parseFrom(mail.getMessage()); - else - message = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage()); - break; - case DONE: - message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); - break; - case ANSWER: - message = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage()); - break; - case ABORT: - message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); - break; - default: - return null; - } - return message; - } catch (InvalidProtocolBufferException e) { - return null; - } - } - - public boolean isStage4() { - return isStage4; - } - - public void setStage4(boolean stage4) { - isStage4 = stage4; - } -} +package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; + +import Communication.MailHandler; +import Communication.MessageHandler; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; +import meerkat.protobuf.DKGMessages; + +/** + * Created by Tzlil on 2/29/2016. + */ +public class SecureDistributedKeyGenerationMailHandler extends MailHandler { + + private boolean isStage4; + + public SecureDistributedKeyGenerationMailHandler(MessageHandler messageHandler) { + super(messageHandler); + this.isStage4 = false; + } + + @Override + public Message extractMessage(DKGMessages.Mail mail) { + try { + Message message; + switch (mail.getType()) { + case SECRET: + message = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage()); + break; + case COMMITMENT: + message = DKGMessages.CommitmentMessage.parseFrom(mail.getMessage()); + break; + case COMPLAINT: + if(!isStage4) + message = DKGMessages.IDMessage.parseFrom(mail.getMessage()); + else + message = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage()); + break; + case DONE: + message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); + break; + case ANSWER: + message = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage()); + break; + case ABORT: + message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); + break; + default: + return null; + } + return message; + } catch (InvalidProtocolBufferException e) { + return null; + } + } + + public boolean isStage4() { + return isStage4; + } + + public void setStage4(boolean stage4) { + isStage4 = stage4; + } +} diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationParty.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationParty.java index ea36136..fc2e8e3 100644 --- a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationParty.java +++ b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationParty.java @@ -1,29 +1,29 @@ -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 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(); - } -} +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 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(); + } +} diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationUserImpl.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationUserImpl.java index 66751eb..141b854 100644 --- a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationUserImpl.java +++ b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationUserImpl.java @@ -1,304 +1,307 @@ -package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; - -import Arithmetics.Arithmetic; -import Arithmetics.Fp; -import Communication.Network; -import JointFeldmanProtocol.DistributedKeyGeneration; -import JointFeldmanProtocol.DistributedKeyGenerationUserImpl; -import ShamirSecretSharing.Polynomial; -import ShamirSecretSharing.SecretSharing; -import com.google.protobuf.Message; -import meerkat.protobuf.DKGMessages; - -import java.math.BigInteger; - -/** - * Created by Tzlil on 3/16/2016. - */ -public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenerationUserImpl { - - protected SecureDistributedKeyGenerationParty[] parties; - protected final SecureDistributedKeyGeneration sdkg; - private Arithmetic arithmetic; - private boolean isStage4; - - public SecureDistributedKeyGenerationUserImpl(SecureDistributedKeyGeneration sdkg, Network network) { - super(sdkg, network,new SecureDistributedKeyGenerationMailHandler(null)); - this.sdkg = sdkg; - this.messageHandler = new MessageHandler(); - this.user.setMessageHandler(this.messageHandler); - this.parties = sdkg.getParties(); - this.arithmetic = new Fp(sdkg.getQ()); - this.isStage4 = false; - } - - /** - * stage1 according to the protocol - * 1. Pi broadcasts Cik=Aik*Bik for k = 0,...,t. - * 2. Pi computes the shares Sij,Sij' for j = 1,...,n and sends Sij,Sij' secretly to Pj. - */ - @Override - protected void stage1() { - sdkg.broadcastVerificationValues(user); - sdkg.sendSecrets(user); - } - - @Override - protected void waitUntilStageOneCompleted(){ - super.waitUntilStageOneCompleted(); - // save the received commitments as verification values - BigInteger[] 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 - */ - @Override - protected void stage2(){ - sdkg.broadcastComplaints(user); - //broadcast done message after all complaints - DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build(); - user.broadcast(DKGMessages.Mail.Type.DONE,doneMessage); - } - - private void ys(){ - sdkg.broadcastCommitments(user); - // wait until all parties in QUAL broadcast their commitments or aborted - for (int i:QUAL) { - for(int k = 0; k <= t; k++) { - while (parties[i - 1].commitments[k] == null && !parties[i - 1].aborted) { - try { - Thread.sleep(SleepTime); - } catch (InterruptedException e) { - // do nothing - } - } - } - } - sdkg.broadcastComplaints(user,QUAL); - //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) { - while (!parties[i - 1].ysDoneFlag && !parties[i - 1].aborted) { - try { - Thread.sleep(SleepTime); - } catch (InterruptedException e) { - // do nothing - } - } - } - - // broadcast i private secret foreach i in QUAL that aborted - for (int i:QUAL) { - if(parties[i - 1].aborted){ - 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){ - while (parties[i - 1].restoreSharesSet.size() <= t) { - try { - Thread.sleep(SleepTime); - } catch (InterruptedException e) { - // do nothing - } - } - } - } - - // restore necessary information - for (int i = 0; i < n ; i++) { - if(parties[i].restoreSharesSet.isEmpty()){ - continue; - } - 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; - } - } - Polynomial polynomial = SecretSharing.restorePolynomial(shares,arithmetic); - BigInteger[] coefficients = polynomial.getCoefficients(); - for (int k = 0 ; k <= t; k++){ - parties[i].commitments[k] = group.multiply(g,coefficients[k]); - } - parties[i].share = new Polynomial.Point(BigInteger.valueOf(id),polynomial); - } - } - - /** - * notifies mail handler that stage 4 was started - */ - protected void setStage4(){ - this.isStage4 = true; - SecureDistributedKeyGenerationMailHandler handler = - (SecureDistributedKeyGenerationMailHandler)user.getMailHandler(); - handler.setStage4(true); - } - - @Override - protected void stage4() { - setStage4(); - ys(); - super.stage4(); - } - - private class MessageHandler extends DistributedKeyGenerationUserImpl.MessageHandler{ - - /** - * as in super, with extension to double secret message - */ - protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { - DKGMessages.SecretMessage secretMessage = DKGMessages.SecretMessage.newBuilder() - .setI(doubleSecretMessage.getI()) - .setJ(doubleSecretMessage.getJ()) - .setSecret(doubleSecretMessage.getSecret()) - .build(); - return super.isValidSecretMessage(sender,isBroadcast,secretMessage); - } - - /** - * as in super, with extension to double secret message - */ - @Override - public void handelSecretMessage(int sender, boolean isBroadcast, Message message) { - DKGMessages.DoubleSecretMessage doubleSecretMessage = (DKGMessages.DoubleSecretMessage)message; - 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()); - } - } - - /** - * if !isStage4 as super, with extension to double secret message - * else answer message is valid if: - * 1. it was received in broadcast chanel - * 2. secret.j == sender - * 3. QUAL contains i and j - */ - 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()) - .build(); - return super.isValidAnswerMessage(sender, isBroadcast, secretMessage); - }else{ - int i = doubleSecretMessage.getI(); - int j = doubleSecretMessage.getJ(); - return isBroadcast && j == sender && parties[i -1].aborted && !parties[j - 1].aborted - && QUAL.contains(i) && QUAL.contains(j); - } - } - - /** - * if !isStage4 as super, with extension to double secret message - * else saves secret - */ - @Override - public void handelAnswerMessage(int sender, boolean isBroadcast, Message message) { - DKGMessages.DoubleSecretMessage doubleSecretMessage = (DKGMessages.DoubleSecretMessage)message; - if(isValidAnswerMessage(sender,isBroadcast,doubleSecretMessage)) { - 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 (sdkg.isValidSecret(secret, secretT, parties[j - 1].verifiableValues, i)) { - parties[i - 1].complaints[j - 1] = DistributedKeyGeneration.ComplaintState.NonDisqualified; - - } else { - parties[i - 1].complaints[j - 1] = DistributedKeyGeneration.ComplaintState.Disqualified; - } - if(j == id){ - parties[i - 1].share = secret; - parties[i - 1].shareT = secretT; - } - } else { - parties[i - 1].restoreSharesSet.add(secret); - } - } - } - - /** - * as in super with respect to protocol stage - */ - @Override - protected boolean isValidDoneMessage(int sender, boolean isBroadcast) { - if(!isStage4) { - return super.isValidDoneMessage(sender, isBroadcast); - }else{ - return isBroadcast && !parties[sender - 1].ysDoneFlag; - } - } - - /** - * as in super with respect to protocol state - */ - @Override - public void handelDoneMessage(int sender, boolean isBroadcast, Message message) { - if(!isStage4) - super.handelDoneMessage(sender, isBroadcast, message); - else{ - if(isValidDoneMessage(sender,isBroadcast)) { - parties[sender - 1].ysDoneFlag = true; - } - } - } - - /** - * use only in stage4 - * complaint message is valid if: - * 1. it was received in broadcast chanel - * 2. secret.j == sender - * 3. QUAL contains i and j - */ - protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, - DKGMessages.DoubleSecretMessage complaintMessage){ - int i = complaintMessage.getI(); - int j = complaintMessage.getJ(); - 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 - * marks i as aborted - */ - @Override - public void handelComplaintMessage(int sender, boolean isBroadcast, Message message) { - if(!isStage4) { - super.handelComplaintMessage(sender, isBroadcast, message); - }else { - DKGMessages.DoubleSecretMessage ysComplaintMessage =(DKGMessages.DoubleSecretMessage)message; - if (isValidComplaintMessage(sender,isBroadcast,ysComplaintMessage)) { - int i = ysComplaintMessage.getI(); - int j = ysComplaintMessage.getJ(); - Polynomial.Point secret = extractSecret(i,ysComplaintMessage.getSecret()); - Polynomial.Point secretT = extractSecret(i,ysComplaintMessage.getSecretT()); - if (sdkg.isValidSecret(secret, secretT, parties[i - 1].verifiableValues, j) - && !dkg.isValidSecret(secret,parties[i - 1].commitments, j)) { - parties[i - 1].aborted = true; - } - } - } - } - } -} +package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; + +import Arithmetics.Arithmetic; +import Arithmetics.Fp; +import Communication.Network; +import JointFeldmanProtocol.DistributedKeyGeneration; +import JointFeldmanProtocol.DistributedKeyGenerationUserImpl; +import ShamirSecretSharing.Polynomial; +import ShamirSecretSharing.SecretSharing; +import com.google.protobuf.Message; +import meerkat.protobuf.DKGMessages; + +import java.math.BigInteger; + +/** + * Created by Tzlil on 3/16/2016. + */ +public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenerationUserImpl { + + protected SecureDistributedKeyGenerationParty[] parties; + protected final SecureDistributedKeyGeneration sdkg; + private Arithmetic arithmetic; + private boolean isStage4; + + public SecureDistributedKeyGenerationUserImpl(SecureDistributedKeyGeneration sdkg, Network network) { + super(sdkg, network,new SecureDistributedKeyGenerationMailHandler(null)); + this.sdkg = sdkg; + this.messageHandler = new MessageHandler(); + this.user.setMessageHandler(this.messageHandler); + this.parties = sdkg.getParties(); + this.arithmetic = new Fp(sdkg.getQ()); + this.isStage4 = false; + } + + /** + * stage1 according to the protocol + * 1. Pi broadcasts Cik=Aik*Bik for k = 0,...,t. + * 2. Pi computes the shares Sij,Sij' for j = 1,...,n and sends Sij,Sij' secretly to Pj. + */ + @Override + protected void stage1() { + sdkg.broadcastVerificationValues(user); + sdkg.sendSecrets(user); + } + + @Override + protected void waitUntilStageOneCompleted(){ + super.waitUntilStageOneCompleted(); + // save the received commitments as verification values + BigInteger[] 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 + */ + @Override + protected void stage2(){ + sdkg.broadcastComplaints(user); + //broadcast done message after all complaints + DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build(); + user.broadcast(DKGMessages.Mail.Type.DONE,doneMessage); + } + + // TODO: ?? + private void resolveQualifyingPublicKey(){ + sdkg.broadcastCommitments(user); + // wait until all parties in QUAL broadcast their commitments or aborted + // TODO: in main run loop + for (int i:QUAL) { + for(int k = 0; k <= t; k++) { + while (parties[i - 1].commitments[k] == null && !parties[i - 1].aborted) { + try { + Thread.sleep(SleepTime); + } catch (InterruptedException e) { + // do nothing + } + } + } + } + sdkg.computeAndBroadcastComplaints(user,QUAL); + //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) { + while (!parties[i - 1].ysDoneFlag && !parties[i - 1].aborted) { + try { + Thread.sleep(SleepTime); + } catch (InterruptedException e) { + // do nothing + } + } + } + + // broadcast i private secret foreach i in QUAL that aborted + for (int i:QUAL) { + if(parties[i - 1].aborted){ + 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){ + while (parties[i - 1].restoreSharesSet.size() <= t) { + try { + Thread.sleep(SleepTime); + } catch (InterruptedException e) { + // do nothing + } + } + } + } + + // restore necessary information + for (int i = 0; i < n ; i++) { + if(parties[i].restoreSharesSet.isEmpty()){ + continue; + } + 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; + } + } + Polynomial polynomial = SecretSharing.recoverPolynomial(shares,arithmetic); + BigInteger[] coefficients = polynomial.getCoefficients(); + for (int k = 0 ; k <= t; k++){ + parties[i].commitments[k] = group.multiply(g,coefficients[k]); + } + parties[i].share = new Polynomial.Point(BigInteger.valueOf(id),polynomial); + } + } + + /** + * notifies mail handler that stage 4 was started + */ + protected void setStage4(){ + this.isStage4 = true; + SecureDistributedKeyGenerationMailHandler handler = + (SecureDistributedKeyGenerationMailHandler)user.getMailHandler(); + handler.setStage4(true); + } + + @Override + protected void stage4() { + setStage4(); + resolveQualifyingPublicKey(); + super.stage4(); + } + + private class MessageHandler extends DistributedKeyGenerationUserImpl.MessageHandler{ + + /** + * as in super, with extension to double secret message + */ + protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { + DKGMessages.SecretMessage secretMessage = DKGMessages.SecretMessage.newBuilder() + .setI(doubleSecretMessage.getI()) + .setJ(doubleSecretMessage.getJ()) + .setSecret(doubleSecretMessage.getSecret()) + .build(); + return super.isValidSecretMessage(sender,isBroadcast,secretMessage); + } + + /** + * as in super, with extension to double secret message + */ + @Override + public void handleSecretMessage(int sender, boolean isBroadcast, Message message) { + DKGMessages.DoubleSecretMessage doubleSecretMessage = (DKGMessages.DoubleSecretMessage)message; + 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()); + } + } + + /** + * if !isStage4 as super, with extension to double secret message + * else answer message is valid if: + * 1. it was received in broadcast chanel + * 2. secret.j == sender + * 3. QUAL contains i and j + */ + 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()) + .build(); + return super.isValidAnswerMessage(sender, isBroadcast, secretMessage); + }else{ + int i = doubleSecretMessage.getI(); + int j = doubleSecretMessage.getJ(); + return isBroadcast && j == sender && parties[i -1].aborted && !parties[j - 1].aborted + && QUAL.contains(i) && QUAL.contains(j); + } + } + + /** + * if !isStage4 as super, with extension to double secret message + * else saves secret + */ + @Override + public void handleAnswerMessage(int sender, boolean isBroadcast, Message message) { + DKGMessages.DoubleSecretMessage doubleSecretMessage = (DKGMessages.DoubleSecretMessage)message; + if(isValidAnswerMessage(sender,isBroadcast,doubleSecretMessage)) { + 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 (sdkg.isValidShare(secret, secretT, parties[j - 1].verifiableValues, i)) { + parties[i - 1].complaints[j - 1] = DistributedKeyGeneration.ComplaintState.NonDisqualified; + + } else { + parties[i - 1].complaints[j - 1] = DistributedKeyGeneration.ComplaintState.Disqualified; + } + if(j == id){ + parties[i - 1].share = secret; + parties[i - 1].shareT = secretT; + } + } else if (sdkg.isValidShare(secret, secretT, parties[j - 1].verifiableValues, i)) { + // TODO: Check that this is ok + parties[i - 1].restoreSharesSet.add(secret); + } + } + } + + /** + * as in super with respect to protocol stage + */ + @Override + protected boolean isValidDoneMessage(int sender, boolean isBroadcast) { + if(!isStage4) { + return super.isValidDoneMessage(sender, isBroadcast); + }else{ + return isBroadcast && !parties[sender - 1].ysDoneFlag; + } + } + + /** + * as in super with respect to protocol state + */ + @Override + public void handleDoneMessage(int sender, boolean isBroadcast, Message message) { + if(!isStage4) + super.handleDoneMessage(sender, isBroadcast, message); + else{ + if(isValidDoneMessage(sender,isBroadcast)) { + parties[sender - 1].ysDoneFlag = true; + } + } + } + + /** + * use only in stage4 + * complaint message is valid if: + * 1. it was received in broadcast chanel + * 2. secret.j == sender + * 3. QUAL contains i and j + */ + protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, + DKGMessages.DoubleSecretMessage complaintMessage){ + int i = complaintMessage.getI(); + int j = complaintMessage.getJ(); + 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 + * marks i as aborted + */ + @Override + public void handleComplaintMessage(int sender, boolean isBroadcast, Message message) { + if(!isStage4) { + super.handleComplaintMessage(sender, isBroadcast, message); + }else { + DKGMessages.DoubleSecretMessage ysComplaintMessage =(DKGMessages.DoubleSecretMessage)message; + if (isValidComplaintMessage(sender,isBroadcast,ysComplaintMessage)) { + int i = ysComplaintMessage.getI(); + 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) + && !dkg.isValidSecret(secret,parties[i - 1].commitments, j)) { + parties[i - 1].aborted = true; + } + } + } + } + } +} diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java index 6fd93ce..c3fb319 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java @@ -1,66 +1,66 @@ -package ShamirSecretSharing; - -import Arithmetics.Arithmetic; - -import java.math.BigInteger; - -/** - * Created by Tzlil on 1/28/2016. - * - * container of lagrange polynomial - * - * can't be constructed, constructor is private - * - * l = (image/divisor)* polynomial - * - * Note : image and divisor stored separately for avoiding lose of information by division - */ -class LagrangePolynomial{ - public final Polynomial polynomial; - public final BigInteger image; - public final BigInteger divisor; - - /** - * inner constructor, stores all given parameters - * @param polynomial - * @param image - * @param divisor - */ - private LagrangePolynomial(Polynomial polynomial, BigInteger image, BigInteger divisor) { - this.polynomial = polynomial; - this.image = image; - this.divisor = divisor; - } - - /** - * static method - * @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. - * in case there exists i != j s.t points[i].x == points[j].x returns null. - */ - public static LagrangePolynomial[] lagrangePolynomials(Polynomial.Point[] points,Arithmetic arithmetic) { - Polynomial one = new Polynomial(new BigInteger[]{BigInteger.ONE},arithmetic); - LagrangePolynomial[] lagrangePolynomials = new LagrangePolynomial[points.length]; - Polynomial[] factors = new Polynomial[points.length]; - for (int i = 0 ; i < factors.length ; i++){ - factors[i] = new Polynomial(new BigInteger[]{points[i].x.negate(),BigInteger.ONE},arithmetic); // X - Xi - } - Polynomial product; - BigInteger divisor; - for(int i = 0; i < points.length; i ++) { - product = one; - divisor = BigInteger.ONE; - for (int j = 0; j < points.length; j++) { - if (i != j) { - divisor = arithmetic.mul(divisor,arithmetic.sub(points[i].x,points[j].x)); - product = product.mul(factors[j]); - } - } - if(divisor.equals(BigInteger.ZERO)) - return null; - lagrangePolynomials[i] = new LagrangePolynomial(product,points[i].y,divisor); - } - return lagrangePolynomials; - } -} +package ShamirSecretSharing; + +import Arithmetics.Arithmetic; + +import java.math.BigInteger; + +/** + * Created by Tzlil on 1/28/2016. + * + * container of lagrange polynomial + * + * Constructor is private (use {@link #lagrangePolynomials(Polynomial.Point[], Arithmetic)} to construct) + * + * l = (evaluate/divisor)* polynomial + * + * Note : image and divisor stored separately for avoiding lose of information by division + */ +class LagrangePolynomial{ + public final Polynomial polynomial; + public final BigInteger image; + public final BigInteger divisor; + + /** + * inner constructor, stores all given parameters + * @param polynomial + * @param image + * @param divisor + */ + private LagrangePolynomial(Polynomial polynomial, BigInteger image, BigInteger divisor) { + this.polynomial = polynomial; + this.image = image; + this.divisor = divisor; + } + + /** + * static method + * @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. + * in case there exists i != j s.t points[i].x == points[j].x returns null. + */ + public static LagrangePolynomial[] lagrangePolynomials(Polynomial.Point[] points,Arithmetic arithmetic) { + Polynomial one = new Polynomial(new BigInteger[]{BigInteger.ONE},arithmetic); + LagrangePolynomial[] lagrangePolynomials = new LagrangePolynomial[points.length]; + Polynomial[] factors = new Polynomial[points.length]; + for (int i = 0 ; i < factors.length ; i++){ + factors[i] = new Polynomial(new BigInteger[]{points[i].x.negate(),BigInteger.ONE},arithmetic); // X - Xi + } + Polynomial product; + BigInteger divisor; + for(int i = 0; i < points.length; i ++) { + product = one; + divisor = BigInteger.ONE; + for (int j = 0; j < points.length; j++) { + if (i != j) { + divisor = arithmetic.mul(divisor,arithmetic.sub(points[i].x,points[j].x)); + product = product.mul(factors[j]); + } + } + if(divisor.equals(BigInteger.ZERO)) + return null; + lagrangePolynomials[i] = new LagrangePolynomial(product,points[i].y,divisor); + } + return lagrangePolynomials; + } +} diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java index ac7fc79..03c8f99 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java @@ -1,207 +1,208 @@ -package ShamirSecretSharing; - -import Arithmetics.Arithmetic; - -import java.math.BigInteger; -import java.util.Arrays; - -/** - * Created by Tzlil on 1/27/2016. - */ -public class Polynomial implements Comparable { - private final int degree; - private final BigInteger[] coefficients; - private final Arithmetic arithmetic; - - /** - * constructor - * @param coefficients - * @param arithmetic - * degree set as max index such that coefficients[degree] not equals zero - */ - public Polynomial(BigInteger[] coefficients,Arithmetic arithmetic) { - int d = coefficients.length - 1; - while (d > 0 && coefficients[d].equals(BigInteger.ZERO)){ - d--; - } - this.degree = d; - this.coefficients = coefficients; - this.arithmetic = arithmetic; - } - - /* - * use for tests - */ - @Override - public int compareTo(Polynomial other) { - if (this.degree != other.degree) - return this.degree - other.degree; - int compare; - for (int i = degree; i >= degree ; i--){ - compare = this.coefficients[i].compareTo(other.coefficients[i]); - if (compare != 0){ - return compare; - } - } - return 0; - } - - /** - * @param x - * @return sum of coefficients[i] * (x ^ i) - */ - public BigInteger image(BigInteger x){ - BigInteger result = BigInteger.ZERO; - BigInteger power = BigInteger.ONE; - for(int i = 0 ; i <= degree ; i++){ - result = arithmetic.add(result,arithmetic.mul(coefficients[i],power)); - power = power.multiply(x); - } - return result; - } - - /** - * @param points - * @return polynomial of minimal degree which goes through all points - */ - public static Polynomial interpolation(Point[] points, Arithmetic arithmetic) { - LagrangePolynomial[] l = LagrangePolynomial.lagrangePolynomials(points,arithmetic); - if (l == null){ - return null; - } - // product = product of l[i].divisor - BigInteger product = BigInteger.ONE; - for (int i = 0; i < l.length;i++){ - product = arithmetic.mul(product,l[i].divisor); - } - - // factor[i] = product divided by l[i].divisor = product of l[j].divisor s.t j!=i - BigInteger[] factors = new BigInteger[l.length]; - for (int i = 0; i < l.length;i++){ - factors[i] = arithmetic.div(product,l[i].divisor); - } - int degree = l[0].polynomial.degree; - - // coefficients[j] = (sum of l[i].image * factor[i] * l[i].coefficients[j] s.t i!=j) divide by product = - // = sum of l[i].image * l[i].coefficients[j] / l[i].divisor s.t i!=j - BigInteger[] coefficients = new BigInteger[degree + 1]; - for (int j = 0; j < coefficients.length;j++){ - coefficients[j] = BigInteger.ZERO; - for (int i = 0; i < l.length; i++){ - BigInteger current = arithmetic.mul(l[i].image,factors[i]); - current = arithmetic.mul(current,l[i].polynomial.coefficients[j]); - coefficients[j] = arithmetic.add(coefficients[j],current); - } - coefficients[j] = arithmetic.div(coefficients[j],product); - } - return new Polynomial(coefficients,arithmetic); - } - - /** - * @param other - * @return new ShamirSecretSharing.PolynomialTests of degree max(this degree,other degree) s.t for all x in Z - * new.image(x) = this.image(x) + other.image(x) - */ - public Polynomial add(Polynomial other){ - Polynomial bigger,smaller; - if(this.degree < other.degree){ - bigger = other; - smaller = this; - }else{ - bigger = this; - smaller = other; - } - BigInteger[] coefficients = bigger.getCoefficients(); - - for (int i = 0; i <= smaller.degree ; i++){ - coefficients[i] = arithmetic.add(smaller.coefficients[i],bigger.coefficients[i]); - } - return new Polynomial(coefficients,other.arithmetic); - } - - /** - * @param constant - * @return new Polynomial of degree this.degree s.t for all x in Z - * new.image(x) = constant * this.image(x) - */ - public Polynomial mul(BigInteger constant){ - - BigInteger[] coefficients = this.getCoefficients(); - - for (int i = 0; i <= this.degree ; i++){ - coefficients[i] = arithmetic.mul(constant,coefficients[i]); - } - return new Polynomial(coefficients,arithmetic); - } - - /** - * @param other - * @return new Polynomial of degree this degree + other degree + 1 s.t for all x in Z - * new.image(x) = this.image(x) * other.image(x) - */ - public Polynomial mul(Polynomial other){ - - BigInteger[] coefficients = new BigInteger[this.degree + other.degree + 1]; - Arrays.fill(coefficients,BigInteger.ZERO); - - for (int i = 0; i <= this.degree ; i++){ - for (int j = 0; j <= other.degree; j++){ - coefficients[i+j] = arithmetic.add(coefficients[i+j],arithmetic.mul(this.coefficients[i],other.coefficients[j])); - } - } - return new Polynomial(coefficients,arithmetic); - } - - - /** getter - * @return copy of coefficients - */ - public BigInteger[] getCoefficients() { - return Arrays.copyOf(coefficients,coefficients.length); - } - - /** getter - * @return degree - */ - public int getDegree() { - return degree; - } - - /** - * inner class - * container for (x,y) x from range and y from image of polynomial - */ - public static class Point implements java.io.Serializable { - public final BigInteger x; - public final BigInteger y; - - /** - * constructor - * @param x - * @param polynomial y = polynomial.image(x) - */ - public Point(BigInteger x, Polynomial polynomial) { - this.x = x; - this.y = polynomial.image(x); - } - - /** - * constructor - * @param x - * @param y - */ - public Point(BigInteger x,BigInteger y) { - this.x = x; - this.y = y; - } - - @Override - public boolean equals(Object obj) { - if(!super.equals(obj)) - return false; - Point other = (Point)obj; - return this.x.equals(other.x) && this.y.equals(other.y); - } - } - -} +package ShamirSecretSharing; + +import Arithmetics.Arithmetic; + +import java.math.BigInteger; +import java.util.Arrays; + +/** + * Created by Tzlil on 1/27/2016. + */ +public class Polynomial implements Comparable { + private final int degree; + private final BigInteger[] coefficients; + private final Arithmetic arithmetic; + + /** + * constructor + * @param coefficients + * @param arithmetic + * degree set as max index such that coefficients[degree] not equals zero + */ + public Polynomial(BigInteger[] coefficients,Arithmetic arithmetic) { + int d = coefficients.length - 1; + while (d > 0 && coefficients[d].equals(BigInteger.ZERO)){ + d--; + } + this.degree = d; + this.coefficients = coefficients; + this.arithmetic = arithmetic; + } + + /** + * Compare to another polynomial (order by degree, then coefficients). + */ + @Override + public int compareTo(Polynomial other) { + if (this.degree != other.degree) + return this.degree - other.degree; + int compare; + for (int i = degree; i >= degree ; i--){ + compare = this.coefficients[i].compareTo(other.coefficients[i]); + if (compare != 0){ + return compare; + } + } + return 0; + } + + /** + * @param x + * @return sum of coefficients[i] * (x ^ i) + */ + public BigInteger evaluate(BigInteger x){ + BigInteger result = BigInteger.ZERO; + BigInteger power = BigInteger.ONE; + for(int i = 0 ; i <= degree ; i++){ + result = arithmetic.add(result,arithmetic.mul(coefficients[i],power)); + power = power.multiply(x); + } + return result; + } + + /** + * @param 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. + */ + public static Polynomial interpolation(Point[] points, Arithmetic arithmetic) { + LagrangePolynomial[] l = LagrangePolynomial.lagrangePolynomials(points,arithmetic); + if (l == null){ + return null; + } + // product = product of l[i].divisor + BigInteger product = BigInteger.ONE; + for (int i = 0; i < l.length;i++){ + product = arithmetic.mul(product,l[i].divisor); + } + + // factor[i] = product divided by l[i].divisor = product of l[j].divisor s.t j!=i + BigInteger[] factors = new BigInteger[l.length]; + for (int i = 0; i < l.length;i++){ + factors[i] = arithmetic.div(product,l[i].divisor); + } + 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 = + // = sum of l[i].evaluate * l[i].coefficients[j] / l[i].divisor s.t i!=j + BigInteger[] coefficients = new BigInteger[degree + 1]; + for (int j = 0; j < coefficients.length;j++){ + coefficients[j] = BigInteger.ZERO; + for (int i = 0; i < l.length; i++){ + BigInteger current = arithmetic.mul(l[i].image,factors[i]); + current = arithmetic.mul(current,l[i].polynomial.coefficients[j]); + coefficients[j] = arithmetic.add(coefficients[j],current); + } + coefficients[j] = arithmetic.div(coefficients[j],product); + } + return new Polynomial(coefficients,arithmetic); + } + + /** + * @param other + * @return new ShamirSecretSharing.PolynomialTests of degree max(this degree,other degree) s.t for all x in Z + * new.evaluate(x) = this.evaluate(x) + other.evaluate(x) + */ + public Polynomial add(Polynomial other){ + Polynomial bigger,smaller; + if(this.degree < other.degree){ + bigger = other; + smaller = this; + }else{ + bigger = this; + smaller = other; + } + BigInteger[] coefficients = bigger.getCoefficients(); + + for (int i = 0; i <= smaller.degree ; i++){ + coefficients[i] = arithmetic.add(smaller.coefficients[i],bigger.coefficients[i]); + } + return new Polynomial(coefficients,other.arithmetic); + } + + /** + * @param constant + * @return new Polynomial of degree this.degree s.t for all x in Z + * new.evaluate(x) = constant * this.evaluate(x) + */ + public Polynomial mul(BigInteger constant){ + + BigInteger[] coefficients = this.getCoefficients(); + + for (int i = 0; i <= this.degree ; i++){ + coefficients[i] = arithmetic.mul(constant,coefficients[i]); + } + return new Polynomial(coefficients,arithmetic); + } + + /** + * @param other + * @return new Polynomial of degree this degree + other degree + 1 s.t for all x in Z + * new.evaluate(x) = this.evaluate(x) * other.evaluate(x) + */ + public Polynomial mul(Polynomial other){ + + BigInteger[] coefficients = new BigInteger[this.degree + other.degree + 1]; + Arrays.fill(coefficients,BigInteger.ZERO); + + for (int i = 0; i <= this.degree ; i++){ + for (int j = 0; j <= other.degree; j++){ + coefficients[i+j] = arithmetic.add(coefficients[i+j],arithmetic.mul(this.coefficients[i],other.coefficients[j])); + } + } + return new Polynomial(coefficients,arithmetic); + } + + + /** getter + * @return copy of coefficients + */ + public BigInteger[] getCoefficients() { + return Arrays.copyOf(coefficients,coefficients.length); + } + + /** getter + * @return degree + */ + public int getDegree() { + return degree; + } + + /** + * inner class + * container for (x,y) x from range and y from evaluate of polynomial + */ + public static class Point implements java.io.Serializable { + public final BigInteger x; + public final BigInteger y; + + /** + * constructor + * @param x + * @param polynomial y = polynomial.evaluate(x) + */ + public Point(BigInteger x, Polynomial polynomial) { + this.x = x; + this.y = polynomial.evaluate(x); + } + + /** + * constructor + * @param x + * @param y + */ + public Point(BigInteger x,BigInteger y) { + this.x = x; + this.y = y; + } + + @Override + public boolean equals(Object obj) { + if(!super.equals(obj)) + return false; + Point other = (Point)obj; + return this.x.equals(other.x) && this.y.equals(other.y); + } + } + +} diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java index 0f424f9..b9c0386 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java @@ -1,112 +1,111 @@ -package ShamirSecretSharing; - -import Arithmetics.Arithmetic; -import Arithmetics.Fp; - -import java.math.BigInteger; -import java.util.Collection; -import java.util.Random; - -/** - * Created by Tzlil on 1/27/2016. - * an implementation of Shamire's secret sharing scheme - */ -public class SecretSharing{ - protected final int t; - protected final int n; - protected final BigInteger q; - protected final Polynomial polynomial; - - /** - * 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 x secret, chosen from Zq - * @param random use for generate random polynomial - */ - public SecretSharing(int t, int n, BigInteger x, Random random, BigInteger q) { - this.q = q; - this.t = t; - this.n = n; - this.polynomial = generateRandomPolynomial(x,random); - } - - /** - * @param x - * @param random - * @return new Polynomial polynomial of degree t ,such that - * 1. polynomial(0) = x - * 2. polynomial coefficients randomly chosen from Zq (except of coefficients[0] = x) - */ - private Polynomial generateRandomPolynomial(BigInteger x, Random random) { - BigInteger[] coefficients = new BigInteger[t + 1]; - coefficients[0] = x.mod(q); - int bits = q.bitLength(); - for (int i = 1 ; i <= t; i++ ){ - coefficients[i] = new BigInteger(bits,random).mod(q); - } - return new Polynomial(coefficients,new Fp(q)); - } - - /** - * @param i in range of [1,...n] - * - * @return polynomial.image(i)%q - */ - public Polynomial.Point getShare(int i){ - assert (i > 0 && i <= n); - return new Polynomial.Point(BigInteger.valueOf(i), polynomial); - } - - /** - * @param shares - subset of the original shares - * - * @return image of interpolation(shares) at x = 0 - */ - public static BigInteger restoreSecret(Polynomial.Point[] shares,Arithmetic arithmetic) throws Exception { - return restorePolynomial(shares,arithmetic).image(BigInteger.ZERO); - } - /** - * @param shares - subset of the original shares - * - * @return interpolation(shares) - */ - public static Polynomial restorePolynomial(Polynomial.Point[] shares,Arithmetic arithmetic) { - return Polynomial.interpolation(shares,arithmetic); - } - - /** - * getter - * @return threshold - */ - public int getT() { - return t; - } - - /** - * getter - * @return number of share holders - */ - public int getN() { - return n; - } - - /** - * getter - * @return the prime was given in the constructor - */ - public BigInteger getQ() { - return q; - } - - - /** - * getter - * @return the polynomial was generated in constructor - */ - public Polynomial getPolynomial() { - return polynomial; - } -} +package ShamirSecretSharing; + +import Arithmetics.Arithmetic; +import Arithmetics.Fp; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/27/2016. + * an implementation of Shamire's secret sharing scheme + */ +public class SecretSharing{ + protected final int t; + protected final int n; + protected final BigInteger q; + protected final Polynomial polynomial; + + /** + * 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 x secret, chosen from Zq + * @param random use for generate random polynomial + */ + public SecretSharing(int t, int n, BigInteger x, Random random, BigInteger q) { + this.q = q; + this.t = t; + this.n = n; + this.polynomial = generateRandomPolynomial(x,random); + } + + /** + * @param x + * @param random + * @return new Polynomial polynomial of degree t ,such that + * 1. polynomial(0) = x + * 2. polynomial coefficients randomly chosen from Zq (except of coefficients[0] = x) + */ + private Polynomial generateRandomPolynomial(BigInteger x, Random random) { + BigInteger[] coefficients = new BigInteger[t + 1]; + coefficients[0] = x.mod(q); + int bits = q.bitLength(); + for (int i = 1 ; i <= t; i++ ){ + coefficients[i] = new BigInteger(bits,random).mod(q); + } + return new Polynomial(coefficients,new Fp(q)); + } + + /** + * @param i in range of [1,...n] + * + * @return polynomial.evaluate(i)%q + */ + public Polynomial.Point getShare(int i){ + assert (i > 0 && i <= n); + return new Polynomial.Point(BigInteger.valueOf(i), polynomial); + } + + /** + * @param shares - subset of the original shares + * + * @return evaluate of interpolation(shares) at x = 0 + */ + public static BigInteger recoverSecret(Polynomial.Point[] shares, Arithmetic arithmetic) throws Exception { + return recoverPolynomial(shares,arithmetic).evaluate(BigInteger.ZERO); + } + /** + * @param shares - subset of the original shares + * + * @return interpolation(shares) + */ + public static Polynomial recoverPolynomial(Polynomial.Point[] shares, Arithmetic arithmetic) { + return Polynomial.interpolation(shares,arithmetic); + } + + /** + * getter + * @return threshold + */ + public int getT() { + return t; + } + + /** + * getter + * @return number of share holders + */ + public int getN() { + return n; + } + + /** + * getter + * @return the prime was given in the constructor + */ + public BigInteger getQ() { + return q; + } + + + /** + * getter + * @return the polynomial was generated in constructor + */ + public Polynomial getPolynomial() { + return polynomial; + } +} diff --git a/destributed-key-generation/src/main/java/UserInterface/DistributedKeyGenerationUser.java b/destributed-key-generation/src/main/java/UserInterface/DistributedKeyGenerationUser.java index d8eb5ef..9fcdbf6 100644 --- a/destributed-key-generation/src/main/java/UserInterface/DistributedKeyGenerationUser.java +++ b/destributed-key-generation/src/main/java/UserInterface/DistributedKeyGenerationUser.java @@ -1,13 +1,13 @@ -package UserInterface; - -import java.math.BigInteger; -import java.util.Set; - -/** - * Created by Tzlil on 2/21/2016. - */ -public interface DistributedKeyGenerationUser extends VerifiableSecretSharingUser { - - BigInteger getPublicValue(); - Set getQUAL(); -} +package UserInterface; + +import java.math.BigInteger; +import java.util.Set; + +/** + * Created by Tzlil on 2/21/2016. + */ +public interface DistributedKeyGenerationUser extends VerifiableSecretSharingUser { + + BigInteger getPublicValue(); + Set getQUAL(); +} diff --git a/destributed-key-generation/src/main/java/UserInterface/SecretSharingUser.java b/destributed-key-generation/src/main/java/UserInterface/SecretSharingUser.java index dc4a6e4..e5462a0 100644 --- a/destributed-key-generation/src/main/java/UserInterface/SecretSharingUser.java +++ b/destributed-key-generation/src/main/java/UserInterface/SecretSharingUser.java @@ -1,14 +1,14 @@ -package UserInterface; - -import ShamirSecretSharing.Polynomial; - -/** - * Created by Tzlil on 2/21/2016. - */ -public interface SecretSharingUser extends Runnable { - - Polynomial.Point getShare(); - int getID(); - int getN(); - int getT(); -} +package UserInterface; + +import ShamirSecretSharing.Polynomial; + +/** + * Created by Tzlil on 2/21/2016. + */ +public interface SecretSharingUser extends Runnable { + + Polynomial.Point getShare(); + int getID(); + int getN(); + int getT(); +} diff --git a/destributed-key-generation/src/main/java/UserInterface/VerifiableSecretSharingUser.java b/destributed-key-generation/src/main/java/UserInterface/VerifiableSecretSharingUser.java index 79cd404..a8e4e96 100644 --- a/destributed-key-generation/src/main/java/UserInterface/VerifiableSecretSharingUser.java +++ b/destributed-key-generation/src/main/java/UserInterface/VerifiableSecretSharingUser.java @@ -1,16 +1,16 @@ -package UserInterface; - -import UserInterface.SecretSharingUser; -import org.factcenter.qilin.primitives.Group; - -import java.math.BigInteger; - -/** - * Created by Tzlil on 2/21/2016. - */ -public interface VerifiableSecretSharingUser extends SecretSharingUser { - - BigInteger[] getCommitments(); - BigInteger getGenerator(); - Group getGroup(); -} +package UserInterface; + +import UserInterface.SecretSharingUser; +import org.factcenter.qilin.primitives.Group; + +import java.math.BigInteger; + +/** + * Created by Tzlil on 2/21/2016. + */ +public interface VerifiableSecretSharingUser extends SecretSharingUser { + + BigInteger[] getCommitments(); + BigInteger getGenerator(); + Group getGroup(); +} diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java index fff8952..897957e 100644 --- a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java +++ b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java @@ -1,68 +1,67 @@ -package FeldmanVerifiableSecretSharing; - -import Communication.Network; -import ShamirSecretSharing.Polynomial; -import org.factcenter.qilin.primitives.Group; -import org.factcenter.qilin.primitives.concrete.Zpstar; -import org.junit.Before; -import org.junit.Test; - -import java.math.BigInteger; -import java.util.Random; - -/** - * Created by Tzlil on 1/29/2016. - */ -public class VerifiableSecretSharingTest { - - - VerifiableSecretSharing[] verifiableSecretSharingArray; - int tests = 1 << 10; - Random random; - - @Before - public void settings(){ - BigInteger p = BigInteger.valueOf(2903); - BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); - Zpstar zpstar = new Zpstar(p); - random = new Random(); - BigInteger g; - BigInteger ZERO = zpstar.zero(); - do{ - g = zpstar.sample(random); - }while (!g.equals(ZERO) && !zpstar.multiply(g,q).equals(ZERO));// sample from QRZp* - int t = 8; - int n = 20; - verifiableSecretSharingArray = new VerifiableSecretSharing[tests]; - for (int i = 0; i < verifiableSecretSharingArray.length; i++){ - 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(); - Group zpstar = verifiableSecretSharing.getGroup(); - BigInteger g = verifiableSecretSharing.getGenerator(); - Polynomial.Point[] shares = new Polynomial.Point[n]; - BigInteger[] commitments = verifiableSecretSharing.getCommitmentsArray(); - BigInteger[] verifications = new BigInteger[n]; - for (int i = 1 ; i <= shares.length; i ++){ - shares[i - 1] = verifiableSecretSharing.getShare(i); - verifications[i - 1] = VerifiableSecretSharing.verify(i,commitments,zpstar); - } - BigInteger expected; - for (int i = 0 ; i < shares.length ; i++){ - expected = zpstar.multiply(g,shares[i].y); - assert (expected.equals(verifications[i])); - } - - } - - @Test - public void secretSharingTest() throws Exception { - for (int i = 0 ; i < verifiableSecretSharingArray.length; i ++){ - oneTest(verifiableSecretSharingArray[i]); - } - } -} +package FeldmanVerifiableSecretSharing; + +import ShamirSecretSharing.Polynomial; +import org.factcenter.qilin.primitives.Group; +import org.factcenter.qilin.primitives.concrete.Zpstar; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/29/2016. + */ +public class VerifiableSecretSharingTest { + + + VerifiableSecretSharing[] verifiableSecretSharingArray; + int tests = 1 << 10; + Random random; + + @Before + public void settings(){ + BigInteger p = BigInteger.valueOf(2903); + BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); + Zpstar zpstar = new Zpstar(p); + random = new Random(); + BigInteger g; + BigInteger ZERO = zpstar.zero(); + do{ + g = zpstar.sample(random); + }while (!g.equals(ZERO) && !zpstar.multiply(g,q).equals(ZERO));// sample from QRZp* + int t = 8; + int n = 20; + verifiableSecretSharingArray = new VerifiableSecretSharing[tests]; + for (int i = 0; i < verifiableSecretSharingArray.length; i++){ + 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(); + Group zpstar = verifiableSecretSharing.getGroup(); + BigInteger g = verifiableSecretSharing.getGenerator(); + Polynomial.Point[] shares = new Polynomial.Point[n]; + BigInteger[] commitments = verifiableSecretSharing.getCommitmentsArray(); + BigInteger[] verifications = new BigInteger[n]; + for (int i = 1 ; i <= shares.length; i ++){ + shares[i - 1] = verifiableSecretSharing.getShare(i); + verifications[i - 1] = VerifiableSecretSharing.computeVerificationValue(i,commitments,zpstar); + } + BigInteger expected; + for (int i = 0 ; i < shares.length ; i++){ + expected = zpstar.multiply(g,shares[i].y); + assert (expected.equals(verifications[i])); + } + + } + + @Test + public void secretSharingTest() throws Exception { + for (int i = 0 ; i < verifiableSecretSharingArray.length; i ++){ + oneTest(verifiableSecretSharingArray[i]); + } + } +} diff --git a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGMaliciousUserImpl.java b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGMaliciousUserImpl.java index ad4aa4d..4dfd4a4 100644 --- a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGMaliciousUserImpl.java +++ b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGMaliciousUserImpl.java @@ -1,72 +1,72 @@ -package JointFeldmanProtocol; - -import Communication.MailHandler; -import Communication.Network; - -import java.math.BigInteger; -import java.util.*; - -/** - * Created by Tzlil on 3/21/2016. - */ -public class DKGMaliciousUserImpl extends DistributedKeyGenerationUserImpl { - - private final DistributedKeyGeneration maliciousDkg; - private final Set falls; - public DKGMaliciousUserImpl(DistributedKeyGeneration dkg,DistributedKeyGeneration maliciousDKG, Network network,Set falls) { - super(dkg, network); - this.falls = falls; - this.maliciousDkg = maliciousDKG; - maliciousDKG.setParties(parties); - } - - public static Set selectFallsRandomly(Set ids, Random random){ - Set falls = new HashSet(); - ArrayList idsList = new ArrayList(); - for (int id : ids){ - idsList.add(id); - } - int fallsSize = random.nextInt(idsList.size()) + 1;// 1 - (n-1) - while (falls.size() < fallsSize){ - falls.add(idsList.remove(random.nextInt(idsList.size()))); - } - return falls; - } - - public static DistributedKeyGeneration generateMaliciousDKG(DistributedKeyGeneration dkg,Random random){ - BigInteger q = dkg.getQ(); - BigInteger zi = new BigInteger(q.bitLength(), random).mod(q); - return new DistributedKeyGeneration(dkg.getT(),dkg.getN(),zi,random,dkg.getQ() - ,dkg.getGenerator(),dkg.getGroup(),dkg.getId()); - } - - @Override - public void stage1() { - dkg.broadcastCommitments(user); - sendSecrets(); //insteadof dkg.sendSecrets(user); - } - - @Override - public void stage3() { - maliciousDkg.answerAllComplainingPlayers(user); - } - - @Override - public void stage4(){ - // do nothing - } - - private void sendSecrets(){ - for (int j = 1; j <= n ; j++){ - if(j != id){ - if(falls.contains(j)){ - maliciousDkg.sendSecret(user,j); - }else { - dkg.sendSecret(user, j); - } - } - } - } - - -} +package JointFeldmanProtocol; + +import Communication.MailHandler; +import Communication.Network; + +import java.math.BigInteger; +import java.util.*; + +/** + * Created by Tzlil on 3/21/2016. + */ +public class DKGMaliciousUserImpl extends DistributedKeyGenerationUserImpl { + + private final DistributedKeyGeneration maliciousDkg; + private final Set falls; + public DKGMaliciousUserImpl(DistributedKeyGeneration dkg,DistributedKeyGeneration maliciousDKG, Network network,Set falls) { + super(dkg, network); + this.falls = falls; + this.maliciousDkg = maliciousDKG; + maliciousDKG.setParties(parties); + } + + public static Set selectFallsRandomly(Set ids, Random random){ + Set falls = new HashSet(); + ArrayList idsList = new ArrayList(); + for (int id : ids){ + idsList.add(id); + } + int fallsSize = random.nextInt(idsList.size()) + 1;// 1 - (n-1) + while (falls.size() < fallsSize){ + falls.add(idsList.remove(random.nextInt(idsList.size()))); + } + return falls; + } + + public static DistributedKeyGeneration generateMaliciousDKG(DistributedKeyGeneration dkg,Random random){ + BigInteger q = dkg.getQ(); + BigInteger zi = new BigInteger(q.bitLength(), random).mod(q); + return new DistributedKeyGeneration(dkg.getT(),dkg.getN(),zi,random,dkg.getQ() + ,dkg.getGenerator(),dkg.getGroup(),dkg.getId()); + } + + @Override + public void stage1() { + dkg.broadcastCommitments(user); + sendSecrets(); //insteadof dkg.sendSecrets(user); + } + + @Override + public void stage3() { + maliciousDkg.answerAllComplainingPlayers(user); + } + + @Override + public void stage4(){ + // do nothing + } + + private void sendSecrets(){ + for (int j = 1; j <= n ; j++){ + if(j != id){ + if(falls.contains(j)){ + maliciousDkg.sendSecret(user,j); + }else { + dkg.sendSecret(user, j); + } + } + } + } + + +} diff --git a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java index 624aeeb..7599a53 100644 --- a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java +++ b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java @@ -1,175 +1,175 @@ -package JointFeldmanProtocol; - -import Arithmetics.Arithmetic; -import Arithmetics.Fp; -import Communication.Network; -import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; -import ShamirSecretSharing.Polynomial; -import ShamirSecretSharing.SecretSharing; -import UserInterface.DistributedKeyGenerationUser; -import Utils.GenerateRandomPrime; -import org.factcenter.qilin.primitives.Group; -import org.factcenter.qilin.primitives.concrete.Zpstar; -import org.junit.Before; -import org.junit.Test; - -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Random; -import java.util.Set; - -/** - * Created by Tzlil on 3/21/2016. - */ -public class DKGTest { - - int tests = 10; - BigInteger p = GenerateRandomPrime.SafePrime100Bits; - BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); - Group group = new Zpstar(p); - Arithmetic arithmetic = new Fp(q); - int t = 9; - int n = 20; - - Testable[] testables; - - @Before - public void settings(){ - 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++){ - testable.threads[i].start(); - } - 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){ - assert (testable.dkgs[i - 1].getPublicValue().equals(publicValue)); - } - - // assert valid verification values - BigInteger expected,verification; - for (int i: testable.valids){ - expected = group.multiply(testable.g, testable.dkgs[i - 1].getShare().y); - verification = VerifiableSecretSharing.verify(i, testable.dkgs[i - 1].getCommitments(), group); - assert (expected.equals(verification)); - } - - - // restore the secret from shares - ArrayList sharesList = new ArrayList(); - - for (int i: testable.valids){ - sharesList.add(testable.dkgs[i - 1].getShare()); - } - Polynomial.Point[] shares = new Polynomial.Point[sharesList.size()]; - for (int i = 0; i < shares.length; i ++){ - shares[i] = sharesList.get(i); - } - - BigInteger calculatedSecret = SecretSharing.restoreSecret(shares,arithmetic); - assert (calculatedSecret.equals(testable.secret)); - } - - @Test - public void test() throws Exception { - for (int i = 0; i < tests; i++){ - oneTest(i); - } - } - - class Testable{ - Set valids; - Set QUAL; - Set aborted; - Set malicious; - DistributedKeyGenerationUser[] dkgs; - Thread[] threads; - BigInteger g; - BigInteger secret; - - public Testable(Random random) { - this.dkgs = new DistributedKeyGenerationUserImpl[n]; - this.valids = new HashSet(); - this.QUAL = new HashSet(); - this.aborted = new HashSet(); - this.malicious = new HashSet(); - this.threads = new Thread[n]; - this.g = sampleGenerator(random); - ArrayList ids = new ArrayList(); - for (int id = 1; id<= n ; id++){ - ids.add(id); - } - Network network = new Network(n); - int id; - BigInteger s; - DistributedKeyGeneration dkg; - this.secret = BigInteger.ZERO; - while (!ids.isEmpty()) { - id = ids.remove(random.nextInt(ids.size())); - s = randomIntModQ(random); - dkg = new DistributedKeyGeneration(t, n, s, random, q, g, group, id); - dkgs[id - 1] = randomDKGUser(id,network,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); - }else{ - int type = random.nextInt(3); - switch (type){ - case 0:// regular - valids.add(id); - QUAL.add(id); - return new DistributedKeyGenerationUserImpl(dkg,network); - case 1:// abort - int abortStage = random.nextInt(2) + 1; // 1 or 2 - aborted.add(id); - if (abortStage == 2){ - QUAL.add(id); - } - return new DKGUserImplAbort(dkg,network,abortStage); - case 2:// malicious - malicious.add(id); - Set falls = DKGMaliciousUserImpl.selectFallsRandomly(valids,random); - DistributedKeyGeneration maliciousDKG = DKGMaliciousUserImpl.generateMaliciousDKG(dkg,random); - return new DKGMaliciousUserImpl(dkg,maliciousDKG,network,falls); - default: - return null; - } - } - } - - public BigInteger sampleGenerator(Random random){ - BigInteger ZERO = group.zero(); - BigInteger g; - do { - g = group.sample(random); - } while (!g.equals(ZERO) && !group.multiply(g, q).equals(ZERO)); - return g; - } - - public BigInteger randomIntModQ(Random random){ - return new BigInteger(q.bitLength(), random).mod(q); - } - - } -} +package JointFeldmanProtocol; + +import Arithmetics.Arithmetic; +import Arithmetics.Fp; +import Communication.Network; +import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; +import ShamirSecretSharing.Polynomial; +import ShamirSecretSharing.SecretSharing; +import UserInterface.DistributedKeyGenerationUser; +import Utils.GenerateRandomPrime; +import org.factcenter.qilin.primitives.Group; +import org.factcenter.qilin.primitives.concrete.Zpstar; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Random; +import java.util.Set; + +/** + * Created by Tzlil on 3/21/2016. + */ +public class DKGTest { + + int tests = 10; + BigInteger p = GenerateRandomPrime.SafePrime100Bits; + BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); + Group group = new Zpstar(p); + Arithmetic arithmetic = new Fp(q); + int t = 9; + int n = 20; + + Testable[] testables; + + @Before + public void settings(){ + 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++){ + testable.threads[i].start(); + } + 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){ + assert (testable.dkgs[i - 1].getPublicValue().equals(publicValue)); + } + + // assert valid verification values + BigInteger expected,verification; + for (int i: testable.valids){ + 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 sharesList = new ArrayList(); + + for (int i: testable.valids){ + sharesList.add(testable.dkgs[i - 1].getShare()); + } + 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)); + } + + @Test + public void test() throws Exception { + for (int i = 0; i < tests; i++){ + oneTest(i); + } + } + + class Testable{ + Set valids; + Set QUAL; + Set aborted; + Set malicious; + DistributedKeyGenerationUser[] dkgs; + Thread[] threads; + BigInteger g; + BigInteger secret; + + public Testable(Random random) { + this.dkgs = new DistributedKeyGenerationUserImpl[n]; + this.valids = new HashSet(); + this.QUAL = new HashSet(); + this.aborted = new HashSet(); + this.malicious = new HashSet(); + this.threads = new Thread[n]; + this.g = sampleGenerator(random); + ArrayList ids = new ArrayList(); + for (int id = 1; id<= n ; id++){ + ids.add(id); + } + Network network = new Network(n); + int id; + BigInteger s; + DistributedKeyGeneration dkg; + this.secret = BigInteger.ZERO; + while (!ids.isEmpty()) { + id = ids.remove(random.nextInt(ids.size())); + s = randomIntModQ(random); + dkg = new DistributedKeyGeneration(t, n, s, random, q, g, group, id); + dkgs[id - 1] = randomDKGUser(id,network,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); + }else{ + int type = random.nextInt(3); + switch (type){ + case 0:// regular + valids.add(id); + QUAL.add(id); + return new DistributedKeyGenerationUserImpl(dkg,network); + case 1:// abort + int abortStage = random.nextInt(2) + 1; // 1 or 2 + aborted.add(id); + if (abortStage == 2){ + QUAL.add(id); + } + return new DKGUserImplAbort(dkg,network,abortStage); + case 2:// malicious + malicious.add(id); + Set falls = DKGMaliciousUserImpl.selectFallsRandomly(valids,random); + DistributedKeyGeneration maliciousDKG = DKGMaliciousUserImpl.generateMaliciousDKG(dkg,random); + return new DKGMaliciousUserImpl(dkg,maliciousDKG,network,falls); + default: + return null; + } + } + } + + public BigInteger sampleGenerator(Random random){ + BigInteger ZERO = group.zero(); + BigInteger g; + do { + g = group.sample(random); + } while (!g.equals(ZERO) && !group.multiply(g, q).equals(ZERO)); + return g; + } + + public BigInteger randomIntModQ(Random random){ + return new BigInteger(q.bitLength(), random).mod(q); + } + + } +} diff --git a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGUserImplAbort.java b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGUserImplAbort.java index 39f211a..6acb8ce 100644 --- a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGUserImplAbort.java +++ b/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGUserImplAbort.java @@ -1,63 +1,63 @@ -package JointFeldmanProtocol; - -import Communication.Network; -import meerkat.protobuf.DKGMessages; - -/** - * Created by Tzlil on 3/14/2016. - */ -public class DKGUserImplAbort extends DistributedKeyGenerationUserImpl { - - final int abortStage; - int stage; - public DKGUserImplAbort(DistributedKeyGeneration dkg, Network network, int abortStage) { - super(dkg, network); - this.abortStage = abortStage;// 1 - 2 - this.stage = 1; - } - - - private void sendAbort(){ - user.broadcast(DKGMessages.Mail.Type.ABORT,DKGMessages.EmptyMessage.getDefaultInstance()); - } - - @Override - protected void stage1() { - if(stage < abortStage) - super.stage1(); - else if(stage == abortStage){ - sendAbort(); - } - stage++; - } - - @Override - protected void stage2() { - if(stage < abortStage) - super.stage2(); - else if(stage == abortStage){ - sendAbort(); - } - stage++; - } - - @Override - protected void stage3() { - if(stage < abortStage) - super.stage3(); - else if(stage == abortStage){ - sendAbort(); - } - stage++; - } - - @Override - protected void stage4() { - if(stage < abortStage) - super.stage4(); - else if(stage == abortStage){ - sendAbort(); - } - stage++; - } -} +package JointFeldmanProtocol; + +import Communication.Network; +import meerkat.protobuf.DKGMessages; + +/** + * Created by Tzlil on 3/14/2016. + */ +public class DKGUserImplAbort extends DistributedKeyGenerationUserImpl { + + final int abortStage; + int stage; + public DKGUserImplAbort(DistributedKeyGeneration dkg, Network network, int abortStage) { + super(dkg, network); + this.abortStage = abortStage;// 1 - 2 + this.stage = 1; + } + + + private void sendAbort(){ + user.broadcast(DKGMessages.Mail.Type.ABORT,DKGMessages.EmptyMessage.getDefaultInstance()); + } + + @Override + protected void stage1() { + if(stage < abortStage) + super.stage1(); + else if(stage == abortStage){ + sendAbort(); + } + stage++; + } + + @Override + protected void stage2() { + if(stage < abortStage) + super.stage2(); + else if(stage == abortStage){ + sendAbort(); + } + stage++; + } + + @Override + protected void stage3() { + if(stage < abortStage) + super.stage3(); + else if(stage == abortStage){ + sendAbort(); + } + stage++; + } + + @Override + protected void stage4() { + if(stage < abortStage) + super.stage4(); + else if(stage == abortStage){ + sendAbort(); + } + stage++; + } +} diff --git a/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGMaliciousUserImpl.java b/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGMaliciousUserImpl.java index 9240dea..a0c1d4e 100644 --- a/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGMaliciousUserImpl.java +++ b/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGMaliciousUserImpl.java @@ -1,64 +1,61 @@ -package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; - -import Communication.Network; -import JointFeldmanProtocol.DistributedKeyGeneration; - -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Random; -import java.util.Set; - -/** - * Created by Tzlil on 3/29/2016. - */ -public class SDKGMaliciousUserImpl extends SecureDistributedKeyGenerationUserImpl { - - private final DistributedKeyGeneration maliciousSDKG; - private final Set falls; - public SDKGMaliciousUserImpl(SecureDistributedKeyGeneration sdkg,SecureDistributedKeyGeneration maliciousSDKG - , Network network,Set falls) { - super(sdkg, network); - this.falls = falls; - this.maliciousSDKG = maliciousSDKG; - maliciousSDKG.setParties(parties); - } - - public static SecureDistributedKeyGeneration generateMaliciousSDKG(SecureDistributedKeyGeneration sdkg,Random random){ - BigInteger q = sdkg.getQ(); - BigInteger zi = new BigInteger(q.bitLength(), random).mod(q); - return new SecureDistributedKeyGeneration(sdkg.getT(),sdkg.getN(),zi,random,sdkg.getQ() - ,sdkg.getGenerator(),sdkg.getH(),sdkg.getGroup(),sdkg.getId()); - } - - @Override - public void stage1() { - sdkg.broadcastVerificationValues(user); - //sdkg.sendSecrets(user); - sendSecrets(); //insteadof dkg.sendSecrets(user); - } - - @Override - public void stage3() { - stopReceiver(); - maliciousSDKG.answerAllComplainingPlayers(user); - } - - @Override - public void stage4(){ - //do nothing - } - - private void sendSecrets(){ - for (int j = 1; j <= n ; j++){ - if(j != id){ - if(falls.contains(j)){ - maliciousSDKG.sendSecret(user,j); - }else { - sdkg.sendSecret(user, j); - } - } - } - } - -} +package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; + +import Communication.Network; +import JointFeldmanProtocol.DistributedKeyGeneration; + +import java.math.BigInteger; +import java.util.Random; +import java.util.Set; + +/** + * Created by Tzlil on 3/29/2016. + */ +public class SDKGMaliciousUserImpl extends SecureDistributedKeyGenerationUserImpl { + + private final DistributedKeyGeneration maliciousSDKG; + private final Set falls; + public SDKGMaliciousUserImpl(SecureDistributedKeyGeneration sdkg,SecureDistributedKeyGeneration maliciousSDKG + , Network network,Set falls) { + super(sdkg, network); + this.falls = falls; + this.maliciousSDKG = maliciousSDKG; + maliciousSDKG.setParties(parties); + } + + public static SecureDistributedKeyGeneration generateMaliciousSDKG(SecureDistributedKeyGeneration sdkg,Random random){ + BigInteger q = sdkg.getQ(); + BigInteger zi = new BigInteger(q.bitLength(), random).mod(q); + return new SecureDistributedKeyGeneration(sdkg.getT(),sdkg.getN(),zi,random,sdkg.getQ() + ,sdkg.getGenerator(),sdkg.getH(),sdkg.getGroup(),sdkg.getId()); + } + + @Override + public void stage1() { + sdkg.broadcastVerificationValues(user); + sendSecrets(); //insteadof dkg.sendSecrets(user); + } + + @Override + public void stage3() { + stopReceiver(); + maliciousSDKG.answerAllComplainingPlayers(user); + } + + @Override + public void stage4(){ + //do nothing + } + + private void sendSecrets(){ + for (int j = 1; j <= n ; j++){ + if(j != id){ + if(falls.contains(j)){ + maliciousSDKG.sendSecret(user,j); + }else { + sdkg.sendSecret(user, j); + } + } + } + } + +} diff --git a/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGTest.java b/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGTest.java index 1b1b261..647e4cf 100644 --- a/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGTest.java +++ b/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGTest.java @@ -1,180 +1,177 @@ -package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; - -import Arithmetics.Arithmetic; -import Arithmetics.Fp; -import Communication.Network; -import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; -import JointFeldmanProtocol.DKGMaliciousUserImpl; -import JointFeldmanProtocol.DKGUserImplAbort; -import JointFeldmanProtocol.DistributedKeyGeneration; -import JointFeldmanProtocol.DistributedKeyGenerationUserImpl; -import ShamirSecretSharing.Polynomial; -import ShamirSecretSharing.SecretSharing; -import UserInterface.DistributedKeyGenerationUser; -import Utils.GenerateRandomPrime; -import org.factcenter.qilin.primitives.Group; -import org.factcenter.qilin.primitives.concrete.Zpstar; -import org.junit.Before; -import org.junit.Test; - -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Random; -import java.util.Set; - -/** - * Created by Tzlil on 3/29/2016. - */ -public class SDKGTest { - - int tests = 10; - BigInteger p = GenerateRandomPrime.SafePrime100Bits; - BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); - Group group = new Zpstar(p); - Arithmetic arithmetic = new Fp(q); - int t = 9; - int n = 20; - Testable[] testables; - - @Before - public void settings(){ - 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++){ - testable.threads[i].start(); - } - 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){ - assert (testable.sdkgs[i - 1].getPublicValue().equals(publicValue)); - } - - // assert valid verification values - BigInteger expected,verification; - for (int i: testable.valids){ - expected = group.multiply(testable.g, testable.sdkgs[i - 1].getShare().y); - verification = VerifiableSecretSharing.verify(i, testable.sdkgs[i - 1].getCommitments(), group); - assert (expected.equals(verification)); - } - - - // restore the secret from shares - ArrayList sharesList = new ArrayList(); - - for (int i: testable.valids){ - sharesList.add(testable.sdkgs[i - 1].getShare()); - } - Polynomial.Point[] shares = new Polynomial.Point[sharesList.size()]; - for (int i = 0; i < shares.length; i ++){ - shares[i] = sharesList.get(i); - } - - BigInteger calculatedSecret = SecretSharing.restoreSecret(shares,arithmetic); - assert (calculatedSecret.equals(testable.secret)); - } - - @Test - public void test() throws Exception { - for (int i = 0; i < tests; i++){ - oneTest(i); - } - } - - class Testable{ - Set valids; - Set QUAL; - Set aborted; - Set malicious; - DistributedKeyGenerationUser[] sdkgs; - Thread[] threads; - BigInteger g; - BigInteger h; - BigInteger secret; - - public Testable(Random random) { - this.sdkgs = new SecureDistributedKeyGenerationUserImpl[n]; - this.valids = new HashSet(); - this.QUAL = new HashSet(); - this.aborted = new HashSet(); - this.malicious = new HashSet(); - this.threads = new Thread[n]; - this.g = sampleGenerator(random); - this.h = group.multiply(g,randomIntModQ(random)); - ArrayList ids = new ArrayList(); - for (int id = 1; id<= n ; id++){ - ids.add(id); - } - Network network = new Network(n); - int id; - BigInteger s; - SecureDistributedKeyGeneration sdkg; - this.secret = BigInteger.ZERO; - while (!ids.isEmpty()) { - id = ids.remove(random.nextInt(ids.size())); - s = randomIntModQ(random); - sdkg = new SecureDistributedKeyGeneration(t, n, s, random, q, g , h, group, id); - sdkgs[id - 1] = randomSDKGUser(id,network,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); - }else{ - int type = random.nextInt(3); - switch (type){ - case 0:// regular - valids.add(id); - QUAL.add(id); - return new SecureDistributedKeyGenerationUserImpl(sdkg,network); - case 1:// abort - int abortStage = random.nextInt(3) + 1; // 1 or 2 or 3 - aborted.add(id); - if (abortStage > 1){ - QUAL.add(id); - } - return new SDKGUserImplAbort(sdkg,network,abortStage); - case 2:// malicious - malicious.add(id); - Set falls = DKGMaliciousUserImpl.selectFallsRandomly(valids,random); - SecureDistributedKeyGeneration maliciousSDKG = SDKGMaliciousUserImpl.generateMaliciousSDKG(sdkg,random); - return new SDKGMaliciousUserImpl(sdkg,maliciousSDKG,network,falls); - default: - return null; - } - } - } - - public BigInteger sampleGenerator(Random random){ - BigInteger ZERO = group.zero(); - BigInteger g; - do { - g = group.sample(random); - } while (!g.equals(ZERO) && !group.multiply(g, q).equals(ZERO)); - return g; - } - - public BigInteger randomIntModQ(Random random){ - return new BigInteger(q.bitLength(), random).mod(q); - } - - } -} +package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; + +import Arithmetics.Arithmetic; +import Arithmetics.Fp; +import Communication.Network; +import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; +import JointFeldmanProtocol.DKGMaliciousUserImpl; +import ShamirSecretSharing.Polynomial; +import ShamirSecretSharing.SecretSharing; +import UserInterface.DistributedKeyGenerationUser; +import Utils.GenerateRandomPrime; +import org.factcenter.qilin.primitives.Group; +import org.factcenter.qilin.primitives.concrete.Zpstar; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Random; +import java.util.Set; + +/** + * Created by Tzlil on 3/29/2016. + */ +public class SDKGTest { + + int tests = 10; + BigInteger p = GenerateRandomPrime.SafePrime100Bits; + BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); + Group group = new Zpstar(p); + Arithmetic arithmetic = new Fp(q); + int t = 9; + int n = 20; + Testable[] testables; + + @Before + public void settings(){ + 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++){ + testable.threads[i].start(); + } + 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){ + assert (testable.sdkgs[i - 1].getPublicValue().equals(publicValue)); + } + + // assert valid verification values + BigInteger expected,verification; + for (int i: testable.valids){ + 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 sharesList = new ArrayList(); + + for (int i: testable.valids){ + sharesList.add(testable.sdkgs[i - 1].getShare()); + } + 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)); + } + + @Test + public void test() throws Exception { + for (int i = 0; i < tests; i++){ + oneTest(i); + } + } + + class Testable{ + Set valids; + Set QUAL; + Set aborted; + Set malicious; + DistributedKeyGenerationUser[] sdkgs; + Thread[] threads; + BigInteger g; + BigInteger h; + BigInteger secret; + + public Testable(Random random) { + this.sdkgs = new SecureDistributedKeyGenerationUserImpl[n]; + this.valids = new HashSet(); + this.QUAL = new HashSet(); + this.aborted = new HashSet(); + this.malicious = new HashSet(); + this.threads = new Thread[n]; + this.g = sampleGenerator(random); + this.h = group.multiply(g,randomIntModQ(random)); + ArrayList ids = new ArrayList(); + for (int id = 1; id<= n ; id++){ + ids.add(id); + } + Network network = new Network(n); + int id; + BigInteger s; + SecureDistributedKeyGeneration sdkg; + this.secret = BigInteger.ZERO; + while (!ids.isEmpty()) { + id = ids.remove(random.nextInt(ids.size())); + s = randomIntModQ(random); + sdkg = new SecureDistributedKeyGeneration(t, n, s, random, q, g , h, group, id); + sdkgs[id - 1] = randomSDKGUser(id,network,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); + }else{ + int type = random.nextInt(3); + switch (type){ + case 0:// regular + valids.add(id); + QUAL.add(id); + return new SecureDistributedKeyGenerationUserImpl(sdkg,network); + case 1:// abort + int abortStage = random.nextInt(3) + 1; // 1 or 2 or 3 + aborted.add(id); + if (abortStage > 1){ + QUAL.add(id); + } + return new SDKGUserImplAbort(sdkg,network,abortStage); + case 2:// malicious + malicious.add(id); + Set falls = DKGMaliciousUserImpl.selectFallsRandomly(valids,random); + SecureDistributedKeyGeneration maliciousSDKG = SDKGMaliciousUserImpl.generateMaliciousSDKG(sdkg,random); + return new SDKGMaliciousUserImpl(sdkg,maliciousSDKG,network,falls); + default: + return null; + } + } + } + + public BigInteger sampleGenerator(Random random){ + BigInteger ZERO = group.zero(); + BigInteger g; + do { + g = group.sample(random); + } while (!g.equals(ZERO) && !group.multiply(g, q).equals(ZERO)); + return g; + } + + public BigInteger randomIntModQ(Random random){ + return new BigInteger(q.bitLength(), random).mod(q); + } + + } +} diff --git a/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGUserImplAbort.java b/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGUserImplAbort.java index c2a6fbe..551de93 100644 --- a/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGUserImplAbort.java +++ b/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGUserImplAbort.java @@ -1,65 +1,65 @@ -package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; - -import Communication.Network; -import SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem.SecureDistributedKeyGeneration; -import SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem.SecureDistributedKeyGenerationUserImpl; -import meerkat.protobuf.DKGMessages; - -/** - * Created by Tzlil on 3/14/2016. - */ -public class SDKGUserImplAbort extends SecureDistributedKeyGenerationUserImpl { - - final int abortStage; - int stage; - public SDKGUserImplAbort(SecureDistributedKeyGeneration sdkg, Network network, int abortStage) { - super(sdkg, network); - this.abortStage = abortStage;// 1 - 4 - this.stage = 1; - } - - private void abort(){ - stopReceiver(); - user.broadcast(DKGMessages.Mail.Type.ABORT,DKGMessages.EmptyMessage.getDefaultInstance()); - } - - @Override - protected void stage1() { - if(stage < abortStage) - super.stage1(); - else if(stage == abortStage){ - abort(); - } - stage++; - } - - @Override - protected void stage2() { - if(stage < abortStage) - super.stage2(); - else if(stage == abortStage){ - abort(); - } - stage++; - } - - @Override - protected void stage3() { - if(stage < abortStage) - super.stage3(); - else if(stage == abortStage){ - abort(); - } - stage++; - } - - @Override - protected void stage4() { - if(stage < abortStage) - super.stage4(); - else if(stage == abortStage){ - abort(); - } - stage++; - } -} +package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; + +import Communication.Network; +import SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem.SecureDistributedKeyGeneration; +import SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem.SecureDistributedKeyGenerationUserImpl; +import meerkat.protobuf.DKGMessages; + +/** + * Created by Tzlil on 3/14/2016. + */ +public class SDKGUserImplAbort extends SecureDistributedKeyGenerationUserImpl { + + final int abortStage; + int stage; + public SDKGUserImplAbort(SecureDistributedKeyGeneration sdkg, Network network, int abortStage) { + super(sdkg, network); + this.abortStage = abortStage;// 1 - 4 + this.stage = 1; + } + + private void abort(){ + stopReceiver(); + user.broadcast(DKGMessages.Mail.Type.ABORT,DKGMessages.EmptyMessage.getDefaultInstance()); + } + + @Override + protected void stage1() { + if(stage < abortStage) + super.stage1(); + else if(stage == abortStage){ + abort(); + } + stage++; + } + + @Override + protected void stage2() { + if(stage < abortStage) + super.stage2(); + else if(stage == abortStage){ + abort(); + } + stage++; + } + + @Override + protected void stage3() { + if(stage < abortStage) + super.stage3(); + else if(stage == abortStage){ + abort(); + } + stage++; + } + + @Override + protected void stage4() { + if(stage < abortStage) + super.stage4(); + else if(stage == abortStage){ + abort(); + } + stage++; + } +} diff --git a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/AddTest.java b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/AddTest.java index fe4e602..a95552d 100644 --- a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/AddTest.java +++ b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/AddTest.java @@ -1,46 +1,46 @@ -package ShamirSecretSharing.PolynomialTests; -import Arithmetics.Z; -import Utils.GenerateRandomPolynomial; -import ShamirSecretSharing.Polynomial; -import org.junit.Before; -import org.junit.Test; - -import java.math.BigInteger; -import java.util.Random; - -/** - * Created by Tzlil on 1/27/2016. - */ -public class AddTest { - - Polynomial[] arr1; - Polynomial[] arr2; - int tests = 1 << 12; - int maxDegree = 15; - int bits = 128; - Random random; - - @Before - public void settings(){ - random = new Random(); - arr1 = new Polynomial[tests]; - arr2 = new Polynomial[tests]; - for (int i = 0; i < arr1.length; i++){ - arr1[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){ - Polynomial sum = p1.add(p2); - BigInteger x = new BigInteger(bits,random); - assert(sum.image(x).equals(p1.image(x).add(p2.image(x)))); - } - - @Test - public void addTest(){ - for (int i = 0 ; i < arr1.length; i ++){ - oneTest(arr1[i],arr2[i]); - } - } -} +package ShamirSecretSharing.PolynomialTests; +import Arithmetics.Z; +import Utils.GenerateRandomPolynomial; +import ShamirSecretSharing.Polynomial; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/27/2016. + */ +public class AddTest { + + Polynomial[] arr1; + Polynomial[] arr2; + int tests = 1 << 12; + int maxDegree = 15; + int bits = 128; + Random random; + + @Before + public void settings(){ + random = new Random(); + arr1 = new Polynomial[tests]; + arr2 = new Polynomial[tests]; + for (int i = 0; i < arr1.length; i++){ + arr1[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){ + Polynomial sum = p1.add(p2); + BigInteger x = new BigInteger(bits,random); + assert(sum.evaluate(x).equals(p1.evaluate(x).add(p2.evaluate(x)))); + } + + @Test + public void addTest(){ + for (int i = 0 ; i < arr1.length; i ++){ + oneTest(arr1[i],arr2[i]); + } + } +} diff --git a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/InterpolationTest.java b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/InterpolationTest.java index 97f1b8d..a222b95 100644 --- a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/InterpolationTest.java +++ b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/InterpolationTest.java @@ -1,68 +1,68 @@ -package ShamirSecretSharing.PolynomialTests; - -import Arithmetics.Arithmetic; -import Arithmetics.Fp; -import Utils.GenerateRandomPolynomial; -import ShamirSecretSharing.Polynomial; -import Utils.GenerateRandomPrime; -import org.junit.Before; -import org.junit.Test; - -import java.math.BigInteger; -import java.util.HashSet; -import java.util.Random; -import java.util.Set; - -/** - * Created by Tzlil on 1/27/2016. - */ -public class InterpolationTest { - Polynomial[] polynomials; - int tests = 1 << 10; - int maxDegree = 15; - int bits = 128; - Random random; - Polynomial.Point[][] pointsArrays; - Arithmetic arithmetic; - BigInteger p = GenerateRandomPrime.SafePrime100Bits; - - @Before - public void settings(){ - random = new Random(); - polynomials = new Polynomial[tests]; - pointsArrays = new Polynomial.Point[tests][]; - for (int i = 0; i < polynomials.length; 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){ - Polynomial.Point[] points = new Polynomial.Point[polynomial.getDegree() + 1]; - BigInteger x; - Set set = new HashSet(); - for (int i = 0; i < points.length; i++){ - x = new BigInteger(bits,random).mod(p); - if(set.contains(x)){ - i--; - continue; - } - set.add(x); - points[i] = new Polynomial.Point(x,polynomial); - } - return points; - } - - public void oneTest(Polynomial p, Polynomial.Point[] points) throws Exception { - Polynomial interpolation = Polynomial.interpolation(points,arithmetic); - assert (p.compareTo(interpolation) == 0); - } - - @Test - public void interpolationTest() throws Exception { - for (int i = 0; i < polynomials.length; i ++){ - oneTest(polynomials[i],pointsArrays[i]); - } - } -} +package ShamirSecretSharing.PolynomialTests; + +import Arithmetics.Arithmetic; +import Arithmetics.Fp; +import Utils.GenerateRandomPolynomial; +import ShamirSecretSharing.Polynomial; +import Utils.GenerateRandomPrime; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.HashSet; +import java.util.Random; +import java.util.Set; + +/** + * Created by Tzlil on 1/27/2016. + */ +public class InterpolationTest { + Polynomial[] polynomials; + int tests = 1 << 10; + int maxDegree = 15; + int bits = 128; + Random random; + Polynomial.Point[][] pointsArrays; + Arithmetic arithmetic; + BigInteger p = GenerateRandomPrime.SafePrime100Bits; + + @Before + public void settings(){ + random = new Random(); + polynomials = new Polynomial[tests]; + pointsArrays = new Polynomial.Point[tests][]; + for (int i = 0; i < polynomials.length; 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){ + Polynomial.Point[] points = new Polynomial.Point[polynomial.getDegree() + 1]; + BigInteger x; + Set set = new HashSet(); + for (int i = 0; i < points.length; i++){ + x = new BigInteger(bits,random).mod(p); + if(set.contains(x)){ + i--; + continue; + } + set.add(x); + points[i] = new Polynomial.Point(x,polynomial); + } + return points; + } + + public void oneTest(Polynomial p, Polynomial.Point[] points) throws Exception { + Polynomial interpolation = Polynomial.interpolation(points,arithmetic); + assert (p.compareTo(interpolation) == 0); + } + + @Test + public void interpolationTest() throws Exception { + for (int i = 0; i < polynomials.length; i ++){ + oneTest(polynomials[i],pointsArrays[i]); + } + } +} diff --git a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulByConstTest.java b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulByConstTest.java index 3a3bf1a..2f073c5 100644 --- a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulByConstTest.java +++ b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulByConstTest.java @@ -1,48 +1,48 @@ -package ShamirSecretSharing.PolynomialTests; - -import Arithmetics.Z; -import Utils.GenerateRandomPolynomial; -import ShamirSecretSharing.Polynomial; -import org.junit.Before; -import org.junit.Test; - -import java.math.BigInteger; -import java.util.Random; - -/** - * Created by Tzlil on 1/27/2016. - */ -public class MulByConstTest { - - - Polynomial[] arr1; - BigInteger[] arr2; - int tests = 1 << 12; - int maxDegree = 15; - int bits = 128; - Random random; - - @Before - public void settings(){ - random = new Random(); - arr1 = new Polynomial[tests]; - arr2 = new BigInteger[tests]; - for (int i = 0; i < arr1.length; i++){ - arr1[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,new Z()); - arr2[i] = new BigInteger(bits,random); - } - } - - public void oneTest(Polynomial p, BigInteger c){ - Polynomial product = p.mul(c); - BigInteger x = new BigInteger(bits,random); - assert(product.image(x).equals(p.image(x).multiply(c))); - } - - @Test - public void mulByConstTest(){ - for (int i = 0 ; i < arr1.length; i ++){ - oneTest(arr1[i],arr2[i]); - } - } -} +package ShamirSecretSharing.PolynomialTests; + +import Arithmetics.Z; +import Utils.GenerateRandomPolynomial; +import ShamirSecretSharing.Polynomial; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/27/2016. + */ +public class MulByConstTest { + + + Polynomial[] arr1; + BigInteger[] arr2; + int tests = 1 << 12; + int maxDegree = 15; + int bits = 128; + Random random; + + @Before + public void settings(){ + random = new Random(); + arr1 = new Polynomial[tests]; + arr2 = new BigInteger[tests]; + for (int i = 0; i < arr1.length; i++){ + arr1[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,new Z()); + arr2[i] = new BigInteger(bits,random); + } + } + + public void oneTest(Polynomial p, BigInteger c){ + Polynomial product = p.mul(c); + BigInteger x = new BigInteger(bits,random); + assert(product.evaluate(x).equals(p.evaluate(x).multiply(c))); + } + + @Test + public void mulByConstTest(){ + for (int i = 0 ; i < arr1.length; i ++){ + oneTest(arr1[i],arr2[i]); + } + } +} diff --git a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulTest.java b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulTest.java index a7dd365..478e541 100644 --- a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulTest.java +++ b/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulTest.java @@ -1,48 +1,48 @@ -package ShamirSecretSharing.PolynomialTests; - -import Arithmetics.Z; -import Utils.GenerateRandomPolynomial; -import ShamirSecretSharing.Polynomial; -import org.junit.Before; -import org.junit.Test; - -import java.math.BigInteger; -import java.util.Random; - -/** - * Created by Tzlil on 1/27/2016. - */ -public class MulTest { - - - Polynomial[] arr1; - Polynomial[] arr2; - int tests = 1 << 12; - int maxDegree = 15; - int bits = 128; - Random random; - - @Before - public void settings(){ - random = new Random(); - arr1 = new Polynomial[tests]; - arr2 = new Polynomial[tests]; - for (int i = 0; i < arr1.length; i++){ - arr1[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){ - Polynomial product = p1.mul(p2); - BigInteger x = new BigInteger(bits,random); - assert(product.image(x).equals(p1.image(x).multiply(p2.image(x)))); - } - - @Test - public void mulTest(){ - for (int i = 0 ; i < arr1.length; i ++){ - oneTest(arr1[i],arr2[i]); - } - } -} +package ShamirSecretSharing.PolynomialTests; + +import Arithmetics.Z; +import Utils.GenerateRandomPolynomial; +import ShamirSecretSharing.Polynomial; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/27/2016. + */ +public class MulTest { + + + Polynomial[] arr1; + Polynomial[] arr2; + int tests = 1 << 12; + int maxDegree = 15; + int bits = 128; + Random random; + + @Before + public void settings(){ + random = new Random(); + arr1 = new Polynomial[tests]; + arr2 = new Polynomial[tests]; + for (int i = 0; i < arr1.length; i++){ + arr1[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){ + Polynomial product = p1.mul(p2); + BigInteger x = new BigInteger(bits,random); + assert(product.evaluate(x).equals(p1.evaluate(x).multiply(p2.evaluate(x)))); + } + + @Test + public void mulTest(){ + for (int i = 0 ; i < arr1.length; i ++){ + oneTest(arr1[i],arr2[i]); + } + } +} diff --git a/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java b/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java index a74148f..40cf306 100644 --- a/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java +++ b/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java @@ -1,63 +1,63 @@ -package ShamirSecretSharing; - -import Arithmetics.Z; -import Utils.GenerateRandomPrime; -import org.factcenter.qilin.primitives.CyclicGroup; -import org.factcenter.qilin.primitives.concrete.Zn; -import org.junit.Before; -import org.junit.Test; - -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -/** - * Created by Tzlil on 1/29/2016. - */ -public class SecretSharingTest { - - SecretSharing[] secretSharingArray; - BigInteger[] secrets; - CyclicGroup group; - int tests = 1 << 10; - Random random; - - @Before - public void settings(){ - BigInteger p = GenerateRandomPrime.SafePrime100Bits; - BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); - group = new Zn(p); - int t = 9; - int n = 20; - random = new Random(); - secretSharingArray = new SecretSharing[tests]; - secrets = new BigInteger[tests]; - - for (int i = 0; i < secretSharingArray.length; i++){ - secrets[i] = group.sample(random); - secretSharingArray[i] = new SecretSharing(t,n,secrets[i],random,q); - } - } - - public void oneTest(SecretSharing secretSharing, BigInteger secret) throws Exception { - int t = secretSharing.getT(); - int n = secretSharing.getN(); - Polynomial.Point[] shares = new Polynomial.Point[t + 1]; - List indexes = new ArrayList(n); - for (int i = 1 ; i <= n; i ++){ - indexes.add(i); - } - for (int i = 0 ; i < shares.length ; i++){ - shares[i] = secretSharing.getShare(indexes.remove(random.nextInt(indexes.size()))); - } - assert(secret.equals(SecretSharing.restoreSecret(shares,new Z()))); - } - - @Test - public void secretSharingTest() throws Exception { - for (int i = 0 ; i < secretSharingArray.length; i ++){ - oneTest(secretSharingArray[i],secrets[i]); - } - } -} +package ShamirSecretSharing; + +import Arithmetics.Z; +import Utils.GenerateRandomPrime; +import org.factcenter.qilin.primitives.CyclicGroup; +import org.factcenter.qilin.primitives.concrete.Zn; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +/** + * Created by Tzlil on 1/29/2016. + */ +public class SecretSharingTest { + + SecretSharing[] secretSharingArray; + BigInteger[] secrets; + CyclicGroup group; + int tests = 1 << 10; + Random random; + + @Before + public void settings(){ + BigInteger p = GenerateRandomPrime.SafePrime100Bits; + BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); + group = new Zn(p); + int t = 9; + int n = 20; + random = new Random(); + secretSharingArray = new SecretSharing[tests]; + secrets = new BigInteger[tests]; + + for (int i = 0; i < secretSharingArray.length; i++){ + secrets[i] = group.sample(random); + secretSharingArray[i] = new SecretSharing(t,n,secrets[i],random,q); + } + } + + public void oneTest(SecretSharing secretSharing, BigInteger secret) throws Exception { + int t = secretSharing.getT(); + int n = secretSharing.getN(); + Polynomial.Point[] shares = new Polynomial.Point[t + 1]; + List indexes = new ArrayList(n); + for (int i = 1 ; i <= n; i ++){ + indexes.add(i); + } + for (int i = 0 ; i < shares.length ; i++){ + shares[i] = secretSharing.getShare(indexes.remove(random.nextInt(indexes.size()))); + } + assert(secret.equals(SecretSharing.recoverSecret(shares,new Z()))); + } + + @Test + public void secretSharingTest() throws Exception { + for (int i = 0 ; i < secretSharingArray.length; i ++){ + oneTest(secretSharingArray[i],secrets[i]); + } + } +} diff --git a/destributed-key-generation/src/test/java/Utils/GenerateRandomPolynomial.java b/destributed-key-generation/src/test/java/Utils/GenerateRandomPolynomial.java index d59d051..4ca7b6a 100644 --- a/destributed-key-generation/src/test/java/Utils/GenerateRandomPolynomial.java +++ b/destributed-key-generation/src/test/java/Utils/GenerateRandomPolynomial.java @@ -1,31 +1,31 @@ -package Utils; - -import Arithmetics.Arithmetic; -import Arithmetics.Fp; -import ShamirSecretSharing.Polynomial; - -import java.math.BigInteger; -import java.util.Random; - -/** - * Created by Tzlil on 1/27/2016. - */ -public class GenerateRandomPolynomial { - - public static Polynomial generateRandomPolynomial(int degree, int bits, Random random,Arithmetic arithmetic) { - BigInteger[] coefficients = new BigInteger[degree + 1]; - - for (int i = 0 ; i <= degree; i++ ){ - coefficients[i] = new BigInteger(bits,random); // sample from Zp [0,... q-1] - } - return new Polynomial(coefficients,arithmetic); - } - - public static Polynomial generateRandomPolynomial(int degree,int bits,Random random,BigInteger p) { - BigInteger[] coefficients = generateRandomPolynomial(degree,bits,random,new Fp(p)).getCoefficients(); - for (int i = 0; i arithmetic) { + BigInteger[] coefficients = new BigInteger[degree + 1]; + + for (int i = 0 ; i <= degree; i++ ){ + coefficients[i] = new BigInteger(bits,random); // sample from Zp [0,... q-1] + } + return new Polynomial(coefficients,arithmetic); + } + + public static Polynomial generateRandomPolynomial(int degree,int bits,Random random,BigInteger p) { + BigInteger[] coefficients = generateRandomPolynomial(degree,bits,random,new Fp(p)).getCoefficients(); + for (int i = 0; i - - def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java" - - // add protobuf generated sources to generated source dir. - if ("test".equals(sourceSet.name)) { - testSourceDirs += file(srcDir) - } else { - sourceDirs += file(srcDir) - } - generatedSourceDirs += file(srcDir) - - } - - // Don't exclude build directory - excludeDirs -= file(buildDir) - } -} - -/*=================================== - * "Fat" Build targets - *===================================*/ - - -task mavenCapsule(type: MavenCapsule){ - description = "Generate a capsule jar that automatically downloads and caches dependencies when run." - applicationClass mainClassName - destinationDir = buildDir -} - -task fatCapsule(type: FatCapsule){ - description = "Generate a single capsule jar containing everything. Use -Pfatmain=... to override main class" - - destinationDir = buildDir - - def fatMain = hasProperty('fatmain') ? fatmain : mainClassName - - applicationClass fatMain - - def testJar = hasProperty('test') - - if (hasProperty('fatmain')) { - appendix = "fat-${fatMain}" - } else { - appendix = "fat" - } - - if (testJar) { - from sourceSets.test.output - } -} - -/*=================================== - * Repositories - *===================================*/ - -repositories { - - mavenLocal(); - - // Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral) - maven { - url nexusRepository - - if (isSnapshot) { - credentials { username - password - - username nexusUser - password nexusPassword - } - } - } - - // Use 'maven central' for other dependencies. - mavenCentral() -} - -task "info" << { - println "Project: ${project.name}" -println "Description: ${project.description}" - println "--------------------------" - println "GroupId: $groupId" - println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})" - println "" -} -info.description 'Print some information about project parameters' - - -/*=================================== - * Publishing - *===================================*/ - -publishing { - publications { - mavenJava(MavenPublication) { - groupId project.groupId - pom.withXml { - asNode().appendNode('description', project.description) - } - from project.components.java - - } - } - repositories { - maven { - url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}" - credentials { username - password - - username nexusUser - password nexusPassword - } - } - } -} - - - + +plugins { + id "us.kirchmeier.capsule" version "1.0.1" + id 'com.google.protobuf' version '0.7.0' +} + +apply plugin: 'java' +apply plugin: 'com.google.protobuf' +apply plugin: 'eclipse' +apply plugin: 'idea' + +apply plugin: 'application' + +apply plugin: 'maven-publish' + +mainClassName='Demo' + +// Is this a snapshot version? +ext { isSnapshot = false } + +ext { + groupId = 'org.factcenter.meerkat' + nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/" + + // Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing) + // Should be set in ${HOME}/.gradle/gradle.properties + nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : "" + nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : "" +} + +description = "Meerkat Voting Common Library" + +// Your project version +version = "0.0" + +version += "${isSnapshot ? '-SNAPSHOT' : ''}" + + +dependencies { + // Logging + compile 'org.slf4j:slf4j-api:1.7.7' + runtime 'ch.qos.logback:logback-classic:1.1.2' + runtime 'ch.qos.logback:logback-core:1.1.2' + + // Google protobufs + compile 'com.google.protobuf:protobuf-java:3.+' + + // ListeningExecutor + compile 'com.google.guava:guava:11.0.+' + + // Crypto + compile 'org.factcenter.qilin:qilin:1.2+' + compile 'org.bouncycastle:bcprov-jdk15on:1.53' + + testCompile 'junit:junit:4.+' + + runtime 'org.codehaus.groovy:groovy:2.4.+' +} + + +/*==== You probably don't have to edit below this line =======*/ + + +// Setup test configuration that can appear as a dependency in +// other subprojects +configurations { + testOutput.extendsFrom (testCompile) +} + +task testJar(type: Jar, dependsOn: testClasses) { + classifier = 'tests' + from sourceSets.test.output +} + +artifacts { + testOutput testJar +} + + + +// The run task added by the application plugin +// is also of type JavaExec. +tasks.withType(JavaExec) { + // Assign all Java system properties from + // the command line to the JavaExec task. + systemProperties System.properties +} + + +protobuf { + // Configure the protoc executable + protoc { + // Download from repositories + artifact = 'com.google.protobuf:protoc:3.+' + } +} + +idea { + module { + project.sourceSets.each { sourceSet -> + + def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java" + + // add protobuf generated sources to generated source dir. + if ("test".equals(sourceSet.name)) { + testSourceDirs += file(srcDir) + } else { + sourceDirs += file(srcDir) + } + generatedSourceDirs += file(srcDir) + + } + + // Don't exclude build directory + excludeDirs -= file(buildDir) + } +} + +/*=================================== + * "Fat" Build targets + *===================================*/ + + +task mavenCapsule(type: MavenCapsule){ + description = "Generate a capsule jar that automatically downloads and caches dependencies when run." + applicationClass mainClassName + destinationDir = buildDir +} + +task fatCapsule(type: FatCapsule){ + description = "Generate a single capsule jar containing everything. Use -Pfatmain=... to override main class" + + destinationDir = buildDir + + def fatMain = hasProperty('fatmain') ? fatmain : mainClassName + + applicationClass fatMain + + def testJar = hasProperty('test') + + if (hasProperty('fatmain')) { + appendix = "fat-${fatMain}" + } else { + appendix = "fat" + } + + if (testJar) { + from sourceSets.test.output + } +} + +/*=================================== + * Repositories + *===================================*/ + +repositories { + + mavenLocal(); + + // Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral) + maven { + url nexusRepository + + if (isSnapshot) { + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } + + // Use 'maven central' for other dependencies. + mavenCentral() +} + +task "info" << { + println "Project: ${project.name}" +println "Description: ${project.description}" + println "--------------------------" + println "GroupId: $groupId" + println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})" + println "" +} +info.description 'Print some information about project parameters' + + +/*=================================== + * Publishing + *===================================*/ + +publishing { + publications { + mavenJava(MavenPublication) { + groupId project.groupId + pom.withXml { + asNode().appendNode('description', project.description) + } + from project.components.java + + } + } + repositories { + maven { + url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}" + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } +} + + + diff --git a/meerkat-common/src/main/java/Demo.java b/meerkat-common/src/main/java/Demo.java index 130adcc..9f5f379 100644 --- a/meerkat-common/src/main/java/Demo.java +++ b/meerkat-common/src/main/java/Demo.java @@ -1,29 +1,29 @@ -import com.google.protobuf.ByteString; -import static meerkat.protobuf.BulletinBoardAPI.*; -import java.io.IOException; - -/** - * Created by talm on 10/26/15. - */ -public class Demo { - public static void main(String args[]) { - System.out.println("Nothing to see yet"); - - BulletinBoardMessage msg; - - UnsignedBulletinBoardMessage msgContents = UnsignedBulletinBoardMessage.newBuilder() - .addTag("test") - .setData(ByteString.copyFromUtf8("some data")) - .build(); - - msg = BulletinBoardMessage.newBuilder() - .setMsg(msgContents) - .build(); - - try { - msg.writeTo(System.err); - } catch (IOException e) { - // Ignore - } - } -} +import com.google.protobuf.ByteString; +import static meerkat.protobuf.BulletinBoardAPI.*; +import java.io.IOException; + +/** + * Created by talm on 10/26/15. + */ +public class Demo { + public static void main(String args[]) { + System.out.println("Nothing to see yet"); + + BulletinBoardMessage msg; + + UnsignedBulletinBoardMessage msgContents = UnsignedBulletinBoardMessage.newBuilder() + .addTag("test") + .setData(ByteString.copyFromUtf8("some data")) + .build(); + + msg = BulletinBoardMessage.newBuilder() + .setMsg(msgContents) + .build(); + + try { + msg.writeTo(System.err); + } catch (IOException e) { + // Ignore + } + } +} diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardClient.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardClient.java index c51e561..c3c875c 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardClient.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardClient.java @@ -1,54 +1,54 @@ -package meerkat.bulletinboard; - -import meerkat.comm.*; -import meerkat.protobuf.Voting.*; - -import static meerkat.protobuf.BulletinBoardAPI.*; - -import java.util.List; - -/** - * Created by talm on 24/10/15. - */ -public interface BulletinBoardClient { - - interface ClientCallback { - void handleCallback(T msg); - void handleFailure(Throwable t); - } - - /** - * Initialize the client to use some specified servers - * @param clientParams contains the parameters required for the client setup - */ - void init(BulletinBoardClientParams clientParams); - - /** - * Post a message to the bulletin board - * @param msg - */ - MessageID postMessage(BulletinBoardMessage msg, ClientCallback callback); - - /** - * Check how "safe" a given message is - * @param id - * @return a normalized "redundancy score" from 0 (local only) to 1 (fully published) - */ - void getRedundancy(MessageID id, ClientCallback callback); - - /** - * Read all messages posted matching the given filter - * Note that if messages haven't been "fully posted", this might return a different - * set of messages in different calls. However, messages that are fully posted - * are guaranteed to be included. - * @param filterList return only messages that match the filters (null means no filtering). - */ - void readMessages(MessageFilterList filterList, ClientCallback> callback); - - /** - * Closes all connections, if any. - * This is done in a synchronous (blocking) way. - */ - void close(); - -} +package meerkat.bulletinboard; + +import meerkat.comm.*; +import meerkat.protobuf.Voting.*; + +import static meerkat.protobuf.BulletinBoardAPI.*; + +import java.util.List; + +/** + * Created by talm on 24/10/15. + */ +public interface BulletinBoardClient { + + interface ClientCallback { + void handleCallback(T msg); + void handleFailure(Throwable t); + } + + /** + * Initialize the client to use some specified servers + * @param clientParams contains the parameters required for the client setup + */ + void init(BulletinBoardClientParams clientParams); + + /** + * Post a message to the bulletin board + * @param msg + */ + MessageID postMessage(BulletinBoardMessage msg, ClientCallback callback); + + /** + * Check how "safe" a given message is + * @param id + * @return a normalized "redundancy score" from 0 (local only) to 1 (fully published) + */ + void getRedundancy(MessageID id, ClientCallback callback); + + /** + * Read all messages posted matching the given filter + * Note that if messages haven't been "fully posted", this might return a different + * set of messages in different calls. However, messages that are fully posted + * are guaranteed to be included. + * @param filterList return only messages that match the filters (null means no filtering). + */ + void readMessages(MessageFilterList filterList, ClientCallback> callback); + + /** + * Closes all connections, if any. + * This is done in a synchronous (blocking) way. + */ + void close(); + +} diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java index da53c1f..741cb61 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java @@ -1,42 +1,42 @@ -package meerkat.bulletinboard; - -import meerkat.comm.CommunicationException; -import meerkat.protobuf.BulletinBoardAPI.*; - -/** - * Created by Arbel on 07/11/15. - * - * This interface refers to a single instance of a Bulletin Board. - * An implementation of this interface may use any DB and be hosted on any machine. - */ - -public interface BulletinBoardServer{ - - /** - * This method initializes the server by reading the signature data and storing it. - * It also establishes the connection to the DB. - * @throws CommunicationException on DB connection error. - */ - public void init(String meerkatDB) throws CommunicationException; - - /** - * Post a message to bulletin board. - * @param msg is the actual (signed) message - * @return TRUE if the message has been authenticated and FALSE otherwise (in ProtoBuf form). - * @throws CommunicationException on DB connection error. - */ - public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException; - - /** - * Read all messages posted matching the given filter. - * @param filter return only messages that match the filter (empty list means no filtering). - * @return - */ - BulletinBoardMessageList readMessages(MessageFilterList filterList) throws CommunicationException; - - /** - * This method closes the connection to the DB. - * @throws CommunicationException on DB connection error. - */ - public void close() throws CommunicationException; -} +package meerkat.bulletinboard; + +import meerkat.comm.CommunicationException; +import meerkat.protobuf.BulletinBoardAPI.*; + +/** + * Created by Arbel on 07/11/15. + * + * This interface refers to a single instance of a Bulletin Board. + * An implementation of this interface may use any DB and be hosted on any machine. + */ + +public interface BulletinBoardServer{ + + /** + * This method initializes the server by reading the signature data and storing it. + * It also establishes the connection to the DB. + * @throws CommunicationException on DB connection error. + */ + public void init(String meerkatDB) throws CommunicationException; + + /** + * Post a message to bulletin board. + * @param msg is the actual (signed) message + * @return TRUE if the message has been authenticated and FALSE otherwise (in ProtoBuf form). + * @throws CommunicationException on DB connection error. + */ + public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException; + + /** + * Read all messages posted matching the given filter. + * @param filter return only messages that match the filter (empty list means no filtering). + * @return + */ + BulletinBoardMessageList readMessages(MessageFilterList filterList) throws CommunicationException; + + /** + * This method closes the connection to the DB. + * @throws CommunicationException on DB connection error. + */ + public void close() throws CommunicationException; +} diff --git a/meerkat-common/src/main/java/meerkat/comm/CommunicationException.java b/meerkat-common/src/main/java/meerkat/comm/CommunicationException.java index 05e7a22..f96dced 100644 --- a/meerkat-common/src/main/java/meerkat/comm/CommunicationException.java +++ b/meerkat-common/src/main/java/meerkat/comm/CommunicationException.java @@ -1,36 +1,36 @@ -package meerkat.comm; - -/** - * Created by talm on 24/10/15. - */ -public class CommunicationException extends Exception { - - /** - * Generated serial. - */ - - private static final long serialVersionUID = 2279440129497891293L; - private String message; - - /** - * Default constructor. To be used only if error type is unknown. - */ - public CommunicationException(){ - message = "Unknown communication exception"; - } - - /** - * Constructor enabling specifying of an error message. - * @param errorMessage - */ - public CommunicationException(String errorMessage){ - message = errorMessage; - } - - /** - * @return the error message specified. - */ - public String getMessage(){ - return message; - } -} +package meerkat.comm; + +/** + * Created by talm on 24/10/15. + */ +public class CommunicationException extends Exception { + + /** + * Generated serial. + */ + + private static final long serialVersionUID = 2279440129497891293L; + private String message; + + /** + * Default constructor. To be used only if error type is unknown. + */ + public CommunicationException(){ + message = "Unknown communication exception"; + } + + /** + * Constructor enabling specifying of an error message. + * @param errorMessage + */ + public CommunicationException(String errorMessage){ + message = errorMessage; + } + + /** + * @return the error message specified. + */ + public String getMessage(){ + return message; + } +} diff --git a/meerkat-common/src/main/java/meerkat/comm/Timestamp.java b/meerkat-common/src/main/java/meerkat/comm/Timestamp.java index 6c63854..568fa86 100644 --- a/meerkat-common/src/main/java/meerkat/comm/Timestamp.java +++ b/meerkat-common/src/main/java/meerkat/comm/Timestamp.java @@ -1,7 +1,7 @@ -package meerkat.comm; - -/** - * Created by talm on 24/10/15. - */ -public class Timestamp { -} +package meerkat.comm; + +/** + * Created by talm on 24/10/15. + */ +public class Timestamp { +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/Digest.java b/meerkat-common/src/main/java/meerkat/crypto/Digest.java index 06b012c..c3f7ea7 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/Digest.java +++ b/meerkat-common/src/main/java/meerkat/crypto/Digest.java @@ -1,38 +1,38 @@ -package meerkat.crypto; - -import com.google.protobuf.Message; - -import java.security.MessageDigest; - -/** - * Created by talm on 11/9/15. - */ -public interface Digest { - /** - * Completes the hash computation by performing final operations such as padding. - * (copied from {@link MessageDigest#digest()}) - * @return - */ - byte[] digest(); - - /** - * Updates the digest using the specified message (in serialized wire form) - * - * Each message is (automatically) prepended with its length as a 32-bit big-endian unsigned integer. - * @param msg - * @return - */ - void update(Message msg); - - /** - * Resets the digest for further use. - */ - void reset(); - - /** - * Clone the current digest state - * @return - */ - public Digest clone() throws CloneNotSupportedException; - -} +package meerkat.crypto; + +import com.google.protobuf.Message; + +import java.security.MessageDigest; + +/** + * Created by talm on 11/9/15. + */ +public interface Digest { + /** + * Completes the hash computation by performing final operations such as padding. + * (copied from {@link MessageDigest#digest()}) + * @return + */ + byte[] digest(); + + /** + * Updates the digest using the specified message (in serialized wire form) + * + * Each message is (automatically) prepended with its length as a 32-bit big-endian unsigned integer. + * @param msg + * @return + */ + void update(Message msg); + + /** + * Resets the digest for further use. + */ + void reset(); + + /** + * Clone the current digest state + * @return + */ + public Digest clone() throws CloneNotSupportedException; + +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/DigitalSignature.java b/meerkat-common/src/main/java/meerkat/crypto/DigitalSignature.java index e7b64e5..3785235 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/DigitalSignature.java +++ b/meerkat-common/src/main/java/meerkat/crypto/DigitalSignature.java @@ -1,96 +1,96 @@ -package meerkat.crypto; - -import com.google.protobuf.ByteString; -import com.google.protobuf.Message; - -import java.io.IOException; -import java.io.InputStream; -import java.security.InvalidKeyException; -import java.security.KeyStore; -import java.security.SignatureException; -import java.security.UnrecoverableKeyException; -import java.security.cert.CertificateException; -import static meerkat.protobuf.Crypto.*; - -/** - * Created by talm on 25/10/15. - * - * Sign and verify arrays of messages - */ -public interface DigitalSignature { - final public static String CERTIFICATE_ENCODING_X509 = "X.509"; - - /** - * Load a set of certificates from an input stream. - * This will consume the entire stream. - * Certificates can be either DER-encoded (binary) or PEM (base64) encoded. - * This may be called multiple times to load several different certificates. - * It must be called before calling {@link #verify()}. - * @param certStream source from which certificates are loaded - * @throws CertificateException on parsing errors - */ - public void loadVerificationCertificates(InputStream certStream) - throws CertificateException; - - /** - * Clear the loaded verification certificates. - */ - public void clearVerificationCertificates(); - - - /** - * Add msg to the content stream to be verified / signed. Each message is (automatically) - * prepended with its length as a 32-bit big-endian unsigned integer. - * - * @param msg - * @throws SignatureException - */ - public void updateContent(Message msg) throws SignatureException; - - - /** - * Sign the content that was added using {@link #updateContent(Message)}. - * Reset the DigitalSignature and make it available to sign a new message using the same key. - * @return - * @throws SignatureException - */ - Signature sign() throws SignatureException; - - /** - * Initialize the verifier with the certificate whose Id is in sig. - * @param sig - * @throws CertificateException - * @throws InvalidKeyException - */ - void initVerify(Signature sig) - throws CertificateException, InvalidKeyException; - - /** - * Verify the updated content using the initialized signature. - * @return - */ - public boolean verify(); - - /** - * Loads a private signing key. The keystore must include both the public and private - * key parts. - * This method must be called before calling {@link #sign()} or {@link #updateContent(Message)} - * Calling this method again will replace the key. - * - * @param keyStoreBuilder A keystore builder that can be used to load a keystore. - */ - public void loadSigningCertificate(KeyStore.Builder keyStoreBuilder) - throws IOException, CertificateException, UnrecoverableKeyException; - - - /** - * @return the signer ID if it exists; null otherwise. - */ - public ByteString getSignerID(); - - /** - * Clear the signing key (will require authentication to use again). - */ - public void clearSigningKey(); - -} +package meerkat.crypto; + +import com.google.protobuf.ByteString; +import com.google.protobuf.Message; + +import java.io.IOException; +import java.io.InputStream; +import java.security.InvalidKeyException; +import java.security.KeyStore; +import java.security.SignatureException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import static meerkat.protobuf.Crypto.*; + +/** + * Created by talm on 25/10/15. + * + * Sign and verify arrays of messages + */ +public interface DigitalSignature { + final public static String CERTIFICATE_ENCODING_X509 = "X.509"; + + /** + * Load a set of certificates from an input stream. + * This will consume the entire stream. + * Certificates can be either DER-encoded (binary) or PEM (base64) encoded. + * This may be called multiple times to load several different certificates. + * It must be called before calling {@link #verify()}. + * @param certStream source from which certificates are loaded + * @throws CertificateException on parsing errors + */ + public void loadVerificationCertificates(InputStream certStream) + throws CertificateException; + + /** + * Clear the loaded verification certificates. + */ + public void clearVerificationCertificates(); + + + /** + * Add msg to the content stream to be verified / signed. Each message is (automatically) + * prepended with its length as a 32-bit big-endian unsigned integer. + * + * @param msg + * @throws SignatureException + */ + public void updateContent(Message msg) throws SignatureException; + + + /** + * Sign the content that was added using {@link #updateContent(Message)}. + * Reset the DigitalSignature and make it available to sign a new message using the same key. + * @return + * @throws SignatureException + */ + Signature sign() throws SignatureException; + + /** + * Initialize the verifier with the certificate whose Id is in sig. + * @param sig + * @throws CertificateException + * @throws InvalidKeyException + */ + void initVerify(Signature sig) + throws CertificateException, InvalidKeyException; + + /** + * Verify the updated content using the initialized signature. + * @return + */ + public boolean verify(); + + /** + * Loads a private signing key. The keystore must include both the public and private + * key parts. + * This method must be called before calling {@link #sign()} or {@link #updateContent(Message)} + * Calling this method again will replace the key. + * + * @param keyStoreBuilder A keystore builder that can be used to load a keystore. + */ + public void loadSigningCertificate(KeyStore.Builder keyStoreBuilder) + throws IOException, CertificateException, UnrecoverableKeyException; + + + /** + * @return the signer ID if it exists; null otherwise. + */ + public ByteString getSignerID(); + + /** + * Clear the signing key (will require authentication to use again). + */ + public void clearSigningKey(); + +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/Encryption.java b/meerkat-common/src/main/java/meerkat/crypto/Encryption.java index 6a40d0d..0628685 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/Encryption.java +++ b/meerkat-common/src/main/java/meerkat/crypto/Encryption.java @@ -1,40 +1,40 @@ -package meerkat.crypto; - -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Message; - -import java.io.IOException; -import java.util.Random; - -import static meerkat.protobuf.Crypto.*; - -/** - * Created by talm on 11/2/15. - */ -public interface Encryption { - /** - * Encrypt the serialized form of a message plaintext. - * @param plaintext - * @param rnd - * @return - */ - RerandomizableEncryptedMessage encrypt(Message plaintext, EncryptionRandomness rnd) throws IOException; // TODO: type of exception; throws - - - /** - * Rerandomize a ciphertext using the supplied randomness. - * @param msg - * @param rnd - * @return - * @throws InvalidProtocolBufferException - */ - RerandomizableEncryptedMessage rerandomize(RerandomizableEncryptedMessage msg, EncryptionRandomness rnd) throws InvalidProtocolBufferException; - - /** - * Generate randomness compatible with {@link #encrypt(Message, EncryptionRandomness) and - * {@link #rerandomize(RerandomizableEncryptedMessage, EncryptionRandomness)}}. - * @param rand - * @return - */ - EncryptionRandomness generateRandomness(Random rand); -} +package meerkat.crypto; + +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; + +import java.io.IOException; +import java.util.Random; + +import static meerkat.protobuf.Crypto.*; + +/** + * Created by talm on 11/2/15. + */ +public interface Encryption { + /** + * Encrypt the serialized form of a message plaintext. + * @param plaintext + * @param rnd + * @return + */ + RerandomizableEncryptedMessage encrypt(Message plaintext, EncryptionRandomness rnd) throws IOException; // TODO: type of exception; throws + + + /** + * Rerandomize a ciphertext using the supplied randomness. + * @param msg + * @param rnd + * @return + * @throws InvalidProtocolBufferException + */ + RerandomizableEncryptedMessage rerandomize(RerandomizableEncryptedMessage msg, EncryptionRandomness rnd) throws InvalidProtocolBufferException; + + /** + * Generate randomness compatible with {@link #encrypt(Message, EncryptionRandomness) and + * {@link #rerandomize(RerandomizableEncryptedMessage, EncryptionRandomness)}}. + * @param rand + * @return + */ + EncryptionRandomness generateRandomness(Random rand); +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSADeterministicSignature.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSADeterministicSignature.java index 0afbdd7..1102c22 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSADeterministicSignature.java +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSADeterministicSignature.java @@ -1,134 +1,134 @@ -package meerkat.crypto.concrete; - -import com.google.protobuf.ByteString; -import com.google.protobuf.Message; -import meerkat.protobuf.Crypto; -import meerkat.protobuf.Crypto.Signature; -import org.bouncycastle.asn1.ASN1Integer; -import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.ECPrivateKeyParameters; -import org.bouncycastle.crypto.signers.DSAKCalculator; -import org.bouncycastle.crypto.signers.ECDSASigner; -import org.bouncycastle.crypto.signers.HMacDSAKCalculator; -import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.io.InputStream; -import java.math.BigInteger; -import java.security.*; -import java.security.cert.*; -import java.security.interfaces.ECPrivateKey; - - -/** - * Sign and verify digital signatures. - * - * Uses deterministic ECDSA signatures as per RFC 6979 - * - * This class uses BouncyCastle directly, so will not work with arbitrary PKCS11 providers. - * - * This class is not thread-safe (each thread should have its own instance). - */ -public class ECDSADeterministicSignature extends ECDSASignature { - final Logger logger = LoggerFactory.getLogger(getClass()); - - /** - * Digest of message contents for deterministic signing. - */ - SHA256Digest msgDigest = new SHA256Digest(); - - /** - * The actual signing implementation. (used only signing -- superclass is used for verification) - */ - ECDSASigner deterministicSigner; - - /** - * Output the DER encoding of the ASN.1 sequence r,s - * @param r - * @param s - * @return - */ - public static byte[] derEncodeSignature(BigInteger r, BigInteger s) { - ASN1Integer[] rs = {new ASN1Integer(r), new ASN1Integer(s)}; - DERSequence seq = new DERSequence(rs); - - try { - return seq.getEncoded(); - } catch (IOException e) { - throw new RuntimeException("Should never happen! DER Encoding exception", e); - } - } - - public ECDSADeterministicSignature() { - DSAKCalculator kCalk = new HMacDSAKCalculator(new org.bouncycastle.crypto.digests.SHA256Digest()); - deterministicSigner = new ECDSASigner(kCalk); - } - - @Override - public void loadSigningCertificate(KeyStore.Builder keyStoreBuilder) - throws CertificateException, UnrecoverableKeyException, IOException { - super.loadSigningCertificate(keyStoreBuilder); - - if (!(loadedSigningKey instanceof ECPrivateKey)) { - logger.error("Wrong private key type (expected ECPrivateKey, got {})", loadedSigningKey.getClass()); - throw new CertificateException("Wrong signing key type!"); - } - ECPrivateKey key = (ECPrivateKey) loadedSigningKey; - - AsymmetricKeyParameter baseParams; - try { - baseParams = ECUtil.generatePrivateKeyParameter(key); - } catch (InvalidKeyException e) { - throw new UnrecoverableKeyException("Couldn't convert private key"); - } - - if (!(baseParams instanceof ECPrivateKeyParameters)) { - logger.error("Error converting to bouncycastle type! (got {})", baseParams.getClass()); - throw new UnrecoverableKeyException("Wrong signing key type!"); - } - - ECPrivateKeyParameters params = (ECPrivateKeyParameters) baseParams; - - deterministicSigner.init(true, params); - } - - /** - * Add the list of messages to the stream that is being verified/signed. - * Messages are prepended with their length in 32-bit big-endian format. - * - * @param msg - * @throws SignatureException - */ - @Override - public void updateContent(Message msg) throws SignatureException { - assert msg != null; - - // We're doing twice the digest work so that we also support verification with the same update. - // If this becomes a problem, we can decide which way to update based on which init was called. - super.updateContent(msg); - msgDigest.update(msg); - } - - @Override - public void updateContent(InputStream in) throws IOException, SignatureException { - ByteString inStr = ByteString.readFrom(in); - signer.update(inStr.asReadOnlyByteBuffer()); - msgDigest.update(inStr); - } - - @Override - public Signature sign() throws SignatureException { - Signature.Builder sig = Signature.newBuilder(); - sig.setType(Crypto.SignatureType.ECDSA); - - BigInteger[] rawSig = deterministicSigner.generateSignature(msgDigest.digest()); - - sig.setData(ByteString.copyFrom(derEncodeSignature(rawSig[0], rawSig[1]))); - - sig.setSignerId(loadedSigningKeyId); - return sig.build(); - } -} +package meerkat.crypto.concrete; + +import com.google.protobuf.ByteString; +import com.google.protobuf.Message; +import meerkat.protobuf.Crypto; +import meerkat.protobuf.Crypto.Signature; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.crypto.params.ECPrivateKeyParameters; +import org.bouncycastle.crypto.signers.DSAKCalculator; +import org.bouncycastle.crypto.signers.ECDSASigner; +import org.bouncycastle.crypto.signers.HMacDSAKCalculator; +import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.math.BigInteger; +import java.security.*; +import java.security.cert.*; +import java.security.interfaces.ECPrivateKey; + + +/** + * Sign and verify digital signatures. + * + * Uses deterministic ECDSA signatures as per RFC 6979 + * + * This class uses BouncyCastle directly, so will not work with arbitrary PKCS11 providers. + * + * This class is not thread-safe (each thread should have its own instance). + */ +public class ECDSADeterministicSignature extends ECDSASignature { + final Logger logger = LoggerFactory.getLogger(getClass()); + + /** + * Digest of message contents for deterministic signing. + */ + SHA256Digest msgDigest = new SHA256Digest(); + + /** + * The actual signing implementation. (used only signing -- superclass is used for verification) + */ + ECDSASigner deterministicSigner; + + /** + * Output the DER encoding of the ASN.1 sequence r,s + * @param r + * @param s + * @return + */ + public static byte[] derEncodeSignature(BigInteger r, BigInteger s) { + ASN1Integer[] rs = {new ASN1Integer(r), new ASN1Integer(s)}; + DERSequence seq = new DERSequence(rs); + + try { + return seq.getEncoded(); + } catch (IOException e) { + throw new RuntimeException("Should never happen! DER Encoding exception", e); + } + } + + public ECDSADeterministicSignature() { + DSAKCalculator kCalk = new HMacDSAKCalculator(new org.bouncycastle.crypto.digests.SHA256Digest()); + deterministicSigner = new ECDSASigner(kCalk); + } + + @Override + public void loadSigningCertificate(KeyStore.Builder keyStoreBuilder) + throws CertificateException, UnrecoverableKeyException, IOException { + super.loadSigningCertificate(keyStoreBuilder); + + if (!(loadedSigningKey instanceof ECPrivateKey)) { + logger.error("Wrong private key type (expected ECPrivateKey, got {})", loadedSigningKey.getClass()); + throw new CertificateException("Wrong signing key type!"); + } + ECPrivateKey key = (ECPrivateKey) loadedSigningKey; + + AsymmetricKeyParameter baseParams; + try { + baseParams = ECUtil.generatePrivateKeyParameter(key); + } catch (InvalidKeyException e) { + throw new UnrecoverableKeyException("Couldn't convert private key"); + } + + if (!(baseParams instanceof ECPrivateKeyParameters)) { + logger.error("Error converting to bouncycastle type! (got {})", baseParams.getClass()); + throw new UnrecoverableKeyException("Wrong signing key type!"); + } + + ECPrivateKeyParameters params = (ECPrivateKeyParameters) baseParams; + + deterministicSigner.init(true, params); + } + + /** + * Add the list of messages to the stream that is being verified/signed. + * Messages are prepended with their length in 32-bit big-endian format. + * + * @param msg + * @throws SignatureException + */ + @Override + public void updateContent(Message msg) throws SignatureException { + assert msg != null; + + // We're doing twice the digest work so that we also support verification with the same update. + // If this becomes a problem, we can decide which way to update based on which init was called. + super.updateContent(msg); + msgDigest.update(msg); + } + + @Override + public void updateContent(InputStream in) throws IOException, SignatureException { + ByteString inStr = ByteString.readFrom(in); + signer.update(inStr.asReadOnlyByteBuffer()); + msgDigest.update(inStr); + } + + @Override + public Signature sign() throws SignatureException { + Signature.Builder sig = Signature.newBuilder(); + sig.setType(Crypto.SignatureType.ECDSA); + + BigInteger[] rawSig = deterministicSigner.generateSignature(msgDigest.digest()); + + sig.setData(ByteString.copyFrom(derEncodeSignature(rawSig[0], rawSig[1]))); + + sig.setSignerId(loadedSigningKeyId); + return sig.build(); + } +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java index 887b8e8..84017e0 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java @@ -1,322 +1,322 @@ -package meerkat.crypto.concrete; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.security.*; -import java.security.cert.*; -import java.security.cert.Certificate; -import java.util.*; - -import com.google.protobuf.ByteString; -import meerkat.protobuf.Crypto; -import meerkat.util.Hex; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.protobuf.Message; - -import meerkat.crypto.DigitalSignature; -import meerkat.protobuf.Crypto.Signature; - -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.PasswordCallback; -import javax.security.auth.callback.UnsupportedCallbackException; - - -/** - * Sign and verify digital signatures. - * - * This class is not thread-safe (each thread should have its own instance). - */ -public class ECDSASignature extends GlobalCryptoSetup implements DigitalSignature { - final Logger logger = LoggerFactory.getLogger(getClass()); - - final public static String KEYSTORE_TYPE = "PKCS12"; - final public static String DEFAULT_SIGNATURE_ALGORITHM = "SHA256withECDSA"; - - SHA256Digest certDigest = new SHA256Digest(); - - /** - * Buffer used to hold length in for hash update - */ - ByteBuffer lenBuf = ByteBuffer.allocate(4); - - - Map loadedCertificates = new HashMap<>(); - - /** - * Signature currently loaded (will be used in calls to {@link #verify()}). - */ - ByteString loadedSignature = null; - - ByteString loadedSigningKeyId = null; - - /** - * The actual signing implementation. (used for both signing and verifying) - */ - java.security.Signature signer; - - /** - * The currently loaded signing key. - */ - PrivateKey loadedSigningKey; - - - /** - * Compute a fingerprint of a cert as a SHA256 hash. - * - * @param cert - * @return - */ - public ByteString computeCertificateFingerprint(Certificate cert) { - try { - certDigest.reset(); - byte[] data = cert.getEncoded(); - certDigest.update(data); - return ByteString.copyFrom(certDigest.digest()); - } catch (CertificateEncodingException e) { - // Shouldn't happen - logger.error("Certificate encoding error", e); - throw new RuntimeException("Certificate encoding error", e); - } - - } - - public ECDSASignature(java.security.Signature signer) { - this.signer = signer; - } - - public ECDSASignature() { - try { - this.signer = java.security.Signature.getInstance(DEFAULT_SIGNATURE_ALGORITHM); - } catch (NoSuchAlgorithmException e) { - // Should never happen - logger.error("Couldn't find implementation for " + DEFAULT_SIGNATURE_ALGORITHM + " signatures", e); - } - } - - @Override - public void loadVerificationCertificates(InputStream certStream) - throws CertificateException { - CertificateFactory certificateFactory = CertificateFactory.getInstance(CERTIFICATE_ENCODING_X509); - Collection certs = certificateFactory.generateCertificates(certStream); - for (Certificate cert : certs) { - // Just checking - if (!(cert instanceof X509Certificate)) { - logger.error("Certificate must be in X509 format; got {} instead!", cert.getClass().getCanonicalName()); - continue; - } - ByteString keyId = computeCertificateFingerprint(cert); - loadedCertificates.put(keyId, cert); - } - } - - @Override - public void clearVerificationCertificates() { - loadedCertificates.clear(); - } - - - /** - * Add the list of messages to the stream that is being verified/signed. - * Messages are prepended with their length in 32-bit big-endian format. - * - * @param msg - * @throws SignatureException - */ - @Override - public void updateContent(Message msg) throws SignatureException { - assert msg != null; - - lenBuf.clear(); - lenBuf.putInt(msg.getSerializedSize()); - lenBuf.flip(); - signer.update(lenBuf); - signer.update(msg.toByteString().asReadOnlyByteBuffer()); - } - - public void updateContent(InputStream in) throws IOException, SignatureException { - ByteString inStr = ByteString.readFrom(in); - signer.update(inStr.asReadOnlyByteBuffer()); - } - - @Override - public Signature sign() throws SignatureException { - Signature.Builder sig = Signature.newBuilder(); - sig.setType(Crypto.SignatureType.ECDSA); - sig.setData(ByteString.copyFrom(signer.sign())); - sig.setSignerId(loadedSigningKeyId); - return sig.build(); - } - - @Override - public void initVerify(Signature sig) - throws CertificateException, InvalidKeyException { - Certificate cert = loadedCertificates.get(sig.getSignerId()); - if (cert == null) { - logger.warn("No certificate loaded for ID {}!", sig.getSignerId()); - throw new CertificateException("No certificate loaded for " + sig.getSignerId()); - } - signer.initVerify(cert.getPublicKey()); - loadedSignature = sig.getData(); - loadedSigningKeyId = null; - } - - @Override - public boolean verify() { - try { - return signer.verify(loadedSignature.toByteArray()); - } catch (SignatureException e) { - // Happens only if signature is invalid! - logger.error("Signature exception", e); - return false; - } - } - - /** - * Utility method to more easily deal with simple password-protected files. - * - * @param password - * @return - */ - public CallbackHandler getFixedPasswordHandler(final char[] password) { - return new CallbackHandler() { - @Override - public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { - for (Callback callback : callbacks) { - if (callback instanceof PasswordCallback) { - PasswordCallback passwordCallback = (PasswordCallback) callback; - logger.debug("Requested password ({})", passwordCallback.getPrompt()); - passwordCallback.setPassword(password); - } - } - - } - }; - } - - /** - * Load a keystore from an input stream in PKCS12 format. - * - * @param keyStream - * @param password - * @return - * @throws IOException - * @throws CertificateException - * @throws KeyStoreException - * @throws NoSuchAlgorithmException - */ - public KeyStore.Builder getPKCS12KeyStoreBuilder(InputStream keyStream, char[] password) - throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException { - KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE); - keyStore.load(keyStream, password); - return KeyStore.Builder.newInstance(keyStore, new KeyStore.CallbackHandlerProtection(getFixedPasswordHandler(password))); - } - - - /** - * For now we only support PKCS12. - * TODO: Support for PKCS11 as well. - * - * @param keyStoreBuilder - * @throws IOException - * @throws CertificateException - * @throws UnrecoverableKeyException - */ - @Override - public void loadSigningCertificate(KeyStore.Builder keyStoreBuilder) - throws IOException, CertificateException, UnrecoverableKeyException { - try { - - KeyStore keyStore = keyStoreBuilder.getKeyStore(); - - // Iterate through all aliases until we find the first privatekey - Enumeration aliases = keyStore.aliases(); - while (aliases.hasMoreElements()) { - String alias = aliases.nextElement(); - logger.trace("Testing keystore entry {}", alias); - - - try { - Certificate cert = keyStore.getCertificate(alias); - logger.trace("keystore entry {}, has cert type {}", alias, cert.getClass()); - - Key key; - - try { - key = keyStore.getKey(alias, null); - } catch (UnrecoverableKeyException e) { - // This might be a keystore that doesn't support callback handlers - // (e.g., Java 8 PKCS12) - // Manually extract password using callback handler - char[] password = null; - KeyStore.ProtectionParameter prot = keyStoreBuilder.getProtectionParameter(alias); - - if (prot instanceof KeyStore.PasswordProtection) { - password = ((KeyStore.PasswordProtection) prot).getPassword(); - } else if (prot instanceof KeyStore.CallbackHandlerProtection) { - PasswordCallback callback = new PasswordCallback("Password for " + alias + "?", false); - Callback[] callbacks = { callback }; - try { - ((KeyStore.CallbackHandlerProtection) prot).getCallbackHandler().handle(callbacks); - password = callback.getPassword(); - } catch (UnsupportedCallbackException e1) { - logger.error("PasswordCallback fallback not supported!", e1); - throw new UnrecoverableKeyException("Couldn't use password callback to get key"); - } - } else { - logger.error("Unrecognized protection handler for keystore: {}", prot.getClass()); - throw new UnrecoverableKeyException("Unrecognized protection handler for keystore"); - } - key = keyStore.getKey(alias, password); - } - logger.trace("keystore entry {}, has key type {}", alias, key.getClass()); - if (key instanceof PrivateKey) { - loadedSigningKey = (PrivateKey) key; - loadedSigningKeyId = computeCertificateFingerprint(cert); - signer.initSign(loadedSigningKey); - logger.debug("Loaded signing key with ID {}", Hex.encode(loadedSigningKeyId)); - - return; - } else { - logger.info("Certificate {} in keystore does not have a private key", cert.toString()); - } - } catch(InvalidKeyException e) { - logger.info("Read invalid key", e); - } catch(UnrecoverableEntryException e) { - logger.info("Read unrecoverable entry", e); - } - } - - } catch (KeyStoreException e) { - logger.error("Keystore exception", e); - } catch (NoSuchAlgorithmException e) { - logger.error("NoSuchAlgorithmException exception", e); - throw new CertificateException(e); - } - logger.error("Didn't find valid private key entry in keystore"); - throw new UnrecoverableKeyException("Didn't find valid private key entry in keystore!"); - } - - @Override - public ByteString getSignerID() { - return loadedSigningKeyId; - } - - public void clearSigningKey() { - try { - // TODO: Check if this really clears the key from memory - if (loadedSigningKeyId != null) - signer.initSign(null); - loadedSigningKeyId = null; - loadedSigningKey = null; - // Start garbage collection? - } catch (InvalidKeyException e) { - // Do nothing - } - } - - -} +package meerkat.crypto.concrete; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.security.*; +import java.security.cert.*; +import java.security.cert.Certificate; +import java.util.*; + +import com.google.protobuf.ByteString; +import meerkat.protobuf.Crypto; +import meerkat.util.Hex; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.protobuf.Message; + +import meerkat.crypto.DigitalSignature; +import meerkat.protobuf.Crypto.Signature; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; + + +/** + * Sign and verify digital signatures. + * + * This class is not thread-safe (each thread should have its own instance). + */ +public class ECDSASignature extends GlobalCryptoSetup implements DigitalSignature { + final Logger logger = LoggerFactory.getLogger(getClass()); + + final public static String KEYSTORE_TYPE = "PKCS12"; + final public static String DEFAULT_SIGNATURE_ALGORITHM = "SHA256withECDSA"; + + SHA256Digest certDigest = new SHA256Digest(); + + /** + * Buffer used to hold length in for hash update + */ + ByteBuffer lenBuf = ByteBuffer.allocate(4); + + + Map loadedCertificates = new HashMap<>(); + + /** + * Signature currently loaded (will be used in calls to {@link #verify()}). + */ + ByteString loadedSignature = null; + + ByteString loadedSigningKeyId = null; + + /** + * The actual signing implementation. (used for both signing and verifying) + */ + java.security.Signature signer; + + /** + * The currently loaded signing key. + */ + PrivateKey loadedSigningKey; + + + /** + * Compute a fingerprint of a cert as a SHA256 hash. + * + * @param cert + * @return + */ + public ByteString computeCertificateFingerprint(Certificate cert) { + try { + certDigest.reset(); + byte[] data = cert.getEncoded(); + certDigest.update(data); + return ByteString.copyFrom(certDigest.digest()); + } catch (CertificateEncodingException e) { + // Shouldn't happen + logger.error("Certificate encoding error", e); + throw new RuntimeException("Certificate encoding error", e); + } + + } + + public ECDSASignature(java.security.Signature signer) { + this.signer = signer; + } + + public ECDSASignature() { + try { + this.signer = java.security.Signature.getInstance(DEFAULT_SIGNATURE_ALGORITHM); + } catch (NoSuchAlgorithmException e) { + // Should never happen + logger.error("Couldn't find implementation for " + DEFAULT_SIGNATURE_ALGORITHM + " signatures", e); + } + } + + @Override + public void loadVerificationCertificates(InputStream certStream) + throws CertificateException { + CertificateFactory certificateFactory = CertificateFactory.getInstance(CERTIFICATE_ENCODING_X509); + Collection certs = certificateFactory.generateCertificates(certStream); + for (Certificate cert : certs) { + // Just checking + if (!(cert instanceof X509Certificate)) { + logger.error("Certificate must be in X509 format; got {} instead!", cert.getClass().getCanonicalName()); + continue; + } + ByteString keyId = computeCertificateFingerprint(cert); + loadedCertificates.put(keyId, cert); + } + } + + @Override + public void clearVerificationCertificates() { + loadedCertificates.clear(); + } + + + /** + * Add the list of messages to the stream that is being verified/signed. + * Messages are prepended with their length in 32-bit big-endian format. + * + * @param msg + * @throws SignatureException + */ + @Override + public void updateContent(Message msg) throws SignatureException { + assert msg != null; + + lenBuf.clear(); + lenBuf.putInt(msg.getSerializedSize()); + lenBuf.flip(); + signer.update(lenBuf); + signer.update(msg.toByteString().asReadOnlyByteBuffer()); + } + + public void updateContent(InputStream in) throws IOException, SignatureException { + ByteString inStr = ByteString.readFrom(in); + signer.update(inStr.asReadOnlyByteBuffer()); + } + + @Override + public Signature sign() throws SignatureException { + Signature.Builder sig = Signature.newBuilder(); + sig.setType(Crypto.SignatureType.ECDSA); + sig.setData(ByteString.copyFrom(signer.sign())); + sig.setSignerId(loadedSigningKeyId); + return sig.build(); + } + + @Override + public void initVerify(Signature sig) + throws CertificateException, InvalidKeyException { + Certificate cert = loadedCertificates.get(sig.getSignerId()); + if (cert == null) { + logger.warn("No certificate loaded for ID {}!", sig.getSignerId()); + throw new CertificateException("No certificate loaded for " + sig.getSignerId()); + } + signer.initVerify(cert.getPublicKey()); + loadedSignature = sig.getData(); + loadedSigningKeyId = null; + } + + @Override + public boolean verify() { + try { + return signer.verify(loadedSignature.toByteArray()); + } catch (SignatureException e) { + // Happens only if signature is invalid! + logger.error("Signature exception", e); + return false; + } + } + + /** + * Utility method to more easily deal with simple password-protected files. + * + * @param password + * @return + */ + public CallbackHandler getFixedPasswordHandler(final char[] password) { + return new CallbackHandler() { + @Override + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { + for (Callback callback : callbacks) { + if (callback instanceof PasswordCallback) { + PasswordCallback passwordCallback = (PasswordCallback) callback; + logger.debug("Requested password ({})", passwordCallback.getPrompt()); + passwordCallback.setPassword(password); + } + } + + } + }; + } + + /** + * Load a keystore from an input stream in PKCS12 format. + * + * @param keyStream + * @param password + * @return + * @throws IOException + * @throws CertificateException + * @throws KeyStoreException + * @throws NoSuchAlgorithmException + */ + public KeyStore.Builder getPKCS12KeyStoreBuilder(InputStream keyStream, char[] password) + throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException { + KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE); + keyStore.load(keyStream, password); + return KeyStore.Builder.newInstance(keyStore, new KeyStore.CallbackHandlerProtection(getFixedPasswordHandler(password))); + } + + + /** + * For now we only support PKCS12. + * TODO: Support for PKCS11 as well. + * + * @param keyStoreBuilder + * @throws IOException + * @throws CertificateException + * @throws UnrecoverableKeyException + */ + @Override + public void loadSigningCertificate(KeyStore.Builder keyStoreBuilder) + throws IOException, CertificateException, UnrecoverableKeyException { + try { + + KeyStore keyStore = keyStoreBuilder.getKeyStore(); + + // Iterate through all aliases until we find the first privatekey + Enumeration aliases = keyStore.aliases(); + while (aliases.hasMoreElements()) { + String alias = aliases.nextElement(); + logger.trace("Testing keystore entry {}", alias); + + + try { + Certificate cert = keyStore.getCertificate(alias); + logger.trace("keystore entry {}, has cert type {}", alias, cert.getClass()); + + Key key; + + try { + key = keyStore.getKey(alias, null); + } catch (UnrecoverableKeyException e) { + // This might be a keystore that doesn't support callback handlers + // (e.g., Java 8 PKCS12) + // Manually extract password using callback handler + char[] password = null; + KeyStore.ProtectionParameter prot = keyStoreBuilder.getProtectionParameter(alias); + + if (prot instanceof KeyStore.PasswordProtection) { + password = ((KeyStore.PasswordProtection) prot).getPassword(); + } else if (prot instanceof KeyStore.CallbackHandlerProtection) { + PasswordCallback callback = new PasswordCallback("Password for " + alias + "?", false); + Callback[] callbacks = { callback }; + try { + ((KeyStore.CallbackHandlerProtection) prot).getCallbackHandler().handle(callbacks); + password = callback.getPassword(); + } catch (UnsupportedCallbackException e1) { + logger.error("PasswordCallback fallback not supported!", e1); + throw new UnrecoverableKeyException("Couldn't use password callback to get key"); + } + } else { + logger.error("Unrecognized protection handler for keystore: {}", prot.getClass()); + throw new UnrecoverableKeyException("Unrecognized protection handler for keystore"); + } + key = keyStore.getKey(alias, password); + } + logger.trace("keystore entry {}, has key type {}", alias, key.getClass()); + if (key instanceof PrivateKey) { + loadedSigningKey = (PrivateKey) key; + loadedSigningKeyId = computeCertificateFingerprint(cert); + signer.initSign(loadedSigningKey); + logger.debug("Loaded signing key with ID {}", Hex.encode(loadedSigningKeyId)); + + return; + } else { + logger.info("Certificate {} in keystore does not have a private key", cert.toString()); + } + } catch(InvalidKeyException e) { + logger.info("Read invalid key", e); + } catch(UnrecoverableEntryException e) { + logger.info("Read unrecoverable entry", e); + } + } + + } catch (KeyStoreException e) { + logger.error("Keystore exception", e); + } catch (NoSuchAlgorithmException e) { + logger.error("NoSuchAlgorithmException exception", e); + throw new CertificateException(e); + } + logger.error("Didn't find valid private key entry in keystore"); + throw new UnrecoverableKeyException("Didn't find valid private key entry in keystore!"); + } + + @Override + public ByteString getSignerID() { + return loadedSigningKeyId; + } + + public void clearSigningKey() { + try { + // TODO: Check if this really clears the key from memory + if (loadedSigningKeyId != null) + signer.initSign(null); + loadedSigningKeyId = null; + loadedSigningKey = null; + // Start garbage collection? + } catch (InvalidKeyException e) { + // Do nothing + } + } + + +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java index 6258f5f..05447c9 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java @@ -1,135 +1,135 @@ -package meerkat.crypto.concrete; - -import com.google.protobuf.ByteString; -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Message; -import meerkat.crypto.Encryption; -import meerkat.protobuf.ConcreteCrypto; -import meerkat.protobuf.Crypto; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.ECDomainParameters; -import org.bouncycastle.crypto.params.ECKeyParameters; -import org.bouncycastle.crypto.params.ECPublicKeyParameters; -import org.bouncycastle.crypto.util.PublicKeyFactory; -import org.bouncycastle.jce.spec.ECParameterSpec; -import org.bouncycastle.math.ec.ECCurve; -import org.bouncycastle.math.ec.ECPoint; -import org.bouncycastle.util.BigIntegers; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.factcenter.qilin.primitives.concrete.ECElGamal; -import org.factcenter.qilin.primitives.concrete.ECGroup; -import org.factcenter.qilin.util.PRGRandom; -import org.factcenter.qilin.util.Pair; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.math.BigInteger; -import java.security.spec.*; -import java.util.Random; - -/** - * Created by talm on 17/11/15. - */ -public class ECElGamalEncryption extends GlobalCryptoSetup implements Encryption { - final Logger logger = LoggerFactory.getLogger(getClass()); - - public final static String KEY_ALGORITHM = "ECDH"; - - /** - * The Qilin format El-Gamal public key - */ - ECElGamal.PK elGamalPK; - - ECCurve curve; - - ECGroup group; - - public ECGroup getGroup() { return group; } - - public ECElGamal.PK getElGamalPK() { - return elGamalPK; - } - - public void init(ConcreteCrypto.ElGamalPublicKey serializedPk) throws InvalidKeySpecException { - AsymmetricKeyParameter keyParam; - - try { - keyParam = PublicKeyFactory.createKey(serializedPk.getSubjectPublicKeyInfo().toByteArray()); - } catch (IOException e) { - // Shouldn't every happen - logger.error("Invalid Public Key Encoding", e); - throw new InvalidKeySpecException("Invalid Public Key Encoding", e); - } - - if (!(keyParam instanceof ECPublicKeyParameters)) { - logger.error("Public key is a {}, not a valid public EC Key!", keyParam.getClass()); - throw new InvalidKeySpecException("Not a valid EC public key!"); - } - - ECDomainParameters params = ((ECKeyParameters) keyParam).getParameters(); - ECParameterSpec ecParams = new ECParameterSpec(params.getCurve(), params.getG(), params.getN(), params.getH(), - params.getSeed()); - - curve = params.getCurve(); - group = new ECGroup(ecParams); - - elGamalPK = new ECElGamal.PK(group, ((ECPublicKeyParameters) keyParam).getQ()); - } - - - @Override - public Crypto.RerandomizableEncryptedMessage encrypt(Message plaintext, Crypto.EncryptionRandomness rnd) { - - // We write the message using writeDelimited to so the length gets prepended. - ByteArrayOutputStream out = new ByteArrayOutputStream(); - try { - plaintext.writeDelimitedTo(out); - } catch (IOException e) { - logger.error("Should never happen!", e); - throw new RuntimeException("Error in ByteArrayOutputStream!", e); - } - byte[] msg = out.toByteArray(); - ECPoint encodedMsg = group.injectiveEncode(msg, new PRGRandom(msg)); - - BigInteger rndInt = BigIntegers.fromUnsignedByteArray(rnd.getData().toByteArray()); - Pair cipherText = elGamalPK.encrypt(encodedMsg, rndInt); - ConcreteCrypto.ElGamalCiphertext encodedCipherText = ConcreteCrypto.ElGamalCiphertext.newBuilder() - .setC1(ByteString.copyFrom(cipherText.a.getEncoded(true))) - .setC2(ByteString.copyFrom(cipherText.b.getEncoded(true))) - .build(); - - return Crypto.RerandomizableEncryptedMessage.newBuilder() - .setData(encodedCipherText.toByteString()) - .build(); - } - - @Override - public Crypto.RerandomizableEncryptedMessage rerandomize(Crypto.RerandomizableEncryptedMessage msg, Crypto.EncryptionRandomness rnd) throws InvalidProtocolBufferException { - BigInteger rndInt = BigIntegers.fromUnsignedByteArray(rnd.getData().toByteArray()); - Pair randomizer = elGamalPK.encrypt(curve.getInfinity(), rndInt); - ConcreteCrypto.ElGamalCiphertext originalEncodedCipher= ConcreteCrypto.ElGamalCiphertext.parseFrom(msg.getData()); - - Pair originalCipher = new Pair( - curve.decodePoint(originalEncodedCipher.getC1().toByteArray()), - curve.decodePoint(originalEncodedCipher.getC2().toByteArray())); - Pair newCipher = elGamalPK.add(originalCipher, randomizer); - - return Crypto.RerandomizableEncryptedMessage.newBuilder() - .setData( - ConcreteCrypto.ElGamalCiphertext.newBuilder() - .setC1(ByteString.copyFrom(newCipher.a.getEncoded(true))) - .setC2(ByteString.copyFrom(newCipher.b.getEncoded(true))) - .build().toByteString() - ).build(); - } - - @Override - public Crypto.EncryptionRandomness generateRandomness(Random rand) { - BigInteger randomInt = new BigInteger(group.getCurveParams().getN().bitLength() - 1, rand); - Crypto.EncryptionRandomness retval = Crypto.EncryptionRandomness.newBuilder() - .setData(ByteString.copyFrom(BigIntegers.asUnsignedByteArray(randomInt))).build(); - - return retval; - } -} +package meerkat.crypto.concrete; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; +import meerkat.crypto.Encryption; +import meerkat.protobuf.ConcreteCrypto; +import meerkat.protobuf.Crypto; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.crypto.params.ECDomainParameters; +import org.bouncycastle.crypto.params.ECKeyParameters; +import org.bouncycastle.crypto.params.ECPublicKeyParameters; +import org.bouncycastle.crypto.util.PublicKeyFactory; +import org.bouncycastle.jce.spec.ECParameterSpec; +import org.bouncycastle.math.ec.ECCurve; +import org.bouncycastle.math.ec.ECPoint; +import org.bouncycastle.util.BigIntegers; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.factcenter.qilin.primitives.concrete.ECElGamal; +import org.factcenter.qilin.primitives.concrete.ECGroup; +import org.factcenter.qilin.util.PRGRandom; +import org.factcenter.qilin.util.Pair; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.security.spec.*; +import java.util.Random; + +/** + * Created by talm on 17/11/15. + */ +public class ECElGamalEncryption extends GlobalCryptoSetup implements Encryption { + final Logger logger = LoggerFactory.getLogger(getClass()); + + public final static String KEY_ALGORITHM = "ECDH"; + + /** + * The Qilin format El-Gamal public key + */ + ECElGamal.PK elGamalPK; + + ECCurve curve; + + ECGroup group; + + public ECGroup getGroup() { return group; } + + public ECElGamal.PK getElGamalPK() { + return elGamalPK; + } + + public void init(ConcreteCrypto.ElGamalPublicKey serializedPk) throws InvalidKeySpecException { + AsymmetricKeyParameter keyParam; + + try { + keyParam = PublicKeyFactory.createKey(serializedPk.getSubjectPublicKeyInfo().toByteArray()); + } catch (IOException e) { + // Shouldn't every happen + logger.error("Invalid Public Key Encoding", e); + throw new InvalidKeySpecException("Invalid Public Key Encoding", e); + } + + if (!(keyParam instanceof ECPublicKeyParameters)) { + logger.error("Public key is a {}, not a valid public EC Key!", keyParam.getClass()); + throw new InvalidKeySpecException("Not a valid EC public key!"); + } + + ECDomainParameters params = ((ECKeyParameters) keyParam).getParameters(); + ECParameterSpec ecParams = new ECParameterSpec(params.getCurve(), params.getG(), params.getN(), params.getH(), + params.getSeed()); + + curve = params.getCurve(); + group = new ECGroup(ecParams); + + elGamalPK = new ECElGamal.PK(group, ((ECPublicKeyParameters) keyParam).getQ()); + } + + + @Override + public Crypto.RerandomizableEncryptedMessage encrypt(Message plaintext, Crypto.EncryptionRandomness rnd) { + + // We write the message using writeDelimited to so the length gets prepended. + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + plaintext.writeDelimitedTo(out); + } catch (IOException e) { + logger.error("Should never happen!", e); + throw new RuntimeException("Error in ByteArrayOutputStream!", e); + } + byte[] msg = out.toByteArray(); + ECPoint encodedMsg = group.injectiveEncode(msg, new PRGRandom(msg)); + + BigInteger rndInt = BigIntegers.fromUnsignedByteArray(rnd.getData().toByteArray()); + Pair cipherText = elGamalPK.encrypt(encodedMsg, rndInt); + ConcreteCrypto.ElGamalCiphertext encodedCipherText = ConcreteCrypto.ElGamalCiphertext.newBuilder() + .setC1(ByteString.copyFrom(cipherText.a.getEncoded(true))) + .setC2(ByteString.copyFrom(cipherText.b.getEncoded(true))) + .build(); + + return Crypto.RerandomizableEncryptedMessage.newBuilder() + .setData(encodedCipherText.toByteString()) + .build(); + } + + @Override + public Crypto.RerandomizableEncryptedMessage rerandomize(Crypto.RerandomizableEncryptedMessage msg, Crypto.EncryptionRandomness rnd) throws InvalidProtocolBufferException { + BigInteger rndInt = BigIntegers.fromUnsignedByteArray(rnd.getData().toByteArray()); + Pair randomizer = elGamalPK.encrypt(curve.getInfinity(), rndInt); + ConcreteCrypto.ElGamalCiphertext originalEncodedCipher= ConcreteCrypto.ElGamalCiphertext.parseFrom(msg.getData()); + + Pair originalCipher = new Pair( + curve.decodePoint(originalEncodedCipher.getC1().toByteArray()), + curve.decodePoint(originalEncodedCipher.getC2().toByteArray())); + Pair newCipher = elGamalPK.add(originalCipher, randomizer); + + return Crypto.RerandomizableEncryptedMessage.newBuilder() + .setData( + ConcreteCrypto.ElGamalCiphertext.newBuilder() + .setC1(ByteString.copyFrom(newCipher.a.getEncoded(true))) + .setC2(ByteString.copyFrom(newCipher.b.getEncoded(true))) + .build().toByteString() + ).build(); + } + + @Override + public Crypto.EncryptionRandomness generateRandomness(Random rand) { + BigInteger randomInt = new BigInteger(group.getCurveParams().getN().bitLength() - 1, rand); + Crypto.EncryptionRandomness retval = Crypto.EncryptionRandomness.newBuilder() + .setData(ByteString.copyFrom(BigIntegers.asUnsignedByteArray(randomInt))).build(); + + return retval; + } +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/concrete/GlobalCryptoSetup.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/GlobalCryptoSetup.java index 4f2e7a5..ca09689 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/concrete/GlobalCryptoSetup.java +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/GlobalCryptoSetup.java @@ -1,43 +1,43 @@ -package meerkat.crypto.concrete; - -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.security.Provider; -import java.security.Security; - -/** - * A class that performs required crypto setup - */ -public class GlobalCryptoSetup { - final static Logger logger = LoggerFactory.getLogger(GlobalCryptoSetup.class); - - static boolean loadedBouncyCastle = false; - static Provider bouncyCastleProvider; - - public static boolean hasSecp256k1Curve() { - // For now we just check if the java version is at least 8 - String[] version = System.getProperty("java.version").split("\\."); - int major = Integer.parseInt(version[0]); - int minor = Integer.parseInt(version[1]); - return ((major > 1) || ((major > 0) && (minor > 7))); - } - - public static Provider getBouncyCastleProvider() { doSetup(); return bouncyCastleProvider; } - - public static synchronized void doSetup() { - if (bouncyCastleProvider == null) { - bouncyCastleProvider = new BouncyCastleProvider(); - // Make bouncycastle our default provider if we're running on a JVM version < 8 - // (earlier version don't support the EC curve we use for signatures) - if (!hasSecp256k1Curve() && !loadedBouncyCastle) { - loadedBouncyCastle = true; - Security.insertProviderAt(bouncyCastleProvider, 1); - logger.info("Using BouncyCastle instead of native provider to support secp256k1 named curve"); - } - } - } - - public GlobalCryptoSetup() { doSetup(); } -} +package meerkat.crypto.concrete; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.security.Provider; +import java.security.Security; + +/** + * A class that performs required crypto setup + */ +public class GlobalCryptoSetup { + final static Logger logger = LoggerFactory.getLogger(GlobalCryptoSetup.class); + + static boolean loadedBouncyCastle = false; + static Provider bouncyCastleProvider; + + public static boolean hasSecp256k1Curve() { + // For now we just check if the java version is at least 8 + String[] version = System.getProperty("java.version").split("\\."); + int major = Integer.parseInt(version[0]); + int minor = Integer.parseInt(version[1]); + return ((major > 1) || ((major > 0) && (minor > 7))); + } + + public static Provider getBouncyCastleProvider() { doSetup(); return bouncyCastleProvider; } + + public static synchronized void doSetup() { + if (bouncyCastleProvider == null) { + bouncyCastleProvider = new BouncyCastleProvider(); + // Make bouncycastle our default provider if we're running on a JVM version < 8 + // (earlier version don't support the EC curve we use for signatures) + if (!hasSecp256k1Curve() && !loadedBouncyCastle) { + loadedBouncyCastle = true; + Security.insertProviderAt(bouncyCastleProvider, 1); + logger.info("Using BouncyCastle instead of native provider to support secp256k1 named curve"); + } + } + } + + public GlobalCryptoSetup() { doSetup(); } +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java index 4f60af3..784da82 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java @@ -1,96 +1,96 @@ -package meerkat.crypto.concrete; - -import com.google.protobuf.ByteString; -import com.google.protobuf.Message; -import meerkat.crypto.Digest; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.ByteBuffer; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -/** - * Created by talm on 11/9/15. - */ -public class SHA256Digest extends GlobalCryptoSetup implements Digest { - final Logger logger = LoggerFactory.getLogger(getClass()); - public static final String SHA256 = "SHA-256"; - - MessageDigest hash; - - /** - * Used to convert length to bytes in proper order. - */ - ByteBuffer lenBuf = ByteBuffer.allocate(4); - - /** - * Instantiate with a specified algorithm. - * @param algorithm - * @throws NoSuchAlgorithmException - */ - public SHA256Digest(String algorithm) throws NoSuchAlgorithmException { - hash = MessageDigest.getInstance(algorithm); - } - - /** - * Instantiate with the default (SHA-256) algorithm - */ - public SHA256Digest() { this(true); } - - - /**SHA - * Instantiate with the default (SHA-256) algorithm, - * or create an empty class (for cloning) - */ - private SHA256Digest(boolean initHash) { - if (initHash) { - try { - hash = MessageDigest.getInstance(SHA256); - } catch (NoSuchAlgorithmException e) { - // Should never happen! - logger.error("Couldn't find default {} algorhtm: {}", SHA256, e); - assert false; - } - } - } - - @Override - public byte[] digest() { - return hash.digest(); - } - - @Override - public void update(Message msg) { - - lenBuf.clear(); - lenBuf.putInt(msg.getSerializedSize()); - lenBuf.flip(); - hash.update(lenBuf); - hash.update(msg.toByteString().asReadOnlyByteBuffer()); - } - - final public void update(ByteString msg) { - hash.update(msg.asReadOnlyByteBuffer()); - } - - final public void update(byte[] msg) { - hash.update(msg); - } - - final public void update(ByteBuffer msg) { - hash.update(msg); - } - - @Override - public void reset() { - hash.reset(); - } - - @Override - public SHA256Digest clone() throws CloneNotSupportedException { - SHA256Digest copy = new SHA256Digest(false); - copy.hash = (MessageDigest) hash.clone(); - return copy; - } -} +package meerkat.crypto.concrete; + +import com.google.protobuf.ByteString; +import com.google.protobuf.Message; +import meerkat.crypto.Digest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.ByteBuffer; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * Created by talm on 11/9/15. + */ +public class SHA256Digest extends GlobalCryptoSetup implements Digest { + final Logger logger = LoggerFactory.getLogger(getClass()); + public static final String SHA256 = "SHA-256"; + + MessageDigest hash; + + /** + * Used to convert length to bytes in proper order. + */ + ByteBuffer lenBuf = ByteBuffer.allocate(4); + + /** + * Instantiate with a specified algorithm. + * @param algorithm + * @throws NoSuchAlgorithmException + */ + public SHA256Digest(String algorithm) throws NoSuchAlgorithmException { + hash = MessageDigest.getInstance(algorithm); + } + + /** + * Instantiate with the default (SHA-256) algorithm + */ + public SHA256Digest() { this(true); } + + + /**SHA + * Instantiate with the default (SHA-256) algorithm, + * or create an empty class (for cloning) + */ + private SHA256Digest(boolean initHash) { + if (initHash) { + try { + hash = MessageDigest.getInstance(SHA256); + } catch (NoSuchAlgorithmException e) { + // Should never happen! + logger.error("Couldn't find default {} algorhtm: {}", SHA256, e); + assert false; + } + } + } + + @Override + public byte[] digest() { + return hash.digest(); + } + + @Override + public void update(Message msg) { + + lenBuf.clear(); + lenBuf.putInt(msg.getSerializedSize()); + lenBuf.flip(); + hash.update(lenBuf); + hash.update(msg.toByteString().asReadOnlyByteBuffer()); + } + + final public void update(ByteString msg) { + hash.update(msg.asReadOnlyByteBuffer()); + } + + final public void update(byte[] msg) { + hash.update(msg); + } + + final public void update(ByteBuffer msg) { + hash.update(msg); + } + + @Override + public void reset() { + hash.reset(); + } + + @Override + public SHA256Digest clone() throws CloneNotSupportedException { + SHA256Digest copy = new SHA256Digest(false); + copy.hash = (MessageDigest) hash.clone(); + return copy; + } +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mix2ZeroKnowledgeProver.java b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mix2ZeroKnowledgeProver.java index 1113bfd..438cb51 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mix2ZeroKnowledgeProver.java +++ b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mix2ZeroKnowledgeProver.java @@ -1,18 +1,18 @@ -package meerkat.crypto.mixnet; - -import meerkat.protobuf.Crypto; -import meerkat.protobuf.Mixing; - -/** - * Prove in zero knowledge that two ciphertexts are a mix of two original ciphertexts. - */ -public interface Mix2ZeroKnowledgeProver { - public Mixing.ZeroKnowledgeProof prove(Crypto.RerandomizableEncryptedMessage in1, - Crypto.RerandomizableEncryptedMessage in2, - Crypto.RerandomizableEncryptedMessage out1, - Crypto.RerandomizableEncryptedMessage out2, - boolean switched, - Crypto.EncryptionRandomness r1, - Crypto.EncryptionRandomness r2); - -} +package meerkat.crypto.mixnet; + +import meerkat.protobuf.Crypto; +import meerkat.protobuf.Mixing; + +/** + * Prove in zero knowledge that two ciphertexts are a mix of two original ciphertexts. + */ +public interface Mix2ZeroKnowledgeProver { + public Mixing.ZeroKnowledgeProof prove(Crypto.RerandomizableEncryptedMessage in1, + Crypto.RerandomizableEncryptedMessage in2, + Crypto.RerandomizableEncryptedMessage out1, + Crypto.RerandomizableEncryptedMessage out2, + boolean switched, + Crypto.EncryptionRandomness r1, + Crypto.EncryptionRandomness r2); + +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mix2ZeroKnowledgeVerifier.java b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mix2ZeroKnowledgeVerifier.java index dd3c251..7fa845c 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mix2ZeroKnowledgeVerifier.java +++ b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mix2ZeroKnowledgeVerifier.java @@ -1,23 +1,23 @@ -package meerkat.crypto.mixnet; - -import meerkat.protobuf.Crypto; -import meerkat.protobuf.Mixing; - -/** - * Verify the two-ciphertext mix proof - */ -public interface Mix2ZeroKnowledgeVerifier { - /** - * Return true iff the proof is valid. - * @param in1 - * @param in2 - * @param out1 - * @param out2 - * @return - */ - boolean verify(Crypto.RerandomizableEncryptedMessage in1, - Crypto.RerandomizableEncryptedMessage in2, - Crypto.RerandomizableEncryptedMessage out1, - Crypto.RerandomizableEncryptedMessage out2, - Mixing.ZeroKnowledgeProof proof); -} +package meerkat.crypto.mixnet; + +import meerkat.protobuf.Crypto; +import meerkat.protobuf.Mixing; + +/** + * Verify the two-ciphertext mix proof + */ +public interface Mix2ZeroKnowledgeVerifier { + /** + * Return true iff the proof is valid. + * @param in1 + * @param in2 + * @param out1 + * @param out2 + * @return + */ + boolean verify(Crypto.RerandomizableEncryptedMessage in1, + Crypto.RerandomizableEncryptedMessage in2, + Crypto.RerandomizableEncryptedMessage out1, + Crypto.RerandomizableEncryptedMessage out2, + Mixing.ZeroKnowledgeProof proof); +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mixer.java b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mixer.java index 52e8844..0be60c3 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mixer.java +++ b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mixer.java @@ -1,11 +1,11 @@ -package meerkat.crypto.mixnet; - -import java.util.List; -import static meerkat.protobuf.Voting.*; - -/** - * Created by talm on 25/10/15. - */ -public interface Mixer { - public List mix(List ballots); -} +package meerkat.crypto.mixnet; + +import java.util.List; +import static meerkat.protobuf.Voting.*; + +/** + * Created by talm on 25/10/15. + */ +public interface Mixer { + public List mix(List ballots); +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Trustee.java b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Trustee.java index e8044cd..a131a65 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Trustee.java +++ b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Trustee.java @@ -1,7 +1,7 @@ -package meerkat.crypto.mixnet; - -/** - * Created by talm on 25/10/15. - */ -public class Trustee { -} +package meerkat.crypto.mixnet; + +/** + * Created by talm on 25/10/15. + */ +public class Trustee { +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Verifier.java b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Verifier.java index b733317..809678e 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Verifier.java +++ b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Verifier.java @@ -1,7 +1,7 @@ -package meerkat.crypto.mixnet; - -/** - * Created by talm on 25/10/15. - */ -public class Verifier { -} +package meerkat.crypto.mixnet; + +/** + * Created by talm on 25/10/15. + */ +public class Verifier { +} diff --git a/meerkat-common/src/main/java/meerkat/logging/LogVerifier.java b/meerkat-common/src/main/java/meerkat/logging/LogVerifier.java index 7ba928a..f27f740 100644 --- a/meerkat-common/src/main/java/meerkat/logging/LogVerifier.java +++ b/meerkat-common/src/main/java/meerkat/logging/LogVerifier.java @@ -1,7 +1,7 @@ -package meerkat.logging; - -/** - * Created by talm on 25/10/15. - */ -public class LogVerifier { -} +package meerkat.logging; + +/** + * Created by talm on 25/10/15. + */ +public class LogVerifier { +} diff --git a/meerkat-common/src/main/java/meerkat/logging/Logger.java b/meerkat-common/src/main/java/meerkat/logging/Logger.java index 343ff31..26ec424 100644 --- a/meerkat-common/src/main/java/meerkat/logging/Logger.java +++ b/meerkat-common/src/main/java/meerkat/logging/Logger.java @@ -1,7 +1,7 @@ -package meerkat.logging; - -/** - * Created by talm on 25/10/15. - */ -public class Logger { -} +package meerkat.logging; + +/** + * Created by talm on 25/10/15. + */ +public class Logger { +} diff --git a/meerkat-common/src/main/java/meerkat/util/BulletinBoardMessageComparator.java b/meerkat-common/src/main/java/meerkat/util/BulletinBoardMessageComparator.java index 77a6663..653f130 100644 --- a/meerkat-common/src/main/java/meerkat/util/BulletinBoardMessageComparator.java +++ b/meerkat-common/src/main/java/meerkat/util/BulletinBoardMessageComparator.java @@ -1,49 +1,49 @@ -package meerkat.util; - -import meerkat.protobuf.BulletinBoardAPI; -import meerkat.protobuf.BulletinBoardAPI.*; -import meerkat.protobuf.Crypto.*; - -import java.util.Comparator; -import java.util.List; - -/** - * Created by Arbel Deutsch Peled on 05-Dec-15. - * This class implements a comparison between BulletinBoardMessage instances that disregards: - * 1. The entry number (since this can be different between database instances) - * 2. The order of the signatures - */ -public class BulletinBoardMessageComparator implements Comparator { - - /** - * Compare the messages - * @param msg1 - * @param msg2 - * @return 0 if the messages are equivalent (see above) and -1 otherwise. - */ - @Override - public int compare(BulletinBoardMessage msg1, BulletinBoardMessage msg2) { - - List msg1Sigs = msg1.getSigList(); - List msg2Sigs = msg2.getSigList(); - - // Compare unsigned message - if (!msg1.getMsg().equals(msg2.getMsg())){ - return -1; - } - - // Compare signatures - - if (msg1Sigs.size() != msg2Sigs.size()){ - return -1; - } - - for (Signature sig : msg1Sigs){ - if (!msg2Sigs.contains(sig)) { - return -1; - } - } - - return 0; - } -} +package meerkat.util; + +import meerkat.protobuf.BulletinBoardAPI; +import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Crypto.*; + +import java.util.Comparator; +import java.util.List; + +/** + * Created by Arbel Deutsch Peled on 05-Dec-15. + * This class implements a comparison between BulletinBoardMessage instances that disregards: + * 1. The entry number (since this can be different between database instances) + * 2. The order of the signatures + */ +public class BulletinBoardMessageComparator implements Comparator { + + /** + * Compare the messages + * @param msg1 + * @param msg2 + * @return 0 if the messages are equivalent (see above) and -1 otherwise. + */ + @Override + public int compare(BulletinBoardMessage msg1, BulletinBoardMessage msg2) { + + List msg1Sigs = msg1.getSigList(); + List msg2Sigs = msg2.getSigList(); + + // Compare unsigned message + if (!msg1.getMsg().equals(msg2.getMsg())){ + return -1; + } + + // Compare signatures + + if (msg1Sigs.size() != msg2Sigs.size()){ + return -1; + } + + for (Signature sig : msg1Sigs){ + if (!msg2Sigs.contains(sig)) { + return -1; + } + } + + return 0; + } +} diff --git a/meerkat-common/src/main/java/meerkat/util/Hex.java b/meerkat-common/src/main/java/meerkat/util/Hex.java index 2d0e4ef..8064d7d 100644 --- a/meerkat-common/src/main/java/meerkat/util/Hex.java +++ b/meerkat-common/src/main/java/meerkat/util/Hex.java @@ -1,26 +1,26 @@ -package meerkat.util; - -import com.google.protobuf.ByteString; - -/** - * Convert to/from Hex - */ -public class Hex { - /** - * Encode a {@link ByteString} as a hex string. - * @param str - * @return - */ - public static String encode(ByteString str) { - StringBuilder s = new StringBuilder(); - for (byte b : str) { - s.append(Integer.toHexString(((int) b) & 0xff)); - } - return s.toString(); - } - - public static String encode(byte[] bytes) { - return encode(ByteString.copyFrom(bytes)); - } -} - +package meerkat.util; + +import com.google.protobuf.ByteString; + +/** + * Convert to/from Hex + */ +public class Hex { + /** + * Encode a {@link ByteString} as a hex string. + * @param str + * @return + */ + public static String encode(ByteString str) { + StringBuilder s = new StringBuilder(); + for (byte b : str) { + s.append(Integer.toHexString(((int) b) & 0xff)); + } + return s.toString(); + } + + public static String encode(byte[] bytes) { + return encode(ByteString.copyFrom(bytes)); + } +} + diff --git a/meerkat-common/src/main/java/meerkat/voting/VotingBooth.java b/meerkat-common/src/main/java/meerkat/voting/VotingBooth.java index e337a83..5f8a7cf 100644 --- a/meerkat-common/src/main/java/meerkat/voting/VotingBooth.java +++ b/meerkat-common/src/main/java/meerkat/voting/VotingBooth.java @@ -1,70 +1,70 @@ -package meerkat.voting; - -import static meerkat.protobuf.Voting.*; - -/** - * Created by talm on 25/10/15. - */ -public interface VotingBooth { - - public interface UI { - /** - * Prepare UI for a new user. - */ - void votingBegin(); - - /** - * UI must physically commit to an encrypted (or Wombat style) ballot. - * (probably by printing) - * - * When commitment is complete, should ask voter to choose between - * cast and audit. - * - * Called by votingbooth thread. - */ - void commitToEncryptedBallot(EncryptedBallot ballot); - - - /** - * Finalize a vote for casting - * Called by votingbooth in case user decides to cast. - */ - void castVote(); - - /** - * Submit audit information and spoil vote. - * Called by votingbooth in case user decides to audit - * @param ballotSecrets - */ - void auditVote(BallotSecrets ballotSecrets); - - - } - - /** - * Must be called before using any other method. - * @param globalParams global election parameters (e.g., global signing key, global encryption key) - * @param boothParams local parameters (e.g., private signature key for booth, randomness table?) - */ - void init(ElectionParams globalParams, BoothParams boothParams); - - - /** - * Called from UI thread when voter has finished making selection. - * - * Should encrypt ballot and commit. - * @param ballot - */ - void submitBallot(PlaintextBallot ballot); - - /** - * UI calls this when the user cancels the voting process in the middle. - */ - void cancelBallot(); - - /** - * Called by UI thread after voter made choice to cast or audit ballot. - * @param castVote - */ - void voterCastOrAudit(boolean castVote); -} +package meerkat.voting; + +import static meerkat.protobuf.Voting.*; + +/** + * Created by talm on 25/10/15. + */ +public interface VotingBooth { + + public interface UI { + /** + * Prepare UI for a new user. + */ + void votingBegin(); + + /** + * UI must physically commit to an encrypted (or Wombat style) ballot. + * (probably by printing) + * + * When commitment is complete, should ask voter to choose between + * cast and audit. + * + * Called by votingbooth thread. + */ + void commitToEncryptedBallot(EncryptedBallot ballot); + + + /** + * Finalize a vote for casting + * Called by votingbooth in case user decides to cast. + */ + void castVote(); + + /** + * Submit audit information and spoil vote. + * Called by votingbooth in case user decides to audit + * @param ballotSecrets + */ + void auditVote(BallotSecrets ballotSecrets); + + + } + + /** + * Must be called before using any other method. + * @param globalParams global election parameters (e.g., global signing key, global encryption key) + * @param boothParams local parameters (e.g., private signature key for booth, randomness table?) + */ + void init(ElectionParams globalParams, BoothParams boothParams); + + + /** + * Called from UI thread when voter has finished making selection. + * + * Should encrypt ballot and commit. + * @param ballot + */ + void submitBallot(PlaintextBallot ballot); + + /** + * UI calls this when the user cancels the voting process in the middle. + */ + void cancelBallot(); + + /** + * Called by UI thread after voter made choice to cast or audit ballot. + * @param castVote + */ + void voterCastOrAudit(boolean castVote); +} diff --git a/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto b/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto index 0fe35f8..e25b2d3 100644 --- a/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto +++ b/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto @@ -1,80 +1,80 @@ -syntax = "proto3"; - -package meerkat; - -option java_package = "meerkat.protobuf"; - -import 'meerkat/crypto.proto'; - -message BoolMsg { - bool value = 1; -} - -message IntMsg { - int32 value = 1; -} - -message MessageID { - // The ID of a message for unique retrieval. - // Note that it is assumed that this ID is a function of the message itself. - bytes ID = 1; -} - -message UnsignedBulletinBoardMessage { - // Optional tags describing message - repeated string tag = 1; - - // The actual content of the message - bytes data = 2; -} - -message BulletinBoardMessage { - - // Serial entry number of message in database - int64 entryNum = 1; - - // Unsigned raw data of message - UnsignedBulletinBoardMessage msg = 2; - - // Signature of message (and tags), excluding the entry number. - repeated meerkat.Signature sig = 3; -} - -message BulletinBoardMessageList { - - repeated BulletinBoardMessage message = 1; - -} - -enum FilterType { - MSG_ID = 0; // Match exact message ID - EXACT_ENTRY = 1; // Match exact entry number in database (chronological) - MAX_ENTRY = 2; // Find all entries in database up to specified entry number (chronological) - SIGNER_ID = 3; // Find all entries in database that correspond to specific signature (signer) - TAG = 4; // Find all entries in database that have a specific tag - - // NOTE: The MAX_MESSAGES filter must remain the last filter type - // This is because the condition it specifies in an SQL statement must come last in the statement - // Keeping it last here allows for easily sorting the filters and keeping the code general - MAX_MESSAGES = 5; // Return at most some specified number of messages -} - -message MessageFilter { - - FilterType type = 1; - - oneof filter{ - bytes id = 2; - int64 entry = 3; - string tag = 4; - int64 maxMessages = 5; - } -} - -message MessageFilterList { - - // Combination of filters. - // To be implemented using intersection ("AND") operations. - repeated MessageFilter filter = 1; - +syntax = "proto3"; + +package meerkat; + +option java_package = "meerkat.protobuf"; + +import 'meerkat/crypto.proto'; + +message BoolMsg { + bool value = 1; +} + +message IntMsg { + int32 value = 1; +} + +message MessageID { + // The ID of a message for unique retrieval. + // Note that it is assumed that this ID is a function of the message itself. + bytes ID = 1; +} + +message UnsignedBulletinBoardMessage { + // Optional tags describing message + repeated string tag = 1; + + // The actual content of the message + bytes data = 2; +} + +message BulletinBoardMessage { + + // Serial entry number of message in database + int64 entryNum = 1; + + // Unsigned raw data of message + UnsignedBulletinBoardMessage msg = 2; + + // Signature of message (and tags), excluding the entry number. + repeated meerkat.Signature sig = 3; +} + +message BulletinBoardMessageList { + + repeated BulletinBoardMessage message = 1; + +} + +enum FilterType { + MSG_ID = 0; // Match exact message ID + EXACT_ENTRY = 1; // Match exact entry number in database (chronological) + MAX_ENTRY = 2; // Find all entries in database up to specified entry number (chronological) + SIGNER_ID = 3; // Find all entries in database that correspond to specific signature (signer) + TAG = 4; // Find all entries in database that have a specific tag + + // NOTE: The MAX_MESSAGES filter must remain the last filter type + // This is because the condition it specifies in an SQL statement must come last in the statement + // Keeping it last here allows for easily sorting the filters and keeping the code general + MAX_MESSAGES = 5; // Return at most some specified number of messages +} + +message MessageFilter { + + FilterType type = 1; + + oneof filter{ + bytes id = 2; + int64 entry = 3; + string tag = 4; + int64 maxMessages = 5; + } +} + +message MessageFilterList { + + // Combination of filters. + // To be implemented using intersection ("AND") operations. + repeated MessageFilter filter = 1; + } \ No newline at end of file diff --git a/meerkat-common/src/main/proto/meerkat/DKGMessages.proto b/meerkat-common/src/main/proto/meerkat/DKGMessages.proto index a13c8a7..81072e9 100644 --- a/meerkat-common/src/main/proto/meerkat/DKGMessages.proto +++ b/meerkat-common/src/main/proto/meerkat/DKGMessages.proto @@ -1,48 +1,48 @@ -syntax = "proto3"; - -package meerkat; - -option java_package = "meerkat.protobuf"; - -message Mail{ - enum Type { - SECRET = 0; - COMMITMENT = 1; - COMPLAINT = 2; - DONE = 3; - ANSWER = 4; - YCOMMITMENT = 5; - YCOMPLAINT = 6; - YANSWER = 7; - ABORT = 8; - } - int32 sender = 1; - int32 destination = 2; - bool isPrivate = 3; - Type type = 4; - bytes message = 5; -} - -message SecretMessage { - int32 i = 1; - int32 j = 2; - bytes secret = 3; -} - -message DoubleSecretMessage{ - int32 i = 1; - int32 j = 2; - bytes secret = 3; - bytes secretT = 4; -} - -message CommitmentMessage{ - int32 k = 1; - bytes commitment = 2; -} - -message EmptyMessage{} - -message IDMessage{ - int32 id = 1; -} +syntax = "proto3"; + +package meerkat; + +option java_package = "meerkat.protobuf"; + +message Mail{ + enum Type { + SECRET = 0; + COMMITMENT = 1; + COMPLAINT = 2; + DONE = 3; + ANSWER = 4; + YCOMMITMENT = 5; + YCOMPLAINT = 6; + YANSWER = 7; + ABORT = 8; + } + int32 sender = 1; + int32 destination = 2; + bool isPrivate = 3; + Type type = 4; + bytes message = 5; +} + +message SecretMessage { + int32 i = 1; + int32 j = 2; + bytes secret = 3; +} + +message DoubleSecretMessage{ + int32 i = 1; + int32 j = 2; + bytes secret = 3; + bytes secretT = 4; +} + +message CommitmentMessage{ + int32 k = 1; + bytes commitment = 2; +} + +message EmptyMessage{} + +message IDMessage{ + int32 id = 1; +} diff --git a/meerkat-common/src/main/proto/meerkat/concrete_crypto.proto b/meerkat-common/src/main/proto/meerkat/concrete_crypto.proto index d8c40d3..9f1f818 100644 --- a/meerkat-common/src/main/proto/meerkat/concrete_crypto.proto +++ b/meerkat-common/src/main/proto/meerkat/concrete_crypto.proto @@ -1,22 +1,22 @@ -// Protobufs for specific crypto primitives - -syntax = "proto3"; - -package meerkat; - -import 'meerkat/crypto.proto'; - -option java_package = "meerkat.protobuf"; - - -message ElGamalPublicKey { - // DER-encoded SubjectPublicKeyInfo as in RFC 3279 - bytes subject_public_key_info = 1; -} - -// An El-Gamal ciphertext -// Each group element should be an ASN.1 encoded curve point with compression. -message ElGamalCiphertext { - bytes c1 = 1; // First group element - bytes c2 = 2; // Second group element +// Protobufs for specific crypto primitives + +syntax = "proto3"; + +package meerkat; + +import 'meerkat/crypto.proto'; + +option java_package = "meerkat.protobuf"; + + +message ElGamalPublicKey { + // DER-encoded SubjectPublicKeyInfo as in RFC 3279 + bytes subject_public_key_info = 1; +} + +// An El-Gamal ciphertext +// Each group element should be an ASN.1 encoded curve point with compression. +message ElGamalCiphertext { + bytes c1 = 1; // First group element + bytes c2 = 2; // Second group element } \ No newline at end of file diff --git a/meerkat-common/src/main/proto/meerkat/crypto.proto b/meerkat-common/src/main/proto/meerkat/crypto.proto index eeec159..3b3e906 100644 --- a/meerkat-common/src/main/proto/meerkat/crypto.proto +++ b/meerkat-common/src/main/proto/meerkat/crypto.proto @@ -1,54 +1,54 @@ -syntax = "proto3"; - -package meerkat; - -option java_package = "meerkat.protobuf"; - -enum SignatureType { - ECDSA = 0; - DSA = 1; -} - -message BigInteger { - bytes data = 1; -} - -// A digital signature -message Signature { - SignatureType type = 1; - - // Data encoding depends on type; default is DER-encoded - bytes data = 2; - - // ID of the signer (should be the fingerprint of the signature verification key) - bytes signer_id = 3; -} - -// Public key used to verify signatures -message SignatureVerificationKey { - SignatureType type = 1; - - // Data encoding depends on type; default is x509 DER-encoded - bytes data = 2; -} - -// A public encryption key -message EncryptionPublicKey { - bytes data = 1; -} - -// Randomness used for encryption -message EncryptionRandomness { - bytes data = 1; -} - -// A proof that randomness is correctly generated -message RandomnessGenerationProof { - bytes data = 1; -} - -// An encrypted message (rerandomizable) -message RerandomizableEncryptedMessage { - bytes data = 1; -} - +syntax = "proto3"; + +package meerkat; + +option java_package = "meerkat.protobuf"; + +enum SignatureType { + ECDSA = 0; + DSA = 1; +} + +message BigInteger { + bytes data = 1; +} + +// A digital signature +message Signature { + SignatureType type = 1; + + // Data encoding depends on type; default is DER-encoded + bytes data = 2; + + // ID of the signer (should be the fingerprint of the signature verification key) + bytes signer_id = 3; +} + +// Public key used to verify signatures +message SignatureVerificationKey { + SignatureType type = 1; + + // Data encoding depends on type; default is x509 DER-encoded + bytes data = 2; +} + +// A public encryption key +message EncryptionPublicKey { + bytes data = 1; +} + +// Randomness used for encryption +message EncryptionRandomness { + bytes data = 1; +} + +// A proof that randomness is correctly generated +message RandomnessGenerationProof { + bytes data = 1; +} + +// An encrypted message (rerandomizable) +message RerandomizableEncryptedMessage { + bytes data = 1; +} + diff --git a/meerkat-common/src/main/proto/meerkat/mixing.proto b/meerkat-common/src/main/proto/meerkat/mixing.proto index 50cffc7..2d5d6da 100644 --- a/meerkat-common/src/main/proto/meerkat/mixing.proto +++ b/meerkat-common/src/main/proto/meerkat/mixing.proto @@ -1,12 +1,12 @@ -syntax = "proto3"; - -package meerkat; - -option java_package = "meerkat.protobuf"; - -import 'meerkat/crypto.proto'; - -// TODO: -message ZeroKnowledgeProof { - bytes data = 1; +syntax = "proto3"; + +package meerkat; + +option java_package = "meerkat.protobuf"; + +import 'meerkat/crypto.proto'; + +// TODO: +message ZeroKnowledgeProof { + bytes data = 1; } \ No newline at end of file diff --git a/meerkat-common/src/main/proto/meerkat/voting.proto b/meerkat-common/src/main/proto/meerkat/voting.proto index 9837cce..f539ab8 100644 --- a/meerkat-common/src/main/proto/meerkat/voting.proto +++ b/meerkat-common/src/main/proto/meerkat/voting.proto @@ -1,90 +1,90 @@ -syntax = "proto3"; - -package meerkat; - -import 'meerkat/crypto.proto'; - -option java_package = "meerkat.protobuf"; - -// A ballot question. This is an opaque -// data type that is parsed by the UI to display -// the question. -message BallotQuestion { - bytes data = 1; -} - -// An answer to a specific ballot question. -// The answer is a vector of signed integers, -// to encompass voting schemes such as ranked voting -// and STV. -message BallotAnswer { - repeated sint64 answer = 1 [packed=true]; -} - -message PlaintextBallot { - uint64 serialNumber = 1; // Ballot serial number - - repeated BallotAnswer answers = 2; -} - -message EncryptedBallot { - uint64 serialNumber = 1; // Ballot serial number - - RerandomizableEncryptedMessage data = 2; -} - -message BallotSecrets { - PlaintextBallot plaintext_ballot = 1; - - EncryptionRandomness encryption_randomness = 2; - RandomnessGenerationProof proof = 3; -} - -message BoothParams { - repeated SignatureVerificationKey pscVerificationKeys = 1; - -} - -// A table to translate to and from compactly encoded answers -// and their human-understandable counterparts. -// This should be parsable by the UI -message BallotAnswerTranslationTable { - bytes data = 1; -} - -// Data required in order to access the Bulletin Board Servers -message BulletinBoardClientParams { - - // Addresses of all Bulletin Board Servers - repeated string bulletinBoardAddress = 1; - - // Threshold fraction of successful servers posts before a post task is considered complete - float minRedundancy = 2; -} - -message ElectionParams { - // TODO: different sets of keys for different roles? - repeated SignatureVerificationKey trusteeVerificationKeys = 1; - - // How many trustees must participate in a signature for it to be considered valid. - uint32 trusteeSignatureThreshold = 2; - - // The key used to encrypt ballots. The corresponding private key - // is shared between the trustees. - EncryptionPublicKey ballotEncryptionKey = 3; - - // Verification keys for valid mixers. - repeated SignatureVerificationKey mixerVerificationKeys = 4; - - // How many mixers must participate for the mixing to be considered valid - uint32 mixerThreshold = 5; - - // Candidate list (or other question format) - repeated BallotQuestion questions = 6; - - // Translation table between answers and plaintext encoding - BallotAnswerTranslationTable answerTranslationTable = 7; - - // Data required in order to access the Bulletin Board Servers - BulletinBoardClientParams bulletinBoardClientParams = 8; -} +syntax = "proto3"; + +package meerkat; + +import 'meerkat/crypto.proto'; + +option java_package = "meerkat.protobuf"; + +// A ballot question. This is an opaque +// data type that is parsed by the UI to display +// the question. +message BallotQuestion { + bytes data = 1; +} + +// An answer to a specific ballot question. +// The answer is a vector of signed integers, +// to encompass voting schemes such as ranked voting +// and STV. +message BallotAnswer { + repeated sint64 answer = 1 [packed=true]; +} + +message PlaintextBallot { + uint64 serialNumber = 1; // Ballot serial number + + repeated BallotAnswer answers = 2; +} + +message EncryptedBallot { + uint64 serialNumber = 1; // Ballot serial number + + RerandomizableEncryptedMessage data = 2; +} + +message BallotSecrets { + PlaintextBallot plaintext_ballot = 1; + + EncryptionRandomness encryption_randomness = 2; + RandomnessGenerationProof proof = 3; +} + +message BoothParams { + repeated SignatureVerificationKey pscVerificationKeys = 1; + +} + +// A table to translate to and from compactly encoded answers +// and their human-understandable counterparts. +// This should be parsable by the UI +message BallotAnswerTranslationTable { + bytes data = 1; +} + +// Data required in order to access the Bulletin Board Servers +message BulletinBoardClientParams { + + // Addresses of all Bulletin Board Servers + repeated string bulletinBoardAddress = 1; + + // Threshold fraction of successful servers posts before a post task is considered complete + float minRedundancy = 2; +} + +message ElectionParams { + // TODO: different sets of keys for different roles? + repeated SignatureVerificationKey trusteeVerificationKeys = 1; + + // How many trustees must participate in a signature for it to be considered valid. + uint32 trusteeSignatureThreshold = 2; + + // The key used to encrypt ballots. The corresponding private key + // is shared between the trustees. + EncryptionPublicKey ballotEncryptionKey = 3; + + // Verification keys for valid mixers. + repeated SignatureVerificationKey mixerVerificationKeys = 4; + + // How many mixers must participate for the mixing to be considered valid + uint32 mixerThreshold = 5; + + // Candidate list (or other question format) + repeated BallotQuestion questions = 6; + + // Translation table between answers and plaintext encoding + BallotAnswerTranslationTable answerTranslationTable = 7; + + // Data required in order to access the Bulletin Board Servers + BulletinBoardClientParams bulletinBoardClientParams = 8; +} diff --git a/meerkat-common/src/main/resources/logback.groovy b/meerkat-common/src/main/resources/logback.groovy index 076b6c4..85fa80d 100644 --- a/meerkat-common/src/main/resources/logback.groovy +++ b/meerkat-common/src/main/resources/logback.groovy @@ -1,46 +1,46 @@ - - -import ch.qos.logback.classic.encoder.PatternLayoutEncoder -import ch.qos.logback.classic.filter.ThresholdFilter -import ch.qos.logback.core.ConsoleAppender -import ch.qos.logback.core.util.Duration -import static ch.qos.logback.classic.Level.* - -if (System.getProperty("log.debug") != null) { - println "Logback configuration debugging enabled" - - statusListener(OnConsoleStatusListener) -} - -def LOG_LEVEL = toLevel(System.getProperty("log.level"), INFO) - -def haveBeagle = System.getProperty("log.beagle") != null -def logOps = System.getProperty("log.ops") != null - -appender("CONSOLE", ConsoleAppender) { - - filter(ThresholdFilter) { - level = toLevel(System.getProperty("log.level"), TRACE) - } - - encoder(PatternLayoutEncoder) { - pattern = "%d{HH:mm:ss.SSS} [%thread %file:%line] %-5level %logger{0} - %msg%n" - } -} - -def appenders = [ "CONSOLE" ] - -if (haveBeagle) { - appender("SOCKET", SocketAppender) { - includeCallerData = true - remoteHost = "localhost" - port = 4321 - reconnectionDelay = new Duration(10000) - } - - appenders += ["SOCKET"] -} - -root(LOG_LEVEL, appenders) - - + + +import ch.qos.logback.classic.encoder.PatternLayoutEncoder +import ch.qos.logback.classic.filter.ThresholdFilter +import ch.qos.logback.core.ConsoleAppender +import ch.qos.logback.core.util.Duration +import static ch.qos.logback.classic.Level.* + +if (System.getProperty("log.debug") != null) { + println "Logback configuration debugging enabled" + + statusListener(OnConsoleStatusListener) +} + +def LOG_LEVEL = toLevel(System.getProperty("log.level"), INFO) + +def haveBeagle = System.getProperty("log.beagle") != null +def logOps = System.getProperty("log.ops") != null + +appender("CONSOLE", ConsoleAppender) { + + filter(ThresholdFilter) { + level = toLevel(System.getProperty("log.level"), TRACE) + } + + encoder(PatternLayoutEncoder) { + pattern = "%d{HH:mm:ss.SSS} [%thread %file:%line] %-5level %logger{0} - %msg%n" + } +} + +def appenders = [ "CONSOLE" ] + +if (haveBeagle) { + appender("SOCKET", SocketAppender) { + includeCallerData = true + remoteHost = "localhost" + port = 4321 + reconnectionDelay = new Duration(10000) + } + + appenders += ["SOCKET"] +} + +root(LOG_LEVEL, appenders) + + diff --git a/meerkat-common/src/test/java/meerkat/crypto/concrete/ECDSADeterministicSignatureTest.java b/meerkat-common/src/test/java/meerkat/crypto/concrete/ECDSADeterministicSignatureTest.java index cc41497..cefc1b2 100644 --- a/meerkat-common/src/test/java/meerkat/crypto/concrete/ECDSADeterministicSignatureTest.java +++ b/meerkat-common/src/test/java/meerkat/crypto/concrete/ECDSADeterministicSignatureTest.java @@ -1,50 +1,50 @@ -package meerkat.crypto.concrete; - -import com.google.protobuf.ByteString; -import com.google.protobuf.Message; - -import meerkat.crypto.concrete.ECDSASignature; -import meerkat.protobuf.Crypto; -import org.junit.Test; - -import java.math.BigInteger; -import static org.junit.Assert.*; - -/** - * Created by talm on 12/11/15. - */ -public class ECDSADeterministicSignatureTest extends ECDSASignatureTest { - - @Override - protected ECDSASignature getSigner() { return new ECDSADeterministicSignature(); } - - - /** - * Make sure signatures don't vary - */ - @Test - public void testDeterministicSigning() throws Exception { - loadSigningKeys(); - - - for (int i = 0; i < REPEAT_COUNT; ++i) { - BigInteger rawMsg = new BigInteger(50, rand); - Message msg = Crypto.BigInteger.newBuilder() - .setData(ByteString.copyFrom(rawMsg.toByteArray())).build(); - Crypto.Signature[] sigs = new Crypto.Signature[REPEAT_COUNT]; - - signer.updateContent(msg); - sigs[0] = signer.sign(); - byte[] canonicalSig = sigs[0].toByteArray(); - - for (int j = 1; j < sigs.length; ++j) { - signer.updateContent(msg); - sigs[j] = signer.sign(); - - byte[] newSig = sigs[j].toByteArray(); - - assertArrayEquals("Signatures on same message differ (i="+i+",j="+j+")", canonicalSig, newSig); - } - } - } -} +package meerkat.crypto.concrete; + +import com.google.protobuf.ByteString; +import com.google.protobuf.Message; + +import meerkat.crypto.concrete.ECDSASignature; +import meerkat.protobuf.Crypto; +import org.junit.Test; + +import java.math.BigInteger; +import static org.junit.Assert.*; + +/** + * Created by talm on 12/11/15. + */ +public class ECDSADeterministicSignatureTest extends ECDSASignatureTest { + + @Override + protected ECDSASignature getSigner() { return new ECDSADeterministicSignature(); } + + + /** + * Make sure signatures don't vary + */ + @Test + public void testDeterministicSigning() throws Exception { + loadSigningKeys(); + + + for (int i = 0; i < REPEAT_COUNT; ++i) { + BigInteger rawMsg = new BigInteger(50, rand); + Message msg = Crypto.BigInteger.newBuilder() + .setData(ByteString.copyFrom(rawMsg.toByteArray())).build(); + Crypto.Signature[] sigs = new Crypto.Signature[REPEAT_COUNT]; + + signer.updateContent(msg); + sigs[0] = signer.sign(); + byte[] canonicalSig = sigs[0].toByteArray(); + + for (int j = 1; j < sigs.length; ++j) { + signer.updateContent(msg); + sigs[j] = signer.sign(); + + byte[] newSig = sigs[j].toByteArray(); + + assertArrayEquals("Signatures on same message differ (i="+i+",j="+j+")", canonicalSig, newSig); + } + } + } +} diff --git a/meerkat-common/src/test/java/meerkat/crypto/concrete/ECDSASignatureTest.java b/meerkat-common/src/test/java/meerkat/crypto/concrete/ECDSASignatureTest.java index 37c2d1b..327292a 100644 --- a/meerkat-common/src/test/java/meerkat/crypto/concrete/ECDSASignatureTest.java +++ b/meerkat-common/src/test/java/meerkat/crypto/concrete/ECDSASignatureTest.java @@ -1,220 +1,220 @@ -package meerkat.crypto.concrete; - -import com.google.protobuf.ByteString; -import com.google.protobuf.Message; -import meerkat.protobuf.Crypto; -import meerkat.crypto.concrete.ECDSASignature; -import org.junit.Before; -import org.junit.Test; - -import java.io.InputStream; -import java.math.BigInteger; -import java.security.KeyStore; -import java.util.Random; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -/** - * Created by talm on 12/11/15. - */ -public class ECDSASignatureTest { - public static String KEYFILE_EXAMPLE = "/certs/enduser-certs/user1-key-with-password-secret.p12"; - public static String KEYFILE_PASSWORD = "secret"; - - public static String CERT1_PEM_EXAMPLE = "/certs/enduser-certs/user1.crt"; - public static String CERT2_DER_EXAMPLE = "/certs/enduser-certs/user2.der"; - - public static String MSG_PLAINTEXT_EXAMPLE = "/certs/signed-messages/helloworld.txt"; - public static String MSG_SIG_EXAMPLE = "/certs/signed-messages/helloworld.txt.sha256sig"; - - public static String HELLO_WORLD = "hello world!"; - - public final static int REPEAT_COUNT = 10; - - Random rand = new Random(0); - - protected ECDSASignature signer; - - protected ECDSASignature getSigner() { return new ECDSASignature(); } - - @Before - public void setup() throws Exception { - signer = getSigner(); - } - - @Test - public void loadSignatureKey() throws Exception { - InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE); - char[] password = KEYFILE_PASSWORD.toCharArray(); - - KeyStore.Builder keyStore = signer.getPKCS12KeyStoreBuilder(keyStream, password); - signer.loadSigningCertificate(keyStore); - keyStream.close(); - } - - @Test - public void loadPEMVerificationKey() throws Exception { - InputStream certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE); - - signer.loadVerificationCertificates(certStream); - certStream.close(); - } - - @Test - public void loadDERVerificationKey() throws Exception { - InputStream certStream = getClass().getResourceAsStream(CERT2_DER_EXAMPLE); - - signer.loadVerificationCertificates(certStream); - certStream.close(); - } - - - @Test - public void verifyValidSig() throws Exception { - InputStream certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE); - InputStream msgStream = getClass().getResourceAsStream(MSG_PLAINTEXT_EXAMPLE); - InputStream sigStream = getClass().getResourceAsStream(MSG_SIG_EXAMPLE); - - signer.loadVerificationCertificates(certStream); - certStream.close(); - - Crypto.Signature.Builder sig = Crypto.Signature.newBuilder(); - sig.setType(Crypto.SignatureType.ECDSA); - sig.setSignerId(signer.loadedCertificates.entrySet().iterator().next().getKey()); - sig.setData(ByteString.readFrom(sigStream)); - - Crypto.Signature builtSig = sig.build(); - signer.initVerify(builtSig); - signer.updateContent(msgStream); - assertTrue("Signature did not verify!", signer.verify()); - } - - @Test - public void verifyInvalidSig() throws Exception { - InputStream certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE); - InputStream msgStream = getClass().getResourceAsStream(MSG_PLAINTEXT_EXAMPLE); - InputStream sigStream = getClass().getResourceAsStream(MSG_SIG_EXAMPLE); - - signer.loadVerificationCertificates(certStream); - certStream.close(); - - Crypto.Signature.Builder sig = Crypto.Signature.newBuilder(); - sig.setType(Crypto.SignatureType.ECDSA); - sig.setSignerId(signer.loadedCertificates.entrySet().iterator().next().getKey()); - byte[] sigData = ByteString.readFrom(sigStream).toByteArray(); - ++sigData[0]; - - sig.setData(ByteString.copyFrom(sigData)); - - - Crypto.Signature builtSig = sig.build(); - signer.initVerify(builtSig); - signer.updateContent(msgStream); - assertFalse("Bad Signature passed verification!", signer.verify()); - } - - - @Test - public void verifyInvalidMsg() throws Exception { - InputStream certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE); - InputStream msgStream = getClass().getResourceAsStream(MSG_PLAINTEXT_EXAMPLE); - InputStream sigStream = getClass().getResourceAsStream(MSG_SIG_EXAMPLE); - - signer.loadVerificationCertificates(certStream); - certStream.close(); - - Crypto.Signature.Builder sig = Crypto.Signature.newBuilder(); - sig.setType(Crypto.SignatureType.ECDSA); - sig.setSignerId(signer.loadedCertificates.entrySet().iterator().next().getKey()); - sig.setData(ByteString.readFrom(sigStream)); - byte[] msgData = ByteString.readFrom(msgStream).toByteArray(); - ++msgData[0]; - - Crypto.Signature builtSig = sig.build(); - signer.initVerify(builtSig); - signer.updateContent(msgStream); - assertFalse("Signature doesn't match message but passed verification!", signer.verify()); - } - - - - protected void loadSigningKeys() throws Exception { - InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE); - char[] password = KEYFILE_PASSWORD.toCharArray(); - - KeyStore.Builder keyStore = signer.getPKCS12KeyStoreBuilder(keyStream, password); - signer.loadSigningCertificate(keyStore); - } - - @Test - public void signAndVerify() throws Exception { - loadSigningKeys(); - - BigInteger rawMsg = new BigInteger(50, rand); - Crypto.BigInteger usMsg = Crypto.BigInteger.newBuilder() - .setData(ByteString.copyFrom(rawMsg.toByteArray())).build(); - - signer.updateContent(usMsg); - Crypto.Signature sig = signer.sign(); - - signer.loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE)); - - signer.initVerify(sig); - signer.updateContent(usMsg); - assertTrue("Couldn't verify signature on ", signer.verify()); - } - - - @Test - public void signMultipleAndVerify() throws Exception { - loadSigningKeys(); - - Message[] msgs = new Message[REPEAT_COUNT]; - for (int i = 0; i < msgs.length; ++i) { - - BigInteger rawMsg = new BigInteger(50, rand); - msgs[i] = Crypto.BigInteger.newBuilder() - .setData(ByteString.copyFrom(rawMsg.toByteArray())).build(); - signer.updateContent(msgs[i]); - } - - Crypto.Signature sig = signer.sign(); - - signer.loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE)); - - signer.initVerify(sig); - for (int i = 0; i < msgs.length; ++i) { - signer.updateContent(msgs[i]); - } - assertTrue("Couldn't verify signature on ", signer.verify()); - } - - @Test - public void multipleSignAndVerify() throws Exception { - loadSigningKeys(); - - Message[] msgs = new Message[REPEAT_COUNT]; - Crypto.Signature[] sigs = new Crypto.Signature[REPEAT_COUNT]; - for (int i = 0; i < msgs.length; ++i) { - BigInteger rawMsg = new BigInteger(50, rand); - msgs[i] = Crypto.BigInteger.newBuilder() - .setData(ByteString.copyFrom(rawMsg.toByteArray())).build(); - signer.updateContent(msgs[i]); - sigs[i] = signer.sign(); - } - - signer.loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE)); - - - for (int i = 0; i < msgs.length; ++i) { - signer.initVerify(sigs[i]); - signer.updateContent(msgs[i]); - assertTrue("Couldn't verify signature on ", signer.verify()); - } - - } - - - -} +package meerkat.crypto.concrete; + +import com.google.protobuf.ByteString; +import com.google.protobuf.Message; +import meerkat.protobuf.Crypto; +import meerkat.crypto.concrete.ECDSASignature; +import org.junit.Before; +import org.junit.Test; + +import java.io.InputStream; +import java.math.BigInteger; +import java.security.KeyStore; +import java.util.Random; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * Created by talm on 12/11/15. + */ +public class ECDSASignatureTest { + public static String KEYFILE_EXAMPLE = "/certs/enduser-certs/user1-key-with-password-secret.p12"; + public static String KEYFILE_PASSWORD = "secret"; + + public static String CERT1_PEM_EXAMPLE = "/certs/enduser-certs/user1.crt"; + public static String CERT2_DER_EXAMPLE = "/certs/enduser-certs/user2.der"; + + public static String MSG_PLAINTEXT_EXAMPLE = "/certs/signed-messages/helloworld.txt"; + public static String MSG_SIG_EXAMPLE = "/certs/signed-messages/helloworld.txt.sha256sig"; + + public static String HELLO_WORLD = "hello world!"; + + public final static int REPEAT_COUNT = 10; + + Random rand = new Random(0); + + protected ECDSASignature signer; + + protected ECDSASignature getSigner() { return new ECDSASignature(); } + + @Before + public void setup() throws Exception { + signer = getSigner(); + } + + @Test + public void loadSignatureKey() throws Exception { + InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE); + char[] password = KEYFILE_PASSWORD.toCharArray(); + + KeyStore.Builder keyStore = signer.getPKCS12KeyStoreBuilder(keyStream, password); + signer.loadSigningCertificate(keyStore); + keyStream.close(); + } + + @Test + public void loadPEMVerificationKey() throws Exception { + InputStream certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE); + + signer.loadVerificationCertificates(certStream); + certStream.close(); + } + + @Test + public void loadDERVerificationKey() throws Exception { + InputStream certStream = getClass().getResourceAsStream(CERT2_DER_EXAMPLE); + + signer.loadVerificationCertificates(certStream); + certStream.close(); + } + + + @Test + public void verifyValidSig() throws Exception { + InputStream certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE); + InputStream msgStream = getClass().getResourceAsStream(MSG_PLAINTEXT_EXAMPLE); + InputStream sigStream = getClass().getResourceAsStream(MSG_SIG_EXAMPLE); + + signer.loadVerificationCertificates(certStream); + certStream.close(); + + Crypto.Signature.Builder sig = Crypto.Signature.newBuilder(); + sig.setType(Crypto.SignatureType.ECDSA); + sig.setSignerId(signer.loadedCertificates.entrySet().iterator().next().getKey()); + sig.setData(ByteString.readFrom(sigStream)); + + Crypto.Signature builtSig = sig.build(); + signer.initVerify(builtSig); + signer.updateContent(msgStream); + assertTrue("Signature did not verify!", signer.verify()); + } + + @Test + public void verifyInvalidSig() throws Exception { + InputStream certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE); + InputStream msgStream = getClass().getResourceAsStream(MSG_PLAINTEXT_EXAMPLE); + InputStream sigStream = getClass().getResourceAsStream(MSG_SIG_EXAMPLE); + + signer.loadVerificationCertificates(certStream); + certStream.close(); + + Crypto.Signature.Builder sig = Crypto.Signature.newBuilder(); + sig.setType(Crypto.SignatureType.ECDSA); + sig.setSignerId(signer.loadedCertificates.entrySet().iterator().next().getKey()); + byte[] sigData = ByteString.readFrom(sigStream).toByteArray(); + ++sigData[0]; + + sig.setData(ByteString.copyFrom(sigData)); + + + Crypto.Signature builtSig = sig.build(); + signer.initVerify(builtSig); + signer.updateContent(msgStream); + assertFalse("Bad Signature passed verification!", signer.verify()); + } + + + @Test + public void verifyInvalidMsg() throws Exception { + InputStream certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE); + InputStream msgStream = getClass().getResourceAsStream(MSG_PLAINTEXT_EXAMPLE); + InputStream sigStream = getClass().getResourceAsStream(MSG_SIG_EXAMPLE); + + signer.loadVerificationCertificates(certStream); + certStream.close(); + + Crypto.Signature.Builder sig = Crypto.Signature.newBuilder(); + sig.setType(Crypto.SignatureType.ECDSA); + sig.setSignerId(signer.loadedCertificates.entrySet().iterator().next().getKey()); + sig.setData(ByteString.readFrom(sigStream)); + byte[] msgData = ByteString.readFrom(msgStream).toByteArray(); + ++msgData[0]; + + Crypto.Signature builtSig = sig.build(); + signer.initVerify(builtSig); + signer.updateContent(msgStream); + assertFalse("Signature doesn't match message but passed verification!", signer.verify()); + } + + + + protected void loadSigningKeys() throws Exception { + InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE); + char[] password = KEYFILE_PASSWORD.toCharArray(); + + KeyStore.Builder keyStore = signer.getPKCS12KeyStoreBuilder(keyStream, password); + signer.loadSigningCertificate(keyStore); + } + + @Test + public void signAndVerify() throws Exception { + loadSigningKeys(); + + BigInteger rawMsg = new BigInteger(50, rand); + Crypto.BigInteger usMsg = Crypto.BigInteger.newBuilder() + .setData(ByteString.copyFrom(rawMsg.toByteArray())).build(); + + signer.updateContent(usMsg); + Crypto.Signature sig = signer.sign(); + + signer.loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE)); + + signer.initVerify(sig); + signer.updateContent(usMsg); + assertTrue("Couldn't verify signature on ", signer.verify()); + } + + + @Test + public void signMultipleAndVerify() throws Exception { + loadSigningKeys(); + + Message[] msgs = new Message[REPEAT_COUNT]; + for (int i = 0; i < msgs.length; ++i) { + + BigInteger rawMsg = new BigInteger(50, rand); + msgs[i] = Crypto.BigInteger.newBuilder() + .setData(ByteString.copyFrom(rawMsg.toByteArray())).build(); + signer.updateContent(msgs[i]); + } + + Crypto.Signature sig = signer.sign(); + + signer.loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE)); + + signer.initVerify(sig); + for (int i = 0; i < msgs.length; ++i) { + signer.updateContent(msgs[i]); + } + assertTrue("Couldn't verify signature on ", signer.verify()); + } + + @Test + public void multipleSignAndVerify() throws Exception { + loadSigningKeys(); + + Message[] msgs = new Message[REPEAT_COUNT]; + Crypto.Signature[] sigs = new Crypto.Signature[REPEAT_COUNT]; + for (int i = 0; i < msgs.length; ++i) { + BigInteger rawMsg = new BigInteger(50, rand); + msgs[i] = Crypto.BigInteger.newBuilder() + .setData(ByteString.copyFrom(rawMsg.toByteArray())).build(); + signer.updateContent(msgs[i]); + sigs[i] = signer.sign(); + } + + signer.loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE)); + + + for (int i = 0; i < msgs.length; ++i) { + signer.initVerify(sigs[i]); + signer.updateContent(msgs[i]); + assertTrue("Couldn't verify signature on ", signer.verify()); + } + + } + + + +} diff --git a/meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalEncryptionTest.java b/meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalEncryptionTest.java index 81375e0..a911b96 100644 --- a/meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalEncryptionTest.java +++ b/meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalEncryptionTest.java @@ -1,122 +1,122 @@ -package meerkat.crypto.concrete; - -import meerkat.protobuf.ConcreteCrypto; -import meerkat.protobuf.Crypto; -import meerkat.protobuf.Voting; -import org.bouncycastle.math.ec.ECPoint; -import org.junit.Before; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.factcenter.qilin.primitives.concrete.ECElGamal; -import org.factcenter.qilin.primitives.concrete.ECGroup; -import org.factcenter.qilin.util.Pair; - -import java.math.BigInteger; -import java.util.Random; - -import static org.junit.Assert.*; - -/** - * Test class for {@link ECElGamalEncryption} - */ -public class ECElGamalEncryptionTest { - final Logger logger = LoggerFactory.getLogger(getClass()); - /** - * Number of times to repeat probabilistic tests. - */ - public final static int CONFIDENCE = 10; - - Random rand = new Random(0); // Insecure deterministic random for testing. - - ECElGamal.SK key; - ECGroup group; - ECElGamalEncryption enc; - ConcreteCrypto.ElGamalPublicKey serializedPk; - - - @Before - public void setup() throws Exception { - group = new ECGroup("secp256k1"); - BigInteger sk = ECElGamal.generateSecretKey(group, rand); - key = new ECElGamal.SK(group, sk); - serializedPk = ECElGamalUtils.serializePk(group, key); - - - enc = new ECElGamalEncryption(); - - enc.init(serializedPk); - } - - - Voting.PlaintextBallot genRandomBallot(int numQuestions, int numAnswers, int maxAnswer) { - Voting.PlaintextBallot.Builder ballot = Voting.PlaintextBallot.newBuilder(); - ballot.setSerialNumber(rand.nextInt(1000000)); - for (int i = 0; i < numQuestions; ++i) { - Voting.BallotAnswer.Builder answers = ballot.addAnswersBuilder(); - for (int j = 0; j < numAnswers; ++j) { - answers.addAnswer(rand.nextInt(maxAnswer)); - } - } - return ballot.build(); - } - - /** - * Testing just the key management - * @throws Exception - */ - @Test - public void testPkSerialization() throws Exception { - ECElGamal.PK pk = enc.getElGamalPK(); - - ECPoint point = enc.getGroup().sample(rand); - Pair cipher = pk.encrypt(point, pk.getRandom(rand)); - - ECPoint decrypted = key.decrypt(cipher); - - assertEquals("Decrypted value not equal to encrypted value!", point, decrypted); - } - - @Test - public void testEncryption() throws Exception { - for (int i = 0; i < CONFIDENCE; ++i) { - Voting.PlaintextBallot msg = genRandomBallot(2,3,16); // 2 questions with 3 answers each, in range 0-15. - if (msg.getSerializedSize() > enc.getGroup().getInjectiveEncodeMsgLength()) { - logger.error("Test Message too big (|msg|={} > max={}), expect failure.", - msg.getSerializedSize(), enc.getGroup().getInjectiveEncodeMsgLength()); - } - - Crypto.RerandomizableEncryptedMessage cipherText = enc.encrypt(msg, enc.generateRandomness(rand)); - - Voting.PlaintextBallot decrypted = ECElGamalUtils.decrypt(Voting.PlaintextBallot.class, key, group, cipherText); - - assertEquals("Decrypted value differs from encrypted value (i="+i+")!", msg, decrypted); - } - } - - @Test - public void testRerandomizeModifiesCiphertext() throws Exception { - Voting.PlaintextBallot msg = genRandomBallot(2,3,16); // 2 questions with 3 answers each, in range 0-15. - Crypto.RerandomizableEncryptedMessage cipher1 = enc.encrypt(msg, enc.generateRandomness(rand)); - Crypto.RerandomizableEncryptedMessage cipher2 = enc.rerandomize(cipher1, enc.generateRandomness(rand)); - assertNotEquals("Rerandomized cipher identical to original!", cipher1, cipher2); - } - - @Test - public void testRerandomizePreservesPlaintext() throws Exception { - for (int i = 0; i < CONFIDENCE; ++i) { - Voting.PlaintextBallot msg = genRandomBallot(2,3,16); // 2 questions with 3 answers each, in range 0-15. - - Crypto.RerandomizableEncryptedMessage cipher = enc.encrypt(msg, enc.generateRandomness(rand)); - Crypto.RerandomizableEncryptedMessage cipher2 = cipher; - for (int j = 0; j < CONFIDENCE; ++j) - cipher2 = enc.rerandomize(cipher2, enc.generateRandomness(rand)); - - Voting.PlaintextBallot decrypted = ECElGamalUtils.decrypt(Voting.PlaintextBallot.class, key, group, - cipher2); - - assertEquals("Decrypted value differs from original encrypted value (i="+i+")!", msg, decrypted); - } - } -} - +package meerkat.crypto.concrete; + +import meerkat.protobuf.ConcreteCrypto; +import meerkat.protobuf.Crypto; +import meerkat.protobuf.Voting; +import org.bouncycastle.math.ec.ECPoint; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.factcenter.qilin.primitives.concrete.ECElGamal; +import org.factcenter.qilin.primitives.concrete.ECGroup; +import org.factcenter.qilin.util.Pair; + +import java.math.BigInteger; +import java.util.Random; + +import static org.junit.Assert.*; + +/** + * Test class for {@link ECElGamalEncryption} + */ +public class ECElGamalEncryptionTest { + final Logger logger = LoggerFactory.getLogger(getClass()); + /** + * Number of times to repeat probabilistic tests. + */ + public final static int CONFIDENCE = 10; + + Random rand = new Random(0); // Insecure deterministic random for testing. + + ECElGamal.SK key; + ECGroup group; + ECElGamalEncryption enc; + ConcreteCrypto.ElGamalPublicKey serializedPk; + + + @Before + public void setup() throws Exception { + group = new ECGroup("secp256k1"); + BigInteger sk = ECElGamal.generateSecretKey(group, rand); + key = new ECElGamal.SK(group, sk); + serializedPk = ECElGamalUtils.serializePk(group, key); + + + enc = new ECElGamalEncryption(); + + enc.init(serializedPk); + } + + + Voting.PlaintextBallot genRandomBallot(int numQuestions, int numAnswers, int maxAnswer) { + Voting.PlaintextBallot.Builder ballot = Voting.PlaintextBallot.newBuilder(); + ballot.setSerialNumber(rand.nextInt(1000000)); + for (int i = 0; i < numQuestions; ++i) { + Voting.BallotAnswer.Builder answers = ballot.addAnswersBuilder(); + for (int j = 0; j < numAnswers; ++j) { + answers.addAnswer(rand.nextInt(maxAnswer)); + } + } + return ballot.build(); + } + + /** + * Testing just the key management + * @throws Exception + */ + @Test + public void testPkSerialization() throws Exception { + ECElGamal.PK pk = enc.getElGamalPK(); + + ECPoint point = enc.getGroup().sample(rand); + Pair cipher = pk.encrypt(point, pk.getRandom(rand)); + + ECPoint decrypted = key.decrypt(cipher); + + assertEquals("Decrypted value not equal to encrypted value!", point, decrypted); + } + + @Test + public void testEncryption() throws Exception { + for (int i = 0; i < CONFIDENCE; ++i) { + Voting.PlaintextBallot msg = genRandomBallot(2,3,16); // 2 questions with 3 answers each, in range 0-15. + if (msg.getSerializedSize() > enc.getGroup().getInjectiveEncodeMsgLength()) { + logger.error("Test Message too big (|msg|={} > max={}), expect failure.", + msg.getSerializedSize(), enc.getGroup().getInjectiveEncodeMsgLength()); + } + + Crypto.RerandomizableEncryptedMessage cipherText = enc.encrypt(msg, enc.generateRandomness(rand)); + + Voting.PlaintextBallot decrypted = ECElGamalUtils.decrypt(Voting.PlaintextBallot.class, key, group, cipherText); + + assertEquals("Decrypted value differs from encrypted value (i="+i+")!", msg, decrypted); + } + } + + @Test + public void testRerandomizeModifiesCiphertext() throws Exception { + Voting.PlaintextBallot msg = genRandomBallot(2,3,16); // 2 questions with 3 answers each, in range 0-15. + Crypto.RerandomizableEncryptedMessage cipher1 = enc.encrypt(msg, enc.generateRandomness(rand)); + Crypto.RerandomizableEncryptedMessage cipher2 = enc.rerandomize(cipher1, enc.generateRandomness(rand)); + assertNotEquals("Rerandomized cipher identical to original!", cipher1, cipher2); + } + + @Test + public void testRerandomizePreservesPlaintext() throws Exception { + for (int i = 0; i < CONFIDENCE; ++i) { + Voting.PlaintextBallot msg = genRandomBallot(2,3,16); // 2 questions with 3 answers each, in range 0-15. + + Crypto.RerandomizableEncryptedMessage cipher = enc.encrypt(msg, enc.generateRandomness(rand)); + Crypto.RerandomizableEncryptedMessage cipher2 = cipher; + for (int j = 0; j < CONFIDENCE; ++j) + cipher2 = enc.rerandomize(cipher2, enc.generateRandomness(rand)); + + Voting.PlaintextBallot decrypted = ECElGamalUtils.decrypt(Voting.PlaintextBallot.class, key, group, + cipher2); + + assertEquals("Decrypted value differs from original encrypted value (i="+i+")!", msg, decrypted); + } + } +} + diff --git a/meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalUtils.java b/meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalUtils.java index 66e1647..f83aaea 100644 --- a/meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalUtils.java +++ b/meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalUtils.java @@ -1,89 +1,89 @@ -package meerkat.crypto.concrete; - -import com.google.protobuf.ByteString; -import com.google.protobuf.GeneratedMessage; -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Message; -import meerkat.protobuf.ConcreteCrypto; -import meerkat.protobuf.Crypto; -import org.bouncycastle.jce.spec.ECParameterSpec; -import org.bouncycastle.jce.spec.ECPublicKeySpec; -import org.bouncycastle.math.ec.ECPoint; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.factcenter.qilin.primitives.concrete.ECElGamal; -import org.factcenter.qilin.primitives.concrete.ECGroup; -import org.factcenter.qilin.primitives.generic.ElGamal; -import org.factcenter.qilin.util.Pair; - -import java.io.ByteArrayInputStream; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PublicKey; -import java.security.spec.InvalidKeySpecException; - -/** - * utilities for ECElgamal - */ -public class ECElGamalUtils { - final static Logger logger = LoggerFactory.getLogger(ECElGamalUtils.class); - - public final static String ENCRYPTION_KEY_ALGORITHM = "ECDH"; - - /** - * Serialize an El-Gamal public key into a form acceptable by {@link ECElGamalEncryption} - * @param pk - * @return - */ - public static ConcreteCrypto.ElGamalPublicKey serializePk(ECGroup group, ElGamal.PK pk) { - ECPoint pkPoint = pk.getPK(); - ECParameterSpec params = group.getCurveParams(); - - ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(pkPoint, params); - - try { - KeyFactory fact = KeyFactory.getInstance(ENCRYPTION_KEY_ALGORITHM, - GlobalCryptoSetup.getBouncyCastleProvider()); - PublicKey javaPk = fact.generatePublic(pubKeySpec); - ConcreteCrypto.ElGamalPublicKey serializedPk = ConcreteCrypto.ElGamalPublicKey.newBuilder() - .setSubjectPublicKeyInfo(ByteString.copyFrom(javaPk.getEncoded())).build(); - - return serializedPk; - } catch (NoSuchAlgorithmException|InvalidKeySpecException e) { - logger.error("Should never happen!", e); - throw new RuntimeException("Error converting public key!", e); - } - } - - /** - * Standard (non-threshold) decryption for testing purposes. - * @param secretKey - * @return - */ - public static T decrypt(Class plaintextMessageType, ECElGamal.SK secretKey, ECGroup group, Crypto.RerandomizableEncryptedMessage opaqueCipher) - throws InvalidProtocolBufferException { - ConcreteCrypto.ElGamalCiphertext cipherText = ConcreteCrypto.ElGamalCiphertext.parseFrom(opaqueCipher.getData()); - ByteString c1encoded = cipherText.getC1(); - ByteString c2encoded = cipherText.getC2(); - - ECPoint c1 = group.decode(c1encoded.toByteArray()); - ECPoint c2 = group.decode(c2encoded.toByteArray()); - - ECPoint plaintextEncoded = secretKey.decrypt(new Pair(c1, c2)); - - byte[] plaintext = group.injectiveDecode(plaintextEncoded); - - ByteArrayInputStream in = new ByteArrayInputStream(plaintext); - - try { - java.lang.reflect.Method newBuilder = plaintextMessageType.getMethod("newBuilder"); - GeneratedMessage.Builder builder = (GeneratedMessage.Builder) newBuilder.invoke(plaintextMessageType); - builder.mergeDelimitedFrom(in); - return plaintextMessageType.cast(builder.build()); - } catch (Exception e) { - logger.error("Error parsing incoming message", e); - throw new InvalidProtocolBufferException("Plaintext protobuf error"); - } - } - -} +package meerkat.crypto.concrete; + +import com.google.protobuf.ByteString; +import com.google.protobuf.GeneratedMessage; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; +import meerkat.protobuf.ConcreteCrypto; +import meerkat.protobuf.Crypto; +import org.bouncycastle.jce.spec.ECParameterSpec; +import org.bouncycastle.jce.spec.ECPublicKeySpec; +import org.bouncycastle.math.ec.ECPoint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.factcenter.qilin.primitives.concrete.ECElGamal; +import org.factcenter.qilin.primitives.concrete.ECGroup; +import org.factcenter.qilin.primitives.generic.ElGamal; +import org.factcenter.qilin.util.Pair; + +import java.io.ByteArrayInputStream; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; + +/** + * utilities for ECElgamal + */ +public class ECElGamalUtils { + final static Logger logger = LoggerFactory.getLogger(ECElGamalUtils.class); + + public final static String ENCRYPTION_KEY_ALGORITHM = "ECDH"; + + /** + * Serialize an El-Gamal public key into a form acceptable by {@link ECElGamalEncryption} + * @param pk + * @return + */ + public static ConcreteCrypto.ElGamalPublicKey serializePk(ECGroup group, ElGamal.PK pk) { + ECPoint pkPoint = pk.getPK(); + ECParameterSpec params = group.getCurveParams(); + + ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(pkPoint, params); + + try { + KeyFactory fact = KeyFactory.getInstance(ENCRYPTION_KEY_ALGORITHM, + GlobalCryptoSetup.getBouncyCastleProvider()); + PublicKey javaPk = fact.generatePublic(pubKeySpec); + ConcreteCrypto.ElGamalPublicKey serializedPk = ConcreteCrypto.ElGamalPublicKey.newBuilder() + .setSubjectPublicKeyInfo(ByteString.copyFrom(javaPk.getEncoded())).build(); + + return serializedPk; + } catch (NoSuchAlgorithmException|InvalidKeySpecException e) { + logger.error("Should never happen!", e); + throw new RuntimeException("Error converting public key!", e); + } + } + + /** + * Standard (non-threshold) decryption for testing purposes. + * @param secretKey + * @return + */ + public static T decrypt(Class plaintextMessageType, ECElGamal.SK secretKey, ECGroup group, Crypto.RerandomizableEncryptedMessage opaqueCipher) + throws InvalidProtocolBufferException { + ConcreteCrypto.ElGamalCiphertext cipherText = ConcreteCrypto.ElGamalCiphertext.parseFrom(opaqueCipher.getData()); + ByteString c1encoded = cipherText.getC1(); + ByteString c2encoded = cipherText.getC2(); + + ECPoint c1 = group.decode(c1encoded.toByteArray()); + ECPoint c2 = group.decode(c2encoded.toByteArray()); + + ECPoint plaintextEncoded = secretKey.decrypt(new Pair(c1, c2)); + + byte[] plaintext = group.injectiveDecode(plaintextEncoded); + + ByteArrayInputStream in = new ByteArrayInputStream(plaintext); + + try { + java.lang.reflect.Method newBuilder = plaintextMessageType.getMethod("newBuilder"); + GeneratedMessage.Builder builder = (GeneratedMessage.Builder) newBuilder.invoke(plaintextMessageType); + builder.mergeDelimitedFrom(in); + return plaintextMessageType.cast(builder.build()); + } catch (Exception e) { + logger.error("Error parsing incoming message", e); + throw new InvalidProtocolBufferException("Plaintext protobuf error"); + } + } + +} diff --git a/meerkat-common/src/test/resources/certs/README.md b/meerkat-common/src/test/resources/certs/README.md index f7283d9..ecb74d0 100644 --- a/meerkat-common/src/test/resources/certs/README.md +++ b/meerkat-common/src/test/resources/certs/README.md @@ -1,6 +1,6 @@ -Certs and private keys for testing generated using OpenSSL - -.crt and .pem files are in PEM format -.der files are in binary DER format - -files that have a name of the form *-with-password-xxxx.pem are encrypted with the password xxxx +Certs and private keys for testing generated using OpenSSL + +.crt and .pem files are in PEM format +.der files are in binary DER format + +files that have a name of the form *-with-password-xxxx.pem are encrypted with the password xxxx diff --git a/meerkat-common/src/test/resources/certs/enduser-certs/user1-key-with-password-secret.pem b/meerkat-common/src/test/resources/certs/enduser-certs/user1-key-with-password-secret.pem index e859995..dccf58d 100644 --- a/meerkat-common/src/test/resources/certs/enduser-certs/user1-key-with-password-secret.pem +++ b/meerkat-common/src/test/resources/certs/enduser-certs/user1-key-with-password-secret.pem @@ -1,8 +1,8 @@ ------BEGIN EC PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: AES-256-CBC,243D718A0D80C59590E582A26E87A49C - -RG6ITUTIdbJdWYX57oMn3tTCzHJSTjXAIZLjoVxy/v4UFYjluaFhGonIlbH1q2pP -ueu29Q3eT6144ypB8ARUJ1x0kRX1OL9zNHgdF9ulrCf9/nhGyC2nL+tHZ0YPbxoQ -+6yCQcRWvjUXLVzPEUnwMuHXJDpaXES8X0R4CISQKIA= ------END EC PRIVATE KEY----- +-----BEGIN EC PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,243D718A0D80C59590E582A26E87A49C + +RG6ITUTIdbJdWYX57oMn3tTCzHJSTjXAIZLjoVxy/v4UFYjluaFhGonIlbH1q2pP +ueu29Q3eT6144ypB8ARUJ1x0kRX1OL9zNHgdF9ulrCf9/nhGyC2nL+tHZ0YPbxoQ ++6yCQcRWvjUXLVzPEUnwMuHXJDpaXES8X0R4CISQKIA= +-----END EC PRIVATE KEY----- diff --git a/meerkat-common/src/test/resources/certs/enduser-certs/user1-key.pem b/meerkat-common/src/test/resources/certs/enduser-certs/user1-key.pem index 6619e37..239bd21 100644 --- a/meerkat-common/src/test/resources/certs/enduser-certs/user1-key.pem +++ b/meerkat-common/src/test/resources/certs/enduser-certs/user1-key.pem @@ -1,5 +1,5 @@ ------BEGIN PRIVATE KEY----- -MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQge8JqCoaLoZq61aQki5Xm -GppcfAAkhHDGNQw/wLof5LmhRANCAAQJD1kW6BsNkRY9tslaugpOJOaoKX4uBz4S -Q96lPaPWkatNVgQchwNeB/hdjZwNuwE7A7XAwr69HFmhXRhsM005 ------END PRIVATE KEY----- +-----BEGIN PRIVATE KEY----- +MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQge8JqCoaLoZq61aQki5Xm +GppcfAAkhHDGNQw/wLof5LmhRANCAAQJD1kW6BsNkRY9tslaugpOJOaoKX4uBz4S +Q96lPaPWkatNVgQchwNeB/hdjZwNuwE7A7XAwr69HFmhXRhsM005 +-----END PRIVATE KEY----- diff --git a/meerkat-common/src/test/resources/certs/enduser-certs/user1-pubkey.pem b/meerkat-common/src/test/resources/certs/enduser-certs/user1-pubkey.pem index 1c0a0c1..4724631 100644 --- a/meerkat-common/src/test/resources/certs/enduser-certs/user1-pubkey.pem +++ b/meerkat-common/src/test/resources/certs/enduser-certs/user1-pubkey.pem @@ -1,4 +1,4 @@ ------BEGIN PUBLIC KEY----- -MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAECQ9ZFugbDZEWPbbJWroKTiTmqCl+Lgc+ -EkPepT2j1pGrTVYEHIcDXgf4XY2cDbsBOwO1wMK+vRxZoV0YbDNNOQ== ------END PUBLIC KEY----- +-----BEGIN PUBLIC KEY----- +MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAECQ9ZFugbDZEWPbbJWroKTiTmqCl+Lgc+ +EkPepT2j1pGrTVYEHIcDXgf4XY2cDbsBOwO1wMK+vRxZoV0YbDNNOQ== +-----END PUBLIC KEY----- diff --git a/meerkat-common/src/test/resources/certs/enduser-certs/user1.crt b/meerkat-common/src/test/resources/certs/enduser-certs/user1.crt index d80093f..e3d4843 100644 --- a/meerkat-common/src/test/resources/certs/enduser-certs/user1.crt +++ b/meerkat-common/src/test/resources/certs/enduser-certs/user1.crt @@ -1,19 +1,19 @@ ------BEGIN CERTIFICATE----- -MIIDFjCCArygAwIBAgICEAAwCgYIKoZIzj0EAwIwgYIxKTAnBgNVBAMMIE1lZXJr -YXQgVm90aW5nIEludGVybWVkaWF0ZSBDQSAxMRMwEQYDVQQIDApTb21lLVN0YXRl -MQswCQYDVQQGEwJJTDEVMBMGA1UECgwMSURDIEhlcnpsaXlhMRwwGgYDVQQLDBNN -ZWVya2F0IFZvdGluZyBUZWFtMB4XDTE1MTExMTE2MTM1NFoXDTI1MTEwODE2MTM1 -NFowbjEaMBgGA1UEAwwRUG9sbGluZyBTdGF0aW9uIDExEzARBgNVBAgMClNvbWUt -U3RhdGUxCzAJBgNVBAYTAklMMRUwEwYDVQQKDAxJREMgSGVyemxpeWExFzAVBgNV -BAsMDk1lZXJrYXQgVm90aW5nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAECQ9ZFugb -DZEWPbbJWroKTiTmqCl+Lgc+EkPepT2j1pGrTVYEHIcDXgf4XY2cDbsBOwO1wMK+ -vRxZoV0YbDNNOaOCATYwggEyMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFLamS8o2 -hFNd0vWy/irEBNWVNwFXMB8GA1UdIwQYMBaAFBeyv0c75eT6PNumHo9TZ2B9vtcp -MAsGA1UdDwQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATBEBgNVHR8EPTA7MDmg -N6A1hjNodHRwOi8vY3JsLmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRp -YXRlMS5jcmwwegYIKwYBBQUHAQEEbjBsMEEGCCsGAQUFBzAChjVodHRwOi8vcGtp -LmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRpYXRlLWNhLmNydDAnBggr -BgEFBQcwAYYbaHR0cDovL29jc3AuZmFjdGNlbnRlci5vcmcvMAoGCCqGSM49BAMC -A0gAMEUCIQD6QbhNNmB3AVVqhmXuiLA7WF6raShw6n0g/VloVGQebQIgEvxYclpO -MMynt5wH6X65rtn4Q1EGaDMvNbFweCDsldk= ------END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDFjCCArygAwIBAgICEAAwCgYIKoZIzj0EAwIwgYIxKTAnBgNVBAMMIE1lZXJr +YXQgVm90aW5nIEludGVybWVkaWF0ZSBDQSAxMRMwEQYDVQQIDApTb21lLVN0YXRl +MQswCQYDVQQGEwJJTDEVMBMGA1UECgwMSURDIEhlcnpsaXlhMRwwGgYDVQQLDBNN +ZWVya2F0IFZvdGluZyBUZWFtMB4XDTE1MTExMTE2MTM1NFoXDTI1MTEwODE2MTM1 +NFowbjEaMBgGA1UEAwwRUG9sbGluZyBTdGF0aW9uIDExEzARBgNVBAgMClNvbWUt +U3RhdGUxCzAJBgNVBAYTAklMMRUwEwYDVQQKDAxJREMgSGVyemxpeWExFzAVBgNV +BAsMDk1lZXJrYXQgVm90aW5nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAECQ9ZFugb +DZEWPbbJWroKTiTmqCl+Lgc+EkPepT2j1pGrTVYEHIcDXgf4XY2cDbsBOwO1wMK+ +vRxZoV0YbDNNOaOCATYwggEyMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFLamS8o2 +hFNd0vWy/irEBNWVNwFXMB8GA1UdIwQYMBaAFBeyv0c75eT6PNumHo9TZ2B9vtcp +MAsGA1UdDwQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATBEBgNVHR8EPTA7MDmg +N6A1hjNodHRwOi8vY3JsLmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRp +YXRlMS5jcmwwegYIKwYBBQUHAQEEbjBsMEEGCCsGAQUFBzAChjVodHRwOi8vcGtp +LmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRpYXRlLWNhLmNydDAnBggr +BgEFBQcwAYYbaHR0cDovL29jc3AuZmFjdGNlbnRlci5vcmcvMAoGCCqGSM49BAMC +A0gAMEUCIQD6QbhNNmB3AVVqhmXuiLA7WF6raShw6n0g/VloVGQebQIgEvxYclpO +MMynt5wH6X65rtn4Q1EGaDMvNbFweCDsldk= +-----END CERTIFICATE----- diff --git a/meerkat-common/src/test/resources/certs/enduser-certs/user1.csr b/meerkat-common/src/test/resources/certs/enduser-certs/user1.csr index 20e1efc..0f59d09 100644 --- a/meerkat-common/src/test/resources/certs/enduser-certs/user1.csr +++ b/meerkat-common/src/test/resources/certs/enduser-certs/user1.csr @@ -1,9 +1,9 @@ ------BEGIN CERTIFICATE REQUEST----- -MIIBOjCB4QIBADCBgTELMAkGA1UEBhMCSUwxEzARBgNVBAgMClNvbWUtU3RhdGUx -ETAPBgNVBAcMCEhlcnpsaXlhMRUwEwYDVQQKDAxJREMgSGVyemxpeWExFzAVBgNV -BAsMDk1lZXJrYXQgVm90aW5nMRowGAYDVQQDDBFQb2xsaW5nIFN0YXRpb24gMTBW -MBAGByqGSM49AgEGBSuBBAAKA0IABAkPWRboGw2RFj22yVq6Ck4k5qgpfi4HPhJD -3qU9o9aRq01WBByHA14H+F2NnA27ATsDtcDCvr0cWaFdGGwzTTmgADAKBggqhkjO -PQQDAgNIADBFAiEA8gmIhALr7O5M1QLReGH3jheildTIr1mDWl14WyMf9U4CIF23 -mInyo4VqNHLzxMLg5Cn3Oddokng3OXa63y4nTfv+ ------END CERTIFICATE REQUEST----- +-----BEGIN CERTIFICATE REQUEST----- +MIIBOjCB4QIBADCBgTELMAkGA1UEBhMCSUwxEzARBgNVBAgMClNvbWUtU3RhdGUx +ETAPBgNVBAcMCEhlcnpsaXlhMRUwEwYDVQQKDAxJREMgSGVyemxpeWExFzAVBgNV +BAsMDk1lZXJrYXQgVm90aW5nMRowGAYDVQQDDBFQb2xsaW5nIFN0YXRpb24gMTBW +MBAGByqGSM49AgEGBSuBBAAKA0IABAkPWRboGw2RFj22yVq6Ck4k5qgpfi4HPhJD +3qU9o9aRq01WBByHA14H+F2NnA27ATsDtcDCvr0cWaFdGGwzTTmgADAKBggqhkjO +PQQDAgNIADBFAiEA8gmIhALr7O5M1QLReGH3jheildTIr1mDWl14WyMf9U4CIF23 +mInyo4VqNHLzxMLg5Cn3Oddokng3OXa63y4nTfv+ +-----END CERTIFICATE REQUEST----- diff --git a/meerkat-common/src/test/resources/certs/enduser-certs/user2-key.pem b/meerkat-common/src/test/resources/certs/enduser-certs/user2-key.pem index 2d31bb8..1967905 100644 --- a/meerkat-common/src/test/resources/certs/enduser-certs/user2-key.pem +++ b/meerkat-common/src/test/resources/certs/enduser-certs/user2-key.pem @@ -1,5 +1,5 @@ ------BEGIN PRIVATE KEY----- -MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgYpBEO+XWm/n6VPeMVK76 -mrZkDTpiwLsDykG7M4fU5RKhRANCAAR71/kVGyA3hdxcLBBT3NPQF6R3LholmLRN -qhnvHqzJWuy7ev+Xbuxtt9AN0ajyeFDy8Oe1bUSidnLyQi+nXC0f ------END PRIVATE KEY----- +-----BEGIN PRIVATE KEY----- +MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgYpBEO+XWm/n6VPeMVK76 +mrZkDTpiwLsDykG7M4fU5RKhRANCAAR71/kVGyA3hdxcLBBT3NPQF6R3LholmLRN +qhnvHqzJWuy7ev+Xbuxtt9AN0ajyeFDy8Oe1bUSidnLyQi+nXC0f +-----END PRIVATE KEY----- diff --git a/meerkat-common/src/test/resources/certs/enduser-certs/user2-pubkey.pem b/meerkat-common/src/test/resources/certs/enduser-certs/user2-pubkey.pem index 5d86d4c..72f7acf 100644 --- a/meerkat-common/src/test/resources/certs/enduser-certs/user2-pubkey.pem +++ b/meerkat-common/src/test/resources/certs/enduser-certs/user2-pubkey.pem @@ -1,4 +1,4 @@ ------BEGIN PUBLIC KEY----- -MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEe9f5FRsgN4XcXCwQU9zT0Bekdy4aJZi0 -TaoZ7x6syVrsu3r/l27sbbfQDdGo8nhQ8vDntW1EonZy8kIvp1wtHw== ------END PUBLIC KEY----- +-----BEGIN PUBLIC KEY----- +MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEe9f5FRsgN4XcXCwQU9zT0Bekdy4aJZi0 +TaoZ7x6syVrsu3r/l27sbbfQDdGo8nhQ8vDntW1EonZy8kIvp1wtHw== +-----END PUBLIC KEY----- diff --git a/meerkat-common/src/test/resources/certs/enduser-certs/user2.crt b/meerkat-common/src/test/resources/certs/enduser-certs/user2.crt index a211365..e618261 100644 --- a/meerkat-common/src/test/resources/certs/enduser-certs/user2.crt +++ b/meerkat-common/src/test/resources/certs/enduser-certs/user2.crt @@ -1,19 +1,19 @@ ------BEGIN CERTIFICATE----- -MIIDFjCCArygAwIBAgICEAEwCgYIKoZIzj0EAwIwgYIxKTAnBgNVBAMMIE1lZXJr -YXQgVm90aW5nIEludGVybWVkaWF0ZSBDQSAxMRMwEQYDVQQIDApTb21lLVN0YXRl -MQswCQYDVQQGEwJJTDEVMBMGA1UECgwMSURDIEhlcnpsaXlhMRwwGgYDVQQLDBNN -ZWVya2F0IFZvdGluZyBUZWFtMB4XDTE1MTExMTE2MjAzM1oXDTI1MTEwODE2MjAz -M1owbjEaMBgGA1UEAwwRUG9sbGluZyBTdGF0aW9uIDIxEzARBgNVBAgMClNvbWUt -U3RhdGUxCzAJBgNVBAYTAklMMRUwEwYDVQQKDAxJREMgSGVyemxpeWExFzAVBgNV -BAsMDk1lZXJrYXQgVm90aW5nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEe9f5FRsg -N4XcXCwQU9zT0Bekdy4aJZi0TaoZ7x6syVrsu3r/l27sbbfQDdGo8nhQ8vDntW1E -onZy8kIvp1wtH6OCATYwggEyMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFKCdquYj -DGHqAHt+4PIDlw0h2UvuMB8GA1UdIwQYMBaAFBeyv0c75eT6PNumHo9TZ2B9vtcp -MAsGA1UdDwQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATBEBgNVHR8EPTA7MDmg -N6A1hjNodHRwOi8vY3JsLmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRp -YXRlMS5jcmwwegYIKwYBBQUHAQEEbjBsMEEGCCsGAQUFBzAChjVodHRwOi8vcGtp -LmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRpYXRlLWNhLmNydDAnBggr -BgEFBQcwAYYbaHR0cDovL29jc3AuZmFjdGNlbnRlci5vcmcvMAoGCCqGSM49BAMC -A0gAMEUCIQDpo5B0vvEJSax3YzOMfE8l0pfDUIKLdBWJVGeq0VLtIgIgVr0+4/0e -n+R+l1OVOLh2GirloOgbv5Ch5BQ2pQNAG2Y= ------END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDFjCCArygAwIBAgICEAEwCgYIKoZIzj0EAwIwgYIxKTAnBgNVBAMMIE1lZXJr +YXQgVm90aW5nIEludGVybWVkaWF0ZSBDQSAxMRMwEQYDVQQIDApTb21lLVN0YXRl +MQswCQYDVQQGEwJJTDEVMBMGA1UECgwMSURDIEhlcnpsaXlhMRwwGgYDVQQLDBNN +ZWVya2F0IFZvdGluZyBUZWFtMB4XDTE1MTExMTE2MjAzM1oXDTI1MTEwODE2MjAz +M1owbjEaMBgGA1UEAwwRUG9sbGluZyBTdGF0aW9uIDIxEzARBgNVBAgMClNvbWUt +U3RhdGUxCzAJBgNVBAYTAklMMRUwEwYDVQQKDAxJREMgSGVyemxpeWExFzAVBgNV +BAsMDk1lZXJrYXQgVm90aW5nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEe9f5FRsg +N4XcXCwQU9zT0Bekdy4aJZi0TaoZ7x6syVrsu3r/l27sbbfQDdGo8nhQ8vDntW1E +onZy8kIvp1wtH6OCATYwggEyMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFKCdquYj +DGHqAHt+4PIDlw0h2UvuMB8GA1UdIwQYMBaAFBeyv0c75eT6PNumHo9TZ2B9vtcp +MAsGA1UdDwQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATBEBgNVHR8EPTA7MDmg +N6A1hjNodHRwOi8vY3JsLmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRp +YXRlMS5jcmwwegYIKwYBBQUHAQEEbjBsMEEGCCsGAQUFBzAChjVodHRwOi8vcGtp +LmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRpYXRlLWNhLmNydDAnBggr +BgEFBQcwAYYbaHR0cDovL29jc3AuZmFjdGNlbnRlci5vcmcvMAoGCCqGSM49BAMC +A0gAMEUCIQDpo5B0vvEJSax3YzOMfE8l0pfDUIKLdBWJVGeq0VLtIgIgVr0+4/0e +n+R+l1OVOLh2GirloOgbv5Ch5BQ2pQNAG2Y= +-----END CERTIFICATE----- diff --git a/meerkat-common/src/test/resources/certs/enduser-certs/user2.csr b/meerkat-common/src/test/resources/certs/enduser-certs/user2.csr index bb3c2d0..774a0d3 100644 --- a/meerkat-common/src/test/resources/certs/enduser-certs/user2.csr +++ b/meerkat-common/src/test/resources/certs/enduser-certs/user2.csr @@ -1,9 +1,9 @@ ------BEGIN CERTIFICATE REQUEST----- -MIIBOzCB4QIBADCBgTELMAkGA1UEBhMCSUwxEzARBgNVBAgMClNvbWUtU3RhdGUx -ETAPBgNVBAcMCEhlcnpsaXlhMRUwEwYDVQQKDAxJREMgSGVyemxpeWExFzAVBgNV -BAsMDk1lZXJrYXQgVm90aW5nMRowGAYDVQQDDBFQb2xsaW5nIFN0YXRpb24gMjBW -MBAGByqGSM49AgEGBSuBBAAKA0IABHvX+RUbIDeF3FwsEFPc09AXpHcuGiWYtE2q -Ge8erMla7Lt6/5du7G230A3RqPJ4UPLw57VtRKJ2cvJCL6dcLR+gADAKBggqhkjO -PQQDAgNJADBGAiEA6Ls/ojRaZT+u4YeOBYcPbRcJE3jSTe1Sm/lR7fDyEhMCIQCk -UOca+e2b8+CqM3CURBv6TqUMmZ3HeMRvEAxFPqOWSw== ------END CERTIFICATE REQUEST----- +-----BEGIN CERTIFICATE REQUEST----- +MIIBOzCB4QIBADCBgTELMAkGA1UEBhMCSUwxEzARBgNVBAgMClNvbWUtU3RhdGUx +ETAPBgNVBAcMCEhlcnpsaXlhMRUwEwYDVQQKDAxJREMgSGVyemxpeWExFzAVBgNV +BAsMDk1lZXJrYXQgVm90aW5nMRowGAYDVQQDDBFQb2xsaW5nIFN0YXRpb24gMjBW +MBAGByqGSM49AgEGBSuBBAAKA0IABHvX+RUbIDeF3FwsEFPc09AXpHcuGiWYtE2q +Ge8erMla7Lt6/5du7G230A3RqPJ4UPLw57VtRKJ2cvJCL6dcLR+gADAKBggqhkjO +PQQDAgNJADBGAiEA6Ls/ojRaZT+u4YeOBYcPbRcJE3jSTe1Sm/lR7fDyEhMCIQCk +UOca+e2b8+CqM3CURBv6TqUMmZ3HeMRvEAxFPqOWSw== +-----END CERTIFICATE REQUEST----- diff --git a/meerkat-common/src/test/resources/certs/intermediate-ca-1/1000.pem b/meerkat-common/src/test/resources/certs/intermediate-ca-1/1000.pem index d80093f..e3d4843 100644 --- a/meerkat-common/src/test/resources/certs/intermediate-ca-1/1000.pem +++ b/meerkat-common/src/test/resources/certs/intermediate-ca-1/1000.pem @@ -1,19 +1,19 @@ ------BEGIN CERTIFICATE----- -MIIDFjCCArygAwIBAgICEAAwCgYIKoZIzj0EAwIwgYIxKTAnBgNVBAMMIE1lZXJr -YXQgVm90aW5nIEludGVybWVkaWF0ZSBDQSAxMRMwEQYDVQQIDApTb21lLVN0YXRl -MQswCQYDVQQGEwJJTDEVMBMGA1UECgwMSURDIEhlcnpsaXlhMRwwGgYDVQQLDBNN -ZWVya2F0IFZvdGluZyBUZWFtMB4XDTE1MTExMTE2MTM1NFoXDTI1MTEwODE2MTM1 -NFowbjEaMBgGA1UEAwwRUG9sbGluZyBTdGF0aW9uIDExEzARBgNVBAgMClNvbWUt -U3RhdGUxCzAJBgNVBAYTAklMMRUwEwYDVQQKDAxJREMgSGVyemxpeWExFzAVBgNV -BAsMDk1lZXJrYXQgVm90aW5nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAECQ9ZFugb -DZEWPbbJWroKTiTmqCl+Lgc+EkPepT2j1pGrTVYEHIcDXgf4XY2cDbsBOwO1wMK+ -vRxZoV0YbDNNOaOCATYwggEyMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFLamS8o2 -hFNd0vWy/irEBNWVNwFXMB8GA1UdIwQYMBaAFBeyv0c75eT6PNumHo9TZ2B9vtcp -MAsGA1UdDwQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATBEBgNVHR8EPTA7MDmg -N6A1hjNodHRwOi8vY3JsLmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRp -YXRlMS5jcmwwegYIKwYBBQUHAQEEbjBsMEEGCCsGAQUFBzAChjVodHRwOi8vcGtp -LmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRpYXRlLWNhLmNydDAnBggr -BgEFBQcwAYYbaHR0cDovL29jc3AuZmFjdGNlbnRlci5vcmcvMAoGCCqGSM49BAMC -A0gAMEUCIQD6QbhNNmB3AVVqhmXuiLA7WF6raShw6n0g/VloVGQebQIgEvxYclpO -MMynt5wH6X65rtn4Q1EGaDMvNbFweCDsldk= ------END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDFjCCArygAwIBAgICEAAwCgYIKoZIzj0EAwIwgYIxKTAnBgNVBAMMIE1lZXJr +YXQgVm90aW5nIEludGVybWVkaWF0ZSBDQSAxMRMwEQYDVQQIDApTb21lLVN0YXRl +MQswCQYDVQQGEwJJTDEVMBMGA1UECgwMSURDIEhlcnpsaXlhMRwwGgYDVQQLDBNN +ZWVya2F0IFZvdGluZyBUZWFtMB4XDTE1MTExMTE2MTM1NFoXDTI1MTEwODE2MTM1 +NFowbjEaMBgGA1UEAwwRUG9sbGluZyBTdGF0aW9uIDExEzARBgNVBAgMClNvbWUt +U3RhdGUxCzAJBgNVBAYTAklMMRUwEwYDVQQKDAxJREMgSGVyemxpeWExFzAVBgNV +BAsMDk1lZXJrYXQgVm90aW5nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAECQ9ZFugb +DZEWPbbJWroKTiTmqCl+Lgc+EkPepT2j1pGrTVYEHIcDXgf4XY2cDbsBOwO1wMK+ +vRxZoV0YbDNNOaOCATYwggEyMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFLamS8o2 +hFNd0vWy/irEBNWVNwFXMB8GA1UdIwQYMBaAFBeyv0c75eT6PNumHo9TZ2B9vtcp +MAsGA1UdDwQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATBEBgNVHR8EPTA7MDmg +N6A1hjNodHRwOi8vY3JsLmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRp +YXRlMS5jcmwwegYIKwYBBQUHAQEEbjBsMEEGCCsGAQUFBzAChjVodHRwOi8vcGtp +LmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRpYXRlLWNhLmNydDAnBggr +BgEFBQcwAYYbaHR0cDovL29jc3AuZmFjdGNlbnRlci5vcmcvMAoGCCqGSM49BAMC +A0gAMEUCIQD6QbhNNmB3AVVqhmXuiLA7WF6raShw6n0g/VloVGQebQIgEvxYclpO +MMynt5wH6X65rtn4Q1EGaDMvNbFweCDsldk= +-----END CERTIFICATE----- diff --git a/meerkat-common/src/test/resources/certs/intermediate-ca-1/1001.pem b/meerkat-common/src/test/resources/certs/intermediate-ca-1/1001.pem index a211365..e618261 100644 --- a/meerkat-common/src/test/resources/certs/intermediate-ca-1/1001.pem +++ b/meerkat-common/src/test/resources/certs/intermediate-ca-1/1001.pem @@ -1,19 +1,19 @@ ------BEGIN CERTIFICATE----- -MIIDFjCCArygAwIBAgICEAEwCgYIKoZIzj0EAwIwgYIxKTAnBgNVBAMMIE1lZXJr -YXQgVm90aW5nIEludGVybWVkaWF0ZSBDQSAxMRMwEQYDVQQIDApTb21lLVN0YXRl -MQswCQYDVQQGEwJJTDEVMBMGA1UECgwMSURDIEhlcnpsaXlhMRwwGgYDVQQLDBNN -ZWVya2F0IFZvdGluZyBUZWFtMB4XDTE1MTExMTE2MjAzM1oXDTI1MTEwODE2MjAz -M1owbjEaMBgGA1UEAwwRUG9sbGluZyBTdGF0aW9uIDIxEzARBgNVBAgMClNvbWUt -U3RhdGUxCzAJBgNVBAYTAklMMRUwEwYDVQQKDAxJREMgSGVyemxpeWExFzAVBgNV -BAsMDk1lZXJrYXQgVm90aW5nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEe9f5FRsg -N4XcXCwQU9zT0Bekdy4aJZi0TaoZ7x6syVrsu3r/l27sbbfQDdGo8nhQ8vDntW1E -onZy8kIvp1wtH6OCATYwggEyMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFKCdquYj -DGHqAHt+4PIDlw0h2UvuMB8GA1UdIwQYMBaAFBeyv0c75eT6PNumHo9TZ2B9vtcp -MAsGA1UdDwQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATBEBgNVHR8EPTA7MDmg -N6A1hjNodHRwOi8vY3JsLmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRp -YXRlMS5jcmwwegYIKwYBBQUHAQEEbjBsMEEGCCsGAQUFBzAChjVodHRwOi8vcGtp -LmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRpYXRlLWNhLmNydDAnBggr -BgEFBQcwAYYbaHR0cDovL29jc3AuZmFjdGNlbnRlci5vcmcvMAoGCCqGSM49BAMC -A0gAMEUCIQDpo5B0vvEJSax3YzOMfE8l0pfDUIKLdBWJVGeq0VLtIgIgVr0+4/0e -n+R+l1OVOLh2GirloOgbv5Ch5BQ2pQNAG2Y= ------END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDFjCCArygAwIBAgICEAEwCgYIKoZIzj0EAwIwgYIxKTAnBgNVBAMMIE1lZXJr +YXQgVm90aW5nIEludGVybWVkaWF0ZSBDQSAxMRMwEQYDVQQIDApTb21lLVN0YXRl +MQswCQYDVQQGEwJJTDEVMBMGA1UECgwMSURDIEhlcnpsaXlhMRwwGgYDVQQLDBNN +ZWVya2F0IFZvdGluZyBUZWFtMB4XDTE1MTExMTE2MjAzM1oXDTI1MTEwODE2MjAz +M1owbjEaMBgGA1UEAwwRUG9sbGluZyBTdGF0aW9uIDIxEzARBgNVBAgMClNvbWUt +U3RhdGUxCzAJBgNVBAYTAklMMRUwEwYDVQQKDAxJREMgSGVyemxpeWExFzAVBgNV +BAsMDk1lZXJrYXQgVm90aW5nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEe9f5FRsg +N4XcXCwQU9zT0Bekdy4aJZi0TaoZ7x6syVrsu3r/l27sbbfQDdGo8nhQ8vDntW1E +onZy8kIvp1wtH6OCATYwggEyMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFKCdquYj +DGHqAHt+4PIDlw0h2UvuMB8GA1UdIwQYMBaAFBeyv0c75eT6PNumHo9TZ2B9vtcp +MAsGA1UdDwQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATBEBgNVHR8EPTA7MDmg +N6A1hjNodHRwOi8vY3JsLmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRp +YXRlMS5jcmwwegYIKwYBBQUHAQEEbjBsMEEGCCsGAQUFBzAChjVodHRwOi8vcGtp +LmZhY3RjZW50ZXIub3JnL21lZXJrYXQtaW50ZXJtZWRpYXRlLWNhLmNydDAnBggr +BgEFBQcwAYYbaHR0cDovL29jc3AuZmFjdGNlbnRlci5vcmcvMAoGCCqGSM49BAMC +A0gAMEUCIQDpo5B0vvEJSax3YzOMfE8l0pfDUIKLdBWJVGeq0VLtIgIgVr0+4/0e +n+R+l1OVOLh2GirloOgbv5Ch5BQ2pQNAG2Y= +-----END CERTIFICATE----- diff --git a/meerkat-common/src/test/resources/certs/intermediate-ca-1/certindex b/meerkat-common/src/test/resources/certs/intermediate-ca-1/certindex index 1cd80cf..72b4dde 100644 --- a/meerkat-common/src/test/resources/certs/intermediate-ca-1/certindex +++ b/meerkat-common/src/test/resources/certs/intermediate-ca-1/certindex @@ -1,2 +1,2 @@ -V 251108161354Z 1000 unknown /CN=Polling Station 1/ST=Some-State/C=IL/O=IDC Herzliya/OU=Meerkat Voting -V 251108162033Z 1001 unknown /CN=Polling Station 2/ST=Some-State/C=IL/O=IDC Herzliya/OU=Meerkat Voting +V 251108161354Z 1000 unknown /CN=Polling Station 1/ST=Some-State/C=IL/O=IDC Herzliya/OU=Meerkat Voting +V 251108162033Z 1001 unknown /CN=Polling Station 2/ST=Some-State/C=IL/O=IDC Herzliya/OU=Meerkat Voting diff --git a/meerkat-common/src/test/resources/certs/intermediate-ca-1/certindex.attr b/meerkat-common/src/test/resources/certs/intermediate-ca-1/certindex.attr index 3a7e39e..f77ac48 100644 --- a/meerkat-common/src/test/resources/certs/intermediate-ca-1/certindex.attr +++ b/meerkat-common/src/test/resources/certs/intermediate-ca-1/certindex.attr @@ -1 +1 @@ -unique_subject = no +unique_subject = no diff --git a/meerkat-common/src/test/resources/certs/intermediate-ca-1/certindex.attr.old b/meerkat-common/src/test/resources/certs/intermediate-ca-1/certindex.attr.old index 3a7e39e..f77ac48 100644 --- a/meerkat-common/src/test/resources/certs/intermediate-ca-1/certindex.attr.old +++ b/meerkat-common/src/test/resources/certs/intermediate-ca-1/certindex.attr.old @@ -1 +1 @@ -unique_subject = no +unique_subject = no diff --git a/meerkat-common/src/test/resources/certs/intermediate-ca-1/certindex.old b/meerkat-common/src/test/resources/certs/intermediate-ca-1/certindex.old index 7dcd55e..60f290b 100644 --- a/meerkat-common/src/test/resources/certs/intermediate-ca-1/certindex.old +++ b/meerkat-common/src/test/resources/certs/intermediate-ca-1/certindex.old @@ -1 +1 @@ -V 251108161354Z 1000 unknown /CN=Polling Station 1/ST=Some-State/C=IL/O=IDC Herzliya/OU=Meerkat Voting +V 251108161354Z 1000 unknown /CN=Polling Station 1/ST=Some-State/C=IL/O=IDC Herzliya/OU=Meerkat Voting diff --git a/meerkat-common/src/test/resources/certs/intermediate-ca-1/certserial b/meerkat-common/src/test/resources/certs/intermediate-ca-1/certserial index 7d802a3..a9b8266 100644 --- a/meerkat-common/src/test/resources/certs/intermediate-ca-1/certserial +++ b/meerkat-common/src/test/resources/certs/intermediate-ca-1/certserial @@ -1 +1 @@ -1002 +1002 diff --git a/meerkat-common/src/test/resources/certs/intermediate-ca-1/certserial.old b/meerkat-common/src/test/resources/certs/intermediate-ca-1/certserial.old index dd11724..ecc680e 100644 --- a/meerkat-common/src/test/resources/certs/intermediate-ca-1/certserial.old +++ b/meerkat-common/src/test/resources/certs/intermediate-ca-1/certserial.old @@ -1 +1 @@ -1001 +1001 diff --git a/meerkat-common/src/test/resources/certs/intermediate-ca-1/crlnumber b/meerkat-common/src/test/resources/certs/intermediate-ca-1/crlnumber index 83b33d2..d5b0eb5 100644 --- a/meerkat-common/src/test/resources/certs/intermediate-ca-1/crlnumber +++ b/meerkat-common/src/test/resources/certs/intermediate-ca-1/crlnumber @@ -1 +1 @@ -1000 +1000 diff --git a/meerkat-common/src/test/resources/certs/intermediate-ca-1/intermediate-ca-1-private-key.pem b/meerkat-common/src/test/resources/certs/intermediate-ca-1/intermediate-ca-1-private-key.pem index cf0a641..5c678f2 100644 --- a/meerkat-common/src/test/resources/certs/intermediate-ca-1/intermediate-ca-1-private-key.pem +++ b/meerkat-common/src/test/resources/certs/intermediate-ca-1/intermediate-ca-1-private-key.pem @@ -1,5 +1,5 @@ ------BEGIN PRIVATE KEY----- -MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgJvMhOfcQfdK/42QlBbri -IYXLM/gVHq/yppOykDqB3s6hRANCAAQoShAtCGW5c9pk/4/sKN1qjCgDKngqJpba -kku6cIDqXDr+aHsl+/KdSHd46OI3fEynl+/Pc85wRsaY6Z7b1PdS ------END PRIVATE KEY----- +-----BEGIN PRIVATE KEY----- +MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgJvMhOfcQfdK/42QlBbri +IYXLM/gVHq/yppOykDqB3s6hRANCAAQoShAtCGW5c9pk/4/sKN1qjCgDKngqJpba +kku6cIDqXDr+aHsl+/KdSHd46OI3fEynl+/Pc85wRsaY6Z7b1PdS +-----END PRIVATE KEY----- diff --git a/meerkat-common/src/test/resources/certs/intermediate-ca-1/intermediate-ca-1.crt b/meerkat-common/src/test/resources/certs/intermediate-ca-1/intermediate-ca-1.crt index 751d8e7..dda53dc 100644 --- a/meerkat-common/src/test/resources/certs/intermediate-ca-1/intermediate-ca-1.crt +++ b/meerkat-common/src/test/resources/certs/intermediate-ca-1/intermediate-ca-1.crt @@ -1,21 +1,21 @@ ------BEGIN CERTIFICATE----- -MIIDfDCCAyGgAwIBAgICEAAwCgYIKoZIzj0EAwIwgbAxCzAJBgNVBAYTAklMMRMw -EQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQHDAhIZXJ6bGl5YTEUMBIGA1UECgwL -SURDIEhlcmxpeWExHzAdBgNVBAsMFk1lZXJrYXQgVm90aW5nIFByb2plY3QxGDAW -BgNVBAMMD1Rlc3RpbmcgUm9vdCBDQTEoMCYGCSqGSIb3DQEJARYZdGVzdGluZy1j -YUBmYWN0Y2VudGVyLm9yZzAeFw0xNTExMTExNjA4MDJaFw0yNTExMDgxNjA4MDJa -MIGCMSkwJwYDVQQDDCBNZWVya2F0IFZvdGluZyBJbnRlcm1lZGlhdGUgQ0EgMTET -MBEGA1UECAwKU29tZS1TdGF0ZTELMAkGA1UEBhMCSUwxFTATBgNVBAoMDElEQyBI -ZXJ6bGl5YTEcMBoGA1UECwwTTWVlcmthdCBWb3RpbmcgVGVhbTBWMBAGByqGSM49 -AgEGBSuBBAAKA0IABChKEC0IZblz2mT/j+wo3WqMKAMqeComltqSS7pwgOpcOv5o -eyX78p1Id3jo4jd8TKeX789zznBGxpjpntvU91KjggFYMIIBVDAPBgNVHRMBAf8E -BTADAQH/MB0GA1UdDgQWBBQXsr9HO+Xk+jzbph6PU2dgfb7XKTAfBgNVHSMEGDAW -gBSJD9L1fLmX4A9CBoLsYXn3OPy1ojALBgNVHQ8EBAMCAaYwEwYDVR0lBAwwCgYI -KwYBBQUHAwEwPgYDVR0fBDcwNTAzoDGgL4YtaHR0cDovL2NybC5mYWN0Y2VudGVy -Lm9yZy9tZWVya2F0LXJvb3QtY2EuY3JsMCsGA1UdEQQkMCKCIE1lZXJrYXQgVm90 -aW5nIEludGVybWVkaWF0ZSBDQSAxMHIGCCsGAQUFBwEBBGYwZDA5BggrBgEFBQcw -AoYtaHR0cDovL3BraS5mYWN0Y2VudGVyLm9yZy9tZWVya2F0LXJvb3QtY2EuY3J0 -MCcGCCsGAQUFBzABhhtodHRwOi8vb2NzcC5mYWN0Y2VudGVyLm9yZy8wCgYIKoZI -zj0EAwIDSQAwRgIhALEMHq2ssC9rLXiG8v6NcZetwwxdu3B3LW9s0KeGoNIEAiEA -skA56tMnhiZe38msyanRyRrAHyBI2fGs6GP3UBrg2P8= ------END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDfDCCAyGgAwIBAgICEAAwCgYIKoZIzj0EAwIwgbAxCzAJBgNVBAYTAklMMRMw +EQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQHDAhIZXJ6bGl5YTEUMBIGA1UECgwL +SURDIEhlcmxpeWExHzAdBgNVBAsMFk1lZXJrYXQgVm90aW5nIFByb2plY3QxGDAW +BgNVBAMMD1Rlc3RpbmcgUm9vdCBDQTEoMCYGCSqGSIb3DQEJARYZdGVzdGluZy1j +YUBmYWN0Y2VudGVyLm9yZzAeFw0xNTExMTExNjA4MDJaFw0yNTExMDgxNjA4MDJa +MIGCMSkwJwYDVQQDDCBNZWVya2F0IFZvdGluZyBJbnRlcm1lZGlhdGUgQ0EgMTET +MBEGA1UECAwKU29tZS1TdGF0ZTELMAkGA1UEBhMCSUwxFTATBgNVBAoMDElEQyBI +ZXJ6bGl5YTEcMBoGA1UECwwTTWVlcmthdCBWb3RpbmcgVGVhbTBWMBAGByqGSM49 +AgEGBSuBBAAKA0IABChKEC0IZblz2mT/j+wo3WqMKAMqeComltqSS7pwgOpcOv5o +eyX78p1Id3jo4jd8TKeX789zznBGxpjpntvU91KjggFYMIIBVDAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBQXsr9HO+Xk+jzbph6PU2dgfb7XKTAfBgNVHSMEGDAW +gBSJD9L1fLmX4A9CBoLsYXn3OPy1ojALBgNVHQ8EBAMCAaYwEwYDVR0lBAwwCgYI +KwYBBQUHAwEwPgYDVR0fBDcwNTAzoDGgL4YtaHR0cDovL2NybC5mYWN0Y2VudGVy +Lm9yZy9tZWVya2F0LXJvb3QtY2EuY3JsMCsGA1UdEQQkMCKCIE1lZXJrYXQgVm90 +aW5nIEludGVybWVkaWF0ZSBDQSAxMHIGCCsGAQUFBwEBBGYwZDA5BggrBgEFBQcw +AoYtaHR0cDovL3BraS5mYWN0Y2VudGVyLm9yZy9tZWVya2F0LXJvb3QtY2EuY3J0 +MCcGCCsGAQUFBzABhhtodHRwOi8vb2NzcC5mYWN0Y2VudGVyLm9yZy8wCgYIKoZI +zj0EAwIDSQAwRgIhALEMHq2ssC9rLXiG8v6NcZetwwxdu3B3LW9s0KeGoNIEAiEA +skA56tMnhiZe38msyanRyRrAHyBI2fGs6GP3UBrg2P8= +-----END CERTIFICATE----- diff --git a/meerkat-common/src/test/resources/certs/intermediate-ca-1/intermediate-ca-1.csr b/meerkat-common/src/test/resources/certs/intermediate-ca-1/intermediate-ca-1.csr index fce3021..55f66c1 100644 --- a/meerkat-common/src/test/resources/certs/intermediate-ca-1/intermediate-ca-1.csr +++ b/meerkat-common/src/test/resources/certs/intermediate-ca-1/intermediate-ca-1.csr @@ -1,10 +1,10 @@ ------BEGIN CERTIFICATE REQUEST----- -MIIBTTCB9QIBADCBlTELMAkGA1UEBhMCSUwxEzARBgNVBAgMClNvbWUtU3RhdGUx -ETAPBgNVBAcMCEhlcnpsaXlhMRUwEwYDVQQKDAxJREMgSGVyemxpeWExHDAaBgNV -BAsME01lZXJrYXQgVm90aW5nIFRlYW0xKTAnBgNVBAMMIE1lZXJrYXQgVm90aW5n -IEludGVybWVkaWF0ZSBDQSAxMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEKEoQLQhl -uXPaZP+P7CjdaowoAyp4KiaW2pJLunCA6lw6/mh7JfvynUh3eOjiN3xMp5fvz3PO -cEbGmOme29T3UqAAMAoGCCqGSM49BAMCA0cAMEQCIFlyJO5NFqnMUu5hOlQa872E -yy0V3zkqeN6Aly+LtEQqAiAfHwbi1lkJOZT2tOX8gfJzcac2jKmbgIhmITNq7uma -Wg== ------END CERTIFICATE REQUEST----- +-----BEGIN CERTIFICATE REQUEST----- +MIIBTTCB9QIBADCBlTELMAkGA1UEBhMCSUwxEzARBgNVBAgMClNvbWUtU3RhdGUx +ETAPBgNVBAcMCEhlcnpsaXlhMRUwEwYDVQQKDAxJREMgSGVyemxpeWExHDAaBgNV +BAsME01lZXJrYXQgVm90aW5nIFRlYW0xKTAnBgNVBAMMIE1lZXJrYXQgVm90aW5n +IEludGVybWVkaWF0ZSBDQSAxMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEKEoQLQhl +uXPaZP+P7CjdaowoAyp4KiaW2pJLunCA6lw6/mh7JfvynUh3eOjiN3xMp5fvz3PO +cEbGmOme29T3UqAAMAoGCCqGSM49BAMCA0cAMEQCIFlyJO5NFqnMUu5hOlQa872E +yy0V3zkqeN6Aly+LtEQqAiAfHwbi1lkJOZT2tOX8gfJzcac2jKmbgIhmITNq7uma +Wg== +-----END CERTIFICATE REQUEST----- diff --git a/meerkat-common/src/test/resources/certs/intermediate-ca-1/openssl-intermediate-ca.conf b/meerkat-common/src/test/resources/certs/intermediate-ca-1/openssl-intermediate-ca.conf index 090ca1a..aa44c33 100644 --- a/meerkat-common/src/test/resources/certs/intermediate-ca-1/openssl-intermediate-ca.conf +++ b/meerkat-common/src/test/resources/certs/intermediate-ca-1/openssl-intermediate-ca.conf @@ -1,46 +1,46 @@ -[ ca ] -default_ca = myca - -[ crl_ext ] -issuerAltName=issuer:copy -authorityKeyIdentifier=keyid:always - - [ myca ] - dir = ./ - new_certs_dir = $dir - unique_subject = no - certificate = $dir/intermediate-ca-1.crt - database = $dir/certindex - private_key = $dir/intermediate-ca-1-private-key.pem - serial = $dir/certserial - default_days = 3650 - default_md = sha256 - policy = myca_policy - x509_extensions = myca_extensions - crlnumber = $dir/crlnumber - default_crl_days = 3650 - - [ myca_policy ] - commonName = supplied - stateOrProvinceName = optional - countryName = optional - emailAddress = optional - organizationName = supplied - organizationalUnitName = optional - - [ myca_extensions ] - basicConstraints = critical,CA:FALSE - keyUsage = critical,any - subjectKeyIdentifier = hash - authorityKeyIdentifier = keyid:always,issuer - keyUsage = digitalSignature,keyEncipherment - extendedKeyUsage = serverAuth - crlDistributionPoints = @crl_section - authorityInfoAccess = @ocsp_section - - [crl_section] - URI.0 = http://crl.factcenter.org/meerkat-intermediate1.crl - - [ocsp_section] - caIssuers;URI.0 = http://pki.factcenter.org/meerkat-intermediate-ca.crt - OCSP;URI.0 = http://ocsp.factcenter.org/ +[ ca ] +default_ca = myca + +[ crl_ext ] +issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + + [ myca ] + dir = ./ + new_certs_dir = $dir + unique_subject = no + certificate = $dir/intermediate-ca-1.crt + database = $dir/certindex + private_key = $dir/intermediate-ca-1-private-key.pem + serial = $dir/certserial + default_days = 3650 + default_md = sha256 + policy = myca_policy + x509_extensions = myca_extensions + crlnumber = $dir/crlnumber + default_crl_days = 3650 + + [ myca_policy ] + commonName = supplied + stateOrProvinceName = optional + countryName = optional + emailAddress = optional + organizationName = supplied + organizationalUnitName = optional + + [ myca_extensions ] + basicConstraints = critical,CA:FALSE + keyUsage = critical,any + subjectKeyIdentifier = hash + authorityKeyIdentifier = keyid:always,issuer + keyUsage = digitalSignature,keyEncipherment + extendedKeyUsage = serverAuth + crlDistributionPoints = @crl_section + authorityInfoAccess = @ocsp_section + + [crl_section] + URI.0 = http://crl.factcenter.org/meerkat-intermediate1.crl + + [ocsp_section] + caIssuers;URI.0 = http://pki.factcenter.org/meerkat-intermediate-ca.crt + OCSP;URI.0 = http://ocsp.factcenter.org/ diff --git a/meerkat-common/src/test/resources/certs/root-ca/1000.pem b/meerkat-common/src/test/resources/certs/root-ca/1000.pem index 751d8e7..dda53dc 100644 --- a/meerkat-common/src/test/resources/certs/root-ca/1000.pem +++ b/meerkat-common/src/test/resources/certs/root-ca/1000.pem @@ -1,21 +1,21 @@ ------BEGIN CERTIFICATE----- -MIIDfDCCAyGgAwIBAgICEAAwCgYIKoZIzj0EAwIwgbAxCzAJBgNVBAYTAklMMRMw -EQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQHDAhIZXJ6bGl5YTEUMBIGA1UECgwL -SURDIEhlcmxpeWExHzAdBgNVBAsMFk1lZXJrYXQgVm90aW5nIFByb2plY3QxGDAW -BgNVBAMMD1Rlc3RpbmcgUm9vdCBDQTEoMCYGCSqGSIb3DQEJARYZdGVzdGluZy1j -YUBmYWN0Y2VudGVyLm9yZzAeFw0xNTExMTExNjA4MDJaFw0yNTExMDgxNjA4MDJa -MIGCMSkwJwYDVQQDDCBNZWVya2F0IFZvdGluZyBJbnRlcm1lZGlhdGUgQ0EgMTET -MBEGA1UECAwKU29tZS1TdGF0ZTELMAkGA1UEBhMCSUwxFTATBgNVBAoMDElEQyBI -ZXJ6bGl5YTEcMBoGA1UECwwTTWVlcmthdCBWb3RpbmcgVGVhbTBWMBAGByqGSM49 -AgEGBSuBBAAKA0IABChKEC0IZblz2mT/j+wo3WqMKAMqeComltqSS7pwgOpcOv5o -eyX78p1Id3jo4jd8TKeX789zznBGxpjpntvU91KjggFYMIIBVDAPBgNVHRMBAf8E -BTADAQH/MB0GA1UdDgQWBBQXsr9HO+Xk+jzbph6PU2dgfb7XKTAfBgNVHSMEGDAW -gBSJD9L1fLmX4A9CBoLsYXn3OPy1ojALBgNVHQ8EBAMCAaYwEwYDVR0lBAwwCgYI -KwYBBQUHAwEwPgYDVR0fBDcwNTAzoDGgL4YtaHR0cDovL2NybC5mYWN0Y2VudGVy -Lm9yZy9tZWVya2F0LXJvb3QtY2EuY3JsMCsGA1UdEQQkMCKCIE1lZXJrYXQgVm90 -aW5nIEludGVybWVkaWF0ZSBDQSAxMHIGCCsGAQUFBwEBBGYwZDA5BggrBgEFBQcw -AoYtaHR0cDovL3BraS5mYWN0Y2VudGVyLm9yZy9tZWVya2F0LXJvb3QtY2EuY3J0 -MCcGCCsGAQUFBzABhhtodHRwOi8vb2NzcC5mYWN0Y2VudGVyLm9yZy8wCgYIKoZI -zj0EAwIDSQAwRgIhALEMHq2ssC9rLXiG8v6NcZetwwxdu3B3LW9s0KeGoNIEAiEA -skA56tMnhiZe38msyanRyRrAHyBI2fGs6GP3UBrg2P8= ------END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDfDCCAyGgAwIBAgICEAAwCgYIKoZIzj0EAwIwgbAxCzAJBgNVBAYTAklMMRMw +EQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQHDAhIZXJ6bGl5YTEUMBIGA1UECgwL +SURDIEhlcmxpeWExHzAdBgNVBAsMFk1lZXJrYXQgVm90aW5nIFByb2plY3QxGDAW +BgNVBAMMD1Rlc3RpbmcgUm9vdCBDQTEoMCYGCSqGSIb3DQEJARYZdGVzdGluZy1j +YUBmYWN0Y2VudGVyLm9yZzAeFw0xNTExMTExNjA4MDJaFw0yNTExMDgxNjA4MDJa +MIGCMSkwJwYDVQQDDCBNZWVya2F0IFZvdGluZyBJbnRlcm1lZGlhdGUgQ0EgMTET +MBEGA1UECAwKU29tZS1TdGF0ZTELMAkGA1UEBhMCSUwxFTATBgNVBAoMDElEQyBI +ZXJ6bGl5YTEcMBoGA1UECwwTTWVlcmthdCBWb3RpbmcgVGVhbTBWMBAGByqGSM49 +AgEGBSuBBAAKA0IABChKEC0IZblz2mT/j+wo3WqMKAMqeComltqSS7pwgOpcOv5o +eyX78p1Id3jo4jd8TKeX789zznBGxpjpntvU91KjggFYMIIBVDAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBQXsr9HO+Xk+jzbph6PU2dgfb7XKTAfBgNVHSMEGDAW +gBSJD9L1fLmX4A9CBoLsYXn3OPy1ojALBgNVHQ8EBAMCAaYwEwYDVR0lBAwwCgYI +KwYBBQUHAwEwPgYDVR0fBDcwNTAzoDGgL4YtaHR0cDovL2NybC5mYWN0Y2VudGVy +Lm9yZy9tZWVya2F0LXJvb3QtY2EuY3JsMCsGA1UdEQQkMCKCIE1lZXJrYXQgVm90 +aW5nIEludGVybWVkaWF0ZSBDQSAxMHIGCCsGAQUFBwEBBGYwZDA5BggrBgEFBQcw +AoYtaHR0cDovL3BraS5mYWN0Y2VudGVyLm9yZy9tZWVya2F0LXJvb3QtY2EuY3J0 +MCcGCCsGAQUFBzABhhtodHRwOi8vb2NzcC5mYWN0Y2VudGVyLm9yZy8wCgYIKoZI +zj0EAwIDSQAwRgIhALEMHq2ssC9rLXiG8v6NcZetwwxdu3B3LW9s0KeGoNIEAiEA +skA56tMnhiZe38msyanRyRrAHyBI2fGs6GP3UBrg2P8= +-----END CERTIFICATE----- diff --git a/meerkat-common/src/test/resources/certs/root-ca/certindex b/meerkat-common/src/test/resources/certs/root-ca/certindex index e4550ca..ec8e90d 100644 --- a/meerkat-common/src/test/resources/certs/root-ca/certindex +++ b/meerkat-common/src/test/resources/certs/root-ca/certindex @@ -1 +1 @@ -V 251108160802Z 1000 unknown /CN=Meerkat Voting Intermediate CA 1/ST=Some-State/C=IL/O=IDC Herzliya/OU=Meerkat Voting Team +V 251108160802Z 1000 unknown /CN=Meerkat Voting Intermediate CA 1/ST=Some-State/C=IL/O=IDC Herzliya/OU=Meerkat Voting Team diff --git a/meerkat-common/src/test/resources/certs/root-ca/certindex.attr b/meerkat-common/src/test/resources/certs/root-ca/certindex.attr index 3a7e39e..f77ac48 100644 --- a/meerkat-common/src/test/resources/certs/root-ca/certindex.attr +++ b/meerkat-common/src/test/resources/certs/root-ca/certindex.attr @@ -1 +1 @@ -unique_subject = no +unique_subject = no diff --git a/meerkat-common/src/test/resources/certs/root-ca/certserial b/meerkat-common/src/test/resources/certs/root-ca/certserial index dd11724..ecc680e 100644 --- a/meerkat-common/src/test/resources/certs/root-ca/certserial +++ b/meerkat-common/src/test/resources/certs/root-ca/certserial @@ -1 +1 @@ -1001 +1001 diff --git a/meerkat-common/src/test/resources/certs/root-ca/certserial.old b/meerkat-common/src/test/resources/certs/root-ca/certserial.old index 83b33d2..d5b0eb5 100644 --- a/meerkat-common/src/test/resources/certs/root-ca/certserial.old +++ b/meerkat-common/src/test/resources/certs/root-ca/certserial.old @@ -1 +1 @@ -1000 +1000 diff --git a/meerkat-common/src/test/resources/certs/root-ca/crlnumber b/meerkat-common/src/test/resources/certs/root-ca/crlnumber index 83b33d2..d5b0eb5 100644 --- a/meerkat-common/src/test/resources/certs/root-ca/crlnumber +++ b/meerkat-common/src/test/resources/certs/root-ca/crlnumber @@ -1 +1 @@ -1000 +1000 diff --git a/meerkat-common/src/test/resources/certs/root-ca/openssl-ca.conf b/meerkat-common/src/test/resources/certs/root-ca/openssl-ca.conf index 39e8b00..e94692e 100644 --- a/meerkat-common/src/test/resources/certs/root-ca/openssl-ca.conf +++ b/meerkat-common/src/test/resources/certs/root-ca/openssl-ca.conf @@ -1,61 +1,61 @@ -[ ca ] -default_ca = myca - -[ crl_ext ] -issuerAltName=issuer:copy -authorityKeyIdentifier=keyid:always - - [ myca ] - dir = ./ - new_certs_dir = $dir - unique_subject = no - certificate = $dir/root-ca.crt - database = $dir/certindex - private_key = $dir/root-ca-private-key.pem - serial = $dir/certserial - default_days = 3650 - default_md = sha256 - policy = myca_policy - x509_extensions = myca_extensions - crlnumber = $dir/crlnumber - default_crl_days = 3650 - - [ myca_policy ] - commonName = supplied - stateOrProvinceName = optional - countryName = optional - emailAddress = optional - organizationName = supplied - organizationalUnitName = optional - - [ myca_extensions ] - basicConstraints = critical,CA:TRUE - keyUsage = critical,any - subjectKeyIdentifier = hash - authorityKeyIdentifier = keyid:always,issuer - keyUsage = digitalSignature,keyEncipherment,cRLSign,keyCertSign - extendedKeyUsage = serverAuth - crlDistributionPoints = @crl_section - subjectAltName = @alt_names - authorityInfoAccess = @ocsp_section - - [ v3_ca ] - basicConstraints = critical,CA:TRUE,pathlen:0 - keyUsage = critical,any - subjectKeyIdentifier = hash - authorityKeyIdentifier = keyid:always,issuer - keyUsage = digitalSignature,keyEncipherment,cRLSign,keyCertSign - extendedKeyUsage = serverAuth - crlDistributionPoints = @crl_section - subjectAltName = @alt_names - authorityInfoAccess = @ocsp_section - - [alt_names] - DNS.0 = Meerkat Voting Intermediate CA 1 - - [crl_section] - URI.0 = http://crl.factcenter.org/meerkat-root-ca.crl - - [ocsp_section] - caIssuers;URI.0 = http://pki.factcenter.org/meerkat-root-ca.crt - OCSP;URI.0 = http://ocsp.factcenter.org/ +[ ca ] +default_ca = myca + +[ crl_ext ] +issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + + [ myca ] + dir = ./ + new_certs_dir = $dir + unique_subject = no + certificate = $dir/root-ca.crt + database = $dir/certindex + private_key = $dir/root-ca-private-key.pem + serial = $dir/certserial + default_days = 3650 + default_md = sha256 + policy = myca_policy + x509_extensions = myca_extensions + crlnumber = $dir/crlnumber + default_crl_days = 3650 + + [ myca_policy ] + commonName = supplied + stateOrProvinceName = optional + countryName = optional + emailAddress = optional + organizationName = supplied + organizationalUnitName = optional + + [ myca_extensions ] + basicConstraints = critical,CA:TRUE + keyUsage = critical,any + subjectKeyIdentifier = hash + authorityKeyIdentifier = keyid:always,issuer + keyUsage = digitalSignature,keyEncipherment,cRLSign,keyCertSign + extendedKeyUsage = serverAuth + crlDistributionPoints = @crl_section + subjectAltName = @alt_names + authorityInfoAccess = @ocsp_section + + [ v3_ca ] + basicConstraints = critical,CA:TRUE,pathlen:0 + keyUsage = critical,any + subjectKeyIdentifier = hash + authorityKeyIdentifier = keyid:always,issuer + keyUsage = digitalSignature,keyEncipherment,cRLSign,keyCertSign + extendedKeyUsage = serverAuth + crlDistributionPoints = @crl_section + subjectAltName = @alt_names + authorityInfoAccess = @ocsp_section + + [alt_names] + DNS.0 = Meerkat Voting Intermediate CA 1 + + [crl_section] + URI.0 = http://crl.factcenter.org/meerkat-root-ca.crl + + [ocsp_section] + caIssuers;URI.0 = http://pki.factcenter.org/meerkat-root-ca.crt + OCSP;URI.0 = http://ocsp.factcenter.org/ diff --git a/meerkat-common/src/test/resources/certs/root-ca/root-ca-private-key-with-password-secret.pem b/meerkat-common/src/test/resources/certs/root-ca/root-ca-private-key-with-password-secret.pem index a0c442d..2801557 100644 --- a/meerkat-common/src/test/resources/certs/root-ca/root-ca-private-key-with-password-secret.pem +++ b/meerkat-common/src/test/resources/certs/root-ca/root-ca-private-key-with-password-secret.pem @@ -1,8 +1,8 @@ ------BEGIN EC PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: AES-256-CBC,B8CA131346FD6C9568A6C80935F2AF14 - -8q1seEln39/tQTo5KqN+qNRhd0fQ0oC71dYpfTHsP0NlNmjMtwKo2niFwzjxnSyP -vpJjGzUlnq30ucbeJA7CDm/1cmYAU5gGQ7gldgpi2TQVS+EBjqi/Y5P9AlrgLv6K -tKe4AvkqQcpi4ZvlUL9xmNaM9jEH4syopR9YClEMfa8= ------END EC PRIVATE KEY----- +-----BEGIN EC PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,B8CA131346FD6C9568A6C80935F2AF14 + +8q1seEln39/tQTo5KqN+qNRhd0fQ0oC71dYpfTHsP0NlNmjMtwKo2niFwzjxnSyP +vpJjGzUlnq30ucbeJA7CDm/1cmYAU5gGQ7gldgpi2TQVS+EBjqi/Y5P9AlrgLv6K +tKe4AvkqQcpi4ZvlUL9xmNaM9jEH4syopR9YClEMfa8= +-----END EC PRIVATE KEY----- diff --git a/meerkat-common/src/test/resources/certs/root-ca/root-ca-private-key.pem b/meerkat-common/src/test/resources/certs/root-ca/root-ca-private-key.pem index 7966a28..7176b2a 100644 --- a/meerkat-common/src/test/resources/certs/root-ca/root-ca-private-key.pem +++ b/meerkat-common/src/test/resources/certs/root-ca/root-ca-private-key.pem @@ -1,5 +1,5 @@ ------BEGIN EC PRIVATE KEY----- -MHQCAQEEIEi9y6pSKu1kDZcIfQQAnojl1iFxm32W0DVCp2P6HRrkoAcGBSuBBAAK -oUQDQgAEoijIYF12bpA0tcjyQnWZGQ4lzdBGR+hK/5al/M+zFgFwvWHoWf6yJsSB -ymviB5yUaH+cE+/3LXlGbpRzYKLBYQ== ------END EC PRIVATE KEY----- +-----BEGIN EC PRIVATE KEY----- +MHQCAQEEIEi9y6pSKu1kDZcIfQQAnojl1iFxm32W0DVCp2P6HRrkoAcGBSuBBAAK +oUQDQgAEoijIYF12bpA0tcjyQnWZGQ4lzdBGR+hK/5al/M+zFgFwvWHoWf6yJsSB +ymviB5yUaH+cE+/3LXlGbpRzYKLBYQ== +-----END EC PRIVATE KEY----- diff --git a/meerkat-common/src/test/resources/certs/root-ca/root-ca.crt b/meerkat-common/src/test/resources/certs/root-ca/root-ca.crt index d0bd1fa..e884528 100644 --- a/meerkat-common/src/test/resources/certs/root-ca/root-ca.crt +++ b/meerkat-common/src/test/resources/certs/root-ca/root-ca.crt @@ -1,17 +1,17 @@ ------BEGIN CERTIFICATE----- -MIICpTCCAkygAwIBAgIJAJoVb07aGgNaMAoGCCqGSM49BAMCMIGwMQswCQYDVQQG -EwJJTDETMBEGA1UECAwKU29tZS1TdGF0ZTERMA8GA1UEBwwISGVyemxpeWExFDAS -BgNVBAoMC0lEQyBIZXJsaXlhMR8wHQYDVQQLDBZNZWVya2F0IFZvdGluZyBQcm9q -ZWN0MRgwFgYDVQQDDA9UZXN0aW5nIFJvb3QgQ0ExKDAmBgkqhkiG9w0BCQEWGXRl -c3RpbmctY2FAZmFjdGNlbnRlci5vcmcwHhcNMTUxMTExMTUzODE4WhcNMjUxMTA4 -MTUzODE4WjCBsDELMAkGA1UEBhMCSUwxEzARBgNVBAgMClNvbWUtU3RhdGUxETAP -BgNVBAcMCEhlcnpsaXlhMRQwEgYDVQQKDAtJREMgSGVybGl5YTEfMB0GA1UECwwW -TWVlcmthdCBWb3RpbmcgUHJvamVjdDEYMBYGA1UEAwwPVGVzdGluZyBSb290IENB -MSgwJgYJKoZIhvcNAQkBFhl0ZXN0aW5nLWNhQGZhY3RjZW50ZXIub3JnMFYwEAYH -KoZIzj0CAQYFK4EEAAoDQgAEoijIYF12bpA0tcjyQnWZGQ4lzdBGR+hK/5al/M+z -FgFwvWHoWf6yJsSBymviB5yUaH+cE+/3LXlGbpRzYKLBYaNQME4wHQYDVR0OBBYE -FIkP0vV8uZfgD0IGguxhefc4/LWiMB8GA1UdIwQYMBaAFIkP0vV8uZfgD0IGguxh -efc4/LWiMAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgNftHrW30Git8 -VFQKyMCkasauSpEHpAGdcRAhRHqUQMUCIDxw++trz/Iv8818xVB1ARr9EQAmH0aC -7MHETGuiBC7L ------END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICpTCCAkygAwIBAgIJAJoVb07aGgNaMAoGCCqGSM49BAMCMIGwMQswCQYDVQQG +EwJJTDETMBEGA1UECAwKU29tZS1TdGF0ZTERMA8GA1UEBwwISGVyemxpeWExFDAS +BgNVBAoMC0lEQyBIZXJsaXlhMR8wHQYDVQQLDBZNZWVya2F0IFZvdGluZyBQcm9q +ZWN0MRgwFgYDVQQDDA9UZXN0aW5nIFJvb3QgQ0ExKDAmBgkqhkiG9w0BCQEWGXRl +c3RpbmctY2FAZmFjdGNlbnRlci5vcmcwHhcNMTUxMTExMTUzODE4WhcNMjUxMTA4 +MTUzODE4WjCBsDELMAkGA1UEBhMCSUwxEzARBgNVBAgMClNvbWUtU3RhdGUxETAP +BgNVBAcMCEhlcnpsaXlhMRQwEgYDVQQKDAtJREMgSGVybGl5YTEfMB0GA1UECwwW +TWVlcmthdCBWb3RpbmcgUHJvamVjdDEYMBYGA1UEAwwPVGVzdGluZyBSb290IENB +MSgwJgYJKoZIhvcNAQkBFhl0ZXN0aW5nLWNhQGZhY3RjZW50ZXIub3JnMFYwEAYH +KoZIzj0CAQYFK4EEAAoDQgAEoijIYF12bpA0tcjyQnWZGQ4lzdBGR+hK/5al/M+z +FgFwvWHoWf6yJsSBymviB5yUaH+cE+/3LXlGbpRzYKLBYaNQME4wHQYDVR0OBBYE +FIkP0vV8uZfgD0IGguxhefc4/LWiMB8GA1UdIwQYMBaAFIkP0vV8uZfgD0IGguxh +efc4/LWiMAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgNftHrW30Git8 +VFQKyMCkasauSpEHpAGdcRAhRHqUQMUCIDxw++trz/Iv8818xVB1ARr9EQAmH0aC +7MHETGuiBC7L +-----END CERTIFICATE----- diff --git a/meerkat-common/src/test/resources/certs/secp256k1.pem b/meerkat-common/src/test/resources/certs/secp256k1.pem index 32d952e..d707107 100644 --- a/meerkat-common/src/test/resources/certs/secp256k1.pem +++ b/meerkat-common/src/test/resources/certs/secp256k1.pem @@ -1,3 +1,3 @@ ------BEGIN EC PARAMETERS----- -BgUrgQQACg== ------END EC PARAMETERS----- +-----BEGIN EC PARAMETERS----- +BgUrgQQACg== +-----END EC PARAMETERS----- diff --git a/polling-station/build.gradle b/polling-station/build.gradle index 34fe58d..d510d26 100644 --- a/polling-station/build.gradle +++ b/polling-station/build.gradle @@ -1,194 +1,194 @@ - -plugins { - id "us.kirchmeier.capsule" version "1.0.1" - id 'com.google.protobuf' version '0.7.0' -} - -apply plugin: 'java' -apply plugin: 'eclipse' -apply plugin: 'idea' - -apply plugin: 'maven-publish' - -// Uncomment the lines below to define an application -// (this will also allow you to build a "fatCapsule" which includes -// the entire application, including all dependencies in a single jar) -//apply plugin: 'application' -//mainClassName='your.main.ApplicationClass' - - -// Is this a snapshot version? -ext { isSnapshot = false } - -ext { - groupId = 'org.factcenter.meerkat' - nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/" - - // Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing) - // Should be set in ${HOME}/.gradle/gradle.properties - nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : "" - nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : "" -} - -description = "Meerkat polling-station application" - -// Your project version -version = "0.0" - -version += "${isSnapshot ? '-SNAPSHOT' : ''}" - - -dependencies { - // Meerkat common - compile project(':meerkat-common') - - // Logging - compile 'org.slf4j:slf4j-api:1.7.7' - runtime 'ch.qos.logback:logback-classic:1.1.2' - runtime 'ch.qos.logback:logback-core:1.1.2' - - // Google protobufs - compile 'com.google.protobuf:protobuf-java:3.+' - - testCompile 'junit:junit:4.+' - - runtime 'org.codehaus.groovy:groovy:2.4.+' -} - - -/*==== You probably don't have to edit below this line =======*/ - -protobuf { - // Configure the protoc executable - protoc { - // Download from repositories - artifact = 'com.google.protobuf:protoc:3.+' - } -} - - -idea { - module { - project.sourceSets.each { sourceSet -> - - def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java" - - // add protobuf generated sources to generated source dir. - if ("test".equals(sourceSet.name)) { - testSourceDirs += file(srcDir) - } else { - sourceDirs += file(srcDir) - } - generatedSourceDirs += file(srcDir) - - } - - // Don't exclude build directory - excludeDirs -= file(buildDir) - } -} - -/*=================================== - * "Fat" Build targets - *===================================*/ - - -if (project.hasProperty('mainClassName') && (mainClassName != null)) { - - task mavenCapsule(type: MavenCapsule) { - description = "Generate a capsule jar that automatically downloads and caches dependencies when run." - applicationClass mainClassName - destinationDir = buildDir - } - - task fatCapsule(type: FatCapsule) { - description = "Generate a single capsule jar containing everything. Use -Pfatmain=... to override main class" - - destinationDir = buildDir - - def fatMain = hasProperty('fatmain') ? fatmain : mainClassName - - applicationClass fatMain - - def testJar = hasProperty('test') - - if (hasProperty('fatmain')) { - appendix = "fat-${fatMain}" - } else { - appendix = "fat" - } - - if (testJar) { - from sourceSets.test.output - } - } -} - -/*=================================== - * Repositories - *===================================*/ - -repositories { - - // Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral) - maven { - url nexusRepository - - if (isSnapshot) { - credentials { username - password - - username nexusUser - password nexusPassword - } - } - } - - // Use local maven repository - mavenLocal() - - // Use 'maven central' for other dependencies. - mavenCentral() -} - -task "info" << { - println "Project: ${project.name}" -println "Description: ${project.description}" - println "--------------------------" - println "GroupId: $groupId" - println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})" - println "" -} -info.description 'Print some information about project parameters' - - -/*=================================== - * Publishing - *===================================*/ - -publishing { - publications { - mavenJava(MavenPublication) { - groupId project.groupId - pom.withXml { - asNode().appendNode('description', project.description) - } - from project.components.java - - } - } - repositories { - maven { - url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}" - credentials { username - password - - username nexusUser - password nexusPassword - } - } - } -} - - - + +plugins { + id "us.kirchmeier.capsule" version "1.0.1" + id 'com.google.protobuf' version '0.7.0' +} + +apply plugin: 'java' +apply plugin: 'eclipse' +apply plugin: 'idea' + +apply plugin: 'maven-publish' + +// Uncomment the lines below to define an application +// (this will also allow you to build a "fatCapsule" which includes +// the entire application, including all dependencies in a single jar) +//apply plugin: 'application' +//mainClassName='your.main.ApplicationClass' + + +// Is this a snapshot version? +ext { isSnapshot = false } + +ext { + groupId = 'org.factcenter.meerkat' + nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/" + + // Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing) + // Should be set in ${HOME}/.gradle/gradle.properties + nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : "" + nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : "" +} + +description = "Meerkat polling-station application" + +// Your project version +version = "0.0" + +version += "${isSnapshot ? '-SNAPSHOT' : ''}" + + +dependencies { + // Meerkat common + compile project(':meerkat-common') + + // Logging + compile 'org.slf4j:slf4j-api:1.7.7' + runtime 'ch.qos.logback:logback-classic:1.1.2' + runtime 'ch.qos.logback:logback-core:1.1.2' + + // Google protobufs + compile 'com.google.protobuf:protobuf-java:3.+' + + testCompile 'junit:junit:4.+' + + runtime 'org.codehaus.groovy:groovy:2.4.+' +} + + +/*==== You probably don't have to edit below this line =======*/ + +protobuf { + // Configure the protoc executable + protoc { + // Download from repositories + artifact = 'com.google.protobuf:protoc:3.+' + } +} + + +idea { + module { + project.sourceSets.each { sourceSet -> + + def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java" + + // add protobuf generated sources to generated source dir. + if ("test".equals(sourceSet.name)) { + testSourceDirs += file(srcDir) + } else { + sourceDirs += file(srcDir) + } + generatedSourceDirs += file(srcDir) + + } + + // Don't exclude build directory + excludeDirs -= file(buildDir) + } +} + +/*=================================== + * "Fat" Build targets + *===================================*/ + + +if (project.hasProperty('mainClassName') && (mainClassName != null)) { + + task mavenCapsule(type: MavenCapsule) { + description = "Generate a capsule jar that automatically downloads and caches dependencies when run." + applicationClass mainClassName + destinationDir = buildDir + } + + task fatCapsule(type: FatCapsule) { + description = "Generate a single capsule jar containing everything. Use -Pfatmain=... to override main class" + + destinationDir = buildDir + + def fatMain = hasProperty('fatmain') ? fatmain : mainClassName + + applicationClass fatMain + + def testJar = hasProperty('test') + + if (hasProperty('fatmain')) { + appendix = "fat-${fatMain}" + } else { + appendix = "fat" + } + + if (testJar) { + from sourceSets.test.output + } + } +} + +/*=================================== + * Repositories + *===================================*/ + +repositories { + + // Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral) + maven { + url nexusRepository + + if (isSnapshot) { + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } + + // Use local maven repository + mavenLocal() + + // Use 'maven central' for other dependencies. + mavenCentral() +} + +task "info" << { + println "Project: ${project.name}" +println "Description: ${project.description}" + println "--------------------------" + println "GroupId: $groupId" + println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})" + println "" +} +info.description 'Print some information about project parameters' + + +/*=================================== + * Publishing + *===================================*/ + +publishing { + publications { + mavenJava(MavenPublication) { + groupId project.groupId + pom.withXml { + asNode().appendNode('description', project.description) + } + from project.components.java + + } + } + repositories { + maven { + url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}" + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } +} + + + diff --git a/restful-api-common/.gitignore b/restful-api-common/.gitignore index ae3c172..3e2fcc7 100644 --- a/restful-api-common/.gitignore +++ b/restful-api-common/.gitignore @@ -1 +1 @@ -/bin/ +/bin/ diff --git a/restful-api-common/build.gradle b/restful-api-common/build.gradle index 3c0ad1e..483790e 100644 --- a/restful-api-common/build.gradle +++ b/restful-api-common/build.gradle @@ -1,160 +1,160 @@ - -plugins { - id "us.kirchmeier.capsule" version "1.0.1" - id 'com.google.protobuf' version '0.7.0' -} - -apply plugin: 'java' -apply plugin: 'eclipse' -apply plugin: 'idea' - -// Uncomment both lines below to define an application (must set mainClassName -//apply plugin: 'application' -//mainClassName='your.main.ApplicationClass' - -apply plugin: 'maven-publish' - -// Is this a snapshot version? -ext { isSnapshot = false } - -ext { - groupId = 'org.factcenter.meerkat' - nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/" - - // Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing) - // Should be set in ${HOME}/.gradle/gradle.properties - nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : "" - nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : "" -} - -description = "Common classes for implementing Meerkat's RESTful API" - -// Your project version -version = "0.0.1" - -version += "${isSnapshot ? '-SNAPSHOT' : ''}" - - -dependencies { - // Meerkat common - compile project(':meerkat-common') - - // Jersey for RESTful API - compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.22.+' - - // Logging - compile 'org.slf4j:slf4j-api:1.7.7' - runtime 'ch.qos.logback:logback-classic:1.1.2' - runtime 'ch.qos.logback:logback-core:1.1.2' - - // Google protobufs - compile 'com.google.protobuf:protobuf-java:3.+' - - testCompile 'junit:junit:4.+' - - runtime 'org.codehaus.groovy:groovy:2.4.+' -} - - -/*==== You probably don't have to edit below this line =======*/ - -protobuf { - // Configure the protoc executable - protoc { - // Download from repositories - artifact = 'com.google.protobuf:protoc:3.+' - } -} - - -idea { - module { - project.sourceSets.each { sourceSet -> - - def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java" - - // add protobuf generated sources to generated source dir. - if ("test".equals(sourceSet.name)) { - testSourceDirs += file(srcDir) - } else { - sourceDirs += file(srcDir) - } - generatedSourceDirs += file(srcDir) - - } - - // Don't exclude build directory - excludeDirs -= file(buildDir) - } -} - - - -/*=================================== - * Repositories - *===================================*/ - -repositories { - - // Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral) - maven { - url nexusRepository - - if (isSnapshot) { - credentials { username - password - - username nexusUser - password nexusPassword - } - } - } - - // Use local maven repository - mavenLocal() - - // Use 'maven central' for other dependencies. - mavenCentral() -} - -task "info" << { - println "Project: ${project.name}" -println "Description: ${project.description}" - println "--------------------------" - println "GroupId: $groupId" - println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})" - println "" -} -info.description 'Print some information about project parameters' - - -/*=================================== - * Publishing - *===================================*/ - -publishing { - publications { - mavenJava(MavenPublication) { - groupId project.groupId - pom.withXml { - asNode().appendNode('description', project.description) - } - from project.components.java - - } - } - repositories { - maven { - url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}" - credentials { username - password - - username nexusUser - password nexusPassword - } - } - } -} - - - + +plugins { + id "us.kirchmeier.capsule" version "1.0.1" + id 'com.google.protobuf' version '0.7.0' +} + +apply plugin: 'java' +apply plugin: 'eclipse' +apply plugin: 'idea' + +// Uncomment both lines below to define an application (must set mainClassName +//apply plugin: 'application' +//mainClassName='your.main.ApplicationClass' + +apply plugin: 'maven-publish' + +// Is this a snapshot version? +ext { isSnapshot = false } + +ext { + groupId = 'org.factcenter.meerkat' + nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/" + + // Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing) + // Should be set in ${HOME}/.gradle/gradle.properties + nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : "" + nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : "" +} + +description = "Common classes for implementing Meerkat's RESTful API" + +// Your project version +version = "0.0.1" + +version += "${isSnapshot ? '-SNAPSHOT' : ''}" + + +dependencies { + // Meerkat common + compile project(':meerkat-common') + + // Jersey for RESTful API + compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.22.+' + + // Logging + compile 'org.slf4j:slf4j-api:1.7.7' + runtime 'ch.qos.logback:logback-classic:1.1.2' + runtime 'ch.qos.logback:logback-core:1.1.2' + + // Google protobufs + compile 'com.google.protobuf:protobuf-java:3.+' + + testCompile 'junit:junit:4.+' + + runtime 'org.codehaus.groovy:groovy:2.4.+' +} + + +/*==== You probably don't have to edit below this line =======*/ + +protobuf { + // Configure the protoc executable + protoc { + // Download from repositories + artifact = 'com.google.protobuf:protoc:3.+' + } +} + + +idea { + module { + project.sourceSets.each { sourceSet -> + + def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java" + + // add protobuf generated sources to generated source dir. + if ("test".equals(sourceSet.name)) { + testSourceDirs += file(srcDir) + } else { + sourceDirs += file(srcDir) + } + generatedSourceDirs += file(srcDir) + + } + + // Don't exclude build directory + excludeDirs -= file(buildDir) + } +} + + + +/*=================================== + * Repositories + *===================================*/ + +repositories { + + // Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral) + maven { + url nexusRepository + + if (isSnapshot) { + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } + + // Use local maven repository + mavenLocal() + + // Use 'maven central' for other dependencies. + mavenCentral() +} + +task "info" << { + println "Project: ${project.name}" +println "Description: ${project.description}" + println "--------------------------" + println "GroupId: $groupId" + println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})" + println "" +} +info.description 'Print some information about project parameters' + + +/*=================================== + * Publishing + *===================================*/ + +publishing { + publications { + mavenJava(MavenPublication) { + groupId project.groupId + pom.withXml { + asNode().appendNode('description', project.description) + } + from project.components.java + + } + } + repositories { + maven { + url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}" + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } +} + + + diff --git a/restful-api-common/src/main/java/meerkat/rest/Constants.java b/restful-api-common/src/main/java/meerkat/rest/Constants.java index 73ed7d1..239b957 100644 --- a/restful-api-common/src/main/java/meerkat/rest/Constants.java +++ b/restful-api-common/src/main/java/meerkat/rest/Constants.java @@ -1,12 +1,12 @@ -package meerkat.rest; - -/** - * Created by talm on 10/11/15. - */ -public interface Constants { - public static final String MEDIATYPE_PROTOBUF = "application/x-protobuf"; - - public static final String BULLETIN_BOARD_SERVER_PATH = "/bbserver"; - public static final String READ_MESSAGES_PATH = "/readmessages"; - public static final String POST_MESSAGE_PATH = "/postmessage"; -} +package meerkat.rest; + +/** + * Created by talm on 10/11/15. + */ +public interface Constants { + public static final String MEDIATYPE_PROTOBUF = "application/x-protobuf"; + + public static final String BULLETIN_BOARD_SERVER_PATH = "/bbserver"; + public static final String READ_MESSAGES_PATH = "/readmessages"; + public static final String POST_MESSAGE_PATH = "/postmessage"; +} diff --git a/restful-api-common/src/main/java/meerkat/rest/ProtobufMessageBodyReader.java b/restful-api-common/src/main/java/meerkat/rest/ProtobufMessageBodyReader.java index d09e213..a139e17 100644 --- a/restful-api-common/src/main/java/meerkat/rest/ProtobufMessageBodyReader.java +++ b/restful-api-common/src/main/java/meerkat/rest/ProtobufMessageBodyReader.java @@ -1,41 +1,41 @@ -package meerkat.rest; - -import com.google.protobuf.GeneratedMessage; -import com.google.protobuf.Message; - - -import javax.ws.rs.*; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.ext.MessageBodyReader; -import javax.ws.rs.ext.Provider; -import java.io.IOException; -import java.io.InputStream; -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.lang.reflect.Type; - -import static meerkat.rest.Constants.*; - -@Provider -@Consumes(MEDIATYPE_PROTOBUF) -public class ProtobufMessageBodyReader implements MessageBodyReader { - @Override - public boolean isReadable(Class type, Type genericType, Annotation[] annotations, - MediaType mediaType) { - return Message.class.isAssignableFrom(type); - } - - @Override - public Message readFrom(Class type, Type genericType, Annotation[] annotations, - MediaType mediaType, MultivaluedMap httpHeaders, - InputStream entityStream) throws IOException, WebApplicationException { - try { - Method newBuilder = type.getMethod("newBuilder"); - GeneratedMessage.Builder builder = (GeneratedMessage.Builder) newBuilder.invoke(type); - return builder.mergeFrom(entityStream).build(); - } catch (Exception e) { - throw new WebApplicationException(e); - } - } -} +package meerkat.rest; + +import com.google.protobuf.GeneratedMessage; +import com.google.protobuf.Message; + + +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.ext.MessageBodyReader; +import javax.ws.rs.ext.Provider; +import java.io.IOException; +import java.io.InputStream; +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.lang.reflect.Type; + +import static meerkat.rest.Constants.*; + +@Provider +@Consumes(MEDIATYPE_PROTOBUF) +public class ProtobufMessageBodyReader implements MessageBodyReader { + @Override + public boolean isReadable(Class type, Type genericType, Annotation[] annotations, + MediaType mediaType) { + return Message.class.isAssignableFrom(type); + } + + @Override + public Message readFrom(Class type, Type genericType, Annotation[] annotations, + MediaType mediaType, MultivaluedMap httpHeaders, + InputStream entityStream) throws IOException, WebApplicationException { + try { + Method newBuilder = type.getMethod("newBuilder"); + GeneratedMessage.Builder builder = (GeneratedMessage.Builder) newBuilder.invoke(type); + return builder.mergeFrom(entityStream).build(); + } catch (Exception e) { + throw new WebApplicationException(e); + } + } +} diff --git a/restful-api-common/src/main/java/meerkat/rest/ProtobufMessageBodyWriter.java b/restful-api-common/src/main/java/meerkat/rest/ProtobufMessageBodyWriter.java index b8ea503..2397b4b 100644 --- a/restful-api-common/src/main/java/meerkat/rest/ProtobufMessageBodyWriter.java +++ b/restful-api-common/src/main/java/meerkat/rest/ProtobufMessageBodyWriter.java @@ -1,41 +1,41 @@ -package meerkat.rest; - -import com.google.protobuf.Message; - -import javax.ws.rs.*; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.ext.MessageBodyWriter; -import javax.ws.rs.ext.Provider; - -import java.io.IOException; -import java.io.OutputStream; -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; - -import static meerkat.rest.Constants.*; - -@Provider -@Produces(MEDIATYPE_PROTOBUF) -public class ProtobufMessageBodyWriter implements MessageBodyWriter { - @Override - public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, - MediaType mediaType) { - return Message.class.isAssignableFrom(type); - } - - @Override - public long getSize(Message message, Class type, Type genericType, Annotation[] annotations, - MediaType mediaType) { - return -1; - } - - @Override - public void writeTo(Message message, Class type, Type genericType, Annotation[] annotations, - MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) - throws IOException, WebApplicationException { - message.writeTo(entityStream); - } -} - - +package meerkat.rest; + +import com.google.protobuf.Message; + +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.ext.MessageBodyWriter; +import javax.ws.rs.ext.Provider; + +import java.io.IOException; +import java.io.OutputStream; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +import static meerkat.rest.Constants.*; + +@Provider +@Produces(MEDIATYPE_PROTOBUF) +public class ProtobufMessageBodyWriter implements MessageBodyWriter { + @Override + public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, + MediaType mediaType) { + return Message.class.isAssignableFrom(type); + } + + @Override + public long getSize(Message message, Class type, Type genericType, Annotation[] annotations, + MediaType mediaType) { + return -1; + } + + @Override + public void writeTo(Message message, Class type, Type genericType, Annotation[] annotations, + MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) + throws IOException, WebApplicationException { + message.writeTo(entityStream); + } +} + + diff --git a/settings.gradle b/settings.gradle index 5f81a65..f019032 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,8 +1,8 @@ -include 'meerkat-common' -include 'voting-booth' -include 'bulletin-board-server' -include 'polling-station' -include 'restful-api-common' -include 'bulletin-board-client' -include 'destributed-key-generation' - +include 'meerkat-common' +include 'voting-booth' +include 'bulletin-board-server' +include 'polling-station' +include 'restful-api-common' +include 'bulletin-board-client' +include 'destributed-key-generation' + diff --git a/voting-booth/build.gradle b/voting-booth/build.gradle index 70d7340..241e3c3 100644 --- a/voting-booth/build.gradle +++ b/voting-booth/build.gradle @@ -1,193 +1,193 @@ - -plugins { - id "us.kirchmeier.capsule" version "1.0.1" - id 'com.google.protobuf' version '0.7.0' -} - -apply plugin: 'java' -apply plugin: 'eclipse' -apply plugin: 'idea' - -apply plugin: 'maven-publish' - -// Uncomment the lines below to define an application -// (this will also allow you to build a "fatCapsule" which includes -// the entire application, including all dependencies in a single jar) -//apply plugin: 'application' -//mainClassName='your.main.ApplicationClass' - -// Is this a snapshot version? -ext { isSnapshot = false } - -ext { - groupId = 'org.factcenter.meerkat' - nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/" - - // Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing) - // Should be set in ${HOME}/.gradle/gradle.properties - nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : "" - nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : "" -} - -description = "Meerkat voting booth application" - -// Your project version -version = "0.0" - -version += "${isSnapshot ? '-SNAPSHOT' : ''}" - - -dependencies { - // Meerkat common - compile project(':meerkat-common') - - // Logging - compile 'org.slf4j:slf4j-api:1.7.7' - runtime 'ch.qos.logback:logback-classic:1.1.2' - runtime 'ch.qos.logback:logback-core:1.1.2' - - // Google protobufs - compile 'com.google.protobuf:protobuf-java:3.+' - - testCompile 'junit:junit:4.+' - - runtime 'org.codehaus.groovy:groovy:2.4.+' -} - - -/*==== You probably don't have to edit below this line =======*/ - -protobuf { - // Configure the protoc executable - protoc { - // Download from repositories - artifact = 'com.google.protobuf:protoc:3.+' - } -} - - -idea { - module { - project.sourceSets.each { sourceSet -> - - def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java" - - // add protobuf generated sources to generated source dir. - if ("test".equals(sourceSet.name)) { - testSourceDirs += file(srcDir) - } else { - sourceDirs += file(srcDir) - } - generatedSourceDirs += file(srcDir) - - } - - // Don't exclude build directory - excludeDirs -= file(buildDir) - } -} - - -/*=================================== - * "Fat" Build targets - *===================================*/ - -if (project.hasProperty('mainClassName') && (mainClassName != null)) { - - task mavenCapsule(type: MavenCapsule) { - description = "Generate a capsule jar that automatically downloads and caches dependencies when run." - applicationClass mainClassName - destinationDir = buildDir - } - - task fatCapsule(type: FatCapsule) { - description = "Generate a single capsule jar containing everything. Use -Pfatmain=... to override main class" - - destinationDir = buildDir - - def fatMain = hasProperty('fatmain') ? fatmain : mainClassName - - applicationClass fatMain - - def testJar = hasProperty('test') - - if (hasProperty('fatmain')) { - appendix = "fat-${fatMain}" - } else { - appendix = "fat" - } - - if (testJar) { - from sourceSets.test.output - } - } -} - -/*=================================== - * Repositories - *===================================*/ - -repositories { - - // Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral) - maven { - url nexusRepository - - if (isSnapshot) { - credentials { username - password - - username nexusUser - password nexusPassword - } - } - } - - // Use local maven repository - mavenLocal() - - // Use 'maven central' for other dependencies. - mavenCentral() -} - -task "info" << { - println "Project: ${project.name}" -println "Description: ${project.description}" - println "--------------------------" - println "GroupId: $groupId" - println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})" - println "" -} -info.description 'Print some information about project parameters' - - -/*=================================== - * Publishing - *===================================*/ - -publishing { - publications { - mavenJava(MavenPublication) { - groupId project.groupId - pom.withXml { - asNode().appendNode('description', project.description) - } - from project.components.java - - } - } - repositories { - maven { - url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}" - credentials { username - password - - username nexusUser - password nexusPassword - } - } - } -} - - - + +plugins { + id "us.kirchmeier.capsule" version "1.0.1" + id 'com.google.protobuf' version '0.7.0' +} + +apply plugin: 'java' +apply plugin: 'eclipse' +apply plugin: 'idea' + +apply plugin: 'maven-publish' + +// Uncomment the lines below to define an application +// (this will also allow you to build a "fatCapsule" which includes +// the entire application, including all dependencies in a single jar) +//apply plugin: 'application' +//mainClassName='your.main.ApplicationClass' + +// Is this a snapshot version? +ext { isSnapshot = false } + +ext { + groupId = 'org.factcenter.meerkat' + nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/" + + // Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing) + // Should be set in ${HOME}/.gradle/gradle.properties + nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : "" + nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : "" +} + +description = "Meerkat voting booth application" + +// Your project version +version = "0.0" + +version += "${isSnapshot ? '-SNAPSHOT' : ''}" + + +dependencies { + // Meerkat common + compile project(':meerkat-common') + + // Logging + compile 'org.slf4j:slf4j-api:1.7.7' + runtime 'ch.qos.logback:logback-classic:1.1.2' + runtime 'ch.qos.logback:logback-core:1.1.2' + + // Google protobufs + compile 'com.google.protobuf:protobuf-java:3.+' + + testCompile 'junit:junit:4.+' + + runtime 'org.codehaus.groovy:groovy:2.4.+' +} + + +/*==== You probably don't have to edit below this line =======*/ + +protobuf { + // Configure the protoc executable + protoc { + // Download from repositories + artifact = 'com.google.protobuf:protoc:3.+' + } +} + + +idea { + module { + project.sourceSets.each { sourceSet -> + + def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java" + + // add protobuf generated sources to generated source dir. + if ("test".equals(sourceSet.name)) { + testSourceDirs += file(srcDir) + } else { + sourceDirs += file(srcDir) + } + generatedSourceDirs += file(srcDir) + + } + + // Don't exclude build directory + excludeDirs -= file(buildDir) + } +} + + +/*=================================== + * "Fat" Build targets + *===================================*/ + +if (project.hasProperty('mainClassName') && (mainClassName != null)) { + + task mavenCapsule(type: MavenCapsule) { + description = "Generate a capsule jar that automatically downloads and caches dependencies when run." + applicationClass mainClassName + destinationDir = buildDir + } + + task fatCapsule(type: FatCapsule) { + description = "Generate a single capsule jar containing everything. Use -Pfatmain=... to override main class" + + destinationDir = buildDir + + def fatMain = hasProperty('fatmain') ? fatmain : mainClassName + + applicationClass fatMain + + def testJar = hasProperty('test') + + if (hasProperty('fatmain')) { + appendix = "fat-${fatMain}" + } else { + appendix = "fat" + } + + if (testJar) { + from sourceSets.test.output + } + } +} + +/*=================================== + * Repositories + *===================================*/ + +repositories { + + // Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral) + maven { + url nexusRepository + + if (isSnapshot) { + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } + + // Use local maven repository + mavenLocal() + + // Use 'maven central' for other dependencies. + mavenCentral() +} + +task "info" << { + println "Project: ${project.name}" +println "Description: ${project.description}" + println "--------------------------" + println "GroupId: $groupId" + println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})" + println "" +} +info.description 'Print some information about project parameters' + + +/*=================================== + * Publishing + *===================================*/ + +publishing { + publications { + mavenJava(MavenPublication) { + groupId project.groupId + pom.withXml { + asNode().appendNode('description', project.description) + } + from project.components.java + + } + } + repositories { + maven { + url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}" + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } +} + + + From 0ae9719bc501d9baadd579b807e64ac0f3d8d8f2 Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Fri, 8 Apr 2016 15:03:32 +0300 Subject: [PATCH 33/49] generic group + wait instead of sleep --- .../src/main/java/Communication/Channel.java | 28 - .../src/main/java/Communication/Network.java | 75 -- .../src/main/java/Communication/User.java | 74 -- .../VerifiableSecretSharing.java | 102 --- .../SecureDistributedKeyGeneration.java | 141 --- .../SecureDistributedKeyGenerationParty.java | 29 - .../DistributedKeyGenerationUser.java | 13 - .../java/UserInterface/SecretSharingUser.java | 14 - .../VerifiableSecretSharingUser.java | 16 - .../java/meerkat/crypto/KeyGeneration.java | 11 + .../java/meerkat/crypto/SecretSharing.java | 7 + .../Communication/ChannelImpl.java | 108 +++ .../Communication/MailHandler.java | 114 ++- .../Communication/MessageHandler.java | 30 +- .../gjkr_secure_protocol/MailHandler.java} | 126 +-- .../gjkr_secure_protocol/Party.java | 29 + .../gjkr_secure_protocol/Protocol.java | 165 ++++ .../gjkr_secure_protocol/User.java} | 633 ++++++------- .../joint_feldman_protocol/MailHandler.java} | 98 +- .../joint_feldman_protocol/Party.java} | 67 +- .../joint_feldman_protocol/Protocol.java} | 636 +++++++------ .../joint_feldman_protocol/User.java} | 847 ++++++++++-------- .../VerifiableSecretSharing.java | 108 +++ .../shamir}/LagrangePolynomial.java | 132 +-- .../secret_shring/shamir}/Polynomial.java | 416 ++++----- .../secret_shring/shamir}/SecretSharing.java | 222 ++--- .../crypto/utilitis}/Arithmetic.java | 36 +- .../java/meerkat/crypto/utilitis/Channel.java | 26 + .../crypto/utilitis/concrete}/Fp.java | 77 +- .../src/test/java/Utils/ChannelImpl.java | 108 +++ .../Arithmetics => test/java/Utils}/Z.java | 59 +- .../SDKGMaliciousUserImpl.java | 123 +-- .../gjkr_secure_protocol}/SDKGTest.java | 358 ++++---- .../SDKGUserImplAbort.java | 128 ++- .../DKGMaliciousUser.java} | 145 +-- .../joint_feldman_protocol}/DKGTest.java | 354 ++++---- .../DKGUserImplAbort.java | 126 +-- .../VerifiableSecretSharingTest.java | 135 +-- .../shamir}/PolynomialTests/AddTest.java | 92 +- .../PolynomialTests/InterpolationTest.java | 136 +-- .../PolynomialTests/MulByConstTest.java | 96 +- .../shamir}/PolynomialTests/MulTest.java | 96 +- .../shamir}/SecretSharingTest.java | 127 +-- 43 files changed, 3351 insertions(+), 3112 deletions(-) delete mode 100644 destributed-key-generation/src/main/java/Communication/Channel.java delete mode 100644 destributed-key-generation/src/main/java/Communication/Network.java delete mode 100644 destributed-key-generation/src/main/java/Communication/User.java delete mode 100644 destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java delete mode 100644 destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGeneration.java delete mode 100644 destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationParty.java delete mode 100644 destributed-key-generation/src/main/java/UserInterface/DistributedKeyGenerationUser.java delete mode 100644 destributed-key-generation/src/main/java/UserInterface/SecretSharingUser.java delete mode 100644 destributed-key-generation/src/main/java/UserInterface/VerifiableSecretSharingUser.java create mode 100644 destributed-key-generation/src/main/java/meerkat/crypto/KeyGeneration.java create mode 100644 destributed-key-generation/src/main/java/meerkat/crypto/SecretSharing.java create mode 100644 destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/ChannelImpl.java rename destributed-key-generation/src/main/java/{ => meerkat/crypto/concrete/distributed_key_generation}/Communication/MailHandler.java (70%) rename destributed-key-generation/src/main/java/{ => meerkat/crypto/concrete/distributed_key_generation}/Communication/MessageHandler.java (89%) rename destributed-key-generation/src/main/java/{SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationMailHandler.java => meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/MailHandler.java} (71%) create mode 100644 destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Party.java create mode 100644 destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Protocol.java rename destributed-key-generation/src/main/java/{SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationUserImpl.java => meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/User.java} (58%) rename destributed-key-generation/src/main/java/{JointFeldmanProtocol/DistributedKeyGenerationMailHandler.java => meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/MailHandler.java} (74%) rename destributed-key-generation/src/main/java/{JointFeldmanProtocol/DistributedKeyGenerationParty.java => meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Party.java} (61%) rename destributed-key-generation/src/main/java/{JointFeldmanProtocol/DistributedKeyGeneration.java => meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Protocol.java} (51%) rename destributed-key-generation/src/main/java/{JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java => meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/User.java} (61%) create mode 100644 destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharing.java rename destributed-key-generation/src/main/java/{ShamirSecretSharing => meerkat/crypto/concrete/secret_shring/shamir}/LagrangePolynomial.java (94%) rename destributed-key-generation/src/main/java/{ShamirSecretSharing => meerkat/crypto/concrete/secret_shring/shamir}/Polynomial.java (94%) rename destributed-key-generation/src/main/java/{ShamirSecretSharing => meerkat/crypto/concrete/secret_shring/shamir}/SecretSharing.java (84%) rename destributed-key-generation/src/main/java/{Arithmetics => meerkat/crypto/utilitis}/Arithmetic.java (85%) create mode 100644 destributed-key-generation/src/main/java/meerkat/crypto/utilitis/Channel.java rename destributed-key-generation/src/main/java/{Arithmetics => meerkat/crypto/utilitis/concrete}/Fp.java (90%) create mode 100644 destributed-key-generation/src/test/java/Utils/ChannelImpl.java rename destributed-key-generation/src/{main/java/Arithmetics => test/java/Utils}/Z.java (84%) rename destributed-key-generation/src/test/java/{SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem => meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol}/SDKGMaliciousUserImpl.java (53%) rename destributed-key-generation/src/test/java/{SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem => meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol}/SDKGTest.java (77%) rename destributed-key-generation/src/test/java/{SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem => meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol}/SDKGUserImplAbort.java (66%) rename destributed-key-generation/src/test/java/{JointFeldmanProtocol/DKGMaliciousUserImpl.java => meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGMaliciousUser.java} (59%) rename destributed-key-generation/src/test/java/{JointFeldmanProtocol => meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol}/DKGTest.java (78%) rename destributed-key-generation/src/test/java/{JointFeldmanProtocol => meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol}/DKGUserImplAbort.java (75%) rename destributed-key-generation/src/test/java/{FeldmanVerifiableSecretSharing => meerkat/crypto/concrete/secret_shring/feldman_verifiable}/VerifiableSecretSharingTest.java (85%) rename destributed-key-generation/src/test/java/{ShamirSecretSharing => meerkat/crypto/concrete/secret_shring/shamir}/PolynomialTests/AddTest.java (89%) rename destributed-key-generation/src/test/java/{ShamirSecretSharing => meerkat/crypto/concrete/secret_shring/shamir}/PolynomialTests/InterpolationTest.java (89%) rename destributed-key-generation/src/test/java/{ShamirSecretSharing => meerkat/crypto/concrete/secret_shring/shamir}/PolynomialTests/MulByConstTest.java (89%) rename destributed-key-generation/src/test/java/{ShamirSecretSharing => meerkat/crypto/concrete/secret_shring/shamir}/PolynomialTests/MulTest.java (89%) rename destributed-key-generation/src/test/java/{ShamirSecretSharing => meerkat/crypto/concrete/secret_shring/shamir}/SecretSharingTest.java (81%) diff --git a/destributed-key-generation/src/main/java/Communication/Channel.java b/destributed-key-generation/src/main/java/Communication/Channel.java deleted file mode 100644 index cedb213..0000000 --- a/destributed-key-generation/src/main/java/Communication/Channel.java +++ /dev/null @@ -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 Channel thread, so no long processing should -// * occur in the callback method. -// * @param callback -// */ -// public void registerReceiverCallback(ReceiverCallback callback); -//} diff --git a/destributed-key-generation/src/main/java/Communication/Network.java b/destributed-key-generation/src/main/java/Communication/Network.java deleted file mode 100644 index 8de25b3..0000000 --- a/destributed-key-generation/src/main/java/Communication/Network.java +++ /dev/null @@ -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 availableIDs; - public static final int BROADCAST = 0; - - - public Network(int n) { - this.n = n; - this.users = new User[n]; - this.availableIDs = new HashSet(); - 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); - } - } - -} diff --git a/destributed-key-generation/src/main/java/Communication/User.java b/destributed-key-generation/src/main/java/Communication/User.java deleted file mode 100644 index 1eb6e4a..0000000 --- a/destributed-key-generation/src/main/java/Communication/User.java +++ /dev/null @@ -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 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( 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 - } - } - } - } - } - - -} diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java deleted file mode 100644 index 7b5b7ad..0000000 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java +++ /dev/null @@ -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 rather than fix to biginteger (allow using EC groups for better comm. complexity) -public class VerifiableSecretSharing extends SecretSharing { - protected final Group 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 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 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 getGroup(){ - return group; - } - - /** - * getter - * @return copy of commitmentsArray - */ - public BigInteger[] getCommitmentsArray() { - return Arrays.copyOf(commitmentsArray, commitmentsArray.length); - } - -} diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGeneration.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGeneration.java deleted file mode 100644 index 9aefeb5..0000000 --- a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGeneration.java +++ /dev/null @@ -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 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 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; - } -} diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationParty.java b/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationParty.java deleted file mode 100644 index fc2e8e3..0000000 --- a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationParty.java +++ /dev/null @@ -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 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(); - } -} diff --git a/destributed-key-generation/src/main/java/UserInterface/DistributedKeyGenerationUser.java b/destributed-key-generation/src/main/java/UserInterface/DistributedKeyGenerationUser.java deleted file mode 100644 index 9fcdbf6..0000000 --- a/destributed-key-generation/src/main/java/UserInterface/DistributedKeyGenerationUser.java +++ /dev/null @@ -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 getQUAL(); -} diff --git a/destributed-key-generation/src/main/java/UserInterface/SecretSharingUser.java b/destributed-key-generation/src/main/java/UserInterface/SecretSharingUser.java deleted file mode 100644 index e5462a0..0000000 --- a/destributed-key-generation/src/main/java/UserInterface/SecretSharingUser.java +++ /dev/null @@ -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(); -} diff --git a/destributed-key-generation/src/main/java/UserInterface/VerifiableSecretSharingUser.java b/destributed-key-generation/src/main/java/UserInterface/VerifiableSecretSharingUser.java deleted file mode 100644 index a8e4e96..0000000 --- a/destributed-key-generation/src/main/java/UserInterface/VerifiableSecretSharingUser.java +++ /dev/null @@ -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 getGroup(); -} diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/KeyGeneration.java b/destributed-key-generation/src/main/java/meerkat/crypto/KeyGeneration.java new file mode 100644 index 0000000..a6db4f9 --- /dev/null +++ b/destributed-key-generation/src/main/java/meerkat/crypto/KeyGeneration.java @@ -0,0 +1,11 @@ +package meerkat.crypto; + +import java.util.Random; + +/** + * Created by Tzlil on 4/8/2016. + */ +public interface KeyGeneration { + + T generateKey(Random random); +} diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/SecretSharing.java b/destributed-key-generation/src/main/java/meerkat/crypto/SecretSharing.java new file mode 100644 index 0000000..e7619b6 --- /dev/null +++ b/destributed-key-generation/src/main/java/meerkat/crypto/SecretSharing.java @@ -0,0 +1,7 @@ +package meerkat.crypto; + +/** + * Created by Tzlil on 4/8/2016. + */ +public class SecretSharing { +} diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/ChannelImpl.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/ChannelImpl.java new file mode 100644 index 0000000..04fa4ef --- /dev/null +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/ChannelImpl.java @@ -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 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( 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(); + } + + + +} diff --git a/destributed-key-generation/src/main/java/Communication/MailHandler.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/MailHandler.java similarity index 70% rename from destributed-key-generation/src/main/java/Communication/MailHandler.java rename to destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/MailHandler.java index 23fd840..b01801f 100644 --- a/destributed-key-generation/src/main/java/Communication/MailHandler.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/MailHandler.java @@ -1,58 +1,56 @@ -package Communication; - -import com.google.protobuf.Message; -import meerkat.protobuf.DKGMessages; - -/** - * Created by Tzlil on 2/14/2016. - */ -public abstract class MailHandler { - - private MessageHandler messageHandler; - public MailHandler(MessageHandler messageHandler){ - this.messageHandler = messageHandler; - } - - public abstract Message extractMessage(DKGMessages.Mail mail); - - public void handel(DKGMessages.Mail mail){ - - Message message = extractMessage(mail); - if (message == null) - return; - - switch (mail.getType()) { - case SECRET: - messageHandler.handleSecretMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST - , message); - break; - case COMMITMENT: - messageHandler.handleCommitmentMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST - , message); - break; - case DONE: - messageHandler.handleDoneMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST - , message); - break; - case COMPLAINT: - messageHandler.handleComplaintMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST - , message); - break; - case ANSWER: - messageHandler.handleAnswerMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST - , message); - break; - case ABORT: - messageHandler.handleAbortMessage(mail.getSender(), mail.getDestination() == Network.BROADCAST - , message); - break; - default: - break; - } - - - } - public void setMessageHandler(MessageHandler messageHandler) { - this.messageHandler = messageHandler; - } -} +package meerkat.crypto.concrete.distributed_key_generation.Communication; + +import com.google.protobuf.Message; +import meerkat.crypto.utilitis.Channel; +import meerkat.protobuf.DKGMessages; + +/** + * Created by Tzlil on 2/14/2016. + */ +public abstract class MailHandler implements Channel.ReceiverCallback{ + + private MessageHandler messageHandler; + public MailHandler(MessageHandler messageHandler){ + this.messageHandler = messageHandler; + } + + public abstract Message extractMessage(DKGMessages.Mail mail); + + public void receiveMail(DKGMessages.Mail mail){ + + Message message = extractMessage(mail); + if (message == null) + return; + + switch (mail.getType()) { + case SHARE: + messageHandler.handleSecretMessage(mail.getSender(), mail.getDestination() == ChannelImpl.BROADCAST + , message); + break; + case COMMITMENT: + messageHandler.handleCommitmentMessage(mail.getSender(), mail.getDestination() == ChannelImpl.BROADCAST + , message); + break; + case DONE: + messageHandler.handleDoneMessage(mail.getSender(), mail.getDestination() == ChannelImpl.BROADCAST + , message); + break; + case COMPLAINT: + messageHandler.handleComplaintMessage(mail.getSender(), mail.getDestination() == ChannelImpl.BROADCAST + , message); + break; + case ANSWER: + messageHandler.handleAnswerMessage(mail.getSender(), mail.getDestination() == ChannelImpl.BROADCAST + , message); + break; + case ABORT: + messageHandler.handleAbortMessage(mail.getSender(), mail.getDestination() == ChannelImpl.BROADCAST + , message); + break; + default: + break; + } + + + } +} diff --git a/destributed-key-generation/src/main/java/Communication/MessageHandler.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/MessageHandler.java similarity index 89% rename from destributed-key-generation/src/main/java/Communication/MessageHandler.java rename to destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/MessageHandler.java index 2bbf3c4..74b453a 100644 --- a/destributed-key-generation/src/main/java/Communication/MessageHandler.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/MessageHandler.java @@ -1,15 +1,15 @@ -package Communication; - -import com.google.protobuf.Message; - -/** - * Created by Tzlil on 2/14/2016. - */ -public interface MessageHandler { - void handleSecretMessage(int sender, boolean isBroadcast, Message message); - void handleCommitmentMessage(int sender, boolean isBroadcast, Message message); - void handleComplaintMessage(int sender, boolean isBroadcast, Message message); - void handleDoneMessage(int sender, boolean isBroadcast, Message message); - void handleAnswerMessage(int sender, boolean isBroadcast, Message message); - void handleAbortMessage(int sender, boolean isBroadcast, Message message); -} +package meerkat.crypto.concrete.distributed_key_generation.Communication; + +import com.google.protobuf.Message; + +/** + * Created by Tzlil on 2/14/2016. + */ +public interface MessageHandler { + void handleSecretMessage(int sender, boolean isBroadcast, Message message); + void handleCommitmentMessage(int sender, boolean isBroadcast, Message message); + void handleComplaintMessage(int sender, boolean isBroadcast, Message message); + void handleDoneMessage(int sender, boolean isBroadcast, Message message); + void handleAnswerMessage(int sender, boolean isBroadcast, Message message); + void handleAbortMessage(int sender, boolean isBroadcast, Message message); +} diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationMailHandler.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/MailHandler.java similarity index 71% rename from destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationMailHandler.java rename to destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/MailHandler.java index 92dba85..4683f04 100644 --- a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationMailHandler.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/MailHandler.java @@ -1,63 +1,63 @@ -package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; - -import Communication.MailHandler; -import Communication.MessageHandler; -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Message; -import meerkat.protobuf.DKGMessages; - -/** - * Created by Tzlil on 2/29/2016. - */ -public class SecureDistributedKeyGenerationMailHandler extends MailHandler { - - private boolean isStage4; - - public SecureDistributedKeyGenerationMailHandler(MessageHandler messageHandler) { - super(messageHandler); - this.isStage4 = false; - } - - @Override - public Message extractMessage(DKGMessages.Mail mail) { - try { - Message message; - switch (mail.getType()) { - case SECRET: - message = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage()); - break; - case COMMITMENT: - message = DKGMessages.CommitmentMessage.parseFrom(mail.getMessage()); - break; - case COMPLAINT: - if(!isStage4) - message = DKGMessages.IDMessage.parseFrom(mail.getMessage()); - else - message = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage()); - break; - case DONE: - message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); - break; - case ANSWER: - message = DKGMessages.DoubleSecretMessage.parseFrom(mail.getMessage()); - break; - case ABORT: - message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); - break; - default: - return null; - } - return message; - } catch (InvalidProtocolBufferException e) { - return null; - } - } - - public boolean isStage4() { - return isStage4; - } - - public void setStage4(boolean stage4) { - isStage4 = stage4; - } -} +package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol; + +import Communication.MailHandler; +import Communication.MessageHandler; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; +import meerkat.protobuf.DKGMessages; + +/** + * Created by Tzlil on 2/29/2016. + */ +public class MailHandler extends Communication.MailHandler { + + private boolean isStage4; + + public MailHandler(MessageHandler messageHandler) { + super(messageHandler); + this.isStage4 = false; + } + + @Override + public Message extractMessage(DKGMessages.Mail mail) { + try { + Message message; + switch (mail.getType()) { + case SHARE: + message = DKGMessages.DoubleShareMessage.parseFrom(mail.getMessage()); + break; + case COMMITMENT: + message = DKGMessages.CommitmentMessage.parseFrom(mail.getMessage()); + break; + case COMPLAINT: + if(!isStage4) + message = DKGMessages.IDMessage.parseFrom(mail.getMessage()); + else + message = DKGMessages.DoubleShareMessage.parseFrom(mail.getMessage()); + break; + case DONE: + message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); + break; + case ANSWER: + message = DKGMessages.DoubleShareMessage.parseFrom(mail.getMessage()); + break; + case ABORT: + message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); + break; + default: + return null; + } + return message; + } catch (InvalidProtocolBufferException e) { + return null; + } + } + + public boolean isStage4() { + return isStage4; + } + + public void setStage4(boolean stage4) { + isStage4 = stage4; + } +} diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Party.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Party.java new file mode 100644 index 0000000..82ebba8 --- /dev/null +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Party.java @@ -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 extends DistributedKeyGenerationParty { + public Polynomial.Point shareT; + public boolean ysDoneFlag; + public ArrayList verifiableValues; + public Set recoverSharesSet; + public Party(int id, int n, int t) { + super(id, n, t); + this.shareT = null; + this.ysDoneFlag = false; + this.verifiableValues = new ArrayList(this.commitments); + this.recoverSharesSet = new HashSet(); + } +} diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Protocol.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Protocol.java new file mode 100644 index 0000000..db0cc56 --- /dev/null +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Protocol.java @@ -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 extends meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.Protocol { + + private VerifiableSecretSharing maskingShares; + private final T h; + private Party[] parties; + + public Protocol(int t, int n, BigInteger zi, Random random, BigInteger q, T g + , T h, Group group, int id, ByteEncoder 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 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 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 verificationValues = new ArrayList(t+1); + ArrayList 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; + } +} diff --git a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationUserImpl.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/User.java similarity index 58% rename from destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationUserImpl.java rename to destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/User.java index 141b854..ac99b6e 100644 --- a/destributed-key-generation/src/main/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SecureDistributedKeyGenerationUserImpl.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/User.java @@ -1,307 +1,326 @@ -package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; - -import Arithmetics.Arithmetic; -import Arithmetics.Fp; -import Communication.Network; -import JointFeldmanProtocol.DistributedKeyGeneration; -import JointFeldmanProtocol.DistributedKeyGenerationUserImpl; -import ShamirSecretSharing.Polynomial; -import ShamirSecretSharing.SecretSharing; -import com.google.protobuf.Message; -import meerkat.protobuf.DKGMessages; - -import java.math.BigInteger; - -/** - * Created by Tzlil on 3/16/2016. - */ -public class SecureDistributedKeyGenerationUserImpl extends DistributedKeyGenerationUserImpl { - - protected SecureDistributedKeyGenerationParty[] parties; - protected final SecureDistributedKeyGeneration sdkg; - private Arithmetic arithmetic; - private boolean isStage4; - - public SecureDistributedKeyGenerationUserImpl(SecureDistributedKeyGeneration sdkg, Network network) { - super(sdkg, network,new SecureDistributedKeyGenerationMailHandler(null)); - this.sdkg = sdkg; - this.messageHandler = new MessageHandler(); - this.user.setMessageHandler(this.messageHandler); - this.parties = sdkg.getParties(); - this.arithmetic = new Fp(sdkg.getQ()); - this.isStage4 = false; - } - - /** - * stage1 according to the protocol - * 1. Pi broadcasts Cik=Aik*Bik for k = 0,...,t. - * 2. Pi computes the shares Sij,Sij' for j = 1,...,n and sends Sij,Sij' secretly to Pj. - */ - @Override - protected void stage1() { - sdkg.broadcastVerificationValues(user); - sdkg.sendSecrets(user); - } - - @Override - protected void waitUntilStageOneCompleted(){ - super.waitUntilStageOneCompleted(); - // save the received commitments as verification values - BigInteger[] 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 - */ - @Override - protected void stage2(){ - sdkg.broadcastComplaints(user); - //broadcast done message after all complaints - DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build(); - user.broadcast(DKGMessages.Mail.Type.DONE,doneMessage); - } - - // TODO: ?? - private void resolveQualifyingPublicKey(){ - sdkg.broadcastCommitments(user); - // wait until all parties in QUAL broadcast their commitments or aborted - // TODO: in main run loop - for (int i:QUAL) { - for(int k = 0; k <= t; k++) { - while (parties[i - 1].commitments[k] == null && !parties[i - 1].aborted) { - try { - Thread.sleep(SleepTime); - } catch (InterruptedException e) { - // do nothing - } - } - } - } - sdkg.computeAndBroadcastComplaints(user,QUAL); - //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) { - while (!parties[i - 1].ysDoneFlag && !parties[i - 1].aborted) { - try { - Thread.sleep(SleepTime); - } catch (InterruptedException e) { - // do nothing - } - } - } - - // broadcast i private secret foreach i in QUAL that aborted - for (int i:QUAL) { - if(parties[i - 1].aborted){ - 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){ - while (parties[i - 1].restoreSharesSet.size() <= t) { - try { - Thread.sleep(SleepTime); - } catch (InterruptedException e) { - // do nothing - } - } - } - } - - // restore necessary information - for (int i = 0; i < n ; i++) { - if(parties[i].restoreSharesSet.isEmpty()){ - continue; - } - 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; - } - } - Polynomial polynomial = SecretSharing.recoverPolynomial(shares,arithmetic); - BigInteger[] coefficients = polynomial.getCoefficients(); - for (int k = 0 ; k <= t; k++){ - parties[i].commitments[k] = group.multiply(g,coefficients[k]); - } - parties[i].share = new Polynomial.Point(BigInteger.valueOf(id),polynomial); - } - } - - /** - * notifies mail handler that stage 4 was started - */ - protected void setStage4(){ - this.isStage4 = true; - SecureDistributedKeyGenerationMailHandler handler = - (SecureDistributedKeyGenerationMailHandler)user.getMailHandler(); - handler.setStage4(true); - } - - @Override - protected void stage4() { - setStage4(); - resolveQualifyingPublicKey(); - super.stage4(); - } - - private class MessageHandler extends DistributedKeyGenerationUserImpl.MessageHandler{ - - /** - * as in super, with extension to double secret message - */ - protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKGMessages.DoubleSecretMessage doubleSecretMessage) { - DKGMessages.SecretMessage secretMessage = DKGMessages.SecretMessage.newBuilder() - .setI(doubleSecretMessage.getI()) - .setJ(doubleSecretMessage.getJ()) - .setSecret(doubleSecretMessage.getSecret()) - .build(); - return super.isValidSecretMessage(sender,isBroadcast,secretMessage); - } - - /** - * as in super, with extension to double secret message - */ - @Override - public void handleSecretMessage(int sender, boolean isBroadcast, Message message) { - DKGMessages.DoubleSecretMessage doubleSecretMessage = (DKGMessages.DoubleSecretMessage)message; - 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()); - } - } - - /** - * if !isStage4 as super, with extension to double secret message - * else answer message is valid if: - * 1. it was received in broadcast chanel - * 2. secret.j == sender - * 3. QUAL contains i and j - */ - 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()) - .build(); - return super.isValidAnswerMessage(sender, isBroadcast, secretMessage); - }else{ - int i = doubleSecretMessage.getI(); - int j = doubleSecretMessage.getJ(); - return isBroadcast && j == sender && parties[i -1].aborted && !parties[j - 1].aborted - && QUAL.contains(i) && QUAL.contains(j); - } - } - - /** - * if !isStage4 as super, with extension to double secret message - * else saves secret - */ - @Override - public void handleAnswerMessage(int sender, boolean isBroadcast, Message message) { - DKGMessages.DoubleSecretMessage doubleSecretMessage = (DKGMessages.DoubleSecretMessage)message; - if(isValidAnswerMessage(sender,isBroadcast,doubleSecretMessage)) { - 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 (sdkg.isValidShare(secret, secretT, parties[j - 1].verifiableValues, i)) { - parties[i - 1].complaints[j - 1] = DistributedKeyGeneration.ComplaintState.NonDisqualified; - - } else { - parties[i - 1].complaints[j - 1] = DistributedKeyGeneration.ComplaintState.Disqualified; - } - if(j == id){ - parties[i - 1].share = secret; - parties[i - 1].shareT = secretT; - } - } else if (sdkg.isValidShare(secret, secretT, parties[j - 1].verifiableValues, i)) { - // TODO: Check that this is ok - parties[i - 1].restoreSharesSet.add(secret); - } - } - } - - /** - * as in super with respect to protocol stage - */ - @Override - protected boolean isValidDoneMessage(int sender, boolean isBroadcast) { - if(!isStage4) { - return super.isValidDoneMessage(sender, isBroadcast); - }else{ - return isBroadcast && !parties[sender - 1].ysDoneFlag; - } - } - - /** - * as in super with respect to protocol state - */ - @Override - public void handleDoneMessage(int sender, boolean isBroadcast, Message message) { - if(!isStage4) - super.handleDoneMessage(sender, isBroadcast, message); - else{ - if(isValidDoneMessage(sender,isBroadcast)) { - parties[sender - 1].ysDoneFlag = true; - } - } - } - - /** - * use only in stage4 - * complaint message is valid if: - * 1. it was received in broadcast chanel - * 2. secret.j == sender - * 3. QUAL contains i and j - */ - protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, - DKGMessages.DoubleSecretMessage complaintMessage){ - int i = complaintMessage.getI(); - int j = complaintMessage.getJ(); - 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 - * marks i as aborted - */ - @Override - public void handleComplaintMessage(int sender, boolean isBroadcast, Message message) { - if(!isStage4) { - super.handleComplaintMessage(sender, isBroadcast, message); - }else { - DKGMessages.DoubleSecretMessage ysComplaintMessage =(DKGMessages.DoubleSecretMessage)message; - if (isValidComplaintMessage(sender,isBroadcast,ysComplaintMessage)) { - int i = ysComplaintMessage.getI(); - 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) - && !dkg.isValidSecret(secret,parties[i - 1].commitments, j)) { - parties[i - 1].aborted = true; - } - } - } - } - } -} +package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol; + +import meerkat.crypto.utilitis.Arithmetic; +import meerkat.crypto.utilitis.concrete.Fp; +import meerkat.crypto.utilitis.Channel; +import meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.User; +import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; +import meerkat.crypto.concrete.secret_shring.shamir.SecretSharing; +import com.google.protobuf.Message; +import meerkat.protobuf.DKGMessages; + +import java.math.BigInteger; +import java.util.ArrayList; + +/** + * Created by Tzlil on 3/16/2016. + */ +public class User extends meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.User { + + protected Party[] parties; + protected final Protocol sdkg; + private Arithmetic arithmetic; + private boolean isStage4; + + public User(Protocol sdkg, Channel channel) { + super(sdkg, channel); + this.sdkg = sdkg; + this.parties = sdkg.getParties(); + this.arithmetic = new Fp(sdkg.getQ()); + this.isStage4 = false; + } + + @Override + protected void registerReceiverCallback(){ + this.mailHandler = new MailHandler(new MessageHandler()); + this.channel.registerReceiverCallback(mailHandler); + } + /** + * stage1 according to the protocol + * 1. Pi broadcasts Cik=Aik*Bik for k = 0,...,t. + * 2. Pi computes the shares Sij,Sij' for j = 1,...,n and sends Sij,Sij' secretly to Pj. + */ + @Override + protected void stage1() { + sdkg.computeAndBroadcastVerificationValues(); + sdkg.sendSecrets(); + } + + @Override + protected void waitUntilStageOneCompleted(){ + super.waitUntilStageOneCompleted(); + // save the received commitments as verification values + ArrayList 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 + */ + @Override + protected void stage2(){ + sdkg.broadcastComplaints(); + //broadcast done message after all complaints + DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build(); + channel.broadcastMessage(DKGMessages.Mail.Type.DONE,doneMessage); + } + + /** + * broadcast commitments and recover parties information if necessary + */ + private void resolveQualifyingPublicKey(){ + sdkg.broadcastCommitments(); + // wait until all parties in QUAL broadcast their commitments or aborted + for (int i:QUAL) { + for(int k = 0; k <= t; k++) { + synchronized (parties[i - 1]) { + while (parties[i - 1].commitments.get(k) == null && !parties[i - 1].aborted) { + try { + parties[i - 1].wait(); + } catch (InterruptedException e) { + //do nothing + } + } + } + } + } + sdkg.computeAndBroadcastComplaints(QUAL); + //broadcast done message after all complaints + DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build(); + channel.broadcastMessage(DKGMessages.Mail.Type.DONE,doneMessage); + + // 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 { + parties[i - 1].wait(); + } catch (InterruptedException e) { + //do nothing + } + } + } + } + + // broadcast i private secret foreach i in QUAL that aborted + for (int i:QUAL) { + if(parties[i - 1].aborted){ + sdkg.broadcastAnswer(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) { + synchronized ((parties[i - 1])) { + if (parties[i - 1].aborted) { + while (parties[i - 1].recoverSharesSet.size() <= t) { + try { + parties[i - 1].wait(); + } catch (InterruptedException e) { + //do nothing + } + } + } + } + } + + // restore necessary information + for (int i = 0; i < n ; i++) { + if(parties[i].recoverSharesSet.isEmpty()){ + continue; + } + Polynomial.Point[] shares = new Polynomial.Point[t + 1]; + int j = 0; + for (Polynomial.Point share: parties[i].recoverSharesSet){ + shares[j++] = share; + if (j >= shares.length){ + break; + } + } + Polynomial polynomial = SecretSharing.recoverPolynomial(shares,arithmetic); + BigInteger[] coefficients = polynomial.getCoefficients(); + for (int k = 0 ; k <= t; k++){ + parties[i].commitments.add(k,group.multiply(g,coefficients[k])); + } + parties[i].share = new Polynomial.Point(BigInteger.valueOf(id),polynomial); + } + } + + /** + * notifies mail handler that stage 4 was started + */ + protected void setStage4(){ + this.isStage4 = true; + ((MailHandler)this.mailHandler).setStage4(true); + } + + @Override + protected void stage4() { + setStage4(); + resolveQualifyingPublicKey(); + super.stage4(); + } + + private class MessageHandler extends meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.User.MessageHandler { + + /** + * 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() + .setI(doubleSecretMessage.getI()) + .setJ(doubleSecretMessage.getJ()) + .setSecret(doubleSecretMessage.getSecret()) + .build(); + return super.isValidSecretMessage(sender,isBroadcast,secretMessage); + } + + /** + * 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 (isValidSecretMessage(sender,isBroadcast,doubleSecretMessage)) { + int i = doubleSecretMessage.getI(); + synchronized (parties[i - 1]) { + parties[i - 1].share = extractShare(id, doubleSecretMessage.getSecret()); + parties[i - 1].shareT = extractShare(id, doubleSecretMessage.getSecretT()); + parties[i - 1].notify(); + } + } + } + + /** + * if !isStage4 as super, with extension to double secret message + * else answer message is valid if: + * 1. it was received in broadcast chanel + * 2. secret.j == sender + * 3. QUAL contains i and j + */ + protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKGMessages.DoubleShareMessage doubleSecretMessage) { + if(!isStage4) { + DKGMessages.ShareMessage secretMessage = DKGMessages.ShareMessage.newBuilder() + .setI(doubleSecretMessage.getI()) + .setJ(doubleSecretMessage.getJ()) + .setSecret(doubleSecretMessage.getSecret()) + .build(); + return super.isValidAnswerMessage(sender, isBroadcast, secretMessage); + }else{ + int i = doubleSecretMessage.getI(); + int j = doubleSecretMessage.getJ(); + return isBroadcast && j == sender && parties[i -1].aborted && !parties[j - 1].aborted + && QUAL.contains(i) && QUAL.contains(j); + } + } + + /** + * if !isStage4 as super, with extension to double secret message + * else saves secret + */ + @Override + public void handleAnswerMessage(int sender, boolean isBroadcast, Message message) { + DKGMessages.DoubleShareMessage doubleSecretMessage = (DKGMessages.DoubleShareMessage)message; + if(isValidAnswerMessage(sender,isBroadcast,doubleSecretMessage)) { + int i = doubleSecretMessage.getI(); + int j = doubleSecretMessage.getJ(); + Polynomial.Point secret = extractShare(j, doubleSecretMessage.getSecret()); + Polynomial.Point secretT = extractShare(j, doubleSecretMessage.getSecretT()); + synchronized (parties[i - 1]) { + if (!isStage4) { + 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; + } + if (j == id) { + parties[i - 1].share = secret; + parties[i - 1].shareT = secretT; + } + } else if (sdkg.isValidShare(secret, secretT, parties[i - 1].verifiableValues, j)) { + parties[i - 1].recoverSharesSet.add(secret); + } + parties[i - 1].notify(); + } + } + } + + /** + * as in super with respect to protocol stage + */ + @Override + protected boolean isValidDoneMessage(int sender, boolean isBroadcast) { + if(!isStage4) { + return super.isValidDoneMessage(sender, isBroadcast); + }else{ + return isBroadcast && !parties[sender - 1].ysDoneFlag; + } + } + + /** + * as in super with respect to protocol state + */ + @Override + public void handleDoneMessage(int sender, boolean isBroadcast, Message message) { + if(!isStage4) + super.handleDoneMessage(sender, isBroadcast, message); + else{ + if(isValidDoneMessage(sender,isBroadcast)) { + synchronized (parties[sender - 1]) { + parties[sender - 1].ysDoneFlag = true; + parties[sender - 1].notify(); + } + } + } + } + + /** + * use only in stage4 + * complaint message is valid if: + * 1. it was received in broadcast chanel + * 2. secret.j == sender + * 3. QUAL contains i and j + */ + protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, + DKGMessages.DoubleShareMessage complaintMessage){ + int i = complaintMessage.getI(); + int j = complaintMessage.getJ(); + 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 + * 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(); + } + } + } + } + } + } +} diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMailHandler.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/MailHandler.java similarity index 74% rename from destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMailHandler.java rename to destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/MailHandler.java index f33959f..19c279e 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationMailHandler.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/MailHandler.java @@ -1,49 +1,49 @@ -package JointFeldmanProtocol; - -import Communication.MailHandler; -import Communication.MessageHandler; -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Message; -import meerkat.protobuf.DKGMessages; - -/** - * Created by Tzlil on 2/29/2016. - */ -public class DistributedKeyGenerationMailHandler extends MailHandler { - - public DistributedKeyGenerationMailHandler(MessageHandler messageHandler) { - super(messageHandler); - } - - @Override - public Message extractMessage(DKGMessages.Mail mail) { - try { - Message message; - switch (mail.getType()) { - case SECRET: - message = DKGMessages.SecretMessage.parseFrom(mail.getMessage()); - break; - case COMMITMENT: - message = DKGMessages.CommitmentMessage.parseFrom(mail.getMessage()); - break; - case COMPLAINT: - message = DKGMessages.IDMessage.parseFrom(mail.getMessage()); - break; - case DONE: - message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); - break; - case ANSWER: - message = DKGMessages.SecretMessage.parseFrom(mail.getMessage()); - break; - case ABORT: - message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); - break; - default: - return null; - } - return message; - } catch (InvalidProtocolBufferException e) { - return null; - } - } -} +package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol; + +import Communication.MailHandler; +import Communication.MessageHandler; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; +import meerkat.protobuf.DKGMessages; + +/** + * Created by Tzlil on 2/29/2016. + */ +public class MailHandler extends Communication.MailHandler { + + public MailHandler(MessageHandler messageHandler) { + super(messageHandler); + } + + @Override + public Message extractMessage(DKGMessages.Mail mail) { + try { + Message message; + switch (mail.getType()) { + case SHARE: + message = DKGMessages.ShareMessage.parseFrom(mail.getMessage()); + break; + case COMMITMENT: + message = DKGMessages.CommitmentMessage.parseFrom(mail.getMessage()); + break; + case COMPLAINT: + message = DKGMessages.IDMessage.parseFrom(mail.getMessage()); + break; + case DONE: + message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); + break; + case ANSWER: + message = DKGMessages.ShareMessage.parseFrom(mail.getMessage()); + break; + case ABORT: + message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); + break; + default: + return null; + } + return message; + } catch (InvalidProtocolBufferException e) { + return null; + } + } +} diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationParty.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Party.java similarity index 61% rename from destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationParty.java rename to destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Party.java index 59ef1ea..b45d5b5 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationParty.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Party.java @@ -1,32 +1,35 @@ -package JointFeldmanProtocol; - -import ShamirSecretSharing.Polynomial; - -import java.math.BigInteger; -import java.util.Arrays; - -/** - * Created by Tzlil on 3/14/2016. - * - * contains all relevant information on specific party during - * the run of Joint Feldamn protocol - */ -// TODO: comments for every field. -public class DistributedKeyGenerationParty { - public final int id; - public Polynomial.Point share; - public BigInteger[] commitments; - public boolean doneFlag; - public DistributedKeyGeneration.ComplaintState[] complaints; - public boolean aborted; - - public DistributedKeyGenerationParty(int id, int n, int t) { - this.id = id; - this.share = null; - this.doneFlag = false; - this.complaints = new DistributedKeyGeneration.ComplaintState[n]; - Arrays.fill(this.complaints, DistributedKeyGeneration.ComplaintState.OK); - this.commitments = new BigInteger[t + 1]; - this.aborted = false; - } -} +package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol; + +import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; + +import java.util.ArrayList; +import java.util.Arrays; + +/** + * Created by Tzlil on 3/14/2016. + * + * contains all relevant information on specific party during + * the run of Joint Feldamn protocol + */ +// TODO: comments for every field. +public class Party { + public final int id; + public Polynomial.Point share; + public ArrayList commitments; + public boolean doneFlag; + public DistributedKeyGeneration.ComplaintState[] complaints; + public boolean aborted; + + public Party(int id, int n, int t) { + this.id = id; + this.share = null; + this.doneFlag = false; + this.complaints = new DistributedKeyGeneration.ComplaintState[n]; + Arrays.fill(this.complaints, DistributedKeyGeneration.ComplaintState.OK); + this.commitments = new ArrayList(t + 1); + for (int i = 0; i <= t ; i++){ + commitments.add(null); + } + this.aborted = false; + } +} diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Protocol.java similarity index 51% rename from destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java rename to destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Protocol.java index a60fd33..ba0a77b 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGeneration.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Protocol.java @@ -1,280 +1,356 @@ -package JointFeldmanProtocol; - -import Communication.User; -import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; -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.Arrays; -import java.util.HashSet; -import java.util.Random; -import java.util.Set; - -/** - * Created by Tzlil on 3/14/2016. - */ -// TODO: Lots of comments... -// TODO: User Channel instead of User -public class DistributedKeyGeneration extends VerifiableSecretSharing { - public enum ComplaintState { - /** - * No complaints, no response required at this point. - */ - OK, - - /** - * Party received complaint, waiting for response from party - */ - Waiting, - - /** - * Party gave invalid answer to conplaint. - */ - Disqualified, - - /** - * Party received complaint, gave valid answer. - */ - NonDisqualified - } - - /** - * My share id. - */ - protected final int id; - - /** - * All parties participating in key generation. - * parties[id-1] has my info. - */ - private DistributedKeyGenerationParty[] parties; - - - // TODO: Copy comment - public DistributedKeyGeneration(int t, int n, BigInteger zi, Random random, BigInteger q, BigInteger g - , Group group, int id) { - super(t, n, zi, random, q, g,group); - this.id = id; - this.parties = new DistributedKeyGenerationParty[n]; - for (int i = 1; i <= n ; i++){ - this.parties[i - 1] = new DistributedKeyGenerationParty(i,n,t); - } - this.parties[id - 1].share = getShare(id); - } - - protected void setParties(DistributedKeyGenerationParty[] parties){ - this.parties = parties; - } - - protected DistributedKeyGenerationParty[] getParties(){ - return parties; - } - - /** - * stage1.1 according to the protocol - * Pi broadcasts Aik for k = 0,...,t. - */ - public void broadcastCommitments(User user){ - broadcastCommitments(user,commitmentsArray); - } - - public void broadcastCommitments(User user, BigInteger[] commitments){ - DKGMessages.CommitmentMessage commitmentMessage; - for (int k = 0; k <= t ; k++){ - commitmentMessage = DKGMessages.CommitmentMessage.newBuilder() - .setCommitment(ByteString.copyFrom(commitments[k].toByteArray())) - .setK(k) - .build(); - user.broadcast(DKGMessages.Mail.Type.COMMITMENT, commitmentMessage); - } - } - - /** - * Send user j her secret share (of my polynomial) - * @param user - * @param j - */ - public void sendSecret(User user, int j){ - ByteString secret = ByteString.copyFrom(getShare(j).y.toByteArray()); - user.send(j, DKGMessages.Mail.Type.SECRET, - DKGMessages.SecretMessage.newBuilder() - .setI(id) - .setJ(j) - .setSecret(secret) - .build()); - } - - /** - * stage1.2 according to the protocol - * Pi computes the shares Sij for j = 1,...,n and sends Sij secretly to Pj. - */ - public void sendSecrets(User user){ - for (int j = 1; j <= n ; j++){ - if(j != id){ - sendSecret(user,j); - } - } - } - - /** - * TODO: comment - * @param i - * @return - */ - public boolean isValidSecret(int i){ - DistributedKeyGenerationParty party = parties[i - 1]; - return isValidSecret(party.share,party.commitments,id); - } - - /** - * TODO: Move to VerifiableSecretSharing - * @param secret - * @param commitments - * @param j - * @return computeVerificationValue(j,commitments,group) == g ^ secret.y mod q - */ - public boolean isValidSecret(Polynomial.Point secret, BigInteger[] commitments, int j){ - try{ - BigInteger v = computeVerificationValue(j,commitments,group); - return group.multiply(g,secret.y).equals(v); - } - catch (NullPointerException e){ - return false; - } - } - - /** - * 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. - */ - public void broadcastComplaints(User user){ - for (int i = 1; i <= n ; i++ ){ - if(i != id && !isValidSecret(i)) { - broadcastComplaint(user,i); - } - } - } - - 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); - } - - public void broadcastComplaintAnswer(User user, int j){ - user.broadcast(DKGMessages.Mail.Type.ANSWER, DKGMessages.SecretMessage.newBuilder() - .setI(id) - .setJ(j) - .setSecret(ByteString.copyFrom(getShare(j).y.toByteArray())) - .build()); - } - - /** - * stage3.1 according to the protocol - * if more than t players complain against a player Pi he is disqualified. - */ - public void answerAllComplainingPlayers(User user){ - ComplaintState[] complaints = parties[id - 1].complaints; - for (int i = 1; i <= n ; i++) { - switch (complaints[i - 1]) { - case Waiting: - broadcastComplaintAnswer(user,i); - break; - default: - break; - } - } - } - - /** - * stage3.2 according to the protocol - * if any of the revealed shares fails the verification test, player Pi is disqualified. - * set QUAL to be the set of non-disqualified players. - */ - public Set calcQUAL(){ - Set QUAL = new HashSet(); - boolean nonDisqualified; - int counter; - for (int i = 1; i <= n; i++){ - ComplaintState[] complaints = parties[i - 1].complaints; - nonDisqualified = true; - counter = 0; - for (int j = 1; j <= n; j++){ - switch (complaints[j - 1]) { - case OK: - break; - case NonDisqualified: - // TODO: Add test for false complaint - counter++; - break; - default: - nonDisqualified = false; - break; - } - if(!nonDisqualified) - break; - } - if(nonDisqualified && counter <= t){ - QUAL.add(i); - } - } - return QUAL; - } - - /** - * 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 BigInteger calcY(Set QUAL){ - BigInteger y = group.zero(); - for (int i : QUAL) { - y = group.add(y , parties[i - 1].commitments[0]); - } - return y; - } - - /** - * 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 - */ - public BigInteger[] calcCommitments(Set QUAL){ - BigInteger[] commitments = new BigInteger[t + 1]; - Arrays.fill(commitments,group.zero()); - for (int i : QUAL) { - for (int k = 0; k <= t; k++){ - commitments[k] = group.add(commitments[k], parties[i - 1].commitments[k]); - } - } - return commitments; - } - - /** - * TODO: better comment. - * stage4.3 according to the protocol - * Pj sets is share of the secret as xj = sum of Sij mod q for i in QUAL - */ - public Polynomial.Point calcShare(Set 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)); - } - - /** - * getter - * @return id - */ - public int getId() { - return id; - } - -} +package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol; + +import meerkat.crypto.utilitis.Channel; +import meerkat.crypto.concrete.secret_shring.feldman_verifiable.VerifiableSecretSharing; +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.*; + +/** + * Created by Tzlil on 3/14/2016. + * + * an implementation of JointFeldman distributed key generation protocol. + * + * allows set of n parties to generate random key with threshold t. + */ +public class Protocol extends VerifiableSecretSharing { + public enum ComplaintState { + /** + * No complaints, no response required at this point. + */ + OK, + + /** + * Party received complaint, waiting for response from party + */ + Waiting, + + /** + * Party gave invalid answer to conplaint. + */ + Disqualified, + + /** + * Party received complaint, gave valid answer. + */ + NonDisqualified + } + + /** + * My share id. + */ + protected final int id; + + /** + * All parties participating in key generation. + * parties[id-1] has my info. + */ + private Party[] parties; + + /** + * communication object + */ + protected Channel channel; + + + /** + * Encode/Decode group elements + */ + protected final ByteEncoder encoder; + + /** + * 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 Protocol(int t, int n, BigInteger zi, Random random, BigInteger q, T g + , Group group, int id, ByteEncoder byteEncoder) { + super(t, n, zi, random, q, g,group); + this.id = id; + 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.encoder = byteEncoder; + } + + /** + * setter + * @param channel + */ + public void setChannel(Channel channel){ + this.channel = channel; + } + + /** + * setter + * @param parties + */ + protected void setParties(Party[] parties){ + this.parties = parties; + } + + /** + * getter + * @return + */ + protected Party[] getParties(){ + return parties; + } + + /** + * stage1.1 according to the protocol + * Pi broadcasts Aik for k = 0,...,t. + */ + public void broadcastCommitments(){ + broadcastCommitments(commitmentsArrayList); + } + + /** + * pack commitments as messages and broadcast them + * @param commitments + */ + public void broadcastCommitments(ArrayList commitments){ + DKGMessages.CommitmentMessage commitmentMessage; + for (int k = 0; k <= t ; k++){ + commitmentMessage = DKGMessages.CommitmentMessage.newBuilder() + .setCommitment(ByteString.copyFrom(encoder.encode(commitments.get(k)))) + .setK(k) + .build(); + channel.broadcastMessage(DKGMessages.Mail.Type.COMMITMENT, commitmentMessage); + } + } + + /** + * Send channel j her secret share (of my polynomial) + * @param j + */ + public void sendSecret(int j){ + ByteString secret = ByteString.copyFrom(getShare(j).y.toByteArray()); + channel.sendMessage(j, DKGMessages.Mail.Type.SHARE, + DKGMessages.ShareMessage.newBuilder() + .setI(id) + .setJ(j) + .setSecret(secret) + .build()); + } + + /** + * stage1.2 according to the protocol + * Pi computes the shares Sij for j = 1,...,n and sends Sij secretly to Pj. + */ + public void sendSecrets(){ + for (int j = 1; j <= n ; j++){ + if(j != id){ + sendSecret(j); + } + } + } + + /** + * + * @param i + * @return computeVerificationValue(j,parties[i - 1].commitments,group) == g ^ parties[i - 1].share mod q + */ + public boolean isValidShare(int i){ + Party party = parties[i - 1]; + return isValidShare(party.share,party.commitments,id); + } + + /** + * @param share + * @param commitments + * @param j + * @return computeVerificationValue(j,commitments,group) == g ^ secret.y mod q + */ + public boolean isValidShare(Polynomial.Point share, ArrayList commitments, int j){ + try{ + T v = computeVerificationValue(j,commitments,group); + return group.multiply(g,share.y).equals(v); + } + catch (NullPointerException e){ + return false; + } + } + + /** + * 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. + */ + public void broadcastComplaints(){ + for (int i = 1; i <= n ; i++ ){ + if(i != id && !isValidShare(i)) { + broadcastComplaint(i); + } + } + } + + /** + * create a complaint message against i and broadcast it + * @param i + */ + private void broadcastComplaint(int i){ + //message = new Message(Type.Complaint, j) + DKGMessages.IDMessage complaint = DKGMessages.IDMessage.newBuilder() + .setId(i) + .build(); + channel.broadcastMessage(DKGMessages.Mail.Type.COMPLAINT, complaint); + } + + /** + * create an answer message for j and broadcast it + * @param j + */ + public void broadcastComplaintAnswer(int j){ + channel.broadcastMessage(DKGMessages.Mail.Type.ANSWER, DKGMessages.ShareMessage.newBuilder() + .setI(id) + .setJ(j) + .setSecret(ByteString.copyFrom(getShare(j).y.toByteArray())) + .build()); + } + + /** + * stage3.1 according to the protocol + * if more than t players complain against a player Pi he is disqualified. + */ + public void answerAllComplainingPlayers(){ + ComplaintState[] complaints = parties[id - 1].complaints; + for (int i = 1; i <= n ; i++) { + switch (complaints[i - 1]) { + case Waiting: + broadcastComplaintAnswer(i); + break; + default: + break; + } + } + } + + /** + * stage3.2 according to the protocol + * if any of the revealed shares fails the verification test, player Pi is disqualified. + * set QUAL to be the set of non-disqualified players. + */ + public Set calcQUAL(){ + Set QUAL = new HashSet(); + boolean nonDisqualified; + int counter; + for (int i = 1; i <= n; i++){ + ComplaintState[] complaints = parties[i - 1].complaints; + nonDisqualified = true; + counter = 0; + for (int j = 1; j <= n; j++){ + switch (complaints[j - 1]) { + case OK: + break; + case NonDisqualified: + counter++; + break; + default: + nonDisqualified = false; + break; + } + if(!nonDisqualified) + break; + } + if(nonDisqualified && counter <= t){ + QUAL.add(i); + } + } + return QUAL; + } + + /** + * 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 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 calcCommitments(Set QUAL){ + ArrayList commitments = new ArrayList(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 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 getEncoder() { + return encoder; + } + +} diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/User.java similarity index 61% rename from destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java rename to destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/User.java index 6198f97..f225d59 100644 --- a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DistributedKeyGenerationUserImpl.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/User.java @@ -1,393 +1,454 @@ -package JointFeldmanProtocol; - -import Communication.MailHandler; -import Communication.Network; -import Communication.User; -import ShamirSecretSharing.Polynomial; -import UserInterface.DistributedKeyGenerationUser; -import com.google.protobuf.ByteString; -import com.google.protobuf.Message; -import meerkat.protobuf.DKGMessages; -import org.factcenter.qilin.primitives.Group; - -import java.math.BigInteger; -import java.util.Arrays; -import java.util.Set; -import JointFeldmanProtocol.DistributedKeyGeneration.ComplaintState; - -/** - * Created by Tzlil on 3/14/2016. - * TODO: Comments - * TODO: Replace polling with monitors/wait/notify (remember synchronization) - */ -public class DistributedKeyGenerationUserImpl implements DistributedKeyGenerationUser { - - // TODO: remove - protected final static int SleepTime = 300; - - protected final DistributedKeyGeneration dkg; - - protected final BigInteger g; - protected final Group group; - protected final int n; - protected final int t; - protected final int id; - - protected MessageHandler messageHandler; - protected final User user; - protected final DistributedKeyGenerationParty[] parties; - protected Set QUAL; // set of all non-disqualified parties - protected BigInteger[] commitments; // public verification values - protected Polynomial.Point share; // final share of the secrete - protected BigInteger y; // final public value - - public DistributedKeyGenerationUserImpl(DistributedKeyGeneration dkg, Network network){ - this(dkg,network,new DistributedKeyGenerationMailHandler(null)); - } - public DistributedKeyGenerationUserImpl(DistributedKeyGeneration dkg, Network network, MailHandler mailHandler) { - this.dkg = dkg; - - this.g = dkg.getGenerator(); - this.group = dkg.getGroup(); - this.n = dkg.getN(); - this.t = dkg.getT(); - this.id = dkg.getId(); - - this.messageHandler = new MessageHandler(); - mailHandler.setMessageHandler(this.messageHandler); - this.user = network.connect(mailHandler,dkg.getId()); - this.parties = dkg.getParties(); - this.QUAL = null; - this.commitments = null; - this.share = null; - this.y = null; - } - - /** - * stage1 according to the protocol - * 1. Pi broadcasts Aik for k = 0,...,t. - * 2. Pi computes the shares Sij for j = 1,...,n and sends Sij secretly to Pj. - */ - protected void stage1() { - dkg.broadcastCommitments(user); - dkg.sendSecrets(user); - } - - - protected void waitUntilStageOneCompleted(){ - // all parties send their share or aborted - for (int i = 0 ; i < n ; i++){ - while (parties[i].share == null && !parties[i].aborted){ - try { - Thread.sleep(SleepTime); - } 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 { - Thread.sleep(SleepTime); - } 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); - //broadcast done message after all complaints - DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build(); - user.broadcast(DKGMessages.Mail.Type.DONE,doneMessage); - } - - - protected void waitUntilStageTwoCompleted(){ - // all parties done or aborted - for (int i = 0 ; i < n ; i++){ - while (!parties[i].doneFlag && !parties[i].aborted){ - try { - Thread.sleep(SleepTime); - } catch (InterruptedException e) { - // do nothing - } - } - } - } - - /** - * stage3 according to the protocol - * 1. if more than t players complain against a player Pi he is disqualified. - * otherwise Pi broadcasts the share Sij for each complaining player Pj. - * 2. if any of the revealed shares fails the verification test, player Pi is disqualified. - * set QUAL to be the set of non-disqualified players. - */ - protected void stage3(){ - dkg.answerAllComplainingPlayers(user); - // wait until there is no complaint waiting for answer - for (int i = 0; i < n; i++){ - for (int j = 0; j < n; j++){ - while (parties[i].complaints[j].equals(ComplaintState.Waiting) && !parties[i].aborted){ - try { - Thread.sleep(SleepTime); - } catch (InterruptedException e) { - // do nothing - } - } - } - } - this.QUAL = dkg.calcQUAL(); - } - - /** - * stage4 according to the protocol - * 1. public value y is computed as y = multiplication of yi mod p for i in QUAL - * 2. public verification values are computed as Ak = multiplication of Aik mod p for i in QUAL for k = 0,...,t - * 3. Pj sets is share of the secret as xj = sum of Sij mod q for i in QUAL - */ - protected void stage4(){ - this.y = dkg.calcY(QUAL); - this.commitments = dkg.calcCommitments(QUAL); - this.share = dkg.calcShare(QUAL); - } - - protected void startReceiver(){ - user.getReceiverThread().start(); - } - protected void stopReceiver(){ - user.getReceiverThread().interrupt(); - } - - @Override - public void run() { - startReceiver(); - stage1(); - waitUntilStageOneCompleted(); - stage2(); - waitUntilStageTwoCompleted(); - stage3(); - stage4(); - stopReceiver(); - } - - /** - * Request the current run loop to exit gracefully - */ - public void stop() { - // TODO: implement - } - - @Override - public BigInteger[] getCommitments() { - return Arrays.copyOf(commitments, commitments.length); - } - - @Override - public BigInteger getGenerator() { - return g; - } - - @Override - public Group getGroup() { - return group; - } - - @Override - public Polynomial.Point getShare() { - return share; - } - - @Override - public int getID() { - return id; - } - - @Override - public int getN() { - return n; - } - - @Override - public int getT() { - return t; - } - - @Override - public BigInteger getPublicValue() { - return y; - } - - @Override - public Set getQUAL() { - return QUAL; - } - - - protected class MessageHandler implements Communication.MessageHandler{ - - /** - * commitment message is valid if: - * 1. it was received in broadcast chanel - * 2. the sender didn't sent this commitment before - */ - protected boolean isValidCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage){ - int i = sender - 1; - int k = commitmentMessage.getK(); - return isBroadcast && parties[i].commitments[k] == null; - } - - /** - * saves the commitment - */ - @Override - public void handleCommitmentMessage(int sender, boolean isBroadcast, Message message) { - DKGMessages.CommitmentMessage commitmentMessage = (DKGMessages.CommitmentMessage) message; - if(isValidCommitmentMessage(sender,isBroadcast,commitmentMessage)){ - int i = sender - 1; - int k = commitmentMessage.getK(); - parties[i].commitments[k] = extractCommitment(commitmentMessage); - } - } - - /** - * 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 - * 4. secret.j == id - */ - protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage){ - int i = secretMessage.getI(); - int j = secretMessage.getJ(); - if(sender != i || isBroadcast) - return false; - else - return parties[i - 1].share == null && j == id; - - } - - /** - * saves the secret - */ - @Override - public void handleSecretMessage(int sender, boolean isBroadcast, Message message) { - DKGMessages.SecretMessage secretMessage = (DKGMessages.SecretMessage) message; - if(isValidSecretMessage(sender,isBroadcast,secretMessage)) { - int i = secretMessage.getI(); - Polynomial.Point secret = extractSecret(id,secretMessage.getSecret()); - parties[i - 1].share = secret; - } - } - - /** - * 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; - } - - /** - * marks that the sender was finished sending all his complaints - */ - @Override - public void handleDoneMessage(int sender, boolean isBroadcast, Message message) { - if(isValidDoneMessage(sender,isBroadcast)) { - parties[sender - 1].doneFlag = true; - } - } - - /** - * complaint message is valid if: - * 1. it was received in broadcast chanel - * 2. the sender didn't complained against id before - */ - protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, DKGMessages.IDMessage complaintMessage){ - int i = sender; - int j = complaintMessage.getId(); - return isBroadcast && parties[i - 1].complaints[j - 1].equals( ComplaintState.OK); - } - - /** - * marks that the sender was complained against id - */ - @Override - 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; - } - } - - /** - * answer message is valid if: - * 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 - */ - protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKGMessages.SecretMessage secretMessage){ - int i = secretMessage.getI(); - int j = secretMessage.getJ(); - 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.SecretMessage secretMessage = (DKGMessages.SecretMessage) message; - if(isValidAnswerMessage(sender,isBroadcast,secretMessage)) { - int i = secretMessage.getI(); - 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; - } else { - parties[i - 1].complaints[j - 1] = ComplaintState.Disqualified; - } - if(j == id){ - parties[i - 1].share = secret; - } - } - } - - /** - * marks that the sender was aborted - */ - @Override - public void handleAbortMessage(int sender, boolean isBroadcast, Message message) { - parties[sender - 1].aborted = true; - } - - public Polynomial.Point extractSecret(int i, ByteString secret){ - BigInteger x = BigInteger.valueOf(i); - BigInteger y = new BigInteger(secret.toByteArray()); - return new Polynomial.Point(x,y); - } - - public BigInteger extractCommitment(DKGMessages.CommitmentMessage commitmentMessage){ - return new BigInteger(commitmentMessage.getCommitment().toByteArray()); - } - } -} +package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol; + +import meerkat.crypto.utilitis.Channel; +import Communication.MailHandler; +import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; +import com.google.protobuf.ByteString; +import com.google.protobuf.Message; +import meerkat.protobuf.DKGMessages; +import org.factcenter.qilin.primitives.Group; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Set; +import meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.DistributedKeyGeneration.ComplaintState; + +/** + * Created by Tzlil on 3/14/2016. + * TODO: Comments + * TODO: Replace polling with monitors/wait/notify (remember synchronization) + */ +public class User implements Runnable{ + + protected final DistributedKeyGeneration dkg; + + protected final T g; + protected final Group group; + protected final int n; + protected final int t; + protected final int id; + protected MailHandler mailHandler; + + protected final Channel channel; + protected final Party[] parties; + protected Set QUAL; // set of all non-disqualified parties + protected Polynomial.Point share; // final share of the secrete + protected ArrayList commitments; // public verification values + protected T y; // final public value + + public User(DistributedKeyGeneration dkg, Channel channel) { + this.dkg = dkg; + + this.g = dkg.getGenerator(); + this.group = dkg.getGroup(); + this.n = dkg.getN(); + this.t = dkg.getT(); + this.id = dkg.getId(); + + this.channel = channel; + dkg.setChannel(channel); + registerReceiverCallback(); + + this.parties = dkg.getParties(); + this.QUAL = null; + this.commitments = null; + this.share = null; + this.y = null; + + } + + /** + * create MailHandler and register it as ReceiverCallback + */ + 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. + */ + protected void stage1() { + dkg.broadcastCommitments(); + dkg.sendSecrets(); + } + + + protected void waitUntilStageOneCompleted(){ + // all parties send their share or aborted + for (int i = 0 ; i < n ; i++){ + synchronized (parties[i]) { + while (parties[i].share == null && !parties[i].aborted) { + 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++) { + 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(); + //broadcast done message after all complaints + DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build(); + channel.broadcastMessage(DKGMessages.Mail.Type.DONE,doneMessage); + } + + + protected void waitUntilStageTwoCompleted(){ + // 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) { + //do nothing + } + } + } + } + } + + + /** + * stage3 according to the protocol + * 1. if more than t players complain against a player Pi he is disqualified. + * otherwise Pi broadcasts the share Sij for each complaining player Pj. + * 2. if any of the revealed shares fails the verification test, player Pi is disqualified. + * set QUAL to be the set of non-disqualified players. + */ + protected void stage3(){ + dkg.answerAllComplainingPlayers(); + // wait until there is no complaint waiting for answer + for (int i = 0; i < n; i++){ + for (int j = 0; j < n; j++){ + synchronized (parties[i]) { + while (parties[i].complaints[j].equals(ComplaintState.Waiting) && !parties[i].aborted) { + try { + parties[i].wait(); + } catch (InterruptedException e) { + //do nothing + } + } + } + } + } + this.QUAL = dkg.calcQUAL(); + } + + /** + * stage4 according to the protocol + * 1. public value y is computed as y = multiplication of yi mod p for i in QUAL + * 2. public verification values are computed as Ak = multiplication of Aik mod p for i in QUAL for k = 0,...,t + * 3. Pj sets is share of the secret as xj = sum of Sij mod q for i in QUAL + */ + protected void stage4(){ + this.y = dkg.calcY(QUAL); + this.commitments = dkg.calcCommitments(QUAL); + this.share = dkg.calcShare(QUAL); + } + + @Override + public void run() { + stage1(); + waitUntilStageOneCompleted(); + stage2(); + waitUntilStageTwoCompleted(); + stage3(); + stage4(); + } + + /** + * Request the current run loop to exit gracefully + */ + public void stop() { + + } + + /** + * getter + * @return commitments + */ + public ArrayList getCommitments() { + return commitments; + } + + /** + * getter + * @return g + */ + public T getGenerator() { + return g; + } + + /** + * getter + * @return group + */ + public Group getGroup() { + return group; + } + + /** + * getter + * @return share + */ + public Polynomial.Point getShare() { + return share; + } + + /** + * getter + * @return id + */ + public int getID() { + return id; + } + + /** + * getter + * @return n + */ + public int getN() { + return n; + } + + /** + * getter + * @return t + */ + public int getT() { + return t; + } + + /** + * getter + * @return y + */ + public T getPublicValue() { + return y; + } + + /** + * getter + * @return QUAL + */ + public Set getQUAL() { + return QUAL; + } + + + public class MessageHandler implements Communication.MessageHandler{ + + public MessageHandler(){ + + } + /** + * commitment message is valid if: + * 1. it was received in broadcast chanel + * 2. the sender didn't sent this commitment before + */ + 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 commitment + */ + @Override + public void handleCommitmentMessage(int sender, boolean isBroadcast, Message message) { + DKGMessages.CommitmentMessage commitmentMessage = (DKGMessages.CommitmentMessage) message; + if(isValidCommitmentMessage(sender,isBroadcast,commitmentMessage)){ + int i = sender - 1; + int k = commitmentMessage.getK(); + synchronized (parties[i]) { + parties[i].commitments.set(k, extractCommitment(commitmentMessage)); + parties[i].notify(); + } + } + } + + /** + * 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 + * 4. secret.j == id + */ + protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKGMessages.ShareMessage secretMessage){ + int i = secretMessage.getI(); + int j = secretMessage.getJ(); + if(sender != i || isBroadcast) + return false; + else + return parties[i - 1].share == null && j == id; + + } + + /** + * saves the secret + */ + @Override + public void handleSecretMessage(int sender, boolean isBroadcast, Message message) { + DKGMessages.ShareMessage secretMessage = (DKGMessages.ShareMessage) message; + if(isValidSecretMessage(sender,isBroadcast,secretMessage)) { + int i = secretMessage.getI(); + Polynomial.Point secret = extractShare(id,secretMessage.getSecret()); + synchronized (parties[i -1]) { + parties[i - 1].share = secret; + parties[i - 1].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; + } + + /** + * marks that the sender was finished sending all his complaints + */ + @Override + public void handleDoneMessage(int sender, boolean isBroadcast, Message message) { + if(isValidDoneMessage(sender,isBroadcast)) { + synchronized (parties[sender - 1]) { + parties[sender - 1].doneFlag = true; + parties[sender - 1].notify(); + } + } + } + + /** + * complaint message is valid if: + * 1. it was received in broadcast chanel + * 2. the sender didn't complained against id before + */ + protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, DKGMessages.IDMessage complaintMessage){ + int i = sender; + int j = complaintMessage.getId(); + return isBroadcast && parties[i - 1].complaints[j - 1].equals( ComplaintState.OK); + } + + /** + * marks that the sender was complained against id + */ + @Override + 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(); + synchronized (parties[j - 1]) { + parties[j - 1].complaints[i - 1] = ComplaintState.Waiting; + parties[j - 1].notify(); + } + } + } + + /** + * answer message is valid if: + * 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 + */ + protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKGMessages.ShareMessage secretMessage){ + int i = secretMessage.getI(); + int j = secretMessage.getJ(); + 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()); + } + } +} diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharing.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharing.java new file mode 100644 index 0000000..a15f0e2 --- /dev/null +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharing.java @@ -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 extends SecretSharing { + protected final Group group; + protected final T g; // public generator of group + protected final ArrayList 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 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 generateCommitments() { + + Polynomial polynomial = getPolynomial(); + BigInteger[] coefficients = polynomial.getCoefficients(); + ArrayList commitments = new ArrayList(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 computeVerificationValue(int j, ArrayList commitments, Group 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 getGroup(){ + return group; + } + + /** + * getter + * @return commitmentsArrayList + */ + public ArrayList getCommitmentsArrayList() { + return commitmentsArrayList; + } + +} diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/shamir/LagrangePolynomial.java similarity index 94% rename from destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java rename to destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/shamir/LagrangePolynomial.java index c3fb319..20aee54 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/shamir/LagrangePolynomial.java @@ -1,66 +1,66 @@ -package ShamirSecretSharing; - -import Arithmetics.Arithmetic; - -import java.math.BigInteger; - -/** - * Created by Tzlil on 1/28/2016. - * - * container of lagrange polynomial - * - * Constructor is private (use {@link #lagrangePolynomials(Polynomial.Point[], Arithmetic)} to construct) - * - * l = (evaluate/divisor)* polynomial - * - * Note : image and divisor stored separately for avoiding lose of information by division - */ -class LagrangePolynomial{ - public final Polynomial polynomial; - public final BigInteger image; - public final BigInteger divisor; - - /** - * inner constructor, stores all given parameters - * @param polynomial - * @param image - * @param divisor - */ - private LagrangePolynomial(Polynomial polynomial, BigInteger image, BigInteger divisor) { - this.polynomial = polynomial; - this.image = image; - this.divisor = divisor; - } - - /** - * static method - * @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. - * in case there exists i != j s.t points[i].x == points[j].x returns null. - */ - public static LagrangePolynomial[] lagrangePolynomials(Polynomial.Point[] points,Arithmetic arithmetic) { - Polynomial one = new Polynomial(new BigInteger[]{BigInteger.ONE},arithmetic); - LagrangePolynomial[] lagrangePolynomials = new LagrangePolynomial[points.length]; - Polynomial[] factors = new Polynomial[points.length]; - for (int i = 0 ; i < factors.length ; i++){ - factors[i] = new Polynomial(new BigInteger[]{points[i].x.negate(),BigInteger.ONE},arithmetic); // X - Xi - } - Polynomial product; - BigInteger divisor; - for(int i = 0; i < points.length; i ++) { - product = one; - divisor = BigInteger.ONE; - for (int j = 0; j < points.length; j++) { - if (i != j) { - divisor = arithmetic.mul(divisor,arithmetic.sub(points[i].x,points[j].x)); - product = product.mul(factors[j]); - } - } - if(divisor.equals(BigInteger.ZERO)) - return null; - lagrangePolynomials[i] = new LagrangePolynomial(product,points[i].y,divisor); - } - return lagrangePolynomials; - } -} +package meerkat.crypto.concrete.secret_shring.shamir; + +import meerkat.crypto.utilitis.Arithmetic; + +import java.math.BigInteger; + +/** + * Created by Tzlil on 1/28/2016. + * + * container of lagrange polynomial + * + * Constructor is private (use {@link #lagrangePolynomials(Polynomial.Point[], Arithmetic)} to construct) + * + * l = (evaluate/divisor)* polynomial + * + * Note : image and divisor stored separately for avoiding lose of information by division + */ +class LagrangePolynomial{ + public final Polynomial polynomial; + public final BigInteger image; + public final BigInteger divisor; + + /** + * inner constructor, stores all given parameters + * @param polynomial + * @param image + * @param divisor + */ + private LagrangePolynomial(Polynomial polynomial, BigInteger image, BigInteger divisor) { + this.polynomial = polynomial; + this.image = image; + this.divisor = divisor; + } + + /** + * static method + * @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. + * in case there exists i != j s.t points[i].x == points[j].x returns null. + */ + public static LagrangePolynomial[] lagrangePolynomials(Polynomial.Point[] points,Arithmetic arithmetic) { + Polynomial one = new Polynomial(new BigInteger[]{BigInteger.ONE},arithmetic); + LagrangePolynomial[] lagrangePolynomials = new LagrangePolynomial[points.length]; + Polynomial[] factors = new Polynomial[points.length]; + for (int i = 0 ; i < factors.length ; i++){ + factors[i] = new Polynomial(new BigInteger[]{points[i].x.negate(),BigInteger.ONE},arithmetic); // X - Xi + } + Polynomial product; + BigInteger divisor; + for(int i = 0; i < points.length; i ++) { + product = one; + divisor = BigInteger.ONE; + for (int j = 0; j < points.length; j++) { + if (i != j) { + divisor = arithmetic.mul(divisor,arithmetic.sub(points[i].x,points[j].x)); + product = product.mul(factors[j]); + } + } + if(divisor.equals(BigInteger.ZERO)) + return null; + lagrangePolynomials[i] = new LagrangePolynomial(product,points[i].y,divisor); + } + return lagrangePolynomials; + } +} diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/shamir/Polynomial.java similarity index 94% rename from destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java rename to destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/shamir/Polynomial.java index 03c8f99..c2d77ff 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/shamir/Polynomial.java @@ -1,208 +1,208 @@ -package ShamirSecretSharing; - -import Arithmetics.Arithmetic; - -import java.math.BigInteger; -import java.util.Arrays; - -/** - * Created by Tzlil on 1/27/2016. - */ -public class Polynomial implements Comparable { - private final int degree; - private final BigInteger[] coefficients; - private final Arithmetic arithmetic; - - /** - * constructor - * @param coefficients - * @param arithmetic - * degree set as max index such that coefficients[degree] not equals zero - */ - public Polynomial(BigInteger[] coefficients,Arithmetic arithmetic) { - int d = coefficients.length - 1; - while (d > 0 && coefficients[d].equals(BigInteger.ZERO)){ - d--; - } - this.degree = d; - this.coefficients = coefficients; - this.arithmetic = arithmetic; - } - - /** - * Compare to another polynomial (order by degree, then coefficients). - */ - @Override - public int compareTo(Polynomial other) { - if (this.degree != other.degree) - return this.degree - other.degree; - int compare; - for (int i = degree; i >= degree ; i--){ - compare = this.coefficients[i].compareTo(other.coefficients[i]); - if (compare != 0){ - return compare; - } - } - return 0; - } - - /** - * @param x - * @return sum of coefficients[i] * (x ^ i) - */ - public BigInteger evaluate(BigInteger x){ - BigInteger result = BigInteger.ZERO; - BigInteger power = BigInteger.ONE; - for(int i = 0 ; i <= degree ; i++){ - result = arithmetic.add(result,arithmetic.mul(coefficients[i],power)); - power = power.multiply(x); - } - return result; - } - - /** - * @param 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. - */ - public static Polynomial interpolation(Point[] points, Arithmetic arithmetic) { - LagrangePolynomial[] l = LagrangePolynomial.lagrangePolynomials(points,arithmetic); - if (l == null){ - return null; - } - // product = product of l[i].divisor - BigInteger product = BigInteger.ONE; - for (int i = 0; i < l.length;i++){ - product = arithmetic.mul(product,l[i].divisor); - } - - // factor[i] = product divided by l[i].divisor = product of l[j].divisor s.t j!=i - BigInteger[] factors = new BigInteger[l.length]; - for (int i = 0; i < l.length;i++){ - factors[i] = arithmetic.div(product,l[i].divisor); - } - 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 = - // = sum of l[i].evaluate * l[i].coefficients[j] / l[i].divisor s.t i!=j - BigInteger[] coefficients = new BigInteger[degree + 1]; - for (int j = 0; j < coefficients.length;j++){ - coefficients[j] = BigInteger.ZERO; - for (int i = 0; i < l.length; i++){ - BigInteger current = arithmetic.mul(l[i].image,factors[i]); - current = arithmetic.mul(current,l[i].polynomial.coefficients[j]); - coefficients[j] = arithmetic.add(coefficients[j],current); - } - coefficients[j] = arithmetic.div(coefficients[j],product); - } - return new Polynomial(coefficients,arithmetic); - } - - /** - * @param other - * @return new ShamirSecretSharing.PolynomialTests of degree max(this degree,other degree) s.t for all x in Z - * new.evaluate(x) = this.evaluate(x) + other.evaluate(x) - */ - public Polynomial add(Polynomial other){ - Polynomial bigger,smaller; - if(this.degree < other.degree){ - bigger = other; - smaller = this; - }else{ - bigger = this; - smaller = other; - } - BigInteger[] coefficients = bigger.getCoefficients(); - - for (int i = 0; i <= smaller.degree ; i++){ - coefficients[i] = arithmetic.add(smaller.coefficients[i],bigger.coefficients[i]); - } - return new Polynomial(coefficients,other.arithmetic); - } - - /** - * @param constant - * @return new Polynomial of degree this.degree s.t for all x in Z - * new.evaluate(x) = constant * this.evaluate(x) - */ - public Polynomial mul(BigInteger constant){ - - BigInteger[] coefficients = this.getCoefficients(); - - for (int i = 0; i <= this.degree ; i++){ - coefficients[i] = arithmetic.mul(constant,coefficients[i]); - } - return new Polynomial(coefficients,arithmetic); - } - - /** - * @param other - * @return new Polynomial of degree this degree + other degree + 1 s.t for all x in Z - * new.evaluate(x) = this.evaluate(x) * other.evaluate(x) - */ - public Polynomial mul(Polynomial other){ - - BigInteger[] coefficients = new BigInteger[this.degree + other.degree + 1]; - Arrays.fill(coefficients,BigInteger.ZERO); - - for (int i = 0; i <= this.degree ; i++){ - for (int j = 0; j <= other.degree; j++){ - coefficients[i+j] = arithmetic.add(coefficients[i+j],arithmetic.mul(this.coefficients[i],other.coefficients[j])); - } - } - return new Polynomial(coefficients,arithmetic); - } - - - /** getter - * @return copy of coefficients - */ - public BigInteger[] getCoefficients() { - return Arrays.copyOf(coefficients,coefficients.length); - } - - /** getter - * @return degree - */ - public int getDegree() { - return degree; - } - - /** - * inner class - * container for (x,y) x from range and y from evaluate of polynomial - */ - public static class Point implements java.io.Serializable { - public final BigInteger x; - public final BigInteger y; - - /** - * constructor - * @param x - * @param polynomial y = polynomial.evaluate(x) - */ - public Point(BigInteger x, Polynomial polynomial) { - this.x = x; - this.y = polynomial.evaluate(x); - } - - /** - * constructor - * @param x - * @param y - */ - public Point(BigInteger x,BigInteger y) { - this.x = x; - this.y = y; - } - - @Override - public boolean equals(Object obj) { - if(!super.equals(obj)) - return false; - Point other = (Point)obj; - return this.x.equals(other.x) && this.y.equals(other.y); - } - } - -} +package meerkat.crypto.concrete.secret_shring.shamir; + +import meerkat.crypto.utilitis.Arithmetic; + +import java.math.BigInteger; +import java.util.Arrays; + +/** + * Created by Tzlil on 1/27/2016. + */ +public class Polynomial implements Comparable { + private final int degree; + private final BigInteger[] coefficients; + private final Arithmetic arithmetic; + + /** + * constructor + * @param coefficients + * @param arithmetic + * degree set as max index such that coefficients[degree] not equals zero + */ + public Polynomial(BigInteger[] coefficients,Arithmetic arithmetic) { + int d = coefficients.length - 1; + while (d > 0 && coefficients[d].equals(BigInteger.ZERO)){ + d--; + } + this.degree = d; + this.coefficients = coefficients; + this.arithmetic = arithmetic; + } + + /** + * Compare to another polynomial (order by degree, then coefficients). + */ + @Override + public int compareTo(Polynomial other) { + if (this.degree != other.degree) + return this.degree - other.degree; + int compare; + for (int i = degree; i >= degree ; i--){ + compare = this.coefficients[i].compareTo(other.coefficients[i]); + if (compare != 0){ + return compare; + } + } + return 0; + } + + /** + * @param x + * @return sum of coefficients[i] * (x ^ i) + */ + public BigInteger evaluate(BigInteger x){ + BigInteger result = BigInteger.ZERO; + BigInteger power = BigInteger.ONE; + for(int i = 0 ; i <= degree ; i++){ + result = arithmetic.add(result,arithmetic.mul(coefficients[i],power)); + power = power.multiply(x); + } + return result; + } + + /** + * @param 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. + */ + public static Polynomial interpolation(Point[] points, Arithmetic arithmetic) { + LagrangePolynomial[] l = LagrangePolynomial.lagrangePolynomials(points,arithmetic); + if (l == null){ + return null; + } + // product = product of l[i].divisor + BigInteger product = BigInteger.ONE; + for (int i = 0; i < l.length;i++){ + product = arithmetic.mul(product,l[i].divisor); + } + + // factor[i] = product divided by l[i].divisor = product of l[j].divisor s.t j!=i + BigInteger[] factors = new BigInteger[l.length]; + for (int i = 0; i < l.length;i++){ + factors[i] = arithmetic.div(product,l[i].divisor); + } + 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 = + // = sum of l[i].evaluate * l[i].coefficients[j] / l[i].divisor s.t i!=j + BigInteger[] coefficients = new BigInteger[degree + 1]; + for (int j = 0; j < coefficients.length;j++){ + coefficients[j] = BigInteger.ZERO; + for (int i = 0; i < l.length; i++){ + BigInteger current = arithmetic.mul(l[i].image,factors[i]); + current = arithmetic.mul(current,l[i].polynomial.coefficients[j]); + coefficients[j] = arithmetic.add(coefficients[j],current); + } + coefficients[j] = arithmetic.div(coefficients[j],product); + } + return new Polynomial(coefficients,arithmetic); + } + + /** + * @param other + * @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) + */ + public Polynomial add(Polynomial other){ + Polynomial bigger,smaller; + if(this.degree < other.degree){ + bigger = other; + smaller = this; + }else{ + bigger = this; + smaller = other; + } + BigInteger[] coefficients = bigger.getCoefficients(); + + for (int i = 0; i <= smaller.degree ; i++){ + coefficients[i] = arithmetic.add(smaller.coefficients[i],bigger.coefficients[i]); + } + return new Polynomial(coefficients,other.arithmetic); + } + + /** + * @param constant + * @return new Polynomial of degree this.degree s.t for all x + * new.evaluate(x) = constant * this.evaluate(x) + */ + public Polynomial mul(BigInteger constant){ + + BigInteger[] coefficients = this.getCoefficients(); + + for (int i = 0; i <= this.degree ; i++){ + coefficients[i] = arithmetic.mul(constant,coefficients[i]); + } + return new Polynomial(coefficients,arithmetic); + } + + /** + * @param other + * @return new Polynomial of degree this degree + other degree + 1 s.t for all x + * new.evaluate(x) = this.evaluate(x) * other.evaluate(x) + */ + public Polynomial mul(Polynomial other){ + + BigInteger[] coefficients = new BigInteger[this.degree + other.degree + 1]; + Arrays.fill(coefficients,BigInteger.ZERO); + + for (int i = 0; i <= this.degree ; i++){ + for (int j = 0; j <= other.degree; j++){ + coefficients[i+j] = arithmetic.add(coefficients[i+j],arithmetic.mul(this.coefficients[i],other.coefficients[j])); + } + } + return new Polynomial(coefficients,arithmetic); + } + + + /** getter + * @return copy of coefficients + */ + public BigInteger[] getCoefficients() { + return Arrays.copyOf(coefficients,coefficients.length); + } + + /** getter + * @return degree + */ + public int getDegree() { + return degree; + } + + /** + * inner class + * container for (x,y) x from range and y from evaluate of polynomial + */ + public static class Point implements java.io.Serializable { + public final BigInteger x; + public final BigInteger y; + + /** + * constructor + * @param x + * @param polynomial y = polynomial.evaluate(x) + */ + public Point(BigInteger x, Polynomial polynomial) { + this.x = x; + this.y = polynomial.evaluate(x); + } + + /** + * constructor + * @param x + * @param y + */ + public Point(BigInteger x,BigInteger y) { + this.x = x; + this.y = y; + } + + @Override + public boolean equals(Object obj) { + if(!super.equals(obj)) + return false; + Point other = (Point)obj; + return this.x.equals(other.x) && this.y.equals(other.y); + } + } + +} diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/shamir/SecretSharing.java similarity index 84% rename from destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java rename to destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/shamir/SecretSharing.java index b9c0386..87853d5 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/shamir/SecretSharing.java @@ -1,111 +1,111 @@ -package ShamirSecretSharing; - -import Arithmetics.Arithmetic; -import Arithmetics.Fp; - -import java.math.BigInteger; -import java.util.Random; - -/** - * Created by Tzlil on 1/27/2016. - * an implementation of Shamire's secret sharing scheme - */ -public class SecretSharing{ - protected final int t; - protected final int n; - protected final BigInteger q; - protected final Polynomial polynomial; - - /** - * 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 x secret, chosen from Zq - * @param random use for generate random polynomial - */ - public SecretSharing(int t, int n, BigInteger x, Random random, BigInteger q) { - this.q = q; - this.t = t; - this.n = n; - this.polynomial = generateRandomPolynomial(x,random); - } - - /** - * @param x - * @param random - * @return new Polynomial polynomial of degree t ,such that - * 1. polynomial(0) = x - * 2. polynomial coefficients randomly chosen from Zq (except of coefficients[0] = x) - */ - private Polynomial generateRandomPolynomial(BigInteger x, Random random) { - BigInteger[] coefficients = new BigInteger[t + 1]; - coefficients[0] = x.mod(q); - int bits = q.bitLength(); - for (int i = 1 ; i <= t; i++ ){ - coefficients[i] = new BigInteger(bits,random).mod(q); - } - return new Polynomial(coefficients,new Fp(q)); - } - - /** - * @param i in range of [1,...n] - * - * @return polynomial.evaluate(i)%q - */ - public Polynomial.Point getShare(int i){ - assert (i > 0 && i <= n); - return new Polynomial.Point(BigInteger.valueOf(i), polynomial); - } - - /** - * @param shares - subset of the original shares - * - * @return evaluate of interpolation(shares) at x = 0 - */ - public static BigInteger recoverSecret(Polynomial.Point[] shares, Arithmetic arithmetic) throws Exception { - return recoverPolynomial(shares,arithmetic).evaluate(BigInteger.ZERO); - } - /** - * @param shares - subset of the original shares - * - * @return interpolation(shares) - */ - public static Polynomial recoverPolynomial(Polynomial.Point[] shares, Arithmetic arithmetic) { - return Polynomial.interpolation(shares,arithmetic); - } - - /** - * getter - * @return threshold - */ - public int getT() { - return t; - } - - /** - * getter - * @return number of share holders - */ - public int getN() { - return n; - } - - /** - * getter - * @return the prime was given in the constructor - */ - public BigInteger getQ() { - return q; - } - - - /** - * getter - * @return the polynomial was generated in constructor - */ - public Polynomial getPolynomial() { - return polynomial; - } -} +package meerkat.crypto.concrete.secret_shring.shamir; + +import meerkat.crypto.utilitis.Arithmetic; +import meerkat.crypto.utilitis.concrete.Fp; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/27/2016. + * an implementation of Shamire's secret sharing scheme + */ +public class SecretSharing{ + protected final int t; + protected final int n; + protected final BigInteger q; + protected final Polynomial polynomial; + + /** + * 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 + */ + public SecretSharing(int t, int n, BigInteger zi, Random random, BigInteger q) { + this.q = q; + this.t = t; + this.n = n; + this.polynomial = generateRandomPolynomial(zi,random); + } + + /** + * @param x + * @param random + * @return new Polynomial polynomial of degree t ,such that + * 1. polynomial(0) = x + * 2. polynomial coefficients randomly chosen from Zq (except of coefficients[0] = x) + */ + private Polynomial generateRandomPolynomial(BigInteger x, Random random) { + BigInteger[] coefficients = new BigInteger[t + 1]; + coefficients[0] = x.mod(q); + int bits = q.bitLength(); + for (int i = 1 ; i <= t; i++ ){ + coefficients[i] = new BigInteger(bits,random).mod(q); + } + return new Polynomial(coefficients,new Fp(q)); + } + + /** + * @param i in range of [1,...n] + * + * @return polynomial.evaluate(i) + */ + public Polynomial.Point getShare(int i){ + assert (i > 0 && i <= n); + return new Polynomial.Point(BigInteger.valueOf(i), polynomial); + } + + /** + * @param shares - subset of the original shares + * + * @return evaluate of interpolation(shares) at x = 0 + */ + public static BigInteger recoverSecret(Polynomial.Point[] shares, Arithmetic arithmetic) { + return recoverPolynomial(shares,arithmetic).evaluate(BigInteger.ZERO); + } + /** + * @param shares - subset of the original shares + * + * @return interpolation(shares) + */ + public static Polynomial recoverPolynomial(Polynomial.Point[] shares, Arithmetic arithmetic) { + return Polynomial.interpolation(shares,arithmetic); + } + + /** + * getter + * @return threshold + */ + public int getT() { + return t; + } + + /** + * getter + * @return number of share holders + */ + public int getN() { + return n; + } + + /** + * getter + * @return the prime was given in the constructor + */ + public BigInteger getQ() { + return q; + } + + + /** + * getter + * @return the polynomial was generated in constructor + */ + public Polynomial getPolynomial() { + return polynomial; + } +} diff --git a/destributed-key-generation/src/main/java/Arithmetics/Arithmetic.java b/destributed-key-generation/src/main/java/meerkat/crypto/utilitis/Arithmetic.java similarity index 85% rename from destributed-key-generation/src/main/java/Arithmetics/Arithmetic.java rename to destributed-key-generation/src/main/java/meerkat/crypto/utilitis/Arithmetic.java index 979ea60..618210a 100644 --- a/destributed-key-generation/src/main/java/Arithmetics/Arithmetic.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/utilitis/Arithmetic.java @@ -1,18 +1,18 @@ -package Arithmetics; - -/** - * Created by Tzlil on 3/17/2016. - */ -public interface Arithmetic { - /** - * - * @param a - * @param b - * @return - */ - T add(T a, T b); - T sub(T a, T b); - T mul(T a, T b); - T div(T a, T b); - -} +package meerkat.crypto.utilitis; + +/** + * Created by Tzlil on 3/17/2016. + */ +public interface Arithmetic { + /** + * + * @param a + * @param b + * @return + */ + T add(T a, T b); + T sub(T a, T b); + T mul(T a, T b); + T div(T a, T b); + +} diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/utilitis/Channel.java b/destributed-key-generation/src/main/java/meerkat/crypto/utilitis/Channel.java new file mode 100644 index 0000000..2be0bf4 --- /dev/null +++ b/destributed-key-generation/src/main/java/meerkat/crypto/utilitis/Channel.java @@ -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 Channel thread, so no long processing should + * occur in the callback method. + * @param callback + */ + public void registerReceiverCallback(ReceiverCallback callback); +} diff --git a/destributed-key-generation/src/main/java/Arithmetics/Fp.java b/destributed-key-generation/src/main/java/meerkat/crypto/utilitis/concrete/Fp.java similarity index 90% rename from destributed-key-generation/src/main/java/Arithmetics/Fp.java rename to destributed-key-generation/src/main/java/meerkat/crypto/utilitis/concrete/Fp.java index 0525d08..e538293 100644 --- a/destributed-key-generation/src/main/java/Arithmetics/Fp.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/utilitis/concrete/Fp.java @@ -1,38 +1,39 @@ -package Arithmetics; - -import org.factcenter.qilin.primitives.concrete.Zpstar; - -import java.math.BigInteger; - -/** - * Created by Tzlil on 3/17/2016. - */ -public class Fp implements Arithmetic { - public final BigInteger p; - private final Zpstar zp; - - public Fp(BigInteger p) { - this.p = p; - this.zp = new Zpstar(p); - } - - @Override - public BigInteger add(BigInteger a, BigInteger b){ - return a.add(b).mod(p); - } - - @Override - public BigInteger sub(BigInteger a, BigInteger b){ - return a.add(p).subtract(b).mod(p); - } - - @Override - public BigInteger mul(BigInteger a, BigInteger b){ - return zp.add(a,b); - } - - @Override - public BigInteger div(BigInteger a, BigInteger b){ - return mul(a,zp.negate(b)); - } -} +package meerkat.crypto.utilitis.concrete; + +import meerkat.crypto.utilitis.Arithmetic; +import org.factcenter.qilin.primitives.concrete.Zpstar; + +import java.math.BigInteger; + +/** + * Created by Tzlil on 3/17/2016. + */ +public class Fp implements Arithmetic { + public final BigInteger p; + private final Zpstar zp; + + public Fp(BigInteger p) { + this.p = p; + this.zp = new Zpstar(p); + } + + @Override + public BigInteger add(BigInteger a, BigInteger b){ + return a.add(b).mod(p); + } + + @Override + public BigInteger sub(BigInteger a, BigInteger b){ + return a.add(p).subtract(b).mod(p); + } + + @Override + public BigInteger mul(BigInteger a, BigInteger b){ + return zp.add(a,b); + } + + @Override + public BigInteger div(BigInteger a, BigInteger b){ + return mul(a,zp.negate(b)); + } +} diff --git a/destributed-key-generation/src/test/java/Utils/ChannelImpl.java b/destributed-key-generation/src/test/java/Utils/ChannelImpl.java new file mode 100644 index 0000000..31bf748 --- /dev/null +++ b/destributed-key-generation/src/test/java/Utils/ChannelImpl.java @@ -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 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( 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(); + } + + + +} diff --git a/destributed-key-generation/src/main/java/Arithmetics/Z.java b/destributed-key-generation/src/test/java/Utils/Z.java similarity index 84% rename from destributed-key-generation/src/main/java/Arithmetics/Z.java rename to destributed-key-generation/src/test/java/Utils/Z.java index acf486d..4f69fa4 100644 --- a/destributed-key-generation/src/main/java/Arithmetics/Z.java +++ b/destributed-key-generation/src/test/java/Utils/Z.java @@ -1,29 +1,30 @@ -package Arithmetics; - -import java.math.BigInteger; - -/** - * Created by Tzlil on 3/17/2016. - */ -public class Z implements Arithmetic { - - @Override - public BigInteger add(BigInteger a, BigInteger b) { - return a.add(b); - } - - @Override - public BigInteger sub(BigInteger a, BigInteger b) { - return a.subtract(b); - } - - @Override - public BigInteger mul(BigInteger a, BigInteger b) { - return a.multiply(b); - } - - @Override - public BigInteger div(BigInteger a, BigInteger b) { - return a.divide(b); - } -} +package Utils; + +import meerkat.crypto.utilitis.Arithmetic; + +import java.math.BigInteger; + +/** + * Created by Tzlil on 4/8/2016. + */ +public class Z implements Arithmetic { + @Override + public BigInteger add(BigInteger a, BigInteger b) { + return a.add(b); + } + + @Override + public BigInteger sub(BigInteger a, BigInteger b) { + return a.subtract(b); + } + + @Override + public BigInteger mul(BigInteger a, BigInteger b) { + return a.multiply(b); + } + + @Override + public BigInteger div(BigInteger a, BigInteger b) { + return a.divide(b); + } +} diff --git a/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGMaliciousUserImpl.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGMaliciousUserImpl.java similarity index 53% rename from destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGMaliciousUserImpl.java rename to destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGMaliciousUserImpl.java index a0c1d4e..e4adfc6 100644 --- a/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGMaliciousUserImpl.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGMaliciousUserImpl.java @@ -1,61 +1,62 @@ -package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; - -import Communication.Network; -import JointFeldmanProtocol.DistributedKeyGeneration; - -import java.math.BigInteger; -import java.util.Random; -import java.util.Set; - -/** - * Created by Tzlil on 3/29/2016. - */ -public class SDKGMaliciousUserImpl extends SecureDistributedKeyGenerationUserImpl { - - private final DistributedKeyGeneration maliciousSDKG; - private final Set falls; - public SDKGMaliciousUserImpl(SecureDistributedKeyGeneration sdkg,SecureDistributedKeyGeneration maliciousSDKG - , Network network,Set falls) { - super(sdkg, network); - this.falls = falls; - this.maliciousSDKG = maliciousSDKG; - maliciousSDKG.setParties(parties); - } - - public static SecureDistributedKeyGeneration generateMaliciousSDKG(SecureDistributedKeyGeneration sdkg,Random random){ - BigInteger q = sdkg.getQ(); - BigInteger zi = new BigInteger(q.bitLength(), random).mod(q); - return new SecureDistributedKeyGeneration(sdkg.getT(),sdkg.getN(),zi,random,sdkg.getQ() - ,sdkg.getGenerator(),sdkg.getH(),sdkg.getGroup(),sdkg.getId()); - } - - @Override - public void stage1() { - sdkg.broadcastVerificationValues(user); - sendSecrets(); //insteadof dkg.sendSecrets(user); - } - - @Override - public void stage3() { - stopReceiver(); - maliciousSDKG.answerAllComplainingPlayers(user); - } - - @Override - public void stage4(){ - //do nothing - } - - private void sendSecrets(){ - for (int j = 1; j <= n ; j++){ - if(j != id){ - if(falls.contains(j)){ - maliciousSDKG.sendSecret(user,j); - }else { - sdkg.sendSecret(user, j); - } - } - } - } - -} +package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol; + +import meerkat.crypto.utilitis.Channel; +import meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.DistributedKeyGeneration; + +import java.math.BigInteger; +import java.util.Random; +import java.util.Set; + +/** + * Created by Tzlil on 3/29/2016. + */ +public class SDKGMaliciousUserImpl extends SecureDistributedKeyGenerationUser { + + private final DistributedKeyGeneration maliciousSDKG; + private final Set falls; + public SDKGMaliciousUserImpl(SecureDistributedKeyGeneration sdkg, SecureDistributedKeyGeneration maliciousSDKG + , Channel channel, Set falls) { + super(sdkg, channel); + this.falls = falls; + this.maliciousSDKG = maliciousSDKG; + maliciousSDKG.setParties(parties); + } + + public static SecureDistributedKeyGeneration generateMaliciousSDKG(SecureDistributedKeyGeneration sdkg,Channel channel,Random random){ + BigInteger q = sdkg.getQ(); + BigInteger zi = new BigInteger(q.bitLength(), random).mod(q); + SecureDistributedKeyGeneration malicious = new SecureDistributedKeyGeneration(sdkg.getT(),sdkg.getN(),zi,random,sdkg.getQ() + ,sdkg.getGenerator(),sdkg.getH(),sdkg.getGroup(),sdkg.getId(),sdkg.getEncoder()); + malicious.setChannel(channel); + return malicious; + } + + @Override + public void stage1() { + sdkg.computeAndBroadcastVerificationValues(); + sendSecrets(); //insteadof dkg.sendSecrets(channel); + } + + @Override + public void stage3() { + maliciousSDKG.answerAllComplainingPlayers(); + } + + @Override + public void stage4(){ + //do nothing + } + + private void sendSecrets(){ + for (int j = 1; j <= n ; j++){ + if(j != id){ + if(falls.contains(j)){ + maliciousSDKG.sendSecret(j); + }else { + sdkg.sendSecret(j); + } + } + } + } + +} diff --git a/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGTest.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGTest.java similarity index 77% rename from destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGTest.java rename to destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGTest.java index 647e4cf..6e44252 100644 --- a/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGTest.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGTest.java @@ -1,177 +1,181 @@ -package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; - -import Arithmetics.Arithmetic; -import Arithmetics.Fp; -import Communication.Network; -import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; -import JointFeldmanProtocol.DKGMaliciousUserImpl; -import ShamirSecretSharing.Polynomial; -import ShamirSecretSharing.SecretSharing; -import UserInterface.DistributedKeyGenerationUser; -import Utils.GenerateRandomPrime; -import org.factcenter.qilin.primitives.Group; -import org.factcenter.qilin.primitives.concrete.Zpstar; -import org.junit.Before; -import org.junit.Test; - -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Random; -import java.util.Set; - -/** - * Created by Tzlil on 3/29/2016. - */ -public class SDKGTest { - - int tests = 10; - BigInteger p = GenerateRandomPrime.SafePrime100Bits; - BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); - Group group = new Zpstar(p); - Arithmetic arithmetic = new Fp(q); - int t = 9; - int n = 20; - Testable[] testables; - - @Before - public void settings(){ - 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++){ - testable.threads[i].start(); - } - 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){ - assert (testable.sdkgs[i - 1].getPublicValue().equals(publicValue)); - } - - // assert valid verification values - BigInteger expected,verification; - for (int i: testable.valids){ - 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 sharesList = new ArrayList(); - - for (int i: testable.valids){ - sharesList.add(testable.sdkgs[i - 1].getShare()); - } - 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)); - } - - @Test - public void test() throws Exception { - for (int i = 0; i < tests; i++){ - oneTest(i); - } - } - - class Testable{ - Set valids; - Set QUAL; - Set aborted; - Set malicious; - DistributedKeyGenerationUser[] sdkgs; - Thread[] threads; - BigInteger g; - BigInteger h; - BigInteger secret; - - public Testable(Random random) { - this.sdkgs = new SecureDistributedKeyGenerationUserImpl[n]; - this.valids = new HashSet(); - this.QUAL = new HashSet(); - this.aborted = new HashSet(); - this.malicious = new HashSet(); - this.threads = new Thread[n]; - this.g = sampleGenerator(random); - this.h = group.multiply(g,randomIntModQ(random)); - ArrayList ids = new ArrayList(); - for (int id = 1; id<= n ; id++){ - ids.add(id); - } - Network network = new Network(n); - int id; - BigInteger s; - SecureDistributedKeyGeneration sdkg; - this.secret = BigInteger.ZERO; - while (!ids.isEmpty()) { - id = ids.remove(random.nextInt(ids.size())); - s = randomIntModQ(random); - sdkg = new SecureDistributedKeyGeneration(t, n, s, random, q, g , h, group, id); - sdkgs[id - 1] = randomSDKGUser(id,network,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); - }else{ - int type = random.nextInt(3); - switch (type){ - case 0:// regular - valids.add(id); - QUAL.add(id); - return new SecureDistributedKeyGenerationUserImpl(sdkg,network); - case 1:// abort - int abortStage = random.nextInt(3) + 1; // 1 or 2 or 3 - aborted.add(id); - if (abortStage > 1){ - QUAL.add(id); - } - return new SDKGUserImplAbort(sdkg,network,abortStage); - case 2:// malicious - malicious.add(id); - Set falls = DKGMaliciousUserImpl.selectFallsRandomly(valids,random); - SecureDistributedKeyGeneration maliciousSDKG = SDKGMaliciousUserImpl.generateMaliciousSDKG(sdkg,random); - return new SDKGMaliciousUserImpl(sdkg,maliciousSDKG,network,falls); - default: - return null; - } - } - } - - public BigInteger sampleGenerator(Random random){ - BigInteger ZERO = group.zero(); - BigInteger g; - do { - g = group.sample(random); - } while (!g.equals(ZERO) && !group.multiply(g, q).equals(ZERO)); - return g; - } - - public BigInteger randomIntModQ(Random random){ - return new BigInteger(q.bitLength(), random).mod(q); - } - - } -} +package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol; + +import meerkat.crypto.utilitis.Arithmetic; +import meerkat.crypto.utilitis.concrete.Fp; +import meerkat.crypto.utilitis.Channel; +import Communication.ChannelImpl; +import meerkat.crypto.concrete.secret_shring.feldman_verifiable.VerifiableSecretSharing; +import meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.DKGMaliciousUser; +import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; +import meerkat.crypto.concrete.secret_shring.shamir.SecretSharing; +import Utils.BigIntegerByteEncoder; +import Utils.GenerateRandomPrime; +import org.factcenter.qilin.primitives.Group; +import org.factcenter.qilin.primitives.concrete.Zpstar; +import org.factcenter.qilin.util.ByteEncoder; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Random; +import java.util.Set; + +/** + * Created by Tzlil on 3/29/2016. + */ +public class SDKGTest { + + int tests = 1; + BigInteger p = GenerateRandomPrime.SafePrime100Bits; + BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); + Group group = new Zpstar(p); + Arithmetic arithmetic = new Fp(q); + int t = 9; + int n = 20; + Testable[] testables; + + @Before + public void settings(){ + 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++){ + testable.threads[i].start(); + } + 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){ + assert (testable.sdkgs[i - 1].getPublicValue().equals(publicValue)); + } + + // assert valid verification values + BigInteger expected,verification; + for (int i: testable.valids){ + 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 sharesList = new ArrayList(); + + for (int i: testable.valids){ + sharesList.add(testable.sdkgs[i - 1].getShare()); + } + 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)); + } + + @Test + public void test() throws Exception { + for (int i = 0; i < tests; i++){ + oneTest(i); + } + } + + class Testable{ + Set valids; + Set QUAL; + Set aborted; + Set malicious; + SecureDistributedKeyGenerationUser[] sdkgs; + Thread[] threads; + BigInteger g; + BigInteger h; + BigInteger secret; + + public Testable(Random random) { + this.sdkgs = new SecureDistributedKeyGenerationUser[n]; + this.valids = new HashSet(); + this.QUAL = new HashSet(); + this.aborted = new HashSet(); + this.malicious = new HashSet(); + this.threads = new Thread[n]; + this.g = sampleGenerator(random); + this.h = group.multiply(g,randomIntModQ(random)); + ArrayList ids = new ArrayList(); + for (int id = 1; id<= n ; id++){ + ids.add(id); + } + int id; + BigInteger s; + Channel channel; + SecureDistributedKeyGeneration sdkg; + this.secret = BigInteger.ZERO; + ByteEncoder encoder = new BigIntegerByteEncoder(); + while (!ids.isEmpty()) { + id = ids.remove(random.nextInt(ids.size())); + s = randomIntModQ(random); + channel = new ChannelImpl(id,n); + 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 SecureDistributedKeyGenerationUser randomSDKGUser(int id, Channel channel, SecureDistributedKeyGeneration sdkg, Random random){ + if (QUAL.size() <= t) { + valids.add(id); + QUAL.add(id); + return new SecureDistributedKeyGenerationUser(sdkg,channel); + }else{ + int type = random.nextInt(3); + switch (type){ + case 0:// regular + valids.add(id); + QUAL.add(id); + return new SecureDistributedKeyGenerationUser(sdkg,channel); + case 1:// abort + int abortStage = random.nextInt(3) + 1; // 1 or 2 or 3 + aborted.add(id); + if (abortStage > 1){ + QUAL.add(id); + } + return new SDKGUserImplAbort(sdkg,channel,abortStage); + case 2:// malicious + malicious.add(id); + Set 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); + } while (!g.equals(ZERO) && !group.multiply(g, q).equals(ZERO)); + return g; + } + + public BigInteger randomIntModQ(Random random){ + return new BigInteger(q.bitLength(), random).mod(q); + } + + } +} diff --git a/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGUserImplAbort.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGUserImplAbort.java similarity index 66% rename from destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGUserImplAbort.java rename to destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGUserImplAbort.java index 551de93..2690048 100644 --- a/destributed-key-generation/src/test/java/SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem/SDKGUserImplAbort.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGUserImplAbort.java @@ -1,65 +1,63 @@ -package SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem; - -import Communication.Network; -import SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem.SecureDistributedKeyGeneration; -import SecureDistributedKeyGenerationForDiscreteLogBasedCryptosystem.SecureDistributedKeyGenerationUserImpl; -import meerkat.protobuf.DKGMessages; - -/** - * Created by Tzlil on 3/14/2016. - */ -public class SDKGUserImplAbort extends SecureDistributedKeyGenerationUserImpl { - - final int abortStage; - int stage; - public SDKGUserImplAbort(SecureDistributedKeyGeneration sdkg, Network network, int abortStage) { - super(sdkg, network); - this.abortStage = abortStage;// 1 - 4 - this.stage = 1; - } - - private void abort(){ - stopReceiver(); - user.broadcast(DKGMessages.Mail.Type.ABORT,DKGMessages.EmptyMessage.getDefaultInstance()); - } - - @Override - protected void stage1() { - if(stage < abortStage) - super.stage1(); - else if(stage == abortStage){ - abort(); - } - stage++; - } - - @Override - protected void stage2() { - if(stage < abortStage) - super.stage2(); - else if(stage == abortStage){ - abort(); - } - stage++; - } - - @Override - protected void stage3() { - if(stage < abortStage) - super.stage3(); - else if(stage == abortStage){ - abort(); - } - stage++; - } - - @Override - protected void stage4() { - if(stage < abortStage) - super.stage4(); - else if(stage == abortStage){ - abort(); - } - stage++; - } -} +package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol; + +import meerkat.crypto.utilitis.Channel; +import meerkat.protobuf.DKGMessages; + +/** + * Created by Tzlil on 3/14/2016. + */ +public class SDKGUserImplAbort extends SecureDistributedKeyGenerationUser { + + final int abortStage; + int stage; + public SDKGUserImplAbort(SecureDistributedKeyGeneration sdkg, Channel channel, int abortStage) { + super(sdkg, channel); + this.abortStage = abortStage;// 1 - 4 + this.stage = 1; + } + + private void abort(){ + //stopReceiver(); + channel.broadcastMessage(DKGMessages.Mail.Type.ABORT,DKGMessages.EmptyMessage.getDefaultInstance()); + } + + @Override + protected void stage1() { + if(stage < abortStage) + super.stage1(); + else if(stage == abortStage){ + abort(); + } + stage++; + } + + @Override + protected void stage2() { + if(stage < abortStage) + super.stage2(); + else if(stage == abortStage){ + abort(); + } + stage++; + } + + @Override + protected void stage3() { + if(stage < abortStage) + super.stage3(); + else if(stage == abortStage){ + abort(); + } + stage++; + } + + @Override + protected void stage4() { + if(stage < abortStage) + super.stage4(); + else if(stage == abortStage){ + abort(); + } + stage++; + } +} diff --git a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGMaliciousUserImpl.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGMaliciousUser.java similarity index 59% rename from destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGMaliciousUserImpl.java rename to destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGMaliciousUser.java index 4dfd4a4..2c7bea2 100644 --- a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGMaliciousUserImpl.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGMaliciousUser.java @@ -1,72 +1,73 @@ -package JointFeldmanProtocol; - -import Communication.MailHandler; -import Communication.Network; - -import java.math.BigInteger; -import java.util.*; - -/** - * Created by Tzlil on 3/21/2016. - */ -public class DKGMaliciousUserImpl extends DistributedKeyGenerationUserImpl { - - private final DistributedKeyGeneration maliciousDkg; - private final Set falls; - public DKGMaliciousUserImpl(DistributedKeyGeneration dkg,DistributedKeyGeneration maliciousDKG, Network network,Set falls) { - super(dkg, network); - this.falls = falls; - this.maliciousDkg = maliciousDKG; - maliciousDKG.setParties(parties); - } - - public static Set selectFallsRandomly(Set ids, Random random){ - Set falls = new HashSet(); - ArrayList idsList = new ArrayList(); - for (int id : ids){ - idsList.add(id); - } - int fallsSize = random.nextInt(idsList.size()) + 1;// 1 - (n-1) - while (falls.size() < fallsSize){ - falls.add(idsList.remove(random.nextInt(idsList.size()))); - } - return falls; - } - - public static DistributedKeyGeneration generateMaliciousDKG(DistributedKeyGeneration dkg,Random random){ - BigInteger q = dkg.getQ(); - BigInteger zi = new BigInteger(q.bitLength(), random).mod(q); - return new DistributedKeyGeneration(dkg.getT(),dkg.getN(),zi,random,dkg.getQ() - ,dkg.getGenerator(),dkg.getGroup(),dkg.getId()); - } - - @Override - public void stage1() { - dkg.broadcastCommitments(user); - sendSecrets(); //insteadof dkg.sendSecrets(user); - } - - @Override - public void stage3() { - maliciousDkg.answerAllComplainingPlayers(user); - } - - @Override - public void stage4(){ - // do nothing - } - - private void sendSecrets(){ - for (int j = 1; j <= n ; j++){ - if(j != id){ - if(falls.contains(j)){ - maliciousDkg.sendSecret(user,j); - }else { - dkg.sendSecret(user, j); - } - } - } - } - - -} +package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol; + +import meerkat.crypto.utilitis.Channel; + +import java.math.BigInteger; +import java.util.*; + +/** + * Created by Tzlil on 3/21/2016. + */ +public class DKGMaliciousUser extends DistributedKeyGenerationUser { + + private final DistributedKeyGeneration maliciousDkg; + private final Set falls; + public DKGMaliciousUser(DistributedKeyGeneration dkg, DistributedKeyGeneration maliciousDKG, Channel channel, Set falls) { + super(dkg, channel); + this.falls = falls; + this.maliciousDkg = maliciousDKG; + maliciousDKG.setParties(parties); + } + + public static Set selectFallsRandomly(Set ids, Random random){ + Set falls = new HashSet(); + ArrayList idsList = new ArrayList(); + for (int id : ids){ + idsList.add(id); + } + int fallsSize = random.nextInt(idsList.size()) + 1;// 1 - (n-1) + while (falls.size() < fallsSize){ + falls.add(idsList.remove(random.nextInt(idsList.size()))); + } + return falls; + } + + public static DistributedKeyGeneration generateMaliciousDKG(DistributedKeyGeneration dkg,Channel channel,Random random){ + BigInteger q = dkg.getQ(); + BigInteger zi = new BigInteger(q.bitLength(), random).mod(q); + DistributedKeyGeneration malicious = new DistributedKeyGeneration(dkg.getT(),dkg.getN(),zi,random,dkg.getQ() + ,dkg.getGenerator(),dkg.getGroup(),dkg.getId(),dkg.getEncoder()); + malicious.setChannel(channel); + return malicious; + } + + @Override + public void stage1() { + dkg.broadcastCommitments(); + sendSecrets(); //insteadof dkg.sendSecrets(channel); + } + + @Override + public void stage3() { + maliciousDkg.answerAllComplainingPlayers(); + } + + @Override + public void stage4(){ + // do nothing + } + + private void sendSecrets(){ + for (int j = 1; j <= n ; j++){ + if(j != id){ + if(falls.contains(j)){ + maliciousDkg.sendSecret(j); + }else { + dkg.sendSecret(j); + } + } + } + } + + +} diff --git a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGTest.java similarity index 78% rename from destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java rename to destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGTest.java index 7599a53..f4b2780 100644 --- a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGTest.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGTest.java @@ -1,175 +1,179 @@ -package JointFeldmanProtocol; - -import Arithmetics.Arithmetic; -import Arithmetics.Fp; -import Communication.Network; -import FeldmanVerifiableSecretSharing.VerifiableSecretSharing; -import ShamirSecretSharing.Polynomial; -import ShamirSecretSharing.SecretSharing; -import UserInterface.DistributedKeyGenerationUser; -import Utils.GenerateRandomPrime; -import org.factcenter.qilin.primitives.Group; -import org.factcenter.qilin.primitives.concrete.Zpstar; -import org.junit.Before; -import org.junit.Test; - -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Random; -import java.util.Set; - -/** - * Created by Tzlil on 3/21/2016. - */ -public class DKGTest { - - int tests = 10; - BigInteger p = GenerateRandomPrime.SafePrime100Bits; - BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); - Group group = new Zpstar(p); - Arithmetic arithmetic = new Fp(q); - int t = 9; - int n = 20; - - Testable[] testables; - - @Before - public void settings(){ - 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++){ - testable.threads[i].start(); - } - 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){ - assert (testable.dkgs[i - 1].getPublicValue().equals(publicValue)); - } - - // assert valid verification values - BigInteger expected,verification; - for (int i: testable.valids){ - 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 sharesList = new ArrayList(); - - for (int i: testable.valids){ - sharesList.add(testable.dkgs[i - 1].getShare()); - } - 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)); - } - - @Test - public void test() throws Exception { - for (int i = 0; i < tests; i++){ - oneTest(i); - } - } - - class Testable{ - Set valids; - Set QUAL; - Set aborted; - Set malicious; - DistributedKeyGenerationUser[] dkgs; - Thread[] threads; - BigInteger g; - BigInteger secret; - - public Testable(Random random) { - this.dkgs = new DistributedKeyGenerationUserImpl[n]; - this.valids = new HashSet(); - this.QUAL = new HashSet(); - this.aborted = new HashSet(); - this.malicious = new HashSet(); - this.threads = new Thread[n]; - this.g = sampleGenerator(random); - ArrayList ids = new ArrayList(); - for (int id = 1; id<= n ; id++){ - ids.add(id); - } - Network network = new Network(n); - int id; - BigInteger s; - DistributedKeyGeneration dkg; - this.secret = BigInteger.ZERO; - while (!ids.isEmpty()) { - id = ids.remove(random.nextInt(ids.size())); - s = randomIntModQ(random); - dkg = new DistributedKeyGeneration(t, n, s, random, q, g, group, id); - dkgs[id - 1] = randomDKGUser(id,network,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); - }else{ - int type = random.nextInt(3); - switch (type){ - case 0:// regular - valids.add(id); - QUAL.add(id); - return new DistributedKeyGenerationUserImpl(dkg,network); - case 1:// abort - int abortStage = random.nextInt(2) + 1; // 1 or 2 - aborted.add(id); - if (abortStage == 2){ - QUAL.add(id); - } - return new DKGUserImplAbort(dkg,network,abortStage); - case 2:// malicious - malicious.add(id); - Set falls = DKGMaliciousUserImpl.selectFallsRandomly(valids,random); - DistributedKeyGeneration maliciousDKG = DKGMaliciousUserImpl.generateMaliciousDKG(dkg,random); - return new DKGMaliciousUserImpl(dkg,maliciousDKG,network,falls); - default: - return null; - } - } - } - - public BigInteger sampleGenerator(Random random){ - BigInteger ZERO = group.zero(); - BigInteger g; - do { - g = group.sample(random); - } while (!g.equals(ZERO) && !group.multiply(g, q).equals(ZERO)); - return g; - } - - public BigInteger randomIntModQ(Random random){ - return new BigInteger(q.bitLength(), random).mod(q); - } - - } -} +package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol; + +import meerkat.crypto.utilitis.Arithmetic; +import meerkat.crypto.utilitis.concrete.Fp; +import meerkat.crypto.utilitis.Channel; +import Communication.ChannelImpl; +import meerkat.crypto.concrete.secret_shring.feldman_verifiable.VerifiableSecretSharing; +import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; +import meerkat.crypto.concrete.secret_shring.shamir.SecretSharing; +import Utils.BigIntegerByteEncoder; +import Utils.GenerateRandomPrime; +import org.factcenter.qilin.primitives.Group; +import org.factcenter.qilin.primitives.concrete.Zpstar; +import org.factcenter.qilin.util.ByteEncoder; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Random; +import java.util.Set; + +/** + * Created by Tzlil on 3/21/2016. + */ +public class DKGTest { + + int tests = 1; + BigInteger p = GenerateRandomPrime.SafePrime100Bits; + BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); + Group group = new Zpstar(p); + Arithmetic arithmetic = new Fp(q); + int t = 9; + int n = 20; + + Testable[] testables; + + @Before + public void settings(){ + 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++){ + testable.threads[i].start(); + } + 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){ + assert (testable.dkgs[i - 1].getPublicValue().equals(publicValue)); + } + + // assert valid verification values + BigInteger expected,verification; + for (int i: testable.valids){ + 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 sharesList = new ArrayList(); + + for (int i: testable.valids){ + sharesList.add(testable.dkgs[i - 1].getShare()); + } + 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)); + } + + @Test + public void test() throws Exception { + for (int i = 0; i < tests; i++){ + oneTest(i); + } + } + + class Testable{ + Set valids; + Set QUAL; + Set aborted; + Set malicious; + DistributedKeyGenerationUser[] dkgs; + Thread[] threads; + BigInteger g; + BigInteger secret; + + public Testable(Random random) { + this.dkgs = new DistributedKeyGenerationUser[n]; + this.valids = new HashSet(); + this.QUAL = new HashSet(); + this.aborted = new HashSet(); + this.malicious = new HashSet(); + this.threads = new Thread[n]; + this.g = sampleGenerator(random); + ArrayList ids = new ArrayList(); + for (int id = 1; id<= n ; id++){ + ids.add(id); + } + int id; + BigInteger s; + DistributedKeyGeneration dkg; + this.secret = BigInteger.ZERO; + Channel channel; + ByteEncoder byteEncoder = new BigIntegerByteEncoder(); + while (!ids.isEmpty()) { + id = ids.remove(random.nextInt(ids.size())); + channel = new ChannelImpl(id,n); + s = randomIntModQ(random); + 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, Channel channel, DistributedKeyGeneration dkg, Random random){ + if (QUAL.size() <= t) { + valids.add(id); + QUAL.add(id); + return new DistributedKeyGenerationUser(dkg,channel); + }else{ + int type = random.nextInt(3); + switch (type){ + case 0:// regular + valids.add(id); + QUAL.add(id); + return new DistributedKeyGenerationUser(dkg,channel); + case 1:// abort + int abortStage = random.nextInt(2) + 1; // 1 or 2 + aborted.add(id); + if (abortStage == 2){ + QUAL.add(id); + } + return new DKGUserImplAbort(dkg,channel,abortStage); + case 2:// malicious + malicious.add(id); + Set 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); + } while (!g.equals(ZERO) && !group.multiply(g, q).equals(ZERO)); + return g; + } + + public BigInteger randomIntModQ(Random random){ + return new BigInteger(q.bitLength(), random).mod(q); + } + + } +} diff --git a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGUserImplAbort.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGUserImplAbort.java similarity index 75% rename from destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGUserImplAbort.java rename to destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGUserImplAbort.java index 6acb8ce..88a0847 100644 --- a/destributed-key-generation/src/test/java/JointFeldmanProtocol/DKGUserImplAbort.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGUserImplAbort.java @@ -1,63 +1,63 @@ -package JointFeldmanProtocol; - -import Communication.Network; -import meerkat.protobuf.DKGMessages; - -/** - * Created by Tzlil on 3/14/2016. - */ -public class DKGUserImplAbort extends DistributedKeyGenerationUserImpl { - - final int abortStage; - int stage; - public DKGUserImplAbort(DistributedKeyGeneration dkg, Network network, int abortStage) { - super(dkg, network); - this.abortStage = abortStage;// 1 - 2 - this.stage = 1; - } - - - private void sendAbort(){ - user.broadcast(DKGMessages.Mail.Type.ABORT,DKGMessages.EmptyMessage.getDefaultInstance()); - } - - @Override - protected void stage1() { - if(stage < abortStage) - super.stage1(); - else if(stage == abortStage){ - sendAbort(); - } - stage++; - } - - @Override - protected void stage2() { - if(stage < abortStage) - super.stage2(); - else if(stage == abortStage){ - sendAbort(); - } - stage++; - } - - @Override - protected void stage3() { - if(stage < abortStage) - super.stage3(); - else if(stage == abortStage){ - sendAbort(); - } - stage++; - } - - @Override - protected void stage4() { - if(stage < abortStage) - super.stage4(); - else if(stage == abortStage){ - sendAbort(); - } - stage++; - } -} +package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol; + +import meerkat.crypto.utilitis.Channel; +import meerkat.protobuf.DKGMessages; + +/** + * Created by Tzlil on 3/14/2016. + */ +public class DKGUserImplAbort extends DistributedKeyGenerationUser { + + final int abortStage; + int stage; + public DKGUserImplAbort(DistributedKeyGeneration dkg, Channel channel, int abortStage) { + super(dkg, channel); + this.abortStage = abortStage;// 1 - 2 + this.stage = 1; + } + + + private void sendAbort(){ + channel.broadcastMessage(DKGMessages.Mail.Type.ABORT,DKGMessages.EmptyMessage.getDefaultInstance()); + } + + @Override + protected void stage1() { + if(stage < abortStage) + super.stage1(); + else if(stage == abortStage){ + sendAbort(); + } + stage++; + } + + @Override + protected void stage2() { + if(stage < abortStage) + super.stage2(); + else if(stage == abortStage){ + sendAbort(); + } + stage++; + } + + @Override + protected void stage3() { + if(stage < abortStage) + super.stage3(); + else if(stage == abortStage){ + sendAbort(); + } + stage++; + } + + @Override + protected void stage4() { + if(stage < abortStage) + super.stage4(); + else if(stage == abortStage){ + sendAbort(); + } + stage++; + } +} diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharingTest.java similarity index 85% rename from destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java rename to destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharingTest.java index 897957e..f7d3a39 100644 --- a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharingTest.java @@ -1,67 +1,68 @@ -package FeldmanVerifiableSecretSharing; - -import ShamirSecretSharing.Polynomial; -import org.factcenter.qilin.primitives.Group; -import org.factcenter.qilin.primitives.concrete.Zpstar; -import org.junit.Before; -import org.junit.Test; - -import java.math.BigInteger; -import java.util.Random; - -/** - * Created by Tzlil on 1/29/2016. - */ -public class VerifiableSecretSharingTest { - - - VerifiableSecretSharing[] verifiableSecretSharingArray; - int tests = 1 << 10; - Random random; - - @Before - public void settings(){ - BigInteger p = BigInteger.valueOf(2903); - BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); - Zpstar zpstar = new Zpstar(p); - random = new Random(); - BigInteger g; - BigInteger ZERO = zpstar.zero(); - do{ - g = zpstar.sample(random); - }while (!g.equals(ZERO) && !zpstar.multiply(g,q).equals(ZERO));// sample from QRZp* - int t = 8; - int n = 20; - verifiableSecretSharingArray = new VerifiableSecretSharing[tests]; - for (int i = 0; i < verifiableSecretSharingArray.length; i++){ - 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(); - Group zpstar = verifiableSecretSharing.getGroup(); - BigInteger g = verifiableSecretSharing.getGenerator(); - Polynomial.Point[] shares = new Polynomial.Point[n]; - BigInteger[] commitments = verifiableSecretSharing.getCommitmentsArray(); - BigInteger[] verifications = new BigInteger[n]; - for (int i = 1 ; i <= shares.length; i ++){ - shares[i - 1] = verifiableSecretSharing.getShare(i); - verifications[i - 1] = VerifiableSecretSharing.computeVerificationValue(i,commitments,zpstar); - } - BigInteger expected; - for (int i = 0 ; i < shares.length ; i++){ - expected = zpstar.multiply(g,shares[i].y); - assert (expected.equals(verifications[i])); - } - - } - - @Test - public void secretSharingTest() throws Exception { - for (int i = 0 ; i < verifiableSecretSharingArray.length; i ++){ - oneTest(verifiableSecretSharingArray[i]); - } - } -} +package meerkat.crypto.concrete.secret_shring.feldman_verifiable; + +import meerkat.crypto.concrete.secret_shring.ShamirSecretSharing.Polynomial; +import org.factcenter.qilin.primitives.Group; +import org.factcenter.qilin.primitives.concrete.Zpstar; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Random; + +/** + * Created by Tzlil on 1/29/2016. + */ +public class VerifiableSecretSharingTest { + + + VerifiableSecretSharing[] verifiableSecretSharingArray; + int tests = 1 << 10; + Random random; + + @Before + public void settings(){ + BigInteger p = BigInteger.valueOf(2903); + BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); + Zpstar zpstar = new Zpstar(p); + random = new Random(); + BigInteger g; + BigInteger ZERO = zpstar.zero(); + do{ + g = zpstar.sample(random); + }while (!g.equals(ZERO) && !zpstar.multiply(g,q).equals(ZERO));// sample from QRZp* + int t = 8; + int n = 20; + verifiableSecretSharingArray = new VerifiableSecretSharing[tests]; + for (int i = 0; i < verifiableSecretSharingArray.length; i++){ + 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(); + Group zpstar = verifiableSecretSharing.getGroup(); + BigInteger g = verifiableSecretSharing.getGenerator(); + Polynomial.Point[] shares = new Polynomial.Point[n]; + ArrayList commitments = verifiableSecretSharing.getCommitmentsArrayList(); + BigInteger[] verifications = new BigInteger[n]; + for (int i = 1 ; i <= shares.length; i ++){ + shares[i - 1] = verifiableSecretSharing.getShare(i); + verifications[i - 1] = VerifiableSecretSharing.computeVerificationValue(i,commitments,zpstar); + } + BigInteger expected; + for (int i = 0 ; i < shares.length ; i++){ + expected = zpstar.multiply(g,shares[i].y); + assert (expected.equals(verifications[i])); + } + + } + + @Test + public void secretSharingTest() throws Exception { + for (int i = 0 ; i < verifiableSecretSharingArray.length; i ++){ + oneTest(verifiableSecretSharingArray[i]); + } + } +} diff --git a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/AddTest.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/AddTest.java similarity index 89% rename from destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/AddTest.java rename to destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/AddTest.java index a95552d..2c78b03 100644 --- a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/AddTest.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/AddTest.java @@ -1,46 +1,46 @@ -package ShamirSecretSharing.PolynomialTests; -import Arithmetics.Z; -import Utils.GenerateRandomPolynomial; -import ShamirSecretSharing.Polynomial; -import org.junit.Before; -import org.junit.Test; - -import java.math.BigInteger; -import java.util.Random; - -/** - * Created by Tzlil on 1/27/2016. - */ -public class AddTest { - - Polynomial[] arr1; - Polynomial[] arr2; - int tests = 1 << 12; - int maxDegree = 15; - int bits = 128; - Random random; - - @Before - public void settings(){ - random = new Random(); - arr1 = new Polynomial[tests]; - arr2 = new Polynomial[tests]; - for (int i = 0; i < arr1.length; i++){ - arr1[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){ - Polynomial sum = p1.add(p2); - BigInteger x = new BigInteger(bits,random); - assert(sum.evaluate(x).equals(p1.evaluate(x).add(p2.evaluate(x)))); - } - - @Test - public void addTest(){ - for (int i = 0 ; i < arr1.length; i ++){ - oneTest(arr1[i],arr2[i]); - } - } -} +package meerkat.crypto.concrete.secret_shring.shamir.PolynomialTests; +import Arithmetics.Z; +import Utils.GenerateRandomPolynomial; +import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/27/2016. + */ +public class AddTest { + + Polynomial[] arr1; + Polynomial[] arr2; + int tests = 1 << 12; + int maxDegree = 15; + int bits = 128; + Random random; + + @Before + public void settings(){ + random = new Random(); + arr1 = new Polynomial[tests]; + arr2 = new Polynomial[tests]; + for (int i = 0; i < arr1.length; i++){ + arr1[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){ + Polynomial sum = p1.add(p2); + BigInteger x = new BigInteger(bits,random); + assert(sum.evaluate(x).equals(p1.evaluate(x).add(p2.evaluate(x)))); + } + + @Test + public void addTest(){ + for (int i = 0 ; i < arr1.length; i ++){ + oneTest(arr1[i],arr2[i]); + } + } +} diff --git a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/InterpolationTest.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/InterpolationTest.java similarity index 89% rename from destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/InterpolationTest.java rename to destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/InterpolationTest.java index a222b95..0183d3f 100644 --- a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/InterpolationTest.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/InterpolationTest.java @@ -1,68 +1,68 @@ -package ShamirSecretSharing.PolynomialTests; - -import Arithmetics.Arithmetic; -import Arithmetics.Fp; -import Utils.GenerateRandomPolynomial; -import ShamirSecretSharing.Polynomial; -import Utils.GenerateRandomPrime; -import org.junit.Before; -import org.junit.Test; - -import java.math.BigInteger; -import java.util.HashSet; -import java.util.Random; -import java.util.Set; - -/** - * Created by Tzlil on 1/27/2016. - */ -public class InterpolationTest { - Polynomial[] polynomials; - int tests = 1 << 10; - int maxDegree = 15; - int bits = 128; - Random random; - Polynomial.Point[][] pointsArrays; - Arithmetic arithmetic; - BigInteger p = GenerateRandomPrime.SafePrime100Bits; - - @Before - public void settings(){ - random = new Random(); - polynomials = new Polynomial[tests]; - pointsArrays = new Polynomial.Point[tests][]; - for (int i = 0; i < polynomials.length; 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){ - Polynomial.Point[] points = new Polynomial.Point[polynomial.getDegree() + 1]; - BigInteger x; - Set set = new HashSet(); - for (int i = 0; i < points.length; i++){ - x = new BigInteger(bits,random).mod(p); - if(set.contains(x)){ - i--; - continue; - } - set.add(x); - points[i] = new Polynomial.Point(x,polynomial); - } - return points; - } - - public void oneTest(Polynomial p, Polynomial.Point[] points) throws Exception { - Polynomial interpolation = Polynomial.interpolation(points,arithmetic); - assert (p.compareTo(interpolation) == 0); - } - - @Test - public void interpolationTest() throws Exception { - for (int i = 0; i < polynomials.length; i ++){ - oneTest(polynomials[i],pointsArrays[i]); - } - } -} +package meerkat.crypto.concrete.secret_shring.shamir.PolynomialTests; + +import meerkat.crypto.utilitis.Arithmetic; +import meerkat.crypto.utilitis.concrete.Fp; +import Utils.GenerateRandomPolynomial; +import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; +import Utils.GenerateRandomPrime; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.HashSet; +import java.util.Random; +import java.util.Set; + +/** + * Created by Tzlil on 1/27/2016. + */ +public class InterpolationTest { + Polynomial[] polynomials; + int tests = 1 << 10; + int maxDegree = 15; + int bits = 128; + Random random; + Polynomial.Point[][] pointsArrays; + Arithmetic arithmetic; + BigInteger p = GenerateRandomPrime.SafePrime100Bits; + + @Before + public void settings(){ + random = new Random(); + polynomials = new Polynomial[tests]; + pointsArrays = new Polynomial.Point[tests][]; + arithmetic = new Fp(p); + for (int i = 0; i < polynomials.length; i++){ + polynomials[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,p); + pointsArrays[i] = randomPoints(polynomials[i]); + } + } + + public Polynomial.Point[] randomPoints(Polynomial polynomial){ + Polynomial.Point[] points = new Polynomial.Point[polynomial.getDegree() + 1]; + BigInteger x; + Set set = new HashSet(); + for (int i = 0; i < points.length; i++){ + x = new BigInteger(bits,random).mod(p); + if(set.contains(x)){ + i--; + continue; + } + set.add(x); + points[i] = new Polynomial.Point(x,polynomial); + } + return points; + } + + public void oneTest(Polynomial p, Polynomial.Point[] points) throws Exception { + Polynomial interpolation = Polynomial.interpolation(points,arithmetic); + assert (p.compareTo(interpolation) == 0); + } + + @Test + public void interpolationTest() throws Exception { + for (int i = 0; i < polynomials.length; i ++){ + oneTest(polynomials[i],pointsArrays[i]); + } + } +} diff --git a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulByConstTest.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/MulByConstTest.java similarity index 89% rename from destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulByConstTest.java rename to destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/MulByConstTest.java index 2f073c5..30e2082 100644 --- a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulByConstTest.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/MulByConstTest.java @@ -1,48 +1,48 @@ -package ShamirSecretSharing.PolynomialTests; - -import Arithmetics.Z; -import Utils.GenerateRandomPolynomial; -import ShamirSecretSharing.Polynomial; -import org.junit.Before; -import org.junit.Test; - -import java.math.BigInteger; -import java.util.Random; - -/** - * Created by Tzlil on 1/27/2016. - */ -public class MulByConstTest { - - - Polynomial[] arr1; - BigInteger[] arr2; - int tests = 1 << 12; - int maxDegree = 15; - int bits = 128; - Random random; - - @Before - public void settings(){ - random = new Random(); - arr1 = new Polynomial[tests]; - arr2 = new BigInteger[tests]; - for (int i = 0; i < arr1.length; i++){ - arr1[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,new Z()); - arr2[i] = new BigInteger(bits,random); - } - } - - public void oneTest(Polynomial p, BigInteger c){ - Polynomial product = p.mul(c); - BigInteger x = new BigInteger(bits,random); - assert(product.evaluate(x).equals(p.evaluate(x).multiply(c))); - } - - @Test - public void mulByConstTest(){ - for (int i = 0 ; i < arr1.length; i ++){ - oneTest(arr1[i],arr2[i]); - } - } -} +package meerkat.crypto.concrete.secret_shring.shamir.PolynomialTests; + +import Arithmetics.Z; +import Utils.GenerateRandomPolynomial; +import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/27/2016. + */ +public class MulByConstTest { + + + Polynomial[] arr1; + BigInteger[] arr2; + int tests = 1 << 12; + int maxDegree = 15; + int bits = 128; + Random random; + + @Before + public void settings(){ + random = new Random(); + arr1 = new Polynomial[tests]; + arr2 = new BigInteger[tests]; + for (int i = 0; i < arr1.length; i++){ + arr1[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,new Z()); + arr2[i] = new BigInteger(bits,random); + } + } + + public void oneTest(Polynomial p, BigInteger c){ + Polynomial product = p.mul(c); + BigInteger x = new BigInteger(bits,random); + assert(product.evaluate(x).equals(p.evaluate(x).multiply(c))); + } + + @Test + public void mulByConstTest(){ + for (int i = 0 ; i < arr1.length; i ++){ + oneTest(arr1[i],arr2[i]); + } + } +} diff --git a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulTest.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/MulTest.java similarity index 89% rename from destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulTest.java rename to destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/MulTest.java index 478e541..8af27ab 100644 --- a/destributed-key-generation/src/test/java/ShamirSecretSharing/PolynomialTests/MulTest.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/MulTest.java @@ -1,48 +1,48 @@ -package ShamirSecretSharing.PolynomialTests; - -import Arithmetics.Z; -import Utils.GenerateRandomPolynomial; -import ShamirSecretSharing.Polynomial; -import org.junit.Before; -import org.junit.Test; - -import java.math.BigInteger; -import java.util.Random; - -/** - * Created by Tzlil on 1/27/2016. - */ -public class MulTest { - - - Polynomial[] arr1; - Polynomial[] arr2; - int tests = 1 << 12; - int maxDegree = 15; - int bits = 128; - Random random; - - @Before - public void settings(){ - random = new Random(); - arr1 = new Polynomial[tests]; - arr2 = new Polynomial[tests]; - for (int i = 0; i < arr1.length; i++){ - arr1[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){ - Polynomial product = p1.mul(p2); - BigInteger x = new BigInteger(bits,random); - assert(product.evaluate(x).equals(p1.evaluate(x).multiply(p2.evaluate(x)))); - } - - @Test - public void mulTest(){ - for (int i = 0 ; i < arr1.length; i ++){ - oneTest(arr1[i],arr2[i]); - } - } -} +package meerkat.crypto.concrete.secret_shring.shamir.PolynomialTests; + +import Arithmetics.Z; +import Utils.GenerateRandomPolynomial; +import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.Random; + +/** + * Created by Tzlil on 1/27/2016. + */ +public class MulTest { + + + Polynomial[] arr1; + Polynomial[] arr2; + int tests = 1 << 12; + int maxDegree = 15; + int bits = 128; + Random random; + + @Before + public void settings(){ + random = new Random(); + arr1 = new Polynomial[tests]; + arr2 = new Polynomial[tests]; + for (int i = 0; i < arr1.length; i++){ + arr1[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){ + Polynomial product = p1.mul(p2); + BigInteger x = new BigInteger(bits,random); + assert(product.evaluate(x).equals(p1.evaluate(x).multiply(p2.evaluate(x)))); + } + + @Test + public void mulTest(){ + for (int i = 0 ; i < arr1.length; i ++){ + oneTest(arr1[i],arr2[i]); + } + } +} diff --git a/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/SecretSharingTest.java similarity index 81% rename from destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java rename to destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/SecretSharingTest.java index 40cf306..0396916 100644 --- a/destributed-key-generation/src/test/java/ShamirSecretSharing/SecretSharingTest.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/SecretSharingTest.java @@ -1,63 +1,64 @@ -package ShamirSecretSharing; - -import Arithmetics.Z; -import Utils.GenerateRandomPrime; -import org.factcenter.qilin.primitives.CyclicGroup; -import org.factcenter.qilin.primitives.concrete.Zn; -import org.junit.Before; -import org.junit.Test; - -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -/** - * Created by Tzlil on 1/29/2016. - */ -public class SecretSharingTest { - - SecretSharing[] secretSharingArray; - BigInteger[] secrets; - CyclicGroup group; - int tests = 1 << 10; - Random random; - - @Before - public void settings(){ - BigInteger p = GenerateRandomPrime.SafePrime100Bits; - BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); - group = new Zn(p); - int t = 9; - int n = 20; - random = new Random(); - secretSharingArray = new SecretSharing[tests]; - secrets = new BigInteger[tests]; - - for (int i = 0; i < secretSharingArray.length; i++){ - secrets[i] = group.sample(random); - secretSharingArray[i] = new SecretSharing(t,n,secrets[i],random,q); - } - } - - public void oneTest(SecretSharing secretSharing, BigInteger secret) throws Exception { - int t = secretSharing.getT(); - int n = secretSharing.getN(); - Polynomial.Point[] shares = new Polynomial.Point[t + 1]; - List indexes = new ArrayList(n); - for (int i = 1 ; i <= n; i ++){ - indexes.add(i); - } - for (int i = 0 ; i < shares.length ; i++){ - shares[i] = secretSharing.getShare(indexes.remove(random.nextInt(indexes.size()))); - } - assert(secret.equals(SecretSharing.recoverSecret(shares,new Z()))); - } - - @Test - public void secretSharingTest() throws Exception { - for (int i = 0 ; i < secretSharingArray.length; i ++){ - oneTest(secretSharingArray[i],secrets[i]); - } - } -} +package meerkat.crypto.concrete.secret_shring.shamir; + +import meerkat.crypto.utilitis.concrete.Fp; +import Utils.GenerateRandomPrime; +import org.factcenter.qilin.primitives.CyclicGroup; +import org.factcenter.qilin.primitives.concrete.Zn; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +/** + * Created by Tzlil on 1/29/2016. + */ +public class SecretSharingTest { + + SecretSharing[] secretSharingArray; + BigInteger[] secrets; + CyclicGroup group; + int tests = 1 << 10; + Random random; + BigInteger p = GenerateRandomPrime.SafePrime100Bits; + BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); + + @Before + public void settings(){ + group = new Zn(q); + int t = 9; + int n = 20; + random = new Random(); + secretSharingArray = new SecretSharing[tests]; + secrets = new BigInteger[tests]; + + for (int i = 0; i < secretSharingArray.length; i++){ + secrets[i] = group.sample(random); + secretSharingArray[i] = new SecretSharing(t,n,secrets[i],random,q); + } + } + + public void oneTest(SecretSharing secretSharing, BigInteger secret) throws Exception { + int t = secretSharing.getT(); + int n = secretSharing.getN(); + Polynomial.Point[] shares = new Polynomial.Point[t + 1]; + List indexes = new ArrayList(n); + for (int i = 1 ; i <= n; i ++){ + indexes.add(i); + } + for (int i = 0 ; i < shares.length ; i++){ + shares[i] = secretSharing.getShare(indexes.remove(random.nextInt(indexes.size()))); + } + BigInteger calculated = SecretSharing.recoverSecret(shares,new Fp(q)); + assert (secret.equals(calculated)); + } + + @Test + public void secretSharingTest() throws Exception { + for (int i = 0 ; i < secretSharingArray.length; i ++){ + oneTest(secretSharingArray[i],secrets[i]); + } + } +} From 5d564c834c5b51970c82bda8f74573c4dce19995 Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Fri, 8 Apr 2016 15:04:07 +0300 Subject: [PATCH 34/49] generic group + wait instead of sleep --- .../java/Utils/BigIntegerByteEncoder.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 destributed-key-generation/src/test/java/Utils/BigIntegerByteEncoder.java diff --git a/destributed-key-generation/src/test/java/Utils/BigIntegerByteEncoder.java b/destributed-key-generation/src/test/java/Utils/BigIntegerByteEncoder.java new file mode 100644 index 0000000..a0c7107 --- /dev/null +++ b/destributed-key-generation/src/test/java/Utils/BigIntegerByteEncoder.java @@ -0,0 +1,28 @@ +package Utils; + +import java.math.BigInteger; + +/** + * Created by Tzlil on 4/7/2016. + */ +public class BigIntegerByteEncoder implements org.factcenter.qilin.util.ByteEncoder { + @Override + public byte[] encode(BigInteger input) { + return input.toByteArray(); + } + + @Override + public BigInteger decode(byte[] input) { + return new BigInteger(1,input); + } + + @Override + public int getMinLength() { + return 0; + } + + @Override + public BigInteger denseDecode(byte[] input) { + return decode(input); + } +} From 3e1f59ec2b58c32aefd70da7aeedbba620e7c968 Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Fri, 8 Apr 2016 15:46:54 +0300 Subject: [PATCH 35/49] switch secret with share --- .../Communication/ChannelImpl.java | 108 ------------------ .../Communication/MailHandler.java | 26 ++--- .../Communication/MessageHandler.java | 2 +- .../gjkr_secure_protocol/MailHandler.java | 5 +- .../gjkr_secure_protocol/Party.java | 3 +- .../gjkr_secure_protocol/Protocol.java | 5 +- .../gjkr_secure_protocol/User.java | 19 ++- .../joint_feldman_protocol/MailHandler.java | 5 +- .../joint_feldman_protocol/Party.java | 7 +- .../joint_feldman_protocol/Protocol.java | 4 +- .../joint_feldman_protocol/User.java | 28 +++-- .../VerifiableSecretSharing.java | 5 +- .../java/Utils/GenerateRandomPolynomial.java | 8 +- .../SDKGMaliciousUserImpl.java | 12 +- .../gjkr_secure_protocol/SDKGTest.java | 18 +-- .../SDKGUserImplAbort.java | 4 +- .../DKGMaliciousUser.java | 10 +- .../joint_feldman_protocol/DKGTest.java | 19 +-- .../DKGUserImplAbort.java | 4 +- .../VerifiableSecretSharingTest.java | 2 +- .../shamir/PolynomialTests/AddTest.java | 2 +- .../PolynomialTests/MulByConstTest.java | 2 +- .../shamir/PolynomialTests/MulTest.java | 2 +- .../src/main/proto/meerkat/DKGMessages.proto | 12 +- 24 files changed, 98 insertions(+), 214 deletions(-) delete mode 100644 destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/ChannelImpl.java diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/ChannelImpl.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/ChannelImpl.java deleted file mode 100644 index 04fa4ef..0000000 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/ChannelImpl.java +++ /dev/null @@ -1,108 +0,0 @@ -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 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( 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(); - } - - - -} diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/MailHandler.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/MailHandler.java index b01801f..c646a5a 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/MailHandler.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/MailHandler.java @@ -1,4 +1,4 @@ -package meerkat.crypto.concrete.distributed_key_generation.Communication; +package meerkat.crypto.concrete.distributed_key_generation.communication; import com.google.protobuf.Message; import meerkat.crypto.utilitis.Channel; @@ -9,13 +9,19 @@ import meerkat.protobuf.DKGMessages; */ public abstract class MailHandler implements Channel.ReceiverCallback{ + public static final int BROADCAST = 0; private MessageHandler messageHandler; + public MailHandler(MessageHandler messageHandler){ this.messageHandler = messageHandler; } public abstract Message extractMessage(DKGMessages.Mail mail); + public boolean isBroadcast(DKGMessages.Mail mail){ + return mail.getDestination() == BROADCAST; + } + public void receiveMail(DKGMessages.Mail mail){ Message message = extractMessage(mail); @@ -24,28 +30,22 @@ public abstract class MailHandler implements Channel.ReceiverCallback{ switch (mail.getType()) { case SHARE: - messageHandler.handleSecretMessage(mail.getSender(), mail.getDestination() == ChannelImpl.BROADCAST - , message); + messageHandler.handleSecretMessage(mail.getSender(), isBroadcast(mail),message); break; case COMMITMENT: - messageHandler.handleCommitmentMessage(mail.getSender(), mail.getDestination() == ChannelImpl.BROADCAST - , message); + messageHandler.handleCommitmentMessage(mail.getSender(), isBroadcast(mail),message); break; case DONE: - messageHandler.handleDoneMessage(mail.getSender(), mail.getDestination() == ChannelImpl.BROADCAST - , message); + messageHandler.handleDoneMessage(mail.getSender(), isBroadcast(mail),message); break; case COMPLAINT: - messageHandler.handleComplaintMessage(mail.getSender(), mail.getDestination() == ChannelImpl.BROADCAST - , message); + messageHandler.handleComplaintMessage(mail.getSender(), isBroadcast(mail),message); break; case ANSWER: - messageHandler.handleAnswerMessage(mail.getSender(), mail.getDestination() == ChannelImpl.BROADCAST - , message); + messageHandler.handleAnswerMessage(mail.getSender(), isBroadcast(mail),message); break; case ABORT: - messageHandler.handleAbortMessage(mail.getSender(), mail.getDestination() == ChannelImpl.BROADCAST - , message); + messageHandler.handleAbortMessage(mail.getSender(), isBroadcast(mail),message); break; default: break; diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/MessageHandler.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/MessageHandler.java index 74b453a..a58cbcc 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/MessageHandler.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/MessageHandler.java @@ -1,4 +1,4 @@ -package meerkat.crypto.concrete.distributed_key_generation.Communication; +package meerkat.crypto.concrete.distributed_key_generation.communication; import com.google.protobuf.Message; diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/MailHandler.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/MailHandler.java index 4683f04..c35fe6c 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/MailHandler.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/MailHandler.java @@ -1,15 +1,14 @@ package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol; -import Communication.MailHandler; -import Communication.MessageHandler; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; +import meerkat.crypto.concrete.distributed_key_generation.communication.MessageHandler; import meerkat.protobuf.DKGMessages; /** * Created by Tzlil on 2/29/2016. */ -public class MailHandler extends Communication.MailHandler { +public class MailHandler extends meerkat.crypto.concrete.distributed_key_generation.communication.MailHandler { private boolean isStage4; diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Party.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Party.java index 82ebba8..c0ee63a 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Party.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Party.java @@ -1,6 +1,5 @@ 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; @@ -14,7 +13,7 @@ import java.util.Set; * contains all relevant information on specific party during * the run of the safe protocol */ -public class Party extends DistributedKeyGenerationParty { +public class Party extends meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.Party { public Polynomial.Point shareT; public boolean ysDoneFlag; public ArrayList verifiableValues; diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Protocol.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Protocol.java index db0cc56..13ff0e6 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Protocol.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Protocol.java @@ -1,7 +1,6 @@ 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; @@ -137,8 +136,8 @@ public class Protocol extends meerkat.crypto.concrete.distributed_key_generat DKGMessages.DoubleShareMessage doubleShareMessage = DKGMessages.DoubleShareMessage.newBuilder() .setI(i) .setJ(j) - .setSecret(ByteString.copyFrom(share.y.toByteArray())) - .setSecretT(ByteString.copyFrom(shareT.y.toByteArray())) + .setShare(ByteString.copyFrom(share.y.toByteArray())) + .setShareT(ByteString.copyFrom(shareT.y.toByteArray())) .build(); return doubleShareMessage; } diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/User.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/User.java index ac99b6e..f976ff9 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/User.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/User.java @@ -3,7 +3,6 @@ package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol; import meerkat.crypto.utilitis.Arithmetic; import meerkat.crypto.utilitis.concrete.Fp; import meerkat.crypto.utilitis.Channel; -import meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.User; import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; import meerkat.crypto.concrete.secret_shring.shamir.SecretSharing; import com.google.protobuf.Message; @@ -22,7 +21,7 @@ public class User extends meerkat.crypto.concrete.distributed_key_generation. private Arithmetic arithmetic; private boolean isStage4; - public User(Protocol sdkg, Channel channel) { + public User(Protocol sdkg, Channel channel) { super(sdkg, channel); this.sdkg = sdkg; this.parties = sdkg.getParties(); @@ -176,7 +175,7 @@ public class User extends meerkat.crypto.concrete.distributed_key_generation. DKGMessages.ShareMessage secretMessage = DKGMessages.ShareMessage.newBuilder() .setI(doubleSecretMessage.getI()) .setJ(doubleSecretMessage.getJ()) - .setSecret(doubleSecretMessage.getSecret()) + .setShare(doubleSecretMessage.getShare()) .build(); return super.isValidSecretMessage(sender,isBroadcast,secretMessage); } @@ -190,8 +189,8 @@ public class User extends meerkat.crypto.concrete.distributed_key_generation. if (isValidSecretMessage(sender,isBroadcast,doubleSecretMessage)) { int i = doubleSecretMessage.getI(); synchronized (parties[i - 1]) { - parties[i - 1].share = extractShare(id, doubleSecretMessage.getSecret()); - parties[i - 1].shareT = extractShare(id, doubleSecretMessage.getSecretT()); + parties[i - 1].share = extractShare(id, doubleSecretMessage.getShare()); + parties[i - 1].shareT = extractShare(id, doubleSecretMessage.getShareT()); parties[i - 1].notify(); } } @@ -209,7 +208,7 @@ public class User extends meerkat.crypto.concrete.distributed_key_generation. DKGMessages.ShareMessage secretMessage = DKGMessages.ShareMessage.newBuilder() .setI(doubleSecretMessage.getI()) .setJ(doubleSecretMessage.getJ()) - .setSecret(doubleSecretMessage.getSecret()) + .setShare(doubleSecretMessage.getShare()) .build(); return super.isValidAnswerMessage(sender, isBroadcast, secretMessage); }else{ @@ -230,8 +229,8 @@ public class User extends meerkat.crypto.concrete.distributed_key_generation. if(isValidAnswerMessage(sender,isBroadcast,doubleSecretMessage)) { int i = doubleSecretMessage.getI(); int j = doubleSecretMessage.getJ(); - Polynomial.Point secret = extractShare(j, doubleSecretMessage.getSecret()); - Polynomial.Point secretT = extractShare(j, doubleSecretMessage.getSecretT()); + Polynomial.Point secret = extractShare(j, doubleSecretMessage.getShare()); + Polynomial.Point secretT = extractShare(j, doubleSecretMessage.getShareT()); synchronized (parties[i - 1]) { if (!isStage4) { if (sdkg.isValidShare(secret, secretT, parties[j - 1].verifiableValues, i)) { @@ -310,8 +309,8 @@ public class User extends meerkat.crypto.concrete.distributed_key_generation. 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()); + Polynomial.Point secret = extractShare(i,ysComplaintMessage.getShare()); + Polynomial.Point secretT = extractShare(i,ysComplaintMessage.getShareT()); if (sdkg.isValidShare(secret, secretT, parties[i - 1].verifiableValues, j) && !dkg.isValidShare(secret,parties[i - 1].commitments, j)) { synchronized (parties[i - 1]) { diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/MailHandler.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/MailHandler.java index 19c279e..8f971fc 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/MailHandler.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/MailHandler.java @@ -1,15 +1,14 @@ package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol; -import Communication.MailHandler; -import Communication.MessageHandler; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; +import meerkat.crypto.concrete.distributed_key_generation.communication.MessageHandler; import meerkat.protobuf.DKGMessages; /** * Created by Tzlil on 2/29/2016. */ -public class MailHandler extends Communication.MailHandler { +public class MailHandler extends meerkat.crypto.concrete.distributed_key_generation.communication.MailHandler { public MailHandler(MessageHandler messageHandler) { super(messageHandler); diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Party.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Party.java index b45d5b5..c30ca97 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Party.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Party.java @@ -11,21 +11,20 @@ import java.util.Arrays; * contains all relevant information on specific party during * the run of Joint Feldamn protocol */ -// TODO: comments for every field. public class Party { public final int id; public Polynomial.Point share; public ArrayList commitments; public boolean doneFlag; - public DistributedKeyGeneration.ComplaintState[] complaints; + public Protocol.ComplaintState[] complaints; public boolean aborted; public Party(int id, int n, int t) { this.id = id; this.share = null; this.doneFlag = false; - this.complaints = new DistributedKeyGeneration.ComplaintState[n]; - Arrays.fill(this.complaints, DistributedKeyGeneration.ComplaintState.OK); + this.complaints = new Protocol.ComplaintState[n]; + Arrays.fill(this.complaints, Protocol.ComplaintState.OK); this.commitments = new ArrayList(t + 1); for (int i = 0; i <= t ; i++){ commitments.add(null); diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Protocol.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Protocol.java index ba0a77b..79a3f9c 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Protocol.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Protocol.java @@ -146,7 +146,7 @@ public class Protocol extends VerifiableSecretSharing { DKGMessages.ShareMessage.newBuilder() .setI(id) .setJ(j) - .setSecret(secret) + .setShare(secret) .build()); } @@ -221,7 +221,7 @@ public class Protocol extends VerifiableSecretSharing { channel.broadcastMessage(DKGMessages.Mail.Type.ANSWER, DKGMessages.ShareMessage.newBuilder() .setI(id) .setJ(j) - .setSecret(ByteString.copyFrom(getShare(j).y.toByteArray())) + .setShare(ByteString.copyFrom(getShare(j).y.toByteArray())) .build()); } diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/User.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/User.java index f225d59..8475aef 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/User.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/User.java @@ -1,7 +1,6 @@ package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol; import meerkat.crypto.utilitis.Channel; -import Communication.MailHandler; import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; import com.google.protobuf.ByteString; import com.google.protobuf.Message; @@ -11,7 +10,6 @@ import org.factcenter.qilin.primitives.Group; import java.math.BigInteger; import java.util.ArrayList; import java.util.Set; -import meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.DistributedKeyGeneration.ComplaintState; /** * Created by Tzlil on 3/14/2016. @@ -20,14 +18,14 @@ import meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol */ public class User implements Runnable{ - protected final DistributedKeyGeneration dkg; + protected final Protocol dkg; protected final T g; protected final Group group; protected final int n; protected final int t; protected final int id; - protected MailHandler mailHandler; + protected meerkat.crypto.concrete.distributed_key_generation.communication.MailHandler mailHandler; protected final Channel channel; protected final Party[] parties; @@ -36,7 +34,7 @@ public class User implements Runnable{ protected ArrayList commitments; // public verification values protected T y; // final public value - public User(DistributedKeyGeneration dkg, Channel channel) { + public User(Protocol dkg, Channel channel) { this.dkg = dkg; this.g = dkg.getGenerator(); @@ -61,7 +59,7 @@ public class User implements Runnable{ * create MailHandler and register it as ReceiverCallback */ protected void registerReceiverCallback(){ - this.mailHandler = new DistributedKeyGenerationMailHandler(new MessageHandler()); + this.mailHandler = new MailHandler(new MessageHandler()); channel.registerReceiverCallback(mailHandler); } @@ -148,7 +146,7 @@ public class User implements Runnable{ for (int i = 0; i < n; i++){ for (int j = 0; j < n; j++){ synchronized (parties[i]) { - while (parties[i].complaints[j].equals(ComplaintState.Waiting) && !parties[i].aborted) { + while (parties[i].complaints[j].equals(Protocol.ComplaintState.Waiting) && !parties[i].aborted) { try { parties[i].wait(); } catch (InterruptedException e) { @@ -263,7 +261,7 @@ public class User implements Runnable{ } - public class MessageHandler implements Communication.MessageHandler{ + public class MessageHandler implements meerkat.crypto.concrete.distributed_key_generation.communication.MessageHandler{ public MessageHandler(){ @@ -320,7 +318,7 @@ public class User implements Runnable{ DKGMessages.ShareMessage secretMessage = (DKGMessages.ShareMessage) message; if(isValidSecretMessage(sender,isBroadcast,secretMessage)) { int i = secretMessage.getI(); - Polynomial.Point secret = extractShare(id,secretMessage.getSecret()); + Polynomial.Point secret = extractShare(id,secretMessage.getShare()); synchronized (parties[i -1]) { parties[i - 1].share = secret; parties[i - 1].notify(); @@ -358,7 +356,7 @@ public class User implements Runnable{ protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, DKGMessages.IDMessage complaintMessage){ int i = sender; int j = complaintMessage.getId(); - return isBroadcast && parties[i - 1].complaints[j - 1].equals( ComplaintState.OK); + return isBroadcast && parties[i - 1].complaints[j - 1].equals( Protocol.ComplaintState.OK); } /** @@ -371,7 +369,7 @@ public class User implements Runnable{ int i = sender; int j = complaintMessage.getId(); synchronized (parties[j - 1]) { - parties[j - 1].complaints[i - 1] = ComplaintState.Waiting; + parties[j - 1].complaints[i - 1] = Protocol.ComplaintState.Waiting; parties[j - 1].notify(); } } @@ -390,7 +388,7 @@ public class User implements Runnable{ if(sender != i || !isBroadcast) return false; else - return j >= 1 && j <= n && parties[i - 1].complaints[j - 1].equals(ComplaintState.Waiting); + return j >= 1 && j <= n && parties[i - 1].complaints[j - 1].equals(Protocol.ComplaintState.Waiting); } /** @@ -404,12 +402,12 @@ public class User implements Runnable{ if(isValidAnswerMessage(sender,isBroadcast,secretMessage)) { int i = secretMessage.getI(); int j = secretMessage.getJ(); - Polynomial.Point secret = extractShare(j,secretMessage.getSecret()); + Polynomial.Point secret = extractShare(j,secretMessage.getShare()); synchronized (parties[i - 1]) { if (dkg.isValidShare(secret, parties[i - 1].commitments, j)) { - parties[i - 1].complaints[j - 1] = ComplaintState.NonDisqualified; + parties[i - 1].complaints[j - 1] = Protocol.ComplaintState.NonDisqualified; } else { - parties[i - 1].complaints[j - 1] = ComplaintState.Disqualified; + parties[i - 1].complaints[j - 1] = Protocol.ComplaintState.Disqualified; } if (j == id) { parties[i - 1].share = secret; diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharing.java b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharing.java index a15f0e2..6f3638b 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharing.java +++ b/destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharing.java @@ -1,8 +1,7 @@ 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 meerkat.crypto.concrete.secret_shring.shamir.Polynomial; +import meerkat.crypto.concrete.secret_shring.shamir.SecretSharing; import org.factcenter.qilin.primitives.Group; import java.util.ArrayList; diff --git a/destributed-key-generation/src/test/java/Utils/GenerateRandomPolynomial.java b/destributed-key-generation/src/test/java/Utils/GenerateRandomPolynomial.java index 4ca7b6a..4521fcd 100644 --- a/destributed-key-generation/src/test/java/Utils/GenerateRandomPolynomial.java +++ b/destributed-key-generation/src/test/java/Utils/GenerateRandomPolynomial.java @@ -1,8 +1,8 @@ package Utils; -import Arithmetics.Arithmetic; -import Arithmetics.Fp; -import ShamirSecretSharing.Polynomial; +import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; +import meerkat.crypto.utilitis.Arithmetic; +import meerkat.crypto.utilitis.concrete.Fp; import java.math.BigInteger; import java.util.Random; @@ -12,7 +12,7 @@ import java.util.Random; */ public class GenerateRandomPolynomial { - public static Polynomial generateRandomPolynomial(int degree, int bits, Random random,Arithmetic arithmetic) { + public static Polynomial generateRandomPolynomial(int degree, int bits, Random random, Arithmetic arithmetic) { BigInteger[] coefficients = new BigInteger[degree + 1]; for (int i = 0 ; i <= degree; i++ ){ diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGMaliciousUserImpl.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGMaliciousUserImpl.java index e4adfc6..34bd672 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGMaliciousUserImpl.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGMaliciousUserImpl.java @@ -1,7 +1,7 @@ package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol; +import meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol.*; import meerkat.crypto.utilitis.Channel; -import meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.DistributedKeyGeneration; import java.math.BigInteger; import java.util.Random; @@ -10,11 +10,11 @@ import java.util.Set; /** * Created by Tzlil on 3/29/2016. */ -public class SDKGMaliciousUserImpl extends SecureDistributedKeyGenerationUser { +public class SDKGMaliciousUserImpl extends User { - private final DistributedKeyGeneration maliciousSDKG; + private final Protocol maliciousSDKG; private final Set falls; - public SDKGMaliciousUserImpl(SecureDistributedKeyGeneration sdkg, SecureDistributedKeyGeneration maliciousSDKG + public SDKGMaliciousUserImpl(Protocol sdkg, Protocol maliciousSDKG , Channel channel, Set falls) { super(sdkg, channel); this.falls = falls; @@ -22,10 +22,10 @@ public class SDKGMaliciousUserImpl extends SecureDistributedKeyGenerationUser { maliciousSDKG.setParties(parties); } - public static SecureDistributedKeyGeneration generateMaliciousSDKG(SecureDistributedKeyGeneration sdkg,Channel channel,Random random){ + public static Protocol generateMaliciousSDKG(Protocol sdkg,Channel channel,Random random){ BigInteger q = sdkg.getQ(); BigInteger zi = new BigInteger(q.bitLength(), random).mod(q); - SecureDistributedKeyGeneration malicious = new SecureDistributedKeyGeneration(sdkg.getT(),sdkg.getN(),zi,random,sdkg.getQ() + Protocol malicious = new Protocol(sdkg.getT(),sdkg.getN(),zi,random,sdkg.getQ() ,sdkg.getGenerator(),sdkg.getH(),sdkg.getGroup(),sdkg.getId(),sdkg.getEncoder()); malicious.setChannel(channel); return malicious; diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGTest.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGTest.java index 6e44252..5fc7e04 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGTest.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGTest.java @@ -1,9 +1,9 @@ package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol; +import Utils.ChannelImpl; import meerkat.crypto.utilitis.Arithmetic; import meerkat.crypto.utilitis.concrete.Fp; import meerkat.crypto.utilitis.Channel; -import Communication.ChannelImpl; import meerkat.crypto.concrete.secret_shring.feldman_verifiable.VerifiableSecretSharing; import meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.DKGMaliciousUser; import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; @@ -95,14 +95,14 @@ public class SDKGTest { Set QUAL; Set aborted; Set malicious; - SecureDistributedKeyGenerationUser[] sdkgs; + User[] sdkgs; Thread[] threads; BigInteger g; BigInteger h; BigInteger secret; public Testable(Random random) { - this.sdkgs = new SecureDistributedKeyGenerationUser[n]; + this.sdkgs = new User[n]; this.valids = new HashSet(); this.QUAL = new HashSet(); this.aborted = new HashSet(); @@ -117,14 +117,14 @@ public class SDKGTest { int id; BigInteger s; Channel channel; - SecureDistributedKeyGeneration sdkg; + Protocol sdkg; this.secret = BigInteger.ZERO; ByteEncoder encoder = new BigIntegerByteEncoder(); while (!ids.isEmpty()) { id = ids.remove(random.nextInt(ids.size())); s = randomIntModQ(random); channel = new ChannelImpl(id,n); - sdkg = new SecureDistributedKeyGeneration(t, n, s, random, q, g , h, group, id,encoder); + sdkg = new Protocol(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)){ @@ -134,18 +134,18 @@ public class SDKGTest { } - public SecureDistributedKeyGenerationUser randomSDKGUser(int id, Channel channel, SecureDistributedKeyGeneration sdkg, Random random){ + public User randomSDKGUser(int id, Channel channel, Protocol sdkg, Random random){ if (QUAL.size() <= t) { valids.add(id); QUAL.add(id); - return new SecureDistributedKeyGenerationUser(sdkg,channel); + return new User(sdkg,channel); }else{ int type = random.nextInt(3); switch (type){ case 0:// regular valids.add(id); QUAL.add(id); - return new SecureDistributedKeyGenerationUser(sdkg,channel); + return new User(sdkg,channel); case 1:// abort int abortStage = random.nextInt(3) + 1; // 1 or 2 or 3 aborted.add(id); @@ -156,7 +156,7 @@ public class SDKGTest { case 2:// malicious malicious.add(id); Set falls = DKGMaliciousUser.selectFallsRandomly(valids,random); - SecureDistributedKeyGeneration maliciousSDKG = SDKGMaliciousUserImpl.generateMaliciousSDKG(sdkg,channel,random); + Protocol maliciousSDKG = SDKGMaliciousUserImpl.generateMaliciousSDKG(sdkg,channel,random); return new SDKGMaliciousUserImpl(sdkg,maliciousSDKG,channel,falls); default: return null; diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGUserImplAbort.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGUserImplAbort.java index 2690048..0a7bb12 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGUserImplAbort.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGUserImplAbort.java @@ -6,11 +6,11 @@ import meerkat.protobuf.DKGMessages; /** * Created by Tzlil on 3/14/2016. */ -public class SDKGUserImplAbort extends SecureDistributedKeyGenerationUser { +public class SDKGUserImplAbort extends User { final int abortStage; int stage; - public SDKGUserImplAbort(SecureDistributedKeyGeneration sdkg, Channel channel, int abortStage) { + public SDKGUserImplAbort(Protocol sdkg, Channel channel, int abortStage) { super(sdkg, channel); this.abortStage = abortStage;// 1 - 4 this.stage = 1; diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGMaliciousUser.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGMaliciousUser.java index 2c7bea2..f20076d 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGMaliciousUser.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGMaliciousUser.java @@ -8,11 +8,11 @@ import java.util.*; /** * Created by Tzlil on 3/21/2016. */ -public class DKGMaliciousUser extends DistributedKeyGenerationUser { +public class DKGMaliciousUser extends User { - private final DistributedKeyGeneration maliciousDkg; + private final Protocol maliciousDkg; private final Set falls; - public DKGMaliciousUser(DistributedKeyGeneration dkg, DistributedKeyGeneration maliciousDKG, Channel channel, Set falls) { + public DKGMaliciousUser(Protocol dkg, Protocol maliciousDKG, Channel channel, Set falls) { super(dkg, channel); this.falls = falls; this.maliciousDkg = maliciousDKG; @@ -32,10 +32,10 @@ public class DKGMaliciousUser extends DistributedKeyGenerationUser { return falls; } - public static DistributedKeyGeneration generateMaliciousDKG(DistributedKeyGeneration dkg,Channel channel,Random random){ + public static Protocol generateMaliciousDKG(Protocol dkg,Channel channel,Random random){ BigInteger q = dkg.getQ(); BigInteger zi = new BigInteger(q.bitLength(), random).mod(q); - DistributedKeyGeneration malicious = new DistributedKeyGeneration(dkg.getT(),dkg.getN(),zi,random,dkg.getQ() + Protocol malicious = new Protocol(dkg.getT(),dkg.getN(),zi,random,dkg.getQ() ,dkg.getGenerator(),dkg.getGroup(),dkg.getId(),dkg.getEncoder()); malicious.setChannel(channel); return malicious; diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGTest.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGTest.java index f4b2780..19693f5 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGTest.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGTest.java @@ -1,14 +1,15 @@ package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol; +import Utils.ChannelImpl; import meerkat.crypto.utilitis.Arithmetic; import meerkat.crypto.utilitis.concrete.Fp; import meerkat.crypto.utilitis.Channel; -import Communication.ChannelImpl; import meerkat.crypto.concrete.secret_shring.feldman_verifiable.VerifiableSecretSharing; import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; import meerkat.crypto.concrete.secret_shring.shamir.SecretSharing; import Utils.BigIntegerByteEncoder; import Utils.GenerateRandomPrime; +import meerkat.protobuf.Crypto; import org.factcenter.qilin.primitives.Group; import org.factcenter.qilin.primitives.concrete.Zpstar; import org.factcenter.qilin.util.ByteEncoder; @@ -95,13 +96,13 @@ public class DKGTest { Set QUAL; Set aborted; Set malicious; - DistributedKeyGenerationUser[] dkgs; + User[] dkgs; Thread[] threads; BigInteger g; BigInteger secret; public Testable(Random random) { - this.dkgs = new DistributedKeyGenerationUser[n]; + this.dkgs = new User[n]; this.valids = new HashSet(); this.QUAL = new HashSet(); this.aborted = new HashSet(); @@ -114,7 +115,7 @@ public class DKGTest { } int id; BigInteger s; - DistributedKeyGeneration dkg; + Protocol dkg; this.secret = BigInteger.ZERO; Channel channel; ByteEncoder byteEncoder = new BigIntegerByteEncoder(); @@ -122,7 +123,7 @@ public class DKGTest { id = ids.remove(random.nextInt(ids.size())); channel = new ChannelImpl(id,n); s = randomIntModQ(random); - dkg = new DistributedKeyGeneration(t, n, s, random, q, g, group, id,byteEncoder); + dkg = new meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.Protocol(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)){ @@ -132,18 +133,18 @@ public class DKGTest { } - public DistributedKeyGenerationUser randomDKGUser(int id, Channel channel, DistributedKeyGeneration dkg, Random random){ + public User randomDKGUser(int id, Channel channel, Protocol dkg, Random random){ if (QUAL.size() <= t) { valids.add(id); QUAL.add(id); - return new DistributedKeyGenerationUser(dkg,channel); + return new User(dkg,channel); }else{ int type = random.nextInt(3); switch (type){ case 0:// regular valids.add(id); QUAL.add(id); - return new DistributedKeyGenerationUser(dkg,channel); + return new User(dkg,channel); case 1:// abort int abortStage = random.nextInt(2) + 1; // 1 or 2 aborted.add(id); @@ -154,7 +155,7 @@ public class DKGTest { case 2:// malicious malicious.add(id); Set falls = DKGMaliciousUser.selectFallsRandomly(valids,random); - DistributedKeyGeneration maliciousDKG = DKGMaliciousUser.generateMaliciousDKG(dkg,channel,random); + Protocol maliciousDKG = DKGMaliciousUser.generateMaliciousDKG(dkg,channel,random); return new DKGMaliciousUser(dkg,maliciousDKG,channel,falls); default: return null; diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGUserImplAbort.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGUserImplAbort.java index 88a0847..2e42299 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGUserImplAbort.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGUserImplAbort.java @@ -6,11 +6,11 @@ import meerkat.protobuf.DKGMessages; /** * Created by Tzlil on 3/14/2016. */ -public class DKGUserImplAbort extends DistributedKeyGenerationUser { +public class DKGUserImplAbort extends User { final int abortStage; int stage; - public DKGUserImplAbort(DistributedKeyGeneration dkg, Channel channel, int abortStage) { + public DKGUserImplAbort(Protocol dkg, Channel channel, int abortStage) { super(dkg, channel); this.abortStage = abortStage;// 1 - 2 this.stage = 1; diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharingTest.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharingTest.java index f7d3a39..f106584 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharingTest.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharingTest.java @@ -1,6 +1,6 @@ package meerkat.crypto.concrete.secret_shring.feldman_verifiable; -import meerkat.crypto.concrete.secret_shring.ShamirSecretSharing.Polynomial; +import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; import org.factcenter.qilin.primitives.Group; import org.factcenter.qilin.primitives.concrete.Zpstar; import org.junit.Before; diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/AddTest.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/AddTest.java index 2c78b03..326b0bf 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/AddTest.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/AddTest.java @@ -1,6 +1,6 @@ package meerkat.crypto.concrete.secret_shring.shamir.PolynomialTests; -import Arithmetics.Z; import Utils.GenerateRandomPolynomial; +import Utils.Z; import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; import org.junit.Before; import org.junit.Test; diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/MulByConstTest.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/MulByConstTest.java index 30e2082..36c42ad 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/MulByConstTest.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/MulByConstTest.java @@ -1,7 +1,7 @@ package meerkat.crypto.concrete.secret_shring.shamir.PolynomialTests; -import Arithmetics.Z; import Utils.GenerateRandomPolynomial; +import Utils.Z; import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; import org.junit.Before; import org.junit.Test; diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/MulTest.java b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/MulTest.java index 8af27ab..1a83f50 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/MulTest.java +++ b/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/MulTest.java @@ -1,7 +1,7 @@ package meerkat.crypto.concrete.secret_shring.shamir.PolynomialTests; -import Arithmetics.Z; import Utils.GenerateRandomPolynomial; +import Utils.Z; import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; import org.junit.Before; import org.junit.Test; diff --git a/meerkat-common/src/main/proto/meerkat/DKGMessages.proto b/meerkat-common/src/main/proto/meerkat/DKGMessages.proto index 81072e9..046f586 100644 --- a/meerkat-common/src/main/proto/meerkat/DKGMessages.proto +++ b/meerkat-common/src/main/proto/meerkat/DKGMessages.proto @@ -6,7 +6,7 @@ option java_package = "meerkat.protobuf"; message Mail{ enum Type { - SECRET = 0; + SHARE = 0; COMMITMENT = 1; COMPLAINT = 2; DONE = 3; @@ -23,17 +23,17 @@ message Mail{ bytes message = 5; } -message SecretMessage { +message ShareMessage { int32 i = 1; int32 j = 2; - bytes secret = 3; + bytes share = 3; } -message DoubleSecretMessage{ +message DoubleShareMessage{ int32 i = 1; int32 j = 2; - bytes secret = 3; - bytes secretT = 4; + bytes share = 3; + bytes shareT = 4; } message CommitmentMessage{ From d0951f8644a46247bbc49b1935ecd9078a0776bc Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Fri, 8 Apr 2016 21:48:08 +0300 Subject: [PATCH 36/49] stop --- .../bulletinboard/BulletinClientWorker.java | 4 +- .../SimpleBulletinBoardClient.java | 4 +- .../ThreadedBulletinBoardClient.java | 4 +- .../sqlserver/BulletinBoardSQLServer.java | 4 +- .../GenericBulletinBoardServerTest.java | 2 +- .../java/meerkat/crypto/KeyGeneration.java | 11 - .../java/meerkat/crypto/SecretSharing.java | 7 - .../meerkat/crypto/utilitis/Arithmetic.java | 18 - .../communication}/MailHandler.java | 31 +- .../communication}/MessageHandler.java | 28 +- .../gjkr_secure_protocol/MailHandler.java | 23 +- .../gjkr_secure_protocol/Party.java | 6 +- .../gjkr_secure_protocol/Protocol.java | 8 +- .../gjkr_secure_protocol/User.java | 71 +- .../joint_feldman_protocol/MailHandler.java | 11 +- .../joint_feldman_protocol/Party.java | 10 +- .../joint_feldman_protocol/Protocol.java | 14 +- .../joint_feldman_protocol/User.java | 146 +++- .../VerifiableSecretSharing.java | 22 +- .../shamir/LagrangePolynomial.java | 4 +- .../secret_shring/shamir/Polynomial.java | 6 +- .../secret_shring/shamir/SecretSharing.java | 18 +- .../utilitis/Arithmetic.java | 38 ++ .../utilitis/Channel.java | 16 +- .../utilitis/concrete/Fp.java | 9 +- .../SDKGMaliciousUserImpl.java | 5 +- .../gjkr_secure_protocol/SDKGTest.java | 53 +- .../SDKGUserImplAbort.java | 4 +- .../DKGMaliciousUser.java | 4 +- .../joint_feldman_protocol/DKGTest.java | 53 +- .../DKGUserImplAbort.java | 4 +- .../VerifiableSecretSharingTest.java | 4 +- .../shamir/PolynomialTests/AddTest.java | 8 +- .../PolynomialTests/InterpolationTest.java | 12 +- .../PolynomialTests/MulByConstTest.java | 8 +- .../shamir/PolynomialTests/MulTest.java | 8 +- .../shamir/SecretSharingTest.java | 6 +- .../utilitis}/BigIntegerByteEncoder.java | 2 +- .../utilitis}/ChannelImpl.java | 11 +- .../utilitis}/GenerateRandomPolynomial.java | 61 +- .../utilitis}/GenerateRandomPrime.java | 62 +- .../utilitis}/Z.java | 4 +- .../Digest.java | 76 +-- .../DigitalSignature.java | 192 +++--- .../Encryption.java | 80 +-- .../concrete/ECDSADeterministicSignature.java | 268 ++++---- .../concrete/ECDSASignature.java | 644 +++++++++--------- .../concrete/ECElGamalEncryption.java | 270 ++++---- .../concrete/GlobalCryptoSetup.java | 86 +-- .../concrete/SHA256Digest.java | 192 +++--- .../mixnet/Mix2ZeroKnowledgeProver.java | 36 +- .../mixnet/Mix2ZeroKnowledgeVerifier.java | 46 +- .../mixnet/Mixer.java | 22 +- .../mixnet/Trustee.java | 14 +- .../mixnet/Verifier.java | 14 +- .../ECDSADeterministicSignatureTest.java | 99 ++- .../concrete/ECDSASignatureTest.java | 439 ++++++------ .../concrete/ECElGamalEncryptionTest.java | 244 +++---- .../concrete/ECElGamalUtils.java | 178 ++--- 59 files changed, 1974 insertions(+), 1750 deletions(-) delete mode 100644 destributed-key-generation/src/main/java/meerkat/crypto/KeyGeneration.java delete mode 100644 destributed-key-generation/src/main/java/meerkat/crypto/SecretSharing.java delete mode 100644 destributed-key-generation/src/main/java/meerkat/crypto/utilitis/Arithmetic.java rename destributed-key-generation/src/main/java/meerkat/{crypto/concrete/distributed_key_generation/Communication => destributed_key_generation/concrete/distributed_key_generation/communication}/MailHandler.java (69%) rename destributed-key-generation/src/main/java/meerkat/{crypto/concrete/distributed_key_generation/Communication => destributed_key_generation/concrete/distributed_key_generation/communication}/MessageHandler.java (51%) rename destributed-key-generation/src/main/java/meerkat/{crypto => destributed_key_generation}/concrete/distributed_key_generation/gjkr_secure_protocol/MailHandler.java (74%) rename destributed-key-generation/src/main/java/meerkat/{crypto => destributed_key_generation}/concrete/distributed_key_generation/gjkr_secure_protocol/Party.java (68%) rename destributed-key-generation/src/main/java/meerkat/{crypto => destributed_key_generation}/concrete/distributed_key_generation/gjkr_secure_protocol/Protocol.java (92%) rename destributed-key-generation/src/main/java/meerkat/{crypto => destributed_key_generation}/concrete/distributed_key_generation/gjkr_secure_protocol/User.java (84%) rename destributed-key-generation/src/main/java/meerkat/{crypto => destributed_key_generation}/concrete/distributed_key_generation/joint_feldman_protocol/MailHandler.java (75%) rename destributed-key-generation/src/main/java/meerkat/{crypto => destributed_key_generation}/concrete/distributed_key_generation/joint_feldman_protocol/Party.java (70%) rename destributed-key-generation/src/main/java/meerkat/{crypto => destributed_key_generation}/concrete/distributed_key_generation/joint_feldman_protocol/Protocol.java (94%) rename destributed-key-generation/src/main/java/meerkat/{crypto => destributed_key_generation}/concrete/distributed_key_generation/joint_feldman_protocol/User.java (80%) rename destributed-key-generation/src/main/java/meerkat/{crypto => destributed_key_generation}/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharing.java (81%) rename destributed-key-generation/src/main/java/meerkat/{crypto => destributed_key_generation}/concrete/secret_shring/shamir/LagrangePolynomial.java (94%) rename destributed-key-generation/src/main/java/meerkat/{crypto => destributed_key_generation}/concrete/secret_shring/shamir/Polynomial.java (95%) rename destributed-key-generation/src/main/java/meerkat/{crypto => destributed_key_generation}/concrete/secret_shring/shamir/SecretSharing.java (88%) create mode 100644 destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis/Arithmetic.java rename destributed-key-generation/src/main/java/meerkat/{crypto => destributed_key_generation}/utilitis/Channel.java (60%) rename destributed-key-generation/src/main/java/meerkat/{crypto => destributed_key_generation}/utilitis/concrete/Fp.java (74%) rename destributed-key-generation/src/test/java/meerkat/{crypto => destributed_key_generation}/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGMaliciousUserImpl.java (89%) rename destributed-key-generation/src/test/java/meerkat/{crypto => destributed_key_generation}/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGTest.java (80%) rename destributed-key-generation/src/test/java/meerkat/{crypto => destributed_key_generation}/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGUserImplAbort.java (89%) rename destributed-key-generation/src/test/java/meerkat/{crypto => destributed_key_generation}/concrete/distributed_key_generation/joint_feldman_protocol/DKGMaliciousUser.java (92%) rename destributed-key-generation/src/test/java/meerkat/{crypto => destributed_key_generation}/concrete/distributed_key_generation/joint_feldman_protocol/DKGTest.java (78%) rename destributed-key-generation/src/test/java/meerkat/{crypto => destributed_key_generation}/concrete/distributed_key_generation/joint_feldman_protocol/DKGUserImplAbort.java (88%) rename destributed-key-generation/src/test/java/meerkat/{crypto => destributed_key_generation}/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharingTest.java (93%) rename destributed-key-generation/src/test/java/meerkat/{crypto => destributed_key_generation}/concrete/secret_shring/shamir/PolynomialTests/AddTest.java (78%) rename destributed-key-generation/src/test/java/meerkat/{crypto => destributed_key_generation}/concrete/secret_shring/shamir/PolynomialTests/InterpolationTest.java (80%) rename destributed-key-generation/src/test/java/meerkat/{crypto => destributed_key_generation}/concrete/secret_shring/shamir/PolynomialTests/MulByConstTest.java (77%) rename destributed-key-generation/src/test/java/meerkat/{crypto => destributed_key_generation}/concrete/secret_shring/shamir/PolynomialTests/MulTest.java (78%) rename destributed-key-generation/src/test/java/meerkat/{crypto => destributed_key_generation}/concrete/secret_shring/shamir/SecretSharingTest.java (90%) rename destributed-key-generation/src/test/java/{Utils => meerkat/destributed_key_generation/utilitis}/BigIntegerByteEncoder.java (91%) rename destributed-key-generation/src/test/java/{Utils => meerkat/destributed_key_generation/utilitis}/ChannelImpl.java (96%) rename destributed-key-generation/src/test/java/{Utils => meerkat/destributed_key_generation/utilitis}/GenerateRandomPolynomial.java (82%) rename destributed-key-generation/src/test/java/{Utils => meerkat/destributed_key_generation/utilitis}/GenerateRandomPrime.java (92%) rename destributed-key-generation/src/test/java/{Utils => meerkat/destributed_key_generation/utilitis}/Z.java (90%) rename meerkat-common/src/main/java/meerkat/{crypto => destributed_key_generation}/Digest.java (92%) rename meerkat-common/src/main/java/meerkat/{crypto => destributed_key_generation}/DigitalSignature.java (96%) rename meerkat-common/src/main/java/meerkat/{crypto => destributed_key_generation}/Encryption.java (94%) rename meerkat-common/src/main/java/meerkat/{crypto => destributed_key_generation}/concrete/ECDSADeterministicSignature.java (96%) rename meerkat-common/src/main/java/meerkat/{crypto => destributed_key_generation}/concrete/ECDSASignature.java (96%) rename meerkat-common/src/main/java/meerkat/{crypto => destributed_key_generation}/concrete/ECElGamalEncryption.java (96%) rename meerkat-common/src/main/java/meerkat/{crypto => destributed_key_generation}/concrete/GlobalCryptoSetup.java (92%) rename meerkat-common/src/main/java/meerkat/{crypto => destributed_key_generation}/concrete/SHA256Digest.java (93%) rename meerkat-common/src/main/java/meerkat/{crypto => destributed_key_generation}/mixnet/Mix2ZeroKnowledgeProver.java (93%) rename meerkat-common/src/main/java/meerkat/{crypto => destributed_key_generation}/mixnet/Mix2ZeroKnowledgeVerifier.java (91%) rename meerkat-common/src/main/java/meerkat/{crypto => destributed_key_generation}/mixnet/Mixer.java (79%) rename meerkat-common/src/main/java/meerkat/{crypto => destributed_key_generation}/mixnet/Trustee.java (56%) rename meerkat-common/src/main/java/meerkat/{crypto => destributed_key_generation}/mixnet/Verifier.java (56%) rename meerkat-common/src/test/java/meerkat/{crypto => destributed_key_generation}/concrete/ECDSADeterministicSignatureTest.java (91%) rename meerkat-common/src/test/java/meerkat/{crypto => destributed_key_generation}/concrete/ECDSASignatureTest.java (96%) rename meerkat-common/src/test/java/meerkat/{crypto => destributed_key_generation}/concrete/ECElGamalEncryptionTest.java (96%) rename meerkat-common/src/test/java/meerkat/{crypto => destributed_key_generation}/concrete/ECElGamalUtils.java (96%) diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java index 1d0d741..b519eb4 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java @@ -2,8 +2,8 @@ package meerkat.bulletinboard; import com.google.protobuf.Message; import meerkat.comm.CommunicationException; -import meerkat.crypto.Digest; -import meerkat.crypto.concrete.SHA256Digest; +import meerkat.destributed_key_generation.Digest; +import meerkat.destributed_key_generation.concrete.SHA256Digest; import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.rest.Constants; import meerkat.rest.ProtobufMessageBodyReader; diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java index 9d3f24a..b12649e 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java @@ -2,8 +2,8 @@ package meerkat.bulletinboard; import com.google.protobuf.ByteString; import meerkat.comm.CommunicationException; -import meerkat.crypto.Digest; -import meerkat.crypto.concrete.SHA256Digest; +import meerkat.destributed_key_generation.Digest; +import meerkat.destributed_key_generation.concrete.SHA256Digest; import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.protobuf.Voting; import meerkat.protobuf.Voting.BulletinBoardClientParams; diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java index 81513f8..d3957cf 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java @@ -6,8 +6,8 @@ import meerkat.bulletinboard.callbacks.GetRedundancyFutureCallback; import meerkat.bulletinboard.callbacks.PostMessageFutureCallback; import meerkat.bulletinboard.callbacks.ReadMessagesFutureCallback; import meerkat.comm.CommunicationException; -import meerkat.crypto.Digest; -import meerkat.crypto.concrete.SHA256Digest; +import meerkat.destributed_key_generation.Digest; +import meerkat.destributed_key_generation.concrete.SHA256Digest; import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.protobuf.Voting; diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java index 8402e55..2c0a8d7 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java @@ -13,8 +13,8 @@ import meerkat.comm.CommunicationException; import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.protobuf.Crypto.Signature; import meerkat.protobuf.Crypto.SignatureVerificationKey; -import meerkat.crypto.Digest; -import meerkat.crypto.concrete.SHA256Digest; +import meerkat.destributed_key_generation.Digest; +import meerkat.destributed_key_generation.concrete.SHA256Digest; import javax.sql.DataSource; diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java index 1c5e3c5..fa4c60b 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java @@ -18,7 +18,7 @@ import java.util.Random; import com.google.protobuf.ByteString; import meerkat.comm.CommunicationException; -import meerkat.crypto.concrete.ECDSASignature; +import meerkat.destributed_key_generation.concrete.ECDSASignature; import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; import meerkat.protobuf.BulletinBoardAPI.FilterType; import meerkat.protobuf.BulletinBoardAPI.MessageFilter; diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/KeyGeneration.java b/destributed-key-generation/src/main/java/meerkat/crypto/KeyGeneration.java deleted file mode 100644 index a6db4f9..0000000 --- a/destributed-key-generation/src/main/java/meerkat/crypto/KeyGeneration.java +++ /dev/null @@ -1,11 +0,0 @@ -package meerkat.crypto; - -import java.util.Random; - -/** - * Created by Tzlil on 4/8/2016. - */ -public interface KeyGeneration { - - T generateKey(Random random); -} diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/SecretSharing.java b/destributed-key-generation/src/main/java/meerkat/crypto/SecretSharing.java deleted file mode 100644 index e7619b6..0000000 --- a/destributed-key-generation/src/main/java/meerkat/crypto/SecretSharing.java +++ /dev/null @@ -1,7 +0,0 @@ -package meerkat.crypto; - -/** - * Created by Tzlil on 4/8/2016. - */ -public class SecretSharing { -} diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/utilitis/Arithmetic.java b/destributed-key-generation/src/main/java/meerkat/crypto/utilitis/Arithmetic.java deleted file mode 100644 index 618210a..0000000 --- a/destributed-key-generation/src/main/java/meerkat/crypto/utilitis/Arithmetic.java +++ /dev/null @@ -1,18 +0,0 @@ -package meerkat.crypto.utilitis; - -/** - * Created by Tzlil on 3/17/2016. - */ -public interface Arithmetic { - /** - * - * @param a - * @param b - * @return - */ - T add(T a, T b); - T sub(T a, T b); - T mul(T a, T b); - T div(T a, T b); - -} diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/MailHandler.java b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/communication/MailHandler.java similarity index 69% rename from destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/MailHandler.java rename to destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/communication/MailHandler.java index c646a5a..cc3b08b 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/MailHandler.java +++ b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/communication/MailHandler.java @@ -1,36 +1,59 @@ -package meerkat.crypto.concrete.distributed_key_generation.communication; +package meerkat.destributed_key_generation.concrete.distributed_key_generation.communication; import com.google.protobuf.Message; -import meerkat.crypto.utilitis.Channel; +import meerkat.destributed_key_generation.utilitis.Channel; import meerkat.protobuf.DKGMessages; /** * Created by Tzlil on 2/14/2016. + * + * an implementation of ReceiverCallback */ public abstract class MailHandler implements Channel.ReceiverCallback{ + /** + * fixed value for broadcasting + */ public static final int BROADCAST = 0; + + /** + * message handler + */ private MessageHandler messageHandler; + /** + * constructor + * @param messageHandler + */ public MailHandler(MessageHandler messageHandler){ this.messageHandler = messageHandler; } + /** + * extract message from mail + * @param mail + * @return + */ public abstract Message extractMessage(DKGMessages.Mail mail); + /** + * is this mail was received by broadcast channel + * @param mail + * @return mail user destination == BROADCAST + */ public boolean isBroadcast(DKGMessages.Mail mail){ return mail.getDestination() == BROADCAST; } + @Override public void receiveMail(DKGMessages.Mail mail){ - Message message = extractMessage(mail); if (message == null) return; switch (mail.getType()) { case SHARE: - messageHandler.handleSecretMessage(mail.getSender(), isBroadcast(mail),message); + messageHandler.handleShareMessage(mail.getSender(), isBroadcast(mail),message); break; case COMMITMENT: messageHandler.handleCommitmentMessage(mail.getSender(), isBroadcast(mail),message); diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/MessageHandler.java b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/communication/MessageHandler.java similarity index 51% rename from destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/MessageHandler.java rename to destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/communication/MessageHandler.java index a58cbcc..0fa7a46 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/Communication/MessageHandler.java +++ b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/communication/MessageHandler.java @@ -1,15 +1,39 @@ -package meerkat.crypto.concrete.distributed_key_generation.communication; +package meerkat.destributed_key_generation.concrete.distributed_key_generation.communication; import com.google.protobuf.Message; /** * Created by Tzlil on 2/14/2016. + * an interface for handling received messages */ public interface MessageHandler { - void handleSecretMessage(int sender, boolean isBroadcast, Message message); + /** + * handle share message + */ + void handleShareMessage(int sender, boolean isBroadcast, Message message); + + /** + * handle commitment message + */ void handleCommitmentMessage(int sender, boolean isBroadcast, Message message); + + /** + * handle complaint message + */ void handleComplaintMessage(int sender, boolean isBroadcast, Message message); + + /** + * handle done message + */ void handleDoneMessage(int sender, boolean isBroadcast, Message message); + + /** + * handle answer message + */ void handleAnswerMessage(int sender, boolean isBroadcast, Message message); + + /** + * handle abort message + */ void handleAbortMessage(int sender, boolean isBroadcast, Message message); } diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/MailHandler.java b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/MailHandler.java similarity index 74% rename from destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/MailHandler.java rename to destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/MailHandler.java index c35fe6c..5f3ee3b 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/MailHandler.java +++ b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/MailHandler.java @@ -1,17 +1,26 @@ -package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol; +package meerkat.destributed_key_generation.concrete.distributed_key_generation.gjkr_secure_protocol; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; -import meerkat.crypto.concrete.distributed_key_generation.communication.MessageHandler; +import meerkat.destributed_key_generation.concrete.distributed_key_generation.communication.MessageHandler; import meerkat.protobuf.DKGMessages; /** * Created by Tzlil on 2/29/2016. + * an extension of MailHandler matching gjkr protocl */ -public class MailHandler extends meerkat.crypto.concrete.distributed_key_generation.communication.MailHandler { +public class MailHandler extends meerkat.destributed_key_generation.concrete.distributed_key_generation.communication.MailHandler { + /** + * flag that indicants whether the + * current run achieved stage 4 of the protocol or not + */ private boolean isStage4; + /** + * constructor + * @param messageHandler + */ public MailHandler(MessageHandler messageHandler) { super(messageHandler); this.isStage4 = false; @@ -52,10 +61,10 @@ public class MailHandler extends meerkat.crypto.concrete.distributed_key_generat } } - public boolean isStage4() { - return isStage4; - } - + /** + * setter + * @param stage4 + */ public void setStage4(boolean stage4) { isStage4 = stage4; } diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Party.java b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/Party.java similarity index 68% rename from destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Party.java rename to destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/Party.java index c0ee63a..d950beb 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Party.java +++ b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/Party.java @@ -1,6 +1,6 @@ -package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol; +package meerkat.destributed_key_generation.concrete.distributed_key_generation.gjkr_secure_protocol; -import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; +import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; import java.util.ArrayList; import java.util.HashSet; @@ -13,7 +13,7 @@ import java.util.Set; * contains all relevant information on specific party during * the run of the safe protocol */ -public class Party extends meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.Party { +public class Party extends meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol.Party { public Polynomial.Point shareT; public boolean ysDoneFlag; public ArrayList verifiableValues; diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Protocol.java b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/Protocol.java similarity index 92% rename from destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Protocol.java rename to destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/Protocol.java index 13ff0e6..a0512d6 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/Protocol.java +++ b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/Protocol.java @@ -1,7 +1,7 @@ -package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol; +package meerkat.destributed_key_generation.concrete.distributed_key_generation.gjkr_secure_protocol; -import meerkat.crypto.concrete.secret_shring.feldman_verifiable.VerifiableSecretSharing; -import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; +import meerkat.destributed_key_generation.concrete.secret_shring.feldman_verifiable.VerifiableSecretSharing; +import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; import com.google.protobuf.ByteString; import meerkat.protobuf.DKGMessages; import org.factcenter.qilin.primitives.Group; @@ -17,7 +17,7 @@ import java.util.Set; * TODO: comments * TODO: put Channel (ChannelImpl) in constructor */ -public class Protocol extends meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.Protocol { +public class Protocol extends meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol.Protocol { private VerifiableSecretSharing maskingShares; private final T h; diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/User.java b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/User.java similarity index 84% rename from destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/User.java rename to destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/User.java index f976ff9..86ed127 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/User.java +++ b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/User.java @@ -1,10 +1,10 @@ -package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol; +package meerkat.destributed_key_generation.concrete.distributed_key_generation.gjkr_secure_protocol; -import meerkat.crypto.utilitis.Arithmetic; -import meerkat.crypto.utilitis.concrete.Fp; -import meerkat.crypto.utilitis.Channel; -import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; -import meerkat.crypto.concrete.secret_shring.shamir.SecretSharing; +import meerkat.destributed_key_generation.utilitis.Arithmetic; +import meerkat.destributed_key_generation.utilitis.concrete.Fp; +import meerkat.destributed_key_generation.utilitis.Channel; +import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; +import meerkat.destributed_key_generation.concrete.secret_shring.shamir.SecretSharing; import com.google.protobuf.Message; import meerkat.protobuf.DKGMessages; @@ -13,25 +13,48 @@ import java.util.ArrayList; /** * Created by Tzlil on 3/16/2016. + * + * implementation of gjkr protocol user. + * + * this protocol extends joint feldman protocol by splitting the protocol to commitment stage (stages 1,2,3) + * and reviling stage (stage 4). + * + * as in joint feldman, each party in QUAL has his own share of the generated random key. + * this key can be recover by any subset of QUAL of size at least t + 1. */ -public class User extends meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.User { +public class User extends meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol.User { + /** + * All parties participating in key generation. + * parties[id-1] has my info. + */ protected Party[] parties; - protected final Protocol sdkg; - private Arithmetic arithmetic; - private boolean isStage4; + /** + * gjkr secure protocol object + */ + protected final Protocol sdkg; + + /** + * message handler + */ + private MessageHandler messageHandler; + + /** + * constructor + * @param sdkg gjkr protocol object + * @param channel channel object + */ public User(Protocol sdkg, Channel channel) { super(sdkg, channel); this.sdkg = sdkg; this.parties = sdkg.getParties(); - this.arithmetic = new Fp(sdkg.getQ()); - this.isStage4 = false; } @Override protected void registerReceiverCallback(){ - this.mailHandler = new MailHandler(new MessageHandler()); + this.messageHandler = new MessageHandler(); + this.mailHandler = new MailHandler(messageHandler); this.channel.registerReceiverCallback(mailHandler); } /** @@ -84,7 +107,7 @@ public class User extends meerkat.crypto.concrete.distributed_key_generation. try { parties[i - 1].wait(); } catch (InterruptedException e) { - //do nothing + if (stop) return; } } } @@ -102,7 +125,7 @@ public class User extends meerkat.crypto.concrete.distributed_key_generation. try { parties[i - 1].wait(); } catch (InterruptedException e) { - //do nothing + if (stop) return; } } } @@ -122,13 +145,13 @@ public class User extends meerkat.crypto.concrete.distributed_key_generation. try { parties[i - 1].wait(); } catch (InterruptedException e) { - //do nothing + if (stop) return; } } } } } - + Arithmetic arithmetic = new Fp(sdkg.getQ()); // restore necessary information for (int i = 0; i < n ; i++) { if(parties[i].recoverSharesSet.isEmpty()){ @@ -152,10 +175,10 @@ public class User extends meerkat.crypto.concrete.distributed_key_generation. } /** - * notifies mail handler that stage 4 was started + * notifies mail handler and message handler that stage 4 was started */ protected void setStage4(){ - this.isStage4 = true; + this.messageHandler.isStage4 = true; ((MailHandler)this.mailHandler).setStage4(true); } @@ -163,11 +186,13 @@ public class User extends meerkat.crypto.concrete.distributed_key_generation. protected void stage4() { setStage4(); resolveQualifyingPublicKey(); + if (stop) return; super.stage4(); } - private class MessageHandler extends meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.User.MessageHandler { + private class MessageHandler extends meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol.User.MessageHandler { + boolean isStage4; /** * as in super, with extension to double secret message */ @@ -184,7 +209,7 @@ public class User extends meerkat.crypto.concrete.distributed_key_generation. * as in super, with extension to double secret message */ @Override - public void handleSecretMessage(int sender, boolean isBroadcast, Message message) { + public void handleShareMessage(int sender, boolean isBroadcast, Message message) { DKGMessages.DoubleShareMessage doubleSecretMessage = (DKGMessages.DoubleShareMessage)message; if (isValidSecretMessage(sender,isBroadcast,doubleSecretMessage)) { int i = doubleSecretMessage.getI(); @@ -234,10 +259,10 @@ public class User extends meerkat.crypto.concrete.distributed_key_generation. synchronized (parties[i - 1]) { if (!isStage4) { 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; + parties[i - 1].complaints[j - 1] = meerkat.destributed_key_generation.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; + parties[i - 1].complaints[j - 1] = meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol.Protocol.ComplaintState.Disqualified; } if (j == id) { parties[i - 1].share = secret; diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/MailHandler.java b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/MailHandler.java similarity index 75% rename from destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/MailHandler.java rename to destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/MailHandler.java index 8f971fc..a2d82b2 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/MailHandler.java +++ b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/MailHandler.java @@ -1,15 +1,20 @@ -package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol; +package meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; -import meerkat.crypto.concrete.distributed_key_generation.communication.MessageHandler; +import meerkat.destributed_key_generation.concrete.distributed_key_generation.communication.MessageHandler; import meerkat.protobuf.DKGMessages; /** * Created by Tzlil on 2/29/2016. + * an extension of MailHandler matching joint feldman protocol */ -public class MailHandler extends meerkat.crypto.concrete.distributed_key_generation.communication.MailHandler { +public class MailHandler extends meerkat.destributed_key_generation.concrete.distributed_key_generation.communication.MailHandler { + /** + * constructor + * @param messageHandler + */ public MailHandler(MessageHandler messageHandler) { super(messageHandler); } diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Party.java b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/Party.java similarity index 70% rename from destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Party.java rename to destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/Party.java index c30ca97..90ee829 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Party.java +++ b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/Party.java @@ -1,6 +1,6 @@ -package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol; +package meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol; -import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; +import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; import java.util.ArrayList; import java.util.Arrays; @@ -19,6 +19,12 @@ public class Party { public Protocol.ComplaintState[] complaints; public boolean aborted; + /** + * + * @param id party identifier - 1 <= id <= n + * @param n number of parties in current run protocol + * @param t protocol's threshold + */ public Party(int id, int n, int t) { this.id = id; this.share = null; diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Protocol.java b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/Protocol.java similarity index 94% rename from destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Protocol.java rename to destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/Protocol.java index 79a3f9c..e3cddbd 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/Protocol.java +++ b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/Protocol.java @@ -1,8 +1,8 @@ -package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol; +package meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol; -import meerkat.crypto.utilitis.Channel; -import meerkat.crypto.concrete.secret_shring.feldman_verifiable.VerifiableSecretSharing; -import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; +import meerkat.destributed_key_generation.utilitis.Channel; +import meerkat.destributed_key_generation.concrete.secret_shring.feldman_verifiable.VerifiableSecretSharing; +import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; import com.google.protobuf.ByteString; import meerkat.protobuf.DKGMessages; import org.factcenter.qilin.primitives.Group; @@ -57,7 +57,6 @@ public class Protocol extends VerifiableSecretSharing { */ protected Channel channel; - /** * Encode/Decode group elements */ @@ -76,9 +75,10 @@ public class Protocol extends VerifiableSecretSharing { * @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. + * @param encoder Encode/Decode group elements (of type T) to/from byte array */ public Protocol(int t, int n, BigInteger zi, Random random, BigInteger q, T g - , Group group, int id, ByteEncoder byteEncoder) { + , Group group, int id, ByteEncoder encoder) { super(t, n, zi, random, q, g,group); this.id = id; this.parties = new Party[n]; @@ -86,7 +86,7 @@ public class Protocol extends VerifiableSecretSharing { this.parties[i - 1] = new Party(i,n,t); } this.parties[id - 1].share = getShare(id); - this.encoder = byteEncoder; + this.encoder = encoder; } /** diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/User.java b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/User.java similarity index 80% rename from destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/User.java rename to destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/User.java index 8475aef..84f5bb8 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/User.java +++ b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/User.java @@ -1,7 +1,7 @@ -package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol; +package meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol; -import meerkat.crypto.utilitis.Channel; -import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; +import meerkat.destributed_key_generation.utilitis.Channel; +import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; import com.google.protobuf.ByteString; import com.google.protobuf.Message; import meerkat.protobuf.DKGMessages; @@ -13,27 +13,91 @@ import java.util.Set; /** * Created by Tzlil on 3/14/2016. - * TODO: Comments - * TODO: Replace polling with monitors/wait/notify (remember synchronization) + * + * implementation of joint feldman protocol user. + * + * according to the protocol, each user run feldman verifiable secret sharing + * as a dealer. + * + * by the end of run(), each party in QUAL has his own share of the generated random key. + * this key can be recover by any subset of QUAL of size at least t + 1. */ public class User implements Runnable{ + /** + * joint feldman protocol object + */ protected final Protocol dkg; + /** + * 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. + */ protected final T g; + + /** + * cyclic group contains g. + */ protected final Group group; - protected final int n; - protected final int t; + + /** + * user id + */ protected final int id; - protected meerkat.crypto.concrete.distributed_key_generation.communication.MailHandler mailHandler; - protected final Channel channel; + /** + * threshold + */ + protected final int t; + + /** + * number of shares + */ + protected final int n; + + /** + * mail handler registered to channel as ReceiverCallback + */ + protected meerkat.destributed_key_generation.concrete.distributed_key_generation.communication.MailHandler mailHandler; + + /** + * channel object + */ + protected final Channel channel; // + + /** + * All parties participating in key generation. + * parties[id-1] has my info. + */ protected final Party[] parties; - protected Set QUAL; // set of all non-disqualified parties - protected Polynomial.Point share; // final share of the secrete - protected ArrayList commitments; // public verification values - protected T y; // final public value + /** + * set of all non-disqualified parties + */ + protected Set QUAL; + + /** + * my own share of the generated random key. + */ + protected Polynomial.Point share; + + /** + * public verification values + */ + protected ArrayList commitments; + + /** + * public value, + * y = g ^ key + */ + protected T y; + + /** + * constructor + * @param dkg joint feldman protocol object + * @param channel channel object + */ public User(Protocol dkg, Channel channel) { this.dkg = dkg; @@ -74,20 +138,23 @@ public class User implements Runnable{ } + /** + * wait for all shares and commitments will arrive from other parties + */ protected void waitUntilStageOneCompleted(){ - // all parties send their share or aborted + // wait for parties' share for (int i = 0 ; i < n ; i++){ synchronized (parties[i]) { while (parties[i].share == null && !parties[i].aborted) { try { parties[i].wait(); } catch (InterruptedException e) { - //do nothing + if (stop) return; } } } } - // all parties broadcast their commitments or aborted + // wait for parties' commitments for (int i = 0 ; i < n ; i++){ for (int k = 0 ; k <= t ; k++) { synchronized (parties[i]) { @@ -95,7 +162,7 @@ public class User implements Runnable{ try { parties[i].wait(); } catch (InterruptedException e) { - //do nothing + if (stop) return; } } } @@ -117,15 +184,17 @@ public class User implements Runnable{ } + /** + * wait until all other parties done complaining by receiving done message + */ protected void waitUntilStageTwoCompleted(){ - // 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) { - //do nothing + if (stop) return; } } } @@ -150,7 +219,7 @@ public class User implements Runnable{ try { parties[i].wait(); } catch (InterruptedException e) { - //do nothing + if (stop) return; } } } @@ -173,18 +242,38 @@ public class User implements Runnable{ @Override public void run() { + this.runThread = Thread.currentThread(); stage1(); waitUntilStageOneCompleted(); + if (stop) return; stage2(); waitUntilStageTwoCompleted(); + if (stop) return; stage3(); + if (stop) return; stage4(); } + /** + * current thread in the main loop + */ + protected Thread runThread; + + /** + * flag indicates if there was request to stop the current run of the protocol + */ + protected boolean stop = false; + /** * Request the current run loop to exit gracefully */ public void stop() { + try { + stop = true; + runThread.interrupt(); + }catch (Exception e){ + //do nothing + } } @@ -260,12 +349,19 @@ public class User implements Runnable{ return QUAL; } + /** + * getter + * @return channel + */ + public Channel getChannel() { + return channel; + } - public class MessageHandler implements meerkat.crypto.concrete.distributed_key_generation.communication.MessageHandler{ + /** + * an implementation of MessageHandler + */ + public class MessageHandler implements meerkat.destributed_key_generation.concrete.distributed_key_generation.communication.MessageHandler{ - public MessageHandler(){ - - } /** * commitment message is valid if: * 1. it was received in broadcast chanel @@ -314,7 +410,7 @@ public class User implements Runnable{ * saves the secret */ @Override - public void handleSecretMessage(int sender, boolean isBroadcast, Message message) { + public void handleShareMessage(int sender, boolean isBroadcast, Message message) { DKGMessages.ShareMessage secretMessage = (DKGMessages.ShareMessage) message; if(isValidSecretMessage(sender,isBroadcast,secretMessage)) { int i = secretMessage.getI(); diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharing.java b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharing.java similarity index 81% rename from destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharing.java rename to destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharing.java index 6f3638b..1544564 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharing.java +++ b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharing.java @@ -1,7 +1,7 @@ -package meerkat.crypto.concrete.secret_shring.feldman_verifiable; +package meerkat.destributed_key_generation.concrete.secret_shring.feldman_verifiable; -import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; -import meerkat.crypto.concrete.secret_shring.shamir.SecretSharing; +import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; +import meerkat.destributed_key_generation.concrete.secret_shring.shamir.SecretSharing; import org.factcenter.qilin.primitives.Group; import java.util.ArrayList; @@ -17,12 +17,22 @@ import java.util.Random; * */ public class VerifiableSecretSharing extends SecretSharing { + /** + * cyclic group contains g. + */ protected final Group group; - protected final T g; // public generator of group + /** + * 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. + */ + protected final T g; + /** + * commitments to polynomial coefficients. + * commitments[k] = g ^ coefficients[k] (group operation) + */ protected final ArrayList commitmentsArrayList; - - /** * constructor * @param q a large prime. diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/shamir/LagrangePolynomial.java b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/LagrangePolynomial.java similarity index 94% rename from destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/shamir/LagrangePolynomial.java rename to destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/LagrangePolynomial.java index 20aee54..0da8f48 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/shamir/LagrangePolynomial.java +++ b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/LagrangePolynomial.java @@ -1,6 +1,6 @@ -package meerkat.crypto.concrete.secret_shring.shamir; +package meerkat.destributed_key_generation.concrete.secret_shring.shamir; -import meerkat.crypto.utilitis.Arithmetic; +import meerkat.destributed_key_generation.utilitis.Arithmetic; import java.math.BigInteger; diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/shamir/Polynomial.java b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/Polynomial.java similarity index 95% rename from destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/shamir/Polynomial.java rename to destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/Polynomial.java index c2d77ff..e0e2361 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/shamir/Polynomial.java +++ b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/Polynomial.java @@ -1,6 +1,6 @@ -package meerkat.crypto.concrete.secret_shring.shamir; +package meerkat.destributed_key_generation.concrete.secret_shring.shamir; -import meerkat.crypto.utilitis.Arithmetic; +import meerkat.destributed_key_generation.utilitis.Arithmetic; import java.math.BigInteger; import java.util.Arrays; @@ -100,7 +100,7 @@ public class Polynomial implements Comparable { /** * @param other - * @return new meerkat.crypto.concrete.secret_shring.shamir.Polynomial of degree max(this degree,other degree) s.t for all x + * @return new meerkat.destributed_key_generation.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) */ public Polynomial add(Polynomial other){ diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/shamir/SecretSharing.java b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/SecretSharing.java similarity index 88% rename from destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/shamir/SecretSharing.java rename to destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/SecretSharing.java index 87853d5..d5e73aa 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/concrete/secret_shring/shamir/SecretSharing.java +++ b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/SecretSharing.java @@ -1,7 +1,7 @@ -package meerkat.crypto.concrete.secret_shring.shamir; +package meerkat.destributed_key_generation.concrete.secret_shring.shamir; -import meerkat.crypto.utilitis.Arithmetic; -import meerkat.crypto.utilitis.concrete.Fp; +import meerkat.destributed_key_generation.utilitis.Arithmetic; +import meerkat.destributed_key_generation.utilitis.concrete.Fp; import java.math.BigInteger; import java.util.Random; @@ -11,9 +11,21 @@ import java.util.Random; * an implementation of Shamire's secret sharing scheme */ public class SecretSharing{ + /** + * threshold + */ protected final int t; + /** + * number of shares + */ protected final int n; + /** + * a large prime + */ protected final BigInteger q; + /** + * random polynomial of degree s.t polynomial.evaluate(0) = secret + */ protected final Polynomial polynomial; /** diff --git a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis/Arithmetic.java b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis/Arithmetic.java new file mode 100644 index 0000000..2aab0cf --- /dev/null +++ b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis/Arithmetic.java @@ -0,0 +1,38 @@ +package meerkat.destributed_key_generation.utilitis; + +/** + * Created by Tzlil on 3/17/2016. + * defines the properties of the traditional operations : add,sub,mul,div + * between two objects of type T + */ +public interface Arithmetic { + /** + * addition + * @param a + * @param b + * @return a + b + */ + T add(T a, T b); + /** + * subtraction + * @param a + * @param b + * @return a - b + */ + T sub(T a, T b); + /** + * multiplication + * @param a + * @param b + * @return a * b + */ + T mul(T a, T b); + /** + * division + * @param a + * @param b + * @return a / b + */ + T div(T a, T b); + +} diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/utilitis/Channel.java b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis/Channel.java similarity index 60% rename from destributed-key-generation/src/main/java/meerkat/crypto/utilitis/Channel.java rename to destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis/Channel.java index 2be0bf4..294ffaf 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/utilitis/Channel.java +++ b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis/Channel.java @@ -1,10 +1,10 @@ -package meerkat.crypto.utilitis; +package meerkat.destributed_key_generation.utilitis; import com.google.protobuf.Message; import meerkat.protobuf.DKGMessages; /** - * A generic commmunication channel that supports point-to-point and broadcast operation + * A generic communication channel that supports point-to-point and broadcast operation */ public interface Channel { @@ -12,8 +12,20 @@ public interface Channel { public void receiveMail(DKGMessages.Mail mail); } + /** + * sends a private message + * @param destUser destination user's identifier + * @param type message type + * @param msg message + */ public void sendMessage(int destUser, DKGMessages.Mail.Type type, Message msg); + + /** + * broadcasts a message to all parties (including the sender) + * @param type message type + * @param msg message + */ public void broadcastMessage(DKGMessages.Mail.Type type, Message msg); /** diff --git a/destributed-key-generation/src/main/java/meerkat/crypto/utilitis/concrete/Fp.java b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis/concrete/Fp.java similarity index 74% rename from destributed-key-generation/src/main/java/meerkat/crypto/utilitis/concrete/Fp.java rename to destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis/concrete/Fp.java index e538293..d7d03bc 100644 --- a/destributed-key-generation/src/main/java/meerkat/crypto/utilitis/concrete/Fp.java +++ b/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis/concrete/Fp.java @@ -1,17 +1,22 @@ -package meerkat.crypto.utilitis.concrete; +package meerkat.destributed_key_generation.utilitis.concrete; -import meerkat.crypto.utilitis.Arithmetic; +import meerkat.destributed_key_generation.utilitis.Arithmetic; import org.factcenter.qilin.primitives.concrete.Zpstar; import java.math.BigInteger; /** * Created by Tzlil on 3/17/2016. + * an implementation of Arithmetic over prime fields: integers modulo p */ public class Fp implements Arithmetic { public final BigInteger p; private final Zpstar zp; + /** + * constructor + * @param p prime + */ public Fp(BigInteger p) { this.p = p; this.zp = new Zpstar(p); diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGMaliciousUserImpl.java b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGMaliciousUserImpl.java similarity index 89% rename from destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGMaliciousUserImpl.java rename to destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGMaliciousUserImpl.java index 34bd672..7afb60e 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGMaliciousUserImpl.java +++ b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGMaliciousUserImpl.java @@ -1,7 +1,6 @@ -package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol; +package meerkat.destributed_key_generation.concrete.distributed_key_generation.gjkr_secure_protocol; -import meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol.*; -import meerkat.crypto.utilitis.Channel; +import meerkat.destributed_key_generation.utilitis.Channel; import java.math.BigInteger; import java.util.Random; diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGTest.java b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGTest.java similarity index 80% rename from destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGTest.java rename to destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGTest.java index 5fc7e04..d296810 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGTest.java +++ b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGTest.java @@ -1,15 +1,15 @@ -package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol; +package meerkat.destributed_key_generation.concrete.distributed_key_generation.gjkr_secure_protocol; -import Utils.ChannelImpl; -import meerkat.crypto.utilitis.Arithmetic; -import meerkat.crypto.utilitis.concrete.Fp; -import meerkat.crypto.utilitis.Channel; -import meerkat.crypto.concrete.secret_shring.feldman_verifiable.VerifiableSecretSharing; -import meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.DKGMaliciousUser; -import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; -import meerkat.crypto.concrete.secret_shring.shamir.SecretSharing; -import Utils.BigIntegerByteEncoder; -import Utils.GenerateRandomPrime; +import meerkat.destributed_key_generation.utilitis.ChannelImpl; +import meerkat.destributed_key_generation.utilitis.Arithmetic; +import meerkat.destributed_key_generation.utilitis.concrete.Fp; +import meerkat.destributed_key_generation.utilitis.Channel; +import meerkat.destributed_key_generation.concrete.secret_shring.feldman_verifiable.VerifiableSecretSharing; +import meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol.DKGMaliciousUser; +import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; +import meerkat.destributed_key_generation.concrete.secret_shring.shamir.SecretSharing; +import meerkat.destributed_key_generation.utilitis.BigIntegerByteEncoder; +import meerkat.destributed_key_generation.utilitis.GenerateRandomPrime; import org.factcenter.qilin.primitives.Group; import org.factcenter.qilin.primitives.concrete.Zpstar; import org.factcenter.qilin.util.ByteEncoder; @@ -27,25 +27,16 @@ import java.util.Set; */ public class SDKGTest { - int tests = 1; + int tests = 10; BigInteger p = GenerateRandomPrime.SafePrime100Bits; BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); Group group = new Zpstar(p); Arithmetic arithmetic = new Fp(q); int t = 9; int n = 20; - Testable[] testables; - @Before - public void settings(){ - 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]; + public void oneTest(Testable testable) throws Exception { for (int i = 0; i < testable.threads.length ; i++){ testable.threads[i].start(); } @@ -83,13 +74,23 @@ public class SDKGTest { assert (calculatedSecret.equals(testable.secret)); } - @Test - public void test() throws Exception { - for (int i = 0; i < tests; i++){ - oneTest(i); + public void stopReceivers(Testable testable){ + ChannelImpl channel; + for (int i = 0 ; i < testable.sdkgs.length ; i++){ + channel = (ChannelImpl)testable.sdkgs[i].getChannel(); + channel.stop(); } } + @Test + public void test() throws Exception { + Testable testable; + for (int i = 0; i < tests; i++) { + testable = new Testable(new Random()); + oneTest(testable); + stopReceivers(testable); + } + } class Testable{ Set valids; Set QUAL; diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGUserImplAbort.java b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGUserImplAbort.java similarity index 89% rename from destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGUserImplAbort.java rename to destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGUserImplAbort.java index 0a7bb12..e91d87e 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGUserImplAbort.java +++ b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGUserImplAbort.java @@ -1,6 +1,6 @@ -package meerkat.crypto.concrete.distributed_key_generation.gjkr_secure_protocol; +package meerkat.destributed_key_generation.concrete.distributed_key_generation.gjkr_secure_protocol; -import meerkat.crypto.utilitis.Channel; +import meerkat.destributed_key_generation.utilitis.Channel; import meerkat.protobuf.DKGMessages; /** diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGMaliciousUser.java b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/DKGMaliciousUser.java similarity index 92% rename from destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGMaliciousUser.java rename to destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/DKGMaliciousUser.java index f20076d..672de21 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGMaliciousUser.java +++ b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/DKGMaliciousUser.java @@ -1,6 +1,6 @@ -package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol; +package meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol; -import meerkat.crypto.utilitis.Channel; +import meerkat.destributed_key_generation.utilitis.Channel; import java.math.BigInteger; import java.util.*; diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGTest.java b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/DKGTest.java similarity index 78% rename from destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGTest.java rename to destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/DKGTest.java index 19693f5..cac11df 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGTest.java +++ b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/DKGTest.java @@ -1,15 +1,14 @@ -package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol; +package meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol; -import Utils.ChannelImpl; -import meerkat.crypto.utilitis.Arithmetic; -import meerkat.crypto.utilitis.concrete.Fp; -import meerkat.crypto.utilitis.Channel; -import meerkat.crypto.concrete.secret_shring.feldman_verifiable.VerifiableSecretSharing; -import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; -import meerkat.crypto.concrete.secret_shring.shamir.SecretSharing; -import Utils.BigIntegerByteEncoder; -import Utils.GenerateRandomPrime; -import meerkat.protobuf.Crypto; +import meerkat.destributed_key_generation.utilitis.ChannelImpl; +import meerkat.destributed_key_generation.utilitis.Arithmetic; +import meerkat.destributed_key_generation.utilitis.concrete.Fp; +import meerkat.destributed_key_generation.utilitis.Channel; +import meerkat.destributed_key_generation.concrete.secret_shring.feldman_verifiable.VerifiableSecretSharing; +import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; +import meerkat.destributed_key_generation.concrete.secret_shring.shamir.SecretSharing; +import meerkat.destributed_key_generation.utilitis.BigIntegerByteEncoder; +import meerkat.destributed_key_generation.utilitis.GenerateRandomPrime; import org.factcenter.qilin.primitives.Group; import org.factcenter.qilin.primitives.concrete.Zpstar; import org.factcenter.qilin.util.ByteEncoder; @@ -27,7 +26,7 @@ import java.util.Set; */ public class DKGTest { - int tests = 1; + int tests = 10; BigInteger p = GenerateRandomPrime.SafePrime100Bits; BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); Group group = new Zpstar(p); @@ -35,18 +34,7 @@ public class DKGTest { int t = 9; int n = 20; - Testable[] testables; - - @Before - public void settings(){ - 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]; + public void oneTest(Testable testable) throws Exception { for (int i = 0; i < testable.threads.length ; i++){ testable.threads[i].start(); } @@ -84,10 +72,21 @@ public class DKGTest { assert (calculatedSecret.equals(testable.secret)); } + public void stopReceivers(Testable testable){ + ChannelImpl channel; + for (int i = 0 ; i < testable.dkgs.length ; i++){ + channel = (ChannelImpl)testable.dkgs[i].getChannel(); + channel.stop(); + } + } + @Test public void test() throws Exception { + Testable testable; for (int i = 0; i < tests; i++){ - oneTest(i); + testable = new Testable(new Random()); + oneTest(testable); + stopReceivers(testable); } } @@ -117,13 +116,13 @@ public class DKGTest { BigInteger s; Protocol dkg; this.secret = BigInteger.ZERO; - Channel channel; + ChannelImpl channel; ByteEncoder byteEncoder = new BigIntegerByteEncoder(); while (!ids.isEmpty()) { id = ids.remove(random.nextInt(ids.size())); channel = new ChannelImpl(id,n); s = randomIntModQ(random); - dkg = new meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol.Protocol(t, n, s, random, q, g, group, id,byteEncoder); + dkg = new meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol.Protocol(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)){ diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGUserImplAbort.java b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/DKGUserImplAbort.java similarity index 88% rename from destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGUserImplAbort.java rename to destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/DKGUserImplAbort.java index 2e42299..dc0f419 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/distributed_key_generation/joint_feldman_protocol/DKGUserImplAbort.java +++ b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/DKGUserImplAbort.java @@ -1,6 +1,6 @@ -package meerkat.crypto.concrete.distributed_key_generation.joint_feldman_protocol; +package meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol; -import meerkat.crypto.utilitis.Channel; +import meerkat.destributed_key_generation.utilitis.Channel; import meerkat.protobuf.DKGMessages; /** diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharingTest.java b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharingTest.java similarity index 93% rename from destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharingTest.java rename to destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharingTest.java index f106584..1f2d15e 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharingTest.java +++ b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharingTest.java @@ -1,6 +1,6 @@ -package meerkat.crypto.concrete.secret_shring.feldman_verifiable; +package meerkat.destributed_key_generation.concrete.secret_shring.feldman_verifiable; -import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; +import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; import org.factcenter.qilin.primitives.Group; import org.factcenter.qilin.primitives.concrete.Zpstar; import org.junit.Before; diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/AddTest.java b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/AddTest.java similarity index 78% rename from destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/AddTest.java rename to destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/AddTest.java index 326b0bf..24c5e9f 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/AddTest.java +++ b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/AddTest.java @@ -1,7 +1,7 @@ -package meerkat.crypto.concrete.secret_shring.shamir.PolynomialTests; -import Utils.GenerateRandomPolynomial; -import Utils.Z; -import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; +package meerkat.destributed_key_generation.concrete.secret_shring.shamir.PolynomialTests; +import meerkat.destributed_key_generation.utilitis.GenerateRandomPolynomial; +import meerkat.destributed_key_generation.utilitis.Z; +import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; import org.junit.Before; import org.junit.Test; diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/InterpolationTest.java b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/InterpolationTest.java similarity index 80% rename from destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/InterpolationTest.java rename to destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/InterpolationTest.java index 0183d3f..9462cec 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/InterpolationTest.java +++ b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/InterpolationTest.java @@ -1,10 +1,10 @@ -package meerkat.crypto.concrete.secret_shring.shamir.PolynomialTests; +package meerkat.destributed_key_generation.concrete.secret_shring.shamir.PolynomialTests; -import meerkat.crypto.utilitis.Arithmetic; -import meerkat.crypto.utilitis.concrete.Fp; -import Utils.GenerateRandomPolynomial; -import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; -import Utils.GenerateRandomPrime; +import meerkat.destributed_key_generation.utilitis.Arithmetic; +import meerkat.destributed_key_generation.utilitis.concrete.Fp; +import meerkat.destributed_key_generation.utilitis.GenerateRandomPolynomial; +import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; +import meerkat.destributed_key_generation.utilitis.GenerateRandomPrime; import org.junit.Before; import org.junit.Test; diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/MulByConstTest.java b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/MulByConstTest.java similarity index 77% rename from destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/MulByConstTest.java rename to destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/MulByConstTest.java index 36c42ad..f63fc2b 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/MulByConstTest.java +++ b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/MulByConstTest.java @@ -1,8 +1,8 @@ -package meerkat.crypto.concrete.secret_shring.shamir.PolynomialTests; +package meerkat.destributed_key_generation.concrete.secret_shring.shamir.PolynomialTests; -import Utils.GenerateRandomPolynomial; -import Utils.Z; -import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; +import meerkat.destributed_key_generation.utilitis.GenerateRandomPolynomial; +import meerkat.destributed_key_generation.utilitis.Z; +import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; import org.junit.Before; import org.junit.Test; diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/MulTest.java b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/MulTest.java similarity index 78% rename from destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/MulTest.java rename to destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/MulTest.java index 1a83f50..e9caa66 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/PolynomialTests/MulTest.java +++ b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/MulTest.java @@ -1,8 +1,8 @@ -package meerkat.crypto.concrete.secret_shring.shamir.PolynomialTests; +package meerkat.destributed_key_generation.concrete.secret_shring.shamir.PolynomialTests; -import Utils.GenerateRandomPolynomial; -import Utils.Z; -import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; +import meerkat.destributed_key_generation.utilitis.GenerateRandomPolynomial; +import meerkat.destributed_key_generation.utilitis.Z; +import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; import org.junit.Before; import org.junit.Test; diff --git a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/SecretSharingTest.java b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/SecretSharingTest.java similarity index 90% rename from destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/SecretSharingTest.java rename to destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/SecretSharingTest.java index 0396916..cf1b8d3 100644 --- a/destributed-key-generation/src/test/java/meerkat/crypto/concrete/secret_shring/shamir/SecretSharingTest.java +++ b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/SecretSharingTest.java @@ -1,7 +1,7 @@ -package meerkat.crypto.concrete.secret_shring.shamir; +package meerkat.destributed_key_generation.concrete.secret_shring.shamir; -import meerkat.crypto.utilitis.concrete.Fp; -import Utils.GenerateRandomPrime; +import meerkat.destributed_key_generation.utilitis.concrete.Fp; +import meerkat.destributed_key_generation.utilitis.GenerateRandomPrime; import org.factcenter.qilin.primitives.CyclicGroup; import org.factcenter.qilin.primitives.concrete.Zn; import org.junit.Before; diff --git a/destributed-key-generation/src/test/java/Utils/BigIntegerByteEncoder.java b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/BigIntegerByteEncoder.java similarity index 91% rename from destributed-key-generation/src/test/java/Utils/BigIntegerByteEncoder.java rename to destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/BigIntegerByteEncoder.java index a0c7107..4548451 100644 --- a/destributed-key-generation/src/test/java/Utils/BigIntegerByteEncoder.java +++ b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/BigIntegerByteEncoder.java @@ -1,4 +1,4 @@ -package Utils; +package meerkat.destributed_key_generation.utilitis; import java.math.BigInteger; diff --git a/destributed-key-generation/src/test/java/Utils/ChannelImpl.java b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/ChannelImpl.java similarity index 96% rename from destributed-key-generation/src/test/java/Utils/ChannelImpl.java rename to destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/ChannelImpl.java index 31bf748..f6e09f1 100644 --- a/destributed-key-generation/src/test/java/Utils/ChannelImpl.java +++ b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/ChannelImpl.java @@ -1,7 +1,6 @@ -package Utils; +package meerkat.destributed_key_generation.utilitis; import com.google.protobuf.Message; -import meerkat.crypto.utilitis.Channel; import meerkat.protobuf.DKGMessages; import java.util.Queue; @@ -76,13 +75,17 @@ public class ChannelImpl implements Channel { } } - @Override - public void registerReceiverCallback(final ReceiverCallback callback) { + public void stop(){ try{ receiverThread.interrupt(); }catch (Exception e){ //do nothing } + } + + @Override + public void registerReceiverCallback(final ReceiverCallback callback) { + stop(); receiverThread = new Thread(new Runnable() { @Override public void run() { diff --git a/destributed-key-generation/src/test/java/Utils/GenerateRandomPolynomial.java b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/GenerateRandomPolynomial.java similarity index 82% rename from destributed-key-generation/src/test/java/Utils/GenerateRandomPolynomial.java rename to destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/GenerateRandomPolynomial.java index 4521fcd..4648598 100644 --- a/destributed-key-generation/src/test/java/Utils/GenerateRandomPolynomial.java +++ b/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/GenerateRandomPolynomial.java @@ -1,31 +1,30 @@ -package Utils; - -import meerkat.crypto.concrete.secret_shring.shamir.Polynomial; -import meerkat.crypto.utilitis.Arithmetic; -import meerkat.crypto.utilitis.concrete.Fp; - -import java.math.BigInteger; -import java.util.Random; - -/** - * Created by Tzlil on 1/27/2016. - */ -public class GenerateRandomPolynomial { - - public static Polynomial generateRandomPolynomial(int degree, int bits, Random random, Arithmetic arithmetic) { - BigInteger[] coefficients = new BigInteger[degree + 1]; - - for (int i = 0 ; i <= degree; i++ ){ - coefficients[i] = new BigInteger(bits,random); // sample from Zp [0,... q-1] - } - return new Polynomial(coefficients,arithmetic); - } - - public static Polynomial generateRandomPolynomial(int degree,int bits,Random random,BigInteger p) { - BigInteger[] coefficients = generateRandomPolynomial(degree,bits,random,new Fp(p)).getCoefficients(); - for (int i = 0; i arithmetic) { + BigInteger[] coefficients = new BigInteger[degree + 1]; + + for (int i = 0 ; i <= degree; i++ ){ + coefficients[i] = new BigInteger(bits,random); // sample from Zp [0,... q-1] + } + return new Polynomial(coefficients,arithmetic); + } + + public static Polynomial generateRandomPolynomial(int degree,int bits,Random random,BigInteger p) { + BigInteger[] coefficients = generateRandomPolynomial(degree,bits,random,new Fp(p)).getCoefficients(); + for (int i = 0; i loadedCertificates = new HashMap<>(); - - /** - * Signature currently loaded (will be used in calls to {@link #verify()}). - */ - ByteString loadedSignature = null; - - ByteString loadedSigningKeyId = null; - - /** - * The actual signing implementation. (used for both signing and verifying) - */ - java.security.Signature signer; - - /** - * The currently loaded signing key. - */ - PrivateKey loadedSigningKey; - - - /** - * Compute a fingerprint of a cert as a SHA256 hash. - * - * @param cert - * @return - */ - public ByteString computeCertificateFingerprint(Certificate cert) { - try { - certDigest.reset(); - byte[] data = cert.getEncoded(); - certDigest.update(data); - return ByteString.copyFrom(certDigest.digest()); - } catch (CertificateEncodingException e) { - // Shouldn't happen - logger.error("Certificate encoding error", e); - throw new RuntimeException("Certificate encoding error", e); - } - - } - - public ECDSASignature(java.security.Signature signer) { - this.signer = signer; - } - - public ECDSASignature() { - try { - this.signer = java.security.Signature.getInstance(DEFAULT_SIGNATURE_ALGORITHM); - } catch (NoSuchAlgorithmException e) { - // Should never happen - logger.error("Couldn't find implementation for " + DEFAULT_SIGNATURE_ALGORITHM + " signatures", e); - } - } - - @Override - public void loadVerificationCertificates(InputStream certStream) - throws CertificateException { - CertificateFactory certificateFactory = CertificateFactory.getInstance(CERTIFICATE_ENCODING_X509); - Collection certs = certificateFactory.generateCertificates(certStream); - for (Certificate cert : certs) { - // Just checking - if (!(cert instanceof X509Certificate)) { - logger.error("Certificate must be in X509 format; got {} instead!", cert.getClass().getCanonicalName()); - continue; - } - ByteString keyId = computeCertificateFingerprint(cert); - loadedCertificates.put(keyId, cert); - } - } - - @Override - public void clearVerificationCertificates() { - loadedCertificates.clear(); - } - - - /** - * Add the list of messages to the stream that is being verified/signed. - * Messages are prepended with their length in 32-bit big-endian format. - * - * @param msg - * @throws SignatureException - */ - @Override - public void updateContent(Message msg) throws SignatureException { - assert msg != null; - - lenBuf.clear(); - lenBuf.putInt(msg.getSerializedSize()); - lenBuf.flip(); - signer.update(lenBuf); - signer.update(msg.toByteString().asReadOnlyByteBuffer()); - } - - public void updateContent(InputStream in) throws IOException, SignatureException { - ByteString inStr = ByteString.readFrom(in); - signer.update(inStr.asReadOnlyByteBuffer()); - } - - @Override - public Signature sign() throws SignatureException { - Signature.Builder sig = Signature.newBuilder(); - sig.setType(Crypto.SignatureType.ECDSA); - sig.setData(ByteString.copyFrom(signer.sign())); - sig.setSignerId(loadedSigningKeyId); - return sig.build(); - } - - @Override - public void initVerify(Signature sig) - throws CertificateException, InvalidKeyException { - Certificate cert = loadedCertificates.get(sig.getSignerId()); - if (cert == null) { - logger.warn("No certificate loaded for ID {}!", sig.getSignerId()); - throw new CertificateException("No certificate loaded for " + sig.getSignerId()); - } - signer.initVerify(cert.getPublicKey()); - loadedSignature = sig.getData(); - loadedSigningKeyId = null; - } - - @Override - public boolean verify() { - try { - return signer.verify(loadedSignature.toByteArray()); - } catch (SignatureException e) { - // Happens only if signature is invalid! - logger.error("Signature exception", e); - return false; - } - } - - /** - * Utility method to more easily deal with simple password-protected files. - * - * @param password - * @return - */ - public CallbackHandler getFixedPasswordHandler(final char[] password) { - return new CallbackHandler() { - @Override - public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { - for (Callback callback : callbacks) { - if (callback instanceof PasswordCallback) { - PasswordCallback passwordCallback = (PasswordCallback) callback; - logger.debug("Requested password ({})", passwordCallback.getPrompt()); - passwordCallback.setPassword(password); - } - } - - } - }; - } - - /** - * Load a keystore from an input stream in PKCS12 format. - * - * @param keyStream - * @param password - * @return - * @throws IOException - * @throws CertificateException - * @throws KeyStoreException - * @throws NoSuchAlgorithmException - */ - public KeyStore.Builder getPKCS12KeyStoreBuilder(InputStream keyStream, char[] password) - throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException { - KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE); - keyStore.load(keyStream, password); - return KeyStore.Builder.newInstance(keyStore, new KeyStore.CallbackHandlerProtection(getFixedPasswordHandler(password))); - } - - - /** - * For now we only support PKCS12. - * TODO: Support for PKCS11 as well. - * - * @param keyStoreBuilder - * @throws IOException - * @throws CertificateException - * @throws UnrecoverableKeyException - */ - @Override - public void loadSigningCertificate(KeyStore.Builder keyStoreBuilder) - throws IOException, CertificateException, UnrecoverableKeyException { - try { - - KeyStore keyStore = keyStoreBuilder.getKeyStore(); - - // Iterate through all aliases until we find the first privatekey - Enumeration aliases = keyStore.aliases(); - while (aliases.hasMoreElements()) { - String alias = aliases.nextElement(); - logger.trace("Testing keystore entry {}", alias); - - - try { - Certificate cert = keyStore.getCertificate(alias); - logger.trace("keystore entry {}, has cert type {}", alias, cert.getClass()); - - Key key; - - try { - key = keyStore.getKey(alias, null); - } catch (UnrecoverableKeyException e) { - // This might be a keystore that doesn't support callback handlers - // (e.g., Java 8 PKCS12) - // Manually extract password using callback handler - char[] password = null; - KeyStore.ProtectionParameter prot = keyStoreBuilder.getProtectionParameter(alias); - - if (prot instanceof KeyStore.PasswordProtection) { - password = ((KeyStore.PasswordProtection) prot).getPassword(); - } else if (prot instanceof KeyStore.CallbackHandlerProtection) { - PasswordCallback callback = new PasswordCallback("Password for " + alias + "?", false); - Callback[] callbacks = { callback }; - try { - ((KeyStore.CallbackHandlerProtection) prot).getCallbackHandler().handle(callbacks); - password = callback.getPassword(); - } catch (UnsupportedCallbackException e1) { - logger.error("PasswordCallback fallback not supported!", e1); - throw new UnrecoverableKeyException("Couldn't use password callback to get key"); - } - } else { - logger.error("Unrecognized protection handler for keystore: {}", prot.getClass()); - throw new UnrecoverableKeyException("Unrecognized protection handler for keystore"); - } - key = keyStore.getKey(alias, password); - } - logger.trace("keystore entry {}, has key type {}", alias, key.getClass()); - if (key instanceof PrivateKey) { - loadedSigningKey = (PrivateKey) key; - loadedSigningKeyId = computeCertificateFingerprint(cert); - signer.initSign(loadedSigningKey); - logger.debug("Loaded signing key with ID {}", Hex.encode(loadedSigningKeyId)); - - return; - } else { - logger.info("Certificate {} in keystore does not have a private key", cert.toString()); - } - } catch(InvalidKeyException e) { - logger.info("Read invalid key", e); - } catch(UnrecoverableEntryException e) { - logger.info("Read unrecoverable entry", e); - } - } - - } catch (KeyStoreException e) { - logger.error("Keystore exception", e); - } catch (NoSuchAlgorithmException e) { - logger.error("NoSuchAlgorithmException exception", e); - throw new CertificateException(e); - } - logger.error("Didn't find valid private key entry in keystore"); - throw new UnrecoverableKeyException("Didn't find valid private key entry in keystore!"); - } - - @Override - public ByteString getSignerID() { - return loadedSigningKeyId; - } - - public void clearSigningKey() { - try { - // TODO: Check if this really clears the key from memory - if (loadedSigningKeyId != null) - signer.initSign(null); - loadedSigningKeyId = null; - loadedSigningKey = null; - // Start garbage collection? - } catch (InvalidKeyException e) { - // Do nothing - } - } - - -} +package meerkat.destributed_key_generation.concrete; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.security.*; +import java.security.cert.*; +import java.security.cert.Certificate; +import java.util.*; + +import com.google.protobuf.ByteString; +import meerkat.protobuf.Crypto; +import meerkat.util.Hex; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.protobuf.Message; + +import meerkat.destributed_key_generation.DigitalSignature; +import meerkat.protobuf.Crypto.Signature; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; + + +/** + * Sign and verify digital signatures. + * + * This class is not thread-safe (each thread should have its own instance). + */ +public class ECDSASignature extends GlobalCryptoSetup implements DigitalSignature { + final Logger logger = LoggerFactory.getLogger(getClass()); + + final public static String KEYSTORE_TYPE = "PKCS12"; + final public static String DEFAULT_SIGNATURE_ALGORITHM = "SHA256withECDSA"; + + SHA256Digest certDigest = new SHA256Digest(); + + /** + * Buffer used to hold length in for hash update + */ + ByteBuffer lenBuf = ByteBuffer.allocate(4); + + + Map loadedCertificates = new HashMap<>(); + + /** + * Signature currently loaded (will be used in calls to {@link #verify()}). + */ + ByteString loadedSignature = null; + + ByteString loadedSigningKeyId = null; + + /** + * The actual signing implementation. (used for both signing and verifying) + */ + java.security.Signature signer; + + /** + * The currently loaded signing key. + */ + PrivateKey loadedSigningKey; + + + /** + * Compute a fingerprint of a cert as a SHA256 hash. + * + * @param cert + * @return + */ + public ByteString computeCertificateFingerprint(Certificate cert) { + try { + certDigest.reset(); + byte[] data = cert.getEncoded(); + certDigest.update(data); + return ByteString.copyFrom(certDigest.digest()); + } catch (CertificateEncodingException e) { + // Shouldn't happen + logger.error("Certificate encoding error", e); + throw new RuntimeException("Certificate encoding error", e); + } + + } + + public ECDSASignature(java.security.Signature signer) { + this.signer = signer; + } + + public ECDSASignature() { + try { + this.signer = java.security.Signature.getInstance(DEFAULT_SIGNATURE_ALGORITHM); + } catch (NoSuchAlgorithmException e) { + // Should never happen + logger.error("Couldn't find implementation for " + DEFAULT_SIGNATURE_ALGORITHM + " signatures", e); + } + } + + @Override + public void loadVerificationCertificates(InputStream certStream) + throws CertificateException { + CertificateFactory certificateFactory = CertificateFactory.getInstance(CERTIFICATE_ENCODING_X509); + Collection certs = certificateFactory.generateCertificates(certStream); + for (Certificate cert : certs) { + // Just checking + if (!(cert instanceof X509Certificate)) { + logger.error("Certificate must be in X509 format; got {} instead!", cert.getClass().getCanonicalName()); + continue; + } + ByteString keyId = computeCertificateFingerprint(cert); + loadedCertificates.put(keyId, cert); + } + } + + @Override + public void clearVerificationCertificates() { + loadedCertificates.clear(); + } + + + /** + * Add the list of messages to the stream that is being verified/signed. + * Messages are prepended with their length in 32-bit big-endian format. + * + * @param msg + * @throws SignatureException + */ + @Override + public void updateContent(Message msg) throws SignatureException { + assert msg != null; + + lenBuf.clear(); + lenBuf.putInt(msg.getSerializedSize()); + lenBuf.flip(); + signer.update(lenBuf); + signer.update(msg.toByteString().asReadOnlyByteBuffer()); + } + + public void updateContent(InputStream in) throws IOException, SignatureException { + ByteString inStr = ByteString.readFrom(in); + signer.update(inStr.asReadOnlyByteBuffer()); + } + + @Override + public Signature sign() throws SignatureException { + Signature.Builder sig = Signature.newBuilder(); + sig.setType(Crypto.SignatureType.ECDSA); + sig.setData(ByteString.copyFrom(signer.sign())); + sig.setSignerId(loadedSigningKeyId); + return sig.build(); + } + + @Override + public void initVerify(Signature sig) + throws CertificateException, InvalidKeyException { + Certificate cert = loadedCertificates.get(sig.getSignerId()); + if (cert == null) { + logger.warn("No certificate loaded for ID {}!", sig.getSignerId()); + throw new CertificateException("No certificate loaded for " + sig.getSignerId()); + } + signer.initVerify(cert.getPublicKey()); + loadedSignature = sig.getData(); + loadedSigningKeyId = null; + } + + @Override + public boolean verify() { + try { + return signer.verify(loadedSignature.toByteArray()); + } catch (SignatureException e) { + // Happens only if signature is invalid! + logger.error("Signature exception", e); + return false; + } + } + + /** + * Utility method to more easily deal with simple password-protected files. + * + * @param password + * @return + */ + public CallbackHandler getFixedPasswordHandler(final char[] password) { + return new CallbackHandler() { + @Override + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { + for (Callback callback : callbacks) { + if (callback instanceof PasswordCallback) { + PasswordCallback passwordCallback = (PasswordCallback) callback; + logger.debug("Requested password ({})", passwordCallback.getPrompt()); + passwordCallback.setPassword(password); + } + } + + } + }; + } + + /** + * Load a keystore from an input stream in PKCS12 format. + * + * @param keyStream + * @param password + * @return + * @throws IOException + * @throws CertificateException + * @throws KeyStoreException + * @throws NoSuchAlgorithmException + */ + public KeyStore.Builder getPKCS12KeyStoreBuilder(InputStream keyStream, char[] password) + throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException { + KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE); + keyStore.load(keyStream, password); + return KeyStore.Builder.newInstance(keyStore, new KeyStore.CallbackHandlerProtection(getFixedPasswordHandler(password))); + } + + + /** + * For now we only support PKCS12. + * TODO: Support for PKCS11 as well. + * + * @param keyStoreBuilder + * @throws IOException + * @throws CertificateException + * @throws UnrecoverableKeyException + */ + @Override + public void loadSigningCertificate(KeyStore.Builder keyStoreBuilder) + throws IOException, CertificateException, UnrecoverableKeyException { + try { + + KeyStore keyStore = keyStoreBuilder.getKeyStore(); + + // Iterate through all aliases until we find the first privatekey + Enumeration aliases = keyStore.aliases(); + while (aliases.hasMoreElements()) { + String alias = aliases.nextElement(); + logger.trace("Testing keystore entry {}", alias); + + + try { + Certificate cert = keyStore.getCertificate(alias); + logger.trace("keystore entry {}, has cert type {}", alias, cert.getClass()); + + Key key; + + try { + key = keyStore.getKey(alias, null); + } catch (UnrecoverableKeyException e) { + // This might be a keystore that doesn't support callback handlers + // (e.g., Java 8 PKCS12) + // Manually extract password using callback handler + char[] password = null; + KeyStore.ProtectionParameter prot = keyStoreBuilder.getProtectionParameter(alias); + + if (prot instanceof KeyStore.PasswordProtection) { + password = ((KeyStore.PasswordProtection) prot).getPassword(); + } else if (prot instanceof KeyStore.CallbackHandlerProtection) { + PasswordCallback callback = new PasswordCallback("Password for " + alias + "?", false); + Callback[] callbacks = { callback }; + try { + ((KeyStore.CallbackHandlerProtection) prot).getCallbackHandler().handle(callbacks); + password = callback.getPassword(); + } catch (UnsupportedCallbackException e1) { + logger.error("PasswordCallback fallback not supported!", e1); + throw new UnrecoverableKeyException("Couldn't use password callback to get key"); + } + } else { + logger.error("Unrecognized protection handler for keystore: {}", prot.getClass()); + throw new UnrecoverableKeyException("Unrecognized protection handler for keystore"); + } + key = keyStore.getKey(alias, password); + } + logger.trace("keystore entry {}, has key type {}", alias, key.getClass()); + if (key instanceof PrivateKey) { + loadedSigningKey = (PrivateKey) key; + loadedSigningKeyId = computeCertificateFingerprint(cert); + signer.initSign(loadedSigningKey); + logger.debug("Loaded signing key with ID {}", Hex.encode(loadedSigningKeyId)); + + return; + } else { + logger.info("Certificate {} in keystore does not have a private key", cert.toString()); + } + } catch(InvalidKeyException e) { + logger.info("Read invalid key", e); + } catch(UnrecoverableEntryException e) { + logger.info("Read unrecoverable entry", e); + } + } + + } catch (KeyStoreException e) { + logger.error("Keystore exception", e); + } catch (NoSuchAlgorithmException e) { + logger.error("NoSuchAlgorithmException exception", e); + throw new CertificateException(e); + } + logger.error("Didn't find valid private key entry in keystore"); + throw new UnrecoverableKeyException("Didn't find valid private key entry in keystore!"); + } + + @Override + public ByteString getSignerID() { + return loadedSigningKeyId; + } + + public void clearSigningKey() { + try { + // TODO: Check if this really clears the key from memory + if (loadedSigningKeyId != null) + signer.initSign(null); + loadedSigningKeyId = null; + loadedSigningKey = null; + // Start garbage collection? + } catch (InvalidKeyException e) { + // Do nothing + } + } + + +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java b/meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/ECElGamalEncryption.java similarity index 96% rename from meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java rename to meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/ECElGamalEncryption.java index 05447c9..973b3c7 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java +++ b/meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/ECElGamalEncryption.java @@ -1,135 +1,135 @@ -package meerkat.crypto.concrete; - -import com.google.protobuf.ByteString; -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Message; -import meerkat.crypto.Encryption; -import meerkat.protobuf.ConcreteCrypto; -import meerkat.protobuf.Crypto; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.ECDomainParameters; -import org.bouncycastle.crypto.params.ECKeyParameters; -import org.bouncycastle.crypto.params.ECPublicKeyParameters; -import org.bouncycastle.crypto.util.PublicKeyFactory; -import org.bouncycastle.jce.spec.ECParameterSpec; -import org.bouncycastle.math.ec.ECCurve; -import org.bouncycastle.math.ec.ECPoint; -import org.bouncycastle.util.BigIntegers; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.factcenter.qilin.primitives.concrete.ECElGamal; -import org.factcenter.qilin.primitives.concrete.ECGroup; -import org.factcenter.qilin.util.PRGRandom; -import org.factcenter.qilin.util.Pair; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.math.BigInteger; -import java.security.spec.*; -import java.util.Random; - -/** - * Created by talm on 17/11/15. - */ -public class ECElGamalEncryption extends GlobalCryptoSetup implements Encryption { - final Logger logger = LoggerFactory.getLogger(getClass()); - - public final static String KEY_ALGORITHM = "ECDH"; - - /** - * The Qilin format El-Gamal public key - */ - ECElGamal.PK elGamalPK; - - ECCurve curve; - - ECGroup group; - - public ECGroup getGroup() { return group; } - - public ECElGamal.PK getElGamalPK() { - return elGamalPK; - } - - public void init(ConcreteCrypto.ElGamalPublicKey serializedPk) throws InvalidKeySpecException { - AsymmetricKeyParameter keyParam; - - try { - keyParam = PublicKeyFactory.createKey(serializedPk.getSubjectPublicKeyInfo().toByteArray()); - } catch (IOException e) { - // Shouldn't every happen - logger.error("Invalid Public Key Encoding", e); - throw new InvalidKeySpecException("Invalid Public Key Encoding", e); - } - - if (!(keyParam instanceof ECPublicKeyParameters)) { - logger.error("Public key is a {}, not a valid public EC Key!", keyParam.getClass()); - throw new InvalidKeySpecException("Not a valid EC public key!"); - } - - ECDomainParameters params = ((ECKeyParameters) keyParam).getParameters(); - ECParameterSpec ecParams = new ECParameterSpec(params.getCurve(), params.getG(), params.getN(), params.getH(), - params.getSeed()); - - curve = params.getCurve(); - group = new ECGroup(ecParams); - - elGamalPK = new ECElGamal.PK(group, ((ECPublicKeyParameters) keyParam).getQ()); - } - - - @Override - public Crypto.RerandomizableEncryptedMessage encrypt(Message plaintext, Crypto.EncryptionRandomness rnd) { - - // We write the message using writeDelimited to so the length gets prepended. - ByteArrayOutputStream out = new ByteArrayOutputStream(); - try { - plaintext.writeDelimitedTo(out); - } catch (IOException e) { - logger.error("Should never happen!", e); - throw new RuntimeException("Error in ByteArrayOutputStream!", e); - } - byte[] msg = out.toByteArray(); - ECPoint encodedMsg = group.injectiveEncode(msg, new PRGRandom(msg)); - - BigInteger rndInt = BigIntegers.fromUnsignedByteArray(rnd.getData().toByteArray()); - Pair cipherText = elGamalPK.encrypt(encodedMsg, rndInt); - ConcreteCrypto.ElGamalCiphertext encodedCipherText = ConcreteCrypto.ElGamalCiphertext.newBuilder() - .setC1(ByteString.copyFrom(cipherText.a.getEncoded(true))) - .setC2(ByteString.copyFrom(cipherText.b.getEncoded(true))) - .build(); - - return Crypto.RerandomizableEncryptedMessage.newBuilder() - .setData(encodedCipherText.toByteString()) - .build(); - } - - @Override - public Crypto.RerandomizableEncryptedMessage rerandomize(Crypto.RerandomizableEncryptedMessage msg, Crypto.EncryptionRandomness rnd) throws InvalidProtocolBufferException { - BigInteger rndInt = BigIntegers.fromUnsignedByteArray(rnd.getData().toByteArray()); - Pair randomizer = elGamalPK.encrypt(curve.getInfinity(), rndInt); - ConcreteCrypto.ElGamalCiphertext originalEncodedCipher= ConcreteCrypto.ElGamalCiphertext.parseFrom(msg.getData()); - - Pair originalCipher = new Pair( - curve.decodePoint(originalEncodedCipher.getC1().toByteArray()), - curve.decodePoint(originalEncodedCipher.getC2().toByteArray())); - Pair newCipher = elGamalPK.add(originalCipher, randomizer); - - return Crypto.RerandomizableEncryptedMessage.newBuilder() - .setData( - ConcreteCrypto.ElGamalCiphertext.newBuilder() - .setC1(ByteString.copyFrom(newCipher.a.getEncoded(true))) - .setC2(ByteString.copyFrom(newCipher.b.getEncoded(true))) - .build().toByteString() - ).build(); - } - - @Override - public Crypto.EncryptionRandomness generateRandomness(Random rand) { - BigInteger randomInt = new BigInteger(group.getCurveParams().getN().bitLength() - 1, rand); - Crypto.EncryptionRandomness retval = Crypto.EncryptionRandomness.newBuilder() - .setData(ByteString.copyFrom(BigIntegers.asUnsignedByteArray(randomInt))).build(); - - return retval; - } -} +package meerkat.destributed_key_generation.concrete; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; +import meerkat.destributed_key_generation.Encryption; +import meerkat.protobuf.ConcreteCrypto; +import meerkat.protobuf.Crypto; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.crypto.params.ECDomainParameters; +import org.bouncycastle.crypto.params.ECKeyParameters; +import org.bouncycastle.crypto.params.ECPublicKeyParameters; +import org.bouncycastle.crypto.util.PublicKeyFactory; +import org.bouncycastle.jce.spec.ECParameterSpec; +import org.bouncycastle.math.ec.ECCurve; +import org.bouncycastle.math.ec.ECPoint; +import org.bouncycastle.util.BigIntegers; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.factcenter.qilin.primitives.concrete.ECElGamal; +import org.factcenter.qilin.primitives.concrete.ECGroup; +import org.factcenter.qilin.util.PRGRandom; +import org.factcenter.qilin.util.Pair; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.security.spec.*; +import java.util.Random; + +/** + * Created by talm on 17/11/15. + */ +public class ECElGamalEncryption extends GlobalCryptoSetup implements Encryption { + final Logger logger = LoggerFactory.getLogger(getClass()); + + public final static String KEY_ALGORITHM = "ECDH"; + + /** + * The Qilin format El-Gamal public key + */ + ECElGamal.PK elGamalPK; + + ECCurve curve; + + ECGroup group; + + public ECGroup getGroup() { return group; } + + public ECElGamal.PK getElGamalPK() { + return elGamalPK; + } + + public void init(ConcreteCrypto.ElGamalPublicKey serializedPk) throws InvalidKeySpecException { + AsymmetricKeyParameter keyParam; + + try { + keyParam = PublicKeyFactory.createKey(serializedPk.getSubjectPublicKeyInfo().toByteArray()); + } catch (IOException e) { + // Shouldn't every happen + logger.error("Invalid Public Key Encoding", e); + throw new InvalidKeySpecException("Invalid Public Key Encoding", e); + } + + if (!(keyParam instanceof ECPublicKeyParameters)) { + logger.error("Public key is a {}, not a valid public EC Key!", keyParam.getClass()); + throw new InvalidKeySpecException("Not a valid EC public key!"); + } + + ECDomainParameters params = ((ECKeyParameters) keyParam).getParameters(); + ECParameterSpec ecParams = new ECParameterSpec(params.getCurve(), params.getG(), params.getN(), params.getH(), + params.getSeed()); + + curve = params.getCurve(); + group = new ECGroup(ecParams); + + elGamalPK = new ECElGamal.PK(group, ((ECPublicKeyParameters) keyParam).getQ()); + } + + + @Override + public Crypto.RerandomizableEncryptedMessage encrypt(Message plaintext, Crypto.EncryptionRandomness rnd) { + + // We write the message using writeDelimited to so the length gets prepended. + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + plaintext.writeDelimitedTo(out); + } catch (IOException e) { + logger.error("Should never happen!", e); + throw new RuntimeException("Error in ByteArrayOutputStream!", e); + } + byte[] msg = out.toByteArray(); + ECPoint encodedMsg = group.injectiveEncode(msg, new PRGRandom(msg)); + + BigInteger rndInt = BigIntegers.fromUnsignedByteArray(rnd.getData().toByteArray()); + Pair cipherText = elGamalPK.encrypt(encodedMsg, rndInt); + ConcreteCrypto.ElGamalCiphertext encodedCipherText = ConcreteCrypto.ElGamalCiphertext.newBuilder() + .setC1(ByteString.copyFrom(cipherText.a.getEncoded(true))) + .setC2(ByteString.copyFrom(cipherText.b.getEncoded(true))) + .build(); + + return Crypto.RerandomizableEncryptedMessage.newBuilder() + .setData(encodedCipherText.toByteString()) + .build(); + } + + @Override + public Crypto.RerandomizableEncryptedMessage rerandomize(Crypto.RerandomizableEncryptedMessage msg, Crypto.EncryptionRandomness rnd) throws InvalidProtocolBufferException { + BigInteger rndInt = BigIntegers.fromUnsignedByteArray(rnd.getData().toByteArray()); + Pair randomizer = elGamalPK.encrypt(curve.getInfinity(), rndInt); + ConcreteCrypto.ElGamalCiphertext originalEncodedCipher= ConcreteCrypto.ElGamalCiphertext.parseFrom(msg.getData()); + + Pair originalCipher = new Pair( + curve.decodePoint(originalEncodedCipher.getC1().toByteArray()), + curve.decodePoint(originalEncodedCipher.getC2().toByteArray())); + Pair newCipher = elGamalPK.add(originalCipher, randomizer); + + return Crypto.RerandomizableEncryptedMessage.newBuilder() + .setData( + ConcreteCrypto.ElGamalCiphertext.newBuilder() + .setC1(ByteString.copyFrom(newCipher.a.getEncoded(true))) + .setC2(ByteString.copyFrom(newCipher.b.getEncoded(true))) + .build().toByteString() + ).build(); + } + + @Override + public Crypto.EncryptionRandomness generateRandomness(Random rand) { + BigInteger randomInt = new BigInteger(group.getCurveParams().getN().bitLength() - 1, rand); + Crypto.EncryptionRandomness retval = Crypto.EncryptionRandomness.newBuilder() + .setData(ByteString.copyFrom(BigIntegers.asUnsignedByteArray(randomInt))).build(); + + return retval; + } +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/concrete/GlobalCryptoSetup.java b/meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/GlobalCryptoSetup.java similarity index 92% rename from meerkat-common/src/main/java/meerkat/crypto/concrete/GlobalCryptoSetup.java rename to meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/GlobalCryptoSetup.java index ca09689..7efc793 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/concrete/GlobalCryptoSetup.java +++ b/meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/GlobalCryptoSetup.java @@ -1,43 +1,43 @@ -package meerkat.crypto.concrete; - -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.security.Provider; -import java.security.Security; - -/** - * A class that performs required crypto setup - */ -public class GlobalCryptoSetup { - final static Logger logger = LoggerFactory.getLogger(GlobalCryptoSetup.class); - - static boolean loadedBouncyCastle = false; - static Provider bouncyCastleProvider; - - public static boolean hasSecp256k1Curve() { - // For now we just check if the java version is at least 8 - String[] version = System.getProperty("java.version").split("\\."); - int major = Integer.parseInt(version[0]); - int minor = Integer.parseInt(version[1]); - return ((major > 1) || ((major > 0) && (minor > 7))); - } - - public static Provider getBouncyCastleProvider() { doSetup(); return bouncyCastleProvider; } - - public static synchronized void doSetup() { - if (bouncyCastleProvider == null) { - bouncyCastleProvider = new BouncyCastleProvider(); - // Make bouncycastle our default provider if we're running on a JVM version < 8 - // (earlier version don't support the EC curve we use for signatures) - if (!hasSecp256k1Curve() && !loadedBouncyCastle) { - loadedBouncyCastle = true; - Security.insertProviderAt(bouncyCastleProvider, 1); - logger.info("Using BouncyCastle instead of native provider to support secp256k1 named curve"); - } - } - } - - public GlobalCryptoSetup() { doSetup(); } -} +package meerkat.destributed_key_generation.concrete; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.security.Provider; +import java.security.Security; + +/** + * A class that performs required destributed_key_generation setup + */ +public class GlobalCryptoSetup { + final static Logger logger = LoggerFactory.getLogger(GlobalCryptoSetup.class); + + static boolean loadedBouncyCastle = false; + static Provider bouncyCastleProvider; + + public static boolean hasSecp256k1Curve() { + // For now we just check if the java version is at least 8 + String[] version = System.getProperty("java.version").split("\\."); + int major = Integer.parseInt(version[0]); + int minor = Integer.parseInt(version[1]); + return ((major > 1) || ((major > 0) && (minor > 7))); + } + + public static Provider getBouncyCastleProvider() { doSetup(); return bouncyCastleProvider; } + + public static synchronized void doSetup() { + if (bouncyCastleProvider == null) { + bouncyCastleProvider = new BouncyCastleProvider(); + // Make bouncycastle our default provider if we're running on a JVM version < 8 + // (earlier version don't support the EC curve we use for signatures) + if (!hasSecp256k1Curve() && !loadedBouncyCastle) { + loadedBouncyCastle = true; + Security.insertProviderAt(bouncyCastleProvider, 1); + logger.info("Using BouncyCastle instead of native provider to support secp256k1 named curve"); + } + } + } + + public GlobalCryptoSetup() { doSetup(); } +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java b/meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/SHA256Digest.java similarity index 93% rename from meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java rename to meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/SHA256Digest.java index 784da82..6c2fce2 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java +++ b/meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/SHA256Digest.java @@ -1,96 +1,96 @@ -package meerkat.crypto.concrete; - -import com.google.protobuf.ByteString; -import com.google.protobuf.Message; -import meerkat.crypto.Digest; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.ByteBuffer; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -/** - * Created by talm on 11/9/15. - */ -public class SHA256Digest extends GlobalCryptoSetup implements Digest { - final Logger logger = LoggerFactory.getLogger(getClass()); - public static final String SHA256 = "SHA-256"; - - MessageDigest hash; - - /** - * Used to convert length to bytes in proper order. - */ - ByteBuffer lenBuf = ByteBuffer.allocate(4); - - /** - * Instantiate with a specified algorithm. - * @param algorithm - * @throws NoSuchAlgorithmException - */ - public SHA256Digest(String algorithm) throws NoSuchAlgorithmException { - hash = MessageDigest.getInstance(algorithm); - } - - /** - * Instantiate with the default (SHA-256) algorithm - */ - public SHA256Digest() { this(true); } - - - /**SHA - * Instantiate with the default (SHA-256) algorithm, - * or create an empty class (for cloning) - */ - private SHA256Digest(boolean initHash) { - if (initHash) { - try { - hash = MessageDigest.getInstance(SHA256); - } catch (NoSuchAlgorithmException e) { - // Should never happen! - logger.error("Couldn't find default {} algorhtm: {}", SHA256, e); - assert false; - } - } - } - - @Override - public byte[] digest() { - return hash.digest(); - } - - @Override - public void update(Message msg) { - - lenBuf.clear(); - lenBuf.putInt(msg.getSerializedSize()); - lenBuf.flip(); - hash.update(lenBuf); - hash.update(msg.toByteString().asReadOnlyByteBuffer()); - } - - final public void update(ByteString msg) { - hash.update(msg.asReadOnlyByteBuffer()); - } - - final public void update(byte[] msg) { - hash.update(msg); - } - - final public void update(ByteBuffer msg) { - hash.update(msg); - } - - @Override - public void reset() { - hash.reset(); - } - - @Override - public SHA256Digest clone() throws CloneNotSupportedException { - SHA256Digest copy = new SHA256Digest(false); - copy.hash = (MessageDigest) hash.clone(); - return copy; - } -} +package meerkat.destributed_key_generation.concrete; + +import com.google.protobuf.ByteString; +import com.google.protobuf.Message; +import meerkat.destributed_key_generation.Digest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.ByteBuffer; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * Created by talm on 11/9/15. + */ +public class SHA256Digest extends GlobalCryptoSetup implements Digest { + final Logger logger = LoggerFactory.getLogger(getClass()); + public static final String SHA256 = "SHA-256"; + + MessageDigest hash; + + /** + * Used to convert length to bytes in proper order. + */ + ByteBuffer lenBuf = ByteBuffer.allocate(4); + + /** + * Instantiate with a specified algorithm. + * @param algorithm + * @throws NoSuchAlgorithmException + */ + public SHA256Digest(String algorithm) throws NoSuchAlgorithmException { + hash = MessageDigest.getInstance(algorithm); + } + + /** + * Instantiate with the default (SHA-256) algorithm + */ + public SHA256Digest() { this(true); } + + + /**SHA + * Instantiate with the default (SHA-256) algorithm, + * or create an empty class (for cloning) + */ + private SHA256Digest(boolean initHash) { + if (initHash) { + try { + hash = MessageDigest.getInstance(SHA256); + } catch (NoSuchAlgorithmException e) { + // Should never happen! + logger.error("Couldn't find default {} algorhtm: {}", SHA256, e); + assert false; + } + } + } + + @Override + public byte[] digest() { + return hash.digest(); + } + + @Override + public void update(Message msg) { + + lenBuf.clear(); + lenBuf.putInt(msg.getSerializedSize()); + lenBuf.flip(); + hash.update(lenBuf); + hash.update(msg.toByteString().asReadOnlyByteBuffer()); + } + + final public void update(ByteString msg) { + hash.update(msg.asReadOnlyByteBuffer()); + } + + final public void update(byte[] msg) { + hash.update(msg); + } + + final public void update(ByteBuffer msg) { + hash.update(msg); + } + + @Override + public void reset() { + hash.reset(); + } + + @Override + public SHA256Digest clone() throws CloneNotSupportedException { + SHA256Digest copy = new SHA256Digest(false); + copy.hash = (MessageDigest) hash.clone(); + return copy; + } +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mix2ZeroKnowledgeProver.java b/meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Mix2ZeroKnowledgeProver.java similarity index 93% rename from meerkat-common/src/main/java/meerkat/crypto/mixnet/Mix2ZeroKnowledgeProver.java rename to meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Mix2ZeroKnowledgeProver.java index 438cb51..aa63aeb 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mix2ZeroKnowledgeProver.java +++ b/meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Mix2ZeroKnowledgeProver.java @@ -1,18 +1,18 @@ -package meerkat.crypto.mixnet; - -import meerkat.protobuf.Crypto; -import meerkat.protobuf.Mixing; - -/** - * Prove in zero knowledge that two ciphertexts are a mix of two original ciphertexts. - */ -public interface Mix2ZeroKnowledgeProver { - public Mixing.ZeroKnowledgeProof prove(Crypto.RerandomizableEncryptedMessage in1, - Crypto.RerandomizableEncryptedMessage in2, - Crypto.RerandomizableEncryptedMessage out1, - Crypto.RerandomizableEncryptedMessage out2, - boolean switched, - Crypto.EncryptionRandomness r1, - Crypto.EncryptionRandomness r2); - -} +package meerkat.destributed_key_generation.mixnet; + +import meerkat.protobuf.Crypto; +import meerkat.protobuf.Mixing; + +/** + * Prove in zero knowledge that two ciphertexts are a mix of two original ciphertexts. + */ +public interface Mix2ZeroKnowledgeProver { + public Mixing.ZeroKnowledgeProof prove(Crypto.RerandomizableEncryptedMessage in1, + Crypto.RerandomizableEncryptedMessage in2, + Crypto.RerandomizableEncryptedMessage out1, + Crypto.RerandomizableEncryptedMessage out2, + boolean switched, + Crypto.EncryptionRandomness r1, + Crypto.EncryptionRandomness r2); + +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mix2ZeroKnowledgeVerifier.java b/meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Mix2ZeroKnowledgeVerifier.java similarity index 91% rename from meerkat-common/src/main/java/meerkat/crypto/mixnet/Mix2ZeroKnowledgeVerifier.java rename to meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Mix2ZeroKnowledgeVerifier.java index 7fa845c..6faf0ca 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mix2ZeroKnowledgeVerifier.java +++ b/meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Mix2ZeroKnowledgeVerifier.java @@ -1,23 +1,23 @@ -package meerkat.crypto.mixnet; - -import meerkat.protobuf.Crypto; -import meerkat.protobuf.Mixing; - -/** - * Verify the two-ciphertext mix proof - */ -public interface Mix2ZeroKnowledgeVerifier { - /** - * Return true iff the proof is valid. - * @param in1 - * @param in2 - * @param out1 - * @param out2 - * @return - */ - boolean verify(Crypto.RerandomizableEncryptedMessage in1, - Crypto.RerandomizableEncryptedMessage in2, - Crypto.RerandomizableEncryptedMessage out1, - Crypto.RerandomizableEncryptedMessage out2, - Mixing.ZeroKnowledgeProof proof); -} +package meerkat.destributed_key_generation.mixnet; + +import meerkat.protobuf.Crypto; +import meerkat.protobuf.Mixing; + +/** + * Verify the two-ciphertext mix proof + */ +public interface Mix2ZeroKnowledgeVerifier { + /** + * Return true iff the proof is valid. + * @param in1 + * @param in2 + * @param out1 + * @param out2 + * @return + */ + boolean verify(Crypto.RerandomizableEncryptedMessage in1, + Crypto.RerandomizableEncryptedMessage in2, + Crypto.RerandomizableEncryptedMessage out1, + Crypto.RerandomizableEncryptedMessage out2, + Mixing.ZeroKnowledgeProof proof); +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mixer.java b/meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Mixer.java similarity index 79% rename from meerkat-common/src/main/java/meerkat/crypto/mixnet/Mixer.java rename to meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Mixer.java index 0be60c3..2b6d3e8 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mixer.java +++ b/meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Mixer.java @@ -1,11 +1,11 @@ -package meerkat.crypto.mixnet; - -import java.util.List; -import static meerkat.protobuf.Voting.*; - -/** - * Created by talm on 25/10/15. - */ -public interface Mixer { - public List mix(List ballots); -} +package meerkat.destributed_key_generation.mixnet; + +import java.util.List; +import static meerkat.protobuf.Voting.*; + +/** + * Created by talm on 25/10/15. + */ +public interface Mixer { + public List mix(List ballots); +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Trustee.java b/meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Trustee.java similarity index 56% rename from meerkat-common/src/main/java/meerkat/crypto/mixnet/Trustee.java rename to meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Trustee.java index a131a65..ded66c5 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Trustee.java +++ b/meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Trustee.java @@ -1,7 +1,7 @@ -package meerkat.crypto.mixnet; - -/** - * Created by talm on 25/10/15. - */ -public class Trustee { -} +package meerkat.destributed_key_generation.mixnet; + +/** + * Created by talm on 25/10/15. + */ +public class Trustee { +} diff --git a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Verifier.java b/meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Verifier.java similarity index 56% rename from meerkat-common/src/main/java/meerkat/crypto/mixnet/Verifier.java rename to meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Verifier.java index 809678e..18271ed 100644 --- a/meerkat-common/src/main/java/meerkat/crypto/mixnet/Verifier.java +++ b/meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Verifier.java @@ -1,7 +1,7 @@ -package meerkat.crypto.mixnet; - -/** - * Created by talm on 25/10/15. - */ -public class Verifier { -} +package meerkat.destributed_key_generation.mixnet; + +/** + * Created by talm on 25/10/15. + */ +public class Verifier { +} diff --git a/meerkat-common/src/test/java/meerkat/crypto/concrete/ECDSADeterministicSignatureTest.java b/meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECDSADeterministicSignatureTest.java similarity index 91% rename from meerkat-common/src/test/java/meerkat/crypto/concrete/ECDSADeterministicSignatureTest.java rename to meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECDSADeterministicSignatureTest.java index cefc1b2..86ae311 100644 --- a/meerkat-common/src/test/java/meerkat/crypto/concrete/ECDSADeterministicSignatureTest.java +++ b/meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECDSADeterministicSignatureTest.java @@ -1,50 +1,49 @@ -package meerkat.crypto.concrete; - -import com.google.protobuf.ByteString; -import com.google.protobuf.Message; - -import meerkat.crypto.concrete.ECDSASignature; -import meerkat.protobuf.Crypto; -import org.junit.Test; - -import java.math.BigInteger; -import static org.junit.Assert.*; - -/** - * Created by talm on 12/11/15. - */ -public class ECDSADeterministicSignatureTest extends ECDSASignatureTest { - - @Override - protected ECDSASignature getSigner() { return new ECDSADeterministicSignature(); } - - - /** - * Make sure signatures don't vary - */ - @Test - public void testDeterministicSigning() throws Exception { - loadSigningKeys(); - - - for (int i = 0; i < REPEAT_COUNT; ++i) { - BigInteger rawMsg = new BigInteger(50, rand); - Message msg = Crypto.BigInteger.newBuilder() - .setData(ByteString.copyFrom(rawMsg.toByteArray())).build(); - Crypto.Signature[] sigs = new Crypto.Signature[REPEAT_COUNT]; - - signer.updateContent(msg); - sigs[0] = signer.sign(); - byte[] canonicalSig = sigs[0].toByteArray(); - - for (int j = 1; j < sigs.length; ++j) { - signer.updateContent(msg); - sigs[j] = signer.sign(); - - byte[] newSig = sigs[j].toByteArray(); - - assertArrayEquals("Signatures on same message differ (i="+i+",j="+j+")", canonicalSig, newSig); - } - } - } -} +package meerkat.destributed_key_generation.concrete; + +import com.google.protobuf.ByteString; +import com.google.protobuf.Message; + +import meerkat.protobuf.Crypto; +import org.junit.Test; + +import java.math.BigInteger; +import static org.junit.Assert.*; + +/** + * Created by talm on 12/11/15. + */ +public class ECDSADeterministicSignatureTest extends ECDSASignatureTest { + + @Override + protected ECDSASignature getSigner() { return new ECDSADeterministicSignature(); } + + + /** + * Make sure signatures don't vary + */ + @Test + public void testDeterministicSigning() throws Exception { + loadSigningKeys(); + + + for (int i = 0; i < REPEAT_COUNT; ++i) { + BigInteger rawMsg = new BigInteger(50, rand); + Message msg = Crypto.BigInteger.newBuilder() + .setData(ByteString.copyFrom(rawMsg.toByteArray())).build(); + Crypto.Signature[] sigs = new Crypto.Signature[REPEAT_COUNT]; + + signer.updateContent(msg); + sigs[0] = signer.sign(); + byte[] canonicalSig = sigs[0].toByteArray(); + + for (int j = 1; j < sigs.length; ++j) { + signer.updateContent(msg); + sigs[j] = signer.sign(); + + byte[] newSig = sigs[j].toByteArray(); + + assertArrayEquals("Signatures on same message differ (i="+i+",j="+j+")", canonicalSig, newSig); + } + } + } +} diff --git a/meerkat-common/src/test/java/meerkat/crypto/concrete/ECDSASignatureTest.java b/meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECDSASignatureTest.java similarity index 96% rename from meerkat-common/src/test/java/meerkat/crypto/concrete/ECDSASignatureTest.java rename to meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECDSASignatureTest.java index 327292a..9e90cce 100644 --- a/meerkat-common/src/test/java/meerkat/crypto/concrete/ECDSASignatureTest.java +++ b/meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECDSASignatureTest.java @@ -1,220 +1,219 @@ -package meerkat.crypto.concrete; - -import com.google.protobuf.ByteString; -import com.google.protobuf.Message; -import meerkat.protobuf.Crypto; -import meerkat.crypto.concrete.ECDSASignature; -import org.junit.Before; -import org.junit.Test; - -import java.io.InputStream; -import java.math.BigInteger; -import java.security.KeyStore; -import java.util.Random; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -/** - * Created by talm on 12/11/15. - */ -public class ECDSASignatureTest { - public static String KEYFILE_EXAMPLE = "/certs/enduser-certs/user1-key-with-password-secret.p12"; - public static String KEYFILE_PASSWORD = "secret"; - - public static String CERT1_PEM_EXAMPLE = "/certs/enduser-certs/user1.crt"; - public static String CERT2_DER_EXAMPLE = "/certs/enduser-certs/user2.der"; - - public static String MSG_PLAINTEXT_EXAMPLE = "/certs/signed-messages/helloworld.txt"; - public static String MSG_SIG_EXAMPLE = "/certs/signed-messages/helloworld.txt.sha256sig"; - - public static String HELLO_WORLD = "hello world!"; - - public final static int REPEAT_COUNT = 10; - - Random rand = new Random(0); - - protected ECDSASignature signer; - - protected ECDSASignature getSigner() { return new ECDSASignature(); } - - @Before - public void setup() throws Exception { - signer = getSigner(); - } - - @Test - public void loadSignatureKey() throws Exception { - InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE); - char[] password = KEYFILE_PASSWORD.toCharArray(); - - KeyStore.Builder keyStore = signer.getPKCS12KeyStoreBuilder(keyStream, password); - signer.loadSigningCertificate(keyStore); - keyStream.close(); - } - - @Test - public void loadPEMVerificationKey() throws Exception { - InputStream certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE); - - signer.loadVerificationCertificates(certStream); - certStream.close(); - } - - @Test - public void loadDERVerificationKey() throws Exception { - InputStream certStream = getClass().getResourceAsStream(CERT2_DER_EXAMPLE); - - signer.loadVerificationCertificates(certStream); - certStream.close(); - } - - - @Test - public void verifyValidSig() throws Exception { - InputStream certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE); - InputStream msgStream = getClass().getResourceAsStream(MSG_PLAINTEXT_EXAMPLE); - InputStream sigStream = getClass().getResourceAsStream(MSG_SIG_EXAMPLE); - - signer.loadVerificationCertificates(certStream); - certStream.close(); - - Crypto.Signature.Builder sig = Crypto.Signature.newBuilder(); - sig.setType(Crypto.SignatureType.ECDSA); - sig.setSignerId(signer.loadedCertificates.entrySet().iterator().next().getKey()); - sig.setData(ByteString.readFrom(sigStream)); - - Crypto.Signature builtSig = sig.build(); - signer.initVerify(builtSig); - signer.updateContent(msgStream); - assertTrue("Signature did not verify!", signer.verify()); - } - - @Test - public void verifyInvalidSig() throws Exception { - InputStream certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE); - InputStream msgStream = getClass().getResourceAsStream(MSG_PLAINTEXT_EXAMPLE); - InputStream sigStream = getClass().getResourceAsStream(MSG_SIG_EXAMPLE); - - signer.loadVerificationCertificates(certStream); - certStream.close(); - - Crypto.Signature.Builder sig = Crypto.Signature.newBuilder(); - sig.setType(Crypto.SignatureType.ECDSA); - sig.setSignerId(signer.loadedCertificates.entrySet().iterator().next().getKey()); - byte[] sigData = ByteString.readFrom(sigStream).toByteArray(); - ++sigData[0]; - - sig.setData(ByteString.copyFrom(sigData)); - - - Crypto.Signature builtSig = sig.build(); - signer.initVerify(builtSig); - signer.updateContent(msgStream); - assertFalse("Bad Signature passed verification!", signer.verify()); - } - - - @Test - public void verifyInvalidMsg() throws Exception { - InputStream certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE); - InputStream msgStream = getClass().getResourceAsStream(MSG_PLAINTEXT_EXAMPLE); - InputStream sigStream = getClass().getResourceAsStream(MSG_SIG_EXAMPLE); - - signer.loadVerificationCertificates(certStream); - certStream.close(); - - Crypto.Signature.Builder sig = Crypto.Signature.newBuilder(); - sig.setType(Crypto.SignatureType.ECDSA); - sig.setSignerId(signer.loadedCertificates.entrySet().iterator().next().getKey()); - sig.setData(ByteString.readFrom(sigStream)); - byte[] msgData = ByteString.readFrom(msgStream).toByteArray(); - ++msgData[0]; - - Crypto.Signature builtSig = sig.build(); - signer.initVerify(builtSig); - signer.updateContent(msgStream); - assertFalse("Signature doesn't match message but passed verification!", signer.verify()); - } - - - - protected void loadSigningKeys() throws Exception { - InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE); - char[] password = KEYFILE_PASSWORD.toCharArray(); - - KeyStore.Builder keyStore = signer.getPKCS12KeyStoreBuilder(keyStream, password); - signer.loadSigningCertificate(keyStore); - } - - @Test - public void signAndVerify() throws Exception { - loadSigningKeys(); - - BigInteger rawMsg = new BigInteger(50, rand); - Crypto.BigInteger usMsg = Crypto.BigInteger.newBuilder() - .setData(ByteString.copyFrom(rawMsg.toByteArray())).build(); - - signer.updateContent(usMsg); - Crypto.Signature sig = signer.sign(); - - signer.loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE)); - - signer.initVerify(sig); - signer.updateContent(usMsg); - assertTrue("Couldn't verify signature on ", signer.verify()); - } - - - @Test - public void signMultipleAndVerify() throws Exception { - loadSigningKeys(); - - Message[] msgs = new Message[REPEAT_COUNT]; - for (int i = 0; i < msgs.length; ++i) { - - BigInteger rawMsg = new BigInteger(50, rand); - msgs[i] = Crypto.BigInteger.newBuilder() - .setData(ByteString.copyFrom(rawMsg.toByteArray())).build(); - signer.updateContent(msgs[i]); - } - - Crypto.Signature sig = signer.sign(); - - signer.loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE)); - - signer.initVerify(sig); - for (int i = 0; i < msgs.length; ++i) { - signer.updateContent(msgs[i]); - } - assertTrue("Couldn't verify signature on ", signer.verify()); - } - - @Test - public void multipleSignAndVerify() throws Exception { - loadSigningKeys(); - - Message[] msgs = new Message[REPEAT_COUNT]; - Crypto.Signature[] sigs = new Crypto.Signature[REPEAT_COUNT]; - for (int i = 0; i < msgs.length; ++i) { - BigInteger rawMsg = new BigInteger(50, rand); - msgs[i] = Crypto.BigInteger.newBuilder() - .setData(ByteString.copyFrom(rawMsg.toByteArray())).build(); - signer.updateContent(msgs[i]); - sigs[i] = signer.sign(); - } - - signer.loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE)); - - - for (int i = 0; i < msgs.length; ++i) { - signer.initVerify(sigs[i]); - signer.updateContent(msgs[i]); - assertTrue("Couldn't verify signature on ", signer.verify()); - } - - } - - - -} +package meerkat.destributed_key_generation.concrete; + +import com.google.protobuf.ByteString; +import com.google.protobuf.Message; +import meerkat.protobuf.Crypto; +import org.junit.Before; +import org.junit.Test; + +import java.io.InputStream; +import java.math.BigInteger; +import java.security.KeyStore; +import java.util.Random; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * Created by talm on 12/11/15. + */ +public class ECDSASignatureTest { + public static String KEYFILE_EXAMPLE = "/certs/enduser-certs/user1-key-with-password-secret.p12"; + public static String KEYFILE_PASSWORD = "secret"; + + public static String CERT1_PEM_EXAMPLE = "/certs/enduser-certs/user1.crt"; + public static String CERT2_DER_EXAMPLE = "/certs/enduser-certs/user2.der"; + + public static String MSG_PLAINTEXT_EXAMPLE = "/certs/signed-messages/helloworld.txt"; + public static String MSG_SIG_EXAMPLE = "/certs/signed-messages/helloworld.txt.sha256sig"; + + public static String HELLO_WORLD = "hello world!"; + + public final static int REPEAT_COUNT = 10; + + Random rand = new Random(0); + + protected ECDSASignature signer; + + protected ECDSASignature getSigner() { return new ECDSASignature(); } + + @Before + public void setup() throws Exception { + signer = getSigner(); + } + + @Test + public void loadSignatureKey() throws Exception { + InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE); + char[] password = KEYFILE_PASSWORD.toCharArray(); + + KeyStore.Builder keyStore = signer.getPKCS12KeyStoreBuilder(keyStream, password); + signer.loadSigningCertificate(keyStore); + keyStream.close(); + } + + @Test + public void loadPEMVerificationKey() throws Exception { + InputStream certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE); + + signer.loadVerificationCertificates(certStream); + certStream.close(); + } + + @Test + public void loadDERVerificationKey() throws Exception { + InputStream certStream = getClass().getResourceAsStream(CERT2_DER_EXAMPLE); + + signer.loadVerificationCertificates(certStream); + certStream.close(); + } + + + @Test + public void verifyValidSig() throws Exception { + InputStream certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE); + InputStream msgStream = getClass().getResourceAsStream(MSG_PLAINTEXT_EXAMPLE); + InputStream sigStream = getClass().getResourceAsStream(MSG_SIG_EXAMPLE); + + signer.loadVerificationCertificates(certStream); + certStream.close(); + + Crypto.Signature.Builder sig = Crypto.Signature.newBuilder(); + sig.setType(Crypto.SignatureType.ECDSA); + sig.setSignerId(signer.loadedCertificates.entrySet().iterator().next().getKey()); + sig.setData(ByteString.readFrom(sigStream)); + + Crypto.Signature builtSig = sig.build(); + signer.initVerify(builtSig); + signer.updateContent(msgStream); + assertTrue("Signature did not verify!", signer.verify()); + } + + @Test + public void verifyInvalidSig() throws Exception { + InputStream certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE); + InputStream msgStream = getClass().getResourceAsStream(MSG_PLAINTEXT_EXAMPLE); + InputStream sigStream = getClass().getResourceAsStream(MSG_SIG_EXAMPLE); + + signer.loadVerificationCertificates(certStream); + certStream.close(); + + Crypto.Signature.Builder sig = Crypto.Signature.newBuilder(); + sig.setType(Crypto.SignatureType.ECDSA); + sig.setSignerId(signer.loadedCertificates.entrySet().iterator().next().getKey()); + byte[] sigData = ByteString.readFrom(sigStream).toByteArray(); + ++sigData[0]; + + sig.setData(ByteString.copyFrom(sigData)); + + + Crypto.Signature builtSig = sig.build(); + signer.initVerify(builtSig); + signer.updateContent(msgStream); + assertFalse("Bad Signature passed verification!", signer.verify()); + } + + + @Test + public void verifyInvalidMsg() throws Exception { + InputStream certStream = getClass().getResourceAsStream(CERT1_PEM_EXAMPLE); + InputStream msgStream = getClass().getResourceAsStream(MSG_PLAINTEXT_EXAMPLE); + InputStream sigStream = getClass().getResourceAsStream(MSG_SIG_EXAMPLE); + + signer.loadVerificationCertificates(certStream); + certStream.close(); + + Crypto.Signature.Builder sig = Crypto.Signature.newBuilder(); + sig.setType(Crypto.SignatureType.ECDSA); + sig.setSignerId(signer.loadedCertificates.entrySet().iterator().next().getKey()); + sig.setData(ByteString.readFrom(sigStream)); + byte[] msgData = ByteString.readFrom(msgStream).toByteArray(); + ++msgData[0]; + + Crypto.Signature builtSig = sig.build(); + signer.initVerify(builtSig); + signer.updateContent(msgStream); + assertFalse("Signature doesn't match message but passed verification!", signer.verify()); + } + + + + protected void loadSigningKeys() throws Exception { + InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE); + char[] password = KEYFILE_PASSWORD.toCharArray(); + + KeyStore.Builder keyStore = signer.getPKCS12KeyStoreBuilder(keyStream, password); + signer.loadSigningCertificate(keyStore); + } + + @Test + public void signAndVerify() throws Exception { + loadSigningKeys(); + + BigInteger rawMsg = new BigInteger(50, rand); + Crypto.BigInteger usMsg = Crypto.BigInteger.newBuilder() + .setData(ByteString.copyFrom(rawMsg.toByteArray())).build(); + + signer.updateContent(usMsg); + Crypto.Signature sig = signer.sign(); + + signer.loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE)); + + signer.initVerify(sig); + signer.updateContent(usMsg); + assertTrue("Couldn't verify signature on ", signer.verify()); + } + + + @Test + public void signMultipleAndVerify() throws Exception { + loadSigningKeys(); + + Message[] msgs = new Message[REPEAT_COUNT]; + for (int i = 0; i < msgs.length; ++i) { + + BigInteger rawMsg = new BigInteger(50, rand); + msgs[i] = Crypto.BigInteger.newBuilder() + .setData(ByteString.copyFrom(rawMsg.toByteArray())).build(); + signer.updateContent(msgs[i]); + } + + Crypto.Signature sig = signer.sign(); + + signer.loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE)); + + signer.initVerify(sig); + for (int i = 0; i < msgs.length; ++i) { + signer.updateContent(msgs[i]); + } + assertTrue("Couldn't verify signature on ", signer.verify()); + } + + @Test + public void multipleSignAndVerify() throws Exception { + loadSigningKeys(); + + Message[] msgs = new Message[REPEAT_COUNT]; + Crypto.Signature[] sigs = new Crypto.Signature[REPEAT_COUNT]; + for (int i = 0; i < msgs.length; ++i) { + BigInteger rawMsg = new BigInteger(50, rand); + msgs[i] = Crypto.BigInteger.newBuilder() + .setData(ByteString.copyFrom(rawMsg.toByteArray())).build(); + signer.updateContent(msgs[i]); + sigs[i] = signer.sign(); + } + + signer.loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE)); + + + for (int i = 0; i < msgs.length; ++i) { + signer.initVerify(sigs[i]); + signer.updateContent(msgs[i]); + assertTrue("Couldn't verify signature on ", signer.verify()); + } + + } + + + +} diff --git a/meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalEncryptionTest.java b/meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECElGamalEncryptionTest.java similarity index 96% rename from meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalEncryptionTest.java rename to meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECElGamalEncryptionTest.java index a911b96..b09fbce 100644 --- a/meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalEncryptionTest.java +++ b/meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECElGamalEncryptionTest.java @@ -1,122 +1,122 @@ -package meerkat.crypto.concrete; - -import meerkat.protobuf.ConcreteCrypto; -import meerkat.protobuf.Crypto; -import meerkat.protobuf.Voting; -import org.bouncycastle.math.ec.ECPoint; -import org.junit.Before; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.factcenter.qilin.primitives.concrete.ECElGamal; -import org.factcenter.qilin.primitives.concrete.ECGroup; -import org.factcenter.qilin.util.Pair; - -import java.math.BigInteger; -import java.util.Random; - -import static org.junit.Assert.*; - -/** - * Test class for {@link ECElGamalEncryption} - */ -public class ECElGamalEncryptionTest { - final Logger logger = LoggerFactory.getLogger(getClass()); - /** - * Number of times to repeat probabilistic tests. - */ - public final static int CONFIDENCE = 10; - - Random rand = new Random(0); // Insecure deterministic random for testing. - - ECElGamal.SK key; - ECGroup group; - ECElGamalEncryption enc; - ConcreteCrypto.ElGamalPublicKey serializedPk; - - - @Before - public void setup() throws Exception { - group = new ECGroup("secp256k1"); - BigInteger sk = ECElGamal.generateSecretKey(group, rand); - key = new ECElGamal.SK(group, sk); - serializedPk = ECElGamalUtils.serializePk(group, key); - - - enc = new ECElGamalEncryption(); - - enc.init(serializedPk); - } - - - Voting.PlaintextBallot genRandomBallot(int numQuestions, int numAnswers, int maxAnswer) { - Voting.PlaintextBallot.Builder ballot = Voting.PlaintextBallot.newBuilder(); - ballot.setSerialNumber(rand.nextInt(1000000)); - for (int i = 0; i < numQuestions; ++i) { - Voting.BallotAnswer.Builder answers = ballot.addAnswersBuilder(); - for (int j = 0; j < numAnswers; ++j) { - answers.addAnswer(rand.nextInt(maxAnswer)); - } - } - return ballot.build(); - } - - /** - * Testing just the key management - * @throws Exception - */ - @Test - public void testPkSerialization() throws Exception { - ECElGamal.PK pk = enc.getElGamalPK(); - - ECPoint point = enc.getGroup().sample(rand); - Pair cipher = pk.encrypt(point, pk.getRandom(rand)); - - ECPoint decrypted = key.decrypt(cipher); - - assertEquals("Decrypted value not equal to encrypted value!", point, decrypted); - } - - @Test - public void testEncryption() throws Exception { - for (int i = 0; i < CONFIDENCE; ++i) { - Voting.PlaintextBallot msg = genRandomBallot(2,3,16); // 2 questions with 3 answers each, in range 0-15. - if (msg.getSerializedSize() > enc.getGroup().getInjectiveEncodeMsgLength()) { - logger.error("Test Message too big (|msg|={} > max={}), expect failure.", - msg.getSerializedSize(), enc.getGroup().getInjectiveEncodeMsgLength()); - } - - Crypto.RerandomizableEncryptedMessage cipherText = enc.encrypt(msg, enc.generateRandomness(rand)); - - Voting.PlaintextBallot decrypted = ECElGamalUtils.decrypt(Voting.PlaintextBallot.class, key, group, cipherText); - - assertEquals("Decrypted value differs from encrypted value (i="+i+")!", msg, decrypted); - } - } - - @Test - public void testRerandomizeModifiesCiphertext() throws Exception { - Voting.PlaintextBallot msg = genRandomBallot(2,3,16); // 2 questions with 3 answers each, in range 0-15. - Crypto.RerandomizableEncryptedMessage cipher1 = enc.encrypt(msg, enc.generateRandomness(rand)); - Crypto.RerandomizableEncryptedMessage cipher2 = enc.rerandomize(cipher1, enc.generateRandomness(rand)); - assertNotEquals("Rerandomized cipher identical to original!", cipher1, cipher2); - } - - @Test - public void testRerandomizePreservesPlaintext() throws Exception { - for (int i = 0; i < CONFIDENCE; ++i) { - Voting.PlaintextBallot msg = genRandomBallot(2,3,16); // 2 questions with 3 answers each, in range 0-15. - - Crypto.RerandomizableEncryptedMessage cipher = enc.encrypt(msg, enc.generateRandomness(rand)); - Crypto.RerandomizableEncryptedMessage cipher2 = cipher; - for (int j = 0; j < CONFIDENCE; ++j) - cipher2 = enc.rerandomize(cipher2, enc.generateRandomness(rand)); - - Voting.PlaintextBallot decrypted = ECElGamalUtils.decrypt(Voting.PlaintextBallot.class, key, group, - cipher2); - - assertEquals("Decrypted value differs from original encrypted value (i="+i+")!", msg, decrypted); - } - } -} - +package meerkat.destributed_key_generation.concrete; + +import meerkat.protobuf.ConcreteCrypto; +import meerkat.protobuf.Crypto; +import meerkat.protobuf.Voting; +import org.bouncycastle.math.ec.ECPoint; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.factcenter.qilin.primitives.concrete.ECElGamal; +import org.factcenter.qilin.primitives.concrete.ECGroup; +import org.factcenter.qilin.util.Pair; + +import java.math.BigInteger; +import java.util.Random; + +import static org.junit.Assert.*; + +/** + * Test class for {@link ECElGamalEncryption} + */ +public class ECElGamalEncryptionTest { + final Logger logger = LoggerFactory.getLogger(getClass()); + /** + * Number of times to repeat probabilistic tests. + */ + public final static int CONFIDENCE = 10; + + Random rand = new Random(0); // Insecure deterministic random for testing. + + ECElGamal.SK key; + ECGroup group; + ECElGamalEncryption enc; + ConcreteCrypto.ElGamalPublicKey serializedPk; + + + @Before + public void setup() throws Exception { + group = new ECGroup("secp256k1"); + BigInteger sk = ECElGamal.generateSecretKey(group, rand); + key = new ECElGamal.SK(group, sk); + serializedPk = ECElGamalUtils.serializePk(group, key); + + + enc = new ECElGamalEncryption(); + + enc.init(serializedPk); + } + + + Voting.PlaintextBallot genRandomBallot(int numQuestions, int numAnswers, int maxAnswer) { + Voting.PlaintextBallot.Builder ballot = Voting.PlaintextBallot.newBuilder(); + ballot.setSerialNumber(rand.nextInt(1000000)); + for (int i = 0; i < numQuestions; ++i) { + Voting.BallotAnswer.Builder answers = ballot.addAnswersBuilder(); + for (int j = 0; j < numAnswers; ++j) { + answers.addAnswer(rand.nextInt(maxAnswer)); + } + } + return ballot.build(); + } + + /** + * Testing just the key management + * @throws Exception + */ + @Test + public void testPkSerialization() throws Exception { + ECElGamal.PK pk = enc.getElGamalPK(); + + ECPoint point = enc.getGroup().sample(rand); + Pair cipher = pk.encrypt(point, pk.getRandom(rand)); + + ECPoint decrypted = key.decrypt(cipher); + + assertEquals("Decrypted value not equal to encrypted value!", point, decrypted); + } + + @Test + public void testEncryption() throws Exception { + for (int i = 0; i < CONFIDENCE; ++i) { + Voting.PlaintextBallot msg = genRandomBallot(2,3,16); // 2 questions with 3 answers each, in range 0-15. + if (msg.getSerializedSize() > enc.getGroup().getInjectiveEncodeMsgLength()) { + logger.error("Test Message too big (|msg|={} > max={}), expect failure.", + msg.getSerializedSize(), enc.getGroup().getInjectiveEncodeMsgLength()); + } + + Crypto.RerandomizableEncryptedMessage cipherText = enc.encrypt(msg, enc.generateRandomness(rand)); + + Voting.PlaintextBallot decrypted = ECElGamalUtils.decrypt(Voting.PlaintextBallot.class, key, group, cipherText); + + assertEquals("Decrypted value differs from encrypted value (i="+i+")!", msg, decrypted); + } + } + + @Test + public void testRerandomizeModifiesCiphertext() throws Exception { + Voting.PlaintextBallot msg = genRandomBallot(2,3,16); // 2 questions with 3 answers each, in range 0-15. + Crypto.RerandomizableEncryptedMessage cipher1 = enc.encrypt(msg, enc.generateRandomness(rand)); + Crypto.RerandomizableEncryptedMessage cipher2 = enc.rerandomize(cipher1, enc.generateRandomness(rand)); + assertNotEquals("Rerandomized cipher identical to original!", cipher1, cipher2); + } + + @Test + public void testRerandomizePreservesPlaintext() throws Exception { + for (int i = 0; i < CONFIDENCE; ++i) { + Voting.PlaintextBallot msg = genRandomBallot(2,3,16); // 2 questions with 3 answers each, in range 0-15. + + Crypto.RerandomizableEncryptedMessage cipher = enc.encrypt(msg, enc.generateRandomness(rand)); + Crypto.RerandomizableEncryptedMessage cipher2 = cipher; + for (int j = 0; j < CONFIDENCE; ++j) + cipher2 = enc.rerandomize(cipher2, enc.generateRandomness(rand)); + + Voting.PlaintextBallot decrypted = ECElGamalUtils.decrypt(Voting.PlaintextBallot.class, key, group, + cipher2); + + assertEquals("Decrypted value differs from original encrypted value (i="+i+")!", msg, decrypted); + } + } +} + diff --git a/meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalUtils.java b/meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECElGamalUtils.java similarity index 96% rename from meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalUtils.java rename to meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECElGamalUtils.java index f83aaea..9b5de78 100644 --- a/meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalUtils.java +++ b/meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECElGamalUtils.java @@ -1,89 +1,89 @@ -package meerkat.crypto.concrete; - -import com.google.protobuf.ByteString; -import com.google.protobuf.GeneratedMessage; -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Message; -import meerkat.protobuf.ConcreteCrypto; -import meerkat.protobuf.Crypto; -import org.bouncycastle.jce.spec.ECParameterSpec; -import org.bouncycastle.jce.spec.ECPublicKeySpec; -import org.bouncycastle.math.ec.ECPoint; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.factcenter.qilin.primitives.concrete.ECElGamal; -import org.factcenter.qilin.primitives.concrete.ECGroup; -import org.factcenter.qilin.primitives.generic.ElGamal; -import org.factcenter.qilin.util.Pair; - -import java.io.ByteArrayInputStream; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PublicKey; -import java.security.spec.InvalidKeySpecException; - -/** - * utilities for ECElgamal - */ -public class ECElGamalUtils { - final static Logger logger = LoggerFactory.getLogger(ECElGamalUtils.class); - - public final static String ENCRYPTION_KEY_ALGORITHM = "ECDH"; - - /** - * Serialize an El-Gamal public key into a form acceptable by {@link ECElGamalEncryption} - * @param pk - * @return - */ - public static ConcreteCrypto.ElGamalPublicKey serializePk(ECGroup group, ElGamal.PK pk) { - ECPoint pkPoint = pk.getPK(); - ECParameterSpec params = group.getCurveParams(); - - ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(pkPoint, params); - - try { - KeyFactory fact = KeyFactory.getInstance(ENCRYPTION_KEY_ALGORITHM, - GlobalCryptoSetup.getBouncyCastleProvider()); - PublicKey javaPk = fact.generatePublic(pubKeySpec); - ConcreteCrypto.ElGamalPublicKey serializedPk = ConcreteCrypto.ElGamalPublicKey.newBuilder() - .setSubjectPublicKeyInfo(ByteString.copyFrom(javaPk.getEncoded())).build(); - - return serializedPk; - } catch (NoSuchAlgorithmException|InvalidKeySpecException e) { - logger.error("Should never happen!", e); - throw new RuntimeException("Error converting public key!", e); - } - } - - /** - * Standard (non-threshold) decryption for testing purposes. - * @param secretKey - * @return - */ - public static T decrypt(Class plaintextMessageType, ECElGamal.SK secretKey, ECGroup group, Crypto.RerandomizableEncryptedMessage opaqueCipher) - throws InvalidProtocolBufferException { - ConcreteCrypto.ElGamalCiphertext cipherText = ConcreteCrypto.ElGamalCiphertext.parseFrom(opaqueCipher.getData()); - ByteString c1encoded = cipherText.getC1(); - ByteString c2encoded = cipherText.getC2(); - - ECPoint c1 = group.decode(c1encoded.toByteArray()); - ECPoint c2 = group.decode(c2encoded.toByteArray()); - - ECPoint plaintextEncoded = secretKey.decrypt(new Pair(c1, c2)); - - byte[] plaintext = group.injectiveDecode(plaintextEncoded); - - ByteArrayInputStream in = new ByteArrayInputStream(plaintext); - - try { - java.lang.reflect.Method newBuilder = plaintextMessageType.getMethod("newBuilder"); - GeneratedMessage.Builder builder = (GeneratedMessage.Builder) newBuilder.invoke(plaintextMessageType); - builder.mergeDelimitedFrom(in); - return plaintextMessageType.cast(builder.build()); - } catch (Exception e) { - logger.error("Error parsing incoming message", e); - throw new InvalidProtocolBufferException("Plaintext protobuf error"); - } - } - -} +package meerkat.destributed_key_generation.concrete; + +import com.google.protobuf.ByteString; +import com.google.protobuf.GeneratedMessage; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; +import meerkat.protobuf.ConcreteCrypto; +import meerkat.protobuf.Crypto; +import org.bouncycastle.jce.spec.ECParameterSpec; +import org.bouncycastle.jce.spec.ECPublicKeySpec; +import org.bouncycastle.math.ec.ECPoint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.factcenter.qilin.primitives.concrete.ECElGamal; +import org.factcenter.qilin.primitives.concrete.ECGroup; +import org.factcenter.qilin.primitives.generic.ElGamal; +import org.factcenter.qilin.util.Pair; + +import java.io.ByteArrayInputStream; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; + +/** + * utilities for ECElgamal + */ +public class ECElGamalUtils { + final static Logger logger = LoggerFactory.getLogger(ECElGamalUtils.class); + + public final static String ENCRYPTION_KEY_ALGORITHM = "ECDH"; + + /** + * Serialize an El-Gamal public key into a form acceptable by {@link ECElGamalEncryption} + * @param pk + * @return + */ + public static ConcreteCrypto.ElGamalPublicKey serializePk(ECGroup group, ElGamal.PK pk) { + ECPoint pkPoint = pk.getPK(); + ECParameterSpec params = group.getCurveParams(); + + ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(pkPoint, params); + + try { + KeyFactory fact = KeyFactory.getInstance(ENCRYPTION_KEY_ALGORITHM, + GlobalCryptoSetup.getBouncyCastleProvider()); + PublicKey javaPk = fact.generatePublic(pubKeySpec); + ConcreteCrypto.ElGamalPublicKey serializedPk = ConcreteCrypto.ElGamalPublicKey.newBuilder() + .setSubjectPublicKeyInfo(ByteString.copyFrom(javaPk.getEncoded())).build(); + + return serializedPk; + } catch (NoSuchAlgorithmException|InvalidKeySpecException e) { + logger.error("Should never happen!", e); + throw new RuntimeException("Error converting public key!", e); + } + } + + /** + * Standard (non-threshold) decryption for testing purposes. + * @param secretKey + * @return + */ + public static T decrypt(Class plaintextMessageType, ECElGamal.SK secretKey, ECGroup group, Crypto.RerandomizableEncryptedMessage opaqueCipher) + throws InvalidProtocolBufferException { + ConcreteCrypto.ElGamalCiphertext cipherText = ConcreteCrypto.ElGamalCiphertext.parseFrom(opaqueCipher.getData()); + ByteString c1encoded = cipherText.getC1(); + ByteString c2encoded = cipherText.getC2(); + + ECPoint c1 = group.decode(c1encoded.toByteArray()); + ECPoint c2 = group.decode(c2encoded.toByteArray()); + + ECPoint plaintextEncoded = secretKey.decrypt(new Pair(c1, c2)); + + byte[] plaintext = group.injectiveDecode(plaintextEncoded); + + ByteArrayInputStream in = new ByteArrayInputStream(plaintext); + + try { + java.lang.reflect.Method newBuilder = plaintextMessageType.getMethod("newBuilder"); + GeneratedMessage.Builder builder = (GeneratedMessage.Builder) newBuilder.invoke(plaintextMessageType); + builder.mergeDelimitedFrom(in); + return plaintextMessageType.cast(builder.build()); + } catch (Exception e) { + logger.error("Error parsing incoming message", e); + throw new InvalidProtocolBufferException("Plaintext protobuf error"); + } + } + +} From 857821c0e4d78096048fd2004813f20ed5d277aa Mon Sep 17 00:00:00 2001 From: Arbel Deutsch Peled Date: Mon, 11 Apr 2016 12:17:05 +0300 Subject: [PATCH 37/49] Adding one more file to version control --- .../SingleServerQuerySyncWorker.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerQuerySyncWorker.java diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerQuerySyncWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerQuerySyncWorker.java new file mode 100644 index 0000000..3a9873d --- /dev/null +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerQuerySyncWorker.java @@ -0,0 +1,59 @@ +package meerkat.bulletinboard.workers.singleserver; + +import meerkat.bulletinboard.SingleServerWorker; +import meerkat.comm.CommunicationException; +import meerkat.protobuf.BulletinBoardAPI.SyncQuery; +import meerkat.protobuf.BulletinBoardAPI.SyncQueryResponse; +import meerkat.rest.Constants; + +import javax.ws.rs.ProcessingException; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Response; + +import static meerkat.bulletinboard.BulletinBoardConstants.BULLETIN_BOARD_SERVER_PATH; +import static meerkat.bulletinboard.BulletinBoardConstants.SYNC_QUERY_PATH; + +/** + * Created by Arbel Deutsch Peled on 27-Dec-15. + * Tries to contact server once and perform a post operation + */ +public class SingleServerQuerySyncWorker extends SingleServerWorker { + + public SingleServerQuerySyncWorker(String serverAddress, SyncQuery payload, int maxRetry) { + super(serverAddress, payload, maxRetry); + } + + @Override + public SyncQueryResponse call() throws Exception { + + Client client = clientLocal.get(); + + WebTarget webTarget; + Response response; + + // Send request to Server + + webTarget = client.target(serverAddress).path(BULLETIN_BOARD_SERVER_PATH).path(SYNC_QUERY_PATH); + response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(payload, Constants.MEDIATYPE_PROTOBUF)); + + // Retrieve answer + + try { + + // If a BulletinBoardMessageList is returned: the read was successful + return response.readEntity(SyncQueryResponse.class); + + } catch (ProcessingException | IllegalStateException e) { + + // Read failed + throw new CommunicationException("Server access failed"); + + } + finally { + response.close(); + } + + } +} From 07aecd52378872c674999261226ad5406deb3abe Mon Sep 17 00:00:00 2001 From: Arbel Deutsch Peled Date: Mon, 11 Apr 2016 12:26:02 +0300 Subject: [PATCH 38/49] TimestampComparator name change --- .../util/{TimeStampComparator.java => TimestampComparator.java} | 1 + 1 file changed, 1 insertion(+) rename meerkat-common/src/main/java/meerkat/util/{TimeStampComparator.java => TimestampComparator.java} (99%) diff --git a/meerkat-common/src/main/java/meerkat/util/TimeStampComparator.java b/meerkat-common/src/main/java/meerkat/util/TimestampComparator.java similarity index 99% rename from meerkat-common/src/main/java/meerkat/util/TimeStampComparator.java rename to meerkat-common/src/main/java/meerkat/util/TimestampComparator.java index 1dc207b..9acdaa6 100644 --- a/meerkat-common/src/main/java/meerkat/util/TimeStampComparator.java +++ b/meerkat-common/src/main/java/meerkat/util/TimestampComparator.java @@ -27,4 +27,5 @@ public class TimestampComparator implements Comparator Date: Mon, 11 Apr 2016 14:13:26 +0300 Subject: [PATCH 39/49] Fixed H2 test time (by using a connection pool) Added same fix to MySQL Fixed and tested H2 SyncQuery --- bulletin-board-server/build.gradle | 1 + .../bulletinboard/sqlserver/H2QueryProvider.java | 10 +++++++--- .../sqlserver/MySQLQueryProvider.java | 14 ++++++++------ .../bulletinboard/H2BulletinBoardServerTest.java | 10 ++++++++++ 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/bulletin-board-server/build.gradle b/bulletin-board-server/build.gradle index 8d824e7..7e06c1c 100644 --- a/bulletin-board-server/build.gradle +++ b/bulletin-board-server/build.gradle @@ -51,6 +51,7 @@ dependencies { compile 'org.xerial:sqlite-jdbc:3.8.+' compile 'mysql:mysql-connector-java:5.1.+' compile 'com.h2database:h2:1.0.+' + compile 'org.apache.commons:commons-dbcp2:2.0.+' // Servlets compile 'javax.servlet:javax.servlet-api:3.0.+' diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java index a54c2ff..44a55da 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/H2QueryProvider.java @@ -1,6 +1,7 @@ package meerkat.bulletinboard.sqlserver; import meerkat.protobuf.BulletinBoardAPI.FilterType; +import org.apache.commons.dbcp2.BasicDataSource; import org.h2.jdbcx.JdbcDataSource; import javax.naming.Context; import javax.naming.InitialContext; @@ -61,7 +62,7 @@ public class H2QueryProvider implements BulletinBoardSQLServer.SQLQueryProvider return "SELECT Signature FROM SignatureTable WHERE EntryNum = :EntryNum"; case INSERT_MSG: - return "INSERT INTO MsgTable (MsgId, Msg) VALUES(:MsgId,:Msg)"; + return "INSERT INTO MsgTable (MsgId, Msg, ExactTime) VALUES(:MsgId,:Msg,:TimeStamp)"; case INSERT_NEW_TAG: return "INSERT INTO TagTable(Tag) SELECT DISTINCT :Tag AS NewTag FROM UtilityTable WHERE" @@ -200,10 +201,13 @@ public class H2QueryProvider implements BulletinBoardSQLServer.SQLQueryProvider @Override public DataSource getDataSource() { - JdbcDataSource dataSource = new JdbcDataSource(); - dataSource.setURL("jdbc:h2:~/" + dbName); + BasicDataSource dataSource = new BasicDataSource(); + + dataSource.setDriverClassName("org.h2.Driver"); + dataSource.setUrl("jdbc:h2:~/" + dbName); return dataSource; + } diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java index f99114e..adf96a4 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/MySQLQueryProvider.java @@ -4,6 +4,7 @@ import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; import meerkat.bulletinboard.BulletinBoardConstants; import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer.SQLQueryProvider; import meerkat.protobuf.BulletinBoardAPI.FilterType; +import org.apache.commons.dbcp2.BasicDataSource; import javax.sql.DataSource; import java.text.MessageFormat; @@ -216,16 +217,17 @@ public class MySQLQueryProvider implements SQLQueryProvider { @Override public DataSource getDataSource() { - MysqlDataSource dataSource = new MysqlDataSource(); - dataSource.setServerName(dbAddress); - dataSource.setPort(dbPort); - dataSource.setDatabaseName(dbName); - dataSource.setUser(username); + BasicDataSource dataSource = new BasicDataSource(); + + dataSource.setDriverClassName("com.mysql.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + dbAddress + ":" + dbPort + "/" + dbName); + + dataSource.setUsername(username); dataSource.setPassword(password); - dataSource.setAllowMultiQueries(true); return dataSource; + } @Override diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/H2BulletinBoardServerTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/H2BulletinBoardServerTest.java index 577c9be..512b4c9 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/H2BulletinBoardServerTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/H2BulletinBoardServerTest.java @@ -140,6 +140,16 @@ public class H2BulletinBoardServerTest { } + @Test + public void testSyncQuery() { + try { + serverTest.testSyncQuery(); + } catch (Exception e) { + System.err.println(e.getMessage()); + fail(e.getMessage()); + } + } + @After public void close() { System.err.println("Starting to close H2BulletinBoardServerTest"); From e904caa74f2c16afa31dddbb3083b0fdeb357f4f Mon Sep 17 00:00:00 2001 From: Arbel Deutsch Peled Date: Mon, 11 Apr 2016 14:21:36 +0300 Subject: [PATCH 40/49] Added certificates to version control --- .../enduser-certs/user3-key-with-password-shh.p12 | Bin 0 -> 857 bytes .../test/resources/certs/enduser-certs/user3.crt | 8 ++++++++ 2 files changed, 8 insertions(+) create mode 100644 meerkat-common/src/test/resources/certs/enduser-certs/user3-key-with-password-shh.p12 create mode 100644 meerkat-common/src/test/resources/certs/enduser-certs/user3.crt diff --git a/meerkat-common/src/test/resources/certs/enduser-certs/user3-key-with-password-shh.p12 b/meerkat-common/src/test/resources/certs/enduser-certs/user3-key-with-password-shh.p12 new file mode 100644 index 0000000000000000000000000000000000000000..c62cee15259b04a77890facb4d68a8f99c46c276 GIT binary patch literal 857 zcmXqLVh&|uWHxAGmS^MCYV&CO&dbQoxS)wyfTf9<2Pn*8(8PEjA;q?!iSYtZ=nNAh z1CTn3kYO~CVdH|Dz{AL9z{kSzR{7cIAM3ZyW@6%CXlP=b!M1fz{)!FRvCEt}g&oR2 z&Q$-iW^?Pp<^?v+>zzcxT{8MUmOPuMen0D;vJlra1G)LKtt)5WO?YOfTtCh5Qo_eN z7f%21Wo_Fu-WYSg`?pbUnR!jghRE*Bn`HbpF7CZ0i<0)FNrkHu>suu6XS0}sJu5WtIU3&GL*Kfrqj~+EHKAAtMTgmqFU!6>s zZsyx8&ODJTS`Iu2ln;Bi;)8af#_Z(Qy;J9$yL)ufwbe@|&AcznyGv=gyx)=M9!__h zx1_5bF8X_2xZRgG=9%u1G^cF`WaH)^QcS z%9iPAP-ourGtUiP{lB92+<_&6*W=Xl#GaH@UClG@uYGkc-C*BD_n#&*DJumY89Eq9 z!oA2TV#p)M#gNR9%232m!eD5ijF1vF6k`#&`R>#2rEbxE-Hr=n)&E6!l=%tmGSD?p xG~i@o)#hVnl450G5wUR6{-*U}YFqOeLl(cwPh$CYANt6`u|?0t*kS67=>Xf8Y@GlA literal 0 HcmV?d00001 diff --git a/meerkat-common/src/test/resources/certs/enduser-certs/user3.crt b/meerkat-common/src/test/resources/certs/enduser-certs/user3.crt new file mode 100644 index 0000000..23ee857 --- /dev/null +++ b/meerkat-common/src/test/resources/certs/enduser-certs/user3.crt @@ -0,0 +1,8 @@ +-----BEGIN CERTIFICATE----- +MIIBGjCBw6ADAgECAgEBMAkGByqGSM49BAEwEDEOMAwGA1UEAxMFY2VydDEwHhcN +MTUxMTI4MTEwNDAwWhcNMTYxMTI4MTEwNDAwWjAQMQ4wDAYDVQQDEwVjZXJ0MTBZ +MBMGByqGSM49AgEGCCqGSM49AwEHA0IABLiyFMVWQtFi4fCjOGLDwQcdjyr48Y8j +P+eLEIGMYKKv8bqL3Vchs0iOPoyGH6jxYj2/ShnLSIEuIMPfVgV9kxSjDzANMAsG +A1UdDwQEAwIHgDAJBgcqhkjOPQQBA0cAMEQCIH7R0AWO0AYiHOs+QsHEpWiebFc1 +cyxCKJGkf8KA1KJrAiArCia7PWl0KzaqA0RQC4J0BKp4rZo1PCqKI8DirKQf/Q== +-----END CERTIFICATE----- From 1ec02173e7859a68f25e205888dc8ddafba0ddc9 Mon Sep 17 00:00:00 2001 From: Tal Moran Date: Mon, 11 Apr 2016 19:48:36 +0300 Subject: [PATCH 41/49] package renaming and protobuf moves --- .../bulletinboard/BulletinClientWorker.java | 4 ++-- .../SimpleBulletinBoardClient.java | 4 ++-- .../ThreadedBulletinBoardClient.java | 4 ++-- .../sqlserver/BulletinBoardSQLServer.java | 4 ++-- .../GenericBulletinBoardServerTest.java | 2 +- .../build.gradle | 0 .../meerkat/crypto/dkg/comm}/MailHandler.java | 4 ++-- .../crypto/dkg/comm}/MessageHandler.java | 2 +- .../crypto/dkg/feldman}/MailHandler.java | 6 ++--- .../meerkat/crypto/dkg/feldman}/Party.java | 4 ++-- .../meerkat/crypto/dkg/feldman}/Protocol.java | 8 +++---- .../meerkat/crypto/dkg/feldman}/User.java | 10 ++++---- .../meerkat/crypto/dkg/gjkr}/MailHandler.java | 6 ++--- .../java/meerkat/crypto/dkg/gjkr}/Party.java | 6 ++--- .../meerkat/crypto/dkg/gjkr}/Protocol.java | 8 +++---- .../java/meerkat/crypto/dkg/gjkr}/User.java | 20 ++++++++-------- .../feldman}/VerifiableSecretSharing.java | 6 ++--- .../shamir/LagrangePolynomial.java | 4 ++-- .../secretsharing}/shamir/Polynomial.java | 6 ++--- .../secretsharing}/shamir/SecretSharing.java | 6 ++--- .../meerkat/crypto/utils}/Arithmetic.java | 2 +- .../java/meerkat/crypto/utils}/Channel.java | 2 +- .../meerkat/crypto/utils}/concrete/Fp.java | 4 ++-- .../src/main/proto/meerkat/DKGMessages.proto | 6 ++--- .../crypto/dkg/feldman}/DKGMaliciousUser.java | 6 ++--- .../meerkat/crypto/dkg/feldman}/DKGTest.java | 23 +++++++++---------- .../crypto/dkg/feldman}/DKGUserImplAbort.java | 4 ++-- .../dkg/gjkr}/SDKGMaliciousUserImpl.java | 6 ++--- .../meerkat/crypto/dkg/gjkr}/SDKGTest.java | 23 +++++++++---------- .../crypto/dkg/gjkr}/SDKGUserImplAbort.java | 4 ++-- .../feldman}/VerifiableSecretSharingTest.java | 4 ++-- .../shamir/PolynomialTests/AddTest.java | 8 +++---- .../PolynomialTests/InterpolationTest.java | 12 +++++----- .../PolynomialTests/MulByConstTest.java | 8 +++---- .../shamir/PolynomialTests/MulTest.java | 8 +++---- .../shamir/SecretSharingTest.java | 6 ++--- .../crypto/utils}/BigIntegerByteEncoder.java | 2 +- .../meerkat/crypto/utils}/ChannelImpl.java | 2 +- .../utils}/GenerateRandomPolynomial.java | 6 ++--- .../crypto/utils}/GenerateRandomPrime.java | 2 +- .../test/java/meerkat/crypto/utils}/Z.java | 2 +- .../Digest.java | 2 +- .../DigitalSignature.java | 2 +- .../Encryption.java | 2 +- .../concrete/ECDSADeterministicSignature.java | 2 +- .../concrete/ECDSASignature.java | 4 ++-- .../concrete/ECElGamalEncryption.java | 4 ++-- .../concrete/GlobalCryptoSetup.java | 4 ++-- .../concrete/SHA256Digest.java | 4 ++-- .../mixnet/Mix2ZeroKnowledgeProver.java | 2 +- .../mixnet/Mix2ZeroKnowledgeVerifier.java | 2 +- .../mixnet/Mixer.java | 2 +- .../mixnet/Trustee.java | 2 +- .../mixnet/Verifier.java | 2 +- .../ECDSADeterministicSignatureTest.java | 2 +- .../concrete/ECDSASignatureTest.java | 2 +- .../concrete/ECElGamalEncryptionTest.java | 2 +- .../concrete/ECElGamalUtils.java | 2 +- settings.gradle | 2 +- 59 files changed, 148 insertions(+), 150 deletions(-) rename {destributed-key-generation => distributed-key-generation}/build.gradle (100%) rename {destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/communication => distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm}/MailHandler.java (93%) rename {destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/communication => distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm}/MessageHandler.java (90%) rename {destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol => distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman}/MailHandler.java (82%) rename {destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol => distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman}/Party.java (84%) rename {destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol => distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman}/Protocol.java (96%) rename {destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol => distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman}/User.java (96%) rename {destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol => distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr}/MailHandler.java (85%) rename {destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol => distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr}/Party.java (68%) rename {destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol => distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr}/Protocol.java (92%) rename {destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol => distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr}/User.java (92%) rename {destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/feldman_verifiable => distributed-key-generation/src/main/java/meerkat/crypto/secretsharing/feldman}/VerifiableSecretSharing.java (93%) rename {destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring => distributed-key-generation/src/main/java/meerkat/crypto/secretsharing}/shamir/LagrangePolynomial.java (94%) rename {destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring => distributed-key-generation/src/main/java/meerkat/crypto/secretsharing}/shamir/Polynomial.java (95%) rename {destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring => distributed-key-generation/src/main/java/meerkat/crypto/secretsharing}/shamir/SecretSharing.java (93%) rename {destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis => distributed-key-generation/src/main/java/meerkat/crypto/utils}/Arithmetic.java (92%) rename {destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis => distributed-key-generation/src/main/java/meerkat/crypto/utils}/Channel.java (95%) rename {destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis => distributed-key-generation/src/main/java/meerkat/crypto/utils}/concrete/Fp.java (88%) rename {meerkat-common => distributed-key-generation}/src/main/proto/meerkat/DKGMessages.proto (85%) rename {destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol => distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman}/DKGMaliciousUser.java (89%) rename {destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol => distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman}/DKGTest.java (85%) rename {destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol => distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman}/DKGUserImplAbort.java (88%) rename {destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol => distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr}/SDKGMaliciousUserImpl.java (87%) rename {destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol => distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr}/SDKGTest.java (86%) rename {destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol => distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr}/SDKGUserImplAbort.java (89%) rename {destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/feldman_verifiable => distributed-key-generation/src/test/java/meerkat/crypto/secretsharing/feldman}/VerifiableSecretSharingTest.java (93%) rename {destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring => distributed-key-generation/src/test/java/meerkat/crypto/secretsharing}/shamir/PolynomialTests/AddTest.java (78%) rename {destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring => distributed-key-generation/src/test/java/meerkat/crypto/secretsharing}/shamir/PolynomialTests/InterpolationTest.java (80%) rename {destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring => distributed-key-generation/src/test/java/meerkat/crypto/secretsharing}/shamir/PolynomialTests/MulByConstTest.java (77%) rename {destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring => distributed-key-generation/src/test/java/meerkat/crypto/secretsharing}/shamir/PolynomialTests/MulTest.java (78%) rename {destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring => distributed-key-generation/src/test/java/meerkat/crypto/secretsharing}/shamir/SecretSharingTest.java (90%) rename {destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis => distributed-key-generation/src/test/java/meerkat/crypto/utils}/BigIntegerByteEncoder.java (91%) rename {destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis => distributed-key-generation/src/test/java/meerkat/crypto/utils}/ChannelImpl.java (98%) rename {destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis => distributed-key-generation/src/test/java/meerkat/crypto/utils}/GenerateRandomPolynomial.java (82%) rename {destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis => distributed-key-generation/src/test/java/meerkat/crypto/utils}/GenerateRandomPrime.java (94%) rename {destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis => distributed-key-generation/src/test/java/meerkat/crypto/utils}/Z.java (91%) rename meerkat-common/src/main/java/meerkat/{destributed_key_generation => crypto}/Digest.java (94%) rename meerkat-common/src/main/java/meerkat/{destributed_key_generation => crypto}/DigitalSignature.java (98%) rename meerkat-common/src/main/java/meerkat/{destributed_key_generation => crypto}/Encryption.java (96%) rename meerkat-common/src/main/java/meerkat/{destributed_key_generation => crypto}/concrete/ECDSADeterministicSignature.java (98%) rename meerkat-common/src/main/java/meerkat/{destributed_key_generation => crypto}/concrete/ECDSASignature.java (99%) rename meerkat-common/src/main/java/meerkat/{destributed_key_generation => crypto}/concrete/ECElGamalEncryption.java (98%) rename meerkat-common/src/main/java/meerkat/{destributed_key_generation => crypto}/concrete/GlobalCryptoSetup.java (92%) rename meerkat-common/src/main/java/meerkat/{destributed_key_generation => crypto}/concrete/SHA256Digest.java (95%) rename meerkat-common/src/main/java/meerkat/{destributed_key_generation => crypto}/mixnet/Mix2ZeroKnowledgeProver.java (93%) rename meerkat-common/src/main/java/meerkat/{destributed_key_generation => crypto}/mixnet/Mix2ZeroKnowledgeVerifier.java (92%) rename meerkat-common/src/main/java/meerkat/{destributed_key_generation => crypto}/mixnet/Mixer.java (79%) rename meerkat-common/src/main/java/meerkat/{destributed_key_generation => crypto}/mixnet/Trustee.java (56%) rename meerkat-common/src/main/java/meerkat/{destributed_key_generation => crypto}/mixnet/Verifier.java (56%) rename meerkat-common/src/test/java/meerkat/{destributed_key_generation => crypto}/concrete/ECDSADeterministicSignatureTest.java (96%) rename meerkat-common/src/test/java/meerkat/{destributed_key_generation => crypto}/concrete/ECDSASignatureTest.java (99%) rename meerkat-common/src/test/java/meerkat/{destributed_key_generation => crypto}/concrete/ECElGamalEncryptionTest.java (98%) rename meerkat-common/src/test/java/meerkat/{destributed_key_generation => crypto}/concrete/ECElGamalUtils.java (98%) diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java index b519eb4..1d0d741 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/BulletinClientWorker.java @@ -2,8 +2,8 @@ package meerkat.bulletinboard; import com.google.protobuf.Message; import meerkat.comm.CommunicationException; -import meerkat.destributed_key_generation.Digest; -import meerkat.destributed_key_generation.concrete.SHA256Digest; +import meerkat.crypto.Digest; +import meerkat.crypto.concrete.SHA256Digest; import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.rest.Constants; import meerkat.rest.ProtobufMessageBodyReader; diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java index b12649e..9d3f24a 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java @@ -2,8 +2,8 @@ package meerkat.bulletinboard; import com.google.protobuf.ByteString; import meerkat.comm.CommunicationException; -import meerkat.destributed_key_generation.Digest; -import meerkat.destributed_key_generation.concrete.SHA256Digest; +import meerkat.crypto.Digest; +import meerkat.crypto.concrete.SHA256Digest; import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.protobuf.Voting; import meerkat.protobuf.Voting.BulletinBoardClientParams; diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java index d3957cf..81513f8 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/ThreadedBulletinBoardClient.java @@ -6,8 +6,8 @@ import meerkat.bulletinboard.callbacks.GetRedundancyFutureCallback; import meerkat.bulletinboard.callbacks.PostMessageFutureCallback; import meerkat.bulletinboard.callbacks.ReadMessagesFutureCallback; import meerkat.comm.CommunicationException; -import meerkat.destributed_key_generation.Digest; -import meerkat.destributed_key_generation.concrete.SHA256Digest; +import meerkat.crypto.Digest; +import meerkat.crypto.concrete.SHA256Digest; import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.protobuf.Voting; diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java index 2c0a8d7..8402e55 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java @@ -13,8 +13,8 @@ import meerkat.comm.CommunicationException; import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.protobuf.Crypto.Signature; import meerkat.protobuf.Crypto.SignatureVerificationKey; -import meerkat.destributed_key_generation.Digest; -import meerkat.destributed_key_generation.concrete.SHA256Digest; +import meerkat.crypto.Digest; +import meerkat.crypto.concrete.SHA256Digest; import javax.sql.DataSource; diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java index fa4c60b..1c5e3c5 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java @@ -18,7 +18,7 @@ import java.util.Random; import com.google.protobuf.ByteString; import meerkat.comm.CommunicationException; -import meerkat.destributed_key_generation.concrete.ECDSASignature; +import meerkat.crypto.concrete.ECDSASignature; import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage; import meerkat.protobuf.BulletinBoardAPI.FilterType; import meerkat.protobuf.BulletinBoardAPI.MessageFilter; diff --git a/destributed-key-generation/build.gradle b/distributed-key-generation/build.gradle similarity index 100% rename from destributed-key-generation/build.gradle rename to distributed-key-generation/build.gradle diff --git a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/communication/MailHandler.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MailHandler.java similarity index 93% rename from destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/communication/MailHandler.java rename to distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MailHandler.java index cc3b08b..3c2052e 100644 --- a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/communication/MailHandler.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MailHandler.java @@ -1,7 +1,7 @@ -package meerkat.destributed_key_generation.concrete.distributed_key_generation.communication; +package meerkat.crypto.dkg.comm; import com.google.protobuf.Message; -import meerkat.destributed_key_generation.utilitis.Channel; +import meerkat.crypto.utils.Channel; import meerkat.protobuf.DKGMessages; /** diff --git a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/communication/MessageHandler.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MessageHandler.java similarity index 90% rename from destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/communication/MessageHandler.java rename to distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MessageHandler.java index 0fa7a46..c33e99a 100644 --- a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/communication/MessageHandler.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MessageHandler.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation.concrete.distributed_key_generation.communication; +package meerkat.crypto.dkg.comm; import com.google.protobuf.Message; diff --git a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/MailHandler.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/MailHandler.java similarity index 82% rename from destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/MailHandler.java rename to distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/MailHandler.java index a2d82b2..d2ca352 100644 --- a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/MailHandler.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/MailHandler.java @@ -1,15 +1,15 @@ -package meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol; +package meerkat.crypto.dkg.feldman; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; -import meerkat.destributed_key_generation.concrete.distributed_key_generation.communication.MessageHandler; +import meerkat.crypto.dkg.comm.MessageHandler; import meerkat.protobuf.DKGMessages; /** * Created by Tzlil on 2/29/2016. * an extension of MailHandler matching joint feldman protocol */ -public class MailHandler extends meerkat.destributed_key_generation.concrete.distributed_key_generation.communication.MailHandler { +public class MailHandler extends meerkat.crypto.dkg.comm.MailHandler { /** * constructor diff --git a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/Party.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/Party.java similarity index 84% rename from destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/Party.java rename to distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/Party.java index 90ee829..1b2cbe8 100644 --- a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/Party.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/Party.java @@ -1,6 +1,6 @@ -package meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol; +package meerkat.crypto.dkg.feldman; -import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; +import meerkat.crypto.secretsharing.shamir.Polynomial; import java.util.ArrayList; import java.util.Arrays; diff --git a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/Protocol.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/Protocol.java similarity index 96% rename from destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/Protocol.java rename to distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/Protocol.java index e3cddbd..616015a 100644 --- a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/Protocol.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/Protocol.java @@ -1,8 +1,8 @@ -package meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol; +package meerkat.crypto.dkg.feldman; -import meerkat.destributed_key_generation.utilitis.Channel; -import meerkat.destributed_key_generation.concrete.secret_shring.feldman_verifiable.VerifiableSecretSharing; -import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; +import meerkat.crypto.utils.Channel; +import meerkat.crypto.secretsharing.feldman.VerifiableSecretSharing; +import meerkat.crypto.secretsharing.shamir.Polynomial; import com.google.protobuf.ByteString; import meerkat.protobuf.DKGMessages; import org.factcenter.qilin.primitives.Group; diff --git a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/User.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/User.java similarity index 96% rename from destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/User.java rename to distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/User.java index 84f5bb8..eee1b85 100644 --- a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/User.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/User.java @@ -1,7 +1,7 @@ -package meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol; +package meerkat.crypto.dkg.feldman; -import meerkat.destributed_key_generation.utilitis.Channel; -import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; +import meerkat.crypto.utils.Channel; +import meerkat.crypto.secretsharing.shamir.Polynomial; import com.google.protobuf.ByteString; import com.google.protobuf.Message; import meerkat.protobuf.DKGMessages; @@ -59,7 +59,7 @@ public class User implements Runnable{ /** * mail handler registered to channel as ReceiverCallback */ - protected meerkat.destributed_key_generation.concrete.distributed_key_generation.communication.MailHandler mailHandler; + protected meerkat.crypto.dkg.comm.MailHandler mailHandler; /** * channel object @@ -360,7 +360,7 @@ public class User implements Runnable{ /** * an implementation of MessageHandler */ - public class MessageHandler implements meerkat.destributed_key_generation.concrete.distributed_key_generation.communication.MessageHandler{ + public class MessageHandler implements meerkat.crypto.dkg.comm.MessageHandler{ /** * commitment message is valid if: diff --git a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/MailHandler.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/MailHandler.java similarity index 85% rename from destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/MailHandler.java rename to distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/MailHandler.java index 5f3ee3b..f82f057 100644 --- a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/MailHandler.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/MailHandler.java @@ -1,15 +1,15 @@ -package meerkat.destributed_key_generation.concrete.distributed_key_generation.gjkr_secure_protocol; +package meerkat.crypto.dkg.gjkr; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; -import meerkat.destributed_key_generation.concrete.distributed_key_generation.communication.MessageHandler; +import meerkat.crypto.dkg.comm.MessageHandler; import meerkat.protobuf.DKGMessages; /** * Created by Tzlil on 2/29/2016. * an extension of MailHandler matching gjkr protocl */ -public class MailHandler extends meerkat.destributed_key_generation.concrete.distributed_key_generation.communication.MailHandler { +public class MailHandler extends meerkat.crypto.dkg.comm.MailHandler { /** * flag that indicants whether the diff --git a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/Party.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/Party.java similarity index 68% rename from destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/Party.java rename to distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/Party.java index d950beb..529b7be 100644 --- a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/Party.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/Party.java @@ -1,6 +1,6 @@ -package meerkat.destributed_key_generation.concrete.distributed_key_generation.gjkr_secure_protocol; +package meerkat.crypto.dkg.gjkr; -import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; +import meerkat.crypto.secretsharing.shamir.Polynomial; import java.util.ArrayList; import java.util.HashSet; @@ -13,7 +13,7 @@ import java.util.Set; * contains all relevant information on specific party during * the run of the safe protocol */ -public class Party extends meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol.Party { +public class Party extends meerkat.crypto.dkg.feldman.Party { public Polynomial.Point shareT; public boolean ysDoneFlag; public ArrayList verifiableValues; diff --git a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/Protocol.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/Protocol.java similarity index 92% rename from destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/Protocol.java rename to distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/Protocol.java index a0512d6..a98265e 100644 --- a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/Protocol.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/Protocol.java @@ -1,7 +1,7 @@ -package meerkat.destributed_key_generation.concrete.distributed_key_generation.gjkr_secure_protocol; +package meerkat.crypto.dkg.gjkr; -import meerkat.destributed_key_generation.concrete.secret_shring.feldman_verifiable.VerifiableSecretSharing; -import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; +import meerkat.crypto.secretsharing.feldman.VerifiableSecretSharing; +import meerkat.crypto.secretsharing.shamir.Polynomial; import com.google.protobuf.ByteString; import meerkat.protobuf.DKGMessages; import org.factcenter.qilin.primitives.Group; @@ -17,7 +17,7 @@ import java.util.Set; * TODO: comments * TODO: put Channel (ChannelImpl) in constructor */ -public class Protocol extends meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol.Protocol { +public class Protocol extends meerkat.crypto.dkg.feldman.Protocol { private VerifiableSecretSharing maskingShares; private final T h; diff --git a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/User.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/User.java similarity index 92% rename from destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/User.java rename to distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/User.java index 86ed127..cb4c693 100644 --- a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/User.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/User.java @@ -1,10 +1,10 @@ -package meerkat.destributed_key_generation.concrete.distributed_key_generation.gjkr_secure_protocol; +package meerkat.crypto.dkg.gjkr; -import meerkat.destributed_key_generation.utilitis.Arithmetic; -import meerkat.destributed_key_generation.utilitis.concrete.Fp; -import meerkat.destributed_key_generation.utilitis.Channel; -import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; -import meerkat.destributed_key_generation.concrete.secret_shring.shamir.SecretSharing; +import meerkat.crypto.utils.Arithmetic; +import meerkat.crypto.utils.concrete.Fp; +import meerkat.crypto.utils.Channel; +import meerkat.crypto.secretsharing.shamir.Polynomial; +import meerkat.crypto.secretsharing.shamir.SecretSharing; import com.google.protobuf.Message; import meerkat.protobuf.DKGMessages; @@ -22,7 +22,7 @@ import java.util.ArrayList; * as in joint feldman, each party in QUAL has his own share of the generated random key. * this key can be recover by any subset of QUAL of size at least t + 1. */ -public class User extends meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol.User { +public class User extends meerkat.crypto.dkg.feldman.User { /** * All parties participating in key generation. @@ -190,7 +190,7 @@ public class User extends meerkat.destributed_key_generation.concrete.distrib super.stage4(); } - private class MessageHandler extends meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol.User.MessageHandler { + private class MessageHandler extends meerkat.crypto.dkg.feldman.User.MessageHandler { boolean isStage4; /** @@ -259,10 +259,10 @@ public class User extends meerkat.destributed_key_generation.concrete.distrib synchronized (parties[i - 1]) { if (!isStage4) { if (sdkg.isValidShare(secret, secretT, parties[j - 1].verifiableValues, i)) { - parties[i - 1].complaints[j - 1] = meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol.Protocol.ComplaintState.NonDisqualified; + parties[i - 1].complaints[j - 1] = meerkat.crypto.dkg.feldman.Protocol.ComplaintState.NonDisqualified; } else { - parties[i - 1].complaints[j - 1] = meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol.Protocol.ComplaintState.Disqualified; + parties[i - 1].complaints[j - 1] = meerkat.crypto.dkg.feldman.Protocol.ComplaintState.Disqualified; } if (j == id) { parties[i - 1].share = secret; diff --git a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharing.java b/distributed-key-generation/src/main/java/meerkat/crypto/secretsharing/feldman/VerifiableSecretSharing.java similarity index 93% rename from destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharing.java rename to distributed-key-generation/src/main/java/meerkat/crypto/secretsharing/feldman/VerifiableSecretSharing.java index 1544564..0c91431 100644 --- a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharing.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/secretsharing/feldman/VerifiableSecretSharing.java @@ -1,7 +1,7 @@ -package meerkat.destributed_key_generation.concrete.secret_shring.feldman_verifiable; +package meerkat.crypto.secretsharing.feldman; -import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; -import meerkat.destributed_key_generation.concrete.secret_shring.shamir.SecretSharing; +import meerkat.crypto.secretsharing.shamir.Polynomial; +import meerkat.crypto.secretsharing.shamir.SecretSharing; import org.factcenter.qilin.primitives.Group; import java.util.ArrayList; diff --git a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/LagrangePolynomial.java b/distributed-key-generation/src/main/java/meerkat/crypto/secretsharing/shamir/LagrangePolynomial.java similarity index 94% rename from destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/LagrangePolynomial.java rename to distributed-key-generation/src/main/java/meerkat/crypto/secretsharing/shamir/LagrangePolynomial.java index 0da8f48..e12d65f 100644 --- a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/LagrangePolynomial.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/secretsharing/shamir/LagrangePolynomial.java @@ -1,6 +1,6 @@ -package meerkat.destributed_key_generation.concrete.secret_shring.shamir; +package meerkat.crypto.secretsharing.shamir; -import meerkat.destributed_key_generation.utilitis.Arithmetic; +import meerkat.crypto.utils.Arithmetic; import java.math.BigInteger; diff --git a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/Polynomial.java b/distributed-key-generation/src/main/java/meerkat/crypto/secretsharing/shamir/Polynomial.java similarity index 95% rename from destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/Polynomial.java rename to distributed-key-generation/src/main/java/meerkat/crypto/secretsharing/shamir/Polynomial.java index e0e2361..58f38fb 100644 --- a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/Polynomial.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/secretsharing/shamir/Polynomial.java @@ -1,6 +1,6 @@ -package meerkat.destributed_key_generation.concrete.secret_shring.shamir; +package meerkat.crypto.secretsharing.shamir; -import meerkat.destributed_key_generation.utilitis.Arithmetic; +import meerkat.crypto.utils.Arithmetic; import java.math.BigInteger; import java.util.Arrays; @@ -100,7 +100,7 @@ public class Polynomial implements Comparable { /** * @param other - * @return new meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial of degree max(this degree,other degree) s.t for all x + * @return new Polynomial of degree max(this degree,other degree) s.t for all x * new.evaluate(x) = this.evaluate(x) + other.evaluate(x) */ public Polynomial add(Polynomial other){ diff --git a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/SecretSharing.java b/distributed-key-generation/src/main/java/meerkat/crypto/secretsharing/shamir/SecretSharing.java similarity index 93% rename from destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/SecretSharing.java rename to distributed-key-generation/src/main/java/meerkat/crypto/secretsharing/shamir/SecretSharing.java index d5e73aa..fb86993 100644 --- a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/SecretSharing.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/secretsharing/shamir/SecretSharing.java @@ -1,7 +1,7 @@ -package meerkat.destributed_key_generation.concrete.secret_shring.shamir; +package meerkat.crypto.secretsharing.shamir; -import meerkat.destributed_key_generation.utilitis.Arithmetic; -import meerkat.destributed_key_generation.utilitis.concrete.Fp; +import meerkat.crypto.utils.Arithmetic; +import meerkat.crypto.utils.concrete.Fp; import java.math.BigInteger; import java.util.Random; diff --git a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis/Arithmetic.java b/distributed-key-generation/src/main/java/meerkat/crypto/utils/Arithmetic.java similarity index 92% rename from destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis/Arithmetic.java rename to distributed-key-generation/src/main/java/meerkat/crypto/utils/Arithmetic.java index 2aab0cf..6221a5c 100644 --- a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis/Arithmetic.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/utils/Arithmetic.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation.utilitis; +package meerkat.crypto.utils; /** * Created by Tzlil on 3/17/2016. diff --git a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis/Channel.java b/distributed-key-generation/src/main/java/meerkat/crypto/utils/Channel.java similarity index 95% rename from destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis/Channel.java rename to distributed-key-generation/src/main/java/meerkat/crypto/utils/Channel.java index 294ffaf..6f477fe 100644 --- a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis/Channel.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/utils/Channel.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation.utilitis; +package meerkat.crypto.utils; import com.google.protobuf.Message; import meerkat.protobuf.DKGMessages; diff --git a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis/concrete/Fp.java b/distributed-key-generation/src/main/java/meerkat/crypto/utils/concrete/Fp.java similarity index 88% rename from destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis/concrete/Fp.java rename to distributed-key-generation/src/main/java/meerkat/crypto/utils/concrete/Fp.java index d7d03bc..52fb324 100644 --- a/destributed-key-generation/src/main/java/meerkat/destributed_key_generation/utilitis/concrete/Fp.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/utils/concrete/Fp.java @@ -1,6 +1,6 @@ -package meerkat.destributed_key_generation.utilitis.concrete; +package meerkat.crypto.utils.concrete; -import meerkat.destributed_key_generation.utilitis.Arithmetic; +import meerkat.crypto.utils.Arithmetic; import org.factcenter.qilin.primitives.concrete.Zpstar; import java.math.BigInteger; diff --git a/meerkat-common/src/main/proto/meerkat/DKGMessages.proto b/distributed-key-generation/src/main/proto/meerkat/DKGMessages.proto similarity index 85% rename from meerkat-common/src/main/proto/meerkat/DKGMessages.proto rename to distributed-key-generation/src/main/proto/meerkat/DKGMessages.proto index 046f586..0e40e17 100644 --- a/meerkat-common/src/main/proto/meerkat/DKGMessages.proto +++ b/distributed-key-generation/src/main/proto/meerkat/DKGMessages.proto @@ -4,7 +4,7 @@ package meerkat; option java_package = "meerkat.protobuf"; -message Mail{ +message Mail { enum Type { SHARE = 0; COMMITMENT = 1; @@ -29,14 +29,14 @@ message ShareMessage { bytes share = 3; } -message DoubleShareMessage{ +message DoubleShareMessage { int32 i = 1; int32 j = 2; bytes share = 3; bytes shareT = 4; } -message CommitmentMessage{ +message CommitmentMessage { int32 k = 1; bytes commitment = 2; } diff --git a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/DKGMaliciousUser.java b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGMaliciousUser.java similarity index 89% rename from destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/DKGMaliciousUser.java rename to distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGMaliciousUser.java index 672de21..ebd2ff6 100644 --- a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/DKGMaliciousUser.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGMaliciousUser.java @@ -1,6 +1,6 @@ -package meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol; +package meerkat.crypto.dkg.feldman; -import meerkat.destributed_key_generation.utilitis.Channel; +import meerkat.crypto.utils.Channel; import java.math.BigInteger; import java.util.*; @@ -44,7 +44,7 @@ public class DKGMaliciousUser extends User { @Override public void stage1() { dkg.broadcastCommitments(); - sendSecrets(); //insteadof dkg.sendSecrets(channel); + sendSecrets(); //insteadof crypto.sendSecrets(channel); } @Override diff --git a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/DKGTest.java b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGTest.java similarity index 85% rename from destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/DKGTest.java rename to distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGTest.java index cac11df..18b3674 100644 --- a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/DKGTest.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGTest.java @@ -1,18 +1,17 @@ -package meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol; +package meerkat.crypto.dkg.feldman; -import meerkat.destributed_key_generation.utilitis.ChannelImpl; -import meerkat.destributed_key_generation.utilitis.Arithmetic; -import meerkat.destributed_key_generation.utilitis.concrete.Fp; -import meerkat.destributed_key_generation.utilitis.Channel; -import meerkat.destributed_key_generation.concrete.secret_shring.feldman_verifiable.VerifiableSecretSharing; -import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; -import meerkat.destributed_key_generation.concrete.secret_shring.shamir.SecretSharing; -import meerkat.destributed_key_generation.utilitis.BigIntegerByteEncoder; -import meerkat.destributed_key_generation.utilitis.GenerateRandomPrime; +import meerkat.crypto.utils.ChannelImpl; +import meerkat.crypto.utils.Arithmetic; +import meerkat.crypto.utils.concrete.Fp; +import meerkat.crypto.utils.Channel; +import meerkat.crypto.secretsharing.feldman.VerifiableSecretSharing; +import meerkat.crypto.secretsharing.shamir.Polynomial; +import meerkat.crypto.secretsharing.shamir.SecretSharing; +import meerkat.crypto.utils.BigIntegerByteEncoder; +import meerkat.crypto.utils.GenerateRandomPrime; import org.factcenter.qilin.primitives.Group; import org.factcenter.qilin.primitives.concrete.Zpstar; import org.factcenter.qilin.util.ByteEncoder; -import org.junit.Before; import org.junit.Test; import java.math.BigInteger; @@ -122,7 +121,7 @@ public class DKGTest { id = ids.remove(random.nextInt(ids.size())); channel = new ChannelImpl(id,n); s = randomIntModQ(random); - dkg = new meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol.Protocol(t, n, s, random, q, g, group, id,byteEncoder); + dkg = new meerkat.crypto.dkg.feldman.Protocol(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)){ diff --git a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/DKGUserImplAbort.java b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGUserImplAbort.java similarity index 88% rename from destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/DKGUserImplAbort.java rename to distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGUserImplAbort.java index dc0f419..c2b05cb 100644 --- a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/joint_feldman_protocol/DKGUserImplAbort.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGUserImplAbort.java @@ -1,6 +1,6 @@ -package meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol; +package meerkat.crypto.dkg.feldman; -import meerkat.destributed_key_generation.utilitis.Channel; +import meerkat.crypto.utils.Channel; import meerkat.protobuf.DKGMessages; /** diff --git a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGMaliciousUserImpl.java b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGMaliciousUserImpl.java similarity index 87% rename from destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGMaliciousUserImpl.java rename to distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGMaliciousUserImpl.java index 7afb60e..f72b00a 100644 --- a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGMaliciousUserImpl.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGMaliciousUserImpl.java @@ -1,6 +1,6 @@ -package meerkat.destributed_key_generation.concrete.distributed_key_generation.gjkr_secure_protocol; +package meerkat.crypto.dkg.gjkr; -import meerkat.destributed_key_generation.utilitis.Channel; +import meerkat.crypto.utils.Channel; import java.math.BigInteger; import java.util.Random; @@ -33,7 +33,7 @@ public class SDKGMaliciousUserImpl extends User { @Override public void stage1() { sdkg.computeAndBroadcastVerificationValues(); - sendSecrets(); //insteadof dkg.sendSecrets(channel); + sendSecrets(); //insteadof crypto.sendSecrets(channel); } @Override diff --git a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGTest.java b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGTest.java similarity index 86% rename from destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGTest.java rename to distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGTest.java index d296810..b5c4c9f 100644 --- a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGTest.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGTest.java @@ -1,19 +1,18 @@ -package meerkat.destributed_key_generation.concrete.distributed_key_generation.gjkr_secure_protocol; +package meerkat.crypto.dkg.gjkr; -import meerkat.destributed_key_generation.utilitis.ChannelImpl; -import meerkat.destributed_key_generation.utilitis.Arithmetic; -import meerkat.destributed_key_generation.utilitis.concrete.Fp; -import meerkat.destributed_key_generation.utilitis.Channel; -import meerkat.destributed_key_generation.concrete.secret_shring.feldman_verifiable.VerifiableSecretSharing; -import meerkat.destributed_key_generation.concrete.distributed_key_generation.joint_feldman_protocol.DKGMaliciousUser; -import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; -import meerkat.destributed_key_generation.concrete.secret_shring.shamir.SecretSharing; -import meerkat.destributed_key_generation.utilitis.BigIntegerByteEncoder; -import meerkat.destributed_key_generation.utilitis.GenerateRandomPrime; +import meerkat.crypto.utils.ChannelImpl; +import meerkat.crypto.utils.Arithmetic; +import meerkat.crypto.utils.concrete.Fp; +import meerkat.crypto.utils.Channel; +import meerkat.crypto.secretsharing.feldman.VerifiableSecretSharing; +import meerkat.crypto.dkg.feldman.DKGMaliciousUser; +import meerkat.crypto.secretsharing.shamir.Polynomial; +import meerkat.crypto.secretsharing.shamir.SecretSharing; +import meerkat.crypto.utils.BigIntegerByteEncoder; +import meerkat.crypto.utils.GenerateRandomPrime; import org.factcenter.qilin.primitives.Group; import org.factcenter.qilin.primitives.concrete.Zpstar; import org.factcenter.qilin.util.ByteEncoder; -import org.junit.Before; import org.junit.Test; import java.math.BigInteger; diff --git a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGUserImplAbort.java b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGUserImplAbort.java similarity index 89% rename from destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGUserImplAbort.java rename to distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGUserImplAbort.java index e91d87e..9fc7756 100644 --- a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/distributed_key_generation/gjkr_secure_protocol/SDKGUserImplAbort.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGUserImplAbort.java @@ -1,6 +1,6 @@ -package meerkat.destributed_key_generation.concrete.distributed_key_generation.gjkr_secure_protocol; +package meerkat.crypto.dkg.gjkr; -import meerkat.destributed_key_generation.utilitis.Channel; +import meerkat.crypto.utils.Channel; import meerkat.protobuf.DKGMessages; /** diff --git a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharingTest.java b/distributed-key-generation/src/test/java/meerkat/crypto/secretsharing/feldman/VerifiableSecretSharingTest.java similarity index 93% rename from destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharingTest.java rename to distributed-key-generation/src/test/java/meerkat/crypto/secretsharing/feldman/VerifiableSecretSharingTest.java index 1f2d15e..7992dfb 100644 --- a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/feldman_verifiable/VerifiableSecretSharingTest.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/secretsharing/feldman/VerifiableSecretSharingTest.java @@ -1,6 +1,6 @@ -package meerkat.destributed_key_generation.concrete.secret_shring.feldman_verifiable; +package meerkat.crypto.secretsharing.feldman; -import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; +import meerkat.crypto.secretsharing.shamir.Polynomial; import org.factcenter.qilin.primitives.Group; import org.factcenter.qilin.primitives.concrete.Zpstar; import org.junit.Before; diff --git a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/AddTest.java b/distributed-key-generation/src/test/java/meerkat/crypto/secretsharing/shamir/PolynomialTests/AddTest.java similarity index 78% rename from destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/AddTest.java rename to distributed-key-generation/src/test/java/meerkat/crypto/secretsharing/shamir/PolynomialTests/AddTest.java index 24c5e9f..79a9aef 100644 --- a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/AddTest.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/secretsharing/shamir/PolynomialTests/AddTest.java @@ -1,7 +1,7 @@ -package meerkat.destributed_key_generation.concrete.secret_shring.shamir.PolynomialTests; -import meerkat.destributed_key_generation.utilitis.GenerateRandomPolynomial; -import meerkat.destributed_key_generation.utilitis.Z; -import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; +package meerkat.crypto.secretsharing.shamir.PolynomialTests; +import meerkat.crypto.utils.GenerateRandomPolynomial; +import meerkat.crypto.utils.Z; +import meerkat.crypto.secretsharing.shamir.Polynomial; import org.junit.Before; import org.junit.Test; diff --git a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/InterpolationTest.java b/distributed-key-generation/src/test/java/meerkat/crypto/secretsharing/shamir/PolynomialTests/InterpolationTest.java similarity index 80% rename from destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/InterpolationTest.java rename to distributed-key-generation/src/test/java/meerkat/crypto/secretsharing/shamir/PolynomialTests/InterpolationTest.java index 9462cec..ea857f8 100644 --- a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/InterpolationTest.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/secretsharing/shamir/PolynomialTests/InterpolationTest.java @@ -1,10 +1,10 @@ -package meerkat.destributed_key_generation.concrete.secret_shring.shamir.PolynomialTests; +package meerkat.crypto.secretsharing.shamir.PolynomialTests; -import meerkat.destributed_key_generation.utilitis.Arithmetic; -import meerkat.destributed_key_generation.utilitis.concrete.Fp; -import meerkat.destributed_key_generation.utilitis.GenerateRandomPolynomial; -import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; -import meerkat.destributed_key_generation.utilitis.GenerateRandomPrime; +import meerkat.crypto.secretsharing.shamir.Polynomial; +import meerkat.crypto.utils.Arithmetic; +import meerkat.crypto.utils.concrete.Fp; +import meerkat.crypto.utils.GenerateRandomPolynomial; +import meerkat.crypto.utils.GenerateRandomPrime; import org.junit.Before; import org.junit.Test; diff --git a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/MulByConstTest.java b/distributed-key-generation/src/test/java/meerkat/crypto/secretsharing/shamir/PolynomialTests/MulByConstTest.java similarity index 77% rename from destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/MulByConstTest.java rename to distributed-key-generation/src/test/java/meerkat/crypto/secretsharing/shamir/PolynomialTests/MulByConstTest.java index f63fc2b..77afc32 100644 --- a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/MulByConstTest.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/secretsharing/shamir/PolynomialTests/MulByConstTest.java @@ -1,8 +1,8 @@ -package meerkat.destributed_key_generation.concrete.secret_shring.shamir.PolynomialTests; +package meerkat.crypto.secretsharing.shamir.PolynomialTests; -import meerkat.destributed_key_generation.utilitis.GenerateRandomPolynomial; -import meerkat.destributed_key_generation.utilitis.Z; -import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; +import meerkat.crypto.utils.GenerateRandomPolynomial; +import meerkat.crypto.utils.Z; +import meerkat.crypto.secretsharing.shamir.Polynomial; import org.junit.Before; import org.junit.Test; diff --git a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/MulTest.java b/distributed-key-generation/src/test/java/meerkat/crypto/secretsharing/shamir/PolynomialTests/MulTest.java similarity index 78% rename from destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/MulTest.java rename to distributed-key-generation/src/test/java/meerkat/crypto/secretsharing/shamir/PolynomialTests/MulTest.java index e9caa66..1f54247 100644 --- a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/PolynomialTests/MulTest.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/secretsharing/shamir/PolynomialTests/MulTest.java @@ -1,8 +1,8 @@ -package meerkat.destributed_key_generation.concrete.secret_shring.shamir.PolynomialTests; +package meerkat.crypto.secretsharing.shamir.PolynomialTests; -import meerkat.destributed_key_generation.utilitis.GenerateRandomPolynomial; -import meerkat.destributed_key_generation.utilitis.Z; -import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; +import meerkat.crypto.utils.GenerateRandomPolynomial; +import meerkat.crypto.utils.Z; +import meerkat.crypto.secretsharing.shamir.Polynomial; import org.junit.Before; import org.junit.Test; diff --git a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/SecretSharingTest.java b/distributed-key-generation/src/test/java/meerkat/crypto/secretsharing/shamir/SecretSharingTest.java similarity index 90% rename from destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/SecretSharingTest.java rename to distributed-key-generation/src/test/java/meerkat/crypto/secretsharing/shamir/SecretSharingTest.java index cf1b8d3..021b529 100644 --- a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/concrete/secret_shring/shamir/SecretSharingTest.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/secretsharing/shamir/SecretSharingTest.java @@ -1,7 +1,7 @@ -package meerkat.destributed_key_generation.concrete.secret_shring.shamir; +package meerkat.crypto.secretsharing.shamir; -import meerkat.destributed_key_generation.utilitis.concrete.Fp; -import meerkat.destributed_key_generation.utilitis.GenerateRandomPrime; +import meerkat.crypto.utils.concrete.Fp; +import meerkat.crypto.utils.GenerateRandomPrime; import org.factcenter.qilin.primitives.CyclicGroup; import org.factcenter.qilin.primitives.concrete.Zn; import org.junit.Before; diff --git a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/BigIntegerByteEncoder.java b/distributed-key-generation/src/test/java/meerkat/crypto/utils/BigIntegerByteEncoder.java similarity index 91% rename from destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/BigIntegerByteEncoder.java rename to distributed-key-generation/src/test/java/meerkat/crypto/utils/BigIntegerByteEncoder.java index 4548451..2781abb 100644 --- a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/BigIntegerByteEncoder.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/utils/BigIntegerByteEncoder.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation.utilitis; +package meerkat.crypto.utils; import java.math.BigInteger; diff --git a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/ChannelImpl.java b/distributed-key-generation/src/test/java/meerkat/crypto/utils/ChannelImpl.java similarity index 98% rename from destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/ChannelImpl.java rename to distributed-key-generation/src/test/java/meerkat/crypto/utils/ChannelImpl.java index f6e09f1..55b34fa 100644 --- a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/ChannelImpl.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/utils/ChannelImpl.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation.utilitis; +package meerkat.crypto.utils; import com.google.protobuf.Message; import meerkat.protobuf.DKGMessages; diff --git a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/GenerateRandomPolynomial.java b/distributed-key-generation/src/test/java/meerkat/crypto/utils/GenerateRandomPolynomial.java similarity index 82% rename from destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/GenerateRandomPolynomial.java rename to distributed-key-generation/src/test/java/meerkat/crypto/utils/GenerateRandomPolynomial.java index 4648598..802c479 100644 --- a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/GenerateRandomPolynomial.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/utils/GenerateRandomPolynomial.java @@ -1,7 +1,7 @@ -package meerkat.destributed_key_generation.utilitis; +package meerkat.crypto.utils; -import meerkat.destributed_key_generation.concrete.secret_shring.shamir.Polynomial; -import meerkat.destributed_key_generation.utilitis.concrete.Fp; +import meerkat.crypto.secretsharing.shamir.Polynomial; +import meerkat.crypto.utils.concrete.Fp; import java.math.BigInteger; import java.util.Random; diff --git a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/GenerateRandomPrime.java b/distributed-key-generation/src/test/java/meerkat/crypto/utils/GenerateRandomPrime.java similarity index 94% rename from destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/GenerateRandomPrime.java rename to distributed-key-generation/src/test/java/meerkat/crypto/utils/GenerateRandomPrime.java index a0bee5a..b2969bf 100644 --- a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/GenerateRandomPrime.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/utils/GenerateRandomPrime.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation.utilitis; +package meerkat.crypto.utils; import java.math.BigInteger; import java.util.Random; diff --git a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/Z.java b/distributed-key-generation/src/test/java/meerkat/crypto/utils/Z.java similarity index 91% rename from destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/Z.java rename to distributed-key-generation/src/test/java/meerkat/crypto/utils/Z.java index fecd227..1814f7e 100644 --- a/destributed-key-generation/src/test/java/meerkat/destributed_key_generation/utilitis/Z.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/utils/Z.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation.utilitis; +package meerkat.crypto.utils; import java.math.BigInteger; diff --git a/meerkat-common/src/main/java/meerkat/destributed_key_generation/Digest.java b/meerkat-common/src/main/java/meerkat/crypto/Digest.java similarity index 94% rename from meerkat-common/src/main/java/meerkat/destributed_key_generation/Digest.java rename to meerkat-common/src/main/java/meerkat/crypto/Digest.java index 97b141e..06b012c 100644 --- a/meerkat-common/src/main/java/meerkat/destributed_key_generation/Digest.java +++ b/meerkat-common/src/main/java/meerkat/crypto/Digest.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation; +package meerkat.crypto; import com.google.protobuf.Message; diff --git a/meerkat-common/src/main/java/meerkat/destributed_key_generation/DigitalSignature.java b/meerkat-common/src/main/java/meerkat/crypto/DigitalSignature.java similarity index 98% rename from meerkat-common/src/main/java/meerkat/destributed_key_generation/DigitalSignature.java rename to meerkat-common/src/main/java/meerkat/crypto/DigitalSignature.java index 0dd76d0..e7b64e5 100644 --- a/meerkat-common/src/main/java/meerkat/destributed_key_generation/DigitalSignature.java +++ b/meerkat-common/src/main/java/meerkat/crypto/DigitalSignature.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation; +package meerkat.crypto; import com.google.protobuf.ByteString; import com.google.protobuf.Message; diff --git a/meerkat-common/src/main/java/meerkat/destributed_key_generation/Encryption.java b/meerkat-common/src/main/java/meerkat/crypto/Encryption.java similarity index 96% rename from meerkat-common/src/main/java/meerkat/destributed_key_generation/Encryption.java rename to meerkat-common/src/main/java/meerkat/crypto/Encryption.java index 69b22b5..6a40d0d 100644 --- a/meerkat-common/src/main/java/meerkat/destributed_key_generation/Encryption.java +++ b/meerkat-common/src/main/java/meerkat/crypto/Encryption.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation; +package meerkat.crypto; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; diff --git a/meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/ECDSADeterministicSignature.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSADeterministicSignature.java similarity index 98% rename from meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/ECDSADeterministicSignature.java rename to meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSADeterministicSignature.java index 3e8b36f..0afbdd7 100644 --- a/meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/ECDSADeterministicSignature.java +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSADeterministicSignature.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation.concrete; +package meerkat.crypto.concrete; import com.google.protobuf.ByteString; import com.google.protobuf.Message; diff --git a/meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/ECDSASignature.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java similarity index 99% rename from meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/ECDSASignature.java rename to meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java index 5578421..887b8e8 100644 --- a/meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/ECDSASignature.java +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECDSASignature.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation.concrete; +package meerkat.crypto.concrete; import java.io.IOException; import java.io.InputStream; @@ -16,7 +16,7 @@ import org.slf4j.LoggerFactory; import com.google.protobuf.Message; -import meerkat.destributed_key_generation.DigitalSignature; +import meerkat.crypto.DigitalSignature; import meerkat.protobuf.Crypto.Signature; import javax.security.auth.callback.Callback; diff --git a/meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/ECElGamalEncryption.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java similarity index 98% rename from meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/ECElGamalEncryption.java rename to meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java index 973b3c7..6258f5f 100644 --- a/meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/ECElGamalEncryption.java +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/ECElGamalEncryption.java @@ -1,9 +1,9 @@ -package meerkat.destributed_key_generation.concrete; +package meerkat.crypto.concrete; import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; -import meerkat.destributed_key_generation.Encryption; +import meerkat.crypto.Encryption; import meerkat.protobuf.ConcreteCrypto; import meerkat.protobuf.Crypto; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; diff --git a/meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/GlobalCryptoSetup.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/GlobalCryptoSetup.java similarity index 92% rename from meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/GlobalCryptoSetup.java rename to meerkat-common/src/main/java/meerkat/crypto/concrete/GlobalCryptoSetup.java index 7efc793..4f2e7a5 100644 --- a/meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/GlobalCryptoSetup.java +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/GlobalCryptoSetup.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation.concrete; +package meerkat.crypto.concrete; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.slf4j.Logger; @@ -8,7 +8,7 @@ import java.security.Provider; import java.security.Security; /** - * A class that performs required destributed_key_generation setup + * A class that performs required crypto setup */ public class GlobalCryptoSetup { final static Logger logger = LoggerFactory.getLogger(GlobalCryptoSetup.class); diff --git a/meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/SHA256Digest.java b/meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java similarity index 95% rename from meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/SHA256Digest.java rename to meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java index 6c2fce2..4f60af3 100644 --- a/meerkat-common/src/main/java/meerkat/destributed_key_generation/concrete/SHA256Digest.java +++ b/meerkat-common/src/main/java/meerkat/crypto/concrete/SHA256Digest.java @@ -1,8 +1,8 @@ -package meerkat.destributed_key_generation.concrete; +package meerkat.crypto.concrete; import com.google.protobuf.ByteString; import com.google.protobuf.Message; -import meerkat.destributed_key_generation.Digest; +import meerkat.crypto.Digest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Mix2ZeroKnowledgeProver.java b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mix2ZeroKnowledgeProver.java similarity index 93% rename from meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Mix2ZeroKnowledgeProver.java rename to meerkat-common/src/main/java/meerkat/crypto/mixnet/Mix2ZeroKnowledgeProver.java index aa63aeb..1113bfd 100644 --- a/meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Mix2ZeroKnowledgeProver.java +++ b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mix2ZeroKnowledgeProver.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation.mixnet; +package meerkat.crypto.mixnet; import meerkat.protobuf.Crypto; import meerkat.protobuf.Mixing; diff --git a/meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Mix2ZeroKnowledgeVerifier.java b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mix2ZeroKnowledgeVerifier.java similarity index 92% rename from meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Mix2ZeroKnowledgeVerifier.java rename to meerkat-common/src/main/java/meerkat/crypto/mixnet/Mix2ZeroKnowledgeVerifier.java index 6faf0ca..dd3c251 100644 --- a/meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Mix2ZeroKnowledgeVerifier.java +++ b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mix2ZeroKnowledgeVerifier.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation.mixnet; +package meerkat.crypto.mixnet; import meerkat.protobuf.Crypto; import meerkat.protobuf.Mixing; diff --git a/meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Mixer.java b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mixer.java similarity index 79% rename from meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Mixer.java rename to meerkat-common/src/main/java/meerkat/crypto/mixnet/Mixer.java index 2b6d3e8..52e8844 100644 --- a/meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Mixer.java +++ b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Mixer.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation.mixnet; +package meerkat.crypto.mixnet; import java.util.List; import static meerkat.protobuf.Voting.*; diff --git a/meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Trustee.java b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Trustee.java similarity index 56% rename from meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Trustee.java rename to meerkat-common/src/main/java/meerkat/crypto/mixnet/Trustee.java index ded66c5..e8044cd 100644 --- a/meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Trustee.java +++ b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Trustee.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation.mixnet; +package meerkat.crypto.mixnet; /** * Created by talm on 25/10/15. diff --git a/meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Verifier.java b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Verifier.java similarity index 56% rename from meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Verifier.java rename to meerkat-common/src/main/java/meerkat/crypto/mixnet/Verifier.java index 18271ed..b733317 100644 --- a/meerkat-common/src/main/java/meerkat/destributed_key_generation/mixnet/Verifier.java +++ b/meerkat-common/src/main/java/meerkat/crypto/mixnet/Verifier.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation.mixnet; +package meerkat.crypto.mixnet; /** * Created by talm on 25/10/15. diff --git a/meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECDSADeterministicSignatureTest.java b/meerkat-common/src/test/java/meerkat/crypto/concrete/ECDSADeterministicSignatureTest.java similarity index 96% rename from meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECDSADeterministicSignatureTest.java rename to meerkat-common/src/test/java/meerkat/crypto/concrete/ECDSADeterministicSignatureTest.java index 86ae311..4baa741 100644 --- a/meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECDSADeterministicSignatureTest.java +++ b/meerkat-common/src/test/java/meerkat/crypto/concrete/ECDSADeterministicSignatureTest.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation.concrete; +package meerkat.crypto.concrete; import com.google.protobuf.ByteString; import com.google.protobuf.Message; diff --git a/meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECDSASignatureTest.java b/meerkat-common/src/test/java/meerkat/crypto/concrete/ECDSASignatureTest.java similarity index 99% rename from meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECDSASignatureTest.java rename to meerkat-common/src/test/java/meerkat/crypto/concrete/ECDSASignatureTest.java index 9e90cce..e5b448d 100644 --- a/meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECDSASignatureTest.java +++ b/meerkat-common/src/test/java/meerkat/crypto/concrete/ECDSASignatureTest.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation.concrete; +package meerkat.crypto.concrete; import com.google.protobuf.ByteString; import com.google.protobuf.Message; diff --git a/meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECElGamalEncryptionTest.java b/meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalEncryptionTest.java similarity index 98% rename from meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECElGamalEncryptionTest.java rename to meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalEncryptionTest.java index b09fbce..81375e0 100644 --- a/meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECElGamalEncryptionTest.java +++ b/meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalEncryptionTest.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation.concrete; +package meerkat.crypto.concrete; import meerkat.protobuf.ConcreteCrypto; import meerkat.protobuf.Crypto; diff --git a/meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECElGamalUtils.java b/meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalUtils.java similarity index 98% rename from meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECElGamalUtils.java rename to meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalUtils.java index 9b5de78..66e1647 100644 --- a/meerkat-common/src/test/java/meerkat/destributed_key_generation/concrete/ECElGamalUtils.java +++ b/meerkat-common/src/test/java/meerkat/crypto/concrete/ECElGamalUtils.java @@ -1,4 +1,4 @@ -package meerkat.destributed_key_generation.concrete; +package meerkat.crypto.concrete; import com.google.protobuf.ByteString; import com.google.protobuf.GeneratedMessage; diff --git a/settings.gradle b/settings.gradle index f019032..236a0d1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -4,5 +4,5 @@ include 'bulletin-board-server' include 'polling-station' include 'restful-api-common' include 'bulletin-board-client' -include 'destributed-key-generation' +include 'distributed-key-generation' From 78207532ecc3c129eedd9e18597d673114a997a0 Mon Sep 17 00:00:00 2001 From: Tal Moran Date: Mon, 11 Apr 2016 20:51:40 +0300 Subject: [PATCH 42/49] protobuf naming convention --- .../src/main/proto/meerkat/DKGMessages.proto | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/distributed-key-generation/src/main/proto/meerkat/DKGMessages.proto b/distributed-key-generation/src/main/proto/meerkat/DKGMessages.proto index 0e40e17..c7d9cba 100644 --- a/distributed-key-generation/src/main/proto/meerkat/DKGMessages.proto +++ b/distributed-key-generation/src/main/proto/meerkat/DKGMessages.proto @@ -18,7 +18,7 @@ message Mail { } int32 sender = 1; int32 destination = 2; - bool isPrivate = 3; + bool is_private = 3; Type type = 4; bytes message = 5; } @@ -33,7 +33,7 @@ message DoubleShareMessage { int32 i = 1; int32 j = 2; bytes share = 3; - bytes shareT = 4; + bytes share_t = 4; } message CommitmentMessage { From c798e827dcfaa0f1f7ada51d501dfc9d0dbe9656 Mon Sep 17 00:00:00 2001 From: Tal Moran Date: Tue, 12 Apr 2016 02:21:46 +0300 Subject: [PATCH 43/49] More renaming and refactoring of DKG code --- .../meerkat/crypto/dkg/comm/MailHandler.java | 56 +--- .../crypto/dkg/comm/MessageHandler.java | 63 ++-- .../meerkat/crypto/dkg/comm/MessageUtils.java | 36 +++ .../crypto/dkg/feldman/MailHandler.java | 34 +- .../meerkat/crypto/dkg/feldman/Protocol.java | 25 +- .../java/meerkat/crypto/dkg/feldman/User.java | 214 +++++++------ .../meerkat/crypto/dkg/gjkr/MailHandler.java | 37 +-- .../meerkat/crypto/dkg/gjkr/Protocol.java | 27 +- .../java/meerkat/crypto/dkg/gjkr/User.java | 302 +++++++++--------- .../java/meerkat/crypto/utils/Channel.java | 16 +- .../meerkat/{DKGMessages.proto => DKG.proto} | 40 +-- .../crypto/dkg/feldman/DKGUserImplAbort.java | 6 +- .../crypto/dkg/gjkr/SDKGUserImplAbort.java | 5 +- .../meerkat/crypto/utils/ChannelImpl.java | 28 +- 14 files changed, 429 insertions(+), 460 deletions(-) create mode 100644 distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MessageUtils.java rename distributed-key-generation/src/main/proto/meerkat/{DKGMessages.proto => DKG.proto} (63%) diff --git a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MailHandler.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MailHandler.java index 3c2052e..5cd1be0 100644 --- a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MailHandler.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MailHandler.java @@ -1,8 +1,11 @@ package meerkat.crypto.dkg.comm; +import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; import meerkat.crypto.utils.Channel; -import meerkat.protobuf.DKGMessages; +import meerkat.protobuf.DKG; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Created by Tzlil on 2/14/2016. @@ -10,6 +13,7 @@ import meerkat.protobuf.DKGMessages; * an implementation of ReceiverCallback */ public abstract class MailHandler implements Channel.ReceiverCallback{ + final Logger logger = LoggerFactory.getLogger(getClass()); /** * fixed value for broadcasting @@ -30,50 +34,20 @@ public abstract class MailHandler implements Channel.ReceiverCallback{ } /** - * extract message from mail - * @param mail - * @return + * Was this broadcastMessage was received by broadcast channel + * @param broadcastMessage + * @return broadcastMessage user destination == BROADCAST */ - public abstract Message extractMessage(DKGMessages.Mail mail); - - /** - * is this mail was received by broadcast channel - * @param mail - * @return mail user destination == BROADCAST - */ - public boolean isBroadcast(DKGMessages.Mail mail){ - return mail.getDestination() == BROADCAST; + public boolean isBroadcast(DKG.BroadcastMessage broadcastMessage){ + return broadcastMessage.getDestination() == BROADCAST; } @Override - public void receiveMail(DKGMessages.Mail mail){ - Message message = extractMessage(mail); - if (message == null) - return; - - switch (mail.getType()) { - case SHARE: - messageHandler.handleShareMessage(mail.getSender(), isBroadcast(mail),message); - break; - case COMMITMENT: - messageHandler.handleCommitmentMessage(mail.getSender(), isBroadcast(mail),message); - break; - case DONE: - messageHandler.handleDoneMessage(mail.getSender(), isBroadcast(mail),message); - break; - case COMPLAINT: - messageHandler.handleComplaintMessage(mail.getSender(), isBroadcast(mail),message); - break; - case ANSWER: - messageHandler.handleAnswerMessage(mail.getSender(), isBroadcast(mail),message); - break; - case ABORT: - messageHandler.handleAbortMessage(mail.getSender(), isBroadcast(mail),message); - break; - default: - break; + public void receiveMail(DKG.BroadcastMessage envelope) { + try { + messageHandler.handleMessage(envelope); + } catch (InvalidProtocolBufferException e) { + logger.warn("Received invalid protocol buffer from channel", e); } - - } } diff --git a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MessageHandler.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MessageHandler.java index c33e99a..4927e94 100644 --- a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MessageHandler.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MessageHandler.java @@ -1,39 +1,50 @@ package meerkat.crypto.dkg.comm; +import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; +import meerkat.protobuf.DKG; /** * Created by Tzlil on 2/14/2016. * an interface for handling received messages */ public interface MessageHandler { - /** - * handle share message - */ - void handleShareMessage(int sender, boolean isBroadcast, Message message); /** - * handle commitment message + * Handle a broadcast (or unicast) message. + * If the message is invalid, the handler can throw an {@link InvalidProtocolBufferException}, in which + * case the message will simply be ignored. + * @param envelope */ - void handleCommitmentMessage(int sender, boolean isBroadcast, Message message); - - /** - * handle complaint message - */ - void handleComplaintMessage(int sender, boolean isBroadcast, Message message); - - /** - * handle done message - */ - void handleDoneMessage(int sender, boolean isBroadcast, Message message); - - /** - * handle answer message - */ - void handleAnswerMessage(int sender, boolean isBroadcast, Message message); - - /** - * handle abort message - */ - void handleAbortMessage(int sender, boolean isBroadcast, Message message); + void handleMessage(DKG.BroadcastMessage envelope) throws InvalidProtocolBufferException; +// +// /** +// * handle share message +// */ +// void handleShareMessage(int sender, boolean isBroadcast, Message message); +// +// /** +// * handle commitment message +// */ +// void handleCommitmentMessage(int sender, boolean isBroadcast, Message message); +// +// /** +// * handle complaint message +// */ +// void handleComplaintMessage(int sender, boolean isBroadcast, Message message); +// +// /** +// * handle done message +// */ +// void handleDoneMessage(int sender, boolean isBroadcast, Message message); +// +// /** +// * handle answer message +// */ +// void handleAnswerMessage(int sender, boolean isBroadcast, Message message); +// +// /** +// * handle abort message +// */ +// void handleAbortMessage(int sender, boolean isBroadcast, Message message); } diff --git a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MessageUtils.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MessageUtils.java new file mode 100644 index 0000000..a0cb79a --- /dev/null +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MessageUtils.java @@ -0,0 +1,36 @@ +package meerkat.crypto.dkg.comm; + +import meerkat.protobuf.DKG; + +/** + * Created by talm on 12/04/16. + */ +public class MessageUtils { + public static DKG.Payload createMessage(DKG.Payload.Type type) { + return DKG.Payload.newBuilder().setType(type).build(); + } + + public static DKG.Payload createMessage(DKG.Payload.Type type, DKG.ShareMessage share) { + return DKG.Payload.newBuilder().setType(type).setShare(share).build(); + } + + public static DKG.Payload createMessage(DKG.Payload.Type type, DKG.ShareMessage.Builder share) { + return DKG.Payload.newBuilder().setType(type).setShare(share).build(); + } + + public static DKG.Payload createMessage(DKG.Payload.Type type, DKG.IDMessage id) { + return DKG.Payload.newBuilder().setType(type).setId(id).build(); + } + + public static DKG.Payload createMessage(DKG.Payload.Type type, DKG.IDMessage.Builder id) { + return DKG.Payload.newBuilder().setType(type).setId(id).build(); + } + + public static DKG.Payload createMessage(DKG.Payload.Type type, DKG.CommitmentMessage commitment) { + return DKG.Payload.newBuilder().setType(type).setCommitment(commitment).build(); + } + + public static DKG.Payload createMessage(DKG.Payload.Type type, DKG.CommitmentMessage.Builder commitment) { + return DKG.Payload.newBuilder().setType(type).setCommitment(commitment).build(); + } +} diff --git a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/MailHandler.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/MailHandler.java index d2ca352..dabfa17 100644 --- a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/MailHandler.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/MailHandler.java @@ -3,7 +3,7 @@ package meerkat.crypto.dkg.feldman; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; import meerkat.crypto.dkg.comm.MessageHandler; -import meerkat.protobuf.DKGMessages; +import meerkat.protobuf.DKG; /** * Created by Tzlil on 2/29/2016. @@ -18,36 +18,4 @@ public class MailHandler extends meerkat.crypto.dkg.comm.MailHandler { public MailHandler(MessageHandler messageHandler) { super(messageHandler); } - - @Override - public Message extractMessage(DKGMessages.Mail mail) { - try { - Message message; - switch (mail.getType()) { - case SHARE: - message = DKGMessages.ShareMessage.parseFrom(mail.getMessage()); - break; - case COMMITMENT: - message = DKGMessages.CommitmentMessage.parseFrom(mail.getMessage()); - break; - case COMPLAINT: - message = DKGMessages.IDMessage.parseFrom(mail.getMessage()); - break; - case DONE: - message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); - break; - case ANSWER: - message = DKGMessages.ShareMessage.parseFrom(mail.getMessage()); - break; - case ABORT: - message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); - break; - default: - return null; - } - return message; - } catch (InvalidProtocolBufferException e) { - return null; - } - } } diff --git a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/Protocol.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/Protocol.java index 616015a..74d35d4 100644 --- a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/Protocol.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/Protocol.java @@ -4,13 +4,15 @@ import meerkat.crypto.utils.Channel; import meerkat.crypto.secretsharing.feldman.VerifiableSecretSharing; import meerkat.crypto.secretsharing.shamir.Polynomial; import com.google.protobuf.ByteString; -import meerkat.protobuf.DKGMessages; +import meerkat.protobuf.DKG; import org.factcenter.qilin.primitives.Group; import org.factcenter.qilin.util.ByteEncoder; import java.math.BigInteger; import java.util.*; +import static meerkat.crypto.dkg.comm.MessageUtils.*; + /** * Created by Tzlil on 3/14/2016. * @@ -126,13 +128,13 @@ public class Protocol extends VerifiableSecretSharing { * @param commitments */ public void broadcastCommitments(ArrayList commitments){ - DKGMessages.CommitmentMessage commitmentMessage; + DKG.CommitmentMessage commitmentMessage; for (int k = 0; k <= t ; k++){ - commitmentMessage = DKGMessages.CommitmentMessage.newBuilder() + commitmentMessage = DKG.CommitmentMessage.newBuilder() .setCommitment(ByteString.copyFrom(encoder.encode(commitments.get(k)))) .setK(k) .build(); - channel.broadcastMessage(DKGMessages.Mail.Type.COMMITMENT, commitmentMessage); + channel.broadcastMessage(createMessage(DKG.Payload.Type.COMMITMENT, commitmentMessage)); } } @@ -142,12 +144,12 @@ public class Protocol extends VerifiableSecretSharing { */ public void sendSecret(int j){ ByteString secret = ByteString.copyFrom(getShare(j).y.toByteArray()); - channel.sendMessage(j, DKGMessages.Mail.Type.SHARE, - DKGMessages.ShareMessage.newBuilder() + channel.sendMessage(j, createMessage(DKG.Payload.Type.SHARE, + DKG.ShareMessage.newBuilder() .setI(id) .setJ(j) .setShare(secret) - .build()); + )); } /** @@ -207,10 +209,10 @@ public class Protocol extends VerifiableSecretSharing { */ private void broadcastComplaint(int i){ //message = new Message(Type.Complaint, j) - DKGMessages.IDMessage complaint = DKGMessages.IDMessage.newBuilder() + DKG.IDMessage complaint = DKG.IDMessage.newBuilder() .setId(i) .build(); - channel.broadcastMessage(DKGMessages.Mail.Type.COMPLAINT, complaint); + channel.broadcastMessage(createMessage(DKG.Payload.Type.COMPLAINT, complaint)); } /** @@ -218,11 +220,10 @@ public class Protocol extends VerifiableSecretSharing { * @param j */ public void broadcastComplaintAnswer(int j){ - channel.broadcastMessage(DKGMessages.Mail.Type.ANSWER, DKGMessages.ShareMessage.newBuilder() + channel.broadcastMessage(createMessage(DKG.Payload.Type.ANSWER, DKG.ShareMessage.newBuilder() .setI(id) .setJ(j) - .setShare(ByteString.copyFrom(getShare(j).y.toByteArray())) - .build()); + .setShare(ByteString.copyFrom(getShare(j).y.toByteArray())))); } /** diff --git a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/User.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/User.java index eee1b85..4e4f155 100644 --- a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/User.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/User.java @@ -1,16 +1,19 @@ package meerkat.crypto.dkg.feldman; +import com.google.protobuf.InvalidProtocolBufferException; import meerkat.crypto.utils.Channel; import meerkat.crypto.secretsharing.shamir.Polynomial; import com.google.protobuf.ByteString; import com.google.protobuf.Message; -import meerkat.protobuf.DKGMessages; +import meerkat.protobuf.DKG; import org.factcenter.qilin.primitives.Group; import java.math.BigInteger; import java.util.ArrayList; import java.util.Set; +import static meerkat.crypto.dkg.comm.MessageUtils.createMessage; + /** * Created by Tzlil on 3/14/2016. * @@ -176,11 +179,10 @@ public class User implements Runnable{ * 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(){ + protected void stage2() { dkg.broadcastComplaints(); //broadcast done message after all complaints - DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build(); - channel.broadcastMessage(DKGMessages.Mail.Type.DONE,doneMessage); + channel.broadcastMessage(createMessage(DKG.Payload.Type.DONE)); } @@ -360,35 +362,19 @@ public class User implements Runnable{ /** * an implementation of MessageHandler */ - public class MessageHandler implements meerkat.crypto.dkg.comm.MessageHandler{ + public class MessageHandler implements meerkat.crypto.dkg.comm.MessageHandler { /** * commitment message is valid if: * 1. it was received in broadcast chanel * 2. the sender didn't sent this commitment before */ - protected boolean isValidCommitmentMessage(int sender, boolean isBroadcast, DKGMessages.CommitmentMessage commitmentMessage){ + protected boolean isValidCommitmentMessage(int sender, boolean isBroadcast, DKG.CommitmentMessage commitmentMessage){ int i = sender - 1; int k = commitmentMessage.getK(); return isBroadcast && parties[i].commitments.get(k) == null; } - /** - * saves the commitment - */ - @Override - public void handleCommitmentMessage(int sender, boolean isBroadcast, Message message) { - DKGMessages.CommitmentMessage commitmentMessage = (DKGMessages.CommitmentMessage) message; - if(isValidCommitmentMessage(sender,isBroadcast,commitmentMessage)){ - int i = sender - 1; - int k = commitmentMessage.getK(); - synchronized (parties[i]) { - parties[i].commitments.set(k, extractCommitment(commitmentMessage)); - parties[i].notify(); - } - } - } - /** * secret message is valid if: * 1. it was received in private chanel @@ -396,7 +382,7 @@ public class User implements Runnable{ * 3. secret.i == i * 4. secret.j == id */ - protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKGMessages.ShareMessage secretMessage){ + protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKG.ShareMessage secretMessage){ int i = secretMessage.getI(); int j = secretMessage.getJ(); if(sender != i || isBroadcast) @@ -406,22 +392,6 @@ public class User implements Runnable{ } - /** - * saves the secret - */ - @Override - public void handleShareMessage(int sender, boolean isBroadcast, Message message) { - DKGMessages.ShareMessage secretMessage = (DKGMessages.ShareMessage) message; - if(isValidSecretMessage(sender,isBroadcast,secretMessage)) { - int i = secretMessage.getI(); - Polynomial.Point secret = extractShare(id,secretMessage.getShare()); - synchronized (parties[i -1]) { - parties[i - 1].share = secret; - parties[i - 1].notify(); - } - } - } - /** * done message is valid if: * 1. it was received in broadcast chanel @@ -431,46 +401,18 @@ public class User implements Runnable{ return isBroadcast && !parties[sender - 1].doneFlag; } - /** - * marks that the sender was finished sending all his complaints - */ - @Override - public void handleDoneMessage(int sender, boolean isBroadcast, Message message) { - if(isValidDoneMessage(sender,isBroadcast)) { - synchronized (parties[sender - 1]) { - parties[sender - 1].doneFlag = true; - parties[sender - 1].notify(); - } - } - } /** * complaint message is valid if: * 1. it was received in broadcast chanel * 2. the sender didn't complained against id before */ - protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, DKGMessages.IDMessage complaintMessage){ + protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, DKG.IDMessage complaintMessage){ int i = sender; int j = complaintMessage.getId(); return isBroadcast && parties[i - 1].complaints[j - 1].equals( Protocol.ComplaintState.OK); } - /** - * marks that the sender was complained against id - */ - @Override - 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(); - synchronized (parties[j - 1]) { - parties[j - 1].complaints[i - 1] = Protocol.ComplaintState.Waiting; - parties[j - 1].notify(); - } - } - } - /** * answer message is valid if: * 1. it was received in broadcast chanel @@ -478,7 +420,7 @@ public class User implements Runnable{ * 3. 1 <= secret.j <= n * 4. it is marked that j complained against i and i didn't received */ - protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKGMessages.ShareMessage secretMessage){ + protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKG.ShareMessage secretMessage){ int i = secretMessage.getI(); int j = secretMessage.getJ(); if(sender != i || !isBroadcast) @@ -487,40 +429,108 @@ public class User implements Runnable{ return j >= 1 && j <= n && parties[i - 1].complaints[j - 1].equals(Protocol.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.getShare()); - synchronized (parties[i - 1]) { - if (dkg.isValidShare(secret, parties[i - 1].commitments, j)) { - parties[i - 1].complaints[j - 1] = Protocol.ComplaintState.NonDisqualified; - } else { - parties[i - 1].complaints[j - 1] = Protocol.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(); + public void handleMessage(DKG.BroadcastMessage envelope) throws InvalidProtocolBufferException { + int sender = envelope.getSender(); + boolean isBroadcast = !envelope.getIsPrivate(); + DKG.Payload msg = DKG.Payload.parseFrom(envelope.getPayload()); + + switch (msg.getType()) { + case COMMITMENT: + /** + * saves the commitment + */ + DKG.CommitmentMessage commitmentMessage = msg.getCommitment(); + if (isValidCommitmentMessage(sender, isBroadcast, commitmentMessage)) { + int i = sender - 1; + int k = commitmentMessage.getK(); + synchronized (parties[i]) { + parties[i].commitments.set(k, extractCommitment(commitmentMessage)); + parties[i].notify(); + } + } + break; + + + case SHARE: + /** + * saves the secret + */ + DKG.ShareMessage secretMessage = msg.getShare(); + if(isValidSecretMessage(sender,isBroadcast,secretMessage)) { + int i = secretMessage.getI(); + Polynomial.Point secret = extractShare(id,secretMessage.getShare()); + synchronized (parties[i -1]) { + parties[i - 1].share = secret; + parties[i - 1].notify(); + } + } + break; + + case DONE: + + /** + * marks that the sender was finished sending all his complaints + */ + if(isValidDoneMessage(sender,isBroadcast)) { + synchronized (parties[sender - 1]) { + parties[sender - 1].doneFlag = true; + parties[sender - 1].notify(); + } + } + break; + + case COMPLAINT: + /** + * marks that the sender was complained against id + */ + DKG.IDMessage complaintMessage = msg.getId(); + if(isValidComplaintMessage(sender,isBroadcast,complaintMessage)){ + int i = sender; + int j = complaintMessage.getId(); + synchronized (parties[j - 1]) { + parties[j - 1].complaints[i - 1] = Protocol.ComplaintState.Waiting; + parties[j - 1].notify(); + } + } + break; + case ANSWER: + /** + * 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 + */ + secretMessage = msg.getShare(); + if(isValidAnswerMessage(sender,isBroadcast,secretMessage)) { + int i = secretMessage.getI(); + int j = secretMessage.getJ(); + Polynomial.Point secret = extractShare(j,secretMessage.getShare()); + synchronized (parties[i - 1]) { + if (dkg.isValidShare(secret, parties[i - 1].commitments, j)) { + parties[i - 1].complaints[j - 1] = Protocol.ComplaintState.NonDisqualified; + } else { + parties[i - 1].complaints[j - 1] = Protocol.ComplaintState.Disqualified; + } + if (j == id) { + parties[i - 1].share = secret; + } + parties[i - 1].notify(); + } + } + break; + case ABORT: + /** + * marks that the sender was aborted + */ + synchronized (parties[sender - 1]) { + parties[sender - 1].aborted = true; + parties[sender - 1].notify(); + } + break; + + + } } @@ -541,7 +551,7 @@ public class User implements Runnable{ * @param commitmentMessage * @return */ - public T extractCommitment(DKGMessages.CommitmentMessage commitmentMessage){ + public T extractCommitment(DKG.CommitmentMessage commitmentMessage){ return dkg.decodeCommitment(commitmentMessage.getCommitment().toByteArray()); } } diff --git a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/MailHandler.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/MailHandler.java index f82f057..36f970e 100644 --- a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/MailHandler.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/MailHandler.java @@ -3,7 +3,7 @@ package meerkat.crypto.dkg.gjkr; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; import meerkat.crypto.dkg.comm.MessageHandler; -import meerkat.protobuf.DKGMessages; +import meerkat.protobuf.DKG; /** * Created by Tzlil on 2/29/2016. @@ -26,41 +26,6 @@ public class MailHandler extends meerkat.crypto.dkg.comm.MailHandler { this.isStage4 = false; } - @Override - public Message extractMessage(DKGMessages.Mail mail) { - try { - Message message; - switch (mail.getType()) { - case SHARE: - message = DKGMessages.DoubleShareMessage.parseFrom(mail.getMessage()); - break; - case COMMITMENT: - message = DKGMessages.CommitmentMessage.parseFrom(mail.getMessage()); - break; - case COMPLAINT: - if(!isStage4) - message = DKGMessages.IDMessage.parseFrom(mail.getMessage()); - else - message = DKGMessages.DoubleShareMessage.parseFrom(mail.getMessage()); - break; - case DONE: - message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); - break; - case ANSWER: - message = DKGMessages.DoubleShareMessage.parseFrom(mail.getMessage()); - break; - case ABORT: - message = DKGMessages.EmptyMessage.parseFrom(mail.getMessage()); - break; - default: - return null; - } - return message; - } catch (InvalidProtocolBufferException e) { - return null; - } - } - /** * setter * @param stage4 diff --git a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/Protocol.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/Protocol.java index a98265e..aad773c 100644 --- a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/Protocol.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/Protocol.java @@ -1,9 +1,10 @@ package meerkat.crypto.dkg.gjkr; +import meerkat.crypto.dkg.comm.MessageUtils; import meerkat.crypto.secretsharing.feldman.VerifiableSecretSharing; import meerkat.crypto.secretsharing.shamir.Polynomial; import com.google.protobuf.ByteString; -import meerkat.protobuf.DKGMessages; +import meerkat.protobuf.DKG; import org.factcenter.qilin.primitives.Group; import org.factcenter.qilin.util.ByteEncoder; @@ -52,9 +53,9 @@ public class Protocol extends meerkat.crypto.dkg.feldman.Protocol { public void sendSecret(int j) { Polynomial.Point secret = getShare(j); Polynomial.Point secretT = maskingShares.getShare(j); - DKGMessages.DoubleShareMessage doubleSecretMessage = doubleShareMessage(id,j,secret,secretT); + DKG.ShareMessage doubleSecretMessage = createShareMessage(id,j,secret,secretT); // TODO: Change SHARE to SHARE - channel.sendMessage(j, DKGMessages.Mail.Type.SHARE, doubleSecretMessage); + channel.sendMessage(j, MessageUtils.createMessage(DKG.Payload.Type.SHARE, doubleSecretMessage)); } @@ -90,8 +91,8 @@ public class Protocol extends meerkat.crypto.dkg.feldman.Protocol { * @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); + DKG.ShareMessage complaint = createShareMessage(i,id,share,shareT); + channel.broadcastMessage(MessageUtils.createMessage(DKG.Payload.Type.COMPLAINT, complaint)); } /** @@ -124,7 +125,7 @@ public class Protocol extends meerkat.crypto.dkg.feldman.Protocol { } /** - * pack share, shareT i,j to doubleShareMessage + * pack share, shareT i,j to createShareMessage * @param i * @param j * @param share @@ -132,26 +133,26 @@ public class Protocol extends meerkat.crypto.dkg.feldman.Protocol { * @return */ - private DKGMessages.DoubleShareMessage doubleShareMessage(int i, int j, Polynomial.Point share, Polynomial.Point shareT){ - DKGMessages.DoubleShareMessage doubleShareMessage = DKGMessages.DoubleShareMessage.newBuilder() + private DKG.ShareMessage createShareMessage(int i, int j, Polynomial.Point share, Polynomial.Point shareT){ + DKG.ShareMessage ShareMessage = DKG.ShareMessage.newBuilder() .setI(i) .setJ(j) .setShare(ByteString.copyFrom(share.y.toByteArray())) .setShareT(ByteString.copyFrom(shareT.y.toByteArray())) .build(); - return doubleShareMessage; + return ShareMessage; } @Override public void broadcastComplaintAnswer(int j) { - DKGMessages.DoubleShareMessage answer = doubleShareMessage(id,j,getShare(j) + DKG.ShareMessage answer = createShareMessage(id,j,getShare(j) , maskingShares.getShare(j)); - channel.broadcastMessage(DKGMessages.Mail.Type.ANSWER,answer); + channel.broadcastMessage(MessageUtils.createMessage(DKG.Payload.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); + DKG.ShareMessage complaint = createShareMessage(i,id,secret,secretT); + channel.broadcastMessage(MessageUtils.createMessage(DKG.Payload.Type.ANSWER,complaint)); } /** diff --git a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/User.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/User.java index cb4c693..6a3e0a4 100644 --- a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/User.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/User.java @@ -1,25 +1,28 @@ package meerkat.crypto.dkg.gjkr; +import com.google.protobuf.InvalidProtocolBufferException; import meerkat.crypto.utils.Arithmetic; import meerkat.crypto.utils.concrete.Fp; import meerkat.crypto.utils.Channel; import meerkat.crypto.secretsharing.shamir.Polynomial; import meerkat.crypto.secretsharing.shamir.SecretSharing; import com.google.protobuf.Message; -import meerkat.protobuf.DKGMessages; +import meerkat.protobuf.DKG; import java.math.BigInteger; import java.util.ArrayList; +import static meerkat.crypto.dkg.comm.MessageUtils.*; + /** * Created by Tzlil on 3/16/2016. - * + *

* implementation of gjkr protocol user. - * - * this protocol extends joint feldman protocol by splitting the protocol to commitment stage (stages 1,2,3) - * and reviling stage (stage 4). - * - * as in joint feldman, each party in QUAL has his own share of the generated random key. + *

+ * this protocol extends joint Feldman protocol by splitting the protocol to commitment stage (stages 1,2,3) + * and revealing stage (stage 4). + *

+ * as in joint Feldman, each party in QUAL has his own share of the generated random key. * this key can be recover by any subset of QUAL of size at least t + 1. */ public class User extends meerkat.crypto.dkg.feldman.User { @@ -42,7 +45,8 @@ public class User extends meerkat.crypto.dkg.feldman.User { /** * constructor - * @param sdkg gjkr protocol object + * + * @param sdkg gjkr protocol object * @param channel channel object */ public User(Protocol sdkg, Channel channel) { @@ -52,15 +56,16 @@ public class User extends meerkat.crypto.dkg.feldman.User { } @Override - protected void registerReceiverCallback(){ + protected void registerReceiverCallback() { this.messageHandler = new MessageHandler(); this.mailHandler = new MailHandler(messageHandler); this.channel.registerReceiverCallback(mailHandler); } + /** * stage1 according to the protocol - * 1. Pi broadcasts Cik=Aik*Bik for k = 0,...,t. - * 2. Pi computes the shares Sij,Sij' for j = 1,...,n and sends Sij,Sij' secretly to Pj. + * 1. Pi broadcasts Cik=Aik*Bik for k = 0,...,t. + * 2. Pi computes the shares Sij,Sij' for j = 1,...,n and sends Sij,Sij' secretly to Pj. */ @Override protected void stage1() { @@ -69,11 +74,11 @@ public class User extends meerkat.crypto.dkg.feldman.User { } @Override - protected void waitUntilStageOneCompleted(){ + protected void waitUntilStageOneCompleted() { super.waitUntilStageOneCompleted(); // save the received commitments as verification values ArrayList temp; - for (int i = 0 ; i < n; i++){ + for (int i = 0; i < n; i++) { temp = parties[i].verifiableValues; parties[i].verifiableValues = parties[i].commitments; parties[i].commitments = temp; @@ -82,26 +87,25 @@ public class User extends meerkat.crypto.dkg.feldman.User { /** * stage2 according to the protocol - * Pj verifies all the shares,sharesT he received - * if check fails for an index i, Pj broadcasts a complaint against Pi. - * Pj broadcasts done message at the end of this stage + * Pj verifies all the shares,sharesT he received + * if check fails for an index i, Pj broadcasts a complaint against Pi. + * Pj broadcasts done message at the end of this stage */ @Override - protected void stage2(){ + protected void stage2() { sdkg.broadcastComplaints(); //broadcast done message after all complaints - DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build(); - channel.broadcastMessage(DKGMessages.Mail.Type.DONE,doneMessage); + channel.broadcastMessage(createMessage(DKG.Payload.Type.DONE)); } /** * broadcast commitments and recover parties information if necessary */ - private void resolveQualifyingPublicKey(){ + private void resolveQualifyingPublicKey() { sdkg.broadcastCommitments(); // wait until all parties in QUAL broadcast their commitments or aborted - for (int i:QUAL) { - for(int k = 0; k <= t; k++) { + for (int i : QUAL) { + for (int k = 0; k <= t; k++) { synchronized (parties[i - 1]) { while (parties[i - 1].commitments.get(k) == null && !parties[i - 1].aborted) { try { @@ -115,11 +119,9 @@ public class User extends meerkat.crypto.dkg.feldman.User { } sdkg.computeAndBroadcastComplaints(QUAL); //broadcast done message after all complaints - DKGMessages.EmptyMessage doneMessage = DKGMessages.EmptyMessage.newBuilder().build(); - channel.broadcastMessage(DKGMessages.Mail.Type.DONE,doneMessage); - + channel.broadcastMessage(createMessage(DKG.Payload.Type.DONE)); // wait until all parties in QUAL done or aborted - for (int i:QUAL) { + for (int i : QUAL) { synchronized ((parties[i - 1])) { while (!parties[i - 1].ysDoneFlag && !parties[i - 1].aborted) { try { @@ -132,13 +134,13 @@ public class User extends meerkat.crypto.dkg.feldman.User { } // broadcast i private secret foreach i in QUAL that aborted - for (int i:QUAL) { - if(parties[i - 1].aborted){ + for (int i : QUAL) { + if (parties[i - 1].aborted) { sdkg.broadcastAnswer(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) { + for (int i : QUAL) { synchronized ((parties[i - 1])) { if (parties[i - 1].aborted) { while (parties[i - 1].recoverSharesSet.size() <= t) { @@ -153,33 +155,33 @@ public class User extends meerkat.crypto.dkg.feldman.User { } Arithmetic arithmetic = new Fp(sdkg.getQ()); // restore necessary information - for (int i = 0; i < n ; i++) { - if(parties[i].recoverSharesSet.isEmpty()){ + for (int i = 0; i < n; i++) { + if (parties[i].recoverSharesSet.isEmpty()) { continue; } Polynomial.Point[] shares = new Polynomial.Point[t + 1]; int j = 0; - for (Polynomial.Point share: parties[i].recoverSharesSet){ + for (Polynomial.Point share : parties[i].recoverSharesSet) { shares[j++] = share; - if (j >= shares.length){ + if (j >= shares.length) { break; } } - Polynomial polynomial = SecretSharing.recoverPolynomial(shares,arithmetic); + Polynomial polynomial = SecretSharing.recoverPolynomial(shares, arithmetic); BigInteger[] coefficients = polynomial.getCoefficients(); - for (int k = 0 ; k <= t; k++){ - parties[i].commitments.add(k,group.multiply(g,coefficients[k])); + for (int k = 0; k <= t; k++) { + parties[i].commitments.add(k, group.multiply(g, coefficients[k])); } - parties[i].share = new Polynomial.Point(BigInteger.valueOf(id),polynomial); + parties[i].share = new Polynomial.Point(BigInteger.valueOf(id), polynomial); } } /** * notifies mail handler and message handler that stage 4 was started */ - protected void setStage4(){ + protected void setStage4() { this.messageHandler.isStage4 = true; - ((MailHandler)this.mailHandler).setStage4(true); + ((MailHandler) this.mailHandler).setStage4(true); } @Override @@ -193,158 +195,148 @@ public class User extends meerkat.crypto.dkg.feldman.User { private class MessageHandler extends meerkat.crypto.dkg.feldman.User.MessageHandler { boolean isStage4; - /** - * 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() - .setI(doubleSecretMessage.getI()) - .setJ(doubleSecretMessage.getJ()) - .setShare(doubleSecretMessage.getShare()) - .build(); - return super.isValidSecretMessage(sender,isBroadcast,secretMessage); - } - - /** - * as in super, with extension to double secret message - */ - @Override - public void handleShareMessage(int sender, boolean isBroadcast, Message message) { - DKGMessages.DoubleShareMessage doubleSecretMessage = (DKGMessages.DoubleShareMessage)message; - if (isValidSecretMessage(sender,isBroadcast,doubleSecretMessage)) { - int i = doubleSecretMessage.getI(); - synchronized (parties[i - 1]) { - parties[i - 1].share = extractShare(id, doubleSecretMessage.getShare()); - parties[i - 1].shareT = extractShare(id, doubleSecretMessage.getShareT()); - parties[i - 1].notify(); - } - } - } /** * if !isStage4 as super, with extension to double secret message * else answer message is valid if: - * 1. it was received in broadcast chanel - * 2. secret.j == sender - * 3. QUAL contains i and j + * 1. it was received in broadcast chanel + * 2. secret.j == sender + * 3. QUAL contains i and j */ - protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKGMessages.DoubleShareMessage doubleSecretMessage) { - if(!isStage4) { - DKGMessages.ShareMessage secretMessage = DKGMessages.ShareMessage.newBuilder() - .setI(doubleSecretMessage.getI()) - .setJ(doubleSecretMessage.getJ()) - .setShare(doubleSecretMessage.getShare()) - .build(); - return super.isValidAnswerMessage(sender, isBroadcast, secretMessage); - }else{ + protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKG.ShareMessage doubleSecretMessage) { + if (!isStage4) { + return super.isValidAnswerMessage(sender, isBroadcast, doubleSecretMessage); + } else { int i = doubleSecretMessage.getI(); int j = doubleSecretMessage.getJ(); - return isBroadcast && j == sender && parties[i -1].aborted && !parties[j - 1].aborted + return isBroadcast && j == sender && parties[i - 1].aborted && !parties[j - 1].aborted && QUAL.contains(i) && QUAL.contains(j); } } - /** - * if !isStage4 as super, with extension to double secret message - * else saves secret - */ - @Override - public void handleAnswerMessage(int sender, boolean isBroadcast, Message message) { - DKGMessages.DoubleShareMessage doubleSecretMessage = (DKGMessages.DoubleShareMessage)message; - if(isValidAnswerMessage(sender,isBroadcast,doubleSecretMessage)) { - int i = doubleSecretMessage.getI(); - int j = doubleSecretMessage.getJ(); - Polynomial.Point secret = extractShare(j, doubleSecretMessage.getShare()); - Polynomial.Point secretT = extractShare(j, doubleSecretMessage.getShareT()); - synchronized (parties[i - 1]) { - if (!isStage4) { - if (sdkg.isValidShare(secret, secretT, parties[j - 1].verifiableValues, i)) { - parties[i - 1].complaints[j - 1] = meerkat.crypto.dkg.feldman.Protocol.ComplaintState.NonDisqualified; - - } else { - parties[i - 1].complaints[j - 1] = meerkat.crypto.dkg.feldman.Protocol.ComplaintState.Disqualified; - } - if (j == id) { - parties[i - 1].share = secret; - parties[i - 1].shareT = secretT; - } - } else if (sdkg.isValidShare(secret, secretT, parties[i - 1].verifiableValues, j)) { - parties[i - 1].recoverSharesSet.add(secret); - } - parties[i - 1].notify(); - } - } - } /** * as in super with respect to protocol stage */ @Override protected boolean isValidDoneMessage(int sender, boolean isBroadcast) { - if(!isStage4) { + if (!isStage4) { return super.isValidDoneMessage(sender, isBroadcast); - }else{ - return isBroadcast && !parties[sender - 1].ysDoneFlag; - } - } - - /** - * as in super with respect to protocol state - */ - @Override - public void handleDoneMessage(int sender, boolean isBroadcast, Message message) { - if(!isStage4) - super.handleDoneMessage(sender, isBroadcast, message); - else{ - if(isValidDoneMessage(sender,isBroadcast)) { - synchronized (parties[sender - 1]) { - parties[sender - 1].ysDoneFlag = true; - parties[sender - 1].notify(); - } - } + } else { + return isBroadcast && !parties[sender - 1].ysDoneFlag; } } /** * use only in stage4 * complaint message is valid if: - * 1. it was received in broadcast chanel - * 2. secret.j == sender - * 3. QUAL contains i and j + * 1. it was received in broadcast chanel + * 2. secret.j == sender + * 3. QUAL contains i and j */ protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, - DKGMessages.DoubleShareMessage complaintMessage){ + DKG.ShareMessage complaintMessage) { int i = complaintMessage.getI(); int j = complaintMessage.getJ(); 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 - * 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.getShare()); - Polynomial.Point secretT = extractShare(i,ysComplaintMessage.getShareT()); - if (sdkg.isValidShare(secret, secretT, parties[i - 1].verifiableValues, j) - && !dkg.isValidShare(secret,parties[i - 1].commitments, j)) { + public void handleMessage(DKG.BroadcastMessage envelope) throws InvalidProtocolBufferException { + int sender = envelope.getSender(); + boolean isBroadcast = !envelope.getIsPrivate(); + DKG.Payload msg = DKG.Payload.parseFrom(envelope.getPayload()); + switch (msg.getType()) { + case SHARE: + /** + * as in super, with extension to double secret message + */ + DKG.ShareMessage doubleSecretMessage = msg.getShare(); + if (isValidSecretMessage(sender, isBroadcast, doubleSecretMessage)) { + int i = doubleSecretMessage.getI(); synchronized (parties[i - 1]) { - parties[i - 1].aborted = true; + parties[i - 1].share = extractShare(id, doubleSecretMessage.getShare()); + parties[i - 1].shareT = extractShare(id, doubleSecretMessage.getShareT()); parties[i - 1].notify(); } } - } + break; + case ANSWER: + /** + * if !isStage4 as super, with extension to double secret message + * else saves secret + */ + doubleSecretMessage = msg.getShare(); + if (isValidAnswerMessage(sender, isBroadcast, doubleSecretMessage)) { + int i = doubleSecretMessage.getI(); + int j = doubleSecretMessage.getJ(); + Polynomial.Point secret = extractShare(j, doubleSecretMessage.getShare()); + Polynomial.Point secretT = extractShare(j, doubleSecretMessage.getShareT()); + synchronized (parties[i - 1]) { + if (!isStage4) { + if (sdkg.isValidShare(secret, secretT, parties[j - 1].verifiableValues, i)) { + parties[i - 1].complaints[j - 1] = meerkat.crypto.dkg.feldman.Protocol.ComplaintState.NonDisqualified; + + } else { + parties[i - 1].complaints[j - 1] = meerkat.crypto.dkg.feldman.Protocol.ComplaintState.Disqualified; + } + if (j == id) { + parties[i - 1].share = secret; + parties[i - 1].shareT = secretT; + } + } else if (sdkg.isValidShare(secret, secretT, parties[i - 1].verifiableValues, j)) { + parties[i - 1].recoverSharesSet.add(secret); + } + parties[i - 1].notify(); + } + } + break; + case DONE: + /** + * as in super with respect to protocol state + */ + if (!isStage4) + super.handleMessage(envelope); + else { + if (isValidDoneMessage(sender, isBroadcast)) { + synchronized (parties[sender - 1]) { + parties[sender - 1].ysDoneFlag = true; + parties[sender - 1].notify(); + } + } + } + break; + case COMPLAINT: + /** + * 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 + * marks i as aborted + */ + if (!isStage4) { + super.handleMessage(envelope); + } else { + DKG.ShareMessage ysComplaintMessage = msg.getShare(); + if (isValidComplaintMessage(sender, isBroadcast, ysComplaintMessage)) { + int i = ysComplaintMessage.getI(); + int j = ysComplaintMessage.getJ(); + Polynomial.Point secret = extractShare(i, ysComplaintMessage.getShare()); + Polynomial.Point secretT = extractShare(i, ysComplaintMessage.getShareT()); + 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(); + } + } + } + } + break; + default: + super.handleMessage(envelope); + break; } } } -} +} \ No newline at end of file diff --git a/distributed-key-generation/src/main/java/meerkat/crypto/utils/Channel.java b/distributed-key-generation/src/main/java/meerkat/crypto/utils/Channel.java index 6f477fe..97a6060 100644 --- a/distributed-key-generation/src/main/java/meerkat/crypto/utils/Channel.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/utils/Channel.java @@ -1,32 +1,36 @@ package meerkat.crypto.utils; import com.google.protobuf.Message; -import meerkat.protobuf.DKGMessages; +import meerkat.protobuf.DKG; /** * A generic communication channel that supports point-to-point and broadcast operation */ public interface Channel { + /** + * Return the id of the channel's endpoint (this will be used as the source of message sent from the channel). + * @return + */ + public int getSourceId(); + public interface ReceiverCallback { - public void receiveMail(DKGMessages.Mail mail); + public void receiveMail(DKG.BroadcastMessage envelope); } /** * sends a private message * @param destUser destination user's identifier - * @param type message type * @param msg message */ - public void sendMessage(int destUser, DKGMessages.Mail.Type type, Message msg); + public void sendMessage(int destUser, Message msg); /** * broadcasts a message to all parties (including the sender) - * @param type message type * @param msg message */ - public void broadcastMessage(DKGMessages.Mail.Type type, Message msg); + public void broadcastMessage(Message msg); /** * Register a callback to handle received messages. diff --git a/distributed-key-generation/src/main/proto/meerkat/DKGMessages.proto b/distributed-key-generation/src/main/proto/meerkat/DKG.proto similarity index 63% rename from distributed-key-generation/src/main/proto/meerkat/DKGMessages.proto rename to distributed-key-generation/src/main/proto/meerkat/DKG.proto index c7d9cba..235f062 100644 --- a/distributed-key-generation/src/main/proto/meerkat/DKGMessages.proto +++ b/distributed-key-generation/src/main/proto/meerkat/DKG.proto @@ -4,7 +4,15 @@ package meerkat; option java_package = "meerkat.protobuf"; -message Mail { +message BroadcastMessage { + int32 sender = 1; + int32 destination = 2; + bool is_private = 3; + + bytes payload = 5; +} + +message Payload { enum Type { SHARE = 0; COMMITMENT = 1; @@ -16,23 +24,25 @@ message Mail { YANSWER = 7; ABORT = 8; } - int32 sender = 1; - int32 destination = 2; - bool is_private = 3; - Type type = 4; - bytes message = 5; + + Type type = 1; + + oneof specific { + IDMessage id = 5; + ShareMessage share = 6; + CommitmentMessage commitment = 7; + } +} + +message IDMessage { + int32 id = 1; } message ShareMessage { int32 i = 1; int32 j = 2; bytes share = 3; -} - -message DoubleShareMessage { - int32 i = 1; - int32 j = 2; - bytes share = 3; + // For double shares (used in GJKR protocol) bytes share_t = 4; } @@ -40,9 +50,3 @@ message CommitmentMessage { int32 k = 1; bytes commitment = 2; } - -message EmptyMessage{} - -message IDMessage{ - int32 id = 1; -} diff --git a/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGUserImplAbort.java b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGUserImplAbort.java index c2b05cb..902d103 100644 --- a/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGUserImplAbort.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGUserImplAbort.java @@ -1,7 +1,9 @@ package meerkat.crypto.dkg.feldman; import meerkat.crypto.utils.Channel; -import meerkat.protobuf.DKGMessages; +import meerkat.protobuf.DKG; + +import static meerkat.crypto.dkg.comm.MessageUtils.createMessage; /** * Created by Tzlil on 3/14/2016. @@ -18,7 +20,7 @@ public class DKGUserImplAbort extends User { private void sendAbort(){ - channel.broadcastMessage(DKGMessages.Mail.Type.ABORT,DKGMessages.EmptyMessage.getDefaultInstance()); + channel.broadcastMessage(createMessage(DKG.Payload.Type.ABORT)); } @Override diff --git a/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGUserImplAbort.java b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGUserImplAbort.java index 9fc7756..b067c1a 100644 --- a/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGUserImplAbort.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGUserImplAbort.java @@ -1,7 +1,8 @@ package meerkat.crypto.dkg.gjkr; +import meerkat.crypto.dkg.comm.MessageUtils; import meerkat.crypto.utils.Channel; -import meerkat.protobuf.DKGMessages; +import meerkat.protobuf.DKG; /** * Created by Tzlil on 3/14/2016. @@ -18,7 +19,7 @@ public class SDKGUserImplAbort extends User { private void abort(){ //stopReceiver(); - channel.broadcastMessage(DKGMessages.Mail.Type.ABORT,DKGMessages.EmptyMessage.getDefaultInstance()); + channel.broadcastMessage(MessageUtils.createMessage(DKG.Payload.Type.ABORT)); } @Override diff --git a/distributed-key-generation/src/test/java/meerkat/crypto/utils/ChannelImpl.java b/distributed-key-generation/src/test/java/meerkat/crypto/utils/ChannelImpl.java index 55b34fa..dfb1bfb 100644 --- a/distributed-key-generation/src/test/java/meerkat/crypto/utils/ChannelImpl.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/utils/ChannelImpl.java @@ -1,7 +1,7 @@ package meerkat.crypto.utils; import com.google.protobuf.Message; -import meerkat.protobuf.DKGMessages; +import meerkat.protobuf.DKG; import java.util.Queue; import java.util.concurrent.ArrayBlockingQueue; @@ -16,7 +16,7 @@ public class ChannelImpl implements Channel { public static int BROADCAST = 0; private static ChannelImpl[] channels = null; - protected final Queue mailbox; + protected final Queue mailbox; protected final int id; protected final int n; protected Thread receiverThread; @@ -26,50 +26,50 @@ public class ChannelImpl implements Channel { if (channels == null){ channels = new ChannelImpl[n]; } - this.mailbox = new ArrayBlockingQueue( n * n * n); + this.mailbox = new ArrayBlockingQueue( n * n * n); this.id = id; this.n = n; channels[id - 1] = this; } - public int getId() { + @Override + public int getSourceId() { return id; } + @Override - public void sendMessage(int destUser, DKGMessages.Mail.Type type, Message msg) { + public void sendMessage(int destUser, Message msg) { if(destUser < 1 || destUser > n) return; ChannelImpl channel = channels[destUser - 1]; if (channel == null) return; - DKGMessages.Mail mail = DKGMessages.Mail.newBuilder() + DKG.BroadcastMessage broadcastMessage = DKG.BroadcastMessage.newBuilder() .setSender(id) .setDestination(destUser) .setIsPrivate(true) - .setType(type) - .setMessage(msg.toByteString()) + .setPayload(msg.toByteString()) .build(); synchronized (channel.mailbox) { - channel.mailbox.add(mail); + channel.mailbox.add(broadcastMessage); channel.mailbox.notify(); } } @Override - public void broadcastMessage(DKGMessages.Mail.Type type,Message msg) { + public void broadcastMessage(Message msg) { ChannelImpl channel; - DKGMessages.Mail mail = DKGMessages.Mail.newBuilder() + DKG.BroadcastMessage broadcastMessage = DKG.BroadcastMessage.newBuilder() .setSender(id) .setDestination(BROADCAST) .setIsPrivate(false) - .setType(type) - .setMessage(msg.toByteString()) + .setPayload(msg.toByteString()) .build(); for (int i = 0 ; i < n ; i++){ channel = channels[i]; synchronized (channel.mailbox) { - channel.mailbox.add(mail); + channel.mailbox.add(broadcastMessage); channel.mailbox.notify(); } } From 1f8df95895e7f17d709fe299200072a11c2fdf45 Mon Sep 17 00:00:00 2001 From: Tal Moran Date: Thu, 14 Apr 2016 03:34:54 +0300 Subject: [PATCH 44/49] More refactoring for tests and protocol -- user class now handles all messages synchronously (in the main thread); concurrency is now simpler) --- distributed-key-generation/build.gradle | 3 + .../meerkat/crypto/dkg/comm/MailHandler.java | 53 -- .../crypto/dkg/comm/MessageHandler.java | 67 ++- .../crypto/dkg/feldman/MailHandler.java | 21 - .../meerkat/crypto/dkg/feldman/Protocol.java | 59 +- .../java/meerkat/crypto/dkg/feldman/User.java | 530 +++++++++--------- .../meerkat/crypto/dkg/gjkr/MailHandler.java | 36 -- .../java/meerkat/crypto/dkg/gjkr/User.java | 411 +++++++------- .../src/main/proto/meerkat/DKG.proto | 12 +- .../crypto/dkg/feldman/DKGMaliciousUser.java | 2 +- .../meerkat/crypto/dkg/feldman/DKGTest.java | 16 +- .../crypto/dkg/feldman/DKGUserImplAbort.java | 2 +- .../dkg/gjkr/SDKGMaliciousUserImpl.java | 2 +- .../meerkat/crypto/dkg/gjkr/SDKGTest.java | 129 +++-- .../crypto/dkg/gjkr/SDKGUserImplAbort.java | 18 +- .../meerkat/crypto/utils/ChannelImpl.java | 111 ---- .../src/main/java/meerkat/comm}/Channel.java | 6 +- .../src/main/proto/meerkat/comm.proto | 13 + .../test/java/meerkat/comm/ChannelImpl.java | 96 ++++ 19 files changed, 780 insertions(+), 807 deletions(-) delete mode 100644 distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MailHandler.java delete mode 100644 distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/MailHandler.java delete mode 100644 distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/MailHandler.java delete mode 100644 distributed-key-generation/src/test/java/meerkat/crypto/utils/ChannelImpl.java rename {distributed-key-generation/src/main/java/meerkat/crypto/utils => meerkat-common/src/main/java/meerkat/comm}/Channel.java (89%) create mode 100644 meerkat-common/src/main/proto/meerkat/comm.proto create mode 100644 meerkat-common/src/test/java/meerkat/comm/ChannelImpl.java diff --git a/distributed-key-generation/build.gradle b/distributed-key-generation/build.gradle index 074667f..8f0a397 100644 --- a/distributed-key-generation/build.gradle +++ b/distributed-key-generation/build.gradle @@ -49,6 +49,9 @@ dependencies { // Google protobufs compile 'com.google.protobuf:protobuf-java:3.+' + // Depend on test resources from meerkat-common + testCompile project(path: ':meerkat-common', configuration: 'testOutput') + testCompile 'junit:junit:4.+' runtime 'org.codehaus.groovy:groovy:2.4.+' diff --git a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MailHandler.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MailHandler.java deleted file mode 100644 index 5cd1be0..0000000 --- a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MailHandler.java +++ /dev/null @@ -1,53 +0,0 @@ -package meerkat.crypto.dkg.comm; - -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Message; -import meerkat.crypto.utils.Channel; -import meerkat.protobuf.DKG; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Created by Tzlil on 2/14/2016. - * - * an implementation of ReceiverCallback - */ -public abstract class MailHandler implements Channel.ReceiverCallback{ - final Logger logger = LoggerFactory.getLogger(getClass()); - - /** - * fixed value for broadcasting - */ - public static final int BROADCAST = 0; - - /** - * message handler - */ - private MessageHandler messageHandler; - - /** - * constructor - * @param messageHandler - */ - public MailHandler(MessageHandler messageHandler){ - this.messageHandler = messageHandler; - } - - /** - * Was this broadcastMessage was received by broadcast channel - * @param broadcastMessage - * @return broadcastMessage user destination == BROADCAST - */ - public boolean isBroadcast(DKG.BroadcastMessage broadcastMessage){ - return broadcastMessage.getDestination() == BROADCAST; - } - - @Override - public void receiveMail(DKG.BroadcastMessage envelope) { - try { - messageHandler.handleMessage(envelope); - } catch (InvalidProtocolBufferException e) { - logger.warn("Received invalid protocol buffer from channel", e); - } - } -} diff --git a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MessageHandler.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MessageHandler.java index 4927e94..02c751b 100644 --- a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MessageHandler.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/comm/MessageHandler.java @@ -1,50 +1,47 @@ package meerkat.crypto.dkg.comm; import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Message; -import meerkat.protobuf.DKG; +import meerkat.comm.Channel; +import meerkat.protobuf.Comm; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Created by Tzlil on 2/14/2016. - * an interface for handling received messages + * + * an implementation of ReceiverCallback */ -public interface MessageHandler { +public abstract class MessageHandler implements Channel.ReceiverCallback { + final Logger logger = LoggerFactory.getLogger(getClass()); /** + * fixed value for broadcasting + */ + public static final int BROADCAST = 0; + + /** * Handle a broadcast (or unicast) message. * If the message is invalid, the handler can throw an {@link InvalidProtocolBufferException}, in which * case the message will simply be ignored. * @param envelope */ - void handleMessage(DKG.BroadcastMessage envelope) throws InvalidProtocolBufferException; -// -// /** -// * handle share message -// */ -// void handleShareMessage(int sender, boolean isBroadcast, Message message); -// -// /** -// * handle commitment message -// */ -// void handleCommitmentMessage(int sender, boolean isBroadcast, Message message); -// -// /** -// * handle complaint message -// */ -// void handleComplaintMessage(int sender, boolean isBroadcast, Message message); -// -// /** -// * handle done message -// */ -// void handleDoneMessage(int sender, boolean isBroadcast, Message message); -// -// /** -// * handle answer message -// */ -// void handleAnswerMessage(int sender, boolean isBroadcast, Message message); -// -// /** -// * handle abort message -// */ -// void handleAbortMessage(int sender, boolean isBroadcast, Message message); + public abstract void handleMessage(Comm.BroadcastMessage envelope) throws InvalidProtocolBufferException; + + /** + * Was this broadcastMessage was received by broadcast channel + * @param broadcastMessage + * @return broadcastMessage user destination == BROADCAST + */ + public boolean isBroadcast(Comm.BroadcastMessage broadcastMessage){ + return broadcastMessage.getDestination() == BROADCAST; + } + + @Override + public void receiveMessage(Comm.BroadcastMessage envelope) { + try { + handleMessage(envelope); + } catch (InvalidProtocolBufferException e) { + logger.warn("Received invalid protocol buffer from channel", e); + } + } } diff --git a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/MailHandler.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/MailHandler.java deleted file mode 100644 index dabfa17..0000000 --- a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/MailHandler.java +++ /dev/null @@ -1,21 +0,0 @@ -package meerkat.crypto.dkg.feldman; - -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Message; -import meerkat.crypto.dkg.comm.MessageHandler; -import meerkat.protobuf.DKG; - -/** - * Created by Tzlil on 2/29/2016. - * an extension of MailHandler matching joint feldman protocol - */ -public class MailHandler extends meerkat.crypto.dkg.comm.MailHandler { - - /** - * constructor - * @param messageHandler - */ - public MailHandler(MessageHandler messageHandler) { - super(messageHandler); - } -} diff --git a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/Protocol.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/Protocol.java index 74d35d4..d81c75a 100644 --- a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/Protocol.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/Protocol.java @@ -1,6 +1,6 @@ package meerkat.crypto.dkg.feldman; -import meerkat.crypto.utils.Channel; +import meerkat.comm.Channel; import meerkat.crypto.secretsharing.feldman.VerifiableSecretSharing; import meerkat.crypto.secretsharing.shamir.Polynomial; import com.google.protobuf.ByteString; @@ -171,7 +171,9 @@ public class Protocol extends VerifiableSecretSharing { */ public boolean isValidShare(int i){ Party party = parties[i - 1]; - return isValidShare(party.share,party.commitments,id); + synchronized (parties[i - 1]) { + return isValidShare(party.share, party.commitments, id); + } } /** @@ -232,7 +234,7 @@ public class Protocol extends VerifiableSecretSharing { */ public void answerAllComplainingPlayers(){ ComplaintState[] complaints = parties[id - 1].complaints; - for (int i = 1; i <= n ; i++) { + for (int i = 1; i <= n; i++) { switch (complaints[i - 1]) { case Waiting: broadcastComplaintAnswer(i); @@ -241,6 +243,7 @@ public class Protocol extends VerifiableSecretSharing { break; } } + } /** @@ -252,26 +255,28 @@ public class Protocol extends VerifiableSecretSharing { Set QUAL = new HashSet(); boolean nonDisqualified; int counter; - for (int i = 1; i <= n; i++){ - ComplaintState[] complaints = parties[i - 1].complaints; - nonDisqualified = true; - counter = 0; - for (int j = 1; j <= n; j++){ - switch (complaints[j - 1]) { - case OK: - break; - case NonDisqualified: - counter++; - break; - default: - nonDisqualified = false; + for (int i = 1; i <= n; i++) { + synchronized (parties[i - 1]) { + ComplaintState[] complaints = parties[i - 1].complaints; + nonDisqualified = true; + counter = 0; + for (int j = 1; j <= n; j++) { + switch (complaints[j - 1]) { + case OK: + break; + case NonDisqualified: + counter++; + break; + default: + nonDisqualified = false; + break; + } + if (!nonDisqualified) break; } - if(!nonDisqualified) - break; - } - if(nonDisqualified && counter <= t){ - QUAL.add(i); + if (nonDisqualified && counter <= t) { + QUAL.add(i); + } } } return QUAL; @@ -285,7 +290,9 @@ public class Protocol extends VerifiableSecretSharing { public T calcY(Set QUAL){ T y = group.zero(); for (int i : QUAL) { - y = group.add(y , parties[i - 1].commitments.get(0)); + synchronized (parties[i - 1]) { + y = group.add(y, parties[i - 1].commitments.get(0)); + } } return y; } @@ -301,7 +308,9 @@ public class Protocol extends VerifiableSecretSharing { for (int k = 0; k <= t; k++){ value = group.zero(); for (int i : QUAL) { - value = group.add(value, parties[i - 1].commitments.get(k)); + synchronized (parties[i - 1]) { + value = group.add(value, parties[i - 1].commitments.get(k)); + } } commitments.add(k,value); } @@ -315,7 +324,9 @@ public class Protocol extends VerifiableSecretSharing { public Polynomial.Point calcShare(Set QUAL){ BigInteger xj = BigInteger.ZERO; for (int i : QUAL) { - xj = xj.add(parties[i - 1].share.y); + synchronized (parties[i - 1]) { + xj = xj.add(parties[i - 1].share.y); + } } return new Polynomial.Point(BigInteger.valueOf(id) , xj.mod(q)); } diff --git a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/User.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/User.java index 4e4f155..6563dfd 100644 --- a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/User.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/feldman/User.java @@ -1,16 +1,23 @@ package meerkat.crypto.dkg.feldman; import com.google.protobuf.InvalidProtocolBufferException; -import meerkat.crypto.utils.Channel; +import com.google.protobuf.TextFormat; +import meerkat.comm.Channel; +import meerkat.crypto.dkg.comm.MessageHandler; import meerkat.crypto.secretsharing.shamir.Polynomial; import com.google.protobuf.ByteString; -import com.google.protobuf.Message; +import meerkat.protobuf.Comm; import meerkat.protobuf.DKG; import org.factcenter.qilin.primitives.Group; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.math.BigInteger; import java.util.ArrayList; import java.util.Set; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingDeque; import static meerkat.crypto.dkg.comm.MessageUtils.createMessage; @@ -25,7 +32,8 @@ import static meerkat.crypto.dkg.comm.MessageUtils.createMessage; * by the end of run(), each party in QUAL has his own share of the generated random key. * this key can be recover by any subset of QUAL of size at least t + 1. */ -public class User implements Runnable{ +public class User implements Runnable { + final Logger logger = LoggerFactory.getLogger(getClass()); /** * joint feldman protocol object @@ -59,10 +67,6 @@ public class User implements Runnable{ */ protected final int n; - /** - * mail handler registered to channel as ReceiverCallback - */ - protected meerkat.crypto.dkg.comm.MailHandler mailHandler; /** * channel object @@ -96,6 +100,8 @@ public class User implements Runnable{ */ protected T y; + protected BlockingQueue receiveQueue; + /** * constructor * @param dkg joint feldman protocol object @@ -120,14 +126,45 @@ public class User implements Runnable{ this.share = null; this.y = null; + this.receiveQueue = new LinkedBlockingDeque<>(); + } /** - * create MailHandler and register it as ReceiverCallback + * create MessageHandler and register it as ReceiverCallback */ - protected void registerReceiverCallback(){ - this.mailHandler = new MailHandler(new MessageHandler()); - channel.registerReceiverCallback(mailHandler); + protected void registerReceiverCallback() { + channel.registerReceiverCallback(new meerkat.crypto.dkg.comm.MessageHandler() { + @Override + public void handleMessage(Comm.BroadcastMessage envelope) throws InvalidProtocolBufferException { + receiveQueue.add(envelope); + } + }); + +// this.messageHandler = new MessageHandler(); +// channel.registerReceiverCallback(messageHandler); + } + + /** + * Wait for at least one message to arrive, then handle any messages currently in the queue + */ + protected void waitAndHandleReceivedMessages() { + Comm.BroadcastMessage msg = null; + while (!stop && msg == null) { + try { + msg = receiveQueue.take(); + } catch (InterruptedException e) { + // Possibly stop + } + } + while (!stop && msg != null) { + try { + handleMessage(msg); + } catch (InvalidProtocolBufferException e) { + logger.warn("Received invalid message: {}", TextFormat.printToString(msg)); + } + msg = receiveQueue.poll(); + } } /** @@ -140,37 +177,34 @@ public class User implements Runnable{ dkg.sendSecrets(); } - /** - * wait for all shares and commitments will arrive from other parties + * Check if all shares and commitments have arrived from other parties */ - protected void waitUntilStageOneCompleted(){ - // wait for parties' share - for (int i = 0 ; i < n ; i++){ - synchronized (parties[i]) { - while (parties[i].share == null && !parties[i].aborted) { - try { - parties[i].wait(); - } catch (InterruptedException e) { - if (stop) return; - } + protected boolean isStageOneCompleted() { + for (int i = 0 ; i < n ; i++) { + if (!parties[i].aborted) { + if (parties[i].share == null) + return false; + for (int k = 0 ; k <= t ; k++) { + if (parties[i].commitments.get(k) == null) + return false; } } } - // wait for parties' commitments - for (int i = 0 ; i < n ; i++){ - for (int k = 0 ; k <= t ; k++) { - synchronized (parties[i]) { - while (parties[i].commitments.get(k) == null && !parties[i].aborted) { - try { - parties[i].wait(); - } catch (InterruptedException e) { - if (stop) return; - } - } - } - } + return true; + } + + protected void waitUntilStageOneCompleted() { + while (!stop && !isStageOneCompleted()) + waitAndHandleReceivedMessages(); + } + + protected boolean isStageTwoCompleted() { + for (int i = 0 ; i < n ; i++) { + if (!parties[i].aborted && !parties[i].doneFlag) + return false; } + return true; } /** @@ -185,25 +219,28 @@ public class User implements Runnable{ channel.broadcastMessage(createMessage(DKG.Payload.Type.DONE)); } - /** * wait until all other parties done complaining by receiving done message */ protected void waitUntilStageTwoCompleted(){ - for (int i = 0 ; i < n ; i++){ - synchronized (parties[i]) { - while (!parties[i].doneFlag && !parties[i].aborted) { - try { - parties[i].wait(); - } catch (InterruptedException e) { - if (stop) return; - } - } - } - } + while (!stop && !isStageTwoCompleted()) + waitAndHandleReceivedMessages(); } + protected boolean haveReceivedAllStage3ComplaintAnswers() { + for (int i = 0; i < n; i++) { + if (parties[i].aborted) + continue; + for (int j = 0; j < n; j++) { + if (parties[i].complaints[j].equals(Protocol.ComplaintState.Waiting)) + return false; + + } + } + return true; + } + /** * stage3 according to the protocol * 1. if more than t players complain against a player Pi he is disqualified. @@ -213,20 +250,11 @@ public class User implements Runnable{ */ 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++){ - synchronized (parties[i]) { - while (parties[i].complaints[j].equals(Protocol.ComplaintState.Waiting) && !parties[i].aborted) { - try { - parties[i].wait(); - } catch (InterruptedException e) { - if (stop) return; - } - } - } - } - } + while (!stop && !haveReceivedAllStage3ComplaintAnswers()) + waitAndHandleReceivedMessages(); + this.QUAL = dkg.calcQUAL(); } @@ -245,15 +273,23 @@ public class User implements Runnable{ @Override public void run() { this.runThread = Thread.currentThread(); - stage1(); - waitUntilStageOneCompleted(); - if (stop) return; - stage2(); - waitUntilStageTwoCompleted(); - if (stop) return; - stage3(); - if (stop) return; - stage4(); + // For debugging + String previousName = runThread.getName(); + runThread.setName(getClass().getName() +":" + getID()); + + try { + stage1(); + waitUntilStageOneCompleted(); + if (stop) return; + stage2(); + waitUntilStageTwoCompleted(); + if (stop) return; + stage3(); + if (stop) return; + stage4(); + } finally { + runThread.setName(previousName); + } } /** @@ -360,199 +396,193 @@ public class User implements Runnable{ } /** - * an implementation of MessageHandler + * commitment message is valid if: + * 1. it was received in broadcast chanel + * 2. the sender didn't sent this commitment before */ - public class MessageHandler implements meerkat.crypto.dkg.comm.MessageHandler { + protected boolean isValidCommitmentMessage(int sender, boolean isBroadcast, DKG.CommitmentMessage commitmentMessage){ + int i = sender - 1; + int k = commitmentMessage.getK(); + return isBroadcast && parties[i].commitments.get(k) == null; + } - /** - * commitment message is valid if: - * 1. it was received in broadcast chanel - * 2. the sender didn't sent this commitment before - */ - protected boolean isValidCommitmentMessage(int sender, boolean isBroadcast, DKG.CommitmentMessage commitmentMessage){ - int i = sender - 1; - int k = commitmentMessage.getK(); - return isBroadcast && parties[i].commitments.get(k) == null; - } + /** + * 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 + * 4. secret.j == id + */ + protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKG.ShareMessage secretMessage){ + int i = secretMessage.getI(); + int j = secretMessage.getJ(); + if(sender != i || isBroadcast) + return false; + else + return parties[i - 1].share == null && j == id; - /** - * 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 - * 4. secret.j == id - */ - protected boolean isValidSecretMessage(int sender, boolean isBroadcast, DKG.ShareMessage secretMessage){ - int i = secretMessage.getI(); - int j = secretMessage.getJ(); - if(sender != i || isBroadcast) - return false; - else - return parties[i - 1].share == null && j == id; + } - } - - /** - * 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; - } + /** + * 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; + } - /** - * complaint message is valid if: - * 1. it was received in broadcast chanel - * 2. the sender didn't complained against id before - */ - protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, DKG.IDMessage complaintMessage){ - int i = sender; - int j = complaintMessage.getId(); - return isBroadcast && parties[i - 1].complaints[j - 1].equals( Protocol.ComplaintState.OK); - } + /** + * complaint message is valid if: + * 1. it was received in broadcast chanel + * 2. the sender didn't complained against id before + */ + protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, DKG.IDMessage complaintMessage){ + int i = sender; + int j = complaintMessage.getId(); - /** - * answer message is valid if: - * 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 - */ - protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKG.ShareMessage secretMessage){ - int i = secretMessage.getI(); - int j = secretMessage.getJ(); - if(sender != i || !isBroadcast) - return false; - else - return j >= 1 && j <= n && parties[i - 1].complaints[j - 1].equals(Protocol.ComplaintState.Waiting); - } + assert(i > 0); + assert(j > 0); + assert(i <= parties.length); + assert(j <= parties[i-1].complaints.length); + + return isBroadcast && parties[i - 1].complaints[j - 1].equals( Protocol.ComplaintState.OK); + } + + /** + * answer message is valid if: + * 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 + */ + protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKG.ShareMessage secretMessage){ + int i = secretMessage.getI(); + int j = secretMessage.getJ(); + if(sender != i || !isBroadcast) + return false; + else + return j >= 1 && j <= n && parties[i - 1].complaints[j - 1].equals(Protocol.ComplaintState.Waiting); + } - @Override - public void handleMessage(DKG.BroadcastMessage envelope) throws InvalidProtocolBufferException { - int sender = envelope.getSender(); - boolean isBroadcast = !envelope.getIsPrivate(); - DKG.Payload msg = DKG.Payload.parseFrom(envelope.getPayload()); + public void handleMessage(Comm.BroadcastMessage envelope) throws InvalidProtocolBufferException { + int sender = envelope.getSender(); + boolean isBroadcast = !envelope.getIsPrivate(); + DKG.Payload msg = DKG.Payload.parseFrom(envelope.getPayload()); - switch (msg.getType()) { - case COMMITMENT: - /** - * saves the commitment - */ - DKG.CommitmentMessage commitmentMessage = msg.getCommitment(); - if (isValidCommitmentMessage(sender, isBroadcast, commitmentMessage)) { - int i = sender - 1; - int k = commitmentMessage.getK(); - synchronized (parties[i]) { - parties[i].commitments.set(k, extractCommitment(commitmentMessage)); - parties[i].notify(); - } + logger.debug("handling Message: Dst={}, Src={}, [{}]", + envelope.getDestination(), envelope.getSender(), TextFormat.printToString(msg)); + + switch (msg.getType()) { + case COMMITMENT: + /** + * saves the commitment + */ + assert msg.getPayloadDataCase() == DKG.Payload.PayloadDataCase.COMMITMENT; + DKG.CommitmentMessage commitmentMessage = msg.getCommitment(); + if (isValidCommitmentMessage(sender, isBroadcast, commitmentMessage)) { + int i = sender - 1; + int k = commitmentMessage.getK(); + + parties[i].commitments.set(k, extractCommitment(commitmentMessage)); + } + break; + + + case SHARE: + /** + * saves the secret + */ + assert msg.getPayloadDataCase() == DKG.Payload.PayloadDataCase.SHARE; + DKG.ShareMessage secretMessage = msg.getShare(); + if(isValidSecretMessage(sender,isBroadcast,secretMessage)) { + int i = secretMessage.getI(); + Polynomial.Point secret = extractShare(id,secretMessage.getShare()); + parties[i - 1].share = secret; + } + break; + + case DONE: + + /** + * marks that the sender was finished sending all his complaints + */ + if(isValidDoneMessage(sender,isBroadcast)) { + parties[sender - 1].doneFlag = true; + } + break; + + case COMPLAINT: + /** + * marks that the sender was complained against id + */ + if (msg.getPayloadDataCase() != DKG.Payload.PayloadDataCase.ID) { + logger.error("User {} Expecting ID message, got from SRC={} msg {}", getID(), envelope.getSender(), TextFormat.printToString(msg)); + assert (msg.getPayloadDataCase() == DKG.Payload.PayloadDataCase.ID); + } + + DKG.IDMessage complaintMessage = msg.getId(); + if(isValidComplaintMessage(sender,isBroadcast,complaintMessage)){ + int i = sender; + int j = complaintMessage.getId(); + parties[j - 1].complaints[i - 1] = Protocol.ComplaintState.Waiting; + } + break; + case ANSWER: + /** + * 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 + */ + assert msg.getPayloadDataCase() == DKG.Payload.PayloadDataCase.SHARE; + secretMessage = msg.getShare(); + if(isValidAnswerMessage(sender,isBroadcast,secretMessage)) { + int i = secretMessage.getI(); + int j = secretMessage.getJ(); + Polynomial.Point secret = extractShare(j,secretMessage.getShare()); + if (dkg.isValidShare(secret, parties[i - 1].commitments, j)) { + parties[i - 1].complaints[j - 1] = Protocol.ComplaintState.NonDisqualified; + } else { + parties[i - 1].complaints[j - 1] = Protocol.ComplaintState.Disqualified; } - break; - - - case SHARE: - /** - * saves the secret - */ - DKG.ShareMessage secretMessage = msg.getShare(); - if(isValidSecretMessage(sender,isBroadcast,secretMessage)) { - int i = secretMessage.getI(); - Polynomial.Point secret = extractShare(id,secretMessage.getShare()); - synchronized (parties[i -1]) { - parties[i - 1].share = secret; - parties[i - 1].notify(); - } + if (j == id) { + parties[i - 1].share = secret; } - break; + } + break; + case ABORT: + /** + * marks that the sender was aborted + */ + parties[sender - 1].aborted = true; + break; + default: + logger.error("Bad message: SRC={}, DST={}, Payload={}", envelope.getSender(), envelope.getDestination(), TextFormat.printToString(msg)); + break; - case DONE: - - /** - * marks that the sender was finished sending all his complaints - */ - if(isValidDoneMessage(sender,isBroadcast)) { - synchronized (parties[sender - 1]) { - parties[sender - 1].doneFlag = true; - parties[sender - 1].notify(); - } - } - break; - - case COMPLAINT: - /** - * marks that the sender was complained against id - */ - DKG.IDMessage complaintMessage = msg.getId(); - if(isValidComplaintMessage(sender,isBroadcast,complaintMessage)){ - int i = sender; - int j = complaintMessage.getId(); - synchronized (parties[j - 1]) { - parties[j - 1].complaints[i - 1] = Protocol.ComplaintState.Waiting; - parties[j - 1].notify(); - } - } - break; - case ANSWER: - /** - * 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 - */ - secretMessage = msg.getShare(); - if(isValidAnswerMessage(sender,isBroadcast,secretMessage)) { - int i = secretMessage.getI(); - int j = secretMessage.getJ(); - Polynomial.Point secret = extractShare(j,secretMessage.getShare()); - synchronized (parties[i - 1]) { - if (dkg.isValidShare(secret, parties[i - 1].commitments, j)) { - parties[i - 1].complaints[j - 1] = Protocol.ComplaintState.NonDisqualified; - } else { - parties[i - 1].complaints[j - 1] = Protocol.ComplaintState.Disqualified; - } - if (j == id) { - parties[i - 1].share = secret; - } - parties[i - 1].notify(); - } - } - break; - case ABORT: - /** - * marks that the sender was aborted - */ - synchronized (parties[sender - 1]) { - parties[sender - 1].aborted = true; - parties[sender - 1].notify(); - } - break; - - - - } - } - - /** - * 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(DKG.CommitmentMessage commitmentMessage){ - return dkg.decodeCommitment(commitmentMessage.getCommitment().toByteArray()); } } + + /** + * 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(DKG.CommitmentMessage commitmentMessage){ + return dkg.decodeCommitment(commitmentMessage.getCommitment().toByteArray()); + } } diff --git a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/MailHandler.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/MailHandler.java deleted file mode 100644 index 36f970e..0000000 --- a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/MailHandler.java +++ /dev/null @@ -1,36 +0,0 @@ -package meerkat.crypto.dkg.gjkr; - -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Message; -import meerkat.crypto.dkg.comm.MessageHandler; -import meerkat.protobuf.DKG; - -/** - * Created by Tzlil on 2/29/2016. - * an extension of MailHandler matching gjkr protocl - */ -public class MailHandler extends meerkat.crypto.dkg.comm.MailHandler { - - /** - * flag that indicants whether the - * current run achieved stage 4 of the protocol or not - */ - private boolean isStage4; - - /** - * constructor - * @param messageHandler - */ - public MailHandler(MessageHandler messageHandler) { - super(messageHandler); - this.isStage4 = false; - } - - /** - * setter - * @param stage4 - */ - public void setStage4(boolean stage4) { - isStage4 = stage4; - } -} diff --git a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/User.java b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/User.java index 6a3e0a4..5c1b418 100644 --- a/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/User.java +++ b/distributed-key-generation/src/main/java/meerkat/crypto/dkg/gjkr/User.java @@ -3,10 +3,10 @@ package meerkat.crypto.dkg.gjkr; import com.google.protobuf.InvalidProtocolBufferException; import meerkat.crypto.utils.Arithmetic; import meerkat.crypto.utils.concrete.Fp; -import meerkat.crypto.utils.Channel; +import meerkat.comm.Channel; import meerkat.crypto.secretsharing.shamir.Polynomial; import meerkat.crypto.secretsharing.shamir.SecretSharing; -import com.google.protobuf.Message; +import meerkat.protobuf.Comm; import meerkat.protobuf.DKG; import java.math.BigInteger; @@ -38,10 +38,7 @@ public class User extends meerkat.crypto.dkg.feldman.User { */ protected final Protocol sdkg; - /** - * message handler - */ - private MessageHandler messageHandler; + boolean isStage4; /** * constructor @@ -55,13 +52,6 @@ public class User extends meerkat.crypto.dkg.feldman.User { this.parties = sdkg.getParties(); } - @Override - protected void registerReceiverCallback() { - this.messageHandler = new MessageHandler(); - this.mailHandler = new MailHandler(messageHandler); - this.channel.registerReceiverCallback(mailHandler); - } - /** * stage1 according to the protocol * 1. Pi broadcasts Cik=Aik*Bik for k = 0,...,t. @@ -73,6 +63,8 @@ public class User extends meerkat.crypto.dkg.feldman.User { sdkg.sendSecrets(); } + + @Override protected void waitUntilStageOneCompleted() { super.waitUntilStageOneCompleted(); @@ -98,40 +90,74 @@ public class User extends meerkat.crypto.dkg.feldman.User { channel.broadcastMessage(createMessage(DKG.Payload.Type.DONE)); } + /** + * Check if all non-aborting qualified parties have sent commitments. + * @return + */ + protected boolean haveAllQualPartiesCommitted() { + for (int i : QUAL) { + if (parties[i - 1].aborted) + continue; + for (int k = 0; k <= t; k++) { + if (parties[i - 1].commitments.get(k) == null) + return false; + } + } + return true; + } + + + /** + * Check if all non-aborting qualified parties sent a done message + * @return + */ + protected boolean areAllQualPartiesDone() { + for (int i : QUAL) { + if (parties[i - 1].aborted) + continue; + for (int k = 0; k <= t; k++) { + if (!parties[i - 1].ysDoneFlag) + return false; + } + } + return true; + } + + /** + * Check if at least t + 1 secrets were received foreach i in QUAL that aborted + * @return + */ + protected boolean haveReceivedEnoughSecretShares() { + for (int i : QUAL) { + if (parties[i - 1].aborted && parties[i - 1].recoverSharesSet.size() <= t) + return false; + } + return true; + } + /** * broadcast commitments and recover parties information if necessary */ private void resolveQualifyingPublicKey() { sdkg.broadcastCommitments(); // wait until all parties in QUAL broadcast their commitments or aborted - for (int i : QUAL) { - for (int k = 0; k <= t; k++) { - synchronized (parties[i - 1]) { - while (parties[i - 1].commitments.get(k) == null && !parties[i - 1].aborted) { - try { - parties[i - 1].wait(); - } catch (InterruptedException e) { - if (stop) return; - } - } - } - } - } + while (!stop && !haveAllQualPartiesCommitted()) + waitAndHandleReceivedMessages(); + + if (stop) + return; + sdkg.computeAndBroadcastComplaints(QUAL); + //broadcast done message after all complaints channel.broadcastMessage(createMessage(DKG.Payload.Type.DONE)); + // 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 { - parties[i - 1].wait(); - } catch (InterruptedException e) { - if (stop) return; - } - } - } - } + while (!stop && !areAllQualPartiesDone()) + waitAndHandleReceivedMessages(); + + if (stop) + return; // broadcast i private secret foreach i in QUAL that aborted for (int i : QUAL) { @@ -140,19 +166,12 @@ public class User extends meerkat.crypto.dkg.feldman.User { } } // 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) { - try { - parties[i - 1].wait(); - } catch (InterruptedException e) { - if (stop) return; - } - } - } - } - } + while (!stop && !haveReceivedEnoughSecretShares()) + waitAndHandleReceivedMessages(); + + if (stop) + return; + Arithmetic arithmetic = new Fp(sdkg.getQ()); // restore necessary information for (int i = 0; i < n; i++) { @@ -177,11 +196,10 @@ public class User extends meerkat.crypto.dkg.feldman.User { } /** - * notifies mail handler and message handler that stage 4 was started + * notifies message handler and message handler that stage 4 was started */ protected void setStage4() { - this.messageHandler.isStage4 = true; - ((MailHandler) this.mailHandler).setStage4(true); + isStage4 = true; } @Override @@ -192,151 +210,150 @@ public class User extends meerkat.crypto.dkg.feldman.User { super.stage4(); } - private class MessageHandler extends meerkat.crypto.dkg.feldman.User.MessageHandler { - boolean isStage4; - - /** - * if !isStage4 as super, with extension to double secret message - * else answer message is valid if: - * 1. it was received in broadcast chanel - * 2. secret.j == sender - * 3. QUAL contains i and j - */ - protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKG.ShareMessage doubleSecretMessage) { - if (!isStage4) { - return super.isValidAnswerMessage(sender, isBroadcast, doubleSecretMessage); - } else { - int i = doubleSecretMessage.getI(); - int j = doubleSecretMessage.getJ(); - return isBroadcast && j == sender && parties[i - 1].aborted && !parties[j - 1].aborted - && QUAL.contains(i) && QUAL.contains(j); - } - } - - - /** - * as in super with respect to protocol stage - */ - @Override - protected boolean isValidDoneMessage(int sender, boolean isBroadcast) { - if (!isStage4) { - return super.isValidDoneMessage(sender, isBroadcast); - } else { - return isBroadcast && !parties[sender - 1].ysDoneFlag; - } - } - - /** - * use only in stage4 - * complaint message is valid if: - * 1. it was received in broadcast chanel - * 2. secret.j == sender - * 3. QUAL contains i and j - */ - protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, - DKG.ShareMessage complaintMessage) { - int i = complaintMessage.getI(); - int j = complaintMessage.getJ(); - return isBroadcast && j == sender && QUAL.contains(i) && QUAL.contains(j); - } - - - @Override - public void handleMessage(DKG.BroadcastMessage envelope) throws InvalidProtocolBufferException { - int sender = envelope.getSender(); - boolean isBroadcast = !envelope.getIsPrivate(); - DKG.Payload msg = DKG.Payload.parseFrom(envelope.getPayload()); - switch (msg.getType()) { - case SHARE: - /** - * as in super, with extension to double secret message - */ - DKG.ShareMessage doubleSecretMessage = msg.getShare(); - if (isValidSecretMessage(sender, isBroadcast, doubleSecretMessage)) { - int i = doubleSecretMessage.getI(); - synchronized (parties[i - 1]) { - parties[i - 1].share = extractShare(id, doubleSecretMessage.getShare()); - parties[i - 1].shareT = extractShare(id, doubleSecretMessage.getShareT()); - parties[i - 1].notify(); - } - } - break; - case ANSWER: - /** - * if !isStage4 as super, with extension to double secret message - * else saves secret - */ - doubleSecretMessage = msg.getShare(); - if (isValidAnswerMessage(sender, isBroadcast, doubleSecretMessage)) { - int i = doubleSecretMessage.getI(); - int j = doubleSecretMessage.getJ(); - Polynomial.Point secret = extractShare(j, doubleSecretMessage.getShare()); - Polynomial.Point secretT = extractShare(j, doubleSecretMessage.getShareT()); - synchronized (parties[i - 1]) { - if (!isStage4) { - if (sdkg.isValidShare(secret, secretT, parties[j - 1].verifiableValues, i)) { - parties[i - 1].complaints[j - 1] = meerkat.crypto.dkg.feldman.Protocol.ComplaintState.NonDisqualified; - - } else { - parties[i - 1].complaints[j - 1] = meerkat.crypto.dkg.feldman.Protocol.ComplaintState.Disqualified; - } - if (j == id) { - parties[i - 1].share = secret; - parties[i - 1].shareT = secretT; - } - } else if (sdkg.isValidShare(secret, secretT, parties[i - 1].verifiableValues, j)) { - parties[i - 1].recoverSharesSet.add(secret); - } - parties[i - 1].notify(); - } - } - break; - case DONE: - /** - * as in super with respect to protocol state - */ - if (!isStage4) - super.handleMessage(envelope); - else { - if (isValidDoneMessage(sender, isBroadcast)) { - synchronized (parties[sender - 1]) { - parties[sender - 1].ysDoneFlag = true; - parties[sender - 1].notify(); - } - } - } - break; - case COMPLAINT: - /** - * 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 - * marks i as aborted - */ - if (!isStage4) { - super.handleMessage(envelope); - } else { - DKG.ShareMessage ysComplaintMessage = msg.getShare(); - if (isValidComplaintMessage(sender, isBroadcast, ysComplaintMessage)) { - int i = ysComplaintMessage.getI(); - int j = ysComplaintMessage.getJ(); - Polynomial.Point secret = extractShare(i, ysComplaintMessage.getShare()); - Polynomial.Point secretT = extractShare(i, ysComplaintMessage.getShareT()); - 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(); - } - } - } - } - break; - default: - super.handleMessage(envelope); - break; - } + /** + * if !isStage4 as super, with extension to double secret message + * else answer message is valid if: + * 1. it was received in broadcast chanel + * 2. secret.j == sender + * 3. QUAL contains i and j + */ + protected boolean isValidAnswerMessage(int sender, boolean isBroadcast, DKG.ShareMessage doubleSecretMessage) { + if (!isStage4) { + return super.isValidAnswerMessage(sender, isBroadcast, doubleSecretMessage); + } else { + int i = doubleSecretMessage.getI(); + int j = doubleSecretMessage.getJ(); + return isBroadcast && j == sender && parties[i - 1].aborted && !parties[j - 1].aborted + && QUAL.contains(i) && QUAL.contains(j); } } + + + /** + * as in super with respect to protocol stage + */ + @Override + protected boolean isValidDoneMessage(int sender, boolean isBroadcast) { + if (!isStage4) { + return super.isValidDoneMessage(sender, isBroadcast); + } else { + return isBroadcast && !parties[sender - 1].ysDoneFlag; + } + } + + /** + * use only in stage4 + * complaint message is valid if: + * 1. it was received in broadcast chanel + * 2. secret.j == sender + * 3. QUAL contains i and j + */ + protected boolean isValidComplaintMessage(int sender, boolean isBroadcast, + DKG.ShareMessage complaintMessage) { + int i = complaintMessage.getI(); + int j = complaintMessage.getJ(); + return isBroadcast && j == sender && QUAL.contains(i) && QUAL.contains(j); + } + + + @Override + public void handleMessage(Comm.BroadcastMessage envelope) throws InvalidProtocolBufferException { + int sender = envelope.getSender(); + boolean isBroadcast = !envelope.getIsPrivate(); + DKG.Payload msg = DKG.Payload.parseFrom(envelope.getPayload()); + switch (msg.getType()) { + case SHARE: + /** + * as in super, with extension to double secret message + */ + DKG.ShareMessage doubleSecretMessage = msg.getShare(); + if (isValidSecretMessage(sender, isBroadcast, doubleSecretMessage)) { + int i = doubleSecretMessage.getI(); + synchronized (parties[i - 1]) { + parties[i - 1].share = extractShare(id, doubleSecretMessage.getShare()); + parties[i - 1].shareT = extractShare(id, doubleSecretMessage.getShareT()); + parties[i - 1].notify(); + } + } + break; + case ANSWER: + /** + * if !isStage4 as super, with extension to double secret message + * else saves secret + */ + assert msg.getPayloadDataCase() == DKG.Payload.PayloadDataCase.SHARE; + doubleSecretMessage = msg.getShare(); + if (isValidAnswerMessage(sender, isBroadcast, doubleSecretMessage)) { + int i = doubleSecretMessage.getI(); + int j = doubleSecretMessage.getJ(); + Polynomial.Point secret = extractShare(j, doubleSecretMessage.getShare()); + Polynomial.Point secretT = extractShare(j, doubleSecretMessage.getShareT()); + synchronized (parties[i - 1]) { + if (!isStage4) { + if (sdkg.isValidShare(secret, secretT, parties[j - 1].verifiableValues, i)) { + parties[i - 1].complaints[j - 1] = meerkat.crypto.dkg.feldman.Protocol.ComplaintState.NonDisqualified; + + } else { + parties[i - 1].complaints[j - 1] = meerkat.crypto.dkg.feldman.Protocol.ComplaintState.Disqualified; + } + if (j == id) { + parties[i - 1].share = secret; + parties[i - 1].shareT = secretT; + } + } else if (sdkg.isValidShare(secret, secretT, parties[i - 1].verifiableValues, j)) { + parties[i - 1].recoverSharesSet.add(secret); + } + parties[i - 1].notify(); + } + } + break; + case DONE: + /** + * as in super with respect to protocol state + */ + if (!isStage4) + super.handleMessage(envelope); + else { + if (isValidDoneMessage(sender, isBroadcast)) { + synchronized (parties[sender - 1]) { + parties[sender - 1].ysDoneFlag = true; + parties[sender - 1].notify(); + } + } + } + break; + case COMPLAINT: + /** + * 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 + * marks i as aborted + */ + if (!isStage4) { + super.handleMessage(envelope); + } else { + assert (msg.getPayloadDataCase() == DKG.Payload.PayloadDataCase.SHARE); + DKG.ShareMessage ysComplaintMessage = msg.getShare(); + if (isValidComplaintMessage(sender, isBroadcast, ysComplaintMessage)) { + int i = ysComplaintMessage.getI(); + int j = ysComplaintMessage.getJ(); + Polynomial.Point secret = extractShare(i, ysComplaintMessage.getShare()); + Polynomial.Point secretT = extractShare(i, ysComplaintMessage.getShareT()); + 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(); + } + } + } + } + break; + default: + super.handleMessage(envelope); + break; + } + } + } \ No newline at end of file diff --git a/distributed-key-generation/src/main/proto/meerkat/DKG.proto b/distributed-key-generation/src/main/proto/meerkat/DKG.proto index 235f062..7d43a67 100644 --- a/distributed-key-generation/src/main/proto/meerkat/DKG.proto +++ b/distributed-key-generation/src/main/proto/meerkat/DKG.proto @@ -4,14 +4,6 @@ package meerkat; option java_package = "meerkat.protobuf"; -message BroadcastMessage { - int32 sender = 1; - int32 destination = 2; - bool is_private = 3; - - bytes payload = 5; -} - message Payload { enum Type { SHARE = 0; @@ -25,9 +17,11 @@ message Payload { ABORT = 8; } + + // Type of message in protocol Type type = 1; - oneof specific { + oneof payload_data { IDMessage id = 5; ShareMessage share = 6; CommitmentMessage commitment = 7; diff --git a/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGMaliciousUser.java b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGMaliciousUser.java index ebd2ff6..78b70d4 100644 --- a/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGMaliciousUser.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGMaliciousUser.java @@ -1,6 +1,6 @@ package meerkat.crypto.dkg.feldman; -import meerkat.crypto.utils.Channel; +import meerkat.comm.Channel; import java.math.BigInteger; import java.util.*; diff --git a/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGTest.java b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGTest.java index 18b3674..f522a42 100644 --- a/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGTest.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGTest.java @@ -1,9 +1,9 @@ package meerkat.crypto.dkg.feldman; -import meerkat.crypto.utils.ChannelImpl; +import meerkat.comm.ChannelImpl; import meerkat.crypto.utils.Arithmetic; import meerkat.crypto.utils.concrete.Fp; -import meerkat.crypto.utils.Channel; +import meerkat.comm.Channel; import meerkat.crypto.secretsharing.feldman.VerifiableSecretSharing; import meerkat.crypto.secretsharing.shamir.Polynomial; import meerkat.crypto.secretsharing.shamir.SecretSharing; @@ -71,13 +71,6 @@ public class DKGTest { assert (calculatedSecret.equals(testable.secret)); } - public void stopReceivers(Testable testable){ - ChannelImpl channel; - for (int i = 0 ; i < testable.dkgs.length ; i++){ - channel = (ChannelImpl)testable.dkgs[i].getChannel(); - channel.stop(); - } - } @Test public void test() throws Exception { @@ -85,7 +78,6 @@ public class DKGTest { for (int i = 0; i < tests; i++){ testable = new Testable(new Random()); oneTest(testable); - stopReceivers(testable); } } @@ -115,11 +107,11 @@ public class DKGTest { BigInteger s; Protocol dkg; this.secret = BigInteger.ZERO; - ChannelImpl channel; + ChannelImpl channels = new ChannelImpl(); ByteEncoder byteEncoder = new BigIntegerByteEncoder(); while (!ids.isEmpty()) { id = ids.remove(random.nextInt(ids.size())); - channel = new ChannelImpl(id,n); + Channel channel = channels.getChannel(id); s = randomIntModQ(random); dkg = new meerkat.crypto.dkg.feldman.Protocol(t, n, s, random, q, g, group, id,byteEncoder); dkgs[id - 1] = randomDKGUser(id,channel,dkg,random); diff --git a/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGUserImplAbort.java b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGUserImplAbort.java index 902d103..528ea9f 100644 --- a/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGUserImplAbort.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/feldman/DKGUserImplAbort.java @@ -1,6 +1,6 @@ package meerkat.crypto.dkg.feldman; -import meerkat.crypto.utils.Channel; +import meerkat.comm.Channel; import meerkat.protobuf.DKG; import static meerkat.crypto.dkg.comm.MessageUtils.createMessage; diff --git a/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGMaliciousUserImpl.java b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGMaliciousUserImpl.java index f72b00a..baf1a81 100644 --- a/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGMaliciousUserImpl.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGMaliciousUserImpl.java @@ -1,6 +1,6 @@ package meerkat.crypto.dkg.gjkr; -import meerkat.crypto.utils.Channel; +import meerkat.comm.Channel; import java.math.BigInteger; import java.util.Random; diff --git a/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGTest.java b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGTest.java index b5c4c9f..e4550f0 100644 --- a/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGTest.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGTest.java @@ -1,9 +1,9 @@ package meerkat.crypto.dkg.gjkr; -import meerkat.crypto.utils.ChannelImpl; +import meerkat.comm.ChannelImpl; import meerkat.crypto.utils.Arithmetic; import meerkat.crypto.utils.concrete.Fp; -import meerkat.crypto.utils.Channel; +import meerkat.comm.Channel; import meerkat.crypto.secretsharing.feldman.VerifiableSecretSharing; import meerkat.crypto.dkg.feldman.DKGMaliciousUser; import meerkat.crypto.secretsharing.shamir.Polynomial; @@ -13,34 +13,45 @@ import meerkat.crypto.utils.GenerateRandomPrime; import org.factcenter.qilin.primitives.Group; import org.factcenter.qilin.primitives.concrete.Zpstar; import org.factcenter.qilin.util.ByteEncoder; +import org.junit.Assert; import org.junit.Test; +import org.junit.internal.runners.statements.Fail; + +import static org.junit.Assert.*; import java.math.BigInteger; import java.util.ArrayList; import java.util.HashSet; import java.util.Random; import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; /** * Created by Tzlil on 3/29/2016. + * TODO: Separate into multiple tests, + * TODO: Make tests deterministic (using constant seed for random generator) */ public class SDKGTest { - int tests = 10; + private ExecutorService executorService = Executors.newCachedThreadPool(); + + final static int NUM_TESTS = 10; BigInteger p = GenerateRandomPrime.SafePrime100Bits; BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); Group group = new Zpstar(p); Arithmetic arithmetic = new Fp(q); - int t = 9; + int t = 1; int n = 20; - + Random rand = new Random(1); public void oneTest(Testable testable) throws Exception { - for (int i = 0; i < testable.threads.length ; i++){ - testable.threads[i].start(); + for (int i = 0; i < testable.sdkgs.length ; i++){ + testable.futures[i] = executorService.submit(testable.sdkgs[i]); } - for (int i = 0; i < testable.threads.length ; i++){ - testable.threads[i].join(); + for (int i = 0; i < testable.futures.length ; i++){ + testable.futures[i].get(); } // got the right public value @@ -73,41 +84,45 @@ public class SDKGTest { assert (calculatedSecret.equals(testable.secret)); } - public void stopReceivers(Testable testable){ - ChannelImpl channel; - for (int i = 0 ; i < testable.sdkgs.length ; i++){ - channel = (ChannelImpl)testable.sdkgs[i].getChannel(); - channel.stop(); - } - } @Test public void test() throws Exception { Testable testable; - for (int i = 0; i < tests; i++) { - testable = new Testable(new Random()); + for (int i = 0; i < NUM_TESTS; i++) { + testable = new Testable(n, t, group, q, rand); oneTest(testable); - stopReceivers(testable); } } - class Testable{ + + static class Testable { Set valids; Set QUAL; Set aborted; Set malicious; User[] sdkgs; - Thread[] threads; + Future[] futures; BigInteger g; BigInteger h; BigInteger secret; + Group group; + int n; + int t; + BigInteger q; + Random random; + ChannelImpl channels = new ChannelImpl(); - public Testable(Random random) { + public Testable(int n, int t, Group group, BigInteger q, Random random) { + this.n = n; + this.t = t; + this.group = group; + this.q = q; + this.random = random; this.sdkgs = new User[n]; this.valids = new HashSet(); this.QUAL = new HashSet(); this.aborted = new HashSet(); this.malicious = new HashSet(); - this.threads = new Thread[n]; + this.futures = new Future[n]; this.g = sampleGenerator(random); this.h = group.multiply(g,randomIntModQ(random)); ArrayList ids = new ArrayList(); @@ -123,10 +138,9 @@ public class SDKGTest { while (!ids.isEmpty()) { id = ids.remove(random.nextInt(ids.size())); s = randomIntModQ(random); - channel = new ChannelImpl(id,n); + channel = channels.getChannel(id); sdkg = new Protocol(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]); + sdkgs[id - 1] = randomSDKGUser(id,channel,sdkg); if(QUAL.contains(id)){ this.secret = this.secret.add(s).mod(q); } @@ -134,33 +148,44 @@ public class SDKGTest { } - public User randomSDKGUser(int id, Channel channel, Protocol sdkg, Random random){ - if (QUAL.size() <= t) { - valids.add(id); - QUAL.add(id); - return new User(sdkg,channel); - }else{ - int type = random.nextInt(3); - switch (type){ - case 0:// regular - valids.add(id); + enum UserType { + HONEST, + FAILSTOP, + MALICIOUS, + } + + public User newSDKGUser(int id, Channel channel, Protocol sdkg, UserType userType) { + switch(userType) { + case HONEST: + valids.add(id); + QUAL.add(id); + return new User(sdkg,channel); + + case FAILSTOP: + int abortStage = random.nextInt(3) + 1; // 1 or 2 or 3 + aborted.add(id); + if (abortStage > 1){ QUAL.add(id); - return new User(sdkg,channel); - case 1:// abort - int abortStage = random.nextInt(3) + 1; // 1 or 2 or 3 - aborted.add(id); - if (abortStage > 1){ - QUAL.add(id); - } - return new SDKGUserImplAbort(sdkg,channel,abortStage); - case 2:// malicious - malicious.add(id); - Set falls = DKGMaliciousUser.selectFallsRandomly(valids,random); - Protocol maliciousSDKG = SDKGMaliciousUserImpl.generateMaliciousSDKG(sdkg,channel,random); - return new SDKGMaliciousUserImpl(sdkg,maliciousSDKG,channel,falls); - default: - return null; - } + } + return new SDKGUserImplAbort(sdkg,channel,abortStage); + + case MALICIOUS: + malicious.add(id); + Set falls = DKGMaliciousUser.selectFallsRandomly(valids,random); + Protocol maliciousSDKG = SDKGMaliciousUserImpl.generateMaliciousSDKG(sdkg,channel,random); + return new SDKGMaliciousUserImpl(sdkg,maliciousSDKG,channel,falls); + + } + fail("Unknown user type"); + return null; + } + + public User randomSDKGUser(int id, Channel channel, Protocol sdkg){ + if (QUAL.size() <= t) { + return newSDKGUser(id, channel, sdkg, UserType.HONEST); + } else { + UserType type = UserType.values()[random.nextInt(UserType.values().length)]; + return newSDKGUser(id, channel, sdkg, type); } } diff --git a/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGUserImplAbort.java b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGUserImplAbort.java index b067c1a..5b0e11b 100644 --- a/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGUserImplAbort.java +++ b/distributed-key-generation/src/test/java/meerkat/crypto/dkg/gjkr/SDKGUserImplAbort.java @@ -1,7 +1,9 @@ package meerkat.crypto.dkg.gjkr; +import com.google.protobuf.InvalidProtocolBufferException; import meerkat.crypto.dkg.comm.MessageUtils; -import meerkat.crypto.utils.Channel; +import meerkat.comm.Channel; +import meerkat.protobuf.Comm; import meerkat.protobuf.DKG; /** @@ -9,6 +11,10 @@ import meerkat.protobuf.DKG; */ public class SDKGUserImplAbort extends User { + public static class AbortException extends RuntimeException { + + } + final int abortStage; int stage; public SDKGUserImplAbort(Protocol sdkg, Channel channel, int abortStage) { @@ -20,6 +26,7 @@ public class SDKGUserImplAbort extends User { private void abort(){ //stopReceiver(); channel.broadcastMessage(MessageUtils.createMessage(DKG.Payload.Type.ABORT)); + throw new AbortException(); } @Override @@ -61,4 +68,13 @@ public class SDKGUserImplAbort extends User { } stage++; } + + @Override + public void run() { + try { + super.run(); + } catch (AbortException e) { + // Expected + } + } } diff --git a/distributed-key-generation/src/test/java/meerkat/crypto/utils/ChannelImpl.java b/distributed-key-generation/src/test/java/meerkat/crypto/utils/ChannelImpl.java deleted file mode 100644 index dfb1bfb..0000000 --- a/distributed-key-generation/src/test/java/meerkat/crypto/utils/ChannelImpl.java +++ /dev/null @@ -1,111 +0,0 @@ -package meerkat.crypto.utils; - -import com.google.protobuf.Message; -import meerkat.protobuf.DKG; - -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 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( n * n * n); - this.id = id; - this.n = n; - channels[id - 1] = this; - } - - @Override - public int getSourceId() { - return id; - } - - - @Override - public void sendMessage(int destUser, Message msg) { - if(destUser < 1 || destUser > n) - return; - ChannelImpl channel = channels[destUser - 1]; - if (channel == null) - return; - DKG.BroadcastMessage broadcastMessage = DKG.BroadcastMessage.newBuilder() - .setSender(id) - .setDestination(destUser) - .setIsPrivate(true) - .setPayload(msg.toByteString()) - .build(); - synchronized (channel.mailbox) { - channel.mailbox.add(broadcastMessage); - channel.mailbox.notify(); - } - } - - @Override - public void broadcastMessage(Message msg) { - ChannelImpl channel; - DKG.BroadcastMessage broadcastMessage = DKG.BroadcastMessage.newBuilder() - .setSender(id) - .setDestination(BROADCAST) - .setIsPrivate(false) - .setPayload(msg.toByteString()) - .build(); - for (int i = 0 ; i < n ; i++){ - channel = channels[i]; - synchronized (channel.mailbox) { - channel.mailbox.add(broadcastMessage); - channel.mailbox.notify(); - } - } - } - - public void stop(){ - try{ - receiverThread.interrupt(); - }catch (Exception e){ - //do nothing - } - } - - @Override - public void registerReceiverCallback(final ReceiverCallback callback) { - stop(); - 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(); - } - - - -} diff --git a/distributed-key-generation/src/main/java/meerkat/crypto/utils/Channel.java b/meerkat-common/src/main/java/meerkat/comm/Channel.java similarity index 89% rename from distributed-key-generation/src/main/java/meerkat/crypto/utils/Channel.java rename to meerkat-common/src/main/java/meerkat/comm/Channel.java index 97a6060..7dd74c1 100644 --- a/distributed-key-generation/src/main/java/meerkat/crypto/utils/Channel.java +++ b/meerkat-common/src/main/java/meerkat/comm/Channel.java @@ -1,7 +1,7 @@ -package meerkat.crypto.utils; +package meerkat.comm; import com.google.protobuf.Message; -import meerkat.protobuf.DKG; +import meerkat.protobuf.Comm; /** * A generic communication channel that supports point-to-point and broadcast operation @@ -15,7 +15,7 @@ public interface Channel { public int getSourceId(); public interface ReceiverCallback { - public void receiveMail(DKG.BroadcastMessage envelope); + public void receiveMessage(Comm.BroadcastMessage envelope); } /** diff --git a/meerkat-common/src/main/proto/meerkat/comm.proto b/meerkat-common/src/main/proto/meerkat/comm.proto new file mode 100644 index 0000000..c509165 --- /dev/null +++ b/meerkat-common/src/main/proto/meerkat/comm.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +package meerkat; + +option java_package = "meerkat.protobuf"; + +message BroadcastMessage { + int32 sender = 1; + int32 destination = 2; + bool is_private = 3; + + bytes payload = 5; +} diff --git a/meerkat-common/src/test/java/meerkat/comm/ChannelImpl.java b/meerkat-common/src/test/java/meerkat/comm/ChannelImpl.java new file mode 100644 index 0000000..cfe32c2 --- /dev/null +++ b/meerkat-common/src/test/java/meerkat/comm/ChannelImpl.java @@ -0,0 +1,96 @@ +package meerkat.comm; + +import com.google.protobuf.Message; +import com.google.protobuf.TextFormat; +import meerkat.protobuf.Comm; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.Map; +import java.util.Queue; +import java.util.TreeMap; +import java.util.concurrent.*; + +/** + * Created by Tzlil on 2/14/2016. + */ +// TODO: Change nane to network + +public class ChannelImpl { + final Logger logger = LoggerFactory.getLogger(getClass()); + + //private ExecutorService executorService = Executors.newCachedThreadPool(); + public static int BROADCAST = 0; + Map channels = new TreeMap<>(); + + + public ChannelImpl() { + } + + public Channel getChannel(int id) { + return new SingleChannel(id); + } + + public class SingleChannel implements Channel { + protected final int id; + + ReceiverCallback callback; + + SingleChannel(int id) { + this.id = id; + channels.put(id, this); + } + + @Override + public int getSourceId() { + return id; + } + + + @Override + public void sendMessage(int destUser, Message msg) { + if (destUser < 1) + return; + SingleChannel channel = channels.get(destUser); + if (channel == null) { + logger.warn("Party {} attempting to send message to non-existing party {}", getSourceId(), destUser); + return; + } + Comm.BroadcastMessage broadcastMessage = Comm.BroadcastMessage.newBuilder() + .setSender(id) + .setDestination(destUser) + .setIsPrivate(true) + .setPayload(msg.toByteString()) + .build(); + + logger.debug("sending Message: Dst={},Src={} [{}]", broadcastMessage.getDestination(), + broadcastMessage.getSender(), TextFormat.printToString(msg)); + + channel.callback.receiveMessage(broadcastMessage); + } + + @Override + public void broadcastMessage(Message msg) { + Comm.BroadcastMessage broadcastMessage = Comm.BroadcastMessage.newBuilder() + .setSender(id) + .setDestination(BROADCAST) + .setIsPrivate(false) + .setPayload(msg.toByteString()) + .build(); + + logger.debug("broadcasting Message: Src={} [{}]", + broadcastMessage.getSender(), TextFormat.printToString(msg)); + + for (SingleChannel channel : channels.values()) { + channel.callback.receiveMessage(broadcastMessage); + } + } + + @Override + public void registerReceiverCallback(final ReceiverCallback callback) { + this.callback = callback; + } + } + +} From b934894bc52d5139d5a0ce460a9f489201fa43cf Mon Sep 17 00:00:00 2001 From: "arbel.peled" Date: Thu, 5 May 2016 16:55:10 +0300 Subject: [PATCH 45/49] Created Polling Station Scanner interface Implemented Web App for the scanner Not tested --- .../PollingStationConstants.java | 15 ++++ .../pollingstation/PollingStationScanner.java | 29 ++++++++ .../main/proto/meerkat/pollingstation.proto | 15 ++++ polling-station/build.gradle | 9 +++ .../PollingStationWebScanner.java | 71 +++++++++++++++++++ .../src/main/webapp/META-INF/jetty-env.xml | 12 ++++ .../src/main/webapp/WEB-INF/web.xml | 20 ++++++ 7 files changed, 171 insertions(+) create mode 100644 meerkat-common/src/main/java/meerkat/pollingstation/PollingStationConstants.java create mode 100644 meerkat-common/src/main/java/meerkat/pollingstation/PollingStationScanner.java create mode 100644 meerkat-common/src/main/proto/meerkat/pollingstation.proto create mode 100644 polling-station/src/main/java/meerkat/pollingstation/PollingStationWebScanner.java create mode 100644 polling-station/src/main/webapp/META-INF/jetty-env.xml create mode 100644 polling-station/src/main/webapp/WEB-INF/web.xml diff --git a/meerkat-common/src/main/java/meerkat/pollingstation/PollingStationConstants.java b/meerkat-common/src/main/java/meerkat/pollingstation/PollingStationConstants.java new file mode 100644 index 0000000..643a73c --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/pollingstation/PollingStationConstants.java @@ -0,0 +1,15 @@ +package meerkat.pollingstation; + +/** + * Created by Arbel Deutsch Peled on 21-Dec-15. + */ +public interface PollingStationConstants { + + // Relative addresses for Scanner operations + + public static final String POLLING_STATION_WEB_SCANNER_PATH = "/scanner"; + public static final String POLLING_STATION_WEB_SCANNER_SCAN_PATH = "/scan"; + public static final String POLLING_STATION_WEB_SCANNER_ERROR_PATH = "/error"; + + +} diff --git a/meerkat-common/src/main/java/meerkat/pollingstation/PollingStationScanner.java b/meerkat-common/src/main/java/meerkat/pollingstation/PollingStationScanner.java new file mode 100644 index 0000000..9bea5b5 --- /dev/null +++ b/meerkat-common/src/main/java/meerkat/pollingstation/PollingStationScanner.java @@ -0,0 +1,29 @@ +package meerkat.pollingstation; + +import com.google.common.util.concurrent.FutureCallback; +import meerkat.protobuf.PollingStation.*; +/** + * Created by Arbel on 05/05/2016. + * An interface for the scanner used by the Polling Station Committee + */ +public interface PollingStationScanner { + + /** + * Subscribes to new scans + * @param scanCallback is the handler for scanned data + */ + public void subscribe(FutureCallback scanCallback); + + /** + * Sends a scan to all subscribers + * @param scannedData contains the scanned data + */ + public void newScan(ScannedData scannedData); + + /** + * Notifies subscribers about an error that occurred during scan + * @param errorMsg is the error that occurred + */ + public void reportScanError(ErrorMsg errorMsg); + +} \ No newline at end of file diff --git a/meerkat-common/src/main/proto/meerkat/pollingstation.proto b/meerkat-common/src/main/proto/meerkat/pollingstation.proto new file mode 100644 index 0000000..0cdc658 --- /dev/null +++ b/meerkat-common/src/main/proto/meerkat/pollingstation.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package meerkat; + +option java_package = "meerkat.protobuf"; + +// Container for scanned data +message ScannedData { + bytes data = 1; +} + +// Container for error messages +message ErrorMsg { + string msg = 1; +} \ No newline at end of file diff --git a/polling-station/build.gradle b/polling-station/build.gradle index d510d26..036d2e8 100644 --- a/polling-station/build.gradle +++ b/polling-station/build.gradle @@ -2,8 +2,10 @@ plugins { id "us.kirchmeier.capsule" version "1.0.1" id 'com.google.protobuf' version '0.7.0' + id 'org.akhikhl.gretty' version "1.2.4" } +apply plugin: 'org.akhikhl.gretty' apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'idea' @@ -41,6 +43,13 @@ version += "${isSnapshot ? '-SNAPSHOT' : ''}" dependencies { // Meerkat common compile project(':meerkat-common') + compile project(':restful-api-common') + + // Jersey for RESTful API + compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.22.+' + + // Servlets + compile 'javax.servlet:javax.servlet-api:3.0.+' // Logging compile 'org.slf4j:slf4j-api:1.7.7' diff --git a/polling-station/src/main/java/meerkat/pollingstation/PollingStationWebScanner.java b/polling-station/src/main/java/meerkat/pollingstation/PollingStationWebScanner.java new file mode 100644 index 0000000..a3aefdd --- /dev/null +++ b/polling-station/src/main/java/meerkat/pollingstation/PollingStationWebScanner.java @@ -0,0 +1,71 @@ +package meerkat.pollingstation; + +import com.google.common.util.concurrent.FutureCallback; +import meerkat.protobuf.PollingStation; +import static meerkat.rest.Constants.*; + +import javax.ws.rs.*; +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; + +import static meerkat.pollingstation.PollingStationConstants.*; +import meerkat.protobuf.PollingStation.*; + +/** + * Created by Arbel on 05/05/2016. + */ +@Path(POLLING_STATION_WEB_SCANNER_PATH) +public class PollingStationWebScanner implements PollingStationScanner{ + + private final List> callbacks; + + public PollingStationWebScanner() { + callbacks = new LinkedList<>(); + } + + @Override + public void subscribe(FutureCallback scanCallback) { + callbacks.add(scanCallback); + } + + @Path(POLLING_STATION_WEB_SCANNER_SCAN_PATH) + @POST + @Consumes(MEDIATYPE_PROTOBUF) + @Produces(MEDIATYPE_PROTOBUF) + @Override + public void newScan(ScannedData scannedData) { + + if (callbacks.size() <= 0) + throw new RuntimeException("No subscribers to forward scan to!"); + + for (FutureCallback callback : callbacks){ + callback.onSuccess(scannedData); + } + + } + + @Path(POLLING_STATION_WEB_SCANNER_ERROR_PATH) + @POST + @Consumes(MEDIATYPE_PROTOBUF) + @Produces(MEDIATYPE_PROTOBUF) + @Override + public void reportScanError(PollingStation.ErrorMsg errorMsg) { + + if (callbacks.size() <= 0) + throw new RuntimeException("No subscribers to forward error to!"); + + for (FutureCallback callback : callbacks){ + callback.onFailure(new IOException(errorMsg.getMsg())); + } + + } + + @Path("/test") + @GET + public String test(){ + return "test"; + } + + +} diff --git a/polling-station/src/main/webapp/META-INF/jetty-env.xml b/polling-station/src/main/webapp/META-INF/jetty-env.xml new file mode 100644 index 0000000..c4d368f --- /dev/null +++ b/polling-station/src/main/webapp/META-INF/jetty-env.xml @@ -0,0 +1,12 @@ + + + + + org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern + none + + + org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern + none + + \ No newline at end of file diff --git a/polling-station/src/main/webapp/WEB-INF/web.xml b/polling-station/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..0632b0d --- /dev/null +++ b/polling-station/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,20 @@ + + + Jersey Hello World + + org.glassfish.jersey.servlet.ServletContainer + + + jersey.config.server.provider.packages + meerkat + + 1 + + + Jersey Hello World + /* + + + meerkat.pollingstation.PollingStationWebScanner + + From 061dc69fbc09a4d3af0b4874bcafa58c7641d79f Mon Sep 17 00:00:00 2001 From: "arbel.peled" Date: Thu, 5 May 2016 17:01:00 +0300 Subject: [PATCH 46/49] File rename --- .../proto/meerkat/{pollingstation.proto => PollingStation.proto} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename meerkat-common/src/main/proto/meerkat/{pollingstation.proto => PollingStation.proto} (100%) diff --git a/meerkat-common/src/main/proto/meerkat/pollingstation.proto b/meerkat-common/src/main/proto/meerkat/PollingStation.proto similarity index 100% rename from meerkat-common/src/main/proto/meerkat/pollingstation.proto rename to meerkat-common/src/main/proto/meerkat/PollingStation.proto From 347e826f7309a6574d163e319bbfbcfa3bdf405a Mon Sep 17 00:00:00 2001 From: "arbel.peled" Date: Tue, 31 May 2016 15:26:56 +0300 Subject: [PATCH 47/49] Working integrated version of Scanner WebApp Fully testsed Moved BoolMsg and IntMsg to Comm package (from BulletinBoardAPI) --- .../SimpleBulletinBoardClient.java | 9 +- .../SingleServerCloseBatchWorker.java | 2 +- .../SingleServerGenericPostWorker.java | 2 +- .../GenericBulletinBoardClientTester.java | 2 +- .../sqlserver/BulletinBoardSQLServer.java | 2 +- .../webapp/BulletinBoardWebApp.java | 2 +- ...BulletinBoardSQLServerIntegrationTest.java | 2 +- .../GenericBulletinBoardServerTest.java | 2 +- .../bulletinboard/BulletinBoardServer.java | 5 +- .../PollingStationConstants.java | 2 - .../pollingstation/PollingStationScanner.java | 54 ++++-- .../main/proto/meerkat/BulletinBoardAPI.proto | 8 - .../main/proto/meerkat/PollingStation.proto | 7 + .../src/main/proto/meerkat/comm.proto | 8 + polling-station/build.gradle | 7 +- .../PollingStationScannerWebApp.java | 89 +++++++++ .../PollingStationWebScanner.java | 91 +++++----- .../src/main/webapp/META-INF/jetty-env.xml | 12 -- .../src/main/webapp/WEB-INF/web.xml | 20 --- .../PollingStationWebScannerTest.java | 169 ++++++++++++++++++ 20 files changed, 374 insertions(+), 121 deletions(-) create mode 100644 polling-station/src/main/java/meerkat/pollingstation/PollingStationScannerWebApp.java delete mode 100644 polling-station/src/main/webapp/META-INF/jetty-env.xml delete mode 100644 polling-station/src/main/webapp/WEB-INF/web.xml create mode 100644 polling-station/src/test/java/meerkat/pollingstation/PollingStationWebScannerTest.java diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java index 80451b8..26b1e4e 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java @@ -1,21 +1,14 @@ package meerkat.bulletinboard; import com.google.protobuf.ByteString; -import com.google.protobuf.Timestamp; import meerkat.comm.CommunicationException; -import meerkat.comm.MessageInputStream; import meerkat.crypto.Digest; import meerkat.crypto.concrete.SHA256Digest; -import meerkat.protobuf.BulletinBoardAPI; import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Comm.*; import meerkat.protobuf.Voting.*; import meerkat.rest.*; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.util.Collection; -import java.util.Iterator; import java.util.List; import javax.ws.rs.client.Client; diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerCloseBatchWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerCloseBatchWorker.java index ab298a5..83e27c2 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerCloseBatchWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerCloseBatchWorker.java @@ -6,7 +6,7 @@ import static meerkat.bulletinboard.BulletinBoardConstants.CLOSE_BATCH_PATH; /** * Created by Arbel Deutsch Peled on 27-Dec-15. - * Tries to contact server once and perform a close batch operation + * Tries to contact server once and perform a stop batch operation */ public class SingleServerCloseBatchWorker extends SingleServerGenericPostWorker { diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerGenericPostWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerGenericPostWorker.java index 621a828..2148801 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerGenericPostWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerGenericPostWorker.java @@ -2,7 +2,7 @@ package meerkat.bulletinboard.workers.singleserver; import meerkat.bulletinboard.SingleServerWorker; import meerkat.comm.CommunicationException; -import meerkat.protobuf.BulletinBoardAPI.BoolMsg; +import meerkat.protobuf.Comm.*; import meerkat.rest.Constants; import javax.ws.rs.ProcessingException; diff --git a/bulletin-board-client/src/test/java/meerkat/bulletinboard/GenericBulletinBoardClientTester.java b/bulletin-board-client/src/test/java/meerkat/bulletinboard/GenericBulletinBoardClientTester.java index 88fb22c..d4bd3ec 100644 --- a/bulletin-board-client/src/test/java/meerkat/bulletinboard/GenericBulletinBoardClientTester.java +++ b/bulletin-board-client/src/test/java/meerkat/bulletinboard/GenericBulletinBoardClientTester.java @@ -508,7 +508,7 @@ public class GenericBulletinBoardClientTester { .build()) .build(); - // Try to close the (unopened) batch; + // Try to stop the (unopened) batch; bulletinBoardClient.closeBatch(closeBatchMessage, failPostCallback); diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java index b652b1a..dd68daf 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/sqlserver/BulletinBoardSQLServer.java @@ -17,6 +17,7 @@ import meerkat.crypto.concrete.ECDSASignature; import meerkat.crypto.concrete.SHA256Digest; import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Comm.*; import meerkat.protobuf.Crypto.Signature; import meerkat.protobuf.Crypto.SignatureVerificationKey; @@ -27,7 +28,6 @@ import javax.sql.DataSource; import meerkat.util.BulletinBoardUtils; import meerkat.util.TimestampComparator; -import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.support.GeneratedKeyHolder; diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java index 5f98ff6..f88d31f 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java @@ -15,8 +15,8 @@ import meerkat.bulletinboard.sqlserver.MySQLQueryProvider; import meerkat.bulletinboard.sqlserver.SQLiteQueryProvider; import meerkat.comm.CommunicationException; import meerkat.comm.MessageOutputStream; -import meerkat.protobuf.BulletinBoardAPI; import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Comm.*; import static meerkat.bulletinboard.BulletinBoardConstants.*; import static meerkat.rest.Constants.*; diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/BulletinBoardSQLServerIntegrationTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/BulletinBoardSQLServerIntegrationTest.java index 8debb83..a9be646 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/BulletinBoardSQLServerIntegrationTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/BulletinBoardSQLServerIntegrationTest.java @@ -8,6 +8,7 @@ import com.google.protobuf.Timestamp; import meerkat.comm.MessageInputStream; import meerkat.protobuf.Crypto.*; import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Comm.*; import static meerkat.bulletinboard.BulletinBoardConstants.*; import meerkat.rest.Constants; import meerkat.rest.ProtobufMessageBodyReader; @@ -20,7 +21,6 @@ import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.InputStream; import java.util.List; diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java index 131aee8..e09f051 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java @@ -28,8 +28,8 @@ import meerkat.crypto.Digest; import meerkat.crypto.concrete.ECDSASignature; import meerkat.crypto.concrete.SHA256Digest; import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Comm.*; import meerkat.util.BulletinBoardMessageGenerator; -import org.h2.util.DateTimeUtils; import static org.junit.Assert.*; import static org.hamcrest.CoreMatchers.*; diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java index f6ca1ab..abe4335 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java @@ -3,6 +3,7 @@ package meerkat.bulletinboard; import meerkat.comm.CommunicationException; import meerkat.comm.MessageOutputStream; import meerkat.protobuf.BulletinBoardAPI.*; +import meerkat.protobuf.Comm.*; import java.util.Collection; @@ -62,8 +63,8 @@ public interface BulletinBoardServer{ public BoolMsg postBatchMessage(BatchMessage batchMessage) throws CommunicationException; /** - * Attempts to close and finalize a batch message - * @param message contains the data necessary to close the batch; in particular: the signature for the batch + * Attempts to stop and finalize a batch message + * @param message contains the data necessary to stop the batch; in particular: the signature for the batch * @return TRUE if the batch was successfully closed, FALSE otherwise * Specifically, if the signature is invalid or if some of the batch parts have not yet been submitted: the value returned will be FALSE * @throws CommunicationException on DB connection error diff --git a/meerkat-common/src/main/java/meerkat/pollingstation/PollingStationConstants.java b/meerkat-common/src/main/java/meerkat/pollingstation/PollingStationConstants.java index 643a73c..1bc6d3c 100644 --- a/meerkat-common/src/main/java/meerkat/pollingstation/PollingStationConstants.java +++ b/meerkat-common/src/main/java/meerkat/pollingstation/PollingStationConstants.java @@ -7,9 +7,7 @@ public interface PollingStationConstants { // Relative addresses for Scanner operations - public static final String POLLING_STATION_WEB_SCANNER_PATH = "/scanner"; public static final String POLLING_STATION_WEB_SCANNER_SCAN_PATH = "/scan"; public static final String POLLING_STATION_WEB_SCANNER_ERROR_PATH = "/error"; - } diff --git a/meerkat-common/src/main/java/meerkat/pollingstation/PollingStationScanner.java b/meerkat-common/src/main/java/meerkat/pollingstation/PollingStationScanner.java index 9bea5b5..9adc616 100644 --- a/meerkat-common/src/main/java/meerkat/pollingstation/PollingStationScanner.java +++ b/meerkat-common/src/main/java/meerkat/pollingstation/PollingStationScanner.java @@ -1,29 +1,61 @@ package meerkat.pollingstation; import com.google.common.util.concurrent.FutureCallback; +import meerkat.protobuf.Comm.BoolMsg; import meerkat.protobuf.PollingStation.*; /** * Created by Arbel on 05/05/2016. * An interface for the scanner used by the Polling Station Committee + * The scanner works as a producer, while the polling station is the consumer + * That is to say: scans are pushed from the scanner rather than requested by the polling station */ public interface PollingStationScanner { /** - * Subscribes to new scans - * @param scanCallback is the handler for scanned data + * An interface for processing scans (Polling Station side) */ - public void subscribe(FutureCallback scanCallback); + public interface Consumer { + + /** + * Sets up the connection to the scanner and begins receiving scans + * @throws Exception when the operation fails + */ + public void start() throws Exception; + + /** + * Closes the connection to the scanner + * @throws Exception when the operation fails + */ + public void stop() throws Exception; + + /** + * Subscribes to new scans + * + * @param scanCallback is the handler for scanned data + */ + public void subscribe(FutureCallback scanCallback); + + } /** - * Sends a scan to all subscribers - * @param scannedData contains the scanned data + * An interface for submitting scanned data (scanner side) */ - public void newScan(ScannedData scannedData); + public interface Producer { - /** - * Notifies subscribers about an error that occurred during scan - * @param errorMsg is the error that occurred - */ - public void reportScanError(ErrorMsg errorMsg); + /** + * Sends a scan to all subscribers + * @param scannedData contains the scanned data + * @return a BoolMsg containing TRUE iff the scanned data has been sent to at least one subscriber + */ + public BoolMsg newScan(ScannedData scannedData); + /** + * Notifies subscribers about an error that occurred during scan + * @param errorMsg is the error that occurred + * @return a BoolMsg containing TRUE iff the error has been sent to at least one subscriber + */ + public BoolMsg reportScanError(ErrorMsg errorMsg); + + } + } \ No newline at end of file diff --git a/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto b/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto index 0edb03b..27ad512 100644 --- a/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto +++ b/meerkat-common/src/main/proto/meerkat/BulletinBoardAPI.proto @@ -7,14 +7,6 @@ option java_package = "meerkat.protobuf"; import 'meerkat/crypto.proto'; import 'google/protobuf/timestamp.proto'; -message BoolMsg { - bool value = 1; -} - -message IntMsg { - int32 value = 1; -} - message MessageID { // The ID of a message for unique retrieval. // Note that it is assumed that this ID is a function of the message itself. diff --git a/meerkat-common/src/main/proto/meerkat/PollingStation.proto b/meerkat-common/src/main/proto/meerkat/PollingStation.proto index 0cdc658..35dbd12 100644 --- a/meerkat-common/src/main/proto/meerkat/PollingStation.proto +++ b/meerkat-common/src/main/proto/meerkat/PollingStation.proto @@ -12,4 +12,11 @@ message ScannedData { // Container for error messages message ErrorMsg { string msg = 1; +} + +// Container for HTTP address +message HTTPAddress { + string hostname = 1; + int32 port = 2; + string address = 3; } \ No newline at end of file diff --git a/meerkat-common/src/main/proto/meerkat/comm.proto b/meerkat-common/src/main/proto/meerkat/comm.proto index c509165..2f23678 100644 --- a/meerkat-common/src/main/proto/meerkat/comm.proto +++ b/meerkat-common/src/main/proto/meerkat/comm.proto @@ -11,3 +11,11 @@ message BroadcastMessage { bytes payload = 5; } + +message BoolMsg { + bool value = 1; +} + +message IntMsg { + int32 value = 1; +} diff --git a/polling-station/build.gradle b/polling-station/build.gradle index 036d2e8..4635668 100644 --- a/polling-station/build.gradle +++ b/polling-station/build.gradle @@ -2,10 +2,8 @@ plugins { id "us.kirchmeier.capsule" version "1.0.1" id 'com.google.protobuf' version '0.7.0' - id 'org.akhikhl.gretty' version "1.2.4" } -apply plugin: 'org.akhikhl.gretty' apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'idea' @@ -46,10 +44,11 @@ dependencies { compile project(':restful-api-common') // Jersey for RESTful API - compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.22.+' + compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.5.+' // Servlets - compile 'javax.servlet:javax.servlet-api:3.0.+' + compile 'org.eclipse.jetty:jetty-server:9.3.+' + compile 'org.eclipse.jetty:jetty-servlet:9.3.+' // Logging compile 'org.slf4j:slf4j-api:1.7.7' diff --git a/polling-station/src/main/java/meerkat/pollingstation/PollingStationScannerWebApp.java b/polling-station/src/main/java/meerkat/pollingstation/PollingStationScannerWebApp.java new file mode 100644 index 0000000..edebe33 --- /dev/null +++ b/polling-station/src/main/java/meerkat/pollingstation/PollingStationScannerWebApp.java @@ -0,0 +1,89 @@ +package meerkat.pollingstation; + +/** + * Created by Arbel on 5/31/2016. + */ + +import com.google.common.util.concurrent.FutureCallback; +import meerkat.protobuf.Comm; +import meerkat.protobuf.PollingStation; + +import javax.annotation.PostConstruct; +import javax.servlet.ServletContext; +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import java.io.IOException; +import java.util.Iterator; + +import static meerkat.pollingstation.PollingStationConstants.POLLING_STATION_WEB_SCANNER_ERROR_PATH; +import static meerkat.pollingstation.PollingStationConstants.POLLING_STATION_WEB_SCANNER_SCAN_PATH; +import static meerkat.rest.Constants.MEDIATYPE_PROTOBUF; + +/** + * Implements a Web-App interface for {@link meerkat.pollingstation.PollingStationScanner.Producer} + * This class depends on {@link meerkat.pollingstation.PollingStationWebScanner} and works in conjunction with it + */ +@Path("/") +public class PollingStationScannerWebApp implements PollingStationScanner.Producer { + + @Context + ServletContext servletContext; + + Iterator> callbacks; + + /** + * This method is called by the Jetty engine when instantiating the servlet + */ + @PostConstruct + public void init() throws Exception{ + callbacks = ((PollingStationWebScanner.CallbackAccessor) servletContext.getAttribute(PollingStationWebScanner.CALLBACKS_ATTRIBUTE_NAME)).getCallbackIterator(); + } + + @POST + @Path(POLLING_STATION_WEB_SCANNER_SCAN_PATH) + @Consumes(MEDIATYPE_PROTOBUF) + @Produces(MEDIATYPE_PROTOBUF) + @Override + public Comm.BoolMsg newScan(PollingStation.ScannedData scannedData) { + + boolean handled = false; + + while (callbacks.hasNext()){ + + callbacks.next().onSuccess(scannedData); + handled = true; + + } + + return Comm.BoolMsg.newBuilder() + .setValue(handled) + .build(); + + } + + @POST + @Path(POLLING_STATION_WEB_SCANNER_ERROR_PATH) + @Consumes(MEDIATYPE_PROTOBUF) + @Produces(MEDIATYPE_PROTOBUF) + @Override + public Comm.BoolMsg reportScanError(PollingStation.ErrorMsg errorMsg) { + + boolean handled = false; + + while (callbacks.hasNext()){ + + callbacks.next().onFailure(new IOException(errorMsg.getMsg())); + handled = true; + + } + + return Comm.BoolMsg.newBuilder() + .setValue(handled) + .build(); + + } + +} diff --git a/polling-station/src/main/java/meerkat/pollingstation/PollingStationWebScanner.java b/polling-station/src/main/java/meerkat/pollingstation/PollingStationWebScanner.java index a3aefdd..d7fc6a4 100644 --- a/polling-station/src/main/java/meerkat/pollingstation/PollingStationWebScanner.java +++ b/polling-station/src/main/java/meerkat/pollingstation/PollingStationWebScanner.java @@ -1,27 +1,57 @@ package meerkat.pollingstation; -import com.google.common.util.concurrent.FutureCallback; -import meerkat.protobuf.PollingStation; -import static meerkat.rest.Constants.*; - -import javax.ws.rs.*; -import java.io.IOException; -import java.util.LinkedList; +import java.util.Iterator; import java.util.List; +import java.util.LinkedList; + +import com.google.common.util.concurrent.FutureCallback; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.*; -import static meerkat.pollingstation.PollingStationConstants.*; import meerkat.protobuf.PollingStation.*; +import org.glassfish.jersey.servlet.ServletContainer; +import org.glassfish.jersey.server.ResourceConfig; + +import meerkat.protobuf.PollingStation.ScannedData; +import meerkat.rest.*; /** * Created by Arbel on 05/05/2016. */ -@Path(POLLING_STATION_WEB_SCANNER_PATH) -public class PollingStationWebScanner implements PollingStationScanner{ +public class PollingStationWebScanner implements PollingStationScanner.Consumer{ + + public final static String CALLBACKS_ATTRIBUTE_NAME = "callbacks"; + + private final Server server; private final List> callbacks; - public PollingStationWebScanner() { + public PollingStationWebScanner(HTTPAddress address) { + callbacks = new LinkedList<>(); + + server = new Server(address.getPort()); + + ServletContextHandler servletContextHandler = new ServletContextHandler(server, address.getAddress()); + servletContextHandler.setAttribute(CALLBACKS_ATTRIBUTE_NAME, new CallbackAccessor()); + + ResourceConfig resourceConfig = new ResourceConfig(PollingStationScannerWebApp.class); + resourceConfig.register(ProtobufMessageBodyReader.class); + resourceConfig.register(ProtobufMessageBodyWriter.class); + + ServletHolder servletHolder = new ServletHolder(new ServletContainer(resourceConfig)); + + servletContextHandler.addServlet(servletHolder, "/*"); + } + + @Override + public void start() throws Exception { + server.start(); + } + + @Override + public void stop() throws Exception { + server.stop(); } @Override @@ -29,43 +59,10 @@ public class PollingStationWebScanner implements PollingStationScanner{ callbacks.add(scanCallback); } - @Path(POLLING_STATION_WEB_SCANNER_SCAN_PATH) - @POST - @Consumes(MEDIATYPE_PROTOBUF) - @Produces(MEDIATYPE_PROTOBUF) - @Override - public void newScan(ScannedData scannedData) { - - if (callbacks.size() <= 0) - throw new RuntimeException("No subscribers to forward scan to!"); - - for (FutureCallback callback : callbacks){ - callback.onSuccess(scannedData); + public class CallbackAccessor { + public Iterator> getCallbackIterator() { + return callbacks.iterator(); } - } - @Path(POLLING_STATION_WEB_SCANNER_ERROR_PATH) - @POST - @Consumes(MEDIATYPE_PROTOBUF) - @Produces(MEDIATYPE_PROTOBUF) - @Override - public void reportScanError(PollingStation.ErrorMsg errorMsg) { - - if (callbacks.size() <= 0) - throw new RuntimeException("No subscribers to forward error to!"); - - for (FutureCallback callback : callbacks){ - callback.onFailure(new IOException(errorMsg.getMsg())); - } - - } - - @Path("/test") - @GET - public String test(){ - return "test"; - } - - } diff --git a/polling-station/src/main/webapp/META-INF/jetty-env.xml b/polling-station/src/main/webapp/META-INF/jetty-env.xml deleted file mode 100644 index c4d368f..0000000 --- a/polling-station/src/main/webapp/META-INF/jetty-env.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern - none - - - org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern - none - - \ No newline at end of file diff --git a/polling-station/src/main/webapp/WEB-INF/web.xml b/polling-station/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 0632b0d..0000000 --- a/polling-station/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - Jersey Hello World - - org.glassfish.jersey.servlet.ServletContainer - - - jersey.config.server.provider.packages - meerkat - - 1 - - - Jersey Hello World - /* - - - meerkat.pollingstation.PollingStationWebScanner - - diff --git a/polling-station/src/test/java/meerkat/pollingstation/PollingStationWebScannerTest.java b/polling-station/src/test/java/meerkat/pollingstation/PollingStationWebScannerTest.java new file mode 100644 index 0000000..63cd8dd --- /dev/null +++ b/polling-station/src/test/java/meerkat/pollingstation/PollingStationWebScannerTest.java @@ -0,0 +1,169 @@ +package meerkat.pollingstation; + +import com.google.common.util.concurrent.FutureCallback; +import com.google.protobuf.ByteString; +import com.sun.org.apache.regexp.internal.RE; +import meerkat.protobuf.PollingStation; +import meerkat.protobuf.PollingStation.*; +import meerkat.rest.Constants; + +import meerkat.rest.*; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Response; + +import java.io.IOException; +import java.util.concurrent.Semaphore; + +import static meerkat.pollingstation.PollingStationConstants.*; + +import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.MatcherAssert.assertThat; + +/** + * Created by Arbel on 25/05/2016. + */ +public class PollingStationWebScannerTest { + + private PollingStationScanner.Consumer scanner; + private HTTPAddress httpAddress; + + private Semaphore semaphore; + private Throwable thrown; + private boolean dataIsAsExpected; + + private class ScanHandler implements FutureCallback { + + private final ScannedData expectedData; + + public ScanHandler(ScannedData expectedData) { + this.expectedData = expectedData; + } + + @Override + public void onSuccess(ScannedData result) { + dataIsAsExpected = result.getData().equals(expectedData.getData()); + semaphore.release(); + } + + @Override + public void onFailure(Throwable t) { + dataIsAsExpected = false; + thrown = t; + semaphore.release(); + } + } + + private class ErrorHandler implements FutureCallback { + + private final String expectedErrorMessage; + + public ErrorHandler(String expectedErrorMessage) { + this.expectedErrorMessage = expectedErrorMessage; + } + + @Override + public void onSuccess(ScannedData result) { + dataIsAsExpected = false; + semaphore.release(); + } + + @Override + public void onFailure(Throwable t) { + dataIsAsExpected = t.getMessage().equals(expectedErrorMessage); + semaphore.release(); + } + } + + @Before + public void init() { + + System.err.println("Setting up Scanner WebApp!"); + + httpAddress = HTTPAddress.newBuilder() + .setPort(8080) + .setHostname("http://localhost") + .build(); + + scanner = new PollingStationWebScanner(httpAddress); + + semaphore = new Semaphore(0); + thrown = null; + + try { + scanner.start(); + } catch (Exception e) { + assertThat("Could not start server: " + e.getMessage(), false); + } + + } + + @Test + public void testSuccessfulScan() throws InterruptedException { + + Client client = ClientBuilder.newClient(); + client.register(ProtobufMessageBodyReader.class); + client.register(ProtobufMessageBodyWriter.class); + WebTarget webTarget = client.target(httpAddress.getHostname() + ":" + httpAddress.getPort()) + .path(httpAddress.getAddress()).path(POLLING_STATION_WEB_SCANNER_SCAN_PATH); + + byte[] data = {(byte) 1, (byte) 2}; + + ScannedData scannedData = ScannedData.newBuilder() + .setData(ByteString.copyFrom(data)) + .build(); + + scanner.subscribe(new ScanHandler(scannedData)); + + Response response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(scannedData, Constants.MEDIATYPE_PROTOBUF)); + response.close(); + + semaphore.acquire(); + assertThat("Scanner has thrown an error", thrown == null); + assertThat("Scanned data received was incorrect", dataIsAsExpected); + + } + + @Test + public void testErroneousScan() throws InterruptedException { + + Client client = ClientBuilder.newClient(); + client.register(ProtobufMessageBodyReader.class); + client.register(ProtobufMessageBodyWriter.class); + WebTarget webTarget = client.target(httpAddress.getHostname() + ":" + httpAddress.getPort()) + .path(httpAddress.getAddress()).path(POLLING_STATION_WEB_SCANNER_ERROR_PATH); + + ErrorMsg errorMsg = ErrorMsg.newBuilder() + .setMsg("!Error Message!") + .build(); + + scanner.subscribe(new ErrorHandler(errorMsg.getMsg())); + + Response response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(errorMsg, Constants.MEDIATYPE_PROTOBUF)); + response.close(); + + semaphore.acquire(); + assertThat("Scanner error received was incorrect", dataIsAsExpected); + + } + + @After + public void close() { + + System.err.println("Scanner WebApp shutting down..."); + + try { + scanner.stop(); + } catch (Exception e) { + assertThat("Could not stop server: " + e.getMessage(), false); + } + + } + +} \ No newline at end of file From ffac7c1e3486291b6e0f36952696013f8cb09654 Mon Sep 17 00:00:00 2001 From: "arbel.peled" Date: Thu, 2 Jun 2016 14:48:48 +0300 Subject: [PATCH 48/49] Fixed all of Tal's remarks. Switched to using the predefined BoolValue Protobuf. --- .../SimpleBulletinBoardClient.java | 3 +- .../SingleServerBulletinBoardClient.java | 2 -- .../SingleServerGenericPostWorker.java | 5 +-- .../sqlserver/BulletinBoardSQLServer.java | 34 +++++++++---------- .../webapp/BulletinBoardWebApp.java | 9 ++--- ...BulletinBoardSQLServerIntegrationTest.java | 7 ++-- .../GenericBulletinBoardServerTest.java | 7 ++-- .../bulletinboard/BulletinBoardServer.java | 10 +++--- .../pollingstation/PollingStationScanner.java | 10 +++--- .../main/proto/meerkat/PollingStation.proto | 7 ---- .../src/main/proto/meerkat/comm.proto | 10 +----- .../PollingStationScannerWebApp.java | 23 ++++++------- .../PollingStationWebScanner.java | 16 +++------ .../PollingStationWebScannerTest.java | 23 +++++-------- 14 files changed, 69 insertions(+), 97 deletions(-) diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java index 26b1e4e..74eacae 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SimpleBulletinBoardClient.java @@ -1,5 +1,6 @@ package meerkat.bulletinboard; +import com.google.protobuf.BoolValue; import com.google.protobuf.ByteString; import meerkat.comm.CommunicationException; import meerkat.crypto.Digest; @@ -70,7 +71,7 @@ public class SimpleBulletinBoardClient implements BulletinBoardClient{ // Only consider valid responses if (response.getStatusInfo() == Response.Status.OK || response.getStatusInfo() == Response.Status.CREATED) { - response.readEntity(BoolMsg.class).getValue(); + response.readEntity(BoolValue.class).getValue(); } } } catch (Exception e) { // Occurs only when server replies with valid status but invalid data diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java index 34531cf..5edd079 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/SingleServerBulletinBoardClient.java @@ -7,12 +7,10 @@ import com.google.common.util.concurrent.MoreExecutors; import com.google.protobuf.ByteString; import meerkat.bulletinboard.workers.singleserver.*; import meerkat.comm.CommunicationException; -import meerkat.protobuf.BulletinBoardAPI; import meerkat.protobuf.BulletinBoardAPI.*; import meerkat.protobuf.Voting.BulletinBoardClientParams; import meerkat.util.BulletinBoardUtils; -import javax.ws.rs.NotFoundException; import java.util.Arrays; import java.util.Iterator; import java.util.LinkedList; diff --git a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerGenericPostWorker.java b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerGenericPostWorker.java index 2148801..08a66d1 100644 --- a/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerGenericPostWorker.java +++ b/bulletin-board-client/src/main/java/meerkat/bulletinboard/workers/singleserver/SingleServerGenericPostWorker.java @@ -1,5 +1,6 @@ package meerkat.bulletinboard.workers.singleserver; +import com.google.protobuf.BoolValue; import meerkat.bulletinboard.SingleServerWorker; import meerkat.comm.CommunicationException; import meerkat.protobuf.Comm.*; @@ -43,8 +44,8 @@ public class SingleServerGenericPostWorker extends SingleServerWorker lengthResult = jdbcTemplate.query(sql, namedParameters, new LongMapper()); if (lengthResult.get(0) != message.getBatchLength()) { - return BoolMsg.newBuilder().setValue(false).build(); + return BoolValue.newBuilder().setValue(false).build(); } // Get Tags and add them to CompleteBatch @@ -813,7 +813,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ // TODO: Actual verification // //signer.verify(completeBatch); // } catch (CertificateException | InvalidKeyException | SignatureException e) { -// return BoolMsg.newBuilder().setValue(false).build(); +// return BoolValue.newBuilder().setValue(false).build(); // } // Batch verified: finalize it @@ -849,7 +849,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{ // Return TRUE - return BoolMsg.newBuilder().setValue(true).build(); + return BoolValue.newBuilder().setValue(true).build(); } diff --git a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java index f88d31f..aef820e 100644 --- a/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java +++ b/bulletin-board-server/src/main/java/meerkat/bulletinboard/webapp/BulletinBoardWebApp.java @@ -8,6 +8,7 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.StreamingOutput; +import com.google.protobuf.BoolValue; import meerkat.bulletinboard.BulletinBoardServer; import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer; import meerkat.bulletinboard.sqlserver.H2QueryProvider; @@ -88,7 +89,7 @@ public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextL @Consumes(MEDIATYPE_PROTOBUF) @Produces(MEDIATYPE_PROTOBUF) @Override - public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException { + public BoolValue postMessage(BulletinBoardMessage msg) throws CommunicationException { init(); return bulletinBoard.postMessage(msg); } @@ -132,7 +133,7 @@ public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextL @Consumes(MEDIATYPE_PROTOBUF) @Produces(MEDIATYPE_PROTOBUF) @Override - public BoolMsg beginBatch(BeginBatchMessage message) { + public BoolValue beginBatch(BeginBatchMessage message) { try { init(); return bulletinBoard.beginBatch(message); @@ -147,7 +148,7 @@ public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextL @Consumes(MEDIATYPE_PROTOBUF) @Produces(MEDIATYPE_PROTOBUF) @Override - public BoolMsg postBatchMessage(BatchMessage batchMessage) { + public BoolValue postBatchMessage(BatchMessage batchMessage) { try { init(); return bulletinBoard.postBatchMessage(batchMessage); @@ -162,7 +163,7 @@ public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextL @Consumes(MEDIATYPE_PROTOBUF) @Produces(MEDIATYPE_PROTOBUF) @Override - public BoolMsg closeBatchMessage(CloseBatchMessage message) { + public BoolValue closeBatchMessage(CloseBatchMessage message) { try { init(); return bulletinBoard.closeBatchMessage(message); diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/BulletinBoardSQLServerIntegrationTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/BulletinBoardSQLServerIntegrationTest.java index a9be646..844a050 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/BulletinBoardSQLServerIntegrationTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/BulletinBoardSQLServerIntegrationTest.java @@ -1,6 +1,7 @@ package meerkat.bulletinboard; +import com.google.protobuf.BoolValue; import com.google.protobuf.ByteString; import com.google.protobuf.TextFormat; @@ -61,7 +62,7 @@ public class BulletinBoardSQLServerIntegrationTest { WebTarget webTarget; Response response; - BoolMsg bool; + BoolValue bool; BulletinBoardMessage msg; @@ -95,7 +96,7 @@ public class BulletinBoardSQLServerIntegrationTest { response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(msg, Constants.MEDIATYPE_PROTOBUF)); System.err.println(response); - bool = response.readEntity(BoolMsg.class); + bool = response.readEntity(BoolValue.class); assert bool.getValue(); msg = BulletinBoardMessage.newBuilder() @@ -114,7 +115,7 @@ public class BulletinBoardSQLServerIntegrationTest { response = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(msg, Constants.MEDIATYPE_PROTOBUF)); System.err.println(response); - bool = response.readEntity(BoolMsg.class); + bool = response.readEntity(BoolValue.class); assert bool.getValue(); // Test reading mechanism diff --git a/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java b/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java index e09f051..49c3050 100644 --- a/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java +++ b/bulletin-board-server/src/test/java/meerkat/bulletinboard/GenericBulletinBoardServerTest.java @@ -17,6 +17,7 @@ import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.util.*; +import com.google.protobuf.BoolValue; import com.google.protobuf.ByteString; import com.google.protobuf.Timestamp; @@ -457,7 +458,7 @@ public class GenericBulletinBoardServerTest { .setSeconds(978325) .setNanos(8097234) .build()); - BoolMsg result; + BoolValue result; // Create data @@ -527,7 +528,7 @@ public class GenericBulletinBoardServerTest { .build()); int currentBatch = completeBatches.size(); - BoolMsg result; + BoolValue result; // Define batch data @@ -646,7 +647,7 @@ public class GenericBulletinBoardServerTest { BulletinBoardMessage newMessage = bulletinBoardMessageGenerator.generateRandomMessage(signers, timestamp, 10, 10); - BoolMsg result = bulletinBoardServer.postMessage(newMessage); + BoolValue result = bulletinBoardServer.postMessage(newMessage); assertThat("Failed to post message to BB Server", result.getValue(), is(true)); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); diff --git a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java index abe4335..1507ab7 100644 --- a/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java +++ b/meerkat-common/src/main/java/meerkat/bulletinboard/BulletinBoardServer.java @@ -1,9 +1,9 @@ package meerkat.bulletinboard; +import com.google.protobuf.BoolValue; import meerkat.comm.CommunicationException; import meerkat.comm.MessageOutputStream; import meerkat.protobuf.BulletinBoardAPI.*; -import meerkat.protobuf.Comm.*; import java.util.Collection; @@ -30,7 +30,7 @@ public interface BulletinBoardServer{ * @return TRUE if the message has been authenticated and FALSE otherwise (in ProtoBuf form) * @throws CommunicationException on DB connection error */ - public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException; + public BoolValue postMessage(BulletinBoardMessage msg) throws CommunicationException; /** * Read all messages posted matching the given filter @@ -48,7 +48,7 @@ public interface BulletinBoardServer{ * However, if such a batch exists and is already closed: the value returned will be FALSE * @throws CommunicationException on DB connection error */ - public BoolMsg beginBatch(BeginBatchMessage message) throws CommunicationException; + public BoolValue beginBatch(BeginBatchMessage message) throws CommunicationException; /** * Posts a (part of a) batch message to the bulletin board @@ -60,7 +60,7 @@ public interface BulletinBoardServer{ * However, requiring to open a batch before insertion of messages is implementation-dependent * @throws CommunicationException on DB connection error */ - public BoolMsg postBatchMessage(BatchMessage batchMessage) throws CommunicationException; + public BoolValue postBatchMessage(BatchMessage batchMessage) throws CommunicationException; /** * Attempts to stop and finalize a batch message @@ -69,7 +69,7 @@ public interface BulletinBoardServer{ * Specifically, if the signature is invalid or if some of the batch parts have not yet been submitted: the value returned will be FALSE * @throws CommunicationException on DB connection error */ - public BoolMsg closeBatchMessage(CloseBatchMessage message) throws CommunicationException; + public BoolValue closeBatchMessage(CloseBatchMessage message) throws CommunicationException; /** * Reads a batch message from the server (starting with the supplied position) diff --git a/meerkat-common/src/main/java/meerkat/pollingstation/PollingStationScanner.java b/meerkat-common/src/main/java/meerkat/pollingstation/PollingStationScanner.java index 9adc616..290d0ee 100644 --- a/meerkat-common/src/main/java/meerkat/pollingstation/PollingStationScanner.java +++ b/meerkat-common/src/main/java/meerkat/pollingstation/PollingStationScanner.java @@ -1,7 +1,7 @@ package meerkat.pollingstation; import com.google.common.util.concurrent.FutureCallback; -import meerkat.protobuf.Comm.BoolMsg; +import com.google.protobuf.BoolValue; import meerkat.protobuf.PollingStation.*; /** * Created by Arbel on 05/05/2016. @@ -45,16 +45,16 @@ public interface PollingStationScanner { /** * Sends a scan to all subscribers * @param scannedData contains the scanned data - * @return a BoolMsg containing TRUE iff the scanned data has been sent to at least one subscriber + * @return a BoolValue containing TRUE iff the scanned data has been sent to at least one subscriber */ - public BoolMsg newScan(ScannedData scannedData); + public BoolValue newScan(ScannedData scannedData); /** * Notifies subscribers about an error that occurred during scan * @param errorMsg is the error that occurred - * @return a BoolMsg containing TRUE iff the error has been sent to at least one subscriber + * @return a BoolValue containing TRUE iff the error has been sent to at least one subscriber */ - public BoolMsg reportScanError(ErrorMsg errorMsg); + public BoolValue reportScanError(ErrorMsg errorMsg); } diff --git a/meerkat-common/src/main/proto/meerkat/PollingStation.proto b/meerkat-common/src/main/proto/meerkat/PollingStation.proto index 35dbd12..0cdc658 100644 --- a/meerkat-common/src/main/proto/meerkat/PollingStation.proto +++ b/meerkat-common/src/main/proto/meerkat/PollingStation.proto @@ -12,11 +12,4 @@ message ScannedData { // Container for error messages message ErrorMsg { string msg = 1; -} - -// Container for HTTP address -message HTTPAddress { - string hostname = 1; - int32 port = 2; - string address = 3; } \ No newline at end of file diff --git a/meerkat-common/src/main/proto/meerkat/comm.proto b/meerkat-common/src/main/proto/meerkat/comm.proto index 2f23678..6808288 100644 --- a/meerkat-common/src/main/proto/meerkat/comm.proto +++ b/meerkat-common/src/main/proto/meerkat/comm.proto @@ -10,12 +10,4 @@ message BroadcastMessage { bool is_private = 3; bytes payload = 5; -} - -message BoolMsg { - bool value = 1; -} - -message IntMsg { - int32 value = 1; -} +} \ No newline at end of file diff --git a/polling-station/src/main/java/meerkat/pollingstation/PollingStationScannerWebApp.java b/polling-station/src/main/java/meerkat/pollingstation/PollingStationScannerWebApp.java index edebe33..327c774 100644 --- a/polling-station/src/main/java/meerkat/pollingstation/PollingStationScannerWebApp.java +++ b/polling-station/src/main/java/meerkat/pollingstation/PollingStationScannerWebApp.java @@ -5,7 +5,7 @@ package meerkat.pollingstation; */ import com.google.common.util.concurrent.FutureCallback; -import meerkat.protobuf.Comm; +import com.google.protobuf.BoolValue; import meerkat.protobuf.PollingStation; import javax.annotation.PostConstruct; @@ -16,7 +16,6 @@ import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import java.io.IOException; -import java.util.Iterator; import static meerkat.pollingstation.PollingStationConstants.POLLING_STATION_WEB_SCANNER_ERROR_PATH; import static meerkat.pollingstation.PollingStationConstants.POLLING_STATION_WEB_SCANNER_SCAN_PATH; @@ -32,14 +31,14 @@ public class PollingStationScannerWebApp implements PollingStationScanner.Produc @Context ServletContext servletContext; - Iterator> callbacks; + Iterable> callbacks; /** * This method is called by the Jetty engine when instantiating the servlet */ @PostConstruct public void init() throws Exception{ - callbacks = ((PollingStationWebScanner.CallbackAccessor) servletContext.getAttribute(PollingStationWebScanner.CALLBACKS_ATTRIBUTE_NAME)).getCallbackIterator(); + callbacks = (Iterable>) servletContext.getAttribute(PollingStationWebScanner.CALLBACKS_ATTRIBUTE_NAME); } @POST @@ -47,18 +46,18 @@ public class PollingStationScannerWebApp implements PollingStationScanner.Produc @Consumes(MEDIATYPE_PROTOBUF) @Produces(MEDIATYPE_PROTOBUF) @Override - public Comm.BoolMsg newScan(PollingStation.ScannedData scannedData) { + public BoolValue newScan(PollingStation.ScannedData scannedData) { boolean handled = false; - while (callbacks.hasNext()){ + for (FutureCallback callback : callbacks){ - callbacks.next().onSuccess(scannedData); + callback.onSuccess(scannedData); handled = true; } - return Comm.BoolMsg.newBuilder() + return BoolValue.newBuilder() .setValue(handled) .build(); @@ -69,18 +68,18 @@ public class PollingStationScannerWebApp implements PollingStationScanner.Produc @Consumes(MEDIATYPE_PROTOBUF) @Produces(MEDIATYPE_PROTOBUF) @Override - public Comm.BoolMsg reportScanError(PollingStation.ErrorMsg errorMsg) { + public BoolValue reportScanError(PollingStation.ErrorMsg errorMsg) { boolean handled = false; - while (callbacks.hasNext()){ + for (FutureCallback callback : callbacks){ - callbacks.next().onFailure(new IOException(errorMsg.getMsg())); + callback.onFailure(new IOException(errorMsg.getMsg())); handled = true; } - return Comm.BoolMsg.newBuilder() + return BoolValue.newBuilder() .setValue(handled) .build(); diff --git a/polling-station/src/main/java/meerkat/pollingstation/PollingStationWebScanner.java b/polling-station/src/main/java/meerkat/pollingstation/PollingStationWebScanner.java index d7fc6a4..a4e290a 100644 --- a/polling-station/src/main/java/meerkat/pollingstation/PollingStationWebScanner.java +++ b/polling-station/src/main/java/meerkat/pollingstation/PollingStationWebScanner.java @@ -1,6 +1,5 @@ package meerkat.pollingstation; -import java.util.Iterator; import java.util.List; import java.util.LinkedList; @@ -8,7 +7,6 @@ import com.google.common.util.concurrent.FutureCallback; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.*; -import meerkat.protobuf.PollingStation.*; import org.glassfish.jersey.servlet.ServletContainer; import org.glassfish.jersey.server.ResourceConfig; @@ -26,14 +24,14 @@ public class PollingStationWebScanner implements PollingStationScanner.Consumer{ private final Server server; private final List> callbacks; - public PollingStationWebScanner(HTTPAddress address) { + public PollingStationWebScanner(int port, String subAddress) { callbacks = new LinkedList<>(); - server = new Server(address.getPort()); + server = new Server(port); - ServletContextHandler servletContextHandler = new ServletContextHandler(server, address.getAddress()); - servletContextHandler.setAttribute(CALLBACKS_ATTRIBUTE_NAME, new CallbackAccessor()); + ServletContextHandler servletContextHandler = new ServletContextHandler(server, subAddress); + servletContextHandler.setAttribute(CALLBACKS_ATTRIBUTE_NAME, (Iterable>) callbacks); ResourceConfig resourceConfig = new ResourceConfig(PollingStationScannerWebApp.class); resourceConfig.register(ProtobufMessageBodyReader.class); @@ -59,10 +57,4 @@ public class PollingStationWebScanner implements PollingStationScanner.Consumer{ callbacks.add(scanCallback); } - public class CallbackAccessor { - public Iterator> getCallbackIterator() { - return callbacks.iterator(); - } - } - } diff --git a/polling-station/src/test/java/meerkat/pollingstation/PollingStationWebScannerTest.java b/polling-station/src/test/java/meerkat/pollingstation/PollingStationWebScannerTest.java index 63cd8dd..7da106c 100644 --- a/polling-station/src/test/java/meerkat/pollingstation/PollingStationWebScannerTest.java +++ b/polling-station/src/test/java/meerkat/pollingstation/PollingStationWebScannerTest.java @@ -2,8 +2,6 @@ package meerkat.pollingstation; import com.google.common.util.concurrent.FutureCallback; import com.google.protobuf.ByteString; -import com.sun.org.apache.regexp.internal.RE; -import meerkat.protobuf.PollingStation; import meerkat.protobuf.PollingStation.*; import meerkat.rest.Constants; @@ -18,12 +16,10 @@ import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.Response; -import java.io.IOException; import java.util.concurrent.Semaphore; import static meerkat.pollingstation.PollingStationConstants.*; -import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.MatcherAssert.assertThat; /** @@ -32,7 +28,9 @@ import static org.hamcrest.MatcherAssert.assertThat; public class PollingStationWebScannerTest { private PollingStationScanner.Consumer scanner; - private HTTPAddress httpAddress; + private static final String ADDRESS = "http://localhost"; + private static final String SUB_ADDRESS = ""; + private static final int PORT = 8080; private Semaphore semaphore; private Throwable thrown; @@ -86,12 +84,7 @@ public class PollingStationWebScannerTest { System.err.println("Setting up Scanner WebApp!"); - httpAddress = HTTPAddress.newBuilder() - .setPort(8080) - .setHostname("http://localhost") - .build(); - - scanner = new PollingStationWebScanner(httpAddress); + scanner = new PollingStationWebScanner(PORT, SUB_ADDRESS); semaphore = new Semaphore(0); thrown = null; @@ -110,8 +103,8 @@ public class PollingStationWebScannerTest { Client client = ClientBuilder.newClient(); client.register(ProtobufMessageBodyReader.class); client.register(ProtobufMessageBodyWriter.class); - WebTarget webTarget = client.target(httpAddress.getHostname() + ":" + httpAddress.getPort()) - .path(httpAddress.getAddress()).path(POLLING_STATION_WEB_SCANNER_SCAN_PATH); + WebTarget webTarget = client.target(ADDRESS + ":" + PORT) + .path(SUB_ADDRESS).path(POLLING_STATION_WEB_SCANNER_SCAN_PATH); byte[] data = {(byte) 1, (byte) 2}; @@ -136,8 +129,8 @@ public class PollingStationWebScannerTest { Client client = ClientBuilder.newClient(); client.register(ProtobufMessageBodyReader.class); client.register(ProtobufMessageBodyWriter.class); - WebTarget webTarget = client.target(httpAddress.getHostname() + ":" + httpAddress.getPort()) - .path(httpAddress.getAddress()).path(POLLING_STATION_WEB_SCANNER_ERROR_PATH); + WebTarget webTarget = client.target(ADDRESS + ":" + PORT) + .path(SUB_ADDRESS).path(POLLING_STATION_WEB_SCANNER_ERROR_PATH); ErrorMsg errorMsg = ErrorMsg.newBuilder() .setMsg("!Error Message!") From 06d69554d9d15317a26889e405e290b4ef6681f6 Mon Sep 17 00:00:00 2001 From: Hai Brenner Date: Sun, 26 Jun 2016 17:07:03 +0300 Subject: [PATCH 49/49] fixed some merge conflicts which appeared for some unknown reason --- bulletin-board-server/build.gradle | 525 ++++++++++++++--------------- voting-booth/build.gradle | 384 +++++++++++---------- 2 files changed, 453 insertions(+), 456 deletions(-) diff --git a/bulletin-board-server/build.gradle b/bulletin-board-server/build.gradle index 46ef4cf..766ed56 100644 --- a/bulletin-board-server/build.gradle +++ b/bulletin-board-server/build.gradle @@ -1,263 +1,262 @@ - -plugins { - id "us.kirchmeier.capsule" version "1.0.1" - id 'com.google.protobuf' version '0.7.0' - id 'org.akhikhl.gretty' version "1.2.4" -} - -apply plugin: 'org.akhikhl.gretty' -apply plugin: 'java' -apply plugin: 'eclipse' -apply plugin: 'idea' - -//apply plugin: 'application' - -//apply plugin: 'jetty' -//mainClassName = 'SQLiteIntegrationTest' - -apply plugin: 'maven-publish' - -// Is this a snapshot version? -ext { isSnapshot = false } - -ext { - groupId = 'org.factcenter.meerkat' - nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/" - - // Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing) - // Should be set in ${HOME}/.gradle/gradle.properties - nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : "" - nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : "" -} - -description = "Bulletin-board server web application" - -// Your project version -version = "0.0.1" - -version += "${isSnapshot ? '-SNAPSHOT' : ''}" - - -dependencies { - // Meerkat common - compile project(':meerkat-common') - compile project(':restful-api-common') - - // Jersey for RESTful API - compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.22.+' - - // JDBC connections - compile 'org.springframework:spring-jdbc:4.2.+' - compile 'org.xerial:sqlite-jdbc:3.8.+' - compile 'mysql:mysql-connector-java:5.1.+' - compile 'com.h2database:h2:1.0.+' - compile 'org.apache.commons:commons-dbcp2:2.0.+' - - // Servlets - compile 'javax.servlet:javax.servlet-api:3.0.+' - - // Logging - compile 'org.slf4j:slf4j-api:1.7.7' - runtime 'ch.qos.logback:logback-classic:1.1.2' - runtime 'ch.qos.logback:logback-core:1.1.2' - - // Google protobufs - compile 'com.google.protobuf:protobuf-java:3.+' - - // Depend on test resources from meerkat-common - testCompile project(path: ':meerkat-common', configuration: 'testOutput') - - testCompile 'junit:junit:4.+' - - runtime 'org.codehaus.groovy:groovy:2.4.+' -} - - -test { - exclude '**/*SQLite*Test*' - exclude '**/*H2*Test*' - exclude '**/*MySQL*Test*' - exclude '**/*IntegrationTest*' -} - -task myTest(type: Test) { - include '**/*MySQL*Test*' - outputs.upToDateWhen { false } -} - -task h2Test(type: Test) { - include '**/*H2*Test*' - outputs.upToDateWhen { false } -} - -task liteTest(type: Test) { - include '**/*SQLite*Test*' - outputs.upToDateWhen { false } -} - -task dbTest(type: Test) { - include '**/*H2*Test*' - include '**/*MySQL*Test*' - include '**/*SQLite*Test*' - outputs.upToDateWhen { false } -} - -task manualIntegration(type: Test) { - include '**/*IntegrationTest*' -} - -task integrationTest(type: Test) { - include '**/*IntegrationTest*' -// debug = true - outputs.upToDateWhen { false } - -} - -gretty { - httpPort = 8081 - contextPath = '/' - integrationTestTask = 'integrationTest' - loggingLevel = 'TRACE' - debugPort = 5006 -} - - - -/*==== You probably don't have to edit below this line =======*/ - -protobuf { - // Configure the protoc executable - protoc { - // Download from repositories - artifact = 'com.google.protobuf:protoc:3.+' - } -} - - -idea { - module { - project.sourceSets.each { sourceSet -> - - def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java" - - // add protobuf generated sources to generated source dir. - if ("test".equals(sourceSet.name)) { - testSourceDirs += file(srcDir) - } else { - sourceDirs += file(srcDir) - } - generatedSourceDirs += file(srcDir) - - } - - // Don't exclude build directory - excludeDirs -= file(buildDir) - } -} - - -/*=================================== - * "Fat" Build targets - *===================================*/ - -if (project.hasProperty('mainClassName') && (mainClassName != null)) { - - task mavenCapsule(type: MavenCapsule) { - description = "Generate a capsule jar that automatically downloads and caches dependencies when run." - applicationClass mainClassName - destinationDir = buildDir - } - - task fatCapsule(type: FatCapsule) { - description = "Generate a single capsule jar containing everything. Use -Pfatmain=... to override main class" - - destinationDir = buildDir - - def fatMain = hasProperty('fatmain') ? fatmain : mainClassName - - applicationClass fatMain - - def testJar = hasProperty('test') - - if (hasProperty('fatmain')) { - appendix = "fat-${fatMain}" - } else { - appendix = "fat" - } - - if (testJar) { - from sourceSets.test.output - } - } -} - -/*=================================== - * Repositories - *===================================*/ - -repositories { - - // Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral) - maven { - url nexusRepository - - if (isSnapshot) { - credentials { username - password - - username nexusUser - password nexusPassword - } - } - } - - // Use local maven repository - mavenLocal() - - jcenter() - - // Use 'maven central' for other dependencies. - mavenCentral() -} - -task "info" << { - println "Project: ${project.name}" -println "Description: ${project.description}" - println "--------------------------" - println "GroupId: $groupId" - println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})" - println "" -} -info.description 'Print some information about project parameters' - - -/*=================================== - * Publishing - *===================================*/ - -publishing { - publications { - mavenJava(MavenPublication) { - groupId project.groupId - pom.withXml { - asNode().appendNode('description', project.description) - } - from project.components.java - - } - } - repositories { - maven { - url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}" - credentials { username - password - - username nexusUser - password nexusPassword - } - } - } -} - - - + +plugins { + id "us.kirchmeier.capsule" version "1.0.1" + id 'com.google.protobuf' version '0.7.0' + id 'org.akhikhl.gretty' version "1.2.4" +} + +apply plugin: 'org.akhikhl.gretty' +apply plugin: 'java' +apply plugin: 'eclipse' +apply plugin: 'idea' + +//apply plugin: 'application' + +//apply plugin: 'jetty' +//mainClassName = 'SQLiteIntegrationTest' + +apply plugin: 'maven-publish' + +// Is this a snapshot version? +ext { isSnapshot = false } + +ext { + groupId = 'org.factcenter.meerkat' + nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/" + + // Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing) + // Should be set in ${HOME}/.gradle/gradle.properties + nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : "" + nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : "" +} + +description = "Bulletin-board server web application" + +// Your project version +version = "0.0.1" + +version += "${isSnapshot ? '-SNAPSHOT' : ''}" + + +dependencies { + // Meerkat common + compile project(':meerkat-common') + compile project(':restful-api-common') + + // Jersey for RESTful API + compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.22.+' + + // JDBC connections + compile 'org.springframework:spring-jdbc:4.2.+' + compile 'org.xerial:sqlite-jdbc:3.8.+' + compile 'mysql:mysql-connector-java:5.1.+' + compile 'com.h2database:h2:1.0.+' + compile 'org.apache.commons:commons-dbcp2:2.0.+' + + // Servlets + compile 'javax.servlet:javax.servlet-api:3.0.+' + + // Logging + compile 'org.slf4j:slf4j-api:1.7.7' + runtime 'ch.qos.logback:logback-classic:1.1.2' + runtime 'ch.qos.logback:logback-core:1.1.2' + + // Google protobufs + compile 'com.google.protobuf:protobuf-java:3.+' + + // Depend on test resources from meerkat-common + testCompile project(path: ':meerkat-common', configuration: 'testOutput') + + testCompile 'junit:junit:4.+' + + runtime 'org.codehaus.groovy:groovy:2.4.+' +} + + +test { + exclude '**/*SQLite*Test*' + exclude '**/*H2*Test*' + exclude '**/*MySQL*Test*' + exclude '**/*IntegrationTest*' +} + +task myTest(type: Test) { + include '**/*MySQL*Test*' + outputs.upToDateWhen { false } +} + +task h2Test(type: Test) { + include '**/*H2*Test*' + outputs.upToDateWhen { false } +} + +task liteTest(type: Test) { + include '**/*SQLite*Test*' + outputs.upToDateWhen { false } +} + +task dbTest(type: Test) { + include '**/*H2*Test*' + include '**/*MySQL*Test*' + include '**/*SQLite*Test*' + outputs.upToDateWhen { false } +} + +task manualIntegration(type: Test) { + include '**/*IntegrationTest*' +} + +task integrationTest(type: Test) { + include '**/*IntegrationTest*' +// debug = true + outputs.upToDateWhen { false } + +} + +gretty { + httpPort = 8081 + contextPath = '/' + integrationTestTask = 'integrationTest' + loggingLevel = 'TRACE' + debugPort = 5006 +} + + + +/*==== You probably don't have to edit below this line =======*/ + +protobuf { + // Configure the protoc executable + protoc { + // Download from repositories + artifact = 'com.google.protobuf:protoc:3.+' + } +} + + +idea { + module { + project.sourceSets.each { sourceSet -> + + def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java" + + // add protobuf generated sources to generated source dir. + if ("test".equals(sourceSet.name)) { + testSourceDirs += file(srcDir) + } else { + sourceDirs += file(srcDir) + } + generatedSourceDirs += file(srcDir) + + } + + // Don't exclude build directory + excludeDirs -= file(buildDir) + } +} + + +/*=================================== + * "Fat" Build targets + *===================================*/ + +if (project.hasProperty('mainClassName') && (mainClassName != null)) { + + task mavenCapsule(type: MavenCapsule) { + description = "Generate a capsule jar that automatically downloads and caches dependencies when run." + applicationClass mainClassName + destinationDir = buildDir + } + + task fatCapsule(type: FatCapsule) { + description = "Generate a single capsule jar containing everything. Use -Pfatmain=... to override main class" + + destinationDir = buildDir + + def fatMain = hasProperty('fatmain') ? fatmain : mainClassName + + applicationClass fatMain + + def testJar = hasProperty('test') + + if (hasProperty('fatmain')) { + appendix = "fat-${fatMain}" + } else { + appendix = "fat" + } + + if (testJar) { + from sourceSets.test.output + } + } +} + +/*=================================== + * Repositories + *===================================*/ + +repositories { + + // Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral) + maven { + url nexusRepository + + if (isSnapshot) { + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } + + // Use local maven repository + mavenLocal() + + jcenter() + + // Use 'maven central' for other dependencies. + mavenCentral() +} + +task "info" << { + println "Project: ${project.name}" +println "Description: ${project.description}" + println "--------------------------" + println "GroupId: $groupId" + println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})" + println "" +} +info.description 'Print some information about project parameters' + + +/*=================================== + * Publishing + *===================================*/ + +publishing { + publications { + mavenJava(MavenPublication) { + groupId project.groupId + pom.withXml { + asNode().appendNode('description', project.description) + } + from project.components.java + + } + } + repositories { + maven { + url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}" + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } +} + + diff --git a/voting-booth/build.gradle b/voting-booth/build.gradle index 241e3c3..7619b48 100644 --- a/voting-booth/build.gradle +++ b/voting-booth/build.gradle @@ -1,193 +1,191 @@ - -plugins { - id "us.kirchmeier.capsule" version "1.0.1" - id 'com.google.protobuf' version '0.7.0' -} - -apply plugin: 'java' -apply plugin: 'eclipse' -apply plugin: 'idea' - -apply plugin: 'maven-publish' - -// Uncomment the lines below to define an application -// (this will also allow you to build a "fatCapsule" which includes -// the entire application, including all dependencies in a single jar) -//apply plugin: 'application' -//mainClassName='your.main.ApplicationClass' - -// Is this a snapshot version? -ext { isSnapshot = false } - -ext { - groupId = 'org.factcenter.meerkat' - nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/" - - // Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing) - // Should be set in ${HOME}/.gradle/gradle.properties - nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : "" - nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : "" -} - -description = "Meerkat voting booth application" - -// Your project version -version = "0.0" - -version += "${isSnapshot ? '-SNAPSHOT' : ''}" - - -dependencies { - // Meerkat common - compile project(':meerkat-common') - - // Logging - compile 'org.slf4j:slf4j-api:1.7.7' - runtime 'ch.qos.logback:logback-classic:1.1.2' - runtime 'ch.qos.logback:logback-core:1.1.2' - - // Google protobufs - compile 'com.google.protobuf:protobuf-java:3.+' - - testCompile 'junit:junit:4.+' - - runtime 'org.codehaus.groovy:groovy:2.4.+' -} - - -/*==== You probably don't have to edit below this line =======*/ - -protobuf { - // Configure the protoc executable - protoc { - // Download from repositories - artifact = 'com.google.protobuf:protoc:3.+' - } -} - - -idea { - module { - project.sourceSets.each { sourceSet -> - - def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java" - - // add protobuf generated sources to generated source dir. - if ("test".equals(sourceSet.name)) { - testSourceDirs += file(srcDir) - } else { - sourceDirs += file(srcDir) - } - generatedSourceDirs += file(srcDir) - - } - - // Don't exclude build directory - excludeDirs -= file(buildDir) - } -} - - -/*=================================== - * "Fat" Build targets - *===================================*/ - -if (project.hasProperty('mainClassName') && (mainClassName != null)) { - - task mavenCapsule(type: MavenCapsule) { - description = "Generate a capsule jar that automatically downloads and caches dependencies when run." - applicationClass mainClassName - destinationDir = buildDir - } - - task fatCapsule(type: FatCapsule) { - description = "Generate a single capsule jar containing everything. Use -Pfatmain=... to override main class" - - destinationDir = buildDir - - def fatMain = hasProperty('fatmain') ? fatmain : mainClassName - - applicationClass fatMain - - def testJar = hasProperty('test') - - if (hasProperty('fatmain')) { - appendix = "fat-${fatMain}" - } else { - appendix = "fat" - } - - if (testJar) { - from sourceSets.test.output - } - } -} - -/*=================================== - * Repositories - *===================================*/ - -repositories { - - // Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral) - maven { - url nexusRepository - - if (isSnapshot) { - credentials { username - password - - username nexusUser - password nexusPassword - } - } - } - - // Use local maven repository - mavenLocal() - - // Use 'maven central' for other dependencies. - mavenCentral() -} - -task "info" << { - println "Project: ${project.name}" -println "Description: ${project.description}" - println "--------------------------" - println "GroupId: $groupId" - println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})" - println "" -} -info.description 'Print some information about project parameters' - - -/*=================================== - * Publishing - *===================================*/ - -publishing { - publications { - mavenJava(MavenPublication) { - groupId project.groupId - pom.withXml { - asNode().appendNode('description', project.description) - } - from project.components.java - - } - } - repositories { - maven { - url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}" - credentials { username - password - - username nexusUser - password nexusPassword - } - } - } -} - - - + +plugins { + id "us.kirchmeier.capsule" version "1.0.1" + id 'com.google.protobuf' version '0.7.0' +} + +apply plugin: 'java' +apply plugin: 'eclipse' +apply plugin: 'idea' + +apply plugin: 'maven-publish' + +// Uncomment the lines below to define an application +// (this will also allow you to build a "fatCapsule" which includes +// the entire application, including all dependencies in a single jar) +//apply plugin: 'application' +//mainClassName='your.main.ApplicationClass' + +// Is this a snapshot version? +ext { isSnapshot = false } + +ext { + groupId = 'org.factcenter.meerkat' + nexusRepository = "https://cs.idc.ac.il/nexus/content/groups/${isSnapshot ? 'unstable' : 'public'}/" + + // Credentials for IDC nexus repositories (needed only for using unstable repositories and publishing) + // Should be set in ${HOME}/.gradle/gradle.properties + nexusUser = project.hasProperty('nexusUser') ? project.property('nexusUser') : "" + nexusPassword = project.hasProperty('nexusPassword') ? project.property('nexusPassword') : "" +} + +description = "Meerkat voting booth application" + +// Your project version +version = "0.0" + +version += "${isSnapshot ? '-SNAPSHOT' : ''}" + + +dependencies { + // Meerkat common + compile project(':meerkat-common') + + // Logging + compile 'org.slf4j:slf4j-api:1.7.7' + runtime 'ch.qos.logback:logback-classic:1.1.2' + runtime 'ch.qos.logback:logback-core:1.1.2' + + // Google protobufs + compile 'com.google.protobuf:protobuf-java:3.+' + + testCompile 'junit:junit:4.+' + + runtime 'org.codehaus.groovy:groovy:2.4.+' +} + + +/*==== You probably don't have to edit below this line =======*/ + +protobuf { + // Configure the protoc executable + protoc { + // Download from repositories + artifact = 'com.google.protobuf:protoc:3.+' + } +} + + +idea { + module { + project.sourceSets.each { sourceSet -> + + def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java" + + // add protobuf generated sources to generated source dir. + if ("test".equals(sourceSet.name)) { + testSourceDirs += file(srcDir) + } else { + sourceDirs += file(srcDir) + } + generatedSourceDirs += file(srcDir) + + } + + // Don't exclude build directory + excludeDirs -= file(buildDir) + } +} + + +/*=================================== + * "Fat" Build targets + *===================================*/ + +if (project.hasProperty('mainClassName') && (mainClassName != null)) { + + task mavenCapsule(type: MavenCapsule) { + description = "Generate a capsule jar that automatically downloads and caches dependencies when run." + applicationClass mainClassName + destinationDir = buildDir + } + + task fatCapsule(type: FatCapsule) { + description = "Generate a single capsule jar containing everything. Use -Pfatmain=... to override main class" + + destinationDir = buildDir + + def fatMain = hasProperty('fatmain') ? fatmain : mainClassName + + applicationClass fatMain + + def testJar = hasProperty('test') + + if (hasProperty('fatmain')) { + appendix = "fat-${fatMain}" + } else { + appendix = "fat" + } + + if (testJar) { + from sourceSets.test.output + } + } +} + +/*=================================== + * Repositories + *===================================*/ + +repositories { + + // Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral) + maven { + url nexusRepository + + if (isSnapshot) { + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } + + // Use local maven repository + mavenLocal() + + // Use 'maven central' for other dependencies. + mavenCentral() +} + +task "info" << { + println "Project: ${project.name}" +println "Description: ${project.description}" + println "--------------------------" + println "GroupId: $groupId" + println "Version: $version (${isSnapshot ? 'snapshot' : 'release'})" + println "" +} +info.description 'Print some information about project parameters' + + +/*=================================== + * Publishing + *===================================*/ + +publishing { + publications { + mavenJava(MavenPublication) { + groupId project.groupId + pom.withXml { + asNode().appendNode('description', project.description) + } + from project.components.java + + } + } + repositories { + maven { + url "https://cs.idc.ac.il/nexus/content/repositories/${project.isSnapshot ? 'snapshots' : 'releases'}" + credentials { username + password + + username nexusUser + password nexusPassword + } + } + } +} +