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>
107 lines
4 KiB
C++
107 lines
4 KiB
C++
/// @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
|