Browse Source

Making Node inherit from Cell

Sajin Sasy 1 year ago
parent
commit
a22a29d2e7
4 changed files with 134 additions and 137 deletions
  1. 0 104
      bst.cpp
  2. 102 0
      bst.hpp
  3. 31 1
      cell.cpp
  4. 1 32
      cell.hpp

+ 0 - 104
bst.cpp

@@ -14,110 +14,6 @@
 // tree balancing information into one field) and the value doesn't
 // really matter, but XOR shared is usually slightly more efficient.
 
-struct Node {
-    RegAS key;
-    RegXS pointers;
-    RegXS value;
-
-// Field-access macros so we can write A[i].NODE_KEY instead of
-// A[i].field(&Node::key)
-
-#define NODE_KEY field(&Node::key)
-#define NODE_POINTERS field(&Node::pointers)
-#define NODE_VALUE field(&Node::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 Node &operator+=(const Node &rhs) {
-        this->key += rhs.key;
-        this->pointers += rhs.pointers;
-        this->value += rhs.value;
-        return *this;
-    }
-
-    inline Node operator+(const Node &rhs) const {
-        Node res = *this;
-        res += rhs;
-        return res;
-    }
-
-    inline Node &operator-=(const Node &rhs) {
-        this->key -= rhs.key;
-        this->pointers -= rhs.pointers;
-        this->value -= rhs.value;
-        return *this;
-    }
-
-    inline Node operator-(const Node &rhs) const {
-        Node res = *this;
-        res -= rhs;
-        return res;
-    }
-
-    inline Node operator-() const {
-        Node 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 Node mulshare(const Node &rhs) const {
-        Node 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.
-    inline void unit(const RDPF &dpf, DPFnode 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 Node &M) {
-        run_coroutines(shyield,
-            [&shape, &idx, &M] (yield_t &yield) {
-                Sh Sh_coro = shape.context(yield);
-                Sh_coro[idx].NODE_KEY += M.key;
-            },
-            [&shape, &idx, &M] (yield_t &yield) {
-                Sh Sh_coro = shape.context(yield);
-                Sh_coro[idx].NODE_POINTERS += M.pointers;
-            },
-            [&shape, &idx, &M] (yield_t &yield) {
-                Sh Sh_coro = shape.context(yield);
-                Sh_coro[idx].NODE_VALUE += M.value;
-            });
-    }
-};
 
 // I/O operations (for sending over the network)
 

+ 102 - 0
bst.hpp

@@ -3,6 +3,108 @@
 
 #include "mpcio.hpp"
 #include "options.hpp"
+#include "cell.hpp"
+
+struct Node: public Cell {
+// Field-access macros so we can write A[i].NODE_KEY instead of
+// A[i].field(&Node::key)
+
+#define NODE_KEY field(&Node::key)
+#define NODE_POINTERS field(&Node::pointers)
+#define NODE_VALUE field(&Node::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 Node &operator+=(const Node &rhs) {
+        this->key += rhs.key;
+        this->pointers += rhs.pointers;
+        this->value += rhs.value;
+        return *this;
+    }
+
+    inline Node operator+(const Node &rhs) const {
+        Node res = *this;
+        res += rhs;
+        return res;
+    }
+
+    inline Node &operator-=(const Node &rhs) {
+        this->key -= rhs.key;
+        this->pointers -= rhs.pointers;
+        this->value -= rhs.value;
+        return *this;
+    }
+
+    inline Node operator-(const Node &rhs) const {
+        Node res = *this;
+        res -= rhs;
+        return res;
+    }
+
+    inline Node operator-() const {
+        Node 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 Node mulshare(const Node &rhs) const {
+        Node 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.
+    inline void unit(const RDPF &dpf, DPFnode 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 Node &M) {
+        run_coroutines(shyield,
+            [&shape, &idx, &M] (yield_t &yield) {
+                Sh Sh_coro = shape.context(yield);
+                Sh_coro[idx].NODE_KEY += M.key;
+            },
+            [&shape, &idx, &M] (yield_t &yield) {
+                Sh Sh_coro = shape.context(yield);
+                Sh_coro[idx].NODE_POINTERS += M.pointers;
+            },
+            [&shape, &idx, &M] (yield_t &yield) {
+                Sh Sh_coro = shape.context(yield);
+                Sh_coro[idx].NODE_VALUE += M.value;
+            });
+    }
+};
 
 void bst(MPCIO &mpcio,
     const PRACOptions &opts, char **args);

+ 31 - 1
cell.cpp

@@ -4,7 +4,37 @@
 #include "duoram.hpp"
 #include "cell.hpp"
 
-// We use the cell in various ways.  This function is called by
+// 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.
+
+// 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.
 
 void cell(MPCIO &mpcio,

+ 1 - 32
cell.hpp

@@ -4,15 +4,6 @@
 #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;
@@ -91,9 +82,7 @@ struct Cell {
     // 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) {
+    inline void unit(const RDPF &dpf, DPFnode leaf) {
         key = dpf.unit_as(leaf);
         pointers = dpf.unit_bs(leaf);
         value = dpf.unit_bs(leaf);
@@ -120,26 +109,6 @@ struct Cell {
     }
 };
 
-// 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);