#include #include #include #include #include "dpf.hpp" #include "dpf/app_flow.hpp" #include "dpf/app_plans.hpp" // Two-server keyword PIR, the DPF step (Gilboa and Ishai, EUROCRYPT 2014). // `eval_sequence_xor` folds the selected records into one XOR accumulator // without materializing a bit vector. // // c++ -std=c++17 -march=native -pthread -I include -I thirdparty \ // examples/applications/keyword_pir.cpp // DPF_EXPERIMENT_DIR=/tmp/kw ./a.out # optional CSV dump namespace { using keyword = dpf::keyword<3, dpf::alphabets::lowercase_alpha>; } // namespace int main() { const std::vector dict{keyword{"bat"}, keyword{"cat"}, keyword{"dog"}, keyword{"pig"}}; const std::vector records{56, 12, 34, 78}; auto [k0, k1] = dpf::make_dpf(keyword{"bat"}, dpf::bit::one); const int selected = dpf::eval_sequence_xor(k0, dict.begin(), dict.end(), records) ^ dpf::eval_sequence_xor(k1, dict.begin(), dict.end(), records); if (selected != 56) { std::cerr << "keyword hit\n"; return 1; } auto [m0, m1] = dpf::make_dpf(keyword{"rat"}, dpf::bit::one); const int missing = dpf::eval_sequence_xor(m0, dict.begin(), dict.end(), records) ^ dpf::eval_sequence_xor(m1, dict.begin(), dict.end(), records); if (missing != 0) { std::cerr << "keyword miss\n"; return 1; } { constexpr std::size_t depth = dpf::utils::bitlength_of::value; if (int rc = dpf::app::run_measured("keyword_pir", dpf::protocol::keyword_pir_compose_plan(0, depth), 2)) return rc; } std::cout << selected << "\n"; return 0; }