/* Copyright (C) 2014 Carlos Aguilar Melchor, Joris Barrier, Marc-Olivier Killijian * This file is part of XPIR. * * XPIR is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * XPIR is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with XPIR. If not, see . */ #include "OptimService.hpp" const std::string OptimService::folderName = "exp/"; const std::string OptimService::fileName = "preCompute"; const std::string OptimService::absFileExtension = ".abs"; const std::string OptimService::decFileExtension = ".dec"; const std::string OptimService::encFileExtension = ".enc"; const std::string OptimService::getCurrentTime() { time_t now = time(0); struct tm tstruct; char buf[80]; tstruct = *localtime(&now); strftime(buf, sizeof(buf), "%Y-%m-%d.%X", &tstruct); return buf; } int OptimService::getNumberOfExperiences(std::string testValuesFileName) { std::string line; std::ifstream f(testValuesFileName); int i = 0; if(!f.is_open()) return -1; while (std::getline(f, line)) { if(!(line.c_str()[0] == '#')) i++;//jump over commented line } f.close(); return --i; } int OptimService::readTestValues(unsigned int i, FixedVars& vars, std::string testValuesFileName) { std::ifstream f(testValuesFileName, std::ios::in); std::string line; std::vector fields; if (f.is_open()) { for (unsigned k = 0 ; k < i+1 ; k++) { std::getline(f, line); if(line.c_str()[0] == '#') i++;//jump over commented line } boost::algorithm::split(fields, line, boost::algorithm::is_any_of(" ")); vars.n = atoi(fields[0].c_str()); vars.l = atoi(fields[1].c_str()); vars.Tupc = vars.Tdos = static_cast(atol(fields[2].c_str())); vars.Tdoc = vars.Tups = static_cast(atol(fields[3].c_str())); vars.k = atoi(fields[4].c_str()); vars.alphaMax = atoi(fields[5].c_str()); vars.dMax = atoi(fields[6].c_str()); } else { return 1; } f.close(); return 0; } void OptimService::writeHeadFile(unsigned int i, FixedVars& fixedVars) { std::ofstream file(std::string("exp/exp"+ std::to_string(i)).c_str(), std::ios::out); file << "# " << std::string("exp" + std::to_string(i)) << " " << getCurrentTime() << std::endl; file << "#Fixed Param : n " << fixedVars.n << ", l " << fixedVars.l << ", Tupc " << fixedVars.Tupc << ", Tdoc " << fixedVars.Tdoc <<", k " << fixedVars.k << std::endl; file << "#Bound Param : " << ", alphaMax " << fixedVars.alphaMax << ", dMax " << fixedVars.dMax << std::endl; 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; file.close(); } int OptimService::readEntireFile(std::string& file_content, const std::string& file_path) { std::ifstream f(file_path); if (!f.is_open()) { f.close(); return 1; } getline(f, file_content, (char)EOF); f.close(); return 0; } int OptimService::readOptimData(map& values, const std::string& file_path) { std::ifstream f(file_path); if(!f.good()) { f.close(); return 1; } std::string line; std::vector fields; while (std::getline(f, line)) { boost::algorithm::split(fields, line, boost::algorithm::is_any_of(" ")); values[fields.at(0)] = atof(fields.at(1).c_str()); } f.close(); return 0; } /** * Write test result into file exp/exp{$exp_nbr} * Params are self explanatory **/ 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) { // Open output file exp/exp{$exp_nbr} std::ofstream file(std::string("exp/exp"+ std::to_string(exp_nbr)).c_str(), std::ios::out | std::ios::app ); // Try to output double values always with the same amount of decimals file.setf( std::ios::fixed, std:: ios::floatfield ); // Output test result in a line 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; file.close(); } int OptimService::writeOptimDataBuffer(const std::string& buffer, const std::string& file_path) { std::ofstream f(file_path); if (!f.good()) { f.close(); return 1; } f << buffer; f.close(); return 0; } void OptimService::writeFootFile(unsigned int i) { std::ofstream file(std::string("exp/exp"+ std::to_string(i)).c_str(), std::ios::out | std::ios::app ); file << std::endl <<"#End " << getCurrentTime() << std::endl; file.close(); } void OptimService::writeTestCurrentResult(unsigned int alpha, unsigned int alphaMul, unsigned int d, unsigned int i, OptimVars& vars) { std::ofstream file(std::string("exp/exp"+ std::to_string(i)).c_str(), std::ios::out | std::ios::app ); file.setf( std::ios::fixed, std:: ios::floatfield ); 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; file.close(); } void OptimService::writeMessage(unsigned int i, std::string const& message) { std::ofstream file(std::string("exp/exp"+ std::to_string(i)).c_str(), std::ios::out | std::ios::app ); file << message << std::endl; file.close(); } void OptimService::writeConfigFile(unsigned int alpha, unsigned int alphaMul, unsigned int d, unsigned int exp_nbr) { std::ofstream file(std::string("configFile" + std::to_string(exp_nbr)).c_str(), std::ios::out); file << "alpha\t" << alpha << endl; file << "alphaM\t" << alphaMul << endl; file.close(); } unsigned int i = 0; string line; while (std::getline(f, line)) { if(!(line.c_str()[0] == '#')) i++;//jump over commented line } return i; } // Returns true if optimization file does not exist or is outdated bool OptimService::fileOutdated(std::string crypto_name, std::string extension) { map cache; std::string file_path(OptimService::folderName + OptimService::fileName + crypto_name + extension); // Try to open and read the file // If it fails suppose that it is because the file does not exist if(readOptimData(cache, file_path)) { std::cout << "OptimService: Could not access cache file" << std::endl; return true; } // Get a set with all the crypto parameters of the requested cryptosystem CryptographicSystem* crypto_ptr = HomomorphicCryptoFactory_internal::getCrypto(crypto_name); std::set crypto_params_set; crypto_ptr->getAllCryptoParams(crypto_params_set); // Try to find each crypto_param in the cache and remove it for (auto crypto_param : crypto_params_set) { // If there is an element missing in the cache file is outdated if (cache.erase(crypto_param) == 0) { std::cout << "OptimService: "<< crypto_param << " not found in the cache" << std::endl; delete crypto_ptr; return true; } } // If some values in the cache do not correspond to a crypto_param file is outdated if(!cache.empty()) { std::cout << "OptimService: " << extension << " cache has too many entries" << std::endl; delete crypto_ptr; return true; } delete crypto_ptr; return false; }