dpf.hpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #ifndef __DPF_HPP__
  2. #define __DPF_HPP__
  3. #include <vector>
  4. #include "prg.hpp"
  5. // We have two major kinds of distributed point functions (DPFs): ones
  6. // used for random-access memory (RDPFs) and ones used for comparisons
  7. // (CDPFs). The major differences:
  8. //
  9. // RDPFs are of depth r in order to obliviously access a memory of size
  10. // 2^r. They are created jointly by P0 and P1, with O(r) communication,
  11. // but O(2^r) local computation. They can output bit shares of a
  12. // single-bit unit vector, word-sized additive shares of a unit vector,
  13. // XOR shares of a scaled unit vector, or additive shares of a scaled
  14. // unit vector. They are typically used by evaluating _all_ 2^r leaves.
  15. // All of the 2^r leaves have to be computed at creation time, anyway,
  16. // so you can choose to store an "expanded" version of them that just
  17. // records those precomputed values, making them much faster to use in
  18. // the online phase, at the cost of storage and memory (and the time it
  19. // takes to just read them from disk, particular on rotational media).
  20. //
  21. // CDPFs are only used to compare VALUE_BITS-bit values (typically
  22. // VALUE_BITS = 64), and can only output bit shares of a single-bit unit
  23. // vector. This allows for an optimization where the leaf nodes of the
  24. // DPF (which are 128 bits wide) can subsume the last 7 levels of the
  25. // tree, so the CDPF is actually of height VALUE_BITS-7 (typically 57).
  26. // They are never used to expand all leaves, since that's way too large,
  27. // nor could P0 and P1 jointly compute them in the way they compute
  28. // RDPFs. On the other hand, P2 never sees these CDPFs in the online
  29. // phase, so P2 can just create them and send the halves to P0 and P1 at
  30. // preprocessing time. They are very cheap to create, store, and send
  31. // over the network (in the preprocessing phase), and evaluate (in the
  32. // online phase); all of these are O(VALUE_BITS-7), somewhat abusing O()
  33. // notation here.
  34. struct DPF {
  35. // The type of nodes
  36. using node = DPFnode;
  37. // The 128-bit seed
  38. DPFnode seed;
  39. // Which half of the DPF are we?
  40. bit_t whichhalf;
  41. // correction words; the depth of the DPF is the length of this
  42. // vector
  43. std::vector<DPFnode> cw;
  44. // correction flag bits: the one for level i is bit i of this word
  45. value_t cfbits;
  46. // The depth
  47. inline nbits_t depth() const { return cw.size(); }
  48. // The seed
  49. inline node get_seed() const { return seed; }
  50. // Descend from a node at depth parentdepth to one of its children
  51. // whichchild = 0: left child
  52. // whichchild = 1: right child
  53. //
  54. // Cost: 1 AES operation
  55. inline DPFnode descend(const DPFnode &parent, nbits_t parentdepth,
  56. bit_t whichchild, size_t &aes_ops) const;
  57. };
  58. // Descend from a node at depth parentdepth to one of its children
  59. // whichchild = 0: left child
  60. // whichchild = 1: right child
  61. inline DPFnode DPF::descend(const DPFnode &parent, nbits_t parentdepth,
  62. bit_t whichchild, size_t &aes_ops) const
  63. {
  64. DPFnode prgout;
  65. bool flag = get_lsb(parent);
  66. prg(prgout, parent, whichchild, aes_ops);
  67. if (flag) {
  68. DPFnode CW = cw[parentdepth];
  69. bit_t cfbit = !!(cfbits & (value_t(1)<<parentdepth));
  70. DPFnode CWR = CW ^ lsb128_mask[cfbit];
  71. prgout ^= (whichchild ? CWR : CW);
  72. }
  73. return prgout;
  74. }
  75. // Don't warn if we never actually use these functions
  76. static void dump_node(DPFnode node, const char *label = NULL)
  77. __attribute__ ((unused));
  78. static void dump_level(DPFnode *nodes, size_t num, const char *label = NULL)
  79. __attribute__ ((unused));
  80. static void dump_node(DPFnode node, const char *label)
  81. {
  82. if (label) printf("%s: ", label);
  83. for(int i=0;i<16;++i) { printf("%02x", ((unsigned char *)&node)[15-i]); } printf("\n");
  84. }
  85. static void dump_level(DPFnode *nodes, size_t num, const char *label)
  86. {
  87. if (label) printf("%s:\n", label);
  88. for (size_t i=0;i<num;++i) {
  89. dump_node(nodes[i]);
  90. }
  91. printf("\n");
  92. }
  93. #endif