Sfoglia il codice sorgente

Refactor RDPF a bit

Move the things that will be in common with CDPFs into a common
superclass DPF
Ian Goldberg 1 anno fa
parent
commit
2e7a8042bd
4 ha cambiato i file con 108 aggiunte e 67 eliminazioni
  1. 7 5
      Makefile
  2. 99 0
      dpf.hpp
  3. 0 41
      rdpf.cpp
  4. 2 21
      rdpf.hpp

+ 7 - 5
Makefile

@@ -28,11 +28,13 @@ depend:
 # DO NOT DELETE THIS LINE -- make depend depends on it.
 
 prac.o: mpcio.hpp types.hpp preproc.hpp options.hpp online.hpp
-mpcio.o: mpcio.hpp types.hpp rdpf.hpp coroutine.hpp bitutils.hpp rdpf.tcc
+mpcio.o: mpcio.hpp types.hpp rdpf.hpp coroutine.hpp bitutils.hpp dpf.hpp
+mpcio.o: prg.hpp aes.hpp rdpf.tcc
 preproc.o: types.hpp coroutine.hpp mpcio.hpp preproc.hpp options.hpp rdpf.hpp
-preproc.o: bitutils.hpp rdpf.tcc
+preproc.o: bitutils.hpp dpf.hpp prg.hpp aes.hpp rdpf.tcc
 online.o: online.hpp mpcio.hpp types.hpp options.hpp mpcops.hpp coroutine.hpp
-online.o: rdpf.hpp bitutils.hpp rdpf.tcc duoram.hpp duoram.tcc
+online.o: rdpf.hpp bitutils.hpp dpf.hpp prg.hpp aes.hpp rdpf.tcc duoram.hpp
+online.o: duoram.tcc
 mpcops.o: mpcops.hpp types.hpp mpcio.hpp coroutine.hpp bitutils.hpp
-rdpf.o: rdpf.hpp mpcio.hpp types.hpp coroutine.hpp bitutils.hpp rdpf.tcc
-rdpf.o: mpcops.hpp aes.hpp prg.hpp
+rdpf.o: rdpf.hpp mpcio.hpp types.hpp coroutine.hpp bitutils.hpp dpf.hpp
+rdpf.o: prg.hpp aes.hpp rdpf.tcc mpcops.hpp

+ 99 - 0
dpf.hpp

@@ -0,0 +1,99 @@
+#ifndef __DPF_HPP__
+#define __DPF_HPP__
+
+#include "prg.hpp"
+
+// We have two major kinds of distributed point functions (DPFs): ones
+// used for random-access memory (RDPFs) and ones used for comparisons
+// (CDPFs).  The major differences:
+//
+// RDPFs are of depth r in order to obliviously access a memory of size
+// 2^r.  They are created jointly by P0 and P1, with O(r) communication,
+// but O(2^r) local computation.  They can output bit shares of a
+// single-bit unit vector, word-sized additive shares of a unit vector,
+// XOR shares of a scaled unit vector, or additive shares of a scaled
+// unit vector.  They are typically used by evaluating _all_ 2^r leaves.
+// All of the 2^r leaves have to be computed at creation time, anyway,
+// so you can choose to store an "expanded" version of them that just
+// records those precomputed values, making them much faster to use in
+// the online phase, at the cost of storage and memory (and the time it
+// takes to just read them from disk, particular on rotational media).
+//
+// CDPFs are only used to compare VALUE_BITS-bit values (typically
+// VALUE_BITS = 64), and can only output bit shares of a single-bit unit
+// vector. This allows for an optimization where the leaf nodes of the
+// DPF (which are 128 bits wide) can subsume the last 7 levels of the
+// tree, so the CDPF is actually of height VALUE_BITS-7 (typically 57).
+// They are never used to expand all leaves, since that's way too large,
+// nor could P0 and P1 jointly compute them in the way they compute
+// RDPFs. On the other hand, P2 never sees these CDPFs in the online
+// phase, so P2 can just create them and send the halves to P0 and P1 at
+// preprocessing time.  They are very cheap to create, store, and send
+// over the network (in the preprocessing phase), and evaluate (in the
+// online phase); all of these are O(VALUE_BITS-7), somewhat abusing O()
+// notation here.
+
+struct DPF {
+    // The type of nodes
+    using node = DPFnode;
+
+    // The 128-bit seed
+    DPFnode seed;
+    // Which half of the DPF are we?
+    bit_t whichhalf;
+    // correction words; the depth of the DPF is the length of this
+    // vector
+    std::vector<DPFnode> cw;
+    // correction flag bits: the one for level i is bit i of this word
+    value_t cfbits;
+
+    // Descend from a node at depth parentdepth to one of its children
+    // whichchild = 0: left child
+    // whichchild = 1: right child
+    //
+    // Cost: 1 AES operation
+    inline DPFnode descend(const DPFnode &parent, nbits_t parentdepth,
+        bit_t whichchild, size_t &op_counter) const;
+};
+
+// Descend from a node at depth parentdepth to one of its children
+// whichchild = 0: left child
+// whichchild = 1: right child
+inline DPFnode DPF::descend(const DPFnode &parent, nbits_t parentdepth,
+    bit_t whichchild, size_t &op_counter) const
+{
+    DPFnode prgout;
+    bool flag = get_lsb(parent);
+    prg(prgout, parent, whichchild, op_counter);
+    if (flag) {
+        DPFnode CW = cw[parentdepth];
+        bit_t cfbit = !!(cfbits & (value_t(1)<<parentdepth));
+        DPFnode CWR = CW ^ lsb128_mask[cfbit];
+        prgout ^= (whichchild ? CWR : CW);
+    }
+    return prgout;
+}
+
+// Don't warn if we never actually use these functions
+static void dump_node(DPFnode node, const char *label = NULL)
+__attribute__ ((unused));
+static void dump_level(DPFnode *nodes, size_t num, const char *label = NULL)
+__attribute__ ((unused));
+
+static void dump_node(DPFnode node, const char *label)
+{
+    if (label) printf("%s: ", label);
+    for(int i=0;i<16;++i) { printf("%02x", ((unsigned char *)&node)[15-i]); } printf("\n");
+}
+
+static void dump_level(DPFnode *nodes, size_t num, const char *label)
+{
+    if (label) printf("%s:\n", label);
+    for (size_t i=0;i<num;++i) {
+        dump_node(nodes[i]);
+    }
+    printf("\n");
+}
+
+
+#endif

