networkServer.cpp 44 KB

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