PIRReplyExtraction_internal.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  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. unsigned long ciphertext_nbr = 1;
  41. unsigned int data_size, data_size2b;
  42. char *data, *in_data, *in_data_2b;
  43. double start = omp_get_wtime();
  44. uint64_t total_ciphertext_nbr= 0;
  45. for (unsigned int rec_lvl = pirParams.d ; rec_lvl >= 1 ; rec_lvl--)
  46. {
  47. ciphertext_nbr = ceil(static_cast<float>(aggregated_maxFileSize) / static_cast<float>(cryptoMethod.getPublicParameters().getAbsorptionBitsize(0)/GlobalConstant::kBitsPerByte));
  48. #ifdef DEBUG
  49. std::cout<<"PIRReplyExtraction_internal: First layer ciphertext_nbr="<<ciphertext_nbr<<std::endl;
  50. #endif
  51. for (unsigned int i = 1 ; i < rec_lvl; i++)
  52. {
  53. ciphertext_nbr = ceil(float(ciphertext_nbr) * float(cryptoMethod.getPublicParameters().getCiphBitsizeFromRecLvl(i)/GlobalConstant::kBitsPerByte) / float(cryptoMethod.getPublicParameters().getAbsorptionBitsize(i)/GlobalConstant::kBitsPerByte));
  54. }
  55. total_ciphertext_nbr += ciphertext_nbr;
  56. #ifdef DEBUG
  57. std::cout<<"PIRReplyextraction: Last layer ciphertext_nbr="<<ciphertext_nbr<<std::endl;
  58. #endif
  59. char* out_data;
  60. data_size = cryptoMethod.getPublicParameters().getCiphBitsizeFromRecLvl(rec_lvl) / GlobalConstant::kBitsPerByte ;
  61. data_size2b = cryptoMethod.getPublicParameters().getAbsorptionBitsize(rec_lvl-1)/GlobalConstant::kBitsPerByte;
  62. if (rec_lvl > 1) in_data_2b = (char*) calloc(data_size2b * ciphertext_nbr, sizeof(char));
  63. #ifdef DEBUG
  64. cout << "PIRReplyExtraction_internal: rec_lvl=" << rec_lvl << " ciphertext_nbr=" << ciphertext_nbr << " data_size=" << data_size << " data_size2b=" << data_size2b << endl;
  65. #endif
  66. cout << "PIRReplyExtraction_internal: Waiting for first replies..." << endl;
  67. for (unsigned int j = 0 ; j < ciphertext_nbr ; j++)
  68. {
  69. data = (rec_lvl == pirParams.d) ? repliesBuffer.pop_front() : in_data+(j*data_size);
  70. if (rec_lvl == pirParams.d && j == 0 )
  71. {
  72. cout << "PIRReplyExtraction_internal: Starting reply extraction..." << endl;
  73. }
  74. out_data = cryptoMethod.decrypt(data, rec_lvl, data_size, data_size2b);
  75. if (rec_lvl > 1) {
  76. memcpy(in_data_2b+(data_size2b * j), out_data, data_size2b);
  77. free(out_data);
  78. }
  79. else
  80. {
  81. clearChunks->push(out_data);
  82. #ifdef CRYPTO_DEBUG
  83. cout << "PIRReplyExtraction_internal : pushed " << hex;
  84. for (int k = 0 ; k < data_size2b ; k++)
  85. cout << (unsigned short) *(out_data+k) << " ";
  86. cout << dec << endl;
  87. #endif
  88. }
  89. if(rec_lvl == pirParams.d) free(data);
  90. }
  91. if (rec_lvl < pirParams.d) free(in_data);
  92. in_data = in_data_2b;
  93. }
  94. cout << "PIRReplyExtraction_internal: Reply extraction finished, " << total_ciphertext_nbr <<
  95. " reply elements decrypted in " << omp_get_wtime() - start << " seconds" << endl;
  96. }
  97. /**
  98. * Start extractReply in a thread.
  99. **/
  100. void PIRReplyExtraction_internal::startExtractReply(int aggregated_maxFileSize, shared_queue<char*>* clearChunks)
  101. {
  102. replyThread = boost::thread(&PIRReplyExtraction_internal::extractReply, this, aggregated_maxFileSize, clearChunks);
  103. }
  104. void PIRReplyExtraction_internal::setFileParam(string filename_ ,int fileSize_)
  105. {
  106. assert (!filename_.empty());
  107. assert (fileSize_ >= 0);
  108. fileSize = fileSize_;
  109. filename = filename_;
  110. }
  111. PIRReplyExtraction_internal::~PIRReplyExtraction_internal()
  112. {
  113. joinThread();
  114. while (!repliesBuffer.empty())
  115. free(repliesBuffer.pop_front());
  116. }
  117. /**
  118. * Join reply extraction thread if it's possible.
  119. **/
  120. void PIRReplyExtraction_internal::joinThread()
  121. {
  122. if (replyThread.joinable()) replyThread.join();
  123. }
  124. int PIRReplyExtraction_internal::getChosenFileSize()
  125. {
  126. return fileSize;
  127. }
  128. //#pragma omp parallel for private(thread_index, buf) shared(index, index_prod)
  129. // for (unsigned int i = 0 ; i < paquet_nbr ; i++)
  130. // {
  131. //#pragma omp critical
  132. // {
  133. // buf = repliesBuffer.pop_front();
  134. // thread_index = index++;
  135. // }
  136. //
  137. // char *tmp1;
  138. // size_t ciph_size = 0, clear_size;
  139. // unsigned int exp_factor = pirParams.recLvl;
  140. //
  141. // if (start == 0)
  142. //#pragma omp critical
  143. // start = omp_get_wtime();
  144. //
  145. // for (unsigned int i = 0 ; i < pirParams.d; i++)
  146. // {
  147. // ciph_size = cryptoMethod.getPublicParameters().getCiphBitsizeFromRecLvl(pirParams.recLvl - i);
  148. // clear_size = cryptoMethod.getPublicParameters().getCiphBitsizeFromRecLvl(pirParams.recLvl - i -1);
  149. // tmp1 = buf;
  150. //
  151. // if (exp_factor - i == 1)
  152. // clear_size--;
  153. //
  154. // buf = cryptoMethod.decrypt(tmp1, exp_factor - i, ciph_size, clear_size);
  155. //
  156. // delete[] tmp1;
  157. // }
  158. //
  159. // while (thread_index != index_prod)
  160. // usleep(5);
  161. //
  162. //#pragma omp critical
  163. // {
  164. // clearChunks.push(buf);
  165. // index_prod = thread_index + 1;
  166. // }
  167. // }
  168. //printf("\n:: Déchiffrement -> Temp écoulé : %f seconds\n", omp_get_wtime() - start);