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
|
|
@ -58,26 +58,31 @@ template <std::size_t N, typename O, typename ...Os>
|
|||
struct is_at<at_pack<N, O, Os...>> : std::true_type {};
|
||||
template <typename T> inline constexpr bool is_at_v = is_at<T>::value;
|
||||
|
||||
/// Phantom pack element for a key's comparison (DCF) channel. Not a leaf: it
|
||||
/// @brief Phantom pack element for a key's comparison (DCF) channel. Not a leaf: it
|
||||
/// only records the cmp prefix depth in the key's type. `Depth` is the number
|
||||
/// of tree levels the comparison walks (0 is reserved for "no cmp").
|
||||
/// `OutBits` is the comparison output group width (bits of the β payload),
|
||||
/// @details `OutBits` is the comparison output group width (bits of the β payload),
|
||||
/// so the value CWs / addend can be stored at group width instead of a full
|
||||
/// padded `uint64_t` per level.
|
||||
/// @tparam Depth depth
|
||||
/// @tparam OutBits out bits
|
||||
/// @tparam Wild whether the payload is a wildcard
|
||||
/// @tparam BlockWidth checkpoint spacing, in levels
|
||||
/// @tparam Incremental whether a final correction is stored at every depth
|
||||
template <std::size_t Depth, std::size_t OutBits = 0, bool Wild = false,
|
||||
std::size_t BlockWidth = 0, bool Incremental = false>
|
||||
struct cmp_channel_tag
|
||||
{
|
||||
static constexpr std::size_t depth = Depth;
|
||||
static constexpr std::size_t out_bits = OutBits;
|
||||
/// True when the comparison payload (β) is a wildcard to be assigned
|
||||
/// @brief True when the comparison payload (β) is a wildcard to be assigned
|
||||
/// after keygen. Concrete (non-wildcard) cmp keys keep `Wild == false`
|
||||
/// so their layout / type name is unchanged.
|
||||
static constexpr bool wild = Wild;
|
||||
/// 0 keeps the per-level path-sum. `B >= 1` selects blocked checkpoints
|
||||
/// @brief 0 keeps the per-level path-sum. `B >= 1` selects blocked checkpoints
|
||||
/// of target width `B`.
|
||||
static constexpr std::size_t block_width = BlockWidth;
|
||||
/// Save a final correction at every depth (`idcf`).
|
||||
/// @brief Save a final correction at every depth (`idcf`).
|
||||
static constexpr bool incremental = Incremental;
|
||||
};
|
||||
|
||||
|
|
@ -90,6 +95,38 @@ template <typename T>
|
|||
inline constexpr bool is_cmp_channel_tag_v =
|
||||
is_cmp_channel_tag<std::decay_t<T>>::value;
|
||||
|
||||
/// Phantom pack element: key carries per-level VDPF correction seeds.
|
||||
struct verifiable
|
||||
{
|
||||
static constexpr bool is_verifiable_tag = true;
|
||||
};
|
||||
|
||||
/// Phantom pack element: ROM leaf stretch + extractability checks.
|
||||
struct extractable
|
||||
{
|
||||
static constexpr bool is_extractable_tag = true;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_verifiable_tag : std::false_type
|
||||
{ };
|
||||
template <>
|
||||
struct is_verifiable_tag<verifiable> : std::true_type
|
||||
{ };
|
||||
template <typename T>
|
||||
inline constexpr bool is_verifiable_tag_v =
|
||||
is_verifiable_tag<std::decay_t<T>>::value;
|
||||
|
||||
template <typename T>
|
||||
struct is_extractable_tag : std::false_type
|
||||
{ };
|
||||
template <>
|
||||
struct is_extractable_tag<extractable> : std::true_type
|
||||
{ };
|
||||
template <typename T>
|
||||
inline constexpr bool is_extractable_tag_v =
|
||||
is_extractable_tag<std::decay_t<T>>::value;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
namespace incr
|
||||
|
|
@ -99,13 +136,25 @@ namespace incr
|
|||
// A concrete placed output: an output type `OutputT` planted at prefix `N`.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// @brief Default: placed payload type is the stored type. Specialized for
|
||||
/// `arith_beta<T>` in `doerner_shelat.hpp` so the key leaf type is `T`.
|
||||
/// @tparam T value type
|
||||
template <typename T>
|
||||
struct unwrap_placed_output
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template <std::size_t N, typename OutputT>
|
||||
struct placed
|
||||
{
|
||||
static constexpr std::size_t prefix = N;
|
||||
using output_type = OutputT;
|
||||
/// @brief Stored argument type (may be `arith_beta<T>`).
|
||||
using stored_type = OutputT;
|
||||
/// @brief Key / leaf payload type (`T` when stored is `arith_beta<T>`).
|
||||
using output_type = typename unwrap_placed_output<OutputT>::type;
|
||||
OutputT value;
|
||||
OutputT addend{}; // public if_false for eq(...); party 0 absorbs at eval
|
||||
output_type addend{}; // public if_false for eq(...); party 0 absorbs at eval
|
||||
};
|
||||
|
||||
template <typename T> struct is_placed : std::false_type {};
|
||||
|
|
@ -114,8 +163,10 @@ struct is_placed<placed<N, O>> : std::true_type {};
|
|||
template <typename T>
|
||||
inline constexpr bool is_placed_v = is_placed<std::decay_t<T>>::value;
|
||||
|
||||
/// Heavy-hitters incremental point function: one payload per prefix length.
|
||||
/// `levels[i]` is the bit length of slot `i`.
|
||||
/// @brief Heavy-hitters incremental point function: one payload per prefix length.
|
||||
/// @details `levels[i]` is the bit length of slot `i`.
|
||||
/// @tparam LevelSeq level seq
|
||||
/// @tparam Betas betas
|
||||
template <typename LevelSeq, typename ...Betas>
|
||||
struct idpf_pack;
|
||||
|
||||
|
|
@ -416,6 +467,8 @@ struct normalize_one
|
|||
static constexpr bool cmp_wild = false;
|
||||
static constexpr std::size_t cmp_block = 0;
|
||||
static constexpr bool cmp_idcf = false;
|
||||
static constexpr bool is_verifiable = false;
|
||||
static constexpr bool is_extractable = false;
|
||||
};
|
||||
template <std::size_t BitLen, std::size_t N, typename T>
|
||||
struct normalize_one<BitLen, placed<N, T>>
|
||||
|
|
@ -426,6 +479,8 @@ struct normalize_one<BitLen, placed<N, T>>
|
|||
static constexpr bool cmp_wild = false;
|
||||
static constexpr std::size_t cmp_block = 0;
|
||||
static constexpr bool cmp_idcf = false;
|
||||
static constexpr bool is_verifiable = false;
|
||||
static constexpr bool is_extractable = false;
|
||||
};
|
||||
template <std::size_t BitLen, std::size_t Depth, std::size_t OutBits, bool Wild,
|
||||
std::size_t Block, bool Incremental>
|
||||
|
|
@ -438,6 +493,32 @@ struct normalize_one<BitLen,
|
|||
static constexpr bool cmp_wild = Wild;
|
||||
static constexpr std::size_t cmp_block = Block;
|
||||
static constexpr bool cmp_idcf = Incremental;
|
||||
static constexpr bool is_verifiable = false;
|
||||
static constexpr bool is_extractable = false;
|
||||
};
|
||||
template <std::size_t BitLen>
|
||||
struct normalize_one<BitLen, verifiable>
|
||||
{
|
||||
using placed_tuple = std::tuple<>;
|
||||
static constexpr std::size_t cmp_depth = 0;
|
||||
static constexpr std::size_t cmp_out_bits = 0;
|
||||
static constexpr bool cmp_wild = false;
|
||||
static constexpr std::size_t cmp_block = 0;
|
||||
static constexpr bool cmp_idcf = false;
|
||||
static constexpr bool is_verifiable = true;
|
||||
static constexpr bool is_extractable = false;
|
||||
};
|
||||
template <std::size_t BitLen>
|
||||
struct normalize_one<BitLen, extractable>
|
||||
{
|
||||
using placed_tuple = std::tuple<>;
|
||||
static constexpr std::size_t cmp_depth = 0;
|
||||
static constexpr std::size_t cmp_out_bits = 0;
|
||||
static constexpr bool cmp_wild = false;
|
||||
static constexpr std::size_t cmp_block = 0;
|
||||
static constexpr bool cmp_idcf = false;
|
||||
static constexpr bool is_verifiable = false;
|
||||
static constexpr bool is_extractable = true;
|
||||
};
|
||||
|
||||
template <std::size_t BitLen, typename ...Elems>
|
||||
|
|
@ -448,18 +529,18 @@ struct normalize_pack
|
|||
std::declval<typename normalize_one<BitLen, Elems>::placed_tuple>()...));
|
||||
static constexpr std::size_t cmp_depth =
|
||||
(std::size_t{0} + ... + normalize_one<BitLen, Elems>::cmp_depth);
|
||||
// At most one comparison channel per key, so the sum is that channel's
|
||||
// output width (0 when there is no cmp channel).
|
||||
static constexpr std::size_t cmp_out_bits =
|
||||
(std::size_t{0} + ... + normalize_one<BitLen, Elems>::cmp_out_bits);
|
||||
// At most one comparison channel per key, so the OR is that channel's
|
||||
// wildcard flag (false when there is no cmp channel).
|
||||
static constexpr bool cmp_wild =
|
||||
(false || ... || normalize_one<BitLen, Elems>::cmp_wild);
|
||||
static constexpr std::size_t cmp_block =
|
||||
(std::size_t{0} + ... + normalize_one<BitLen, Elems>::cmp_block);
|
||||
static constexpr bool cmp_idcf =
|
||||
(false || ... || normalize_one<BitLen, Elems>::cmp_idcf);
|
||||
static constexpr bool is_verifiable =
|
||||
(false || ... || normalize_one<BitLen, Elems>::is_verifiable);
|
||||
static constexpr bool is_extractable =
|
||||
(false || ... || normalize_one<BitLen, Elems>::is_extractable);
|
||||
};
|
||||
|
||||
template <std::size_t BitLen>
|
||||
|
|
@ -471,19 +552,26 @@ struct normalize_pack<BitLen>
|
|||
static constexpr bool cmp_wild = false;
|
||||
static constexpr std::size_t cmp_block = 0;
|
||||
static constexpr bool cmp_idcf = false;
|
||||
static constexpr bool is_verifiable = false;
|
||||
static constexpr bool is_extractable = false;
|
||||
};
|
||||
|
||||
/// True iff the pack is "classic-shaped": every element is a bare output (no
|
||||
/// `placed<>` from `at<>` and no `cmp_channel_tag<>`).
|
||||
/// @brief True iff the pack is "classic-shaped": every element is a bare output (no
|
||||
/// `placed<>` from `at<>`, no `cmp_channel_tag<>`, and no verifiable/extractable).
|
||||
template <typename ...Elems>
|
||||
inline constexpr bool is_classic_pack_v =
|
||||
!((is_placed_v<Elems> || is_cmp_channel_tag_v<Elems>) || ...);
|
||||
!((is_placed_v<Elems> || is_cmp_channel_tag_v<Elems>
|
||||
|| is_verifiable_tag_v<Elems> || is_extractable_tag_v<Elems>) || ...);
|
||||
|
||||
} // namespace incr
|
||||
} // namespace detail
|
||||
|
||||
/// Sparse heavy-hitters IDPF. Slot `i` is the point function on prefix
|
||||
/// @brief Sparse heavy-hitters IDPF. Slot `i` is the point function on prefix
|
||||
/// `Levels[i]`, evaluated with `out<i>`.
|
||||
/// @tparam Levels levels
|
||||
/// @tparam Betas betas
|
||||
/// @param betas the `betas`
|
||||
/// @return Sparse heavy-hitters IDPF
|
||||
template <std::size_t ...Levels, typename ...Betas>
|
||||
auto idpf_at(Betas ...betas)
|
||||
{
|
||||
|
|
@ -500,7 +588,10 @@ auto idpf_from_seq(std::index_sequence<I...>, Betas ...betas)
|
|||
return idpf_at<(I + 1)...>(std::move(betas)...);
|
||||
}
|
||||
|
||||
/// Consecutive prefixes of length 1, 2, …, `sizeof...(Betas)`.
|
||||
/// @brief Consecutive prefixes of length 1, 2, …, `sizeof...(Betas)`.
|
||||
/// @tparam Betas betas
|
||||
/// @param betas the `betas`
|
||||
/// @return Consecutive prefixes of length 1, 2, …, `sizeof...(Betas)`
|
||||
template <typename ...Betas>
|
||||
auto idpf(Betas ...betas)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue