Skip to content

Commit fb8da24

Browse files
committed
fix(bb): stop reading past end_index in sumcheck extend_edges and partially_evaluate
1 parent a4ac021 commit fb8da24

2 files changed

Lines changed: 24 additions & 8 deletions

File tree

barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -675,11 +675,19 @@ template <typename Flavor> class SumcheckProver {
675675
parallel_for(source_view.size(), [&](size_t j) {
676676
BB_BENCH_TRACY_NAME("Sumcheck::partially_evaluate");
677677
const auto& poly = source_view[j];
678-
size_t limit = poly.end_index();
679-
for (size_t i = 0; i < limit; i += 2) {
680-
dest_view[j].at(i >> 1) = poly[i] + round_challenge * (poly[i + 1] - poly[i]);
678+
const size_t limit = poly.end_index();
679+
const size_t num_full_pairs = limit / 2;
680+
for (size_t i = 0; i < num_full_pairs; ++i) {
681+
const size_t idx = i << 1;
682+
dest_view[j].at(i) = poly[idx] + round_challenge * (poly[idx + 1] - poly[idx]);
681683
}
682-
dest_view[j].shrink_end_index((limit / 2) + (limit % 2));
684+
// If the active region has an odd length, fold the lone trailing coefficient against an
685+
// implicit zero partner instead of reading poly[limit] (past end_index, would trip the
686+
// virtual-zeroes assertion for polynomials with virtual_size == end_index).
687+
if ((limit & 1) != 0) {
688+
dest_view[j].at(num_full_pairs) = poly[limit - 1] * (FF(1) - round_challenge);
689+
}
690+
dest_view[j].shrink_end_index(num_full_pairs + (limit & 1));
683691
});
684692
};
685693

barretenberg/cpp/src/barretenberg/sumcheck/sumcheck_round.hpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,15 +160,23 @@ template <typename Flavor> class SumcheckProverRound {
160160
const size_t edge_idx)
161161
{
162162
for (auto [extended_edge, multivariate] : zip_view(extended_edges.get_all(), multivariates.get_all())) {
163+
const size_t end = multivariate.end_index();
163164
if constexpr (Flavor::USE_SHORT_MONOMIALS) {
164-
extended_edge = bb::Univariate<FF, 2>({ multivariate[edge_idx], multivariate[edge_idx + 1] });
165+
// The main loop iterates up to effective_round_size, which rounds max_end_index up to even.
166+
// For odd max_end_index, the second read of the final edge lands at index == end_index, which
167+
// would trip the virtual-zeroes assertion for polynomials with virtual_size == end_index
168+
// (e.g. gemini_masking_poly). Treat reads past end_index as zero directly.
169+
const FF v0 = (edge_idx < end) ? FF(multivariate[edge_idx]) : FF::zero();
170+
const FF v1 = (edge_idx + 1 < end) ? FF(multivariate[edge_idx + 1]) : FF::zero();
171+
extended_edge = bb::Univariate<FF, 2>({ v0, v1 });
165172
} else {
166-
if (multivariate.end_index() < edge_idx) {
173+
if (end <= edge_idx) {
167174
static const auto zero_univariate = bb::Univariate<FF, MAX_PARTIAL_RELATION_LENGTH>::zero();
168175
extended_edge = zero_univariate;
169176
} else {
170-
extended_edge = bb::Univariate<FF, 2>({ multivariate[edge_idx], multivariate[edge_idx + 1] })
171-
.template extend_to<MAX_PARTIAL_RELATION_LENGTH>();
177+
const FF v0 = multivariate[edge_idx];
178+
const FF v1 = (edge_idx + 1 < end) ? FF(multivariate[edge_idx + 1]) : FF::zero();
179+
extended_edge = bb::Univariate<FF, 2>({ v0, v1 }).template extend_to<MAX_PARTIAL_RELATION_LENGTH>();
172180
}
173181
}
174182
}

0 commit comments

Comments
 (0)