Skip to content
10 changes: 8 additions & 2 deletions barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,14 +387,20 @@ template <typename Fr> 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 <typename T> void copy_vector(const std::vector<T>& 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];
}
}
Expand Down
2 changes: 1 addition & 1 deletion barretenberg/cpp/src/barretenberg/relations/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
barretenberg_module(relations polynomials)
barretenberg_module(relations polynomials)
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ template <typename FF_> 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<size_t, 10> 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
Expand All @@ -29,7 +30,10 @@ template <typename FF_> 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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ void TranslatorDeltaRangeConstraintRelationImpl<FF>::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;
Expand All @@ -55,7 +59,7 @@ void TranslatorDeltaRangeConstraintRelationImpl<FF>::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;

Expand All @@ -64,7 +68,7 @@ void TranslatorDeltaRangeConstraintRelationImpl<FF>::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;
Expand All @@ -74,7 +78,7 @@ void TranslatorDeltaRangeConstraintRelationImpl<FF>::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;

Expand All @@ -83,7 +87,7 @@ void TranslatorDeltaRangeConstraintRelationImpl<FF>::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;

Expand All @@ -92,7 +96,7 @@ void TranslatorDeltaRangeConstraintRelationImpl<FF>::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;
}();
Expand All @@ -105,24 +109,24 @@ void TranslatorDeltaRangeConstraintRelationImpl<FF>::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
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ template <typename FF_> class TranslatorPermutationRelationImpl {
inline static Accumulator compute_grand_product_numerator(const AllEntities& in, const Parameters& params)
{
using View = typename Accumulator::View;
using ParameterView = GetParameterView<Parameters, View>;

auto interleaved_range_constraints_0 = View(in.interleaved_range_constraints_0);
auto interleaved_range_constraints_1 = View(in.interleaved_range_constraints_1);
Expand All @@ -29,28 +30,37 @@ template <typename FF_> 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) *
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this construction (in particular the + lagrange_masking * beta) feels like it deserves some comments, unless its explained elsewhere and I'm missing it. What are we establishing by adding an additional constant to the sum only at the masked indices?

Copy link
Author

@maramihali maramihali Mar 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, will add comments to the declaration of accumulate

(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 <typename Accumulator, typename AllEntities, typename Parameters>
inline static Accumulator compute_grand_product_denominator(const AllEntities& in, const Parameters& params)
{
using View = typename Accumulator::View;
using ParameterView = GetParameterView<Parameters, View>;

auto ordered_range_constraints_0 = View(in.ordered_range_constraints_0);
auto ordered_range_constraints_1 = View(in.ordered_range_constraints_1);
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);

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)
Expand All @@ -67,6 +77,8 @@ template <typename FF_> 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, ....
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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, ....
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<FF>::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)
Expand Down Expand Up @@ -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;

Expand All @@ -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
Expand All @@ -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<Relation>(expected_values, input_elements, parameters);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,11 @@ std::array<typename Flavor::GroupElement, 2> TranslatorRecursiveVerifier_<Flavor
}

// Get permutation challenges
FF beta = transcript->template get_challenge<FF>("beta");
FF gamma = transcript->template get_challenge<FF>("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>(commitment_labels.z_perm);
Expand Down
Loading