ソースを参照

Be able to send RDPFs to other parties

Ian Goldberg 1 年間 前
コミット
c8a0051158
4 ファイル変更124 行追加3 行削除
  1. 15 0
      mpcio.cpp
  2. 37 3
      mpcio.hpp
  3. 54 0
      rdpf.cpp
  4. 18 0
      rdpf.hpp

+ 15 - 0
mpcio.cpp

@@ -279,6 +279,21 @@ MPCServerIO::MPCServerIO(bool preprocessing,
     }
 }
 
+MPCTIO::MPCTIO(MPCIO &mpcio, int thread_num) :
+        thread_num(thread_num), thread_lamport(mpcio.lamport),
+        mpcio(mpcio)
+{
+    if (mpcio.player < 2) {
+        MPCPeerIO &mpcpio = static_cast<MPCPeerIO&>(mpcio);
+        peer_iostream.emplace(mpcpio.peerios[thread_num], thread_lamport);
+        server_iostream.emplace(mpcpio.serverios[thread_num], thread_lamport);
+    } else {
+        MPCServerIO &mpcsrvio = static_cast<MPCServerIO&>(mpcio);
+        p0_iostream.emplace(mpcsrvio.p0ios[thread_num], thread_lamport);
+        p1_iostream.emplace(mpcsrvio.p1ios[thread_num], thread_lamport);
+    }
+}
+
 // Sync our per-thread lamport clock with the master one in the
 // mpcio.  You only need to call this explicitly if your MPCTIO
 // outlives your thread (in which case call it after the join), or

+ 37 - 3
mpcio.hpp

@@ -216,17 +216,38 @@ struct MPCServerIO : public MPCIO {
             std::deque<tcp::socket> &p1socks);
 };
 
+class MPCSingleIOStream {
+    MPCSingleIO &sio;
+    lamport_t &lamport;
+
+public:
+    MPCSingleIOStream(MPCSingleIO &sio, lamport_t &lamport) :
+        sio(sio), lamport(lamport) {}
+
+    MPCSingleIOStream& write(const char *data, std::streamsize len) {
+        sio.queue(data, len, lamport);
+        return *this;
+    }
+
+    MPCSingleIOStream& read(char *data, std::streamsize len) {
+        sio.recv(data, len, lamport);
+        return *this;
+    }
+};
+
 // A handle to one thread's sockets and streams in a MPCIO
 
 class MPCTIO {
     int thread_num;
     lamport_t thread_lamport;
     MPCIO &mpcio;
+    std::optional<MPCSingleIOStream> peer_iostream;
+    std::optional<MPCSingleIOStream> server_iostream;
+    std::optional<MPCSingleIOStream> p0_iostream;
+    std::optional<MPCSingleIOStream> p1_iostream;
 
 public:
-    MPCTIO(MPCIO &mpcio, int thread_num):
-        thread_num(thread_num), thread_lamport(mpcio.lamport),
-        mpcio(mpcio) {}
+    MPCTIO(MPCIO &mpcio, int thread_num);
 
     // Sync our per-thread lamport clock with the master one in the
     // mpcio.  You only need to call this explicitly if your MPCTIO
@@ -243,6 +264,8 @@ public:
         sync_lamport();
     }
 
+    // Computational peers use these functions:
+
     // Queue up data to the peer or to the server
 
     void queue_peer(const void *data, size_t len);
@@ -253,6 +276,11 @@ public:
     size_t recv_peer(void *data, size_t len);
     size_t recv_server(void *data, size_t len);
 
+    // Or get these MPCSingleIOStreams
+    MPCSingleIOStream& iostream_peer() { return peer_iostream.value(); }
+    MPCSingleIOStream& iostream_server() { return server_iostream.value(); }
+
+    // The server uses these functions:
 
     // Queue up data to p0 or p1
 
@@ -264,6 +292,12 @@ public:
     size_t recv_p0(void *data, size_t len);
     size_t recv_p1(void *data, size_t len);
 
+    // Or get these MPCSingleIOStreams
+    MPCSingleIOStream& iostream_p0() { return p0_iostream.value(); }
+    MPCSingleIOStream& iostream_p1() { return p1_iostream.value(); }
+
+    // Everyone can use the remaining functions.
+
     // Send all queued data for this thread
 
     void send();

