#include #include #include #include "dpf.hpp" #include "dpf/app_flow.hpp" #include "dpf/app_plans.hpp" // Pika, the lookup (Wagh, PoPETs 2022, Fig. 1). Party P2 is the dealer. // P2 keys a unit DPF at a fresh index r and shares r. P0 and P1 open // x = r - a, and take the inner product of the DPF with the table rotated // by x. A word payload of 1 reconstructs to +1. A 1-bit payload lifts to // +1 or -1; the dealer reads that sign off Gen's final control bit. // // The rotation is folded into the walk with `dpf::rotate{s}` (no rotated // copy of the table), and the sign is recorded at keygen with // `dpf::unit_sign` (no evaluator-side eval_point). // // c++ -std=c++17 -march=native -I include -I thirdparty \ // examples/applications/pika.cpp int main() { constexpr std::size_t n = 256; constexpr std::uint8_t r = 50; constexpr std::uint8_t a0 = 10; constexpr std::uint8_t a1 = 7; constexpr std::uint8_t a = static_cast(a0 + a1); constexpr std::uint8_t x = static_cast(r - a); std::vector table(n); for (std::size_t i = 0; i < n; ++i) table[i] = static_cast(i) * i; // Lookup: DPF at r dotted with the table read at (i - x) mod n, i.e. // rotated by s = (n - x) mod n. The walk applies the offset; no copy. auto [k0, k1] = dpf::make_dpf(r, std::uint64_t{1}); const std::size_t s = (n - static_cast(x)) % n; const auto value = dpf::reconstruct( dpf::eval_full_inner_product(dpf::paired, k0, table, dpf::rotate{s}), dpf::eval_full_inner_product(dpf::paired, k1, table, dpf::rotate{s})); if (value != table[a]) { std::cerr << "pika lookup\n"; return 1; } // The early-stop bit leaf. The dealer, who sees both keys, records a // sign of +1 or -1 at r via `unit_sign`; the evaluators never open r. int w0 = 0, w1 = 0; auto [b0, b1] = dpf::make_dpf(r, dpf::bit::one, dpf::unit_sign{w0, w1}); const int sign = w0 - w1; if (sign != 1 && sign != -1) { std::cerr << "pika sign\n"; return 1; } if (dpf::reconstruct(*dpf::eval_point(k0, r), *dpf::eval_point(k1, r)) != 1) { std::cerr << "pika unit\n"; return 1; } { if (int rc = dpf::app::run_measured("pika", dpf::protocol::pika_lookup_plan(0, 8, 3), 5)) return rc; } std::cout << value << "\n"; return 0; }