123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- #include "server.hpp"
- extern const scalar_t bn_n;
- const Scalar PrsonaServer::scalarN(bn_n);
- extern const curvepoint_fp_t bn_curvegen;
- const Curvepoint PrsonaServer::elGamalGenerator(bn_curvegen);
- PrsonaServer::PrsonaServer()
- {
- Scalar lambda;
- lambda.set_random();
- elGamalBlindGenerator = elGamalGenerator * lambda;
- currentSeed.set_random();
- }
- Curvepoint PrsonaServer::get_blinding_generator() const
- {
- return elGamalBlindGenerator;
- }
- Curvepoint PrsonaServer::get_fresh_generator() const
- {
- return elGamalGenerator * currentSeed;
- }
- Curvepoint PrsonaServer::add_new_client(const Curvepoint& longTermPublicKey)
- {
- Curvepoint newPseudonym = longTermPublicKey * currentSeed;
- currentPseudonyms.push_back(newPseudonym);
- TwistBipoint newTalliedVote;
- encrypt(newTalliedVote, Scalar(0));
- previousVoteTally.push_back(newTalliedVote);
- CurveBipoint defaultVote;
- encrypt(defaultVote, Scalar(0));
- vector<CurveBipoint> newRow;
- for (size_t i = 0; i < voteMatrix.size(); i++)
- {
- rerandomize(defaultVote);
- voteMatrix[i].push_back(defaultVote);
- rerandomize(defaultVote);
- newRow.push_back(defaultVote);
- }
- rerandomize(defaultVote);
- newRow.push_back(defaultVote);
- voteMatrix.push_back(newRow);
- return newPseudonym;
- }
- vector<EGCiphertext> PrsonaServer::epoch()
- {
- Scalar inverseSeed = scalarN - currentSeed;
- Scalar nextSeed;
- nextSeed.set_random();
- vector<Quadripoint> BGNEncryptedTallies;
- vector<Scalar> decryptedTallies;
- vector<EGCiphertext> EGEncryptedTallies(currentPseudonyms.size());
- for (size_t i = 0; i < voteMatrix.size(); i++)
- {
- vector<Quadripoint> currTally;
- for (size_t j = 0; j < previousVoteTally.size(); j++)
- {
- Quadripoint curr;
- homomorphic_multiplication(curr, voteMatrix[j][i], previousVoteTally[j]);
- currTally.push_back(curr);
- }
- BGNEncryptedTallies.push_back(std::accumulate(currTally.begin(), currTally.end(), Quadripoint()));
- }
-
- for (size_t i = 0; i < currentPseudonyms.size(); i++)
- {
- currentPseudonyms[i] = currentPseudonyms[i] * nextSeed;
- decryptedTallies.push_back(decrypt(BGNEncryptedTallies[i]));
- }
- shuffle_vote_matrix(decryptedTallies);
-
- Curvepoint nextGenerator = elGamalGenerator * nextSeed;
- for (size_t i = 0; i < currentPseudonyms.size(); i++)
- {
- Scalar currMask;
- currMask.set_random();
- previousVoteTally[i] = encrypt(decryptedTallies[i]);
-
- EGEncryptedTallies[i].mask = currentPseudonyms[i] * currMask;
- EGEncryptedTallies[i].encryptedMessage = (nextGenerator * currMask) + (elGamalBlindGenerator * decryptedTallies[i]);
- }
- for (size_t i = 0; i < currentPseudonyms.size(); i++)
- {
- currentPseudonyms[i] = currentPseudonyms[i] * inverseSeed;
- EGEncryptedTallies[i].mask = EGEncryptedTallies[i].mask * inverseSeed;
- }
- shuffle_vote_matrix(EGEncryptedTallies);
- return EGEncryptedTallies;
- }
- template <typename T>
- void PrsonaServer::shuffle_vote_matrix(vector<T>& otherVector)
- {
- vector<sorting_t> sortTracker;
- for (size_t i = 0; i < currentPseudonyms.size(); i++)
- {
- sorting_t curr;
-
- curr.pseudonym = currentPseudonyms[i];
- curr.index = i;
- sortTracker.push_back(curr);
- }
- std::sort(sortTracker.begin(), sortTracker.end());
- vector<Curvepoint> newPseudonyms;
- vector<TwistBipoint> newVoteTallies;
- vector<vector<CurveBipoint>> newVoteMatrix;
- vector<T> newOtherVector;
- for (size_t i = 0; i < currentPseudonyms.size(); i++)
- {
- newPseudonyms.push_back(sortTracker[i].pseudonym);
- newVoteTallies.push_back(previousVoteTally[sortTracker[i].index]);
- newOtherVector.push_back(otherVector[sortTracker[i].index]);
- vector<CurveBipoint> currNewRow;
- for (size_t j = 0; j < currentPseudonyms.size(); j++)
- {
- currNewRow.push_back(voteMatrix[sortTracker[i].index][sortTracker[j].index]);
- }
- newVoteMatrix.push_back(currNewRow);
- }
- currentPseudonyms = newPseudonyms;
- previousVoteTally = newVoteTallies;
- voteMatrix = newVoteMatrix;
- otherVector = newOtherVector;
- rerandomize_vote_matrix();
- }
- void PrsonaServer::rerandomize_vote_matrix()
- {
- for (size_t i = 0; i < voteMatrix.size(); i++)
- {
- for (size_t j = 0; j < voteMatrix[0].size(); j++)
- {
- voteMatrix[i][j] = rerandomize(voteMatrix[i][j]);
- }
- }
- }
- void PrsonaServer::receive_vote(const Proof& pi, const vector<CurveBipoint>& votes, const Curvepoint& shortTermPublicKey)
- {
- if (!verify_vote_proof(pi, votes, shortTermPublicKey))
- return;
- size_t voteSubmitter = binary_search(shortTermPublicKey);
- voteMatrix[voteSubmitter] = votes;
- rerandomize_vote_matrix();
- }
- size_t PrsonaServer::binary_search(const Curvepoint& index) const
- {
- size_t lo, hi;
- lo = 0;
- hi = currentPseudonyms.size() - 1;
- while (lo < hi)
- {
- size_t mid = (lo + hi) / 2;
- if (currentPseudonyms[mid] < index)
- lo = mid + 1;
- else if (index == currentPseudonyms[mid])
- return mid;
- else hi = mid - 1;
- }
- return lo;
- }
- bool PrsonaServer::verify_vote_proof(const Proof& pi, const vector<CurveBipoint>& votes, const Curvepoint& shortTermPublicKey) const
- {
- }
|