OptimService.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. /* Copyright (C) 2014 Carlos Aguilar Melchor, Joris Barrier, Marc-Olivier Killijian
  2. * This file is part of XPIR.
  3. *
  4. * XPIR is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * XPIR is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with XPIR. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "OptimService.hpp"
  18. const std::string OptimService::folderName = "exp/";
  19. const std::string OptimService::fileName = "preCompute";
  20. const std::string OptimService::absFileExtension = ".abs";
  21. const std::string OptimService::decFileExtension = ".dec";
  22. const std::string OptimService::encFileExtension = ".enc";
  23. const std::string OptimService::getCurrentTime()
  24. {
  25. time_t now = time(0);
  26. struct tm tstruct;
  27. char buf[80];
  28. tstruct = *localtime(&now);
  29. strftime(buf, sizeof(buf), "%Y-%m-%d.%X", &tstruct);
  30. return buf;
  31. }
  32. void OptimService::getAllOptimData(std::vector<FixedVars>& fixed_vars_vec, std::string testValuesFileName)
  33. {
  34. unsigned int experience_nbr = getNumberOfExperiences(testValuesFileName);
  35. for(unsigned int i = 0 ; i < experience_nbr ; i++)
  36. {
  37. FixedVars vars;
  38. readTestValues(i, vars, testValuesFileName);
  39. fixed_vars_vec.push_back(vars);
  40. }
  41. }
  42. int OptimService::getNumberOfExperiences(std::string testValuesFileName)
  43. {
  44. std::string line;
  45. std::ifstream f(testValuesFileName);
  46. int i = 0;
  47. if(!f.is_open())
  48. return -1;
  49. while (std::getline(f, line))
  50. {
  51. if(!(line.c_str()[0] == '#')) i++;//jump over commented line
  52. }
  53. f.close();
  54. return --i;
  55. }
  56. int OptimService::readTestValues(unsigned int i, FixedVars& vars, std::string testValuesFileName)
  57. {
  58. std::ifstream f(testValuesFileName, std::ios::in);
  59. std::string line;
  60. std::vector<std::string> fields;
  61. if (f.is_open())
  62. {
  63. for (unsigned k = 0 ; k < i+1 ; k++)
  64. {
  65. std::getline(f, line);
  66. if(line.c_str()[0] == '#') i++;//jump over commented line
  67. }
  68. boost::algorithm::split(fields, line, boost::algorithm::is_any_of(" "));
  69. vars.n = atoi(fields[0].c_str());
  70. vars.l = atoi(fields[1].c_str());
  71. vars.Tupc = vars.Tdos = static_cast<double>(atol(fields[2].c_str()));
  72. vars.Tdoc = vars.Tups = static_cast<double>(atol(fields[3].c_str()));
  73. vars.k = atoi(fields[4].c_str());
  74. vars.alphaMax = atoi(fields[5].c_str());
  75. vars.dMax = atoi(fields[6].c_str());
  76. }
  77. else
  78. {
  79. return 1;
  80. }
  81. f.close();
  82. return 0;
  83. }
  84. void OptimService::writeHeadFile(unsigned int i, FixedVars& fixedVars)
  85. {
  86. std::ofstream file(std::string("exp/exp"+ std::to_string(i)).c_str(), std::ios::out);
  87. file << "# " << std::string("exp" + std::to_string(i)) << " " << getCurrentTime() << std::endl;
  88. file << "#Fixed Param : n " << fixedVars.n << ", l " << fixedVars.l << ", Tupc " << fixedVars.Tupc << ", Tdoc " << fixedVars.Tdoc <<", k " << fixedVars.k << std::endl;
  89. file << "#Bound Param : " << ", alphaMax " << fixedVars.alphaMax << ", dMax " << fixedVars.dMax << std::endl;
  90. file << "#1:d 2a:alpha_min\t 2b:alpha_max\t 2c:current_best_alpha\t2d:alpha_lowbound\t2e:alpha_upbound\t3:GenQ \t 4:SendQ \t 5:GenR \t 6:SendR \t 7:DecR \t 8:Total Time (pot. pipelined)" << std::endl;
  91. file.close();
  92. }
  93. int OptimService::readEntireFile(std::string& file_content, const std::string& file_path)
  94. {
  95. std::ifstream f(file_path);
  96. if (!f.is_open())
  97. {
  98. f.close();
  99. return 1;
  100. }
  101. getline(f, file_content, (char)EOF);
  102. f.close();
  103. return 0;
  104. }
  105. int OptimService::readOptimData(map<std::string,double>& values, const std::string& file_path)
  106. {
  107. std::ifstream f(file_path);
  108. if(!f.good())
  109. {
  110. f.close();
  111. return 1;
  112. }
  113. std::string line;
  114. std::vector<std::string> fields;
  115. while (std::getline(f, line))
  116. {
  117. boost::algorithm::split(fields, line, boost::algorithm::is_any_of(" "));
  118. values[fields.at(0)] = atof(fields.at(1).c_str());
  119. }
  120. f.close();
  121. return 0;
  122. }
  123. /**
  124. * Write test result into file exp/exp{$exp_nbr}
  125. * Params are self explanatory
  126. **/
  127. void OptimService::writeTestCurrentResult(unsigned int alpha_min, unsigned int alpha_max, unsigned int alpha_curr, unsigned int a_inf_bound, unsigned int a_sup_bound, unsigned int d, unsigned int exp_nbr, OptimVars& vars)
  128. {
  129. // Open output file exp/exp{$exp_nbr}
  130. std::ofstream file(std::string("exp/exp"+ std::to_string(exp_nbr)).c_str(), std::ios::out | std::ios::app );
  131. // Try to output double values always with the same amount of decimals
  132. file.setf( std::ios::fixed, std:: ios::floatfield );
  133. // Output test result in a line
  134. file << d << "\t" << alpha_min << "\t" << alpha_max << "\t" << alpha_curr << "\t" << a_inf_bound << " \t" << a_sup_bound << "\t" << vars.getGenQ() << " \t " << vars.getSendQ() << " \t " << vars.getGenR() << "\t" << vars.getSendR() << " \t " << vars.getDecR() << "\t" << vars.getValue() << std::endl;
  135. file.close();
  136. }
  137. int OptimService::writeOptimData(double encrypt_time, double decrypt_time, std::string crypto_params_desc, std::string crypto_name)
  138. {
  139. std::ofstream fdec(folderName + fileName + crypto_name + decFileExtension, ios::app);
  140. std::ofstream fenc(folderName + fileName + crypto_name + encFileExtension, ios::app);
  141. fdec.setf( std::ios::fixed, std:: ios::floatfield );
  142. fenc.setf( std::ios::fixed, std:: ios::floatfield );
  143. if (!fdec.good() || !fenc.good())
  144. {
  145. fenc.close();
  146. fdec.close();
  147. return 1;
  148. }
  149. fenc << crypto_params_desc << " " << encrypt_time << std::endl;
  150. fdec << crypto_params_desc << " " << decrypt_time << std::endl;
  151. return 0;
  152. }
  153. int OptimService::writeOptimDataBuffer(const std::string& buffer, const std::string& file_path)
  154. {
  155. std::ofstream f(file_path);
  156. if (!f.good())
  157. {
  158. f.close();
  159. return 1;
  160. }
  161. f << buffer;
  162. f.close();
  163. return 0;
  164. }
  165. void OptimService::gotoLine(std::ifstream& file, unsigned int num)
  166. {
  167. if (num > 0)
  168. {
  169. file.seekg(std::ios::beg);
  170. for (unsigned int i = 0 ; i < num ; ++i)
  171. {
  172. file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
  173. }
  174. }
  175. }
  176. void OptimService::writeFootFile(unsigned int i)
  177. {
  178. std::ofstream file(std::string("exp/exp"+ std::to_string(i)).c_str(), std::ios::out | std::ios::app );
  179. file << std::endl <<"#End " << getCurrentTime() << std::endl;
  180. file.close();
  181. }
  182. void OptimService::writeTestCurrentResult(unsigned int alpha, unsigned int alphaMul, unsigned int d, unsigned int i, OptimVars& vars)
  183. {
  184. std::ofstream file(std::string("exp/exp"+ std::to_string(i)).c_str(), std::ios::out | std::ios::app );
  185. file.setf( std::ios::fixed, std:: ios::floatfield );
  186. file << d << "\t" << alpha << " \t" << alphaMul << "\t" << vars.getGenQ() << " \t " << vars.getSendQ() << " \t " << vars.getGenR() << "\t" << vars.getSendR() << " \t " << vars.getDecR() << "\t" << vars.getValue() << std::endl;
  187. file.close();
  188. }
  189. void OptimService::writeMessage(unsigned int i, std::string const& message)
  190. {
  191. std::ofstream file(std::string("exp/exp"+ std::to_string(i)).c_str(), std::ios::out | std::ios::app );
  192. file << message << std::endl;
  193. file.close();
  194. }
  195. void OptimService::writeConfigFile(unsigned int alpha, unsigned int alphaMul, unsigned int d, unsigned int exp_nbr)
  196. {
  197. std::ofstream file(std::string("configFile" + std::to_string(exp_nbr)).c_str(), std::ios::out);
  198. file << "alpha\t" << alpha << endl;
  199. file << "alphaM\t" << alphaMul << endl;
  200. file.close();
  201. }
  202. void OptimService::writeLWEFile(unsigned int order, unsigned int p_size, unsigned int exp_nbr)
  203. {
  204. std::ofstream file(std::string("LWEFile" + std::to_string(exp_nbr)).c_str(), std::ios::out);
  205. file << "degree\t" << order << endl;
  206. file << "p_size\t" << p_size << endl;
  207. file.close();
  208. }
  209. // Ugly test can cause segfault if file is somehow too big
  210. // Should try to build a cache dictionary and test whether the
  211. // desired crypto_params have been filled
  212. int OptimService::verifyOptimData(set<string> crypto_params_set, const std::string& fenc_path, const std::string& fdec_path)
  213. {
  214. string line_dec, line_enc;
  215. unsigned int params_nbr = crypto_params_set.size();
  216. int return_value = 1;
  217. std::ifstream fdec(fenc_path);
  218. std::ifstream fenc(fdec_path);
  219. if (!fenc.is_open() || !fdec.is_open())
  220. {
  221. return 0;
  222. }
  223. if(getNumberOfLines(fdec) < params_nbr || getNumberOfLines(fenc) < params_nbr)
  224. {
  225. fdec.close();
  226. fenc.close();
  227. std::ofstream fdec_in(fdec_path);
  228. std::ofstream fenc_in(fenc_path);
  229. fdec_in.close();
  230. fdec_in.close();
  231. return_value = 0;
  232. }
  233. fdec.close();
  234. fenc.close();
  235. return return_value;
  236. }
  237. unsigned int OptimService::getNumberOfLines(std::ifstream& f)
  238. {
  239. unsigned int i = 0;
  240. string line;
  241. while (std::getline(f, line))
  242. {
  243. if(!(line.c_str()[0] == '#')) i++;//jump over commented line
  244. }
  245. return i;
  246. }
  247. // Returns true if optimization file does not exist or is outdated
  248. bool OptimService::fileOutdated(std::string crypto_name, std::string extension)
  249. {
  250. map<string, double> cache;
  251. std::string file_path(OptimService::folderName + OptimService::fileName + crypto_name
  252. + extension);
  253. // Try to open and read the file
  254. // If it fails suppose that it is because the file does not exist
  255. if(readOptimData(cache, file_path))
  256. {
  257. std::cout << "OptimService: Could not access cache file" << std::endl;
  258. return true;
  259. }
  260. // Get a set with all the crypto parameters of the requested cryptosystem
  261. CryptographicSystem* crypto_ptr = HomomorphicCryptoFactory_internal::getCrypto(crypto_name);
  262. std::set<std::string> crypto_params_set;
  263. crypto_ptr->getAllCryptoParams(crypto_params_set);
  264. // Try to find each crypto_param in the cache and remove it
  265. for (auto crypto_param : crypto_params_set)
  266. {
  267. // If there is an element missing in the cache file is outdated
  268. if (cache.erase(crypto_param) == 0)
  269. {
  270. std::cout << "OptimService: "<< crypto_param << " not found in the cache" << std::endl;
  271. delete crypto_ptr;
  272. return true;
  273. }
  274. }
  275. // If some values in the cache do not correspond to a crypto_param file is outdated
  276. if(!cache.empty())
  277. {
  278. std::cout << "OptimService: " << extension << " cache has too many entries" << std::endl;
  279. delete crypto_ptr;
  280. return true;
  281. }
  282. delete crypto_ptr;
  283. return false;
  284. }