serverEntity.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  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. retval = servers[j].add_seed_to_generator(pi, retval);
  30. return retval;
  31. }
  32. Scalar PrsonaServerEntity::decrypt(const CurveBipoint& input)
  33. {
  34. return servers[0].bgn_system.decrypt(input);
  35. }
  36. std::vector<CurveBipoint> PrsonaServerEntity::get_current_votes_by(Proof& pi, const Curvepoint& shortTermPublicKey) const
  37. {
  38. return servers[0].get_current_votes_by(pi, shortTermPublicKey);
  39. }
  40. void PrsonaServerEntity::add_new_client(PrsonaClient& newUser)
  41. {
  42. Proof proofOfValidGenerator, proofOfValidSTPK, proofOfCorrectAddition, proofOfDefaultTally, proofOfValidVotes;
  43. Curvepoint freshGenerator = get_fresh_generator(proofOfValidGenerator);
  44. newUser.receive_fresh_generator(proofOfValidGenerator, freshGenerator);
  45. Curvepoint shortTermPublicKey = newUser.get_short_term_public_key(proofOfValidSTPK);
  46. servers[0].add_new_client(proofOfValidSTPK, proofOfCorrectAddition, shortTermPublicKey);
  47. std::vector<TwistBipoint> previousVoteTally;
  48. std::vector<Curvepoint> currentPseudonyms;
  49. std::vector<std::vector<CurveBipoint>> voteMatrix;
  50. servers[0].export_updates(previousVoteTally, currentPseudonyms, voteMatrix);
  51. for (size_t j = 1; j < servers.size(); j++)
  52. servers[j].import_updates(proofOfCorrectAddition, previousVoteTally, currentPseudonyms, voteMatrix);
  53. EGCiphertext defaultTally = get_default_tally(proofOfDefaultTally, shortTermPublicKey);
  54. newUser.receive_vote_tally(proofOfDefaultTally, defaultTally, true);
  55. std::vector<CurveBipoint> encryptedDefaults = servers[0].get_current_votes_by(proofOfValidVotes, shortTermPublicKey);
  56. newUser.receive_encrypted_votes(proofOfValidVotes, encryptedDefaults, true);
  57. }
  58. void PrsonaServerEntity::receive_vote(const Proof& pi, const std::vector<CurveBipoint>& votes, const Curvepoint& shortTermPublicKey)
  59. {
  60. for (size_t j = 0; j < servers.size(); j++)
  61. servers[j].receive_vote(pi, votes, shortTermPublicKey);
  62. }
  63. void PrsonaServerEntity::epoch()
  64. {
  65. Proof pi, proofOfCorrectTally, testUserPi;
  66. Curvepoint nextGenerator = PrsonaServer::elGamalGenerator;
  67. std::vector<Scalar> decryptedTalliedScores = tally_scores(proofOfCorrectTally);
  68. std::vector<TwistBipoint> previousVoteTally;
  69. std::vector<Curvepoint> currentPseudonyms;
  70. std::vector<std::vector<CurveBipoint>> voteMatrix;
  71. for (size_t i = 0; i < servers.size(); i++)
  72. {
  73. servers[i].epoch_part_one(pi, nextGenerator, decryptedTalliedScores);
  74. servers[i].export_updates(previousVoteTally, currentPseudonyms, voteMatrix);
  75. if (i < servers.size() - 1)
  76. servers[i + 1].import_updates(pi, previousVoteTally, currentPseudonyms, voteMatrix);
  77. }
  78. encryptedTallies.clear();
  79. for (size_t i = 0; i < decryptedTalliedScores.size(); i++)
  80. {
  81. EGCiphertext currCiphertext;
  82. encryptedTallies.push_back(currCiphertext);
  83. Scalar currMask;
  84. currMask.set_random();
  85. servers[0].bgn_system.encrypt(previousVoteTally[i], decryptedTalliedScores[i]);
  86. encryptedTallies[i].mask = currentPseudonyms[i] * currMask;
  87. encryptedTallies[i].encryptedMessage = (nextGenerator * currMask) + (get_blinding_generator() * decryptedTalliedScores[i]);
  88. }
  89. pi = generate_epoch_round_one_proof(pi, proofOfCorrectTally);
  90. servers[0].import_updates(pi, previousVoteTally, currentPseudonyms, voteMatrix);
  91. for (size_t i = 0; i < servers.size(); i++)
  92. {
  93. servers[i].epoch_part_two(pi, encryptedTallies);
  94. servers[i].export_updates(previousVoteTally, currentPseudonyms, voteMatrix);
  95. if (i < servers.size() - 1)
  96. servers[i + 1].import_updates(pi, previousVoteTally, currentPseudonyms, voteMatrix);
  97. }
  98. for (size_t i = 0; i < servers.size() - 1; i++)
  99. servers[i].import_updates(pi, previousVoteTally, currentPseudonyms, voteMatrix);
  100. tallyProofs.clear();
  101. for (size_t i = 0; i < encryptedTallies.size(); i++)
  102. tallyProofs.push_back(generate_epoch_proof(pi, encryptedTallies[i]));
  103. }
  104. void PrsonaServerEntity::transmit_score(PrsonaClient& newUser) const
  105. {
  106. Proof proofOfValidGenerator, proofOfValidSTPK, proofOfScore, proofOfCorrectVotes;
  107. Curvepoint freshGenerator = get_fresh_generator(proofOfValidGenerator);
  108. newUser.receive_fresh_generator(proofOfValidGenerator, freshGenerator);
  109. Curvepoint shortTermPublicKey = newUser.get_short_term_public_key(proofOfValidSTPK);
  110. EGCiphertext score = get_current_tally(proofOfScore, shortTermPublicKey);
  111. newUser.receive_vote_tally(proofOfScore, score, false);
  112. std::vector<CurveBipoint> encryptedVotes = servers[0].get_current_votes_by(proofOfCorrectVotes, shortTermPublicKey);
  113. newUser.receive_encrypted_votes(proofOfCorrectVotes, encryptedVotes, false);
  114. }
  115. EGCiphertext PrsonaServerEntity::get_default_tally(Proof& pi, const Curvepoint& shortTermPublicKey) const
  116. {
  117. Proof unused;
  118. EGCiphertext retval;
  119. Scalar lambda;
  120. lambda.set_random();
  121. retval.mask = shortTermPublicKey * lambda;
  122. retval.encryptedMessage = get_fresh_generator(unused) * lambda + get_blinding_generator() * PrsonaServer::defaultTally;
  123. pi = generate_valid_default_tally_proof(retval, lambda);
  124. return retval;
  125. }
  126. Proof PrsonaServerEntity::generate_valid_default_tally_proof(const EGCiphertext& encryptedDefaultTally, const Scalar& lambda) const
  127. {
  128. if (!PrsonaServer::malicious_server)
  129. return "PROOF";
  130. return "PROOF";
  131. }
  132. Proof PrsonaServerEntity::generate_epoch_round_one_proof(const Proof& pi1, const Proof& pi2) const
  133. {
  134. if (!PrsonaServer::malicious_server)
  135. return "PROOF";
  136. return "PROOF";
  137. }
  138. Proof PrsonaServerEntity::generate_epoch_proof(const Proof& pi, const EGCiphertext& encryptedTally) const
  139. {
  140. if (!PrsonaServer::malicious_server)
  141. return "PROOF";
  142. return "PROOF";
  143. }
  144. EGCiphertext PrsonaServerEntity::get_current_tally(Proof& pi, const Curvepoint& shortTermPublicKey) const
  145. {
  146. size_t requester = binary_search(shortTermPublicKey);
  147. pi = tallyProofs[requester];
  148. return encryptedTallies[requester];
  149. }
  150. std::vector<Scalar> PrsonaServerEntity::tally_scores(Proof& pi)
  151. {
  152. return servers[0].tally_scores(pi);
  153. }
  154. size_t PrsonaServerEntity::binary_search(const Curvepoint& shortTermPublicKey) const
  155. {
  156. return servers[0].binary_search(shortTermPublicKey);
  157. }