serverEntity.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. #include <iostream>
  2. #include "serverEntity.hpp"
  3. const int maxAllowedVote = 3;
  4. PrsonaServerEntity::PrsonaServerEntity(size_t numServers)
  5. {
  6. if (numServers < 1)
  7. std::cerr << "You have to have at least 1 server. I'm making it anyways." << std::endl;
  8. PrsonaServer firstServer;
  9. servers.push_back(firstServer);
  10. const BGN& sharedBGN = firstServer.get_bgn_details();
  11. Curvepoint sharedEGBlindGenerator = firstServer.get_blinding_generator();
  12. for (size_t i = 1; i < numServers; i++)
  13. {
  14. PrsonaServer currServer(sharedBGN, sharedEGBlindGenerator);
  15. servers.push_back(currServer);
  16. }
  17. }
  18. BGNPublicKey PrsonaServerEntity::get_bgn_public_key() const
  19. {
  20. return servers[0].get_bgn_public_key();
  21. }
  22. Curvepoint PrsonaServerEntity::get_blinding_generator() const
  23. {
  24. return servers[0].get_blinding_generator();
  25. }
  26. Curvepoint PrsonaServerEntity::get_fresh_generator(Proof& pi) const
  27. {
  28. Curvepoint retval = PrsonaServer::elGamalGenerator;
  29. for (size_t j = 0; j < servers.size(); j++)
  30. retval = servers[j].add_seed_to_generator(pi, retval);
  31. return retval;
  32. }
  33. Scalar PrsonaServerEntity::decrypt(const CurveBipoint& input)
  34. {
  35. return servers[0].bgn_system.decrypt(input);
  36. }
  37. std::vector<CurveBipoint> PrsonaServerEntity::get_current_votes_by(Proof& pi, const Curvepoint& shortTermPublicKey) const
  38. {
  39. return servers[0].get_current_votes_by(pi, shortTermPublicKey);
  40. }
  41. void PrsonaServerEntity::add_new_client(PrsonaClient& newUser)
  42. {
  43. Proof proofOfValidGenerator, proofOfValidSTPK, proofOfCorrectAddition, proofOfDefaultTally, proofOfValidVotes;
  44. Curvepoint freshGenerator = get_fresh_generator(proofOfValidGenerator);
  45. newUser.receive_fresh_generator(proofOfValidGenerator, freshGenerator);
  46. Curvepoint shortTermPublicKey = newUser.get_short_term_public_key(proofOfValidSTPK);
  47. servers[0].add_new_client(proofOfValidSTPK, proofOfCorrectAddition, shortTermPublicKey);
  48. std::vector<TwistBipoint> previousVoteTally;
  49. std::vector<Curvepoint> currentPseudonyms;
  50. std::vector<std::vector<CurveBipoint>> voteMatrix;
  51. servers[0].export_updates(previousVoteTally, currentPseudonyms, voteMatrix);
  52. for (size_t j = 1; j < servers.size(); j++)
  53. servers[j].import_updates(proofOfCorrectAddition, previousVoteTally, currentPseudonyms, voteMatrix);
  54. Scalar randomizationMask;
  55. EGCiphertext defaultTally = get_default_tally(proofOfDefaultTally, shortTermPublicKey, randomizationMask);
  56. newUser.receive_vote_tally(proofOfDefaultTally, defaultTally, true, randomizationMask);
  57. std::vector<CurveBipoint> encryptedDefaults = servers[0].get_current_votes_by(proofOfValidVotes, shortTermPublicKey);
  58. newUser.receive_encrypted_votes(proofOfValidVotes, encryptedDefaults, true);
  59. }
  60. void PrsonaServerEntity::receive_vote(const Proof& pi, const std::vector<CurveBipoint>& votes, const Curvepoint& shortTermPublicKey)
  61. {
  62. for (size_t j = 0; j < servers.size(); j++)
  63. servers[j].receive_vote(pi, votes, shortTermPublicKey);
  64. }
  65. void PrsonaServerEntity::epoch()
  66. {
  67. Proof pi, proofOfCorrectTally, testUserPi;
  68. Curvepoint nextGenerator = PrsonaServer::elGamalGenerator;
  69. std::vector<Scalar> decryptedTalliedScores = tally_scores(proofOfCorrectTally);
  70. std::vector<TwistBipoint> previousVoteTally;
  71. std::vector<Curvepoint> currentPseudonyms;
  72. std::vector<std::vector<CurveBipoint>> voteMatrix;
  73. encryptedTallyMasks.clear();
  74. for (size_t i = 0; i < decryptedTalliedScores.size(); i++)
  75. encryptedTallyMasks.push_back(Scalar());
  76. for (size_t i = 0; i < servers.size(); i++)
  77. {
  78. servers[i].epoch_part_one(pi, nextGenerator, decryptedTalliedScores, encryptedTallyMasks);
  79. servers[i].export_updates(previousVoteTally, currentPseudonyms, voteMatrix);
  80. if (i < servers.size() - 1)
  81. servers[i + 1].import_updates(pi, previousVoteTally, currentPseudonyms, voteMatrix);
  82. }
  83. encryptedTallies.clear();
  84. for (size_t i = 0; i < decryptedTalliedScores.size(); i++)
  85. {
  86. EGCiphertext currCiphertext;
  87. encryptedTallies.push_back(currCiphertext);
  88. servers[0].bgn_system.encrypt(previousVoteTally[i], decryptedTalliedScores[i]);
  89. encryptedTallies[i].mask = currentPseudonyms[i] * encryptedTallyMasks[i];
  90. encryptedTallies[i].encryptedMessage = (nextGenerator * encryptedTallyMasks[i]) + (get_blinding_generator() * decryptedTalliedScores[i]);
  91. }
  92. pi = generate_epoch_round_one_proof(pi, proofOfCorrectTally);
  93. servers[0].import_updates(pi, previousVoteTally, currentPseudonyms, voteMatrix);
  94. for (size_t i = 0; i < servers.size(); i++)
  95. {
  96. servers[i].epoch_part_two(pi, nextGenerator, encryptedTallies, encryptedTallyMasks);
  97. servers[i].export_updates(previousVoteTally, currentPseudonyms, voteMatrix);
  98. if (i < servers.size() - 1)
  99. servers[i + 1].import_updates(pi, previousVoteTally, currentPseudonyms, voteMatrix);
  100. }
  101. for (size_t i = 0; i < servers.size() - 1; i++)
  102. servers[i].import_updates(pi, previousVoteTally, currentPseudonyms, voteMatrix);
  103. tallyProofs.clear();
  104. for (size_t i = 0; i < encryptedTallies.size(); i++)
  105. tallyProofs.push_back(generate_epoch_proof(pi, encryptedTallies[i]));
  106. }
  107. void PrsonaServerEntity::transmit_score(PrsonaClient& newUser) const
  108. {
  109. Proof proofOfValidGenerator, proofOfValidSTPK, proofOfScore, proofOfCorrectVotes;
  110. Curvepoint freshGenerator = get_fresh_generator(proofOfValidGenerator);
  111. newUser.receive_fresh_generator(proofOfValidGenerator, freshGenerator);
  112. Curvepoint shortTermPublicKey = newUser.get_short_term_public_key(proofOfValidSTPK);
  113. Scalar randomizationMask;
  114. Proof proofOfOwner = newUser.generate_ownership_proof();
  115. EGCiphertext score = get_current_tally(proofOfOwner, proofOfScore, shortTermPublicKey, true, randomizationMask);
  116. newUser.receive_vote_tally(proofOfScore, score, false, randomizationMask);
  117. std::vector<CurveBipoint> encryptedVotes = servers[0].get_current_votes_by(proofOfCorrectVotes, shortTermPublicKey);
  118. newUser.receive_encrypted_votes(proofOfCorrectVotes, encryptedVotes, false);
  119. }
  120. EGCiphertext PrsonaServerEntity::get_default_tally(Proof& pi, const Curvepoint& shortTermPublicKey, Scalar& randomizationMask) const
  121. {
  122. Proof unused;
  123. EGCiphertext retval;
  124. randomizationMask.set_random();
  125. retval.mask = shortTermPublicKey * randomizationMask;
  126. retval.encryptedMessage = get_fresh_generator(unused) * randomizationMask + get_blinding_generator() * PrsonaServer::defaultTally;
  127. pi = generate_valid_default_tally_proof(retval, randomizationMask);
  128. return retval;
  129. }
  130. Proof PrsonaServerEntity::generate_valid_default_tally_proof(const EGCiphertext& encryptedDefaultTally, const Scalar& lambda) const
  131. {
  132. Proof retval;
  133. if (!PrsonaServer::malicious_server)
  134. {
  135. retval.basic = "PROOF";
  136. return retval;
  137. }
  138. retval.basic = "PROOF";
  139. return retval;
  140. }
  141. Proof PrsonaServerEntity::generate_epoch_round_one_proof(const Proof& pi1, const Proof& pi2) const
  142. {
  143. Proof retval;
  144. if (!PrsonaServer::malicious_server)
  145. {
  146. retval.basic = "PROOF";
  147. return retval;
  148. }
  149. retval.basic = "PROOF";
  150. return retval;
  151. }
  152. Proof PrsonaServerEntity::generate_epoch_proof(const Proof& pi, const EGCiphertext& encryptedTally) const
  153. {
  154. Proof retval;
  155. if (!PrsonaServer::malicious_server)
  156. {
  157. retval.basic = "PROOF";
  158. return retval;
  159. }
  160. retval.basic = "PROOF";
  161. return retval;
  162. }
  163. bool PrsonaServerEntity::verify_ownership_proof(const Proof& pi, const Curvepoint& shortTermPublicKey) const
  164. {
  165. if (!PrsonaServer::malicious_client)
  166. return pi.basic == "PROOF";
  167. // Proof unused;
  168. // Curvepoint g = get_fresh_generator(unused);
  169. // Curvepoint u = pi.initParts[0];
  170. // std::stringstream oracleInput;
  171. // oracleInput << g << shortTermPublicKey << u;
  172. // Scalar c = oracle(oracleInput.str());
  173. // Scalar z = pi.responseParts[0];
  174. // return (g * z) == (shortTermPublicKey * c + u);
  175. return pi.basic == "PROOF";
  176. }
  177. EGCiphertext PrsonaServerEntity::get_current_tally(const Proof& ownerProof, Proof& serverProof, const Curvepoint& shortTermPublicKey, bool isOwner, Scalar& randomizationMask) const
  178. {
  179. if (isOwner)
  180. {
  181. if (!verify_ownership_proof(ownerProof, shortTermPublicKey))
  182. return EGCiphertext();
  183. }
  184. size_t requester = binary_search(shortTermPublicKey);
  185. serverProof = tallyProofs[requester];
  186. if (isOwner)
  187. randomizationMask = encryptedTallyMasks[requester];
  188. return encryptedTallies[requester];
  189. }
  190. std::vector<Scalar> PrsonaServerEntity::tally_scores(Proof& pi)
  191. {
  192. std::vector<Scalar> retval = servers[0].tally_scores(pi);
  193. mpz_class maxScorePossibleThisRound = servers[0].get_max_possible_score(pi).toInt() * maxAllowedVote;
  194. mpz_class topOfScoreRange = retval.size() * maxAllowedVote;
  195. for (size_t i = 0; i < retval.size(); i++)
  196. retval[i] = Scalar((retval[i].toInt() * topOfScoreRange) / maxScorePossibleThisRound);
  197. return retval;
  198. }
  199. size_t PrsonaServerEntity::binary_search(const Curvepoint& shortTermPublicKey) const
  200. {
  201. return servers[0].binary_search(shortTermPublicKey);
  202. }