41#include <gtest/gtest.h>
54struct ValidTranslatorState {
66ValidTranslatorState build_valid_translator_state()
68 const size_t full_circuit_size = Flavor::MINI_CIRCUIT_SIZE * Flavor::CONCATENATION_GROUP_SIZE;
76 for (
const auto&
group : pp.get_groups_to_be_concatenated()) {
77 for (
auto& poly :
group) {
78 if (poly.is_empty()) {
81 for (
size_t i = poly.start_index(); i < poly.end_index() - NUM_DISABLED_ROWS_IN_SUMCHECK; i++) {
84 for (
size_t i = poly.end_index() - NUM_DISABLED_ROWS_IN_SUMCHECK; i < poly.end_index(); i++) {
96 key.compute_lagrange_polynomials();
97 key.compute_extra_range_constraint_numerator();
98 key.compute_concatenated_polynomials();
99 key.compute_translator_range_constraint_ordered_polynomials();
103 compute_grand_product<Flavor, TranslatorPermutationRelation<FF>>(pp, params);
116ValidTranslatorState build_valid_accumulator_transfer_state()
126 op_queue->no_op_ultra_only();
127 for (
size_t i = 0; i < Flavor::CircuitBuilder::NUM_RANDOM_OPS_START; i++) {
128 op_queue->random_op_ultra_only();
130 for (
size_t i = 0; i < 50; i++) {
131 op_queue->add_accumulate(GroupElement::random_element(&
engine));
134 op_queue->eq_and_reset();
136 for (
size_t i = 0; i < 50; i++) {
137 op_queue->add_accumulate(GroupElement::random_element(&
engine));
140 op_queue->eq_and_reset();
141 for (
size_t i = 0; i < Flavor::CircuitBuilder::NUM_RANDOM_OPS_END; i++) {
142 op_queue->random_op_ultra_only();
146 const auto batching_challenge_v = BF::random_element(&
engine);
147 const auto evaluation_input_x = BF::random_element(&
engine);
153 auto& pp =
key.proving_key->polynomials;
156 pp.accumulators_binary_limbs_1[Flavor::RESULT_ROW],
157 pp.accumulators_binary_limbs_2[Flavor::RESULT_ROW],
158 pp.accumulators_binary_limbs_3[Flavor::RESULT_ROW] };
176 auto [
key, params] = build_valid_translator_state();
177 auto& pp =
key.proving_key->polynomials;
182 EXPECT_TRUE(baseline.empty()) <<
"Baseline permutation should pass";
186 const size_t corrupt_pos = Flavor::MINI_CIRCUIT_SIZE + 1;
190 compute_grand_product<Flavor, TranslatorPermutationRelation<FF>>(pp, params);
194 EXPECT_FALSE(failures.empty()) <<
"Permutation should fail after concatenated corruption";
203 auto [
key, params] = build_valid_translator_state();
204 auto& pp =
key.proving_key->polynomials;
206 const size_t full_circuit_size = Flavor::MINI_CIRCUIT_SIZE * Flavor::CONCATENATION_GROUP_SIZE;
210 pp, params,
"TranslatorDeltaRangeConstraintRelation");
211 EXPECT_TRUE(baseline.empty()) <<
"Baseline delta range should pass";
214 const size_t real_last_pos = full_circuit_size - Flavor::MAX_RANDOM_VALUES_PER_ORDERED - 1;
215 pp.ordered_range_constraints_0.at(real_last_pos) =
FF(42);
218 pp, params,
"TranslatorDeltaRangeConstraintRelation");
219 EXPECT_FALSE(failures.empty()) <<
"Delta range should fail when real_last position != 2^14 - 1";
227 auto [
key, params] = build_valid_translator_state();
228 auto& pp =
key.proving_key->polynomials;
233 EXPECT_TRUE(baseline.empty()) <<
"Baseline permutation should pass";
236 const size_t corrupt_pos = (Flavor::MINI_CIRCUIT_SIZE * 2) + 500;
243 EXPECT_FALSE(failures.empty()) <<
"Permutation should fail after z_perm corruption";
256 auto [
key, params] = build_valid_translator_state();
257 auto& pp =
key.proving_key->polynomials;
259 const size_t full_circuit_size = Flavor::MINI_CIRCUIT_SIZE * Flavor::CONCATENATION_GROUP_SIZE;
263 pp, params,
"TranslatorDeltaRangeConstraintRelation");
264 EXPECT_TRUE(baseline.empty()) <<
"Baseline delta range should pass";
268 const size_t boundary_pos = full_circuit_size - Flavor::MAX_RANDOM_VALUES_PER_ORDERED - 2;
269 pp.ordered_range_constraints_0.at(boundary_pos) =
FF(0);
272 pp, params,
"TranslatorDeltaRangeConstraintRelation");
273 EXPECT_FALSE(failures.empty()) <<
"Delta range should fail at the masking boundary";
282 auto [
key, params] = build_valid_translator_state();
283 auto& pp =
key.proving_key->polynomials;
287 pp, params,
"TranslatorDeltaRangeConstraintRelation");
288 EXPECT_TRUE(baseline.empty()) <<
"Baseline delta range should pass";
293 const size_t pos = 5000;
294 pp.ordered_range_constraints_0.at(pos) = pp.ordered_range_constraints_0[pos + 1] +
FF(1);
297 pp, params,
"TranslatorDeltaRangeConstraintRelation");
298 EXPECT_FALSE(failures.empty()) <<
"Delta range should fail on descending (negative delta) pair";
307 auto [
key, params] = build_valid_translator_state();
308 auto& pp =
key.proving_key->polynomials;
312 pp, params,
"TranslatorDeltaRangeConstraintRelation");
313 EXPECT_TRUE(baseline.empty()) <<
"Baseline delta range should pass";
316 const size_t pos = 3000;
317 FF next_val = pp.ordered_range_constraints_0[pos + 1];
318 pp.ordered_range_constraints_0.at(pos) = next_val -
FF(4);
321 pp, params,
"TranslatorDeltaRangeConstraintRelation");
322 EXPECT_FALSE(failures.empty()) <<
"Delta range should fail when delta is exactly 4";
331 auto [
key, params] = build_valid_translator_state();
332 auto& pp =
key.proving_key->polynomials;
336 pp, params,
"TranslatorDeltaRangeConstraintRelation");
337 EXPECT_TRUE(baseline.empty()) <<
"Baseline delta range should pass";
341 pp.ordered_range_constraints_0.at(1) =
FF(100);
344 pp, params,
"TranslatorDeltaRangeConstraintRelation");
345 EXPECT_FALSE(failures.empty()) <<
"Delta range should fail when first sorted value > 3";
354 auto [
key, params] = build_valid_translator_state();
355 auto& pp =
key.proving_key->polynomials;
359 pp, params,
"TranslatorDeltaRangeConstraintRelation");
360 EXPECT_TRUE(baseline.empty()) <<
"Baseline delta range should pass";
363 const size_t pos = 2000;
364 pp.ordered_range_constraints_4.at(pos) = pp.ordered_range_constraints_4[pos - 1] +
FF(100);
367 pp, params,
"TranslatorDeltaRangeConstraintRelation");
368 EXPECT_FALSE(failures.empty()) <<
"Delta range should fail on 5th ordered poly corruption";
377 auto [
key, params] = build_valid_translator_state();
378 auto& pp =
key.proving_key->polynomials;
383 EXPECT_TRUE(baseline.empty()) <<
"Baseline permutation should pass";
386 const size_t corrupt_pos = 500;
391 EXPECT_FALSE(failures.empty()) <<
"Permutation should fail after ordered poly corruption";
404 const size_t full_circuit_size = Flavor::MINI_CIRCUIT_SIZE * Flavor::CONCATENATION_GROUP_SIZE;
412 for (
const auto&
group : pp.get_groups_to_be_concatenated()) {
413 for (
auto& poly :
group) {
414 if (poly.is_empty()) {
417 for (
size_t i = poly.start_index(); i < poly.end_index() - NUM_DISABLED_ROWS_IN_SUMCHECK; i++) {
420 for (
size_t i = poly.end_index() - NUM_DISABLED_ROWS_IN_SUMCHECK; i < poly.end_index(); i++) {
428 const FF sentinel(42);
429 auto groups = pp.get_groups_to_be_concatenated();
430 auto& target_wire = groups[0][0];
431 const size_t wire_masking_start = target_wire.end_index() - NUM_DISABLED_ROWS_IN_SUMCHECK;
432 target_wire.at(wire_masking_start) = sentinel;
440 key.compute_lagrange_polynomials();
441 key.compute_extra_range_constraint_numerator();
442 key.compute_concatenated_polynomials();
446 const size_t concat_masking_pos = wire_masking_start;
447 EXPECT_EQ(pp.concatenated_range_constraints_0[concat_masking_pos], sentinel)
448 <<
"Sentinel should appear at the correct concatenated position";
450 key.compute_translator_range_constraint_ordered_polynomials();
461 for (
const auto& ord_poly : pp.get_ordered_range_constraints()) {
462 for (
size_t pos = full_circuit_size - Flavor::MAX_RANDOM_VALUES_PER_ORDERED; pos < full_circuit_size; pos++) {
463 if (ord_poly[pos] == sentinel) {
472 EXPECT_TRUE(found) <<
"Sentinel value 42 should appear in the ordered poly masking tail";
476 compute_grand_product<Flavor, TranslatorPermutationRelation<FF>>(pp, params);
480 EXPECT_TRUE(perm_failures.empty()) <<
"Permutation should pass with in-range masking value";
483 pp, params,
"TranslatorDeltaRangeConstraintRelation");
484 EXPECT_TRUE(delta_failures.empty()) <<
"Delta range should pass with in-range masking value";
493 auto [
key, params] = build_valid_translator_state();
494 auto& pp =
key.proving_key->polynomials;
499 EXPECT_TRUE(baseline.empty()) <<
"Baseline permutation should pass";
502 const size_t corrupt_pos = 5;
507 EXPECT_FALSE(failures.empty()) <<
"Permutation should fail after extra numerator corruption";
518 auto [
key, params] = build_valid_accumulator_transfer_state();
519 auto& pp =
key.proving_key->polynomials;
523 pp, params,
"TranslatorAccumulatorTransferRelation");
524 EXPECT_TRUE(baseline.empty()) <<
"Baseline accumulator transfer should pass";
531 pp, params,
"TranslatorAccumulatorTransferRelation");
532 EXPECT_FALSE(failures.empty()) <<
"Accumulator transfer should fail after odd row corruption";
541 auto [
key, params] = build_valid_accumulator_transfer_state();
542 auto& pp =
key.proving_key->polynomials;
545 pp, params,
"TranslatorAccumulatorTransferRelation");
546 EXPECT_TRUE(baseline.empty()) <<
"Baseline accumulator transfer should pass";
549 const size_t last_in_minicircuit = Flavor::MINI_CIRCUIT_SIZE - Flavor::NUM_MASKED_ROWS_END - 1;
550 pp.accumulators_binary_limbs_0.at(last_in_minicircuit) =
FF(1);
553 pp, params,
"TranslatorAccumulatorTransferRelation");
554 EXPECT_FALSE(failures.empty()) <<
"Accumulator transfer should fail when zero-init position is non-zero";
563 auto [
key, params] = build_valid_accumulator_transfer_state();
564 auto& pp =
key.proving_key->polynomials;
567 pp, params,
"TranslatorAccumulatorTransferRelation");
568 EXPECT_TRUE(baseline.empty()) <<
"Baseline accumulator transfer should pass";
571 params.accumulated_result[0] +=
FF(1);
574 pp, params,
"TranslatorAccumulatorTransferRelation");
575 EXPECT_FALSE(failures.empty()) <<
"Accumulator transfer should fail on result mismatch";
590 auto [
key, params] = build_valid_accumulator_transfer_state();
591 auto& pp =
key.proving_key->polynomials;
594 for (
size_t i = Flavor::RANDOMNESS_START; i < Flavor::RESULT_ROW; i++) {
602 const size_t end_mask_start = Flavor::MINI_CIRCUIT_SIZE - Flavor::NUM_MASKED_ROWS_END;
603 for (
size_t i = end_mask_start; i < Flavor::MINI_CIRCUIT_SIZE; i++) {
612 pp, params,
"TranslatorAccumulatorTransferRelation");
613 EXPECT_TRUE(failures.empty()) <<
"Accumulator transfer should pass even with arbitrary masking region values";
622 auto [
key, params] = build_valid_accumulator_transfer_state();
623 auto& pp =
key.proving_key->polynomials;
626 pp, params,
"TranslatorAccumulatorTransferRelation");
627 EXPECT_TRUE(baseline.empty()) <<
"Baseline accumulator transfer should pass";
631 const size_t first_transfer_row = Flavor::RESULT_ROW + 1;
635 pp, params,
"TranslatorAccumulatorTransferRelation");
636 EXPECT_FALSE(failures.empty()) <<
"Accumulator transfer should fail at first transfer row";
646 auto [
key, params] = build_valid_accumulator_transfer_state();
647 auto& pp =
key.proving_key->polynomials;
650 pp, params,
"TranslatorAccumulatorTransferRelation");
651 EXPECT_TRUE(baseline.empty()) <<
"Baseline accumulator transfer should pass";
654 const size_t last_transfer_row = Flavor::MINI_CIRCUIT_SIZE - Flavor::NUM_MASKED_ROWS_END - 3;
658 pp, params,
"TranslatorAccumulatorTransferRelation");
659 EXPECT_FALSE(failures.empty()) <<
"Accumulator transfer should fail at last transfer row";
669 auto [
key, params] = build_valid_translator_state();
670 auto& pp =
key.proving_key->polynomials;
675 EXPECT_TRUE(baseline.empty()) <<
"Baseline permutation should pass";
679 const size_t block_boundary_pos = 5 * Flavor::MINI_CIRCUIT_SIZE;
680 EXPECT_EQ(pp.concatenated_range_constraints_0[block_boundary_pos],
FF(0))
681 <<
"Block boundary should initially be zero";
683 pp.concatenated_range_constraints_0.at(block_boundary_pos) =
FF(999);
686 compute_grand_product<Flavor, TranslatorPermutationRelation<FF>>(pp, params);
690 EXPECT_FALSE(failures.empty()) <<
"Permutation should fail after block boundary corruption";
static void SetUpTestSuite()
static const size_t OP_QUEUE_SIZE
A container for the prover polynomials.
typename Curve::ScalarField FF
ECCVMCircuitBuilder CircuitBuilder
typename Curve::BaseField BF
bb::Polynomial< FF > Polynomial
typename G1::element GroupElement
A debugging utility for checking whether a set of polynomials satisfies the relations for a given Fla...
A wrapper for Relations to expose methods used by the Sumcheck prover or verifier to add the contribu...
group class. Represents an elliptic curve group element. Group is parametrised by Fq and Fr
virtual uint16_t get_random_uint16()=0
typename ECCVMFlavor::ProverPolynomials ProverPolynomials
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
Entry point for Barretenberg command-line interface.
TEST_F(IPATest, ChallengesAreZero)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Container for parameters used by the grand product (permutation, lookup) Honk relations.
std::array< T, NUM_BINARY_LIMBS_IN_GOBLIN_TRANSLATOR > accumulated_result
static field random_element(numeric::RNG *engine=nullptr) noexcept