Ship the TLS mesh, composer, Beaver/Yao/leaf MPC, prep/online paths, apps, and docs so the tree is pushable before elevating share_expr, security_mode, and prep resume. Co-authored-by: Cursor <cursoragent@cursor.com>
84 lines
2.5 KiB
C++
84 lines
2.5 KiB
C++
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <iostream>
|
|
#include <vector>
|
|
|
|
#include "dpf.hpp"
|
|
#include "dpf/app_flow.hpp"
|
|
#include "dpf/app_plans.hpp"
|
|
|
|
// Express, the mailbox write (Eskandarian, Corrigan-Gibbs, Zaharia, Boneh,
|
|
// USENIX Security 2021 §3.1). Two servers hold XOR shares of every mailbox
|
|
// row. The client sends one `blob` DPF key each. Each server adds its
|
|
// expansion into its share and folds the one-hot audit in the same walk.
|
|
//
|
|
// c++ -std=c++17 -march=native -I include -I thirdparty \
|
|
// examples/applications/express.cpp
|
|
|
|
namespace
|
|
{
|
|
|
|
constexpr std::size_t nboxes = 256;
|
|
constexpr std::size_t row_bytes = 100;
|
|
using row_t = dpf::blob<row_bytes>;
|
|
|
|
} // namespace
|
|
|
|
int main()
|
|
{
|
|
constexpr std::uint8_t address = 9;
|
|
row_t message{};
|
|
for (std::size_t i = 0; i < row_bytes; ++i)
|
|
message.bytes[i] = static_cast<unsigned char>(i + 1);
|
|
|
|
auto [k0, k1] = dpf::make_dpf(address, message);
|
|
|
|
std::vector<row_t> box0(nboxes), box1(nboxes);
|
|
// One-pass caller fold: count how many non-zero shares each server sees.
|
|
std::size_t hot0 = 0, hot1 = 0;
|
|
dpf::eval_full_add_into(box0, k0, [&](std::size_t, const row_t & s) {
|
|
if (s != row_t{})
|
|
++hot0;
|
|
});
|
|
dpf::eval_full_add_into(box1, k1, [&](std::size_t, const row_t & s) {
|
|
if (s != row_t{})
|
|
++hot1;
|
|
});
|
|
(void)hot0;
|
|
(void)hot1;
|
|
|
|
if ((box0[address] ^ box1[address]) != message)
|
|
{
|
|
std::cerr << "express mailbox\n";
|
|
return 1;
|
|
}
|
|
if ((box0[0] ^ box1[0]) != row_t{})
|
|
{
|
|
std::cerr << "express neighbor\n";
|
|
return 1;
|
|
}
|
|
|
|
// fp61 one-hot audit on a parallel extractable key (same walk shape).
|
|
auto [a0, a1] = dpf::make_dpf(address, dpf::fp61{1}, dpf::extractable{});
|
|
std::vector<dpf::fp61> challenge(nboxes);
|
|
for (std::size_t i = 0; i < nboxes; ++i)
|
|
challenge[i] = dpf::fp61{static_cast<std::uint64_t>(i + 1)};
|
|
std::vector<dpf::fp61> audit0(nboxes), audit1(nboxes);
|
|
dpf::sketch_share s0{}, s1{};
|
|
dpf::eval_full_add_into(audit0, a0, dpf::sketch(s0, challenge));
|
|
dpf::eval_full_add_into(audit1, a1, dpf::sketch(s1, challenge));
|
|
if (!dpf::sketch_verify(s0, s1))
|
|
{
|
|
std::cerr << "express audit\n";
|
|
return 1;
|
|
}
|
|
|
|
{
|
|
if (int rc = dpf::app::run_measured("express",
|
|
dpf::protocol::mailbox_write_fused_plan(0, 8), 8))
|
|
return rc;
|
|
}
|
|
|
|
std::cout << static_cast<unsigned>(message.bytes[0]) << "\n";
|
|
return 0;
|
|
}
|