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:
Ryan Henry 2026-09-28 05:59:19 -06:00
parent 695f8e84f7
commit 0d22946a0e
1835 changed files with 170291 additions and 2849 deletions

View file

@ -8,13 +8,20 @@
#ifndef LIBDPF_INCLUDE_DPF_LEAF_WRAPPER_HPP__
#define LIBDPF_INCLUDE_DPF_LEAF_WRAPPER_HPP__
#include <stdexcept>
#include "hedley/hedley.h"
#include "dpf/leaf_arithmetic.hpp"
#include "dpf/secret_share.hpp"
namespace dpf
{
/// @brief Concrete leaf. `get()` is ready immediately.
/// @tparam OutputT output type
/// @tparam NodeT exterior node type
/// @see dpf::wildcard_value
template <typename OutputT,
typename NodeT>
struct leaf_wrapper
@ -31,10 +38,18 @@ struct leaf_wrapper
HEDLEY_NO_THROW
constexpr const leaf_type & get() const noexcept { return leaf_; }
HEDLEY_ALWAYS_INLINE
HEDLEY_NO_THROW
constexpr leaf_type & get() noexcept { return leaf_; }
HEDLEY_ALWAYS_INLINE
HEDLEY_NO_THROW
constexpr const leaf_type & raw_leaf() const noexcept { return leaf_; }
HEDLEY_ALWAYS_INLINE
HEDLEY_NO_THROW
constexpr leaf_type & raw_leaf() noexcept { return leaf_; }
HEDLEY_ALWAYS_INLINE
HEDLEY_NO_THROW
const dpf::beaver<false, NodeT, OutputT> & beaver() const noexcept
@ -141,10 +156,11 @@ struct leaf_wrapper<wildcard_value<ConcreteOutputT>, NodeT>
leaf_wrapper() = delete;
leaf_wrapper(leaf_type leaf_share, beaver_type beaver)
: leaf_{std::forward<leaf_type>(leaf_share)},
: leaf_{leaf_share},
beaver_{beaver},
output_share_{},
leaf_state_{leaf_status::notset}
leaf_state_{leaf_status::notset},
updating_{false}
{ }
HEDLEY_ALWAYS_INLINE
@ -157,11 +173,12 @@ struct leaf_wrapper<wildcard_value<ConcreteOutputT>, NodeT>
return leaf_;
}
const output_type compute_and_get_blinded_output_share(output_type output_share)
output_type compute_and_get_blinded_output_share(output_type output_share)
{
begin_transition(leaf_status::notset);
output_share_ = output_share;
auto blinded_output_share = output_share_ + beaver_.output_blind;
// Use the leaf group (XOR of IEEE bits for float/double), not `operator+`.
auto blinded_output_share = leaf_group_add(output_share_, beaver_.output_blind);
leaf_state_ = leaf_status::blinded;
return blinded_output_share;
}
@ -170,16 +187,28 @@ struct leaf_wrapper<wildcard_value<ConcreteOutputT>, NodeT>
/// @tparam Party party index, `0` or `1`
/// @tparam Scheme scheme
/// @param output_share the `output_share`
/// @return the returned `const output_type`
/// @return the blinded output share
template <std::size_t Party, sharing Scheme>
const output_type compute_and_get_blinded_output_share(
output_type compute_and_get_blinded_output_share(
const secret_share<output_type, Party, Scheme> & output_share)
{
return compute_and_get_blinded_output_share(
output_share.as_additive().raw());
// Beaver leaf math is a (2,2) additive absorb. (3,3) and replicated
// shares are a different party count; fold them with `add_replicated`.
if constexpr (is_two_party_sharing_v<Scheme>)
{
return compute_and_get_blinded_output_share(
output_share.as_additive().raw());
}
else
{
static_assert(is_two_party_sharing_v<Scheme>,
"wildcard Beaver absorb expects a (2,2) additive or "
"subtractive share");
return output_type{};
}
}
const leaf_type compute_and_get_leaf_share(output_type other_output_share)
leaf_type compute_and_get_leaf_share(output_type other_output_share)
{
begin_transition(leaf_status::blinded);
leaf_ = add_leaf<output_type>(leaf_, subtract_leaf<output_type>(
@ -189,10 +218,16 @@ struct leaf_wrapper<wildcard_value<ConcreteOutputT>, NodeT>
return leaf_;
}
const leaf_type reconstruct_correction_word(leaf_type other_share)
leaf_type reconstruct_correction_word(leaf_type other_share)
{
begin_transition(leaf_status::waiting);
leaf_ = add_leaf<output_type>(leaf_, other_share);
if (updating_)
{
// Opened naked delta; add it onto the previously committed payload.
leaf_ = add_leaf<output_type>(committed_, leaf_);
updating_ = false;
}
leaf_state_ = leaf_status::ready;
return leaf_;
}
@ -211,6 +246,10 @@ struct leaf_wrapper<wildcard_value<ConcreteOutputT>, NodeT>
HEDLEY_NO_THROW
const leaf_type & raw_leaf() const noexcept { return leaf_; }
HEDLEY_ALWAYS_INLINE
HEDLEY_NO_THROW
leaf_type & raw_leaf() noexcept { return leaf_; }
HEDLEY_ALWAYS_INLINE
HEDLEY_NO_THROW
const beaver_type & beaver() const noexcept { return beaver_; }
@ -241,6 +280,23 @@ struct leaf_wrapper<wildcard_value<ConcreteOutputT>, NodeT>
leaf_state_ = static_cast<leaf_status>(state);
}
/// @brief Re-open a ready leaf so a later assign installs `β' − β`.
/// @details Saves the committed correction word and restores the keygen
/// Beaver pad (not the zero-payload CW) so the next opening adds
/// only a naked delta. Reusing one scale Beaver for two openings
/// is not maliciously secure; honest parties that install `β'−β`
/// still get a correct leaf.
HEDLEY_ALWAYS_INLINE
void begin_update()
{
if (leaf_state_ != leaf_status::ready)
throw std::runtime_error("begin_update: leaf is not ready");
committed_ = leaf_;
leaf_ = beaver_.assign_pad;
updating_ = true;
leaf_state_ = leaf_status::notset;
}
private:
enum class leaf_status : psnip_uint8_t { ready = 0, waiting = 1, computing = 2, blinded = 3, notset = 4 };
@ -254,9 +310,11 @@ struct leaf_wrapper<wildcard_value<ConcreteOutputT>, NodeT>
}
leaf_type leaf_;
leaf_type committed_{};
beaver_type beaver_;
output_type output_share_;
leaf_status leaf_state_;
bool updating_;
};
} // namespace dpf