types.hpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. #ifndef __OBLIVDS_TYPES_HPP__
  2. #define __OBLIVDS_TYPES_HPP__
  3. #include <tuple>
  4. #include <cstdint>
  5. #include <x86intrin.h> // SSE and AVX intrinsics
  6. #include <bsd/stdlib.h> // arc4random_buf
  7. // The number of bits in an MPC secret-shared memory word
  8. #ifndef VALUE_BITS
  9. #define VALUE_BITS 64
  10. #endif
  11. // Values in MPC secret-shared memory are of this type.
  12. // This is the type of the underlying shared value, not the types of the
  13. // shares themselves.
  14. #if VALUE_BITS == 64
  15. using value_t = uint64_t;
  16. #elif VALUE_BITS == 32
  17. using value_t = uint32_t;
  18. #else
  19. #error "Unsupported value of VALUE_BITS"
  20. #endif
  21. // Secret-shared bits are of this type. Note that it is standards
  22. // compliant to treat a bool as an unsigned integer type with values 0
  23. // and 1.
  24. using bit_t = bool;
  25. // Counts of the number of bits in a value are of this type, which must
  26. // be large enough to store the _value_ VALUE_BITS
  27. using nbits_t = uint8_t;
  28. // Convert a number of bits to the number of bytes required to store (or
  29. // more to the point, send) them.
  30. #define BITBYTES(nbits) (((nbits)+7)>>3)
  31. // A mask of this many bits; the test is to prevent 1<<nbits from
  32. // overflowing if nbits == VALUE_BITS
  33. #define MASKBITS(nbits) (((nbits) < VALUE_BITS) ? (value_t(1)<<(nbits))-1 : ~0)
  34. // The type of a register holding an additive share of a value
  35. struct RegAS {
  36. value_t ashare;
  37. RegAS() : ashare(0) {}
  38. // Set each side's share to a random value nbits bits long
  39. inline void randomize(size_t nbits = VALUE_BITS) {
  40. value_t mask = MASKBITS(nbits);
  41. arc4random_buf(&ashare, sizeof(ashare));
  42. ashare &= mask;
  43. }
  44. inline RegAS &operator+=(const RegAS &rhs) {
  45. this->ashare += rhs.ashare;
  46. return *this;
  47. }
  48. inline RegAS operator+(const RegAS &rhs) const {
  49. RegAS res = *this;
  50. res += rhs;
  51. return res;
  52. }
  53. inline RegAS &operator-=(const RegAS &rhs) {
  54. this->ashare -= rhs.ashare;
  55. return *this;
  56. }
  57. inline RegAS operator-(const RegAS &rhs) const {
  58. RegAS res = *this;
  59. res -= rhs;
  60. return res;
  61. }
  62. inline RegAS &operator*=(value_t rhs) {
  63. this->ashare *= rhs;
  64. return *this;
  65. }
  66. inline RegAS operator*(value_t rhs) const {
  67. RegAS res = *this;
  68. res *= rhs;
  69. return res;
  70. }
  71. inline RegAS &operator&=(value_t mask) {
  72. this->ashare &= mask;
  73. return *this;
  74. }
  75. inline RegAS operator&(value_t mask) const {
  76. RegAS res = *this;
  77. res &= mask;
  78. return res;
  79. }
  80. };
  81. // The type of a register holding a bit share
  82. struct RegBS {
  83. bit_t bshare;
  84. RegBS() : bshare(0) {}
  85. // Set each side's share to a random bit
  86. inline void randomize() {
  87. unsigned char randb;
  88. arc4random_buf(&randb, sizeof(randb));
  89. bshare = randb & 1;
  90. }
  91. inline RegBS &operator^=(const RegBS &rhs) {
  92. this->bshare ^= rhs.bshare;
  93. return *this;
  94. }
  95. inline RegBS operator^(const RegBS &rhs) const {
  96. RegBS res = *this;
  97. res ^= rhs;
  98. return res;
  99. }
  100. };
  101. // The type of a register holding an XOR share of a value
  102. struct RegXS {
  103. value_t xshare;
  104. RegXS() : xshare(0) {}
  105. // Set each side's share to a random value nbits bits long
  106. inline void randomize(size_t nbits = VALUE_BITS) {
  107. value_t mask = MASKBITS(nbits);
  108. arc4random_buf(&xshare, sizeof(xshare));
  109. xshare &= mask;
  110. }
  111. inline RegXS &operator^=(const RegXS &rhs) {
  112. this->xshare ^= rhs.xshare;
  113. return *this;
  114. }
  115. inline RegXS operator^(const RegXS &rhs) const {
  116. RegXS res = *this;
  117. res ^= rhs;
  118. return res;
  119. }
  120. inline RegXS &operator&=(value_t mask) {
  121. this->xshare &= mask;
  122. return *this;
  123. }
  124. inline RegXS operator&(value_t mask) const {
  125. RegXS res = *this;
  126. res &= mask;
  127. return res;
  128. }
  129. // Extract a bit share of bit bitnum of the XOR-shared register
  130. inline RegBS bit(nbits_t bitnum) const {
  131. RegBS bs;
  132. bs.bshare = !!(xshare & (value_t(1)<<bitnum));
  133. return bs;
  134. }
  135. };
  136. // The _maximum_ number of bits in an MPC address; the actual size of
  137. // the memory will typically be set at runtime, but it cannot exceed
  138. // this value. It is more efficient (in terms of communication) in some
  139. // places for this value to be at most 32.
  140. #ifndef ADDRESS_MAX_BITS
  141. #define ADDRESS_MAX_BITS 32
  142. #endif
  143. // Addresses of MPC secret-shared memory are of this type
  144. #if ADDRESS_MAX_BITS <= 32
  145. using address_t = uint32_t;
  146. #elif ADDRESS_MAX_BITS <= 64
  147. using address_t = uint64_t;
  148. #else
  149. #error "Unsupported value of ADDRESS_MAX_BITS"
  150. #endif
  151. #if ADDRESS_MAX_BITS > VALUE_BITS
  152. #error "VALUE_BITS must be at least as large as ADDRESS_MAX_BITS"
  153. #endif
  154. // A multiplication triple is a triple (X0,Y0,Z0) held by P0 (and
  155. // correspondingly (X1,Y1,Z1) held by P1), with all values random,
  156. // but subject to the relation that X0*Y1 + Y0*X1 = Z0+Z1
  157. using MultTriple = std::tuple<value_t, value_t, value_t>;
  158. // The *Name structs are a way to get strings representing the names of
  159. // the types as would be given to preprocessing to create them in
  160. // advance.
  161. struct MultTripleName { static constexpr const char *name = "t"; };
  162. // A half-triple is (X0,Z0) held by P0 (and correspondingly (Y1,Z1) held
  163. // by P1), with all values random, but subject to the relation that
  164. // X0*Y1 = Z0+Z1
  165. using HalfTriple = std::tuple<value_t, value_t>;
  166. struct HalfTripleName { static constexpr const char *name = "h"; };
  167. // The type of nodes in a DPF. This must be at least as many bits as
  168. // the security parameter, and at least twice as many bits as value_t.
  169. using DPFnode = __m128i;
  170. // A Select triple is a triple of (X0,Y0,Z0) where X0 is a bit and Y0
  171. // and Z0 are DPFnodes held by P0 (and correspondingly (X1,Y1,Z1) held
  172. // by P1), with all values random, but subject to the relation that
  173. // (X0*Y1) ^ (Y0*X1) = Z0^Z1. These are only used while creating RDPFs
  174. // in the preprocessing phase, so we never need to store them. This is
  175. // a struct instead of a tuple for alignment reasons.
  176. struct SelectTriple {
  177. bit_t X;
  178. DPFnode Y, Z;
  179. };
  180. // These are defined in rdpf.hpp, but declared here to avoid cyclic
  181. // header dependencies.
  182. struct RDPFPair;
  183. struct RDPFPairName { static constexpr const char *name = "r"; };
  184. struct RDPFTriple;
  185. struct RDPFTripleName { static constexpr const char *name = "r"; };
  186. // We want the I/O (using << and >>) for many classes
  187. // to just be a common thing: write out the bytes
  188. // straight from memory
  189. #define DEFAULT_IO(CLASSNAME) \
  190. template <typename T> \
  191. T& operator>>(T& is, CLASSNAME &x) \
  192. { \
  193. is.read((char *)&x, sizeof(x)); \
  194. return is; \
  195. } \
  196. \
  197. template <typename T> \
  198. T& operator<<(T& os, const CLASSNAME &x) \
  199. { \
  200. os.write((const char *)&x, sizeof(x)); \
  201. return os; \
  202. }
  203. // Default I/O for various types
  204. DEFAULT_IO(RegBS)
  205. DEFAULT_IO(RegAS)
  206. DEFAULT_IO(RegXS)
  207. DEFAULT_IO(MultTriple)
  208. DEFAULT_IO(HalfTriple)
  209. #endif