PIRSession.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  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 "PIRSession.hpp"
  18. #include "pir/replyGenerator/PIROptimizer.hpp"
  19. #define NDSS_UPLOAD_SPEED 100000000UL
  20. PIRSession::pointer PIRSession::create(boost::asio::io_service& ios)
  21. {
  22. return PIRSession::pointer(new PIRSession(ios));
  23. }
  24. PIRSession::PIRSession(boost::asio::io_service& ios) :
  25. sessionSocket(ios),
  26. handmadeExceptionRaised(false),
  27. finished(false),
  28. cryptoMethod(NULL),
  29. generator(NULL),
  30. no_pipeline_mode(false)
  31. {
  32. }
  33. void PIRSession::setDBHandler(DBHandler *db)
  34. {
  35. dbhandler = db;
  36. }
  37. /**
  38. * Do the PIR protocol
  39. **/
  40. bool PIRSession::start(session_option_t session_option)
  41. {
  42. uint64_t nbFiles=dbhandler->getNbStream();
  43. maxFileBytesize = dbhandler->getmaxFileBytesize();
  44. short exchange_method = (session_option.driven_mode) ? CLIENT_DRIVEN : SERVER_DRIVEN;
  45. bool rcv_paramsandkey = true;
  46. // Deal with Optimizer dry-run queries if requested
  47. if(!rcvIsClient())
  48. {
  49. std::cout << "PIRSession: Incoming dry-run optimizer request, dealing with it ..." << std::endl;
  50. PIROptimizer optimizer(dbhandler);
  51. optimizer.prepareOptimData();
  52. optimizer.controlAndCommand(sessionSocket);
  53. std::cout << "PIRSession: Session finished" << std::endl << std::endl;
  54. finished = true;
  55. return 1; // Did deal with a dry-run query
  56. }
  57. sendCatalog();
  58. sendPIRParamsExchangeMethod(exchange_method);
  59. if(session_option.driven_mode) {
  60. PIROptimizer optimizer(dbhandler);
  61. optimizer.prepareOptimData();
  62. optimizer.controlAndCommand(sessionSocket);
  63. rcvCryptoParams(rcv_paramsandkey);
  64. rcvPirParams();
  65. }
  66. else //not driven
  67. {
  68. std::vector<std::string> fields;
  69. boost::algorithm::split(fields, pirParam.crypto_params, boost::algorithm::is_any_of(GlobalConstant::kDelim));
  70. cryptoMethod = HomomorphicCryptoFactory_internal::getCrypto(fields.at(0));
  71. cryptoMethod->setNewParameters(pirParam.crypto_params);
  72. generator = PIRReplyGeneratorFactory::getPIRReplyGenerator(fields.at(0), pirParam,dbhandler);
  73. generator->setCryptoMethod(cryptoMethod);
  74. sendCryptoParams();
  75. rcvCryptoParams(!rcv_paramsandkey);
  76. sendPirParams();
  77. }
  78. // If one of the functions above generates an error, handmadeExceptionRaised is set
  79. if (!handmadeExceptionRaised)
  80. {
  81. // This is just a download thread. Reply generation is unlocked (by a mutex)
  82. // when this thread finishes.
  83. startProcessQuery();
  84. // Import the database
  85. // Start reply generation when mutex unlocked
  86. // Start a thread which uploads the reply as it is generated
  87. startProcessResult(session_option);
  88. }
  89. // Wait for child threads
  90. if (upThread.joinable()) upThread.join();
  91. if (downThread.joinable()) downThread.join();
  92. std::cout << "PIRSession: Session finished" << std::endl << std::endl;
  93. // Note that we have finished so that the PIRServer can do garbage collection
  94. finished = true;
  95. if (generator != NULL) delete generator;
  96. return 0; // Did deal with a client query
  97. }
  98. /**
  99. * Getter for other classes (such as PIRServer)
  100. **/
  101. tcp::socket& PIRSession::getSessionSocket()
  102. {
  103. return sessionSocket;
  104. }
  105. /**
  106. * Send the catalog to the client as a string.
  107. * Format : file_list_size \n filename1 \n filesize1 \n filename2 \n ... filesizeN \n
  108. * if SEND_CATALOG is defined and catalog size is less than 1000, the full catalog is sent
  109. * otherwise only the size of the catalog is sent
  110. **/
  111. void PIRSession::sendCatalog()
  112. {
  113. string buf;
  114. #ifdef SEND_CATALOG
  115. if(dbhandler->getNbStream()>1000) {
  116. buf=dbhandler->getCatalog(false);
  117. } else {
  118. buf=dbhandler->getCatalog(true);
  119. }
  120. #else
  121. buf = dbhandler->getCatalog(false);
  122. #endif
  123. // Send the buffer
  124. const boost::uint64_t size = buf.size();
  125. try
  126. {
  127. if (write(sessionSocket, boost::asio::buffer(&size, sizeof(size))) <= 0)
  128. exitWithErrorMessage(__FUNCTION__,"Error sending catalog size");
  129. if (write(sessionSocket, boost::asio::buffer(buf.c_str(), size)) < size)
  130. exitWithErrorMessage(__FUNCTION__,"Error sending catalog");
  131. } catch (std::exception const& ex) {
  132. exitWithErrorMessage(__FUNCTION__,"Error sending catalog: " + string(ex.what()));
  133. }
  134. writeWarningMessage(__FUNCTION__ , "done.");
  135. }
  136. void PIRSession::sendCryptoParams()
  137. {
  138. std::cout << "PIRSession: Mandatory crypto params sent to the client are " << pirParam.crypto_params << std::endl;
  139. try
  140. {
  141. int crypto_params_size = pirParam.crypto_params.size();
  142. write(sessionSocket, boost::asio::buffer(&crypto_params_size, sizeof(crypto_params_size)));
  143. write(sessionSocket, boost::asio::buffer(pirParam.crypto_params));
  144. }
  145. catch(std::exception const& ex)
  146. {
  147. exitWithErrorMessage(__FUNCTION__, string(ex.what()));
  148. }
  149. }
  150. bool PIRSession::rcvIsClient()
  151. {
  152. try{
  153. int is_client;
  154. while ( read(sessionSocket, boost::asio::buffer(&(is_client), sizeof(int))) == 0)
  155. boost::this_thread::yield();
  156. //exitWithErrorMessage(__FUNCTION__, "No client or optim choice recieved");
  157. return is_client == 1;
  158. }catch (std::exception const& ex)
  159. {
  160. exitWithErrorMessage(__FUNCTION__, string(ex.what()));
  161. }
  162. }
  163. /**
  164. * Receive client's cryptographic parameters as:
  165. * - An int describing a string size
  166. * - A string of the given size containing the public parameters
  167. * - A second int describing a byte size
  168. * - A buffer of bytes of the given size with key material
  169. **/
  170. void PIRSession::rcvCryptoParams(bool paramsandkey)
  171. {
  172. unsigned int size = 0;
  173. try{
  174. std::vector<std::string> fields;
  175. if(paramsandkey == true)
  176. {
  177. // First get the int and allocate space for the string (plus the null caracter)
  178. read(sessionSocket, boost::asio::buffer(&size, sizeof(int)));
  179. char params_buf[size + 1];
  180. // Get the string in the buffer and add a null character
  181. read(sessionSocket, boost::asio::buffer(params_buf, size));
  182. params_buf[size] = '\0';
  183. cout << "PIRSession: Received crypto parameters " << params_buf << " processing them ..." << endl;
  184. #ifdef DEBUG
  185. cout << "PIRSession: Parameter string size is " << size << endl;
  186. #endif
  187. // Extract cryptosystem's name
  188. string crypto_system_desc(params_buf);
  189. boost::algorithm::split(fields, crypto_system_desc, boost::algorithm::is_any_of(":"));
  190. // Create cryptosystem using a factory and the extracted name
  191. cryptoMethod = HomomorphicCryptoFactory_internal::getCrypto(fields[0]);
  192. // Set cryptosystem with received parameters and key material
  193. cryptoMethod->setNewParameters(params_buf);
  194. // Create the PIR reply generator object using a factory to have
  195. // the correct object given the cryptosystem used (for optimization
  196. // reply generation is cryptosystem dependent)
  197. generator = PIRReplyGeneratorFactory::getPIRReplyGenerator(fields[0], pirParam, dbhandler);
  198. if (generator == NULL)
  199. {
  200. std::cout << "PIRSession: CRITICAL no reply generator found, exiting session" << std::endl;
  201. pthread_exit(this);
  202. }
  203. else
  204. {
  205. generator->setCryptoMethod(cryptoMethod);
  206. }
  207. }
  208. // Use again size to describe the key size
  209. if (read(sessionSocket, boost::asio::buffer(&size ,sizeof(size))) <= 0)
  210. exitWithErrorMessage(__FUNCTION__,"No key received, abort.");
  211. #ifdef DEBUG
  212. cout << "PIRSession: Size of received key material is " << size << endl;
  213. #endif
  214. // Get the key material only if there is some
  215. if(size > 0)
  216. {
  217. // This time we don't use a string so no need for an extra character
  218. char buf[size];
  219. if (read(sessionSocket, boost::asio::buffer(buf, size)) < size)
  220. exitWithErrorMessage(__FUNCTION__,"No parameters received, abort.");
  221. cryptoMethod->getPublicParameters().setModulus(buf);
  222. }
  223. }catch(std::exception const& ex)
  224. {
  225. exitWithErrorMessage(__FUNCTION__, string(ex.what()));
  226. }
  227. std::cout << "PIRSession: Finished processing crypto parameters" << std::endl;
  228. }
  229. void PIRSession::sendPIRParamsExchangeMethod(short exchange_method)
  230. {
  231. if (exchange_method == CLIENT_DRIVEN)
  232. {
  233. cout << "PIRSession: Notifying the client this is a client-driven session" << endl;
  234. }
  235. else
  236. {
  237. cout << "PIRSession: Notifying the client this is a server-driven session" << endl;
  238. }
  239. try
  240. {
  241. write(sessionSocket, boost::asio::buffer(&exchange_method, sizeof(exchange_method)));
  242. }catch(std::exception const& ex)
  243. {
  244. exitWithErrorMessage(__FUNCTION__, string(ex.what()));
  245. }
  246. }
  247. /**
  248. * Receive client's PIR parameters.
  249. **/
  250. void PIRSession::rcvPirParams()
  251. {
  252. try{
  253. // First we get an int with the recursion level
  254. if ( read(sessionSocket, boost::asio::buffer(&(pirParam.d), sizeof(int))) <= 0)
  255. exitWithErrorMessage(__FUNCTION__, "No pir param recieved");
  256. // Then we get an int with the aggregation
  257. if ( read(sessionSocket, boost::asio::buffer(&(pirParam.alpha), sizeof(int))) <= 0)
  258. exitWithErrorMessage(__FUNCTION__, "No pir param recieved");
  259. // Finally for each level we get an int withe the corresponding dimension size
  260. for (unsigned int i = 0 ; i < pirParam.d ; i++)
  261. {
  262. if ( read(sessionSocket, boost::asio::buffer( &(pirParam.n[i]), sizeof(int))) <= 0)
  263. exitWithErrorMessage(__FUNCTION__, "No pir param recieved");
  264. }
  265. // The last dimension + 1 is set to 1 (used in some functions to compute the number of
  266. // elements after a PIR recursion level)
  267. pirParam.n[pirParam.d] = 1;
  268. // Pass the PIR parameters to the reply generator
  269. generator->setPirParams(pirParam);
  270. cout << "PIRSession: PIR params recieved from the client are d=" << pirParam.d << ", alpha=" << pirParam.alpha << ", data_layout=";
  271. for (unsigned int i = 0; i < pirParam.d; i++)
  272. {
  273. if (pirParam.d == 1) cout << "1x";
  274. cout << pirParam.n[i];
  275. if (i != pirParam.d-1) cout << "x";
  276. }
  277. cout << endl;
  278. }catch (std::exception const& ex)
  279. {
  280. exitWithErrorMessage(__FUNCTION__, string(ex.what()));
  281. }
  282. }
  283. void PIRSession::sendPirParams()
  284. {
  285. cout << "PIRSession: Mandatory PIR params sent to the client are d=" << pirParam.d << ", alpha=" << pirParam.alpha << ", data_layout=";
  286. for (unsigned int i = 0; i < pirParam.d; i++)
  287. {
  288. if (pirParam.d == 1) cout << "1x";
  289. cout << pirParam.n[i];
  290. if (i != pirParam.d-1) cout << "x";
  291. }
  292. cout << endl;
  293. try{
  294. // First we send an int with the recursion level
  295. if ( write(sessionSocket, boost::asio::buffer(&(pirParam.d), sizeof(int))) <= 0)
  296. exitWithErrorMessage(__FUNCTION__, "No pir param sended");
  297. // Then we send an int with the aggregation
  298. if ( write(sessionSocket, boost::asio::buffer(&(pirParam.alpha), sizeof(int))) <= 0)
  299. exitWithErrorMessage(__FUNCTION__, "No pir param sended");
  300. // Finally for each level we send an int withe the corresponding dimension size
  301. for (unsigned int i = 0 ; i < pirParam.d ; i++)
  302. {
  303. if ( write(sessionSocket, boost::asio::buffer( &(pirParam.n[i]), sizeof(int))) <= 0)
  304. exitWithErrorMessage(__FUNCTION__, "No pir param sended");
  305. }
  306. // The last dimension + 1 is set to 1 (used in some functions to compute the number of
  307. // elements after a PIR recursion level)
  308. pirParam.n[pirParam.d] = 1;
  309. // Pass the PIR parameters to the reply generator
  310. generator->setPirParams(pirParam);
  311. }catch (std::exception const& ex)
  312. {
  313. exitWithErrorMessage(__FUNCTION__, string(ex.what()));
  314. }
  315. }
  316. /**
  317. * Start downloadworker in downThread.
  318. **/
  319. void PIRSession::startProcessQuery ()
  320. {
  321. if(no_pipeline_mode) {
  322. std::cout << "No pipeline in query processing." << std::endl;
  323. downloadWorker();
  324. } else {
  325. downThread = boost::thread(&PIRSession::downloadWorker, this);
  326. }
  327. }
  328. /**
  329. * Recieve queries n messages with n = nbr of files.
  330. **/
  331. void PIRSession::downloadWorker()
  332. {
  333. double start = omp_get_wtime();
  334. unsigned int msg_size = 0;
  335. // Allocate an array with d dimensions with pointers to arrays of n[i] lwe_query elements
  336. generator->initQueriesBuffer();
  337. #ifdef PERF_TIMERS
  338. double vtstart = omp_get_wtime();
  339. bool wasVerbose = false;
  340. unsigned int previous_elts = 0;
  341. unsigned int total_elts = 0;
  342. for (unsigned int k = 0 ; k < pirParam.d ; k++) total_elts += pirParam.n[k];
  343. #endif
  344. try{
  345. for (unsigned int j = 0 ; j < pirParam.d ; j++)
  346. {
  347. // Compute and allocate the size in bytes of a query ELEMENT of dimension j
  348. msg_size = cryptoMethod->getPublicParameters().getQuerySizeFromRecLvl(j+1) / 8;
  349. boost::asio::socket_base::receive_buffer_size opt(65535);
  350. sessionSocket.set_option(opt);
  351. // boost_buffer = new boost::asio::buffer(buf, msg_size);
  352. #ifdef DEBUG
  353. cout << "PIRSession: Size of the query element to be received is " << msg_size << endl;
  354. cout << "PIRSession: Number of query elements to be received is " << pirParam.n[j] << endl;
  355. #endif
  356. // Iterate over all the elements of the query corresponding to the j-th dimension
  357. for (unsigned int i = 0; i < pirParam.n[j]; i++)
  358. {
  359. char *buf = (char *) malloc(msg_size*sizeof(char));
  360. auto boost_buffer = boost::asio::buffer(buf,msg_size);
  361. if (i==0 && j == 0) cout << "PIRSession: Waiting for query elements ..." << endl;
  362. // Get a query element
  363. //( async_read(sessionSocket, boost_buffer,boost::bind(&blo,boost::asio::placeholders::error)) );
  364. if (read(sessionSocket, boost_buffer) < msg_size )
  365. writeWarningMessage(__FUNCTION__, "Query element not entirely recieved");
  366. // std::cout <<"PIRSession: " << total_elts << " query elements received in " << omp_get_wtime() - start << std::endl;
  367. // Allocate the memory for the element, copy it, and point to it with the query buffer
  368. if (i==0 && j == 0) cout << "PIRSession: Starting query element reception" << endl;
  369. #ifdef PERF_TIMERS
  370. // Give some feedback if it takes too long
  371. double vtstop = omp_get_wtime();
  372. if (vtstop - vtstart > 1)
  373. {
  374. vtstart = vtstop;
  375. previous_elts = 0;
  376. for (unsigned int k = 0 ; k < j ; k++) previous_elts += pirParam.n[k];
  377. std::cout <<"PIRSession: Query element " << i+1+previous_elts << "/" << total_elts << " received\r" << std::flush;
  378. }
  379. #endif
  380. generator->pushQuery(buf, msg_size, j, i);
  381. }
  382. }
  383. }catch (std::exception const& ex)
  384. {
  385. exitWithErrorMessage(__FUNCTION__, string(ex.what()));
  386. return;
  387. }
  388. #ifdef PERF_TIMERS
  389. std::cout <<"PIRSession: Query element " << total_elts << "/" << total_elts << " received" << std::endl;
  390. std::cout <<"PIRSession: " << total_elts << " query elements received in " << omp_get_wtime() - start << std::endl;
  391. #endif
  392. // All the query elements received, unlock reply generation
  393. generator->mutex.unlock();
  394. // Output we are done
  395. writeWarningMessage(__FUNCTION__, "done.");
  396. }
  397. /**
  398. * Start uploadWorker in a thread.
  399. **/
  400. void PIRSession::startProcessResult(session_option_t session_option)
  401. {
  402. if (no_pipeline_mode) {
  403. std::cout << "No pipeline in query Generation." << std::endl;
  404. }
  405. else {
  406. upThread = boost::thread(&PIRSession::uploadWorker, this);
  407. }
  408. // Import and generate reply once unlocked by the query downloader thread
  409. // If we got a preimported database generate reply directly from it
  410. if (session_option.got_preimported_database == true)
  411. {
  412. std::cout << "PIRSession: Already got an imported database available, using it" << std::endl;
  413. generator->generateReplyGenericFromData(session_option.data);
  414. }
  415. else if (session_option.keep_database == true) {
  416. savedDatabase = generator->generateReplyGeneric(true);
  417. }
  418. else if (session_option.keep_database == false)
  419. {
  420. generator->generateReplyGeneric(false);
  421. }
  422. if (no_pipeline_mode) {
  423. uploadWorker();
  424. }
  425. }
  426. void sleepForBytes(unsigned int bytes) {
  427. #ifdef NDSS_UPLOAD_SPEED
  428. uint64_t seconds=(bytes*8)/NDSS_UPLOAD_SPEED;
  429. uint64_t nanoseconds=((((double)bytes*8.)/(double)NDSS_UPLOAD_SPEED)-(double)seconds)*1000000000UL;
  430. struct timespec req={0},rem={0};
  431. req.tv_sec=seconds;
  432. req.tv_nsec=nanoseconds;
  433. nanosleep(&req,&rem);
  434. #endif
  435. }
  436. /**
  437. * Send PIR's result, asynchronously.
  438. **/
  439. void PIRSession::uploadWorker()
  440. {
  441. // Ciphertext byte size
  442. unsigned int byteSize = cryptoMethod->getPublicParameters().getCiphBitsizeFromRecLvl(pirParam.d)/GlobalConstant::kBitsPerByte;
  443. uint64_t totalbytesent=0;
  444. // Number of ciphertexts in the reply
  445. unsigned long reply_nbr = generator->computeReplySizeInChunks(maxFileBytesize);
  446. #ifdef DEBUG
  447. cout << "PIRSession: Number of ciphertexts to send is " << reply_nbr << endl;
  448. cout << "PIRSession: maxFileBytesize is " << maxFileBytesize << endl;
  449. cout << "PIRSession: Ciphertext bytesize is " << byteSize << endl;
  450. #endif
  451. try
  452. {
  453. // Pointer for the ciphertexts to be sent
  454. char *ptr;
  455. // For each ciphertext in the reply
  456. for (unsigned i = 0 ; i < reply_nbr ; i++)
  457. {
  458. while (generator->repliesArray == NULL || generator->repliesArray[i] == NULL)
  459. {
  460. boost::this_thread::sleep(boost::posix_time::milliseconds(10));
  461. }
  462. ptr = generator->repliesArray[i];
  463. // Send it
  464. //int byteSent=sessionSocket.send(boost::asio::buffer(ptr, byteSize));
  465. if (write(sessionSocket,boost::asio::buffer(ptr, byteSize)) <= 0)
  466. exitWithErrorMessage(__FUNCTION__,"Error sending request" );
  467. totalbytesent+=byteSize;
  468. #ifdef NDSS_UPLOAD_SPEED
  469. sleepForBytes(byteSize);
  470. #endif
  471. // Free its memory
  472. free(ptr);
  473. generator->repliesArray[i]=NULL;
  474. }
  475. // When everythind is send close the socket
  476. sessionSocket.close();
  477. }
  478. // If there was a problem sending the reply
  479. catch (std::exception const& ex)
  480. {
  481. #ifdef DEBUG
  482. std::cerr << "Number of chunks sent: " << i << "/" << reply_nbr << std::endl;
  483. #endif
  484. exitWithErrorMessage(__FUNCTION__, string(ex.what()));
  485. return;
  486. }
  487. // Tell when we have finished
  488. writeWarningMessage(__FUNCTION__ , "done.");;
  489. }
  490. // Functions for displaying logs
  491. void PIRSession::writeErrorMessage(string funcName, string message)
  492. {
  493. cerr << BOLD << funcName << " : " << RESET_COLOR << RED << message << RESET_COLOR <<endl;
  494. }
  495. void PIRSession::writeWarningMessage(string funcName, string message)
  496. {
  497. cerr << BOLD << funcName << " : " << RESET_COLOR << ORANGE << message << RESET_COLOR <<endl;
  498. }
  499. // For critical erros
  500. void PIRSession::exitWithErrorMessage(string funcName, string message)
  501. {
  502. writeErrorMessage(funcName, message);
  503. // This is used in the main function (start()) to skip costly operations if an error occurred
  504. handmadeExceptionRaised = true;
  505. }
  506. // Used by the PIRServer for garbage collection
  507. bool PIRSession::isFinished()
  508. {
  509. return finished;
  510. }
  511. // Destructor
  512. PIRSession::~PIRSession()
  513. {
  514. if (cryptoMethod != NULL) delete cryptoMethod;
  515. }
  516. PIRParameters PIRSession::getPIRParams()
  517. {
  518. pirParam.crypto_params = cryptoMethod->getPublicParameters().getSerializedParams(false);
  519. return pirParam;
  520. }
  521. void PIRSession::setPIRParams(PIRParameters pir_parameters)
  522. {
  523. pirParam = pir_parameters;
  524. }
  525. imported_database_t PIRSession::getSavedDatabase() {
  526. return savedDatabase;
  527. }
  528. void PIRSession::no_pipeline(bool b)
  529. {
  530. no_pipeline_mode = b;
  531. }