server.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. #include <iostream>
  2. #include "server.hpp"
  3. extern const curvepoint_fp_t bn_curvegen;
  4. const Curvepoint PrsonaServer::elGamalGenerator(bn_curvegen);
  5. extern const scalar_t bn_n;
  6. const Scalar PrsonaServer::scalarN(bn_n);
  7. const Scalar PrsonaServer::defaultTally(0);
  8. const Scalar PrsonaServer::defaultVote(0);
  9. bool PrsonaServer::malicious_server = false;
  10. bool PrsonaServer::malicious_client = false;
  11. PrsonaServer::PrsonaServer()
  12. {
  13. Scalar lambda;
  14. lambda.set_random();
  15. elGamalBlindGenerator = elGamalGenerator * lambda;
  16. currentSeed.set_random();
  17. }
  18. PrsonaServer::PrsonaServer(const BGN& other_bgn, const Curvepoint& other_blind_gen)
  19. : bgn_system(other_bgn), elGamalBlindGenerator(other_blind_gen)
  20. {
  21. currentSeed.set_random();
  22. }
  23. void PrsonaServer::set_malicious_server()
  24. {
  25. malicious_server = true;
  26. }
  27. void PrsonaServer::set_malicious_client()
  28. {
  29. malicious_client = true;
  30. }
  31. BGNPublicKey PrsonaServer::get_bgn_public_key() const
  32. {
  33. return bgn_system.get_public_key();
  34. }
  35. Curvepoint PrsonaServer::get_blinding_generator() const
  36. {
  37. return elGamalBlindGenerator;
  38. }
  39. Curvepoint PrsonaServer::add_seed_to_generator(Proof& pi, const Curvepoint& currGenerator) const
  40. {
  41. pi = generate_valid_fresh_generator_proof(pi);
  42. return currGenerator * currentSeed;
  43. }
  44. std::vector<CurveBipoint> PrsonaServer::get_current_votes_by(Proof& pi, const Curvepoint& shortTermPublicKey) const
  45. {
  46. std::vector<CurveBipoint> retval;
  47. size_t voteSubmitter = binary_search(shortTermPublicKey);
  48. retval = voteMatrix[voteSubmitter];
  49. pi = generate_votes_valid_proof(retval, shortTermPublicKey);
  50. return retval;
  51. }
  52. void PrsonaServer::add_new_client(const Proof& proofOfValidKey, Proof& proofOfValidAddition, const Curvepoint& shortTermPublicKey)
  53. {
  54. if (!verify_valid_key_proof(proofOfValidKey, shortTermPublicKey))
  55. {
  56. std::cerr << "Could not verify proof of valid key." << std::endl;
  57. return;
  58. }
  59. currentPseudonyms.push_back(shortTermPublicKey);
  60. TwistBipoint newTalliedVote;
  61. bgn_system.encrypt(newTalliedVote, Scalar(defaultTally));
  62. previousVoteTally.push_back(newTalliedVote);
  63. CurveBipoint encryptedDefaultVote;
  64. bgn_system.encrypt(encryptedDefaultVote, Scalar(defaultVote));
  65. std::vector<CurveBipoint> newRow;
  66. for (size_t i = 0; i < voteMatrix.size(); i++)
  67. {
  68. encryptedDefaultVote = bgn_system.rerandomize(encryptedDefaultVote);
  69. voteMatrix[i].push_back(encryptedDefaultVote);
  70. encryptedDefaultVote = bgn_system.rerandomize(encryptedDefaultVote);
  71. newRow.push_back(encryptedDefaultVote);
  72. }
  73. encryptedDefaultVote = bgn_system.rerandomize(encryptedDefaultVote);
  74. newRow.push_back(encryptedDefaultVote);
  75. voteMatrix.push_back(newRow);
  76. order_data();
  77. proofOfValidAddition = generate_proof_of_added_user(shortTermPublicKey);
  78. }
  79. void PrsonaServer::receive_vote(const Proof& pi, const std::vector<CurveBipoint>& votes, const Curvepoint& shortTermPublicKey)
  80. {
  81. if (!verify_vote_proof(pi, votes, shortTermPublicKey))
  82. {
  83. std::cerr << "Could not verify votes." << std::endl;
  84. return;
  85. }
  86. size_t voteSubmitter = binary_search(shortTermPublicKey);
  87. voteMatrix[voteSubmitter] = votes;
  88. }
  89. const BGN& PrsonaServer::get_bgn_details() const
  90. {
  91. return bgn_system;
  92. }
  93. std::vector<Scalar> PrsonaServer::tally_scores(Proof& pi)
  94. {
  95. std::vector<Quadripoint> BGNEncryptedTallies;
  96. std::vector<Scalar> decryptedTallies;
  97. for (size_t i = 0; i < voteMatrix.size(); i++)
  98. {
  99. std::vector<Quadripoint> weightedVotes;
  100. for (size_t j = 0; j < previousVoteTally.size(); j++)
  101. {
  102. Quadripoint curr = bgn_system.homomorphic_multiplication(voteMatrix[j][i], previousVoteTally[j]);
  103. weightedVotes.push_back(curr);
  104. }
  105. Quadripoint currEncryptedTally = weightedVotes[0];
  106. for (size_t j = 1; j < weightedVotes.size(); j++)
  107. currEncryptedTally = bgn_system.homomorphic_addition(currEncryptedTally, weightedVotes[j]);
  108. currEncryptedTally = bgn_system.rerandomize(currEncryptedTally);
  109. decryptedTallies.push_back(bgn_system.decrypt(currEncryptedTally));
  110. }
  111. pi = generate_proof_of_correct_tally(BGNEncryptedTallies, decryptedTallies);
  112. return decryptedTallies;
  113. }
  114. void PrsonaServer::export_updates(std::vector<TwistBipoint>& otherPreviousVoteTally,
  115. std::vector<Curvepoint>& otherCurrentPseudonyms, std::vector<std::vector<CurveBipoint>>& otherVoteMatrix) const
  116. {
  117. otherPreviousVoteTally = previousVoteTally;
  118. otherCurrentPseudonyms = currentPseudonyms;
  119. otherVoteMatrix = voteMatrix;
  120. }
  121. void PrsonaServer::import_updates(const Proof& pi, const std::vector<TwistBipoint>& otherPreviousVoteTally,
  122. const std::vector<Curvepoint>& otherCurrentPseudonyms, const std::vector<std::vector<CurveBipoint>>& otherVoteMatrix)
  123. {
  124. if (!verify_update_proof(pi, otherPreviousVoteTally, otherCurrentPseudonyms, otherVoteMatrix))
  125. {
  126. std::cerr << "Could not verify valid update." << std::endl;
  127. return;
  128. }
  129. previousVoteTally = otherPreviousVoteTally;
  130. currentPseudonyms = otherCurrentPseudonyms;
  131. voteMatrix = otherVoteMatrix;
  132. }
  133. void PrsonaServer::epoch_part_one(Proof& pi, Curvepoint& nextGenerator, std::vector<Scalar>& decryptedTallies)
  134. {
  135. nextSeed.set_random();
  136. nextGenerator = nextGenerator * nextSeed;
  137. for (size_t i = 0; i < currentPseudonyms.size(); i++)
  138. currentPseudonyms[i] = currentPseudonyms[i] * nextSeed;
  139. std::vector<size_t> shuffleOrder = order_data();
  140. rerandomize_vote_matrix();
  141. std::vector<Scalar> reorderedTallies;
  142. for (size_t i = 0; i < shuffleOrder.size(); i++)
  143. reorderedTallies.push_back(decryptedTallies[shuffleOrder[i]]);
  144. decryptedTallies = reorderedTallies;
  145. pi = generate_proof_of_shuffle(shuffleOrder);
  146. }
  147. void PrsonaServer::epoch_part_two(Proof& pi, std::vector<EGCiphertext>& encryptedTallies)
  148. {
  149. // TOFIX
  150. Scalar inverseSeed = scalarN - currentSeed;
  151. for (size_t i = 0; i < currentPseudonyms.size(); i++)
  152. {
  153. currentPseudonyms[i] = currentPseudonyms[i] * inverseSeed;
  154. encryptedTallies[i].mask = encryptedTallies[i].mask * inverseSeed;
  155. }
  156. std::vector<size_t> shuffleOrder = order_data();
  157. rerandomize_vote_matrix();
  158. std::vector<EGCiphertext> reorderedTallies;
  159. for (size_t i = 0; i < shuffleOrder.size(); i++)
  160. reorderedTallies.push_back(encryptedTallies[shuffleOrder[i]]);
  161. encryptedTallies = reorderedTallies;
  162. pi = generate_proof_of_shuffle(shuffleOrder);
  163. currentSeed = nextSeed;
  164. }
  165. std::vector<size_t> PrsonaServer::order_data()
  166. {
  167. std::vector<size_t> retval;
  168. std::vector<SortingType> sortTracker;
  169. for (size_t i = 0; i < currentPseudonyms.size(); i++)
  170. {
  171. SortingType curr;
  172. curr.pseudonym = currentPseudonyms[i];
  173. curr.index = i;
  174. sortTracker.push_back(curr);
  175. }
  176. std::sort(sortTracker.begin(), sortTracker.end());
  177. std::vector<Curvepoint> newPseudonyms;
  178. std::vector<TwistBipoint> newVoteTallies;
  179. std::vector<std::vector<CurveBipoint>> newVoteMatrix;
  180. for (size_t i = 0; i < sortTracker.size(); i++)
  181. {
  182. newPseudonyms.push_back(sortTracker[i].pseudonym);
  183. newVoteTallies.push_back(previousVoteTally[sortTracker[i].index]);
  184. std::vector<CurveBipoint> currNewRow;
  185. for (size_t j = 0; j < currentPseudonyms.size(); j++)
  186. {
  187. currNewRow.push_back(voteMatrix[sortTracker[i].index][sortTracker[j].index]);
  188. }
  189. newVoteMatrix.push_back(currNewRow);
  190. retval.push_back(sortTracker[i].index);
  191. }
  192. currentPseudonyms = newPseudonyms;
  193. previousVoteTally = newVoteTallies;
  194. voteMatrix = newVoteMatrix;
  195. return retval;
  196. }
  197. void PrsonaServer::rerandomize_vote_matrix()
  198. {
  199. for (size_t i = 0; i < voteMatrix.size(); i++)
  200. {
  201. for (size_t j = 0; j < voteMatrix[0].size(); j++)
  202. {
  203. voteMatrix[i][j] = bgn_system.rerandomize(voteMatrix[i][j]);
  204. }
  205. }
  206. }
  207. size_t PrsonaServer::binary_search(const Curvepoint& index) const
  208. {
  209. size_t lo, hi;
  210. lo = 0;
  211. hi = currentPseudonyms.size() - 1;
  212. while (lo < hi)
  213. {
  214. size_t mid = (lo + hi) / 2;
  215. if (currentPseudonyms[mid] < index)
  216. lo = mid + 1;
  217. else if (index == currentPseudonyms[mid])
  218. return mid;
  219. else hi = mid - 1;
  220. }
  221. return lo;
  222. }
  223. bool PrsonaServer::verify_valid_key_proof(const Proof& pi, const Curvepoint& shortTermPublicKey) const
  224. {
  225. if (!malicious_client)
  226. return pi == "PROOF";
  227. return pi == "PROOF";
  228. }
  229. bool PrsonaServer::verify_vote_proof(const Proof& pi, const std::vector<CurveBipoint>& votes, const Curvepoint& shortTermPublicKey) const
  230. {
  231. if (!malicious_client)
  232. return pi == "PROOF";
  233. return pi == "PROOF";
  234. }
  235. bool PrsonaServer::verify_update_proof(const Proof& pi, const std::vector<TwistBipoint>& otherPreviousVoteTally, const std::vector<Curvepoint>& otherCurrentPseudonyms, const std::vector<std::vector<CurveBipoint>>& otherVoteMatrix) const
  236. {
  237. if (!malicious_server)
  238. return pi == "PROOF";
  239. return pi == "PROOF";
  240. }
  241. Proof PrsonaServer::generate_valid_fresh_generator_proof(const Proof& oldProof) const
  242. {
  243. if (!malicious_server)
  244. return "PROOF";
  245. return "PROOF";
  246. }
  247. Proof PrsonaServer::generate_votes_valid_proof(const std::vector<CurveBipoint>& votes, const Curvepoint& voter) const
  248. {
  249. if (!malicious_server)
  250. return "PROOF";
  251. return "PROOF";
  252. }
  253. Proof PrsonaServer::generate_proof_of_added_user(const Curvepoint& shortTermPublicKey) const
  254. {
  255. if (!malicious_server)
  256. return "PROOF";
  257. return "PROOF";
  258. }
  259. Proof PrsonaServer::generate_score_proof(const EGCiphertext& score) const
  260. {
  261. if (!malicious_server)
  262. return "PROOF";
  263. return "PROOF";
  264. }
  265. Proof PrsonaServer::generate_proof_of_correct_tally(const std::vector<Quadripoint>& BGNEncryptedTallies, const std::vector<Scalar>& decryptedTallies) const
  266. {
  267. if (!malicious_server)
  268. return "PROOF";
  269. return "PROOF";
  270. }
  271. Proof PrsonaServer::generate_proof_of_shuffle(const std::vector<size_t>& shuffle_order) const
  272. {
  273. if (!malicious_server)
  274. return "PROOF";
  275. return "PROOF";
  276. }