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
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue