networkServer.cpp 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656
  1. #include <iostream>
  2. #include <sstream>
  3. #include <cstring>
  4. #include <cstdio>
  5. #include "networkServer.hpp"
  6. void obtain_update_locks(
  7. std::unique_lock<std::mutex> &lck,
  8. const std::vector<std::string>& serverIPs,
  9. const std::string& selfIP,
  10. struct synchronization_tool *sync)
  11. {
  12. size_t i = 0;
  13. while (i < serverIPs.size())
  14. {
  15. if (serverIPs[i] == selfIP)
  16. {
  17. lck.lock();
  18. i++;
  19. continue;
  20. }
  21. struct mg_connection *conn =
  22. mg_connect_websocket_client(
  23. serverIPs[i].c_str(),
  24. PRSONA_PORT,
  25. USE_SSL,
  26. NULL,
  27. 0,
  28. UPDATE_LOCK_URI,
  29. "null",
  30. synchro_websocket_data_handler,
  31. synchro_websocket_close_handler,
  32. (void *) sync);
  33. if (!conn)
  34. {
  35. std::cerr << "Couldn't get server " << i << "'s lock" << std::endl;
  36. continue;
  37. }
  38. unique_lock<mutex> lck(sync->mtx);
  39. sync->val = 0;
  40. sync->val2 = 0;
  41. mg_websocket_client_write(
  42. conn,
  43. MG_WEBSOCKET_OPCODE_DATACOMPLETE,
  44. "",
  45. 0);
  46. while (!sync->val2)
  47. sync->cv.wait(lck);
  48. mg_close_connection(conn);
  49. if (sync->val)
  50. i++;
  51. }
  52. }
  53. void release_update_locks(
  54. std::unique_lock<std::mutex> &lck,
  55. const std::vector<std::string>& serverIPs,
  56. const std::string& selfIP,
  57. struct synchronization_tool *sync)
  58. {
  59. ssize_t i = serverIPs.size() - 1;
  60. while (i >= 0)
  61. {
  62. if (serverIPs[i] == selfIP)
  63. {
  64. lck.unlock();
  65. i--;
  66. continue;
  67. }
  68. struct mg_connection *conn =
  69. mg_connect_websocket_client(
  70. serverIPs[i].c_str(),
  71. PRSONA_PORT,
  72. USE_SSL,
  73. NULL,
  74. 0,
  75. UPDATE_UNLOCK_URI,
  76. "null",
  77. synchro_websocket_data_handler,
  78. synchro_websocket_close_handler,
  79. (void *) sync);
  80. if (!conn)
  81. {
  82. std::cerr << "Couldn't get server " << i << "'s lock" << std::endl;
  83. continue;
  84. }
  85. unique_lock<mutex> lck(sync->mtx);
  86. sync->val = 0;
  87. sync->val2 = 0;
  88. mg_websocket_client_write(
  89. conn,
  90. MG_WEBSOCKET_OPCODE_DATACOMPLETE,
  91. "",
  92. 0);
  93. while (!sync->val2)
  94. sync->cv.wait(lck);
  95. mg_close_connection(conn);
  96. if (sync->val)
  97. i--;
  98. }
  99. }
  100. std::string make_epoch_initiator_string(
  101. const std::vector<Proof>& generatorProof,
  102. const Twistpoint& nextGenerator)
  103. {
  104. std::stringstream buffer;
  105. BinarySizeT sizeOfVector(generatorProof.size());
  106. buffer << sizeOfVector;
  107. for (size_t i = 0; i < sizeOfVector.val(); i++)
  108. buffer << generatorProof[i];
  109. buffer << nextGenerator;
  110. return buffer.str();
  111. }
  112. void read_epoch_initiator_string(
  113. const char *filename,
  114. std::vector<Proof>& generatorProof,
  115. Twistpoint& nextGenerator)
  116. {
  117. ifstream file(filename);
  118. BinarySizeT sizeOfVector;
  119. generatorProof.clear();
  120. file >> sizeOfVector;
  121. for (size_t i = 0; i < sizeOfVector.val(); i++)
  122. {
  123. Proof currProof;
  124. file >> currProof;
  125. generatorProof.push_back;
  126. }
  127. file >> nextGenerator;
  128. }
  129. std::string make_epoch_update_string(
  130. const std::vector<std::vector<Proof>>& pi,
  131. const std::vector<std::vector<Twistpoint>>& permutationCommits,
  132. const std::vector<std::vector<Twistpoint>>& freshPseudonymCommits,
  133. const std::vector<std::vector<Twistpoint>>& freshPseudonymSeedCommits,
  134. const std::vector<std::vector<CurveBipoint>>& serverTallyCommits,
  135. const std::vector<std::vector<std::vector<TwistBipoint>>>& partwayVoteMatrixCommits,
  136. const std::vector<std::vector<std::vector<TwistBipoint>>>& finalVoteMatrixCommits,
  137. const std::vector<std::vector<Twistpoint>>& userTallyMaskCommits,
  138. const std::vector<std::vector<Twistpoint>>& userTallyMessageCommits,
  139. const std::vector<std::vector<Twistpoint>>& userTallySeedCommits,
  140. const Twistpoint& nextGenerator,
  141. bool doUserTallies)
  142. {
  143. std::stringstream buffer;
  144. BinarySizeT sizeOfVectorI, sizeOfVectorJ;
  145. sizeOfVectorI.set(pi.size());
  146. buffer << sizeOfVectorI;
  147. for (size_t i = 0; i < sizeOfVectorI.val(); i++)
  148. {
  149. sizeOfVectorJ.set(pi[i].size());
  150. buffer << sizeOfVectorJ;
  151. for (size_t j = 0; j < sizeOfVectorJ.val(); j++)
  152. buffer << pi[i][j];
  153. }
  154. sizeOfVectorI.set(permutationCommits.size());
  155. buffer << sizeOfVectorI;
  156. for (size_t i = 0; i < sizeOfVectorI.val(); i++)
  157. for (size_t j = 0; j < sizeOfVectorI.val(); j++)
  158. buffer << permutationCommits[i][j];
  159. sizeOfVectorI.set(freshPseudonymCommits.size());
  160. buffer << sizeOfVectorI;
  161. for (size_t i = 0; i < sizeOfVectorI.val(); i++)
  162. for (size_t j = 0; j < sizeOfVectorI.val(); j++)
  163. buffer << freshPseudonymCommits[i][j];
  164. sizeOfVectorI.set(freshPseudonymSeedCommits.size());
  165. buffer << sizeOfVectorI;
  166. for (size_t i = 0; i < sizeOfVectorI.val(); i++)
  167. for (size_t j = 0; j < sizeOfVectorI.val(); j++)
  168. buffer << freshPseudonymSeedCommits[i][j];
  169. sizeOfVectorI.set(serverTallyCommits.size());
  170. buffer << sizeOfVectorI;
  171. for (size_t i = 0; i < sizeOfVectorI.val(); i++)
  172. for (size_t j = 0; j < sizeOfVectorI.val(); j++)
  173. buffer << serverTallyCommits[i][j];
  174. sizeOfVectorI.set(partwayVoteMatrixCommits.size());
  175. buffer << sizeOfVectorI;
  176. for (size_t i = 0; i < sizeOfVectorI.val(); i++)
  177. for (size_t j = 0; j < sizeOfVectorI.val(); j++)
  178. for (size_t k = 0; k < sizeOfVectorI.val(); k++)
  179. buffer << partwayVoteMatrixCommits[i][j][k];
  180. sizeOfVectorI.set(finalVoteMatrixCommits.size());
  181. buffer << sizeOfVectorI;
  182. for (size_t i = 0; i < sizeOfVectorI.val(); i++)
  183. for (size_t j = 0; j < sizeOfVectorI.val(); j++)
  184. for (size_t k = 0; k < sizeOfVectorI.val(); k++)
  185. buffer << finalVoteMatrixCommits[i][j][k];
  186. sizeOfVectorI.set(userTallyMaskCommits.size());
  187. buffer << sizeOfVectorI;
  188. for (size_t i = 0; i < sizeOfVectorI.val(); i++)
  189. for (size_t j = 0; j < sizeOfVectorI.val(); j++)
  190. buffer << userTallyMaskCommits[i][j];
  191. sizeOfVectorI.set(userTallyMessageCommits.size());
  192. buffer << sizeOfVectorI;
  193. for (size_t i = 0; i < sizeOfVectorI.val(); i++)
  194. for (size_t j = 0; j < sizeOfVectorI.val(); j++)
  195. buffer << userTallyMessageCommits[i][j];
  196. sizeOfVectorI.set(userTallySeedCommits.size());
  197. buffer << sizeOfVectorI;
  198. for (size_t i = 0; i < sizeOfVectorI.val(); i++)
  199. for (size_t j = 0; j < sizeOfVectorI.val(); j++)
  200. buffer << userTallySeedCommits[i][j];
  201. buffer << nextGenerator;
  202. BinaryBool flag(doUserTallies);
  203. buffer << flag;
  204. return buffer.str();
  205. }
  206. bool read_epoch_update_string(
  207. const char *filename,
  208. std::vector<std::vector<Proof>>& pi,
  209. std::vector<std::vector<Twistpoint>>& permutationCommits,
  210. std::vector<std::vector<Twistpoint>>& freshPseudonymCommits,
  211. std::vector<std::vector<Twistpoint>>& freshPseudonymSeedCommits,
  212. std::vector<std::vector<CurveBipoint>>& serverTallyCommits,
  213. std::vector<std::vector<std::vector<TwistBipoint>>>& partwayVoteMatrixCommits,
  214. std::vector<std::vector<std::vector<TwistBipoint>>>& finalVoteMatrixCommits,
  215. std::vector<std::vector<Twistpoint>>& userTallyMaskCommits,
  216. std::vector<std::vector<Twistpoint>>& userTallyMessageCommits,
  217. std::vector<std::vector<Twistpoint>>& userTallySeedCommits,
  218. Twistpoint& nextGenerator)
  219. {
  220. ifstream file(filename);
  221. BinarySizeT sizeOfVectorI, sizeOfVectorJ;
  222. pi.clear();
  223. permutationCommits.clear();
  224. freshPseudonymCommits.clear();
  225. freshPseudonymSeedCommits.clear();
  226. serverTallyCommits.clear();
  227. partwayVoteMatrixCommits.clear();
  228. finalVoteMatrixCommits.clear();
  229. userTallyMaskCommits.clear();
  230. userTallyMessageCommits.clear();
  231. userTallySeedCommits.clear();
  232. file >> sizeOfVectorI;
  233. for (size_t i = 0; i < sizeOfVectorI.val(); i++)
  234. {
  235. std::vector<Proof> currRow;
  236. file >> sizeOfVectorJ;
  237. for (size_t j = 0; j < sizeOfVectorJ.val(); j++)
  238. {
  239. Proof currProof;
  240. file >> currProof;
  241. currRow.push_back(currProof);
  242. }
  243. pi.push_back(currRow);
  244. }
  245. file >> sizeOfVectorI;
  246. for (size_t i = 0; i < sizeOfVectorI.val(); i++)
  247. {
  248. std::vector<Twistpoint> currRow;
  249. for (size_t j = 0; j < sizeOfVectorI.val(); j++)
  250. {
  251. Twistpoint currCommit;
  252. file >> currCommit;
  253. currRow.push_back(currCommit);
  254. }
  255. permutationCommits.push_back(currRow);
  256. }
  257. file >> sizeOfVectorI;
  258. for (size_t i = 0; i < sizeOfVectorI.val(); i++)
  259. {
  260. std::vector<Twistpoint> currRow;
  261. for (size_t j = 0; j < sizeOfVectorI.val(); j++)
  262. {
  263. Twistpoint currCommit;
  264. file >> currCommit;
  265. currRow.push_back(currCommit);
  266. }
  267. freshPseudonymCommits.push_back(currRow);
  268. }
  269. file >> sizeOfVectorI;
  270. for (size_t i = 0; i < sizeOfVectorI.val(); i++)
  271. {
  272. std::vector<Twistpoint> currRow;
  273. for (size_t j = 0; j < sizeOfVectorI.val(); j++)
  274. {
  275. Twistpoint currCommit;
  276. file >> currCommit;
  277. currRow.push_back(currCommit);
  278. }
  279. freshPseudonymSeedCommits.push_back(currRow);
  280. }
  281. file >> sizeOfVectorI;
  282. for (size_t i = 0; i < sizeOfVectorI.val(); i++)
  283. {
  284. std::vector<CurveBipoint> currRow;
  285. for (size_t j = 0; j < sizeOfVectorI.val(); j++)
  286. {
  287. CurveBipoint currCommit;
  288. file >> currCommit;
  289. currRow.push_back(currCommit);
  290. }
  291. serverTallyCommits.push_back(currRow);
  292. }
  293. file >> sizeOfVectorI;
  294. for (size_t i = 0; i < sizeOfVectorI.val(); i++)
  295. {
  296. std::vector<std::vector<TwistBipoint>> currMatrix;
  297. for (size_t j = 0; j < sizeOfVectorI.val(); j++)
  298. {
  299. std::vector<TwistBipoint> currRow;
  300. for (size_t k = 0; k < sizeOfVectorI.val(); k++)
  301. {
  302. TwistBipoint currCommit;
  303. file >> currCommit;
  304. currRow.push_back(currCommit);
  305. }
  306. currMatrix.push_back(currRow);
  307. }
  308. partwayVoteMatrixCommits.push_back(currMatrix);
  309. }
  310. file >> sizeOfVectorI;
  311. for (size_t i = 0; i < sizeOfVectorI.val(); i++)
  312. {
  313. std::vector<std::vector<TwistBipoint>> currMatrix;
  314. for (size_t j = 0; j < sizeOfVectorI.val(); j++)
  315. {
  316. std::vector<TwistBipoint> currRow;
  317. for (size_t k = 0; k < sizeOfVectorI.val(); k++)
  318. {
  319. TwistBipoint currCommit;
  320. file >> currCommit;
  321. currRow.push_back(currCommit);
  322. }
  323. currMatrix.push_back(currRow);
  324. }
  325. finalVoteMatrixCommits.push_back(currMatrix);
  326. }
  327. file >> sizeOfVectorI;
  328. for (size_t i = 0; i < sizeOfVectorI.val(); i++)
  329. {
  330. std::vector<Twistpoint> currRow;
  331. for (size_t j = 0; j < sizeOfVectorI.val(); j++)
  332. {
  333. Twistpoint currCommit;
  334. file >> currCommit;
  335. currRow.push_back(currCommit);
  336. }
  337. userTallyMaskCommits.push_back(currRow);
  338. }
  339. file >> sizeOfVectorI;
  340. for (size_t i = 0; i < sizeOfVectorI.val(); i++)
  341. {
  342. std::vector<Twistpoint> currRow;
  343. for (size_t j = 0; j < sizeOfVectorI.val(); j++)
  344. {
  345. Twistpoint currCommit;
  346. file >> currCommit;
  347. currRow.push_back(currCommit);
  348. }
  349. userTallyMessageCommits.push_back(currRow);
  350. }
  351. file >> sizeOfVectorI;
  352. for (size_t i = 0; i < sizeOfVectorI.val(); i++)
  353. {
  354. std::vector<Twistpoint> currRow;
  355. for (size_t j = 0; j < sizeOfVectorI.val(); j++)
  356. {
  357. Twistpoint currCommit;
  358. file >> currCommit;
  359. currRow.push_back(currCommit);
  360. }
  361. userTallySeedCommits.push_back(currRow);
  362. }
  363. file >> nextGenerator;
  364. BinaryBool doUserTallies;
  365. file >> doUserTallies;
  366. return doUserTallies.val();
  367. }
  368. void distribute_epoch_updates(
  369. const std::string& recipient,
  370. const std::string& data,
  371. const struct synchronization_tool* sync)
  372. {
  373. bool flag = false;
  374. while (!flag)
  375. {
  376. struct mg_connection *conn =
  377. mg_connect_websocket_client(
  378. serverIPs[i].c_str(),
  379. PRSONA_PORT,
  380. USE_SSL,
  381. NULL,
  382. 0,
  383. ACCEPT_EPOCH_UPDATES_URI,
  384. "null",
  385. synchro_websocket_data_handler,
  386. empty_websocket_close_handler,
  387. (void *) sync);
  388. if (!conn)
  389. {
  390. std::cerr << "Trouble giving epoch updates to server at " << recipient << std::endl;
  391. continue;
  392. }
  393. mg_websocket_client_write(
  394. conn,
  395. MG_WEBSOCKET_OPCODE_BINARY,
  396. data.c_str(),
  397. data.length());
  398. mg_websocket_client_write(
  399. conn,
  400. MG_WEBSOCKET_OPCODE_DATACOMPLETE,
  401. "",
  402. 0);
  403. mg_close_connection(conn);
  404. flag = true;
  405. }
  406. }
  407. /*
  408. * CONSTRUCTORS
  409. */
  410. PrsonaServerWebSocketHandler::PrsonaServerWebSocketHandler(
  411. const PrsonaServer *prsonaServer,
  412. const std::mutex *updateMtx,
  413. const std::atomic<size_t> *epochNum,
  414. const std::vector<std::string> &serverIPs,
  415. const std::string &selfIP)
  416. : prsonaServer(prsonaServer), updateMtx(updateMtx), epochNum(epochNum),
  417. serverIPs(serverIPs), selfIP(selfIP)
  418. { /* */ }
  419. virtual bool PrsonaServerWebSocketHandler::handleConnection(
  420. CivetServer *server,
  421. const struct mg_connection *conn)
  422. {
  423. const struct mg_request_info *info = mg_get_request_info(conn);
  424. bool flag = info->query_string && info->query_string[0] >= PRSONA_ADD_CLIENT && info->query_string[0] <= PRSONA_RECEIVE_PARTIAL_DECRYPTION;
  425. flag = flag || (info->query_string && info->query_string[0] == PRSONA_GET_FRESH_GENERATOR);
  426. flag = flag || (info->query_string && info->query_string[0] == PRSONA_GET_EG_BLIND_GENERATOR);
  427. return flag;
  428. }
  429. virtual void PrsonaServerWebSocketHandler::handleReadyState(
  430. CivetServer *server,
  431. struct mg_connection *conn)
  432. {
  433. const struct mg_request_info *info = mg_get_request_info(conn);
  434. switch (info->query_string[0])
  435. {
  436. case PRSONA_ADD_CLIENT:
  437. case PRSONA_RECEIVE_VOTE:
  438. case PRSONA_GET_VOTES_BY:
  439. case PRSONA_GET_USER_TALLY:
  440. case PRSONA_GET_SERVER_TALLY:
  441. case PRSONA_GET_VOTE_ROW_COMMITMENT:
  442. case PRSONA_GET_USER_TALLY_COMMITMENT:
  443. case PRSONA_GET_SERVER_TALLY_COMMITMENT:
  444. case PRSONA_ADD_CURR_SEED_TO_GENERATOR:
  445. case PRSONA_SET_FRESH_GENERATOR:
  446. case PRSONA_ADD_RAND_SEED_TO_GENERATOR:
  447. case PRSONA_SET_EG_BLIND_GENERATOR:
  448. case PRSONA_EPOCH_UPDATE:
  449. case PRSONA_NEW_USER_UPDATE:
  450. case PRSONA_RECEIVE_PARTIAL_DECRYPTION:
  451. set_temp_filename(conn);
  452. break;
  453. default:
  454. mg_set_user_connection_data(conn, NULL);
  455. break;
  456. }
  457. }
  458. virtual bool PrsonaServerWebSocketHandler::handleData(
  459. CivetServer *server,
  460. struct mg_connection *conn,
  461. int bits,
  462. char *data,
  463. size_t data_len)
  464. {
  465. char *filename = (char *) mg_get_user_connection_data(conn);
  466. if ((bits & 0xf) == MG_WEBSOCKET_OPCODE_DATACOMPLETE)
  467. {
  468. generate_response(conn, filename);
  469. return false;
  470. }
  471. if ((bits & 0xf) != MG_WEBSOCKET_OPCODE_BINARY && (bits & 0xf) != MG_WEBSOCKET_OPCODE_CONTINUATION)
  472. {
  473. std::cerr << "Unknown opcode: failing." << std::endl;
  474. return false;
  475. }
  476. FILE *currFile = fopen(filename, "ab");
  477. fwrite(data, sizeof(char), data_len, currFile);
  478. fclose(currFile);
  479. return true;
  480. }
  481. void PrsonaServerWebSocketHandler::generate_response(
  482. struct mg_connection *conn,
  483. char *filename)
  484. {
  485. const struct mg_request_info *info = mg_get_request_info(conn);
  486. switch (info->query_string[0])
  487. {
  488. case PRSONA_ADD_CLIENT:
  489. add_new_client(conn, filename);
  490. break;
  491. case PRSONA_RECEIVE_VOTE:
  492. receive_vote(filename);
  493. break;
  494. case PRSONA_GET_BGN_PUBKEY:
  495. get_bgn_public_key(conn);
  496. break;
  497. case PRSONA_GET_NUM_CLIENTS:
  498. get_num_clients(conn);
  499. break;
  500. case PRSONA_GET_NUM_SERVERS:
  501. get_num_servers(conn);
  502. break;
  503. case PRSONA_GET_VOTES_BY:
  504. get_current_votes_by(conn, filename);
  505. break;
  506. case PRSONA_GET_ALL_VOTES:
  507. get_all_current_votes(conn);
  508. break;
  509. case PRSONA_GET_USER_TALLY:
  510. get_current_user_encrypted_tally(conn, filename);
  511. break;
  512. case PRSONA_GET_SERVER_TALLY:
  513. get_current_server_encrypted_tally(conn, filename);
  514. break;
  515. case PRSONA_GET_PSEUDONYMS:
  516. get_current_pseudonyms(conn);
  517. break;
  518. case PRSONA_GET_VOTE_ROW_COMMITMENT:
  519. get_vote_row_commitment(conn, filename);
  520. break;
  521. case PRSONA_GET_VOTE_MATRIX_COMMITMENT:
  522. get_vote_matrix_commitment(conn);
  523. break;
  524. case PRSONA_GET_USER_TALLY_COMMITMENT:
  525. get_user_tally_commitment(conn, filename);
  526. break;
  527. case PRSONA_GET_SERVER_TALLY_COMMITMENT:
  528. get_server_tally_commitment(conn, filename);
  529. break;
  530. case PRSONA_GET_PSEUDONYMS_COMMITMENT:
  531. get_pseudonyms_commitment(conn);
  532. break;
  533. case PRSONA_GET_BGN_DETAILS:
  534. get_bgn_details(conn);
  535. break;
  536. case PRSONA_ADD_CURR_SEED_TO_GENERATOR:
  537. add_seed_to_generator(conn, filename, true);
  538. break;
  539. case PRSONA_SET_FRESH_GENERATOR:
  540. set_generator(filename, true);
  541. break;
  542. case PRSONA_ADD_RAND_SEED_TO_GENERATOR:
  543. add_seed_to_generator(conn, filename, false);
  544. break;
  545. case PRSONA_SET_EG_BLIND_GENERATOR:
  546. set_generator(filename, false);
  547. break;
  548. case PRSONA_EPOCH_BUILD_UP:
  549. build_up_midway_pseudonyms(conn);
  550. break;
  551. case PRSONA_EPOCH_BREAK_DOWN:
  552. break_down_midway_pseudonyms(conn);
  553. break;
  554. case PRSONA_EPOCH_UPDATE:
  555. accept_epoch_updates(filename);
  556. break;
  557. case PRSONA_NEW_USER_UPDATE:
  558. import_new_user_update(filename);
  559. break;
  560. case PRSONA_GET_PARTIAL_DECRYPTION:
  561. get_partial_decryption(conn, filename);
  562. break;
  563. case PRSONA_RECEIVE_PARTIAL_DECRYPTION:
  564. receive_tallied_scores(conn, filename);
  565. break;
  566. case PRSONA_GET_FRESH_GENERATOR:
  567. get_generator(conn, true);
  568. break;
  569. case PRSONA_GET_EG_BLIND_GENERATOR:
  570. get_generator(conn, false);
  571. break;
  572. default:
  573. break;
  574. }
  575. }
  576. virtual void PrsonaServerWebSocketHandler::handleClose(
  577. CivetServer *server,
  578. const struct mg_connection *conn)
  579. {
  580. char *filename = (char *) mg_get_user_connection_data(conn);
  581. if (!filename)
  582. return;
  583. remove(filename);
  584. delete filename;
  585. }
  586. /*
  587. * BASIC PUBLIC SYSTEM INFO GETTERS
  588. */
  589. void PrsonaServerWebSocketHandler::get_bgn_public_key(
  590. struct mg_connection *conn) const
  591. {
  592. std::stringstream buffer;
  593. std::string data;
  594. BGNPublicKey pubKey = prsonaServer->get_bgn_public_key();
  595. buffer << pubKey;
  596. data = buffer.str();
  597. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
  598. }
  599. void PrsonaServerWebSocketHandler::get_num_clients(
  600. struct mg_connection *conn) const
  601. {
  602. std::stringstream buffer;
  603. std::string data;
  604. BinarySizeT numClients(prsonaServer->get_num_clients());
  605. buffer << numClients;
  606. data = buffer.str();
  607. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
  608. }
  609. void PrsonaServerWebSocketHandler::get_num_servers(
  610. struct mg_connection *conn) const
  611. {
  612. std::stringstream buffer;
  613. std::string data;
  614. BinarySizeT numServers(prsonaServer->get_num_servers());
  615. buffer << numServers;
  616. data = buffer.str();
  617. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
  618. }
  619. /*
  620. * ENCRYPTED DATA GETTERS
  621. */
  622. void PrsonaServerWebSocketHandler::get_current_votes_by(
  623. struct mg_connection *conn, const char *filename) const
  624. {
  625. ifstream file(filename);
  626. Twistpoint shortTermPublicKey;
  627. file >> shortTermPublicKey;
  628. std::stringstream buffer;
  629. std::string data;
  630. Proof pi;
  631. std::vector<TwistBipoint> votes =
  632. prsonaServer->get_current_votes_by(pi, shortTermPublicKey);
  633. buffer << pi;
  634. BinarySizeT sizeOfVector(votes.size());
  635. buffer << sizeOfVector;
  636. for (size_t i = 0; i < sizeOfVector.val(); i++)
  637. buffer << votes[i];
  638. data = buffer.str();
  639. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
  640. }
  641. void PrsonaServerWebSocketHandler::get_all_current_votes(
  642. struct mg_connection *conn) const
  643. {
  644. std::stringstream buffer;
  645. std::string data;
  646. Proof pi;
  647. std::vector<std::vector<TwistBipoint>> votes =
  648. prsonaServer->get_all_current_votes(pi);
  649. buffer << pi;
  650. BinarySizeT sizeOfVector(votes.size());
  651. buffer << sizeOfVector;
  652. for (size_t i = 0; i < sizeOfVector.val(); i++)
  653. for (size_t j = 0; j < sizeOfVector.val(); j++)
  654. buffer << votes[i][j];
  655. data = buffer.str();
  656. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
  657. }
  658. void PrsonaServerWebSocketHandler::get_current_user_encrypted_tally(
  659. struct mg_connection *conn, const char *filename) const
  660. {
  661. ifstream file(filename);
  662. Twistpoint shortTermPublicKey;
  663. file >> shortTermPublicKey;
  664. std::stringstream buffer;
  665. std::string data;
  666. Proof pi;
  667. EGCiphertext tally =
  668. prsonaServer->get_current_user_encrypted_tally(pi, shortTermPublicKey);
  669. buffer << pi;
  670. buffer << tally;
  671. data = buffer.str();
  672. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
  673. }
  674. void PrsonaServerWebSocketHandler::get_current_server_encrypted_tally(
  675. struct mg_connection *conn, const char *filename) const
  676. {
  677. ifstream file(filename);
  678. Twistpoint shortTermPublicKey;
  679. file >> shortTermPublicKey;
  680. std::stringstream buffer;
  681. std::string data;
  682. Proof pi;
  683. CurveBipoint tally =
  684. prsonaServer->get_current_server_encrypted_tally(pi, shortTermPublicKey);
  685. buffer << pi;
  686. buffer << tally;
  687. data = buffer.str();
  688. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
  689. }
  690. void PrsonaServerWebSocketHandler::get_current_pseudonyms(
  691. struct mg_connection *conn) const
  692. {
  693. std::stringstream buffer;
  694. std::string data;
  695. Proof pi;
  696. std::vector<Twistpoint> pseudonyms =
  697. prsonaServer->get_current_pseudonyms(pi);
  698. buffer << pi;
  699. BinarySizeT sizeOfVector(pseudonyms.size());
  700. buffer << sizeOfVector;
  701. for (size_t i = 0; i < sizeOfVector.val(); i++)
  702. buffer << pseudonyms[i];
  703. data = buffer.str();
  704. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
  705. }
  706. /*
  707. * PROOF COMMITMENT GETTERS
  708. */
  709. void PrsonaServerWebSocketHandler::get_vote_row_commitment(
  710. struct mg_connection *conn, const char *filename) const
  711. {
  712. ifstream file(filename);
  713. Twistpoint shortTermPublicKey;
  714. file >> shortTermPublicKey;
  715. std::stringstream buffer;
  716. std::string data;
  717. Proof pi =
  718. prsonaServer->get_vote_row_commitment(shortTermPublicKey);
  719. buffer << pi;
  720. data = buffer.str();
  721. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
  722. }
  723. void PrsonaServerWebSocketHandler::get_vote_matrix_commitment(
  724. struct mg_connection *conn) const
  725. {
  726. std::stringstream buffer;
  727. std::string data;
  728. Proof pi =
  729. prsonaServer->get_vote_matrix_commitment();
  730. buffer << pi;
  731. data = buffer.str();
  732. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
  733. }
  734. void PrsonaServerWebSocketHandler::get_user_tally_commitment(
  735. struct mg_connection *conn, const char *filename) const
  736. {
  737. ifstream file(filename);
  738. Twistpoint shortTermPublicKey;
  739. file >> shortTermPublicKey;
  740. std::stringstream buffer;
  741. std::string data;
  742. Proof pi =
  743. prsonaServer->get_user_tally_commitment(shortTermPublicKey);
  744. buffer << pi;
  745. data = buffer.str();
  746. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
  747. }
  748. void PrsonaServerWebSocketHandler::get_server_tally_commitment(
  749. struct mg_connection *conn, const char *filename) const
  750. {
  751. ifstream file(filename);
  752. Twistpoint shortTermPublicKey;
  753. file >> shortTermPublicKey;
  754. std::stringstream buffer;
  755. std::string data;
  756. Proof pi =
  757. prsonaServer->get_server_tally_commitment(shortTermPublicKey);
  758. buffer << pi;
  759. data = buffer.str();
  760. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
  761. }
  762. void PrsonaServerWebSocketHandler::get_pseudonyms_commitment(
  763. struct mg_connection *conn) const
  764. {
  765. std::stringstream buffer;
  766. std::string data;
  767. Proof pi =
  768. prsonaServer->get_pseudonyms_commitment();
  769. buffer << pi;
  770. data = buffer.str();
  771. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
  772. }
  773. void PrsonaServerWebSocketHandler::distribute_new_user_updates(
  774. std::vector<Proof> proofOfValidAddition,
  775. std::vector<CurveBipoint> previousVoteTallies,
  776. std::vector<Twistpoint> currentPseudonyms,
  777. std::vector<EGCiphertext> currentUserEncryptedTallies,
  778. std::vector<std::vector<TwistBipoint>> voteMatrix) const
  779. {
  780. std::stringstream buffer;
  781. std::string data;
  782. BinarySizeT sizeOfVector;
  783. sizeOfVector.set(proofOfValidAddition.size());
  784. buffer << sizeOfVector;
  785. for (size_t i = 0; i < sizeOfVector.val(); i++)
  786. buffer << proofOfValidAddition[i];
  787. sizeOfVector.set(previousVoteTallies.size());
  788. buffer << sizeOfVector;
  789. for (size_t i = 0; i < sizeOfVector.val(); i++)
  790. buffer << previousVoteTallies[i];
  791. sizeOfVector.set(currentPseudonyms.size());
  792. buffer << sizeOfVector;
  793. for (size_t i = 0; i < sizeOfVector.val(); i++)
  794. buffer << currentPseudonyms[i];
  795. sizeOfVector.set(currentUserEncryptedTallies.size());
  796. buffer << sizeOfVector;
  797. for (size_t i = 0; i < sizeOfVector.val(); i++)
  798. buffer << currentUserEncryptedTallies[i];
  799. sizeOfVector.set(voteMatrix.size());
  800. buffer << sizeOfVector;
  801. for (size_t i = 0; i < sizeOfVector.val(); i++)
  802. for (size_t j = 0; j < sizeOfVector.val(); j++)
  803. buffer << voteMatrix[i][j];
  804. data = buffer.str();
  805. size_t i = 0;
  806. while (i < serverIPs.size())
  807. {
  808. if (serverIPs[i] == selfIP)
  809. continue;
  810. struct mg_connection *conn =
  811. mg_connect_websocket_client(
  812. serverIPs[i].c_str(),
  813. PRSONA_PORT,
  814. USE_SSL,
  815. NULL,
  816. 0,
  817. GIVE_NEW_USER_URI,
  818. "null",
  819. synchro_websocket_data_handler,
  820. synchro_websocket_close_handler,
  821. (void *) distributeSync);
  822. if (!conn)
  823. {
  824. std::cerr << "Couldn't give server " << i << " new user" << std::endl;
  825. continue;
  826. }
  827. unique_lock<mutex> syncLock(distributeSync->mtx);
  828. distributeSync->val = 0;
  829. distributeSync->val2 = 0;
  830. mg_websocket_client_write(
  831. conn,
  832. MG_WEBSOCKET_OPCODE_BINARY,
  833. data.c_str(),
  834. data.length());
  835. while (!distributeSync->val2)
  836. distributeSync->cv.wait(syncLock);
  837. mg_close_connection(conn);
  838. if (distributeSync->val)
  839. i++;
  840. }
  841. }
  842. void PrsonaServerWebSocketHandler::distribute_new_vote(
  843. std::vector<Proof> pi;
  844. std::vector<TwistBipoint> newVotes,
  845. Twistpoint shortTermPublicKey) const
  846. {
  847. std::stringstream buffer;
  848. std::string data;
  849. BinarySizeT sizeOfVector;
  850. sizeOfVector.set(pi.size());
  851. buffer << sizeOfVector;
  852. for (size_t i = 0; i < sizeOfVector.val(); i++)
  853. buffer << pi[i];
  854. sizeOfVector.set(newVotes.size());
  855. buffer << sizeOfVector;
  856. for (size_t i = 0; i < sizeOfVector.val(); i++)
  857. buffer << newVotes[i];
  858. buffer << shortTermPublicKey;
  859. BinaryBool flag(false);
  860. buffer << flag;
  861. data = buffer.str();
  862. size_t i = 0;
  863. while (i < serverIPs.size())
  864. {
  865. if (serverIPs[i] == selfIP)
  866. continue;
  867. struct mg_connection *conn =
  868. mg_connect_websocket_client(
  869. serverIPs[i].c_str(),
  870. PRSONA_PORT,
  871. USE_SSL,
  872. NULL,
  873. 0,
  874. GIVE_NEW_VOTE_URI,
  875. "null",
  876. synchro_websocket_data_handler,
  877. synchro_websocket_close_handler,
  878. (void *) distributeSync);
  879. if (!conn)
  880. {
  881. std::cerr << "Couldn't give server " << i << " new user" << std::endl;
  882. continue;
  883. }
  884. unique_lock<mutex> syncLock(distributeSync->mtx);
  885. distributeSync->val = 0;
  886. distributeSync->val2 = 0;
  887. mg_websocket_client_write(
  888. conn,
  889. MG_WEBSOCKET_OPCODE_BINARY,
  890. data.c_str(),
  891. data.length());
  892. while (!distributeSync->val2)
  893. distributeSync->cv.wait(syncLock);
  894. mg_close_connection(conn);
  895. if (distributeSync->val)
  896. i++;
  897. }
  898. }
  899. /*
  900. * CLIENT INTERACTIONS
  901. */
  902. void PrsonaServerWebSocketHandler::add_new_client(
  903. struct mg_connection *conn, const char *filename)
  904. {
  905. ifstream file(filename);
  906. Proof proofOfValidKey;
  907. file >> proofOfValidKey;
  908. Twistpoint shortTermPublicKey;
  909. file >> shortTermPublicKey;
  910. std::unique_lock<std::mutex> lck(*updateMtx, std::defer_lock);
  911. obtain_update_locks(
  912. lck,
  913. serverIPs,
  914. selfIP,
  915. &updateSync);
  916. std::vector<Proof> proofOfValidAddition;
  917. prsonaServer->add_new_client(
  918. proofOfValidAddition,
  919. proofOfValidKey,
  920. shortTermPublicKey);
  921. std::vector<CurveBipoint> previousVoteTallies;
  922. std::vector<Twistpoint> currentPseudonyms;
  923. std::vector<EGCiphertext> currentUserEncryptedTallies;
  924. std::vector<std::vector<TwistBipoint>> voteMatrix;
  925. prsonaServer->export_new_user_update(
  926. previousVoteTallies,
  927. currentPseudonyms,
  928. currentUserEncryptedTallies,
  929. voteMatrix);
  930. distribute_new_user_updates(
  931. proofOfValidAddition,
  932. previousVoteTallies,
  933. currentPseudonyms,
  934. currentUserEncryptedTallies,
  935. voteMatrix);
  936. release_update_locks(
  937. lck,
  938. serverIPs,
  939. selfIP,
  940. &updateSync);
  941. BinarySizeT sizeOfVector(proofOfValidAddition.size());
  942. buffer << sizeOfVector;
  943. for (size_t i = 0; i < sizeOfVector.val(); i++)
  944. buffer << proofOfValidAddition[i];
  945. data = buffer.str();
  946. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
  947. }
  948. void PrsonaServerWebSocketHandler::receive_vote(
  949. const char *filename)
  950. {
  951. ifstream file(filename);
  952. BinarySizeT sizeOfVector;
  953. file >> sizeOfVector;
  954. std::vector<Proof> pi;
  955. for (size_t i = 0; i < sizeOfVector.val(); i++)
  956. {
  957. Proof currProof;
  958. file >> currProof;
  959. pi.push_back(currProof);
  960. }
  961. file >> sizeOfVector;
  962. std::vector<TwistBipoint> newVotes;
  963. for (size_t i = 0; i < sizeOfVector.val(); i++)
  964. {
  965. TwistBipoint currVote;
  966. file >> currVote;
  967. newVotes.push_back(currVote);
  968. }
  969. Twistpoint shortTermPublicKey;
  970. file >> shortTermPublicKey;
  971. BinaryBool shouldDeal;
  972. file >> shouldDeal;
  973. std::unique_lock<std::mutex> lck(*updateMtx, std::defer_lock);
  974. if (shouldDeal.val())
  975. {
  976. obtain_update_locks(
  977. lck,
  978. serverIPs,
  979. selfIP,
  980. &distributeSync);
  981. }
  982. prsonaServer->receive_vote(
  983. pi,
  984. newVotes,
  985. shortTermPublicKey);
  986. if (shouldDeal.val())
  987. {
  988. distribute_new_vote(pi, newVotes, shortTermPublicKey);
  989. release_update_locks(
  990. lck,
  991. serverIPs,
  992. selfIP,
  993. &distributeSync);
  994. }
  995. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
  996. }
  997. /*
  998. * CONSTRUCTOR HELPERS
  999. */
  1000. void PrsonaServerWebSocketHandler::get_bgn_details(
  1001. struct mg_connection *conn) const
  1002. {
  1003. std::stringstream buffer;
  1004. std::string data;
  1005. const BGN& sharedBGN = prsonaServer->get_bgn_details();
  1006. buffer << sharedBGN;
  1007. data = buffer.str();
  1008. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
  1009. }
  1010. void PrsonaServerWebSocketHandler::add_seed_to_generator(
  1011. struct mg_connection *conn, const char *filename, bool fresh) const
  1012. {
  1013. ifstream file(filename);
  1014. Twistpoint currGenerator;
  1015. file >> currGenerator;
  1016. std::stringstream buffer;
  1017. std::string data;
  1018. std::vector<Proof> pi;
  1019. if (fresh)
  1020. {
  1021. currGenerator =
  1022. prsonaServer->add_curr_seed_to_generator(pi, currGenerator);
  1023. }
  1024. else
  1025. {
  1026. currGenerator =
  1027. prsonaServer->add_rand_seed_to_generator(pi, currGenerator);
  1028. }
  1029. buffer << pi[0];
  1030. buffer << currGenerator;
  1031. data = buffer.str();
  1032. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
  1033. }
  1034. void PrsonaServerWebSocketHandler::set_generator(
  1035. const char *filename, bool fresh)
  1036. {
  1037. ifstream file(filename);
  1038. BinarySizeT sizeOfVector;
  1039. file >> sizeOfVector;
  1040. std::vector<Proof> pi;
  1041. for (size_t i = 0; i < sizeOfVector.val(); i++)
  1042. {
  1043. Proof currProof;
  1044. file >> currProof;
  1045. pi.push_back(currProof);
  1046. }
  1047. Twistpoint newGenerator;
  1048. file >> newGenerator;
  1049. if (fresh)
  1050. prsonaServer->initialize_fresh_generator(pi, newGenerator);
  1051. else
  1052. prsonaServer->set_EG_blind_generator(pi, newGenerator);
  1053. }
  1054. /*
  1055. * EPOCH ROUNDS
  1056. */
  1057. void PrsonaServerWebSocketHandler::build_up_midway_pseudonyms(
  1058. struct mg_connection *conn, const char *filename)
  1059. {
  1060. std::vector<std::vector<Proof>> generatorProofHolder;
  1061. std::vector<Proof> generatorProof;
  1062. Twistpoint nextGenerator;
  1063. read_epoch_initiator_string(
  1064. filename,
  1065. generatorProof,
  1066. nextGenerator);
  1067. generatorProofHolder.push_back(generatorProof);
  1068. std::vector<std::vector<std::vector<Proof>>> pi;
  1069. std::vector<std::vector<std::vector<Twistpoint>>> permutationCommits;
  1070. std::vector<std::vector<std::vector<Twistpoint>>> freshPseudonymCommits;
  1071. std::vector<std::vector<std::vector<Twistpoint>>> freshPseudonymSeedCommits;
  1072. std::vector<std::vector<std::vector<CurveBipoint>>> serverTallyCommits;
  1073. std::vector<std::vector<std::vector<std::vector<TwistBipoint>>>> partwayVoteMatrixCommits;
  1074. std::vector<std::vector<std::vector<std::vector<TwistBipoint>>>> finalVoteMatrixCommits;
  1075. pi.push_back(generatorProofHolder);
  1076. prsonaServer->build_up_midway_pseudonyms(
  1077. pi,
  1078. permutationCommits,
  1079. freshPseudonymCommits,
  1080. freshPseudonymSeedCommits,
  1081. serverTallyCommits,
  1082. partwayVoteMatrixCommits,
  1083. finalVoteMatrixCommits,
  1084. nextGenerator);
  1085. std::vector<std::vector<Twistpoint>> userTallyMaskCommits, userTallyMessageCommits, userTallySeedCommits;
  1086. string data =
  1087. make_epoch_update_string(
  1088. pi[1],
  1089. permutationCommits[0],
  1090. freshPseudonymCommits[0],
  1091. freshPseudonymSeedCommits[0],
  1092. serverTallyCommits[0],
  1093. partwayVoteMatrixCommits[0],
  1094. finalVoteMatrixCommits[0],
  1095. userTallyMaskCommits,
  1096. userTallyMessageCommits,
  1097. userTallySeedCommits,
  1098. nextGenerator,
  1099. false);
  1100. struct synchronization_tool epochSync;
  1101. epochSync->val = 1;
  1102. for (size_t i = 0; i < serverIPs.size(); i++)
  1103. {
  1104. if (serverIPs[i] == selfIP)
  1105. continue;
  1106. distribute_epoch_updates(
  1107. serverIPs[i],
  1108. data,
  1109. &epochSync);
  1110. }
  1111. unique_lock<mutex> lck(epochSync);
  1112. while (epochSync.val < serverIPs.size())
  1113. epochSync.cv.wait(lck);
  1114. data = make_epoch_initiator_string(
  1115. pi[0][0],
  1116. nextGenerator);
  1117. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
  1118. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
  1119. }
  1120. void PrsonaServerWebSocketHandler::break_down_midway_pseudonyms(
  1121. struct mg_connection *conn, const char *filename)
  1122. {
  1123. std::vector<Proof> generatorProof;
  1124. Twistpoint nextGenerator;
  1125. read_epoch_initiator_string(
  1126. filename,
  1127. generatorProof,
  1128. nextGenerator);
  1129. std::vector<std::vector<std::vector<Proof>>> pi;
  1130. std::vector<std::vector<std::vector<Twistpoint>>> permutationCommits;
  1131. std::vector<std::vector<std::vector<Twistpoint>>> freshPseudonymCommits;
  1132. std::vector<std::vector<std::vector<Twistpoint>>> freshPseudonymSeedCommits;
  1133. std::vector<std::vector<std::vector<CurveBipoint>>> serverTallyCommits;
  1134. std::vector<std::vector<std::vector<std::vector<TwistBipoint>>>> partwayVoteMatrixCommits;
  1135. std::vector<std::vector<std::vector<std::vector<TwistBipoint>>>> finalVoteMatrixCommits;
  1136. std::vector<std::vector<std::vector<Twistpoint>>> userTallyMaskCommits;
  1137. std::vector<std::vector<std::vector<Twistpoint>>> userTallyMessageCommits;
  1138. std::vector<std::vector<std::vector<Twistpoint>>> userTallySeedCommits;
  1139. prsonaServer->break_down_midway_pseudonyms(
  1140. generatorProof,
  1141. pi,
  1142. permutationCommits,
  1143. freshPseudonymCommits,
  1144. freshPseudonymSeedCommits,
  1145. serverTallyCommits,
  1146. partwayVoteMatrixCommits,
  1147. finalVoteMatrixCommits,
  1148. userTallyMaskCommits,
  1149. userTallyMessageCommits,
  1150. userTallySeedCommits,
  1151. nextGenerator);
  1152. string data =
  1153. make_epoch_update_string(
  1154. pi[0],
  1155. permutationCommits[0],
  1156. freshPseudonymCommits[0],
  1157. freshPseudonymSeedCommits[0],
  1158. serverTallyCommits[0],
  1159. partwayVoteMatrixCommits[0],
  1160. finalVoteMatrixCommits[0],
  1161. userTallyMaskCommits[0],
  1162. userTallyMessageCommits[0],
  1163. userTallySeedCommits[0],
  1164. nextGenerator,
  1165. true);
  1166. struct synchronization_tool epochSync;
  1167. epochSync.val = 1;
  1168. for (size_t i = 0; i < serverIPs.size(); i++)
  1169. {
  1170. if (serverIPs[i] == selfIP)
  1171. continue;
  1172. distribute_epoch_updates(
  1173. serverIPs[i],
  1174. data,
  1175. &epochSync);
  1176. }
  1177. unique_lock<mutex> lck(epochSync.mtx);
  1178. while (epochSync.val < serverIPs.size())
  1179. epochSync.cv.wait(lck);
  1180. epochNum->fetch_add(1);
  1181. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
  1182. }
  1183. void PrsonaServerWebSocketHandler::accept_epoch_updates(
  1184. struct mg_connection *conn, const char *filename)
  1185. {
  1186. std::vector<std::vector<Proof>> pi;
  1187. std::vector<std::vector<Twistpoint>> permutationCommits;
  1188. std::vector<std::vector<Twistpoint>> freshPseudonymCommits;
  1189. std::vector<std::vector<Twistpoint>> freshPseudonymSeedCommits;
  1190. std::vector<std::vector<CurveBipoint>> serverTallyCommits;
  1191. std::vector<std::vector<std::vector<TwistBipoint>>> partwayVoteMatrixCommits;
  1192. std::vector<std::vector<std::vector<TwistBipoint>>> finalVoteMatrixCommits;
  1193. std::vector<std::vector<Twistpoint>> userTallyMaskCommits;
  1194. std::vector<std::vector<Twistpoint>> userTallyMessageCommits;
  1195. std::vector<std::vector<Twistpoint>> userTallySeedCommits;
  1196. Twistpoint nextGenerator;
  1197. bool doUserTallies =
  1198. read_epoch_update_string(
  1199. filename,
  1200. pi,
  1201. permutationCommits,
  1202. freshPseudonymCommits,
  1203. freshPseudonymSeedCommits,
  1204. serverTallyCommits,
  1205. partwayVoteMatrixCommits,
  1206. finalVoteMatrixCommits,
  1207. userTallyMaskCommits,
  1208. userTallyMessageCommits,
  1209. userTallySeedCommits,
  1210. nextGenerator);
  1211. prsonaServer->accept_epoch_updates(
  1212. pi,
  1213. permutationCommits,
  1214. freshPseudonymCommits,
  1215. freshPseudonymSeedCommits,
  1216. serverTallyCommits,
  1217. partwayVoteMatrixCommits,
  1218. finalVoteMatrixCommits,
  1219. userTallyMaskCommits,
  1220. userTallyMessageCommits,
  1221. userTallySeedCommits,
  1222. nextGenerator,
  1223. doUserTallies);
  1224. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
  1225. }
  1226. /*
  1227. * DATA MAINTENANCE
  1228. */
  1229. void PrsonaServerWebSocketHandler::import_new_user_update(
  1230. const char *filename)
  1231. {
  1232. std::vector<Proof> proofOfValidAddition;
  1233. std::vector<CurveBipoint> previousVoteTallies;
  1234. std::vector<Twistpoint> currentPseudonyms;
  1235. std::vector<EGCiphertext> currentUserEncryptedTallies;
  1236. std::vector<std::vector<TwistBipoint>> voteMatrix;
  1237. ifstream file(filename);
  1238. BinarySizeT sizeOfVector;
  1239. file >> sizeOfVector;
  1240. for (size_t i = 0; i < sizeOfVector.val(); i++)
  1241. {
  1242. Proof currProof;
  1243. file >> currProof;
  1244. proofOfValidAddition.push_back(currProof);
  1245. }
  1246. file >> sizeOfVector;
  1247. for (size_t i = 0; i < sizeOfVector.val(); i++)
  1248. {
  1249. CurveBipoint currTally;
  1250. file >> currTally;
  1251. previousVoteTallies.push_back(currTally);
  1252. }
  1253. file >> sizeOfVector;
  1254. for (size_t i = 0; i < sizeOfVector.val(); i++)
  1255. {
  1256. Twistpoint currNym;
  1257. file >> currNym;
  1258. currentPseudonyms.push_back(currNym);
  1259. }
  1260. file >> sizeOfVector;
  1261. for (size_t i = 0; i < sizeOfVector.val(); i++)
  1262. {
  1263. EGCiphertext currTally;
  1264. file >> currTally;
  1265. currentUserEncryptedTallies.push_back(currTally);
  1266. }
  1267. file >> sizeOfVector;
  1268. for (size_t i = 0; i < sizeOfVector.val(); i++)
  1269. {
  1270. std::vector<TwistBipoint> currRow;
  1271. for (size_t j = 0; j < sizeOfVector.val(); j++)
  1272. {
  1273. TwistBipoint currVote;
  1274. file >> currVote;
  1275. currRow.push_back(currVote);
  1276. }
  1277. voteMatrix.push_back(currRow);
  1278. }
  1279. prsonaServer->import_new_user_update(
  1280. proofOfValidAddition,
  1281. previousVoteTallies,
  1282. currentPseudonyms,
  1283. currentUserEncryptedTallies,
  1284. voteMatrix);
  1285. }
  1286. void PrsonaServerWebSocketHandler::get_partial_decryption(
  1287. struct mg_connection *conn)
  1288. {
  1289. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
  1290. }
  1291. void PrsonaServerWebSocketHandler::receive_tallied_scores(
  1292. struct mg_connection *conn, const char *filename)
  1293. {
  1294. ifstream file(filename);
  1295. std::vector<EGCiphertext> userScores;
  1296. std::vector<CurveBipoint> serverScores;
  1297. BinarySizeT sizeOfVector;
  1298. file >> sizeOfVector;
  1299. for (size_t i = 0; i < sizeOfVector.val(); i++)
  1300. {
  1301. EGCiphertext currScore;
  1302. file >> currScore;
  1303. userScores.push_back(currScore);
  1304. }
  1305. for (size_t i = 0; i < sizeOfVector.val(); i++)
  1306. {
  1307. CurveBipoint currScore;
  1308. file >> currScore;
  1309. serverScores.push_back(currScore);
  1310. }
  1311. prsonaServer->receive_tallied_scores(userScores, serverScores);
  1312. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
  1313. }
  1314. void PrsonaServerWebSocketHandler::get_generator(
  1315. struct mg_connection *conn, bool fresh)
  1316. {
  1317. Twistpoint generator;
  1318. std::vector<Proof> pi;
  1319. if (fresh)
  1320. generator = prsonaServer->get_fresh_generator(pi);
  1321. else
  1322. generator = prsonaServer->get_blinding_generator(pi);
  1323. std::stringstream buffer;
  1324. std::string data;
  1325. BinarySizeT sizeOfVector(pi.size());
  1326. buffer << sizeOfVector;
  1327. for (size_t i = 0; i < sizeOfVector.val(); i++)
  1328. buffer << pi[i];
  1329. buffer << generator;
  1330. data = buffer.str();
  1331. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), data.length());
  1332. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
  1333. }