cdpf.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #include <bsd/stdlib.h> // arc4random_buf
  2. #include "bitutils.hpp"
  3. #include "cdpf.hpp"
  4. // Generate a pair of CDPFs with the given target value
  5. std::tuple<CDPF,CDPF> CDPF::generate(value_t target, size_t &aes_ops)
  6. {
  7. CDPF dpf0, dpf1;
  8. nbits_t depth = VALUE_BITS - 7;
  9. // Pick two random seeds
  10. arc4random_buf(&dpf0.seed, sizeof(dpf0.seed));
  11. arc4random_buf(&dpf1.seed, sizeof(dpf1.seed));
  12. // Ensure the flag bits (the lsb of each node) are different
  13. dpf0.seed = set_lsb(dpf0.seed, 0);
  14. dpf1.seed = set_lsb(dpf1.seed, 1);
  15. dpf0.whichhalf = 0;
  16. dpf1.whichhalf = 1;
  17. dpf0.cfbits = 0;
  18. dpf1.cfbits = 0;
  19. dpf0.as_target.randomize();
  20. dpf1.as_target.ashare = target - dpf0.as_target.ashare;
  21. dpf0.xs_target.randomize();
  22. dpf1.xs_target.xshare = target ^ dpf0.xs_target.xshare;
  23. // The current node in each CDPF as we descend the tree. The
  24. // invariant is that cur0 and cur1 are the nodes on the path to the
  25. // target at level curlevel. They will necessarily be different,
  26. // and indeed must have different flag (low) bits.
  27. DPFnode cur0 = dpf0.seed;
  28. DPFnode cur1 = dpf1.seed;
  29. nbits_t curlevel = 0;
  30. while(curlevel < depth) {
  31. // Construct the two (uncorrected) children of each node
  32. DPFnode left0, right0, left1, right1;
  33. prgboth(left0, right0, cur0, aes_ops);
  34. prgboth(left1, right1, cur1, aes_ops);
  35. // Which way lies the target?
  36. bool targetdir = !!(target & (value_t(1)<<(depth-curlevel-1)));
  37. DPFnode CW;
  38. bool cfbit = !get_lsb(left0 ^ left1 ^ right0 ^ right1);
  39. bool flag0 = get_lsb(cur0);
  40. bool flag1 = get_lsb(cur1);
  41. // The last level is special
  42. if (curlevel < depth-1) {
  43. if (targetdir == 0) {
  44. // The target is to the left, so make the correction word
  45. // and bit make the right children the same and the left
  46. // children have different flag bits.
  47. // Recall that descend will apply (only for the party whose
  48. // current node (cur0 or cur1) has the flag bit set, for
  49. // which exactly one of the two will) CW to both children,
  50. // and cfbit to the flag bit of the right child.
  51. CW = right0 ^ right1 ^ lsb128_mask[cfbit];
  52. // Compute the current nodes for the next level
  53. // Exactly one of these two XORs will fire, so afterwards,
  54. // cur0 ^ cur1 = left0 ^ left1 ^ CW, which will have low bit
  55. // 1 by the definition of cfbit.
  56. cur0 = xor_if(left0, CW, flag0);
  57. cur1 = xor_if(left1, CW, flag1);
  58. } else {
  59. // The target is to the right, so make the correction word
  60. // and bit make the left children the same and the right
  61. // children have different flag bits.
  62. CW = left0 ^ left1;
  63. // Compute the current nodes for the next level
  64. // Exactly one of these two XORs will fire, so similar to
  65. // the above, afterwards, cur0 ^ cur1 = right0 ^ right1 ^ CWR,
  66. // which will have low bit 1.
  67. DPFnode CWR = CW ^ lsb128_mask[cfbit];
  68. cur0 = xor_if(right0, CWR, flag0);
  69. cur1 = xor_if(right1, CWR, flag1);
  70. }
  71. } else {
  72. // We're at the last level before the leaves. We still want
  73. // the children not in the direction of targetdir to end up
  74. // the same, but now we want the child in the direction of
  75. // targetdir to also end up the same, except for the single
  76. // target bit. Importantly, the low bit (the flag bit in
  77. // all other nodes) is not special, and will in fact usually
  78. // end up the same for the two DPFs (unless the target bit
  79. // happens to be the low bit of the word; i.e., the low 7
  80. // bits of target are all 0).
  81. // This will be a 128-bit word with a single bit set, in
  82. // position (target & 0x7f).
  83. uint8_t loc = (target & 0x7f);
  84. DPFnode target_set_bit = _mm_set_epi64x(
  85. loc >= 64 ? (uint64_t(1)<<(loc-64)) : 0,
  86. loc >= 64 ? 0 : (uint64_t(1)<<loc));
  87. if (targetdir == 0) {
  88. // We want the right children to be the same, and the
  89. // left children to be the same except for the target
  90. // bit.
  91. // Remember for exactly one of the two parties, CW will
  92. // be applied to the left and CWR will be applied to the
  93. // right.
  94. CW = left0 ^ left1 ^ target_set_bit;
  95. DPFnode CWR = right0 ^ right1;
  96. dpf0.leaf_cwr = CWR;
  97. dpf1.leaf_cwr = CWR;
  98. } else {
  99. // We want the left children to be the same, and the
  100. // right children to be the same except for the target
  101. // bit.
  102. // Remember for exactly one of the two parties, CW will
  103. // be applied to the left and CWR will be applied to the
  104. // right.
  105. CW = left0 ^ left1;
  106. DPFnode CWR = right0 ^ right1 ^ target_set_bit;
  107. dpf0.leaf_cwr = CWR;
  108. dpf1.leaf_cwr = CWR;
  109. }
  110. }
  111. dpf0.cw.push_back(CW);
  112. dpf1.cw.push_back(CW);
  113. dpf0.cfbits |= (value_t(cfbit)<<curlevel);
  114. dpf1.cfbits |= (value_t(cfbit)<<curlevel);
  115. ++curlevel;
  116. }
  117. return std::make_tuple(dpf0, dpf1);
  118. }
  119. // Generate a pair of CDPFs with a random target value
  120. std::tuple<CDPF,CDPF> CDPF::generate(size_t &aes_ops)
  121. {
  122. value_t target;
  123. arc4random_buf(&target, sizeof(target));
  124. return generate(target, aes_ops);
  125. }