duoram.cpp 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. #include "duoram.hpp"
  2. // Assuming the memory is already sorted, do an oblivious binary
  3. // search for the largest index containing the value at most the
  4. // given one. (The answer will be 0 if all of the memory elements
  5. // are greate than the target.) This Flat must be a power of 2 size.
  6. // Only available for additive shared databases for now.
  7. template <>
  8. RegAS Duoram<RegAS>::Flat::obliv_binary_search(RegAS &target)
  9. {
  10. nbits_t depth = this->addr_size;
  11. // Start in the middle
  12. RegAS index;
  13. index.set(this->tio.player() ? 0 : 1<<(depth-1));
  14. // Invariant: index points to the first element of the right half of
  15. // the remaining possible range
  16. while (depth > 0) {
  17. // Obliviously read the value there
  18. RegAS val = operator[](index);
  19. // Compare it to the target
  20. CDPF cdpf = tio.cdpf(this->yield);
  21. auto [lt, eq, gt] = cdpf.compare(this->tio, this->yield,
  22. val-target, tio.aes_ops());
  23. if (depth > 1) {
  24. // If val > target, the answer is strictly to the left
  25. // and we should subtract 2^{depth-2} from index
  26. // If val <= target, the answer is here or to the right
  27. // and we should add 2^{depth-2} to index
  28. // So we unconditionally subtract 2^{depth-2} from index, and
  29. // add (lt+eq)*2^{depth-1}.
  30. RegAS uncond;
  31. uncond.set(tio.player() ? 0 : address_t(1)<<(depth-2));
  32. RegAS cond;
  33. cond.set(tio.player() ? 0 : address_t(1)<<(depth-1));
  34. RegAS condprod;
  35. RegBS le = lt ^ eq;
  36. mpc_flagmult(this->tio, this->yield, condprod, le, cond);
  37. index -= uncond;
  38. index += condprod;
  39. } else {
  40. // If val > target, the answer is strictly to the left
  41. // If val <= target, the answer is here or to the right
  42. // so subtract gt from index
  43. RegAS cond;
  44. cond.set(tio.player() ? 0 : 1);
  45. RegAS condprod;
  46. mpc_flagmult(this->tio, this->yield, condprod, gt, cond);
  47. index -= condprod;
  48. }
  49. --depth;
  50. }
  51. return index;
  52. }