Skip to content

Commit

Permalink
feat: Goblin translator non-native field relation (Goblin Translator …
Browse files Browse the repository at this point in the history
…part 6) (#2871)

This PR adds the last of the Goblin translator relations (the non-native
field relation) to the codebase. It also adds consistency tests.
  • Loading branch information
Rumata888 authored Oct 19, 2023
1 parent 4ffe9be commit c4d8d96
Show file tree
Hide file tree
Showing 3 changed files with 494 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "barretenberg/proof_system/relations/decomposition_relation.hpp"
#include "barretenberg/proof_system/relations/extra_relations.hpp"
#include "barretenberg/proof_system/relations/gen_perm_sort_relation.hpp"
#include "barretenberg/proof_system/relations/non_native_field_relation.hpp"
#include "barretenberg/proof_system/relations/permutation_relation.hpp"
#include "decomposition_relation.hpp"
#include "extra_relations.hpp"
Expand Down Expand Up @@ -980,4 +981,158 @@ TEST_F(GoblinTranslatorRelationConsistency, AccumulatorTransferRelation)
run_test(/*random_inputs=*/true);
};

TEST_F(GoblinTranslatorRelationConsistency, NonNativeFieldRelation)
{
const auto run_test = [](bool random_inputs) {
constexpr size_t NUM_LIMB_BITS = 68;
constexpr FF shift = FF(uint256_t(1) << NUM_LIMB_BITS);
constexpr FF shiftx2 = FF(uint256_t(1) << (NUM_LIMB_BITS * 2));
constexpr FF shiftx3 = FF(uint256_t(1) << (NUM_LIMB_BITS * 3));
constexpr uint512_t MODULUS_U512 = uint512_t(curve::BN254::BaseField::modulus);
constexpr uint512_t BINARY_BASIS_MODULUS = uint512_t(1) << (NUM_LIMB_BITS << 2);
constexpr uint512_t NEGATIVE_PRIME_MODULUS = BINARY_BASIS_MODULUS - MODULUS_U512;
constexpr std::array<FF, 5> NEGATIVE_MODULUS_LIMBS = {
FF(NEGATIVE_PRIME_MODULUS.slice(0, NUM_LIMB_BITS).lo),
FF(NEGATIVE_PRIME_MODULUS.slice(NUM_LIMB_BITS, NUM_LIMB_BITS * 2).lo),
FF(NEGATIVE_PRIME_MODULUS.slice(NUM_LIMB_BITS * 2, NUM_LIMB_BITS * 3).lo),
FF(NEGATIVE_PRIME_MODULUS.slice(NUM_LIMB_BITS * 3, NUM_LIMB_BITS * 4).lo),
-FF(curve::BN254::BaseField::modulus)
};

using Relation = GoblinTranslatorNonNativeFieldRelation<FF>;
using RelationValues = typename Relation::SumcheckArrayOfValuesOverSubrelations;

const InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();

auto& op = input_elements.op;
auto& p_x_low_limbs = input_elements.p_x_low_limbs;
auto& p_y_low_limbs = input_elements.p_y_low_limbs;
auto& p_x_high_limbs = input_elements.p_x_high_limbs;
auto& p_y_high_limbs = input_elements.p_y_high_limbs;
auto& accumulators_binary_limbs_0 = input_elements.accumulators_binary_limbs_0;
auto& accumulators_binary_limbs_1 = input_elements.accumulators_binary_limbs_1;
auto& accumulators_binary_limbs_2 = input_elements.accumulators_binary_limbs_2;
auto& accumulators_binary_limbs_3 = input_elements.accumulators_binary_limbs_3;
auto& z_low_limbs = input_elements.z_low_limbs;
auto& z_high_limbs = input_elements.z_high_limbs;
auto& quotient_low_binary_limbs = input_elements.quotient_low_binary_limbs;
auto& quotient_high_binary_limbs = input_elements.quotient_high_binary_limbs;
auto& p_x_low_limbs_shift = input_elements.p_x_low_limbs_shift;
auto& p_y_low_limbs_shift = input_elements.p_y_low_limbs_shift;
auto& p_x_high_limbs_shift = input_elements.p_x_high_limbs_shift;
auto& p_y_high_limbs_shift = input_elements.p_y_high_limbs_shift;
auto& accumulators_binary_limbs_0_shift = input_elements.accumulators_binary_limbs_0_shift;
auto& accumulators_binary_limbs_1_shift = input_elements.accumulators_binary_limbs_1_shift;
auto& accumulators_binary_limbs_2_shift = input_elements.accumulators_binary_limbs_2_shift;
auto& accumulators_binary_limbs_3_shift = input_elements.accumulators_binary_limbs_3_shift;
auto& z_low_limbs_shift = input_elements.z_low_limbs_shift;
auto& z_high_limbs_shift = input_elements.z_high_limbs_shift;
auto& quotient_low_binary_limbs_shift = input_elements.quotient_low_binary_limbs_shift;
auto& quotient_high_binary_limbs_shift = input_elements.quotient_high_binary_limbs_shift;
auto& relation_wide_limbs = input_elements.relation_wide_limbs;
auto& relation_wide_limbs_shift = input_elements.relation_wide_limbs_shift;
auto& lagrange_odd = input_elements.lagrange_odd;

RelationValues expected_values;

const auto parameters = RelationParameters<FF>::get_random();

// A detailed description of these subrelations is located in the relation's documentation

// Lower wide limb (lower 136 bits) subrelation
expected_values[0] =
(accumulators_binary_limbs_0_shift * parameters.evaluation_input_x[0] + op +
p_x_low_limbs * parameters.batching_challenge_v[0][0] +
p_y_low_limbs * parameters.batching_challenge_v[1][0] +
z_low_limbs * parameters.batching_challenge_v[2][0] +
z_low_limbs_shift * parameters.batching_challenge_v[3][0] +
quotient_low_binary_limbs * NEGATIVE_MODULUS_LIMBS[0] - accumulators_binary_limbs_0 +
(accumulators_binary_limbs_1_shift * parameters.evaluation_input_x[0] +
accumulators_binary_limbs_0_shift * parameters.evaluation_input_x[1] +
p_x_low_limbs * parameters.batching_challenge_v[0][1] +
p_x_low_limbs_shift * parameters.batching_challenge_v[0][0] +
p_y_low_limbs * parameters.batching_challenge_v[1][1] +
p_y_low_limbs_shift * parameters.batching_challenge_v[1][0] +
z_low_limbs * parameters.batching_challenge_v[2][1] +
z_high_limbs * parameters.batching_challenge_v[2][0] +
z_low_limbs_shift * parameters.batching_challenge_v[3][1] +
z_high_limbs_shift * parameters.batching_challenge_v[3][0] +
quotient_low_binary_limbs * NEGATIVE_MODULUS_LIMBS[1] +
quotient_low_binary_limbs_shift * NEGATIVE_MODULUS_LIMBS[0] - accumulators_binary_limbs_1) *
shift -
relation_wide_limbs * shiftx2) *
lagrange_odd;

// Higher wide limb subrelation
expected_values[1] =
(relation_wide_limbs + accumulators_binary_limbs_2_shift * parameters.evaluation_input_x[0] +
accumulators_binary_limbs_1_shift * parameters.evaluation_input_x[1] +
accumulators_binary_limbs_0_shift * parameters.evaluation_input_x[2] +
p_x_high_limbs * parameters.batching_challenge_v[0][0] +
p_x_low_limbs_shift * parameters.batching_challenge_v[0][1] +
p_x_low_limbs * parameters.batching_challenge_v[0][2] +
p_y_high_limbs * parameters.batching_challenge_v[1][0] +
p_y_low_limbs_shift * parameters.batching_challenge_v[1][1] +
p_y_low_limbs * parameters.batching_challenge_v[1][2] +
z_high_limbs * parameters.batching_challenge_v[2][1] +
z_low_limbs * parameters.batching_challenge_v[2][2] +
z_high_limbs_shift * parameters.batching_challenge_v[3][1] +
z_low_limbs_shift * parameters.batching_challenge_v[3][2] +
quotient_high_binary_limbs * NEGATIVE_MODULUS_LIMBS[0] +
quotient_low_binary_limbs_shift * NEGATIVE_MODULUS_LIMBS[1] +
quotient_low_binary_limbs * NEGATIVE_MODULUS_LIMBS[2] - accumulators_binary_limbs_2 +
(accumulators_binary_limbs_3_shift * parameters.evaluation_input_x[0] +
accumulators_binary_limbs_2_shift * parameters.evaluation_input_x[1] +
accumulators_binary_limbs_1_shift * parameters.evaluation_input_x[2] +
accumulators_binary_limbs_0_shift * parameters.evaluation_input_x[3] +
p_x_high_limbs_shift * parameters.batching_challenge_v[0][0] +
p_x_high_limbs * parameters.batching_challenge_v[0][1] +
p_x_low_limbs_shift * parameters.batching_challenge_v[0][2] +
p_x_low_limbs * parameters.batching_challenge_v[0][3] +
p_y_high_limbs_shift * parameters.batching_challenge_v[1][0] +
p_y_high_limbs * parameters.batching_challenge_v[1][1] +
p_y_low_limbs_shift * parameters.batching_challenge_v[1][2] +
p_y_low_limbs * parameters.batching_challenge_v[1][3] +
z_high_limbs * parameters.batching_challenge_v[2][2] +
z_low_limbs * parameters.batching_challenge_v[2][3] +
z_high_limbs_shift * parameters.batching_challenge_v[3][2] +
z_low_limbs_shift * parameters.batching_challenge_v[3][3] +
quotient_high_binary_limbs_shift * NEGATIVE_MODULUS_LIMBS[0] +
quotient_high_binary_limbs * NEGATIVE_MODULUS_LIMBS[1] +
quotient_low_binary_limbs_shift * NEGATIVE_MODULUS_LIMBS[2] +
quotient_low_binary_limbs * NEGATIVE_MODULUS_LIMBS[3] - accumulators_binary_limbs_3) *
shift -
relation_wide_limbs_shift * shiftx2) *
lagrange_odd;
auto reconstructed_p_x =
(p_x_low_limbs + p_x_low_limbs_shift * shift + p_x_high_limbs * shiftx2 + p_x_high_limbs_shift * shiftx3);
auto reconstructed_p_y =
(p_y_low_limbs + p_y_low_limbs_shift * shift + p_y_high_limbs * shiftx2 + p_y_high_limbs_shift * shiftx3);
auto reconstructed_previous_accumulator =
(accumulators_binary_limbs_0_shift + accumulators_binary_limbs_1_shift * shift +
accumulators_binary_limbs_2_shift * shiftx2 + accumulators_binary_limbs_3_shift * shiftx3);
auto reconstructed_current_accumulator =
(accumulators_binary_limbs_0 + accumulators_binary_limbs_1 * shift + accumulators_binary_limbs_2 * shiftx2 +
accumulators_binary_limbs_3 * shiftx3);
auto reconstructed_z1 = (z_low_limbs + z_high_limbs * shift);
auto reconstructed_z2 = (z_low_limbs_shift + z_high_limbs_shift * shift);
auto reconstructed_quotient =
(quotient_low_binary_limbs + quotient_low_binary_limbs_shift * shift +
quotient_high_binary_limbs * shiftx2 + quotient_high_binary_limbs_shift * shiftx3);

// Native field relation
expected_values[2] = (reconstructed_previous_accumulator * parameters.evaluation_input_x[4] + op +
reconstructed_p_x * parameters.batching_challenge_v[0][4] +
reconstructed_p_y * parameters.batching_challenge_v[1][4] +
reconstructed_z1 * parameters.batching_challenge_v[2][4] +
reconstructed_z2 * parameters.batching_challenge_v[3][4] +
reconstructed_quotient * NEGATIVE_MODULUS_LIMBS[4] - reconstructed_current_accumulator) *
lagrange_odd;

validate_relation_execution<Relation>(expected_values, input_elements, parameters);
};
run_test(/*random_inputs=*/false);
run_test(/*random_inputs=*/true);
};

} // namespace proof_system::ultra_relation_consistency_tests
Loading

0 comments on commit c4d8d96

Please sign in to comment.