|
@@ -122,7 +122,11 @@ void make_epoch(
|
|
obtain_update_locks(updateLock, serverIPs, serverPorts, selfIP, selfPort, bandwidthData);
|
|
obtain_update_locks(updateLock, serverIPs, serverPorts, selfIP, selfPort, bandwidthData);
|
|
|
|
|
|
// Do the first half of the epoch calculations (building up the intermediary values)
|
|
// Do the first half of the epoch calculations (building up the intermediary values)
|
|
- std::vector<Proof> generatorProof = epoch_build_up(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, nextGenerator, civetServer, buildUpOutputMtx, buildUpOutputFilename, usageMtx, usageFilename, bandwidthData);
|
|
|
|
|
|
+ std::vector<Proof> generatorProof;
|
|
|
|
+ if (prsonaServer->is_server_malicious())
|
|
|
|
+ generatorProof = epoch_build_up(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, nextGenerator, civetServer, buildUpOutputMtx, buildUpOutputFilename, usageMtx, usageFilename, bandwidthData);
|
|
|
|
+ else
|
|
|
|
+ generatorProof = hbc_epoch_build_up(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, nextGenerator, civetServer, buildUpOutputMtx, buildUpOutputFilename, usageMtx, usageFilename, bandwidthData);
|
|
|
|
|
|
// Tally up the current scores at the end of the epoch for the users
|
|
// Tally up the current scores at the end of the epoch for the users
|
|
std::vector<EGCiphertext> currentUserEncryptedTallies;
|
|
std::vector<EGCiphertext> currentUserEncryptedTallies;
|
|
@@ -133,7 +137,10 @@ void make_epoch(
|
|
distribute_tallied_scores(prsonaServer, serverIPs, serverPorts, selfIP, selfPort, nextGenerator, currentUserEncryptedTallies, currentServerEncryptedTallies, bandwidthData);
|
|
distribute_tallied_scores(prsonaServer, serverIPs, serverPorts, selfIP, selfPort, nextGenerator, currentUserEncryptedTallies, currentServerEncryptedTallies, bandwidthData);
|
|
|
|
|
|
// Do the second half of the epoch calculations (breaking down values to their final values, to be given to users)
|
|
// Do the second half of the epoch calculations (breaking down values to their final values, to be given to users)
|
|
- epoch_break_down(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, generatorProof, nextGenerator, civetServer, breakDownOutputMtx, breakDownOutputFilename, usageMtx, usageFilename, bandwidthData);
|
|
|
|
|
|
+ if (prsonaServer->is_server_malicious())
|
|
|
|
+ epoch_break_down(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, generatorProof, nextGenerator, civetServer, breakDownOutputMtx, breakDownOutputFilename, usageMtx, usageFilename, bandwidthData);
|
|
|
|
+ else
|
|
|
|
+ hbc_epoch_break_down(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, generatorProof, nextGenerator, civetServer, breakDownOutputMtx, breakDownOutputFilename, usageMtx, usageFilename, bandwidthData);
|
|
|
|
|
|
// Indicate we are in a new epoch
|
|
// Indicate we are in a new epoch
|
|
epochNum.fetch_add(1);
|
|
epochNum.fetch_add(1);
|
|
@@ -595,6 +602,118 @@ std::vector<Proof> epoch_build_up(
|
|
return generatorProofHolder[0];
|
|
return generatorProofHolder[0];
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+std::vector<Proof> hbc_epoch_build_up(
|
|
|
|
+ std::default_random_engine& rng,
|
|
|
|
+ PrsonaServer *prsonaServer,
|
|
|
|
+ const std::vector<std::string>& serverIPs,
|
|
|
|
+ const std::vector<int>& serverPorts,
|
|
|
|
+ const std::string& selfIP,
|
|
|
|
+ int selfPort,
|
|
|
|
+ Twistpoint& nextGenerator,
|
|
|
|
+ const CivetServer& civetServer,
|
|
|
|
+ std::mutex& outputMtx,
|
|
|
|
+ const std::string& outputFilename,
|
|
|
|
+ std::mutex& usageMtx,
|
|
|
|
+ const std::string& usageFilename,
|
|
|
|
+ std::vector<size_t>& overallBandwidthData)
|
|
|
|
+{
|
|
|
|
+ std::vector<Proof> generatorProof;
|
|
|
|
+ std::vector<Twistpoint> newFreshPseudonyms;
|
|
|
|
+ std::vector<CurveBipoint> newServerTallies;
|
|
|
|
+ std::vector<std::vector<TwistBipoint>> newVoteMatrix;
|
|
|
|
+
|
|
|
|
+ // Go through each server to perform the epoch calculation at hand
|
|
|
|
+ for (size_t i = 0; i < serverIPs.size(); i++)
|
|
|
|
+ {
|
|
|
|
+ // When it's our turn, do things as normal
|
|
|
|
+ if (serverIPs[i] == selfIP && serverPorts[i] == selfPort)
|
|
|
|
+ {
|
|
|
|
+ newFreshPseudonyms.clear();
|
|
|
|
+ newServerTallies.clear();
|
|
|
|
+ newVoteMatrix.clear();
|
|
|
|
+ std::vector<size_t> bandwidthData(2);
|
|
|
|
+ std::vector<std::vector<size_t>> otherBandwidthDataBefore;
|
|
|
|
+
|
|
|
|
+ std::vector<size_t> serverBandwidthDataBefore = get_server_log_data(civetServer.getContext());
|
|
|
|
+ std::chrono::high_resolution_clock::time_point wallTimeBefore = std::chrono::high_resolution_clock::now();
|
|
|
|
+ clock_t cpuTimeBefore = clock();
|
|
|
|
+
|
|
|
|
+ // Perform the actual calculation
|
|
|
|
+ prsonaServer->hbc_build_up_midway_pseudonyms(generatorProof, newFreshPseudonyms, newServerTallies, newVoteMatrix, nextGenerator);
|
|
|
|
+
|
|
|
|
+ std::vector<EGCiphertext> newUserTallies;
|
|
|
|
+
|
|
|
|
+ // Serialize the relevant data
|
|
|
|
+ std::string data = make_hbc_epoch_update_string(generatorProof, newFreshPseudonyms, newServerTallies, newVoteMatrix, newUserTallies, nextGenerator, false);
|
|
|
|
+
|
|
|
|
+ struct synchronization_tool sync;
|
|
|
|
+ std::vector<struct mg_connection *> conns;
|
|
|
|
+
|
|
|
|
+ // Distribute the data to each server (in parallel, roughly)
|
|
|
|
+ std::unique_lock<std::mutex> lck(sync.mtx);
|
|
|
|
+ sync.val = 1;
|
|
|
|
+ for (size_t j = 0; j < serverIPs.size(); j++)
|
|
|
|
+ {
|
|
|
|
+ // But, obviously, don't send it back to ourselves
|
|
|
|
+ if (i == j)
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ // Send that data
|
|
|
|
+ struct mg_connection *currConn = distribute_epoch_updates(serverIPs[j], serverPorts[j], data, &sync);
|
|
|
|
+
|
|
|
|
+ otherBandwidthDataBefore.push_back(get_conn_log_data(mg_get_context(currConn), false));
|
|
|
|
+
|
|
|
|
+ // But keep track of that connection, as we can't close it until we know the server's gotten its data
|
|
|
|
+ conns.push_back(currConn);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Wait for the other servers to all report back that they have received the update
|
|
|
|
+ while (sync.val < serverIPs.size())
|
|
|
|
+ sync.cv.wait(lck);
|
|
|
|
+
|
|
|
|
+ for (size_t j = 0; j < conns.size(); j++)
|
|
|
|
+ {
|
|
|
|
+ std::vector<size_t> currBandwidthDataAfter = get_conn_log_data(mg_get_context(conns[j]), false);
|
|
|
|
+
|
|
|
|
+ bandwidthData[0] += currBandwidthDataAfter[0] - otherBandwidthDataBefore[j][0];
|
|
|
|
+ bandwidthData[1] += currBandwidthDataAfter[1] - otherBandwidthDataBefore[j][1];
|
|
|
|
+ overallBandwidthData[0] += currBandwidthDataAfter[0] - otherBandwidthDataBefore[j][0];
|
|
|
|
+ overallBandwidthData[1] += currBandwidthDataAfter[1] - otherBandwidthDataBefore[j][1];
|
|
|
|
+
|
|
|
|
+ mg_close_connection(conns[j]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ clock_t cpuTimeAfter = clock();
|
|
|
|
+ std::chrono::high_resolution_clock::time_point wallTimeAfter = std::chrono::high_resolution_clock::now();
|
|
|
|
+ std::vector<size_t> serverBandwidthDataAfter = get_server_log_data(civetServer.getContext());
|
|
|
|
+
|
|
|
|
+ std::vector<double> timingData(2);
|
|
|
|
+ timingData[0] = std::chrono::duration_cast<std::chrono::duration<double>>(wallTimeAfter - wallTimeBefore).count();
|
|
|
|
+ timingData[1] = ((double)(cpuTimeAfter - cpuTimeBefore)) / CLOCKS_PER_SEC;
|
|
|
|
+
|
|
|
|
+ bandwidthData[0] += serverBandwidthDataAfter[0] - serverBandwidthDataBefore[0];
|
|
|
|
+ bandwidthData[1] += serverBandwidthDataAfter[1] - serverBandwidthDataBefore[1];
|
|
|
|
+
|
|
|
|
+ write_log_data(outputMtx, outputFilename, timingData, bandwidthData);
|
|
|
|
+ write_usage_data(usageMtx, usageFilename);
|
|
|
|
+ }
|
|
|
|
+ else // When it's another server's turn, tell them to do their part
|
|
|
|
+ {
|
|
|
|
+ // Serialize the request
|
|
|
|
+ std::string data = make_epoch_initiator_string(generatorProof, nextGenerator);
|
|
|
|
+
|
|
|
|
+ std::vector<std::vector<Proof>> generatorProofHolder;
|
|
|
|
+ generatorProofHolder.push_back(generatorProof);
|
|
|
|
+
|
|
|
|
+ // And have them do that request
|
|
|
|
+ nextGenerator = initiate_epoch_updates(rng, serverIPs[i], serverPorts[i], data, false, generatorProofHolder, overallBandwidthData);
|
|
|
|
+ generatorProof = generatorProofHolder[0];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return generatorProof;
|
|
|
|
+}
|
|
|
|
+
|
|
void epoch_break_down(
|
|
void epoch_break_down(
|
|
std::default_random_engine& rng,
|
|
std::default_random_engine& rng,
|
|
PrsonaServer *prsonaServer,
|
|
PrsonaServer *prsonaServer,
|
|
@@ -715,6 +834,114 @@ void epoch_break_down(
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void hbc_epoch_break_down(
|
|
|
|
+ std::default_random_engine& rng,
|
|
|
|
+ PrsonaServer *prsonaServer,
|
|
|
|
+ const std::vector<std::string>& serverIPs,
|
|
|
|
+ const std::vector<int>& serverPorts,
|
|
|
|
+ const std::string& selfIP,
|
|
|
|
+ int selfPort,
|
|
|
|
+ const std::vector<Proof>& generatorProof,
|
|
|
|
+ const Twistpoint& nextGenerator,
|
|
|
|
+ const CivetServer& civetServer,
|
|
|
|
+ std::mutex& outputMtx,
|
|
|
|
+ const std::string& outputFilename,
|
|
|
|
+ std::mutex& usageMtx,
|
|
|
|
+ const std::string& usageFilename,
|
|
|
|
+ std::vector<size_t>& overallBandwidthData)
|
|
|
|
+{
|
|
|
|
+ std::vector<Twistpoint> newFreshPseudonyms;
|
|
|
|
+ std::vector<CurveBipoint> newServerTallies;
|
|
|
|
+ std::vector<std::vector<TwistBipoint>> newVoteMatrix;
|
|
|
|
+ std::vector<EGCiphertext> newUserTallies;
|
|
|
|
+
|
|
|
|
+ // Go through each server to perform the epoch calculation at hand
|
|
|
|
+ for (size_t i = 0; i < serverIPs.size(); i++)
|
|
|
|
+ {
|
|
|
|
+ // When it's our turn, do things as normal
|
|
|
|
+ if (serverIPs[i] == selfIP && serverPorts[i] == selfPort)
|
|
|
|
+ {
|
|
|
|
+ newFreshPseudonyms.clear();
|
|
|
|
+ newServerTallies.clear();
|
|
|
|
+ newVoteMatrix.clear();
|
|
|
|
+ newUserTallies.clear();
|
|
|
|
+ std::vector<size_t> bandwidthData(2);
|
|
|
|
+ std::vector<std::vector<size_t>> otherBandwidthDataBefore;
|
|
|
|
+
|
|
|
|
+ std::vector<size_t> serverBandwidthDataBefore = get_server_log_data(civetServer.getContext());
|
|
|
|
+ std::chrono::high_resolution_clock::time_point wallTimeBefore = std::chrono::high_resolution_clock::now();
|
|
|
|
+ clock_t cpuTimeBefore = clock();
|
|
|
|
+
|
|
|
|
+ // Perform the actual calculation
|
|
|
|
+ prsonaServer->hbc_break_down_midway_pseudonyms(generatorProof, newFreshPseudonyms, newServerTallies, newVoteMatrix, newUserTallies, nextGenerator);
|
|
|
|
+
|
|
|
|
+ // Serialize the relevant data
|
|
|
|
+ std::string data = make_hbc_epoch_update_string(generatorProof, newFreshPseudonyms, newServerTallies, newVoteMatrix, newUserTallies, nextGenerator, true);
|
|
|
|
+
|
|
|
|
+ struct synchronization_tool sync;
|
|
|
|
+ std::vector<struct mg_connection *> conns;
|
|
|
|
+
|
|
|
|
+ // Distribute the data to each server (in parallel, roughly)
|
|
|
|
+ std::unique_lock<std::mutex> lck(sync.mtx);
|
|
|
|
+ sync.val = 1;
|
|
|
|
+ for (size_t j = 0; j < serverIPs.size(); j++)
|
|
|
|
+ {
|
|
|
|
+ // But, obviously, don't send it back to ourselves
|
|
|
|
+ if (i == j)
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ // Send that data
|
|
|
|
+ struct mg_connection *currConn = distribute_epoch_updates(serverIPs[j], serverPorts[j], data, &sync);
|
|
|
|
+
|
|
|
|
+ otherBandwidthDataBefore.push_back(get_conn_log_data(mg_get_context(currConn), false));
|
|
|
|
+
|
|
|
|
+ // But keep track of that connection, as we can't close it until we know the server's gotten its data
|
|
|
|
+ conns.push_back(currConn);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Wait for the other servers to all report back that they have received the update
|
|
|
|
+ while (sync.val < serverIPs.size())
|
|
|
|
+ sync.cv.wait(lck);
|
|
|
|
+
|
|
|
|
+ for (size_t j = 0; j < conns.size(); j++)
|
|
|
|
+ {
|
|
|
|
+ std::vector<size_t> currBandwidthDataAfter = get_conn_log_data(mg_get_context(conns[j]), false);
|
|
|
|
+
|
|
|
|
+ bandwidthData[0] += currBandwidthDataAfter[0] - otherBandwidthDataBefore[j][0];
|
|
|
|
+ bandwidthData[1] += currBandwidthDataAfter[1] - otherBandwidthDataBefore[j][1];
|
|
|
|
+ overallBandwidthData[0] += currBandwidthDataAfter[0] - otherBandwidthDataBefore[j][0];
|
|
|
|
+ overallBandwidthData[1] += currBandwidthDataAfter[1] - otherBandwidthDataBefore[j][1];
|
|
|
|
+
|
|
|
|
+ mg_close_connection(conns[j]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ clock_t cpuTimeAfter = clock();
|
|
|
|
+ std::chrono::high_resolution_clock::time_point wallTimeAfter = std::chrono::high_resolution_clock::now();
|
|
|
|
+ std::vector<size_t> serverBandwidthDataAfter = get_server_log_data(civetServer.getContext());
|
|
|
|
+
|
|
|
|
+ std::vector<double> timingData(2);
|
|
|
|
+ timingData[0] = std::chrono::duration_cast<std::chrono::duration<double>>(wallTimeAfter - wallTimeBefore).count();
|
|
|
|
+ timingData[1] = ((double)(cpuTimeAfter - cpuTimeBefore)) / CLOCKS_PER_SEC;
|
|
|
|
+
|
|
|
|
+ bandwidthData[0] += serverBandwidthDataAfter[0] - serverBandwidthDataBefore[0];
|
|
|
|
+ bandwidthData[1] += serverBandwidthDataAfter[1] - serverBandwidthDataBefore[1];
|
|
|
|
+
|
|
|
|
+ write_log_data(outputMtx, outputFilename, timingData, bandwidthData);
|
|
|
|
+ write_usage_data(usageMtx, usageFilename);
|
|
|
|
+ }
|
|
|
|
+ else // When it's another server's turn, tell them to do their part
|
|
|
|
+ {
|
|
|
|
+ std::vector<std::vector<Proof>> unused;
|
|
|
|
+
|
|
|
|
+ // Serialize the request
|
|
|
|
+ std::string data = make_epoch_initiator_string(generatorProof, nextGenerator);
|
|
|
|
+
|
|
|
|
+ // And have them do that request
|
|
|
|
+ initiate_epoch_updates(rng, serverIPs[i], serverPorts[i], data, true, unused, overallBandwidthData);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* HELPERS FOR EPOCH HELPERS
|
|
* HELPERS FOR EPOCH HELPERS
|
|
*/
|
|
*/
|
|
@@ -1168,6 +1395,53 @@ std::string make_epoch_update_string(
|
|
return buffer.str();
|
|
return buffer.str();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+std::string make_hbc_epoch_update_string(
|
|
|
|
+ const std::vector<Proof>& generatorProof,
|
|
|
|
+ const std::vector<Twistpoint>& newFreshPseudonyms,
|
|
|
|
+ const std::vector<CurveBipoint>& newServerTallies,
|
|
|
|
+ const std::vector<std::vector<TwistBipoint>>& newVoteMatrix,
|
|
|
|
+ const std::vector<EGCiphertext>& newUserTallies,
|
|
|
|
+ const Twistpoint& nextGenerator,
|
|
|
|
+ bool doUserTallies)
|
|
|
|
+{
|
|
|
|
+ std::stringstream buffer;
|
|
|
|
+
|
|
|
|
+ BinarySizeT sizeOfVector;
|
|
|
|
+
|
|
|
|
+ sizeOfVector.set(generatorProof.size());
|
|
|
|
+ buffer << sizeOfVector;
|
|
|
|
+ for (size_t i = 0; i < sizeOfVector.val(); i++)
|
|
|
|
+ buffer << generatorProof[i];
|
|
|
|
+
|
|
|
|
+ sizeOfVector.set(newFreshPseudonyms.size());
|
|
|
|
+ buffer << sizeOfVector;
|
|
|
|
+ for (size_t i = 0; i < sizeOfVector.val(); i++)
|
|
|
|
+ buffer << newFreshPseudonyms[i];
|
|
|
|
+
|
|
|
|
+ sizeOfVector.set(newServerTallies.size());
|
|
|
|
+ buffer << sizeOfVector;
|
|
|
|
+ for (size_t i = 0; i < sizeOfVector.val(); i++)
|
|
|
|
+ buffer << newServerTallies[i];
|
|
|
|
+
|
|
|
|
+ sizeOfVector.set(newVoteMatrix.size());
|
|
|
|
+ buffer << sizeOfVector;
|
|
|
|
+ for (size_t i = 0; i < sizeOfVector.val(); i++)
|
|
|
|
+ for (size_t j = 0; j < sizeOfVector.val(); j++)
|
|
|
|
+ buffer << newVoteMatrix[i][j];
|
|
|
|
+
|
|
|
|
+ sizeOfVector.set(newUserTallies.size());
|
|
|
|
+ buffer << sizeOfVector;
|
|
|
|
+ for (size_t i = 0; i < sizeOfVector.val(); i++)
|
|
|
|
+ buffer << newUserTallies[i];
|
|
|
|
+
|
|
|
|
+ buffer << nextGenerator;
|
|
|
|
+
|
|
|
|
+ BinaryBool flag(doUserTallies);
|
|
|
|
+ buffer << flag;
|
|
|
|
+
|
|
|
|
+ return buffer.str();
|
|
|
|
+}
|
|
|
|
+
|
|
ssize_t read_epoch_update_string(
|
|
ssize_t read_epoch_update_string(
|
|
const char *filename,
|
|
const char *filename,
|
|
std::vector<std::vector<Proof>>& pi,
|
|
std::vector<std::vector<Proof>>& pi,
|
|
@@ -1366,6 +1640,91 @@ ssize_t read_epoch_update_string(
|
|
return retval;
|
|
return retval;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ssize_t read_hbc_epoch_update_string(
|
|
|
|
+ const char *filename,
|
|
|
|
+ std::vector<Proof>& generatorProof,
|
|
|
|
+ std::vector<Twistpoint>& newFreshPseudonyms,
|
|
|
|
+ std::vector<CurveBipoint>& newServerTallies,
|
|
|
|
+ std::vector<std::vector<TwistBipoint>>& newVoteMatrix,
|
|
|
|
+ std::vector<EGCiphertext>& newUserTallies,
|
|
|
|
+ Twistpoint& nextGenerator,
|
|
|
|
+ bool& doUserTallies)
|
|
|
|
+{
|
|
|
|
+ std::ifstream file(filename);
|
|
|
|
+
|
|
|
|
+ file.ignore(std::numeric_limits<std::streamsize>::max());
|
|
|
|
+ std::streamsize retval = file.gcount();
|
|
|
|
+ file.clear();
|
|
|
|
+ file.seekg(0, std::ios_base::beg);
|
|
|
|
+
|
|
|
|
+ BinarySizeT sizeOfVector;
|
|
|
|
+
|
|
|
|
+ generatorProof.clear();
|
|
|
|
+ newFreshPseudonyms.clear();
|
|
|
|
+ newServerTallies.clear();
|
|
|
|
+ newVoteMatrix.clear();
|
|
|
|
+ newUserTallies.clear();
|
|
|
|
+
|
|
|
|
+ file >> sizeOfVector;
|
|
|
|
+ for (size_t i = 0; i < sizeOfVector.val(); i++)
|
|
|
|
+ {
|
|
|
|
+ Proof currProof;
|
|
|
|
+ file >> currProof;
|
|
|
|
+
|
|
|
|
+ generatorProof.push_back(currProof);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ file >> sizeOfVector;
|
|
|
|
+ for (size_t i = 0; i < sizeOfVector.val(); i++)
|
|
|
|
+ {
|
|
|
|
+ Twistpoint currFreshPseudonym;
|
|
|
|
+ file >> currFreshPseudonym;
|
|
|
|
+
|
|
|
|
+ newFreshPseudonyms.push_back(currFreshPseudonym);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ file >> sizeOfVector;
|
|
|
|
+ for (size_t i = 0; i < sizeOfVector.val(); i++)
|
|
|
|
+ {
|
|
|
|
+ CurveBipoint currServerTally;
|
|
|
|
+ file >> currServerTally;
|
|
|
|
+
|
|
|
|
+ newServerTallies.push_back(currServerTally);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ file >> sizeOfVector;
|
|
|
|
+ for (size_t i = 0; i < sizeOfVector.val(); i++)
|
|
|
|
+ {
|
|
|
|
+ std::vector<TwistBipoint> currRow;
|
|
|
|
+ for (size_t j = 0; j < sizeOfVector.val(); j++)
|
|
|
|
+ {
|
|
|
|
+ TwistBipoint currVote;
|
|
|
|
+ file >> currVote;
|
|
|
|
+
|
|
|
|
+ currRow.push_back(currVote);
|
|
|
|
+ }
|
|
|
|
+ newVoteMatrix.push_back(currRow);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ file >> sizeOfVector;
|
|
|
|
+ for (size_t i = 0; i < sizeOfVector.val(); i++)
|
|
|
|
+ {
|
|
|
|
+ EGCiphertext currUserTally;
|
|
|
|
+ file >> currUserTally;
|
|
|
|
+
|
|
|
|
+ newUserTallies.push_back(currUserTally);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ file >> nextGenerator;
|
|
|
|
+
|
|
|
|
+ BinaryBool binaryDoUserTallies;
|
|
|
|
+ file >> binaryDoUserTallies;
|
|
|
|
+
|
|
|
|
+ doUserTallies = binaryDoUserTallies.val();
|
|
|
|
+
|
|
|
|
+ return retval;
|
|
|
|
+}
|
|
|
|
+
|
|
/**********************************************************
|
|
/**********************************************************
|
|
**** ****
|
|
**** ****
|
|
**** other server-relevant handler member functions ****
|
|
**** other server-relevant handler member functions ****
|
|
@@ -1782,15 +2141,24 @@ void PrsonaServerWebSocketHandler::generate_response(
|
|
|
|
|
|
// EPOCH ROUNDS
|
|
// EPOCH ROUNDS
|
|
case PRSONA_PERFORM_EPOCH_BUILD_UP:
|
|
case PRSONA_PERFORM_EPOCH_BUILD_UP:
|
|
- build_up_midway_pseudonyms(server, conn, filename);
|
|
|
|
|
|
+ if (prsonaServer->is_server_malicious())
|
|
|
|
+ build_up_midway_pseudonyms(server, conn, filename);
|
|
|
|
+ else
|
|
|
|
+ hbc_build_up_midway_pseudonyms(server, conn, filename);
|
|
break;
|
|
break;
|
|
|
|
|
|
case PRSONA_PERFORM_EPOCH_BREAK_DOWN:
|
|
case PRSONA_PERFORM_EPOCH_BREAK_DOWN:
|
|
- break_down_midway_pseudonyms(server, conn, filename);
|
|
|
|
|
|
+ if (prsonaServer->is_server_malicious())
|
|
|
|
+ break_down_midway_pseudonyms(server, conn, filename);
|
|
|
|
+ else
|
|
|
|
+ hbc_break_down_midway_pseudonyms(server, conn, filename);
|
|
break;
|
|
break;
|
|
|
|
|
|
case PRSONA_RECEIVE_EPOCH_UPDATE:
|
|
case PRSONA_RECEIVE_EPOCH_UPDATE:
|
|
- accept_epoch_updates(server, conn, filename);
|
|
|
|
|
|
+ if (prsonaServer->is_server_malicious())
|
|
|
|
+ accept_epoch_updates(server, conn, filename);
|
|
|
|
+ else
|
|
|
|
+ hbc_accept_epoch_updates(server, conn, filename);
|
|
break;
|
|
break;
|
|
|
|
|
|
// DISTRIBUTED BGN
|
|
// DISTRIBUTED BGN
|
|
@@ -2656,6 +3024,91 @@ void PrsonaServerWebSocketHandler::build_up_midway_pseudonyms(
|
|
mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
|
|
mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void PrsonaServerWebSocketHandler::hbc_build_up_midway_pseudonyms(
|
|
|
|
+ CivetServer *civetServer,
|
|
|
|
+ struct mg_connection *conn,
|
|
|
|
+ const char *filename)
|
|
|
|
+{
|
|
|
|
+ std::vector<Proof> generatorProof;
|
|
|
|
+ Twistpoint nextGenerator;
|
|
|
|
+
|
|
|
|
+ // Un-serialize request
|
|
|
|
+ ssize_t bandwidthRcv = read_epoch_initiator_string(filename, generatorProof, nextGenerator);
|
|
|
|
+
|
|
|
|
+ std::vector<Twistpoint> newFreshPseudonyms;
|
|
|
|
+ std::vector<CurveBipoint> newServerTallies;
|
|
|
|
+ std::vector<std::vector<TwistBipoint>> newVoteMatrix;
|
|
|
|
+
|
|
|
|
+ std::vector<size_t> bandwidthData(2);
|
|
|
|
+ std::vector<std::vector<size_t>> otherBandwidthDataBefore;
|
|
|
|
+
|
|
|
|
+ std::vector<size_t> serverBandwidthDataBefore = get_server_log_data(civetServer->getContext());
|
|
|
|
+ std::chrono::high_resolution_clock::time_point wallTimeBefore = std::chrono::high_resolution_clock::now();
|
|
|
|
+ clock_t cpuTimeBefore = clock();
|
|
|
|
+
|
|
|
|
+ // Do actual epoch calculation
|
|
|
|
+ prsonaServer->hbc_build_up_midway_pseudonyms(generatorProof, newFreshPseudonyms, newServerTallies, newVoteMatrix, nextGenerator);
|
|
|
|
+
|
|
|
|
+ std::vector<EGCiphertext> newUserTallies;
|
|
|
|
+
|
|
|
|
+ // Serialize update data
|
|
|
|
+ std::string data = make_hbc_epoch_update_string(generatorProof, newFreshPseudonyms, newServerTallies, newVoteMatrix, newUserTallies, nextGenerator, false);
|
|
|
|
+
|
|
|
|
+ struct synchronization_tool sync;
|
|
|
|
+ std::vector<struct mg_connection *> conns;
|
|
|
|
+
|
|
|
|
+ // Connect to all other servers (roughly in parallel)
|
|
|
|
+ std::unique_lock<std::mutex> lck(sync.mtx);
|
|
|
|
+ sync.val = 1;
|
|
|
|
+ for (size_t i = 0; i < serverIPs.size(); i++)
|
|
|
|
+ {
|
|
|
|
+ if (serverIPs[i] == selfIP && serverPorts[i] == selfPort)
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ // Send them update data
|
|
|
|
+ struct mg_connection *currConn = distribute_epoch_updates(serverIPs[i], serverPorts[i], data, &sync);
|
|
|
|
+
|
|
|
|
+ conns.push_back(currConn);
|
|
|
|
+ otherBandwidthDataBefore.push_back(get_conn_log_data(mg_get_context(currConn), false));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Wait for all to acknowledge receipt of the update data
|
|
|
|
+ while (sync.val < serverIPs.size())
|
|
|
|
+ sync.cv.wait(lck);
|
|
|
|
+
|
|
|
|
+ // Close connections
|
|
|
|
+ for (size_t i = 0; i < conns.size(); i++)
|
|
|
|
+ {
|
|
|
|
+ std::vector<size_t> currBandwidthDataAfter = get_conn_log_data(mg_get_context(conns[i]), false);
|
|
|
|
+
|
|
|
|
+ bandwidthData[0] += currBandwidthDataAfter[0] - otherBandwidthDataBefore[i][0];
|
|
|
|
+ bandwidthData[1] += currBandwidthDataAfter[1] - otherBandwidthDataBefore[i][1];
|
|
|
|
+
|
|
|
|
+ mg_close_connection(conns[i]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ clock_t cpuTimeAfter = clock();
|
|
|
|
+ std::chrono::high_resolution_clock::time_point wallTimeAfter = std::chrono::high_resolution_clock::now();
|
|
|
|
+ std::vector<size_t> serverBandwidthDataAfter = get_server_log_data(civetServer->getContext());
|
|
|
|
+
|
|
|
|
+ std::vector<double> timingData(2);
|
|
|
|
+ timingData[0] = std::chrono::duration_cast<std::chrono::duration<double>>(wallTimeAfter - wallTimeBefore).count();
|
|
|
|
+ timingData[1] = ((double)(cpuTimeAfter - cpuTimeBefore)) / CLOCKS_PER_SEC;
|
|
|
|
+
|
|
|
|
+ bandwidthData[0] += serverBandwidthDataAfter[0] - serverBandwidthDataBefore[0] + bandwidthRcv;
|
|
|
|
+ bandwidthData[1] += serverBandwidthDataAfter[1] - serverBandwidthDataBefore[1];
|
|
|
|
+
|
|
|
|
+ write_log_data(buildUpOutputMtx, buildUpOutputFilename, timingData, bandwidthData);
|
|
|
|
+ write_usage_data(usageMtx, usageFilename);
|
|
|
|
+
|
|
|
|
+ // Serialize response
|
|
|
|
+ data = make_epoch_initiator_string(generatorProof, nextGenerator);
|
|
|
|
+
|
|
|
|
+ // Send response
|
|
|
|
+ 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(
|
|
void PrsonaServerWebSocketHandler::break_down_midway_pseudonyms(
|
|
CivetServer *civetServer,
|
|
CivetServer *civetServer,
|
|
struct mg_connection *conn,
|
|
struct mg_connection *conn,
|
|
@@ -2744,6 +3197,88 @@ void PrsonaServerWebSocketHandler::break_down_midway_pseudonyms(
|
|
mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
|
|
mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void PrsonaServerWebSocketHandler::hbc_break_down_midway_pseudonyms(
|
|
|
|
+ CivetServer *civetServer,
|
|
|
|
+ struct mg_connection *conn,
|
|
|
|
+ const char *filename)
|
|
|
|
+{
|
|
|
|
+ std::vector<Proof> generatorProof;
|
|
|
|
+ Twistpoint nextGenerator;
|
|
|
|
+
|
|
|
|
+ // Un-serialize request
|
|
|
|
+ ssize_t bandwidthRcv = read_epoch_initiator_string(filename, generatorProof, nextGenerator);
|
|
|
|
+
|
|
|
|
+ std::vector<Twistpoint> newFreshPseudonyms;
|
|
|
|
+ std::vector<CurveBipoint> newServerTallies;
|
|
|
|
+ std::vector<std::vector<TwistBipoint>> newVoteMatrix;
|
|
|
|
+ std::vector<EGCiphertext> newUserTallies;
|
|
|
|
+ std::vector<size_t> bandwidthData(2);
|
|
|
|
+ std::vector<std::vector<size_t>> otherBandwidthDataBefore;
|
|
|
|
+
|
|
|
|
+ std::vector<size_t> serverBandwidthDataBefore = get_server_log_data(civetServer->getContext());
|
|
|
|
+ std::chrono::high_resolution_clock::time_point wallTimeBefore = std::chrono::high_resolution_clock::now();
|
|
|
|
+ clock_t cpuTimeBefore = clock();
|
|
|
|
+
|
|
|
|
+ // Perform the actual calculation
|
|
|
|
+ prsonaServer->hbc_break_down_midway_pseudonyms(generatorProof, newFreshPseudonyms, newServerTallies, newVoteMatrix, newUserTallies, nextGenerator);
|
|
|
|
+
|
|
|
|
+ // Serialize the relevant data
|
|
|
|
+ std::string data = make_hbc_epoch_update_string(generatorProof, newFreshPseudonyms, newServerTallies, newVoteMatrix, newUserTallies, nextGenerator, true);
|
|
|
|
+
|
|
|
|
+ struct synchronization_tool sync;
|
|
|
|
+ std::vector<struct mg_connection *> conns;
|
|
|
|
+
|
|
|
|
+ // Connect to all other servers (roughly in parallel)
|
|
|
|
+ std::unique_lock<std::mutex> lck(sync.mtx);
|
|
|
|
+ sync.val = 1;
|
|
|
|
+ for (size_t i = 0; i < serverIPs.size(); i++)
|
|
|
|
+ {
|
|
|
|
+ if (serverIPs[i] == selfIP && serverPorts[i] == selfPort)
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ // Send them update data
|
|
|
|
+ struct mg_connection *currConn = distribute_epoch_updates(serverIPs[i], serverPorts[i], data, &sync);
|
|
|
|
+
|
|
|
|
+ conns.push_back(currConn);
|
|
|
|
+ otherBandwidthDataBefore.push_back(get_conn_log_data(mg_get_context(currConn), false));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Wait for all to acknowledge receipt of the update data
|
|
|
|
+ while (sync.val < serverIPs.size())
|
|
|
|
+ sync.cv.wait(lck);
|
|
|
|
+
|
|
|
|
+ // Close connections
|
|
|
|
+ for (size_t i = 0; i < conns.size(); i++)
|
|
|
|
+ {
|
|
|
|
+ std::vector<size_t> currBandwidthDataAfter = get_conn_log_data(mg_get_context(conns[i]), false);
|
|
|
|
+
|
|
|
|
+ bandwidthData[0] += currBandwidthDataAfter[0] - otherBandwidthDataBefore[i][0];
|
|
|
|
+ bandwidthData[1] += currBandwidthDataAfter[1] - otherBandwidthDataBefore[i][1];
|
|
|
|
+
|
|
|
|
+ mg_close_connection(conns[i]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ clock_t cpuTimeAfter = clock();
|
|
|
|
+ std::chrono::high_resolution_clock::time_point wallTimeAfter = std::chrono::high_resolution_clock::now();
|
|
|
|
+ std::vector<size_t> serverBandwidthDataAfter = get_server_log_data(civetServer->getContext());
|
|
|
|
+
|
|
|
|
+ std::vector<double> timingData(2);
|
|
|
|
+ timingData[0] = std::chrono::duration_cast<std::chrono::duration<double>>(wallTimeAfter - wallTimeBefore).count();
|
|
|
|
+ timingData[1] = ((double)(cpuTimeAfter - cpuTimeBefore)) / CLOCKS_PER_SEC;
|
|
|
|
+
|
|
|
|
+ bandwidthData[0] += serverBandwidthDataAfter[0] - serverBandwidthDataBefore[0] + bandwidthRcv;
|
|
|
|
+ bandwidthData[1] += serverBandwidthDataAfter[1] - serverBandwidthDataBefore[1];
|
|
|
|
+
|
|
|
|
+ write_log_data(breakDownOutputMtx, breakDownOutputFilename, timingData, bandwidthData);
|
|
|
|
+ write_usage_data(usageMtx, usageFilename);
|
|
|
|
+
|
|
|
|
+ // Keep our epoch value up-to-date
|
|
|
|
+ epochNum.fetch_add(1);
|
|
|
|
+
|
|
|
|
+ // Tell initiator we have finished
|
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
|
|
|
|
+}
|
|
|
|
+
|
|
void PrsonaServerWebSocketHandler::accept_epoch_updates(
|
|
void PrsonaServerWebSocketHandler::accept_epoch_updates(
|
|
CivetServer *civetServer,
|
|
CivetServer *civetServer,
|
|
struct mg_connection *conn,
|
|
struct mg_connection *conn,
|
|
@@ -2791,6 +3326,48 @@ void PrsonaServerWebSocketHandler::accept_epoch_updates(
|
|
mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
|
|
mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void PrsonaServerWebSocketHandler::hbc_accept_epoch_updates(
|
|
|
|
+ CivetServer *civetServer,
|
|
|
|
+ struct mg_connection *conn,
|
|
|
|
+ const char *filename)
|
|
|
|
+{
|
|
|
|
+ std::vector<Proof> generatorProof;
|
|
|
|
+ std::vector<Twistpoint> newFreshPseudonyms;
|
|
|
|
+ std::vector<CurveBipoint> newServerTallies;
|
|
|
|
+ std::vector<std::vector<TwistBipoint>> newVoteMatrix;
|
|
|
|
+ std::vector<EGCiphertext> newUserTallies;
|
|
|
|
+ Twistpoint nextGenerator;
|
|
|
|
+ bool doUserTallies;
|
|
|
|
+
|
|
|
|
+ // Un-serialize request
|
|
|
|
+ ssize_t bandwidthRcv = read_hbc_epoch_update_string(filename, generatorProof, newFreshPseudonyms, newServerTallies, newVoteMatrix, newUserTallies, nextGenerator, doUserTallies);
|
|
|
|
+
|
|
|
|
+ std::vector<size_t> bandwidthDataBefore = get_server_log_data(civetServer->getContext());
|
|
|
|
+ std::chrono::high_resolution_clock::time_point wallTimeBefore = std::chrono::high_resolution_clock::now();
|
|
|
|
+ clock_t cpuTimeBefore = clock();
|
|
|
|
+
|
|
|
|
+ // Load data into server object
|
|
|
|
+ prsonaServer->hbc_accept_epoch_updates(newFreshPseudonyms, newServerTallies, newVoteMatrix, newUserTallies, doUserTallies);
|
|
|
|
+
|
|
|
|
+ clock_t cpuTimeAfter = clock();
|
|
|
|
+ std::chrono::high_resolution_clock::time_point wallTimeAfter = std::chrono::high_resolution_clock::now();
|
|
|
|
+ std::vector<size_t> bandwidthDataAfter = get_server_log_data(civetServer->getContext());
|
|
|
|
+
|
|
|
|
+ std::vector<double> timingData(2);
|
|
|
|
+ timingData[0] = std::chrono::duration_cast<std::chrono::duration<double>>(wallTimeAfter - wallTimeBefore).count();
|
|
|
|
+ timingData[1] = ((double)(cpuTimeAfter - cpuTimeBefore)) / CLOCKS_PER_SEC;
|
|
|
|
+
|
|
|
|
+ std::vector<size_t> bandwidthData(2);
|
|
|
|
+ bandwidthData[0] = bandwidthDataAfter[0] - bandwidthDataBefore[0] + bandwidthRcv;
|
|
|
|
+ bandwidthData[1] = bandwidthDataAfter[1] - bandwidthDataBefore[1];
|
|
|
|
+
|
|
|
|
+ write_log_data(updateOutputMtx, updateOutputFilename, timingData, bandwidthData);
|
|
|
|
+ write_usage_data(usageMtx, usageFilename);
|
|
|
|
+
|
|
|
|
+ // Acknowledge receipt of request
|
|
|
|
+ mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* DISTRIBUTED BGN
|
|
* DISTRIBUTED BGN
|
|
*/
|
|
*/
|