Checkpoint the party/runtime stack before share-program and malicious-mode work.
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>
This commit is contained in:
parent
695f8e84f7
commit
0d22946a0e
1835 changed files with 170291 additions and 2849 deletions
88
examples/applications/prio.cpp
Normal file
88
examples/applications/prio.cpp
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "dpf.hpp"
|
||||
#include "dpf/app_flow.hpp"
|
||||
#include "dpf/app_plans.hpp"
|
||||
|
||||
// Prio's frequency count, with the one-hot vector replaced by a DPF, and
|
||||
// the prefix walk Poplar uses for heavy hitters (Boneh, Boyle,
|
||||
// Corrigan-Gibbs, Gilboa, Ishai). Classic Prio proves an encoding with a
|
||||
// SNIP; this file is only the DPF-shaped encoding.
|
||||
// field64 is libprio's Field64.
|
||||
//
|
||||
// c++ -std=c++17 -march=native -I include -I thirdparty \
|
||||
// examples/applications/prio.cpp
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
constexpr int nbins = 256;
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
// Histogram. Each client sends one unit DPF at a secret bin.
|
||||
// Each server adds the expansion into its running share with
|
||||
// `eval_full_add_into` (no separate expansion buffer). The opened bin
|
||||
// is the count.
|
||||
const std::array<std::uint8_t, 4> bins{3, 3, 7, 3};
|
||||
std::vector<dpf::field64> h0(nbins);
|
||||
std::vector<dpf::field64> h1(nbins);
|
||||
for (std::uint8_t bin : bins)
|
||||
{
|
||||
auto [k0, k1] = dpf::make_dpf(bin, dpf::field64{1});
|
||||
dpf::eval_full_add_into(h0, k0);
|
||||
dpf::eval_full_add_into(h1, k1);
|
||||
}
|
||||
// Leaf shares are subtractive, so the opened bin is share0 - share1.
|
||||
const dpf::field64 c3 = h0[3] - h1[3];
|
||||
const dpf::field64 c7 = h0[7] - h1[7];
|
||||
const dpf::field64 c0 = h0[0] - h1[0];
|
||||
if (c3.raw() != 3 || c7.raw() != 1 || c0.raw() != 0)
|
||||
{
|
||||
std::cerr << "prio histogram\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Heavy-hitter prefixes. idpf plants a 1 on each prefix length.
|
||||
// Length 1 is the high bit. 0xA0 and 0xB0 share 101; they split at bit 4.
|
||||
constexpr std::uint8_t left = 0xA0;
|
||||
constexpr std::uint8_t right = 0xB0;
|
||||
auto [a0, a1] = dpf::make_dpf(left,
|
||||
dpf::idpf(std::uint64_t{1}, std::uint64_t{1}, std::uint64_t{1}));
|
||||
auto [b0, b1] = dpf::make_dpf(right,
|
||||
dpf::idpf(std::uint64_t{1}, std::uint64_t{1}, std::uint64_t{1}));
|
||||
|
||||
auto one = [](auto tag, auto k0, auto k1, std::uint8_t node) {
|
||||
return dpf::reconstruct(*dpf::eval_point(tag, k0, node),
|
||||
*dpf::eval_point(tag, k1, node));
|
||||
};
|
||||
auto count = [&](auto tag, std::uint8_t node) {
|
||||
return one(tag, a0, a1, node) + one(tag, b0, b1, node);
|
||||
};
|
||||
|
||||
// out<0> is prefix length 1, out<1> length 2, out<2> length 3.
|
||||
const auto high = count(dpf::out<0, 1>, std::uint8_t{0x80});
|
||||
const auto low = count(dpf::out<0, 1>, std::uint8_t{0x00});
|
||||
const auto shared = count(dpf::out<2, 3>, std::uint8_t{0xA0});
|
||||
const auto split = count(dpf::out<2, 3>, std::uint8_t{0x80});
|
||||
if (high != 2 || low != 0 || shared != 2 || split != 0)
|
||||
{
|
||||
std::cerr << "prio prefixes " << high << " " << low << " " << shared
|
||||
<< " " << split << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
{
|
||||
if (int rc = dpf::app::run_measured("prio",
|
||||
dpf::protocol::poplar_prefix_plan(0), 8))
|
||||
return rc;
|
||||
}
|
||||
|
||||
std::cout << c3.raw() << "\n";
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue