networkClient.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. #include <fstream>
  2. #include <cstring>
  3. #include <cstdio>
  4. #include "networkClient.hpp"
  5. template <>
  6. EGCiphertext get_committed_val_from_file<EGCiphertext>(
  7. struct synchronization_tool *sync,
  8. const char *filename,
  9. Proof& pi)
  10. {
  11. std::unique_lock<std::mutex> lck(sync->mtx);
  12. std::ifstream valFile(filename);
  13. EGCiphertext retval;
  14. valFile >> pi;
  15. valFile >> retval;
  16. return retval;
  17. }
  18. template <>
  19. CurveBipoint get_committed_val_from_file<CurveBipoint>(
  20. struct synchronization_tool *sync,
  21. const char *filename,
  22. Proof& pi)
  23. {
  24. std::unique_lock<std::mutex> lck(sync->mtx);
  25. std::ifstream valFile(filename);
  26. CurveBipoint retval;
  27. valFile >> pi;
  28. valFile >> retval;
  29. return retval;
  30. }
  31. template <>
  32. std::vector<TwistBipoint> get_committed_val_from_file<std::vector<TwistBipoint>>(
  33. struct synchronization_tool *sync,
  34. const char *filename,
  35. Proof& pi)
  36. {
  37. std::unique_lock<std::mutex> lck(sync->mtx);
  38. std::ifstream valFile(filename);
  39. valFile >> pi;
  40. std::vector<TwistBipoint> retval;
  41. BinarySizeT sizeOfVector;
  42. valFile >> sizeOfVector;
  43. for (size_t i = 0; i < sizeOfVector.val(); i++)
  44. {
  45. TwistBipoint currVote;
  46. valFile >> currVote;
  47. retval.push_back(currVote);
  48. }
  49. return retval;
  50. }
  51. template <>
  52. std::vector<Twistpoint> get_committed_val_from_file<std::vector<Twistpoint>>(
  53. struct synchronization_tool *sync,
  54. const char *filename,
  55. Proof& pi)
  56. {
  57. std::unique_lock<std::mutex> lck(sync->mtx);
  58. std::ifstream valFile(filename);
  59. valFile >> pi;
  60. std::vector<Twistpoint> retval;
  61. BinarySizeT sizeOfVector;
  62. valFile >> sizeOfVector;
  63. for (size_t i = 0; i < sizeOfVector.val(); i++)
  64. {
  65. Twistpoint currVote;
  66. valFile >> currVote;
  67. retval.push_back(currVote);
  68. }
  69. return retval;
  70. }
  71. template <>
  72. std::vector<std::vector<TwistBipoint>> get_committed_val_from_file<std::vector<std::vector<TwistBipoint>>>(
  73. struct synchronization_tool *sync,
  74. const char *filename,
  75. Proof& pi)
  76. {
  77. std::unique_lock<std::mutex> lck(sync->mtx);
  78. std::ifstream valFile(filename);
  79. valFile >> pi;
  80. std::vector<std::vector<TwistBipoint>> retval;
  81. BinarySizeT sizeOfVector;
  82. valFile >> sizeOfVector;
  83. for (size_t i = 0; i < sizeOfVector.val(); i++)
  84. {
  85. std::vector<TwistBipoint> currRow;
  86. for (size_t j = 0; j < sizeOfVector.val(); j++)
  87. {
  88. TwistBipoint currVote;
  89. valFile >> currVote;
  90. currRow.push_back(currVote);
  91. }
  92. retval.push_back(currRow);
  93. }
  94. return retval;
  95. }
  96. template <typename T>
  97. T get_first_committed_val(
  98. std::default_random_engine *rng,
  99. const std::string& serverIP,
  100. int serverPort,
  101. Proof& pi,
  102. const Twistpoint& shortTermPublicKey,
  103. const char *firstUri)
  104. {
  105. struct synchronization_tool sync;
  106. std::stringstream buffer;
  107. std::string data;
  108. char *filename = NULL;
  109. buffer << shortTermPublicKey;
  110. data = buffer.str();
  111. bool flag = false;
  112. while (!flag)
  113. {
  114. struct mg_connection *conn =
  115. mg_connect_websocket_client(
  116. serverIP.c_str(),
  117. serverPort,
  118. USE_SSL,
  119. NULL,
  120. 0,
  121. firstUri,
  122. "null",
  123. file_websocket_data_handler,
  124. file_websocket_close_handler,
  125. (void *) &sync);
  126. if (!conn)
  127. {
  128. std::cerr << "Trouble getting encrypted score from server at " << serverIP << ":" << serverPort << std::endl;
  129. continue;
  130. }
  131. std::unique_lock<std::mutex> lck(sync.mtx);
  132. filename = set_temp_filename(*rng, conn);
  133. sync.val = 0;
  134. mg_websocket_client_write(
  135. conn,
  136. MG_WEBSOCKET_OPCODE_BINARY,
  137. data.c_str(),
  138. data.length());
  139. mg_websocket_client_write(
  140. conn,
  141. MG_WEBSOCKET_OPCODE_DATACOMPLETE,
  142. "",
  143. 0);
  144. while (!sync.val)
  145. sync.cv.wait(lck);
  146. mg_close_connection(conn);
  147. flag = true;
  148. }
  149. T retval = get_committed_val_from_file<T>(&sync, filename, pi);
  150. remove(filename);
  151. delete [] filename;
  152. return retval;
  153. }
  154. Proof get_commitment_from_file(
  155. struct synchronization_tool *sync,
  156. char *filename)
  157. {
  158. std::unique_lock<std::mutex> lck(sync->mtx);
  159. std::ifstream scoreFile(filename);
  160. Proof retval;
  161. scoreFile >> retval;
  162. return retval;
  163. }
  164. void get_additional_commitment(
  165. std::default_random_engine *rng,
  166. const std::vector<std::string>& serverIPs,
  167. const std::vector<int>& serverPorts,
  168. const std::string& skipIP,
  169. int skipPort,
  170. std::vector<Proof>& pi,
  171. const Twistpoint& shortTermPublicKey,
  172. const char *commitUri)
  173. {
  174. std::vector<char *> commitmentFilenames;
  175. std::vector<struct synchronization_tool *> commitmentSyncs;
  176. for (size_t i = 0; i < serverIPs.size(); i++)
  177. {
  178. if (serverIPs[i] == skipIP && serverPorts[i] == skipPort)
  179. continue;
  180. struct synchronization_tool *currSync = new struct synchronization_tool;
  181. commitmentSyncs.push_back(currSync);
  182. bool flag = false;
  183. while (!flag)
  184. {
  185. struct mg_connection *conn =
  186. mg_connect_websocket_client(
  187. serverIPs[i].c_str(),
  188. serverPorts[i],
  189. USE_SSL,
  190. NULL,
  191. 0,
  192. commitUri,
  193. "null",
  194. file_websocket_data_handler,
  195. file_websocket_close_handler,
  196. (void *) currSync);
  197. if (!conn)
  198. {
  199. std::cerr << "Trouble getting commitment from server at " << serverIPs[i] << ":" << serverPorts[i] << std::endl;
  200. continue;
  201. }
  202. std::unique_lock<std::mutex> lck(currSync->mtx);
  203. currSync->val = 0;
  204. commitmentFilenames.push_back(set_temp_filename(*rng, conn));
  205. mg_websocket_client_write(
  206. conn,
  207. MG_WEBSOCKET_OPCODE_DATACOMPLETE,
  208. "",
  209. 0);
  210. while (!currSync->val)
  211. currSync->cv.wait(lck);
  212. mg_close_connection(conn);
  213. flag = true;
  214. }
  215. }
  216. for (size_t i = 0; i < commitmentFilenames.size(); i++)
  217. {
  218. pi.push_back(
  219. get_commitment_from_file(
  220. commitmentSyncs[i], commitmentFilenames[i]));
  221. delete commitmentSyncs[i];
  222. remove(commitmentFilenames[i]);
  223. delete [] commitmentFilenames[i];
  224. }
  225. }
  226. template <typename T>
  227. T get_server_committed_val(
  228. std::default_random_engine *generator,
  229. const std::vector<std::string>& serverIPs,
  230. const std::vector<int>& serverPorts,
  231. std::vector<Proof>& pi,
  232. const Twistpoint& shortTermPublicKey,
  233. const char *firstUri,
  234. const char *commitUri)
  235. {
  236. std::uniform_int_distribution<size_t> distribution(0, serverIPs.size() - 1);
  237. size_t whichServer = distribution(*generator);
  238. pi.clear();
  239. Proof firstProof;
  240. T retval =
  241. get_first_committed_val<T>(
  242. generator,
  243. serverIPs[whichServer],
  244. serverPorts[whichServer],
  245. firstProof,
  246. shortTermPublicKey,
  247. firstUri);
  248. pi.push_back(firstProof);
  249. get_additional_commitment(
  250. generator,
  251. serverIPs,
  252. serverPorts,
  253. serverIPs[whichServer],
  254. serverPorts[whichServer],
  255. pi,
  256. shortTermPublicKey,
  257. commitUri);
  258. return retval;
  259. }
  260. template EGCiphertext get_server_committed_val<EGCiphertext>(
  261. std::default_random_engine *generator,
  262. const std::vector<std::string>& serverIPs,
  263. const std::vector<int>& serverPorts,
  264. std::vector<Proof>& pi,
  265. const Twistpoint& shortTermPublicKey,
  266. const char *firstUri,
  267. const char *commitUri);
  268. template CurveBipoint get_server_committed_val<CurveBipoint>(
  269. std::default_random_engine *generator,
  270. const std::vector<std::string>& serverIPs,
  271. const std::vector<int>& serverPorts,
  272. std::vector<Proof>& pi,
  273. const Twistpoint& shortTermPublicKey,
  274. const char *firstUri,
  275. const char *commitUri);
  276. template std::vector<Twistpoint> get_server_committed_val<std::vector<Twistpoint>>(
  277. std::default_random_engine *generator,
  278. const std::vector<std::string>& serverIPs,
  279. const std::vector<int>& serverPorts,
  280. std::vector<Proof>& pi,
  281. const Twistpoint& shortTermPublicKey,
  282. const char *firstUri,
  283. const char *commitUri);
  284. template std::vector<TwistBipoint> get_server_committed_val<std::vector<TwistBipoint>>(
  285. std::default_random_engine *generator,
  286. const std::vector<std::string>& serverIPs,
  287. const std::vector<int>& serverPorts,
  288. std::vector<Proof>& pi,
  289. const Twistpoint& shortTermPublicKey,
  290. const char *firstUri,
  291. const char *commitUri);
  292. template std::vector<std::vector<TwistBipoint>> get_server_committed_val<std::vector<std::vector<TwistBipoint>>>(
  293. std::default_random_engine *generator,
  294. const std::vector<std::string>& serverIPs,
  295. const std::vector<int>& serverPorts,
  296. std::vector<Proof>& pi,
  297. const Twistpoint& shortTermPublicKey,
  298. const char *firstUri,
  299. const char *commitUri);
  300. Twistpoint get_generator_from_file(
  301. struct synchronization_tool *sync,
  302. const char *filename,
  303. std::vector<Proof>& pi)
  304. {
  305. std::ifstream genFile(filename);
  306. BinarySizeT sizeOfVector;
  307. genFile >> sizeOfVector;
  308. for (size_t i = 0; i < sizeOfVector.val(); i++)
  309. {
  310. Proof currProof;
  311. genFile >> currProof;
  312. pi.push_back(currProof);
  313. }
  314. Twistpoint retval;
  315. genFile >> retval;
  316. return retval;
  317. }
  318. Twistpoint get_generator(
  319. std::default_random_engine *randomGenerator,
  320. const std::vector<std::string>& serverIPs,
  321. const std::vector<int>& serverPorts,
  322. std::vector<Proof>& pi,
  323. bool fresh)
  324. {
  325. struct synchronization_tool sync;
  326. std::uniform_int_distribution<size_t> distribution(0, serverIPs.size() - 1);
  327. size_t whichServer = distribution(*randomGenerator);
  328. char *filename = NULL;
  329. pi.clear();
  330. const char* whichUri = (fresh ? FRESH_GEN_URI : BLIND_GEN_URI);
  331. bool flag = false;
  332. while (!flag)
  333. {
  334. struct mg_connection *conn = mg_connect_websocket_client(
  335. serverIPs[whichServer].c_str(),
  336. serverPorts[whichServer],
  337. USE_SSL,
  338. NULL,
  339. 0,
  340. whichUri,
  341. "null",
  342. file_websocket_data_handler,
  343. file_websocket_close_handler,
  344. (void *) &sync);
  345. if (!conn)
  346. {
  347. std::cerr << "Couldn't obtain BGN details" << std::endl;
  348. continue;
  349. }
  350. std::unique_lock<std::mutex> lck(sync.mtx);
  351. filename = set_temp_filename(*randomGenerator, conn);
  352. sync.val = 0;
  353. mg_websocket_client_write(
  354. conn,
  355. MG_WEBSOCKET_OPCODE_DATACOMPLETE,
  356. "",
  357. 0);
  358. while (!sync.val)
  359. sync.cv.wait(lck);
  360. mg_close_connection(conn);
  361. flag = true;
  362. }
  363. Twistpoint retval =
  364. get_generator_from_file(&sync, filename, pi);
  365. remove(filename);
  366. delete [] filename;
  367. return retval;
  368. }
  369. PrsonaClientWebSocketHandler::PrsonaClientWebSocketHandler(
  370. PrsonaClient *prsonaClient,
  371. const std::vector<std::string>& serverIPs,
  372. const std::vector<int>& serverPorts,
  373. std::default_random_engine *generator)
  374. : prsonaClient(prsonaClient), serverIPs(serverIPs),
  375. serverPorts(serverPorts), generator(generator)
  376. { /* */ }
  377. bool PrsonaClientWebSocketHandler::handleConnection(
  378. CivetServer *server,
  379. const struct mg_connection *conn)
  380. {
  381. const struct mg_request_info *info = mg_get_request_info(conn);
  382. bool flag = (info->query_string && info->query_string[0] == PRSONA_VERIFY_REPUTATION_PROOF);
  383. return flag;
  384. }
  385. void PrsonaClientWebSocketHandler::handleReadyState(
  386. CivetServer *server,
  387. struct mg_connection *conn)
  388. {
  389. const struct mg_request_info *info = mg_get_request_info(conn);
  390. switch (info->query_string[0])
  391. {
  392. case PRSONA_VERIFY_REPUTATION_PROOF:
  393. set_temp_filename(*generator, conn);
  394. break;
  395. default:
  396. mg_set_user_connection_data(conn, NULL);
  397. break;
  398. }
  399. }
  400. bool PrsonaClientWebSocketHandler::handleData(
  401. CivetServer *server,
  402. struct mg_connection *conn,
  403. int bits,
  404. char *data,
  405. size_t data_len)
  406. {
  407. char *filename = (char *) mg_get_user_connection_data(conn);
  408. if ((bits & 0xf) == MG_WEBSOCKET_OPCODE_DATACOMPLETE)
  409. {
  410. generate_response(conn, filename);
  411. return false;
  412. }
  413. if ((bits & 0xf) != MG_WEBSOCKET_OPCODE_BINARY && (bits & 0xf) != MG_WEBSOCKET_OPCODE_CONTINUATION)
  414. {
  415. std::cerr << "Unknown opcode: failing." << std::endl;
  416. return false;
  417. }
  418. FILE *currFile = fopen(filename, "ab");
  419. fwrite(data, sizeof(char), data_len, currFile);
  420. fclose(currFile);
  421. return true;
  422. }
  423. void PrsonaClientWebSocketHandler::generate_response(
  424. struct mg_connection *conn,
  425. const char *filename) const
  426. {
  427. const struct mg_request_info *info = mg_get_request_info(conn);
  428. switch (info->query_string[0])
  429. {
  430. case PRSONA_VERIFY_REPUTATION_PROOF:
  431. verify_reputation_proof(conn, filename);
  432. break;
  433. default:
  434. break;
  435. }
  436. }
  437. void PrsonaClientWebSocketHandler::handleClose(
  438. CivetServer *server,
  439. const struct mg_connection *conn)
  440. {
  441. char *filename = (char *) mg_get_user_connection_data(conn);
  442. if (!filename)
  443. return;
  444. remove(filename);
  445. delete [] filename;
  446. }
  447. void PrsonaClientWebSocketHandler::verify_reputation_proof(
  448. struct mg_connection *conn, const char *filename) const
  449. {
  450. std::ifstream file(filename);
  451. std::vector<Proof> pi;
  452. Twistpoint shortTermPublicKey;
  453. Scalar threshold;
  454. BinarySizeT sizeOfVector;
  455. file >> sizeOfVector;
  456. for (size_t i = 0; i < sizeOfVector.val(); i++)
  457. {
  458. Proof currProof;
  459. file >> currProof;
  460. pi.push_back(currProof);
  461. }
  462. file >> shortTermPublicKey;
  463. file >> threshold;
  464. std::vector<Proof> generatorProof;
  465. Twistpoint freshGenerator =
  466. get_generator(
  467. generator,
  468. serverIPs,
  469. serverPorts,
  470. generatorProof,
  471. true);
  472. prsonaClient->receive_fresh_generator(
  473. generatorProof,
  474. freshGenerator);
  475. std::vector<Proof> encryptedScoreProof;
  476. EGCiphertext encryptedScore =
  477. get_server_committed_val<EGCiphertext>(
  478. generator,
  479. serverIPs,
  480. serverPorts,
  481. encryptedScoreProof,
  482. shortTermPublicKey,
  483. USER_TALLY_URI,
  484. USER_TALLY_COMMIT_URI);
  485. bool flag =
  486. prsonaClient->verify_reputation_proof(
  487. pi,
  488. shortTermPublicKey,
  489. threshold,
  490. encryptedScoreProof,
  491. encryptedScore);
  492. std::string data = flag ? "\x01" : "\x00";
  493. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_BINARY, data.c_str(), 1);
  494. mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
  495. }