#include #include #include #include #include "dpf.hpp" #include "dpf/app_flow.hpp" #include "dpf/app_plans.hpp" // Waldo, the FSS steps (Dauterman, Fang, Crooks, and Popa, S&P 2022). A // private time-series database. The store is append-only: a new event writes // a fresh point and never updates an old one. A range/threshold aggregate // uses the comparison (DCF) channel: the parties dot the per-timestamp // comparison shares with a public value column, so a SUM over the timestamps // past a *secret* threshold reveals neither the threshold nor the matches. // // c++ -std=c++17 -march=native -I include -I thirdparty \ // examples/applications/waldo.cpp int main() { constexpr std::size_t horizon = 256; // timestamp domain // Append-only writes. Each event is a unit DPF at its timestamp; the // servers fold it into their subtractive value shares. Never an update. std::vector col0(horizon, 0), col1(horizon, 0); const std::pair events[] = { {30, 5}, {90, 8}, {200, 3}}; for (auto [ts, val] : events) { auto [k0, k1] = dpf::make_dpf(ts, val); dpf::eval_full_add_into(col0, k0); dpf::eval_full_add_into(col1, k1); } if (col0[90] - col1[90] != 8 || col0[30] - col1[30] != 5) { std::cerr << "waldo append\n"; return 1; } // Public per-timestamp magnitudes (metadata the response consumes). std::vector magnitude(horizon, 0); for (auto [ts, val] : events) magnitude[ts] = val; // Private-threshold aggregate: SUM of magnitudes at timestamps > T, with // T secret. Key a gt comparison at T and dot its per-timestamp shares // with the public magnitude column in one comparison walk. constexpr std::uint8_t secret_T = 50; auto [c0, c1] = dpf::make_dpf(secret_T, dpf::gt(std::uint64_t{1})); const auto h0 = dpf::eval_full_inner_product(dpf::cmp, c0, magnitude); const auto h1 = dpf::eval_full_inner_product(dpf::cmp, c1, magnitude); const auto after = dpf::reconstruct_cmp_halves(h0, h1).raw(); // Timestamps 90 and 200 are past T=50: 8 + 3 = 11. if (after != 11) { std::cerr << "waldo threshold aggregate " << after << "\n"; return 1; } { if (int rc = dpf::app::run_measured("waldo", dpf::protocol::fss_cmp_plan(0), 8)) return rc; } std::cout << after << "\n"; return 0; }