clientMain.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794
  1. #include <mutex>
  2. #include <condition_variable>
  3. #include <chrono>
  4. #include <iostream>
  5. #include <fstream>
  6. #include <cstring>
  7. #include <cstdlib>
  8. #include "networkClient.hpp"
  9. using namespace std;
  10. enum EventType {
  11. CLIENT_MAKE_VOTE = 1,
  12. CLIENT_MAKE_REP_PROOF
  13. };
  14. // Initialize the classes we use
  15. void initialize_prsona_classes()
  16. {
  17. Scalar::init();
  18. PrsonaBase::init();
  19. PrsonaBase::set_client_malicious();
  20. }
  21. BGNPublicKey get_bgn_public_key_from_file(
  22. struct synchronization_tool *sync,
  23. const char *filename)
  24. {
  25. unique_lock<mutex> lck(sync->mtx);
  26. ifstream bgnFile(filename);
  27. BGNPublicKey publicKey;
  28. bgnFile >> publicKey;
  29. return publicKey;
  30. }
  31. vector<Proof> get_valid_addition_proof_from_file(
  32. struct synchronization_tool *sync,
  33. const char *filename)
  34. {
  35. unique_lock<mutex> lck(sync->mtx);
  36. ifstream additionFile(filename);
  37. vector<Proof> retval;
  38. BinarySizeT sizeOfVector;
  39. additionFile >> sizeOfVector;
  40. for (size_t i = 0; i < sizeOfVector.val(); i++)
  41. {
  42. Proof currProof;
  43. additionFile >> currProof;
  44. retval.push_back(currProof);
  45. }
  46. return retval;
  47. }
  48. BGNPublicKey get_bgn_public_key(
  49. default_random_engine *randomGenerator,
  50. const vector<string>& serverIPs,
  51. const vector<int>& serverPorts)
  52. {
  53. struct synchronization_tool sync;
  54. char *filename = NULL;
  55. uniform_int_distribution<size_t> distribution(0, serverIPs.size() - 1);
  56. size_t whichServer = distribution(*randomGenerator);
  57. bool flag = false;
  58. while (!flag)
  59. {
  60. struct mg_connection *conn = mg_connect_websocket_client(
  61. serverIPs[whichServer].c_str(),
  62. serverPorts[whichServer],
  63. USE_SSL,
  64. NULL,
  65. 0,
  66. PUBLIC_BGN_URI,
  67. "null",
  68. file_websocket_data_handler,
  69. file_websocket_close_handler,
  70. (void *) &sync);
  71. if (!conn)
  72. {
  73. cerr << "Couldn't obtain BGN details" << endl;
  74. continue;
  75. }
  76. unique_lock<mutex> lck(sync.mtx);
  77. filename = set_temp_filename(*randomGenerator, conn);
  78. sync.val = 0;
  79. mg_websocket_client_write(
  80. conn,
  81. MG_WEBSOCKET_OPCODE_DATACOMPLETE,
  82. "",
  83. 0);
  84. while (!sync.val)
  85. sync.cv.wait(lck);
  86. mg_close_connection(conn);
  87. flag = true;
  88. }
  89. BGNPublicKey retval =
  90. get_bgn_public_key_from_file(&sync, filename);
  91. remove(filename);
  92. delete [] filename;
  93. return retval;
  94. }
  95. void verify_valid_addition(
  96. PrsonaClient *newUser,
  97. default_random_engine *rng,
  98. const vector<string>& serverIPs,
  99. const vector<int>& serverPorts,
  100. const vector<Proof>& proofOfValidAddition,
  101. const Twistpoint& shortTermPublicKey)
  102. {
  103. vector<Proof> serverEncryptedScoreProof;
  104. CurveBipoint serverEncryptedScore =
  105. get_server_committed_val<CurveBipoint>(
  106. rng,
  107. serverIPs,
  108. serverPorts,
  109. serverEncryptedScoreProof,
  110. shortTermPublicKey,
  111. SERVER_TALLY_URI,
  112. SERVER_TALLY_COMMIT_URI);
  113. vector<Proof> userEncryptedScoreProof;
  114. EGCiphertext userEncryptedScore =
  115. get_server_committed_val<EGCiphertext>(
  116. rng,
  117. serverIPs,
  118. serverPorts,
  119. userEncryptedScoreProof,
  120. shortTermPublicKey,
  121. USER_TALLY_URI,
  122. USER_TALLY_COMMIT_URI);
  123. vector<Proof> voteMatrixProof;
  124. vector<vector<TwistBipoint>> voteMatrix =
  125. get_server_committed_val<vector<vector<TwistBipoint>>>(
  126. rng,
  127. serverIPs,
  128. serverPorts,
  129. voteMatrixProof,
  130. shortTermPublicKey,
  131. VOTE_MATRIX_URI,
  132. VOTE_MATRIX_COMMIT_URI);
  133. vector<Proof> pseudonymsProof;
  134. vector<Twistpoint> currentPseudonyms =
  135. get_server_committed_val<vector<Twistpoint>>(
  136. rng,
  137. serverIPs,
  138. serverPorts,
  139. pseudonymsProof,
  140. shortTermPublicKey,
  141. PSEUDONYMS_URI,
  142. PSEUDONYMS_COMMIT_URI);
  143. newUser->receive_new_user_data(
  144. proofOfValidAddition,
  145. serverEncryptedScoreProof,
  146. serverEncryptedScore,
  147. userEncryptedScoreProof,
  148. userEncryptedScore,
  149. voteMatrixProof,
  150. voteMatrix,
  151. pseudonymsProof,
  152. currentPseudonyms);
  153. }
  154. void register_new_client(
  155. default_random_engine *generator,
  156. const vector<string>& serverIPs,
  157. const vector<int>& serverPorts,
  158. PrsonaClient *newUser,
  159. const Proof& proofOfValidSTPK,
  160. const Twistpoint& shortTermPublicKey)
  161. {
  162. struct synchronization_tool sync;
  163. char *filename = NULL;
  164. stringstream buffer;
  165. string data;
  166. buffer << proofOfValidSTPK;
  167. buffer << shortTermPublicKey;
  168. data = buffer.str();
  169. uniform_int_distribution<size_t> distribution(0, serverIPs.size() - 1);
  170. size_t whichServer = distribution(*generator);
  171. bool flag = false;
  172. while (!flag)
  173. {
  174. struct mg_connection *conn = mg_connect_websocket_client(
  175. serverIPs[whichServer].c_str(),
  176. serverPorts[whichServer],
  177. USE_SSL,
  178. NULL,
  179. 0,
  180. ADD_USER_URI,
  181. "null",
  182. file_websocket_data_handler,
  183. file_websocket_close_handler,
  184. (void *) &sync);
  185. if (!conn)
  186. {
  187. cerr << "Couldn't register new client" << endl;
  188. continue;
  189. }
  190. unique_lock<mutex> lck(sync.mtx);
  191. filename = set_temp_filename(*generator, conn);
  192. sync.val = 0;
  193. mg_websocket_client_write(
  194. conn,
  195. MG_WEBSOCKET_OPCODE_BINARY,
  196. data.c_str(),
  197. data.length());
  198. mg_websocket_client_write(
  199. conn,
  200. MG_WEBSOCKET_OPCODE_DATACOMPLETE,
  201. "",
  202. 0);
  203. while (!sync.val)
  204. sync.cv.wait(lck);
  205. mg_close_connection(conn);
  206. flag = true;
  207. }
  208. vector<Proof> proofOfValidAddition =
  209. get_valid_addition_proof_from_file(&sync, filename);
  210. remove(filename);
  211. delete [] filename;
  212. verify_valid_addition(newUser, generator, serverIPs, serverPorts, proofOfValidAddition, shortTermPublicKey);
  213. }
  214. PrsonaClient *create_client(
  215. default_random_engine *generator,
  216. const vector<string>& serverIPs,
  217. const vector<int>& serverPorts,
  218. size_t numServers)
  219. {
  220. BGNPublicKey publicKey =
  221. get_bgn_public_key(
  222. generator,
  223. serverIPs,
  224. serverPorts);
  225. vector<Proof> generatorProof;
  226. Twistpoint blindGenerator =
  227. get_generator(
  228. generator,
  229. serverIPs,
  230. serverPorts,
  231. generatorProof,
  232. false);
  233. PrsonaClient *retval =
  234. new PrsonaClient(generatorProof, blindGenerator, publicKey, numServers);
  235. generatorProof.clear();
  236. Twistpoint freshGenerator =
  237. get_generator(
  238. generator,
  239. serverIPs,
  240. serverPorts,
  241. generatorProof,
  242. true);
  243. retval->receive_fresh_generator(
  244. generatorProof, freshGenerator);
  245. Proof proofOfValidSTPK;
  246. Twistpoint shortTermPublicKey = retval->get_short_term_public_key(
  247. proofOfValidSTPK);
  248. register_new_client(
  249. generator,
  250. serverIPs,
  251. serverPorts,
  252. retval,
  253. proofOfValidSTPK,
  254. shortTermPublicKey);
  255. return retval;
  256. }
  257. string make_vote_string(
  258. const vector<Proof>& pi,
  259. const vector<TwistBipoint>& newVotes,
  260. const Twistpoint& shortTermPublicKey)
  261. {
  262. stringstream buffer;
  263. BinarySizeT sizeOfVector;
  264. sizeOfVector.set(pi.size());
  265. buffer << sizeOfVector;
  266. for (size_t i = 0; i < sizeOfVector.val(); i++)
  267. buffer << pi[i];
  268. sizeOfVector.set(newVotes.size());
  269. buffer << sizeOfVector;
  270. for (size_t i = 0; i < sizeOfVector.val(); i++)
  271. buffer << newVotes[i];
  272. buffer << shortTermPublicKey;
  273. BinaryBool shouldDeal(true);
  274. buffer << shouldDeal;
  275. return buffer.str();
  276. }
  277. char *send_item(
  278. std::default_random_engine& rng,
  279. const string& target,
  280. int targetPort,
  281. const string& data,
  282. const char* whichUri,
  283. bool responseExpected)
  284. {
  285. struct synchronization_tool sync;
  286. char *retval = NULL;
  287. unique_lock<mutex> lck(sync.mtx);
  288. sync.val = 0;
  289. sync.val2 = 0;
  290. while (!sync.val)
  291. {
  292. struct mg_connection *conn = NULL;
  293. while (!conn)
  294. {
  295. if (responseExpected)
  296. {
  297. conn = mg_connect_websocket_client(
  298. target.c_str(),
  299. targetPort,
  300. USE_SSL,
  301. NULL,
  302. 0,
  303. whichUri,
  304. "null",
  305. file_websocket_data_handler,
  306. file_websocket_close_handler,
  307. (void *) &sync);
  308. }
  309. else
  310. {
  311. conn = mg_connect_websocket_client(
  312. target.c_str(),
  313. targetPort,
  314. USE_SSL,
  315. NULL,
  316. 0,
  317. whichUri,
  318. "null",
  319. synchro_websocket_data_handler,
  320. synchro_websocket_close_handler,
  321. (void *) &sync);
  322. }
  323. if (!conn)
  324. cerr << "Couldn't connect to server for purposes of sending item." << endl;
  325. }
  326. if (responseExpected)
  327. retval = set_temp_filename(rng, conn);
  328. mg_websocket_client_write(
  329. conn,
  330. MG_WEBSOCKET_OPCODE_BINARY,
  331. data.c_str(),
  332. data.length());
  333. mg_websocket_client_write(
  334. conn,
  335. MG_WEBSOCKET_OPCODE_DATACOMPLETE,
  336. "",
  337. 0);
  338. while (!sync.val2)
  339. sync.cv.wait(lck);
  340. mg_close_connection(conn);
  341. }
  342. return retval;
  343. }
  344. void make_vote(
  345. default_random_engine& generator,
  346. const string& target,
  347. int targetPort,
  348. PrsonaClient* prsonaClient,
  349. const vector<string>& serverIPs,
  350. const vector<int>& serverPorts,
  351. size_t numClients)
  352. {
  353. uniform_int_distribution<int> voteDistribution(
  354. 0, PrsonaBase::get_max_allowed_vote());
  355. uniform_int_distribution<int> numVoteDistribution(
  356. 0, numClients);
  357. size_t numVotes = numVoteDistribution(generator);
  358. // Make the correct number of new votes, but shuffle where they go
  359. vector<Scalar> votes;
  360. vector<bool> replaces;
  361. for (size_t j = 0; j < numClients; j++)
  362. {
  363. votes.push_back(Scalar(voteDistribution(generator)));
  364. replaces.push_back(j < numVotes);
  365. }
  366. shuffle(replaces.begin(), replaces.end(), generator);
  367. vector<Proof> generatorProof;
  368. Twistpoint freshGenerator =
  369. get_generator(
  370. &generator,
  371. serverIPs,
  372. serverPorts,
  373. generatorProof,
  374. true);
  375. prsonaClient->receive_fresh_generator(
  376. generatorProof, freshGenerator);
  377. Twistpoint shortTermPublicKey =
  378. prsonaClient->get_short_term_public_key();
  379. vector<Proof> fullProof;
  380. vector<TwistBipoint> encryptedVotes =
  381. get_server_committed_val<vector<TwistBipoint>>(
  382. &generator,
  383. serverIPs,
  384. serverPorts,
  385. fullProof,
  386. shortTermPublicKey,
  387. VOTES_BY_URI,
  388. VOTES_BY_COMMIT_URI);
  389. vector<Proof> voteProof;
  390. encryptedVotes =
  391. prsonaClient->make_votes(
  392. voteProof,
  393. fullProof,
  394. encryptedVotes,
  395. votes,
  396. replaces);
  397. string data =
  398. make_vote_string(voteProof, encryptedVotes, shortTermPublicKey);
  399. send_item(generator, target, targetPort, data, GIVE_NEW_VOTE_URI, false);
  400. }
  401. string make_vote_string(
  402. const vector<Proof>& pi,
  403. const Twistpoint& shortTermPublicKey,
  404. const Scalar& threshold)
  405. {
  406. stringstream buffer;
  407. BinarySizeT sizeOfVector;
  408. sizeOfVector.set(pi.size());
  409. buffer << sizeOfVector;
  410. for (size_t i = 0; i < sizeOfVector.val(); i++)
  411. buffer << pi[i];
  412. buffer << shortTermPublicKey;
  413. buffer << threshold;
  414. return buffer.str();
  415. }
  416. string make_rep_proof_string(
  417. const vector<Proof>& pi,
  418. const Twistpoint& shortTermPublicKey,
  419. const Scalar& threshold)
  420. {
  421. stringstream buffer;
  422. BinarySizeT sizeOfVector;
  423. sizeOfVector.set(pi.size());
  424. buffer << sizeOfVector;
  425. for (size_t i = 0; i < sizeOfVector.val(); i++)
  426. buffer << pi[i];
  427. buffer << shortTermPublicKey;
  428. buffer << threshold;
  429. return buffer.str();
  430. }
  431. bool make_reputation_proof(
  432. default_random_engine& generator,
  433. const string& target,
  434. int targetPort,
  435. PrsonaClient* prsonaClient,
  436. const vector<string>& serverIPs,
  437. const vector<int>& serverPorts,
  438. size_t numClients)
  439. {
  440. vector<Proof> generatorProof;
  441. Twistpoint freshGenerator =
  442. get_generator(
  443. &generator,
  444. serverIPs,
  445. serverPorts,
  446. generatorProof,
  447. true);
  448. prsonaClient->receive_fresh_generator(
  449. generatorProof, freshGenerator);
  450. Twistpoint shortTermPublicKey =
  451. prsonaClient->get_short_term_public_key();
  452. vector<Proof> encryptedScoreProof;
  453. EGCiphertext encryptedScore =
  454. get_server_committed_val<EGCiphertext>(
  455. &generator,
  456. serverIPs,
  457. serverPorts,
  458. encryptedScoreProof,
  459. shortTermPublicKey,
  460. USER_TALLY_URI,
  461. USER_TALLY_COMMIT_URI);
  462. prsonaClient->receive_vote_tally(
  463. encryptedScoreProof,
  464. encryptedScore);
  465. Scalar threshold(0);
  466. vector<Proof> repProof =
  467. prsonaClient->generate_reputation_proof(
  468. threshold, numClients);
  469. string data =
  470. make_rep_proof_string(repProof, shortTermPublicKey, threshold);
  471. char *responseFile = send_item(generator, target, targetPort, data, REP_PROOF_URI, true);
  472. ifstream response(responseFile);
  473. char passed = response.get();
  474. remove(responseFile);
  475. delete responseFile;
  476. return passed == '\x01';
  477. }
  478. int main(int argc, char *argv[])
  479. {
  480. initialize_prsona_classes();
  481. #if USE_SSL
  482. mg_init_library(0);
  483. #else
  484. mg_init_library(MG_FEATURES_SSL);
  485. #endif
  486. string id = "";
  487. if (argc > 1)
  488. id = argv[1];
  489. string seedStr;
  490. if (id.empty())
  491. seedStr = "default-client";
  492. else
  493. {
  494. seedStr = id;
  495. seedStr += "-client";
  496. }
  497. vector<string> serverIPs, clientIPs;
  498. vector<int> serverPorts, clientPorts;
  499. string selfIP, selfPortStr;
  500. int selfPort = 0;
  501. char buffer[46], *helper;
  502. ifstream serverConfig("cfg/serverIPs.cfg");
  503. while (!serverConfig.eof())
  504. {
  505. serverConfig.getline(buffer, 46);
  506. if (strlen(buffer) > 0)
  507. {
  508. helper = buffer;
  509. if (strchr(helper, ':'))
  510. {
  511. helper = strtok(helper, ":");
  512. serverIPs.push_back(string(helper));
  513. helper = strtok(NULL, ":");
  514. serverPorts.push_back(atoi(helper));
  515. }
  516. else
  517. {
  518. serverIPs.push_back(string(helper));
  519. serverPorts.push_back(atoi(PRSONA_PORT_STR));
  520. }
  521. }
  522. }
  523. ifstream clientConfig("cfg/clientIPs.cfg");
  524. while (!clientConfig.eof())
  525. {
  526. clientConfig.getline(buffer, 46);
  527. if (strlen(buffer) > 0)
  528. {
  529. helper = buffer;
  530. if (strchr(helper, ':'))
  531. {
  532. helper = strtok(helper, ":");
  533. clientIPs.push_back(string(helper));
  534. helper = strtok(NULL, ":");
  535. clientPorts.push_back(atoi(helper));
  536. }
  537. else
  538. {
  539. clientIPs.push_back(string(helper));
  540. clientPorts.push_back(atoi(PRSONA_PORT_STR));
  541. }
  542. }
  543. }
  544. string selfConfigFilename = "cfg/selfIP";
  545. if (!id.empty())
  546. {
  547. selfConfigFilename += "-";
  548. selfConfigFilename += id;
  549. }
  550. selfConfigFilename += ".cfg";
  551. ifstream selfConfig(selfConfigFilename);
  552. while (!selfConfig.eof())
  553. {
  554. selfConfig.getline(buffer, 46);
  555. if (strlen(buffer) > 0)
  556. {
  557. helper = buffer;
  558. if (strchr(helper, ':'))
  559. {
  560. helper = strtok(helper, ":");
  561. selfIP = helper;
  562. helper = strtok(NULL, ":");
  563. selfPortStr = helper;
  564. selfPort = atoi(helper);
  565. }
  566. else
  567. {
  568. selfIP = helper;
  569. selfPortStr = PRSONA_PORT_STR;
  570. selfPort = atoi(PRSONA_PORT_STR);
  571. }
  572. }
  573. }
  574. // Defaults
  575. size_t numServers = serverIPs.size();
  576. size_t numClients = clientIPs.size();
  577. bool maliciousServers = true;
  578. uniform_int_distribution<size_t> distribution(0, numServers - 1);
  579. const char *options[] = {"listening_ports", selfPortStr.c_str(), 0};
  580. if (argc > 2)
  581. {
  582. bool setting = argv[2][0] == 't' || argv[2][0] == 'T';
  583. maliciousServers = setting;
  584. }
  585. seed_seq seed(seedStr.begin(), seedStr.end());
  586. default_random_engine generator(seed);
  587. cout << "[" << seedStr << "] Establishing PRSONA client with the following parameters: " << endl;
  588. cout << "[" << seedStr << "] " << numServers << " PRSONA servers" << endl;
  589. cout << "[" << seedStr << "] " << numClients << " PRSONA clients" << endl;
  590. cout << "[" << seedStr << "] Servers are set to " << (maliciousServers ? "MALICIOUS" : "HBC") << " security" << endl;
  591. cout << "[" << seedStr << "] This client is at IP address: " << selfIP << ":" << selfPort << endl;
  592. cout << endl;
  593. // Set malicious flags where necessary
  594. if (maliciousServers)
  595. PrsonaBase::set_server_malicious();
  596. // Entities we operate with
  597. cout << "[" << seedStr << "] Creating PRSONA client." << endl;
  598. PrsonaClient *prsonaClient =
  599. create_client(&generator, serverIPs, serverPorts, numServers);
  600. CivetServer server(options);
  601. cout << "[" << seedStr << "] Setting up handlers for client." << endl;
  602. PrsonaClientWebSocketHandler wsHandler(prsonaClient, serverIPs, serverPorts, &generator);
  603. server.addWebSocketHandler("/ws", wsHandler);
  604. struct synchronization_tool exitSync;
  605. unique_lock<mutex> exitLock(exitSync.mtx);
  606. exitSync.val = 0;
  607. exitSync.val2 = 0;
  608. RemoteControlHandler exitHandler(&exitSync, "Client coming down!");
  609. server.addHandler(EXIT_URI, exitHandler);
  610. AltRemoteControlHandler triggerVoteHandler(CLIENT_MAKE_VOTE, &exitSync, "Client will make new votes!");
  611. server.addHandler(TRIGGER_VOTE_URI, triggerVoteHandler);
  612. AltRemoteControlHandler triggerRepHandler(CLIENT_MAKE_REP_PROOF, &exitSync, "Client will make reputation proof!");
  613. server.addHandler(TRIGGER_REP_URI, triggerRepHandler);
  614. cout << "[" << seedStr << "] Entering main ready loop." << endl;
  615. while (!exitSync.val)
  616. {
  617. while (!exitSync.val && !exitSync.val2)
  618. exitSync.cv.wait(exitLock);
  619. size_t whichServer = distribution(generator);
  620. string fullQuery, target;
  621. size_t colonLocation;
  622. int targetPort;
  623. switch (exitSync.val2)
  624. {
  625. case CLIENT_MAKE_VOTE:
  626. cout << "[" << seedStr << "] Making new vote row." << endl;
  627. make_vote(
  628. generator,
  629. serverIPs[whichServer],
  630. serverPorts[whichServer],
  631. prsonaClient,
  632. serverIPs,
  633. serverPorts,
  634. numClients);
  635. cout << "[" << seedStr << "] New vote row complete." << endl;
  636. break;
  637. case CLIENT_MAKE_REP_PROOF:
  638. fullQuery = triggerRepHandler.getQuery();
  639. colonLocation = fullQuery.find(":");
  640. target = fullQuery.substr(0, colonLocation);
  641. targetPort = stoi(fullQuery.substr(colonLocation + 1));
  642. cout << "[" << seedStr << "] Making new reputation proof." << endl;
  643. make_reputation_proof(
  644. generator,
  645. target,
  646. targetPort,
  647. prsonaClient,
  648. serverIPs,
  649. serverPorts,
  650. numClients);
  651. cout << "[" << seedStr << "] New reputation proof complete." << endl;
  652. break;
  653. default:
  654. break;
  655. }
  656. exitSync.val2 = 0;
  657. }
  658. cout << "[" << seedStr << "] Shutting down." << endl;
  659. mg_exit_library();
  660. delete prsonaClient;
  661. return 0;
  662. }