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
|
|
@ -77,6 +77,27 @@ template <typename OutputT,
|
|||
static constexpr std::size_t block_length_of_leaf_v
|
||||
= block_length_of_leaf<OutputT, NodeT>::value;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// dpf::blob<N> stretched byte leaves.
|
||||
// A `dpf::blob<N>` is an XOR share of `N` bytes and is *never* packed several
|
||||
// per node: Boyle packing keeps `lg(outputs_per_leaf) = 0` so the tree depth
|
||||
// follows the input bitlength (Express `genDPF`). Instead it stretches the
|
||||
// final seed over `ceil(8N / lambda)` exterior blocks in counter mode. These
|
||||
// specializations override the generic `is_packable` heuristic, which would
|
||||
// otherwise pack small blobs (e.g. `blob<1>`, whose 8 bits divide `lambda`).
|
||||
// See dpf/blob.hpp.
|
||||
template <std::size_t N,
|
||||
typename NodeT>
|
||||
struct outputs_per_leaf<dpf::blob<N>, NodeT>
|
||||
: public std::integral_constant<std::size_t, 1> { };
|
||||
|
||||
template <std::size_t N,
|
||||
typename NodeT>
|
||||
struct block_length_of_leaf<dpf::blob<N>, NodeT>
|
||||
: public std::integral_constant<std::size_t,
|
||||
utils::quotient_ceiling(N * 8,
|
||||
utils::bitlength_of_output_v<NodeT, NodeT>)> { };
|
||||
|
||||
template <typename OutputT,
|
||||
typename NodeT,
|
||||
typename InputT>
|
||||
|
|
@ -205,6 +226,10 @@ struct beaver<true, NodeT, OutputT> final
|
|||
OutputT output_blind;
|
||||
LeafT vector_blind;
|
||||
LeafT blinded_vector;
|
||||
/// @brief Keygen pad `vector_blind_i · output_blind_{1-i}` so a later
|
||||
/// `begin_update` can open a fresh naked delta without replaying
|
||||
/// the zero-payload correction word.
|
||||
LeafT assign_pad{};
|
||||
};
|
||||
|
||||
template <typename NodeT,
|
||||
|
|
@ -287,6 +312,33 @@ constexpr auto * leaf_blocks(LeafT & leaf) noexcept
|
|||
return leaf.data();
|
||||
}
|
||||
|
||||
/// @brief After a PRG fills `leaf`, map curve-point types through `from_seed`.
|
||||
template <typename Concrete, typename = void>
|
||||
struct is_curve_leaf_encode : std::false_type {};
|
||||
|
||||
template <typename Concrete>
|
||||
struct is_curve_leaf_encode<Concrete, std::void_t<
|
||||
std::bool_constant<Concrete::dpf_curve_point>,
|
||||
decltype(Concrete::from_seed(static_cast<const void *>(nullptr),
|
||||
std::size_t{0})),
|
||||
std::integral_constant<std::size_t, Concrete::encoded_size>,
|
||||
decltype(std::declval<const Concrete &>().bytes())>>
|
||||
: std::bool_constant<Concrete::dpf_curve_point> {};
|
||||
|
||||
template <typename Concrete, typename Leaf>
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
void encode_curve_leaf_mask(Leaf & leaf) noexcept
|
||||
{
|
||||
if constexpr (is_curve_leaf_encode<Concrete>::value)
|
||||
{
|
||||
const Concrete pt = Concrete::from_seed(
|
||||
std::addressof(leaf), sizeof(leaf));
|
||||
leaf = Leaf{};
|
||||
std::memcpy(std::addressof(leaf), pt.bytes(),
|
||||
Concrete::encoded_size);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ExteriorPRG,
|
||||
std::size_t I,
|
||||
typename OutputsTuple,
|
||||
|
|
@ -295,6 +347,7 @@ auto make_leaf_mask_inner(const InteriorBlock & seed, std::size_t pos_base = 0)
|
|||
{
|
||||
using node_type = typename ExteriorPRG::block_type;
|
||||
using output_type = std::tuple_element_t<I, OutputsTuple>;
|
||||
using concrete = concrete_type_t<output_type>;
|
||||
HEDLEY_PRAGMA(GCC diagnostic push)
|
||||
HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
|
||||
using leaf_type = dpf::leaf_node_t<node_type, output_type>;
|
||||
|
|
@ -305,6 +358,7 @@ HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
|
|||
auto seed_ = utils::to_exterior_node<node_type>(seed);
|
||||
ExteriorPRG::eval(seed_, leaf_blocks<node_type>(output), count,
|
||||
static_cast<psnip_uint32_t>(pos));
|
||||
encode_curve_leaf_mask<concrete>(output);
|
||||
|
||||
return output;
|
||||
HEDLEY_PRAGMA(GCC diagnostic pop)
|
||||
|
|
@ -370,6 +424,23 @@ auto make_leaves_impl(InputT x, const ExteriorBlock & seed0, const ExteriorBlock
|
|||
make_leaf<ExteriorPRG, Is>(x, seed0, seed1, sign, pos_base, ys...)...);
|
||||
}
|
||||
|
||||
namespace beavers
|
||||
{
|
||||
|
||||
/// @brief Fill wildcard leaf scale blinds from `sample_scale`.
|
||||
/// @tparam Concrete lane type
|
||||
/// @tparam LeafT packed leaf type
|
||||
/// @tparam Sample ring sampler
|
||||
template <typename Concrete, typename LeafT, typename Sample>
|
||||
void fill_wildcard_scale_blinds(Concrete & out0, Concrete & out1, LeafT & vec0,
|
||||
LeafT & vec1, std::size_t nlanes, Sample && rng);
|
||||
|
||||
template <typename Concrete, typename LeafT>
|
||||
void fill_wildcard_scale_blinds(Concrete & out0, Concrete & out1, LeafT & vec0,
|
||||
LeafT & vec1, std::size_t nlanes);
|
||||
|
||||
} // namespace beavers
|
||||
|
||||
template <typename ExteriorPRG,
|
||||
typename InputT,
|
||||
typename ExteriorBlock,
|
||||
|
|
@ -435,38 +506,43 @@ HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
|
|||
// secret share the value
|
||||
dpf::uniform_fill(leaf0);
|
||||
leaf1 = dpf::subtract_leaf<concrete_type>(leaf, leaf0);
|
||||
// also initialize the beavers
|
||||
if constexpr(!dpf::utils::has_characteristic_two_v<concrete_type>
|
||||
|| dpf::outputs_per_leaf_v<concrete_type, node_type> > 1)
|
||||
// Always plant a scale Beaver, including full-width XOR
|
||||
// (char-2, one lane). Skipping it left blinds at zero so
|
||||
// online assign exchanged beta in the clear.
|
||||
dpf::leaf_node_t<node_type, concrete_type> vector;
|
||||
// XOR/AND leaf groups use the all-ones word as unit, not ±1.
|
||||
// Check the OUTPUT type: input may be modint while the
|
||||
// leaf is xor_wrapper (wildcard XOR payload). IEEE
|
||||
// float/double leaves are the same bitwise group.
|
||||
if constexpr(utils::is_xor_wrapper_v<std::decay_t<decltype(x)>> == true
|
||||
|| utils::is_xor_wrapper_v<concrete_type> == true
|
||||
|| std::is_same_v<concrete_type, float>
|
||||
|| std::is_same_v<concrete_type, double>)
|
||||
{
|
||||
dpf::leaf_node_t<node_type, concrete_type> vector;
|
||||
// XOR-group multiply is AND, whose unit is ~0, not ±1.
|
||||
// Check the OUTPUT type: input may be modint while the
|
||||
// leaf is xor_wrapper (wildcard XOR payload).
|
||||
if constexpr(utils::is_xor_wrapper_v<std::decay_t<decltype(x)>> == true
|
||||
|| utils::is_xor_wrapper_v<concrete_type> == true)
|
||||
{
|
||||
vector = make_naked_leaf<node_type>(x, concrete_type(~0));
|
||||
}
|
||||
else
|
||||
{
|
||||
vector = make_naked_leaf<node_type>(x, concrete_type(2*sign-1));
|
||||
}
|
||||
|
||||
uniform_fill(beaver0.output_blind);
|
||||
uniform_fill(beaver0.vector_blind);
|
||||
|
||||
uniform_fill(beaver1.output_blind);
|
||||
uniform_fill(beaver1.vector_blind);
|
||||
|
||||
beaver0.blinded_vector = dpf::add_leaf<concrete_type>(vector, beaver1.vector_blind);
|
||||
beaver1.blinded_vector = dpf::add_leaf<concrete_type>(vector, beaver0.vector_blind);
|
||||
|
||||
leaf0 = dpf::add_leaf<concrete_type>(leaf0,
|
||||
dpf::multiply_leaf(beaver0.vector_blind, beaver1.output_blind));
|
||||
leaf1 = dpf::add_leaf<concrete_type>(leaf1,
|
||||
dpf::multiply_leaf(beaver1.vector_blind, beaver0.output_blind));
|
||||
vector = make_naked_leaf<node_type>(x,
|
||||
dpf::leaf_group_one<concrete_type>());
|
||||
}
|
||||
else
|
||||
{
|
||||
vector = make_naked_leaf<node_type>(x, concrete_type(2*sign-1));
|
||||
}
|
||||
|
||||
constexpr std::size_t nlanes =
|
||||
dpf::outputs_per_leaf_v<concrete_type, node_type>;
|
||||
dpf::beavers::fill_wildcard_scale_blinds(
|
||||
beaver0.output_blind, beaver1.output_blind,
|
||||
beaver0.vector_blind, beaver1.vector_blind,
|
||||
nlanes > 0 ? nlanes : std::size_t{1});
|
||||
|
||||
beaver0.blinded_vector = dpf::add_leaf<concrete_type>(vector, beaver1.vector_blind);
|
||||
beaver1.blinded_vector = dpf::add_leaf<concrete_type>(vector, beaver0.vector_blind);
|
||||
|
||||
beaver0.assign_pad = dpf::multiply_leaf(
|
||||
beaver0.vector_blind, beaver1.output_blind);
|
||||
beaver1.assign_pad = dpf::multiply_leaf(
|
||||
beaver1.vector_blind, beaver0.output_blind);
|
||||
leaf0 = dpf::add_leaf<concrete_type>(leaf0, beaver0.assign_pad);
|
||||
leaf1 = dpf::add_leaf<concrete_type>(leaf1, beaver1.assign_pad);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue