dpf.hpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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
  42. std::vector<DPFnode> cw;
  43. // correction flag bits: the one for level i is bit i of this word
  44. value_t cfbits;
  45. // The seed
  46. inline node get_seed() const { return seed; }
  47. // Descend from a node at depth parentdepth to one of its children
  48. // whichchild = 0: left child
  49. // whichchild = 1: right child
  50. //
  51. // Cost: 1 AES operation
  52. inline DPFnode descend(const DPFnode &parent, nbits_t parentdepth,
  53. bit_t whichchild, size_t &aes_ops) const;
  54. };
  55. // Descend from a node at depth parentdepth to one of its children
  56. // whichchild = 0: left child
  57. // whichchild = 1: right child
  58. inline DPFnode DPF::descend(const DPFnode &parent, nbits_t parentdepth,
  59. bit_t whichchild, size_t &aes_ops) const
  60. {
  61. DPFnode prgout;
  62. bool flag = get_lsb(parent);
  63. prg(prgout, parent, whichchild, aes_ops);
  64. if (flag) {
  65. DPFnode CW = cw[parentdepth];
  66. bit_t cfbit = !!(cfbits & (value_t(1)<<parentdepth));
  67. DPFnode CWR = CW ^ lsb128_mask[cfbit];
  68. prgout ^= (whichchild ? CWR : CW);
  69. }
  70. return prgout;
  71. }
  72. // Don't warn if we never actually use these functions
  73. static void dump_node(DPFnode node, const char *label = NULL)
  74. __attribute__ ((unused));
  75. static void dump_level(DPFnode *nodes, size_t num, const char *label = NULL)
  76. __attribute__ ((unused));
  77. static void dump_node(DPFnode node, const char *label)
  78. {
  79. if (label) printf("%s: ", label);
  80. for(int i=0;i<16;++i) { printf("%02x", ((unsigned char *)&node)[15-i]); } printf("\n");
  81. }
  82. static void dump_level(DPFnode *nodes, size_t num, const char *label)
  83. {
  84. if (label) printf("%s:\n", label);
  85. for (size_t i=0;i<num;++i) {
  86. dump_node(nodes[i]);
  87. }
  88. printf("\n");
  89. }
  90. #endif