#include #include #include #include "dpf.hpp" #include "dpf/app_flow.hpp" #include "dpf/app_plans.hpp" // Three-server index PIR. The database is public and replicated. The // secret index is one (2,3) point key: each server holds one share and // dots it with the database. Any two of those dots reconstruct the // record. This is the library's three-evaluator key (ePrint 2024/1658), // the same sharing the ledger appends with. // // c++ -std=c++17 -march=native -I include -I thirdparty \ // examples/applications/pir3.cpp int main() { constexpr std::size_t n = 256; constexpr std::uint8_t index = 42; std::vector database(n); for (std::size_t i = 0; i < n; ++i) database[i] = dpf::fp61{static_cast(i * i + 1)}; auto [k1, k2, k3] = dpf::make_dpf3(index, dpf::fp61{1}); const auto s1 = dpf::eval_full_inner_product(k1, database); const auto s2 = dpf::eval_full_inner_product(k2, database); const auto s3 = dpf::eval_full_inner_product(k3, database); const auto opened = dpf::shamir3::reconstruct( dpf::as_share(k1, s1), dpf::as_share(k2, s2)); const auto opened_13 = dpf::shamir3::reconstruct( dpf::as_share(k1, s1), dpf::as_share(k3, s3)); if (opened != database[index] || opened_13 != database[index]) { std::cerr << "pir3\n"; return 1; } { // Client uploads one (2,3) key (two point-key spines) to each server. constexpr std::size_t depth = 8; constexpr std::size_t query_bytes = 2 * (16 + depth * 16); if (int rc = dpf::app::run_measured("pir3", dpf::protocol::n_server_pir_plan(0, 3, query_bytes, sizeof(dpf::fp61)), 2)) return rc; } std::cout << opened.raw() << "\n"; return 0; }