14#include <gtest/gtest.h>
15#include <unordered_set>
21constexpr std::array<size_t, 4> kDValues = { 4, 8, 11, 12 };
24TEST(ShpleminiZkMaskSupport, ShapeContract)
26 for (
size_t d : kDValues) {
27 const size_t n =
size_t{ 1 } << d;
29 const size_t expected_size = std::min(2 * d, n);
31 EXPECT_EQ(support.size(), expected_size) <<
"support size at d=" << d;
33 std::unordered_set<size_t> seen(support.begin(), support.end());
34 EXPECT_EQ(seen.size(), support.size()) <<
"duplicate support entry at d=" << d;
35 for (
size_t s : support) {
36 EXPECT_LT(s, n) <<
"out-of-range support entry at d=" << d;
42TEST(ShpleminiZkMaskSupport, ContainsTailHalvingPairs)
44 for (
size_t d : kDValues) {
45 const size_t n =
size_t{ 1 } << d;
47 const std::unordered_set<size_t> seen(support.begin(), support.end());
50 EXPECT_TRUE(seen.count(n - 1)) <<
"missing top entry N-1 at d=" << d;
51 EXPECT_TRUE(seen.count(n - 2)) <<
"missing top entry N-2 at d=" << d;
54 for (
size_t level = 1; level < d; ++level) {
55 const size_t base = n >> level;
56 EXPECT_TRUE(seen.count(base)) <<
"missing dyadic entry " << base <<
" at d=" << d;
57 EXPECT_TRUE(seen.count(base - 1)) <<
"missing dyadic entry " << (base - 1) <<
" at d=" << d;
64TEST(ShpleminiZkMaskSupport, ExactDescendingSupportAtFullExtent)
66 for (
size_t d : kDValues) {
67 const size_t n =
size_t{ 1 } << d;
68 std::vector<size_t> expected = { n - 1, n - 2 };
69 for (
size_t level = 1; level < d; ++level) {
70 const size_t base = n >> level;
71 expected.push_back(base);
72 expected.push_back(base - 1);
74 ASSERT_EQ(expected.size(), std::min(2 * d, n)) <<
"expected support size at d=" << d;
82TEST(ShpleminiZkMaskSupport, OddExtentRoundsUp)
85 const size_t n =
size_t{ 1 } << d;
86 const size_t extent = (n / 2) + 5;
88 const size_t E = extent + 1;
90 const std::unordered_set<size_t> seen(support.begin(), support.end());
91 EXPECT_EQ(support.size(), std::min(2 * d, n));
92 EXPECT_EQ(seen.size(), support.size());
93 EXPECT_TRUE(seen.count(E - 1)) <<
"missing rounded-up top entry E-1";
94 EXPECT_TRUE(seen.count(E - 2)) <<
"missing rounded-up top entry E-2";
101TEST(ShpleminiZkMaskSupport, CollisionExtentStaysFull)
103 for (
size_t d : kDValues) {
104 const size_t n =
size_t{ 1 } << d;
105 const size_t extent = (n / 2) + 2;
108 const std::unordered_set<size_t> seen(support.begin(), support.end());
109 EXPECT_EQ(support.size(), std::min(2 * d, n)) <<
"size at d=" << d;
110 EXPECT_EQ(seen.size(), support.size()) <<
"duplicate support entry at d=" << d;
111 for (
size_t s : support) {
112 EXPECT_LT(s, n) <<
"out-of-range support entry at d=" << d;
121TEST(ShpleminiZkMaskSupport, DenseMaskBelowSparseThreshold)
124 const auto count_nonzero = [](
const auto& poly) {
126 for (
size_t i = poly.start_index(); i < poly.end_index(); ++i) {
127 if (!poly.at(i).is_zero()) {
135 const size_t n3 =
size_t{ 1 } << 3;
136 EXPECT_EQ(count_nonzero(build_gemini_masking_poly<fr>(3, n3, n3)), n3) <<
"expected dense mask at d=3";
139 for (
size_t d : {
size_t{ 4 },
size_t{ 8 } }) {
140 const size_t n =
size_t{ 1 } << d;
141 const auto poly = build_gemini_masking_poly<fr>(d, n, n);
142 EXPECT_EQ(count_nonzero(poly), std::min(2 * d, n)) <<
"expected sparse mask at d=" << d;
Entry point for Barretenberg command-line interface.
std::vector< size_t > tail_halving_support(size_t d, size_t extent)
TEST(BoomerangMegaCircuitBuilder, BasicCircuit)