#include #include #include #include #include "dpf.hpp" #include "dpf/app_flow.hpp" #include "dpf/app_plans.hpp" // Private set intersection, the DPF step (Kolesnikov, Kumaresan, Rosulek, // and Trieu, CCS 2016). The sender keeps a puncturable-PRF master. Each // receiver element is a puncture; the servers evaluate the punctured key // and test whether the tag sits in the sender's image. No full-domain table. // // c++ -std=c++17 -march=native -I include -I thirdparty \ // examples/applications/psi.cpp namespace { using domain_t = std::uint8_t; bool blocks_eq(simde__m128i a, simde__m128i b) { return std::memcmp(&a, &b, sizeof(a)) == 0; } bool in_image(simde__m128i tag, const std::vector & image) { for (auto v : image) if (blocks_eq(v, tag)) return true; return false; } } // namespace int main() { auto master = dpf::make_pprf_master(); const domain_t sender[] = {4, 10, 42}; const domain_t receiver[] = {42, 7}; std::vector image; for (auto x : sender) image.push_back(dpf::pprf_eval(master, x)); auto punctured_hit = dpf::puncture(master, receiver[0]); auto punctured_miss = dpf::puncture(master, receiver[1]); // Off-path points agree with the master; the programmed leaf at alpha // matches the master leaf (sender who keeps the master set it). const auto hit = dpf::pprf_eval(punctured_hit, receiver[0]); const auto miss_off = dpf::pprf_eval(punctured_miss, domain_t{0}); const auto master_miss_off = dpf::pprf_eval(master, domain_t{0}); if (!blocks_eq(hit, dpf::pprf_eval(master, receiver[0])) || !in_image(hit, image) || in_image(dpf::pprf_eval(master, receiver[1]), image) || !blocks_eq(miss_off, master_miss_off)) { std::cerr << "psi\n"; return 1; } { if (int rc = dpf::app::run_measured("psi", dpf::protocol::psi_cuckoo_plan(0, {0, 1, 0}), 9)) return rc; } std::cout << "1\n"; return 0; }