#include #include #include #include #include "dpf.hpp" #include "dpf/app_flow.hpp" #include "dpf/app_plans.hpp" // Sabre, the mailbox write with a fast audit (Vadapalli, Storrier, and Henry, // S&P 2022). Sender-anonymous messaging: two servers hold subtractive shares // of every mailbox and the client sends one key each. Like Express the write // is a full-domain add; unlike Express the audit is a *verifiable* DPF proof // (Boyle et al. once-per-node fold), a constant-size token per party that // opens to accept iff the key is a single honest point. // // c++ -std=c++17 -march=native -I include -I thirdparty \ // examples/applications/sabre.cpp namespace { constexpr std::size_t nboxes = 256; } // namespace int main() { constexpr std::uint8_t address = 17; constexpr std::uint64_t message = 42; auto [k0, k1] = dpf::make_dpf(address, message, dpf::verifiable{}); // Each server folds the write into its mailbox shares (one full walk). std::vector box0(nboxes, 0), box1(nboxes, 0); dpf::eval_full_add_into(box0, k0); dpf::eval_full_add_into(box1, k1); if (box0[address] - box1[address] != message) { std::cerr << "sabre mailbox\n"; return 1; } if (box0[0] - box1[0] != 0) { std::cerr << "sabre neighbor\n"; return 1; } // Fast audit: a full-domain VDPF proof. Each party folds a constant-size // token; the tokens open to accept an honest single-point write. dpf::proof_token pi0{}, pi1{}; dpf::prove_full(k0, dpf::prove(pi0)); dpf::prove_full(k1, dpf::prove(pi1)); if (!dpf::verify(pi0, pi1)) { std::cerr << "sabre audit\n"; return 1; } // A proof folded over a mismatched pair of points (the shape a malformed, // multi-point write produces) fails the same check. dpf::proof_token bad0{}, bad1{}; dpf::prove_interval(k0, std::uint8_t{0}, std::uint8_t{7}, dpf::prove(bad0)); dpf::prove_interval(k1, std::uint8_t{8}, std::uint8_t{15}, dpf::prove(bad1)); if (dpf::verify(bad0, bad1)) { std::cerr << "sabre audit accepted a mismatch\n"; return 1; } { if (int rc = dpf::app::run_measured("sabre", dpf::protocol::mailbox_write_fused_plan(0, 8), 8)) return rc; } std::cout << (box0[address] - box1[address]) << "\n"; return 0; }