diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp index 08e78e539758..049e97173325 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp @@ -387,14 +387,20 @@ template class Polynomial { /** * @brief Copy over values from a vector that is of a convertible type. * + * @details There is an underlying assumption that the relevant start index in the vector + * corresponds to the start_index of the destination polynomial and also that the number of elements we want to copy + * corresponds to the size of the polynomial. This is quirky behavior and we might want to improve the UX. + * + * @todo https://github.com/AztecProtocol/barretenberg/issues/1292 + * * @tparam T a convertible type * @param vec the vector */ template void copy_vector(const std::vector& vec) { ASSERT(vec.size() <= end_index()); - for (size_t i : indices()) { - ASSERT(i < vec.size()); + ASSERT(vec.size() - start_index() <= size()); + for (size_t i = start_index(); i < vec.size(); i++) { at(i) = vec[i]; } } diff --git a/barretenberg/cpp/src/barretenberg/relations/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/relations/CMakeLists.txt index 5f3aaaaa660e..16452cdbddbe 100644 --- a/barretenberg/cpp/src/barretenberg/relations/CMakeLists.txt +++ b/barretenberg/cpp/src/barretenberg/relations/CMakeLists.txt @@ -1 +1 @@ -barretenberg_module(relations polynomials) \ No newline at end of file +barretenberg_module(relations polynomials) diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation.hpp index 1515598dc883..bb3aaaa1b3ab 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation.hpp @@ -8,14 +8,15 @@ template class TranslatorDeltaRangeConstraintRelationImpl { using FF = FF_; // 1 + polynomial degree of this relation - static constexpr size_t RELATION_LENGTH = 6; // degree((lagrange_last-1) * D(D - 1)(D - 2)(D - 3)) = 5 + static constexpr size_t RELATION_LENGTH = + 7; // degree((lagrange_real_last - 1)(lagrange_masking - 1) * D(D - 1)(D - 2)(D - 3)) = 5 static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - 6, // ordered_range_constraints_0 step in {0,1,2,3} subrelation - 6, // ordered_range_constraints_1 step in {0,1,2,3} subrelation - 6, // ordered_range_constraints_2 step in {0,1,2,3} subrelation - 6, // ordered_range_constraints_3 step in {0,1,2,3} subrelation - 6, // ordered_range_constraints_4 step in {0,1,2,3} subrelation + 7, // ordered_range_constraints_0 step in {0,1,2,3} subrelation + 7, // ordered_range_constraints_1 step in {0,1,2,3} subrelation + 7, // ordered_range_constraints_2 step in {0,1,2,3} subrelation + 7, // ordered_range_constraints_3 step in {0,1,2,3} subrelation + 7, // ordered_range_constraints_4 step in {0,1,2,3} subrelation 3, // ordered_range_constraints_0 ends with defined maximum value subrelation 3, // ordered_range_constraints_1 ends with defined maximum value subrelation 3, // ordered_range_constraints_2 ends with defined maximum value subrelation @@ -29,7 +30,10 @@ template class TranslatorDeltaRangeConstraintRelationImpl { * * @details The relation enforces 2 constraints on each of the ordered_range_constraints wires: * 1) 2 sequential values are non-descending and have a difference of at most 3, except for the value at last index - * 2) The value at last index is 2¹⁴ - 1 + * 2) The value at last index is 2¹⁴ - 1. + * + * When operating in zero knowledge, specific values of the polynomials, currently at the end, which contain random + * values, are marked to be excluded from the checks above. * * @param evals transformed to `evals + C(in(X)...)*scaling_factor` * @param in an std::array containing the fully extended Univariate edges. diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation_impl.hpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation_impl.hpp index 4a3304d13fcd..db712c35a4ea 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation_impl.hpp @@ -41,7 +41,11 @@ void TranslatorDeltaRangeConstraintRelationImpl::accumulate(ContainerOverSub auto ordered_range_constraints_2_shift = View(in.ordered_range_constraints_2_shift); auto ordered_range_constraints_3_shift = View(in.ordered_range_constraints_3_shift); auto ordered_range_constraints_4_shift = View(in.ordered_range_constraints_4_shift); - auto lagrange_last = View(in.lagrange_last); + // Represents the positon of the final non masked witness index + auto lagrange_real_last = View(in.lagrange_real_last); + auto lagrange_masking = View(in.lagrange_masking); + + auto is_last_witness_or_masking = (lagrange_real_last + minus_one) * (lagrange_masking + minus_one); // Compute wire differences auto delta_1 = ordered_range_constraints_0_shift - ordered_range_constraints_0; @@ -55,7 +59,7 @@ void TranslatorDeltaRangeConstraintRelationImpl::accumulate(ContainerOverSub tmp_1 *= (delta_1 + minus_one); tmp_1 *= (delta_1 + minus_two); tmp_1 *= (delta_1 + minus_three); - tmp_1 *= (lagrange_last + minus_one); + tmp_1 *= is_last_witness_or_masking; tmp_1 *= scaling_factor; std::get<0>(accumulators) += tmp_1; @@ -64,7 +68,7 @@ void TranslatorDeltaRangeConstraintRelationImpl::accumulate(ContainerOverSub tmp_2 *= (delta_2 + minus_one); tmp_2 *= (delta_2 + minus_two); tmp_2 *= (delta_2 + minus_three); - tmp_2 *= (lagrange_last + minus_one); + tmp_2 *= is_last_witness_or_masking; tmp_2 *= scaling_factor; std::get<1>(accumulators) += tmp_2; @@ -74,7 +78,7 @@ void TranslatorDeltaRangeConstraintRelationImpl::accumulate(ContainerOverSub tmp_3 *= (delta_3 + minus_one); tmp_3 *= (delta_3 + minus_two); tmp_3 *= (delta_3 + minus_three); - tmp_3 *= (lagrange_last + minus_one); + tmp_3 *= is_last_witness_or_masking; tmp_3 *= scaling_factor; std::get<2>(accumulators) += tmp_3; @@ -83,7 +87,7 @@ void TranslatorDeltaRangeConstraintRelationImpl::accumulate(ContainerOverSub tmp_4 *= (delta_4 + minus_one); tmp_4 *= (delta_4 + minus_two); tmp_4 *= (delta_4 + minus_three); - tmp_4 *= (lagrange_last + minus_one); + tmp_4 *= is_last_witness_or_masking; tmp_4 *= scaling_factor; std::get<3>(accumulators) += tmp_4; @@ -92,7 +96,7 @@ void TranslatorDeltaRangeConstraintRelationImpl::accumulate(ContainerOverSub tmp_5 *= (delta_5 + minus_one); tmp_5 *= (delta_5 + minus_two); tmp_5 *= (delta_5 + minus_three); - tmp_5 *= (lagrange_last + minus_one); + tmp_5 *= is_last_witness_or_masking; tmp_5 *= scaling_factor; std::get<4>(accumulators) += tmp_5; }(); @@ -105,24 +109,24 @@ void TranslatorDeltaRangeConstraintRelationImpl::accumulate(ContainerOverSub auto ordered_range_constraints_2 = View(in.ordered_range_constraints_2); auto ordered_range_constraints_3 = View(in.ordered_range_constraints_3); auto ordered_range_constraints_4 = View(in.ordered_range_constraints_4); - auto lagrange_last = View(in.lagrange_last); + auto lagrange_real_last = View(in.lagrange_real_last); // Contribution (6) (Contributions 6-10 ensure that the last value is the designated maximum value. We don't // need to constrain the first value to be 0, because the shift mechanic does this for us) std::get<5>(accumulators) += - lagrange_last * (ordered_range_constraints_0 + maximum_sort_value) * scaling_factor; + lagrange_real_last * (ordered_range_constraints_0 + maximum_sort_value) * scaling_factor; // Contribution (7) std::get<6>(accumulators) += - lagrange_last * (ordered_range_constraints_1 + maximum_sort_value) * scaling_factor; + lagrange_real_last * (ordered_range_constraints_1 + maximum_sort_value) * scaling_factor; // Contribution (8) std::get<7>(accumulators) += - lagrange_last * (ordered_range_constraints_2 + maximum_sort_value) * scaling_factor; + lagrange_real_last * (ordered_range_constraints_2 + maximum_sort_value) * scaling_factor; // Contribution (9) std::get<8>(accumulators) += - lagrange_last * (ordered_range_constraints_3 + maximum_sort_value) * scaling_factor; + lagrange_real_last * (ordered_range_constraints_3 + maximum_sort_value) * scaling_factor; // Contribution (10) std::get<9>(accumulators) += - lagrange_last * (ordered_range_constraints_4 + maximum_sort_value) * scaling_factor; + lagrange_real_last * (ordered_range_constraints_4 + maximum_sort_value) * scaling_factor; }(); }; } // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation.hpp index 9ad9bfadddd3..6bb732644ad2 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation.hpp @@ -21,6 +21,7 @@ template class TranslatorPermutationRelationImpl { inline static Accumulator compute_grand_product_numerator(const AllEntities& in, const Parameters& params) { using View = typename Accumulator::View; + using ParameterView = GetParameterView; auto interleaved_range_constraints_0 = View(in.interleaved_range_constraints_0); auto interleaved_range_constraints_1 = View(in.interleaved_range_constraints_1); @@ -29,16 +30,21 @@ template class TranslatorPermutationRelationImpl { auto ordered_extra_range_constraints_numerator = View(in.ordered_extra_range_constraints_numerator); - const auto& gamma = params.gamma; - return (interleaved_range_constraints_0 + gamma) * (interleaved_range_constraints_1 + gamma) * - (interleaved_range_constraints_2 + gamma) * (interleaved_range_constraints_3 + gamma) * - (ordered_extra_range_constraints_numerator + gamma); + auto lagrange_masking = View(in.lagrange_masking); + const auto& gamma = ParameterView(params.gamma); + const auto& beta = ParameterView(params.beta); + return (interleaved_range_constraints_0 + lagrange_masking * beta + gamma) * + (interleaved_range_constraints_1 + lagrange_masking * beta + gamma) * + (interleaved_range_constraints_2 + lagrange_masking * beta + gamma) * + (interleaved_range_constraints_3 + lagrange_masking * beta + gamma) * + (ordered_extra_range_constraints_numerator + lagrange_masking * beta + gamma); } template inline static Accumulator compute_grand_product_denominator(const AllEntities& in, const Parameters& params) { using View = typename Accumulator::View; + using ParameterView = GetParameterView; auto ordered_range_constraints_0 = View(in.ordered_range_constraints_0); auto ordered_range_constraints_1 = View(in.ordered_range_constraints_1); @@ -46,11 +52,15 @@ template class TranslatorPermutationRelationImpl { auto ordered_range_constraints_3 = View(in.ordered_range_constraints_3); auto ordered_range_constraints_4 = View(in.ordered_range_constraints_4); - const auto& gamma = params.gamma; + auto lagrange_masking = View(in.lagrange_masking); - return (ordered_range_constraints_0 + gamma) * (ordered_range_constraints_1 + gamma) * - (ordered_range_constraints_2 + gamma) * (ordered_range_constraints_3 + gamma) * - (ordered_range_constraints_4 + gamma); + const auto& gamma = ParameterView(params.gamma); + const auto& beta = ParameterView(params.beta); + return (ordered_range_constraints_0 + lagrange_masking * beta + gamma) * + (ordered_range_constraints_1 + lagrange_masking * beta + gamma) * + (ordered_range_constraints_2 + lagrange_masking * beta + gamma) * + (ordered_range_constraints_3 + lagrange_masking * beta + gamma) * + (ordered_range_constraints_4 + lagrange_masking * beta + gamma); } /** * @brief Compute contribution of the goblin translator permutation relation for a given edge (internal function) @@ -67,6 +77,8 @@ template class TranslatorPermutationRelationImpl { * the first 4 numerator polynomials are interleaved range constraint polynomials and the last one is the constant * extra numerator * + * If operating in zero-knowledge, we mark the positions (via the lagrange_masking polynomial) that should contain + * masking values, expected to be at the same indices both for the ordered and interleaved polynomials. * @param evals transformed to `evals + C(in(X)...)*scaling_factor` * @param in an std::array containing the fully extended Univariate edges. * @param parameters contains beta, gamma, and public_input_delta, .... diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation_impl.hpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation_impl.hpp index e6811a099467..23a51e4f5b3f 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation_impl.hpp @@ -18,6 +18,8 @@ namespace bb { * the first 4 numerator polynomials are interleaved range constraint polynomials and the last one is the constant * extra numerator * + * If operating in zero-knowledge, we mark the positions (via the lagrange_masking polynomial) that + * contain random values. * @param evals transformed to `evals + C(in(X)...)*scaling_factor` * @param in an std::array containing the fully extended Univariate edges. * @param parameters contains beta, gamma, and public_input_delta, .... diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_relation_consistency.test.cpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_relation_consistency.test.cpp index df8912a05b4d..a62062b48434 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_relation_consistency.test.cpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_relation_consistency.test.cpp @@ -77,20 +77,26 @@ TEST_F(TranslatorRelationConsistency, PermutationRelation) const auto& z_perm_shift = input_elements.z_perm_shift; const auto& lagrange_first = input_elements.lagrange_first; const auto& lagrange_last = input_elements.lagrange_last; + const auto& lagrange_masking = input_elements.lagrange_masking; RelationValues expected_values; const auto parameters = RelationParameters::get_random(); const auto& gamma = parameters.gamma; + const auto& beta = parameters.beta; // (Contribution 1) auto contribution_1 = - (z_perm + lagrange_first) * (interleaved_range_constraints_0 + gamma) * - (interleaved_range_constraints_1 + gamma) * (interleaved_range_constraints_2 + gamma) * - (interleaved_range_constraints_3 + gamma) * (ordered_extra_range_constraints_numerator + gamma) - - (z_perm_shift + lagrange_last) * (ordered_range_constraints_0 + gamma) * - (ordered_range_constraints_1 + gamma) * (ordered_range_constraints_2 + gamma) * - (ordered_range_constraints_3 + gamma) * (ordered_range_constraints_4 + gamma); + (z_perm + lagrange_first) * (interleaved_range_constraints_0 + lagrange_masking * beta + gamma) * + (interleaved_range_constraints_1 + lagrange_masking * beta + gamma) * + (interleaved_range_constraints_2 + lagrange_masking * beta + gamma) * + (interleaved_range_constraints_3 + lagrange_masking * beta + gamma) * + (ordered_extra_range_constraints_numerator + lagrange_masking * beta + gamma) - + (z_perm_shift + lagrange_last) * (ordered_range_constraints_0 + lagrange_masking * beta + gamma) * + (ordered_range_constraints_1 + lagrange_masking * beta + gamma) * + (ordered_range_constraints_2 + lagrange_masking * beta + gamma) * + (ordered_range_constraints_3 + lagrange_masking * beta + gamma) * + (ordered_range_constraints_4 + lagrange_masking * beta + gamma); expected_values[0] = contribution_1; // (Contribution 2) @@ -121,7 +127,8 @@ TEST_F(TranslatorRelationConsistency, DeltaRangeConstraintRelation) const auto& ordered_range_constraints_2_shift = input_elements.ordered_range_constraints_2_shift; const auto& ordered_range_constraints_3_shift = input_elements.ordered_range_constraints_3_shift; const auto& ordered_range_constraints_4_shift = input_elements.ordered_range_constraints_4_shift; - const auto& lagrange_last = input_elements.lagrange_last; + const auto& lagrange_masking = input_elements.lagrange_masking; + const auto& lagrange_real_last = input_elements.lagrange_real_last; RelationValues expected_values; @@ -140,11 +147,13 @@ TEST_F(TranslatorRelationConsistency, DeltaRangeConstraintRelation) const auto delta_4 = ordered_range_constraints_3_shift - ordered_range_constraints_3; const auto delta_5 = ordered_range_constraints_4_shift - ordered_range_constraints_4; - const auto not_last = lagrange_last + minus_one; + const auto not_real_last = lagrange_real_last + minus_one; + const auto not_masked = lagrange_masking + minus_one; // Check the delta is {0,1,2,3} - auto delta_in_range = [not_last, minus_one, minus_two, minus_three](auto delta) { - return not_last * delta * (delta + minus_one) * (delta + minus_two) * (delta + minus_three); + auto delta_in_range = [&](auto delta) { + return not_real_last * not_masked * delta * (delta + minus_one) * (delta + minus_two) * + (delta + minus_three); }; // Check delta correctness @@ -154,11 +163,11 @@ TEST_F(TranslatorRelationConsistency, DeltaRangeConstraintRelation) expected_values[3] = delta_in_range(delta_4); expected_values[4] = delta_in_range(delta_5); // Check that the last value is maximum allowed - expected_values[5] = lagrange_last * (ordered_range_constraints_0 + maximum_value); - expected_values[6] = lagrange_last * (ordered_range_constraints_1 + maximum_value); - expected_values[7] = lagrange_last * (ordered_range_constraints_2 + maximum_value); - expected_values[8] = lagrange_last * (ordered_range_constraints_3 + maximum_value); - expected_values[9] = lagrange_last * (ordered_range_constraints_4 + maximum_value); + expected_values[5] = lagrange_real_last * (ordered_range_constraints_0 + maximum_value); + expected_values[6] = lagrange_real_last * (ordered_range_constraints_1 + maximum_value); + expected_values[7] = lagrange_real_last * (ordered_range_constraints_2 + maximum_value); + expected_values[8] = lagrange_real_last * (ordered_range_constraints_3 + maximum_value); + expected_values[9] = lagrange_real_last * (ordered_range_constraints_4 + maximum_value); // We don't check that the first value is zero, because the shift mechanism already ensures it validate_relation_execution(expected_values, input_elements, parameters); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.cpp index 7a1be373a1b2..c05c03610f77 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.cpp @@ -93,12 +93,11 @@ std::array TranslatorRecursiveVerifier_template get_challenge("beta"); FF gamma = transcript->template get_challenge("gamma"); - relation_parameters.beta = 0; + relation_parameters.beta = beta; relation_parameters.gamma = gamma; - relation_parameters.public_input_delta = 0; - relation_parameters.lookup_grand_product_delta = 0; // Get commitment to permutation and lookup grand products commitments.z_perm = transcript->template receive_from_prover(commitment_labels.z_perm); diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/relation_correctness.test.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/relation_correctness.test.cpp index 389b2c3f1389..26401e2af8c0 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/relation_correctness.test.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/relation_correctness.test.cpp @@ -26,12 +26,8 @@ TEST_F(TranslatorRelationCorrectnessTests, Permutation) const size_t mini_circuit_size = 2048; const size_t full_circuit_size = mini_circuit_size * Flavor::INTERLEAVING_GROUP_SIZE; - // We only need gamma, because permutationr elation only uses gamma - FF gamma = FF::random_element(); - - // Fill relation parameters - RelationParameters params; - params.gamma = gamma; + // Fill needed relation parameters + RelationParameters params{ .beta = FF::random_element(), .gamma = FF::random_element() }; // Create storage for polynomials TranslatorProvingKey key{ mini_circuit_size }; @@ -43,7 +39,7 @@ TEST_F(TranslatorRelationCorrectnessTests, Permutation) // Put random values in all the non-interleaved constraint polynomials used to range constrain the values auto fill_polynomial_with_random_14_bit_values = [&](auto& polynomial) { - for (size_t i = polynomial.start_index(); i < polynomial.size(); i++) { + for (size_t i = polynomial.start_index(); i < polynomial.end_index(); i++) { polynomial.at(i) = engine.get_random_uint16() & ((1 << Flavor::MICRO_LIMB_BITS) - 1); } }; @@ -78,18 +74,15 @@ TEST_F(TranslatorRelationCorrectnessTests, DeltaRangeConstraint) using ProverPolynomials = typename Flavor::ProverPolynomials; auto& engine = numeric::get_debug_randomness(); const size_t mini_circuit_size = 2048; - const size_t circuit_size = Flavor::INTERLEAVING_GROUP_SIZE * mini_circuit_size; + const size_t full_circuit_size = Flavor::INTERLEAVING_GROUP_SIZE * mini_circuit_size; const auto sort_step = Flavor::SORT_STEP; const auto max_value = (1 << Flavor::MICRO_LIMB_BITS) - 1; - // No relation parameters are used in this relation - RelationParameters params; - ProverPolynomials prover_polynomials(mini_circuit_size); // Construct lagrange polynomials that are needed for Translator's DeltaRangeConstraint Relation prover_polynomials.lagrange_first.at(0) = 0; - prover_polynomials.lagrange_last.at(circuit_size - 1) = 1; + prover_polynomials.lagrange_real_last.at(full_circuit_size - 1) = 1; // Create a vector and fill with necessary steps for the DeltaRangeConstraint relation auto sorted_elements_count = (max_value / sort_step) + 1; @@ -130,7 +123,7 @@ TEST_F(TranslatorRelationCorrectnessTests, DeltaRangeConstraint) // Check that DeltaRangeConstraint relation is satisfied across each row of the prover polynomials RelationChecker::check>( - prover_polynomials, params, "TranslatorDeltaRangeConstraintRelation"); + prover_polynomials, RelationParameters(), "TranslatorDeltaRangeConstraintRelation"); } /** @@ -651,3 +644,148 @@ TEST_F(TranslatorRelationCorrectnessTests, NonNative) RelationChecker::check>( prover_polynomials, params, "TranslatorNonNativeFieldRelation"); } + +TEST_F(TranslatorRelationCorrectnessTests, ZeroKnowledgePermutation) +{ + using Flavor = TranslatorFlavor; + using FF = typename Flavor::FF; + using ProverPolynomials = typename Flavor::ProverPolynomials; + + const size_t mini_circuit_size = 2048; + auto& engine = numeric::get_debug_randomness(); + const size_t full_circuit_size = mini_circuit_size * Flavor::INTERLEAVING_GROUP_SIZE; + const size_t full_masking_offset = MASKING_OFFSET * Flavor::INTERLEAVING_GROUP_SIZE; + const size_t real_circuit_size = full_circuit_size - full_masking_offset; + + TranslatorProvingKey key{ mini_circuit_size }; + ProverPolynomials& prover_polynomials = key.proving_key->polynomials; + + // Fill required relation parameters + RelationParameters params{ .beta = FF::random_element(), .gamma = FF::random_element() }; + + // Populate the group polynomials with appropriate values and also enough random values to mask their commitment and + // evaluation + auto fill_polynomial_with_random_14_bit_values = [&](auto& polynomial) { + for (size_t i = polynomial.start_index(); i < polynomial.end_index() - MASKING_OFFSET; i++) { + polynomial.at(i) = engine.get_random_uint16() & ((1 << Flavor::MICRO_LIMB_BITS) - 1); + } + for (size_t i = polynomial.end_index() - MASKING_OFFSET; i < polynomial.end_index(); i++) { + polynomial.at(i) = FF::random_element(); + } + }; + + for (const auto& group : prover_polynomials.get_groups_to_be_interleaved()) { + for (auto& poly : group) { + fill_polynomial_with_random_14_bit_values(poly); + } + } + + // Fill in lagrange polynomials used in the permutation relation + prover_polynomials.lagrange_first.at(0) = 1; + prover_polynomials.lagrange_real_last.at(real_circuit_size - 1) = 1; + prover_polynomials.lagrange_last.at(full_circuit_size - 1) = 1; + for (size_t i = real_circuit_size; i < full_circuit_size; i++) { + prover_polynomials.lagrange_masking.at(i) = 1; + } + + key.compute_interleaved_polynomials(); + key.compute_extra_range_constraint_numerator(); + key.compute_translator_range_constraint_ordered_polynomials(true); + + // Populate the first 4 ordered polynomials with the random values from the interleaved polynomials + for (size_t i = 0; i < 4; i++) { + auto& ordered = prover_polynomials.get_ordered_constraints()[i]; + auto& interleaved = prover_polynomials.get_interleaved()[i]; + for (size_t j = real_circuit_size; j < full_circuit_size; j++) { + ordered.at(j) = interleaved.at(j); + } + } + + // Populate the last ordered range constraint and the extra polynomial in the numerator with random values + for (size_t i = real_circuit_size; i < full_circuit_size; i++) { + FF random_value = FF::random_element(); + prover_polynomials.ordered_extra_range_constraints_numerator.at(i) = random_value; + prover_polynomials.ordered_range_constraints_4.at(i) = random_value; + } + + // Compute the grand product polynomial + compute_grand_product>(prover_polynomials, params); + + // Check that permutation relation is satisfied across each row of the prover polynomials + RelationChecker::check>( + prover_polynomials, params, "TranslatorPermutationRelation"); + RelationChecker::check>( + prover_polynomials, params, "TranslatorPermutationRelation"); +} + +TEST_F(TranslatorRelationCorrectnessTests, ZeroKnowledgeDeltaRange) +{ + using Flavor = TranslatorFlavor; + using FF = typename Flavor::FF; + using ProverPolynomials = typename Flavor::ProverPolynomials; + auto& engine = numeric::get_debug_randomness(); + const size_t mini_circuit_size = 2048; + const size_t full_circuit_size = Flavor::INTERLEAVING_GROUP_SIZE * mini_circuit_size; + const auto sort_step = Flavor::SORT_STEP; + const auto max_value = (1 << Flavor::MICRO_LIMB_BITS) - 1; + + ProverPolynomials prover_polynomials(mini_circuit_size); + + const size_t full_masking_offset = MASKING_OFFSET * Flavor::INTERLEAVING_GROUP_SIZE; + const size_t real_circuit_size = full_circuit_size - full_masking_offset; + + // Construct lagrange polynomials that are needed for Translator's DeltaRangeConstraint Relation + prover_polynomials.lagrange_first.at(0) = 0; + prover_polynomials.lagrange_real_last.at(real_circuit_size - 1) = 1; + + for (size_t i = real_circuit_size; i < full_circuit_size; i++) { + prover_polynomials.lagrange_masking.at(i) = 1; + } + + // Create a vector and fill with necessary steps for the DeltaRangeConstraint relation + auto sorted_elements_count = (max_value / sort_step) + 1; + std::vector vector_for_sorting; + vector_for_sorting.reserve(prover_polynomials.ordered_range_constraints_0.size()); + for (size_t i = 0; i < sorted_elements_count - 1; i++) { + vector_for_sorting.emplace_back(i * sort_step); + } + vector_for_sorting[sorted_elements_count - 1] = max_value; + + // Add random values in the appropriate range to fill the leftover space + for (size_t i = sorted_elements_count; i < real_circuit_size; i++) { + vector_for_sorting.emplace_back(engine.get_random_uint16() & ((1 << Flavor::MICRO_LIMB_BITS) - 1)); + } + + // Get ordered polynomials + auto polynomial_pointers = std::vector{ &prover_polynomials.ordered_range_constraints_0, + &prover_polynomials.ordered_range_constraints_1, + &prover_polynomials.ordered_range_constraints_2, + &prover_polynomials.ordered_range_constraints_3, + &prover_polynomials.ordered_range_constraints_4 }; + + // Sort the vector + std::sort(vector_for_sorting.begin(), vector_for_sorting.end()); + + // Add masking values + for (size_t i = real_circuit_size; i < full_circuit_size; i++) { + vector_for_sorting.emplace_back(FF::random_element()); + } + + // Copy values, transforming them into Finite Field elements + std::transform(vector_for_sorting.cbegin(), + vector_for_sorting.cend(), + prover_polynomials.ordered_range_constraints_0.coeffs().begin(), + [](uint64_t in) { return FF(in); }); + + // Copy the same polynomial into the 4 other ordered polynomials (they are not the same in an actual proof, but + // we only need to check the correctness of the relation and it acts independently on each polynomial) + for (size_t i = 0; i < 4; ++i) { + std::copy(prover_polynomials.ordered_range_constraints_0.coeffs().begin(), + prover_polynomials.ordered_range_constraints_0.coeffs().end(), + polynomial_pointers[i + 1]->coeffs().begin()); + } + + // Check that DeltaRangeConstraint relation is satisfied across each row of the prover polynomials + RelationChecker::check>( + prover_polynomials, RelationParameters(), "TranslatorDeltaRangeConstraintRelation"); +} diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp index 8971000d542f..ac996b1a4ae2 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp @@ -65,7 +65,7 @@ class TranslatorFlavor { // Number of wires static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES; - // The step in the DeltaRangeConstraint relation + // The step in the DeltaRangeConstraint relation i.e. the maximum difference between two consecutive values static constexpr size_t SORT_STEP = 3; // The bitness of the range constraint @@ -81,10 +81,10 @@ class TranslatorFlavor { // The number of multivariate polynomials on which a sumcheck prover sumcheck operates (including shifts). We // often need containers of this size to hold related data, so we choose a name more agnostic than // `NUM_POLYNOMIALS`. Note: this number does not include the individual sorted list polynomials. - static constexpr size_t NUM_ALL_ENTITIES = 184; + static constexpr size_t NUM_ALL_ENTITIES = 186; // The number of polynomials precomputed to describe a circuit and to aid a prover in constructing a satisfying // assignment of witnesses. We again choose a neutral name. - static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 7; + static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 9; // The total number of witness entities not including shifts. static constexpr size_t NUM_WITNESS_ENTITIES = 91; static constexpr size_t NUM_WIRES_NON_SHIFTED = 1; @@ -149,11 +149,14 @@ class TranslatorFlavor { ordered_extra_range_constraints_numerator, // column 0 lagrange_first, // column 1 lagrange_last, // column 2 - // TODO(#758): Check if one of these can be replaced by shifts - lagrange_odd_in_minicircuit, // column 3 - lagrange_even_in_minicircuit, // column 4 - lagrange_second, // column 5 - lagrange_second_to_last_in_minicircuit); // column 6 + // TODO(https://github.com/AztecProtocol/barretenberg/issues/758): Check if one of these + // can be replaced by shifts + lagrange_odd_in_minicircuit, // column 3 + lagrange_even_in_minicircuit, // column 4 + lagrange_second, // column 5 + lagrange_second_to_last_in_minicircuit, // column 6 + lagrange_masking, // column 7 + lagrange_real_last); // column 8 }; template class InterleavedRangeConstraints { @@ -557,7 +560,6 @@ class TranslatorFlavor { this->ordered_range_constraints_4 }; }; - // Gemini-specific getters. auto get_unshifted() { return concatenate(PrecomputedEntities::get_all(), WitnessEntities::get_unshifted()); @@ -622,6 +624,7 @@ class TranslatorFlavor { z_perm = Polynomial{ /*size*/ circuit_size - 1, /*virtual_size*/ circuit_size, /*start_index*/ 1 }; + // All to_be_shifted witnesses except the ordered range constraints and z_perm are only non-zero in the mini // circuit for (auto& poly : get_to_be_shifted()) { @@ -725,7 +728,9 @@ class TranslatorFlavor { lagrange_odd_in_minicircuit, lagrange_even_in_minicircuit, lagrange_second, - lagrange_second_to_last_in_minicircuit); + lagrange_second_to_last_in_minicircuit, + lagrange_masking, + lagrange_real_last); }; /** @@ -866,6 +871,8 @@ class TranslatorFlavor { this->lagrange_second = "__LAGRANGE_SECOND"; this->lagrange_second_to_last_in_minicircuit = "__LAGRANGE_SECOND_TO_LAST_IN_MINICIRCUIT"; this->ordered_extra_range_constraints_numerator = "__ORDERED_EXTRA_RANGE_CONSTRAINTS_NUMERATOR"; + this->lagrange_masking = "__LAGRANGE_MASKING"; + this->lagrange_real_last = "__LAGRANGE_REAL_LAST"; }; }; @@ -882,6 +889,8 @@ class TranslatorFlavor { this->lagrange_second_to_last_in_minicircuit = verification_key->lagrange_second_to_last_in_minicircuit; this->ordered_extra_range_constraints_numerator = verification_key->ordered_extra_range_constraints_numerator; + this->lagrange_masking = verification_key->lagrange_masking; + this->lagrange_real_last = verification_key->lagrange_real_last; } }; using VerifierCommitments = VerifierCommitments_; diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.cpp index 5aa699212399..34fe3a19c18e 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.cpp @@ -76,12 +76,11 @@ void TranslatorProver::execute_wire_and_sorted_constraints_commitments_round() void TranslatorProver::execute_grand_product_computation_round() { // Compute and store parameters required by relations in Sumcheck + FF beta = transcript->template get_challenge("beta"); FF gamma = transcript->template get_challenge("gamma"); const size_t NUM_LIMB_BITS = Flavor::NUM_LIMB_BITS; - relation_parameters.beta = 0; + relation_parameters.beta = beta; relation_parameters.gamma = gamma; - relation_parameters.public_input_delta = 0; - relation_parameters.lookup_grand_product_delta = 0; auto uint_evaluation_input = uint256_t(key->evaluation_input_x); relation_parameters.evaluation_input_x = { uint_evaluation_input.slice(0, NUM_LIMB_BITS), uint_evaluation_input.slice(NUM_LIMB_BITS, NUM_LIMB_BITS * 2), diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_proving_key.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_proving_key.cpp index 090093a853c8..8f38c3f70720 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_proving_key.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_proving_key.cpp @@ -42,7 +42,7 @@ void TranslatorProvingKey::compute_interleaved_polynomials() // Copy into appropriate position in the interleaved polynomial // We offset by start_index() as the first 0 is not physically represented for shiftable values - for (size_t k = group[j].start_index(); k < group[j].size(); k++) { + for (size_t k = group[j].start_index(); k < group[j].end_index(); k++) { current_target.at(k * num_polys_in_group + j) = group[j][k]; } }; @@ -52,40 +52,47 @@ void TranslatorProvingKey::compute_interleaved_polynomials() /** * @brief Compute denominator polynomials for Translator's range constraint permutation * - * @details We need to prove that all the range constraint wires indeed have values within the given range (unless - * changed ∈ [0 , 2¹⁴ - 1]. To do this, we use several virtual interleaved wires, each of which represents a subset - * or original wires (interleaved_range_constraints_). We also generate several new polynomials of the same length - * as interleaved ones. These polynomials have values within range, but they are also constrained by the - * TranslatorFlavor's DeltaRangeConstraint relation, which ensures that sequential values differ by not more than - * 3, the last value is the maximum and the first value is zero (zero at the start allows us not to dance around - * shifts). + * @details We need to prove that all the range constraint wires in the groups indeed have values within the given + * range [0 , 2¹⁴ -1]. To do this, we use several virtual interleaved wires, each of which represents a subset of + * the original wires (the virtual wires are interleaved_range_constraints_). We also generate several new + * polynomials of the same length as the interleaved ones (ordered_range_constraints_ which, as the name suggests, + * are sorted in non-descending order). To show the interleaved range constraints have values within the appropriate + * range, we in fact use the ordered range constraints, on which TranslatorFlavor's DeltaRangeConstraint relation + * operates. The relation ensures that sequential values differ by no more than 3, the last value is the maximum and the + * first value is zero (zero at the start allows us not to dance around shifts). Then, we run the + * TranslatorPermutationRelation on interleaved_range_constraint_ and ordered_range_constraint_ to show that they + * contain the same values which implies that the small wires in the groups are indeed within the correct range. * - * Ideally, we could simply rearrange the values in interleaved_.._0 ,..., interleaved_.._3 and get denominator - * polynomials (ordered_constraints), but we could get the worst case scenario: each value in the polynomials is + * Ideally, we could simply rearrange the values in interleaved_.._0 ,..., interleaved_.._3 and get 4 denominator + * polynomials (ordered_constraints), but we could get the worst case scenario: each value in the polynomials is the * maximum value. What can we do in that case? We still have to add (max_range/3)+1 values to each of the ordered - * wires for the sort constraint to hold. So we also need a and extra denominator to store k ⋅ ( max_range / 3 + 1 ) + * wires for the sort constraint to hold. So we also need an extra denominator to store k ⋅ ( max_range / 3 + 1 ) * values that couldn't go in + ( max_range / 3 + 1 ) connecting values. To counteract the extra ( k + 1 ) ⋅ * ⋅ (max_range / 3 + 1 ) values needed for denominator sort constraints we need a polynomial in the numerator. So we * can construct a proof when ( k + 1 ) ⋅ ( max_range/ 3 + 1 ) < interleaved size * - * @tparam Flavor - * @param proving_key + * @param masking if operating in zero-knowledge the real sizes of the polynomial should be adjusted to make space for + * the random values. */ -void TranslatorProvingKey::compute_translator_range_constraint_ordered_polynomials() +void TranslatorProvingKey::compute_translator_range_constraint_ordered_polynomials(bool masking) { // Get constants - constexpr auto sort_step = Flavor::SORT_STEP; - constexpr auto num_interleaved_wires = Flavor::NUM_INTERLEAVED_WIRES; - const auto full_circuit_size = mini_circuit_dyadic_size * Flavor::INTERLEAVING_GROUP_SIZE; + constexpr size_t sort_step = Flavor::SORT_STEP; + constexpr size_t num_interleaved_wires = Flavor::NUM_INTERLEAVED_WIRES; - // The value we have to end polynomials with + const size_t full_circuit_size = mini_circuit_dyadic_size * Flavor::INTERLEAVING_GROUP_SIZE; + const size_t mini_masking_offset = masking ? MASKING_OFFSET : 0; + const size_t full_masking_offset = masking ? mini_masking_offset * Flavor::INTERLEAVING_GROUP_SIZE : 0; + const size_t real_circuit_size = full_circuit_size - full_masking_offset; + + // The value we have to end polynomials with, 2¹⁴ - 1 constexpr uint32_t max_value = (1 << Flavor::MICRO_LIMB_BITS) - 1; // Number of elements needed to go from 0 to MAX_VALUE with our step constexpr size_t sorted_elements_count = (max_value / sort_step) + 1 + (max_value % sort_step == 0 ? 0 : 1); // Check if we can construct these polynomials - ASSERT((num_interleaved_wires + 1) * sorted_elements_count < full_circuit_size); + ASSERT((num_interleaved_wires + 1) * sorted_elements_count < real_circuit_size); // First use integers (easier to sort) std::vector sorted_elements(sorted_elements_count); @@ -96,41 +103,39 @@ void TranslatorProvingKey::compute_translator_range_constraint_ordered_polynomia sorted_elements[i] = (sorted_elements_count - 1 - i) * sort_step; } - std::vector> ordered_vectors_uint(num_interleaved_wires); RefArray ordered_constraint_polynomials{ proving_key->polynomials.ordered_range_constraints_0, proving_key->polynomials.ordered_range_constraints_1, proving_key->polynomials.ordered_range_constraints_2, proving_key->polynomials.ordered_range_constraints_3 }; - std::vector extra_denominator_uint(full_circuit_size); + std::vector extra_denominator_uint(real_circuit_size); - // Get information which polynomials need to be interleaved auto to_be_interleaved_groups = proving_key->polynomials.get_groups_to_be_interleaved(); - // A function that transfers elements from each of the polynomials in the chosen interleaved group in the uint - // ordered polynomials + // Given the polynomials in group_i, transfer their elements, sorted in non-descending order, into the corresponding + // ordered_range_constraint_i up to the given capacity and the remaining elements to the last range constraint. + // Sorting is done by converting the elements to uint for efficiency. auto ordering_function = [&](size_t i) { - // Get the group and the main target vector auto group = to_be_interleaved_groups[i]; - auto& current_vector = ordered_vectors_uint[i]; - current_vector.resize(full_circuit_size); + std::vector ordered_vectors_uint(real_circuit_size); - // Calculate how much space there is for values from the original polynomials - auto free_space_before_runway = full_circuit_size - sorted_elements_count; + // Calculate how much space there is for values from the group polynomials given we also need to append the + // additional steps + auto free_space_before_runway = real_circuit_size - sorted_elements_count; - // Calculate the offset of this group's overflowing elements in the extra denominator polynomial + // Calculate the starting index of this group's overflowing elements in the extra denominator polynomial size_t extra_denominator_offset = i * sorted_elements_count; // Go through each polynomial in the interleaved group for (size_t j = 0; j < Flavor::INTERLEAVING_GROUP_SIZE; j++) { // Calculate the offset in the target vector - auto current_offset = j * mini_circuit_dyadic_size; + auto current_offset = j * (mini_circuit_dyadic_size - mini_masking_offset); // For each element in the polynomial - for (size_t k = group[j].start_index(); k < group[j].size(); k++) { + for (size_t k = group[j].start_index(); k < group[j].end_index() - mini_masking_offset; k++) { // Put it it the target polynomial if ((current_offset + k) < free_space_before_runway) { - current_vector[current_offset + k] = static_cast(uint256_t(group[j][k]).data[0]); + ordered_vectors_uint[current_offset + k] = static_cast(uint256_t(group[j][k]).data[0]); // Or in the extra one if there is no space left } else { @@ -140,36 +145,40 @@ void TranslatorProvingKey::compute_translator_range_constraint_ordered_polynomia } } } - // Copy the steps into the target polynomial - auto starting_write_offset = current_vector.begin(); - std::advance(starting_write_offset, free_space_before_runway); - std::copy(sorted_elements.cbegin(), sorted_elements.cend(), starting_write_offset); + // Advance the iterator past the last written element in the range constraint polynomial and complete it with + // sorted steps + auto ordered_vector_it = ordered_vectors_uint.begin(); + std::advance(ordered_vector_it, free_space_before_runway); + std::copy(sorted_elements.cbegin(), sorted_elements.cend(), ordered_vector_it); - // Sort the polynomial in nondescending order. We sort using vector with size_t elements for 2 reasons: + // Sort the polynomial in nondescending order. We sort using the size_t vector for 2 reasons: // 1. It is faster to sort size_t // 2. Comparison operators for finite fields are operating on internal form, so we'd have to convert them // from Montgomery - std::sort(current_vector.begin(), current_vector.end()); + std::sort(ordered_vectors_uint.begin(), ordered_vectors_uint.end()); + ASSERT(ordered_vectors_uint.size() == real_circuit_size); // Copy the values into the actual polynomial - ordered_constraint_polynomials[i].copy_vector(current_vector); + ordered_constraint_polynomials[i].copy_vector(ordered_vectors_uint); }; // Construct the first 4 polynomials parallel_for(num_interleaved_wires, ordering_function); - ordered_vectors_uint.clear(); - auto sorted_element_insertion_offset = extra_denominator_uint.begin(); - std::advance(sorted_element_insertion_offset, num_interleaved_wires * sorted_elements_count); + // Advance the iterator into the extra range constraint past the last written element + auto extra_denominator_it = extra_denominator_uint.begin(); + std::advance(extra_denominator_it, num_interleaved_wires * sorted_elements_count); - // Add steps to the extra denominator polynomial - std::copy(sorted_elements.cbegin(), sorted_elements.cend(), sorted_element_insertion_offset); + // Add steps to the extra denominator polynomial to fill it + std::copy(sorted_elements.cbegin(), sorted_elements.cend(), extra_denominator_it); + ASSERT(extra_denominator_uint.size() == real_circuit_size); // Sort it #ifdef NO_PAR_ALGOS std::sort(extra_denominator_uint.begin(), extra_denominator_uint.end()); #else std::sort(std::execution::par_unseq, extra_denominator_uint.begin(), extra_denominator_uint.end()); #endif + ASSERT(extra_denominator_uint.size() == real_circuit_size); // Copy the values into the actual polynomial proving_key->polynomials.ordered_range_constraints_4.copy_vector(extra_denominator_uint); @@ -187,17 +196,18 @@ void TranslatorProvingKey::compute_lagrange_polynomials() } /** - * @brief Compute the extra numerator for Goblin range constraint argument + * @brief Compute the extra numerator for the grand product polynomial. * * @details Goblin proves that several polynomials contain only values in a certain range through 2 * relations: 1) A grand product which ignores positions of elements (TranslatorPermutationRelation) 2) A - * relation enforcing a certain ordering on the elements of the given polynomial + * relation enforcing a certain ordering on the elements of given polynomials * (TranslatorDeltaRangeConstraintRelation) * - * We take the values from 4 polynomials, and spread them into 5 polynomials + add all the steps from - * MAX_VALUE to 0. We order these polynomials and use them in the denominator of the grand product, at the - * same time checking that they go from MAX_VALUE to 0. To counteract the added steps we also generate an - * extra range constraint numerator, which contains 5 MAX_VALUE, 5 (MAX_VALUE-STEP),... values + * We take the values from 4 polynomials (interleaved_range_constraint_), and spread them into 5 polynomials to be + * sorted (ordered_range_constraint_), adding all the steps from MAX_VALUE to 0 in each ordered range constraint to + * complete them. The latter polynomials will be in the numerator of the grand product, the former in the numerator. To + * make up for the added steps in the numerator, an additional polynomial needs to be generated which contains 5 + * MAX_VALUE, 5 (MAX_VALUE-STEP),... values. * */ void TranslatorProvingKey::compute_extra_range_constraint_numerator() @@ -226,7 +236,7 @@ void TranslatorProvingKey::compute_extra_range_constraint_numerator() extra_range_constraint_numerator.at(shift + i * (Flavor::NUM_INTERLEAVED_WIRES + 1)) = sorted_elements[i]; } }; - // Fill polynomials with a sequence, where each element is repeatedNUM_INTERLEAVED_WIRES+1 times + // Fill polynomials with a sequence, where each element is repeated NUM_INTERLEAVED_WIRES+1 times parallel_for(Flavor::NUM_INTERLEAVED_WIRES + 1, fill_with_shift); } } // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_proving_key.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_proving_key.hpp index bff2d80fc212..2ec1c1382abb 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_proving_key.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_proving_key.hpp @@ -43,13 +43,10 @@ class TranslatorProvingKey { proving_key = std::make_shared(dyadic_circuit_size, std::move(commitment_key)); proving_key->polynomials = Flavor::ProverPolynomials(mini_circuit_dyadic_size); - // Populate the wire polynomials from the wire vectors in the circuit constructor. Note: In goblin translator - // wires - // come as is, since they have to reflect the structure of polynomials in the first 4 wires, which we've - // commited to + // Populate the wire polynomials from the wire vectors in the circuit for (auto [wire_poly_, wire_] : zip_view(proving_key->polynomials.get_wires(), circuit.wires)) { auto& wire_poly = wire_poly_; - auto& wire = wire_; + const auto& wire = wire_; parallel_for_range(circuit.num_gates, [&](size_t start, size_t end) { for (size_t i = start; i < end; i++) { if (i >= wire_poly.start_index() && i < wire_poly.end_index()) { @@ -63,22 +60,23 @@ class TranslatorProvingKey { // First and last lagrange polynomials (in the full circuit size) proving_key->polynomials.lagrange_first.at(0) = 1; + proving_key->polynomials.lagrange_real_last.at(dyadic_circuit_size - 1) = 1; proving_key->polynomials.lagrange_last.at(dyadic_circuit_size - 1) = 1; - // Compute polynomials with odd and even indices set to 1 up to the minicircuit margin + lagrange + // Construct polynomials with odd and even indices set to 1 up to the minicircuit margin + lagrange // polynomials at second and second to last indices in the minicircuit compute_lagrange_polynomials(); - // Compute the numerator for the permutation argument with several repetitions of steps bridging 0 and - // maximum range constraint compute_extra_range_constraint_numerator(); + // Construct the extra range constraint numerator which contains all the additional values in the ordered range + // constraints not present in the interleaved polynomials + // NB this will always have a fixed size unless we change the allowed range compute_extra_range_constraint_numerator(); - // Creates the polynomials resulting from interleaving each group of range constraints into one polynomial. - // These are not commited to. + // Construct the polynomials resulted from interleaving the small polynomials in each group compute_interleaved_polynomials(); - // We also contruct ordered polynomials, which have the same values as interleaved ones + enough values to - // bridge the range from 0 to maximum range defined by the range constraint. + // Construct the ordered polynomials, containing the values of the interleaved polynomials + enough values to + // bridge the range from 0 to 3 (3 is the maximum allowed range defined by the range constraint). compute_translator_range_constraint_ordered_polynomials(); }; @@ -95,8 +93,7 @@ class TranslatorProvingKey { // Check that the Translator Circuit does not exceed the fixed upper bound, the current value 8192 corresponds // to 10 rounds of folding (i.e. 20 circuits) if (circuit.num_gates > Flavor::TRANSLATOR_VM_FIXED_SIZE) { - info("The Translator circuit size has exceeded the fixed upper bound"); - ASSERT(false); + throw_or_abort("The Translator circuit size has exceeded the fixed upper bound"); } mini_circuit_dyadic_size = Flavor::TRANSLATOR_VM_FIXED_SIZE; } @@ -105,7 +102,7 @@ class TranslatorProvingKey { void compute_extra_range_constraint_numerator(); - void compute_translator_range_constraint_ordered_polynomials(); + void compute_translator_range_constraint_ordered_polynomials(bool masking = false); void compute_interleaved_polynomials(); }; diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.cpp index 24039a92b54e..d7bffc0ee0db 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.cpp @@ -81,12 +81,11 @@ bool TranslatorVerifier::verify_proof(const HonkProof& proof, } // Get permutation challenges + FF beta = transcript->template get_challenge("beta"); FF gamma = transcript->template get_challenge("gamma"); - relation_parameters.beta = 0; + relation_parameters.beta = beta; relation_parameters.gamma = gamma; - relation_parameters.public_input_delta = 0; - relation_parameters.lookup_grand_product_delta = 0; // Get commitment to permutation and lookup grand products commitments.z_perm = transcript->template receive_from_prover(commitment_labels.z_perm);