From 9321aef1a49eb33ea388838ba7b0c00dddd9c898 Mon Sep 17 00:00:00 2001 From: maramihali Date: Tue, 21 May 2024 14:21:41 +0100 Subject: [PATCH] feat: translator recursive verifier (#6327) First iteration of the translator recursive verifier as a standalone component, arithmetised with either vanilla Ultra, Goblin Ultra or simulator. This required refactoring the translator relations so their `field_t` instantiation is only used in the recursive verifier. For now, we work around the fact that the transcript should be shared between eccvm and translator which limits a bit the amount of testing we can do. These TODOs will be addressed after we have an ECCVM recursive verifier. --- .../cpp/scripts/analyze_client_ivc_bench.py | 2 +- barretenberg/cpp/src/CMakeLists.txt | 2 + .../benchmark/goblin_bench/goblin.bench.cpp | 4 +- .../relations_bench/relations.bench.cpp | 14 +- .../zeromorph/zeromorph.hpp | 8 +- .../src/barretenberg/eccvm/eccvm_flavor.hpp | 3 +- .../src/barretenberg/eccvm/eccvm_prover.hpp | 5 +- .../cpp/src/barretenberg/flavor/flavor.hpp | 4 +- .../flavor/relation_definitions.hpp | 5 +- .../cpp/src/barretenberg/goblin/goblin.hpp | 17 +- .../goblin/translation_evaluations.hpp | 20 +- .../honk/proof_system/permutation_library.hpp | 12 +- .../arithmetization/arithmetization.hpp | 2 +- .../relations/relation_parameters.hpp | 6 +- .../translator_decomposition_relation.cpp | 626 +----------------- .../translator_decomposition_relation.hpp | 5 +- ...translator_decomposition_relation_impl.hpp | 618 +++++++++++++++++ ...slator_delta_range_constraint_relation.cpp | 136 +--- ...slator_delta_range_constraint_relation.hpp | 4 +- ...r_delta_range_constraint_relation_impl.hpp | 128 ++++ .../translator_extra_relations.cpp | 160 +---- .../translator_extra_relations.hpp | 9 +- .../translator_extra_relations_impl.hpp | 148 +++++ .../translator_non_native_field_relation.cpp | 287 +------- .../translator_non_native_field_relation.hpp | 9 +- ...nslator_non_native_field_relation_impl.hpp | 279 ++++++++ .../translator_permutation_relation.cpp | 69 +- .../translator_permutation_relation.hpp | 5 +- .../translator_permutation_relation_impl.hpp | 61 ++ ... translator_relation_consistency.test.cpp} | 32 +- .../cpp/src/barretenberg/relations/utils.hpp | 3 - .../primitives/field/field_conversion.cpp | 3 + .../goblin_ultra_recursive_flavor.hpp | 1 - .../ultra_recursive_flavor.hpp | 1 - .../goblin_translator_verifier.cpp | 302 --------- .../relation_correctness.test.cpp | 40 +- ...lator.fuzzer.hpp => translator.fuzzer.hpp} | 4 +- ..._composer.test.cpp => translator.test.cpp} | 18 +- ...der.cpp => translator_circuit_builder.cpp} | 95 ++- ... => translator_circuit_builder.fuzzer.cpp} | 4 +- ...der.hpp => translator_circuit_builder.hpp} | 68 +- ...pp => translator_circuit_builder.test.cpp} | 16 +- ...zer.cpp => translator_composer.fuzzer.cpp} | 16 +- ...lator_flavor.hpp => translator_flavor.hpp} | 72 +- ....fuzzer.cpp => translator_mini.fuzzer.cpp} | 8 +- ...lator_prover.cpp => translator_prover.cpp} | 29 +- ...lator_prover.hpp => translator_prover.hpp} | 10 +- .../translator_vm/translator_verifier.cpp | 161 +++++ ...r_verifier.hpp => translator_verifier.hpp} | 19 +- .../translator_vm_recursion/CMakeLists.txt | 1 + .../translator_decomposition_relation.cpp | 13 + ...slator_delta_range_constraint_relation.cpp | 12 + .../translator_extra_relations.cpp | 19 + .../translator_non_native_field_relation.cpp | 13 + .../translator_permutation_relation.cpp | 12 + .../translator_recursive_flavor.hpp | 155 +++++ .../translator_recursive_verifier.cpp | 166 +++++ .../translator_recursive_verifier.hpp | 50 ++ .../translator_recursive_verifier.test.cpp | 135 ++++ 59 files changed, 2287 insertions(+), 1839 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_decomposition_relation_impl.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation_impl.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_extra_relations_impl.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation_impl.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation_impl.hpp rename barretenberg/cpp/src/barretenberg/relations/translator_vm/{goblin_translator_relation_consistency.test.cpp => translator_relation_consistency.test.cpp} (98%) delete mode 100644 barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.cpp rename barretenberg/cpp/src/barretenberg/translator_vm/{goblin_translator.fuzzer.hpp => translator.fuzzer.hpp} (97%) rename barretenberg/cpp/src/barretenberg/translator_vm/{goblin_translator_composer.test.cpp => translator.test.cpp} (80%) rename barretenberg/cpp/src/barretenberg/translator_vm/{goblin_translator_circuit_builder.cpp => translator_circuit_builder.cpp} (94%) rename barretenberg/cpp/src/barretenberg/translator_vm/{goblin_translator_circuit_builder.fuzzer.cpp => translator_circuit_builder.fuzzer.cpp} (92%) rename barretenberg/cpp/src/barretenberg/translator_vm/{goblin_translator_circuit_builder.hpp => translator_circuit_builder.hpp} (89%) rename barretenberg/cpp/src/barretenberg/translator_vm/{goblin_translator_circuit_builder.test.cpp => translator_circuit_builder.test.cpp} (87%) rename barretenberg/cpp/src/barretenberg/translator_vm/{goblin_translator_composer.fuzzer.cpp => translator_composer.fuzzer.cpp} (65%) rename barretenberg/cpp/src/barretenberg/translator_vm/{goblin_translator_flavor.hpp => translator_flavor.hpp} (96%) rename barretenberg/cpp/src/barretenberg/translator_vm/{goblin_translator_mini.fuzzer.cpp => translator_mini.fuzzer.cpp} (84%) rename barretenberg/cpp/src/barretenberg/translator_vm/{goblin_translator_prover.cpp => translator_prover.cpp} (88%) rename barretenberg/cpp/src/barretenberg/translator_vm/{goblin_translator_prover.hpp => translator_prover.hpp} (86%) create mode 100644 barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.cpp rename barretenberg/cpp/src/barretenberg/translator_vm/{goblin_translator_verifier.hpp => translator_verifier.hpp} (60%) create mode 100644 barretenberg/cpp/src/barretenberg/translator_vm_recursion/CMakeLists.txt create mode 100644 barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_decomposition_relation.cpp create mode 100644 barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_delta_range_constraint_relation.cpp create mode 100644 barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_extra_relations.cpp create mode 100644 barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_non_native_field_relation.cpp create mode 100644 barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_permutation_relation.cpp create mode 100644 barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_recursive_flavor.hpp create mode 100644 barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_recursive_verifier.cpp create mode 100644 barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_recursive_verifier.hpp create mode 100644 barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_recursive_verifier.test.cpp diff --git a/barretenberg/cpp/scripts/analyze_client_ivc_bench.py b/barretenberg/cpp/scripts/analyze_client_ivc_bench.py index 07809f1f1cc..0c1911f0ae3 100644 --- a/barretenberg/cpp/scripts/analyze_client_ivc_bench.py +++ b/barretenberg/cpp/scripts/analyze_client_ivc_bench.py @@ -13,7 +13,7 @@ "Decider::construct_proof(t)", "ECCVMProver(CircuitBuilder&)(t)", "ECCVMProver::construct_proof(t)", - "GoblinTranslatorProver::construct_proof(t)", + "TranslatorProver::construct_proof(t)", "Goblin::merge(t)" ] with open(PREFIX/IVC_BENCH_JSON, "r") as read_file: diff --git a/barretenberg/cpp/src/CMakeLists.txt b/barretenberg/cpp/src/CMakeLists.txt index a9809f12c61..09ab2820dee 100644 --- a/barretenberg/cpp/src/CMakeLists.txt +++ b/barretenberg/cpp/src/CMakeLists.txt @@ -82,6 +82,7 @@ add_subdirectory(barretenberg/stdlib_circuit_builders) add_subdirectory(barretenberg/sumcheck) add_subdirectory(barretenberg/transcript) add_subdirectory(barretenberg/translator_vm) +add_subdirectory(barretenberg/translator_vm_recursion) add_subdirectory(barretenberg/ultra_honk) add_subdirectory(barretenberg/vm) add_subdirectory(barretenberg/wasi) @@ -146,6 +147,7 @@ set(BARRETENBERG_TARGET_OBJECTS $ $ $ + $ $ $) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/goblin_bench/goblin.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/goblin_bench/goblin.bench.cpp index 95bce45dcac..c79d5837bf1 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/goblin_bench/goblin.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/goblin_bench/goblin.bench.cpp @@ -109,7 +109,7 @@ BENCHMARK_DEFINE_F(GoblinBench, GoblinECCVMProve)(benchmark::State& state) * @brief Benchmark only the Translator component * */ -BENCHMARK_DEFINE_F(GoblinBench, GoblinTranslatorProve)(benchmark::State& state) +BENCHMARK_DEFINE_F(GoblinBench, TranslatorProve)(benchmark::State& state) { Goblin goblin; @@ -136,7 +136,7 @@ BENCHMARK_DEFINE_F(GoblinBench, GoblinTranslatorProve)(benchmark::State& state) BENCHMARK_REGISTER_F(GoblinBench, GoblinFull)->Unit(benchmark::kMillisecond)->ARGS; BENCHMARK_REGISTER_F(GoblinBench, GoblinAccumulate)->Unit(benchmark::kMillisecond)->ARGS; BENCHMARK_REGISTER_F(GoblinBench, GoblinECCVMProve)->Unit(benchmark::kMillisecond)->ARGS; -BENCHMARK_REGISTER_F(GoblinBench, GoblinTranslatorProve)->Unit(benchmark::kMillisecond)->ARGS; +BENCHMARK_REGISTER_F(GoblinBench, TranslatorProve)->Unit(benchmark::kMillisecond)->ARGS; } // namespace diff --git a/barretenberg/cpp/src/barretenberg/benchmark/relations_bench/relations.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/relations_bench/relations.bench.cpp index af040b8da4b..0ad1bcc8490 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/relations_bench/relations.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/relations_bench/relations.bench.cpp @@ -2,7 +2,7 @@ #include "barretenberg/protogalaxy/protogalaxy_prover.hpp" #include "barretenberg/stdlib_circuit_builders/goblin_ultra_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp" -#include "barretenberg/translator_vm/goblin_translator_flavor.hpp" +#include "barretenberg/translator_vm/translator_flavor.hpp" #include namespace { @@ -103,12 +103,12 @@ BENCHMARK(execute_relation_for_values>); // Translator VM -BENCHMARK(execute_relation_for_values>); -BENCHMARK(execute_relation_for_values>); -BENCHMARK(execute_relation_for_values>); -BENCHMARK(execute_relation_for_values>); -BENCHMARK(execute_relation_for_values>); -BENCHMARK(execute_relation_for_values>); +BENCHMARK(execute_relation_for_values>); +BENCHMARK(execute_relation_for_values>); +BENCHMARK(execute_relation_for_values>); +BENCHMARK(execute_relation_for_values>); +BENCHMARK(execute_relation_for_values>); +BENCHMARK(execute_relation_for_values>); // ECCVM BENCHMARK(execute_relation_for_values>); diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp index 53c52675952..b46575ef086 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp @@ -198,7 +198,7 @@ template class ZeroMorphProver_ { * * and concatenation_term = \sum_{i=0}^{num_chunks_per_group}(x^{i * min_N + 1}concatenation_groups_batched_{i}) * - * @note The concatenation term arises from an implementation detail in the Goblin Translator and is not part of the + * @note The concatenation term arises from an implementation detail in the Translator and is not part of the * conventional ZM protocol * @param input_polynomial * @param quotients @@ -250,7 +250,7 @@ template class ZeroMorphProver_ { // If necessary, add to Z_x the contribution related to concatenated polynomials: // \sum_{i=0}^{num_chunks_per_group}(x^{i * min_n + 1}concatenation_groups_batched_{i}). // We are effectively reconstructing concatenated polynomials from their chunks now that we know x - // Note: this is an implementation detail related to Goblin Translator and is not part of the standard protocol. + // Note: this is an implementation detail related to Translator and is not part of the standard protocol. if (!concatenation_groups_batched.empty()) { size_t MINICIRCUIT_N = N / concatenation_groups_batched.size(); auto x_to_minicircuit_N = @@ -507,7 +507,7 @@ template class ZeroMorphVerifier_ { * concatenation_term = \sum{i=0}^{o-1}\sum_{j=0}^{num_chunks_per_group}(rho^{m+l+i} * x^{j * min_N + 1} * * concatenation_groups_commitments_{i}_{j}) * - * @note The concatenation term arises from an implementation detail in the Goblin Translator and is not part of the + * @note The concatenation term arises from an implementation detail in the Translator and is not part of the * conventional ZM protocol * @param first_g1 first element in the SRS * @param f_commitments Commitments to unshifted polynomials [f_i] @@ -565,7 +565,7 @@ template class ZeroMorphVerifier_ { } // If applicable, add contribution from concatenated polynomial commitments - // Note: this is an implementation detail related to Goblin Translator and is not part of the standard protocol. + // Note: this is an implementation detail related to Translator and is not part of the standard protocol. if (!concatenation_groups_commitments.empty()) { size_t CONCATENATION_GROUP_SIZE = concatenation_groups_commitments[0].size(); size_t MINICIRCUIT_N = N / CONCATENATION_GROUP_SIZE; diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp index 759353edb0a..5f53b7e1784 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp @@ -27,7 +27,8 @@ class ECCVMFlavor { using Curve = curve::Grumpkin; using G1 = typename Curve::Group; using PCS = IPA; - using FF = typename G1::subgroup_field; + using FF = typename Curve::ScalarField; + using BF = typename Curve::BaseField; using Polynomial = bb::Polynomial; using GroupElement = typename G1::element; using Commitment = typename G1::affine_element; diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.hpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.hpp index 24c6349d20e..c6661069473 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.hpp @@ -13,19 +13,20 @@ namespace bb { // We won't compile this class with Standard, but we will like want to compile it (at least for testing) // with a flavor that uses the curve Grumpkin, or a flavor that does/does not have zk, etc. class ECCVMProver { + public: using Flavor = ECCVMFlavor; using FF = typename Flavor::FF; + using BF = typename Flavor::BF; using PCS = typename Flavor::PCS; using CommitmentKey = typename Flavor::CommitmentKey; using ProvingKey = typename Flavor::ProvingKey; using Polynomial = typename Flavor::Polynomial; using CommitmentLabels = typename Flavor::CommitmentLabels; using Transcript = typename Flavor::Transcript; - using TranslationEvaluations = bb::TranslationEvaluations; + using TranslationEvaluations = bb::TranslationEvaluations_; using ZeroMorph = ZeroMorphProver_; using CircuitBuilder = typename Flavor::CircuitBuilder; - public: explicit ECCVMProver(CircuitBuilder& builder, const std::shared_ptr& transcript = std::make_shared()); diff --git a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp index b3be9e6483f..b283ecf806c 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp @@ -310,8 +310,10 @@ namespace bb { class UltraFlavor; class ECCVMFlavor; class GoblinUltraFlavor; +class TranslatorFlavor; template class UltraRecursiveFlavor_; template class GoblinUltraRecursiveFlavor_; +template class TranslatorRecursiveFlavor_; } // namespace bb // Forward declare plonk flavors @@ -356,7 +358,7 @@ concept IsRecursiveFlavor = IsAnyOf, GoblinUltraRecursiveFlavor_, GoblinUltraRecursiveFlavor_ -,GoblinUltraRecursiveFlavor_>; +,GoblinUltraRecursiveFlavor_, TranslatorRecursiveFlavor_, TranslatorRecursiveFlavor_, TranslatorRecursiveFlavor_>; template concept IsGrumpkinFlavor = IsAnyOf; diff --git a/barretenberg/cpp/src/barretenberg/flavor/relation_definitions.hpp b/barretenberg/cpp/src/barretenberg/flavor/relation_definitions.hpp index 0b1fed6342e..dbfd02da9fc 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/relation_definitions.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/relation_definitions.hpp @@ -23,13 +23,14 @@ RelationImpl::MethodName>::AccumulatorType, EdgeType(Flavor)>( \ EdgeType(Flavor) const&, RelationParameters const&); -#define SUMCHECK_RELATION_CLASS(...) _SUMCHECK_RELATION_CLASS(__VA_ARGS__) #define DEFINE_SUMCHECK_RELATION_CLASS(RelationImpl, Flavor) \ ACCUMULATE(RelationImpl, Flavor, SumcheckTupleOfUnivariatesOverSubrelations, ExtendedEdge) \ ACCUMULATE(RelationImpl, Flavor, SumcheckArrayOfValuesOverSubrelations, EvaluationEdge) \ ACCUMULATE(RelationImpl, Flavor, SumcheckArrayOfValuesOverSubrelations, EntityEdge) -#define SUMCHECK_PERMUTATION_CLASS(...) _SUMCHECK_PERMUTATION_CLASS(__VA_ARGS__) +#define DEFINE_SUMCHECK_VERIFIER_RELATION_CLASS(RelationImpl, Flavor) \ + ACCUMULATE(RelationImpl, Flavor, SumcheckArrayOfValuesOverSubrelations, EvaluationEdge) + #define DEFINE_SUMCHECK_PERMUTATION_CLASS(RelationImpl, Flavor) \ PERMUTATION_METHOD(compute_grand_product_numerator, RelationImpl, Flavor, UnivariateAccumulator0, ExtendedEdge) \ PERMUTATION_METHOD(compute_grand_product_numerator, RelationImpl, Flavor, ValueAccumulator0, EvaluationEdge) \ diff --git a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp index 3823a510059..7cfc5406801 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp @@ -8,9 +8,9 @@ #include "barretenberg/stdlib/honk_recursion/verifier/merge_recursive_verifier.hpp" #include "barretenberg/stdlib_circuit_builders/goblin_ultra_circuit_builder.hpp" #include "barretenberg/stdlib_circuit_builders/goblin_ultra_flavor.hpp" -#include "barretenberg/translator_vm/goblin_translator_circuit_builder.hpp" -#include "barretenberg/translator_vm/goblin_translator_prover.hpp" -#include "barretenberg/translator_vm/goblin_translator_verifier.hpp" +#include "barretenberg/translator_vm/translator_circuit_builder.hpp" +#include "barretenberg/translator_vm/translator_prover.hpp" +#include "barretenberg/translator_vm/translator_verifier.hpp" #include "barretenberg/ultra_honk/merge_prover.hpp" #include "barretenberg/ultra_honk/merge_verifier.hpp" #include "barretenberg/ultra_honk/ultra_prover.hpp" @@ -32,8 +32,9 @@ class Goblin { using ECCVMFlavor = bb::ECCVMFlavor; using ECCVMBuilder = bb::ECCVMCircuitBuilder; using ECCVMProver = bb::ECCVMProver; - using TranslatorBuilder = bb::GoblinTranslatorCircuitBuilder; - using TranslatorProver = bb::GoblinTranslatorProver; + using TranslationEvaluations = ECCVMProver::TranslationEvaluations; + using TranslatorBuilder = bb::TranslatorCircuitBuilder; + using TranslatorProver = bb::TranslatorProver; using RecursiveMergeVerifier = bb::stdlib::recursion::goblin::MergeRecursiveVerifier_; using MergeProver = bb::MergeProver_; using MergeVerifier = bb::MergeVerifier_; @@ -175,7 +176,7 @@ class Goblin { { translator_builder = std::make_unique( eccvm_prover->translation_batching_challenge_v, eccvm_prover->evaluation_challenge_x, op_queue); - translator_prover = std::make_unique(*translator_builder, eccvm_prover->transcript); + translator_prover = std::make_unique(*translator_builder, eccvm_prover->transcript); goblin_proof.translator_proof = translator_prover->construct_proof(); }; @@ -209,7 +210,7 @@ class Goblin { ECCVMVerifier eccvm_verifier(eccvm_prover->key); bool eccvm_verified = eccvm_verifier.verify_proof(proof.eccvm_proof); - GoblinTranslatorVerifier translator_verifier(translator_prover->key, eccvm_verifier.transcript); + TranslatorVerifier translator_verifier(translator_prover->key, eccvm_verifier.transcript); bool accumulator_construction_verified = translator_verifier.verify_proof(proof.translator_proof); // TODO(https://github.com/AztecProtocol/barretenberg/issues/799): Ensure translation_evaluations are passed @@ -296,7 +297,7 @@ class Goblin { ECCVMVerifier eccvm_verifier(eccvm_prover->key); bool eccvm_verified = eccvm_verifier.verify_proof(goblin_proof.eccvm_proof); - GoblinTranslatorVerifier translator_verifier(translator_prover->key, eccvm_verifier.transcript); + TranslatorVerifier translator_verifier(translator_prover->key, eccvm_verifier.transcript); bool translation_accumulator_construction_verified = translator_verifier.verify_proof(goblin_proof.translator_proof); diff --git a/barretenberg/cpp/src/barretenberg/goblin/translation_evaluations.hpp b/barretenberg/cpp/src/barretenberg/goblin/translation_evaluations.hpp index 5495504296d..fb16372f308 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/translation_evaluations.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/translation_evaluations.hpp @@ -3,16 +3,22 @@ #include "barretenberg/ecc/fields/field_conversion.hpp" namespace bb { -struct TranslationEvaluations { - fq op, Px, Py, z1, z2; +/** + * @brief Stores the evaluations from ECCVM, checked against the translator evaluations as a final step of translator. + * + * @tparam BF The base field of the curve, translation evaluations are represented in the base field. + * @tparam FF The scalar field of the curve, used in Goblin to help convert the proof into a buffer for ACIR. + */ +template struct TranslationEvaluations_ { + BF op, Px, Py, z1, z2; static constexpr uint32_t NUM_EVALUATIONS = 5; - static size_t size() { return field_conversion::calc_num_bn254_frs() * NUM_EVALUATIONS; } - std::vector to_buffer() const + static size_t size() { return field_conversion::calc_num_bn254_frs() * NUM_EVALUATIONS; } + std::vector to_buffer() const { - std::vector result; + std::vector result; result.reserve(size()); - const auto insert = [&result](const fq& elt) { - std::vector buf = field_conversion::convert_to_bn254_frs(elt); + const auto insert = [&result](const BF& elt) { + std::vector buf = field_conversion::convert_to_bn254_frs(elt); result.insert(result.end(), buf.begin(), buf.end()); }; insert(op); diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp index bf2f8b5274e..e42d5e41d98 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp @@ -14,7 +14,7 @@ namespace bb { * commitments. This method creates concatenated version of polynomials we won't need to commit to. Used in Goblin * Translator * - * Concatenation in Goblin Translator mean the action of constructing a new Polynomial from existing ones by writing + * Concatenation in Translator mean the action of constructing a new Polynomial from existing ones by writing * their multilinear representations sequentially. For example, if we have f(x₁,x₂)={0, 1, 0, 1} and * g(x₁,x₂)={1, 0, 0, 1} then h(x₁ ,x₂ ,x₃ )=concatenation(f(x₁,x₂),g(x₁,x₂))={0, 1, 0, 1, 1, 0, 0, 1} * @@ -37,7 +37,7 @@ template void compute_concatenated_polynomials(typename Flavor ASSERT(MINI_CIRCUIT_SIZE * Flavor::CONCATENATION_GROUP_SIZE == targets[0].size()); // A function that produces 1 concatenated polynomial - // Goblin Translator uses concatenated polynomials in the permutation argument. These polynomials contain the same + // Translator uses concatenated polynomials in the permutation argument. These polynomials contain the same // coefficients as other shorter polynomials, but we don't have to commit to them due to reusing commitments of // shorter polynomials and updating our PCS to open using them. But the prover still needs the concatenated // polynomials. This function constructs a chunk of the polynomial. @@ -60,13 +60,13 @@ template void compute_concatenated_polynomials(typename Flavor } /** - * @brief Compute denominator polynomials for Goblin Translator's range constraint permutation + * @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 concatenated wires, each of which represents a subset * or original wires (concatenated_range_constraints_). We also generate several new polynomials of the same length * as concatenated ones. These polynomials have values within range, but they are also constrained by the - * GoblinTranslatorFlavor's DeltaRangeConstraint relation, which ensures that sequential values differ by not more than + * 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). * @@ -82,8 +82,8 @@ template void compute_concatenated_polynomials(typename Flavor * @param proving_key */ template -void compute_goblin_translator_range_constraint_ordered_polynomials(typename Flavor::ProverPolynomials& polynomials, - size_t mini_circuit_dyadic_size) +void compute_translator_range_constraint_ordered_polynomials(typename Flavor::ProverPolynomials& polynomials, + size_t mini_circuit_dyadic_size) { using FF = typename Flavor::FF; diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/arithmetization.hpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/arithmetization.hpp index f71b77021ee..7477343ec1e 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/arithmetization.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/arithmetization/arithmetization.hpp @@ -389,7 +389,7 @@ template class UltraHonkArith { inline static const std::vector selector_names = {}; }; -class GoblinTranslatorArith { +class TranslatorArith { public: static constexpr size_t NUM_WIRES = 81; static constexpr size_t NUM_SELECTORS = 0; diff --git a/barretenberg/cpp/src/barretenberg/relations/relation_parameters.hpp b/barretenberg/cpp/src/barretenberg/relations/relation_parameters.hpp index 70573ad8626..1c312b09b3f 100644 --- a/barretenberg/cpp/src/barretenberg/relations/relation_parameters.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/relation_parameters.hpp @@ -27,12 +27,10 @@ template struct RelationParameters { // eccvm_set_permutation_delta is used in the set membership gadget in eccvm/ecc_set_relation.hpp // We can remove this by modifying the relation, but increases complexity T eccvm_set_permutation_delta = T(0); - std::array accumulated_result = { - T(0), T(0), T(0), T(0) - }; // Goblin Translator + std::array accumulated_result = { T(0), T(0), T(0), T(0) }; // Translator std::array evaluation_input_x = { T(0), T(0), T(0), T(0), T(0) - }; // Goblin Translator + }; // Translator std::array, NUM_CHALLENGE_POWERS_IN_GOBLIN_TRANSLATOR> batching_challenge_v = { { { T(0), T(0), T(0), T(0), T(0) }, diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_decomposition_relation.cpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_decomposition_relation.cpp index 7c097207fb3..5fe72e975bd 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_decomposition_relation.cpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_decomposition_relation.cpp @@ -1,622 +1,6 @@ -#include "barretenberg/relations/translator_vm/translator_decomposition_relation.hpp" -#include "barretenberg/translator_vm/goblin_translator_flavor.hpp" - +#include "barretenberg/relations/translator_vm/translator_decomposition_relation_impl.hpp" +#include "barretenberg/translator_vm/translator_flavor.hpp" namespace bb { - -/** - * @brief Expression for decomposition of various values into smaller limbs or microlimbs. - * @details This relation enforces three types of subrelations: - * 1) A subrelation decomposing a value from the transcript (for example, z1) into 68-bit limbs. These relations - * will have the structure `lagrange_odd_in_minicircuit⋅(a - a_low - a_high⋅2⁶⁸)` - * 2) A subrelation decomposing a value of one of the limbs used in bigfield computation (for example, the lower - * wide relation limb) into 14-bit limbs. These relations will have the structure `lagrange_odd_in_minicircuit⋅(a - - * a_0 - a_1⋅2¹⁴ - - * ....)` 3) A subrelation making a microlimb range constraint more constraining. For example, we want to constrain - * some values to 12 bits instead of 14. So we add a constraint `lagrange_odd_in_minicircuit⋅(a_highest⋅4 - - * a_tail)`. In a separate relation both a_highest and a_tail are constrained to be 14 bits, but this relation - * changes the constraint on a_highest to be 12 bits. - * - * @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, .... - * @param scaling_factor optional term to scale the evaluation before adding to evals. - */ -template -template -void GoblinTranslatorDecompositionRelationImpl::accumulate(ContainerOverSubrelations& accumulators, - const AllEntities& in, - const Parameters&, - const FF& scaling_factor) -{ - static constexpr size_t NUM_LIMB_BITS = 68; // Number of bits in a standard limb used for bigfield operations - static constexpr size_t NUM_MICRO_LIMB_BITS = 14; // Number of bits in a standard limb used for bigfield operations - - // Value to multiply an element by to perform an appropriate shift - static constexpr auto LIMB_SHIFT = FF(uint256_t(1) << NUM_LIMB_BITS); - - // Values to multiply an element by to perform an appropriate shift - static constexpr auto MICRO_LIMB_SHIFT = FF(uint256_t(1) << NUM_MICRO_LIMB_BITS); - static constexpr auto MICRO_LIMB_SHIFTx2 = MICRO_LIMB_SHIFT * MICRO_LIMB_SHIFT; - static constexpr auto MICRO_LIMB_SHIFTx3 = MICRO_LIMB_SHIFTx2 * MICRO_LIMB_SHIFT; - static constexpr auto MICRO_LIMB_SHIFTx4 = MICRO_LIMB_SHIFTx3 * MICRO_LIMB_SHIFT; - static constexpr auto MICRO_LIMB_SHIFTx5 = MICRO_LIMB_SHIFTx4 * MICRO_LIMB_SHIFT; - - // Shifts used to constrain ranges further - static constexpr auto SHIFT_12_TO_14 = - FF(4); // Shift used to range constrain the last microlimb of 68-bit limbs (standard limbs) - static constexpr auto SHIFT_10_TO_14 = - FF(16); // Shift used to range constrain the last microlimb of 52-bit limb (top quotient limb) - static constexpr auto SHIFT_8_TO_14 = FF(64); // Shift used to range constrain the last microlimb of 50-bit - // limbs (top limb of standard 254-bit value) - static constexpr auto SHIFT_4_TO_14 = - FF(1024); // Shift used to range constrain the last mircrolimb of 60-bit limbs from z scalars - - using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; - using View = typename Accumulator::View; - - auto p_x_low_limbs = View(in.p_x_low_limbs); - auto p_x_low_limbs_range_constraint_0 = View(in.p_x_low_limbs_range_constraint_0); - auto p_x_low_limbs_range_constraint_1 = View(in.p_x_low_limbs_range_constraint_1); - auto p_x_low_limbs_range_constraint_2 = View(in.p_x_low_limbs_range_constraint_2); - auto p_x_low_limbs_range_constraint_3 = View(in.p_x_low_limbs_range_constraint_3); - auto p_x_low_limbs_range_constraint_4 = View(in.p_x_low_limbs_range_constraint_4); - auto p_x_low_limbs_shift = View(in.p_x_low_limbs_shift); - auto p_x_low_limbs_range_constraint_0_shift = View(in.p_x_low_limbs_range_constraint_0_shift); - auto p_x_low_limbs_range_constraint_1_shift = View(in.p_x_low_limbs_range_constraint_1_shift); - auto p_x_low_limbs_range_constraint_2_shift = View(in.p_x_low_limbs_range_constraint_2_shift); - auto p_x_low_limbs_range_constraint_3_shift = View(in.p_x_low_limbs_range_constraint_3_shift); - auto p_x_low_limbs_range_constraint_4_shift = View(in.p_x_low_limbs_range_constraint_4_shift); - auto p_x_high_limbs = View(in.p_x_high_limbs); - auto p_x_high_limbs_range_constraint_0 = View(in.p_x_high_limbs_range_constraint_0); - auto p_x_high_limbs_range_constraint_1 = View(in.p_x_high_limbs_range_constraint_1); - auto p_x_high_limbs_range_constraint_2 = View(in.p_x_high_limbs_range_constraint_2); - auto p_x_high_limbs_range_constraint_3 = View(in.p_x_high_limbs_range_constraint_3); - auto p_x_high_limbs_range_constraint_4 = View(in.p_x_high_limbs_range_constraint_4); - auto p_x_high_limbs_shift = View(in.p_x_high_limbs_shift); - auto p_x_high_limbs_range_constraint_0_shift = View(in.p_x_high_limbs_range_constraint_0_shift); - auto p_x_high_limbs_range_constraint_1_shift = View(in.p_x_high_limbs_range_constraint_1_shift); - auto p_x_high_limbs_range_constraint_2_shift = View(in.p_x_high_limbs_range_constraint_2_shift); - auto p_x_high_limbs_range_constraint_3_shift = View(in.p_x_high_limbs_range_constraint_3_shift); - auto p_y_low_limbs = View(in.p_y_low_limbs); - auto p_y_low_limbs_range_constraint_0 = View(in.p_y_low_limbs_range_constraint_0); - auto p_y_low_limbs_range_constraint_1 = View(in.p_y_low_limbs_range_constraint_1); - auto p_y_low_limbs_range_constraint_2 = View(in.p_y_low_limbs_range_constraint_2); - auto p_y_low_limbs_range_constraint_3 = View(in.p_y_low_limbs_range_constraint_3); - auto p_y_low_limbs_range_constraint_4 = View(in.p_y_low_limbs_range_constraint_4); - auto p_y_low_limbs_shift = View(in.p_y_low_limbs_shift); - auto p_y_low_limbs_range_constraint_0_shift = View(in.p_y_low_limbs_range_constraint_0_shift); - auto p_y_low_limbs_range_constraint_1_shift = View(in.p_y_low_limbs_range_constraint_1_shift); - auto p_y_low_limbs_range_constraint_2_shift = View(in.p_y_low_limbs_range_constraint_2_shift); - auto p_y_low_limbs_range_constraint_3_shift = View(in.p_y_low_limbs_range_constraint_3_shift); - auto p_y_low_limbs_range_constraint_4_shift = View(in.p_y_low_limbs_range_constraint_4_shift); - auto p_y_high_limbs = View(in.p_y_high_limbs); - auto p_y_high_limbs_range_constraint_0 = View(in.p_y_high_limbs_range_constraint_0); - auto p_y_high_limbs_range_constraint_1 = View(in.p_y_high_limbs_range_constraint_1); - auto p_y_high_limbs_range_constraint_2 = View(in.p_y_high_limbs_range_constraint_2); - auto p_y_high_limbs_range_constraint_3 = View(in.p_y_high_limbs_range_constraint_3); - auto p_y_high_limbs_range_constraint_4 = View(in.p_y_high_limbs_range_constraint_4); - auto p_y_high_limbs_shift = View(in.p_y_high_limbs_shift); - auto p_y_high_limbs_range_constraint_0_shift = View(in.p_y_high_limbs_range_constraint_0_shift); - auto p_y_high_limbs_range_constraint_1_shift = View(in.p_y_high_limbs_range_constraint_1_shift); - auto p_y_high_limbs_range_constraint_2_shift = View(in.p_y_high_limbs_range_constraint_2_shift); - auto p_y_high_limbs_range_constraint_3_shift = View(in.p_y_high_limbs_range_constraint_3_shift); - auto z_low_limbs = View(in.z_low_limbs); - auto z_low_limbs_range_constraint_0 = View(in.z_low_limbs_range_constraint_0); - auto z_low_limbs_range_constraint_1 = View(in.z_low_limbs_range_constraint_1); - auto z_low_limbs_range_constraint_2 = View(in.z_low_limbs_range_constraint_2); - auto z_low_limbs_range_constraint_3 = View(in.z_low_limbs_range_constraint_3); - auto z_low_limbs_range_constraint_4 = View(in.z_low_limbs_range_constraint_4); - auto z_low_limbs_shift = View(in.z_low_limbs_shift); - auto z_low_limbs_range_constraint_0_shift = View(in.z_low_limbs_range_constraint_0_shift); - auto z_low_limbs_range_constraint_1_shift = View(in.z_low_limbs_range_constraint_1_shift); - auto z_low_limbs_range_constraint_2_shift = View(in.z_low_limbs_range_constraint_2_shift); - auto z_low_limbs_range_constraint_3_shift = View(in.z_low_limbs_range_constraint_3_shift); - auto z_low_limbs_range_constraint_4_shift = View(in.z_low_limbs_range_constraint_4_shift); - auto z_high_limbs = View(in.z_high_limbs); - auto z_high_limbs_range_constraint_0 = View(in.z_high_limbs_range_constraint_0); - auto z_high_limbs_range_constraint_1 = View(in.z_high_limbs_range_constraint_1); - auto z_high_limbs_range_constraint_2 = View(in.z_high_limbs_range_constraint_2); - auto z_high_limbs_range_constraint_3 = View(in.z_high_limbs_range_constraint_3); - auto z_high_limbs_range_constraint_4 = View(in.z_high_limbs_range_constraint_4); - auto z_high_limbs_shift = View(in.z_high_limbs_shift); - auto z_high_limbs_range_constraint_0_shift = View(in.z_high_limbs_range_constraint_0_shift); - auto z_high_limbs_range_constraint_1_shift = View(in.z_high_limbs_range_constraint_1_shift); - auto z_high_limbs_range_constraint_2_shift = View(in.z_high_limbs_range_constraint_2_shift); - auto z_high_limbs_range_constraint_3_shift = View(in.z_high_limbs_range_constraint_3_shift); - auto z_high_limbs_range_constraint_4_shift = View(in.z_high_limbs_range_constraint_4_shift); - auto accumulators_binary_limbs_0 = View(in.accumulators_binary_limbs_0); - auto accumulators_binary_limbs_1 = View(in.accumulators_binary_limbs_1); - auto accumulators_binary_limbs_2 = View(in.accumulators_binary_limbs_2); - auto accumulators_binary_limbs_3 = View(in.accumulators_binary_limbs_3); - auto accumulator_low_limbs_range_constraint_0 = View(in.accumulator_low_limbs_range_constraint_0); - auto accumulator_low_limbs_range_constraint_1 = View(in.accumulator_low_limbs_range_constraint_1); - auto accumulator_low_limbs_range_constraint_2 = View(in.accumulator_low_limbs_range_constraint_2); - auto accumulator_low_limbs_range_constraint_3 = View(in.accumulator_low_limbs_range_constraint_3); - auto accumulator_low_limbs_range_constraint_4 = View(in.accumulator_low_limbs_range_constraint_4); - auto accumulator_low_limbs_range_constraint_0_shift = View(in.accumulator_low_limbs_range_constraint_0_shift); - auto accumulator_low_limbs_range_constraint_1_shift = View(in.accumulator_low_limbs_range_constraint_1_shift); - auto accumulator_low_limbs_range_constraint_2_shift = View(in.accumulator_low_limbs_range_constraint_2_shift); - auto accumulator_low_limbs_range_constraint_3_shift = View(in.accumulator_low_limbs_range_constraint_3_shift); - auto accumulator_low_limbs_range_constraint_4_shift = View(in.accumulator_low_limbs_range_constraint_4_shift); - auto accumulator_high_limbs_range_constraint_0 = View(in.accumulator_high_limbs_range_constraint_0); - auto accumulator_high_limbs_range_constraint_1 = View(in.accumulator_high_limbs_range_constraint_1); - auto accumulator_high_limbs_range_constraint_2 = View(in.accumulator_high_limbs_range_constraint_2); - auto accumulator_high_limbs_range_constraint_3 = View(in.accumulator_high_limbs_range_constraint_3); - auto accumulator_high_limbs_range_constraint_4 = View(in.accumulator_high_limbs_range_constraint_4); - auto accumulator_high_limbs_range_constraint_0_shift = View(in.accumulator_high_limbs_range_constraint_0_shift); - auto accumulator_high_limbs_range_constraint_1_shift = View(in.accumulator_high_limbs_range_constraint_1_shift); - auto accumulator_high_limbs_range_constraint_2_shift = View(in.accumulator_high_limbs_range_constraint_2_shift); - auto accumulator_high_limbs_range_constraint_3_shift = View(in.accumulator_high_limbs_range_constraint_3_shift); - auto quotient_low_binary_limbs = View(in.quotient_low_binary_limbs); - auto quotient_low_limbs_range_constraint_0 = View(in.quotient_low_limbs_range_constraint_0); - auto quotient_low_limbs_range_constraint_1 = View(in.quotient_low_limbs_range_constraint_1); - auto quotient_low_limbs_range_constraint_2 = View(in.quotient_low_limbs_range_constraint_2); - auto quotient_low_limbs_range_constraint_3 = View(in.quotient_low_limbs_range_constraint_3); - auto quotient_low_limbs_range_constraint_4 = View(in.quotient_low_limbs_range_constraint_4); - auto quotient_low_binary_limbs_shift = View(in.quotient_low_binary_limbs_shift); - auto quotient_low_limbs_range_constraint_0_shift = View(in.quotient_low_limbs_range_constraint_0_shift); - auto quotient_low_limbs_range_constraint_1_shift = View(in.quotient_low_limbs_range_constraint_1_shift); - auto quotient_low_limbs_range_constraint_2_shift = View(in.quotient_low_limbs_range_constraint_2_shift); - auto quotient_low_limbs_range_constraint_3_shift = View(in.quotient_low_limbs_range_constraint_3_shift); - auto quotient_low_limbs_range_constraint_4_shift = View(in.quotient_low_limbs_range_constraint_4_shift); - auto quotient_high_binary_limbs = View(in.quotient_high_binary_limbs); - auto quotient_high_limbs_range_constraint_0 = View(in.quotient_high_limbs_range_constraint_0); - auto quotient_high_limbs_range_constraint_1 = View(in.quotient_high_limbs_range_constraint_1); - auto quotient_high_limbs_range_constraint_2 = View(in.quotient_high_limbs_range_constraint_2); - auto quotient_high_limbs_range_constraint_3 = View(in.quotient_high_limbs_range_constraint_3); - auto quotient_high_limbs_range_constraint_4 = View(in.quotient_high_limbs_range_constraint_4); - auto quotient_high_binary_limbs_shift = View(in.quotient_high_binary_limbs_shift); - auto quotient_high_limbs_range_constraint_0_shift = View(in.quotient_high_limbs_range_constraint_0_shift); - auto quotient_high_limbs_range_constraint_1_shift = View(in.quotient_high_limbs_range_constraint_1_shift); - auto quotient_high_limbs_range_constraint_2_shift = View(in.quotient_high_limbs_range_constraint_2_shift); - auto quotient_high_limbs_range_constraint_3_shift = View(in.quotient_high_limbs_range_constraint_3_shift); - auto relation_wide_limbs = View(in.relation_wide_limbs); - auto relation_wide_limbs_range_constraint_0 = View(in.relation_wide_limbs_range_constraint_0); - auto relation_wide_limbs_range_constraint_1 = View(in.relation_wide_limbs_range_constraint_1); - auto relation_wide_limbs_range_constraint_2 = View(in.relation_wide_limbs_range_constraint_2); - auto relation_wide_limbs_range_constraint_3 = View(in.relation_wide_limbs_range_constraint_3); - auto p_x_high_limbs_range_constraint_tail_shift = View(in.p_x_high_limbs_range_constraint_tail_shift); - auto accumulator_high_limbs_range_constraint_tail_shift = - View(in.accumulator_high_limbs_range_constraint_tail_shift); - auto relation_wide_limbs_shift = View(in.relation_wide_limbs_shift); - auto relation_wide_limbs_range_constraint_0_shift = View(in.relation_wide_limbs_range_constraint_0_shift); - auto relation_wide_limbs_range_constraint_1_shift = View(in.relation_wide_limbs_range_constraint_1_shift); - auto relation_wide_limbs_range_constraint_2_shift = View(in.relation_wide_limbs_range_constraint_2_shift); - auto relation_wide_limbs_range_constraint_3_shift = View(in.relation_wide_limbs_range_constraint_3_shift); - auto p_y_high_limbs_range_constraint_tail_shift = View(in.p_y_high_limbs_range_constraint_tail_shift); - auto quotient_high_limbs_range_constraint_tail_shift = View(in.quotient_high_limbs_range_constraint_tail_shift); - auto p_x_low_limbs_range_constraint_tail = View(in.p_x_low_limbs_range_constraint_tail); - auto p_x_low_limbs_range_constraint_tail_shift = View(in.p_x_low_limbs_range_constraint_tail_shift); - auto p_x_high_limbs_range_constraint_tail = View(in.p_x_high_limbs_range_constraint_tail); - auto p_x_high_limbs_range_constraint_4_shift = View(in.p_x_high_limbs_range_constraint_4_shift); - auto p_y_low_limbs_range_constraint_tail = View(in.p_y_low_limbs_range_constraint_tail); - auto p_y_low_limbs_range_constraint_tail_shift = View(in.p_y_low_limbs_range_constraint_tail_shift); - auto p_y_high_limbs_range_constraint_tail = View(in.p_y_high_limbs_range_constraint_tail); - auto p_y_high_limbs_range_constraint_4_shift = View(in.p_y_high_limbs_range_constraint_4_shift); - auto z_low_limbs_range_constraint_tail = View(in.z_low_limbs_range_constraint_tail); - auto z_low_limbs_range_constraint_tail_shift = View(in.z_low_limbs_range_constraint_tail_shift); - auto z_high_limbs_range_constraint_tail = View(in.z_high_limbs_range_constraint_tail); - auto z_high_limbs_range_constraint_tail_shift = View(in.z_high_limbs_range_constraint_tail_shift); - auto accumulator_low_limbs_range_constraint_tail = View(in.accumulator_low_limbs_range_constraint_tail); - auto accumulator_low_limbs_range_constraint_tail_shift = View(in.accumulator_low_limbs_range_constraint_tail_shift); - auto accumulator_high_limbs_range_constraint_tail = View(in.accumulator_high_limbs_range_constraint_tail); - auto accumulator_high_limbs_range_constraint_4_shift = View(in.accumulator_high_limbs_range_constraint_4_shift); - auto quotient_low_limbs_range_constraint_tail = View(in.quotient_low_limbs_range_constraint_tail); - auto quotient_low_limbs_range_constraint_tail_shift = View(in.quotient_low_limbs_range_constraint_tail_shift); - auto quotient_high_limbs_range_constraint_tail = View(in.quotient_high_limbs_range_constraint_tail); - auto quotient_high_limbs_range_constraint_4_shift = View(in.quotient_high_limbs_range_constraint_4_shift); - auto x_lo_y_hi = View(in.x_lo_y_hi); - auto x_hi_z_1 = View(in.x_hi_z_1); - auto y_lo_z_2 = View(in.y_lo_z_2); - auto x_lo_y_hi_shift = View(in.x_lo_y_hi_shift); - auto x_hi_z_1_shift = View(in.x_hi_z_1_shift); - auto y_lo_z_2_shift = View(in.y_lo_z_2_shift); - auto lagrange_odd_in_minicircuit = View(in.lagrange_odd_in_minicircuit); - - // Contributions that decompose 50, 52, 68 or 84 bit limbs used for computation into range-constrained chunks - // Contribution 1 , P_x lowest limb decomposition - auto tmp_1 = ((p_x_low_limbs_range_constraint_0 + p_x_low_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + - p_x_low_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + - p_x_low_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + - p_x_low_limbs_range_constraint_4 * MICRO_LIMB_SHIFTx4) - - p_x_low_limbs); - tmp_1 *= lagrange_odd_in_minicircuit; - tmp_1 *= scaling_factor; - std::get<0>(accumulators) += tmp_1; - - // Contribution 2 , P_x second lowest limb decomposition - auto tmp_2 = ((p_x_low_limbs_range_constraint_0_shift + p_x_low_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + - p_x_low_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + - p_x_low_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3 + - p_x_low_limbs_range_constraint_4_shift * MICRO_LIMB_SHIFTx4) - - p_x_low_limbs_shift); - tmp_2 *= lagrange_odd_in_minicircuit; - tmp_2 *= scaling_factor; - std::get<1>(accumulators) += tmp_2; - - // Contribution 3 , P_x third limb decomposition - auto tmp_3 = ((p_x_high_limbs_range_constraint_0 + p_x_high_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + - p_x_high_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + - p_x_high_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + - p_x_high_limbs_range_constraint_4 * MICRO_LIMB_SHIFTx4) - - p_x_high_limbs); - tmp_3 *= lagrange_odd_in_minicircuit; - tmp_3 *= scaling_factor; - std::get<2>(accumulators) += tmp_3; - - // Contribution 4 , P_x highest limb decomposition - auto tmp_4 = - ((p_x_high_limbs_range_constraint_0_shift + p_x_high_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + - p_x_high_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + - p_x_high_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3) - - p_x_high_limbs_shift); - tmp_4 *= lagrange_odd_in_minicircuit; - tmp_4 *= scaling_factor; - std::get<3>(accumulators) += tmp_4; - - // Contribution 5 , P_y lowest limb decomposition - auto tmp_5 = ((p_y_low_limbs_range_constraint_0 + p_y_low_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + - p_y_low_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + - p_y_low_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + - p_y_low_limbs_range_constraint_4 * MICRO_LIMB_SHIFTx4) - - p_y_low_limbs); - tmp_5 *= lagrange_odd_in_minicircuit; - tmp_5 *= scaling_factor; - std::get<4>(accumulators) += tmp_5; - - // Contribution 6 , P_y second lowest limb decomposition - auto tmp_6 = ((p_y_low_limbs_range_constraint_0_shift + p_y_low_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + - p_y_low_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + - p_y_low_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3 + - p_y_low_limbs_range_constraint_4_shift * MICRO_LIMB_SHIFTx4) - - p_y_low_limbs_shift); - tmp_6 *= lagrange_odd_in_minicircuit; - tmp_6 *= scaling_factor; - std::get<5>(accumulators) += tmp_6; - - // Contribution 7 , P_y third limb decomposition - auto tmp_7 = ((p_y_high_limbs_range_constraint_0 + p_y_high_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + - p_y_high_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + - p_y_high_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + - p_y_high_limbs_range_constraint_4 * MICRO_LIMB_SHIFTx4) - - p_y_high_limbs); - tmp_7 *= lagrange_odd_in_minicircuit; - tmp_7 *= scaling_factor; - std::get<6>(accumulators) += tmp_7; - - // Contribution 8 , P_y highest limb decomposition - auto tmp_8 = - ((p_y_high_limbs_range_constraint_0_shift + p_y_high_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + - p_y_high_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + - p_y_high_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3) - - p_y_high_limbs_shift); - tmp_8 *= lagrange_odd_in_minicircuit; - tmp_8 *= scaling_factor; - std::get<7>(accumulators) += tmp_8; - - // Contribution 9 , z_1 low limb decomposition - auto tmp_9 = - ((z_low_limbs_range_constraint_0 + z_low_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + - z_low_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + z_low_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + - z_low_limbs_range_constraint_4 * MICRO_LIMB_SHIFTx4) - - z_low_limbs); - tmp_9 *= lagrange_odd_in_minicircuit; - tmp_9 *= scaling_factor; - std::get<8>(accumulators) += tmp_9; - - // Contribution 10 , z_2 low limb decomposition - auto tmp_10 = ((z_low_limbs_range_constraint_0_shift + z_low_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + - z_low_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + - z_low_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3 + - z_low_limbs_range_constraint_4_shift * MICRO_LIMB_SHIFTx4) - - z_low_limbs_shift); - tmp_10 *= lagrange_odd_in_minicircuit; - tmp_10 *= scaling_factor; - std::get<9>(accumulators) += tmp_10; - - // Contribution 11 , z_1 high limb decomposition - auto tmp_11 = - ((z_high_limbs_range_constraint_0 + z_high_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + - z_high_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + z_high_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + - z_high_limbs_range_constraint_4 * MICRO_LIMB_SHIFTx4) - - z_high_limbs); - tmp_11 *= lagrange_odd_in_minicircuit; - tmp_11 *= scaling_factor; - std::get<10>(accumulators) += tmp_11; - - // Contribution 12 , z_2 high limb decomposition - auto tmp_12 = ((z_high_limbs_range_constraint_0_shift + z_high_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + - z_high_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + - z_high_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3 + - z_high_limbs_range_constraint_4_shift * MICRO_LIMB_SHIFTx4) - - z_high_limbs_shift); - tmp_12 *= lagrange_odd_in_minicircuit; - tmp_12 *= scaling_factor; - std::get<11>(accumulators) += tmp_12; - - // Contribution 13 , accumulator lowest limb decomposition - auto tmp_13 = - ((accumulator_low_limbs_range_constraint_0 + accumulator_low_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + - accumulator_low_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + - accumulator_low_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + - accumulator_low_limbs_range_constraint_4 * MICRO_LIMB_SHIFTx4) - - accumulators_binary_limbs_0); - tmp_13 *= lagrange_odd_in_minicircuit; - tmp_13 *= scaling_factor; - std::get<12>(accumulators) += tmp_13; - // Contribution 14 , accumulator second limb decomposition - auto tmp_14 = ((accumulator_low_limbs_range_constraint_0_shift + - accumulator_low_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + - accumulator_low_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + - accumulator_low_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3 + - accumulator_low_limbs_range_constraint_4_shift * MICRO_LIMB_SHIFTx4) - - accumulators_binary_limbs_1); - tmp_14 *= lagrange_odd_in_minicircuit; - tmp_14 *= scaling_factor; - std::get<13>(accumulators) += tmp_14; - - // Contribution 15 , accumulator second highest limb decomposition - auto tmp_15 = - ((accumulator_high_limbs_range_constraint_0 + accumulator_high_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + - accumulator_high_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + - accumulator_high_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + - accumulator_high_limbs_range_constraint_4 * MICRO_LIMB_SHIFTx4) - - accumulators_binary_limbs_2); - tmp_15 *= lagrange_odd_in_minicircuit; - tmp_15 *= scaling_factor; - std::get<14>(accumulators) += tmp_15; - // Contribution 16 , accumulator highest limb decomposition - auto tmp_16 = ((accumulator_high_limbs_range_constraint_0_shift + - accumulator_high_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + - accumulator_high_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + - accumulator_high_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3) - - accumulators_binary_limbs_3); - tmp_16 *= lagrange_odd_in_minicircuit; - tmp_16 *= scaling_factor; - std::get<15>(accumulators) += tmp_16; - - // Contribution 15 , quotient lowest limb decomposition - auto tmp_17 = ((quotient_low_limbs_range_constraint_0 + quotient_low_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + - quotient_low_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + - quotient_low_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + - quotient_low_limbs_range_constraint_4 * MICRO_LIMB_SHIFTx4) - - quotient_low_binary_limbs); - tmp_17 *= lagrange_odd_in_minicircuit; - tmp_17 *= scaling_factor; - std::get<16>(accumulators) += tmp_17; - // Contribution 16 , quotient second lowest limb decomposition - auto tmp_18 = - ((quotient_low_limbs_range_constraint_0_shift + quotient_low_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + - quotient_low_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + - quotient_low_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3 + - quotient_low_limbs_range_constraint_4_shift * MICRO_LIMB_SHIFTx4) - - quotient_low_binary_limbs_shift); - tmp_18 *= lagrange_odd_in_minicircuit; - tmp_18 *= scaling_factor; - std::get<17>(accumulators) += tmp_18; - - // Contribution 19 , quotient second highest limb decomposition - auto tmp_19 = ((quotient_high_limbs_range_constraint_0 + quotient_high_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + - quotient_high_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + - quotient_high_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + - quotient_high_limbs_range_constraint_4 * MICRO_LIMB_SHIFTx4) - - quotient_high_binary_limbs); - tmp_19 *= lagrange_odd_in_minicircuit; - tmp_19 *= scaling_factor; - std::get<18>(accumulators) += tmp_19; - // Contribution 20 , quotient highest limb decomposition - auto tmp_20 = ((quotient_high_limbs_range_constraint_0_shift + - quotient_high_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + - quotient_high_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + - quotient_high_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3) - - quotient_high_binary_limbs_shift); - tmp_20 *= lagrange_odd_in_minicircuit; - tmp_20 *= scaling_factor; - std::get<19>(accumulators) += tmp_20; - - // Contribution 21 , decomposition of the low wide relation limb used for the bigfield relation. - // N.B. top microlimbs of relation wide limbs are stored in microlimbs for range constraints of P_x, P_y, - // accumulator and quotient. This is to save space and because these microlimbs are not used by their namesakes, - // since top limbs in 254/6-bit values use one less microlimb for the top 50/52-bit limb - auto tmp_21 = ((relation_wide_limbs_range_constraint_0 + relation_wide_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + - relation_wide_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + - relation_wide_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + - p_x_high_limbs_range_constraint_tail_shift * MICRO_LIMB_SHIFTx4 + - accumulator_high_limbs_range_constraint_tail_shift * MICRO_LIMB_SHIFTx5) - - relation_wide_limbs); - tmp_21 *= lagrange_odd_in_minicircuit; - tmp_21 *= scaling_factor; - std::get<20>(accumulators) += tmp_21; - - // Contribution 22 , decomposition of high relation limb - auto tmp_22 = ((relation_wide_limbs_range_constraint_0_shift + - relation_wide_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + - relation_wide_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + - relation_wide_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3 + - p_y_high_limbs_range_constraint_tail_shift * MICRO_LIMB_SHIFTx4 + - quotient_high_limbs_range_constraint_tail_shift * MICRO_LIMB_SHIFTx5) - - relation_wide_limbs_shift); - tmp_22 *= lagrange_odd_in_minicircuit; - tmp_22 *= scaling_factor; - std::get<21>(accumulators) += tmp_22; - - // Contributions enfocing a reduced range constraint on high limbs (these relation force the last microlimb in - // each limb to be more severely range constrained) - - // Contribution 23, range constrain the highest microlimb of lowest P.x limb to be 12 bits (68 % 14 = 12) - auto tmp_23 = p_x_low_limbs_range_constraint_4 * SHIFT_12_TO_14 - p_x_low_limbs_range_constraint_tail; - tmp_23 *= lagrange_odd_in_minicircuit; - tmp_23 *= scaling_factor; - std::get<22>(accumulators) += tmp_23; - - // Contribution 24, range constrain the highest microlimb of second lowest P.x limb to be 12 bits - auto tmp_24 = p_x_low_limbs_range_constraint_4_shift * SHIFT_12_TO_14 - p_x_low_limbs_range_constraint_tail_shift; - tmp_24 *= lagrange_odd_in_minicircuit; - tmp_24 *= scaling_factor; - std::get<23>(accumulators) += tmp_24; - - // Contribution 25, range constrain the highest microlimb of second highest P.x limb to be 12 bits - auto tmp_25 = p_x_high_limbs_range_constraint_4 * SHIFT_12_TO_14 - p_x_high_limbs_range_constraint_tail; - tmp_25 *= lagrange_odd_in_minicircuit; - tmp_25 *= scaling_factor; - std::get<24>(accumulators) += tmp_25; - - // Contribution 26, range constrain the highest microilmb of highest P.x limb to be 8 bits (50 % 14 = 8) - auto tmp_26 = (p_x_high_limbs_range_constraint_3_shift * SHIFT_8_TO_14 - p_x_high_limbs_range_constraint_4_shift); - - tmp_26 *= lagrange_odd_in_minicircuit; - tmp_26 *= scaling_factor; - std::get<25>(accumulators) += tmp_26; - - // Contribution 27, range constrain the highest microlimb of lowest P.y limb to be 12 bits (68 % 14 = 12) - auto tmp_27 = p_y_low_limbs_range_constraint_4 * SHIFT_12_TO_14 - p_y_low_limbs_range_constraint_tail; - tmp_27 *= lagrange_odd_in_minicircuit; - tmp_27 *= scaling_factor; - std::get<26>(accumulators) += tmp_27; - - // Contribution 28, range constrain the highest microlimb of second lowest P.y limb to be 12 bits (68 % 14 = 12) - auto tmp_28 = p_y_low_limbs_range_constraint_4_shift * SHIFT_12_TO_14 - p_y_low_limbs_range_constraint_tail_shift; - tmp_28 *= lagrange_odd_in_minicircuit; - tmp_28 *= scaling_factor; - std::get<27>(accumulators) += tmp_28; - - // Contribution 29, range constrain the highest microlimb of second highest P.y limb to be 12 bits (68 % 14 = - // 12) - auto tmp_29 = p_y_high_limbs_range_constraint_4 * SHIFT_12_TO_14 - p_y_high_limbs_range_constraint_tail; - tmp_29 *= lagrange_odd_in_minicircuit; - tmp_29 *= scaling_factor; - std::get<28>(accumulators) += tmp_29; - - // Contribution 30, range constrain the highest microlimb of highest P.y limb to be 8 bits (50 % 14 = 8) - auto tmp_30 = (p_y_high_limbs_range_constraint_3_shift * SHIFT_8_TO_14 - p_y_high_limbs_range_constraint_4_shift); - - tmp_30 *= lagrange_odd_in_minicircuit; - tmp_30 *= scaling_factor; - std::get<29>(accumulators) += tmp_30; - - // Contribution 31, range constrain the highest microlimb of low z1 limb to be 12 bits (68 % 14 = 12) - auto tmp_31 = (z_low_limbs_range_constraint_4 * SHIFT_12_TO_14 - z_low_limbs_range_constraint_tail); - tmp_31 *= lagrange_odd_in_minicircuit; - tmp_31 *= scaling_factor; - std::get<30>(accumulators) += tmp_31; - - // Contribution 32, range constrain the highest microlimb of low z2 limb to be 12 bits (68 % 14 = 12) - auto tmp_32 = (z_low_limbs_range_constraint_4_shift * SHIFT_12_TO_14 - z_low_limbs_range_constraint_tail_shift); - tmp_32 *= lagrange_odd_in_minicircuit; - tmp_32 *= scaling_factor; - std::get<31>(accumulators) += tmp_32; - - // Contribution 33, range constrain the highest microlimb of high z1 limb to be 4 bits (60 % 14 = 12) - auto tmp_33 = (z_high_limbs_range_constraint_4 * SHIFT_4_TO_14 - z_high_limbs_range_constraint_tail); - tmp_33 *= lagrange_odd_in_minicircuit; - tmp_33 *= scaling_factor; - std::get<32>(accumulators) += tmp_33; - - // Contribution 34, range constrain the highest microlimb of high z2 limb to be 4 bits (60 % 14 = 12) - auto tmp_34 = (z_high_limbs_range_constraint_4_shift * SHIFT_4_TO_14 - z_high_limbs_range_constraint_tail_shift); - tmp_34 *= lagrange_odd_in_minicircuit; - tmp_34 *= scaling_factor; - std::get<33>(accumulators) += tmp_34; - - // Contribution 35, range constrain the highest microlimb of lowest current accumulator limb to be 12 bits (68 % - // 14 = 12) - auto tmp_35 = - (accumulator_low_limbs_range_constraint_4 * SHIFT_12_TO_14 - accumulator_low_limbs_range_constraint_tail); - tmp_35 *= lagrange_odd_in_minicircuit; - tmp_35 *= scaling_factor; - std::get<34>(accumulators) += tmp_35; - - // Contribution 36, range constrain the highest microlimb of second lowest current accumulator limb to be 12 - // bits (68 % 14 = 12) - auto tmp_36 = (accumulator_low_limbs_range_constraint_4_shift * SHIFT_12_TO_14 - - accumulator_low_limbs_range_constraint_tail_shift); - tmp_36 *= lagrange_odd_in_minicircuit; - tmp_36 *= scaling_factor; - std::get<35>(accumulators) += tmp_36; - - // Contribution 37, range constrain the highest microlimb of second highest current accumulator limb to be 12 - // bits (68 % 14 = 12) - auto tmp_37 = - (accumulator_high_limbs_range_constraint_4 * SHIFT_12_TO_14 - accumulator_high_limbs_range_constraint_tail); - tmp_37 *= lagrange_odd_in_minicircuit; - tmp_37 *= scaling_factor; - std::get<36>(accumulators) += tmp_37; - - // Contribution 38, range constrain the highest microlimb of highest current accumulator limb to be 8 bits (50 % - // 14 = 12) - auto tmp_38 = (accumulator_high_limbs_range_constraint_3_shift * SHIFT_8_TO_14 - - accumulator_high_limbs_range_constraint_4_shift); - tmp_38 *= lagrange_odd_in_minicircuit; - tmp_38 *= scaling_factor; - std::get<37>(accumulators) += tmp_38; - - // Contribution 39, range constrain the highest microlimb of lowest quotient limb to be 12 bits (68 % 14 = 12) - auto tmp_39 = (quotient_low_limbs_range_constraint_4 * SHIFT_12_TO_14 - quotient_low_limbs_range_constraint_tail); - tmp_39 *= lagrange_odd_in_minicircuit; - tmp_39 *= scaling_factor; - std::get<38>(accumulators) += tmp_39; - - // Contribution 40, range constrain the highest microlimb of second lowest quotient limb to be 12 bits (68 % 14 - // = 12) - auto tmp_40 = - (quotient_low_limbs_range_constraint_4_shift * SHIFT_12_TO_14 - quotient_low_limbs_range_constraint_tail_shift); - tmp_40 *= lagrange_odd_in_minicircuit; - tmp_40 *= scaling_factor; - std::get<39>(accumulators) += tmp_40; - - // Contribution 41, range constrain the highest microlimb of second highest quotient limb to be 12 bits (68 % 14 - // = 12) - auto tmp_41 = (quotient_high_limbs_range_constraint_4 * SHIFT_12_TO_14 - quotient_high_limbs_range_constraint_tail); - tmp_41 *= lagrange_odd_in_minicircuit; - tmp_41 *= scaling_factor; - std::get<40>(accumulators) += tmp_41; - - // Contribution 42, range constrain the highest microlimb of highest quotient limb to be 10 bits (52 % 14 = 12) - auto tmp_42 = - (quotient_high_limbs_range_constraint_3_shift * SHIFT_10_TO_14 - quotient_high_limbs_range_constraint_4_shift); - tmp_42 *= lagrange_odd_in_minicircuit; - tmp_42 *= scaling_factor; - std::get<41>(accumulators) += tmp_42; - - // Contributions where we decompose initial EccOpQueue values into 68-bit limbs - - // Contribution 43, decompose x_lo - auto tmp_43 = (p_x_low_limbs + p_x_low_limbs_shift * LIMB_SHIFT) - x_lo_y_hi; - tmp_43 *= lagrange_odd_in_minicircuit; - tmp_43 *= scaling_factor; - std::get<42>(accumulators) += tmp_43; - - // Contribution 44, decompose x_hi - auto tmp_44 = (p_x_high_limbs + p_x_high_limbs_shift * LIMB_SHIFT) - x_hi_z_1; - tmp_44 *= lagrange_odd_in_minicircuit; - tmp_44 *= scaling_factor; - std::get<43>(accumulators) += tmp_44; - // Contribution 45, decompose y_lo - auto tmp_45 = (p_y_low_limbs + p_y_low_limbs_shift * LIMB_SHIFT) - y_lo_z_2; - tmp_45 *= lagrange_odd_in_minicircuit; - tmp_45 *= scaling_factor; - std::get<44>(accumulators) += tmp_45; - - // Contribution 46, decompose y_hi - auto tmp_46 = (p_y_high_limbs + p_y_high_limbs_shift * LIMB_SHIFT) - x_lo_y_hi_shift; - tmp_46 *= lagrange_odd_in_minicircuit; - tmp_46 *= scaling_factor; - std::get<45>(accumulators) += tmp_46; - - // Contribution 47, decompose z1 - auto tmp_47 = (z_low_limbs + z_high_limbs * LIMB_SHIFT) - x_hi_z_1_shift; - tmp_47 *= lagrange_odd_in_minicircuit; - tmp_47 *= scaling_factor; - std::get<46>(accumulators) += tmp_47; - - // Contribution 48, decompose z2 - auto tmp_48 = (z_low_limbs_shift + z_high_limbs_shift * LIMB_SHIFT) - y_lo_z_2_shift; - tmp_48 *= lagrange_odd_in_minicircuit; - tmp_48 *= scaling_factor; - std::get<47>(accumulators) += tmp_48; -}; - -template class GoblinTranslatorDecompositionRelationImpl; -DEFINE_SUMCHECK_RELATION_CLASS(GoblinTranslatorDecompositionRelationImpl, GoblinTranslatorFlavor); - -} // namespace bb +template class TranslatorDecompositionRelationImpl; +DEFINE_SUMCHECK_RELATION_CLASS(TranslatorDecompositionRelationImpl, TranslatorFlavor); +} // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_decomposition_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_decomposition_relation.hpp index 519f1a4e119..a5f4956edbc 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_decomposition_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_decomposition_relation.hpp @@ -4,7 +4,7 @@ namespace bb { -template class GoblinTranslatorDecompositionRelationImpl { +template class TranslatorDecompositionRelationImpl { public: using FF = FF_; @@ -96,7 +96,6 @@ template class GoblinTranslatorDecompositionRelationImpl { const FF& scaling_factor); }; -template -using GoblinTranslatorDecompositionRelation = Relation>; +template using TranslatorDecompositionRelation = Relation>; } // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_decomposition_relation_impl.hpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_decomposition_relation_impl.hpp new file mode 100644 index 00000000000..70194d2635a --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_decomposition_relation_impl.hpp @@ -0,0 +1,618 @@ +#pragma once +#include "barretenberg/relations/translator_vm/translator_decomposition_relation.hpp" + +namespace bb { + +/** + * @brief Expression for decomposition of various values into smaller limbs or microlimbs. + * @details This relation enforces three types of subrelations: + * 1) A subrelation decomposing a value from the transcript (for example, z1) into 68-bit limbs. These relations + * will have the structure `lagrange_odd_in_minicircuit⋅(a - a_low - a_high⋅2⁶⁸)` + * 2) A subrelation decomposing a value of one of the limbs used in bigfield computation (for example, the lower + * wide relation limb) into 14-bit limbs. These relations will have the structure `lagrange_odd_in_minicircuit⋅(a - + * a_0 - a_1⋅2¹⁴ - + * ....)` 3) A subrelation making a microlimb range constraint more constraining. For example, we want to constrain + * some values to 12 bits instead of 14. So we add a constraint `lagrange_odd_in_minicircuit⋅(a_highest⋅4 - + * a_tail)`. In a separate relation both a_highest and a_tail are constrained to be 14 bits, but this relation + * changes the constraint on a_highest to be 12 bits. + * + * @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, .... + * @param scaling_factor optional term to scale the evaluation before adding to evals. + */ +template +template +void TranslatorDecompositionRelationImpl::accumulate(ContainerOverSubrelations& accumulators, + const AllEntities& in, + const Parameters&, + const FF& scaling_factor) +{ + static constexpr size_t NUM_LIMB_BITS = 68; // Number of bits in a standard limb used for bigfield operations + static constexpr size_t NUM_MICRO_LIMB_BITS = 14; // Number of bits in a standard limb used for bigfield operations + + // Value to multiply an element by to perform an appropriate shift + static auto LIMB_SHIFT = FF(uint256_t(1) << NUM_LIMB_BITS); + + // Values to multiply an element by to perform an appropriate shift + static auto MICRO_LIMB_SHIFT = FF(uint256_t(1) << NUM_MICRO_LIMB_BITS); + static auto MICRO_LIMB_SHIFTx2 = MICRO_LIMB_SHIFT * MICRO_LIMB_SHIFT; + static auto MICRO_LIMB_SHIFTx3 = MICRO_LIMB_SHIFTx2 * MICRO_LIMB_SHIFT; + static auto MICRO_LIMB_SHIFTx4 = MICRO_LIMB_SHIFTx3 * MICRO_LIMB_SHIFT; + static auto MICRO_LIMB_SHIFTx5 = MICRO_LIMB_SHIFTx4 * MICRO_LIMB_SHIFT; + + // Shifts used to constrain ranges further + static auto SHIFT_12_TO_14 = + FF(4); // Shift used to range constrain the last microlimb of 68-bit limbs (standard limbs) + static auto SHIFT_10_TO_14 = + FF(16); // Shift used to range constrain the last microlimb of 52-bit limb (top quotient limb) + static auto SHIFT_8_TO_14 = FF(64); // Shift used to range constrain the last microlimb of 50-bit + // limbs (top limb of standard 254-bit value) + static auto SHIFT_4_TO_14 = + FF(1024); // Shift used to range constrain the last mircrolimb of 60-bit limbs from z scalars + + using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; + using View = typename Accumulator::View; + + auto p_x_low_limbs = View(in.p_x_low_limbs); + auto p_x_low_limbs_range_constraint_0 = View(in.p_x_low_limbs_range_constraint_0); + auto p_x_low_limbs_range_constraint_1 = View(in.p_x_low_limbs_range_constraint_1); + auto p_x_low_limbs_range_constraint_2 = View(in.p_x_low_limbs_range_constraint_2); + auto p_x_low_limbs_range_constraint_3 = View(in.p_x_low_limbs_range_constraint_3); + auto p_x_low_limbs_range_constraint_4 = View(in.p_x_low_limbs_range_constraint_4); + auto p_x_low_limbs_shift = View(in.p_x_low_limbs_shift); + auto p_x_low_limbs_range_constraint_0_shift = View(in.p_x_low_limbs_range_constraint_0_shift); + auto p_x_low_limbs_range_constraint_1_shift = View(in.p_x_low_limbs_range_constraint_1_shift); + auto p_x_low_limbs_range_constraint_2_shift = View(in.p_x_low_limbs_range_constraint_2_shift); + auto p_x_low_limbs_range_constraint_3_shift = View(in.p_x_low_limbs_range_constraint_3_shift); + auto p_x_low_limbs_range_constraint_4_shift = View(in.p_x_low_limbs_range_constraint_4_shift); + auto p_x_high_limbs = View(in.p_x_high_limbs); + auto p_x_high_limbs_range_constraint_0 = View(in.p_x_high_limbs_range_constraint_0); + auto p_x_high_limbs_range_constraint_1 = View(in.p_x_high_limbs_range_constraint_1); + auto p_x_high_limbs_range_constraint_2 = View(in.p_x_high_limbs_range_constraint_2); + auto p_x_high_limbs_range_constraint_3 = View(in.p_x_high_limbs_range_constraint_3); + auto p_x_high_limbs_range_constraint_4 = View(in.p_x_high_limbs_range_constraint_4); + auto p_x_high_limbs_shift = View(in.p_x_high_limbs_shift); + auto p_x_high_limbs_range_constraint_0_shift = View(in.p_x_high_limbs_range_constraint_0_shift); + auto p_x_high_limbs_range_constraint_1_shift = View(in.p_x_high_limbs_range_constraint_1_shift); + auto p_x_high_limbs_range_constraint_2_shift = View(in.p_x_high_limbs_range_constraint_2_shift); + auto p_x_high_limbs_range_constraint_3_shift = View(in.p_x_high_limbs_range_constraint_3_shift); + auto p_y_low_limbs = View(in.p_y_low_limbs); + auto p_y_low_limbs_range_constraint_0 = View(in.p_y_low_limbs_range_constraint_0); + auto p_y_low_limbs_range_constraint_1 = View(in.p_y_low_limbs_range_constraint_1); + auto p_y_low_limbs_range_constraint_2 = View(in.p_y_low_limbs_range_constraint_2); + auto p_y_low_limbs_range_constraint_3 = View(in.p_y_low_limbs_range_constraint_3); + auto p_y_low_limbs_range_constraint_4 = View(in.p_y_low_limbs_range_constraint_4); + auto p_y_low_limbs_shift = View(in.p_y_low_limbs_shift); + auto p_y_low_limbs_range_constraint_0_shift = View(in.p_y_low_limbs_range_constraint_0_shift); + auto p_y_low_limbs_range_constraint_1_shift = View(in.p_y_low_limbs_range_constraint_1_shift); + auto p_y_low_limbs_range_constraint_2_shift = View(in.p_y_low_limbs_range_constraint_2_shift); + auto p_y_low_limbs_range_constraint_3_shift = View(in.p_y_low_limbs_range_constraint_3_shift); + auto p_y_low_limbs_range_constraint_4_shift = View(in.p_y_low_limbs_range_constraint_4_shift); + auto p_y_high_limbs = View(in.p_y_high_limbs); + auto p_y_high_limbs_range_constraint_0 = View(in.p_y_high_limbs_range_constraint_0); + auto p_y_high_limbs_range_constraint_1 = View(in.p_y_high_limbs_range_constraint_1); + auto p_y_high_limbs_range_constraint_2 = View(in.p_y_high_limbs_range_constraint_2); + auto p_y_high_limbs_range_constraint_3 = View(in.p_y_high_limbs_range_constraint_3); + auto p_y_high_limbs_range_constraint_4 = View(in.p_y_high_limbs_range_constraint_4); + auto p_y_high_limbs_shift = View(in.p_y_high_limbs_shift); + auto p_y_high_limbs_range_constraint_0_shift = View(in.p_y_high_limbs_range_constraint_0_shift); + auto p_y_high_limbs_range_constraint_1_shift = View(in.p_y_high_limbs_range_constraint_1_shift); + auto p_y_high_limbs_range_constraint_2_shift = View(in.p_y_high_limbs_range_constraint_2_shift); + auto p_y_high_limbs_range_constraint_3_shift = View(in.p_y_high_limbs_range_constraint_3_shift); + auto z_low_limbs = View(in.z_low_limbs); + auto z_low_limbs_range_constraint_0 = View(in.z_low_limbs_range_constraint_0); + auto z_low_limbs_range_constraint_1 = View(in.z_low_limbs_range_constraint_1); + auto z_low_limbs_range_constraint_2 = View(in.z_low_limbs_range_constraint_2); + auto z_low_limbs_range_constraint_3 = View(in.z_low_limbs_range_constraint_3); + auto z_low_limbs_range_constraint_4 = View(in.z_low_limbs_range_constraint_4); + auto z_low_limbs_shift = View(in.z_low_limbs_shift); + auto z_low_limbs_range_constraint_0_shift = View(in.z_low_limbs_range_constraint_0_shift); + auto z_low_limbs_range_constraint_1_shift = View(in.z_low_limbs_range_constraint_1_shift); + auto z_low_limbs_range_constraint_2_shift = View(in.z_low_limbs_range_constraint_2_shift); + auto z_low_limbs_range_constraint_3_shift = View(in.z_low_limbs_range_constraint_3_shift); + auto z_low_limbs_range_constraint_4_shift = View(in.z_low_limbs_range_constraint_4_shift); + auto z_high_limbs = View(in.z_high_limbs); + auto z_high_limbs_range_constraint_0 = View(in.z_high_limbs_range_constraint_0); + auto z_high_limbs_range_constraint_1 = View(in.z_high_limbs_range_constraint_1); + auto z_high_limbs_range_constraint_2 = View(in.z_high_limbs_range_constraint_2); + auto z_high_limbs_range_constraint_3 = View(in.z_high_limbs_range_constraint_3); + auto z_high_limbs_range_constraint_4 = View(in.z_high_limbs_range_constraint_4); + auto z_high_limbs_shift = View(in.z_high_limbs_shift); + auto z_high_limbs_range_constraint_0_shift = View(in.z_high_limbs_range_constraint_0_shift); + auto z_high_limbs_range_constraint_1_shift = View(in.z_high_limbs_range_constraint_1_shift); + auto z_high_limbs_range_constraint_2_shift = View(in.z_high_limbs_range_constraint_2_shift); + auto z_high_limbs_range_constraint_3_shift = View(in.z_high_limbs_range_constraint_3_shift); + auto z_high_limbs_range_constraint_4_shift = View(in.z_high_limbs_range_constraint_4_shift); + auto accumulators_binary_limbs_0 = View(in.accumulators_binary_limbs_0); + auto accumulators_binary_limbs_1 = View(in.accumulators_binary_limbs_1); + auto accumulators_binary_limbs_2 = View(in.accumulators_binary_limbs_2); + auto accumulators_binary_limbs_3 = View(in.accumulators_binary_limbs_3); + auto accumulator_low_limbs_range_constraint_0 = View(in.accumulator_low_limbs_range_constraint_0); + auto accumulator_low_limbs_range_constraint_1 = View(in.accumulator_low_limbs_range_constraint_1); + auto accumulator_low_limbs_range_constraint_2 = View(in.accumulator_low_limbs_range_constraint_2); + auto accumulator_low_limbs_range_constraint_3 = View(in.accumulator_low_limbs_range_constraint_3); + auto accumulator_low_limbs_range_constraint_4 = View(in.accumulator_low_limbs_range_constraint_4); + auto accumulator_low_limbs_range_constraint_0_shift = View(in.accumulator_low_limbs_range_constraint_0_shift); + auto accumulator_low_limbs_range_constraint_1_shift = View(in.accumulator_low_limbs_range_constraint_1_shift); + auto accumulator_low_limbs_range_constraint_2_shift = View(in.accumulator_low_limbs_range_constraint_2_shift); + auto accumulator_low_limbs_range_constraint_3_shift = View(in.accumulator_low_limbs_range_constraint_3_shift); + auto accumulator_low_limbs_range_constraint_4_shift = View(in.accumulator_low_limbs_range_constraint_4_shift); + auto accumulator_high_limbs_range_constraint_0 = View(in.accumulator_high_limbs_range_constraint_0); + auto accumulator_high_limbs_range_constraint_1 = View(in.accumulator_high_limbs_range_constraint_1); + auto accumulator_high_limbs_range_constraint_2 = View(in.accumulator_high_limbs_range_constraint_2); + auto accumulator_high_limbs_range_constraint_3 = View(in.accumulator_high_limbs_range_constraint_3); + auto accumulator_high_limbs_range_constraint_4 = View(in.accumulator_high_limbs_range_constraint_4); + auto accumulator_high_limbs_range_constraint_0_shift = View(in.accumulator_high_limbs_range_constraint_0_shift); + auto accumulator_high_limbs_range_constraint_1_shift = View(in.accumulator_high_limbs_range_constraint_1_shift); + auto accumulator_high_limbs_range_constraint_2_shift = View(in.accumulator_high_limbs_range_constraint_2_shift); + auto accumulator_high_limbs_range_constraint_3_shift = View(in.accumulator_high_limbs_range_constraint_3_shift); + auto quotient_low_binary_limbs = View(in.quotient_low_binary_limbs); + auto quotient_low_limbs_range_constraint_0 = View(in.quotient_low_limbs_range_constraint_0); + auto quotient_low_limbs_range_constraint_1 = View(in.quotient_low_limbs_range_constraint_1); + auto quotient_low_limbs_range_constraint_2 = View(in.quotient_low_limbs_range_constraint_2); + auto quotient_low_limbs_range_constraint_3 = View(in.quotient_low_limbs_range_constraint_3); + auto quotient_low_limbs_range_constraint_4 = View(in.quotient_low_limbs_range_constraint_4); + auto quotient_low_binary_limbs_shift = View(in.quotient_low_binary_limbs_shift); + auto quotient_low_limbs_range_constraint_0_shift = View(in.quotient_low_limbs_range_constraint_0_shift); + auto quotient_low_limbs_range_constraint_1_shift = View(in.quotient_low_limbs_range_constraint_1_shift); + auto quotient_low_limbs_range_constraint_2_shift = View(in.quotient_low_limbs_range_constraint_2_shift); + auto quotient_low_limbs_range_constraint_3_shift = View(in.quotient_low_limbs_range_constraint_3_shift); + auto quotient_low_limbs_range_constraint_4_shift = View(in.quotient_low_limbs_range_constraint_4_shift); + auto quotient_high_binary_limbs = View(in.quotient_high_binary_limbs); + auto quotient_high_limbs_range_constraint_0 = View(in.quotient_high_limbs_range_constraint_0); + auto quotient_high_limbs_range_constraint_1 = View(in.quotient_high_limbs_range_constraint_1); + auto quotient_high_limbs_range_constraint_2 = View(in.quotient_high_limbs_range_constraint_2); + auto quotient_high_limbs_range_constraint_3 = View(in.quotient_high_limbs_range_constraint_3); + auto quotient_high_limbs_range_constraint_4 = View(in.quotient_high_limbs_range_constraint_4); + auto quotient_high_binary_limbs_shift = View(in.quotient_high_binary_limbs_shift); + auto quotient_high_limbs_range_constraint_0_shift = View(in.quotient_high_limbs_range_constraint_0_shift); + auto quotient_high_limbs_range_constraint_1_shift = View(in.quotient_high_limbs_range_constraint_1_shift); + auto quotient_high_limbs_range_constraint_2_shift = View(in.quotient_high_limbs_range_constraint_2_shift); + auto quotient_high_limbs_range_constraint_3_shift = View(in.quotient_high_limbs_range_constraint_3_shift); + auto relation_wide_limbs = View(in.relation_wide_limbs); + auto relation_wide_limbs_range_constraint_0 = View(in.relation_wide_limbs_range_constraint_0); + auto relation_wide_limbs_range_constraint_1 = View(in.relation_wide_limbs_range_constraint_1); + auto relation_wide_limbs_range_constraint_2 = View(in.relation_wide_limbs_range_constraint_2); + auto relation_wide_limbs_range_constraint_3 = View(in.relation_wide_limbs_range_constraint_3); + auto p_x_high_limbs_range_constraint_tail_shift = View(in.p_x_high_limbs_range_constraint_tail_shift); + auto accumulator_high_limbs_range_constraint_tail_shift = + View(in.accumulator_high_limbs_range_constraint_tail_shift); + auto relation_wide_limbs_shift = View(in.relation_wide_limbs_shift); + auto relation_wide_limbs_range_constraint_0_shift = View(in.relation_wide_limbs_range_constraint_0_shift); + auto relation_wide_limbs_range_constraint_1_shift = View(in.relation_wide_limbs_range_constraint_1_shift); + auto relation_wide_limbs_range_constraint_2_shift = View(in.relation_wide_limbs_range_constraint_2_shift); + auto relation_wide_limbs_range_constraint_3_shift = View(in.relation_wide_limbs_range_constraint_3_shift); + auto p_y_high_limbs_range_constraint_tail_shift = View(in.p_y_high_limbs_range_constraint_tail_shift); + auto quotient_high_limbs_range_constraint_tail_shift = View(in.quotient_high_limbs_range_constraint_tail_shift); + auto p_x_low_limbs_range_constraint_tail = View(in.p_x_low_limbs_range_constraint_tail); + auto p_x_low_limbs_range_constraint_tail_shift = View(in.p_x_low_limbs_range_constraint_tail_shift); + auto p_x_high_limbs_range_constraint_tail = View(in.p_x_high_limbs_range_constraint_tail); + auto p_x_high_limbs_range_constraint_4_shift = View(in.p_x_high_limbs_range_constraint_4_shift); + auto p_y_low_limbs_range_constraint_tail = View(in.p_y_low_limbs_range_constraint_tail); + auto p_y_low_limbs_range_constraint_tail_shift = View(in.p_y_low_limbs_range_constraint_tail_shift); + auto p_y_high_limbs_range_constraint_tail = View(in.p_y_high_limbs_range_constraint_tail); + auto p_y_high_limbs_range_constraint_4_shift = View(in.p_y_high_limbs_range_constraint_4_shift); + auto z_low_limbs_range_constraint_tail = View(in.z_low_limbs_range_constraint_tail); + auto z_low_limbs_range_constraint_tail_shift = View(in.z_low_limbs_range_constraint_tail_shift); + auto z_high_limbs_range_constraint_tail = View(in.z_high_limbs_range_constraint_tail); + auto z_high_limbs_range_constraint_tail_shift = View(in.z_high_limbs_range_constraint_tail_shift); + auto accumulator_low_limbs_range_constraint_tail = View(in.accumulator_low_limbs_range_constraint_tail); + auto accumulator_low_limbs_range_constraint_tail_shift = View(in.accumulator_low_limbs_range_constraint_tail_shift); + auto accumulator_high_limbs_range_constraint_tail = View(in.accumulator_high_limbs_range_constraint_tail); + auto accumulator_high_limbs_range_constraint_4_shift = View(in.accumulator_high_limbs_range_constraint_4_shift); + auto quotient_low_limbs_range_constraint_tail = View(in.quotient_low_limbs_range_constraint_tail); + auto quotient_low_limbs_range_constraint_tail_shift = View(in.quotient_low_limbs_range_constraint_tail_shift); + auto quotient_high_limbs_range_constraint_tail = View(in.quotient_high_limbs_range_constraint_tail); + auto quotient_high_limbs_range_constraint_4_shift = View(in.quotient_high_limbs_range_constraint_4_shift); + auto x_lo_y_hi = View(in.x_lo_y_hi); + auto x_hi_z_1 = View(in.x_hi_z_1); + auto y_lo_z_2 = View(in.y_lo_z_2); + auto x_lo_y_hi_shift = View(in.x_lo_y_hi_shift); + auto x_hi_z_1_shift = View(in.x_hi_z_1_shift); + auto y_lo_z_2_shift = View(in.y_lo_z_2_shift); + auto lagrange_odd_in_minicircuit = View(in.lagrange_odd_in_minicircuit); + + // Contributions that decompose 50, 52, 68 or 84 bit limbs used for computation into range-constrained chunks + // Contribution 1 , P_x lowest limb decomposition + auto tmp_1 = ((p_x_low_limbs_range_constraint_0 + p_x_low_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + + p_x_low_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + + p_x_low_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + + p_x_low_limbs_range_constraint_4 * MICRO_LIMB_SHIFTx4) - + p_x_low_limbs); + tmp_1 *= lagrange_odd_in_minicircuit; + tmp_1 *= scaling_factor; + std::get<0>(accumulators) += tmp_1; + + // Contribution 2 , P_x second lowest limb decomposition + auto tmp_2 = ((p_x_low_limbs_range_constraint_0_shift + p_x_low_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + + p_x_low_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + + p_x_low_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3 + + p_x_low_limbs_range_constraint_4_shift * MICRO_LIMB_SHIFTx4) - + p_x_low_limbs_shift); + tmp_2 *= lagrange_odd_in_minicircuit; + tmp_2 *= scaling_factor; + std::get<1>(accumulators) += tmp_2; + + // Contribution 3 , P_x third limb decomposition + auto tmp_3 = ((p_x_high_limbs_range_constraint_0 + p_x_high_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + + p_x_high_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + + p_x_high_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + + p_x_high_limbs_range_constraint_4 * MICRO_LIMB_SHIFTx4) - + p_x_high_limbs); + tmp_3 *= lagrange_odd_in_minicircuit; + tmp_3 *= scaling_factor; + std::get<2>(accumulators) += tmp_3; + + // Contribution 4 , P_x highest limb decomposition + auto tmp_4 = + ((p_x_high_limbs_range_constraint_0_shift + p_x_high_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + + p_x_high_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + + p_x_high_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3) - + p_x_high_limbs_shift); + tmp_4 *= lagrange_odd_in_minicircuit; + tmp_4 *= scaling_factor; + std::get<3>(accumulators) += tmp_4; + + // Contribution 5 , P_y lowest limb decomposition + auto tmp_5 = ((p_y_low_limbs_range_constraint_0 + p_y_low_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + + p_y_low_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + + p_y_low_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + + p_y_low_limbs_range_constraint_4 * MICRO_LIMB_SHIFTx4) - + p_y_low_limbs); + tmp_5 *= lagrange_odd_in_minicircuit; + tmp_5 *= scaling_factor; + std::get<4>(accumulators) += tmp_5; + + // Contribution 6 , P_y second lowest limb decomposition + auto tmp_6 = ((p_y_low_limbs_range_constraint_0_shift + p_y_low_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + + p_y_low_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + + p_y_low_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3 + + p_y_low_limbs_range_constraint_4_shift * MICRO_LIMB_SHIFTx4) - + p_y_low_limbs_shift); + tmp_6 *= lagrange_odd_in_minicircuit; + tmp_6 *= scaling_factor; + std::get<5>(accumulators) += tmp_6; + + // Contribution 7 , P_y third limb decomposition + auto tmp_7 = ((p_y_high_limbs_range_constraint_0 + p_y_high_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + + p_y_high_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + + p_y_high_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + + p_y_high_limbs_range_constraint_4 * MICRO_LIMB_SHIFTx4) - + p_y_high_limbs); + tmp_7 *= lagrange_odd_in_minicircuit; + tmp_7 *= scaling_factor; + std::get<6>(accumulators) += tmp_7; + + // Contribution 8 , P_y highest limb decomposition + auto tmp_8 = + ((p_y_high_limbs_range_constraint_0_shift + p_y_high_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + + p_y_high_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + + p_y_high_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3) - + p_y_high_limbs_shift); + tmp_8 *= lagrange_odd_in_minicircuit; + tmp_8 *= scaling_factor; + std::get<7>(accumulators) += tmp_8; + + // Contribution 9 , z_1 low limb decomposition + auto tmp_9 = + ((z_low_limbs_range_constraint_0 + z_low_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + + z_low_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + z_low_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + + z_low_limbs_range_constraint_4 * MICRO_LIMB_SHIFTx4) - + z_low_limbs); + tmp_9 *= lagrange_odd_in_minicircuit; + tmp_9 *= scaling_factor; + std::get<8>(accumulators) += tmp_9; + + // Contribution 10 , z_2 low limb decomposition + auto tmp_10 = ((z_low_limbs_range_constraint_0_shift + z_low_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + + z_low_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + + z_low_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3 + + z_low_limbs_range_constraint_4_shift * MICRO_LIMB_SHIFTx4) - + z_low_limbs_shift); + tmp_10 *= lagrange_odd_in_minicircuit; + tmp_10 *= scaling_factor; + std::get<9>(accumulators) += tmp_10; + + // Contribution 11 , z_1 high limb decomposition + auto tmp_11 = + ((z_high_limbs_range_constraint_0 + z_high_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + + z_high_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + z_high_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + + z_high_limbs_range_constraint_4 * MICRO_LIMB_SHIFTx4) - + z_high_limbs); + tmp_11 *= lagrange_odd_in_minicircuit; + tmp_11 *= scaling_factor; + std::get<10>(accumulators) += tmp_11; + + // Contribution 12 , z_2 high limb decomposition + auto tmp_12 = ((z_high_limbs_range_constraint_0_shift + z_high_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + + z_high_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + + z_high_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3 + + z_high_limbs_range_constraint_4_shift * MICRO_LIMB_SHIFTx4) - + z_high_limbs_shift); + tmp_12 *= lagrange_odd_in_minicircuit; + tmp_12 *= scaling_factor; + std::get<11>(accumulators) += tmp_12; + + // Contribution 13 , accumulator lowest limb decomposition + auto tmp_13 = + ((accumulator_low_limbs_range_constraint_0 + accumulator_low_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + + accumulator_low_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + + accumulator_low_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + + accumulator_low_limbs_range_constraint_4 * MICRO_LIMB_SHIFTx4) - + accumulators_binary_limbs_0); + tmp_13 *= lagrange_odd_in_minicircuit; + tmp_13 *= scaling_factor; + std::get<12>(accumulators) += tmp_13; + // Contribution 14 , accumulator second limb decomposition + auto tmp_14 = ((accumulator_low_limbs_range_constraint_0_shift + + accumulator_low_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + + accumulator_low_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + + accumulator_low_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3 + + accumulator_low_limbs_range_constraint_4_shift * MICRO_LIMB_SHIFTx4) - + accumulators_binary_limbs_1); + tmp_14 *= lagrange_odd_in_minicircuit; + tmp_14 *= scaling_factor; + std::get<13>(accumulators) += tmp_14; + + // Contribution 15 , accumulator second highest limb decomposition + auto tmp_15 = + ((accumulator_high_limbs_range_constraint_0 + accumulator_high_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + + accumulator_high_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + + accumulator_high_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + + accumulator_high_limbs_range_constraint_4 * MICRO_LIMB_SHIFTx4) - + accumulators_binary_limbs_2); + tmp_15 *= lagrange_odd_in_minicircuit; + tmp_15 *= scaling_factor; + std::get<14>(accumulators) += tmp_15; + // Contribution 16 , accumulator highest limb decomposition + auto tmp_16 = ((accumulator_high_limbs_range_constraint_0_shift + + accumulator_high_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + + accumulator_high_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + + accumulator_high_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3) - + accumulators_binary_limbs_3); + tmp_16 *= lagrange_odd_in_minicircuit; + tmp_16 *= scaling_factor; + std::get<15>(accumulators) += tmp_16; + + // Contribution 15 , quotient lowest limb decomposition + auto tmp_17 = ((quotient_low_limbs_range_constraint_0 + quotient_low_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + + quotient_low_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + + quotient_low_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + + quotient_low_limbs_range_constraint_4 * MICRO_LIMB_SHIFTx4) - + quotient_low_binary_limbs); + tmp_17 *= lagrange_odd_in_minicircuit; + tmp_17 *= scaling_factor; + std::get<16>(accumulators) += tmp_17; + // Contribution 16 , quotient second lowest limb decomposition + auto tmp_18 = + ((quotient_low_limbs_range_constraint_0_shift + quotient_low_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + + quotient_low_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + + quotient_low_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3 + + quotient_low_limbs_range_constraint_4_shift * MICRO_LIMB_SHIFTx4) - + quotient_low_binary_limbs_shift); + tmp_18 *= lagrange_odd_in_minicircuit; + tmp_18 *= scaling_factor; + std::get<17>(accumulators) += tmp_18; + + // Contribution 19 , quotient second highest limb decomposition + auto tmp_19 = ((quotient_high_limbs_range_constraint_0 + quotient_high_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + + quotient_high_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + + quotient_high_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + + quotient_high_limbs_range_constraint_4 * MICRO_LIMB_SHIFTx4) - + quotient_high_binary_limbs); + tmp_19 *= lagrange_odd_in_minicircuit; + tmp_19 *= scaling_factor; + std::get<18>(accumulators) += tmp_19; + // Contribution 20 , quotient highest limb decomposition + auto tmp_20 = ((quotient_high_limbs_range_constraint_0_shift + + quotient_high_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + + quotient_high_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + + quotient_high_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3) - + quotient_high_binary_limbs_shift); + tmp_20 *= lagrange_odd_in_minicircuit; + tmp_20 *= scaling_factor; + std::get<19>(accumulators) += tmp_20; + + // Contribution 21 , decomposition of the low wide relation limb used for the bigfield relation. + // N.B. top microlimbs of relation wide limbs are stored in microlimbs for range constraints of P_x, P_y, + // accumulator and quotient. This is to save space and because these microlimbs are not used by their namesakes, + // since top limbs in 254/6-bit values use one less microlimb for the top 50/52-bit limb + auto tmp_21 = ((relation_wide_limbs_range_constraint_0 + relation_wide_limbs_range_constraint_1 * MICRO_LIMB_SHIFT + + relation_wide_limbs_range_constraint_2 * MICRO_LIMB_SHIFTx2 + + relation_wide_limbs_range_constraint_3 * MICRO_LIMB_SHIFTx3 + + p_x_high_limbs_range_constraint_tail_shift * MICRO_LIMB_SHIFTx4 + + accumulator_high_limbs_range_constraint_tail_shift * MICRO_LIMB_SHIFTx5) - + relation_wide_limbs); + tmp_21 *= lagrange_odd_in_minicircuit; + tmp_21 *= scaling_factor; + std::get<20>(accumulators) += tmp_21; + + // Contribution 22 , decomposition of high relation limb + auto tmp_22 = ((relation_wide_limbs_range_constraint_0_shift + + relation_wide_limbs_range_constraint_1_shift * MICRO_LIMB_SHIFT + + relation_wide_limbs_range_constraint_2_shift * MICRO_LIMB_SHIFTx2 + + relation_wide_limbs_range_constraint_3_shift * MICRO_LIMB_SHIFTx3 + + p_y_high_limbs_range_constraint_tail_shift * MICRO_LIMB_SHIFTx4 + + quotient_high_limbs_range_constraint_tail_shift * MICRO_LIMB_SHIFTx5) - + relation_wide_limbs_shift); + tmp_22 *= lagrange_odd_in_minicircuit; + tmp_22 *= scaling_factor; + std::get<21>(accumulators) += tmp_22; + + // Contributions enfocing a reduced range constraint on high limbs (these relation force the last microlimb in + // each limb to be more severely range constrained) + + // Contribution 23, range constrain the highest microlimb of lowest P.x limb to be 12 bits (68 % 14 = 12) + auto tmp_23 = p_x_low_limbs_range_constraint_4 * SHIFT_12_TO_14 - p_x_low_limbs_range_constraint_tail; + tmp_23 *= lagrange_odd_in_minicircuit; + tmp_23 *= scaling_factor; + std::get<22>(accumulators) += tmp_23; + + // Contribution 24, range constrain the highest microlimb of second lowest P.x limb to be 12 bits + auto tmp_24 = p_x_low_limbs_range_constraint_4_shift * SHIFT_12_TO_14 - p_x_low_limbs_range_constraint_tail_shift; + tmp_24 *= lagrange_odd_in_minicircuit; + tmp_24 *= scaling_factor; + std::get<23>(accumulators) += tmp_24; + + // Contribution 25, range constrain the highest microlimb of second highest P.x limb to be 12 bits + auto tmp_25 = p_x_high_limbs_range_constraint_4 * SHIFT_12_TO_14 - p_x_high_limbs_range_constraint_tail; + tmp_25 *= lagrange_odd_in_minicircuit; + tmp_25 *= scaling_factor; + std::get<24>(accumulators) += tmp_25; + + // Contribution 26, range constrain the highest microilmb of highest P.x limb to be 8 bits (50 % 14 = 8) + auto tmp_26 = (p_x_high_limbs_range_constraint_3_shift * SHIFT_8_TO_14 - p_x_high_limbs_range_constraint_4_shift); + + tmp_26 *= lagrange_odd_in_minicircuit; + tmp_26 *= scaling_factor; + std::get<25>(accumulators) += tmp_26; + + // Contribution 27, range constrain the highest microlimb of lowest P.y limb to be 12 bits (68 % 14 = 12) + auto tmp_27 = p_y_low_limbs_range_constraint_4 * SHIFT_12_TO_14 - p_y_low_limbs_range_constraint_tail; + tmp_27 *= lagrange_odd_in_minicircuit; + tmp_27 *= scaling_factor; + std::get<26>(accumulators) += tmp_27; + + // Contribution 28, range constrain the highest microlimb of second lowest P.y limb to be 12 bits (68 % 14 = 12) + auto tmp_28 = p_y_low_limbs_range_constraint_4_shift * SHIFT_12_TO_14 - p_y_low_limbs_range_constraint_tail_shift; + tmp_28 *= lagrange_odd_in_minicircuit; + tmp_28 *= scaling_factor; + std::get<27>(accumulators) += tmp_28; + + // Contribution 29, range constrain the highest microlimb of second highest P.y limb to be 12 bits (68 % 14 = + // 12) + auto tmp_29 = p_y_high_limbs_range_constraint_4 * SHIFT_12_TO_14 - p_y_high_limbs_range_constraint_tail; + tmp_29 *= lagrange_odd_in_minicircuit; + tmp_29 *= scaling_factor; + std::get<28>(accumulators) += tmp_29; + + // Contribution 30, range constrain the highest microlimb of highest P.y limb to be 8 bits (50 % 14 = 8) + auto tmp_30 = (p_y_high_limbs_range_constraint_3_shift * SHIFT_8_TO_14 - p_y_high_limbs_range_constraint_4_shift); + + tmp_30 *= lagrange_odd_in_minicircuit; + tmp_30 *= scaling_factor; + std::get<29>(accumulators) += tmp_30; + + // Contribution 31, range constrain the highest microlimb of low z1 limb to be 12 bits (68 % 14 = 12) + auto tmp_31 = (z_low_limbs_range_constraint_4 * SHIFT_12_TO_14 - z_low_limbs_range_constraint_tail); + tmp_31 *= lagrange_odd_in_minicircuit; + tmp_31 *= scaling_factor; + std::get<30>(accumulators) += tmp_31; + + // Contribution 32, range constrain the highest microlimb of low z2 limb to be 12 bits (68 % 14 = 12) + auto tmp_32 = (z_low_limbs_range_constraint_4_shift * SHIFT_12_TO_14 - z_low_limbs_range_constraint_tail_shift); + tmp_32 *= lagrange_odd_in_minicircuit; + tmp_32 *= scaling_factor; + std::get<31>(accumulators) += tmp_32; + + // Contribution 33, range constrain the highest microlimb of high z1 limb to be 4 bits (60 % 14 = 12) + auto tmp_33 = (z_high_limbs_range_constraint_4 * SHIFT_4_TO_14 - z_high_limbs_range_constraint_tail); + tmp_33 *= lagrange_odd_in_minicircuit; + tmp_33 *= scaling_factor; + std::get<32>(accumulators) += tmp_33; + + // Contribution 34, range constrain the highest microlimb of high z2 limb to be 4 bits (60 % 14 = 12) + auto tmp_34 = (z_high_limbs_range_constraint_4_shift * SHIFT_4_TO_14 - z_high_limbs_range_constraint_tail_shift); + tmp_34 *= lagrange_odd_in_minicircuit; + tmp_34 *= scaling_factor; + std::get<33>(accumulators) += tmp_34; + + // Contribution 35, range constrain the highest microlimb of lowest current accumulator limb to be 12 bits (68 % + // 14 = 12) + auto tmp_35 = + (accumulator_low_limbs_range_constraint_4 * SHIFT_12_TO_14 - accumulator_low_limbs_range_constraint_tail); + tmp_35 *= lagrange_odd_in_minicircuit; + tmp_35 *= scaling_factor; + std::get<34>(accumulators) += tmp_35; + + // Contribution 36, range constrain the highest microlimb of second lowest current accumulator limb to be 12 + // bits (68 % 14 = 12) + auto tmp_36 = (accumulator_low_limbs_range_constraint_4_shift * SHIFT_12_TO_14 - + accumulator_low_limbs_range_constraint_tail_shift); + tmp_36 *= lagrange_odd_in_minicircuit; + tmp_36 *= scaling_factor; + std::get<35>(accumulators) += tmp_36; + + // Contribution 37, range constrain the highest microlimb of second highest current accumulator limb to be 12 + // bits (68 % 14 = 12) + auto tmp_37 = + (accumulator_high_limbs_range_constraint_4 * SHIFT_12_TO_14 - accumulator_high_limbs_range_constraint_tail); + tmp_37 *= lagrange_odd_in_minicircuit; + tmp_37 *= scaling_factor; + std::get<36>(accumulators) += tmp_37; + + // Contribution 38, range constrain the highest microlimb of highest current accumulator limb to be 8 bits (50 % + // 14 = 12) + auto tmp_38 = (accumulator_high_limbs_range_constraint_3_shift * SHIFT_8_TO_14 - + accumulator_high_limbs_range_constraint_4_shift); + tmp_38 *= lagrange_odd_in_minicircuit; + tmp_38 *= scaling_factor; + std::get<37>(accumulators) += tmp_38; + + // Contribution 39, range constrain the highest microlimb of lowest quotient limb to be 12 bits (68 % 14 = 12) + auto tmp_39 = (quotient_low_limbs_range_constraint_4 * SHIFT_12_TO_14 - quotient_low_limbs_range_constraint_tail); + tmp_39 *= lagrange_odd_in_minicircuit; + tmp_39 *= scaling_factor; + std::get<38>(accumulators) += tmp_39; + + // Contribution 40, range constrain the highest microlimb of second lowest quotient limb to be 12 bits (68 % 14 + // = 12) + auto tmp_40 = + (quotient_low_limbs_range_constraint_4_shift * SHIFT_12_TO_14 - quotient_low_limbs_range_constraint_tail_shift); + tmp_40 *= lagrange_odd_in_minicircuit; + tmp_40 *= scaling_factor; + std::get<39>(accumulators) += tmp_40; + + // Contribution 41, range constrain the highest microlimb of second highest quotient limb to be 12 bits (68 % 14 + // = 12) + auto tmp_41 = (quotient_high_limbs_range_constraint_4 * SHIFT_12_TO_14 - quotient_high_limbs_range_constraint_tail); + tmp_41 *= lagrange_odd_in_minicircuit; + tmp_41 *= scaling_factor; + std::get<40>(accumulators) += tmp_41; + + // Contribution 42, range constrain the highest microlimb of highest quotient limb to be 10 bits (52 % 14 = 12) + auto tmp_42 = + (quotient_high_limbs_range_constraint_3_shift * SHIFT_10_TO_14 - quotient_high_limbs_range_constraint_4_shift); + tmp_42 *= lagrange_odd_in_minicircuit; + tmp_42 *= scaling_factor; + std::get<41>(accumulators) += tmp_42; + + // Contributions where we decompose initial EccOpQueue values into 68-bit limbs + + // Contribution 43, decompose x_lo + auto tmp_43 = (p_x_low_limbs + p_x_low_limbs_shift * LIMB_SHIFT) - x_lo_y_hi; + tmp_43 *= lagrange_odd_in_minicircuit; + tmp_43 *= scaling_factor; + std::get<42>(accumulators) += tmp_43; + + // Contribution 44, decompose x_hi + auto tmp_44 = (p_x_high_limbs + p_x_high_limbs_shift * LIMB_SHIFT) - x_hi_z_1; + tmp_44 *= lagrange_odd_in_minicircuit; + tmp_44 *= scaling_factor; + std::get<43>(accumulators) += tmp_44; + // Contribution 45, decompose y_lo + auto tmp_45 = (p_y_low_limbs + p_y_low_limbs_shift * LIMB_SHIFT) - y_lo_z_2; + tmp_45 *= lagrange_odd_in_minicircuit; + tmp_45 *= scaling_factor; + std::get<44>(accumulators) += tmp_45; + + // Contribution 46, decompose y_hi + auto tmp_46 = (p_y_high_limbs + p_y_high_limbs_shift * LIMB_SHIFT) - x_lo_y_hi_shift; + tmp_46 *= lagrange_odd_in_minicircuit; + tmp_46 *= scaling_factor; + std::get<45>(accumulators) += tmp_46; + + // Contribution 47, decompose z1 + auto tmp_47 = (z_low_limbs + z_high_limbs * LIMB_SHIFT) - x_hi_z_1_shift; + tmp_47 *= lagrange_odd_in_minicircuit; + tmp_47 *= scaling_factor; + std::get<46>(accumulators) += tmp_47; + + // Contribution 48, decompose z2 + auto tmp_48 = (z_low_limbs_shift + z_high_limbs_shift * LIMB_SHIFT) - y_lo_z_2_shift; + tmp_48 *= lagrange_odd_in_minicircuit; + tmp_48 *= scaling_factor; + std::get<47>(accumulators) += tmp_48; +}; +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation.cpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation.cpp index 9489cec0042..fd651d31f2e 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation.cpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation.cpp @@ -1,132 +1,6 @@ -#include "barretenberg/relations/translator_vm/translator_delta_range_constraint_relation.hpp" -#include "barretenberg/translator_vm/goblin_translator_flavor.hpp" - +#include "barretenberg/relations/translator_vm/translator_delta_range_constraint_relation_impl.hpp" +#include "barretenberg/translator_vm/translator_flavor.hpp" namespace bb { - -/** - * @brief Expression for the generalized permutation sort relation - * - * @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 - * - * @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, .... - * @param scaling_factor optional term to scale the evaluation before adding to evals. - */ -template -template -void GoblinTranslatorDeltaRangeConstraintRelationImpl::accumulate(ContainerOverSubrelations& accumulators, - const AllEntities& in, - const Parameters&, - const FF& scaling_factor) -{ - static const FF minus_one = FF(-1); - static const FF minus_two = FF(-2); - static const FF minus_three = FF(-3); - static const size_t micro_limb_bits = 14; - static const auto maximum_sort_value = -FF((1 << micro_limb_bits) - 1); - - [&]() { - using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; - using View = typename Accumulator::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); - auto ordered_range_constraints_0_shift = View(in.ordered_range_constraints_0_shift); - auto ordered_range_constraints_1_shift = View(in.ordered_range_constraints_1_shift); - 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); - - // Compute wire differences - auto delta_1 = ordered_range_constraints_0_shift - ordered_range_constraints_0; - auto delta_2 = ordered_range_constraints_1_shift - ordered_range_constraints_1; - auto delta_3 = ordered_range_constraints_2_shift - ordered_range_constraints_2; - auto delta_4 = ordered_range_constraints_3_shift - ordered_range_constraints_3; - auto delta_5 = ordered_range_constraints_4_shift - ordered_range_constraints_4; - - // Contribution (1) (contributions 1-5 ensure that the sequential values have a difference of {0,1,2,3}) - auto tmp_1 = delta_1; - 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 *= scaling_factor; - std::get<0>(accumulators) += tmp_1; - - // Contribution (2) - auto tmp_2 = delta_2; - 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 *= scaling_factor; - - std::get<1>(accumulators) += tmp_2; - - // Contribution (3) - auto tmp_3 = delta_3; - 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 *= scaling_factor; - std::get<2>(accumulators) += tmp_3; - - // Contribution (4) - auto tmp_4 = delta_4; - 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 *= scaling_factor; - std::get<3>(accumulators) += tmp_4; - - // Contribution (5) - auto tmp_5 = delta_5; - 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 *= scaling_factor; - std::get<4>(accumulators) += tmp_5; - }(); - - [&]() { - using Accumulator = std::tuple_element_t<5, ContainerOverSubrelations>; - using View = typename Accumulator::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); - auto lagrange_last = View(in.lagrange_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; - // Contribution (7) - std::get<6>(accumulators) += - lagrange_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; - // Contribution (9) - std::get<8>(accumulators) += - lagrange_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; - }(); -}; - -template class GoblinTranslatorDeltaRangeConstraintRelationImpl; -DEFINE_SUMCHECK_RELATION_CLASS(GoblinTranslatorDeltaRangeConstraintRelationImpl, GoblinTranslatorFlavor); - -} // namespace bb +template class TranslatorDeltaRangeConstraintRelationImpl; +DEFINE_SUMCHECK_RELATION_CLASS(TranslatorDeltaRangeConstraintRelationImpl, TranslatorFlavor); +} // namespace bb \ No newline at end of file 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 01547603e0c..1515598dc88 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 @@ -3,7 +3,7 @@ namespace bb { -template class GoblinTranslatorDeltaRangeConstraintRelationImpl { +template class TranslatorDeltaRangeConstraintRelationImpl { public: using FF = FF_; @@ -44,6 +44,6 @@ template class GoblinTranslatorDeltaRangeConstraintRelationImpl { }; template -using GoblinTranslatorDeltaRangeConstraintRelation = Relation>; +using TranslatorDeltaRangeConstraintRelation = Relation>; } // namespace bb 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 new file mode 100644 index 00000000000..4a3304d13fc --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_delta_range_constraint_relation_impl.hpp @@ -0,0 +1,128 @@ +#pragma once +#include "barretenberg/relations/translator_vm/translator_delta_range_constraint_relation.hpp" + +namespace bb { + +/** + * @brief Expression for the generalized permutation sort relation + * + * @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 + * + * @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, .... + * @param scaling_factor optional term to scale the evaluation before adding to evals. + */ +template +template +void TranslatorDeltaRangeConstraintRelationImpl::accumulate(ContainerOverSubrelations& accumulators, + const AllEntities& in, + const Parameters&, + const FF& scaling_factor) +{ + static const FF minus_one = FF(-1); + static const FF minus_two = FF(-2); + static const FF minus_three = FF(-3); + static const size_t micro_limb_bits = 14; + static const auto maximum_sort_value = -FF((1 << micro_limb_bits) - 1); + + [&]() { + using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; + using View = typename Accumulator::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); + auto ordered_range_constraints_0_shift = View(in.ordered_range_constraints_0_shift); + auto ordered_range_constraints_1_shift = View(in.ordered_range_constraints_1_shift); + 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); + + // Compute wire differences + auto delta_1 = ordered_range_constraints_0_shift - ordered_range_constraints_0; + auto delta_2 = ordered_range_constraints_1_shift - ordered_range_constraints_1; + auto delta_3 = ordered_range_constraints_2_shift - ordered_range_constraints_2; + auto delta_4 = ordered_range_constraints_3_shift - ordered_range_constraints_3; + auto delta_5 = ordered_range_constraints_4_shift - ordered_range_constraints_4; + + // Contribution (1) (contributions 1-5 ensure that the sequential values have a difference of {0,1,2,3}) + auto tmp_1 = delta_1; + 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 *= scaling_factor; + std::get<0>(accumulators) += tmp_1; + + // Contribution (2) + auto tmp_2 = delta_2; + 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 *= scaling_factor; + + std::get<1>(accumulators) += tmp_2; + + // Contribution (3) + auto tmp_3 = delta_3; + 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 *= scaling_factor; + std::get<2>(accumulators) += tmp_3; + + // Contribution (4) + auto tmp_4 = delta_4; + 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 *= scaling_factor; + std::get<3>(accumulators) += tmp_4; + + // Contribution (5) + auto tmp_5 = delta_5; + 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 *= scaling_factor; + std::get<4>(accumulators) += tmp_5; + }(); + + [&]() { + using Accumulator = std::tuple_element_t<5, ContainerOverSubrelations>; + using View = typename Accumulator::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); + auto lagrange_last = View(in.lagrange_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; + // Contribution (7) + std::get<6>(accumulators) += + lagrange_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; + // Contribution (9) + std::get<8>(accumulators) += + lagrange_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; + }(); +}; +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_extra_relations.cpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_extra_relations.cpp index 70379dae2b7..bf4bd53ac57 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_extra_relations.cpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_extra_relations.cpp @@ -1,155 +1,9 @@ -#include "barretenberg/relations/translator_vm/translator_extra_relations.hpp" -#include "barretenberg/translator_vm/goblin_translator_flavor.hpp" - +#include "barretenberg/relations/translator_vm/translator_extra_relations_impl.hpp" +#include "barretenberg/translator_vm/translator_flavor.hpp" namespace bb { +template class TranslatorOpcodeConstraintRelationImpl; +template class TranslatorAccumulatorTransferRelationImpl; -/** - * @brief Expression for enforcing the value of the Opcode to be {0,1,2,3,4,8} - * @details This relation enforces the opcode to be one of described values. Since we don't care about even - * values in the opcode wire and usually just set them to zero, we don't use a lagrange polynomial to specify - * the relation to be enforced just at odd indices, which brings the degree down by 1. - * - * @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, .... - * @param scaling_factor optional term to scale the evaluation before adding to evals. - */ -template -template -void GoblinTranslatorOpcodeConstraintRelationImpl::accumulate(ContainerOverSubrelations& accumulators, - const AllEntities& in, - const Parameters&, - const FF& scaling_factor) -{ - - using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; - using View = typename Accumulator::View; - - auto op = View(in.op); - static const FF minus_one = FF(-1); - static const FF minus_two = FF(-2); - static const FF minus_three = FF(-3); - static const FF minus_four = FF(-4); - static const FF minus_eight = FF(-8); - - // Contribution (1) (op(op-1)(op-2)(op-3)(op-4)(op-8)) - auto tmp_1 = op * (op + minus_one); - tmp_1 *= (op + minus_two); - tmp_1 *= (op + minus_three); - tmp_1 *= (op + minus_four); - tmp_1 *= (op + minus_eight); - tmp_1 *= scaling_factor; - std::get<0>(accumulators) += tmp_1; -}; - -/** - * @brief Relation enforcing non-arithmetic transitions of accumulator (value that is tracking the batched - * evaluation of polynomials in non-native field) - * @details This relation enforces three pieces of logic: - * 1) Accumulator starts as zero before we start accumulating stuff - * 2) Accumulator limbs stay the same if accumulation is not occurring (at even indices) - * 3) Accumulator limbs result in the values specified by relation parameters after accumulation - * - * @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, .... - * @param scaling_factor optional term to scale the evaluation before adding to evals. - */ -template -template -void GoblinTranslatorAccumulatorTransferRelationImpl::accumulate(ContainerOverSubrelations& accumulators, - const AllEntities& in, - const Parameters& params, - const FF& scaling_factor) -{ - using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; - using View = typename Accumulator::View; - // We use combination of lagrange polynomials at even indices in the minicircuit for copying the accumulator - auto lagrange_even_in_minicircuit = View(in.lagrange_even_in_minicircuit); - - // Lagrange at index 1 is used to confirm the accumulator result - auto lagrange_second = View(in.lagrange_second); - - // Lagrange at index (size of minicircuit - 2) is used to enforce that it starts with zero - auto lagrange_second_to_last_in_minicircuit = View(in.lagrange_second_to_last_in_minicircuit); - - auto accumulators_binary_limbs_0 = View(in.accumulators_binary_limbs_0); - auto accumulators_binary_limbs_1 = View(in.accumulators_binary_limbs_1); - auto accumulators_binary_limbs_2 = View(in.accumulators_binary_limbs_2); - auto accumulators_binary_limbs_3 = View(in.accumulators_binary_limbs_3); - auto accumulators_binary_limbs_0_shift = View(in.accumulators_binary_limbs_0_shift); - auto accumulators_binary_limbs_1_shift = View(in.accumulators_binary_limbs_1_shift); - auto accumulators_binary_limbs_2_shift = View(in.accumulators_binary_limbs_2_shift); - auto accumulators_binary_limbs_3_shift = View(in.accumulators_binary_limbs_3_shift); - - // Contribution (1) (1-4 ensure transfer of accumulator limbs at even indices of the minicircuit) - auto tmp_1 = accumulators_binary_limbs_0 - accumulators_binary_limbs_0_shift; - tmp_1 *= lagrange_even_in_minicircuit; - tmp_1 *= scaling_factor; - std::get<0>(accumulators) += tmp_1; - - // Contribution (2) - auto tmp_2 = accumulators_binary_limbs_1 - accumulators_binary_limbs_1_shift; - tmp_2 *= lagrange_even_in_minicircuit; - tmp_2 *= scaling_factor; - std::get<1>(accumulators) += tmp_2; - // Contribution (3) - auto tmp_3 = accumulators_binary_limbs_2 - accumulators_binary_limbs_2_shift; - tmp_3 *= lagrange_even_in_minicircuit; - tmp_3 *= scaling_factor; - std::get<2>(accumulators) += tmp_3; - // Contribution (4) - auto tmp_4 = accumulators_binary_limbs_3 - accumulators_binary_limbs_3_shift; - tmp_4 *= lagrange_even_in_minicircuit; - tmp_4 *= scaling_factor; - std::get<3>(accumulators) += tmp_4; - - // Contribution (5) (5-9 ensure that accumulator starts with zeroed-out limbs) - auto tmp_5 = accumulators_binary_limbs_0 * lagrange_second_to_last_in_minicircuit; - tmp_5 *= scaling_factor; - std::get<4>(accumulators) += tmp_5; - - // Contribution (6) - auto tmp_6 = accumulators_binary_limbs_1 * lagrange_second_to_last_in_minicircuit; - tmp_6 *= scaling_factor; - std::get<5>(accumulators) += tmp_6; - - // Contribution (7) - auto tmp_7 = accumulators_binary_limbs_2 * lagrange_second_to_last_in_minicircuit; - tmp_7 *= scaling_factor; - std::get<6>(accumulators) += tmp_7; - - // Contribution (8) - auto tmp_8 = accumulators_binary_limbs_3 * lagrange_second_to_last_in_minicircuit; - tmp_8 *= scaling_factor; - std::get<7>(accumulators) += tmp_8; - - // Contribution (9) (9-12 ensure the output is as stated, we basically use this to get the result out of the - // proof) - auto tmp_9 = (accumulators_binary_limbs_0 - params.accumulated_result[0]) * lagrange_second; - tmp_9 *= scaling_factor; - std::get<8>(accumulators) += tmp_9; - - // Contribution (10) - auto tmp_10 = (accumulators_binary_limbs_1 - params.accumulated_result[1]) * lagrange_second; - tmp_10 *= scaling_factor; - std::get<9>(accumulators) += tmp_10; - - // Contribution (11) - auto tmp_11 = (accumulators_binary_limbs_2 - params.accumulated_result[2]) * lagrange_second; - tmp_11 *= scaling_factor; - std::get<10>(accumulators) += tmp_11; - - // Contribution (12) - auto tmp_12 = (accumulators_binary_limbs_3 - params.accumulated_result[3]) * lagrange_second; - tmp_12 *= scaling_factor; - std::get<11>(accumulators) += tmp_12; -}; - -template class GoblinTranslatorOpcodeConstraintRelationImpl; -template class GoblinTranslatorAccumulatorTransferRelationImpl; - -DEFINE_SUMCHECK_RELATION_CLASS(GoblinTranslatorOpcodeConstraintRelationImpl, GoblinTranslatorFlavor); -DEFINE_SUMCHECK_RELATION_CLASS(GoblinTranslatorAccumulatorTransferRelationImpl, GoblinTranslatorFlavor); - -} // namespace bb +DEFINE_SUMCHECK_RELATION_CLASS(TranslatorOpcodeConstraintRelationImpl, TranslatorFlavor); +DEFINE_SUMCHECK_RELATION_CLASS(TranslatorAccumulatorTransferRelationImpl, TranslatorFlavor); +} // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_extra_relations.hpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_extra_relations.hpp index 3d0805af27c..5e25c0eaf00 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_extra_relations.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_extra_relations.hpp @@ -3,7 +3,7 @@ namespace bb { -template class GoblinTranslatorOpcodeConstraintRelationImpl { +template class TranslatorOpcodeConstraintRelationImpl { public: using FF = FF_; @@ -36,7 +36,7 @@ template class GoblinTranslatorOpcodeConstraintRelationImpl { const FF& scaling_factor); }; -template class GoblinTranslatorAccumulatorTransferRelationImpl { +template class TranslatorAccumulatorTransferRelationImpl { public: using FF = FF_; @@ -91,10 +91,9 @@ template class GoblinTranslatorAccumulatorTransferRelationImpl { const FF& scaling_factor); }; -template -using GoblinTranslatorOpcodeConstraintRelation = Relation>; +template using TranslatorOpcodeConstraintRelation = Relation>; template -using GoblinTranslatorAccumulatorTransferRelation = Relation>; +using TranslatorAccumulatorTransferRelation = Relation>; } // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_extra_relations_impl.hpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_extra_relations_impl.hpp new file mode 100644 index 00000000000..63d6522238e --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_extra_relations_impl.hpp @@ -0,0 +1,148 @@ +#pragma once +#include "barretenberg/relations/translator_vm/translator_extra_relations.hpp" + +namespace bb { + +/** + * @brief Expression for enforcing the value of the Opcode to be {0,1,2,3,4,8} + * @details This relation enforces the opcode to be one of described values. Since we don't care about even + * values in the opcode wire and usually just set them to zero, we don't use a lagrange polynomial to specify + * the relation to be enforced just at odd indices, which brings the degree down by 1. + * + * @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, .... + * @param scaling_factor optional term to scale the evaluation before adding to evals. + */ +template +template +void TranslatorOpcodeConstraintRelationImpl::accumulate(ContainerOverSubrelations& accumulators, + const AllEntities& in, + const Parameters&, + const FF& scaling_factor) +{ + + using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; + using View = typename Accumulator::View; + + auto op = View(in.op); + static const FF minus_one = FF(-1); + static const FF minus_two = FF(-2); + static const FF minus_three = FF(-3); + static const FF minus_four = FF(-4); + static const FF minus_eight = FF(-8); + + // Contribution (1) (op(op-1)(op-2)(op-3)(op-4)(op-8)) + auto tmp_1 = op * (op + minus_one); + tmp_1 *= (op + minus_two); + tmp_1 *= (op + minus_three); + tmp_1 *= (op + minus_four); + tmp_1 *= (op + minus_eight); + tmp_1 *= scaling_factor; + std::get<0>(accumulators) += tmp_1; +}; + +/** + * @brief Relation enforcing non-arithmetic transitions of accumulator (value that is tracking the batched + * evaluation of polynomials in non-native field) + * @details This relation enforces three pieces of logic: + * 1) Accumulator starts as zero before we start accumulating stuff + * 2) Accumulator limbs stay the same if accumulation is not occurring (at even indices) + * 3) Accumulator limbs result in the values specified by relation parameters after accumulation + * + * @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, .... + * @param scaling_factor optional term to scale the evaluation before adding to evals. + */ +template +template +void TranslatorAccumulatorTransferRelationImpl::accumulate(ContainerOverSubrelations& accumulators, + const AllEntities& in, + const Parameters& params, + const FF& scaling_factor) +{ + using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; + using View = typename Accumulator::View; + // We use combination of lagrange polynomials at even indices in the minicircuit for copying the accumulator + auto lagrange_even_in_minicircuit = View(in.lagrange_even_in_minicircuit); + + // Lagrange at index 1 is used to confirm the accumulator result + auto lagrange_second = View(in.lagrange_second); + + // Lagrange at index (size of minicircuit - 2) is used to enforce that it starts with zero + auto lagrange_second_to_last_in_minicircuit = View(in.lagrange_second_to_last_in_minicircuit); + + auto accumulators_binary_limbs_0 = View(in.accumulators_binary_limbs_0); + auto accumulators_binary_limbs_1 = View(in.accumulators_binary_limbs_1); + auto accumulators_binary_limbs_2 = View(in.accumulators_binary_limbs_2); + auto accumulators_binary_limbs_3 = View(in.accumulators_binary_limbs_3); + auto accumulators_binary_limbs_0_shift = View(in.accumulators_binary_limbs_0_shift); + auto accumulators_binary_limbs_1_shift = View(in.accumulators_binary_limbs_1_shift); + auto accumulators_binary_limbs_2_shift = View(in.accumulators_binary_limbs_2_shift); + auto accumulators_binary_limbs_3_shift = View(in.accumulators_binary_limbs_3_shift); + + // Contribution (1) (1-4 ensure transfer of accumulator limbs at even indices of the minicircuit) + auto tmp_1 = accumulators_binary_limbs_0 - accumulators_binary_limbs_0_shift; + tmp_1 *= lagrange_even_in_minicircuit; + tmp_1 *= scaling_factor; + std::get<0>(accumulators) += tmp_1; + + // Contribution (2) + auto tmp_2 = accumulators_binary_limbs_1 - accumulators_binary_limbs_1_shift; + tmp_2 *= lagrange_even_in_minicircuit; + tmp_2 *= scaling_factor; + std::get<1>(accumulators) += tmp_2; + // Contribution (3) + auto tmp_3 = accumulators_binary_limbs_2 - accumulators_binary_limbs_2_shift; + tmp_3 *= lagrange_even_in_minicircuit; + tmp_3 *= scaling_factor; + std::get<2>(accumulators) += tmp_3; + // Contribution (4) + auto tmp_4 = accumulators_binary_limbs_3 - accumulators_binary_limbs_3_shift; + tmp_4 *= lagrange_even_in_minicircuit; + tmp_4 *= scaling_factor; + std::get<3>(accumulators) += tmp_4; + + // Contribution (5) (5-9 ensure that accumulator starts with zeroed-out limbs) + auto tmp_5 = accumulators_binary_limbs_0 * lagrange_second_to_last_in_minicircuit; + tmp_5 *= scaling_factor; + std::get<4>(accumulators) += tmp_5; + + // Contribution (6) + auto tmp_6 = accumulators_binary_limbs_1 * lagrange_second_to_last_in_minicircuit; + tmp_6 *= scaling_factor; + std::get<5>(accumulators) += tmp_6; + + // Contribution (7) + auto tmp_7 = accumulators_binary_limbs_2 * lagrange_second_to_last_in_minicircuit; + tmp_7 *= scaling_factor; + std::get<6>(accumulators) += tmp_7; + + // Contribution (8) + auto tmp_8 = accumulators_binary_limbs_3 * lagrange_second_to_last_in_minicircuit; + tmp_8 *= scaling_factor; + std::get<7>(accumulators) += tmp_8; + + // Contribution (9) (9-12 ensure the output is as stated, we basically use this to get the result out of the + // proof) + auto tmp_9 = (accumulators_binary_limbs_0 - params.accumulated_result[0]) * lagrange_second; + tmp_9 *= scaling_factor; + std::get<8>(accumulators) += tmp_9; + + // Contribution (10) + auto tmp_10 = (accumulators_binary_limbs_1 - params.accumulated_result[1]) * lagrange_second; + tmp_10 *= scaling_factor; + std::get<9>(accumulators) += tmp_10; + + // Contribution (11) + auto tmp_11 = (accumulators_binary_limbs_2 - params.accumulated_result[2]) * lagrange_second; + tmp_11 *= scaling_factor; + std::get<10>(accumulators) += tmp_11; + + // Contribution (12) + auto tmp_12 = (accumulators_binary_limbs_3 - params.accumulated_result[3]) * lagrange_second; + tmp_12 *= scaling_factor; + std::get<11>(accumulators) += tmp_12; +}; +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation.cpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation.cpp index 26a5f0f7961..f80ddfe235c 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation.cpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation.cpp @@ -1,283 +1,6 @@ -#include "barretenberg/relations/translator_vm/translator_non_native_field_relation.hpp" -#include "barretenberg/translator_vm/goblin_translator_flavor.hpp" - +#include "barretenberg/relations/translator_vm/translator_non_native_field_relation_impl.hpp" +#include "barretenberg/translator_vm/translator_flavor.hpp" namespace bb { -/** - * @brief Expression for the computation of Goblin Translator accumulator in integers through 68-bit limbs and - * native field (prime) limb - * @details This relation is a part of system of relations that enforce a formula in non-native field (base field of - * bn254 curve Fp (p - modulus of Fp)). We are trying to compute: - * - * `current_accumulator = previous_accumulator ⋅ x + op + P.x ⋅ v + P.y ⋅ v² +z1 ⋅ v³ + z2 ⋅ v⁴ mod p`. - * - * However, we can only operate in Fr (scalar field of bn254) with - * modulus r. To emulate arithmetic in Fp we rephrase the equation in integers: - * - * `previous_accumulator ⋅ x + op + P.x ⋅ v + P.y ⋅ v² +z1 ⋅ v³ + z2 ⋅ v⁴ - quotient⋅p - current_accumulator = 0` - * - * We can't operate over unbounded integers, but since we know the maximum value of each element (we also treat - * powers of v as new constants constrained to 254 bits) we know that the maximum values of the sum of the positive - * products is ~2⁵¹⁴, so we only need to make sure that no overflow happens till that bound. We calculate integer - * logic until the bound 2²⁷²⋅r (which is more than 2⁵¹⁴) by using the representations modulo 2²⁷² (requires limb - * computation over native scalar field) and r (native scalar field computation). - * - * We perform modulo 2²⁷² computations by separating each of values into 4 68-bit limbs (z1 and z2 are just two - * since they represent the values < 2¹²⁸ and op is just itself). Then we compute the first subrelation (index means - * sublimb and we use 2²⁷² - p instead of -p): - * ` previous_accumulator[0]⋅x[0] + op + P.x[0]⋅v[0] + P.y[0]⋅v²[0] + z1[0] ⋅ v³[0] + z2[0] ⋅ v⁴[0] - * + quotient[0]⋅(-p)[0] - current_accumulator[0] - * + 2⁶⁸⋅(previous_accumulator[1]⋅x[0] + P.x[1]⋅v[0] + P.y[1]⋅v²[0] + z1[1] ⋅ v³[0] + z2[1] ⋅ v⁴[0] - * + quotient[1]⋅(-p)[0] + - * previous_accumulator[0]⋅x[1] + P.x[0]⋅v[1] + P.y[0]⋅v²[1] + z1[0] ⋅ v³[1] + z2[0] ⋅ v⁴[1] - * + quotient[0]⋅(-p)[1] - current_accumulator[1]) - * - 2¹³⁶⋅relation_wide_lower_limb - * == 0` - * - * We use 2 relation wide limbs which are called wide, because they contain the results of products (like you needed - * EDX:EAX in x86 to hold the product results of two standard 32-bit registers) and because they are constrained to - * 84 bits instead of 68 or lower by other relations. - * - * We show that the evaluation in 2 lower limbs results in relation_wide_lower_limb multiplied by 2¹³⁶. If - * relation_wide_lower_limb is propertly constrained (this is performed in other relations), then that means that - * the lower 136 bits of the result are 0. This is the first subrelation. - * - * We then use the relation_wide_lower_limb as carry and add it to the next expression, computing the evaluation in - * higher bits (carry + combinations of limbs (0,2), (1,1), (2,0), (0,3), (2,1), (1,2), (0,3)) and checking that it - * results in 2¹³⁶⋅relation_wide_higher_limb. This ensures that the logic was sound modulo 2²⁷². This is the second - * subrelation. - * - * Finally, we check that the relation holds in the native field. For this we reconstruct each value, for example: - * `previous_accumulator_native = previous_accumulator[0] + 2⁶⁸ ⋅previous_accumulator[1] - * + 2¹³⁶⋅previous_accumulator[2] + 2²⁰⁴⋅previous accumulator[3] mod r` - * - * Then the last subrelation is simply checking the integer equation in this native form - * - * All of these subrelations are multiplied by lagrange_odd_in_minicircuit, which is a polynomial with 1 at each odd - * index less than the size of the mini-circuit (16 times smaller than the final circuit and the only part over - * which we need to calculate non-permutation relations). All other indices are set to zero. Each EccOpQueue entry - * (operation) occupies 2 rows in bn254 transcripts. So the Goblin Translator VM has a 2-row cycle and we need to - * switch the checks being performed depending on which row we are at right now. We have half a cycle of - * accumulation, where we perform this computation, and half a cycle where we just copy accumulator data. - * - * @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, .... - * @param scaling_factor optional term to scale the evaluation before adding to evals. - */ -template -template -void GoblinTranslatorNonNativeFieldRelationImpl::accumulate(ContainerOverSubrelations& accumulators, - const AllEntities& in, - const Parameters& params, - const FF& scaling_factor) -{ - - using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; - using View = typename Accumulator::View; - - static constexpr size_t NUM_LIMB_BITS = 68; - static constexpr FF shift = FF(uint256_t(1) << NUM_LIMB_BITS); - static constexpr FF shiftx2 = FF(uint256_t(1) << (NUM_LIMB_BITS * 2)); - static constexpr FF shiftx3 = FF(uint256_t(1) << (NUM_LIMB_BITS * 3)); - static constexpr uint512_t MODULUS_U512 = uint512_t(curve::BN254::BaseField::modulus); - static constexpr uint512_t BINARY_BASIS_MODULUS = uint512_t(1) << (NUM_LIMB_BITS << 2); - static constexpr uint512_t NEGATIVE_PRIME_MODULUS = BINARY_BASIS_MODULUS - MODULUS_U512; - static constexpr std::array 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) - }; - - const auto& evaluation_input_x_0 = params.evaluation_input_x[0]; - const auto& evaluation_input_x_1 = params.evaluation_input_x[1]; - const auto& evaluation_input_x_2 = params.evaluation_input_x[2]; - const auto& evaluation_input_x_3 = params.evaluation_input_x[3]; - const auto& evaluation_input_x_4 = params.evaluation_input_x[4]; - // for j < 4, v_i_j is the j-th limb of v^{1+i} - // v_i_4 is v^{1+i} in the native field - const auto& v_0_0 = params.batching_challenge_v[0][0]; - const auto& v_0_1 = params.batching_challenge_v[0][1]; - const auto& v_0_2 = params.batching_challenge_v[0][2]; - const auto& v_0_3 = params.batching_challenge_v[0][3]; - const auto& v_0_4 = params.batching_challenge_v[0][4]; - const auto& v_1_0 = params.batching_challenge_v[1][0]; - const auto& v_1_1 = params.batching_challenge_v[1][1]; - const auto& v_1_2 = params.batching_challenge_v[1][2]; - const auto& v_1_3 = params.batching_challenge_v[1][3]; - const auto& v_1_4 = params.batching_challenge_v[1][4]; - const auto& v_2_0 = params.batching_challenge_v[2][0]; - const auto& v_2_1 = params.batching_challenge_v[2][1]; - const auto& v_2_2 = params.batching_challenge_v[2][2]; - const auto& v_2_3 = params.batching_challenge_v[2][3]; - const auto& v_2_4 = params.batching_challenge_v[2][4]; - const auto& v_3_0 = params.batching_challenge_v[3][0]; - const auto& v_3_1 = params.batching_challenge_v[3][1]; - const auto& v_3_2 = params.batching_challenge_v[3][2]; - const auto& v_3_3 = params.batching_challenge_v[3][3]; - const auto& v_3_4 = params.batching_challenge_v[3][4]; - - const auto& op = View(in.op); - const auto& p_x_low_limbs = View(in.p_x_low_limbs); - const auto& p_y_low_limbs = View(in.p_y_low_limbs); - const auto& p_x_high_limbs = View(in.p_x_high_limbs); - const auto& p_y_high_limbs = View(in.p_y_high_limbs); - const auto& accumulators_binary_limbs_0 = View(in.accumulators_binary_limbs_0); - const auto& accumulators_binary_limbs_1 = View(in.accumulators_binary_limbs_1); - const auto& accumulators_binary_limbs_2 = View(in.accumulators_binary_limbs_2); - const auto& accumulators_binary_limbs_3 = View(in.accumulators_binary_limbs_3); - const auto& z_low_limbs = View(in.z_low_limbs); - const auto& z_high_limbs = View(in.z_high_limbs); - const auto& quotient_low_binary_limbs = View(in.quotient_low_binary_limbs); - const auto& quotient_high_binary_limbs = View(in.quotient_high_binary_limbs); - const auto& p_x_low_limbs_shift = View(in.p_x_low_limbs_shift); - const auto& p_y_low_limbs_shift = View(in.p_y_low_limbs_shift); - const auto& p_x_high_limbs_shift = View(in.p_x_high_limbs_shift); - const auto& p_y_high_limbs_shift = View(in.p_y_high_limbs_shift); - const auto& accumulators_binary_limbs_0_shift = View(in.accumulators_binary_limbs_0_shift); - const auto& accumulators_binary_limbs_1_shift = View(in.accumulators_binary_limbs_1_shift); - const auto& accumulators_binary_limbs_2_shift = View(in.accumulators_binary_limbs_2_shift); - const auto& accumulators_binary_limbs_3_shift = View(in.accumulators_binary_limbs_3_shift); - const auto& z_low_limbs_shift = View(in.z_low_limbs_shift); - const auto& z_high_limbs_shift = View(in.z_high_limbs_shift); - const auto& quotient_low_binary_limbs_shift = View(in.quotient_low_binary_limbs_shift); - const auto& quotient_high_binary_limbs_shift = View(in.quotient_high_binary_limbs_shift); - const auto& relation_wide_limbs = View(in.relation_wide_limbs); - const auto& relation_wide_limbs_shift = View(in.relation_wide_limbs_shift); - const auto& lagrange_odd_in_minicircuit = View(in.lagrange_odd_in_minicircuit); - - // Contribution (1) Computing the mod 2²⁷² relation over lower 136 bits - // clang-format off - // the index-0 limb - auto tmp = accumulators_binary_limbs_0_shift * evaluation_input_x_0 - + op - + p_x_low_limbs * v_0_0 - + p_y_low_limbs * v_1_0 - + z_low_limbs * v_2_0 - + z_low_limbs_shift * v_3_0 - + quotient_low_binary_limbs * NEGATIVE_MODULUS_LIMBS[0] - - accumulators_binary_limbs_0; - - // the index-1 limb - tmp += (accumulators_binary_limbs_1_shift * evaluation_input_x_0 - + accumulators_binary_limbs_0_shift * evaluation_input_x_1 - + p_x_low_limbs * v_0_1 - + p_x_low_limbs_shift * v_0_0 - + p_y_low_limbs * v_1_1 - + p_y_low_limbs_shift * v_1_0 - + z_low_limbs * v_2_1 - + z_high_limbs * v_2_0 - + z_low_limbs_shift * v_3_1 - + z_high_limbs_shift * 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 ; - // clang-format on - // subtract large value; vanishing shows the desired relation holds on low 136-bit limb - tmp -= relation_wide_limbs * shiftx2; - tmp *= lagrange_odd_in_minicircuit; - tmp *= scaling_factor; - std::get<0>(accumulators) += tmp; - - // Contribution (2) Computing the 2²⁷² relation over higher 136 bits - // why declare another temporary? - // clang-format off - // the index-2 limb, with a carry from the previous calculation - tmp = relation_wide_limbs - + accumulators_binary_limbs_2_shift * evaluation_input_x_0 - + accumulators_binary_limbs_1_shift * evaluation_input_x_1 - + accumulators_binary_limbs_0_shift * evaluation_input_x_2 - + p_x_high_limbs * v_0_0 - + p_x_low_limbs_shift * v_0_1 - + p_x_low_limbs * v_0_2 - + p_y_high_limbs * v_1_0 - + p_y_low_limbs_shift * v_1_1 - + p_y_low_limbs * v_1_2 - + z_high_limbs * v_2_1 - + z_low_limbs * v_2_2 - + z_high_limbs_shift * v_3_1 - + z_low_limbs_shift * 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; - - // the index-2 limb - tmp += (accumulators_binary_limbs_3_shift * evaluation_input_x_0 - + accumulators_binary_limbs_2_shift * evaluation_input_x_1 - + accumulators_binary_limbs_1_shift * evaluation_input_x_2 - + accumulators_binary_limbs_0_shift * evaluation_input_x_3 - + p_x_high_limbs_shift * v_0_0 - + p_x_high_limbs * v_0_1 - + p_x_low_limbs_shift * v_0_2 - + p_x_low_limbs * v_0_3 - + p_y_high_limbs_shift * v_1_0 - + p_y_high_limbs * v_1_1 - + p_y_low_limbs_shift * v_1_2 - + p_y_low_limbs * v_1_3 - + z_high_limbs * v_2_2 - + z_low_limbs * v_2_3 - + z_high_limbs_shift * v_3_2 - + z_low_limbs_shift * 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; - // clang-format on - // subtract large value; vanishing shows the desired relation holds on high 136-bit limb - tmp -= relation_wide_limbs_shift * shiftx2; - tmp *= lagrange_odd_in_minicircuit; - tmp *= scaling_factor; - std::get<1>(accumulators) += tmp; - - const auto reconstruct_from_two = [](const auto& l0, const auto& l1) { return l0 + l1 * shift; }; - - const auto reconstruct_from_four = [](const auto& l0, const auto& l1, const auto& l2, const auto& l3) { - return l0 + l1 * shift + l2 * shiftx2 + l3 * shiftx3; - }; - - // Reconstructing native versions of values - auto reconstructed_p_x = - reconstruct_from_four(p_x_low_limbs, p_x_low_limbs_shift, p_x_high_limbs, p_x_high_limbs_shift); - auto reconstructed_p_y = - reconstruct_from_four(p_y_low_limbs, p_y_low_limbs_shift, p_y_high_limbs, p_y_high_limbs_shift); - auto reconstructed_previous_accumulator = reconstruct_from_four(accumulators_binary_limbs_0_shift, - accumulators_binary_limbs_1_shift, - accumulators_binary_limbs_2_shift, - accumulators_binary_limbs_3_shift); - auto reconstructed_current_accumulator = reconstruct_from_four(accumulators_binary_limbs_0, - accumulators_binary_limbs_1, - accumulators_binary_limbs_2, - accumulators_binary_limbs_3); - auto reconstructed_z1 = reconstruct_from_two(z_low_limbs, z_high_limbs); - auto reconstructed_z2 = reconstruct_from_two(z_low_limbs_shift, z_high_limbs_shift); - auto reconstructed_quotient = reconstruct_from_four(quotient_low_binary_limbs, - quotient_low_binary_limbs_shift, - quotient_high_binary_limbs, - quotient_high_binary_limbs_shift); - - // Contribution (3). Evaluating integer relation over native field - // clang-format off - // the native limb index is 4 - tmp = reconstructed_previous_accumulator * evaluation_input_x_4 - + op - + reconstructed_p_x * v_0_4 - + reconstructed_p_y * v_1_4 - + reconstructed_z1 * v_2_4 - + reconstructed_z2 * v_3_4 - + reconstructed_quotient * NEGATIVE_MODULUS_LIMBS[4] - - reconstructed_current_accumulator; - // clang-format on - tmp *= lagrange_odd_in_minicircuit; - tmp *= scaling_factor; - std::get<2>(accumulators) += tmp; -}; - -template class GoblinTranslatorNonNativeFieldRelationImpl; -DEFINE_SUMCHECK_RELATION_CLASS(GoblinTranslatorNonNativeFieldRelationImpl, GoblinTranslatorFlavor); - -} // namespace bb +template class TranslatorNonNativeFieldRelationImpl; +DEFINE_SUMCHECK_RELATION_CLASS(TranslatorNonNativeFieldRelationImpl, TranslatorFlavor); +} // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation.hpp index dc94e814ad3..b94fa346e97 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation.hpp @@ -4,7 +4,7 @@ namespace bb { -template class GoblinTranslatorNonNativeFieldRelationImpl { +template class TranslatorNonNativeFieldRelationImpl { public: using FF = FF_; @@ -24,7 +24,7 @@ template class GoblinTranslatorNonNativeFieldRelationImpl { return in.lagrange_odd_in_minicircuit.is_zero(); } /** - * @brief Expression for the computation of Goblin Translator accumulator in integers through 68-bit limbs and + * @brief Expression for the computation of Translator accumulator in integers through 68-bit limbs and * native field (prime) limb * @details This relation is a part of system of relations that enforce a formula in non-native field (base field of * bn254 curve Fp (p - modulus of Fp)). We are trying to compute: @@ -76,7 +76,7 @@ template class GoblinTranslatorNonNativeFieldRelationImpl { * All of these subrelations are multiplied by lagrange_odd_in_minicircuit, which is a polynomial with 1 at each odd * index less than the size of the mini-circuit (16 times smaller than the final circuit and the only part over * which we need to calculate non-permutation relations). All other indices are set to zero. Each EccOpQueue entry - * (operation) occupies 2 rows in bn254 transcripts. So the Goblin Translator VM has a 2-row cycle and we need to + * (operation) occupies 2 rows in bn254 transcripts. So the Translator VM has a 2-row cycle and we need to * switch the checks being performed depending on which row we are at right now. We have half a cycle of * accumulation, where we perform this computation, and half a cycle where we just copy accumulator data. * @@ -92,7 +92,6 @@ template class GoblinTranslatorNonNativeFieldRelationImpl { const FF& scaling_factor); }; -template -using GoblinTranslatorNonNativeFieldRelation = Relation>; +template using TranslatorNonNativeFieldRelation = Relation>; } // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation_impl.hpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation_impl.hpp new file mode 100644 index 00000000000..d4ea43e6024 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation_impl.hpp @@ -0,0 +1,279 @@ +#pragma once +#include "barretenberg/relations/translator_vm/translator_non_native_field_relation.hpp" + +namespace bb { +/** + * @brief Expression for the computation of Translator accumulator in integers through 68-bit limbs and + * native field (prime) limb + * @details This relation is a part of system of relations that enforce a formula in non-native field (base field of + * bn254 curve Fp (p - modulus of Fp)). We are trying to compute: + * + * `current_accumulator = previous_accumulator ⋅ x + op + P.x ⋅ v + P.y ⋅ v² +z1 ⋅ v³ + z2 ⋅ v⁴ mod p`. + * + * However, we can only operate in Fr (scalar field of bn254) with + * modulus r. To emulate arithmetic in Fp we rephrase the equation in integers: + * + * `previous_accumulator ⋅ x + op + P.x ⋅ v + P.y ⋅ v² +z1 ⋅ v³ + z2 ⋅ v⁴ - quotient⋅p - current_accumulator = 0` + * + * We can't operate over unbounded integers, but since we know the maximum value of each element (we also treat + * powers of v as new constants constrained to 254 bits) we know that the maximum values of the sum of the positive + * products is ~2⁵¹⁴, so we only need to make sure that no overflow happens till that bound. We calculate integer + * logic until the bound 2²⁷²⋅r (which is more than 2⁵¹⁴) by using the representations modulo 2²⁷² (requires limb + * computation over native scalar field) and r (native scalar field computation). + * + * We perform modulo 2²⁷² computations by separating each of values into 4 68-bit limbs (z1 and z2 are just two + * since they represent the values < 2¹²⁸ and op is just itself). Then we compute the first subrelation (index means + * sublimb and we use 2²⁷² - p instead of -p): + * ` previous_accumulator[0]⋅x[0] + op + P.x[0]⋅v[0] + P.y[0]⋅v²[0] + z1[0] ⋅ v³[0] + z2[0] ⋅ v⁴[0] + * + quotient[0]⋅(-p)[0] - current_accumulator[0] + * + 2⁶⁸⋅(previous_accumulator[1]⋅x[0] + P.x[1]⋅v[0] + P.y[1]⋅v²[0] + z1[1] ⋅ v³[0] + z2[1] ⋅ v⁴[0] + * + quotient[1]⋅(-p)[0] + + * previous_accumulator[0]⋅x[1] + P.x[0]⋅v[1] + P.y[0]⋅v²[1] + z1[0] ⋅ v³[1] + z2[0] ⋅ v⁴[1] + * + quotient[0]⋅(-p)[1] - current_accumulator[1]) + * - 2¹³⁶⋅relation_wide_lower_limb + * == 0` + * + * We use 2 relation wide limbs which are called wide, because they contain the results of products (like you needed + * EDX:EAX in x86 to hold the product results of two standard 32-bit registers) and because they are constrained to + * 84 bits instead of 68 or lower by other relations. + * + * We show that the evaluation in 2 lower limbs results in relation_wide_lower_limb multiplied by 2¹³⁶. If + * relation_wide_lower_limb is propertly constrained (this is performed in other relations), then that means that + * the lower 136 bits of the result are 0. This is the first subrelation. + * + * We then use the relation_wide_lower_limb as carry and add it to the next expression, computing the evaluation in + * higher bits (carry + combinations of limbs (0,2), (1,1), (2,0), (0,3), (2,1), (1,2), (0,3)) and checking that it + * results in 2¹³⁶⋅relation_wide_higher_limb. This ensures that the logic was sound modulo 2²⁷². This is the second + * subrelation. + * + * Finally, we check that the relation holds in the native field. For this we reconstruct each value, for example: + * `previous_accumulator_native = previous_accumulator[0] + 2⁶⁸ ⋅previous_accumulator[1] + * + 2¹³⁶⋅previous_accumulator[2] + 2²⁰⁴⋅previous accumulator[3] mod r` + * + * Then the last subrelation is simply checking the integer equation in this native form + * + * All of these subrelations are multiplied by lagrange_odd_in_minicircuit, which is a polynomial with 1 at each odd + * index less than the size of the mini-circuit (16 times smaller than the final circuit and the only part over + * which we need to calculate non-permutation relations). All other indices are set to zero. Each EccOpQueue entry + * (operation) occupies 2 rows in bn254 transcripts. So the Translator VM has a 2-row cycle and we need to + * switch the checks being performed depending on which row we are at right now. We have half a cycle of + * accumulation, where we perform this computation, and half a cycle where we just copy accumulator data. + * + * @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, .... + * @param scaling_factor optional term to scale the evaluation before adding to evals. + */ +template +template +void TranslatorNonNativeFieldRelationImpl::accumulate(ContainerOverSubrelations& accumulators, + const AllEntities& in, + const Parameters& params, + const FF& scaling_factor) +{ + + using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; + using View = typename Accumulator::View; + + static constexpr size_t NUM_LIMB_BITS = 68; + static FF shift = FF(uint256_t(1) << NUM_LIMB_BITS); + static FF shiftx2 = FF(uint256_t(1) << (NUM_LIMB_BITS * 2)); + static FF shiftx3 = FF(uint256_t(1) << (NUM_LIMB_BITS * 3)); + static uint512_t MODULUS_U512 = uint512_t(curve::BN254::BaseField::modulus); + static uint512_t BINARY_BASIS_MODULUS = uint512_t(1) << (NUM_LIMB_BITS << 2); + static uint512_t NEGATIVE_PRIME_MODULUS = BINARY_BASIS_MODULUS - MODULUS_U512; + static std::array 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) + }; + + const auto& evaluation_input_x_0 = params.evaluation_input_x[0]; + const auto& evaluation_input_x_1 = params.evaluation_input_x[1]; + const auto& evaluation_input_x_2 = params.evaluation_input_x[2]; + const auto& evaluation_input_x_3 = params.evaluation_input_x[3]; + const auto& evaluation_input_x_4 = params.evaluation_input_x[4]; + // for j < 4, v_i_j is the j-th limb of v^{1+i} + // v_i_4 is v^{1+i} in the native field + const auto& v_0_0 = params.batching_challenge_v[0][0]; + const auto& v_0_1 = params.batching_challenge_v[0][1]; + const auto& v_0_2 = params.batching_challenge_v[0][2]; + const auto& v_0_3 = params.batching_challenge_v[0][3]; + const auto& v_0_4 = params.batching_challenge_v[0][4]; + const auto& v_1_0 = params.batching_challenge_v[1][0]; + const auto& v_1_1 = params.batching_challenge_v[1][1]; + const auto& v_1_2 = params.batching_challenge_v[1][2]; + const auto& v_1_3 = params.batching_challenge_v[1][3]; + const auto& v_1_4 = params.batching_challenge_v[1][4]; + const auto& v_2_0 = params.batching_challenge_v[2][0]; + const auto& v_2_1 = params.batching_challenge_v[2][1]; + const auto& v_2_2 = params.batching_challenge_v[2][2]; + const auto& v_2_3 = params.batching_challenge_v[2][3]; + const auto& v_2_4 = params.batching_challenge_v[2][4]; + const auto& v_3_0 = params.batching_challenge_v[3][0]; + const auto& v_3_1 = params.batching_challenge_v[3][1]; + const auto& v_3_2 = params.batching_challenge_v[3][2]; + const auto& v_3_3 = params.batching_challenge_v[3][3]; + const auto& v_3_4 = params.batching_challenge_v[3][4]; + + const auto& op = View(in.op); + const auto& p_x_low_limbs = View(in.p_x_low_limbs); + const auto& p_y_low_limbs = View(in.p_y_low_limbs); + const auto& p_x_high_limbs = View(in.p_x_high_limbs); + const auto& p_y_high_limbs = View(in.p_y_high_limbs); + const auto& accumulators_binary_limbs_0 = View(in.accumulators_binary_limbs_0); + const auto& accumulators_binary_limbs_1 = View(in.accumulators_binary_limbs_1); + const auto& accumulators_binary_limbs_2 = View(in.accumulators_binary_limbs_2); + const auto& accumulators_binary_limbs_3 = View(in.accumulators_binary_limbs_3); + const auto& z_low_limbs = View(in.z_low_limbs); + const auto& z_high_limbs = View(in.z_high_limbs); + const auto& quotient_low_binary_limbs = View(in.quotient_low_binary_limbs); + const auto& quotient_high_binary_limbs = View(in.quotient_high_binary_limbs); + const auto& p_x_low_limbs_shift = View(in.p_x_low_limbs_shift); + const auto& p_y_low_limbs_shift = View(in.p_y_low_limbs_shift); + const auto& p_x_high_limbs_shift = View(in.p_x_high_limbs_shift); + const auto& p_y_high_limbs_shift = View(in.p_y_high_limbs_shift); + const auto& accumulators_binary_limbs_0_shift = View(in.accumulators_binary_limbs_0_shift); + const auto& accumulators_binary_limbs_1_shift = View(in.accumulators_binary_limbs_1_shift); + const auto& accumulators_binary_limbs_2_shift = View(in.accumulators_binary_limbs_2_shift); + const auto& accumulators_binary_limbs_3_shift = View(in.accumulators_binary_limbs_3_shift); + const auto& z_low_limbs_shift = View(in.z_low_limbs_shift); + const auto& z_high_limbs_shift = View(in.z_high_limbs_shift); + const auto& quotient_low_binary_limbs_shift = View(in.quotient_low_binary_limbs_shift); + const auto& quotient_high_binary_limbs_shift = View(in.quotient_high_binary_limbs_shift); + const auto& relation_wide_limbs = View(in.relation_wide_limbs); + const auto& relation_wide_limbs_shift = View(in.relation_wide_limbs_shift); + const auto& lagrange_odd_in_minicircuit = View(in.lagrange_odd_in_minicircuit); + + // Contribution (1) Computing the mod 2²⁷² relation over lower 136 bits + // clang-format off + // the index-0 limb + auto tmp = accumulators_binary_limbs_0_shift * evaluation_input_x_0 + + op + + p_x_low_limbs * v_0_0 + + p_y_low_limbs * v_1_0 + + z_low_limbs * v_2_0 + + z_low_limbs_shift * v_3_0 + + quotient_low_binary_limbs * NEGATIVE_MODULUS_LIMBS[0] + - accumulators_binary_limbs_0; + + // the index-1 limb + tmp += (accumulators_binary_limbs_1_shift * evaluation_input_x_0 + + accumulators_binary_limbs_0_shift * evaluation_input_x_1 + + p_x_low_limbs * v_0_1 + + p_x_low_limbs_shift * v_0_0 + + p_y_low_limbs * v_1_1 + + p_y_low_limbs_shift * v_1_0 + + z_low_limbs * v_2_1 + + z_high_limbs * v_2_0 + + z_low_limbs_shift * v_3_1 + + z_high_limbs_shift * 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 ; + // clang-format on + // subtract large value; vanishing shows the desired relation holds on low 136-bit limb + tmp -= relation_wide_limbs * shiftx2; + tmp *= lagrange_odd_in_minicircuit; + tmp *= scaling_factor; + std::get<0>(accumulators) += tmp; + + // Contribution (2) Computing the 2²⁷² relation over higher 136 bits + // why declare another temporary? + // clang-format off + // the index-2 limb, with a carry from the previous calculation + tmp = relation_wide_limbs + + accumulators_binary_limbs_2_shift * evaluation_input_x_0 + + accumulators_binary_limbs_1_shift * evaluation_input_x_1 + + accumulators_binary_limbs_0_shift * evaluation_input_x_2 + + p_x_high_limbs * v_0_0 + + p_x_low_limbs_shift * v_0_1 + + p_x_low_limbs * v_0_2 + + p_y_high_limbs * v_1_0 + + p_y_low_limbs_shift * v_1_1 + + p_y_low_limbs * v_1_2 + + z_high_limbs * v_2_1 + + z_low_limbs * v_2_2 + + z_high_limbs_shift * v_3_1 + + z_low_limbs_shift * 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; + + // the index-2 limb + tmp += (accumulators_binary_limbs_3_shift * evaluation_input_x_0 + + accumulators_binary_limbs_2_shift * evaluation_input_x_1 + + accumulators_binary_limbs_1_shift * evaluation_input_x_2 + + accumulators_binary_limbs_0_shift * evaluation_input_x_3 + + p_x_high_limbs_shift * v_0_0 + + p_x_high_limbs * v_0_1 + + p_x_low_limbs_shift * v_0_2 + + p_x_low_limbs * v_0_3 + + p_y_high_limbs_shift * v_1_0 + + p_y_high_limbs * v_1_1 + + p_y_low_limbs_shift * v_1_2 + + p_y_low_limbs * v_1_3 + + z_high_limbs * v_2_2 + + z_low_limbs * v_2_3 + + z_high_limbs_shift * v_3_2 + + z_low_limbs_shift * 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; + // clang-format on + // subtract large value; vanishing shows the desired relation holds on high 136-bit limb + tmp -= relation_wide_limbs_shift * shiftx2; + tmp *= lagrange_odd_in_minicircuit; + tmp *= scaling_factor; + std::get<1>(accumulators) += tmp; + + const auto reconstruct_from_two = [](const auto& l0, const auto& l1) { return l0 + l1 * shift; }; + + const auto reconstruct_from_four = [](const auto& l0, const auto& l1, const auto& l2, const auto& l3) { + return l0 + l1 * shift + l2 * shiftx2 + l3 * shiftx3; + }; + + // Reconstructing native versions of values + auto reconstructed_p_x = + reconstruct_from_four(p_x_low_limbs, p_x_low_limbs_shift, p_x_high_limbs, p_x_high_limbs_shift); + auto reconstructed_p_y = + reconstruct_from_four(p_y_low_limbs, p_y_low_limbs_shift, p_y_high_limbs, p_y_high_limbs_shift); + auto reconstructed_previous_accumulator = reconstruct_from_four(accumulators_binary_limbs_0_shift, + accumulators_binary_limbs_1_shift, + accumulators_binary_limbs_2_shift, + accumulators_binary_limbs_3_shift); + auto reconstructed_current_accumulator = reconstruct_from_four(accumulators_binary_limbs_0, + accumulators_binary_limbs_1, + accumulators_binary_limbs_2, + accumulators_binary_limbs_3); + auto reconstructed_z1 = reconstruct_from_two(z_low_limbs, z_high_limbs); + auto reconstructed_z2 = reconstruct_from_two(z_low_limbs_shift, z_high_limbs_shift); + auto reconstructed_quotient = reconstruct_from_four(quotient_low_binary_limbs, + quotient_low_binary_limbs_shift, + quotient_high_binary_limbs, + quotient_high_binary_limbs_shift); + + // Contribution (3). Evaluating integer relation over native field + // clang-format off + // the native limb index is 4 + tmp = reconstructed_previous_accumulator * evaluation_input_x_4 + + op + + reconstructed_p_x * v_0_4 + + reconstructed_p_y * v_1_4 + + reconstructed_z1 * v_2_4 + + reconstructed_z2 * v_3_4 + + reconstructed_quotient * NEGATIVE_MODULUS_LIMBS[4] + - reconstructed_current_accumulator; + // clang-format on + tmp *= lagrange_odd_in_minicircuit; + tmp *= scaling_factor; + std::get<2>(accumulators) += tmp; +}; +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation.cpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation.cpp index 6fd66d454f6..81f96d8f8ff 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation.cpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation.cpp @@ -1,65 +1,6 @@ -#include "barretenberg/relations/translator_vm/translator_permutation_relation.hpp" -#include "barretenberg/translator_vm/goblin_translator_flavor.hpp" - +#include "barretenberg/relations/translator_vm/translator_permutation_relation_impl.hpp" +#include "barretenberg/translator_vm/translator_flavor.hpp" namespace bb { - -/** - * @brief Compute contribution of the goblin translator permutation relation for a given edge (internal function) - * - * @details There are 2 relations associated with enforcing the set permutation relation - * This file handles the relation that confirms faithful calculation of the grand - * product polynomial Z_perm. - * - * C(in(X)...) = - * ( z_perm(X) + lagrange_first(X) )*P(X) - * - ( z_perm_shift(X) + lagrange_last(X))*Q(X), - * where P(X) = Prod_{i=0:4} numerator_polynomial_i(X) + γ - * Q(X) = Prod_{i=0:4} ordered_range_constraint_i(X) + γ - * the first 4 numerator polynomials are concatenated range constraint polynomials and the last one is the constant - * extra numerator - * - * @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, .... - * @param scaling_factor optional term to scale the evaluation before adding to evals. - */ - -template -template -void GoblinTranslatorPermutationRelationImpl::accumulate(ContainerOverSubrelations& accumulators, - const AllEntities& in, - const Parameters& params, - const FF& scaling_factor) -{ - [&]() { - using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; - using View = typename Accumulator::View; - - auto z_perm = View(in.z_perm); - auto z_perm_shift = View(in.z_perm_shift); - auto lagrange_first = View(in.lagrange_first); - auto lagrange_last = View(in.lagrange_last); - - // Contribution (1) - std::get<0>(accumulators) += - (((z_perm + lagrange_first) * compute_grand_product_numerator(in, params)) - - ((z_perm_shift + lagrange_last) * compute_grand_product_denominator(in, params))) * - scaling_factor; - }(); - - [&]() { - using Accumulator = std::tuple_element_t<1, ContainerOverSubrelations>; - using View = typename Accumulator::View; - - auto z_perm_shift = View(in.z_perm_shift); - auto lagrange_last = View(in.lagrange_last); - - // Contribution (2) - std::get<1>(accumulators) += (lagrange_last * z_perm_shift) * scaling_factor; - }(); -}; - -template class GoblinTranslatorPermutationRelationImpl; -DEFINE_SUMCHECK_RELATION_CLASS(GoblinTranslatorPermutationRelationImpl, GoblinTranslatorFlavor); - -} // namespace bb +template class TranslatorPermutationRelationImpl; +DEFINE_SUMCHECK_RELATION_CLASS(TranslatorPermutationRelationImpl, TranslatorFlavor); +} // namespace bb \ No newline at end of file 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 8b304145c3b..b5b6f276ab5 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 @@ -3,7 +3,7 @@ namespace bb { -template class GoblinTranslatorPermutationRelationImpl { +template class TranslatorPermutationRelationImpl { public: using FF = FF_; // 1 + polynomial degree of this relation @@ -80,7 +80,6 @@ template class GoblinTranslatorPermutationRelationImpl { const FF& scaling_factor); }; -template -using GoblinTranslatorPermutationRelation = Relation>; +template using TranslatorPermutationRelation = Relation>; } // namespace bb 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 new file mode 100644 index 00000000000..6be0d17e022 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_permutation_relation_impl.hpp @@ -0,0 +1,61 @@ +#pragma once +#include "barretenberg/relations/translator_vm/translator_permutation_relation.hpp" + +namespace bb { + +/** + * @brief Compute contribution of the goblin translator permutation relation for a given edge (internal function) + * + * @details There are 2 relations associated with enforcing the set permutation relation + * This file handles the relation that confirms faithful calculation of the grand + * product polynomial Z_perm. + * + * C(in(X)...) = + * ( z_perm(X) + lagrange_first(X) )*P(X) + * - ( z_perm_shift(X) + lagrange_last(X))*Q(X), + * where P(X) = Prod_{i=0:4} numerator_polynomial_i(X) + γ + * Q(X) = Prod_{i=0:4} ordered_range_constraint_i(X) + γ + * the first 4 numerator polynomials are concatenated range constraint polynomials and the last one is the constant + * extra numerator + * + * @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, .... + * @param scaling_factor optional term to scale the evaluation before adding to evals. + */ + +template +template +void TranslatorPermutationRelationImpl::accumulate(ContainerOverSubrelations& accumulators, + const AllEntities& in, + const Parameters& params, + const FF& scaling_factor) +{ + [&]() { + using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>; + using View = typename Accumulator::View; + + const auto z_perm = View(in.z_perm); + const auto z_perm_shift = View(in.z_perm_shift); + const auto lagrange_first = View(in.lagrange_first); + const auto lagrange_last = View(in.lagrange_last); + + // Contribution (1) + std::get<0>(accumulators) += + (((z_perm + lagrange_first) * compute_grand_product_numerator(in, params)) - + ((z_perm_shift + lagrange_last) * compute_grand_product_denominator(in, params))) * + scaling_factor; + }(); + + [&]() { + using Accumulator = std::tuple_element_t<1, ContainerOverSubrelations>; + using View = typename Accumulator::View; + + const auto z_perm_shift = View(in.z_perm_shift); + const auto lagrange_last = View(in.lagrange_last); + + // Contribution (2) + std::get<1>(accumulators) += (lagrange_last * z_perm_shift) * scaling_factor; + }(); +}; +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/goblin_translator_relation_consistency.test.cpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_relation_consistency.test.cpp similarity index 98% rename from barretenberg/cpp/src/barretenberg/relations/translator_vm/goblin_translator_relation_consistency.test.cpp rename to barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_relation_consistency.test.cpp index bac3b7b1a99..4a7b8cdcde9 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/goblin_translator_relation_consistency.test.cpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_relation_consistency.test.cpp @@ -1,5 +1,5 @@ /** - * @file goblin_translator_relation_consistency.test.cpp + * @file translator_relation_consistency.test.cpp * @brief Show that relation arithmetic has a simple form. * @details The purpose of this test suite is to show that the identity arithmetic implemented in the Relations is * equivalent to a simpler unoptimized version implemented in the tests themselves. This is useful 1) as documentation @@ -11,12 +11,12 @@ * satisfied in general by random inputs) only that the two implementations are equivalent. * */ -#include "barretenberg/translator_vm/goblin_translator_flavor.hpp" +#include "barretenberg/translator_vm/translator_flavor.hpp" #include using namespace bb; -using Flavor = GoblinTranslatorFlavor; +using Flavor = TranslatorFlavor; using FF = typename Flavor::FF; using InputElements = typename Flavor::AllValues; @@ -40,7 +40,7 @@ InputElements get_special_input() // use non-random values return result; } -class GoblinTranslatorRelationConsistency : public testing::Test { +class TranslatorRelationConsistency : public testing::Test { public: template static void validate_relation_execution(const auto& expected_values, @@ -54,10 +54,10 @@ class GoblinTranslatorRelationConsistency : public testing::Test { }; }; -TEST_F(GoblinTranslatorRelationConsistency, PermutationRelation) +TEST_F(TranslatorRelationConsistency, PermutationRelation) { const auto run_test = [](bool random_inputs) { - using Relation = GoblinTranslatorPermutationRelation; + using Relation = TranslatorPermutationRelation; using RelationValues = typename Relation::SumcheckArrayOfValuesOverSubrelations; const InputElements input_elements = random_inputs ? get_random_input() : get_special_input(); @@ -102,10 +102,10 @@ TEST_F(GoblinTranslatorRelationConsistency, PermutationRelation) run_test(/*random_inputs=*/true); }; -TEST_F(GoblinTranslatorRelationConsistency, DeltaRangeConstraintRelation) +TEST_F(TranslatorRelationConsistency, DeltaRangeConstraintRelation) { const auto run_test = [](bool random_inputs) { - using Relation = GoblinTranslatorDeltaRangeConstraintRelation; + using Relation = TranslatorDeltaRangeConstraintRelation; using RelationValues = typename Relation::SumcheckArrayOfValuesOverSubrelations; const InputElements input_elements = random_inputs ? get_random_input() : get_special_input(); @@ -166,10 +166,10 @@ TEST_F(GoblinTranslatorRelationConsistency, DeltaRangeConstraintRelation) run_test(/*random_inputs=*/true); }; -TEST_F(GoblinTranslatorRelationConsistency, DecompositionRelation) +TEST_F(TranslatorRelationConsistency, DecompositionRelation) { const auto run_test = [](bool random_inputs) { - using Relation = GoblinTranslatorDecompositionRelation; + using Relation = TranslatorDecompositionRelation; using RelationValues = typename Relation::SumcheckArrayOfValuesOverSubrelations; const InputElements input_elements = random_inputs ? get_random_input() : get_special_input(); @@ -715,10 +715,10 @@ TEST_F(GoblinTranslatorRelationConsistency, DecompositionRelation) run_test(/*random_inputs=*/true); }; -TEST_F(GoblinTranslatorRelationConsistency, OpcodeConstraintRelation) +TEST_F(TranslatorRelationConsistency, OpcodeConstraintRelation) { const auto run_test = [](bool random_inputs) { - using Relation = GoblinTranslatorOpcodeConstraintRelation; + using Relation = TranslatorOpcodeConstraintRelation; using RelationValues = typename Relation::SumcheckArrayOfValuesOverSubrelations; const InputElements input_elements = random_inputs ? get_random_input() : get_special_input(); @@ -738,10 +738,10 @@ TEST_F(GoblinTranslatorRelationConsistency, OpcodeConstraintRelation) run_test(/*random_inputs=*/true); }; -TEST_F(GoblinTranslatorRelationConsistency, AccumulatorTransferRelation) +TEST_F(TranslatorRelationConsistency, AccumulatorTransferRelation) { const auto run_test = [](bool random_inputs) { - using Relation = GoblinTranslatorAccumulatorTransferRelation; + using Relation = TranslatorAccumulatorTransferRelation; using RelationValues = typename Relation::SumcheckArrayOfValuesOverSubrelations; const InputElements input_elements = random_inputs ? get_random_input() : get_special_input(); @@ -792,7 +792,7 @@ TEST_F(GoblinTranslatorRelationConsistency, AccumulatorTransferRelation) run_test(/*random_inputs=*/true); }; -TEST_F(GoblinTranslatorRelationConsistency, NonNativeFieldRelation) +TEST_F(TranslatorRelationConsistency, NonNativeFieldRelation) { const auto run_test = [](bool random_inputs) { constexpr size_t NUM_LIMB_BITS = 68; @@ -810,7 +810,7 @@ TEST_F(GoblinTranslatorRelationConsistency, NonNativeFieldRelation) -FF(curve::BN254::BaseField::modulus) }; - using Relation = GoblinTranslatorNonNativeFieldRelation; + using Relation = TranslatorNonNativeFieldRelation; using RelationValues = typename Relation::SumcheckArrayOfValuesOverSubrelations; const InputElements input_elements = random_inputs ? get_random_input() : get_special_input(); diff --git a/barretenberg/cpp/src/barretenberg/relations/utils.hpp b/barretenberg/cpp/src/barretenberg/relations/utils.hpp index 680f9190427..f5d3c5470b7 100644 --- a/barretenberg/cpp/src/barretenberg/relations/utils.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/utils.hpp @@ -2,9 +2,6 @@ #include "barretenberg/flavor/flavor.hpp" #include "barretenberg/polynomials/pow.hpp" #include "barretenberg/relations/relation_parameters.hpp" -#include "barretenberg/stdlib_circuit_builders/goblin_ultra_flavor.hpp" -#include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp" - namespace bb { template class RelationUtils { diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field_conversion.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field_conversion.cpp index 66a72dcd48d..6b17b953d88 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field_conversion.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field_conversion.cpp @@ -45,4 +45,7 @@ template fq convert_to_grumpkin_fr(Ult template fq convert_to_grumpkin_fr( GoblinUltraCircuitBuilder& builder, const fr& f); +template fq convert_to_grumpkin_fr(CircuitSimulatorBN254& builder, + const fr& f); + } // namespace bb::stdlib::field_conversion diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/goblin_ultra_recursive_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/goblin_ultra_recursive_flavor.hpp index 393014d1f48..373632d29ad 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/goblin_ultra_recursive_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/goblin_ultra_recursive_flavor.hpp @@ -76,7 +76,6 @@ template class GoblinUltraRecursiveFlavor_ { using RelationSeparator = std::array; // define the container for storing the univariate contribution from each relation in Sumcheck - using SumcheckTupleOfTuplesOfUnivariates = decltype(create_sumcheck_tuple_of_tuples_of_univariates()); using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values()); /** diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp index e72937089d6..1040dbea88c 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp @@ -97,7 +97,6 @@ template class UltraRecursiveFlavor_ { using RelationSeparator = std::array; // define the container for storing the univariate contribution from each relation in Sumcheck - using SumcheckTupleOfTuplesOfUnivariates = decltype(create_sumcheck_tuple_of_tuples_of_univariates()); using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values()); private: diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.cpp deleted file mode 100644 index 5607769937d..00000000000 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.cpp +++ /dev/null @@ -1,302 +0,0 @@ -#include "./goblin_translator_verifier.hpp" -#include "barretenberg/commitment_schemes/zeromorph/zeromorph.hpp" -#include "barretenberg/sumcheck/sumcheck.hpp" -#include "barretenberg/transcript/transcript.hpp" - -namespace bb { - -GoblinTranslatorVerifier::GoblinTranslatorVerifier( - const std::shared_ptr& verifier_key, - const std::shared_ptr& transcript) - : key(verifier_key) - , transcript(transcript) -{} - -GoblinTranslatorVerifier::GoblinTranslatorVerifier( - const std::shared_ptr& proving_key, - const std::shared_ptr& transcript) - : GoblinTranslatorVerifier(std::make_shared(proving_key), transcript){}; - -void GoblinTranslatorVerifier::put_translation_data_in_relation_parameters(const uint256_t& evaluation_input_x, - const BF& batching_challenge_v, - const uint256_t& accumulated_result) -{ - - const auto compute_four_limbs = [](const auto& in) { - constexpr size_t NUM_LIMB_BITS = Flavor::NUM_LIMB_BITS; - return std::array{ in.slice(0, NUM_LIMB_BITS), - in.slice(NUM_LIMB_BITS, NUM_LIMB_BITS * 2), - in.slice(NUM_LIMB_BITS * 2, NUM_LIMB_BITS * 3), - in.slice(NUM_LIMB_BITS * 3, NUM_LIMB_BITS * 4) }; - }; - - const auto compute_five_limbs = [](const auto& in) { - constexpr size_t NUM_LIMB_BITS = Flavor::NUM_LIMB_BITS; - return std::array{ in.slice(0, NUM_LIMB_BITS), - in.slice(NUM_LIMB_BITS, NUM_LIMB_BITS * 2), - in.slice(NUM_LIMB_BITS * 2, NUM_LIMB_BITS * 3), - in.slice(NUM_LIMB_BITS * 3, NUM_LIMB_BITS * 4), - in }; - }; - - relation_parameters.evaluation_input_x = compute_five_limbs(evaluation_input_x); - - uint256_t batching_challenge_v_power{ batching_challenge_v }; - for (size_t i = 0; i < 4; i++) { - relation_parameters.batching_challenge_v[i] = compute_five_limbs(batching_challenge_v_power); - batching_challenge_v_power = BF(batching_challenge_v_power) * batching_challenge_v; - } - - relation_parameters.accumulated_result = compute_four_limbs(accumulated_result); -}; - -/** - * @brief This function verifies an GoblinTranslatorFlavor Honk proof for given program settings. - */ -bool GoblinTranslatorVerifier::verify_proof(const HonkProof& proof) -{ - batching_challenge_v = transcript->template get_challenge("Translation:batching_challenge"); - transcript->load_proof(proof); - - Flavor::VerifierCommitments commitments{ key }; - Flavor::CommitmentLabels commitment_labels; - - // TODO(Adrian): Change the initialization of the transcript to take the VK hash? - const auto circuit_size = transcript->template receive_from_prover("circuit_size"); - evaluation_input_x = transcript->template receive_from_prover("evaluation_input_x"); - - const BF accumulated_result = transcript->template receive_from_prover("accumulated_result"); - - put_translation_data_in_relation_parameters(evaluation_input_x, batching_challenge_v, accumulated_result); - - if (circuit_size != key->circuit_size) { - return false; - } - - // Get all the values of wires - const auto receive_commitment = [&](const std::string& label) { - return transcript->template receive_from_prover(label); - }; - - commitments.op = receive_commitment(commitment_labels.op); - commitments.x_lo_y_hi = receive_commitment(commitment_labels.x_lo_y_hi); - commitments.x_hi_z_1 = receive_commitment(commitment_labels.x_hi_z_1); - commitments.y_lo_z_2 = receive_commitment(commitment_labels.y_lo_z_2); - commitments.p_x_low_limbs = receive_commitment(commitment_labels.p_x_low_limbs); - commitments.p_x_low_limbs_range_constraint_0 = - receive_commitment(commitment_labels.p_x_low_limbs_range_constraint_0); - commitments.p_x_low_limbs_range_constraint_1 = - receive_commitment(commitment_labels.p_x_low_limbs_range_constraint_1); - commitments.p_x_low_limbs_range_constraint_2 = - receive_commitment(commitment_labels.p_x_low_limbs_range_constraint_2); - commitments.p_x_low_limbs_range_constraint_3 = - receive_commitment(commitment_labels.p_x_low_limbs_range_constraint_3); - commitments.p_x_low_limbs_range_constraint_4 = - receive_commitment(commitment_labels.p_x_low_limbs_range_constraint_4); - commitments.p_x_low_limbs_range_constraint_tail = - receive_commitment(commitment_labels.p_x_low_limbs_range_constraint_tail); - commitments.p_x_high_limbs = receive_commitment(commitment_labels.p_x_high_limbs); - commitments.p_x_high_limbs_range_constraint_0 = - receive_commitment(commitment_labels.p_x_high_limbs_range_constraint_0); - commitments.p_x_high_limbs_range_constraint_1 = - receive_commitment(commitment_labels.p_x_high_limbs_range_constraint_1); - commitments.p_x_high_limbs_range_constraint_2 = - receive_commitment(commitment_labels.p_x_high_limbs_range_constraint_2); - commitments.p_x_high_limbs_range_constraint_3 = - receive_commitment(commitment_labels.p_x_high_limbs_range_constraint_3); - commitments.p_x_high_limbs_range_constraint_4 = - receive_commitment(commitment_labels.p_x_high_limbs_range_constraint_4); - commitments.p_x_high_limbs_range_constraint_tail = - receive_commitment(commitment_labels.p_x_high_limbs_range_constraint_tail); - commitments.p_y_low_limbs = receive_commitment(commitment_labels.p_y_low_limbs); - commitments.p_y_low_limbs_range_constraint_0 = - receive_commitment(commitment_labels.p_y_low_limbs_range_constraint_0); - commitments.p_y_low_limbs_range_constraint_1 = - receive_commitment(commitment_labels.p_y_low_limbs_range_constraint_1); - commitments.p_y_low_limbs_range_constraint_2 = - receive_commitment(commitment_labels.p_y_low_limbs_range_constraint_2); - commitments.p_y_low_limbs_range_constraint_3 = - receive_commitment(commitment_labels.p_y_low_limbs_range_constraint_3); - commitments.p_y_low_limbs_range_constraint_4 = - receive_commitment(commitment_labels.p_y_low_limbs_range_constraint_4); - commitments.p_y_low_limbs_range_constraint_tail = - receive_commitment(commitment_labels.p_y_low_limbs_range_constraint_tail); - commitments.p_y_high_limbs = receive_commitment(commitment_labels.p_y_high_limbs); - commitments.p_y_high_limbs_range_constraint_0 = - receive_commitment(commitment_labels.p_y_high_limbs_range_constraint_0); - commitments.p_y_high_limbs_range_constraint_1 = - receive_commitment(commitment_labels.p_y_high_limbs_range_constraint_1); - commitments.p_y_high_limbs_range_constraint_2 = - receive_commitment(commitment_labels.p_y_high_limbs_range_constraint_2); - commitments.p_y_high_limbs_range_constraint_3 = - receive_commitment(commitment_labels.p_y_high_limbs_range_constraint_3); - commitments.p_y_high_limbs_range_constraint_4 = - receive_commitment(commitment_labels.p_y_high_limbs_range_constraint_4); - commitments.p_y_high_limbs_range_constraint_tail = - receive_commitment(commitment_labels.p_y_high_limbs_range_constraint_tail); - commitments.z_low_limbs = receive_commitment(commitment_labels.z_low_limbs); - commitments.z_low_limbs_range_constraint_0 = receive_commitment(commitment_labels.z_low_limbs_range_constraint_0); - commitments.z_low_limbs_range_constraint_1 = receive_commitment(commitment_labels.z_low_limbs_range_constraint_1); - commitments.z_low_limbs_range_constraint_2 = receive_commitment(commitment_labels.z_low_limbs_range_constraint_2); - commitments.z_low_limbs_range_constraint_3 = receive_commitment(commitment_labels.z_low_limbs_range_constraint_3); - commitments.z_low_limbs_range_constraint_4 = receive_commitment(commitment_labels.z_low_limbs_range_constraint_4); - commitments.z_low_limbs_range_constraint_tail = - receive_commitment(commitment_labels.z_low_limbs_range_constraint_tail); - commitments.z_high_limbs = receive_commitment(commitment_labels.z_high_limbs); - commitments.z_high_limbs_range_constraint_0 = receive_commitment(commitment_labels.z_high_limbs_range_constraint_0); - commitments.z_high_limbs_range_constraint_1 = receive_commitment(commitment_labels.z_high_limbs_range_constraint_1); - commitments.z_high_limbs_range_constraint_2 = receive_commitment(commitment_labels.z_high_limbs_range_constraint_2); - commitments.z_high_limbs_range_constraint_3 = receive_commitment(commitment_labels.z_high_limbs_range_constraint_3); - commitments.z_high_limbs_range_constraint_4 = receive_commitment(commitment_labels.z_high_limbs_range_constraint_4); - commitments.z_high_limbs_range_constraint_tail = - receive_commitment(commitment_labels.z_high_limbs_range_constraint_tail); - commitments.accumulators_binary_limbs_0 = receive_commitment(commitment_labels.accumulators_binary_limbs_0); - commitments.accumulators_binary_limbs_1 = receive_commitment(commitment_labels.accumulators_binary_limbs_1); - commitments.accumulators_binary_limbs_2 = receive_commitment(commitment_labels.accumulators_binary_limbs_2); - commitments.accumulators_binary_limbs_3 = receive_commitment(commitment_labels.accumulators_binary_limbs_3); - commitments.accumulator_low_limbs_range_constraint_0 = - receive_commitment(commitment_labels.accumulator_low_limbs_range_constraint_0); - commitments.accumulator_low_limbs_range_constraint_1 = - receive_commitment(commitment_labels.accumulator_low_limbs_range_constraint_1); - commitments.accumulator_low_limbs_range_constraint_2 = - receive_commitment(commitment_labels.accumulator_low_limbs_range_constraint_2); - commitments.accumulator_low_limbs_range_constraint_3 = - receive_commitment(commitment_labels.accumulator_low_limbs_range_constraint_3); - commitments.accumulator_low_limbs_range_constraint_4 = - receive_commitment(commitment_labels.accumulator_low_limbs_range_constraint_4); - commitments.accumulator_low_limbs_range_constraint_tail = - receive_commitment(commitment_labels.accumulator_low_limbs_range_constraint_tail); - commitments.accumulator_high_limbs_range_constraint_0 = - receive_commitment(commitment_labels.accumulator_high_limbs_range_constraint_0); - commitments.accumulator_high_limbs_range_constraint_1 = - receive_commitment(commitment_labels.accumulator_high_limbs_range_constraint_1); - commitments.accumulator_high_limbs_range_constraint_2 = - receive_commitment(commitment_labels.accumulator_high_limbs_range_constraint_2); - commitments.accumulator_high_limbs_range_constraint_3 = - receive_commitment(commitment_labels.accumulator_high_limbs_range_constraint_3); - commitments.accumulator_high_limbs_range_constraint_4 = - receive_commitment(commitment_labels.accumulator_high_limbs_range_constraint_4); - commitments.accumulator_high_limbs_range_constraint_tail = - receive_commitment(commitment_labels.accumulator_high_limbs_range_constraint_tail); - commitments.quotient_low_binary_limbs = receive_commitment(commitment_labels.quotient_low_binary_limbs); - commitments.quotient_high_binary_limbs = receive_commitment(commitment_labels.quotient_high_binary_limbs); - commitments.quotient_low_limbs_range_constraint_0 = - receive_commitment(commitment_labels.quotient_low_limbs_range_constraint_0); - commitments.quotient_low_limbs_range_constraint_1 = - receive_commitment(commitment_labels.quotient_low_limbs_range_constraint_1); - commitments.quotient_low_limbs_range_constraint_2 = - receive_commitment(commitment_labels.quotient_low_limbs_range_constraint_2); - commitments.quotient_low_limbs_range_constraint_3 = - receive_commitment(commitment_labels.quotient_low_limbs_range_constraint_3); - commitments.quotient_low_limbs_range_constraint_4 = - receive_commitment(commitment_labels.quotient_low_limbs_range_constraint_4); - commitments.quotient_low_limbs_range_constraint_tail = - receive_commitment(commitment_labels.quotient_low_limbs_range_constraint_tail); - commitments.quotient_high_limbs_range_constraint_0 = - receive_commitment(commitment_labels.quotient_high_limbs_range_constraint_0); - commitments.quotient_high_limbs_range_constraint_1 = - receive_commitment(commitment_labels.quotient_high_limbs_range_constraint_1); - commitments.quotient_high_limbs_range_constraint_2 = - receive_commitment(commitment_labels.quotient_high_limbs_range_constraint_2); - commitments.quotient_high_limbs_range_constraint_3 = - receive_commitment(commitment_labels.quotient_high_limbs_range_constraint_3); - commitments.quotient_high_limbs_range_constraint_4 = - receive_commitment(commitment_labels.quotient_high_limbs_range_constraint_4); - commitments.quotient_high_limbs_range_constraint_tail = - receive_commitment(commitment_labels.quotient_high_limbs_range_constraint_tail); - commitments.relation_wide_limbs = receive_commitment(commitment_labels.relation_wide_limbs); - commitments.relation_wide_limbs_range_constraint_0 = - receive_commitment(commitment_labels.relation_wide_limbs_range_constraint_0); - commitments.relation_wide_limbs_range_constraint_1 = - receive_commitment(commitment_labels.relation_wide_limbs_range_constraint_1); - commitments.relation_wide_limbs_range_constraint_2 = - receive_commitment(commitment_labels.relation_wide_limbs_range_constraint_2); - commitments.relation_wide_limbs_range_constraint_3 = - receive_commitment(commitment_labels.relation_wide_limbs_range_constraint_3); - commitments.ordered_range_constraints_0 = receive_commitment(commitment_labels.ordered_range_constraints_0); - commitments.ordered_range_constraints_1 = receive_commitment(commitment_labels.ordered_range_constraints_1); - commitments.ordered_range_constraints_2 = receive_commitment(commitment_labels.ordered_range_constraints_2); - commitments.ordered_range_constraints_3 = receive_commitment(commitment_labels.ordered_range_constraints_3); - commitments.ordered_range_constraints_4 = receive_commitment(commitment_labels.ordered_range_constraints_4); - - // Get permutation challenges - FF gamma = transcript->template get_challenge("gamma"); - - relation_parameters.beta = 0; - 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 = receive_commitment(commitment_labels.z_perm); - - // Execute Sumcheck Verifier - const size_t log_circuit_size = numeric::get_msb(circuit_size); - auto sumcheck = SumcheckVerifier(log_circuit_size, transcript); - FF alpha = transcript->template get_challenge("Sumcheck:alpha"); - std::vector gate_challenges(static_cast(numeric::get_msb(key->circuit_size))); - for (size_t idx = 0; idx < gate_challenges.size(); idx++) { - gate_challenges[idx] = transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); - } - - auto [multivariate_challenge, claimed_evaluations, sumcheck_verified] = - sumcheck.verify(relation_parameters, alpha, gate_challenges); - - // If Sumcheck did not verify, return false - if (sumcheck_verified.has_value() && !sumcheck_verified.value()) { - return false; - } - - // Execute ZeroMorph rounds. See https://hackmd.io/dlf9xEwhTQyE3hiGbq4FsA?view for a complete description ofthe - // unrolled protocol. - auto pairing_points = - ZeroMorphVerifier_::verify(commitments.get_unshifted_without_concatenated(), - commitments.get_to_be_shifted(), - claimed_evaluations.get_unshifted_without_concatenated(), - claimed_evaluations.get_shifted(), - multivariate_challenge, - transcript, - commitments.get_concatenation_groups(), - claimed_evaluations.get_concatenated_constraints()); - - auto verified = key->pcs_verification_key->pairing_check(pairing_points[0], pairing_points[1]); - - return verified; -} - -bool GoblinTranslatorVerifier::verify_translation(const TranslationEvaluations& translation_evaluations) -{ - const auto reconstruct_from_array = [&](const auto& arr) { - const BF elt_0 = (static_cast(arr[0])); - const BF elt_1 = (static_cast(arr[1]) << 68); - const BF elt_2 = (static_cast(arr[2]) << 136); - const BF elt_3 = (static_cast(arr[3]) << 204); - const BF reconstructed = elt_0 + elt_1 + elt_2 + elt_3; - return reconstructed; - }; - - const auto& reconstruct_value_from_eccvm_evaluations = [&](const TranslationEvaluations& translation_evaluations, - auto& relation_parameters) { - const BF accumulated_result = reconstruct_from_array(relation_parameters.accumulated_result); - const BF x = reconstruct_from_array(relation_parameters.evaluation_input_x); - const BF v1 = reconstruct_from_array(relation_parameters.batching_challenge_v[0]); - const BF v2 = reconstruct_from_array(relation_parameters.batching_challenge_v[1]); - const BF v3 = reconstruct_from_array(relation_parameters.batching_challenge_v[2]); - const BF v4 = reconstruct_from_array(relation_parameters.batching_challenge_v[3]); - const BF& op = translation_evaluations.op; - const BF& Px = translation_evaluations.Px; - const BF& Py = translation_evaluations.Py; - const BF& z1 = translation_evaluations.z1; - const BF& z2 = translation_evaluations.z2; - - const BF eccvm_opening = (op + (v1 * Px) + (v2 * Py) + (v3 * z1) + (v4 * z2)); - // multiply by x here to deal with shift - return x * accumulated_result == eccvm_opening; - }; - - bool is_value_reconstructed = - reconstruct_value_from_eccvm_evaluations(translation_evaluations, relation_parameters); - return is_value_reconstructed; -} - -} // namespace bb 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 c1b1cca3778..14336957ea7 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/relation_correctness.test.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/relation_correctness.test.cpp @@ -1,6 +1,6 @@ #include "barretenberg/honk/proof_system/permutation_library.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_library.hpp" -#include "barretenberg/translator_vm/goblin_translator_flavor.hpp" +#include "barretenberg/translator_vm/translator_flavor.hpp" #include using namespace bb; @@ -29,7 +29,7 @@ template void check_relation(auto circuit_s } } -class GoblinTranslatorRelationCorrectnessTests : public ::testing::Test { +class TranslatorRelationCorrectnessTests : public ::testing::Test { protected: static void SetUpTestSuite() { bb::srs::init_crs_factory("../srs_db/ignition"); } }; @@ -38,9 +38,9 @@ class GoblinTranslatorRelationCorrectnessTests : public ::testing::Test { * @brief Test the correctness of GolbinTranslator's Permutation Relation * */ -TEST_F(GoblinTranslatorRelationCorrectnessTests, Permutation) +TEST_F(TranslatorRelationCorrectnessTests, Permutation) { - using Flavor = GoblinTranslatorFlavor; + using Flavor = TranslatorFlavor; using FF = typename Flavor::FF; using ProverPolynomials = typename Flavor::ProverPolynomials; using Polynomial = bb::Polynomial; @@ -137,7 +137,7 @@ TEST_F(GoblinTranslatorRelationCorrectnessTests, Permutation) fill_polynomial_with_random_14_bit_values(prover_polynomials.relation_wide_limbs_range_constraint_3); // Compute ordered range constraint polynomials that go in the denominator of the grand product polynomial - compute_goblin_translator_range_constraint_ordered_polynomials(prover_polynomials, mini_circuit_size); + compute_translator_range_constraint_ordered_polynomials(prover_polynomials, mini_circuit_size); // Compute the fixed numerator (part of verification key) prover_polynomials.compute_extra_range_constraint_numerator(); @@ -146,7 +146,7 @@ TEST_F(GoblinTranslatorRelationCorrectnessTests, Permutation) compute_concatenated_polynomials(prover_polynomials); // Compute the grand product polynomial - compute_grand_product>(prover_polynomials, params); + compute_grand_product>(prover_polynomials, params); prover_polynomials.z_perm_shift = prover_polynomials.z_perm.shifted(); using Relations = typename Flavor::Relations; @@ -155,9 +155,9 @@ TEST_F(GoblinTranslatorRelationCorrectnessTests, Permutation) check_relation>(full_circuit_size, prover_polynomials, params); } -TEST_F(GoblinTranslatorRelationCorrectnessTests, DeltaRangeConstraint) +TEST_F(TranslatorRelationCorrectnessTests, DeltaRangeConstraint) { - using Flavor = GoblinTranslatorFlavor; + using Flavor = TranslatorFlavor; using FF = typename Flavor::FF; using ProverPolynomials = typename Flavor::ProverPolynomials; using Polynomial = bb::Polynomial; @@ -176,7 +176,7 @@ TEST_F(GoblinTranslatorRelationCorrectnessTests, DeltaRangeConstraint) polynomial = Polynomial{ circuit_size }; } - // Construct lagrange polynomials that are needed for Goblin Translator's DeltaRangeConstraint Relation + // Construct lagrange polynomials that are needed for Translator's DeltaRangeConstraint Relation prover_polynomials.lagrange_first[0] = 1; prover_polynomials.lagrange_last[circuit_size - 1] = 1; @@ -231,13 +231,13 @@ TEST_F(GoblinTranslatorRelationCorrectnessTests, DeltaRangeConstraint) } /** - * @brief Test the correctness of GoblinTranslatorFlavor's extra relations (GoblinTranslatorOpcodeConstraintRelation - * and GoblinTranslatorAccumulatorTransferRelation) + * @brief Test the correctness of TranslatorFlavor's extra relations (TranslatorOpcodeConstraintRelation + * and TranslatorAccumulatorTransferRelation) * */ -TEST_F(GoblinTranslatorRelationCorrectnessTests, GoblinTranslatorExtraRelationsCorrectness) +TEST_F(TranslatorRelationCorrectnessTests, TranslatorExtraRelationsCorrectness) { - using Flavor = GoblinTranslatorFlavor; + using Flavor = TranslatorFlavor; using FF = typename Flavor::FF; using ProverPolynomials = typename Flavor::ProverPolynomials; using ProverPolynomialIds = typename Flavor::ProverPolynomialIds; @@ -334,12 +334,12 @@ TEST_F(GoblinTranslatorRelationCorrectnessTests, GoblinTranslatorExtraRelationsC check_relation>(circuit_size, prover_polynomials, params); } /** - * @brief Test the correctness of GoblinTranslatorFlavor's Decomposition Relation + * @brief Test the correctness of TranslatorFlavor's Decomposition Relation * */ -TEST_F(GoblinTranslatorRelationCorrectnessTests, Decomposition) +TEST_F(TranslatorRelationCorrectnessTests, Decomposition) { - using Flavor = GoblinTranslatorFlavor; + using Flavor = TranslatorFlavor; using FF = typename Flavor::FF; using BF = typename Flavor::BF; using ProverPolynomials = typename Flavor::ProverPolynomials; @@ -708,12 +708,12 @@ TEST_F(GoblinTranslatorRelationCorrectnessTests, Decomposition) } /** - * @brief Test the correctness of GoblinTranslatorFlavor's NonNativeField Relation + * @brief Test the correctness of TranslatorFlavor's NonNativeField Relation * */ -TEST_F(GoblinTranslatorRelationCorrectnessTests, NonNative) +TEST_F(TranslatorRelationCorrectnessTests, NonNative) { - using Flavor = GoblinTranslatorFlavor; + using Flavor = TranslatorFlavor; using FF = typename Flavor::FF; using BF = typename Flavor::BF; using ProverPolynomials = typename Flavor::ProverPolynomials; @@ -750,7 +750,7 @@ TEST_F(GoblinTranslatorRelationCorrectnessTests, NonNative) const auto evaluation_input_x = BF::random_element(&engine); // Generating all the values is pretty tedious, so just use CircuitBuilder - auto circuit_builder = GoblinTranslatorCircuitBuilder(batching_challenge_v, evaluation_input_x, op_queue); + auto circuit_builder = TranslatorCircuitBuilder(batching_challenge_v, evaluation_input_x, op_queue); // The non-native field relation uses limbs of evaluation_input_x and powers of batching_challenge_v as inputs RelationParameters params; diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator.fuzzer.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator.fuzzer.hpp similarity index 97% rename from barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator.fuzzer.hpp rename to barretenberg/cpp/src/barretenberg/translator_vm/translator.fuzzer.hpp index 407f202854a..eb54ebb9988 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator.fuzzer.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator.fuzzer.hpp @@ -1,12 +1,12 @@ /** - * @file goblin_translator.fuzzer.hpp + * @file translator.fuzzer.hpp * @author Rumata888 * @brief Contains common procedures used by the circuit builder fuzzer and the composer fuzzer * @date 2024-02-25 * */ #include "barretenberg/numeric/uint256/uint256.hpp" -#include "goblin_translator_circuit_builder.hpp" +#include "translator_circuit_builder.hpp" using namespace bb; diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.test.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator.test.cpp similarity index 80% rename from barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.test.cpp rename to barretenberg/cpp/src/barretenberg/translator_vm/translator.test.cpp index ce8ea528f12..62e3eefff30 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.test.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator.test.cpp @@ -2,16 +2,16 @@ #include "barretenberg/numeric/uint256/uint256.hpp" #include "barretenberg/relations/relation_parameters.hpp" #include "barretenberg/sumcheck/sumcheck_round.hpp" -#include "barretenberg/translator_vm/goblin_translator_circuit_builder.hpp" -#include "barretenberg/translator_vm/goblin_translator_prover.hpp" -#include "barretenberg/translator_vm/goblin_translator_verifier.hpp" +#include "barretenberg/translator_vm/translator_circuit_builder.hpp" +#include "barretenberg/translator_vm/translator_prover.hpp" +#include "barretenberg/translator_vm/translator_verifier.hpp" #include using namespace bb; namespace { -using CircuitBuilder = GoblinTranslatorFlavor::CircuitBuilder; -using Transcript = GoblinTranslatorFlavor::Transcript; +using CircuitBuilder = TranslatorFlavor::CircuitBuilder; +using Transcript = TranslatorFlavor::Transcript; using OpQueue = ECCOpQueue; auto& engine = numeric::get_debug_randomness(); @@ -33,7 +33,7 @@ void ensure_non_zero(auto& polynomial) ASSERT_TRUE(has_non_zero_coefficient); } -class GoblinTranslatorComposerTests : public ::testing::Test { +class TranslatorTests : public ::testing::Test { protected: static void SetUpTestSuite() { bb::srs::init_crs_factory("../srs_db/ignition"); } }; @@ -43,7 +43,7 @@ class GoblinTranslatorComposerTests : public ::testing::Test { * @brief Test simple circuit with public inputs * */ -TEST_F(GoblinTranslatorComposerTests, Basic) +TEST_F(TranslatorTests, Basic) { using G1 = g1::affine_element; using Fr = fr; @@ -71,12 +71,12 @@ TEST_F(GoblinTranslatorComposerTests, Basic) auto circuit_builder = CircuitBuilder(translation_batching_challenge, translation_evaluation_challenge, op_queue); EXPECT_TRUE(circuit_builder.check_circuit()); - GoblinTranslatorProver prover{ circuit_builder, prover_transcript }; + TranslatorProver prover{ circuit_builder, prover_transcript }; auto proof = prover.construct_proof(); auto verifier_transcript = std::make_shared(prover_transcript->proof_data); verifier_transcript->template receive_from_prover("init"); - GoblinTranslatorVerifier verifier(prover.key, verifier_transcript); + TranslatorVerifier verifier(prover.key, verifier_transcript); bool verified = verifier.verify_proof(proof); EXPECT_TRUE(verified); } diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_circuit_builder.cpp similarity index 94% rename from barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_circuit_builder.cpp rename to barretenberg/cpp/src/barretenberg/translator_vm/translator_circuit_builder.cpp index 4c05d017e59..9094e12a561 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_circuit_builder.cpp @@ -1,5 +1,5 @@ /** - * @file goblin_translator_circuit_builder.cpp + * @file translator_circuit_builder.cpp * @author @Rumata888 * @brief Circuit Logic generation for Goblin Plonk translator (checks equivalence of Queues/Transcripts for ECCVM and * Recursive Circuits) @@ -7,7 +7,7 @@ * @copyright Copyright (c) 2023 * */ -#include "goblin_translator_circuit_builder.hpp" +#include "translator_circuit_builder.hpp" #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/numeric/uint256/uint256.hpp" #include "barretenberg/plonk/proof_system/constants.hpp" @@ -32,34 +32,34 @@ using ECCVMOperation = ECCOpQueue::ECCVMOperation; * @param previous_accumulator The value of the previous accumulator (we assume standard decomposition into limbs) * @param batching_challenge_v The value of the challenge for batching polynomial evaluations * @param evaluation_input_x The value at which we evaluate the polynomials - * @return GoblinTranslatorCircuitBuilder::AccumulationInput + * @return TranslatorCircuitBuilder::AccumulationInput */ template -GoblinTranslatorCircuitBuilder::AccumulationInput generate_witness_values(Fr op_code, - Fr p_x_lo, - Fr p_x_hi, - Fr p_y_lo, - Fr p_y_hi, - Fr z1, - Fr z2, - Fq previous_accumulator, - Fq batching_challenge_v, - Fq evaluation_input_x) +TranslatorCircuitBuilder::AccumulationInput generate_witness_values(Fr op_code, + Fr p_x_lo, + Fr p_x_hi, + Fr p_y_lo, + Fr p_y_hi, + Fr z1, + Fr z2, + Fq previous_accumulator, + Fq batching_challenge_v, + Fq evaluation_input_x) { // All parameters are well-described in the header, this is just for convenience - constexpr size_t NUM_LIMB_BITS = GoblinTranslatorCircuitBuilder::NUM_LIMB_BITS; - constexpr size_t NUM_BINARY_LIMBS = GoblinTranslatorCircuitBuilder::NUM_BINARY_LIMBS; - constexpr size_t NUM_MICRO_LIMBS = GoblinTranslatorCircuitBuilder::NUM_MICRO_LIMBS; - constexpr size_t NUM_LAST_LIMB_BITS = GoblinTranslatorCircuitBuilder::NUM_LAST_LIMB_BITS; - constexpr size_t MICRO_LIMB_BITS = GoblinTranslatorCircuitBuilder::MICRO_LIMB_BITS; + constexpr size_t NUM_LIMB_BITS = TranslatorCircuitBuilder::NUM_LIMB_BITS; + constexpr size_t NUM_BINARY_LIMBS = TranslatorCircuitBuilder::NUM_BINARY_LIMBS; + constexpr size_t NUM_MICRO_LIMBS = TranslatorCircuitBuilder::NUM_MICRO_LIMBS; + constexpr size_t NUM_LAST_LIMB_BITS = TranslatorCircuitBuilder::NUM_LAST_LIMB_BITS; + constexpr size_t MICRO_LIMB_BITS = TranslatorCircuitBuilder::MICRO_LIMB_BITS; constexpr size_t TOP_STANDARD_MICROLIMB_BITS = NUM_LAST_LIMB_BITS % MICRO_LIMB_BITS; - constexpr size_t NUM_Z_BITS = GoblinTranslatorCircuitBuilder::NUM_Z_BITS; + constexpr size_t NUM_Z_BITS = TranslatorCircuitBuilder::NUM_Z_BITS; constexpr size_t TOP_Z_MICROLIMB_BITS = (NUM_Z_BITS % NUM_LIMB_BITS) % MICRO_LIMB_BITS; constexpr size_t TOP_QUOTIENT_MICROLIMB_BITS = - (GoblinTranslatorCircuitBuilder::NUM_QUOTIENT_BITS % NUM_LIMB_BITS) % MICRO_LIMB_BITS; - constexpr auto shift_1 = GoblinTranslatorCircuitBuilder::SHIFT_1; - constexpr auto neg_modulus_limbs = GoblinTranslatorCircuitBuilder::NEGATIVE_MODULUS_LIMBS; - constexpr auto shift_2_inverse = GoblinTranslatorCircuitBuilder::SHIFT_2_INVERSE; + (TranslatorCircuitBuilder::NUM_QUOTIENT_BITS % NUM_LIMB_BITS) % MICRO_LIMB_BITS; + constexpr auto shift_1 = TranslatorCircuitBuilder::SHIFT_1; + constexpr auto neg_modulus_limbs = TranslatorCircuitBuilder::NEGATIVE_MODULUS_LIMBS; + constexpr auto shift_2_inverse = TranslatorCircuitBuilder::SHIFT_2_INVERSE; /** * @brief A small function to transform a native element Fq into its bigfield representation in Fr scalars @@ -95,10 +95,9 @@ GoblinTranslatorCircuitBuilder::AccumulationInput generate_witness_values(Fr op_ * */ auto split_wide_limb_into_2_limbs = [](Fr& wide_limb) { - return std::array{ - Fr(uint256_t(wide_limb).slice(0, NUM_LIMB_BITS)), - Fr(uint256_t(wide_limb).slice(NUM_LIMB_BITS, 2 * NUM_LIMB_BITS)) - }; + return std::array{ Fr(uint256_t(wide_limb).slice(0, NUM_LIMB_BITS)), + Fr(uint256_t(wide_limb).slice( + NUM_LIMB_BITS, 2 * NUM_LIMB_BITS)) }; }; /** * @brief A method to split a full 68-bit limb into 5 14-bit limb and 1 shifted limb for a more secure constraint @@ -285,9 +284,9 @@ GoblinTranslatorCircuitBuilder::AccumulationInput generate_witness_values(Fr op_ // Get divided version auto high_wide_relation_limb_divided = high_wide_relation_limb * shift_2_inverse; - const auto last_limb_index = GoblinTranslatorCircuitBuilder::NUM_BINARY_LIMBS - 1; + const auto last_limb_index = TranslatorCircuitBuilder::NUM_BINARY_LIMBS - 1; - const auto NUM_Z_LIMBS = GoblinTranslatorCircuitBuilder::NUM_Z_LIMBS; + const auto NUM_Z_LIMBS = TranslatorCircuitBuilder::NUM_Z_LIMBS; std::array, NUM_BINARY_LIMBS> P_x_microlimbs; std::array, NUM_BINARY_LIMBS> P_y_microlimbs; std::array, NUM_Z_LIMBS> z_1_microlimbs; @@ -313,10 +312,10 @@ GoblinTranslatorCircuitBuilder::AccumulationInput generate_witness_values(Fr op_ z_1_microlimbs[i] = split_standard_limb_into_micro_limbs(z_1_limbs[i]); z_2_microlimbs[i] = split_standard_limb_into_micro_limbs(z_2_limbs[i]); } - z_1_microlimbs[GoblinTranslatorCircuitBuilder::NUM_Z_LIMBS - 1] = split_top_z_limb_into_micro_limbs( - z_1_limbs[GoblinTranslatorCircuitBuilder::NUM_Z_LIMBS - 1], TOP_Z_MICROLIMB_BITS); - z_2_microlimbs[GoblinTranslatorCircuitBuilder::NUM_Z_LIMBS - 1] = split_top_z_limb_into_micro_limbs( - z_2_limbs[GoblinTranslatorCircuitBuilder::NUM_Z_LIMBS - 1], TOP_Z_MICROLIMB_BITS); + z_1_microlimbs[TranslatorCircuitBuilder::NUM_Z_LIMBS - 1] = + split_top_z_limb_into_micro_limbs(z_1_limbs[TranslatorCircuitBuilder::NUM_Z_LIMBS - 1], TOP_Z_MICROLIMB_BITS); + z_2_microlimbs[TranslatorCircuitBuilder::NUM_Z_LIMBS - 1] = + split_top_z_limb_into_micro_limbs(z_2_limbs[TranslatorCircuitBuilder::NUM_Z_LIMBS - 1], TOP_Z_MICROLIMB_BITS); // Split current accumulator into microlimbs for range constraining for (size_t i = 0; i < last_limb_index; i++) { @@ -333,7 +332,7 @@ GoblinTranslatorCircuitBuilder::AccumulationInput generate_witness_values(Fr op_ split_top_limb_into_micro_limbs(quotient_limbs[last_limb_index], TOP_QUOTIENT_MICROLIMB_BITS); // Start filling the witness container - GoblinTranslatorCircuitBuilder::AccumulationInput input{ + TranslatorCircuitBuilder::AccumulationInput input{ .op_code = op_code, .P_x_lo = p_x_lo, .P_x_hi = p_x_hi, @@ -372,7 +371,7 @@ GoblinTranslatorCircuitBuilder::AccumulationInput generate_witness_values(Fr op_ * * @param acc_step */ -void GoblinTranslatorCircuitBuilder::create_accumulation_gate(const AccumulationInput acc_step) +void TranslatorCircuitBuilder::create_accumulation_gate(const AccumulationInput acc_step) { // The first wires OpQueue/Transcript wires // Opcode should be {0,1,2,3,4,8} @@ -560,13 +559,13 @@ void GoblinTranslatorCircuitBuilder::create_accumulation_gate(const Accumulation * accumulation * * @tparam Fq - * @return GoblinTranslatorCircuitBuilder::AccumulationInput + * @return TranslatorCircuitBuilder::AccumulationInput */ template -GoblinTranslatorCircuitBuilder::AccumulationInput compute_witness_values_for_one_ecc_op(const ECCVMOperation& ecc_op, - Fq previous_accumulator, - Fq batching_challenge_v, - Fq evaluation_input_x) +TranslatorCircuitBuilder::AccumulationInput compute_witness_values_for_one_ecc_op(const ECCVMOperation& ecc_op, + Fq previous_accumulator, + Fq batching_challenge_v, + Fq evaluation_input_x) { using Fr = bb::fr; @@ -578,14 +577,12 @@ GoblinTranslatorCircuitBuilder::AccumulationInput compute_witness_values_for_one Fr p_y_hi(0); // Split P.x and P.y into their representations in bn254 transcript - p_x_lo = Fr(uint256_t(ecc_op.base_point.x).slice(0, 2 * GoblinTranslatorCircuitBuilder::NUM_LIMB_BITS)); + p_x_lo = Fr(uint256_t(ecc_op.base_point.x).slice(0, 2 * TranslatorCircuitBuilder::NUM_LIMB_BITS)); p_x_hi = Fr(uint256_t(ecc_op.base_point.x) - .slice(2 * GoblinTranslatorCircuitBuilder::NUM_LIMB_BITS, - 4 * GoblinTranslatorCircuitBuilder::NUM_LIMB_BITS)); - p_y_lo = Fr(uint256_t(ecc_op.base_point.y).slice(0, 2 * GoblinTranslatorCircuitBuilder::NUM_LIMB_BITS)); + .slice(2 * TranslatorCircuitBuilder::NUM_LIMB_BITS, 4 * TranslatorCircuitBuilder::NUM_LIMB_BITS)); + p_y_lo = Fr(uint256_t(ecc_op.base_point.y).slice(0, 2 * TranslatorCircuitBuilder::NUM_LIMB_BITS)); p_y_hi = Fr(uint256_t(ecc_op.base_point.y) - .slice(2 * GoblinTranslatorCircuitBuilder::NUM_LIMB_BITS, - 4 * GoblinTranslatorCircuitBuilder::NUM_LIMB_BITS)); + .slice(2 * TranslatorCircuitBuilder::NUM_LIMB_BITS, 4 * TranslatorCircuitBuilder::NUM_LIMB_BITS)); // Generate the full witness values return generate_witness_values(op, @@ -599,7 +596,7 @@ GoblinTranslatorCircuitBuilder::AccumulationInput compute_witness_values_for_one batching_challenge_v, evaluation_input_x); } -void GoblinTranslatorCircuitBuilder::feed_ecc_op_queue_into_circuit(std::shared_ptr ecc_op_queue) +void TranslatorCircuitBuilder::feed_ecc_op_queue_into_circuit(std::shared_ptr ecc_op_queue) { using Fq = bb::fq; const auto& raw_ops = ecc_op_queue->get_raw_ops(); @@ -640,7 +637,7 @@ void GoblinTranslatorCircuitBuilder::feed_ecc_op_queue_into_circuit(std::shared_ create_accumulation_gate(one_accumulation_step); } } -bool GoblinTranslatorCircuitBuilder::check_circuit() +bool TranslatorCircuitBuilder::check_circuit() { // Compute the limbs of evaluation_input_x and powers of batching_challenge_v (these go into the relation) RelationInputs relation_inputs = compute_relation_inputs_limbs(batching_challenge_v, evaluation_input_x); @@ -1066,6 +1063,6 @@ bool GoblinTranslatorCircuitBuilder::check_circuit() } return true; }; -template GoblinTranslatorCircuitBuilder::AccumulationInput generate_witness_values( +template TranslatorCircuitBuilder::AccumulationInput generate_witness_values( bb::fr, bb::fr, bb::fr, bb::fr, bb::fr, bb::fr, bb::fr, bb::fq, bb::fq, bb::fq); } // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_circuit_builder.fuzzer.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_circuit_builder.fuzzer.cpp similarity index 92% rename from barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_circuit_builder.fuzzer.cpp rename to barretenberg/cpp/src/barretenberg/translator_vm/translator_circuit_builder.fuzzer.cpp index 7a93e3bf157..aac38c9b9ca 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_circuit_builder.fuzzer.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_circuit_builder.fuzzer.cpp @@ -1,4 +1,4 @@ -#include "barretenberg/translator_vm/goblin_translator.fuzzer.hpp" +#include "barretenberg/translator_vm/translator.fuzzer.hpp" /** * @brief A very primitive fuzzing harness, no interesting mutations, just parse and throw at the circuit builder * @@ -14,7 +14,7 @@ extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) } auto [batching_challenge, x, op_queue] = parsing_result.value(); // Construct the circuit - auto circuit_builder = GoblinTranslatorCircuitBuilder(batching_challenge, x, op_queue); + auto circuit_builder = TranslatorCircuitBuilder(batching_challenge, x, op_queue); Fq x_inv = x.invert(); auto op_accumulator = Fq(0); diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_circuit_builder.hpp similarity index 89% rename from barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_circuit_builder.hpp rename to barretenberg/cpp/src/barretenberg/translator_vm/translator_circuit_builder.hpp index 680a0b57472..d72cb072bf3 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_circuit_builder.hpp @@ -1,6 +1,6 @@ #pragma once /** - * @file goblin_translator_builder.hpp + * @file translator_builder.hpp * @author @Rumata888 * @brief Circuit Logic generation for Goblin Plonk translator (checks equivalence of Queues/Transcripts for ECCVM and * Recursive Circuits) @@ -17,10 +17,10 @@ namespace bb { /** - * @brief GoblinTranslatorCircuitBuilder creates a circuit that evaluates the correctness of the evaluation of + * @brief TranslatorCircuitBuilder creates a circuit that evaluates the correctness of the evaluation of * EccOpQueue in Fq while operating in the Fr scalar field (r is the modulus of Fr and p is the modulus of Fp) * - * @details Goblin Translator Circuit Builder builds a circuit the purpose of which is to calculate the batched + * @details Translator Circuit Builder builds a circuit the purpose of which is to calculate the batched * evaluation of 5 polynomials in non-native field represented through coefficients in 4 native polynomials (op, * x_lo_y_hi, x_hi_z_1, y_lo_z_2): * @@ -31,7 +31,7 @@ namespace bb { * X_* and Y_* are supposed to be the decompositions of bn254 base fields elements P.x and P.y and are split into two * chunks each because the scalar field we are operating on can't fit them * - * Goblin Translator calculates the result of evaluation of a polynomial op + P.x⋅v +P.y⋅v² + z1 ⋅ v³ + z2⋅v⁴ at the + * Translator calculates the result of evaluation of a polynomial op + P.x⋅v +P.y⋅v² + z1 ⋅ v³ + z2⋅v⁴ at the * given challenge x (evaluation_input_x). For this it uses logic similar to the stdlib bigfield class. We operate in Fr * while trying to calculate values in Fq. To show that a⋅b=c mod p, we: * 1) Compute a⋅b in integers @@ -41,7 +41,7 @@ namespace bb { * This ensures that the logic is sound modulo 2²⁷²⋅r, which means it's correct in integers, if all the values are * sufficiently constrained (there is no way to undeflow or overflow) * - * Concretely, Goblin Translator computes one accumulation every two gates: + * Concretely, Translator computes one accumulation every two gates: * previous_accumulator⋅x + op + P.x⋅v +P.y⋅v² + z1⋅v³ + z2⋅v⁴ = current_accumulator mod p. Because of the nature of * polynomial commitment, previous_accumulator is located at higher index than the current_accumulator. Values of x * (evaluation_input_x) and v (batching_challenge_v) are precomputed and considered inputs to the relations. @@ -58,7 +58,7 @@ namespace bb { * dividing the result by 2¹³⁶ and range constraining it). Then we use the overlow and higher limbs to prove the same * modulo 2¹³⁶ again and as a result we get correctness modulo 2²⁷². * - * One big issue are range constraints. In Goblin Translator we check ranges by decomposing LIMBS into special other + * One big issue are range constraints. In Translator we check ranges by decomposing LIMBS into special other * range constrained MICROLIMBS (have "_CONSTRAINT_" in the name of their wires). These wires always have the range of * 14 bits, so when we need to constrain something further we use two wires at once and scale the values (for example, * 68 bits are decomposed into 5 14-bit limbs + 1 shifted limb, which is equal to the highest microlimb multiplied by @@ -69,11 +69,11 @@ namespace bb { * microlimb. * */ -class GoblinTranslatorCircuitBuilder : public CircuitBuilderBase { +class TranslatorCircuitBuilder : public CircuitBuilderBase { // We don't need templating for Goblin using Fr = bb::fr; using Fq = bb::fq; - using Arithmetization = GoblinTranslatorArith; + using Arithmetization = TranslatorArith; public: static constexpr size_t NUM_WIRES = Arithmetization::NUM_WIRES; @@ -314,7 +314,7 @@ class GoblinTranslatorCircuitBuilder : public CircuitBuilderBase { std::array v_cubed_limbs = { 0 }; std::array v_quarted_limbs = { 0 }; }; - static constexpr std::string_view NAME_STRING = "GoblinTranslatorArithmetization"; + static constexpr std::string_view NAME_STRING = "TranslatorArithmetization"; // The challenge that is used for batching together evaluations of several polynomials Fq batching_challenge_v; @@ -325,15 +325,15 @@ class GoblinTranslatorCircuitBuilder : public CircuitBuilderBase { std::array>, NUM_WIRES> wires; /** - * @brief Construct a new Goblin Translator Circuit Builder object + * @brief Construct a new Translator Circuit Builder object * - * @details Goblin Translator Circuit builder has to be initializaed with evaluation input and batching challenge + * @details Translator Circuit builder has to be initializaed with evaluation input and batching challenge * (they are used to compute witness and to store the value for the prover) * * @param batching_challenge_v_ * @param evaluation_input_x_ */ - GoblinTranslatorCircuitBuilder(Fq batching_challenge_v_, Fq evaluation_input_x_) + TranslatorCircuitBuilder(Fq batching_challenge_v_, Fq evaluation_input_x_) : CircuitBuilderBase(DEFAULT_TRANSLATOR_VM_LENGTH) , batching_challenge_v(batching_challenge_v_) , evaluation_input_x(evaluation_input_x_) @@ -346,35 +346,33 @@ class GoblinTranslatorCircuitBuilder : public CircuitBuilderBase { }; /** - * @brief Construct a new Goblin Translator Circuit Builder object and feed op_queue inside + * @brief Construct a new Translator Circuit Builder object and feed op_queue inside * - * @details Goblin Translator Circuit builder has to be initialized with evaluation input and batching challenge + * @details Translator Circuit builder has to be initialized with evaluation input and batching challenge * (they are used to compute witness and to store the value for the prover) * * @param batching_challenge_v_ * @param evaluation_input_x_ * @param op_queue */ - GoblinTranslatorCircuitBuilder(Fq batching_challenge_v_, - Fq evaluation_input_x_, - std::shared_ptr op_queue) - : GoblinTranslatorCircuitBuilder(batching_challenge_v_, evaluation_input_x_) + TranslatorCircuitBuilder(Fq batching_challenge_v_, Fq evaluation_input_x_, std::shared_ptr op_queue) + : TranslatorCircuitBuilder(batching_challenge_v_, evaluation_input_x_) { - BB_OP_COUNT_TIME_NAME("GoblinTranslatorCircuitBuilder::constructor"); + BB_OP_COUNT_TIME_NAME("TranslatorCircuitBuilder::constructor"); feed_ecc_op_queue_into_circuit(op_queue); } - GoblinTranslatorCircuitBuilder() = default; - GoblinTranslatorCircuitBuilder(const GoblinTranslatorCircuitBuilder& other) = delete; - GoblinTranslatorCircuitBuilder(GoblinTranslatorCircuitBuilder&& other) noexcept + TranslatorCircuitBuilder() = default; + TranslatorCircuitBuilder(const TranslatorCircuitBuilder& other) = delete; + TranslatorCircuitBuilder(TranslatorCircuitBuilder&& other) noexcept : CircuitBuilderBase(std::move(other)){}; - GoblinTranslatorCircuitBuilder& operator=(const GoblinTranslatorCircuitBuilder& other) = delete; - GoblinTranslatorCircuitBuilder& operator=(GoblinTranslatorCircuitBuilder&& other) noexcept + TranslatorCircuitBuilder& operator=(const TranslatorCircuitBuilder& other) = delete; + TranslatorCircuitBuilder& operator=(TranslatorCircuitBuilder&& other) noexcept { CircuitBuilderBase::operator=(std::move(other)); return *this; }; - ~GoblinTranslatorCircuitBuilder() override = default; + ~TranslatorCircuitBuilder() override = default; /** * @brief Create limb representations of x and powers of v that are needed to compute the witness or check @@ -459,14 +457,14 @@ class GoblinTranslatorCircuitBuilder : public CircuitBuilderBase { bool check_circuit(); }; template -GoblinTranslatorCircuitBuilder::AccumulationInput generate_witness_values(Fr op_code, - Fr p_x_lo, - Fr p_x_hi, - Fr p_y_lo, - Fr p_y_hi, - Fr z1, - Fr z2, - Fq previous_accumulator, - Fq batching_challenge_v, - Fq evaluation_input_x); +TranslatorCircuitBuilder::AccumulationInput generate_witness_values(Fr op_code, + Fr p_x_lo, + Fr p_x_hi, + Fr p_y_lo, + Fr p_y_hi, + Fr z1, + Fr z2, + Fq previous_accumulator, + Fq batching_challenge_v, + Fq evaluation_input_x); } // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_circuit_builder.test.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_circuit_builder.test.cpp similarity index 87% rename from barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_circuit_builder.test.cpp rename to barretenberg/cpp/src/barretenberg/translator_vm/translator_circuit_builder.test.cpp index ee3a785fc58..d1d5e921431 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_circuit_builder.test.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_circuit_builder.test.cpp @@ -1,4 +1,4 @@ -#include "goblin_translator_circuit_builder.hpp" +#include "translator_circuit_builder.hpp" #include "barretenberg/ecc/curves/bn254/bn254.hpp" #include "barretenberg/stdlib_circuit_builders/op_queue/ecc_op_queue.hpp" #include @@ -13,13 +13,13 @@ auto& engine = numeric::get_debug_randomness(); * @brief Check that a single accumulation gate is created correctly * */ -TEST(GoblinTranslatorCircuitBuilder, CircuitBuilderBaseCase) +TEST(TranslatorCircuitBuilder, CircuitBuilderBaseCase) { using Fr = ::curve::BN254::ScalarField; using Fq = ::curve::BN254::BaseField; - constexpr size_t NUM_LIMB_BITS = GoblinTranslatorCircuitBuilder::NUM_LIMB_BITS; - constexpr size_t NUM_Z_BITS = GoblinTranslatorCircuitBuilder::NUM_Z_BITS; + constexpr size_t NUM_LIMB_BITS = TranslatorCircuitBuilder::NUM_LIMB_BITS; + constexpr size_t NUM_Z_BITS = TranslatorCircuitBuilder::NUM_Z_BITS; // Generate random EccOpQueue transcript values Fr op; @@ -59,11 +59,11 @@ TEST(GoblinTranslatorCircuitBuilder, CircuitBuilderBaseCase) Fq previous_accumulator = Fq::random_element(); // Generate the witness for a single step - GoblinTranslatorCircuitBuilder::AccumulationInput single_accumulation_step = + TranslatorCircuitBuilder::AccumulationInput single_accumulation_step = generate_witness_values(op, p_x_lo, p_x_hi, p_y_lo, p_y_hi, z_1, z_2, previous_accumulator, v, x); // Create a circuit builder - auto circuit_builder = GoblinTranslatorCircuitBuilder(v, x); + auto circuit_builder = TranslatorCircuitBuilder(v, x); // Submit one accumulation step in the builder circuit_builder.create_accumulation_gate(single_accumulation_step); // Check if the circuit fails @@ -74,7 +74,7 @@ TEST(GoblinTranslatorCircuitBuilder, CircuitBuilderBaseCase) * @brief Check that the circuit can handle several accumulations * */ -TEST(GoblinTranslatorCircuitBuilder, SeveralOperationCorrectness) +TEST(TranslatorCircuitBuilder, SeveralOperationCorrectness) { using point = g1::affine_element; using scalar = fr; @@ -122,7 +122,7 @@ TEST(GoblinTranslatorCircuitBuilder, SeveralOperationCorrectness) x_pow; // Create circuit builder and feed the queue inside - auto circuit_builder = GoblinTranslatorCircuitBuilder(batching_challenge, x, op_queue); + auto circuit_builder = TranslatorCircuitBuilder(batching_challenge, x, op_queue); // Check that the circuit passes EXPECT_TRUE(circuit_builder.check_circuit()); // Check the computation result is in line with what we've computed diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.fuzzer.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_composer.fuzzer.cpp similarity index 65% rename from barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.fuzzer.cpp rename to barretenberg/cpp/src/barretenberg/translator_vm/translator_composer.fuzzer.cpp index 9865675145d..33636a911dc 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.fuzzer.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_composer.fuzzer.cpp @@ -1,6 +1,6 @@ -#include "barretenberg/translator_vm/goblin_translator.fuzzer.hpp" -#include "barretenberg/translator_vm/goblin_translator_prover.hpp" -#include "barretenberg/translator_vm/goblin_translator_verifier.hpp" +#include "barretenberg/translator_vm/translator.fuzzer.hpp" +#include "barretenberg/translator_vm/translator_prover.hpp" +#include "barretenberg/translator_vm/translator_verifier.hpp" extern "C" void LLVMFuzzerInitialize(int*, char***) { srs::init_crs_factory("../srs_db/ignition"); @@ -20,25 +20,25 @@ extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) return 0; } auto [batching_challenge_init, x, op_queue] = parsing_result.value(); - auto prover_transcript = std::make_shared(); + auto prover_transcript = std::make_shared(); prover_transcript->send_to_verifier("init", batching_challenge_init); prover_transcript->export_proof(); Fq translation_batching_challenge = prover_transcript->template get_challenge("Translation:batching_challenge"); // Construct circuit - auto circuit_builder = GoblinTranslatorCircuitBuilder(translation_batching_challenge, x, op_queue); + auto circuit_builder = TranslatorCircuitBuilder(translation_batching_challenge, x, op_queue); // Check that the circuit passes bool checked = circuit_builder.check_circuit(); // Construct proof - GoblinTranslatorProver prover(circuit_builder, prover_transcript); + TranslatorProver prover(circuit_builder, prover_transcript); auto proof = prover.construct_proof(); // Verify proof - auto verifier_transcript = std::make_shared(prover_transcript->proof_data); + auto verifier_transcript = std::make_shared(prover_transcript->proof_data); verifier_transcript->template receive_from_prover("init"); - GoblinTranslatorVerifier verifier(prover.key, verifier_transcript); + TranslatorVerifier verifier(prover.key, verifier_transcript); bool verified = verifier.verify_proof(proof); (void)checked; (void)verified; diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_flavor.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp similarity index 96% rename from barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_flavor.hpp rename to barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp index ff7cc5fffa8..d3823592a48 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp @@ -15,15 +15,15 @@ #include "barretenberg/relations/translator_vm/translator_extra_relations.hpp" #include "barretenberg/relations/translator_vm/translator_non_native_field_relation.hpp" #include "barretenberg/relations/translator_vm/translator_permutation_relation.hpp" -#include "barretenberg/translator_vm/goblin_translator_circuit_builder.hpp" +#include "barretenberg/translator_vm/translator_circuit_builder.hpp" namespace bb { -class GoblinTranslatorFlavor { +class TranslatorFlavor { public: static constexpr size_t mini_circuit_size = 2048; - using CircuitBuilder = GoblinTranslatorCircuitBuilder; + using CircuitBuilder = TranslatorCircuitBuilder; using Curve = curve::BN254; using PCS = KZG; using GroupElement = Curve::Element; @@ -79,14 +79,16 @@ class GoblinTranslatorFlavor { // The total number of witness entities not including shifts. static constexpr size_t NUM_WITNESS_ENTITIES = 91; - using GrandProductRelations = std::tuple>; + using GrandProductRelations = std::tuple>; // define the tuple of Relations that comprise the Sumcheck relation - using Relations = std::tuple, - GoblinTranslatorDeltaRangeConstraintRelation, - GoblinTranslatorOpcodeConstraintRelation, - GoblinTranslatorAccumulatorTransferRelation, - GoblinTranslatorDecompositionRelation, - GoblinTranslatorNonNativeFieldRelation>; + template + using Relations_ = std::tuple, + TranslatorDeltaRangeConstraintRelation, + TranslatorOpcodeConstraintRelation, + TranslatorAccumulatorTransferRelation, + TranslatorDecompositionRelation, + TranslatorNonNativeFieldRelation>; + using Relations = Relations_; static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); static constexpr size_t MAX_TOTAL_RELATION_LENGTH = compute_max_total_relation_length(); @@ -99,16 +101,15 @@ class GoblinTranslatorFlavor { static constexpr size_t NUM_RELATIONS = std::tuple_size_v; // define the containers for storing the contributions from each relation in Sumcheck - using SumcheckTupleOfTuplesOfUnivariates = std::tuple< - typename GoblinTranslatorPermutationRelation::SumcheckTupleOfUnivariatesOverSubrelations, - typename GoblinTranslatorDeltaRangeConstraintRelation::SumcheckTupleOfUnivariatesOverSubrelations, - typename GoblinTranslatorOpcodeConstraintRelation::SumcheckTupleOfUnivariatesOverSubrelations, - typename GoblinTranslatorAccumulatorTransferRelation::SumcheckTupleOfUnivariatesOverSubrelations, - typename GoblinTranslatorDecompositionRelation::SumcheckTupleOfUnivariatesOverSubrelations, - typename GoblinTranslatorNonNativeFieldRelation::SumcheckTupleOfUnivariatesOverSubrelations>; + using SumcheckTupleOfTuplesOfUnivariates = + std::tuple::SumcheckTupleOfUnivariatesOverSubrelations, + typename TranslatorDeltaRangeConstraintRelation::SumcheckTupleOfUnivariatesOverSubrelations, + typename TranslatorOpcodeConstraintRelation::SumcheckTupleOfUnivariatesOverSubrelations, + typename TranslatorAccumulatorTransferRelation::SumcheckTupleOfUnivariatesOverSubrelations, + typename TranslatorDecompositionRelation::SumcheckTupleOfUnivariatesOverSubrelations, + typename TranslatorNonNativeFieldRelation::SumcheckTupleOfUnivariatesOverSubrelations>; using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values()); - private: /** * @brief A base class labelling precomputed entities and (ordered) subsets of interest. * @details Used to build the proving key and verification key. @@ -117,14 +118,15 @@ class GoblinTranslatorFlavor { public: using DataType = DataType_; DEFINE_FLAVOR_MEMBERS(DataType, - lagrange_first, // column 0 - lagrange_last, // column 1 + + 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 2 - lagrange_even_in_minicircuit, // column 3 - lagrange_second, // column 4 - lagrange_second_to_last_in_minicircuit, // column 5 - ordered_extra_range_constraints_numerator); // column 6 + lagrange_odd_in_minicircuit, // column 3 + lagrange_even_in_minicircuit, // column 4 + lagrange_second, // column 5 + lagrange_second_to_last_in_minicircuit); // column 6 auto get_selectors() { return RefArray{}; }; auto get_sigma_polynomials() { return RefArray{}; }; auto get_id_polynomials() { return RefArray{}; }; @@ -145,9 +147,9 @@ class GoblinTranslatorFlavor { * @brief Compute the extra numerator for Goblin range constraint argument * * @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 (GoblinTranslatorPermutationRelation) + * 1) A grand product which ignores positions of elements (TranslatorPermutationRelation) * 2) A relation enforcing a certain ordering on the elements of the given polynomial - * (GoblinTranslatorDeltaRangeConstraintRelation) + * (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 @@ -552,6 +554,8 @@ class GoblinTranslatorFlavor { ordered_range_constraints_4_shift, // column 84 z_perm_shift) // column 85 }; + + public: /** * @brief A base class labelling all entities (for instance, all of the polynomials used by the prover during * sumcheck) in this Honk variant along with particular subsets of interest @@ -693,6 +697,11 @@ class GoblinTranslatorFlavor { // get_to_be_shifted is inherited auto get_shifted() { return ShiftedEntities::get_all(); }; + auto get_wires_and_ordered_range_constraints() + { + return WitnessEntities::get_wires_and_ordered_range_constraints(); + }; + /** * @brief Polynomials/commitments, that can be constructed only after the r challenge has been received from * gemini @@ -845,13 +854,10 @@ class GoblinTranslatorFlavor { */ class VerificationKey : public VerificationKey_, VerifierCommitmentKey> { public: - std::vector public_inputs; - VerificationKey(const size_t circuit_size, const size_t num_public_inputs) : VerificationKey_(circuit_size, num_public_inputs) {} VerificationKey(const std::shared_ptr& proving_key) - : public_inputs(proving_key->public_inputs) { this->pcs_verification_key = std::make_shared(); this->circuit_size = proving_key->circuit_size; @@ -1010,9 +1016,10 @@ class GoblinTranslatorFlavor { }; }; - class VerifierCommitments : public AllEntities { + template + class VerifierCommitments_ : public AllEntities { public: - VerifierCommitments(const std::shared_ptr& verification_key) + VerifierCommitments_(const std::shared_ptr& verification_key) { this->lagrange_first = verification_key->lagrange_first; this->lagrange_last = verification_key->lagrange_last; @@ -1024,6 +1031,7 @@ class GoblinTranslatorFlavor { verification_key->ordered_extra_range_constraints_numerator; } }; + using VerifierCommitments = VerifierCommitments_; using Transcript = NativeTranscript; }; diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_mini.fuzzer.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_mini.fuzzer.cpp similarity index 84% rename from barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_mini.fuzzer.cpp rename to barretenberg/cpp/src/barretenberg/translator_vm/translator_mini.fuzzer.cpp index f390dd0b8ef..94fe4e73495 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_mini.fuzzer.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_mini.fuzzer.cpp @@ -1,5 +1,5 @@ #include "barretenberg/numeric/uint256/uint256.hpp" -#include "goblin_translator_circuit_builder.hpp" +#include "translator_circuit_builder.hpp" using namespace bb; @@ -8,7 +8,7 @@ using Fq = curve::BN254::BaseField; extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) { - constexpr size_t NUM_LIMB_BITS = bb::GoblinTranslatorCircuitBuilder::NUM_LIMB_BITS; + constexpr size_t NUM_LIMB_BITS = bb::TranslatorCircuitBuilder::NUM_LIMB_BITS; constexpr size_t WIDE_LIMB_BYTES = 2 * NUM_LIMB_BITS / 8; constexpr size_t TOTAL_SIZE = 1 + 5 * sizeof(numeric::uint256_t) + 2 * WIDE_LIMB_BYTES; char buffer[32] = { 0 }; @@ -35,10 +35,10 @@ extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) memcpy(buffer, data + 1 + 5 * sizeof(uint256_t) + WIDE_LIMB_BYTES, WIDE_LIMB_BYTES); Fr z_2 = Fr(*(uint256_t*)(buffer)); - bb::GoblinTranslatorCircuitBuilder::AccumulationInput single_accumulation_step = + bb::TranslatorCircuitBuilder::AccumulationInput single_accumulation_step = bb::generate_witness_values(op, p_x_lo, p_x_hi, p_y_lo, p_y_hi, z_1, z_2, previous_accumulator, v, x); - auto circuit_builder = bb::GoblinTranslatorCircuitBuilder(v, x); + auto circuit_builder = bb::TranslatorCircuitBuilder(v, x); circuit_builder.create_accumulation_gate(single_accumulation_step); if (!circuit_builder.check_circuit()) { return 1; diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.cpp similarity index 88% rename from barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.cpp rename to barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.cpp index abf534b0247..f0b7101086b 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.cpp @@ -1,4 +1,4 @@ -#include "goblin_translator_prover.hpp" +#include "translator_prover.hpp" #include "barretenberg/commitment_schemes/claim.hpp" #include "barretenberg/commitment_schemes/commitment_key.hpp" #include "barretenberg/commitment_schemes/zeromorph/zeromorph.hpp" @@ -8,8 +8,7 @@ namespace bb { -GoblinTranslatorProver::GoblinTranslatorProver(CircuitBuilder& circuit_builder, - const std::shared_ptr& transcript) +TranslatorProver::TranslatorProver(CircuitBuilder& circuit_builder, const std::shared_ptr& transcript) : dyadic_circuit_size(Flavor::compute_dyadic_circuit_size(circuit_builder)) , mini_circuit_dyadic_size(Flavor::compute_mini_circuit_dyadic_size(circuit_builder)) , transcript(transcript) @@ -26,7 +25,7 @@ GoblinTranslatorProver::GoblinTranslatorProver(CircuitBuilder& circuit_builder, * @brief Compute witness polynomials * */ -void GoblinTranslatorProver::compute_witness(CircuitBuilder& circuit_builder) +void TranslatorProver::compute_witness(CircuitBuilder& circuit_builder) { if (computed_witness) { return; @@ -48,14 +47,12 @@ void GoblinTranslatorProver::compute_witness(CircuitBuilder& circuit_builder) // We also contruct ordered polynomials, which have the same values as concatenated ones + enough values to bridge // the range from 0 to maximum range defined by the range constraint. - bb::compute_goblin_translator_range_constraint_ordered_polynomials(key->polynomials, - mini_circuit_dyadic_size); + bb::compute_translator_range_constraint_ordered_polynomials(key->polynomials, mini_circuit_dyadic_size); computed_witness = true; } -std::shared_ptr GoblinTranslatorProver::compute_commitment_key( - size_t circuit_size) +std::shared_ptr TranslatorProver::compute_commitment_key(size_t circuit_size) { if (commitment_key) { return commitment_key; @@ -69,7 +66,7 @@ std::shared_ptr GoblinTranslatorProver::c * @brief Add circuit size and values used in the relations to the transcript * */ -void GoblinTranslatorProver::execute_preamble_round() +void TranslatorProver::execute_preamble_round() { const auto circuit_size = static_cast(key->circuit_size); const auto SHIFT = uint256_t(1) << Flavor::NUM_LIMB_BITS; @@ -88,7 +85,7 @@ void GoblinTranslatorProver::execute_preamble_round() * @brief Compute commitments to the first three wires * */ -void GoblinTranslatorProver::execute_wire_and_sorted_constraints_commitments_round() +void TranslatorProver::execute_wire_and_sorted_constraints_commitments_round() { // Commit to all wire polynomials and ordered range constraint polynomials auto wire_polys = key->polynomials.get_wires_and_ordered_range_constraints(); @@ -102,7 +99,7 @@ void GoblinTranslatorProver::execute_wire_and_sorted_constraints_commitments_rou * @brief Compute permutation product polynomial and commitments * */ -void GoblinTranslatorProver::execute_grand_product_computation_round() +void TranslatorProver::execute_grand_product_computation_round() { // Compute and store parameters required by relations in Sumcheck FF gamma = transcript->template get_challenge("gamma"); @@ -152,7 +149,7 @@ void GoblinTranslatorProver::execute_grand_product_computation_round() * @brief Run Sumcheck resulting in u = (u_1,...,u_d) challenges and all evaluations at u being calculated. * */ -void GoblinTranslatorProver::execute_relation_check_rounds() +void TranslatorProver::execute_relation_check_rounds() { using Sumcheck = SumcheckProver; @@ -170,7 +167,7 @@ void GoblinTranslatorProver::execute_relation_check_rounds() * @details See https://hackmd.io/dlf9xEwhTQyE3hiGbq4FsA?view for a complete description of the unrolled protocol. * * */ -void GoblinTranslatorProver::execute_zeromorph_rounds() +void TranslatorProver::execute_zeromorph_rounds() { using ZeroMorph = ZeroMorphProver_; ZeroMorph::prove(key->polynomials.get_unshifted_without_concatenated(), @@ -185,15 +182,15 @@ void GoblinTranslatorProver::execute_zeromorph_rounds() key->polynomials.get_concatenation_groups()); } -HonkProof GoblinTranslatorProver::export_proof() +HonkProof TranslatorProver::export_proof() { proof = transcript->export_proof(); return proof; } -HonkProof GoblinTranslatorProver::construct_proof() +HonkProof TranslatorProver::construct_proof() { - BB_OP_COUNT_TIME_NAME("GoblinTranslatorProver::construct_proof"); + BB_OP_COUNT_TIME_NAME("TranslatorProver::construct_proof"); // Add circuit size public input size and public inputs to transcript. execute_preamble_round(); diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.hpp similarity index 86% rename from barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.hpp rename to barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.hpp index 8dedc08ae41..62409ffbe8b 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.hpp @@ -2,15 +2,15 @@ #include "barretenberg/honk/proof_system/types/proof.hpp" #include "barretenberg/relations/relation_parameters.hpp" #include "barretenberg/sumcheck/sumcheck_output.hpp" -#include "barretenberg/translator_vm/goblin_translator_flavor.hpp" +#include "barretenberg/translator_vm/translator_flavor.hpp" namespace bb { // We won't compile this class with Standard, but we will like want to compile it (at least for testing) // with a flavor that uses the curve Grumpkin, or a flavor that does/does not have zk, etc. -class GoblinTranslatorProver { +class TranslatorProver { public: - using Flavor = GoblinTranslatorFlavor; + using Flavor = TranslatorFlavor; using CircuitBuilder = typename Flavor::CircuitBuilder; using FF = typename Flavor::FF; using BF = typename Flavor::BF; @@ -27,7 +27,7 @@ class GoblinTranslatorProver { size_t dyadic_circuit_size = 0; // final power-of-2 circuit size size_t mini_circuit_dyadic_size = 0; // The size of the small circuit that contains non-range constraint relations - explicit GoblinTranslatorProver(CircuitBuilder& circuit_builder, const std::shared_ptr& transcript); + explicit TranslatorProver(CircuitBuilder& circuit_builder, const std::shared_ptr& transcript); void compute_witness(CircuitBuilder& circuit_builder); std::shared_ptr compute_commitment_key(size_t circuit_size); @@ -40,7 +40,7 @@ class GoblinTranslatorProver { HonkProof export_proof(); HonkProof construct_proof(); - std::shared_ptr transcript = std::make_shared(); + std::shared_ptr transcript; bb::RelationParameters relation_parameters; diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.cpp new file mode 100644 index 00000000000..53880bc0cf0 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.cpp @@ -0,0 +1,161 @@ +#include "./translator_verifier.hpp" +#include "barretenberg/commitment_schemes/zeromorph/zeromorph.hpp" +#include "barretenberg/sumcheck/sumcheck.hpp" +#include "barretenberg/transcript/transcript.hpp" + +namespace bb { + +TranslatorVerifier::TranslatorVerifier(const std::shared_ptr& verifier_key, + const std::shared_ptr& transcript) + : key(verifier_key) + , transcript(transcript) +{} + +TranslatorVerifier::TranslatorVerifier(const std::shared_ptr& proving_key, + const std::shared_ptr& transcript) + : TranslatorVerifier(std::make_shared(proving_key), transcript){}; + +void TranslatorVerifier::put_translation_data_in_relation_parameters(const uint256_t& evaluation_input_x, + const BF& batching_challenge_v, + const uint256_t& accumulated_result) +{ + + const auto compute_four_limbs = [](const auto& in) { + constexpr size_t NUM_LIMB_BITS = Flavor::NUM_LIMB_BITS; + return std::array{ in.slice(0, NUM_LIMB_BITS), + in.slice(NUM_LIMB_BITS, NUM_LIMB_BITS * 2), + in.slice(NUM_LIMB_BITS * 2, NUM_LIMB_BITS * 3), + in.slice(NUM_LIMB_BITS * 3, NUM_LIMB_BITS * 4) }; + }; + + const auto compute_five_limbs = [](const auto& in) { + constexpr size_t NUM_LIMB_BITS = Flavor::NUM_LIMB_BITS; + return std::array{ in.slice(0, NUM_LIMB_BITS), + in.slice(NUM_LIMB_BITS, NUM_LIMB_BITS * 2), + in.slice(NUM_LIMB_BITS * 2, NUM_LIMB_BITS * 3), + in.slice(NUM_LIMB_BITS * 3, NUM_LIMB_BITS * 4), + in }; + }; + + relation_parameters.evaluation_input_x = compute_five_limbs(evaluation_input_x); + + uint256_t batching_challenge_v_power{ batching_challenge_v }; + for (size_t i = 0; i < 4; i++) { + relation_parameters.batching_challenge_v[i] = compute_five_limbs(batching_challenge_v_power); + batching_challenge_v_power = BF(batching_challenge_v_power) * batching_challenge_v; + } + + relation_parameters.accumulated_result = compute_four_limbs(accumulated_result); +}; + +/** + * @brief This function verifies an TranslatorFlavor Honk proof for given program settings. + */ +bool TranslatorVerifier::verify_proof(const HonkProof& proof) +{ + batching_challenge_v = transcript->template get_challenge("Translation:batching_challenge"); + + // Load the proof produced by the translator prover + transcript->load_proof(proof); + + Flavor::VerifierCommitments commitments{ key }; + Flavor::CommitmentLabels commitment_labels; + + const auto circuit_size = transcript->template receive_from_prover("circuit_size"); + evaluation_input_x = transcript->template receive_from_prover("evaluation_input_x"); + + const BF accumulated_result = transcript->template receive_from_prover("accumulated_result"); + + put_translation_data_in_relation_parameters(evaluation_input_x, batching_challenge_v, accumulated_result); + + if (circuit_size != key->circuit_size) { + return false; + } + + // Get commitments to wires and the ordered range constraints that do not require additional challenges + for (auto [comm, label] : zip_view(commitments.get_wires_and_ordered_range_constraints(), + commitment_labels.get_wires_and_ordered_range_constraints())) { + comm = transcript->template receive_from_prover(label); + } + + // Get permutation challenges + FF gamma = transcript->template get_challenge("gamma"); + + relation_parameters.beta = 0; + 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); + + // Execute Sumcheck Verifier + const size_t log_circuit_size = numeric::get_msb(circuit_size); + auto sumcheck = SumcheckVerifier(log_circuit_size, transcript); + FF alpha = transcript->template get_challenge("Sumcheck:alpha"); + std::vector gate_challenges(static_cast(numeric::get_msb(key->circuit_size))); + for (size_t idx = 0; idx < gate_challenges.size(); idx++) { + gate_challenges[idx] = transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); + } + + auto [multivariate_challenge, claimed_evaluations, sumcheck_verified] = + sumcheck.verify(relation_parameters, alpha, gate_challenges); + + // If Sumcheck did not verify, return false + if (sumcheck_verified.has_value() && !sumcheck_verified.value()) { + return false; + } + + // Execute ZeroMorph rounds. See https://hackmd.io/dlf9xEwhTQyE3hiGbq4FsA?view for a complete description ofthe + // unrolled protocol. + auto pairing_points = + ZeroMorphVerifier_::verify(commitments.get_unshifted_without_concatenated(), + commitments.get_to_be_shifted(), + claimed_evaluations.get_unshifted_without_concatenated(), + claimed_evaluations.get_shifted(), + multivariate_challenge, + transcript, + commitments.get_concatenation_groups(), + claimed_evaluations.get_concatenated_constraints()); + + auto verified = key->pcs_verification_key->pairing_check(pairing_points[0], pairing_points[1]); + + return verified; +} + +bool TranslatorVerifier::verify_translation(const TranslationEvaluations& translation_evaluations) +{ + const auto reconstruct_from_array = [&](const auto& arr) { + const BF elt_0 = (static_cast(arr[0])); + const BF elt_1 = (static_cast(arr[1]) << 68); + const BF elt_2 = (static_cast(arr[2]) << 136); + const BF elt_3 = (static_cast(arr[3]) << 204); + const BF reconstructed = elt_0 + elt_1 + elt_2 + elt_3; + return reconstructed; + }; + + const auto& reconstruct_value_from_eccvm_evaluations = [&](const TranslationEvaluations& translation_evaluations, + auto& relation_parameters) { + const BF accumulated_result = reconstruct_from_array(relation_parameters.accumulated_result); + const BF x = reconstruct_from_array(relation_parameters.evaluation_input_x); + const BF v1 = reconstruct_from_array(relation_parameters.batching_challenge_v[0]); + const BF v2 = reconstruct_from_array(relation_parameters.batching_challenge_v[1]); + const BF v3 = reconstruct_from_array(relation_parameters.batching_challenge_v[2]); + const BF v4 = reconstruct_from_array(relation_parameters.batching_challenge_v[3]); + const BF& op = translation_evaluations.op; + const BF& Px = translation_evaluations.Px; + const BF& Py = translation_evaluations.Py; + const BF& z1 = translation_evaluations.z1; + const BF& z2 = translation_evaluations.z2; + + const BF eccvm_opening = (op + (v1 * Px) + (v2 * Py) + (v3 * z1) + (v4 * z2)); + // multiply by x here to deal with shift + return x * accumulated_result == eccvm_opening; + }; + + bool is_value_reconstructed = + reconstruct_value_from_eccvm_evaluations(translation_evaluations, relation_parameters); + return is_value_reconstructed; +} + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.hpp similarity index 60% rename from barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.hpp rename to barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.hpp index 7bed2936b6a..dbe0dc66cdb 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.hpp @@ -1,21 +1,20 @@ #pragma once #include "barretenberg/goblin/translation_evaluations.hpp" #include "barretenberg/honk/proof_system/types/proof.hpp" -#include "barretenberg/translator_vm/goblin_translator_flavor.hpp" -#include "barretenberg/translator_vm/goblin_translator_prover.hpp" +#include "barretenberg/translator_vm/translator_flavor.hpp" +#include "barretenberg/translator_vm/translator_prover.hpp" namespace bb { -class GoblinTranslatorVerifier { +class TranslatorVerifier { public: - using Flavor = GoblinTranslatorFlavor; - using CircuitBuilder = typename Flavor::CircuitBuilder; + using Flavor = TranslatorFlavor; using FF = typename Flavor::FF; using BF = typename Flavor::BF; using Commitment = typename Flavor::Commitment; using ProvingKey = typename Flavor::ProvingKey; using VerificationKey = typename Flavor::VerificationKey; using VerifierCommitmentKey = typename Flavor::VerifierCommitmentKey; - using TranslationEvaluations = bb::TranslationEvaluations; + using TranslationEvaluations = bb::TranslationEvaluations_; using Transcript = typename Flavor::Transcript; BF evaluation_input_x = 0; @@ -23,15 +22,13 @@ class GoblinTranslatorVerifier { std::shared_ptr key; std::map commitments; - std::map pcs_fr_elements; std::shared_ptr transcript; RelationParameters relation_parameters; - GoblinTranslatorVerifier(const std::shared_ptr& verifier_key = nullptr, - const std::shared_ptr& transcript = std::make_shared()); + TranslatorVerifier(const std::shared_ptr& verifier_key, + const std::shared_ptr& transcript); - GoblinTranslatorVerifier(const std::shared_ptr& proving_key, - const std::shared_ptr& transcript = std::make_shared()); + TranslatorVerifier(const std::shared_ptr& proving_key, const std::shared_ptr& transcript); void put_translation_data_in_relation_parameters(const uint256_t& evaluation_input_x, const BF& batching_challenge_v, diff --git a/barretenberg/cpp/src/barretenberg/translator_vm_recursion/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/CMakeLists.txt new file mode 100644 index 00000000000..c4377cbcd1c --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/CMakeLists.txt @@ -0,0 +1 @@ +barretenberg_module(translator_vm_recursion translator_vm stdlib_honk_recursion) \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_decomposition_relation.cpp b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_decomposition_relation.cpp new file mode 100644 index 00000000000..8f4ff852f3b --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_decomposition_relation.cpp @@ -0,0 +1,13 @@ +#include "barretenberg/relations/translator_vm/translator_decomposition_relation_impl.hpp" +#include "barretenberg/stdlib/primitives/field/field.hpp" +#include "barretenberg/translator_vm_recursion/translator_recursive_flavor.hpp" + +namespace bb { +template class TranslatorDecompositionRelationImpl>; +template class TranslatorDecompositionRelationImpl>; +DEFINE_SUMCHECK_VERIFIER_RELATION_CLASS(TranslatorDecompositionRelationImpl, + TranslatorRecursiveFlavor_); +DEFINE_SUMCHECK_VERIFIER_RELATION_CLASS(TranslatorDecompositionRelationImpl, + TranslatorRecursiveFlavor_); + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_delta_range_constraint_relation.cpp b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_delta_range_constraint_relation.cpp new file mode 100644 index 00000000000..979513af1da --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_delta_range_constraint_relation.cpp @@ -0,0 +1,12 @@ +#include "barretenberg/relations/translator_vm/translator_delta_range_constraint_relation_impl.hpp" +#include "barretenberg/stdlib/primitives/field/field.hpp" +#include "barretenberg/translator_vm_recursion/translator_recursive_flavor.hpp" + +namespace bb { +template class TranslatorDeltaRangeConstraintRelationImpl>; +template class TranslatorDeltaRangeConstraintRelationImpl>; +DEFINE_SUMCHECK_VERIFIER_RELATION_CLASS(TranslatorDeltaRangeConstraintRelationImpl, + TranslatorRecursiveFlavor_); +DEFINE_SUMCHECK_VERIFIER_RELATION_CLASS(TranslatorDeltaRangeConstraintRelationImpl, + TranslatorRecursiveFlavor_); +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_extra_relations.cpp b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_extra_relations.cpp new file mode 100644 index 00000000000..73ea7b7e6c9 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_extra_relations.cpp @@ -0,0 +1,19 @@ +#include "barretenberg/relations/translator_vm/translator_extra_relations_impl.hpp" +#include "barretenberg/stdlib/primitives/field/field.hpp" +#include "barretenberg/translator_vm_recursion/translator_recursive_flavor.hpp" + +namespace bb { +template class TranslatorOpcodeConstraintRelationImpl>; +template class TranslatorAccumulatorTransferRelationImpl>; +template class TranslatorOpcodeConstraintRelationImpl>; +template class TranslatorAccumulatorTransferRelationImpl>; +DEFINE_SUMCHECK_VERIFIER_RELATION_CLASS(TranslatorOpcodeConstraintRelationImpl, + TranslatorRecursiveFlavor_); +DEFINE_SUMCHECK_VERIFIER_RELATION_CLASS(TranslatorOpcodeConstraintRelationImpl, + TranslatorRecursiveFlavor_); +DEFINE_SUMCHECK_VERIFIER_RELATION_CLASS(TranslatorAccumulatorTransferRelationImpl, + TranslatorRecursiveFlavor_); +DEFINE_SUMCHECK_VERIFIER_RELATION_CLASS(TranslatorAccumulatorTransferRelationImpl, + TranslatorRecursiveFlavor_); + +} // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_non_native_field_relation.cpp b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_non_native_field_relation.cpp new file mode 100644 index 00000000000..1c2a9b096bc --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_non_native_field_relation.cpp @@ -0,0 +1,13 @@ +#include "barretenberg/relations/translator_vm/translator_non_native_field_relation_impl.hpp" +#include "barretenberg/stdlib/primitives/field/field.hpp" +#include "barretenberg/translator_vm_recursion/translator_recursive_flavor.hpp" + +namespace bb { +template class TranslatorNonNativeFieldRelationImpl>; +template class TranslatorNonNativeFieldRelationImpl>; + +DEFINE_SUMCHECK_VERIFIER_RELATION_CLASS(TranslatorNonNativeFieldRelationImpl, + TranslatorRecursiveFlavor_); +DEFINE_SUMCHECK_VERIFIER_RELATION_CLASS(TranslatorNonNativeFieldRelationImpl, + TranslatorRecursiveFlavor_); +} // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_permutation_relation.cpp b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_permutation_relation.cpp new file mode 100644 index 00000000000..5d92ad73848 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_permutation_relation.cpp @@ -0,0 +1,12 @@ +#include "barretenberg/relations/translator_vm/translator_permutation_relation_impl.hpp" +#include "barretenberg/stdlib/primitives/field/field.hpp" +#include "barretenberg/translator_vm_recursion/translator_recursive_flavor.hpp" + +namespace bb { +template class TranslatorPermutationRelationImpl>; +template class TranslatorPermutationRelationImpl>; +DEFINE_SUMCHECK_VERIFIER_RELATION_CLASS(TranslatorPermutationRelationImpl, + TranslatorRecursiveFlavor_); +DEFINE_SUMCHECK_VERIFIER_RELATION_CLASS(TranslatorPermutationRelationImpl, + TranslatorRecursiveFlavor_); +} // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_recursive_flavor.hpp b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_recursive_flavor.hpp new file mode 100644 index 00000000000..2eeba4106bb --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_recursive_flavor.hpp @@ -0,0 +1,155 @@ +#pragma once +#include "barretenberg/commitment_schemes/commitment_key.hpp" +#include "barretenberg/commitment_schemes/kzg/kzg.hpp" +#include "barretenberg/flavor/flavor.hpp" +#include "barretenberg/flavor/flavor_macros.hpp" +#include "barretenberg/polynomials/univariate.hpp" +#include "barretenberg/relations/relation_parameters.hpp" +#include "barretenberg/stdlib/honk_recursion/transcript/transcript.hpp" +#include "barretenberg/stdlib/primitives/curves/bn254.hpp" +#include "barretenberg/stdlib/primitives/field/field.hpp" +#include "barretenberg/stdlib_circuit_builders/goblin_ultra_circuit_builder.hpp" +#include "barretenberg/translator_vm/translator_flavor.hpp" + +namespace bb { + +/** + * @brief The recursive counterpart of the native Translator flavor. + * @details is flavor can be used to instantiate a recursive Translator verifier for a proof created using the + * Translator flavor. It is similar in structure to its native counterpart with two main differences: 1) the + * curve types are stdlib types (e.g. field_t instead of field) and 2) it does not specify any Prover related types + * (e.g. Polynomial, ExtendedEdges, etc.) since we do not emulate prover computation in circuits, i.e. it only makes + * sense to instantiate a Verifier with this flavor. We reuse the native flavor to initialise identical constructions. + * @tparam BuilderType Determines the arithmetization of the verifier circuit defined based on this flavor. + */ +template class TranslatorRecursiveFlavor_ { + + public: + // TODO(https://github.com/AztecProtocol/barretenberg/issues/990): Establish whether mini_circuit_size pattern is + // needed + static constexpr size_t mini_circuit_size = 2048; + using CircuitBuilder = BuilderType; + using Curve = stdlib::bn254; + using PCS = KZG; + using GroupElement = Curve::Element; + using Commitment = Curve::AffineElement; + using FF = Curve::ScalarField; + using BF = Curve::BaseField; + using RelationSeparator = FF; + + using NativeFlavor = TranslatorFlavor; + using NativeVerificationKey = NativeFlavor::VerificationKey; + + using VerifierCommitmentKey = bb::VerifierCommitmentKey; + static constexpr size_t MINIMUM_MINI_CIRCUIT_SIZE = 2048; + + // The size of the circuit which is filled with non-zero values for most polynomials. Most relations (everything + // except for Permutation and DeltaRangeConstraint) can be evaluated just on the first chunk + // It is also the only parameter that can be changed without updating relations or structures in the flavor + static constexpr size_t MINI_CIRCUIT_SIZE = mini_circuit_size; + + // None of this parameters can be changed + + // How many mini_circuit_size polynomials are concatenated in one concatenated_* + static constexpr size_t CONCATENATION_GROUP_SIZE = NativeFlavor::CONCATENATION_GROUP_SIZE; + + // The number of concatenated_* wires + static constexpr size_t NUM_CONCATENATED_WIRES = NativeFlavor::NUM_CONCATENATED_WIRES; + + // Actual circuit size + static constexpr size_t FULL_CIRCUIT_SIZE = MINI_CIRCUIT_SIZE * CONCATENATION_GROUP_SIZE; + + // Number of wires + static constexpr size_t NUM_WIRES = NativeFlavor::NUM_WIRES; + + // The step in the DeltaRangeConstraint relation + static constexpr size_t SORT_STEP = NativeFlavor::SORT_STEP; + + // The bitness of the range constraint + static constexpr size_t MICRO_LIMB_BITS = NativeFlavor::MICRO_LIMB_BITS; + + // The limbs of the modulus we are emulating in the goblin translator. 4 binary 68-bit limbs and the prime one + static constexpr auto NEGATIVE_MODULUS_LIMBS = NativeFlavor::NEGATIVE_MODULUS_LIMBS; + + // Number of bits in a binary limb + // This is not a configurable value. Relations are sepcifically designed for it to be 68 + static constexpr size_t NUM_LIMB_BITS = NativeFlavor::NUM_LIMB_BITS; + + // 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 = NativeFlavor::NUM_ALL_ENTITIES; + // 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 = NativeFlavor::NUM_PRECOMPUTED_ENTITIES; + // The total number of witness entities not including shifts. + static constexpr size_t NUM_WITNESS_ENTITIES = NativeFlavor::NUM_WITNESS_ENTITIES; + + using Relations = TranslatorFlavor::Relations_; + + static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); + static constexpr size_t MAX_TOTAL_RELATION_LENGTH = compute_max_total_relation_length(); + + // BATCHED_RELATION_PARTIAL_LENGTH = algebraic degree of sumcheck relation *after* multiplying by the `pow_zeta` + // random polynomial e.g. For \sum(x) [A(x) * B(x) + C(x)] * PowZeta(X), relation length = 2 and random relation + // length = 3 + static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 1; + static constexpr size_t BATCHED_RELATION_TOTAL_LENGTH = MAX_TOTAL_RELATION_LENGTH + 1; + static constexpr size_t NUM_RELATIONS = std::tuple_size_v; + + // define the containers for storing the contributions from each relation in Sumcheck + using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values()); + + /** + * @brief A field element for each entity of the flavor. These entities represent the prover polynomials + * evaluated at one point. + */ + class AllValues : public TranslatorFlavor::AllEntities { + public: + using Base = TranslatorFlavor::AllEntities; + using Base::Base; + }; + /** + * @brief The verification key is responsible for storing the the commitments to the precomputed (non-witnessk) + * polynomials used by the verifier. + * + * @note Note the discrepancy with what sort of data is stored here vs in the proving key. We may want to + * resolve that, and split out separate PrecomputedPolynomials/Commitments data for clarity but also for + * portability of our circuits. + */ + class VerificationKey + : public VerificationKey_, VerifierCommitmentKey> { + public: + VerificationKey(const size_t circuit_size, const size_t num_public_inputs) + { + this->circuit_size = circuit_size; + this->log_circuit_size = numeric::get_msb(circuit_size); + this->num_public_inputs = num_public_inputs; + } + + VerificationKey(CircuitBuilder* builder, const std::shared_ptr& native_key) + { + this->pcs_verification_key = std::make_shared(); // ? + this->circuit_size = native_key->circuit_size; + this->log_circuit_size = numeric::get_msb(this->circuit_size); + this->num_public_inputs = native_key->num_public_inputs; + this->pub_inputs_offset = native_key->pub_inputs_offset; + + for (auto [native_comm, comm] : zip_view(native_key->get_all(), this->get_all())) { + comm = Commitment::from_witness(builder, native_comm); + } + } + }; + + /** + * @brief A container for the witness commitments. + */ + using WitnessCommitments = TranslatorFlavor::WitnessEntities; + + using CommitmentLabels = TranslatorFlavor::CommitmentLabels; + // Reuse the VerifierCommitments from Translator + using VerifierCommitments = TranslatorFlavor::VerifierCommitments_; + // Reuse the transcript from Translator + using Transcript = bb::BaseTranscript>; +}; +} // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_recursive_verifier.cpp new file mode 100644 index 00000000000..188c7ac6dad --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_recursive_verifier.cpp @@ -0,0 +1,166 @@ +#include "./translator_recursive_verifier.hpp" +#include "barretenberg/commitment_schemes/zeromorph/zeromorph.hpp" +#include "barretenberg/relations/translator_vm/translator_decomposition_relation_impl.hpp" +#include "barretenberg/relations/translator_vm/translator_delta_range_constraint_relation_impl.hpp" +#include "barretenberg/relations/translator_vm/translator_extra_relations_impl.hpp" +#include "barretenberg/relations/translator_vm/translator_non_native_field_relation_impl.hpp" +#include "barretenberg/relations/translator_vm/translator_permutation_relation_impl.hpp" +#include "barretenberg/sumcheck/sumcheck.hpp" + +namespace bb { + +template +TranslatorRecursiveVerifier_::TranslatorRecursiveVerifier_( + Builder* builder, const std::shared_ptr& native_verifier_key) + : key(std::make_shared(builder, native_verifier_key)) + , builder(builder) +{} + +// Relation params used in sumcheck which is done over FF but the received data is from BF +template +void TranslatorRecursiveVerifier_::put_translation_data_in_relation_parameters(const BF& evaluation_input_x, + const BF& batching_challenge_v, + const BF& accumulated_result) +{ + + const auto compute_four_limbs = [](const BF& in) { + return std::array{ FF(in.binary_basis_limbs[0].element), + FF(in.binary_basis_limbs[1].element), + FF(in.binary_basis_limbs[2].element), + FF(in.binary_basis_limbs[3].element) }; + }; + + const auto compute_five_limbs = [](const BF& in) { + return std::array{ FF(in.binary_basis_limbs[0].element), + FF(in.binary_basis_limbs[1].element), + FF(in.binary_basis_limbs[2].element), + FF(in.binary_basis_limbs[3].element), + FF(in.prime_basis_limb) }; + }; + + relation_parameters.evaluation_input_x = compute_five_limbs(evaluation_input_x); + + BF batching_challenge_v_power = batching_challenge_v; + for (size_t i = 0; i < 4; i++) { + relation_parameters.batching_challenge_v[i] = compute_five_limbs(batching_challenge_v_power); + batching_challenge_v_power = batching_challenge_v_power * batching_challenge_v; + } + + relation_parameters.accumulated_result = compute_four_limbs(accumulated_result); +}; + +/** + * @brief This function verifies an TranslatorFlavor Honk proof for given program settings. + */ +template +std::array TranslatorRecursiveVerifier_::verify_proof(const HonkProof& proof) +{ + using Sumcheck = ::bb::SumcheckVerifier; + using PCS = typename Flavor::PCS; + using ZeroMorph = ::bb::ZeroMorphVerifier_; + using VerifierCommitments = typename Flavor::VerifierCommitments; + using CommitmentLabels = typename Flavor::CommitmentLabels; + using Transcript = typename Flavor::Transcript; + + StdlibProof stdlib_proof = bb::convert_proof_to_witness(builder, proof); + transcript = std::make_shared(stdlib_proof); + + // TODO(github.com/AztecProtocol/barretenberg/issues/985): Normally, the ECCVM verifier would have run + // before the translator and there will already by data in the transcript that can be hash to get the batching + // challenge. Once this is implemented the hack can be removed. + transcript->template receive_from_prover("init"); + batching_challenge_v = transcript->template get_challenge("Translation:batching_challenge"); + + VerifierCommitments commitments{ key }; + CommitmentLabels commitment_labels; + + const auto circuit_size = transcript->template receive_from_prover("circuit_size"); + ASSERT(static_cast(circuit_size.get_value()) == key->circuit_size); + evaluation_input_x = transcript->template receive_from_prover("evaluation_input_x"); + + const BF accumulated_result = transcript->template receive_from_prover("accumulated_result"); + + put_translation_data_in_relation_parameters(evaluation_input_x, batching_challenge_v, accumulated_result); + + // Get commitments to wires and the ordered range constraints that do not require additional challenges + for (auto [comm, label] : zip_view(commitments.get_wires_and_ordered_range_constraints(), + commitment_labels.get_wires_and_ordered_range_constraints())) { + comm = transcript->template receive_from_prover(label); + } + + // Get permutation challenges + FF gamma = transcript->template get_challenge("gamma"); + + relation_parameters.beta = 0; + 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); + + // Execute Sumcheck Verifier + const size_t log_circuit_size = numeric::get_msb(static_cast(circuit_size.get_value())); + auto sumcheck = Sumcheck(log_circuit_size, transcript); + FF alpha = transcript->template get_challenge("Sumcheck:alpha"); + std::vector gate_challenges(log_circuit_size); + for (size_t idx = 0; idx < gate_challenges.size(); idx++) { + gate_challenges[idx] = transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); + } + + auto [multivariate_challenge, claimed_evaluations, sumcheck_verified] = + sumcheck.verify(relation_parameters, alpha, gate_challenges); + + // Execute ZeroMorph rounds. See https://hackmd.io/dlf9xEwhTQyE3hiGbq4FsA?view for a complete description ofthe + // unrolled protocol. + auto pairing_points = ZeroMorph::verify(commitments.get_unshifted_without_concatenated(), + commitments.get_to_be_shifted(), + claimed_evaluations.get_unshifted_without_concatenated(), + claimed_evaluations.get_shifted(), + multivariate_challenge, + transcript, + commitments.get_concatenation_groups(), + claimed_evaluations.get_concatenated_constraints()); + + return pairing_points; +} + +// this we verify outside translator +template +bool TranslatorRecursiveVerifier_::verify_translation( + const TranslationEvaluations_& translation_evaluations) +{ + const auto reconstruct_from_array = [&](const auto& arr) { + const BF reconstructed = BF(arr[0], arr[1], arr[2], arr[3]); + return reconstructed; + }; + + const auto& reconstruct_value_from_eccvm_evaluations = [&](const TranslationEvaluations& translation_evaluations, + auto& relation_parameters) { + const BF accumulated_result = reconstruct_from_array(relation_parameters.accumulated_result); + const BF x = reconstruct_from_array(relation_parameters.evaluation_input_x); + const BF v1 = reconstruct_from_array(relation_parameters.batching_challenge_v[0]); + const BF v2 = reconstruct_from_array(relation_parameters.batching_challenge_v[1]); + const BF v3 = reconstruct_from_array(relation_parameters.batching_challenge_v[2]); + const BF v4 = reconstruct_from_array(relation_parameters.batching_challenge_v[3]); + const BF& op = translation_evaluations.op; + const BF& Px = translation_evaluations.Px; + const BF& Py = translation_evaluations.Py; + const BF& z1 = translation_evaluations.z1; + const BF& z2 = translation_evaluations.z2; + + const BF eccvm_opening = (op + (v1 * Px) + (v2 * Py) + (v3 * z1) + (v4 * z2)); + // multiply by x here to deal with shift + eccvm_opening.assert_equal(x * accumulated_result); + return true; + }; + + bool is_value_reconstructed = + reconstruct_value_from_eccvm_evaluations(translation_evaluations, relation_parameters); + return is_value_reconstructed; +} +template class TranslatorRecursiveVerifier_>; +template class TranslatorRecursiveVerifier_>; +template class TranslatorRecursiveVerifier_>; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_recursive_verifier.hpp new file mode 100644 index 00000000000..09b2c3bb25e --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_recursive_verifier.hpp @@ -0,0 +1,50 @@ +#pragma once +#include "barretenberg/goblin/translation_evaluations.hpp" +#include "barretenberg/honk/proof_system/types/proof.hpp" +#include "barretenberg/stdlib/honk_recursion/transcript/transcript.hpp" +#include "barretenberg/sumcheck/sumcheck.hpp" +#include "barretenberg/translator_vm/translator_prover.hpp" +#include "barretenberg/translator_vm_recursion/translator_recursive_flavor.hpp" + +namespace bb { +template class TranslatorRecursiveVerifier_ { + public: + using FF = typename Flavor::FF; + using BF = typename Flavor::BF; + using NativeBF = typename Flavor::Curve::BaseFieldNative; + using Commitment = typename Flavor::Commitment; + using GroupElement = typename Flavor::GroupElement; + using VerificationKey = typename Flavor::VerificationKey; + using NativeVerificationKey = typename Flavor::NativeVerificationKey; + using VerifierCommitmentKey = typename Flavor::VerifierCommitmentKey; + using Builder = typename Flavor::CircuitBuilder; + using RelationSeparator = typename Flavor::RelationSeparator; + using PairingPoints = std::array; + using TranslationEvaluations = TranslationEvaluations_; + using Transcript = bb::BaseTranscript>; + using RelationParams = ::bb::RelationParameters; + + BF evaluation_input_x = 0; + BF batching_challenge_v = 0; + + std::shared_ptr key; + std::map commitments; + std::shared_ptr transcript; + std::shared_ptr pcs_verification_key; // can remove maybe hopefully + Builder* builder; + + RelationParams relation_parameters; + + TranslatorRecursiveVerifier_(Builder* builder, const std::shared_ptr& native_verifier_key); + + void put_translation_data_in_relation_parameters(const BF& evaluation_input_x, + const BF& batching_challenge_v, + const BF& accumulated_result); + + PairingPoints verify_proof(const HonkProof& proof); + + // TODO(https://github.com/AztecProtocol/barretenberg/issues/986): Ensure the translation is also recursively + // verified somewhere + bool verify_translation(const TranslationEvaluations& translation_evaluations); +}; +} // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_recursive_verifier.test.cpp new file mode 100644 index 00000000000..e9ae3d4f8d7 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/translator_vm_recursion/translator_recursive_verifier.test.cpp @@ -0,0 +1,135 @@ +#include "barretenberg/translator_vm_recursion/translator_recursive_verifier.hpp" +#include "barretenberg/common/log.hpp" +#include "barretenberg/numeric/uint256/uint256.hpp" +#include "barretenberg/relations/relation_parameters.hpp" +#include "barretenberg/sumcheck/sumcheck_round.hpp" +#include "barretenberg/translator_vm/translator_circuit_builder.hpp" +#include "barretenberg/translator_vm/translator_prover.hpp" +#include "barretenberg/translator_vm/translator_verifier.hpp" +#include "barretenberg/ultra_honk/ultra_prover.hpp" +#include "barretenberg/ultra_honk/ultra_verifier.hpp" +#include +namespace bb { + +/** + * @brief Test suite for standalone recursive verification of translation proofs. + * @details `Inner*` types describe the type of circuits (and everything else required to generate a proof) that we aim + * to recursively verify. `Outer*` describes the arithmetisation of the recursive verifier circuit and the types + * required to ensure the recursive verifier circuit is correct (i.e. by producing a proof and verifying it). + */ + +// TODO(https://github.com/AztecProtocol/barretenberg/issues/980): Add failing tests after we have a proper shared +// transcript interface between ECCVM and Translator and we are able to deserialise and serialise the transcript +// correctly. +template class TranslatorRecursiveTests : public ::testing::Test { + public: + using InnerFlavor = typename RecursiveFlavor::NativeFlavor; + using InnerBuilder = typename InnerFlavor::CircuitBuilder; + using InnerProver = TranslatorProver; + using InnerVerifier = TranslatorVerifier; + using InnerG1 = InnerFlavor::Commitment; + using InnerFF = InnerFlavor::FF; + using InnerBF = InnerFlavor::BF; + + using RecursiveVerifier = TranslatorRecursiveVerifier_; + + using OuterBuilder = typename RecursiveFlavor::CircuitBuilder; + using OuterFlavor = std::conditional_t, GoblinUltraFlavor, UltraFlavor>; + using OuterProver = UltraProver_; + using OuterVerifier = UltraVerifier_; + using OuterProverInstance = ProverInstance_; + + using Transcript = InnerFlavor::Transcript; + + static void SetUpTestSuite() { bb::srs::init_crs_factory("../srs_db/ignition"); } + + static void test_recursive_verification() + { + auto P1 = InnerG1::random_element(); + auto P2 = InnerG1::random_element(); + auto z = InnerFF::random_element(); + + // Add the same operations to the ECC op queue; the native computation is performed under the hood. + auto op_queue = std::make_shared(); + op_queue->append_nonzero_ops(); + + for (size_t i = 0; i < 500; i++) { + op_queue->add_accumulate(P1); + op_queue->mul_accumulate(P2, z); + } + + auto prover_transcript = std::make_shared(); + prover_transcript->send_to_verifier("init", InnerBF::random_element()); + // normally this would be the eccvm proof + auto fake_inital_proof = prover_transcript->export_proof(); + InnerBF translation_batching_challenge = + prover_transcript->template get_challenge("Translation:batching_challenge"); + InnerBF translation_evaluation_challenge = InnerBF::random_element(); + + auto circuit_builder = InnerBuilder(translation_batching_challenge, translation_evaluation_challenge, op_queue); + EXPECT_TRUE(circuit_builder.check_circuit()); + + InnerProver prover{ circuit_builder, prover_transcript }; + auto proof = prover.construct_proof(); + + // TODO(https://github.com/AztecProtocol/barretenberg/issues/985): Insert the proof that serves as the content + // neeeded by the Translator verifier in the ECCVM proof. Unlike the native verifier where we can directly pass + // a transcript initialised with the correct information, in the recursive scenario the transcript is a circuit + // primitives that is initialised from the proof so we need the batching challenge contained in the proof. + proof.insert(proof.begin(), fake_inital_proof.begin(), fake_inital_proof.end()); + + auto verification_key = std::make_shared(prover.key); + OuterBuilder outer_circuit; + RecursiveVerifier verifier{ &outer_circuit, verification_key }; + auto pairing_points = verifier.verify_proof(proof); + info("Recursive Verifier: num gates = ", outer_circuit.num_gates); + + // Check for a failure flag in the recursive verifier circuit + EXPECT_EQ(outer_circuit.failed(), false) << outer_circuit.err(); + + auto native_verifier_transcript = std::make_shared(prover_transcript->proof_data); + native_verifier_transcript->template receive_from_prover("init"); + InnerVerifier native_verifier(prover.key, native_verifier_transcript); + bool native_result = native_verifier.verify_proof(proof); + auto recursive_result = native_verifier.key->pcs_verification_key->pairing_check(pairing_points[0].get_value(), + pairing_points[1].get_value()); + EXPECT_EQ(recursive_result, native_result); + + auto recursive_manifest = verifier.transcript->get_manifest(); + auto native_manifest = native_verifier.transcript->get_manifest(); + for (size_t i = 0; i < recursive_manifest.size(); ++i) { + EXPECT_EQ(recursive_manifest[i], native_manifest[i]) + << "Recursive Verifier/Verifier manifest discrepency in round " << i; + } + + EXPECT_EQ(verifier.key->circuit_size, verification_key->circuit_size); + EXPECT_EQ(verifier.key->log_circuit_size, verification_key->log_circuit_size); + EXPECT_EQ(verifier.key->num_public_inputs, verification_key->num_public_inputs); + for (auto [vk_poly, native_vk_poly] : zip_view(verifier.key->get_all(), verification_key->get_all())) { + EXPECT_EQ(vk_poly.get_value(), native_vk_poly); + } + + if constexpr (!IsSimulator) { + auto instance = std::make_shared(outer_circuit); + OuterProver prover(instance); + auto verification_key = std::make_shared(instance->proving_key); + OuterVerifier verifier(verification_key); + auto proof = prover.construct_proof(); + bool verified = verifier.verify_proof(proof); + + ASSERT(verified); + } + } +}; + +using FlavorTypes = testing::Types, + TranslatorRecursiveFlavor_, + TranslatorRecursiveFlavor_>; + +TYPED_TEST_SUITE(TranslatorRecursiveTests, FlavorTypes); + +TYPED_TEST(TranslatorRecursiveTests, SingleRecursiveVerification) +{ + TestFixture::test_recursive_verification(); +}; +} // namespace bb \ No newline at end of file