server.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  1. #include <iostream>
  2. #include "server.hpp"
  3. extern const curvepoint_fp_t bn_curvegen;
  4. extern const scalar_t bn_n;
  5. const int MAX_ALLOWED_VOTE = 2;
  6. /* These lines need to be here so these static variables are defined,
  7. * but in C++ putting code here doesn't actually execute
  8. * (or at least, with g++, whenever it would execute is not at a useful time)
  9. * so we have an init() function to actually put the correct values in them. */
  10. Curvepoint PrsonaServer::EL_GAMAL_GENERATOR = Curvepoint();
  11. Scalar PrsonaServer::SCALAR_N = Scalar();
  12. Scalar PrsonaServer::DEFAULT_TALLY = Scalar();
  13. Scalar PrsonaServer::DEFAULT_VOTE = Scalar();
  14. bool PrsonaServer::SERVER_IS_MALICIOUS = false;
  15. bool PrsonaServer::CLIENT_IS_MALICIOUS = false;
  16. /********************
  17. * PUBLIC FUNCTIONS *
  18. ********************/
  19. /*
  20. * CONSTRUCTORS
  21. */
  22. // Used to generate the first server; instantiates BGN for the first time
  23. PrsonaServer::PrsonaServer()
  24. {
  25. currentSeed.set_random();
  26. }
  27. // Used for all other servers, so they have the same BGN parameters
  28. PrsonaServer::PrsonaServer(const BGN& other_bgn)
  29. : bgn_system(other_bgn)
  30. {
  31. currentSeed.set_random();
  32. }
  33. /*
  34. * SETUP FUNCTIONS
  35. */
  36. // Must be called once before any usage of this class
  37. void PrsonaServer::init()
  38. {
  39. Scalar lambda;
  40. lambda.set_random();
  41. EL_GAMAL_GENERATOR = Curvepoint(bn_curvegen);
  42. SCALAR_N = Scalar(bn_n);
  43. DEFAULT_TALLY = Scalar(1);
  44. DEFAULT_VOTE = Scalar(1);
  45. }
  46. // Call this (once) if using malicious-security servers
  47. void PrsonaServer::set_server_malicious()
  48. {
  49. SERVER_IS_MALICIOUS = true;
  50. }
  51. // Call this (once) if using malicious-security clients
  52. void PrsonaServer::set_client_malicious()
  53. {
  54. CLIENT_IS_MALICIOUS = true;
  55. }
  56. /*
  57. * BASIC PUBLIC SYSTEM INFO GETTERS
  58. */
  59. Curvepoint PrsonaServer::get_blinding_generator() const
  60. {
  61. return elGamalBlindGenerator;
  62. }
  63. BGNPublicKey PrsonaServer::get_bgn_public_key() const
  64. {
  65. return bgn_system.get_public_key();
  66. }
  67. /*
  68. * FRESH GENERATOR CALCULATION
  69. */
  70. // To calculate the current epoch's generator, start from the base generator,
  71. // then have every server call this function on it iteratively (in any order).
  72. Curvepoint PrsonaServer::add_curr_seed_to_generator(
  73. const Curvepoint& currGenerator) const
  74. {
  75. return currGenerator * currentSeed;
  76. }
  77. // To calculate the next epoch's generator, start from the base generator,
  78. // then have every server call this function on it iteratively (in any order).
  79. Curvepoint PrsonaServer::add_next_seed_to_generator(
  80. const Curvepoint& currGenerator) const
  81. {
  82. return currGenerator * nextSeed;
  83. }
  84. /*
  85. * ENCRYPTED DATA GETTERS
  86. */
  87. /* Call this in order to get the current encrypted votes cast by a given user
  88. * (who is identified by their short term public key).
  89. * In practice, this is intended for clients,
  90. * who need to know their current votes in order to rerandomize them. */
  91. std::vector<CurveBipoint> PrsonaServer::get_current_votes_by(
  92. Proof& pi, const Curvepoint& shortTermPublicKey) const
  93. {
  94. std::vector<CurveBipoint> retval;
  95. size_t voteSubmitter = binary_search(shortTermPublicKey);
  96. retval = voteMatrix[voteSubmitter];
  97. pi = generate_votes_valid_proof(retval, shortTermPublicKey);
  98. return retval;
  99. }
  100. /* Call this in order to get the current encrypted tally of a given user
  101. * (who is identified by their short term public key).
  102. * In practice, this is intended for clients, so that the servers vouch
  103. * for their ciphertexts being valid as part of their reputation proofs. */
  104. EGCiphertext PrsonaServer::get_current_tally(
  105. Proof& pi, const Curvepoint& shortTermPublicKey) const
  106. {
  107. EGCiphertext retval;
  108. size_t tallyOwner = binary_search(shortTermPublicKey);
  109. retval = currentUserEncryptedTallies[tallyOwner];
  110. pi = currentTallyProofs[tallyOwner];
  111. return retval;
  112. }
  113. /*
  114. * CLIENT INTERACTIONS
  115. */
  116. /* Add a new client (who is identified only by their short term public key)
  117. * One server will do this, then ask all other servers to import their
  118. * (proven) exported data. */
  119. void PrsonaServer::add_new_client(
  120. const Proof& proofOfValidKey,
  121. Proof& proofOfValidAddition,
  122. const Curvepoint& shortTermPublicKey)
  123. {
  124. if (!verify_ownership_proof(proofOfValidKey, shortTermPublicKey))
  125. {
  126. std::cerr << "Could not verify proof of valid key." << std::endl;
  127. return;
  128. }
  129. currentPseudonyms.push_back(shortTermPublicKey);
  130. // The first epoch's score for a new user will be low,
  131. // but will typically converge on an average score quickly
  132. TwistBipoint encryptedDefaultTally;
  133. bgn_system.encrypt(encryptedDefaultTally, DEFAULT_TALLY);
  134. previousVoteTallies.push_back(encryptedDefaultTally);
  135. Scalar mask;
  136. mask.set_random();
  137. EGCiphertext newUserEncryptedTally;
  138. newUserEncryptedTally.mask = shortTermPublicKey * mask;
  139. newUserEncryptedTally.encryptedMessage =
  140. currentFreshGenerator * mask +
  141. get_blinding_generator() * DEFAULT_TALLY;
  142. currentUserEncryptedTallies.push_back(newUserEncryptedTally);
  143. currentTallyProofs.push_back(
  144. generate_valid_default_tally_proof(newUserEncryptedTally, mask));
  145. // Users are defaulted to casting a neutral vote for others.
  146. CurveBipoint encryptedDefaultVote, encryptedSelfVote;
  147. bgn_system.encrypt(encryptedDefaultVote, DEFAULT_VOTE);
  148. bgn_system.encrypt(encryptedSelfVote, Scalar(MAX_ALLOWED_VOTE));
  149. std::vector<CurveBipoint> newRow;
  150. for (size_t i = 0; i < voteMatrix.size(); i++)
  151. {
  152. encryptedDefaultVote = bgn_system.rerandomize(encryptedDefaultVote);
  153. voteMatrix[i].push_back(encryptedDefaultVote);
  154. encryptedDefaultVote = bgn_system.rerandomize(encryptedDefaultVote);
  155. newRow.push_back(encryptedDefaultVote);
  156. }
  157. // Because we are adding the new user to the end (and then sorting it),
  158. // this last element (bottom right corner) is always the self vote.
  159. newRow.push_back(encryptedSelfVote);
  160. voteMatrix.push_back(newRow);
  161. order_data(proofOfValidAddition);
  162. proofOfValidAddition = generate_proof_of_added_user(shortTermPublicKey);
  163. }
  164. // Receive a new vote row from a user (identified by short term public key).
  165. bool PrsonaServer::receive_vote(
  166. const std::vector<Proof>& pi,
  167. const std::vector<CurveBipoint>& newVotes,
  168. const Curvepoint& shortTermPublicKey)
  169. {
  170. size_t voteSubmitter = binary_search(shortTermPublicKey);
  171. std::vector<CurveBipoint> oldVotes = voteMatrix[voteSubmitter];
  172. if (!verify_vote_proof(pi, oldVotes, newVotes, shortTermPublicKey))
  173. {
  174. std::cerr << "Could not verify votes." << std::endl;
  175. return false;
  176. }
  177. voteMatrix[voteSubmitter] = newVotes;
  178. return true;
  179. }
  180. /*********************
  181. * PRIVATE FUNCTIONS *
  182. *********************/
  183. /*
  184. * CONSTRUCTOR HELPERS
  185. */
  186. const BGN& PrsonaServer::get_bgn_details() const
  187. {
  188. return bgn_system;
  189. }
  190. void PrsonaServer::initialize_fresh_generator(const Curvepoint& firstGenerator)
  191. {
  192. currentFreshGenerator = firstGenerator;
  193. }
  194. // To calculate the blind generator for ElGamal, start from the base generator,
  195. // then have every server call this function on it iteratively (in any order).
  196. Curvepoint PrsonaServer::add_rand_seed_to_generator(
  197. const Curvepoint& currGenerator) const
  198. {
  199. Scalar lambda;
  200. lambda.set_random();
  201. return currGenerator + EL_GAMAL_GENERATOR * lambda;
  202. }
  203. void PrsonaServer::set_EG_blind_generator(const Curvepoint& currGenerator)
  204. {
  205. elGamalBlindGenerator = currGenerator;
  206. }
  207. /*
  208. * SCORE TALLYING
  209. */
  210. /* Calculate scores homomorphically (as an individual server would normally)
  211. * and then decrypt them (which the servers would normally work together to do).
  212. *
  213. * Note that since these calculations are just for us, we don't need to do any
  214. * expensive rerandomizations of intermediate values. */
  215. std::vector<Scalar> PrsonaServer::tally_scores(std::vector<Proof>& tallyProofs)
  216. {
  217. std::vector<Quadripoint> BGNEncryptedTallies;
  218. std::vector<Scalar> decryptedTallies;
  219. for (size_t i = 0; i < voteMatrix.size(); i++)
  220. {
  221. std::vector<Quadripoint> weightedVotes;
  222. // ZIP
  223. for (size_t j = 0; j < previousVoteTallies.size(); j++)
  224. {
  225. Quadripoint curr =
  226. bgn_system.homomorphic_multiplication_no_rerandomize(
  227. voteMatrix[j][i], previousVoteTallies[j]);
  228. weightedVotes.push_back(curr);
  229. }
  230. // FOLDL
  231. Quadripoint currEncryptedTally = weightedVotes[0];
  232. for (size_t j = 1; j < weightedVotes.size(); j++)
  233. {
  234. currEncryptedTally =
  235. bgn_system.homomorphic_addition_no_rerandomize(
  236. currEncryptedTally, weightedVotes[j]);
  237. }
  238. // DECRYPT
  239. decryptedTallies.push_back(bgn_system.decrypt(currEncryptedTally));
  240. tallyProofs.push_back(
  241. generate_proof_of_correct_tally(
  242. currEncryptedTally, decryptedTallies[i]));
  243. }
  244. return decryptedTallies;
  245. }
  246. /* Calculate what the maximum possible score this round was (that is,
  247. * given the current user weights, what was the highest possible score?).
  248. *
  249. * As with individual scores, this also does the decryption that servers
  250. * would ordinarily work together to form. */
  251. Scalar PrsonaServer::get_max_possible_score(Proof& pi)
  252. {
  253. // FOLDL
  254. TwistBipoint currEncryptedVal = previousVoteTallies[0];
  255. for (size_t i = 1; i < previousVoteTallies.size(); i++)
  256. {
  257. currEncryptedVal =
  258. bgn_system.homomorphic_addition_no_rerandomize(
  259. currEncryptedVal, previousVoteTallies[i]);
  260. }
  261. // DECRYPT
  262. Scalar retval = bgn_system.decrypt(currEncryptedVal);
  263. pi = generate_proof_of_correct_sum(currEncryptedVal, retval);
  264. return retval;
  265. }
  266. /*
  267. * EPOCH ROUNDS
  268. */
  269. // The first round, going from A_0 to A_0.5
  270. void PrsonaServer::build_up_midway_pseudonyms(
  271. Proof& pi, Curvepoint& nextGenerator)
  272. {
  273. nextSeed.set_random();
  274. nextGenerator = nextGenerator * nextSeed;
  275. currentUserEncryptedTallies.clear();
  276. currentTallyProofs.clear();
  277. for (size_t i = 0; i < currentPseudonyms.size(); i++)
  278. currentPseudonyms[i] = currentPseudonyms[i] * nextSeed;
  279. rerandomize_data();
  280. order_data(pi);
  281. }
  282. // In between these rounds, scores are tallied, decrypted,
  283. // and encrypted to fresh user pseudonyms (possible through weird math)
  284. // The second round, going from A_0.5 to A_1
  285. void PrsonaServer::break_down_midway_pseudonyms(
  286. Proof& pi, const Curvepoint& nextGenerator)
  287. {
  288. Scalar inverseSeed = currentSeed.curveInverse();
  289. for (size_t i = 0; i < currentPseudonyms.size(); i++)
  290. {
  291. currentPseudonyms[i] = currentPseudonyms[i] * inverseSeed;
  292. currentUserEncryptedTallies[i].mask =
  293. currentUserEncryptedTallies[i].mask * inverseSeed;
  294. }
  295. currentSeed = nextSeed;
  296. currentFreshGenerator = nextGenerator;
  297. rerandomize_data();
  298. order_data(pi);
  299. }
  300. /*
  301. * DATA MAINTENANCE
  302. */
  303. void PrsonaServer::import_updates(
  304. const Proof& pi,
  305. const std::vector<TwistBipoint>& otherPreviousVoteTallies,
  306. const std::vector<Curvepoint>& otherCurrentPseudonyms,
  307. const std::vector<EGCiphertext>& otherCurrentUserEncryptedTallies,
  308. const std::vector<Proof>& otherCurrentTallyProofs,
  309. const std::vector<std::vector<CurveBipoint>>& otherVoteMatrix)
  310. {
  311. if (!verify_update_proof(pi))
  312. {
  313. std::cerr << "Could not verify valid update." << std::endl;
  314. return;
  315. }
  316. previousVoteTallies = otherPreviousVoteTallies;
  317. currentPseudonyms = otherCurrentPseudonyms;
  318. currentUserEncryptedTallies = otherCurrentUserEncryptedTallies;
  319. currentTallyProofs = otherCurrentTallyProofs;
  320. voteMatrix = otherVoteMatrix;
  321. }
  322. void PrsonaServer::export_updates(
  323. std::vector<TwistBipoint>& otherPreviousVoteTallies,
  324. std::vector<Curvepoint>& otherCurrentPseudonyms,
  325. std::vector<EGCiphertext>& otherCurrentUserEncryptedTallies,
  326. std::vector<Proof>& otherCurrentTallyProofs,
  327. std::vector<std::vector<CurveBipoint>>& otherVoteMatrix) const
  328. {
  329. otherPreviousVoteTallies = previousVoteTallies;
  330. otherCurrentPseudonyms = currentPseudonyms;
  331. otherCurrentUserEncryptedTallies = currentUserEncryptedTallies;
  332. otherCurrentTallyProofs = currentTallyProofs;
  333. otherVoteMatrix = voteMatrix;
  334. }
  335. /*
  336. * DATA SAFEKEEPING
  337. */
  338. // Everything needs to be rerandomized during epoch rounds
  339. // NOTE: this may need to add something about proofs later?
  340. void PrsonaServer::rerandomize_data()
  341. {
  342. for (size_t i = 0; i < voteMatrix.size(); i++)
  343. {
  344. for (size_t j = 0; j < voteMatrix[0].size(); j++)
  345. voteMatrix[i][j] = bgn_system.rerandomize(voteMatrix[i][j]);
  346. bgn_system.rerandomize(previousVoteTallies[i]);
  347. if (!currentUserEncryptedTallies.empty())
  348. {
  349. Scalar rerandomizer;
  350. rerandomizer.set_random();
  351. currentUserEncryptedTallies[i].mask =
  352. currentUserEncryptedTallies[i].mask +
  353. currentPseudonyms[i] * rerandomizer;
  354. currentUserEncryptedTallies[i].encryptedMessage =
  355. currentUserEncryptedTallies[i].encryptedMessage +
  356. currentFreshGenerator * rerandomizer;
  357. }
  358. }
  359. }
  360. /* This is what powers the "shuffle"; really, as pseudonyms get updated,
  361. * the pseudonyms are no longer in the order prescribed by operator<().
  362. * So, we put them (and everything else) back into that order,
  363. * effectively shuffling them (and making lookups easier later on). */
  364. std::vector<size_t> PrsonaServer::order_data(Proof& pi)
  365. {
  366. std::vector<size_t> retval;
  367. // SortingType's index member allows us to replicate the "sort" across
  368. std::vector<SortingType> sortTracker;
  369. for (size_t i = 0; i < currentPseudonyms.size(); i++)
  370. {
  371. SortingType curr;
  372. curr.pseudonym = currentPseudonyms[i];
  373. curr.index = i;
  374. sortTracker.push_back(curr);
  375. }
  376. std::sort(sortTracker.begin(), sortTracker.end());
  377. // Order all other data in the same way, for consistency
  378. std::vector<Curvepoint> newPseudonyms;
  379. std::vector<TwistBipoint> newVoteTallies;
  380. std::vector<EGCiphertext> newUserEncryptedTallies;
  381. std::vector<Proof> newTallyProofs;
  382. std::vector<std::vector<CurveBipoint>> newVoteMatrix;
  383. for (size_t i = 0; i < sortTracker.size(); i++)
  384. {
  385. newPseudonyms.push_back(sortTracker[i].pseudonym);
  386. newVoteTallies.push_back(previousVoteTallies[sortTracker[i].index]);
  387. if (!currentUserEncryptedTallies.empty())
  388. {
  389. newUserEncryptedTallies.push_back(
  390. currentUserEncryptedTallies[sortTracker[i].index]);
  391. }
  392. if (!currentTallyProofs.empty())
  393. {
  394. newTallyProofs.push_back(
  395. currentTallyProofs[sortTracker[i].index]);
  396. }
  397. std::vector<CurveBipoint> currNewRow;
  398. for (size_t j = 0; j < currentPseudonyms.size(); j++)
  399. {
  400. currNewRow.push_back(
  401. voteMatrix[sortTracker[i].index][sortTracker[j].index]);
  402. }
  403. newVoteMatrix.push_back(currNewRow);
  404. retval.push_back(sortTracker[i].index);
  405. }
  406. previousVoteTallies = newVoteTallies;
  407. currentPseudonyms = newPseudonyms;
  408. currentUserEncryptedTallies = newUserEncryptedTallies;
  409. currentTallyProofs = newTallyProofs;
  410. voteMatrix = newVoteMatrix;
  411. pi = generate_proof_of_shuffle(retval);
  412. return retval;
  413. }
  414. /*
  415. * BINARY SEARCH
  416. */
  417. /* Completely normal binary search
  418. * There might be a standard function for this in <algorithms>?
  419. * But it returns an iterator, not a size_t, so less useful. */
  420. size_t PrsonaServer::binary_search(const Curvepoint& index) const
  421. {
  422. size_t lo, hi;
  423. lo = 0;
  424. hi = currentPseudonyms.size() - 1;
  425. while (lo < hi)
  426. {
  427. size_t mid = (lo + hi) / 2;
  428. if (currentPseudonyms[mid] < index)
  429. lo = mid + 1;
  430. else if (index == currentPseudonyms[mid])
  431. return mid;
  432. else hi = mid - 1;
  433. }
  434. return lo;
  435. }
  436. /*
  437. * PROOF VERIFICATION
  438. */
  439. bool PrsonaServer::verify_ownership_proof(
  440. const Proof& pi,
  441. const Curvepoint& shortTermPublicKey) const
  442. {
  443. if (!CLIENT_IS_MALICIOUS)
  444. return pi.basic == "PROOF";
  445. Scalar c = pi.challengeParts[0];
  446. Scalar z = pi.responseParts[0];
  447. Curvepoint u = currentFreshGenerator * z - shortTermPublicKey * c;
  448. std::stringstream oracleInput;
  449. oracleInput << currentFreshGenerator << shortTermPublicKey << u;
  450. return c == oracle(oracleInput.str());
  451. }
  452. bool PrsonaServer::verify_vote_proof(
  453. const std::vector<Proof>& pi,
  454. const std::vector<CurveBipoint>& oldVotes,
  455. const std::vector<CurveBipoint>& newVotes,
  456. const Curvepoint& shortTermPublicKey) const
  457. {
  458. // Reject outright if there's no proof to check
  459. if (pi.empty())
  460. {
  461. std::cerr << "Proof was empty, aborting." << std::endl;
  462. return false;
  463. }
  464. // Base case
  465. if (!CLIENT_IS_MALICIOUS)
  466. return pi[0].basic == "PROOF";
  467. // User should be able to prove they are who they say they are
  468. if (!verify_ownership_proof(pi[0], shortTermPublicKey))
  469. {
  470. std::cerr << "Schnorr proof failed, aborting." << std::endl;
  471. return false;
  472. }
  473. /* This proof structure is documented in my notes.
  474. * It's inspired by the proof in Fig. 1 at
  475. * https://eprint.iacr.org/2014/764.pdf, but adapted so that you prove
  476. * m(m-1)(m-2) = 0 instead of m(m-1) = 0.
  477. *
  478. * The rerandomization part is just a slight variation on an
  479. * ordinary Schnorr proof, so that part's less scary. */
  480. for (size_t i = 1; i < pi.size(); i++)
  481. {
  482. size_t voteIndex = i - 1;
  483. Curvepoint C_c_0, C_c_1;
  484. C_c_0 = pi[i].partialUniversals[0];
  485. C_c_1 = pi[i].partialUniversals[1];
  486. CurveBipoint g, h;
  487. g = bgn_system.get_public_key().get_bipoint_curvegen();
  488. h = bgn_system.get_public_key().get_bipoint_curve_subgroup_gen();
  489. CurveBipoint C_c(C_c_0, C_c_1);
  490. Scalar c_r, c_n, z_r, f_1, f_2, z_na, z_nb, z_nc;
  491. c_r = pi[i].challengeParts[0];
  492. c_n = pi[i].challengeParts[1];
  493. z_r = pi[i].responseParts[0];
  494. f_1 = pi[i].responseParts[1];
  495. f_2 = pi[i].responseParts[2];
  496. z_na = pi[i].responseParts[3];
  497. z_nb = pi[i].responseParts[4];
  498. z_nc = pi[i].responseParts[5];
  499. CurveBipoint U, C_a, C_b, C_d;
  500. U = h * z_r + oldVotes[voteIndex] * c_r - newVotes[voteIndex] * c_r;
  501. C_a = g * f_1 + h * z_na - newVotes[voteIndex] * c_n;
  502. C_b = g * f_2 + h * z_nb - newVotes[voteIndex] * c_n;
  503. Scalar f_1_c_n = f_1.curveSub(c_n);
  504. Scalar c_n_f_2 = c_n.curveAdd(c_n).curveSub(f_2);
  505. C_d = h * z_nc - newVotes[voteIndex] * f_1_c_n.curveMult(c_n_f_2) - C_c * c_n;
  506. std::stringstream oracleInput;
  507. oracleInput << g << h << oldVotes[voteIndex] << newVotes[voteIndex]
  508. << U << C_a << C_b << C_c << C_d;
  509. if (oracle(oracleInput.str()) != c_r.curveAdd(c_n))
  510. {
  511. std::cerr << "Valid vote proof failed at index " << i << " of " << pi.size() - 1 << ", aborting." << std::endl;
  512. return false;
  513. }
  514. }
  515. return true;
  516. }
  517. bool PrsonaServer::verify_update_proof(
  518. const Proof& pi) const
  519. {
  520. if (!SERVER_IS_MALICIOUS)
  521. return pi.basic == "PROOF";
  522. return pi.basic == "PROOF";
  523. }
  524. /*
  525. * PROOF GENERATION
  526. */
  527. Proof PrsonaServer::generate_valid_default_tally_proof(
  528. const EGCiphertext& newUserEncryptedTally, const Scalar& mask) const
  529. {
  530. Proof retval;
  531. if (!SERVER_IS_MALICIOUS)
  532. {
  533. retval.basic = "PROOF";
  534. return retval;
  535. }
  536. retval.basic = "PROOF";
  537. return retval;
  538. }
  539. Proof PrsonaServer::generate_valid_fresh_generator_proof(
  540. const Proof& oldProof) const
  541. {
  542. Proof retval;
  543. if (!SERVER_IS_MALICIOUS)
  544. {
  545. retval.basic = "PROOF";
  546. return retval;
  547. }
  548. retval.basic = "PROOF";
  549. return retval;
  550. }
  551. Proof PrsonaServer::generate_votes_valid_proof(
  552. const std::vector<CurveBipoint>& votes, const Curvepoint& voter) const
  553. {
  554. Proof retval;
  555. if (!SERVER_IS_MALICIOUS)
  556. {
  557. retval.basic = "PROOF";
  558. return retval;
  559. }
  560. retval.basic = "PROOF";
  561. return retval;
  562. }
  563. Proof PrsonaServer::generate_proof_of_added_user(
  564. const Curvepoint& shortTermPublicKey) const
  565. {
  566. Proof retval;
  567. if (!SERVER_IS_MALICIOUS)
  568. {
  569. retval.basic = "PROOF";
  570. return retval;
  571. }
  572. retval.basic = "PROOF";
  573. return retval;
  574. }
  575. Proof PrsonaServer::generate_score_proof(const EGCiphertext& score) const
  576. {
  577. Proof retval;
  578. if (!SERVER_IS_MALICIOUS)
  579. {
  580. retval.basic = "PROOF";
  581. return retval;
  582. }
  583. retval.basic = "PROOF";
  584. return retval;
  585. }
  586. Proof PrsonaServer::generate_proof_of_correct_tally(
  587. const Quadripoint& BGNEncryptedTally,
  588. const Scalar& decryptedTally) const
  589. {
  590. Proof retval;
  591. if (!SERVER_IS_MALICIOUS)
  592. {
  593. retval.basic = "PROOF";
  594. return retval;
  595. }
  596. retval.basic = "PROOF";
  597. return retval;
  598. }
  599. Proof PrsonaServer::generate_proof_of_correct_sum(
  600. const TwistBipoint& BGNEncryptedSum, const Scalar& decryptedSum) const
  601. {
  602. Proof retval;
  603. if (!SERVER_IS_MALICIOUS)
  604. {
  605. retval.basic = "PROOF";
  606. return retval;
  607. }
  608. retval.basic = "PROOF";
  609. return retval;
  610. }
  611. Proof PrsonaServer::generate_proof_of_shuffle(
  612. const std::vector<size_t>& shuffle_order) const
  613. {
  614. Proof retval;
  615. if (!SERVER_IS_MALICIOUS)
  616. {
  617. retval.basic = "PROOF";
  618. return retval;
  619. }
  620. retval.basic = "PROOF";
  621. return retval;
  622. }