ソースを参照

If we run out of some type of precomputed element, be explicit about what type it was

Ian Goldberg 1 年間 前
コミット
dc610848be
3 ファイル変更33 行追加15 行削除
  1. 18 9
      mpcio.cpp
  2. 8 6
      mpcio.hpp
  3. 7 0
      types.hpp

+ 18 - 9
mpcio.cpp

@@ -2,19 +2,23 @@
 #include "rdpf.hpp"
 #include "bitutils.hpp"
 
-template<typename T>
-PreCompStorage<T>::PreCompStorage(unsigned player, bool preprocessing,
-        const char *filenameprefix, unsigned thread_num) {
+template<typename T, typename N>
+PreCompStorage<T,N>::PreCompStorage(unsigned player, bool preprocessing,
+        const char *filenameprefix, unsigned thread_num) :
+        name(N::name), depth(0)
+{
     init(player, preprocessing, filenameprefix, thread_num);
 }
 
-template<typename T>
-void PreCompStorage<T>::init(unsigned player, bool preprocessing,
-        const char *filenameprefix, unsigned thread_num, nbits_t depth) {
+template<typename T, typename N>
+void PreCompStorage<T,N>::init(unsigned player, bool preprocessing,
+        const char *filenameprefix, unsigned thread_num, nbits_t depth)
+{
     if (preprocessing) return;
     std::string filename(filenameprefix);
     char suffix[20];
     if (depth) {
+        this->depth = depth;
         sprintf(suffix, "%02d.p%d.t%u", depth, player%10, thread_num);
     } else {
         sprintf(suffix, ".p%d.t%u", player%10, thread_num);
@@ -29,11 +33,16 @@ void PreCompStorage<T>::init(unsigned player, bool preprocessing,
     count = 0;
 }
 
-template<typename T>
-void PreCompStorage<T>::get(T& nextval) {
+template<typename T, typename N>
+void PreCompStorage<T,N>::get(T& nextval)
+{
     storage >> nextval;
     if (!storage.good()) {
-        std::cerr << "Failed to read precomputed value from storage\n";
+        std::cerr << "Failed to read precomputed value from " << name;
+        if (depth) {
+            std::cerr << (int)depth;
+        }
+        std::cerr << " storage\n";
         exit(1);
     }
     ++count;

+ 8 - 6
mpcio.hpp

@@ -22,10 +22,10 @@ using boost::asio::ip::tcp;
 
 // Classes to represent stored precomputed data (e.g., multiplication triples)
 
-template<typename T>
+template<typename T, typename N>
 class PreCompStorage {
 public:
-    PreCompStorage() : count(0) {}
+    PreCompStorage() : name(N::name), depth(0), count(0) {}
     PreCompStorage(unsigned player, bool preprocessing,
         const char *filenameprefix, unsigned thread_num);
     void init(unsigned player, bool preprocessing,
@@ -36,6 +36,8 @@ public:
     inline void reset_stats() { count = 0; }
 private:
     std::ifstream storage;
+    std::string name;
+    nbits_t depth;
     size_t count;
 };
 
@@ -194,11 +196,11 @@ struct MPCPeerIO : public MPCIO {
     // culprit), but you can have a deque of those for some reason.
     std::deque<MPCSingleIO> peerios;
     std::deque<MPCSingleIO> serverios;
-    std::vector<PreCompStorage<MultTriple>> triples;
-    std::vector<PreCompStorage<HalfTriple>> halftriples;
+    std::vector<PreCompStorage<MultTriple, MultTripleName>> triples;
+    std::vector<PreCompStorage<HalfTriple, HalfTripleName>> halftriples;
     // The outer vector is (like above) one item per thread
     // The inner array is indexed by DPF depth (depth d is at entry d-1)
-    std::vector<std::array<PreCompStorage<RDPFTriple>,ADDRESS_MAX_BITS>> rdpftriples;
+    std::vector<std::array<PreCompStorage<RDPFTriple, RDPFTripleName>,ADDRESS_MAX_BITS>> rdpftriples;
 
     MPCPeerIO(unsigned player, bool preprocessing,
             std::deque<tcp::socket> &peersocks,
@@ -219,7 +221,7 @@ struct MPCServerIO : public MPCIO {
     std::deque<MPCSingleIO> p1ios;
     // The outer vector is (like above) one item per thread
     // The inner array is indexed by DPF depth (depth d is at entry d-1)
-    std::vector<std::array<PreCompStorage<RDPFPair>,ADDRESS_MAX_BITS>> rdpfpairs;
+    std::vector<std::array<PreCompStorage<RDPFPair, RDPFPairName>,ADDRESS_MAX_BITS>> rdpfpairs;
 
     MPCServerIO(bool preprocessing,
             std::deque<tcp::socket> &p0socks,

+ 7 - 0
types.hpp

@@ -190,12 +190,17 @@ using address_t = uint64_t;
 // but subject to the relation that X0*Y1 + Y0*X1 = Z0+Z1
 
 using MultTriple = std::tuple<value_t, value_t, value_t>;
+// The *Name structs are a way to get strings representing the names of
+// the types as would be given to preprocessing to create them in
+// advance.
+struct MultTripleName { static constexpr const char *name = "t"; };
 
 // A half-triple is (X0,Z0) held by P0 (and correspondingly (Y1,Z1) held
 // by P1), with all values random, but subject to the relation that
 // X0*Y1 = Z0+Z1
 
 using HalfTriple = std::tuple<value_t, value_t>;
+struct HalfTripleName { static constexpr const char *name = "h"; };
 
 // The type of nodes in a DPF.  This must be at least as many bits as
 // the security parameter, and at least twice as many bits as value_t.
@@ -217,7 +222,9 @@ struct SelectTriple {
 // These are defined in rdpf.hpp, but declared here to avoid cyclic
 // header dependencies.
 struct RDPFPair;
+struct RDPFPairName { static constexpr const char *name = "r"; };
 struct RDPFTriple;
+struct RDPFTripleName { static constexpr const char *name = "r"; };
 
 // We want the I/O (using << and >>) for many classes
 // to just be a common thing: write out the bytes