PIRReplyExtraction_internal.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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 "PIRReplyExtraction_internal.hpp"
  18. #include "apps/client/PIRViewCLI.hpp"
  19. //#define DEBUG
  20. /**
  21. * Class constructor.
  22. * Params :
  23. * - crypto_ptr crypto : HomomorphicCrypto shared_ptr ;
  24. * - PIRParameters& param : PIRParameters reference ;
  25. * - signal1<void, WriteEvent> : writeEvent listeners reference shared with PIRClient ;
  26. * - ignal1<void, MessageEvent&> : messageEvent listeners reference shared with PIRClient.
  27. **/
  28. PIRReplyExtraction_internal::PIRReplyExtraction_internal(PIRParameters& param_, HomomorphicCrypto& cryptoMethod_) :
  29. filePath("reception"),
  30. pirParams(param_),
  31. cryptoMethod(cryptoMethod_),
  32. repliesBuffer("coucou"),
  33. fileSize(0)
  34. {}
  35. /**
  36. * Parallely extract/decrypt file, store clear chunk in clearChunks shared queue.
  37. **/
  38. void PIRReplyExtraction_internal::extractReply(int aggregated_maxFileSize, shared_queue<char*>* clearChunks)
  39. {
  40. uint64_t response_size=0;
  41. unsigned long ciphertext_nbr = 1;
  42. unsigned int data_size, data_size2b;
  43. char *data, *in_data, *in_data_2b;
  44. double start = omp_get_wtime();
  45. clock_t er_start, er_stop;
  46. uint64_t total_ciphertext_nbr= 0;
  47. er_start=clock();
  48. for (unsigned int rec_lvl = pirParams.d ; rec_lvl >= 1 ; rec_lvl--)
  49. {
  50. ciphertext_nbr = ceil(static_cast<float>(aggregated_maxFileSize) / static_cast<float>(cryptoMethod.getPublicParameters().getAbsorptionBitsize(0)/GlobalConstant::kBitsPerByte));
  51. std::cout<<"consensgx:PIRReplyExtraction_internal: First layer ciphertext_nbr="<<ciphertext_nbr<<", AbsorptionBitsize = "<<cryptoMethod.getPublicParameters().getAbsorptionBitsize(0)<<", aggregated_maxFileSize="<<aggregated_maxFileSize<<std::endl;
  52. #ifdef DEBUG
  53. std::cout<<"PIRReplyExtraction_internal: First layer ciphertext_nbr="<<ciphertext_nbr<<std::endl;
  54. #endif
  55. for (unsigned int i = 1 ; i < rec_lvl; i++)
  56. {
  57. ciphertext_nbr = ceil(float(ciphertext_nbr) * float(cryptoMethod.getPublicParameters().getCiphBitsizeFromRecLvl(i)/GlobalConstant::kBitsPerByte) / float(cryptoMethod.getPublicParameters().getAbsorptionBitsize(i)/GlobalConstant::kBitsPerByte));
  58. }
  59. total_ciphertext_nbr += ciphertext_nbr;
  60. std::cout<<"consensgx: Total_ciphertext_nbr = "<<total_ciphertext_nbr<<std::endl;
  61. #ifdef DEBUG
  62. std::cout<<"PIRReplyextraction: Last layer ciphertext_nbr="<<ciphertext_nbr<<std::endl;
  63. #endif
  64. char* out_data;
  65. data_size = cryptoMethod.getPublicParameters().getCiphBitsizeFromRecLvl(rec_lvl) / GlobalConstant::kBitsPerByte ;
  66. data_size2b = cryptoMethod.getPublicParameters().getAbsorptionBitsize(rec_lvl-1)/GlobalConstant::kBitsPerByte;
  67. std::cout<<"consensgx: data_size="<<data_size<<" data_size2b="<<data_size2b;
  68. if (rec_lvl > 1) in_data_2b = (char*) calloc(data_size2b * ciphertext_nbr, sizeof(char));
  69. #ifdef DEBUG
  70. cout << "PIRReplyExtraction_internal: rec_lvl=" << rec_lvl << " ciphertext_nbr=" << ciphertext_nbr << " data_size=" << data_size << " data_size2b=" << data_size2b << endl;
  71. #endif
  72. cout << "PIRReplyExtraction_internal: Waiting for first replies..." << endl;
  73. for (unsigned int j = 0 ; j < ciphertext_nbr ; j++)
  74. {
  75. data = (rec_lvl == pirParams.d) ? repliesBuffer.pop_front() : in_data+(j*data_size);
  76. if (rec_lvl == pirParams.d && j == 0 )
  77. {
  78. cout << "PIRReplyExtraction_internal: Starting reply extraction..." << endl;
  79. }
  80. out_data = cryptoMethod.decrypt(data, rec_lvl, data_size, data_size2b);
  81. if (rec_lvl > 1) {
  82. memcpy(in_data_2b+(data_size2b * j), out_data, data_size2b);
  83. free(out_data);
  84. }
  85. else
  86. {
  87. clearChunks->push(out_data);
  88. #ifdef CRYPTO_DEBUG
  89. cout << "PIRReplyExtraction_internal : pushed " << hex;
  90. for (int k = 0 ; k < data_size2b ; k++)
  91. cout << (unsigned short) *(out_data+k) << " ";
  92. cout << dec << endl;
  93. #endif
  94. }
  95. if(rec_lvl == pirParams.d) free(data);
  96. }
  97. if (rec_lvl < pirParams.d) free(in_data);
  98. in_data = in_data_2b;
  99. }
  100. er_stop = clock();
  101. response_size = data_size * total_ciphertext_nbr;
  102. std::cout<<"measure_response_size:"<<response_size<<std::endl;
  103. cout << "PIRReplyExtraction_internal: Reply extraction finished, " << total_ciphertext_nbr <<
  104. " reply elements decrypted in " << omp_get_wtime() - start << " seconds" << std::endl;
  105. cout << "consensgx2 : ReplyExtraction finished, time taken was " << (double)1000 * (double)(er_stop - er_start) /(double)(CLOCKS_PER_SEC) << " ms" << std::endl;
  106. cout << "PIRReplyExtraction_internal: data_size=" << data_size << " data_size2b=" << data_size2b << std::endl << std::flush;
  107. }
  108. /**
  109. * Start extractReply in a thread.
  110. **/
  111. void PIRReplyExtraction_internal::startExtractReply(int aggregated_maxFileSize, shared_queue<char*>* clearChunks)
  112. {
  113. replyThread = boost::thread(&PIRReplyExtraction_internal::extractReply, this, aggregated_maxFileSize, clearChunks);
  114. }
  115. void PIRReplyExtraction_internal::setFileParam(string filename_ ,int fileSize_)
  116. {
  117. assert (!filename_.empty());
  118. assert (fileSize_ >= 0);
  119. fileSize = fileSize_;
  120. filename = filename_;
  121. }
  122. PIRReplyExtraction_internal::~PIRReplyExtraction_internal()
  123. {
  124. joinThread();
  125. while (!repliesBuffer.empty())
  126. free(repliesBuffer.pop_front());
  127. }
  128. /**
  129. * Join reply extraction thread if it's possible.
  130. **/
  131. void PIRReplyExtraction_internal::joinThread()
  132. {
  133. if (replyThread.joinable()) replyThread.join();
  134. }
  135. int PIRReplyExtraction_internal::getChosenFileSize()
  136. {
  137. return fileSize;
  138. }
  139. //#pragma omp parallel for private(thread_index, buf) shared(index, index_prod)
  140. // for (unsigned int i = 0 ; i < paquet_nbr ; i++)
  141. // {
  142. //#pragma omp critical
  143. // {
  144. // buf = repliesBuffer.pop_front();
  145. // thread_index = index++;
  146. // }
  147. //
  148. // char *tmp1;
  149. // size_t ciph_size = 0, clear_size;
  150. // unsigned int exp_factor = pirParams.recLvl;
  151. //
  152. // if (start == 0)
  153. //#pragma omp critical
  154. // start = omp_get_wtime();
  155. //
  156. // for (unsigned int i = 0 ; i < pirParams.d; i++)
  157. // {
  158. // ciph_size = cryptoMethod.getPublicParameters().getCiphBitsizeFromRecLvl(pirParams.recLvl - i);
  159. // clear_size = cryptoMethod.getPublicParameters().getCiphBitsizeFromRecLvl(pirParams.recLvl - i -1);
  160. // tmp1 = buf;
  161. //
  162. // if (exp_factor - i == 1)
  163. // clear_size--;
  164. //
  165. // buf = cryptoMethod.decrypt(tmp1, exp_factor - i, ciph_size, clear_size);
  166. //
  167. // delete[] tmp1;
  168. // }
  169. //
  170. // while (thread_index != index_prod)
  171. // usleep(5);
  172. //
  173. //#pragma omp critical
  174. // {
  175. // clearChunks.push(buf);
  176. // index_prod = thread_index + 1;
  177. // }
  178. // }
  179. //printf("\n:: Déchiffrement -> Temp écoulé : %f seconds\n", omp_get_wtime() - start);