Просмотр исходного кода

Change some functions from templated on return values to overloaded on reference parameters

Ian Goldberg 1 год назад
Родитель
Сommit
d8d08f2a6e
4 измененных файлов с 126 добавлено и 159 удалено
  1. 21 8
      duoram.tcc
  2. 6 2
      online.cpp
  3. 99 18
      rdpf.hpp
  4. 0 131
      rdpf.tcc

+ 21 - 8
duoram.tcc

@@ -276,7 +276,8 @@ Duoram<T>::Shape::MemRefS<U,FT,FST,Sh>::operator FT()
         RDPFTriple dt = shape.tio.rdpftriple(shape.yield, shape.addr_size);
 
         // Compute the index offset
-        U indoffset = dt.target<U>();
+        U indoffset;
+        dt.get_target(indoffset);
         indoffset -= idx;
 
         // We only need two of the DPFs for reading
@@ -305,7 +306,9 @@ Duoram<T>::Shape::MemRefS<U,FT,FST,Sh>::operator FT()
         res = pe.reduce(init, [this, &dp, &shape] (int thread_num,
                 address_t i, const RDPFPair::node &leaf) {
             // The values from the two DPFs, which will each be of type T
-            auto [V0, V1] = dp.unit<FT>(leaf);
+            std::tuple<FT,FT> V;
+            dp.unit(V, leaf);
+            auto [V0, V1] = V;
             // References to the appropriate cells in our database, our
             // blind, and our copy of the peer's blinded database
             auto [DB, BL, PBD] = shape.get_comp(i, fieldsel);
@@ -340,7 +343,9 @@ Duoram<T>::Shape::MemRefS<U,FT,FST,Sh>::operator FT()
         gamma = pe.reduce(init, [this, &dp, &shape] (int thread_num,
                 address_t i, const RDPFPair::node &leaf) {
             // The values from the two DPFs, each of type FT
-            auto [V0, V1] = dp.unit<FT>(leaf);
+            std::tuple<FT,FT> V;
+            dp.unit(V, leaf);
+            auto [V0, V1] = V;
 
             // shape.get_server(i) returns a pair of references to the
             // appropriate cells in the two blinded databases
@@ -381,10 +386,13 @@ typename Duoram<T>::Shape::template MemRefS<U,FT,FST,Sh>
         RDPFTriple dt = shape.tio.rdpftriple(shape.yield, shape.addr_size);
 
         // Compute the index and message offsets
-        U indoffset = dt.target<U>();
+        U indoffset;
+        dt.get_target(indoffset);
         indoffset -= idx;
         auto Moffset = std::make_tuple(M, M, M);
-        Moffset -= dt.scaled_value<FT>();
+        std::tuple<FT,FT,FT> scaled_val;
+        dt.scaled_value(scaled_val);
+        Moffset -= scaled_val;
 
         // Send them to the peer, and everything except the first offset
         // to the server
@@ -414,8 +422,10 @@ typename Duoram<T>::Shape::template MemRefS<U,FT,FST,Sh>
         pe.reduce(init, [this, &dt, &shape, &Mshift, player] (int thread_num,
                 address_t i, const RDPFTriple::node &leaf) {
             // The values from the three DPFs
-            auto [V0, V1, V2] =
-                dt.scaled<FT>(leaf) + dt.unit<FT>(leaf) * Mshift;
+            std::tuple<FT,FT,FT> scaled, unit;
+            dt.scaled(scaled, leaf);
+            dt.unit(unit, leaf);
+            auto [V0, V1, V2] = scaled + unit * Mshift;
             // References to the appropriate cells in our database, our
             // blind, and our copy of the peer's blinded database
             auto [DB, BL, PBD] = shape.get_comp(i,fieldsel);
@@ -455,7 +465,10 @@ typename Duoram<T>::Shape::template MemRefS<U,FT,FST,Sh>
         pe.reduce(init, [this, &dp, &shape, &Mshift] (int thread_num,
                 address_t i, const RDPFPair::node &leaf) {
             // The values from the two DPFs
-            auto V = dp.scaled<FT>(leaf) + dp.unit<FT>(leaf) * Mshift;
+            std::tuple<FT,FT> scaled, unit;
+            dp.scaled(scaled, leaf);
+            dp.unit(unit, leaf);
+            auto V = scaled + unit * Mshift;
             // shape.get_server(i) returns a pair of references to the
             // appropriate cells in the two blinded databases, so we can
             // subtract the pair directly.

+ 6 - 2
online.cpp

@@ -558,7 +558,9 @@ static void par_tupleeval_timing(MPCIO &mpcio,
             V result, init;
             result = pe.reduce(init, [&dp] (int thread_num, address_t i,
                     const RDPFPair::node &leaf) {
-                return dp.scaled<RegXS>(leaf);
+                std::tuple<RegXS,RegXS> scaled;
+                dp.scaled(scaled, leaf);
+                return scaled;
             });
             printf("%016lx\n%016lx\n", std::get<0>(result).xshare,
                 dp.dpf[0].scaled_xor.xshare);
@@ -574,7 +576,9 @@ static void par_tupleeval_timing(MPCIO &mpcio,
             V result, init;
             result = pe.reduce(init, [&dt] (int thread_num, address_t i,
                     const RDPFTriple::node &leaf) {
-                return dt.scaled<RegXS>(leaf);
+                std::tuple<RegXS,RegXS,RegXS> scaled;
+                dt.scaled(scaled, leaf);
+                return scaled;
             });
             printf("%016lx\n%016lx\n", std::get<0>(result).xshare,
                 dt.dpf[0].scaled_xor.xshare);

+ 99 - 18
rdpf.hpp

@@ -77,7 +77,7 @@ struct RDPF : public DPF {
         return a;
     }
 
-    // Get the XOR-shared scaled vector entry from the leaf ndoe
+    // Get the XOR-shared scaled vector entry from the leaf node
     inline RegXS scaled_xs(DPFnode leaf) const {
         RegXS x;
         value_t highword =
@@ -86,7 +86,7 @@ struct RDPF : public DPF {
         return x;
     }
 
-    // Get the additive-shared scaled vector entry from the leaf ndoe
+    // Get the additive-shared scaled vector entry from the leaf node
     inline RegAS scaled_as(DPFnode leaf) const {
         RegAS a;
         value_t highword =
@@ -148,21 +148,65 @@ struct RDPFTriple {
     node descend(const node &parent, nbits_t parentdepth,
         bit_t whichchild, size_t &aes_ops) const;
 
-    // Templated versions of functions to get DPF components and outputs
-    // so that the appropriate one can be selected with a template
+    // Overloaded versions of functions to get DPF components and
+    // outputs so that the appropriate one can be selected with a
     // parameter
 
-    template <typename T>
-    inline T target() const;
+    inline void get_target(RegAS &target) const { target = as_target; }
+    inline void get_target(RegXS &target) const { target = xs_target; }
 
-    template <typename T>
-    inline std::tuple<T,T,T> scaled_value() const;
+    // Additive share of the scaling value M_as such that the high words
+    // of the leaf values for P0 and P1 add to M_as * e_{target}
+    inline void scaled_value(std::tuple<RegAS,RegAS,RegAS> &v) const {
+        std::get<0>(v) = dpf[0].scaled_sum;
+        std::get<1>(v) = dpf[1].scaled_sum;
+        std::get<2>(v) = dpf[2].scaled_sum;
+    }
 
-    template <typename T>
-    inline std::tuple<T,T,T> unit(node leaf) const;
+    // XOR share of the scaling value M_xs such that the high words
+    // of the leaf values for P0 and P1 XOR to M_xs * e_{target}
+    inline void scaled_value(std::tuple<RegXS,RegXS,RegXS> &v) const {
+        std::get<0>(v) = dpf[0].scaled_xor;
+        std::get<1>(v) = dpf[1].scaled_xor;
+        std::get<2>(v) = dpf[2].scaled_xor;
+    }
+
+    // Get the additive-shared unit vector entry from the leaf node
+    inline void unit(std::tuple<RegAS,RegAS,RegAS> &u, node leaf) const {
+        std::get<0>(u) = dpf[0].unit_as(std::get<0>(leaf));
+        std::get<1>(u) = dpf[1].unit_as(std::get<1>(leaf));
+        std::get<2>(u) = dpf[2].unit_as(std::get<2>(leaf));
+    }
+
+    // Get the bit-shared unit vector entry from the leaf node
+    inline void unit(std::tuple<RegXS,RegXS,RegXS> &u, node leaf) const {
+        std::get<0>(u) = dpf[0].unit_bs(std::get<0>(leaf));
+        std::get<1>(u) = dpf[1].unit_bs(std::get<1>(leaf));
+        std::get<2>(u) = dpf[2].unit_bs(std::get<2>(leaf));
+    }
 
+    // For any more complex entry type, that type will handle the conversion
+    // for each DPF
     template <typename T>
-    inline std::tuple<T,T,T> scaled(node leaf) const;
+    inline void unit(std::tuple<T,T,T> &u, node leaf) const {
+        std::get<0>(u).unit(dpf[0], std::get<0>(leaf));
+        std::get<1>(u).unit(dpf[1], std::get<1>(leaf));
+        std::get<2>(u).unit(dpf[2], std::get<2>(leaf));
+    }
+
+    // Get the additive-shared scaled vector entry from the leaf node
+    inline void scaled(std::tuple<RegAS,RegAS,RegAS> &s, node leaf) const {
+        std::get<0>(s) = dpf[0].scaled_as(std::get<0>(leaf));
+        std::get<1>(s) = dpf[1].scaled_as(std::get<1>(leaf));
+        std::get<2>(s) = dpf[2].scaled_as(std::get<2>(leaf));
+    }
+
+    // Get the XOR-shared scaled vector entry from the leaf node
+    inline void scaled(std::tuple<RegXS,RegXS,RegXS> &s, node leaf) const {
+        std::get<0>(s) = dpf[0].scaled_xs(std::get<0>(leaf));
+        std::get<1>(s) = dpf[1].scaled_xs(std::get<1>(leaf));
+        std::get<2>(s) = dpf[2].scaled_xs(std::get<2>(leaf));
+    }
 };
 
 struct RDPFPair {
@@ -205,18 +249,55 @@ struct RDPFPair {
     node descend(const node &parent, nbits_t parentdepth,
         bit_t whichchild, size_t &aes_ops) const;
 
-    // Templated versions of functions to get DPF components and outputs
-    // so that the appropriate one can be selected with a template
+    // Overloaded versions of functions to get DPF components and
+    // outputs so that the appropriate one can be selected with a
     // parameter
 
-    template <typename T>
-    inline std::tuple<T,T> scaled_value() const;
+    // Additive share of the scaling value M_as such that the high words
+    // of the leaf values for P0 and P1 add to M_as * e_{target}
+    inline void scaled_value(std::tuple<RegAS,RegAS> &v) const {
+        std::get<0>(v) = dpf[0].scaled_sum;
+        std::get<1>(v) = dpf[1].scaled_sum;
+    }
 
-    template <typename T>
-    inline std::tuple<T,T> unit(node leaf) const;
+    // XOR share of the scaling value M_xs such that the high words
+    // of the leaf values for P0 and P1 XOR to M_xs * e_{target}
+    inline void scaled_value(std::tuple<RegXS,RegXS> &v) const {
+        std::get<0>(v) = dpf[0].scaled_xor;
+        std::get<1>(v) = dpf[1].scaled_xor;
+    }
 
+    // Get the additive-shared unit vector entry from the leaf node
+    inline void unit(std::tuple<RegAS,RegAS> &u, node leaf) const {
+        std::get<0>(u) = dpf[0].unit_as(std::get<0>(leaf));
+        std::get<1>(u) = dpf[1].unit_as(std::get<1>(leaf));
+    }
+
+    // Get the bit-shared unit vector entry from the leaf node
+    inline void unit(std::tuple<RegXS,RegXS> &u, node leaf) const {
+        std::get<0>(u) = dpf[0].unit_bs(std::get<0>(leaf));
+        std::get<1>(u) = dpf[1].unit_bs(std::get<1>(leaf));
+    }
+
+    // For any more complex entry type, that type will handle the conversion
+    // for each DPF
     template <typename T>
-    inline std::tuple<T,T> scaled(node leaf) const;
+    inline void unit(std::tuple<T,T> &u, node leaf) const {
+        std::get<0>(u).unit(dpf[0], std::get<0>(leaf));
+        std::get<1>(u).unit(dpf[1], std::get<1>(leaf));
+    }
+
+    // Get the additive-shared scaled vector entry from the leaf node
+    inline void scaled(std::tuple<RegAS,RegAS> &s, node leaf) const {
+        std::get<0>(s) = dpf[0].scaled_as(std::get<0>(leaf));
+        std::get<1>(s) = dpf[1].scaled_as(std::get<1>(leaf));
+    }
+
+    // Get the XOR-shared scaled vector entry from the leaf node
+    inline void scaled(std::tuple<RegXS,RegXS> &s, node leaf) const {
+        std::get<0>(s) = dpf[0].scaled_xs(std::get<0>(leaf));
+        std::get<1>(s) = dpf[1].scaled_xs(std::get<1>(leaf));
+    }
 
 };
 

+ 0 - 131
rdpf.tcc

@@ -161,137 +161,6 @@ inline V ParallelEval<T>::reduce(V init, W process)
     return total;
 }
 
-// Additive share of the target index
-template <>
-inline RegAS RDPFTriple::target<RegAS>() const {
-    return as_target;
-}
-
-// XOR share of the target index
-template <>
-inline RegXS RDPFTriple::target<RegXS>() const {
-    return xs_target;
-}
-
-// Additive share of the scaling value M_as such that the high words
-// of the leaf values for P0 and P1 add to M_as * e_{target}
-template <>
-inline std::tuple<RegAS,RegAS,RegAS> RDPFTriple::scaled_value<RegAS>() const {
-    return std::make_tuple(dpf[0].scaled_sum, dpf[1].scaled_sum,
-        dpf[2].scaled_sum);
-}
-
-// XOR share of the scaling value M_xs such that the high words
-// of the leaf values for P0 and P1 XOR to M_xs * e_{target}
-template <>
-inline std::tuple<RegXS,RegXS,RegXS> RDPFTriple::scaled_value<RegXS>() const {
-    return std::make_tuple(dpf[0].scaled_xor, dpf[1].scaled_xor,
-        dpf[2].scaled_xor);
-}
-
-// Get the bit-shared unit vector entry from the leaf node
-template <>
-inline std::tuple<RegXS,RegXS,RegXS> RDPFTriple::unit<RegXS>(node leaf) const {
-    return std::make_tuple(
-        dpf[0].unit_bs(std::get<0>(leaf)),
-        dpf[1].unit_bs(std::get<1>(leaf)),
-        dpf[2].unit_bs(std::get<2>(leaf)));
-}
-
-// Get the additive-shared unit vector entry from the leaf node
-template <>
-inline std::tuple<RegAS,RegAS,RegAS> RDPFTriple::unit<RegAS>(node leaf) const {
-    return std::make_tuple(
-        dpf[0].unit_as(std::get<0>(leaf)),
-        dpf[1].unit_as(std::get<1>(leaf)),
-        dpf[2].unit_as(std::get<2>(leaf)));
-}
-
-// For any more complex entry type, that type will handle the conversion
-// for each DPF
-template <typename T>
-inline std::tuple<T,T,T> RDPFTriple::unit(node leaf) const {
-    T v0, v1, v2;
-    v0.unit(dpf[0], std::get<0>(leaf));
-    v1.unit(dpf[1], std::get<1>(leaf));
-    v2.unit(dpf[2], std::get<2>(leaf));
-    return std::make_tuple(v0,v1,v2);
-}
-
-// Get the XOR-shared scaled vector entry from the leaf ndoe
-template <>
-inline std::tuple<RegXS,RegXS,RegXS> RDPFTriple::scaled<RegXS>(node leaf) const {
-    return std::make_tuple(
-        dpf[0].scaled_xs(std::get<0>(leaf)),
-        dpf[1].scaled_xs(std::get<1>(leaf)),
-        dpf[2].scaled_xs(std::get<2>(leaf)));
-}
-
-// Get the additive-shared scaled vector entry from the leaf node
-template <>
-inline std::tuple<RegAS,RegAS,RegAS> RDPFTriple::scaled<RegAS>(node leaf) const {
-    return std::make_tuple(
-        dpf[0].scaled_as(std::get<0>(leaf)),
-        dpf[1].scaled_as(std::get<1>(leaf)),
-        dpf[2].scaled_as(std::get<2>(leaf)));
-}
-
-// Additive share of the scaling value M_as such that the high words
-// of the leaf values for P0 and P1 add to M_as * e_{target}
-template <>
-inline std::tuple<RegAS,RegAS> RDPFPair::scaled_value<RegAS>() const {
-    return std::make_tuple(dpf[0].scaled_sum, dpf[1].scaled_sum);
-}
-
-// XOR share of the scaling value M_xs such that the high words
-// of the leaf values for P0 and P1 XOR to M_xs * e_{target}
-template <>
-inline std::tuple<RegXS,RegXS> RDPFPair::scaled_value<RegXS>() const {
-    return std::make_tuple(dpf[0].scaled_xor, dpf[1].scaled_xor);
-}
-
-// Get the bit-shared unit vector entry from the leaf node
-template <>
-inline std::tuple<RegXS,RegXS> RDPFPair::unit<RegXS>(node leaf) const {
-    return std::make_tuple(
-        dpf[0].unit_bs(std::get<0>(leaf)),
-        dpf[1].unit_bs(std::get<1>(leaf)));
-}
-
-// Get the additive-shared unit vector entry from the leaf node
-template <>
-inline std::tuple<RegAS,RegAS> RDPFPair::unit<RegAS>(node leaf) const {
-    return std::make_tuple(
-        dpf[0].unit_as(std::get<0>(leaf)),
-        dpf[1].unit_as(std::get<1>(leaf)));
-}
-
-// For any more complex entry type, that type will handle the conversion
-// for each DPF
-template <typename T>
-inline std::tuple<T,T> RDPFPair::unit(node leaf) const {
-    T v0, v1;
-    v0.unit(dpf[0], std::get<0>(leaf));
-    v1.unit(dpf[1], std::get<1>(leaf));
-    return std::make_tuple(v0,v1);
-}
-
-// Get the XOR-shared scaled vector entry from the leaf ndoe
-template <>
-inline std::tuple<RegXS,RegXS> RDPFPair::scaled<RegXS>(node leaf) const {
-    return std::make_tuple(
-        dpf[0].scaled_xs(std::get<0>(leaf)),
-        dpf[1].scaled_xs(std::get<1>(leaf)));
-}
-
-// Get the additive-shared scaled vector entry from the leaf node
-template <>
-inline std::tuple<RegAS,RegAS> RDPFPair::scaled<RegAS>(node leaf) const {
-    return std::make_tuple(
-        dpf[0].scaled_as(std::get<0>(leaf)),
-        dpf[1].scaled_as(std::get<1>(leaf)));
-}
-
 // I/O for RDPFs
 
 template <typename T>