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

@ -3,6 +3,7 @@
/// @details `lt`/`leq`/`gt`/`geq` (+ `_at`) take `(if_true, if_false=0)`.
/// Eval walks the same GGM tree as the DPF (per-level value CWs).
/// `eq` / `eq_at` are synonyms for ordinary point placements.
/// @note Following Boyle, Chandran, Gilboa, Gupta, Ishai, Kumar, and Rathee, EUROCRYPT 2021 (ePrint 2020/1392): a comparison is a DPF spine plus one value-correction word per level. `eq` is a point payload, not that DCF.
/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors)
/// @license Released under a GNU General Public v2.0 (GPLv2) license.
@ -163,7 +164,7 @@ Beta sub_beta(const Beta & a, const Beta & b) noexcept
if constexpr (std::is_same_v<Beta, dpf::bit>)
return dpf::bit{static_cast<bool>(a) ^ static_cast<bool>(b)};
else if constexpr (dpf::utils::is_xor_wrapper_v<Beta>)
return Beta{static_cast<uint64_t>(a) ^ static_cast<uint64_t>(b)};
return a ^ b;
else
return static_cast<Beta>(a - b);
}
@ -504,42 +505,50 @@ struct cmp_at_pack
: if_true{std::move(t)}, if_false{std::move(f)} { }
};
/// \complexity O(1). Builds a spec object. The n-level walk is `make_dpf` or `ds_advance_level`, not this function.
template <typename Beta>
inline auto lt(Beta t, Beta f = detail::dcf_impl::default_false<std::decay_t<Beta>>())
{
return cmp_pack<cmp_kind::lt, std::decay_t<Beta>>(std::move(t), std::move(f));
}
/// \complexity O(1). Builds a spec object. The n-level walk is `make_dpf` or `ds_advance_level`, not this function.
template <typename Beta>
inline auto leq(Beta t, Beta f = detail::dcf_impl::default_false<std::decay_t<Beta>>())
{
return cmp_pack<cmp_kind::leq, std::decay_t<Beta>>(std::move(t), std::move(f));
}
/// \complexity O(1). Builds a spec object. The n-level walk is `make_dpf` or `ds_advance_level`, not this function.
template <typename Beta>
inline auto gt(Beta t, Beta f = detail::dcf_impl::default_false<std::decay_t<Beta>>())
{
return cmp_pack<cmp_kind::gt, std::decay_t<Beta>>(std::move(t), std::move(f));
}
/// \complexity O(1). Builds a spec object. The n-level walk is `make_dpf` or `ds_advance_level`, not this function.
template <typename Beta>
inline auto geq(Beta t, Beta f = detail::dcf_impl::default_false<std::decay_t<Beta>>())
{
return cmp_pack<cmp_kind::geq, std::decay_t<Beta>>(std::move(t), std::move(f));
}
/// \complexity O(1). Builds a spec object. The n-level walk is `make_dpf` or `ds_advance_level`, not this function.
template <std::size_t N, typename Beta>
inline auto lt_at(Beta t, Beta f = detail::dcf_impl::default_false<std::decay_t<Beta>>())
{
return cmp_at_pack<N, cmp_kind::lt, std::decay_t<Beta>>(std::move(t), std::move(f));
}
/// \complexity O(1). Builds a spec object. The n-level walk is `make_dpf` or `ds_advance_level`, not this function.
template <std::size_t N, typename Beta>
inline auto leq_at(Beta t, Beta f = detail::dcf_impl::default_false<std::decay_t<Beta>>())
{
return cmp_at_pack<N, cmp_kind::leq, std::decay_t<Beta>>(std::move(t), std::move(f));
}
/// \complexity O(1). Builds a spec object. The n-level walk is `make_dpf` or `ds_advance_level`, not this function.
template <std::size_t N, typename Beta>
inline auto gt_at(Beta t, Beta f = detail::dcf_impl::default_false<std::decay_t<Beta>>())
{
return cmp_at_pack<N, cmp_kind::gt, std::decay_t<Beta>>(std::move(t), std::move(f));
}
/// \complexity O(1). Builds a spec object. The n-level walk is `make_dpf` or `ds_advance_level`, not this function.
template <std::size_t N, typename Beta>
inline auto geq_at(Beta t, Beta f = detail::dcf_impl::default_false<std::decay_t<Beta>>())
{
@ -758,6 +767,7 @@ struct idcf_pack
static constexpr std::size_t prefix = Spec::prefix;
static constexpr std::size_t block_width = Spec::block_width;
static constexpr std::size_t length_bits = spec_length_bits<Spec>::value;
using inner_spec = Spec;
using beta_type = typename Spec::beta_type;
beta_type if_true;
beta_type if_false;
@ -817,6 +827,12 @@ inline auto eq_at(Beta t, Beta f = detail::dcf_impl::default_false<std::decay_t<
return eq_at_pack<N, std::decay_t<Beta>>(std::move(t), std::move(f));
}
template <typename T, typename = void>
struct pack_has_fn : std::false_type {};
template <typename T>
struct pack_has_fn<T, std::void_t<decltype(std::declval<T &>().fn)>>
: std::true_type {};
template <std::size_t BlockWidth, typename Spec>
struct block_width_pack
{
@ -828,6 +844,7 @@ struct block_width_pack
static constexpr std::size_t prefix = Spec::prefix;
static constexpr bool incremental = spec_is_incremental<Spec>::value;
static constexpr std::size_t length_bits = spec_length_bits<Spec>::value;
using inner_spec = Spec;
using beta_type = typename Spec::beta_type;
beta_type if_true;
beta_type if_false;
@ -849,6 +866,99 @@ struct block_width_fn
template <std::size_t BlockWidth>
inline constexpr block_width_fn<BlockWidth> block_width{};
// ---------------------------------------------------------------------------
// Same comparison shape, wildcard payload. Wrappers (`idcf`, `block_width`,
// `*_at`, path paints) keep their outer type; only the leaf beta changes.
// ---------------------------------------------------------------------------
template <typename T> struct is_idcf_pack : std::false_type {};
template <typename Spec>
struct is_idcf_pack<idcf_pack<Spec>> : std::true_type {};
template <typename T>
inline constexpr bool is_idcf_pack_v = is_idcf_pack<std::decay_t<T>>::value;
template <typename T> struct is_block_width_pack : std::false_type {};
template <std::size_t B, typename Spec>
struct is_block_width_pack<block_width_pack<B, Spec>> : std::true_type {};
template <typename T>
inline constexpr bool is_block_width_pack_v =
is_block_width_pack<std::decay_t<T>>::value;
namespace detail
{
template <typename Spec>
auto cmp_wildcard_shape();
template <cmp_kind K, typename B>
auto cmp_wildcard_shape(cmp_pack<K, B>)
{
using W = wildcard_value<concrete_type_t<B>>;
return cmp_pack<K, W>(W{}, W{});
}
template <std::size_t N, cmp_kind K, typename B>
auto cmp_wildcard_shape(cmp_at_pack<N, K, B>)
{
using W = wildcard_value<concrete_type_t<B>>;
return cmp_at_pack<N, K, W>(W{}, W{});
}
template <cmp_kind K, typename B, std::size_t L>
auto cmp_wildcard_shape(paint_pack<K, B, L>)
{
using W = wildcard_value<concrete_type_t<B>>;
return paint_pack<K, W, L>(W{}, W{});
}
template <std::size_t N, cmp_kind K, typename B, std::size_t L>
auto cmp_wildcard_shape(paint_at_pack<N, K, B, L>)
{
using W = wildcard_value<concrete_type_t<B>>;
return paint_at_pack<N, K, W, L>(W{}, W{});
}
template <typename B, typename Fn>
auto cmp_wildcard_shape(paint_fn_pack<B, Fn> spec)
{
using W = wildcard_value<concrete_type_t<B>>;
return paint_fn_pack<W, std::decay_t<Fn>>(W{}, W{}, std::move(spec.fn));
}
template <std::size_t N, typename B, typename Fn>
auto cmp_wildcard_shape(paint_fn_at_pack<N, B, Fn> spec)
{
using W = wildcard_value<concrete_type_t<B>>;
return paint_fn_at_pack<N, W, std::decay_t<Fn>>(W{}, W{}, std::move(spec.fn));
}
template <typename Spec>
auto cmp_wildcard_shape()
{
if constexpr (is_idcf_pack_v<Spec>)
return idcf(cmp_wildcard_shape<typename Spec::inner_spec>());
else if constexpr (is_block_width_pack_v<Spec>)
return block_width<Spec::block_width>(
cmp_wildcard_shape<typename Spec::inner_spec>());
else
{
using B = typename Spec::beta_type;
return cmp_wildcard_shape(Spec{B{}, B{}});
}
}
} // namespace detail
/// @brief The same comparison or paint spec, with a wildcard payload.
/// @details `idcf`, `block_width`, and `*_at` stay wrapped. A spec that is
/// already wildcard is returned unchanged. `path_paint` keeps `fn`.
template <typename Spec>
auto cmp_spec_as_wildcard(Spec spec)
{
using S = std::decay_t<Spec>;
if constexpr (is_wildcard_v<typename S::beta_type>)
return spec;
else if constexpr (pack_has_fn<S>::value)
return detail::cmp_wildcard_shape(std::move(spec));
else
return detail::cmp_wildcard_shape<S>();
}
template <typename T> struct is_cmp_spec : std::false_type {};
template <cmp_kind K, typename B> struct is_cmp_spec<cmp_pack<K, B>> : std::true_type {};
template <std::size_t N, cmp_kind K, typename B>