Browse Source

Putting the class back into hpp for cell

sshsshy 9 months ago
parent
commit
d826b2e97f
2 changed files with 135 additions and 128 deletions
  1. 0 128
      cell.cpp
  2. 135 0
      cell.hpp

+ 0 - 128
cell.cpp

@@ -13,134 +13,6 @@
 // tree balancing information into one field) and the value doesn't
 // really matter, but XOR shared is usually slightly more efficient.
 
-struct Cell {
-    RegAS key;
-    RegXS pointers;
-    RegXS value;
-
-// Field-access macros so we can write A[i].CELL_KEY instead of
-// A[i].field(&Cell::key)
-
-#define CELL_KEY field(&Cell::key)
-#define CELL_POINTERS field(&Cell::pointers)
-#define CELL_VALUE field(&Cell::value)
-
-    // For debugging and checking answers
-    void dump() const {
-        printf("[%016lx %016lx %016lx]", key.share(), pointers.share(),
-            value.share());
-    }
-
-    // You'll need to be able to create a random element, and do the
-    // operations +=, +, -=, - (binary and unary).  Note that for
-    // XOR-shared fields, + and - are both really XOR.
-
-    inline void randomize() {
-        key.randomize();
-        pointers.randomize();
-        value.randomize();
-    }
-
-    inline Cell &operator+=(const Cell &rhs) {
-        this->key += rhs.key;
-        this->pointers += rhs.pointers;
-        this->value += rhs.value;
-        return *this;
-    }
-
-    inline Cell operator+(const Cell &rhs) const {
-        Cell res = *this;
-        res += rhs;
-        return res;
-    }
-
-    inline Cell &operator-=(const Cell &rhs) {
-        this->key -= rhs.key;
-        this->pointers -= rhs.pointers;
-        this->value -= rhs.value;
-        return *this;
-    }
-
-    inline Cell operator-(const Cell &rhs) const {
-        Cell res = *this;
-        res -= rhs;
-        return res;
-    }
-
-    inline Cell operator-() const {
-        Cell res;
-        res.key = -this->key;
-        res.pointers = -this->pointers;
-        res.value = -this->value;
-        return res;
-    }
-
-    // Multiply each field by the local share of the corresponding field
-    // in the argument
-    inline Cell mulshare(const Cell &rhs) const {
-        Cell res = *this;
-        res.key.mulshareeq(rhs.key);
-        res.pointers.mulshareeq(rhs.pointers);
-        res.value.mulshareeq(rhs.value);
-        return res;
-    }
-
-    // You need a method to turn a leaf node of a DPF into a share of a
-    // unit element of your type.  Typically set each RegAS to
-    // dpf.unit_as(leaf) and each RegXS or RegBS to dpf.unit_bs(leaf).
-    // Note that RegXS will extend a RegBS of 1 to the all-1s word, not
-    // the word with value 1.  This is used for ORAM reads, where the
-    // same DPF is used for all the fields.
-    template <nbits_t WIDTH>
-    inline void unit(const RDPF<WIDTH> &dpf,
-        typename RDPF<WIDTH>::LeafNode leaf) {
-        key = dpf.unit_as(leaf);
-        pointers = dpf.unit_bs(leaf);
-        value = dpf.unit_bs(leaf);
-    }
-
-    // Perform an update on each of the fields, using field-specific
-    // MemRefs constructed from the Shape shape and the index idx
-    template <typename Sh, typename U>
-    inline static void update(Sh &shape, yield_t &shyield, U idx,
-            const Cell &M) {
-        run_coroutines(shyield,
-            [&shape, &idx, &M] (yield_t &yield) {
-                Sh Sh_coro = shape.context(yield);
-                Sh_coro[idx].CELL_KEY += M.key;
-            },
-            [&shape, &idx, &M] (yield_t &yield) {
-                Sh Sh_coro = shape.context(yield);
-                Sh_coro[idx].CELL_POINTERS += M.pointers;
-            },
-            [&shape, &idx, &M] (yield_t &yield) {
-                Sh Sh_coro = shape.context(yield);
-                Sh_coro[idx].CELL_VALUE += M.value;
-            });
-    }
-};
-
-// I/O operations (for sending over the network)
-
-template <typename T>
-T& operator>>(T& is, Cell &x)
-{
-    is >> x.key >> x.pointers >> x.value;
-    return is;
-}
-
-template <typename T>
-T& operator<<(T& os, const Cell &x)
-{
-    os << x.key << x.pointers << x.value;
-    return os;
-}
-
-// This macro will define I/O on tuples of two or three of the cell type
-
-DEFAULT_TUPLE_IO(Cell)
-
-
 // Now we use the cell in various ways.  This function is called by
 // online.cpp.
 

+ 135 - 0
cell.hpp

@@ -4,6 +4,141 @@
 #include "mpcio.hpp"
 #include "options.hpp"
 
+// This file demonstrates how to implement custom ORAM wide cell types.
+// Such types can be structures of arbitrary numbers of RegAS and RegXS
+// fields.  The example here imagines a cell of a binary search tree,
+// where you would want the key to be additively shared (so that you can
+// easily do comparisons), the pointers field to be XOR shared (so that
+// you can easily do bit operations to pack two pointers and maybe some
+// tree balancing information into one field) and the value doesn't
+// really matter, but XOR shared is usually slightly more efficient.
+
+struct Cell {
+    RegAS key;
+    RegXS pointers;
+    RegXS value;
+
+// Field-access macros so we can write A[i].CELL_KEY instead of
+// A[i].field(&Cell::key)
+
+#define CELL_KEY field(&Cell::key)
+#define CELL_POINTERS field(&Cell::pointers)
+#define CELL_VALUE field(&Cell::value)
+
+    // For debugging and checking answers
+    void dump() const {
+        printf("[%016lx %016lx %016lx]", key.share(), pointers.share(),
+            value.share());
+    }
+
+    // You'll need to be able to create a random element, and do the
+    // operations +=, +, -=, - (binary and unary).  Note that for
+    // XOR-shared fields, + and - are both really XOR.
+
+    inline void randomize() {
+        key.randomize();
+        pointers.randomize();
+        value.randomize();
+    }
+
+    inline Cell &operator+=(const Cell &rhs) {
+        this->key += rhs.key;
+        this->pointers += rhs.pointers;
+        this->value += rhs.value;
+        return *this;
+    }
+
+    inline Cell operator+(const Cell &rhs) const {
+        Cell res = *this;
+        res += rhs;
+        return res;
+    }
+
+    inline Cell &operator-=(const Cell &rhs) {
+        this->key -= rhs.key;
+        this->pointers -= rhs.pointers;
+        this->value -= rhs.value;
+        return *this;
+    }
+
+    inline Cell operator-(const Cell &rhs) const {
+        Cell res = *this;
+        res -= rhs;
+        return res;
+    }
+
+    inline Cell operator-() const {
+        Cell res;
+        res.key = -this->key;
+        res.pointers = -this->pointers;
+        res.value = -this->value;
+        return res;
+    }
+
+    // Multiply each field by the local share of the corresponding field
+    // in the argument
+    inline Cell mulshare(const Cell &rhs) const {
+        Cell res = *this;
+        res.key.mulshareeq(rhs.key);
+        res.pointers.mulshareeq(rhs.pointers);
+        res.value.mulshareeq(rhs.value);
+        return res;
+    }
+
+    // You need a method to turn a leaf node of a DPF into a share of a
+    // unit element of your type.  Typically set each RegAS to
+    // dpf.unit_as(leaf) and each RegXS or RegBS to dpf.unit_bs(leaf).
+    // Note that RegXS will extend a RegBS of 1 to the all-1s word, not
+    // the word with value 1.  This is used for ORAM reads, where the
+    // same DPF is used for all the fields.
+    template <nbits_t WIDTH>
+    inline void unit(const RDPF<WIDTH> &dpf,
+        typename RDPF<WIDTH>::LeafNode leaf) {
+        key = dpf.unit_as(leaf);
+        pointers = dpf.unit_bs(leaf);
+        value = dpf.unit_bs(leaf);
+    }
+
+    // Perform an update on each of the fields, using field-specific
+    // MemRefs constructed from the Shape shape and the index idx
+    template <typename Sh, typename U>
+    inline static void update(Sh &shape, yield_t &shyield, U idx,
+            const Cell &M) {
+        run_coroutines(shyield,
+            [&shape, &idx, &M] (yield_t &yield) {
+                Sh Sh_coro = shape.context(yield);
+                Sh_coro[idx].CELL_KEY += M.key;
+            },
+            [&shape, &idx, &M] (yield_t &yield) {
+                Sh Sh_coro = shape.context(yield);
+                Sh_coro[idx].CELL_POINTERS += M.pointers;
+            },
+            [&shape, &idx, &M] (yield_t &yield) {
+                Sh Sh_coro = shape.context(yield);
+                Sh_coro[idx].CELL_VALUE += M.value;
+            });
+    }
+};
+
+// I/O operations (for sending over the network)
+
+template <typename T>
+T& operator>>(T& is, Cell &x)
+{
+    is >> x.key >> x.pointers >> x.value;
+    return is;
+}
+
+template <typename T>
+T& operator<<(T& os, const Cell &x)
+{
+    os << x.key << x.pointers << x.value;
+    return os;
+}
+
+// This macro will define I/O on tuples of two or three of the cell type
+DEFAULT_TUPLE_IO(Cell)
+
 void cell(MPCIO &mpcio,
     const PRACOptions &opts, char **args);