libdpf/examples/applications/sabre.cpp

80 lines
2.4 KiB
C++
Raw Permalink Normal View History

#include <cstddef>
#include <cstdint>
#include <iostream>
#include <vector>
#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<std::uint64_t> 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;
}