Browse Source

Tests for CDPF creation, transmission, storage, retrieval, use

Ian Goldberg 1 year ago
parent
commit
67ffe06b19
5 changed files with 80 additions and 1 deletions
  1. 18 1
      cdpf.cpp
  2. 4 0
      cdpf.hpp
  3. 3 0
      mpcio.cpp
  4. 54 0
      online.cpp
  5. 1 0
      types.hpp

+ 18 - 1
cdpf.cpp

@@ -38,7 +38,7 @@ std::tuple<CDPF,CDPF> CDPF::generate(value_t target, size_t &aes_ops)
         prgboth(left1, right1, cur1, aes_ops);
 
         // Which way lies the target?
-        bool targetdir = !!(target & (value_t(1)<<(depth-curlevel-1)));
+        bool targetdir = !!(target & (value_t(1)<<((depth+7)-curlevel-1)));
         DPFnode CW;
         bool cfbit = !get_lsb(left0 ^ left1 ^ right0 ^ right1);
         bool flag0 = get_lsb(cur0);
@@ -135,3 +135,20 @@ std::tuple<CDPF,CDPF> CDPF::generate(size_t &aes_ops)
     arc4random_buf(&target, sizeof(target));
     return generate(target, aes_ops);
 }
+
+// Get the leaf node for the given input.  We don't actually use
+// this in the protocol, but it's useful for testing.
+DPFnode CDPF::leaf(value_t input, size_t &aes_ops) const
+{
+    nbits_t depth = cw.size();
+    DPFnode node = seed;
+    input >>= 7;
+    for (nbits_t d=0;d<depth-1;++d) {
+        bit_t dir = !!(input & (value_t(1)<<(depth-d-1)));
+        node = descend(node, d, dir, aes_ops);
+    }
+    // The last layer is special
+    bit_t dir = input & 1;
+    node = descend_to_leaf(node, dir, aes_ops);
+    return node;
+}

+ 4 - 0
cdpf.hpp

@@ -100,6 +100,10 @@ struct CDPF : public DPF {
     // Descend from the parent of a leaf node to the leaf node
     inline DPFnode descend_to_leaf(const DPFnode &parent,
         bit_t whichchild, size_t &aes_ops) const;
+
+    // Get the leaf node for the given input.  We don't actually use
+    // this in the protocol, but it's useful for testing.
+    DPFnode leaf(value_t input, size_t &aes_ops) const;
 };
 
 // Descend from the parent of a leaf node to the leaf node

+ 3 - 0
mpcio.cpp

@@ -274,6 +274,9 @@ MPCPeerIO::MPCPeerIO(unsigned player, bool preprocessing,
                 "rdpf", i, depth);
         }
     }
+    for (unsigned i=0; i<num_threads; ++i) {
+        cdpfs.emplace_back(player, preprocessing, "cdpf", i);
+    }
     for (auto &&sock : peersocks) {
         peerios.emplace_back(std::move(sock));
     }

+ 54 - 0
online.cpp

@@ -4,6 +4,7 @@
 #include "mpcops.hpp"
 #include "rdpf.hpp"
 #include "duoram.hpp"
+#include "cdpf.hpp"
 
 
 static void online_test(MPCIO &mpcio, yield_t &yield,
@@ -496,6 +497,56 @@ static void duoram_test(MPCIO &mpcio, yield_t &yield,
     pool.join();
 }
 
+static void cdpf_test(MPCIO &mpcio, yield_t &yield,
+    const PRACOptions &opts, char **args)
+{
+    value_t query, target;
+    arc4random_buf(&query, sizeof(query));
+    arc4random_buf(&target, sizeof(target));
+
+    if (*args) {
+        query = strtoull(*args, NULL, 16);
+        ++args;
+    }
+    if (*args) {
+        target = strtoull(*args, NULL, 16);
+        ++args;
+    }
+
+    int num_threads = opts.num_threads;
+    boost::asio::thread_pool pool(num_threads);
+    for (int thread_num = 0; thread_num < num_threads; ++thread_num) {
+        boost::asio::post(pool, [&mpcio, thread_num, &query, &target] {
+            MPCTIO tio(mpcio, thread_num);
+            size_t &aes_ops = tio.aes_ops();
+            if (mpcio.player == 2) {
+                auto [ dpf0, dpf1 ] = CDPF::generate(target, aes_ops);
+                DPFnode leaf0 = dpf0.leaf(query, aes_ops);
+                DPFnode leaf1 = dpf1.leaf(query, aes_ops);
+                printf("DPFXOR_{%016lx}(%016lx} = ", target, query);
+                dump_node(leaf0 ^ leaf1);
+            } else {
+                CDPF dpf = tio.cdpf();
+                printf("ashare = %016lX\nxshare = %016lX\n",
+                    dpf.as_target.ashare, dpf.xs_target.xshare);
+                DPFnode leaf = dpf.leaf(query, aes_ops);
+                printf("DPF(%016lx) = ", query);
+                dump_node(leaf);
+                if (mpcio.player == 1) {
+                    tio.iostream_peer() << leaf;
+                } else {
+                    DPFnode peerleaf;
+                    tio.iostream_peer() >> peerleaf;
+                    printf("XOR = ");
+                    dump_node(leaf ^ peerleaf);
+                }
+            }
+            tio.send();
+        });
+    }
+    pool.join();
+}
+
 void online_main(MPCIO &mpcio, const PRACOptions &opts, char **args)
 {
     // Run everything inside a coroutine so that simple tests don't have
@@ -532,6 +583,9 @@ void online_main(MPCIO &mpcio, const PRACOptions &opts, char **args)
                 } else {
                     duoram_test<RegAS>(mpcio, yield, opts, args);
                 }
+            } else if (!strcmp(*args, "cdpftest")) {
+                ++args;
+                cdpf_test(mpcio, yield, opts, args);
             } else {
                 std::cerr << "Unknown mode " << *args << "\n";
             }

+ 1 - 0
types.hpp

@@ -511,6 +511,7 @@ struct CDPFName { static constexpr const char *name = "c"; };
 
 // Default I/O for various types
 
+DEFAULT_IO(DPFnode)
 DEFAULT_IO(RegBS)
 DEFAULT_IO(RegAS)
 DEFAULT_IO(RegXS)