p2.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. #include <type_traits> // std::is_same<>
  2. #include <limits> // std::numeric_limits<>
  3. #include <climits> // CHAR_BIT
  4. #include <cmath> // std::log2, std::ceil, std::floor
  5. #include <stdexcept> // std::runtime_error
  6. #include <array> // std::array<>
  7. #include <iostream> // std::istream and std::ostream
  8. #include <vector> // std::vector<>
  9. #include <memory> // std::shared_ptr<>
  10. #include <utility> // std::move
  11. #include <algorithm> // std::copy
  12. #include <cstring> // std::memcpy
  13. #include <bsd/stdlib.h> // arc4random_buf
  14. #include <x86intrin.h> // SSE and AVX intrinsics
  15. #include <chrono>
  16. #include <sys/mman.h>
  17. #include <sys/stat.h>
  18. #include <fcntl.h>
  19. #include <fstream>
  20. #include <mutex>
  21. #include <../boost/asio.hpp>
  22. #include <../boost/lexical_cast.hpp>
  23. using boost::asio::ip::tcp;
  24. #include "prg.h"
  25. #include "prg_aes_impl.h"
  26. #include "block.h"
  27. #include "duoram-utils.h"
  28. #include "readvectors.h"
  29. DB_t * X0;
  30. DB_t * X1;
  31. DB_t alpha;
  32. typedef __m128i leaf_t;
  33. typedef __m128i node_t;
  34. using socket_t = boost::asio::ip::tcp::socket;
  35. using namespace std;
  36. size_t communication_cost_dep_read = 0;
  37. size_t communication_cost_write = 0;
  38. size_t communication_cost_ind_read = 0;
  39. double dependent_read_time = 0.0;
  40. double write_time = 0.0;
  41. auto generate_cancelation_terms(int8_t c0[], int8_t d1[], size_t db_nitems, size_t rotate_by = 0)
  42. {
  43. DB_t Z0 = dot_product_with_bool(X0, d1, db_nitems, rotate_by);
  44. DB_t Z1 = dot_product_with_bool(X1, c0, db_nitems, rotate_by);
  45. DB_t cancelation_term0 = -Z0 ;
  46. DB_t cancelation_term1 = -Z1 ;
  47. return std::make_pair(cancelation_term0, cancelation_term1);
  48. }
  49. void refresh_blinds(int8_t writing_c[], int8_t writing_d[],
  50. DB_t c[], DB_t d[],
  51. DB_t finalcw0, DB_t finalcw1, size_t db_nitems, size_t rotate_by = 0)
  52. {
  53. for(size_t j = 0; j < db_nitems; ++j)
  54. {
  55. X0[j] = X0[j] - c[(j + rotate_by) % db_nitems] - ((writing_c[(j + rotate_by) % db_nitems]) * finalcw0);// tmp0; //c0
  56. X1[j] = X1[j] - d[(j + rotate_by) % db_nitems] - ((writing_d[(j + rotate_by) % db_nitems]) * finalcw1); //c2
  57. }
  58. }
  59. void accept_conncections_from_Pb(boost::asio::io_context&io_context, std::vector<socket_t>& sockets_0, int port, size_t j)
  60. {
  61. tcp::acceptor acceptor2_(io_context, tcp::endpoint(tcp::v4(), port));
  62. tcp::socket s2(acceptor2_.accept());
  63. sockets_0[j] = std::move(s2);
  64. }
  65. int main(int argc, char* argv[])
  66. {
  67. size_t expo = atoi(argv[3]);
  68. size_t db_nitems = 1ULL << expo;
  69. size_t number_of_ind_writes = atoi(argv[4]);;
  70. size_t number_of_ind_reads = atoi(argv[5]);;
  71. size_t number_of_dep_reads = atoi(argv[6]);;
  72. size_t number_of_accesses = atoi(argv[7]);
  73. b = (DB_t *) std::aligned_alloc(sizeof(__m256i), db_nitems * sizeof(DB_t));
  74. c = (DB_t *) std::aligned_alloc(sizeof(__m256i), db_nitems * sizeof(DB_t));
  75. d = (DB_t *) std::aligned_alloc(sizeof(__m256i), db_nitems * sizeof(DB_t));
  76. reading_b = (int8_t *) malloc(db_nitems * sizeof(int8_t));
  77. reading_c = (int8_t *) malloc(db_nitems * sizeof(int8_t));
  78. reading_d = (int8_t *) malloc(db_nitems * sizeof(int8_t));
  79. writing_b = (int8_t *) malloc(db_nitems * sizeof(int8_t));
  80. writing_c = (int8_t *) malloc(db_nitems * sizeof(int8_t));
  81. writing_d = (int8_t *) malloc(db_nitems * sizeof(int8_t));
  82. boost::asio::io_context io_context;
  83. AES_KEY aeskey;
  84. const size_t number_of_sockets = 40;
  85. std::vector<int> ports2_0;
  86. for(size_t j = 0; j < number_of_sockets; ++j)
  87. {
  88. int port = 8000;
  89. ports2_0.push_back(port + j);
  90. }
  91. std::vector<int> ports2_1;
  92. for(size_t j = 0; j < number_of_sockets; ++j)
  93. {
  94. int port = 9000;
  95. ports2_1.push_back(port + j);
  96. }
  97. std::vector<socket_t> sockets_0;
  98. std::vector<socket_t> sockets_1;
  99. sockets_0.reserve(number_of_sockets + 1);
  100. sockets_1.reserve(number_of_sockets + 1);
  101. boost::asio::thread_pool pool2(number_of_sockets * 2);
  102. for(size_t j = 0; j < number_of_sockets; ++j)
  103. {
  104. boost::asio::post(pool2, std::bind(accept_conncections_from_Pb, std::ref(io_context), std::ref(sockets_1), ports2_1[j], j));
  105. }
  106. for(size_t j = 0; j < number_of_sockets; ++j)
  107. {
  108. boost::asio::post(pool2, std::bind(accept_conncections_from_Pb, std::ref(io_context), std::ref(sockets_0), ports2_0[j], j));
  109. }
  110. pool2.join();
  111. X0 = (DB_t *) std::aligned_alloc(sizeof(__m256i), db_nitems * sizeof(DB_t));
  112. X1 = (DB_t *) std::aligned_alloc(sizeof(__m256i), db_nitems * sizeof(DB_t));
  113. for(size_t j = 0; j < db_nitems; ++j)
  114. {
  115. X0[j] = 0;
  116. X1[j] = 0;
  117. }
  118. DuORAM_Write * WriteP0_recv = new DuORAM_Write[number_of_ind_writes];
  119. DuORAM_Write * WriteP1_recv = new DuORAM_Write[number_of_ind_writes];
  120. DB_t * Gamma0_ = new DB_t[number_of_ind_writes];
  121. DB_t * Gamma1_ = new DB_t[number_of_ind_writes];
  122. DB_t * update_message0 = new DB_t[number_of_ind_writes];
  123. DB_t * update_message1 = new DB_t[number_of_ind_writes];
  124. DB_t * FCW = new DB_t[number_of_ind_writes];
  125. for(size_t i = 0; i < number_of_accesses; ++i)
  126. {
  127. auto start_writes = std::chrono::steady_clock::now();
  128. for(size_t w = 0; w < number_of_ind_writes; ++w)
  129. {
  130. read_flags_for_refreshing(db_nitems);
  131. size_t rotate_by_ = WriteP0_recv[w].shift + WriteP1_recv[w].shift;
  132. auto [Gamma0, Gamma1] = generate_cancelation_terms(writing_c, writing_d, db_nitems, rotate_by_);
  133. Gamma0_[w] = Gamma0;
  134. Gamma1_[w] = Gamma1;
  135. boost::asio::read(sockets_0[0], boost::asio::buffer(&WriteP0_recv[w], sizeof(DuORAM_Write)));
  136. boost::asio::read(sockets_1[0], boost::asio::buffer(&WriteP1_recv[w], sizeof(DuORAM_Write)));
  137. boost::asio::write(sockets_0[1], boost::asio::buffer(&Gamma0_[w], sizeof(DB_t)));
  138. boost::asio::write(sockets_1[1], boost::asio::buffer(&Gamma1_[w], sizeof(DB_t)));
  139. communication_cost_write += sizeof(DB_t);
  140. communication_cost_write += sizeof(DB_t);
  141. boost::asio::read(sockets_0[2], boost::asio::buffer(&update_message0[w], sizeof(DB_t)));
  142. boost::asio::read(sockets_1[2], boost::asio::buffer(&update_message1[w], sizeof(DB_t)));
  143. FCW[w] = update_message0[w] + update_message1[w];
  144. }
  145. for(size_t w = 0; w < number_of_ind_writes; ++w)
  146. {
  147. size_t rotate_by_ = WriteP0_recv[w].shift + WriteP1_recv[w].shift;
  148. refresh_blinds(writing_c, writing_d, c, d, FCW[w], FCW[w], db_nitems, -rotate_by_);
  149. #ifdef DEBUG
  150. for(size_t j = 0; j < db_nitems; ++j)
  151. {
  152. boost::asio::write(sockets_0[0], boost::asio::buffer(&X0[j], sizeof(X0[j]))); //DEBUG
  153. boost::asio::write(sockets_1[0], boost::asio::buffer(&X1[j], sizeof(X1[j]))); //DUBUG
  154. }
  155. #endif
  156. }
  157. auto end_writes = std::chrono::steady_clock::now();
  158. std::chrono::duration<double> elapsed_seconds_writes = end_writes - start_writes;
  159. write_time = elapsed_seconds_writes.count();
  160. auto start_ind_reads = std::chrono::steady_clock::now();
  161. DB_t * Gamma0_reads = new DB_t[number_of_ind_reads];
  162. DB_t * Gamma1_reads = new DB_t[number_of_ind_reads];
  163. size_t * reads_shift_from_P0 = new size_t[number_of_ind_reads];
  164. size_t * reads_shift_from_P1 = new size_t[number_of_ind_reads];
  165. size_t * rotate = new size_t[number_of_ind_reads];
  166. boost::asio::read(sockets_0[3], boost::asio::buffer(reads_shift_from_P0, number_of_ind_reads * sizeof(size_t)));
  167. boost::asio::read(sockets_1[3], boost::asio::buffer(reads_shift_from_P1, number_of_ind_reads * sizeof(size_t)));
  168. for(size_t r = 0; r < number_of_ind_reads; ++r)
  169. {
  170. #ifdef VERBOSE
  171. std::cout << "rotate[r] " << rotate[r] << std::endl;
  172. #endif
  173. rotate[r] = reads_shift_from_P0[r] + reads_shift_from_P1[r];
  174. read_flags_for_generating_cancellation_terms(db_nitems);
  175. auto [Gamma0, Gamma1] = generate_cancelation_terms(reading_c, reading_d, db_nitems, rotate[r]);
  176. Gamma0_reads[r] = Gamma0;
  177. Gamma1_reads[r] = Gamma1;
  178. }
  179. delete[] reads_shift_from_P0;
  180. delete[] reads_shift_from_P1;
  181. delete[] rotate;
  182. boost::asio::write(sockets_0[4], boost::asio::buffer(Gamma0_reads, number_of_ind_reads * sizeof(DB_t)));
  183. boost::asio::write(sockets_1[4], boost::asio::buffer(Gamma1_reads, number_of_ind_reads * sizeof(DB_t)));
  184. delete[] Gamma0_reads;
  185. delete[] Gamma1_reads;
  186. communication_cost_ind_read += number_of_ind_reads * sizeof(DB_t);
  187. communication_cost_ind_read += number_of_ind_reads * sizeof(DB_t);
  188. auto end_ind_reads = std::chrono::steady_clock::now();
  189. std::chrono::duration<double> elapsed_seconds_ind_reads = end_ind_reads - start_ind_reads;
  190. auto start_dep_reads = std::chrono::steady_clock::now();
  191. for(size_t d = 0; d < number_of_dep_reads; ++d)
  192. {
  193. size_t shifts0, shifts1, rotate;
  194. boost::asio::read(sockets_0[5], boost::asio::buffer(&shifts0, sizeof(shifts0)));
  195. boost::asio::read(sockets_1[5], boost::asio::buffer(&shifts1, sizeof(shifts1)));
  196. rotate = shifts0 + shifts1;
  197. read_flags_for_generating_cancellation_terms(db_nitems);
  198. auto [Gamma0, Gamma1] = generate_cancelation_terms(reading_c, reading_d, db_nitems, rotate);
  199. boost::asio::write(sockets_0[6], boost::asio::buffer(&Gamma0, sizeof(Gamma0)));
  200. boost::asio::write(sockets_1[6], boost::asio::buffer(&Gamma1, sizeof(Gamma1)));
  201. communication_cost_dep_read += sizeof(Gamma0);
  202. communication_cost_dep_read += sizeof(Gamma1);
  203. }
  204. auto end_dep_reads = std::chrono::steady_clock::now();
  205. std::chrono::duration<double> elapsed_seconds_dep_reads = end_dep_reads - start_dep_reads;
  206. dependent_read_time = elapsed_seconds_dep_reads.count();
  207. }
  208. delete[] WriteP0_recv;
  209. delete[] WriteP1_recv;
  210. delete[] Gamma0_;
  211. delete[] Gamma1_;
  212. delete[] update_message0;
  213. delete[] update_message1;
  214. delete[] FCW;
  215. free(X0);
  216. free(X1);
  217. free(b);
  218. free(c);
  219. free(d);
  220. free(reading_b);
  221. free(reading_c);
  222. free(reading_d);
  223. free(writing_b);
  224. free(writing_c);
  225. free(writing_d);
  226. std::cout << "write_time = " << write_time << std::endl;
  227. std::cout << "communication_cost_writes = " << communication_cost_write << " bytes" << std::endl;
  228. std::cout << "dependent_read_time = " << dependent_read_time << std::endl;
  229. std::cout << "communication_cost_dep_read = " << communication_cost_dep_read << " bytes" << std::endl;
  230. std::cout << "interleaved_time = " << dependent_read_time + write_time << std::endl;
  231. std::cout << "communication_cost_interleaved = " << (communication_cost_dep_read + communication_cost_write) << " bytes" << std::endl;
  232. return 0;
  233. }