Document the new DPF surfaces in one command set, and test the field, half-tree, and multipoint edges.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
0d8a5a8131
commit
0dff6df8ed
250 changed files with 12199 additions and 1981 deletions
|
|
@ -5,6 +5,7 @@
|
|||
/// `eval_point<I0, I1, ...>` returns a tuple of shares.
|
||||
/// Pass a `basic_path_memoizer` lvalue to resume a previous path.
|
||||
/// An unassigned wildcard output throws `std::runtime_error`.
|
||||
/// `eval_point(key, x, dpf::prove(π))` folds a VDPF proof token.
|
||||
/// @snippet evaluation/eval_point.cpp eval-point
|
||||
/// @author Ryan Henry <ryan.henry@ucalgary.ca>
|
||||
/// @author Christopher Jiang <christopher.jiang@ucalgary.ca>
|
||||
|
|
@ -25,6 +26,7 @@
|
|||
#include "dpf/eval_common.hpp"
|
||||
#include "dpf/eval_target.hpp"
|
||||
#include "dpf/path_memoizer.hpp"
|
||||
#include "dpf/verifiable.hpp"
|
||||
|
||||
namespace dpf
|
||||
{
|
||||
|
|
@ -35,7 +37,8 @@ namespace internal
|
|||
template <typename DpfKey,
|
||||
typename InputT,
|
||||
typename PathMemoizer>
|
||||
inline auto eval_point_interior(const DpfKey & dpf, InputT && x, PathMemoizer && path)
|
||||
inline auto eval_point_interior(const DpfKey & dpf, InputT && x, PathMemoizer && path,
|
||||
proof_token * pi = nullptr)
|
||||
{
|
||||
using dpf_type = DpfKey;
|
||||
|
||||
|
|
@ -47,7 +50,21 @@ inline auto eval_point_interior(const DpfKey & dpf, InputT && x, PathMemoizer &&
|
|||
{
|
||||
bool bit = !!(mask & x);
|
||||
auto cw = dpf.correction_word(level_index-1, bit);
|
||||
path[level_index] = dpf_type::traverse_interior(path[level_index-1], cw, bit);
|
||||
const bool is_last = dpf_type::tree::is_last_level(level_index - 1,
|
||||
dpf.depth);
|
||||
path[level_index] = dpf_type::traverse_interior(path[level_index-1],
|
||||
cw, bit, is_last);
|
||||
if constexpr (dpf_type::is_verifiable)
|
||||
{
|
||||
if (pi != nullptr)
|
||||
{
|
||||
const auto x_bits = static_cast<psnip_uint64_t>(
|
||||
utils::to_integral_type<std::decay_t<InputT>>{}(x)
|
||||
>> (utils::bitlength_of_v<std::decay_t<InputT>> - level_index));
|
||||
detail::vdpf::fold_node(*pi, level_index - 1, x_bits,
|
||||
path[level_index], dpf.correction_seeds()[level_index - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
detail::path_note_filled_to(path, dpf.depth);
|
||||
}
|
||||
|
|
@ -68,19 +85,17 @@ template <std::size_t I,
|
|||
typename InputT,
|
||||
typename PathMemoizer>
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
auto eval_point(const DpfKey & dpf, InputT && x, PathMemoizer && path)
|
||||
auto eval_point(const DpfKey & dpf, InputT && x, PathMemoizer && path,
|
||||
proof_token * pi = nullptr)
|
||||
{
|
||||
utils::flip_msb_if_signed_integral(x);
|
||||
internal::eval_point_interior(dpf, x, path);
|
||||
internal::eval_point_interior(dpf, x, path, pi);
|
||||
return internal::eval_point_exterior<I>(dpf, path);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
/// Evaluate output `I` at `x`.
|
||||
/// @param path Mutable path memoizer. The default is a fresh
|
||||
/// nonmemoizing workspace for this call.
|
||||
/// @return Handle whose `operator*` is the party's share.
|
||||
template <std::size_t I = 0,
|
||||
typename DpfKey,
|
||||
typename InputT,
|
||||
|
|
@ -97,8 +112,28 @@ auto eval_point(const DpfKey & dpf, InputT && x, PathMemoizer && path = PathMemo
|
|||
internal::eval_point<I>(dpf, tx, path), tx);
|
||||
}
|
||||
|
||||
/// Evaluate and fold a VDPF proof token for the walked path.
|
||||
template <std::size_t I = 0,
|
||||
typename DpfKey,
|
||||
typename InputT,
|
||||
typename PathMemoizer = dpf::nonmemoizing_path_memoizer<DpfKey>,
|
||||
std::enable_if_t<looks_like_dpf_key_v<DpfKey>, bool> = true>
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
auto eval_point(const DpfKey & dpf, InputT && x, prove_ref pr,
|
||||
PathMemoizer && path = PathMemoizer{})
|
||||
{
|
||||
static_assert(DpfKey::is_verifiable,
|
||||
"eval_point(..., prove(π)): key must carry dpf::verifiable");
|
||||
assert_not_wildcard_output<I>(dpf);
|
||||
using output_type = typename DpfKey::concrete_output_type<I>;
|
||||
|
||||
detail::vdpf::init_proof(pr.token, dpf);
|
||||
auto tx = dpf.offset_x(x);
|
||||
return make_eval_dpf_output<DpfKey, output_type>(
|
||||
internal::eval_point<I>(dpf, tx, path, &pr.token), tx);
|
||||
}
|
||||
|
||||
/// Evaluate several outputs at `x`.
|
||||
/// @return Tuple of shares, already dereferenced.
|
||||
template <std::size_t I0,
|
||||
std::size_t I1,
|
||||
std::size_t ...Is,
|
||||
|
|
@ -115,6 +150,37 @@ auto eval_point(const DpfKey & dpf, InputT && x, PathMemoizer && path = PathMemo
|
|||
*eval_point<Is>(dpf, x, path)...);
|
||||
}
|
||||
|
||||
/// Fold every point in `[from, to]` into `pi` (caller must `init_proof` first,
|
||||
/// or pass a fresh token via `prove_interval` below).
|
||||
template <typename KeyT, typename InputT>
|
||||
void prove_fold_interval(const KeyT & key, InputT from, InputT to,
|
||||
proof_token & pi)
|
||||
{
|
||||
static_assert(KeyT::is_verifiable,
|
||||
"prove_fold_interval: key must carry dpf::verifiable");
|
||||
using input_type = typename KeyT::input_type;
|
||||
auto cur = static_cast<input_type>(from);
|
||||
const auto last = static_cast<input_type>(to);
|
||||
for (;;)
|
||||
{
|
||||
nonmemoizing_path_memoizer<KeyT> path{};
|
||||
auto tx = key.offset_x(cur);
|
||||
utils::flip_msb_if_signed_integral(tx);
|
||||
internal::eval_point_interior(key, tx, path, &pi);
|
||||
if (cur == last)
|
||||
break;
|
||||
++cur;
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialise `pr.token` and fold `[from, to]`.
|
||||
template <typename KeyT, typename InputT>
|
||||
void prove_interval(const KeyT & key, InputT from, InputT to, prove_ref pr)
|
||||
{
|
||||
detail::vdpf::init_proof(pr.token, key);
|
||||
prove_fold_interval(key, from, to, pr.token);
|
||||
}
|
||||
|
||||
} // namespace dpf
|
||||
|
||||
#endif // LIBDPF_INCLUDE_DPF_EVAL_POINT_HPP__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue