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
|
|
@ -2,6 +2,8 @@
|
|||
/// @brief Evaluate every input in the DPF domain.
|
||||
/// @details Equivalent to `eval_interval` from
|
||||
/// `std::numeric_limits<input_type>::min()` through `max()`.
|
||||
/// When the input offset is not yet assigned, use `defer_eval_full`
|
||||
/// (full-domain identity eval plus a deferred rotation view).
|
||||
/// @snippet evaluation/eval_full.cpp eval-full
|
||||
/// @author Ryan Henry <ryan.henry@ucalgary.ca>
|
||||
/// @author Christopher Jiang <christopher.jiang@ucalgary.ca>
|
||||
|
|
@ -27,6 +29,7 @@
|
|||
#include "dpf/interval_memoizer.hpp"
|
||||
#include "dpf/rotation_iterable.hpp"
|
||||
#include "dpf/subinterval_iterable.hpp"
|
||||
#include "dpf/verifiable.hpp"
|
||||
|
||||
namespace dpf
|
||||
{
|
||||
|
|
@ -41,7 +44,8 @@ template <std::size_t ...Is,
|
|||
std::size_t ...IIs,
|
||||
std::enable_if_t<dpf::is_wildcard_v<typename DpfKey::raw_input_type>, bool> = false>
|
||||
auto eval_full(const DpfKey & dpf, OutputBuffers && outbufs,
|
||||
IntervalMemoizer && memoizer, std::index_sequence<IIs...>)
|
||||
IntervalMemoizer && memoizer, std::index_sequence<IIs...>,
|
||||
proof_token * pi = nullptr)
|
||||
{
|
||||
using dpf_type = DpfKey;
|
||||
using input_type = typename dpf_type::input_type;
|
||||
|
|
@ -50,7 +54,7 @@ auto eval_full(const DpfKey & dpf, OutputBuffers && outbufs,
|
|||
dpf::internal::eval_interval_impl<Is...>(dpf,
|
||||
std::numeric_limits<input_type>::min(),
|
||||
std::numeric_limits<input_type>::max(),
|
||||
outbufs, memoizer, std::make_index_sequence<sizeof...(Is)>());
|
||||
outbufs, memoizer, std::make_index_sequence<sizeof...(Is)>(), pi);
|
||||
|
||||
return utils::make_tuple(dpf::rotation_iterable(std::begin(utils::get<IIs>(outbufs)), std::end(utils::get<IIs>(outbufs)), offset)...);
|
||||
}
|
||||
|
|
@ -62,7 +66,8 @@ template <std::size_t ...Is,
|
|||
std::size_t ...IIs,
|
||||
std::enable_if_t<!dpf::is_wildcard_v<typename DpfKey::raw_input_type>, bool> = false>
|
||||
auto eval_full(const DpfKey & dpf, OutputBuffers && outbufs,
|
||||
IntervalMemoizer && memoizer, std::index_sequence<IIs...>)
|
||||
IntervalMemoizer && memoizer, std::index_sequence<IIs...>,
|
||||
proof_token * pi = nullptr)
|
||||
{
|
||||
using dpf_type = DpfKey;
|
||||
using input_type = typename dpf_type::input_type;
|
||||
|
|
@ -70,7 +75,7 @@ auto eval_full(const DpfKey & dpf, OutputBuffers && outbufs,
|
|||
dpf::internal::eval_interval_impl<Is...>(dpf,
|
||||
std::numeric_limits<input_type>::min(),
|
||||
std::numeric_limits<input_type>::max(),
|
||||
outbufs, memoizer, std::make_index_sequence<sizeof...(Is)>());
|
||||
outbufs, memoizer, std::make_index_sequence<sizeof...(Is)>(), pi);
|
||||
|
||||
return utils::make_tuple(
|
||||
subinterval_iterable(std::begin(utils::get<IIs>(outbufs)),
|
||||
|
|
@ -83,6 +88,7 @@ auto eval_full(const DpfKey & dpf, OutputBuffers && outbufs,
|
|||
|
||||
} // namespace internal
|
||||
|
||||
/// \complexity Same expansion as `eval_interval` on the whole domain. L = 2^{n - lg(outputs_per_leaf)} leaf nodes, n = `depth`. Time Θ(L) interior traversals. The output buffer stores one slot per domain point (2^n).
|
||||
template <std::size_t I = 0,
|
||||
std::size_t ...Is,
|
||||
typename DpfKey,
|
||||
|
|
@ -91,13 +97,60 @@ template <std::size_t I = 0,
|
|||
std::enable_if_t<looks_like_dpf_key_v<DpfKey> && !is_multilevel_key_v<DpfKey>, bool> = true>
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
auto eval_full(const DpfKey & dpf, OutputBuffers && outbufs,
|
||||
IntervalMemoizer && memoizer)
|
||||
IntervalMemoizer && memoizer, proof_token * pi = nullptr)
|
||||
{
|
||||
assert_not_wildcard_output<I, Is...>(dpf);
|
||||
|
||||
return internal::eval_full<I, Is...>(dpf, outbufs, memoizer, std::make_index_sequence<1+sizeof...(Is)>());
|
||||
return internal::eval_full<I, Is...>(dpf, outbufs, memoizer,
|
||||
std::make_index_sequence<1+sizeof...(Is)>(), pi);
|
||||
}
|
||||
|
||||
/// @brief Evaluate the whole domain and fold a once-per-BFS-node VDPF proof.
|
||||
/// \complexity Same expansion as `eval_interval` on the whole domain. L = 2^{n - lg(outputs_per_leaf)} leaf nodes, n = `depth`. Time Θ(L) interior traversals. The output buffer stores one slot per domain point (2^n).
|
||||
template <std::size_t I = 0,
|
||||
std::size_t ...Is,
|
||||
typename DpfKey,
|
||||
typename OutputBuffers,
|
||||
typename IntervalMemoizer,
|
||||
std::enable_if_t<looks_like_dpf_key_v<DpfKey> && !is_multilevel_key_v<DpfKey>, bool> = true>
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
auto eval_full(const DpfKey & dpf, OutputBuffers && outbufs,
|
||||
IntervalMemoizer && memoizer, prove_ref pr)
|
||||
{
|
||||
static_assert(DpfKey::is_verifiable,
|
||||
"eval_full(..., prove(π)): key must carry dpf::verifiable");
|
||||
detail::vdpf::init_proof(pr.token, dpf);
|
||||
auto out = eval_full<I, Is...>(dpf, std::forward<OutputBuffers>(outbufs),
|
||||
std::forward<IntervalMemoizer>(memoizer), &pr.token);
|
||||
detail::vdpf::fold_output_binding(pr.token, dpf);
|
||||
return out;
|
||||
}
|
||||
|
||||
/// @brief Evaluate the whole domain and fold each written output into a sketch.
|
||||
/// \complexity Same expansion as `eval_interval` on the whole domain. L = 2^{n - lg(outputs_per_leaf)} leaf nodes, n = `depth`. Time Θ(L) interior traversals. The output buffer stores one slot per domain point (2^n).
|
||||
template <std::size_t I = 0,
|
||||
std::size_t ...Is,
|
||||
typename DpfKey,
|
||||
typename OutputBuffers,
|
||||
typename IntervalMemoizer,
|
||||
std::enable_if_t<looks_like_dpf_key_v<DpfKey> && !is_multilevel_key_v<DpfKey>, bool> = true>
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
auto eval_full(const DpfKey & dpf, OutputBuffers && outbufs,
|
||||
IntervalMemoizer && memoizer, sketch_ref & sk)
|
||||
{
|
||||
static_assert(DpfKey::is_extractable,
|
||||
"eval_full(..., sketch(σ)): key must carry dpf::extractable");
|
||||
auto ret = eval_full<I, Is...>(dpf, outbufs,
|
||||
std::forward<IntervalMemoizer>(memoizer));
|
||||
if constexpr (sizeof...(Is) == 0)
|
||||
{
|
||||
for (std::size_t k = 0; k < utils::size(outbufs); ++k)
|
||||
sk.absorb(outbufs[k]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// \complexity Same expansion as `eval_interval` on the whole domain. L = 2^{n - lg(outputs_per_leaf)} leaf nodes, n = `depth`. Time Θ(L) interior traversals. The output buffer stores one slot per domain point (2^n).
|
||||
template <std::size_t I = 0,
|
||||
std::size_t ...Is,
|
||||
typename DpfKey,
|
||||
|
|
@ -109,11 +162,33 @@ template <std::size_t I = 0,
|
|||
HEDLEY_ALWAYS_INLINE
|
||||
auto eval_full(const DpfKey & dpf, OutputBuffers & outbufs) // NOLINT(runtime/references)
|
||||
{
|
||||
using input_type = typename DpfKey::input_type;
|
||||
return eval_full<I, Is...>(dpf, outbufs,
|
||||
dpf::make_basic_full_memoizer(dpf));
|
||||
// The full-domain workspace is keyed only by the key type. Reusing it
|
||||
// drops a heap allocation per call and lets a repeated key skip the
|
||||
// interior rebuild (assign_interval keeps the last level).
|
||||
thread_local auto memo = dpf::make_basic_full_memoizer<DpfKey>();
|
||||
return eval_full<I, Is...>(dpf, outbufs, memo);
|
||||
}
|
||||
|
||||
/// @brief Evaluate the whole domain into `outbufs` and fold a VDPF proof.
|
||||
/// \complexity Same expansion as `eval_interval` on the whole domain. L = 2^{n - lg(outputs_per_leaf)} leaf nodes, n = `depth`. Time Θ(L) interior traversals. The output buffer stores one slot per domain point (2^n).
|
||||
template <std::size_t I = 0,
|
||||
std::size_t ...Is,
|
||||
typename DpfKey,
|
||||
typename OutputBuffers,
|
||||
std::enable_if_t<looks_like_dpf_key_v<DpfKey> && !is_multilevel_key_v<DpfKey>, bool> = true,
|
||||
std::enable_if_t<!std::is_base_of_v<
|
||||
dpf::interval_memoizer_base<unwrap_party_key_t<DpfKey>>,
|
||||
std::decay_t<OutputBuffers>>, bool> = true>
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
auto eval_full(const DpfKey & dpf, OutputBuffers & outbufs, prove_ref pr) // NOLINT(runtime/references)
|
||||
{
|
||||
static_assert(DpfKey::is_verifiable,
|
||||
"eval_full(..., prove(π)): key must carry dpf::verifiable");
|
||||
return eval_full<I, Is...>(dpf, outbufs,
|
||||
dpf::make_basic_full_memoizer(dpf), pr);
|
||||
}
|
||||
|
||||
/// \complexity Same expansion as `eval_interval` on the whole domain. L = 2^{n - lg(outputs_per_leaf)} leaf nodes, n = `depth`. Time Θ(L) interior traversals. The output buffer stores one slot per domain point (2^n).
|
||||
template <std::size_t I = 0,
|
||||
std::size_t ...Is,
|
||||
typename DpfKey,
|
||||
|
|
@ -144,6 +219,7 @@ auto eval_full(const DpfKey & dpf,
|
|||
/// @tparam DpfKey DPF key type
|
||||
/// @param dpf the DPF key
|
||||
/// @return the evaluation result
|
||||
/// \complexity Same expansion as `eval_interval` on the whole domain. L = 2^{n - lg(outputs_per_leaf)} leaf nodes, n = `depth`. Time Θ(L) interior traversals. The output buffer stores one slot per domain point (2^n).
|
||||
template <std::size_t I = 0,
|
||||
std::size_t ...Is,
|
||||
typename DpfKey,
|
||||
|
|
@ -151,11 +227,47 @@ template <std::size_t I = 0,
|
|||
HEDLEY_ALWAYS_INLINE
|
||||
auto eval_full(const DpfKey & dpf)
|
||||
{
|
||||
using input_type = typename DpfKey::input_type;
|
||||
return eval_full<I, Is...>(dpf,
|
||||
dpf::make_basic_full_memoizer(dpf));
|
||||
}
|
||||
|
||||
/// @brief Full-domain deferred eval while the input offset is unset.
|
||||
/// @details Sugar for `defer_eval_interval` over `[min, max]`. `outbufs` must
|
||||
/// be full-domain sized. After assign, `.get()` yields the logical
|
||||
/// full-domain view (same values as eager `eval_full` after assign).
|
||||
template <std::size_t I = 0,
|
||||
std::size_t ...Is,
|
||||
typename DpfKey,
|
||||
typename OutputBuffers,
|
||||
typename IntervalMemoizer,
|
||||
std::enable_if_t<looks_like_dpf_key_v<DpfKey>
|
||||
&& !is_multilevel_key_v<DpfKey>, bool> = true>
|
||||
auto defer_eval_full(const DpfKey & dpf, OutputBuffers & outbufs,
|
||||
IntervalMemoizer && memoizer) // NOLINT(runtime/references)
|
||||
{
|
||||
using input_type = typename DpfKey::input_type;
|
||||
return defer_eval_interval<I, Is...>(dpf,
|
||||
std::numeric_limits<input_type>::min(),
|
||||
std::numeric_limits<input_type>::max(),
|
||||
outbufs, std::forward<IntervalMemoizer>(memoizer));
|
||||
}
|
||||
|
||||
/// @brief `defer_eval_full` with a basic full-domain memoizer.
|
||||
template <std::size_t I = 0,
|
||||
std::size_t ...Is,
|
||||
typename DpfKey,
|
||||
typename OutputBuffers,
|
||||
std::enable_if_t<looks_like_dpf_key_v<DpfKey>
|
||||
&& !is_multilevel_key_v<DpfKey>, bool> = true,
|
||||
std::enable_if_t<!std::is_base_of_v<
|
||||
dpf::interval_memoizer_base<unwrap_party_key_t<DpfKey>>,
|
||||
std::decay_t<OutputBuffers>>, bool> = true>
|
||||
auto defer_eval_full(const DpfKey & dpf, OutputBuffers & outbufs) // NOLINT(runtime/references)
|
||||
{
|
||||
return defer_eval_full<I, Is...>(dpf, outbufs,
|
||||
dpf::make_basic_full_memoizer(dpf));
|
||||
}
|
||||
|
||||
} // namespace dpf
|
||||
|
||||
#endif // LIBDPF_INCLUDE_DPF_EVAL_FULL_HPP__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue