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
149
include/dpf/net/round_lane.hpp
Normal file
149
include/dpf/net/round_lane.hpp
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/// @file dpf/net/round_lane.hpp
|
||||
/// @brief Round→lane mapping and wire framing when rounds share lanes.
|
||||
/// @details A fixed pool of duplex streams can carry any number of exchange
|
||||
/// rounds: lane = `round % n_lanes`. A framed lane prefixes each write
|
||||
/// with a little-endian `{u16 round, u32 nbytes}` header, and the
|
||||
/// receiver appends those bytes to that round's inbox. Unframed lanes
|
||||
/// carry one round each (round == lane) with no header.
|
||||
#ifndef LIBDPF_INCLUDE_DPF_NET_ROUND_LANE_HPP__
|
||||
#define LIBDPF_INCLUDE_DPF_NET_ROUND_LANE_HPP__
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "dpf/net/policy.hpp"
|
||||
|
||||
namespace dpf
|
||||
{
|
||||
namespace net
|
||||
{
|
||||
|
||||
/// @brief On-wire header for a framed round payload on a shared lane.
|
||||
struct round_lane_hdr
|
||||
{
|
||||
static constexpr std::size_t size = 6;
|
||||
|
||||
std::uint16_t round = 0;
|
||||
std::uint32_t nbytes = 0;
|
||||
|
||||
void pack(std::uint8_t * dst) const noexcept
|
||||
{
|
||||
dst[0] = static_cast<std::uint8_t>(round & 0xffu);
|
||||
dst[1] = static_cast<std::uint8_t>((round >> 8) & 0xffu);
|
||||
dst[2] = static_cast<std::uint8_t>(nbytes & 0xffu);
|
||||
dst[3] = static_cast<std::uint8_t>((nbytes >> 8) & 0xffu);
|
||||
dst[4] = static_cast<std::uint8_t>((nbytes >> 16) & 0xffu);
|
||||
dst[5] = static_cast<std::uint8_t>((nbytes >> 24) & 0xffu);
|
||||
}
|
||||
|
||||
static round_lane_hdr unpack(const std::uint8_t * src) noexcept
|
||||
{
|
||||
round_lane_hdr h;
|
||||
h.round = static_cast<std::uint16_t>(src[0] | (src[1] << 8));
|
||||
h.nbytes = static_cast<std::uint32_t>(src[2] | (src[3] << 8) |
|
||||
(src[4] << 16) | (src[5] << 24));
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
||||
/// @brief Lane count used when a caller passes `0`.
|
||||
inline constexpr std::size_t default_lanes = 8;
|
||||
/// @brief Request one stream per round.
|
||||
inline constexpr std::size_t lanes_one_per_round = static_cast<std::size_t>(-1);
|
||||
/// @brief Round ids travel as `u16`.
|
||||
inline constexpr std::size_t max_rounds = 0xffffu;
|
||||
|
||||
/// @brief Streams to open for `n_rounds`. `requested` 0 → `default_lanes`.
|
||||
inline std::size_t lane_count_for_rounds(std::size_t n_rounds,
|
||||
std::size_t requested = 0)
|
||||
{
|
||||
if (n_rounds == 0)
|
||||
return 1;
|
||||
if (requested == lanes_one_per_round)
|
||||
return n_rounds;
|
||||
std::size_t want = requested == 0 ? default_lanes : requested;
|
||||
if (want > n_rounds)
|
||||
want = n_rounds;
|
||||
return want == 0 ? 1 : want;
|
||||
}
|
||||
|
||||
/// @brief Lane index and whether the wire uses round headers.
|
||||
struct round_lane_map
|
||||
{
|
||||
std::size_t n_lanes = 1;
|
||||
std::size_t n_rounds = 0;
|
||||
bool framed = false;
|
||||
|
||||
round_lane_map() = default;
|
||||
|
||||
round_lane_map(std::size_t streams, std::size_t rounds,
|
||||
framing_mode mode = framing_mode::automatic)
|
||||
: n_lanes(streams == 0 ? 1 : streams),
|
||||
n_rounds(rounds)
|
||||
{
|
||||
if (rounds > max_rounds)
|
||||
throw std::invalid_argument("round_lane_map: "
|
||||
+ std::to_string(rounds) + " rounds exceed the u16 round id");
|
||||
switch (mode)
|
||||
{
|
||||
case framing_mode::automatic:
|
||||
framed = rounds > n_lanes;
|
||||
break;
|
||||
case framing_mode::always:
|
||||
framed = true;
|
||||
break;
|
||||
case framing_mode::never:
|
||||
if (rounds > n_lanes)
|
||||
throw std::invalid_argument("round_lane_map: framing never needs "
|
||||
"one lane per round (" + std::to_string(rounds)
|
||||
+ " rounds, " + std::to_string(n_lanes) + " lanes)");
|
||||
framed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t lane(std::uint16_t round) const
|
||||
{
|
||||
if (static_cast<std::size_t>(round) >= n_rounds && n_rounds != 0)
|
||||
throw std::out_of_range("round_lane_map round");
|
||||
if (!framed)
|
||||
return static_cast<std::size_t>(round);
|
||||
return static_cast<std::size_t>(round) % n_lanes;
|
||||
}
|
||||
};
|
||||
|
||||
/// @brief Build `hdr || payload` for a framed write.
|
||||
inline std::vector<std::uint8_t> pack_round_frame(std::uint16_t round,
|
||||
const std::uint8_t * payload, std::size_t n)
|
||||
{
|
||||
std::vector<std::uint8_t> out(round_lane_hdr::size + n);
|
||||
round_lane_hdr{round, static_cast<std::uint32_t>(n)}.pack(out.data());
|
||||
if (n != 0)
|
||||
std::memcpy(out.data() + round_lane_hdr::size, payload, n);
|
||||
return out;
|
||||
}
|
||||
|
||||
/// @brief FNV-1a over a slot-width vector (plan shape fingerprint).
|
||||
inline std::uint64_t slots_fingerprint(const std::vector<std::size_t> & slots)
|
||||
{
|
||||
std::uint64_t h = 14695981039346656037ull;
|
||||
for (auto s : slots)
|
||||
{
|
||||
std::uint64_t v = static_cast<std::uint64_t>(s);
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
h ^= (v >> (8 * i)) & 0xffu;
|
||||
h *= 1099511628211ull;
|
||||
}
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace dpf
|
||||
|
||||
#endif // LIBDPF_INCLUDE_DPF_NET_ROUND_LANE_HPP__
|
||||
Loading…
Add table
Add a link
Reference in a new issue