RecursiveShuffle.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. #ifndef BEFTS_MODE
  2. #include <array>
  3. #include <sgx_tcrypto.h>
  4. #include "oasm_lib.h"
  5. #include "utils.hpp"
  6. #include "RecursiveShuffle.hpp"
  7. #endif
  8. size_t RS_RB_BUFFER_SIZE;
  9. unsigned char *random_bytes_buffer = NULL;
  10. uint32_t *random_bytes_buffer_ptr;
  11. uint32_t *random_bytes_buffer_ptr_end;
  12. /*
  13. MarkHalf: Marks half of the elements of an N sized array randomly.
  14. Pass in a bool array of size N, which will be populated with 1's at indexes which
  15. r get marked by MarkHalf
  16. NOTE: MarkHalf assumes selected_list is initialized to all 0's before passed to MarkHalf
  17. */
  18. void MarkHalf(uint64_t N, bool *selected_list) {
  19. uint64_t left_to_mark = N/2;
  20. uint64_t total_left = N;
  21. PRB_buffer *randpool = PRB_pool + g_thread_id;
  22. uint32_t coins[RS_MARKHALF_MAX_COINS];
  23. size_t coinsleft=0;
  24. FOAV_SAFE_CNTXT(MarkHalf_marking_half, N)
  25. for(uint64_t i=0; i<N; i++){
  26. FOAV_SAFE2_CNTXT(MarkHalf_marking_half, i, coinsleft)
  27. if (coinsleft == 0) {
  28. size_t numcoins = (N-i);
  29. FOAV_SAFE_CNTXT(MarkHalf_marking_half, numcoins)
  30. if (numcoins > RS_MARKHALF_MAX_COINS) {
  31. numcoins = RS_MARKHALF_MAX_COINS;
  32. }
  33. randpool->getRandomBytes((unsigned char *) coins,
  34. sizeof(coins[0])*numcoins);
  35. coinsleft = numcoins;
  36. }
  37. //Mark with probability left_to_mark/total_left;
  38. uint32_t random_coin;
  39. random_coin = (total_left * coins[--coinsleft]) >> 32;
  40. uint32_t mark_threshold = total_left - left_to_mark;
  41. uint8_t mark_element = oge_set_flag(random_coin, mark_threshold);
  42. //If mark_element, obliviously set selected_list[i] to 1
  43. FOAV_SAFE_CNTXT(MarkHalf_marking_half, i)
  44. selected_list[i] = mark_element;
  45. left_to_mark-= mark_element;
  46. total_left--;
  47. FOAV_SAFE2_CNTXT(MarkHalf_marking_half, i, N)
  48. }
  49. }
  50. #if 0
  51. #ifndef BEFTS_MODE
  52. void RecursiveShuffle_M1(unsigned char *buf, uint64_t N, size_t block_size) {
  53. FOAV_SAFE2_CNTXT(RS_M1, N, block_size)
  54. size_t num_random_bytes = calculatelog2(N) * N * sizeof(uint32_t);
  55. #ifdef RS_M2_MEM_OPT1
  56. FOAV_SAFE2_CNTXT(RS_M1, num_random_bytes, RS_RB_BUFFER_LIMIT)
  57. if(num_random_bytes > RS_RB_BUFFER_LIMIT) {
  58. RS_RB_BUFFER_SIZE = RS_RB_BUFFER_LIMIT;
  59. }
  60. else{
  61. RS_RB_BUFFER_SIZE = num_random_bytes;
  62. }
  63. try {
  64. random_bytes_buffer = new unsigned char[RS_RB_BUFFER_SIZE];
  65. //FOAV_SAFE_CNTXT(RS_M1_initializing_selected_list, N)
  66. selected_list = new bool[N]{};
  67. } catch (std::bad_alloc&){
  68. printf("Allocating memory failed in RS_M2\n");
  69. }
  70. getBulkRandomBytes((unsigned char*)random_bytes_buffer, RS_RB_BUFFER_SIZE);
  71. random_bytes_buffer_ptr_end = (uint32_t*)(random_bytes_buffer + RS_RB_BUFFER_SIZE);
  72. #else
  73. try {
  74. random_bytes_buffer = new unsigned char[num_random_bytes];
  75. selected_list = new bool[N]{};
  76. } catch (std::bad_alloc&){
  77. printf("Allocating memory failed in RS_M2\n");
  78. }
  79. getBulkRandomBytes((unsigned char*)random_bytes_buffer, num_random_bytes);
  80. #endif
  81. random_bytes_buffer_ptr = (uint32_t*) random_bytes_buffer;
  82. FOAV_SAFE_CNTXT(RS_M1_branching_on_block_size_for_OSwap_Style_templates, block_size)
  83. if(block_size==4){
  84. FOAV_SAFE_CNTXT(RS_M1_branching_on_block_size_for_OSwap_Style_templates, block_size)
  85. RecursiveShuffle_M1_inner<OSWAP_4>(buf, N, block_size, selected_list);
  86. FOAV_SAFE_CNTXT(RS_M1_branching_on_block_size_for_OSwap_Style_templates, block_size)
  87. } else if(block_size==8){
  88. FOAV_SAFE_CNTXT(RS_M1_branching_on_block_size_for_OSwap_Style_templates, block_size)
  89. RecursiveShuffle_M1_inner<OSWAP_8>(buf, N, block_size, selected_list);
  90. FOAV_SAFE_CNTXT(RS_M1_branching_on_block_size_for_OSwap_Style_templates, block_size)
  91. } else if(block_size%16==0) {
  92. FOAV_SAFE_CNTXT(RS_M1_branching_on_block_size_for_OSwap_Style_templates, block_size)
  93. RecursiveShuffle_M1_inner<OSWAP_16X>(buf, N, block_size, selected_list);
  94. FOAV_SAFE_CNTXT(RS_M1_branching_on_block_size_for_OSwap_Style_templates, block_size)
  95. } else {
  96. FOAV_SAFE_CNTXT(RS_M1_branching_on_block_size_for_OSwap_Style_templates, block_size)
  97. RecursiveShuffle_M1_inner<OSWAP_8_16X>(buf, N, block_size, selected_list);
  98. FOAV_SAFE_CNTXT(RS_M1_branching_on_block_size_for_OSwap_Style_templates, block_size)
  99. }
  100. FOAV_SAFE_CNTXT(RecursiveShuffle_M1_delete, random_bytes_buffer)
  101. delete []random_bytes_buffer;
  102. FOAV_SAFE_CNTXT(RecursiveShuffle_M1_delete, selected_list)
  103. delete []selected_list;
  104. }
  105. #endif
  106. #endif
  107. void RecursiveShuffle_M2(unsigned char *buf, uint64_t N, size_t block_size){
  108. RecursiveShuffle_M2_parallel(buf, N, block_size, 1);
  109. }
  110. void RecursiveShuffle_M2_parallel(unsigned char *buf, uint64_t N, size_t block_size, size_t nthreads){
  111. FOAV_SAFE2_CNTXT(RS_M2, N, block_size)
  112. bool *selected_list;
  113. try {
  114. selected_list = new bool[N]{};
  115. } catch (std::bad_alloc&){
  116. printf("Allocating memory failed in RS_M2\n");
  117. }
  118. threadpool_init(nthreads);
  119. FOAV_SAFE_CNTXT(RS_M2_branching_on_block_size_for_OSwap_Style_templates, block_size)
  120. if(block_size==4){
  121. RecursiveShuffle_M2_inner_parallel<OSWAP_4>(buf, N, block_size, selected_list, nthreads);
  122. } else if(block_size==8){
  123. RecursiveShuffle_M2_inner_parallel<OSWAP_8>(buf, N, block_size, selected_list, nthreads);
  124. } else if(block_size%16==0) {
  125. RecursiveShuffle_M2_inner_parallel<OSWAP_16X>(buf, N, block_size, selected_list, nthreads);
  126. } else {
  127. RecursiveShuffle_M2_inner_parallel<OSWAP_8_16X>(buf, N, block_size, selected_list, nthreads);
  128. }
  129. threadpool_shutdown();
  130. FOAV_SAFE_CNTXT(RecursiveShuffle_M2_delete, selected_list)
  131. delete []selected_list;
  132. }
  133. #if 0
  134. // We maintain a double type return version of RecusiveShuffle_M2,
  135. // to time strictly the RS_M2 component when using it without any encryption or decryption
  136. // We need this only for the BOS optimizer!!
  137. double RecursiveShuffle_M2_opt(unsigned char *buf, uint64_t N, size_t block_size){
  138. FOAV_SAFE2_CNTXT(RS_M2_opt, N, block_size)
  139. //In a single call allocate all the randomness we need here!
  140. size_t num_random_bytes = calculatelog2(N) * N * sizeof(uint32_t);
  141. long t0, t1;
  142. ocall_clock(&t0);
  143. #ifdef RS_M2_MEM_OPT1
  144. if(num_random_bytes > RS_RB_BUFFER_LIMIT) {
  145. RS_RB_BUFFER_SIZE = RS_RB_BUFFER_LIMIT;
  146. }
  147. else{
  148. RS_RB_BUFFER_SIZE = num_random_bytes;
  149. }
  150. try {
  151. random_bytes_buffer = new unsigned char[RS_RB_BUFFER_SIZE];
  152. selected_list = new bool[N]{};
  153. } catch (std::bad_alloc&){
  154. printf("Allocating memory failed in RS_M2\n");
  155. }
  156. getBulkRandomBytes((unsigned char*)random_bytes_buffer, RS_RB_BUFFER_SIZE);
  157. random_bytes_buffer_ptr_end = (uint32_t*)(random_bytes_buffer + RS_RB_BUFFER_SIZE);
  158. #else
  159. try {
  160. random_bytes_buffer = new unsigned char[num_random_bytes];
  161. selected_list = new bool[N]{};
  162. } catch (std::bad_alloc&){
  163. printf("Allocating memory failed in RS_M2\n");
  164. }
  165. getBulkRandomBytes((unsigned char*)random_bytes_buffer, num_random_bytes);
  166. #endif
  167. random_bytes_buffer_ptr = (uint32_t*) random_bytes_buffer;
  168. FOAV_SAFE_CNTXT(RS_M2_opt, num_random_bytes)
  169. FOAV_SAFE2_CNTXT(RS_M2_opt, N, block_size)
  170. FOAV_SAFE_CNTXT(RS_M2_opt, block_size)
  171. if(block_size==4){
  172. RecursiveShuffle_M2_inner<OSWAP_4>(buf, N, block_size, selected_list);
  173. } else if(block_size==8){
  174. RecursiveShuffle_M2_inner<OSWAP_8>(buf, N, block_size, selected_list);
  175. } else if(block_size%16==0) {
  176. RecursiveShuffle_M2_inner<OSWAP_16X>(buf, N, block_size, selected_list);
  177. } else {
  178. RecursiveShuffle_M2_inner<OSWAP_8_16X>(buf, N, block_size, selected_list);
  179. }
  180. delete []random_bytes_buffer;
  181. delete []selected_list;
  182. ocall_clock(&t1);
  183. double ptime = ((double)(t1-t0))/1000.0;
  184. return ptime;
  185. }
  186. #ifndef BEFTS_MODE
  187. double DecryptAndShuffleM1(unsigned char *encrypted_buffer, size_t N, size_t encrypted_block_size, unsigned char *result_buffer, enc_ret *ret) {
  188. // Decrypt buffer to decrypted_buffer
  189. unsigned char *decrypted_buffer = NULL;
  190. size_t decrypted_block_size = decryptBuffer(encrypted_buffer, N, encrypted_block_size, &decrypted_buffer);
  191. long t0, t1;
  192. ocall_clock(&t0);
  193. // ShuffleM1 on decrypted_buffer
  194. PRB_pool_init(1);
  195. RecursiveShuffle_M1(decrypted_buffer, N, decrypted_block_size);
  196. ocall_clock(&t1);
  197. // Encrypt buffer to result_buffer
  198. encryptBuffer(decrypted_buffer, N, decrypted_block_size, result_buffer);
  199. PRB_pool_shutdown();
  200. free(decrypted_buffer);
  201. double ptime = ((double)(t1-t0))/1000.0;
  202. ret->OSWAP_count = OSWAP_COUNTER;
  203. ret->ptime = ptime;
  204. return(ptime);
  205. }
  206. #endif
  207. double DecryptAndShuffleM2(unsigned char *encrypted_buffer, size_t N, size_t encrypted_block_size, size_t nthreads, unsigned char *result_buffer, enc_ret *ret) {
  208. // Decrypt buffer to decrypted_buffer
  209. unsigned char *decrypted_buffer = NULL;
  210. size_t decrypted_block_size = decryptBuffer(encrypted_buffer, N, encrypted_block_size, &decrypted_buffer);
  211. long t0, t1;
  212. ocall_clock(&t0);
  213. // ShuffleM2 on decrypted_buffer
  214. PRB_pool_init(nthreads);
  215. RecursiveShuffle_M2_parallel(decrypted_buffer, N, decrypted_block_size, nthreads);
  216. ocall_clock(&t1);
  217. // Encrypt buffer to result_buffer
  218. encryptBuffer(decrypted_buffer, N, decrypted_block_size, result_buffer);
  219. PRB_pool_shutdown();
  220. #ifdef TIME_MARKHALF
  221. printf("Time taken in MarkHalf calls = %f\n", MARKHALF_TIME);
  222. #endif
  223. free(decrypted_buffer);
  224. double ptime = ((double)(t1-t0))/1000.0;
  225. ret->OSWAP_count = OSWAP_COUNTER;
  226. ret->ptime = ptime;
  227. return(ptime);
  228. }
  229. #endif