+ 54 - 0
rdpf.cpp

@@ -254,3 +254,57 @@ RDPF::RDPF(MPCTIO &tio, yield_t &yield,
     delete[] curlevel;
     delete[] nextlevel;
 }
+
+// The number of bytes it will take to store a RDPF of the given depth
+size_t RDPF::size(nbits_t depth)
+{
+    return sizeof(seed) + depth*sizeof(DPFnode) + BITBYTES(depth) +
+        sizeof(unit_sum_inverse) + sizeof(scaled_sum) +
+        sizeof(scaled_xor);
+}
+
+// The number of bytes it will take to store this RDPF
+size_t RDPF::size() const
+{
+    uint8_t depth = cw.size();
+    return size(depth);
+}
+
+MPCSingleIOStream& operator>>(MPCSingleIOStream &is, RDPF &rdpf)
+{
+    is.read((char *)&rdpf.seed, sizeof(rdpf.seed));
+    uint8_t depth;
+    assert(depth <= VALUE_BITS);
+    is.read((char *)&depth, sizeof(depth));
+    rdpf.cw.clear();
+    for (uint8_t i=0; i<depth; ++i) {
+        DPFnode cw;
+        is.read((char *)&cw, sizeof(cw));
+        rdpf.cw.push_back(cw);
+    }
+    value_t cfbits = 0;
+    is.read((char *)&cfbits, BITBYTES(depth));
+    rdpf.cfbits = cfbits;
+    is.read((char *)&rdpf.unit_sum_inverse, sizeof(rdpf.unit_sum_inverse));
+    is.read((char *)&rdpf.scaled_sum, sizeof(rdpf.scaled_sum));
+    is.read((char *)&rdpf.scaled_xor, sizeof(rdpf.scaled_xor));
+
+    return is;
+}
+
+MPCSingleIOStream& operator<<(MPCSingleIOStream &os, const RDPF &rdpf)
+{
+    os.write((const char *)&rdpf.seed, sizeof(rdpf.seed));
+    uint8_t depth = rdpf.cw.size();
+    assert(depth <= VALUE_BITS);
+    os.write((const char *)&depth, sizeof(depth));
+    for (uint8_t i=0; i<depth; ++i) {
+        os.write((const char *)&rdpf.cw[i], sizeof(rdpf.cw[i]));
+    }
+    os.write((const char *)&rdpf.cfbits, BITBYTES(depth));
+    os.write((const char *)&rdpf.unit_sum_inverse, sizeof(rdpf.unit_sum_inverse));
+    os.write((const char *)&rdpf.scaled_sum, sizeof(rdpf.scaled_sum));
+    os.write((const char *)&rdpf.scaled_xor, sizeof(rdpf.scaled_xor));
+
+    return os;
+}

+ 18 - 0
rdpf.hpp

@@ -2,6 +2,7 @@
 #define __RDPF_HPP__
 
 #include <vector>
+#include <iostream>
 
 #include "mpcio.hpp"
 #include "coroutine.hpp"
@@ -25,6 +26,8 @@ struct RDPF {
     // of the leaf values for P0 and P1 XOR to M_xs * e_{target}
     RegXS scaled_xor;
 
+    RDPF() {}
+
     // Construct a DPF with the given (XOR-shared) target location, and
     // of the given depth, to be used for random-access memory reads and
     // writes.  The DPF is constructed collaboratively by P0 and P1,
@@ -39,6 +42,21 @@ struct RDPF {
     // 0 local AES operations for P2
     RDPF(MPCTIO &tio, yield_t &yield,
         RegXS target, nbits_t depth);
+
+    // The number of bytes it will take to store this RDPF
+    size_t size() const;
+
+    // The number of bytes it will take to store a RDPF of the given
+    // depth
+    static size_t size(nbits_t depth);
+
+    // The depth
+    inline nbits_t depth() const { return cw.size(); }
 };
 
+// I/O for RDPFs
+
+MPCSingleIOStream& operator>>(MPCSingleIOStream &is, RDPF &rdpf);
+MPCSingleIOStream& operator<<(MPCSingleIOStream &os, const RDPF &rdpf);
+
 #endif