networkServer.cpp 44 KB

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