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:
Ryan Henry 2026-09-24 23:18:10 -06:00
parent 0d8a5a8131
commit 0dff6df8ed
250 changed files with 12199 additions and 1981 deletions

View file

@ -1,6 +1,7 @@
#include <gtest/gtest.h>
#include "dpf.hpp"
#include "dpf/blocked_dcf.hpp"
#include "dpf/json.hpp"
#include "grotto/offset_horner.hpp"
#include "grotto/prefix_parity.hpp"
@ -238,7 +239,10 @@ TEST(BlockedDcf, DealerMatchesDoernerShelat)
dpf::root_sampler_t<dpf::prg::aes128>{take_root},
dpf::block_width<4>(dpf::lt(uint64_t{15}, uint64_t{2})));
reset_tape();
HEDLEY_PRAGMA(GCC diagnostic push)
HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
dpf::ds_randomness<simde__m128i (*)(), PadA> rng{take_root, {}};
HEDLEY_PRAGMA(GCC diagnostic pop)
auto ds = dpf::make_dpf_doerner_shelat(x0, x1, rng,
dpf::block_width<4>(dpf::lt(uint64_t{15}, uint64_t{2})));
@ -336,7 +340,10 @@ TEST(BlockedDcf, GenevalOpensCheckpointWords)
const uint8_t x0 = 1;
const uint8_t x1 = static_cast<uint8_t>(alpha ^ x0);
reset_tape();
HEDLEY_PRAGMA(GCC diagnostic push)
HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
dpf::ds_randomness<simde__m128i (*)(), PadA> rng{take_root, {}};
HEDLEY_PRAGMA(GCC diagnostic pop)
std::array<uint8_t, 3> ends{{0, 20, 21}};
auto g = dpf::geneval_cmp(x0, x1, ends.begin(), ends.end(), rng,
dpf::block_width<4>(dpf::lt(uint64_t{5})));
@ -350,6 +357,85 @@ TEST(BlockedDcf, GenevalOpensCheckpointWords)
EXPECT_EQ((g.party0[2] + g.party1[2]) & g.mask, 0u);
}
TEST(BlockedDcf, UnevenScheduleMatchesDenseComparison)
{
const uint16_t alpha = 0x0B4C;
auto dense = dpf::make_dpf(alpha, dpf::lt(uint64_t{9}, uint64_t{2}));
auto blocked = dpf::make_dpf(alpha,
dpf::block_width<4>(dpf::lt(uint64_t{9}, uint64_t{2})));
using KT = std::decay_t<decltype(blocked.first)>;
EXPECT_EQ(KT::cmp_h, 14u);
EXPECT_EQ(KT::cmp_block, 4u);
EXPECT_NE(KT::cmp_h % KT::cmp_block, 0u);
EXPECT_EQ(blocked.first.value_cw().size(), KT::cmp_checkpoints);
using sched = dpf::detail::blocked::schedule<KT::cmp_h, KT::cmp_block>;
ASSERT_GE(sched::count, 2u);
bool uneven = false;
const auto first_step = sched::depths[1] - sched::depths[0];
for (std::size_t i = 1; i < sched::count; ++i)
{
if (sched::depths[i] - sched::depths[i - 1] != first_step)
uneven = true;
}
EXPECT_TRUE(uneven);
for (uint32_t x = 0; x < 65536u; ++x)
{
const auto q = static_cast<uint16_t>(x);
ASSERT_EQ(recon_cmp(blocked.first, blocked.second, q),
recon_cmp(dense.first, dense.second, q))
<< x;
}
}
TEST(BlockedDcf, WideCheckpointFrontierMatchesDense)
{
const uint32_t alpha = 0x01020304u;
// `cmp_q` is 2, so `lt_at<19>` checkpoints at height 17. One block of 17
// parks a root sibling 16 levels above that checkpoint.
auto dense = dpf::make_dpf(alpha, dpf::lt_at<19>(uint64_t{5}, uint64_t{1}));
auto blocked = dpf::make_dpf(alpha,
dpf::block_width<17>(dpf::lt_at<19>(uint64_t{5}, uint64_t{1})));
using KT = std::decay_t<decltype(blocked.first)>;
EXPECT_GE(KT::cmp_h, 17u);
EXPECT_EQ(KT::cmp_checkpoints, 1u);
const uint32_t pts[] = {
0u, 1u, alpha - 1u, alpha, alpha + 1u, 0x80000000u, 0xffffffffu
};
for (uint32_t x : pts)
{
EXPECT_EQ(recon_cmp(blocked.first, blocked.second, x),
recon_cmp(dense.first, dense.second, x))
<< std::hex << x;
}
const uint32_t from = 100, to = 101;
auto buf0 = dpf::make_output_buffer(dpf::cmp, blocked.first, from, to);
auto buf1 = dpf::make_output_buffer(dpf::cmp, blocked.second, from, to);
dpf::eval_interval(dpf::cmp, blocked.first, from, to, buf0);
dpf::eval_interval(dpf::cmp, blocked.second, from, to, buf1);
EXPECT_EQ(recon(buf0[0], buf1[0]) & blocked.first.cmp().mask,
recon_cmp(blocked.first, blocked.second, from));
EXPECT_EQ(recon(buf0[1], buf1[1]) & blocked.first.cmp().mask,
recon_cmp(blocked.first, blocked.second, to));
}
TEST(BlockedDcf, PathRecipesStayOnThePerLevelChannel)
{
const uint8_t alpha = 0x3C;
EXPECT_THROW(dpf::make_dpf(alpha, dpf::block_width<4>(dpf::lcp(uint64_t{1}))),
std::invalid_argument);
EXPECT_THROW(dpf::make_dpf(alpha, dpf::block_width<4>(dpf::break_bit(uint64_t{3}))),
std::invalid_argument);
EXPECT_THROW(dpf::make_dpf(alpha,
dpf::block_width<4>(dpf::prefix_with_length<4>(uint64_t{1}))),
std::invalid_argument);
EXPECT_THROW(dpf::make_dpf(alpha, dpf::block_width<2>(dpf::path_paint(
[](std::size_t matched, uint64_t, bool) {
return static_cast<uint64_t>(matched);
}))),
std::invalid_argument);
}
TEST(BlockedDcf, GrottoPrefixSegmentAndHorner)
{
const uint16_t alpha = 1000;