libdpf/include/dpf/factory_tapes.hpp
Ryan Henry 0d22946a0e 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>
2026-09-28 05:59:19 -06:00

107 lines
4 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/// @file dpf/factory_tapes.hpp
/// @brief Dealer stream layouts for `factory_gadgets` online tapes (A2B, trunc, GT).
#ifndef LIBDPF_INCLUDE_DPF_FACTORY_TAPES_HPP__
#define LIBDPF_INCLUDE_DPF_FACTORY_TAPES_HPP__
#include <cstddef>
#include <cstdint>
#include <stdexcept>
#include <type_traits>
#include <utility>
#include "dpf/protocol_factory.hpp"
namespace dpf
{
namespace factory
{
namespace detail
{
inline std::pair<gmw_and_blind, gmw_and_blind> deal_gmw_and_blind_pair()
{
auto t = deal_bit_triple();
gmw_and_blind v0{t.first.a, t.first.b, t.first.c};
gmw_and_blind v1{t.second.a, t.second.b, t.second.c};
return {v0, v1};
}
template <typename F>
inline void deal_tape_pod(net::stream_array & party0, net::stream_array & party1,
std::size_t stream, std::size_t count, F && f)
{
if (stream >= party0.size() || stream >= party1.size())
throw std::invalid_argument("deal_tape_pod: stream index");
for (std::size_t j = 0; j < count; ++j)
{
auto views = f();
using V0 = std::decay_t<decltype(views.first)>;
using V1 = std::decay_t<decltype(views.second)>;
static_assert(std::is_trivially_copyable_v<V0>
&& std::is_trivially_copyable_v<V1>,
"deal_tape_pod views must be trivially copyable");
if (sizeof(V0) != sizeof(V1))
throw std::logic_error("deal_tape_pod: unequal view sizes");
detail::write_pod(party0, stream, views.first);
detail::write_pod(party1, stream, views.second);
}
party0.flush(stream);
party1.flush(stream);
}
} // namespace detail
/// @brief Sequential dabits then AND blinds for one `a2b_online` pass.
inline void deal_a2b_tape(unsigned width, std::uint16_t limb,
net::stream_array & party0, net::stream_array & party1,
std::size_t dabit_stream = 0, std::size_t and_blind_stream = 1)
{
if (width == 0 || width > 64)
throw std::invalid_argument("deal_a2b_tape width");
const std::size_t need =
1 + (dabit_stream > and_blind_stream ? dabit_stream : and_blind_stream);
if (party0.size() < need || party1.size() < need)
throw std::invalid_argument("deal_a2b_tape: not enough streams");
detail::deal_tape_pod(party0, party1, dabit_stream, width,
[limb] { return deal_dabit(limb); });
detail::deal_tape_pod(party0, party1, and_blind_stream, width,
[] { return detail::deal_gmw_and_blind_pair(); });
}
/// @brief `s + 1` dabits (low mask + B2A wrap) and `s` AND blinds for trunc.
inline void deal_trunc_tape(unsigned n, unsigned s, std::uint16_t limb,
net::stream_array & party0, net::stream_array & party1,
std::size_t dabit_stream = 0, std::size_t and_blind_stream = 1)
{
if (s >= n || n > 64)
throw std::invalid_argument("deal_trunc_tape");
const std::size_t need =
1 + (dabit_stream > and_blind_stream ? dabit_stream : and_blind_stream);
if (party0.size() < need || party1.size() < need)
throw std::invalid_argument("deal_trunc_tape: not enough streams");
detail::deal_tape_pod(party0, party1, dabit_stream, s + 1u,
[limb] { return deal_dabit(limb); });
detail::deal_tape_pod(party0, party1, and_blind_stream, s,
[] { return detail::deal_gmw_and_blind_pair(); });
}
/// @brief Dealer layout for `gt_online`: streams 0–1 (x A2B), 2–3 (y), 4 compare.
inline void deal_gt_tape(unsigned width, std::uint16_t limb,
net::stream_array & party0, net::stream_array & party1)
{
if (width == 0 || width > 64)
throw std::invalid_argument("deal_gt_tape width");
constexpr std::size_t k_gt_streams = 5;
if (party0.size() < k_gt_streams || party1.size() < k_gt_streams)
throw std::invalid_argument("deal_gt_tape: need 5 dealer streams");
deal_a2b_tape(width, limb, party0, party1, 0, 1);
deal_a2b_tape(width, limb, party0, party1, 2, 3);
detail::deal_tape_pod(party0, party1, 4, 3u * width,
[] { return detail::deal_gmw_and_blind_pair(); });
}
} // namespace factory
} // namespace dpf
#endif