serverEntity.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #include <iostream>
  2. #include "serverEntity.hpp"
  3. PrsonaServerEntity::PrsonaServerEntity(size_t numServers)
  4. {
  5. if (numServers < 1)
  6. std::cerr << "You have to have at least 1 server. I'm making it anyways." << std::endl;
  7. PrsonaServer firstServer;
  8. servers.push_back(firstServer);
  9. const BGN& sharedBGN = firstServer.get_bgn_details();
  10. Curvepoint sharedEGBlindGenerator = firstServer.get_blinding_generator();
  11. for (size_t i = 1; i < numServers; i++)
  12. {
  13. PrsonaServer currServer(sharedBGN, sharedEGBlindGenerator);
  14. servers.push_back(currServer);
  15. }
  16. }
  17. BGNPublicKey PrsonaServerEntity::get_bgn_public_key() const
  18. {
  19. return servers[0].get_bgn_public_key();
  20. }
  21. Curvepoint PrsonaServerEntity::get_blinding_generator() const
  22. {
  23. return servers[0].get_blinding_generator();
  24. }
  25. Curvepoint PrsonaServerEntity::get_fresh_generator(Proof& pi) const
  26. {
  27. Curvepoint retval = PrsonaServer::elGamalGenerator;
  28. for (size_t j = 0; j < servers.size(); j++)
  29. servers[j].add_seed_to_generator(pi, retval);
  30. return retval;
  31. }
  32. void PrsonaServerEntity::add_new_client(PrsonaClient& newUser)
  33. {
  34. Proof proofOfValidGenerator, proofOfValidSTPK, proofOfCorrectAddition, proofOfDefaultTally, proofOfValidVotes;
  35. Curvepoint freshGenerator = get_fresh_generator(proofOfValidGenerator);
  36. newUser.receive_fresh_generator(proofOfValidGenerator, freshGenerator);
  37. Curvepoint shortTermPublicKey = newUser.get_short_term_public_key(proofOfValidSTPK);
  38. servers[0].add_new_client(proofOfValidSTPK, proofOfCorrectAddition, shortTermPublicKey);
  39. std::vector<TwistBipoint> previousVoteTally;
  40. std::vector<Curvepoint> currentPseudonyms;
  41. std::vector<std::vector<CurveBipoint>> voteMatrix;
  42. servers[0].export_updates(previousVoteTally, currentPseudonyms, voteMatrix);
  43. for (size_t j = 1; j < servers.size(); j++)
  44. servers[j].import_updates(proofOfCorrectAddition, previousVoteTally, currentPseudonyms, voteMatrix);
  45. EGCiphertext defaultTally = get_default_tally(proofOfDefaultTally, shortTermPublicKey);
  46. newUser.receive_vote_tally(proofOfDefaultTally, defaultTally, true);
  47. std::vector<CurveBipoint> encryptedDefaults = servers[0].get_current_votes_by(proofOfValidVotes, shortTermPublicKey);
  48. newUser.receive_encrypted_votes(proofOfValidVotes, encryptedDefaults, true);
  49. }
  50. void PrsonaServerEntity::receive_vote(const Proof& pi, const std::vector<CurveBipoint>& votes, const Curvepoint& shortTermPublicKey)
  51. {
  52. for (size_t j = 0; j < servers.size(); j++)
  53. servers[j].receive_vote(pi, votes, shortTermPublicKey);
  54. }
  55. void PrsonaServerEntity::epoch()
  56. {
  57. Proof pi, proofOfCorrectTally;
  58. Curvepoint nextGenerator = PrsonaServer::elGamalGenerator;
  59. std::vector<Scalar> decryptedTalliedScores = tally_scores(proofOfCorrectTally);
  60. std::vector<TwistBipoint> previousVoteTally;
  61. std::vector<Curvepoint> currentPseudonyms;
  62. std::vector<std::vector<CurveBipoint>> voteMatrix;
  63. for (size_t i = 0; i < servers.size() - 1; i++)
  64. {
  65. servers[i].epoch_part_one(pi, nextGenerator, decryptedTalliedScores);
  66. servers[i].export_updates(previousVoteTally, currentPseudonyms, voteMatrix);
  67. servers[i + 1].import_updates(pi, previousVoteTally, currentPseudonyms, voteMatrix);
  68. }
  69. servers[servers.size() - 1].epoch_part_one(pi, nextGenerator, decryptedTalliedScores);
  70. servers[servers.size() - 1].export_updates(previousVoteTally, currentPseudonyms, voteMatrix);
  71. encryptedTallies.clear();
  72. for (size_t i = 0; i < decryptedTalliedScores.size(); i++)
  73. {
  74. EGCiphertext currCiphertext;
  75. encryptedTallies.push_back(currCiphertext);
  76. Scalar currMask;
  77. currMask.set_random();
  78. servers[0].bgn_system.encrypt(previousVoteTally[i], decryptedTalliedScores[i]);
  79. encryptedTallies[i].mask = currentPseudonyms[i] * currMask;
  80. encryptedTallies[i].encryptedMessage = (nextGenerator * currMask) + (get_blinding_generator() * decryptedTalliedScores[i]);
  81. }
  82. pi = generate_epoch_round_one_proof(pi, proofOfCorrectTally);
  83. servers[0].import_updates(pi, previousVoteTally, currentPseudonyms, voteMatrix);
  84. for (size_t i = 0; i < servers.size() - 1; i++)
  85. {
  86. servers[i].epoch_part_two(pi, encryptedTallies);
  87. servers[i].export_updates(previousVoteTally, currentPseudonyms, voteMatrix);
  88. servers[i + 1].import_updates(pi, previousVoteTally, currentPseudonyms, voteMatrix);
  89. }
  90. servers[servers.size() - 1].epoch_part_two(pi, encryptedTallies);
  91. servers[servers.size() - 1].export_updates(previousVoteTally, currentPseudonyms, voteMatrix);
  92. for (size_t i = 0; i < servers.size() - 1; i++)
  93. servers[i].import_updates(pi, previousVoteTally, currentPseudonyms, voteMatrix);
  94. for (size_t i = 0; i < encryptedTallies.size(); i++)
  95. tallyProofs[i] = generate_epoch_proof(pi, encryptedTallies[i]);
  96. }
  97. void PrsonaServerEntity::transmit_score(PrsonaClient& newUser) const
  98. {
  99. Proof proofOfValidGenerator, proofOfValidSTPK, proofOfScore, proofOfCorrectVotes;
  100. Curvepoint freshGenerator = get_fresh_generator(proofOfValidGenerator);
  101. newUser.receive_fresh_generator(proofOfValidGenerator, freshGenerator);
  102. Curvepoint shortTermPublicKey = newUser.get_short_term_public_key(proofOfValidSTPK);
  103. EGCiphertext score = get_current_tally(proofOfScore, shortTermPublicKey);
  104. newUser.receive_vote_tally(proofOfScore, score, false);
  105. std::vector<CurveBipoint> encryptedVotes = servers[0].get_current_votes_by(proofOfCorrectVotes, shortTermPublicKey);
  106. newUser.receive_encrypted_votes(proofOfCorrectVotes, encryptedVotes, false);
  107. }
  108. EGCiphertext PrsonaServerEntity::get_default_tally(Proof& pi, const Curvepoint& shortTermPublicKey) const
  109. {
  110. Proof unused;
  111. EGCiphertext retval;
  112. Scalar lambda;
  113. lambda.set_random();
  114. retval.mask = shortTermPublicKey * lambda;
  115. retval.encryptedMessage = get_fresh_generator(unused) * lambda + get_blinding_generator() * PrsonaServer::defaultTally;
  116. pi = generate_valid_default_tally_proof(retval, lambda);
  117. return retval;
  118. }
  119. Proof PrsonaServerEntity::generate_valid_default_tally_proof(const EGCiphertext& encryptedDefaultTally, const Scalar& lambda) const
  120. {
  121. if (!PrsonaServer::malicious_server)
  122. return "PROOF";
  123. return "PROOF";
  124. }
  125. Proof PrsonaServerEntity::generate_epoch_round_one_proof(const Proof& pi1, const Proof& pi2) const
  126. {
  127. if (!PrsonaServer::malicious_server)
  128. return "PROOF";
  129. return "PROOF";
  130. }
  131. Proof PrsonaServerEntity::generate_epoch_proof(const Proof& pi, const EGCiphertext& encryptedTally) const
  132. {
  133. if (!PrsonaServer::malicious_server)
  134. return "PROOF";
  135. return "PROOF";
  136. }
  137. EGCiphertext PrsonaServerEntity::get_current_tally(Proof& pi, const Curvepoint& shortTermPublicKey) const
  138. {
  139. size_t requester = binary_search(shortTermPublicKey);
  140. pi = tallyProofs[requester];
  141. return encryptedTallies[requester];
  142. }
  143. std::vector<Scalar> PrsonaServerEntity::tally_scores(Proof& pi)
  144. {
  145. return servers[0].tally_scores(pi);
  146. }
  147. size_t PrsonaServerEntity::binary_search(const Curvepoint& shortTermPublicKey) const
  148. {
  149. return servers[0].binary_search(shortTermPublicKey);
  150. }