main.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. // #include <boost/program_options.hpp>
  2. // namespace po = boost::program_options;
  3. #include <iostream>
  4. #include <algorithm>
  5. #include <random>
  6. #include <chrono>
  7. #include "BGN.hpp"
  8. #include "client.hpp"
  9. #include "server.hpp"
  10. #include "serverEntity.hpp"
  11. using namespace std;
  12. const int MAX_ALLOWED_VOTE = 2;
  13. // int argparse(
  14. // int argc,
  15. // char *argv[],
  16. // size_t &numServers,
  17. // size_t &numClients,
  18. // size_t &numRounds,
  19. // size_t &numVotes,
  20. // bool &maliciousServers,
  21. // bool &maliciousUsers,
  22. // string &seedStr)
  23. // {
  24. // string config_file;
  25. // // Declare a group of options that will be
  26. // // allowed only on command line
  27. // po::options_description generic("General options");
  28. // generic.add_options()
  29. // ("help", "produce this help message")
  30. // ("config,c", po::value<string>(&config_file)->default_value(""),
  31. // "name of a configuration file")
  32. // ;
  33. // // Declare a group of options that will be
  34. // // allowed both on command line and in
  35. // // config file
  36. // po::options_description config("Configuration");
  37. // config.add_options()
  38. // ("malicious-servers,M",
  39. // "presence of this flag indicates servers will operate in malicious model")
  40. // ("malicious-users,U",
  41. // "presence of this flag indicates users will operate in malicious model")
  42. // ("seed", po::value<string>(&seedStr)->default_value("default"),
  43. // "the random seed to use for this test")
  44. // ;
  45. // // Hidden options, will be allowed both on command line and
  46. // // in config file, but will not be shown to the user.
  47. // po::options_description hidden("Hidden options");
  48. // hidden.add_options()
  49. // ("number-servers,S", po::value<size_t>(&numServers)->default_value(2),
  50. // "number of servers in test")
  51. // ("number-users,N", po::value<size_t>(&numClients)->default_value(5),
  52. // "number of users in test")
  53. // ("number-rounds,R", po::value<size_t>(&numRounds)->default_value(3),
  54. // "number of rounds to perform in test")
  55. // ("number-votes,V", po::value<size_t>(&numVotes)->default_value(3),
  56. // "number of votes each user makes per round during test")
  57. // ;
  58. // po::options_description cmdline_options;
  59. // cmdline_options.add(generic).add(config).add(hidden);
  60. // po::options_description config_file_options;
  61. // config_file_options.add(config).add(hidden);
  62. // po::options_description visible("Allowed options");
  63. // visible.add(generic).add(config);
  64. // po::positional_options_description p;
  65. // p.add("number-servers", 1);
  66. // p.add("number-users", 1);
  67. // p.add("number-rounds", 1);
  68. // p.add("number-votes", 1);
  69. // po::variables_map vm;
  70. // store(po::command_line_parser(argc, argv).
  71. // options(cmdline_options).positional(p).run(), vm);
  72. // notify(vm);
  73. // if (!config_file.empty())
  74. // {
  75. // ifstream config(config_file.c_str());
  76. // if (!config)
  77. // {
  78. // cerr << "Cannot open config file: " << config_file << "\n";
  79. // return 2;
  80. // }
  81. // else
  82. // {
  83. // store(parse_config_file(config, config_file_options), vm);
  84. // notify(vm);
  85. // }
  86. // }
  87. // if (vm.count("help"))
  88. // {
  89. // cout << visible << endl;
  90. // return 1;
  91. // }
  92. // maliciousServers = vm.count("malicious-servers");
  93. // maliciousUsers = vm.count("malicious-users");
  94. // return 0;
  95. // }
  96. // Initialize the classes we use
  97. void initialize_prsona_classes()
  98. {
  99. Scalar::init();
  100. Curvepoint elGamalBlindGenerator = PrsonaServer::init();
  101. PrsonaClient::init(elGamalBlindGenerator);
  102. }
  103. // Do an epoch (including votes, etc.), and return the timing to print out
  104. double epoch(
  105. default_random_engine& generator,
  106. PrsonaServerEntity& servers,
  107. vector<PrsonaClient>& users,
  108. size_t numVotes)
  109. {
  110. Proof unused;
  111. uniform_int_distribution<int> voteDistribution(0, MAX_ALLOWED_VOTE);
  112. size_t numUsers = users.size();
  113. for (size_t i = 0; i < numUsers; i++)
  114. {
  115. // Make the correct number of new votes, but shuffle where they go
  116. vector<Scalar> votes;
  117. vector<bool> replace;
  118. for (size_t j = 0; j < numUsers; j++)
  119. {
  120. votes.push_back(Scalar(voteDistribution(generator)));
  121. replace.push_back(j < numVotes);
  122. }
  123. shuffle(replace.begin(), replace.end(), generator);
  124. // Make the actual votes to give to the servers
  125. Proof pi;
  126. Curvepoint shortTermPublicKey = users[i].get_short_term_public_key(pi);
  127. vector<CurveBipoint> encryptedVotes = users[i].make_votes(
  128. pi, votes, replace);
  129. // Give the servers these new votes
  130. servers.receive_vote(pi, encryptedVotes, shortTermPublicKey);
  131. }
  132. // Do the epoch server calculations
  133. chrono::high_resolution_clock::time_point t0 =
  134. chrono::high_resolution_clock::now();
  135. servers.epoch(unused);
  136. chrono::high_resolution_clock::time_point t1 =
  137. chrono::high_resolution_clock::now();
  138. // Transmit the results of the epoch to each user
  139. for (size_t i = 0; i < numUsers; i++)
  140. servers.transmit_updates(users[i]);
  141. // Return the timing of the epoch server calculations
  142. chrono::duration<double> time_span =
  143. chrono::duration_cast<chrono::duration<double>>(t1 - t0);
  144. return time_span.count();
  145. }
  146. int main(int argc, char *argv[])
  147. {
  148. initialize_prsona_classes();
  149. // Defaults
  150. size_t numServers = 2;
  151. size_t numUsers = 5;
  152. size_t numRounds = 3;
  153. size_t numVotesPerRound = 3;
  154. bool maliciousServers = false;
  155. bool maliciousUsers = false;
  156. string seedStr = "seed";
  157. // Potentially accept command line inputs
  158. if (argc > 1)
  159. numServers = atoi(argv[1]);
  160. if (argc > 2)
  161. numUsers = atoi(argv[2]);
  162. if (argc > 3)
  163. numRounds = atoi(argv[3]);
  164. if (argc > 4)
  165. numVotesPerRound = atoi(argv[4]);
  166. cout << "Running the protocol with the following parameters: " << endl;
  167. cout << numServers << " PRSONA servers" << endl;
  168. cout << numUsers << " participants (voters/votees)" << endl;
  169. cout << numRounds << " epochs" << endl;
  170. cout << numVotesPerRound << " new (random) votes by each user per epoch"
  171. << endl;
  172. // Set malicious flags where necessary
  173. if (maliciousServers)
  174. {
  175. PrsonaServer::set_server_malicious();
  176. PrsonaClient::set_server_malicious();
  177. }
  178. if (maliciousUsers)
  179. {
  180. PrsonaServer::set_client_malicious();
  181. PrsonaClient::set_client_malicious();
  182. }
  183. // Entities we operate with
  184. PrsonaServerEntity servers(numServers);
  185. BGNPublicKey bgnPublicKey = servers.get_bgn_public_key();
  186. cout << "Initialization: adding users to system" << endl;
  187. vector<PrsonaClient> users;
  188. for (size_t i = 0; i < numUsers; i++)
  189. {
  190. PrsonaClient currUser(bgnPublicKey, &servers);
  191. servers.add_new_client(currUser);
  192. users.push_back(currUser);
  193. }
  194. // Seeded randomness for random votes used in epoch
  195. seed_seq seed(seedStr.begin(), seedStr.end());
  196. default_random_engine generator(seed);
  197. for (size_t i = 0; i < numRounds; i++)
  198. {
  199. cout << "Round " << i+1 << " of " << numRounds << ": " << endl;
  200. double timing = epoch(generator, servers, users, numVotesPerRound);
  201. cout << "Server computation: " << timing << " seconds" << endl;
  202. }
  203. return 0;
  204. }