|
@@ -1,15 +1,1662 @@
|
|
|
+#include <iostream>
|
|
|
+
|
|
|
#include "networkServer.hpp"
|
|
|
|
|
|
+#define TMP_FILE_SIZE 12
|
|
|
+#define TMP_DIR "~/tmp/"
|
|
|
+#define TMP_DIR_SIZE 6
|
|
|
+
|
|
|
+std::string random_string(size_t length)
|
|
|
+{
|
|
|
+ auto randchar = []() -> char
|
|
|
+ {
|
|
|
+ const char charset[] =
|
|
|
+ "0123456789_-"
|
|
|
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
|
+ "abcdefghijklmnopqrstuvwxyz";
|
|
|
+ const size_t max_index = (sizeof(charset) - 1);
|
|
|
+ return charset[ rand() % max_index ];
|
|
|
+ };
|
|
|
+ std::string str(length,0);
|
|
|
+ std::generate_n(str.begin(), length, randchar);
|
|
|
+ return str;
|
|
|
+}
|
|
|
+
|
|
|
+static int synchro_websocket_data_handler(
|
|
|
+ struct mg_connection *conn,
|
|
|
+ int bits,
|
|
|
+ char *data,
|
|
|
+ size_t data_len,
|
|
|
+ void *user_data)
|
|
|
+{
|
|
|
+ if ((bits & 0xf) == MG_WEBSOCKET_OPCODE_CONNECTION_CLOSE)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if ((bits & 0xf) == MG_WEBSOCKET_OPCODE_DATACOMPLETE)
|
|
|
+ {
|
|
|
+ struct synchronization_tool *synch = (struct synchronization_tool *) user_data;
|
|
|
+
|
|
|
+ unique_lock<mutex> lck(synch->mtx);
|
|
|
+ synch->val++;
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ std::cerr << "Unknown response when trying to get update lock." << std::endl;
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+static void synchro_websocket_close_handler(
|
|
|
+ const struct mg_connection *conn,
|
|
|
+ void *user_data)
|
|
|
+{
|
|
|
+ struct synchronization_tool *synch = (struct synchronization_tool *) user_data;
|
|
|
+
|
|
|
+ unique_lock<mutex> lck(synch->mtx);
|
|
|
+ synch->val2 = 0;
|
|
|
+ synch->cv.notify_all();
|
|
|
+}
|
|
|
+
|
|
|
+void obtain_update_locks(
|
|
|
+ std::unique_lock<std::mutex> &lck,
|
|
|
+ const std::vector<std::string>& serverIPs,
|
|
|
+ const std::string& selfIP,
|
|
|
+ struct synchronization_tool *synch)
|
|
|
+{
|
|
|
+ size_t i = 0;
|
|
|
+ while (i < serverIPs.size())
|
|
|
+ {
|
|
|
+ if (serverIPs[i] == selfIP)
|
|
|
+ {
|
|
|
+ lck.lock();
|
|
|
+ i++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ struct mg_connection *conn =
|
|
|
+ mg_connect_websocket_client(
|
|
|
+ serverIPs[i].c_str(),
|
|
|
+ PRSONA_PORT,
|
|
|
+ USE_SSL,
|
|
|
+ NULL,
|
|
|
+ 0,
|
|
|
+ UPDATE_LOCK_URI,
|
|
|
+ "null",
|
|
|
+ synchro_websocket_data_handler,
|
|
|
+ synchro_websocket_close_handler,
|
|
|
+ (void *) synch);
|
|
|
+
|
|
|
+ if (!conn)
|
|
|
+ {
|
|
|
+ std::cerr << "Couldn't get server " << i << "'s lock" << std::endl;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ unique_lock<mutex> lck(synch->mtx);
|
|
|
+ synch->val = 0;
|
|
|
+ synch->val2 = 1;
|
|
|
+ mg_websocket_client_write(
|
|
|
+ conn,
|
|
|
+ MG_WEBSOCKET_OPCODE_DATACOMPLETE,
|
|
|
+ "",
|
|
|
+ 0);
|
|
|
+
|
|
|
+ while (synch->val2)
|
|
|
+ synch->cv.wait(lck);
|
|
|
+
|
|
|
+ if (synch->val)
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void release_update_locks(
|
|
|
+ std::unique_lock<std::mutex> &lck,
|
|
|
+ const std::vector<std::string>& serverIPs,
|
|
|
+ const std::string& selfIP,
|
|
|
+ struct synchronization_tool *synch)
|
|
|
+{
|
|
|
+ ssize_t i = serverIPs.size() - 1;
|
|
|
+ while (i >= 0)
|
|
|
+ {
|
|
|
+ if (serverIPs[i] == selfIP)
|
|
|
+ {
|
|
|
+ lck.unlock();
|
|
|
+ i--;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ struct mg_connection *conn =
|
|
|
+ mg_connect_websocket_client(
|
|
|
+ serverIPs[i].c_str(),
|
|
|
+ PRSONA_PORT,
|
|
|
+ USE_SSL,
|
|
|
+ NULL,
|
|
|
+ 0,
|
|
|
+ UPDATE_UNLOCK_URI,
|
|
|
+ "null",
|
|
|
+ synchro_websocket_data_handler,
|
|
|
+ synchro_websocket_close_handler,
|
|
|
+ (void *) synch);
|
|
|
+
|
|
|
+ if (!conn)
|
|
|
+ {
|
|
|
+ std::cerr << "Couldn't get server " << i << "'s lock" << std::endl;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ unique_lock<mutex> lck(synch->mtx);
|
|
|
+ synch->val = 0;
|
|
|
+ synch->val2 = 1;
|
|
|
+ mg_websocket_client_write(
|
|
|
+ conn,
|
|
|
+ MG_WEBSOCKET_OPCODE_DATACOMPLETE,
|
|
|
+ "",
|
|
|
+ 0);
|
|
|
+
|
|
|
+ while (synch->val2)
|
|
|
+ synch->cv.wait(lck);
|
|
|
+
|
|
|
+ if (synch->val)
|
|
|
+ i--;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+std::string make_epoch_initiator_string(
|
|
|
+ const std::vector<Proof>& generatorProof,
|
|
|
+ const Twistpoint& nextGenerator)
|
|
|
+{
|
|
|
+ stringstream buffer;
|
|
|
+
|
|
|
+ buffer << generatorProof.size();
|
|
|
+ for (size_t i = 0; i < generatorProof.size(); i++)
|
|
|
+ buffer << generatorProof[i];
|
|
|
+
|
|
|
+ buffer << nextGenerator;
|
|
|
+
|
|
|
+ return buffer.str();
|
|
|
+}
|
|
|
+
|
|
|
+void read_epoch_initiator_string(
|
|
|
+ const char *filename,
|
|
|
+ std::vector<Proof>& generatorProof,
|
|
|
+ Twistpoint& nextGenerator)
|
|
|
+{
|
|
|
+ ifstream file(filename);
|
|
|
+ size_t limitI;
|
|
|
+
|
|
|
+ generatorProof.clear();
|
|
|
+
|
|
|
+ file >> limitI;
|
|
|
+ for (size_t i = 0; i < limitI; i++)
|
|
|
+ {
|
|
|
+ Proof currProof;
|
|
|
+ file >> currProof;
|
|
|
+ generatorProof.push_back;
|
|
|
+ }
|
|
|
+
|
|
|
+ file >> nextGenerator;
|
|
|
+}
|
|
|
+
|
|
|
+std::string make_epoch_update_string(
|
|
|
+ const std::vector<std::vector<Proof>>& pi,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& permutationCommits,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& freshPseudonymCommits,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& freshPseudonymSeedCommits,
|
|
|
+ const std::vector<std::vector<CurveBipoint>>& serverTallyCommits,
|
|
|
+ const std::vector<std::vector<std::vector<TwistBipoint>>>& partwayVoteMatrixCommits,
|
|
|
+ const std::vector<std::vector<std::vector<TwistBipoint>>>& finalVoteMatrixCommits,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& userTallyMaskCommits,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& userTallyMessageCommits,
|
|
|
+ const std::vector<std::vector<Twistpoint>>& userTallySeedCommits,
|
|
|
+ const Twistpoint& nextGenerator,
|
|
|
+ bool doUserTallies)
|
|
|
+{
|
|
|
+ stringstream buffer;
|
|
|
+
|
|
|
+ buffer << pi.size();
|
|
|
+ for (size_t i = 0; i < pi.size(); i++)
|
|
|
+ {
|
|
|
+ buffer << pi[i].size();
|
|
|
+ for (size_t j = 0; j < pi[i].size(); j++)
|
|
|
+ buffer << pi[i][j];
|
|
|
+ }
|
|
|
+
|
|
|
+ buffer << permutationCommits.size();
|
|
|
+ for (size_t i = 0; i < permutationCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < permutationCommits[i].size(); j++)
|
|
|
+ buffer << permutationCommits[i][j];
|
|
|
+
|
|
|
+ buffer << freshPseudonymCommits.size();
|
|
|
+ for (size_t i = 0; i < freshPseudonymCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < freshPseudonymCommits[i].size(); j++)
|
|
|
+ buffer << freshPseudonymCommits[i][j];
|
|
|
+
|
|
|
+ buffer << freshPseudonymSeedCommits.size();
|
|
|
+ for (size_t i = 0; i < freshPseudonymSeedCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < freshPseudonymSeedCommits[i].size(); j++)
|
|
|
+ buffer << freshPseudonymSeedCommits[i][j];
|
|
|
+
|
|
|
+ buffer << serverTallyCommits.size();
|
|
|
+ for (size_t i = 0; i < serverTallyCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < serverTallyCommits[i].size(); j++)
|
|
|
+ buffer << serverTallyCommits[i][j];
|
|
|
+
|
|
|
+ buffer << partwayVoteMatrixCommits.size();
|
|
|
+ for (size_t i = 0; i < partwayVoteMatrixCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < partwayVoteMatrixCommits[i].size(); j++)
|
|
|
+ for (size_t k = 0; k < partwayVoteMatrixCommits[i][j].size(); k++)
|
|
|
+ buffer << partwayVoteMatrixCommits[i][j][k];
|
|
|
+
|
|
|
+ buffer << finalVoteMatrixCommits.size();
|
|
|
+ for (size_t i = 0; i < finalVoteMatrixCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < finalVoteMatrixCommits[i].size(); j++)
|
|
|
+ for (size_t k = 0; k < finalVoteMatrixCommits[i][j].size(); k++)
|
|
|
+ buffer << finalVoteMatrixCommits[i][j][k];
|
|
|
+
|
|
|
+ buffer << userTallyMaskCommits.size();
|
|
|
+ for (size_t i = 0; i < userTallyMaskCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < userTallyMaskCommits[i].size(); j++)
|
|
|
+ buffer << userTallyMaskCommits[i][j];
|
|
|
+
|
|
|
+ buffer << userTallyMessageCommits.size();
|
|
|
+ for (size_t i = 0; i < userTallyMessageCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < userTallyMessageCommits[i].size(); j++)
|
|
|
+ buffer << userTallyMessageCommits[i][j];
|
|
|
+
|
|
|
+ buffer << userTallySeedCommits.size();
|
|
|
+ for (size_t i = 0; i < userTallySeedCommits.size(); i++)
|
|
|
+ for (size_t j = 0; j < userTallySeedCommits[i].size(); j++)
|
|
|
+ buffer << userTallySeedCommits[i][j];
|
|
|
+
|
|
|
+ buffer << nextGenerator;
|
|
|
+ buffer << doUserTallies;
|
|
|
+
|
|
|
+ return buffer.str();
|
|
|
+}
|
|
|
+
|
|
|
+bool read_epoch_update_string(
|
|
|
+ const char *filename,
|
|
|
+ std::vector<std::vector<Proof>>& pi,
|
|
|
+ std::vector<std::vector<Twistpoint>>& permutationCommits,
|
|
|
+ std::vector<std::vector<Twistpoint>>& freshPseudonymCommits,
|
|
|
+ std::vector<std::vector<Twistpoint>>& freshPseudonymSeedCommits,
|
|
|
+ std::vector<std::vector<CurveBipoint>>& serverTallyCommits,
|
|
|
+ std::vector<std::vector<std::vector<TwistBipoint>>>& partwayVoteMatrixCommits,
|
|
|
+ std::vector<std::vector<std::vector<TwistBipoint>>>& finalVoteMatrixCommits,
|
|
|
+ std::vector<std::vector<Twistpoint>>& userTallyMaskCommits,
|
|
|
+ std::vector<std::vector<Twistpoint>>& userTallyMessageCommits,
|
|
|
+ std::vector<std::vector<Twistpoint>>& userTallySeedCommits,
|
|
|
+ Twistpoint& nextGenerator)
|
|
|
+{
|
|
|
+ ifstream file(filename);
|
|
|
+ size_t limitI, limitJ;
|
|
|
+
|
|
|
+ pi.clear();
|
|
|
+ permutationCommits.clear();
|
|
|
+ freshPseudonymCommits.clear();
|
|
|
+ freshPseudonymSeedCommits.clear();
|
|
|
+ serverTallyCommits.clear();
|
|
|
+ partwayVoteMatrixCommits.clear();
|
|
|
+ finalVoteMatrixCommits.clear();
|
|
|
+ userTallyMaskCommits.clear();
|
|
|
+ userTallyMessageCommits.clear();
|
|
|
+ userTallySeedCommits.clear();
|
|
|
+
|
|
|
+ file >> limitI;
|
|
|
+ for (size_t i = 0; i < limitI; i++)
|
|
|
+ {
|
|
|
+ std::vector<Proof> currRow;
|
|
|
+
|
|
|
+ file >> limitJ;
|
|
|
+ for (size_t j = 0; j < limitJ; j++)
|
|
|
+ {
|
|
|
+ Proof currProof;
|
|
|
+ file >> currProof;
|
|
|
+ currRow.push_back(currProof);
|
|
|
+ }
|
|
|
+
|
|
|
+ pi.push_back(currRow);
|
|
|
+ }
|
|
|
+
|
|
|
+ file >> limitI;
|
|
|
+ for (size_t i = 0; i < limitI; i++)
|
|
|
+ {
|
|
|
+ std::vector<Twistpoint> currRow;
|
|
|
+ for (size_t j = 0; j < limitI; j++)
|
|
|
+ {
|
|
|
+ Twistpoint currCommit;
|
|
|
+ file >> currCommit;
|
|
|
+ currRow.push_back(currCommit);
|
|
|
+ }
|
|
|
+ permutationCommits.push_back(currRow);
|
|
|
+ }
|
|
|
+
|
|
|
+ file >> limitI;
|
|
|
+ for (size_t i = 0; i < limitI; i++)
|
|
|
+ {
|
|
|
+ std::vector<Twistpoint> currRow;
|
|
|
+ for (size_t j = 0; j < limitI; j++)
|
|
|
+ {
|
|
|
+ Twistpoint currCommit;
|
|
|
+ file >> currCommit;
|
|
|
+ currRow.push_back(currCommit);
|
|
|
+ }
|
|
|
+ freshPseudonymCommits.push_back(currRow);
|
|
|
+ }
|
|
|
+
|
|
|
+ file >> limitI;
|
|
|
+ for (size_t i = 0; i < limitI; i++)
|
|
|
+ {
|
|
|
+ std::vector<Twistpoint> currRow;
|
|
|
+ for (size_t j = 0; j < limitI; j++)
|
|
|
+ {
|
|
|
+ Twistpoint currCommit;
|
|
|
+ file >> currCommit;
|
|
|
+ currRow.push_back(currCommit);
|
|
|
+ }
|
|
|
+ freshPseudonymSeedCommits.push_back(currRow);
|
|
|
+ }
|
|
|
+
|
|
|
+ file >> limitI;
|
|
|
+ for (size_t i = 0; i < limitI; i++)
|
|
|
+ {
|
|
|
+ std::vector<CurveBipoint> currRow;
|
|
|
+ for (size_t j = 0; j < limitI; j++)
|
|
|
+ {
|
|
|
+ CurveBipoint currCommit;
|
|
|
+ file >> currCommit;
|
|
|
+ currRow.push_back(currCommit);
|
|
|
+ }
|
|
|
+ serverTallyCommits.push_back(currRow);
|
|
|
+ }
|
|
|
+
|
|
|
+ file >> limitI;
|
|
|
+ for (size_t i = 0; i < limitI; i++)
|
|
|
+ {
|
|
|
+ std::vector<std::vector<TwistBipoint>> currMatrix;
|
|
|
+ for (size_t j = 0; j < limitI; j++)
|
|
|
+ {
|
|
|
+ std::vector<TwistBipoint> currRow;
|
|
|
+ for (size_t k = 0; k < limitI; k++)
|
|
|
+ {
|
|
|
+ TwistBipoint currCommit;
|
|
|
+ file >> currCommit;
|
|
|
+ currRow.push_back(currCommit);
|
|
|
+ }
|
|
|
+ currMatrix.push_back(currRow);
|
|
|
+ }
|
|
|
+ partwayVoteMatrixCommits.push_back(currMatrix);
|
|
|
+ }
|
|
|
+
|
|
|
+ file >> limitI;
|
|
|
+ for (size_t i = 0; i < limitI; i++)
|
|
|
+ {
|
|
|
+ std::vector<std::vector<TwistBipoint>> currMatrix;
|
|
|
+ for (size_t j = 0; j < limitI; j++)
|
|
|
+ {
|
|
|
+ std::vector<TwistBipoint> currRow;
|
|
|
+ for (size_t k = 0; k < limitI; k++)
|
|
|
+ {
|
|
|
+ TwistBipoint currCommit;
|
|
|
+ file >> currCommit;
|
|
|
+ currRow.push_back(currCommit);
|
|
|
+ }
|
|
|
+ currMatrix.push_back(currRow);
|
|
|
+ }
|
|
|
+ finalVoteMatrixCommits.push_back(currMatrix);
|
|
|
+ }
|
|
|
+
|
|
|
+ file >> limitI;
|
|
|
+ for (size_t i = 0; i < limitI; i++)
|
|
|
+ {
|
|
|
+ std::vector<Twistpoint> currRow;
|
|
|
+ for (size_t j = 0; j < limitI; j++)
|
|
|
+ {
|
|
|
+ Twistpoint currCommit;
|
|
|
+ file >> currCommit;
|
|
|
+ currRow.push_back(currCommit);
|
|
|
+ }
|
|
|
+ userTallyMaskCommits.push_back(currRow);
|
|
|
+ }
|
|
|
+
|
|
|
+ file >> limitI;
|
|
|
+ for (size_t i = 0; i < limitI; i++)
|
|
|
+ {
|
|
|
+ std::vector<Twistpoint> currRow;
|
|
|
+ for (size_t j = 0; j < limitI; j++)
|
|
|
+ {
|
|
|
+ Twistpoint currCommit;
|
|
|
+ file >> currCommit;
|
|
|
+ currRow.push_back(currCommit);
|
|
|
+ }
|
|
|
+ userTallyMessageCommits.push_back(currRow);
|
|
|
+ }
|
|
|
+
|
|
|
+ file >> limitI;
|
|
|
+ for (size_t i = 0; i < limitI; i++)
|
|
|
+ {
|
|
|
+ std::vector<Twistpoint> currRow;
|
|
|
+ for (size_t j = 0; j < limitI; j++)
|
|
|
+ {
|
|
|
+ Twistpoint currCommit;
|
|
|
+ file >> currCommit;
|
|
|
+ currRow.push_back(currCommit);
|
|
|
+ }
|
|
|
+ userTallySeedCommits.push_back(currRow);
|
|
|
+ }
|
|
|
+
|
|
|
+ file >> nextGenerator;
|
|
|
+
|
|
|
+ bool doUserTallies;
|
|
|
+ file >> doUserTallies;
|
|
|
+
|
|
|
+ return doUserTallies;
|
|
|
+}
|
|
|
+
|
|
|
+void distribute_epoch_updates(
|
|
|
+ const std::string& recipient,
|
|
|
+ const std::string& data,
|
|
|
+ const struct synchronization_tool* synch)
|
|
|
+{
|
|
|
+ bool flag = false;
|
|
|
+ while (!flag)
|
|
|
+ {
|
|
|
+ struct mg_connection *conn =
|
|
|
+ mg_connect_websocket_client(
|
|
|
+ serverIPs[i].c_str(),
|
|
|
+ PRSONA_PORT,
|
|
|
+ USE_SSL,
|
|
|
+ NULL,
|
|
|
+ 0,
|
|
|
+ ACCEPT_EPOCH_UPDATES_URI,
|
|
|
+ "null",
|
|
|
+ synchro_websocket_data_handler,
|
|
|
+ empty_websocket_close_handler,
|
|
|
+ (void *) synch);
|
|
|
+
|
|
|
+ if (!conn)
|
|
|
+ {
|
|
|
+ std::cerr << "Trouble giving epoch updates to server at " << recipient << std::endl;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ mg_websocket_client_write(
|
|
|
+ conn,
|
|
|
+ MG_WEBSOCKET_OPCODE_BINARY,
|
|
|
+ data.c_str(),
|
|
|
+ data.length());
|
|
|
+
|
|
|
+ mg_websocket_client_write(
|
|
|
+ conn,
|
|
|
+ MG_WEBSOCKET_OPCODE_DATACOMPLETE,
|
|
|
+ "",
|
|
|
+ 0);
|
|
|
+
|
|
|
+ flag = true;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
* CONSTRUCTORS
|
|
|
*/
|
|
|
|
|
|
-
|
|
|
-PrsonaNetworkServer::PrsonaNetworkServer(size_t numServers)
|
|
|
-: PrsonaServer(numServers)
|
|
|
-{ }
|
|
|
+PrsonaServerWebSocketHandler::PrsonaServerWebSocketHandler(
|
|
|
+ const PrsonaServer *prsonaServer,
|
|
|
+ const std::mutex *updateMtx,
|
|
|
+ const size_t *epochNum,
|
|
|
+ const std::vector<std::string> &serverIPs,
|
|
|
+ const std::string &selfIP)
|
|
|
+: prsonaServer(prsonaServer), updateMtx(updateMtx), epochNum(epochNum),
|
|
|
+ serverIPs(serverIPs), selfIP(selfIP)
|
|
|
+{ }
|
|
|
+
|
|
|
+virtual bool PrsonaServerWebSocketHandler::handleConnection(
|
|
|
+ CivetServer *server,
|
|
|
+ const struct mg_connection *conn)
|
|
|
+{
|
|
|
+ const struct mg_request_info *info = mg_get_request_info(conn);
|
|
|
+
|
|
|
+ bool flag = info->query_string && info->query_string[0] >= PRSONA_ADD_CLIENT && info->query_string[0] <= PRSONA_RECEIVE_PARTIAL_DECRYPTION;
|
|
|
+ flag = flag || (info->query_string && info->query_string[0] == PRSONA_GET_FRESH_GENERATOR);
|
|
|
+ flag = flag || (info->query_string && info->query_string[0] == PRSONA_GET_EG_BLIND_GENERATOR);
|
|
|
+
|
|
|
+ return flag;
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::set_temp_filename(
|
|
|
+ struct mg_connection *conn) const
|
|
|
+{
|
|
|
+ std::string filename = random_string(TMP_FILE_SIZE);
|
|
|
+
|
|
|
+ char *c_filename = new char[TMP_FILE_SIZE+TMP_DIR_SIZE+1];
|
|
|
+ strncpy(c_filename, TMP_DIR, TMP_DIR_SIZE);
|
|
|
+ for (size_t i = 0; i < TMP_FILE_SIZE; i++)
|
|
|
+ c_filename[i + TMP_DIR_SIZE] = filename[i];
|
|
|
+ c_filename[TMP_DIR_SIZE + TMP_FILE_SIZE] = 0;
|
|
|
+
|
|
|
+ mg_set_user_connection_data(conn, c_filename);
|
|
|
+}
|
|
|
+
|
|
|
+virtual void PrsonaServerWebSocketHandler::handleReadyState(
|
|
|
+ CivetServer *server,
|
|
|
+ struct mg_connection *conn)
|
|
|
+{
|
|
|
+ const struct mg_request_info *info = mg_get_request_info(conn);
|
|
|
+
|
|
|
+ switch (info->query_string[0])
|
|
|
+ {
|
|
|
+ case PRSONA_ADD_CLIENT:
|
|
|
+ case PRSONA_RECEIVE_VOTE:
|
|
|
+ case PRSONA_GET_VOTES_BY:
|
|
|
+ case PRSONA_GET_USER_TALLY:
|
|
|
+ case PRSONA_GET_SERVER_TALLY:
|
|
|
+ case PRSONA_GET_VOTE_ROW_COMMITMENT:
|
|
|
+ case PRSONA_GET_USER_TALLY_COMMITMENT:
|
|
|
+ case PRSONA_GET_SERVER_TALLY_COMMITMENT:
|
|
|
+ case PRSONA_ADD_CURR_SEED_TO_GENERATOR:
|
|
|
+ case PRSONA_SET_FRESH_GENERATOR:
|
|
|
+ case PRSONA_ADD_RAND_SEED_TO_GENERATOR:
|
|
|
+ case PRSONA_SET_EG_BLIND_GENERATOR:
|
|
|
+ case PRSONA_EPOCH_UPDATE:
|
|
|
+ case PRSONA_NEW_USER_UPDATE:
|
|
|
+ case PRSONA_RECEIVE_PARTIAL_DECRYPTION:
|
|
|
+ set_temp_filename(conn);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ mg_set_user_connection_data(conn, NULL);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+virtual bool PrsonaServerWebSocketHandler::handleData(
|
|
|
+ CivetServer *server,
|
|
|
+ struct mg_connection *conn,
|
|
|
+ int bits,
|
|
|
+ char *data,
|
|
|
+ size_t data_len)
|
|
|
+{
|
|
|
+ char *filename = (char *) mg_get_user_connection_data(conn);
|
|
|
+
|
|
|
+ if ((bits & 0xf) == MG_WEBSOCKET_OPCODE_DATACOMPLETE)
|
|
|
+ {
|
|
|
+ generate_response(conn, filename);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((bits & 0xf) != MG_WEBSOCKET_OPCODE_BINARY && (bits & 0xf) != MG_WEBSOCKET_OPCODE_CONTINUATION)
|
|
|
+ {
|
|
|
+ std::cerr << "Unknown opcode: failing." << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ FILE *currFile = fopen(filename, "ab");
|
|
|
+ fwrite(data, sizeof(char), data_len, currFile);
|
|
|
+ fclose(currFile);
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::generate_response(
|
|
|
+ struct mg_connection *conn,
|
|
|
+ char *filename)
|
|
|
+{
|
|
|
+ const struct mg_request_info *info = mg_get_request_info(conn);
|
|
|
+
|
|
|
+ switch (info->query_string[0])
|
|
|
+ {
|
|
|
+ case PRSONA_ADD_CLIENT:
|
|
|
+ add_new_client(conn, filename);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_RECEIVE_VOTE:
|
|
|
+ receive_vote(filename);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_GET_BGN_PUBKEY:
|
|
|
+ get_bgn_public_key(conn);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_GET_NUM_CLIENTS:
|
|
|
+ get_num_clients(conn);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_GET_NUM_SERVERS:
|
|
|
+ get_num_servers(conn);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_GET_VOTES_BY:
|
|
|
+ get_current_votes_by(conn, filename);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_GET_ALL_VOTES:
|
|
|
+ get_all_current_votes(conn);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_GET_USER_TALLY:
|
|
|
+ get_current_user_encrypted_tally(conn, filename);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_GET_SERVER_TALLY:
|
|
|
+ get_current_server_encrypted_tally(conn, filename);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_GET_PSEUDONYMS:
|
|
|
+ get_current_pseudonyms(conn);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_GET_VOTE_ROW_COMMITMENT:
|
|
|
+ get_vote_row_commitment(conn, filename);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_GET_VOTE_MATRIX_COMMITMENT:
|
|
|
+ get_vote_matrix_commitment(conn);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_GET_USER_TALLY_COMMITMENT:
|
|
|
+ get_user_tally_commitment(conn, filename);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_GET_SERVER_TALLY_COMMITMENT:
|
|
|
+ get_server_tally_commitment(conn, filename);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_GET_PSEUDONYMS_COMMITMENT:
|
|
|
+ get_pseudonyms_commitment(conn);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_GET_BGN_DETAILS:
|
|
|
+ get_bgn_details(conn);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_ADD_CURR_SEED_TO_GENERATOR:
|
|
|
+ add_seed_to_generator(conn, filename, true);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_SET_FRESH_GENERATOR:
|
|
|
+ set_generator(filename, true);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_ADD_RAND_SEED_TO_GENERATOR:
|
|
|
+ add_seed_to_generator(conn, filename, false);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_SET_EG_BLIND_GENERATOR:
|
|
|
+ set_generator(filename, false);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_EPOCH_BUILD_UP:
|
|
|
+ build_up_midway_pseudonyms(conn);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_EPOCH_BREAK_DOWN:
|
|
|
+ break_down_midway_pseudonyms(conn);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_EPOCH_UPDATE:
|
|
|
+ accept_epoch_updates(filename);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_NEW_USER_UPDATE:
|
|
|
+ import_new_user_update(filename);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_GET_PARTIAL_DECRYPTION:
|
|
|
+ get_partial_decryption(conn, filename);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_RECEIVE_PARTIAL_DECRYPTION:
|
|
|
+ receive_tallied_scores(conn, filename);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_GET_FRESH_GENERATOR:
|
|
|
+ get_generator(conn, true);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PRSONA_GET_EG_BLIND_GENERATOR:
|
|
|
+ get_generator(conn, false);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+virtual void PrsonaServerWebSocketHandler::handleClose(
|
|
|
+ CivetServer *server,
|
|
|
+ const struct mg_connection *conn)
|
|
|
+{
|
|
|
+ char *filename = (char *) mg_get_user_connection_data(conn);
|
|
|
+ if (!filename)
|
|
|
+ return;
|
|
|
+
|
|
|
+ remove(filename);
|
|
|
+ delete filename;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ * BASIC PUBLIC SYSTEM INFO GETTERS
|
|
|
+ */
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::get_bgn_public_key(
|
|
|
+ struct mg_connection *conn) const
|
|
|
+{
|
|
|
+ std::stringstream buffer;
|
|
|
+ std::string data;
|
|
|
+
|
|
|
+ BGNPublicKey pubKey = prsonaServer->get_bgn_public_key();
|
|
|
+ buffer << pubKey;
|
|
|
+ data = buffer.str();
|
|
|
+
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::get_num_clients(
|
|
|
+ struct mg_connection *conn) const
|
|
|
+{
|
|
|
+ std::stringstream buffer;
|
|
|
+ std::string data;
|
|
|
+
|
|
|
+ size_t numClients = prsonaServer->get_num_clients();
|
|
|
+ buffer << numClients;
|
|
|
+ data = buffer.str();
|
|
|
+
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::get_num_servers(
|
|
|
+ struct mg_connection *conn) const
|
|
|
+{
|
|
|
+ std::stringstream buffer;
|
|
|
+ std::string data;
|
|
|
+
|
|
|
+ size_t numServers = prsonaServer->get_num_servers();
|
|
|
+ buffer << numServers;
|
|
|
+ data = buffer.str();
|
|
|
+
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ * ENCRYPTED DATA GETTERS
|
|
|
+ */
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::get_current_votes_by(
|
|
|
+ struct mg_connection *conn, const char *filename) const
|
|
|
+{
|
|
|
+ ifstream file(filename);
|
|
|
+
|
|
|
+ Twistpoint shortTermPublicKey;
|
|
|
+ file >> shortTermPublicKey;
|
|
|
+
|
|
|
+ std::stringstream buffer;
|
|
|
+ std::string data;
|
|
|
+
|
|
|
+ Proof pi;
|
|
|
+ std::vector<TwistBipoint> votes =
|
|
|
+ prsonaServer->get_current_votes_by(pi, shortTermPublicKey);
|
|
|
+
|
|
|
+ buffer << pi;
|
|
|
+ buffer << votes.size();
|
|
|
+ for (size_t i = 0; i < votes.size(); i++)
|
|
|
+ buffer << votes[i];
|
|
|
+
|
|
|
+ data = buffer.str();
|
|
|
+
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::get_all_current_votes(
|
|
|
+ struct mg_connection *conn) const
|
|
|
+{
|
|
|
+ std::stringstream buffer;
|
|
|
+ std::string data;
|
|
|
+
|
|
|
+ Proof pi;
|
|
|
+ std::vector<std::vector<TwistBipoint>> votes =
|
|
|
+ prsonaServer->get_all_current_votes(pi);
|
|
|
+
|
|
|
+ buffer << pi;
|
|
|
+ buffer << votes.size();
|
|
|
+ for (size_t i = 0; i < votes.size(); i++)
|
|
|
+ for (size_t j = 0; j < votes[i].size(); j++)
|
|
|
+ buffer << votes[i][j];
|
|
|
+
|
|
|
+ data = buffer.str();
|
|
|
+
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::get_current_user_encrypted_tally(
|
|
|
+ struct mg_connection *conn, const char *filename) const
|
|
|
+{
|
|
|
+ ifstream file(filename);
|
|
|
+
|
|
|
+ Twistpoint shortTermPublicKey;
|
|
|
+ file >> shortTermPublicKey;
|
|
|
+
|
|
|
+ std::stringstream buffer;
|
|
|
+ std::string data;
|
|
|
+
|
|
|
+ Proof pi;
|
|
|
+ EGCiphertext tally =
|
|
|
+ prsonaServer->get_current_user_encrypted_tally(pi, shortTermPublicKey);
|
|
|
+
|
|
|
+ buffer << pi;
|
|
|
+ buffer << tally;
|
|
|
+
|
|
|
+ data = buffer.str();
|
|
|
+
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::get_current_server_encrypted_tally(
|
|
|
+ struct mg_connection *conn, const char *filename) const
|
|
|
+{
|
|
|
+ ifstream file(filename);
|
|
|
+
|
|
|
+ Twistpoint shortTermPublicKey;
|
|
|
+ file >> shortTermPublicKey;
|
|
|
+
|
|
|
+ std::stringstream buffer;
|
|
|
+ std::string data;
|
|
|
+
|
|
|
+ Proof pi;
|
|
|
+ CurveBipoint tally =
|
|
|
+ prsonaServer->get_current_server_encrypted_tally(pi, shortTermPublicKey);
|
|
|
+
|
|
|
+ buffer << pi;
|
|
|
+ buffer << tally;
|
|
|
+
|
|
|
+ data = buffer.str();
|
|
|
+
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::get_current_pseudonyms(
|
|
|
+ struct mg_connection *conn) const
|
|
|
+{
|
|
|
+ std::stringstream buffer;
|
|
|
+ std::string data;
|
|
|
+
|
|
|
+ Proof pi;
|
|
|
+ std::vector<Twistpoint> pseudonyms =
|
|
|
+ prsonaServer->get_current_pseudonyms(pi);
|
|
|
+
|
|
|
+ buffer << pi;
|
|
|
+ buffer << pseudonyms.size();
|
|
|
+ for (size_t i = 0; i < pseudonyms.size(); i++)
|
|
|
+ buffer << pseudonyms[i];
|
|
|
+
|
|
|
+ data = buffer.str();
|
|
|
+
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ * PROOF COMMITMENT GETTERS
|
|
|
+ */
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::get_vote_row_commitment(
|
|
|
+ struct mg_connection *conn, const char *filename) const
|
|
|
+{
|
|
|
+ ifstream file(filename);
|
|
|
+
|
|
|
+ Twistpoint shortTermPublicKey;
|
|
|
+ file >> shortTermPublicKey;
|
|
|
+
|
|
|
+ std::stringstream buffer;
|
|
|
+ std::string data;
|
|
|
+
|
|
|
+ Proof pi =
|
|
|
+ prsonaServer->get_vote_row_commitment(shortTermPublicKey);
|
|
|
+
|
|
|
+ buffer << pi;
|
|
|
+
|
|
|
+ data = buffer.str();
|
|
|
+
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::get_vote_matrix_commitment(
|
|
|
+ struct mg_connection *conn) const
|
|
|
+{
|
|
|
+ std::stringstream buffer;
|
|
|
+ std::string data;
|
|
|
+
|
|
|
+ Proof pi =
|
|
|
+ prsonaServer->get_vote_matrix_commitment();
|
|
|
+
|
|
|
+ buffer << pi;
|
|
|
+
|
|
|
+ data = buffer.str();
|
|
|
+
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::get_user_tally_commitment(
|
|
|
+ struct mg_connection *conn, const char *filename) const
|
|
|
+{
|
|
|
+ ifstream file(filename);
|
|
|
+
|
|
|
+ Twistpoint shortTermPublicKey;
|
|
|
+ file >> shortTermPublicKey;
|
|
|
+
|
|
|
+ std::stringstream buffer;
|
|
|
+ std::string data;
|
|
|
+
|
|
|
+ Proof pi =
|
|
|
+ prsonaServer->get_user_tally_commitment(shortTermPublicKey);
|
|
|
+
|
|
|
+ buffer << pi;
|
|
|
+
|
|
|
+ data = buffer.str();
|
|
|
+
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::get_server_tally_commitment(
|
|
|
+ struct mg_connection *conn, const char *filename) const
|
|
|
+{
|
|
|
+ ifstream file(filename);
|
|
|
+
|
|
|
+ Twistpoint shortTermPublicKey;
|
|
|
+ file >> shortTermPublicKey;
|
|
|
+
|
|
|
+ std::stringstream buffer;
|
|
|
+ std::string data;
|
|
|
+
|
|
|
+ Proof pi =
|
|
|
+ prsonaServer->get_server_tally_commitment(shortTermPublicKey);
|
|
|
+
|
|
|
+ buffer << pi;
|
|
|
+
|
|
|
+ data = buffer.str();
|
|
|
+
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::get_pseudonyms_commitment(
|
|
|
+ struct mg_connection *conn) const
|
|
|
+{
|
|
|
+ std::stringstream buffer;
|
|
|
+ std::string data;
|
|
|
+
|
|
|
+ Proof pi =
|
|
|
+ prsonaServer->get_pseudonyms_commitment();
|
|
|
+
|
|
|
+ buffer << pi;
|
|
|
+
|
|
|
+ data = buffer.str();
|
|
|
+
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::distribute_new_user_updates(
|
|
|
+ std::vector<Proof> proofOfValidAddition,
|
|
|
+ std::vector<CurveBipoint> previousVoteTallies,
|
|
|
+ std::vector<Twistpoint> currentPseudonyms,
|
|
|
+ std::vector<EGCiphertext> currentUserEncryptedTallies,
|
|
|
+ std::vector<std::vector<TwistBipoint>> voteMatrix) const
|
|
|
+{
|
|
|
+ std::stringstream buffer;
|
|
|
+ std::string data;
|
|
|
+
|
|
|
+ buffer << proofOfValidAddition.size();
|
|
|
+ for (size_t i = 0; i < proofOfValidAddition.size(); i++)
|
|
|
+ buffer << proofOfValidAddition[i];
|
|
|
+
|
|
|
+ buffer << previousVoteTallies.size();
|
|
|
+ for (size_t i = 0; i < previousVoteTallies.size(); i++)
|
|
|
+ buffer << previousVoteTallies[i];
|
|
|
+
|
|
|
+ buffer << currentPseudonyms.size();
|
|
|
+ for (size_t i = 0; i < currentPseudonyms.size(); i++)
|
|
|
+ buffer << currentPseudonyms[i];
|
|
|
+
|
|
|
+ buffer << currentUserEncryptedTallies.size();
|
|
|
+ for (size_t i = 0; i < currentUserEncryptedTallies.size(); i++)
|
|
|
+ buffer << currentUserEncryptedTallies[i];
|
|
|
+
|
|
|
+ buffer << voteMatrix.size();
|
|
|
+ for (size_t i = 0; i < voteMatrix.size(); i++)
|
|
|
+ for (size_t j = 0; j < voteMatrix[i].size(); j++)
|
|
|
+ buffer << voteMatrix[i][j];
|
|
|
+
|
|
|
+ data = buffer.str();
|
|
|
+
|
|
|
+ size_t i = 0;
|
|
|
+ while (i < serverIPs.size())
|
|
|
+ {
|
|
|
+ if (serverIPs[i] == selfIP)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ struct mg_connection *conn =
|
|
|
+ mg_connect_websocket_client(
|
|
|
+ serverIPs[i].c_str(),
|
|
|
+ PRSONA_PORT,
|
|
|
+ USE_SSL,
|
|
|
+ NULL,
|
|
|
+ 0,
|
|
|
+ GIVE_NEW_USER_URI,
|
|
|
+ "null",
|
|
|
+ synchro_websocket_data_handler,
|
|
|
+ synchro_websocket_close_handler,
|
|
|
+ (void *) distributeSynch);
|
|
|
+
|
|
|
+ if (!conn)
|
|
|
+ {
|
|
|
+ std::cerr << "Couldn't give server " << i << " new user" << std::endl;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ unique_lock<mutex> synchLock(distributeSynch->mtx);
|
|
|
+ distributeSynch->isReady = false;
|
|
|
+ distributeSynch->isOngoing = true;
|
|
|
+ mg_websocket_client_write(
|
|
|
+ conn,
|
|
|
+ MG_WEBSOCKET_OPCODE_BINARY,
|
|
|
+ data.c_str(),
|
|
|
+ data.length());
|
|
|
+
|
|
|
+ while (distributeSynch->isOngoing)
|
|
|
+ distributeSynch->cv.wait(synchLock);
|
|
|
+
|
|
|
+ if (distributeSynch->isReady)
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::distribute_new_vote(
|
|
|
+ std::vector<Proof> pi;
|
|
|
+ std::vector<TwistBipoint> newVotes,
|
|
|
+ Twistpoint shortTermPublicKey) const
|
|
|
+{
|
|
|
+ std::stringstream buffer;
|
|
|
+ std::string data;
|
|
|
+
|
|
|
+ buffer << pi.size();
|
|
|
+ for (size_t i = 0; i < pi.size(); i++)
|
|
|
+ buffer << pi[i];
|
|
|
+
|
|
|
+ buffer << newVotes.size();
|
|
|
+ for (size_t i = 0; i < newVotes.size(); i++)
|
|
|
+ buffer << newVotes[i];
|
|
|
+
|
|
|
+ buffer << shortTermPublicKey;
|
|
|
+ buffer << false;
|
|
|
+
|
|
|
+ data = buffer.str();
|
|
|
+
|
|
|
+ size_t i = 0;
|
|
|
+ while (i < serverIPs.size())
|
|
|
+ {
|
|
|
+ if (serverIPs[i] == selfIP)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ struct mg_connection *conn =
|
|
|
+ mg_connect_websocket_client(
|
|
|
+ serverIPs[i].c_str(),
|
|
|
+ PRSONA_PORT,
|
|
|
+ USE_SSL,
|
|
|
+ NULL,
|
|
|
+ 0,
|
|
|
+ GIVE_NEW_VOTE_URI,
|
|
|
+ "null",
|
|
|
+ synchro_websocket_data_handler,
|
|
|
+ synchro_websocket_close_handler,
|
|
|
+ (void *) distributeSynch);
|
|
|
+
|
|
|
+ if (!conn)
|
|
|
+ {
|
|
|
+ std::cerr << "Couldn't give server " << i << " new user" << std::endl;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ unique_lock<mutex> synchLock(distributeSynch->mtx);
|
|
|
+ distributeSynch->isReady = false;
|
|
|
+ distributeSynch->isOngoing = true;
|
|
|
+ mg_websocket_client_write(
|
|
|
+ conn,
|
|
|
+ MG_WEBSOCKET_OPCODE_BINARY,
|
|
|
+ data.c_str(),
|
|
|
+ data.length());
|
|
|
+
|
|
|
+ while (distributeSynch->isOngoing)
|
|
|
+ distributeSynch->cv.wait(synchLock);
|
|
|
+
|
|
|
+ if (distributeSynch->isReady)
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ * CLIENT INTERACTIONS
|
|
|
+ */
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::add_new_client(
|
|
|
+ struct mg_connection *conn, const char *filename)
|
|
|
+{
|
|
|
+ ifstream file(filename);
|
|
|
+
|
|
|
+ Proof proofOfValidKey;
|
|
|
+ file >> proofOfValidKey;
|
|
|
+
|
|
|
+ Twistpoint shortTermPublicKey;
|
|
|
+ file >> shortTermPublicKey;
|
|
|
+
|
|
|
+ std::unique_lock<std::mutex> lck(*updateMtx, std::defer_lock);
|
|
|
+ obtain_update_locks(
|
|
|
+ lck,
|
|
|
+ serverIPs,
|
|
|
+ selfIP,
|
|
|
+ &updateSynch);
|
|
|
+
|
|
|
+ std::vector<Proof> proofOfValidAddition;
|
|
|
+ prsonaServer->add_new_client(
|
|
|
+ proofOfValidAddition,
|
|
|
+ proofOfValidKey,
|
|
|
+ shortTermPublicKey);
|
|
|
+
|
|
|
+ std::vector<CurveBipoint> previousVoteTallies;
|
|
|
+ std::vector<Twistpoint> currentPseudonyms;
|
|
|
+ std::vector<EGCiphertext> currentUserEncryptedTallies;
|
|
|
+ std::vector<std::vector<TwistBipoint>> voteMatrix;
|
|
|
+ prsonaServer->export_new_user_update(
|
|
|
+ previousVoteTallies,
|
|
|
+ currentPseudonyms,
|
|
|
+ currentUserEncryptedTallies,
|
|
|
+ voteMatrix);
|
|
|
+
|
|
|
+ distribute_new_user_updates(
|
|
|
+ proofOfValidAddition,
|
|
|
+ previousVoteTallies,
|
|
|
+ currentPseudonyms,
|
|
|
+ currentUserEncryptedTallies,
|
|
|
+ voteMatrix);
|
|
|
+
|
|
|
+ release_update_locks(
|
|
|
+ lck,
|
|
|
+ serverIPs,
|
|
|
+ selfIP,
|
|
|
+ &updateSynch);
|
|
|
+
|
|
|
+ buffer << proofOfValidAddition.size();
|
|
|
+ for (size_t i = 0; i < proofOfValidAddition.size(); i++)
|
|
|
+ buffer << proofOfValidAddition[i];
|
|
|
+
|
|
|
+ data = buffer.str();
|
|
|
+
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::receive_vote(
|
|
|
+ const char *filename)
|
|
|
+{
|
|
|
+ ifstream file(filename);
|
|
|
+
|
|
|
+ size_t sizeOfPi;
|
|
|
+ file >> sizeOfPi;
|
|
|
+
|
|
|
+ std::vector<Proof> pi;
|
|
|
+ for (size_t i = 0; i < sizeOfPi; i++)
|
|
|
+ {
|
|
|
+ Proof currProof;
|
|
|
+ file >> currProof;
|
|
|
+
|
|
|
+ pi.push_back(currProof);
|
|
|
+ }
|
|
|
+
|
|
|
+ size_t sizeOfVotes;
|
|
|
+ file >> sizeOfVotes;
|
|
|
+
|
|
|
+ std::vector<TwistBipoint> newVotes;
|
|
|
+ for (size_t i = 0; i < sizeOfVotes; i++)
|
|
|
+ {
|
|
|
+ TwistBipoint currVote;
|
|
|
+ file >> currVote;
|
|
|
+
|
|
|
+ newVotes.push_back(currVote);
|
|
|
+ }
|
|
|
+
|
|
|
+ Twistpoint shortTermPublicKey;
|
|
|
+ file >> shortTermPublicKey;
|
|
|
+
|
|
|
+ bool shouldDeal;
|
|
|
+ file >> shouldDeal;
|
|
|
+
|
|
|
+ std::unique_lock<std::mutex> lck(*updateMtx, std::defer_lock);
|
|
|
+ if (shouldDeal)
|
|
|
+ {
|
|
|
+ obtain_update_locks(
|
|
|
+ lck,
|
|
|
+ serverIPs,
|
|
|
+ selfIP,
|
|
|
+ &distributeSynch);
|
|
|
+ }
|
|
|
+
|
|
|
+ prsonaServer->receive_vote(
|
|
|
+ pi,
|
|
|
+ newVotes,
|
|
|
+ shortTermPublicKey);
|
|
|
+
|
|
|
+ if (shouldDeal)
|
|
|
+ {
|
|
|
+ distribute_new_vote(pi, newVotes, shortTermPublicKey);
|
|
|
+ release_update_locks(
|
|
|
+ lck,
|
|
|
+ serverIPs,
|
|
|
+ selfIP,
|
|
|
+ &distributeSynch);
|
|
|
+ }
|
|
|
+
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ * CONSTRUCTOR HELPERS
|
|
|
+ */
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::get_bgn_details(
|
|
|
+ struct mg_connection *conn) const
|
|
|
+{
|
|
|
+ std::stringstream buffer;
|
|
|
+ std::string data;
|
|
|
+
|
|
|
+ const BGN& sharedBGN = prsonaServer->get_bgn_details();
|
|
|
+ buffer << sharedBGN;
|
|
|
+
|
|
|
+ data = buffer.str();
|
|
|
+
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::add_seed_to_generator(
|
|
|
+ struct mg_connection *conn, const char *filename, bool fresh) const
|
|
|
+{
|
|
|
+ ifstream file(filename);
|
|
|
+
|
|
|
+ Twistpoint currGenerator;
|
|
|
+ file >> currGenerator;
|
|
|
+
|
|
|
+ std::stringstream buffer;
|
|
|
+ std::string data;
|
|
|
+
|
|
|
+ std::vector<Proof> pi;
|
|
|
+ if (fresh)
|
|
|
+ {
|
|
|
+ currGenerator =
|
|
|
+ prsonaServer->add_curr_seed_to_generator(pi, currGenerator);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ currGenerator =
|
|
|
+ prsonaServer->add_rand_seed_to_generator(pi, currGenerator);
|
|
|
+ }
|
|
|
+
|
|
|
+ buffer << pi[0];
|
|
|
+ buffer << currGenerator;
|
|
|
+
|
|
|
+ data = buffer.str();
|
|
|
+
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::set_generator(
|
|
|
+ const char *filename, bool fresh)
|
|
|
+{
|
|
|
+ ifstream file(filename);
|
|
|
+
|
|
|
+ size_t sizeOfPi;
|
|
|
+ file >> sizeOfPi;
|
|
|
+
|
|
|
+ std::vector<Proof> pi;
|
|
|
+ for (size_t i = 0; i < sizeOfPi; i++)
|
|
|
+ {
|
|
|
+ Proof currProof;
|
|
|
+ file >> currProof;
|
|
|
+ pi.push_back(currProof);
|
|
|
+ }
|
|
|
+
|
|
|
+ Twistpoint newGenerator;
|
|
|
+ file >> newGenerator;
|
|
|
+
|
|
|
+ if (fresh)
|
|
|
+ prsonaServer->initialize_fresh_generator(pi, newGenerator);
|
|
|
+ else
|
|
|
+ prsonaServer->set_EG_blind_generator(pi, newGenerator);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ * EPOCH ROUNDS
|
|
|
+ */
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::build_up_midway_pseudonyms(
|
|
|
+ struct mg_connection *conn, const char *filename)
|
|
|
+{
|
|
|
+ std::vector<std::vector<Proof>> generatorProofHolder;
|
|
|
+ std::vector<Proof> generatorProof;
|
|
|
+ Twistpoint nextGenerator;
|
|
|
+
|
|
|
+ read_epoch_initiator_string(
|
|
|
+ filename,
|
|
|
+ generatorProof,
|
|
|
+ nextGenerator);
|
|
|
+
|
|
|
+ generatorProofHolder.push_back(generatorProof);
|
|
|
+
|
|
|
+ std::vector<std::vector<std::vector<Proof>>> pi;
|
|
|
+ std::vector<std::vector<std::vector<Twistpoint>>> permutationCommits;
|
|
|
+ std::vector<std::vector<std::vector<Twistpoint>>> freshPseudonymCommits;
|
|
|
+ std::vector<std::vector<std::vector<Twistpoint>>> freshPseudonymSeedCommits;
|
|
|
+ std::vector<std::vector<std::vector<CurveBipoint>>> serverTallyCommits;
|
|
|
+ std::vector<std::vector<std::vector<std::vector<TwistBipoint>>>> partwayVoteMatrixCommits;
|
|
|
+ std::vector<std::vector<std::vector<std::vector<TwistBipoint>>>> finalVoteMatrixCommits;
|
|
|
+
|
|
|
+ pi.push_back(generatorProofHolder);
|
|
|
+
|
|
|
+ prsonaServer->build_up_midway_pseudonyms(
|
|
|
+ pi,
|
|
|
+ permutationCommits,
|
|
|
+ freshPseudonymCommits,
|
|
|
+ freshPseudonymSeedCommits,
|
|
|
+ serverTallyCommits,
|
|
|
+ partwayVoteMatrixCommits,
|
|
|
+ finalVoteMatrixCommits,
|
|
|
+ nextGenerator);
|
|
|
+
|
|
|
+ std::vector<std::vector<Twistpoint>> userTallyMaskCommits, userTallyMessageCommits, userTallySeedCommits;
|
|
|
+
|
|
|
+ string data =
|
|
|
+ make_epoch_update_string(
|
|
|
+ pi[1],
|
|
|
+ permutationCommits[0],
|
|
|
+ freshPseudonymCommits[0],
|
|
|
+ freshPseudonymSeedCommits[0],
|
|
|
+ serverTallyCommits[0],
|
|
|
+ partwayVoteMatrixCommits[0],
|
|
|
+ finalVoteMatrixCommits[0],
|
|
|
+ userTallyMaskCommits,
|
|
|
+ userTallyMessageCommits,
|
|
|
+ userTallySeedCommits,
|
|
|
+ nextGenerator,
|
|
|
+ false);
|
|
|
+
|
|
|
+ struct synchronization_tool epochSync;
|
|
|
+ epochSync->val = 1;
|
|
|
+ for (size_t i = 0; i < serverIPs.size(); i++)
|
|
|
+ {
|
|
|
+ if (serverIPs[i] == selfIP)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ distribute_epoch_updates(
|
|
|
+ serverIPs[i],
|
|
|
+ data,
|
|
|
+ &epochSync);
|
|
|
+ }
|
|
|
+
|
|
|
+ unique_lock<mutex> lck(epochSync);
|
|
|
+ while (epochSync.val < serverIPs.size())
|
|
|
+ epochSync.cv.wait(lck);
|
|
|
+
|
|
|
+ data = make_epoch_initiator_string(
|
|
|
+ pi[0][0],
|
|
|
+ nextGenerator);
|
|
|
+
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::break_down_midway_pseudonyms(
|
|
|
+ struct mg_connection *conn, const char *filename)
|
|
|
+{
|
|
|
+ std::vector<Proof> generatorProof;
|
|
|
+ Twistpoint nextGenerator;
|
|
|
+
|
|
|
+ read_epoch_initiator_string(
|
|
|
+ filename,
|
|
|
+ generatorProof,
|
|
|
+ nextGenerator);
|
|
|
+
|
|
|
+ std::vector<std::vector<std::vector<Proof>>> pi;
|
|
|
+ std::vector<std::vector<std::vector<Twistpoint>>> permutationCommits;
|
|
|
+ std::vector<std::vector<std::vector<Twistpoint>>> freshPseudonymCommits;
|
|
|
+ std::vector<std::vector<std::vector<Twistpoint>>> freshPseudonymSeedCommits;
|
|
|
+ std::vector<std::vector<std::vector<CurveBipoint>>> serverTallyCommits;
|
|
|
+ std::vector<std::vector<std::vector<std::vector<TwistBipoint>>>> partwayVoteMatrixCommits;
|
|
|
+ std::vector<std::vector<std::vector<std::vector<TwistBipoint>>>> finalVoteMatrixCommits;
|
|
|
+ std::vector<std::vector<std::vector<Twistpoint>>> userTallyMaskCommits;
|
|
|
+ std::vector<std::vector<std::vector<Twistpoint>>> userTallyMessageCommits;
|
|
|
+ std::vector<std::vector<std::vector<Twistpoint>>> userTallySeedCommits;
|
|
|
+
|
|
|
+ prsonaServer->break_down_midway_pseudonyms(
|
|
|
+ generatorProof,
|
|
|
+ pi,
|
|
|
+ permutationCommits,
|
|
|
+ freshPseudonymCommits,
|
|
|
+ freshPseudonymSeedCommits,
|
|
|
+ serverTallyCommits,
|
|
|
+ partwayVoteMatrixCommits,
|
|
|
+ finalVoteMatrixCommits,
|
|
|
+ userTallyMaskCommits,
|
|
|
+ userTallyMessageCommits,
|
|
|
+ userTallySeedCommits,
|
|
|
+ nextGenerator);
|
|
|
+
|
|
|
+ string data =
|
|
|
+ make_epoch_update_string(
|
|
|
+ pi[0],
|
|
|
+ permutationCommits[0],
|
|
|
+ freshPseudonymCommits[0],
|
|
|
+ freshPseudonymSeedCommits[0],
|
|
|
+ serverTallyCommits[0],
|
|
|
+ partwayVoteMatrixCommits[0],
|
|
|
+ finalVoteMatrixCommits[0],
|
|
|
+ userTallyMaskCommits[0],
|
|
|
+ userTallyMessageCommits[0],
|
|
|
+ userTallySeedCommits[0],
|
|
|
+ nextGenerator,
|
|
|
+ true);
|
|
|
+
|
|
|
+ struct synchronization_tool epochSync;
|
|
|
+ epochSync.val = 1;
|
|
|
+ for (size_t i = 0; i < serverIPs.size(); i++)
|
|
|
+ {
|
|
|
+ if (serverIPs[i] == selfIP)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ distribute_epoch_updates(
|
|
|
+ serverIPs[i],
|
|
|
+ data,
|
|
|
+ &epochSync);
|
|
|
+ }
|
|
|
+
|
|
|
+ unique_lock<mutex> lck(epochSync.mtx);
|
|
|
+ while (epochSync.val < serverIPs.size())
|
|
|
+ epochSync.cv.wait(lck);
|
|
|
+
|
|
|
+ (*epochNum)++;
|
|
|
+
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::accept_epoch_updates(
|
|
|
+ struct mg_connection *conn, const char *filename)
|
|
|
+{
|
|
|
+ std::vector<std::vector<Proof>> pi;
|
|
|
+ std::vector<std::vector<Twistpoint>> permutationCommits;
|
|
|
+ std::vector<std::vector<Twistpoint>> freshPseudonymCommits;
|
|
|
+ std::vector<std::vector<Twistpoint>> freshPseudonymSeedCommits;
|
|
|
+ std::vector<std::vector<CurveBipoint>> serverTallyCommits;
|
|
|
+ std::vector<std::vector<std::vector<TwistBipoint>>> partwayVoteMatrixCommits;
|
|
|
+ std::vector<std::vector<std::vector<TwistBipoint>>> finalVoteMatrixCommits;
|
|
|
+ std::vector<std::vector<Twistpoint>> userTallyMaskCommits;
|
|
|
+ std::vector<std::vector<Twistpoint>> userTallyMessageCommits;
|
|
|
+ std::vector<std::vector<Twistpoint>> userTallySeedCommits;
|
|
|
+ Twistpoint nextGenerator;
|
|
|
+ bool doUserTallies =
|
|
|
+ read_epoch_update_string(
|
|
|
+ filename,
|
|
|
+ pi,
|
|
|
+ permutationCommits,
|
|
|
+ freshPseudonymCommits,
|
|
|
+ freshPseudonymSeedCommits,
|
|
|
+ serverTallyCommits,
|
|
|
+ partwayVoteMatrixCommits,
|
|
|
+ finalVoteMatrixCommits,
|
|
|
+ userTallyMaskCommits,
|
|
|
+ userTallyMessageCommits,
|
|
|
+ userTallySeedCommits,
|
|
|
+ nextGenerator);
|
|
|
+
|
|
|
+ prsonaServer->accept_epoch_updates(
|
|
|
+ pi,
|
|
|
+ permutationCommits,
|
|
|
+ freshPseudonymCommits,
|
|
|
+ freshPseudonymSeedCommits,
|
|
|
+ serverTallyCommits,
|
|
|
+ partwayVoteMatrixCommits,
|
|
|
+ finalVoteMatrixCommits,
|
|
|
+ userTallyMaskCommits,
|
|
|
+ userTallyMessageCommits,
|
|
|
+ userTallySeedCommits,
|
|
|
+ nextGenerator,
|
|
|
+ doUserTallies);
|
|
|
+
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ * DATA MAINTENANCE
|
|
|
+ */
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::import_new_user_update(
|
|
|
+ const char *filename)
|
|
|
+{
|
|
|
+ std::vector<Proof> proofOfValidAddition;
|
|
|
+ std::vector<CurveBipoint> previousVoteTallies;
|
|
|
+ std::vector<Twistpoint> currentPseudonyms;
|
|
|
+ std::vector<EGCiphertext> currentUserEncryptedTallies;
|
|
|
+ std::vector<std::vector<TwistBipoint>> voteMatrix;
|
|
|
+
|
|
|
+ ifstream file(filename);
|
|
|
+
|
|
|
+ buffer << voteMatrix.size();
|
|
|
+ for (size_t i = 0; i < voteMatrix.size(); i++)
|
|
|
+ for (size_t j = 0; j < voteMatrix[i].size(); j++)
|
|
|
+ buffer << voteMatrix[i][j];
|
|
|
+
|
|
|
+ size_t sizeOfVector;
|
|
|
+
|
|
|
+ file >> sizeOfVector;
|
|
|
+ for (size_t i = 0; i < sizeOfVector; i++)
|
|
|
+ {
|
|
|
+ Proof currProof;
|
|
|
+ file >> currProof;
|
|
|
+ proofOfValidAddition.push_back(currProof);
|
|
|
+ }
|
|
|
+
|
|
|
+ file >> sizeOfVector;
|
|
|
+ for (size_t i = 0; i < sizeOfVector; i++)
|
|
|
+ {
|
|
|
+ CurveBipoint currTally;
|
|
|
+ file >> currTally;
|
|
|
+ previousVoteTallies.push_back(currTally);
|
|
|
+ }
|
|
|
+
|
|
|
+ file >> sizeOfVector;
|
|
|
+ for (size_t i = 0; i < sizeOfVector; i++)
|
|
|
+ {
|
|
|
+ Twistpoint currNym;
|
|
|
+ file >> currNym;
|
|
|
+ currentPseudonyms.push_back(currNym);
|
|
|
+ }
|
|
|
+
|
|
|
+ file >> sizeOfVector;
|
|
|
+ for (size_t i = 0; i < sizeOfVector; i++)
|
|
|
+ {
|
|
|
+ EGCiphertext currTally;
|
|
|
+ file >> currTally;
|
|
|
+ currentUserEncryptedTallies.push_back(currTally);
|
|
|
+ }
|
|
|
+
|
|
|
+ file >> sizeOfVector;
|
|
|
+ for (size_t i = 0; i < sizeOfVector; i++)
|
|
|
+ {
|
|
|
+ std::vector<TwistBipoint> currRow;
|
|
|
+ for (size_t j = 0; j < sizeOfVector; j++)
|
|
|
+ {
|
|
|
+ TwistBipoint currVote;
|
|
|
+ file >> currVote;
|
|
|
+ currRow.push_back(currVote);
|
|
|
+ }
|
|
|
+ voteMatrix.push_back(currRow);
|
|
|
+ }
|
|
|
+
|
|
|
+ prsonaServer->import_new_user_update(
|
|
|
+ proofOfValidAddition,
|
|
|
+ previousVoteTallies,
|
|
|
+ currentPseudonyms,
|
|
|
+ currentUserEncryptedTallies,
|
|
|
+ voteMatrix);
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::get_partial_decryption(
|
|
|
+ struct mg_connection *conn)
|
|
|
+{
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::receive_tallied_scores(
|
|
|
+ struct mg_connection *conn, const char *filename)
|
|
|
+{
|
|
|
+ ifstream file(filename);
|
|
|
+
|
|
|
+ std::vector<EGCiphertext> userScores;
|
|
|
+ std::vector<CurveBipoint> serverScores;
|
|
|
+
|
|
|
+ size_t sizeOfVector;
|
|
|
+ file >> sizeOfVector;
|
|
|
+ for (size_t i = 0; i < sizeOfVector; i++)
|
|
|
+ {
|
|
|
+ EGCiphertext currScore;
|
|
|
+ file >> currScore;
|
|
|
+ userScores.push_back(currScore);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (size_t i = 0; i < sizeOfVector; i++)
|
|
|
+ {
|
|
|
+ CurveBipoint currScore;
|
|
|
+ file >> currScore;
|
|
|
+ serverScores.push_back(currScore);
|
|
|
+ }
|
|
|
+
|
|
|
+ prsonaServer->receive_tallied_scores(userScores, serverScores);
|
|
|
+
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
|
|
|
+}
|
|
|
+
|
|
|
+void PrsonaServerWebSocketHandler::get_generator(
|
|
|
+ struct mg_connection *conn, bool fresh)
|
|
|
+{
|
|
|
+ Twistpoint generator;
|
|
|
+ std::vector<Proof> pi;
|
|
|
+ if (fresh)
|
|
|
+ generator = prsonaServer->get_fresh_generator(pi);
|
|
|
+ else
|
|
|
+ generator = prsonaServer->get_blinding_generator(pi);
|
|
|
+
|
|
|
+ std::stringstream buffer;
|
|
|
+ std::string data;
|
|
|
+
|
|
|
+ buffer << pi.size();
|
|
|
+ for (size_t i = 0; i < pi.size(); i++)
|
|
|
+ buffer << pi[i];
|
|
|
+
|
|
|
+ buffer << generator;
|
|
|
+
|
|
|
+ data = buffer.str();
|
|
|
|
|
|
-
|
|
|
-PrsonaNetworkServer::PrsonaNetworkServer(size_t numServers, const BGN& otherBgn)
|
|
|
-: PrsonaServer(numServers, otherBgn)
|
|
|
-{ }
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
|
|
|
+}
|