From a8d081c3cd1667c0d7e4cb9716f6daaa6b950c9b Mon Sep 17 00:00:00 2001 From: AztecBot Date: Tue, 5 May 2026 06:01:31 +0000 Subject: [PATCH 1/2] fix(bb): pad gemini_masking_poly size to even to avoid sumcheck OOB --- .../cpp/src/barretenberg/ultra_honk/oink_prover.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp index 32494b09caea..6e38b9864f30 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp @@ -186,8 +186,11 @@ template void OinkProver::commit_to_z_perm() template void OinkProver::commit_to_masking_poly() { if constexpr (flavor_has_gemini_masking()) { - // Gemini masking poly only needs to cover the actual polynomial extent, not full dyadic size - const size_t polynomial_size = prover_instance->polynomials.max_end_index(); + // Gemini masking poly only needs to cover the actual polynomial extent, not full dyadic size. + // Round up to even so sumcheck's pairwise (edge_idx, edge_idx + 1) iteration over the effective + // round size — which itself rounds max_end_index up to even — stays in bounds. + const size_t max_end_index = prover_instance->polynomials.max_end_index(); + const size_t polynomial_size = max_end_index + (max_end_index % 2); prover_instance->polynomials.gemini_masking_poly = Polynomial::random(polynomial_size); // Commit to the masking polynomial and send to transcript From 326515a142c33c9ebe08194c7dcdb5e8774f873c Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Wed, 6 May 2026 17:12:52 +0000 Subject: [PATCH 2/2] fix the fix --- .../cpp/src/barretenberg/ultra_honk/oink_prover.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp index 6e38b9864f30..d2157c11fe73 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp @@ -186,12 +186,10 @@ template void OinkProver::commit_to_z_perm() template void OinkProver::commit_to_masking_poly() { if constexpr (flavor_has_gemini_masking()) { - // Gemini masking poly only needs to cover the actual polynomial extent, not full dyadic size. - // Round up to even so sumcheck's pairwise (edge_idx, edge_idx + 1) iteration over the effective - // round size — which itself rounds max_end_index up to even — stays in bounds. - const size_t max_end_index = prover_instance->polynomials.max_end_index(); - const size_t polynomial_size = max_end_index + (max_end_index % 2); - prover_instance->polynomials.gemini_masking_poly = Polynomial::random(polynomial_size); + // virtual_size = dyadic_size matches every other witness poly, so sumcheck's pairwise read + // past end_index lands in the virtual-zero region. + prover_instance->polynomials.gemini_masking_poly = Polynomial::random( + prover_instance->polynomials.max_end_index(), prover_instance->dyadic_size(), /*start_index=*/0); // Commit to the masking polynomial and send to transcript auto masking_commitment = commitment_key.commit(prover_instance->polynomials.gemini_masking_poly);