108 lines
4 KiB
C++
108 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
|