+ 0 - 41
rdpf.cpp

@@ -3,29 +3,6 @@
 #include "rdpf.hpp"
 #include "bitutils.hpp"
 #include "mpcops.hpp"
-#include "aes.hpp"
-#include "prg.hpp"
-
-// Don't warn if we never actually use these functions
-static void dump_node(DPFnode node, const char *label = NULL)
-__attribute__ ((unused));
-static void dump_level(DPFnode *nodes, size_t num, const char *label = NULL)
-__attribute__ ((unused));
-
-static void dump_node(DPFnode node, const char *label)
-{
-    if (label) printf("%s: ", label);
-    for(int i=0;i<16;++i) { printf("%02x", ((unsigned char *)&node)[15-i]); } printf("\n");
-}
-
-static void dump_level(DPFnode *nodes, size_t num, const char *label)
-{
-    if (label) printf("%s:\n", label);
-    for (size_t i=0;i<num;++i) {
-        dump_node(nodes[i]);
-    }
-    printf("\n");
-}
 
 // Compute the multiplicative inverse of x mod 2^{VALUE_BITS}
 // This is the same as computing x to the power of
@@ -283,24 +260,6 @@ size_t RDPF::size() const
     return size(depth);
 }
 
-// Descend from a node at depth parentdepth to one of its children
-// whichchild = 0: left child
-// whichchild = 1: right child
-DPFnode RDPF::descend(const DPFnode &parent, nbits_t parentdepth,
-    bit_t whichchild, size_t &op_counter) const
-{
-    DPFnode prgout;
-    bool flag = get_lsb(parent);
-    prg(prgout, parent, whichchild, op_counter);
-    if (flag) {
-        DPFnode CW = cw[parentdepth];
-        bit_t cfbit = !!(cfbits & (value_t(1)<<parentdepth));
-        DPFnode CWR = CW ^ lsb128_mask[cfbit];
-        prgout ^= (whichchild ? CWR : CW);
-    }
-    return prgout;
-}
-
 // Get the leaf node for the given input
 DPFnode RDPF::leaf(address_t input, size_t &op_counter) const
 {

+ 2 - 21
rdpf.hpp

@@ -8,6 +8,7 @@
 #include "coroutine.hpp"
 #include "types.hpp"
 #include "bitutils.hpp"
+#include "dpf.hpp"
 
 // Streaming evaluation, to avoid taking up enough memory to store
 // an entire evaluation.  T can be RDPF, RDPFPair, or RDPFTriple.
@@ -41,19 +42,7 @@ public:
     typename T::node next();
 };
 
-struct RDPF {
-    // The type of nodes
-    using node = DPFnode;
-
-    // The 128-bit seed
-    DPFnode seed;
-    // Which half of the DPF are we?
-    bit_t whichhalf;
-    // correction words; the depth of the DPF is the length of this
-    // vector
-    std::vector<DPFnode> cw;
-    // correction flag bits: the one for level i is bit i of this word
-    value_t cfbits;
+struct RDPF : public DPF {
     // The amount we have to scale the low words of the leaf values by
     // to get additive shares of a unit vector
     value_t unit_sum_inverse;
@@ -104,14 +93,6 @@ struct RDPF {
         return expansion[index];
     }
 
-    // Descend from a node at depth parentdepth to one of its children
-    // whichchild = 0: left child
-    // whichchild = 1: right child
-    //
-    // Cost: 1 AES operation
-    DPFnode descend(const DPFnode &parent, nbits_t parentdepth,
-        bit_t whichchild, size_t &op_counter) const;
-
     // Get the leaf node for the given input
     //
     // Cost: depth AES operations