|
@@ -2,8 +2,6 @@
|
|
|
|
|
|
#include "serverEntity.hpp"
|
|
#include "serverEntity.hpp"
|
|
|
|
|
|
-const int MAX_ALLOWED_VOTE = 2;
|
|
|
|
-
|
|
|
|
/********************
|
|
/********************
|
|
* PUBLIC FUNCTIONS *
|
|
* PUBLIC FUNCTIONS *
|
|
********************/
|
|
********************/
|
|
@@ -21,27 +19,33 @@ PrsonaServerEntity::PrsonaServerEntity(size_t numServers)
|
|
}
|
|
}
|
|
|
|
|
|
// Make the first server, which makes the BGN parameters
|
|
// Make the first server, which makes the BGN parameters
|
|
- PrsonaServer firstServer;
|
|
|
|
|
|
+ PrsonaServer firstServer(numServers);
|
|
servers.push_back(firstServer);
|
|
servers.push_back(firstServer);
|
|
|
|
|
|
// Make the rest of the servers, which take the BGN parameters
|
|
// Make the rest of the servers, which take the BGN parameters
|
|
const BGN& sharedBGN = firstServer.get_bgn_details();
|
|
const BGN& sharedBGN = firstServer.get_bgn_details();
|
|
for (size_t i = 1; i < numServers; i++)
|
|
for (size_t i = 1; i < numServers; i++)
|
|
- servers.push_back(PrsonaServer(sharedBGN));
|
|
|
|
|
|
+ servers.push_back(PrsonaServer(numServers, sharedBGN));
|
|
|
|
|
|
// After all servers have made their seeds,
|
|
// After all servers have made their seeds,
|
|
// make sure they have the initial fresh generator
|
|
// make sure they have the initial fresh generator
|
|
- Curvepoint firstGenerator = get_fresh_generator();
|
|
|
|
|
|
+ std::vector<Proof> pi;
|
|
|
|
+ Curvepoint firstGenerator = get_fresh_generator(pi);
|
|
for (size_t i = 0; i < numServers; i++)
|
|
for (size_t i = 0; i < numServers; i++)
|
|
- servers[i].initialize_fresh_generator(firstGenerator);
|
|
|
|
|
|
+ servers[i].initialize_fresh_generator(pi, firstGenerator);
|
|
|
|
+
|
|
|
|
+ pi.clear();
|
|
|
|
|
|
// It's important that no server knows the DLOG between g and h for ElGamal,
|
|
// It's important that no server knows the DLOG between g and h for ElGamal,
|
|
// so have each server collaborate to make h.
|
|
// so have each server collaborate to make h.
|
|
Curvepoint blindGenerator = PrsonaServer::EL_GAMAL_GENERATOR;
|
|
Curvepoint blindGenerator = PrsonaServer::EL_GAMAL_GENERATOR;
|
|
for (size_t i = 0; i < numServers; i++)
|
|
for (size_t i = 0; i < numServers; i++)
|
|
- blindGenerator = servers[i].add_rand_seed_to_generator(blindGenerator);
|
|
|
|
|
|
+ {
|
|
|
|
+ blindGenerator =
|
|
|
|
+ servers[i].add_rand_seed_to_generator(pi, blindGenerator);
|
|
|
|
+ }
|
|
for (size_t i = 0; i < numServers; i++)
|
|
for (size_t i = 0; i < numServers; i++)
|
|
- servers[i].set_EG_blind_generator(blindGenerator);
|
|
|
|
|
|
+ servers[i].set_EG_blind_generator(pi, blindGenerator);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -50,45 +54,131 @@ PrsonaServerEntity::PrsonaServerEntity(size_t numServers)
|
|
|
|
|
|
BGNPublicKey PrsonaServerEntity::get_bgn_public_key() const
|
|
BGNPublicKey PrsonaServerEntity::get_bgn_public_key() const
|
|
{
|
|
{
|
|
- return servers[0].get_bgn_public_key();
|
|
|
|
|
|
+ return get_bgn_public_key(0);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+BGNPublicKey PrsonaServerEntity::get_bgn_public_key(size_t which) const
|
|
|
|
+{
|
|
|
|
+ return servers[which].get_bgn_public_key();
|
|
}
|
|
}
|
|
|
|
|
|
Curvepoint PrsonaServerEntity::get_blinding_generator() const
|
|
Curvepoint PrsonaServerEntity::get_blinding_generator() const
|
|
{
|
|
{
|
|
- return servers[0].get_blinding_generator();
|
|
|
|
|
|
+ return get_blinding_generator(0);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Curvepoint PrsonaServerEntity::get_blinding_generator(size_t which) const
|
|
|
|
+{
|
|
|
|
+ std::vector<Proof> pi;
|
|
|
|
+ Curvepoint retval = get_blinding_generator(pi, which);
|
|
|
|
+
|
|
|
|
+ if (!servers[which].verify_generator_proof(
|
|
|
|
+ pi, retval, servers[which].get_num_servers()))
|
|
|
|
+ {
|
|
|
|
+ std::cerr << "Error making the generator, aborting." << std::endl;
|
|
|
|
+ return Curvepoint();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return retval;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Curvepoint PrsonaServerEntity::get_blinding_generator(
|
|
|
|
+ std::vector<Proof>& pi) const
|
|
|
|
+{
|
|
|
|
+ return get_blinding_generator(pi, 0);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Curvepoint PrsonaServerEntity::get_blinding_generator(
|
|
|
|
+ std::vector<Proof>& pi, size_t which) const
|
|
|
|
+{
|
|
|
|
+ return servers[which].get_blinding_generator(pi);
|
|
}
|
|
}
|
|
|
|
|
|
Curvepoint PrsonaServerEntity::get_fresh_generator() const
|
|
Curvepoint PrsonaServerEntity::get_fresh_generator() const
|
|
|
|
+{
|
|
|
|
+ return get_fresh_generator(0);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Curvepoint PrsonaServerEntity::get_fresh_generator(size_t which) const
|
|
|
|
+{
|
|
|
|
+ std::vector<Proof> pi;
|
|
|
|
+ Curvepoint retval = get_fresh_generator(pi, which);
|
|
|
|
+
|
|
|
|
+ if (!servers[which].verify_generator_proof(
|
|
|
|
+ pi, retval, servers[which].get_num_servers()))
|
|
|
|
+ {
|
|
|
|
+ std::cerr << "Error making the generator, aborting." << std::endl;
|
|
|
|
+ return Curvepoint();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return retval;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Curvepoint PrsonaServerEntity::get_fresh_generator(
|
|
|
|
+ std::vector<Proof>& pi) const
|
|
|
|
+{
|
|
|
|
+ return get_fresh_generator(pi, 0);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Curvepoint PrsonaServerEntity::get_fresh_generator(
|
|
|
|
+ std::vector<Proof>& pi, size_t which) const
|
|
{
|
|
{
|
|
Curvepoint retval = PrsonaServer::EL_GAMAL_GENERATOR;
|
|
Curvepoint retval = PrsonaServer::EL_GAMAL_GENERATOR;
|
|
- for (size_t j = 0; j < servers.size(); j++)
|
|
|
|
- retval = servers[j].add_curr_seed_to_generator(retval);
|
|
|
|
|
|
+
|
|
|
|
+ pi.clear();
|
|
|
|
+ for (size_t j = 0; j < servers[which].get_num_servers(); j++)
|
|
|
|
+ {
|
|
|
|
+ size_t index = (which + j) % servers[which].get_num_servers();
|
|
|
|
+ retval = servers[index].add_curr_seed_to_generator(pi, retval);
|
|
|
|
+ }
|
|
|
|
|
|
return retval;
|
|
return retval;
|
|
}
|
|
}
|
|
|
|
|
|
size_t PrsonaServerEntity::get_num_clients() const
|
|
size_t PrsonaServerEntity::get_num_clients() const
|
|
{
|
|
{
|
|
- return servers[0].currentPseudonyms.size();
|
|
|
|
|
|
+ return get_num_clients(0);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+size_t PrsonaServerEntity::get_num_clients(size_t which) const
|
|
|
|
+{
|
|
|
|
+ return servers[which].get_num_clients();
|
|
}
|
|
}
|
|
|
|
|
|
size_t PrsonaServerEntity::get_num_servers() const
|
|
size_t PrsonaServerEntity::get_num_servers() const
|
|
{
|
|
{
|
|
- return servers.size();
|
|
|
|
|
|
+ return get_num_servers(0);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+size_t PrsonaServerEntity::get_num_servers(size_t which) const
|
|
|
|
+{
|
|
|
|
+ return servers[which].get_num_servers();
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
* ENCRYPTED DATA GETTERS
|
|
* ENCRYPTED DATA GETTERS
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
+std::vector<CurveBipoint> PrsonaServerEntity::get_current_votes_by(
|
|
|
|
+ Proof& pi, const Curvepoint& shortTermPublicKey) const
|
|
|
|
+{
|
|
|
|
+ return get_current_votes_by(pi, shortTermPublicKey, 0);
|
|
|
|
+}
|
|
|
|
+
|
|
/* Call this in order to get the current encrypted votes cast by a given user
|
|
/* Call this in order to get the current encrypted votes cast by a given user
|
|
* (who is identified by their short term public key).
|
|
* (who is identified by their short term public key).
|
|
* In practice, this is intended for clients,
|
|
* In practice, this is intended for clients,
|
|
* who need to know their current votes in order to rerandomize them. */
|
|
* who need to know their current votes in order to rerandomize them. */
|
|
std::vector<CurveBipoint> PrsonaServerEntity::get_current_votes_by(
|
|
std::vector<CurveBipoint> PrsonaServerEntity::get_current_votes_by(
|
|
|
|
+ Proof& pi, const Curvepoint& shortTermPublicKey, size_t which) const
|
|
|
|
+{
|
|
|
|
+ return servers[which].get_current_votes_by(pi, shortTermPublicKey);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+EGCiphertext PrsonaServerEntity::get_current_tally(
|
|
Proof& pi, const Curvepoint& shortTermPublicKey) const
|
|
Proof& pi, const Curvepoint& shortTermPublicKey) const
|
|
{
|
|
{
|
|
- return servers[0].get_current_votes_by(pi, shortTermPublicKey);
|
|
|
|
|
|
+ return get_current_tally(pi, shortTermPublicKey, 0);
|
|
}
|
|
}
|
|
|
|
|
|
/* Call this in order to get the current encrypted tally of a given user
|
|
/* Call this in order to get the current encrypted tally of a given user
|
|
@@ -96,31 +186,38 @@ std::vector<CurveBipoint> PrsonaServerEntity::get_current_votes_by(
|
|
* In practice, this is intended for clients, so that the servers vouch
|
|
* In practice, this is intended for clients, so that the servers vouch
|
|
* for their ciphertexts being valid as part of their reputation proofs. */
|
|
* for their ciphertexts being valid as part of their reputation proofs. */
|
|
EGCiphertext PrsonaServerEntity::get_current_tally(
|
|
EGCiphertext PrsonaServerEntity::get_current_tally(
|
|
- Proof& pi, const Curvepoint& shortTermPublicKey) const
|
|
|
|
|
|
+ Proof& pi, const Curvepoint& shortTermPublicKey, size_t which) const
|
|
{
|
|
{
|
|
- return servers[0].get_current_tally(pi, shortTermPublicKey);
|
|
|
|
|
|
+ return servers[which].get_current_tally(pi, shortTermPublicKey);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
* CLIENT INTERACTIONS
|
|
* CLIENT INTERACTIONS
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
+void PrsonaServerEntity::add_new_client(PrsonaClient& newUser)
|
|
|
|
+{
|
|
|
|
+ add_new_client(newUser, 0);
|
|
|
|
+}
|
|
|
|
+
|
|
/* Add a new client (who is identified only by their short term public key)
|
|
/* Add a new client (who is identified only by their short term public key)
|
|
* One server does the main work, then other servers import their (proven)
|
|
* One server does the main work, then other servers import their (proven)
|
|
* exported data. */
|
|
* exported data. */
|
|
-void PrsonaServerEntity::add_new_client(PrsonaClient& newUser)
|
|
|
|
|
|
+void PrsonaServerEntity::add_new_client(PrsonaClient& newUser, size_t which)
|
|
{
|
|
{
|
|
Proof proofOfValidSTPK, proofOfCorrectAddition, proofOfValidVotes;
|
|
Proof proofOfValidSTPK, proofOfCorrectAddition, proofOfValidVotes;
|
|
- Curvepoint freshGenerator = get_fresh_generator();
|
|
|
|
|
|
+ std::vector<Proof> proofOfValidGenerator;
|
|
|
|
+ Curvepoint freshGenerator =
|
|
|
|
+ get_fresh_generator(proofOfValidGenerator, which);
|
|
|
|
|
|
// Users can't actually announce a short term public key
|
|
// Users can't actually announce a short term public key
|
|
// if they don't know the fresh generator.
|
|
// if they don't know the fresh generator.
|
|
- newUser.receive_fresh_generator(freshGenerator);
|
|
|
|
|
|
+ newUser.receive_fresh_generator(proofOfValidGenerator, freshGenerator);
|
|
Curvepoint shortTermPublicKey = newUser.get_short_term_public_key(
|
|
Curvepoint shortTermPublicKey = newUser.get_short_term_public_key(
|
|
proofOfValidSTPK);
|
|
proofOfValidSTPK);
|
|
|
|
|
|
// Do the actual work of adding the client to the first server
|
|
// Do the actual work of adding the client to the first server
|
|
- servers[0].add_new_client(
|
|
|
|
|
|
+ servers[which].add_new_client(
|
|
proofOfValidSTPK, proofOfCorrectAddition, shortTermPublicKey);
|
|
proofOfValidSTPK, proofOfCorrectAddition, shortTermPublicKey);
|
|
|
|
|
|
// Then, export the data to the rest of the servers
|
|
// Then, export the data to the rest of the servers
|
|
@@ -129,15 +226,16 @@ void PrsonaServerEntity::add_new_client(PrsonaClient& newUser)
|
|
std::vector<EGCiphertext> currentUserEncryptedTallies;
|
|
std::vector<EGCiphertext> currentUserEncryptedTallies;
|
|
std::vector<Proof> currentTallyProofs;
|
|
std::vector<Proof> currentTallyProofs;
|
|
std::vector<std::vector<CurveBipoint>> voteMatrix;
|
|
std::vector<std::vector<CurveBipoint>> voteMatrix;
|
|
- servers[0].export_updates(
|
|
|
|
|
|
+ servers[which].export_updates(
|
|
previousVoteTally,
|
|
previousVoteTally,
|
|
currentPseudonyms,
|
|
currentPseudonyms,
|
|
currentUserEncryptedTallies,
|
|
currentUserEncryptedTallies,
|
|
currentTallyProofs,
|
|
currentTallyProofs,
|
|
voteMatrix);
|
|
voteMatrix);
|
|
- for (size_t j = 1; j < servers.size(); j++)
|
|
|
|
|
|
+ for (size_t j = 1; j < servers[which].get_num_servers(); j++)
|
|
{
|
|
{
|
|
- servers[j].import_updates(
|
|
|
|
|
|
+ size_t index = (which + j) % servers[which].get_num_servers();
|
|
|
|
+ servers[index].import_updates(
|
|
proofOfCorrectAddition,
|
|
proofOfCorrectAddition,
|
|
previousVoteTally,
|
|
previousVoteTally,
|
|
currentPseudonyms,
|
|
currentPseudonyms,
|
|
@@ -148,7 +246,7 @@ void PrsonaServerEntity::add_new_client(PrsonaClient& newUser)
|
|
|
|
|
|
// Finally, give the user the information it needs
|
|
// Finally, give the user the information it needs
|
|
// about its current tally and votes
|
|
// about its current tally and votes
|
|
- transmit_updates(newUser);
|
|
|
|
|
|
+ transmit_updates(newUser, which);
|
|
}
|
|
}
|
|
|
|
|
|
// Receive a new vote row from a user (identified by short term public key).
|
|
// Receive a new vote row from a user (identified by short term public key).
|
|
@@ -156,41 +254,52 @@ bool PrsonaServerEntity::receive_vote(
|
|
const std::vector<Proof>& pi,
|
|
const std::vector<Proof>& pi,
|
|
const std::vector<CurveBipoint>& newVotes,
|
|
const std::vector<CurveBipoint>& newVotes,
|
|
const Curvepoint& shortTermPublicKey)
|
|
const Curvepoint& shortTermPublicKey)
|
|
|
|
+{
|
|
|
|
+ return receive_vote(pi, newVotes, shortTermPublicKey, 0);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool PrsonaServerEntity::receive_vote(
|
|
|
|
+ const std::vector<Proof>& pi,
|
|
|
|
+ const std::vector<CurveBipoint>& newVotes,
|
|
|
|
+ const Curvepoint& shortTermPublicKey,
|
|
|
|
+ size_t which)
|
|
{
|
|
{
|
|
bool retval = true;
|
|
bool retval = true;
|
|
|
|
|
|
- for (size_t i = 0; i < servers.size(); i++)
|
|
|
|
|
|
+ for (size_t i = 0; i < servers[which].get_num_servers(); i++)
|
|
{
|
|
{
|
|
- retval =
|
|
|
|
- retval && servers[i].receive_vote(pi, newVotes, shortTermPublicKey);
|
|
|
|
|
|
+ size_t index = (i + which) % servers[which].get_num_servers();
|
|
|
|
+
|
|
|
|
+ retval = retval &&
|
|
|
|
+ servers[index].receive_vote(pi, newVotes, shortTermPublicKey);
|
|
}
|
|
}
|
|
|
|
|
|
return retval;
|
|
return retval;
|
|
}
|
|
}
|
|
|
|
|
|
-bool PrsonaServerEntity::receive_vote(
|
|
|
|
- const std::vector<Proof>& pi,
|
|
|
|
- const std::vector<CurveBipoint>& newVotes,
|
|
|
|
- const Curvepoint& shortTermPublicKey,
|
|
|
|
- size_t which)
|
|
|
|
|
|
+void PrsonaServerEntity::transmit_updates(PrsonaClient& currUser) const
|
|
{
|
|
{
|
|
- return servers[which].receive_vote(pi, newVotes, shortTermPublicKey);
|
|
|
|
|
|
+ transmit_updates(currUser, 0);
|
|
}
|
|
}
|
|
|
|
|
|
// After tallying scores and new vote matrix,
|
|
// After tallying scores and new vote matrix,
|
|
// give those to a user for the new epoch
|
|
// give those to a user for the new epoch
|
|
-void PrsonaServerEntity::transmit_updates(PrsonaClient& currUser) const
|
|
|
|
|
|
+void PrsonaServerEntity::transmit_updates(
|
|
|
|
+ PrsonaClient& currUser, size_t which) const
|
|
{
|
|
{
|
|
Proof proofOfValidSTPK, proofOfScore, proofOfCorrectVotes;
|
|
Proof proofOfValidSTPK, proofOfScore, proofOfCorrectVotes;
|
|
- Curvepoint freshGenerator = get_fresh_generator();
|
|
|
|
|
|
+ std::vector<Proof> proofOfValidGenerator;
|
|
|
|
+ Curvepoint freshGenerator =
|
|
|
|
+ get_fresh_generator(proofOfValidGenerator, which);
|
|
|
|
|
|
// Get users the next fresh generator so they can correctly
|
|
// Get users the next fresh generator so they can correctly
|
|
// ask for their new scores and vote row
|
|
// ask for their new scores and vote row
|
|
- currUser.receive_fresh_generator(freshGenerator);
|
|
|
|
- Curvepoint shortTermPublicKey = currUser.get_short_term_public_key(
|
|
|
|
- proofOfValidSTPK);
|
|
|
|
|
|
+ currUser.receive_fresh_generator(proofOfValidGenerator, freshGenerator);
|
|
|
|
+ Curvepoint shortTermPublicKey =
|
|
|
|
+ currUser.get_short_term_public_key(proofOfValidSTPK);
|
|
|
|
|
|
- EGCiphertext score = get_current_tally(proofOfScore, shortTermPublicKey);
|
|
|
|
|
|
+ EGCiphertext score =
|
|
|
|
+ get_current_tally(proofOfScore, shortTermPublicKey, which);
|
|
currUser.receive_vote_tally(proofOfScore, score);
|
|
currUser.receive_vote_tally(proofOfScore, score);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -198,8 +307,13 @@ void PrsonaServerEntity::transmit_updates(PrsonaClient& currUser) const
|
|
* EPOCH
|
|
* EPOCH
|
|
*/
|
|
*/
|
|
|
|
|
|
-// Do the epoch process
|
|
|
|
void PrsonaServerEntity::epoch(Proof& pi)
|
|
void PrsonaServerEntity::epoch(Proof& pi)
|
|
|
|
+{
|
|
|
|
+ epoch(pi, 0);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// Do the epoch process
|
|
|
|
+void PrsonaServerEntity::epoch(Proof& pi, size_t which)
|
|
{
|
|
{
|
|
Curvepoint nextGenerator = PrsonaServer::EL_GAMAL_GENERATOR;
|
|
Curvepoint nextGenerator = PrsonaServer::EL_GAMAL_GENERATOR;
|
|
|
|
|
|
@@ -210,16 +324,19 @@ void PrsonaServerEntity::epoch(Proof& pi)
|
|
std::vector<std::vector<CurveBipoint>> voteMatrix;
|
|
std::vector<std::vector<CurveBipoint>> voteMatrix;
|
|
|
|
|
|
// go from A_0 to A_0.5
|
|
// go from A_0 to A_0.5
|
|
- for (size_t i = 0; i < servers.size(); i++)
|
|
|
|
|
|
+ for (size_t i = 0; i < servers[which].get_num_servers(); i++)
|
|
{
|
|
{
|
|
- servers[i].build_up_midway_pseudonyms(pi, nextGenerator);
|
|
|
|
- servers[i].export_updates(
|
|
|
|
|
|
+ size_t index = (which + i) % servers[which].get_num_servers();
|
|
|
|
+ size_t nextIndex = (which + i + 1) % servers[which].get_num_servers();
|
|
|
|
+
|
|
|
|
+ servers[index].build_up_midway_pseudonyms(pi, nextGenerator);
|
|
|
|
+ servers[index].export_updates(
|
|
previousVoteTally,
|
|
previousVoteTally,
|
|
currentPseudonyms,
|
|
currentPseudonyms,
|
|
currentUserEncryptedTallies,
|
|
currentUserEncryptedTallies,
|
|
currentTallyProofs,
|
|
currentTallyProofs,
|
|
voteMatrix);
|
|
voteMatrix);
|
|
- servers[(i + 1) % servers.size()].import_updates(
|
|
|
|
|
|
+ servers[nextIndex].import_updates(
|
|
pi,
|
|
pi,
|
|
previousVoteTally,
|
|
previousVoteTally,
|
|
currentPseudonyms,
|
|
currentPseudonyms,
|
|
@@ -232,19 +349,23 @@ void PrsonaServerEntity::epoch(Proof& pi)
|
|
* knows a secret mask and encrypted the correct value everyone else already
|
|
* knows a secret mask and encrypted the correct value everyone else already
|
|
* knows. Everyone else then adds a mask and proves they added a secret mask
|
|
* knows. Everyone else then adds a mask and proves they added a secret mask
|
|
* to the committed values. */
|
|
* to the committed values. */
|
|
- currentUserEncryptedTallies = tally_scores(currentTallyProofs, nextGenerator);
|
|
|
|
|
|
+ currentUserEncryptedTallies =
|
|
|
|
+ tally_scores(currentTallyProofs, nextGenerator, which);
|
|
|
|
|
|
// go from A_0.5 to A_1
|
|
// go from A_0.5 to A_1
|
|
- for (size_t i = 0; i < servers.size(); i++)
|
|
|
|
|
|
+ for (size_t i = 0; i < servers[which].get_num_servers(); i++)
|
|
{
|
|
{
|
|
- servers[i].break_down_midway_pseudonyms(pi, nextGenerator);
|
|
|
|
- servers[i].export_updates(
|
|
|
|
|
|
+ size_t index = (which + i) % servers[which].get_num_servers();
|
|
|
|
+ size_t nextIndex = (which + i + 1) % servers[which].get_num_servers();
|
|
|
|
+
|
|
|
|
+ servers[index].break_down_midway_pseudonyms(pi, nextGenerator);
|
|
|
|
+ servers[index].export_updates(
|
|
previousVoteTally,
|
|
previousVoteTally,
|
|
currentPseudonyms,
|
|
currentPseudonyms,
|
|
currentUserEncryptedTallies,
|
|
currentUserEncryptedTallies,
|
|
currentTallyProofs,
|
|
currentTallyProofs,
|
|
voteMatrix);
|
|
voteMatrix);
|
|
- servers[(i + 1) % servers.size()].import_updates(
|
|
|
|
|
|
+ servers[nextIndex].import_updates(
|
|
pi,
|
|
pi,
|
|
previousVoteTally,
|
|
previousVoteTally,
|
|
currentPseudonyms,
|
|
currentPseudonyms,
|
|
@@ -254,9 +375,11 @@ void PrsonaServerEntity::epoch(Proof& pi)
|
|
}
|
|
}
|
|
|
|
|
|
// At the end, make sure all servers have same information
|
|
// At the end, make sure all servers have same information
|
|
- for (size_t i = 1; i < servers.size() - 1; i++)
|
|
|
|
|
|
+ for (size_t i = 1; i < servers[which].get_num_servers() - 1; i++)
|
|
{
|
|
{
|
|
- servers[i].import_updates(
|
|
|
|
|
|
+ size_t index = (which + i) % servers[which].get_num_servers();
|
|
|
|
+
|
|
|
|
+ servers[index].import_updates(
|
|
pi,
|
|
pi,
|
|
previousVoteTally,
|
|
previousVoteTally,
|
|
currentPseudonyms,
|
|
currentPseudonyms,
|
|
@@ -280,16 +403,19 @@ void PrsonaServerEntity::epoch(Proof& pi)
|
|
* We're treating it as if we are one server, so that server gets the updated
|
|
* We're treating it as if we are one server, so that server gets the updated
|
|
* weights to be sent to all other servers for the next epoch. */
|
|
* weights to be sent to all other servers for the next epoch. */
|
|
std::vector<EGCiphertext> PrsonaServerEntity::tally_scores(
|
|
std::vector<EGCiphertext> PrsonaServerEntity::tally_scores(
|
|
- std::vector<Proof>& tallyProofs, const Curvepoint& nextGenerator)
|
|
|
|
|
|
+ std::vector<Proof>& tallyProofs,
|
|
|
|
+ const Curvepoint& nextGenerator,
|
|
|
|
+ size_t which)
|
|
{
|
|
{
|
|
std::vector<EGCiphertext> retval;
|
|
std::vector<EGCiphertext> retval;
|
|
Proof maxScoreProof;
|
|
Proof maxScoreProof;
|
|
- std::vector<Scalar> decryptedTalliedScores = servers[0].tally_scores(
|
|
|
|
|
|
+ std::vector<Scalar> decryptedTalliedScores = servers[which].tally_scores(
|
|
tallyProofs);
|
|
tallyProofs);
|
|
mpz_class maxScorePossibleThisRound =
|
|
mpz_class maxScorePossibleThisRound =
|
|
- servers[0].get_max_possible_score(maxScoreProof).toInt() *
|
|
|
|
- MAX_ALLOWED_VOTE;
|
|
|
|
- mpz_class topOfScoreRange = decryptedTalliedScores.size() * MAX_ALLOWED_VOTE;
|
|
|
|
|
|
+ servers[which].get_max_possible_score(maxScoreProof).toInt() *
|
|
|
|
+ PrsonaBase::get_max_allowed_vote();
|
|
|
|
+ mpz_class topOfScoreRange =
|
|
|
|
+ decryptedTalliedScores.size() * PrsonaBase::get_max_allowed_vote();
|
|
|
|
|
|
for (size_t i = 0; i < decryptedTalliedScores.size(); i++)
|
|
for (size_t i = 0; i < decryptedTalliedScores.size(); i++)
|
|
{
|
|
{
|
|
@@ -306,17 +432,17 @@ std::vector<EGCiphertext> PrsonaServerEntity::tally_scores(
|
|
|
|
|
|
// Give the server the new weights,
|
|
// Give the server the new weights,
|
|
// to get passed around to the other servers
|
|
// to get passed around to the other servers
|
|
- servers[0].bgn_system.encrypt(
|
|
|
|
- servers[0].previousVoteTallies[i], decryptedTalliedScores[i]);
|
|
|
|
|
|
+ servers[which].bgnSystem.encrypt(
|
|
|
|
+ servers[which].previousVoteTallies[i], decryptedTalliedScores[i]);
|
|
|
|
|
|
- retval[i].mask = servers[0].currentPseudonyms[i] * currMask;
|
|
|
|
|
|
+ retval[i].mask = servers[which].currentPseudonyms[i] * currMask;
|
|
retval[i].encryptedMessage =
|
|
retval[i].encryptedMessage =
|
|
(nextGenerator * currMask) +
|
|
(nextGenerator * currMask) +
|
|
- (servers[0].get_blinding_generator() * decryptedTalliedScores[i]);
|
|
|
|
|
|
+ (servers[which].get_blinding_generator() * decryptedTalliedScores[i]);
|
|
}
|
|
}
|
|
|
|
|
|
- servers[0].currentUserEncryptedTallies = retval;
|
|
|
|
- servers[0].currentTallyProofs = tallyProofs;
|
|
|
|
|
|
+ servers[which].currentUserEncryptedTallies = retval;
|
|
|
|
+ servers[which].currentTallyProofs = tallyProofs;
|
|
return retval;
|
|
return retval;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -326,7 +452,7 @@ std::vector<EGCiphertext> PrsonaServerEntity::tally_scores(
|
|
|
|
|
|
// Completely normal binary search
|
|
// Completely normal binary search
|
|
size_t PrsonaServerEntity::binary_search(
|
|
size_t PrsonaServerEntity::binary_search(
|
|
- const Curvepoint& shortTermPublicKey) const
|
|
|
|
|
|
+ const Curvepoint& shortTermPublicKey, size_t which) const
|
|
{
|
|
{
|
|
- return servers[0].binary_search(shortTermPublicKey);
|
|
|
|
|
|
+ return servers[which].binary_search(shortTermPublicKey);
|
|
}
|
|
}
|