diff --git a/README.md b/README.md index 39b6978234..8d32969d7a 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ Barretenberg can generate a smart contract that verifies proofs in Solidity (i.e First, prove the valid execution of your Noir program and export the verification key: ```bash -bb prove --sceme ultra_honk -b ./target/hello_world.json -w ./target/witness-name.gz -o ./target/proof +bb prove --scheme ultra_honk -b ./target/hello_world.json -w ./target/witness-name.gz -o ./target/proof bb write_vk --scheme ultra_honk -b ./target/hello_world.json -o ./target/vk ``` diff --git a/cpp/CMakePresets.json b/cpp/CMakePresets.json index a5e2e32a64..bf03c207a7 100644 --- a/cpp/CMakePresets.json +++ b/cpp/CMakePresets.json @@ -767,7 +767,7 @@ "configurePreset": "wasm-threads", "inheritConfigureEnvironment": true, "jobs": 0, - "targets": ["barretenberg.wasm", "barretenberg.wasm.gz", "bb_cli_bench"] + "targets": ["barretenberg.wasm", "barretenberg.wasm.gz"] }, { "name": "xray", diff --git a/cpp/bootstrap.sh b/cpp/bootstrap.sh index bd2b9418e9..c34886bf2e 100755 --- a/cpp/bootstrap.sh +++ b/cpp/bootstrap.sh @@ -107,7 +107,12 @@ function build_wasm { function build_wasm_threads { set -eu if ! cache_download barretenberg-wasm-threads-$hash.zst; then - build_preset wasm-threads + if [ "$(arch)" == "amd64" ] && [ "$CI" -eq 1 ]; then + # We only want to sanity check that we haven't broken wasm ecc ops in merge queue. + build_preset wasm-threads --target barretenberg.wasm barretenberg.wasm.gz ecc_tests + else + build_preset wasm-threads + fi cache_upload barretenberg-wasm-threads-$hash.zst build-wasm-threads/bin fi } @@ -199,7 +204,9 @@ function test_cmds { echo -e "$prefix barretenberg/cpp/scripts/run_test.sh $bin_name $test" done || (echo "Failed to list tests in $bin" && exit 1) done - if [ "$(arch)" == "amd64" ] && [ "$CI" -eq 1 ]; then + if [ "$(arch)" == "amd64" ] && [ "$CI_FULL" -eq 1 ]; then + # We only want to sanity check that we haven't broken wasm ecc in merge queue. + echo "$hash barretenberg/cpp/scripts/wasmtime.sh barretenberg/cpp/build-wasm-threads/bin/ecc_tests" # If in amd64 CI, iterate asan_tests, creating a gtest invocation for each. for bin_name in "${!asan_tests[@]}"; do local filter=${asan_tests[$bin_name]} @@ -296,8 +303,8 @@ case "$cmd" in fi # Recreation of logic from bench. - ../../yarn-project/end-to-end/bootstrap.sh generate_example_app_ivc_inputs - ../../barretenberg/cpp/scripts/ci_benchmark_ivc_flows.sh $(pwd)/../../yarn-project/end-to-end/example-app-ivc-inputs-out $(pwd)/bench-out + ../../yarn-project/end-to-end/bootstrap.sh build_bench + ../../yarn-project/end-to-end/bootstrap.sh bench_cmds | grep barretenberg/cpp/scripts/ci_benchmark_ivc_flows.sh | STRICT_SCHEDULING=1 parallelise ;; "hash") echo $hash diff --git a/cpp/cmake/module.cmake b/cpp/cmake/module.cmake index 0f9d1a8a46..053ea81e0d 100644 --- a/cpp/cmake/module.cmake +++ b/cpp/cmake/module.cmake @@ -98,7 +98,6 @@ function(barretenberg_module MODULE_NAME) PRIVATE ${TRACY_LIBS} GTest::gtest - GTest::gtest_main GTest::gmock_main ${TBB_IMPORTED_TARGETS} ) diff --git a/cpp/scripts/ci_benchmark_ivc_flows.sh b/cpp/scripts/ci_benchmark_ivc_flows.sh index 6d9eb7cd68..8d80518fc2 100755 --- a/cpp/scripts/ci_benchmark_ivc_flows.sh +++ b/cpp/scripts/ci_benchmark_ivc_flows.sh @@ -79,7 +79,7 @@ function client_ivc_flow { mkdir -p "$output" export MEMUSAGE_OUT="$output/peak-memory-mb.txt" - run_bb_cli_bench "$runtime" "$output" "prove -o $output --ivc_inputs_path $flow_folder/ivc-inputs.msgpack --scheme client_ivc" + run_bb_cli_bench "$runtime" "$output" "prove -o $output --ivc_inputs_path $flow_folder/ivc-inputs.msgpack --scheme client_ivc -v" local end=$(date +%s%N) local elapsed_ns=$(( end - start )) diff --git a/cpp/scripts/test_civc_standalone_vks_havent_changed.sh b/cpp/scripts/test_civc_standalone_vks_havent_changed.sh index 4b823425c7..70acf0e9af 100755 --- a/cpp/scripts/test_civc_standalone_vks_havent_changed.sh +++ b/cpp/scripts/test_civc_standalone_vks_havent_changed.sh @@ -8,7 +8,7 @@ cd .. # IF A VK CHANGE IS EXPECTED - we need to redo this: # - Generate inputs: $root/yarn-project/end-to-end/bootstrap.sh generate_example_app_ivc_inputs # - Upload the compressed results: aws s3 cp bb-civc-inputs-[version].tar.gz s3://aztec-ci-artifacts/protocol/bb-civc-inputs-[version].tar.gz -pinned_civc_inputs_url="https://aztec-ci-artifacts.s3.us-east-2.amazonaws.com/protocol/bb-civc-inputs-v7.tar.gz" +pinned_civc_inputs_url="https://aztec-ci-artifacts.s3.us-east-2.amazonaws.com/protocol/bb-civc-inputs-7f48a235.tar.gz" export inputs_tmp_dir=$(mktemp -d) trap 'rm -rf "$inputs_tmp_dir"' EXIT SIGINT diff --git a/cpp/scripts/wasmtime.sh b/cpp/scripts/wasmtime.sh index 430081372c..439cb5a436 100755 --- a/cpp/scripts/wasmtime.sh +++ b/cpp/scripts/wasmtime.sh @@ -2,12 +2,11 @@ # Helper for passing environment variables to wasm and common config. # Allows accessing ~/.bb-crs and ./ (more can be added as parameters to this script). set -eu - +export WASMTIME_BACKTRACE_DETAILS=1 exec wasmtime run \ -Wthreads=y \ -Sthreads=y \ - --env HARDWARE_CONCURRENCY \ - --env WASM_BACKTRACE_DETAILS=1 \ + ${HARDWARE_CONCURRENCY:+--env HARDWARE_CONCURRENCY} \ --env HOME \ ${MAIN_ARGS:+--env MAIN_ARGS} \ --dir=$HOME/.bb-crs \ diff --git a/cpp/src/barretenberg/api/api_avm.cpp b/cpp/src/barretenberg/api/api_avm.cpp index 326be4b945..6f7a848c3f 100644 --- a/cpp/src/barretenberg/api/api_avm.cpp +++ b/cpp/src/barretenberg/api/api_avm.cpp @@ -24,43 +24,7 @@ void print_avm_stats() } // namespace -void avm_check_circuit(const std::filesystem::path&, const std::filesystem::path&) -{ - info("!!! VM1 is deprecated. Quitting !!!"); -} - -void avm_prove(const std::filesystem::path&, const std::filesystem::path&, const std::filesystem::path& output_path) -{ - info("!!! VM1 is deprecated. Sleeping 60s and generating fake outputs !!!"); - - bb::HonkProof proof(AVM_PROOF_LENGTH_IN_FIELDS); - std::fill(proof.begin(), proof.end(), fr::zero()); - sleep(60); - - std::vector vk_as_fields(AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS); - std::fill(vk_as_fields.begin(), vk_as_fields.end(), fr::zero()); - - vinfo("vk fields size: ", vk_as_fields.size()); - vinfo("circuit size: ", static_cast(vk_as_fields[0])); - vinfo("num of pub inputs: ", static_cast(vk_as_fields[1])); - - const auto to_json = [](const std::vector& data) { - return format("[", join(transform::map(data, [](auto fr) { return format("\"", fr, "\""); })), "]"); - }; - std::string vk_json = to_json(vk_as_fields); - const auto proof_path = output_path / "proof"; - const auto vk_path = output_path / "vk"; - const auto vk_fields_path = output_path / "vk_fields.json"; - - write_file(proof_path, to_buffer(proof)); - vinfo("proof written to: ", proof_path); - write_file(vk_path, to_buffer(vk_as_fields)); - vinfo("vk written to: ", vk_path); - write_file(vk_fields_path, { vk_json.begin(), vk_json.end() }); - vinfo("vk as fields written to: ", vk_fields_path); -} - -void avm2_prove(const std::filesystem::path& inputs_path, const std::filesystem::path& output_path) +void avm_prove(const std::filesystem::path& inputs_path, const std::filesystem::path& output_path) { avm2::AvmAPI avm; auto inputs = avm2::AvmAPI::ProvingInputs::from(read_file(inputs_path)); @@ -83,7 +47,7 @@ void avm2_prove(const std::filesystem::path& inputs_path, const std::filesystem: } } -void avm2_check_circuit(const std::filesystem::path& inputs_path) +void avm_check_circuit(const std::filesystem::path& inputs_path) { avm2::AvmAPI avm; auto inputs = avm2::AvmAPI::ProvingInputs::from(read_file(inputs_path)); @@ -94,16 +58,10 @@ void avm2_check_circuit(const std::filesystem::path& inputs_path) print_avm_stats(); } -bool avm_verify(const std::filesystem::path&, const std::filesystem::path&) -{ - info("!!! VM1 is deprecated. Saying yes !!!"); - return true; -} - // NOTE: The proof should NOT include the public inputs. -bool avm2_verify(const std::filesystem::path& proof_path, - const std::filesystem::path& public_inputs_path, - const std::filesystem::path& vk_path) +bool avm_verify(const std::filesystem::path& proof_path, + const std::filesystem::path& public_inputs_path, + const std::filesystem::path& vk_path) { const auto proof = many_from_buffer(read_file(proof_path)); std::vector vk_bytes = read_file(vk_path); diff --git a/cpp/src/barretenberg/api/api_avm.hpp b/cpp/src/barretenberg/api/api_avm.hpp index 9ac4323b0d..cf8a4e8a5e 100644 --- a/cpp/src/barretenberg/api/api_avm.hpp +++ b/cpp/src/barretenberg/api/api_avm.hpp @@ -3,31 +3,18 @@ namespace bb { -/** - * @brief Performs "check circuit" on the AVM circuit for the given public inputs and hints. - * - * @param public_inputs_path Path to the file containing the serialised avm public inputs - * @param hints_path Path to the file containing the serialised avm circuit hints - */ -void avm_check_circuit(const std::filesystem::path& public_inputs_path, const std::filesystem::path& hints_path); - /** * @brief Writes an avm proof and corresponding (incomplete) verification key to files. * * Communication: - * - Filesystem: The proof and vk are written to the paths output_path/proof and output_path/{vk, vk_fields.json} + * - Filesystem: The proof and vk are written to the paths output_path/proof and output_path/vk * - * @param public_inputs_path Path to the file containing the serialised avm public inputs - * @param hints_path Path to the file containing the serialised avm circuit hints + * @param inputs_path Path to the file containing the serialised avm public inputs and hints * @param output_path Path (directory) to write the output proof and verification keys */ -void avm_prove(const std::filesystem::path& public_inputs_path, - const std::filesystem::path& hints_path, - const std::filesystem::path& output_path); - -void avm2_prove(const std::filesystem::path& inputs_path, const std::filesystem::path& output_path); +void avm_prove(const std::filesystem::path& inputs_path, const std::filesystem::path& output_path); -void avm2_check_circuit(const std::filesystem::path& inputs_path); +void avm_check_circuit(const std::filesystem::path& inputs_path); /** * @brief Verifies an avm proof and writes the result to stdout @@ -41,11 +28,9 @@ void avm2_check_circuit(const std::filesystem::path& inputs_path); * @return true If the proof is valid * @return false If the proof is invalid */ -bool avm_verify(const std::filesystem::path& proof_path, const std::filesystem::path& vk_path); - // NOTE: The proof should NOT include the public inputs. -bool avm2_verify(const std::filesystem::path& proof_path, - const std::filesystem::path& public_inputs_path, - const std::filesystem::path& vk_path); +bool avm_verify(const std::filesystem::path& proof_path, + const std::filesystem::path& public_inputs_path, + const std::filesystem::path& vk_path); } // namespace bb #endif diff --git a/cpp/src/barretenberg/bb/cli.cpp b/cpp/src/barretenberg/bb/cli.cpp index c591213cb6..2287c4902b 100644 --- a/cpp/src/barretenberg/bb/cli.cpp +++ b/cpp/src/barretenberg/bb/cli.cpp @@ -494,38 +494,16 @@ int parse_and_run_cli_command(int argc, char* argv[]) }; /*************************************************************************************************************** - * Subcommand: avm2_prove - ***************************************************************************************************************/ - CLI::App* avm2_prove_command = app.add_subcommand("avm2_prove", ""); - avm2_prove_command->group(""); // hide from list of subcommands - add_verbose_flag(avm2_prove_command); - add_debug_flag(avm2_prove_command); - add_crs_path_option(avm2_prove_command); - std::filesystem::path avm2_prove_output_path{ "./proofs" }; - add_output_path_option(avm2_prove_command, avm2_prove_output_path); - add_avm_inputs_option(avm2_prove_command); - - /*************************************************************************************************************** - * Subcommand: avm2_check_circuit - ***************************************************************************************************************/ - CLI::App* avm2_check_circuit_command = app.add_subcommand("avm2_check_circuit", ""); - avm2_check_circuit_command->group(""); // hide from list of subcommands - add_verbose_flag(avm2_check_circuit_command); - add_debug_flag(avm2_check_circuit_command); - add_crs_path_option(avm2_check_circuit_command); - add_avm_inputs_option(avm2_check_circuit_command); - - /*************************************************************************************************************** - * Subcommand: avm2_verify + * Subcommand: avm_prove ***************************************************************************************************************/ - CLI::App* avm2_verify_command = app.add_subcommand("avm2_verify", ""); - avm2_verify_command->group(""); // hide from list of subcommands - add_verbose_flag(avm2_verify_command); - add_debug_flag(avm2_verify_command); - add_crs_path_option(avm2_verify_command); - add_avm_public_inputs_option(avm2_verify_command); - add_proof_path_option(avm2_verify_command); - add_vk_path_option(avm2_verify_command); + CLI::App* avm_prove_command = app.add_subcommand("avm_prove", ""); + avm_prove_command->group(""); // hide from list of subcommands + add_verbose_flag(avm_prove_command); + add_debug_flag(avm_prove_command); + add_crs_path_option(avm_prove_command); + std::filesystem::path avm_prove_output_path{ "./proofs" }; + add_output_path_option(avm_prove_command, avm_prove_output_path); + add_avm_inputs_option(avm_prove_command); /*************************************************************************************************************** * Subcommand: avm_check_circuit @@ -535,20 +513,7 @@ int parse_and_run_cli_command(int argc, char* argv[]) add_verbose_flag(avm_check_circuit_command); add_debug_flag(avm_check_circuit_command); add_crs_path_option(avm_check_circuit_command); - add_avm_public_inputs_option(avm_check_circuit_command); - add_output_path_option(avm_check_circuit_command, output_path); - - /*************************************************************************************************************** - * Subcommand: avm_prove - ***************************************************************************************************************/ - CLI::App* avm_prove_command = app.add_subcommand("avm_prove", ""); - avm_prove_command->group(""); // hide from list of subcommands - add_verbose_flag(avm_prove_command); - add_debug_flag(avm_prove_command); - add_crs_path_option(avm_prove_command); - std::filesystem::path avm_prove_output_path{ "./proofs" }; - add_avm_public_inputs_option(avm_prove_command); - add_output_path_option(avm_prove_command, avm_prove_output_path); + add_avm_inputs_option(avm_check_circuit_command); /*************************************************************************************************************** * Subcommand: avm_verify @@ -559,7 +524,6 @@ int parse_and_run_cli_command(int argc, char* argv[]) add_debug_flag(avm_verify_command); add_crs_path_option(avm_verify_command); add_avm_public_inputs_option(avm_verify_command); - add_output_path_option(avm_verify_command, output_path); add_proof_path_option(avm_verify_command); add_vk_path_option(avm_verify_command); #endif @@ -655,20 +619,13 @@ int parse_and_run_cli_command(int argc, char* argv[]) } // AVM #ifndef DISABLE_AZTEC_VM - else if (avm2_prove_command->parsed()) { + else if (avm_prove_command->parsed()) { // This outputs both files: proof and vk, under the given directory. - avm2_prove(avm_inputs_path, avm2_prove_output_path); - } else if (avm2_check_circuit_command->parsed()) { - avm2_check_circuit(avm_inputs_path); - } else if (avm2_verify_command->parsed()) { - return avm2_verify(proof_path, avm_public_inputs_path, vk_path) ? 0 : 1; + avm_prove(avm_inputs_path, avm_prove_output_path); } else if (avm_check_circuit_command->parsed()) { - avm_check_circuit(avm_public_inputs_path, "ignored"); - } else if (avm_prove_command->parsed()) { - // This outputs both files: proof and vk, under the given directory. - avm_prove(avm_public_inputs_path, "ignored", avm_prove_output_path); + avm_check_circuit(avm_inputs_path); } else if (avm_verify_command->parsed()) { - return avm_verify(proof_path, vk_path) ? 0 : 1; + return avm_verify(proof_path, avm_public_inputs_path, vk_path) ? 0 : 1; } #endif // CLIENT IVC EXTRA COMMAND diff --git a/cpp/src/barretenberg/benchmark/client_ivc_bench/client_ivc.bench.cpp b/cpp/src/barretenberg/benchmark/client_ivc_bench/client_ivc.bench.cpp index 8992d29b20..63e24424ea 100644 --- a/cpp/src/barretenberg/benchmark/client_ivc_bench/client_ivc.bench.cpp +++ b/cpp/src/barretenberg/benchmark/client_ivc_bench/client_ivc.bench.cpp @@ -43,7 +43,6 @@ BENCHMARK_DEFINE_F(ClientIVCBench, Full)(benchmark::State& state) ivc.prove(); } } - /** * @brief Benchmark the prover work for the full PG-Goblin IVC protocol * @details Processes "dense" circuits of size 2^17 in a size 2^20 structured trace diff --git a/cpp/src/barretenberg/benchmark/goblin_bench/eccvm.bench.cpp b/cpp/src/barretenberg/benchmark/goblin_bench/eccvm.bench.cpp index 3895a29cca..c22516f00e 100644 --- a/cpp/src/barretenberg/benchmark/goblin_bench/eccvm.bench.cpp +++ b/cpp/src/barretenberg/benchmark/goblin_bench/eccvm.bench.cpp @@ -19,7 +19,7 @@ Builder generate_trace(size_t target_num_gates) using G1 = typename Flavor::CycleGroup; using Fr = typename G1::Fr; - auto generators = G1::derive_generators("test generators", 2); + auto generators = get_precomputed_generators(); typename G1::element a = generators[0]; typename G1::element b = generators[1]; diff --git a/cpp/src/barretenberg/benchmark/ultra_bench/mock_circuits.hpp b/cpp/src/barretenberg/benchmark/ultra_bench/mock_circuits.hpp index 78e2e57746..85f2c0d794 100644 --- a/cpp/src/barretenberg/benchmark/ultra_bench/mock_circuits.hpp +++ b/cpp/src/barretenberg/benchmark/ultra_bench/mock_circuits.hpp @@ -18,9 +18,6 @@ namespace bb::mock_circuits { */ template void generate_basic_arithmetic_circuit(Builder& builder, size_t log2_num_gates) { - // Add default pairing points as its required, but this causes gates to be created... - // TODO(https://github.com/AztecProtocol/barretenberg/issues/984): Get rid of gates when creating default - // pairing points. stdlib::recursion::PairingPoints::add_default_to_public_inputs(builder); stdlib::field_t a(stdlib::witness_t(&builder, fr::random_element())); diff --git a/cpp/src/barretenberg/boomerang_value_detection/graph_description_bigfield.test.cpp b/cpp/src/barretenberg/boomerang_value_detection/graph_description_bigfield.test.cpp index ed3c4689da..16f847f67e 100644 --- a/cpp/src/barretenberg/boomerang_value_detection/graph_description_bigfield.test.cpp +++ b/cpp/src/barretenberg/boomerang_value_detection/graph_description_bigfield.test.cpp @@ -41,7 +41,7 @@ using witness_ct = bn254::witness_ct; */ void fix_bigfield_element(const fq_ct& element) { - for (int i = 0; i < 4; i++) { + for (size_t i = 0; i < 4; i++) { element.binary_basis_limbs[i].element.fix_witness(); } element.prime_basis_limb.fix_witness(); diff --git a/cpp/src/barretenberg/circuit_checker/translator_circuit_checker.cpp b/cpp/src/barretenberg/circuit_checker/translator_circuit_checker.cpp index 4de39a6980..9c16cb0c33 100644 --- a/cpp/src/barretenberg/circuit_checker/translator_circuit_checker.cpp +++ b/cpp/src/barretenberg/circuit_checker/translator_circuit_checker.cpp @@ -356,7 +356,7 @@ bool TranslatorCircuitChecker::check(const Builder& circuit) // // We also limit computation on limbs of op, z_1 and z_2, since we know that op has only the lowest // limb and z_1 and z_2 have only the two lowest limbs - const std::array NEGATIVE_MODULUS_LIMBS = Builder::NEGATIVE_MODULUS_LIMBS; + constexpr std::array NEGATIVE_MODULUS_LIMBS = Builder::NEGATIVE_MODULUS_LIMBS; const uint256_t SHIFT_1 = Builder::SHIFT_1; const uint256_t SHIFT_2 = Builder::SHIFT_2; const uint256_t SHIFT_3 = Builder::SHIFT_3; @@ -470,4 +470,4 @@ bool TranslatorCircuitChecker::check(const Builder& circuit) } return true; }; -}; // namespace bb \ No newline at end of file +}; // namespace bb diff --git a/cpp/src/barretenberg/circuit_checker/ultra_circuit_builder.test.cpp b/cpp/src/barretenberg/circuit_checker/ultra_circuit_builder.test.cpp index ee0eaecd23..00606c511b 100644 --- a/cpp/src/barretenberg/circuit_checker/ultra_circuit_builder.test.cpp +++ b/cpp/src/barretenberg/circuit_checker/ultra_circuit_builder.test.cpp @@ -61,7 +61,7 @@ TEST(UltraCircuitBuilder, CreateGatesFromPlookupAccumulators) { const auto mask = plookup::fixed_base::table::MAX_TABLE_SIZE - 1; - grumpkin::g1::affine_element base_point = plookup::fixed_base::table::LHS_GENERATOR_POINT; + grumpkin::g1::affine_element base_point = plookup::fixed_base::table::lhs_generator_point(); std::vector input_buf; write(input_buf, base_point); const auto offset_generators = diff --git a/cpp/src/barretenberg/client_ivc/client_ivc.cpp b/cpp/src/barretenberg/client_ivc/client_ivc.cpp index b603b3109a..f78d259128 100644 --- a/cpp/src/barretenberg/client_ivc/client_ivc.cpp +++ b/cpp/src/barretenberg/client_ivc/client_ivc.cpp @@ -404,7 +404,6 @@ HonkProof ClientIVC::decider_prove() const vinfo("prove decider..."); fold_output.accumulator->proving_key.commitment_key = bn254_commitment_key; MegaDeciderProver decider_prover(fold_output.accumulator); - vinfo("finished decider proving."); return decider_prover.construct_proof(); } diff --git a/cpp/src/barretenberg/commitment_schemes/pairing_points.hpp b/cpp/src/barretenberg/commitment_schemes/pairing_points.hpp index b26108af92..8a1a0b08db 100644 --- a/cpp/src/barretenberg/commitment_schemes/pairing_points.hpp +++ b/cpp/src/barretenberg/commitment_schemes/pairing_points.hpp @@ -78,6 +78,11 @@ class PairingPoints { */ void aggregate(const PairingPoints& other) { + if (P0 == Point::infinity() || P1 == Point::infinity() || other.P0 == Point::infinity() || + other.P1 == Point::infinity()) { + throw_or_abort("WARNING: Shouldn't be aggregating with Point at infinity! The pairing points are probably " + "uninitialized."); + } Fr aggregation_separator = Fr::random_element(); P0 = P0 + other.P0 * aggregation_separator; P1 = P1 + other.P1 * aggregation_separator; diff --git a/cpp/src/barretenberg/crypto/generators/generator_data.hpp b/cpp/src/barretenberg/crypto/generators/generator_data.hpp index c561167fba..37d9585512 100644 --- a/cpp/src/barretenberg/crypto/generators/generator_data.hpp +++ b/cpp/src/barretenberg/crypto/generators/generator_data.hpp @@ -9,6 +9,8 @@ #include "barretenberg/common/container.hpp" #include "barretenberg/ecc/curves/bn254/bn254.hpp" #include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp" +#include "barretenberg/ecc/groups/group.hpp" +#include "barretenberg/ecc/groups/precomputed_generators_grumpkin_impl.hpp" #include #include #include @@ -53,20 +55,12 @@ template class generator_data { static inline constexpr std::string_view DEFAULT_DOMAIN_SEPARATOR = "DEFAULT_DOMAIN_SEPARATOR"; inline constexpr generator_data() = default; - static inline constexpr std::array make_precomputed_generators() - { - std::array output; - std::vector res = Group::derive_generators(DEFAULT_DOMAIN_SEPARATOR, DEFAULT_NUM_GENERATORS, 0); - std::copy(res.begin(), res.end(), output.begin()); - return output; - } - /** - * @brief Precompute a small number of generators at compile time. For small pedersen commitments + pedersen hashes, - * this prevents us from having to derive generators at runtime + * @brief We precompute and hard-code a small number of generators. For small pedersen commitments + pedersen + * hashes, this prevents us from having to derive generators at runtime */ - static inline constexpr std::array precomputed_generators = - make_precomputed_generators(); + static constexpr std::span precomputed_generators = + get_precomputed_generators(); [[nodiscard]] inline GeneratorView get(const size_t num_generators, const size_t generator_offset = 0, @@ -149,4 +143,4 @@ template struct GeneratorContext { , domain_separator(_domain_separator) {} }; -} // namespace bb::crypto \ No newline at end of file +} // namespace bb::crypto diff --git a/cpp/src/barretenberg/crypto/generators/generator_data.test.cpp b/cpp/src/barretenberg/crypto/generators/generator_data.test.cpp index c3bea7555f..ae5dbe2fa4 100644 --- a/cpp/src/barretenberg/crypto/generators/generator_data.test.cpp +++ b/cpp/src/barretenberg/crypto/generators/generator_data.test.cpp @@ -8,7 +8,7 @@ namespace bb::crypto { TEST(GeneratorContext, DeriveDefaultGenerators) { - auto default_generators = generator_data::make_precomputed_generators(); + auto default_generators = generator_data::precomputed_generators; std::vector expected_default_generators; expected_default_generators.emplace_back(grumpkin::g1::affine_element( @@ -42,4 +42,4 @@ TEST(GeneratorContext, DeriveDefaultGenerators) } } -} // namespace bb::crypto \ No newline at end of file +} // namespace bb::crypto diff --git a/cpp/src/barretenberg/crypto/merkle_tree/append_only_tree/content_addressed_append_only_tree.test.cpp b/cpp/src/barretenberg/crypto/merkle_tree/append_only_tree/content_addressed_append_only_tree.test.cpp index 4c01c53a48..b8d8c942a7 100644 --- a/cpp/src/barretenberg/crypto/merkle_tree/append_only_tree/content_addressed_append_only_tree.test.cpp +++ b/cpp/src/barretenberg/crypto/merkle_tree/append_only_tree/content_addressed_append_only_tree.test.cpp @@ -1262,6 +1262,11 @@ TEST_F(PersistedContentAddressedAppendOnlyTreeTest, can_remove_historic_block_da // trying to remove a block that is not the most historic should fail remove_historic_block(tree, oldestBlock + 1, false); + if (oldestBlock > 1) { + // trying to remove a block that is older than the most historic should succeed + remove_historic_block(tree, oldestBlock - 1, true); + } + fr rootToRemove = roots[oldestBlock - 1]; check_block_and_root_data(db, oldestBlock, rootToRemove, true); diff --git a/cpp/src/barretenberg/crypto/merkle_tree/node_store/cached_content_addressed_tree_store.hpp b/cpp/src/barretenberg/crypto/merkle_tree/node_store/cached_content_addressed_tree_store.hpp index 0bec9cd6ac..c473a09545 100644 --- a/cpp/src/barretenberg/crypto/merkle_tree/node_store/cached_content_addressed_tree_store.hpp +++ b/cpp/src/barretenberg/crypto/merkle_tree/node_store/cached_content_addressed_tree_store.hpp @@ -991,6 +991,12 @@ void ContentAddressedCachedTreeStore::remove_historical_block(con ReadTransactionPtr tx = create_read_transaction(); get_meta(uncommittedMeta); get_meta(committedMeta, *tx, false); + if (blockNumber < committedMeta.oldestHistoricBlock) { + // Nothing to do, the block was probably already removed + finalMeta = uncommittedMeta; + extract_db_stats(dbStats); + return; + } if (blockNumber != committedMeta.oldestHistoricBlock) { throw std::runtime_error(format("Unable to remove historical block: ", blockNumber, diff --git a/cpp/src/barretenberg/crypto/pedersen_hash/pedersen.hpp b/cpp/src/barretenberg/crypto/pedersen_hash/pedersen.hpp index a171d190a5..ca11339002 100644 --- a/cpp/src/barretenberg/crypto/pedersen_hash/pedersen.hpp +++ b/cpp/src/barretenberg/crypto/pedersen_hash/pedersen.hpp @@ -8,18 +8,19 @@ #include "../generators/generator_data.hpp" #include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp" +#include "barretenberg/ecc/groups/precomputed_generators_grumpkin_impl.hpp" namespace bb::crypto { /** * @brief Performs pedersen hashes! * - * To hash to a size-n list of field elements `x`, we return the X-coordinate of: + * To hash a size-n list of field elements `v`, we return the X-coordinate of: * - * Hash(x) = n.[h] + Commit(x) + * Hash(v) = n * [h] + Commit(v, g) * * Where `g` is a list of generator points defined by `generator_data` * And `h` is a unique generator whose domain separator is the string `pedersen_hash_length`. * - * The addition of `n.[h]` into the hash is to prevent length-extension attacks. + * The addition of `n * [h]` into the hash is to prevent length-extension attacks. * It also ensures that the hash output is never the point at infinity. * * It is neccessary that all generator points are linearly independent of one another, @@ -34,7 +35,8 @@ template class pedersen_hash_base { using Fr = typename Curve::ScalarField; using Group = typename Curve::Group; using GeneratorContext = typename crypto::GeneratorContext; - inline static constexpr AffineElement length_generator = Group::derive_generators("pedersen_hash_length", 1)[0]; + inline static constexpr AffineElement length_generator = + get_precomputed_generators()[0]; static Fq hash(const std::vector& inputs, GeneratorContext context = {}); static Fq hash_buffer(const std::vector& input, GeneratorContext context = {}); diff --git a/cpp/src/barretenberg/crypto/schnorr/multisig.hpp b/cpp/src/barretenberg/crypto/schnorr/multisig.hpp index 911e045579..5f671650f9 100644 --- a/cpp/src/barretenberg/crypto/schnorr/multisig.hpp +++ b/cpp/src/barretenberg/crypto/schnorr/multisig.hpp @@ -39,8 +39,8 @@ template cl static_assert(!std::is_same_v); public: - using Fq = typename G1::coordinate_field; - using Fr = typename G1::subgroup_field; + using Fq = typename G1::Fq; + using Fr = typename G1::Fr; using affine_element = typename G1::affine_element; using element = typename G1::element; using key_pair = crypto::schnorr_key_pair; diff --git a/cpp/src/barretenberg/crypto/schnorr/proof_of_possession.hpp b/cpp/src/barretenberg/crypto/schnorr/proof_of_possession.hpp index 5953a9d888..92bf21de31 100644 --- a/cpp/src/barretenberg/crypto/schnorr/proof_of_possession.hpp +++ b/cpp/src/barretenberg/crypto/schnorr/proof_of_possession.hpp @@ -22,8 +22,8 @@ namespace bb::crypto { * @tparam Hash function used to derive the Fiat-Shamir challenge */ template struct SchnorrProofOfPossession { - using Fq = typename G1::coordinate_field; - using Fr = typename G1::subgroup_field; + using Fq = typename G1::Fq; + using Fr = typename G1::Fr; using affine_element = typename G1::affine_element; using element = typename G1::element; using key_pair = crypto::schnorr_key_pair; diff --git a/cpp/src/barretenberg/crypto/schnorr/schnorr.tcc b/cpp/src/barretenberg/crypto/schnorr/schnorr.tcc index efd6bc0351..0dc691ea7e 100644 --- a/cpp/src/barretenberg/crypto/schnorr/schnorr.tcc +++ b/cpp/src/barretenberg/crypto/schnorr/schnorr.tcc @@ -40,7 +40,7 @@ static auto schnorr_generate_challenge(const std::string& message, const typename G1::affine_element& pubkey, const typename G1::affine_element& R) { - using Fq = typename G1::coordinate_field; + using Fq = typename G1::Fq; // create challenge message pedersen_commitment(R.x, pubkey) Fq compressed_keys = crypto::pedersen_hash::hash({ R.x, pubkey.x, pubkey.y }); std::vector e_buffer; diff --git a/cpp/src/barretenberg/dsl/acir_format/avm2_recursion_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/avm2_recursion_constraint.cpp index 067b74f6c1..3f85065d3b 100644 --- a/cpp/src/barretenberg/dsl/acir_format/avm2_recursion_constraint.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/avm2_recursion_constraint.cpp @@ -81,8 +81,11 @@ void create_dummy_vkey_and_proof(Builder& builder, offset += 4; } - builder.assert_equal(builder.add_variable(1 << log_circuit_size), proof_fields[0].witness_index); - offset = 1; + // This routine is adding some placeholders for avm proof and avm vk in the case where witnesses are not present. + // TODO(#14234)[Unconditional PIs validation]: Remove next line and use offset == 0 for subsequent line. + builder.assert_equal(builder.add_variable(1), proof_fields[0].witness_index); + builder.assert_equal(builder.add_variable(1 << log_circuit_size), proof_fields[1].witness_index); + offset = 2; // TODO(#14234)[Unconditional PIs validation]: reset offset = 1 // Witness Commitments for (size_t i = 0; i < Flavor::NUM_WITNESS_ENTITIES; i++) { diff --git a/cpp/src/barretenberg/dsl/acir_format/avm2_recursion_constraint.test.cpp b/cpp/src/barretenberg/dsl/acir_format/avm2_recursion_constraint.test.cpp index a494b6d0a8..fc11c97047 100644 --- a/cpp/src/barretenberg/dsl/acir_format/avm2_recursion_constraint.test.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/avm2_recursion_constraint.test.cpp @@ -51,13 +51,16 @@ class AcirAvm2RecursionConstraint : public ::testing::Test { auto [trace, public_inputs] = avm2::testing::get_minimal_trace_with_pi(); InnerProver prover; - const auto [proof, vk_data] = prover.prove(std::move(trace)); + auto [proof, vk_data] = prover.prove(std::move(trace)); const auto verification_key = InnerProver::create_verification_key(vk_data); const bool verified = prover.verify(proof, public_inputs, vk_data); EXPECT_TRUE(verified) << "native proof verification failed"; const auto public_inputs_flat = PublicInputs::columns_to_flat(public_inputs.to_columns()); + + // TODO(#14234)[Unconditional PIs validation]: Remove next line + proof.insert(proof.begin(), 0); return { proof, verification_key, public_inputs_flat }; } diff --git a/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.cpp index 885b107e75..34c26d1fc3 100644 --- a/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.cpp @@ -94,16 +94,17 @@ void create_dummy_vkey_and_proof(typename Flavor::CircuitBuilder& builder, builder.assert_equal(builder.add_variable(fr::random_element()), proof_fields[offset].witness_index); offset++; } - // TODO(https://github.com/AztecProtocol/barretenberg/issues/1352): Using SMALL_DUMMY_VALUE might resolve this - // issue. - fr SMALL_DUMMY_VALUE(2); // arbtirary small value that shouldn't cause builder problems. - // The aggregation object + + // Get some values for a valid aggregation object and use them here to avoid divide by 0 or other issues. + std::array::PUBLIC_INPUTS_SIZE> dummy_pairing_points_values = + PairingPoints::construct_dummy(); for (size_t i = 0; i < PairingPoints::PUBLIC_INPUTS_SIZE; i++) { - builder.assert_equal(builder.add_variable(SMALL_DUMMY_VALUE), proof_fields[offset].witness_index); + builder.assert_equal(builder.add_variable(dummy_pairing_points_values[i]), proof_fields[offset].witness_index); offset++; } // IPA claim + // TODO(https://github.com/AztecProtocol/barretenberg/issues/1392): Don't use random elements here. if constexpr (HasIPAAccumulator) { for (size_t i = 0; i < bb::IPA_CLAIM_SIZE; i++) { builder.assert_equal(builder.add_variable(fr::random_element()), proof_fields[offset].witness_index); diff --git a/cpp/src/barretenberg/dsl/acir_format/ivc_recursion_constraint.cpp b/cpp/src/barretenberg/dsl/acir_format/ivc_recursion_constraint.cpp index ec2bb48070..60b20c2a95 100644 --- a/cpp/src/barretenberg/dsl/acir_format/ivc_recursion_constraint.cpp +++ b/cpp/src/barretenberg/dsl/acir_format/ivc_recursion_constraint.cpp @@ -145,11 +145,32 @@ std::vector create_mock_oink_proof(const size_t num_public_inputs std::vector proof; // Populate mock public inputs - FF MAGIC_PUBLIC_INPUT = 2; // arbitrary small non-zero value to avoid errors - for (size_t i = 0; i < num_public_inputs; ++i) { - proof.emplace_back(MAGIC_PUBLIC_INPUT); + // Get some values for a valid aggregation object and use them here to avoid divide by 0 or other issues. + std::array::PUBLIC_INPUTS_SIZE> + dummy_pairing_points_values = stdlib::recursion::PairingPoints::construct_dummy(); + size_t public_input_count = 0; + for (size_t i = 0; i < stdlib::recursion::PairingPoints::PUBLIC_INPUTS_SIZE; i++) { + proof.emplace_back(dummy_pairing_points_values[i]); + public_input_count++; } + if (public_input_count < num_public_inputs) { + // Databus commitments if necessary + for (size_t i = 0; i < NUM_DATABUS_COMMITMENTS; ++i) { + // We represent commitments in the public inputs as biggroup elements. + using BigGroup = stdlib::element_default::element, + stdlib::field_t, + curve::BN254::Group>; + auto pub_input_comm_vals = BigGroup::construct_dummy(); + for (const fr& comm_fr : pub_input_comm_vals) { + proof.emplace_back(comm_fr); + public_input_count++; + } + } + } + BB_ASSERT_EQ(public_input_count, num_public_inputs, "Mock oink proof has the wrong number of public inputs."); + // Populate mock witness polynomial commitments auto mock_commitment = curve::BN254::AffineElement::one(); std::vector mock_commitment_frs = field_conversion::convert_to_bn254_frs(mock_commitment); diff --git a/cpp/src/barretenberg/ecc/curves/bn254/fq.test.cpp b/cpp/src/barretenberg/ecc/curves/bn254/fq.test.cpp index 7281257356..eb7c914345 100644 --- a/cpp/src/barretenberg/ecc/curves/bn254/fq.test.cpp +++ b/cpp/src/barretenberg/ecc/curves/bn254/fq.test.cpp @@ -118,10 +118,10 @@ TEST(fq, MulShortIntegers) constexpr fq b{ 0xb, 0, 0, 0 }; constexpr uint256_t a_original(a); constexpr uint256_t b_original(b); - constexpr uint256_t prod_expected = (uint512_t(a_original) * uint512_t(b_original) % uint512_t(fq::modulus)).lo; - constexpr fq const_expected = prod_expected; + uint256_t prod_expected = (uint512_t(a_original) * uint512_t(b_original) % uint512_t(fq::modulus)).lo; + fq const_expected = prod_expected; constexpr fq const_result = a * b; - static_assert(const_result == const_expected); + ASSERT(const_result == const_expected); fq c; fq d; @@ -541,4 +541,4 @@ TEST(fq, EquivalentRandomness) uint512_t q(fq::modulus); constexpr auto pow_2_256 = fq(uint256_t(1) << 128).sqr(); EXPECT_EQ(random_lo + pow_2_256 * random_hi, fq((random_uint512 % q).lo)); -} \ No newline at end of file +} diff --git a/cpp/src/barretenberg/ecc/curves/bn254/g1.test.cpp b/cpp/src/barretenberg/ecc/curves/bn254/g1.test.cpp index e217198125..dec5d260d9 100644 --- a/cpp/src/barretenberg/ecc/curves/bn254/g1.test.cpp +++ b/cpp/src/barretenberg/ecc/curves/bn254/g1.test.cpp @@ -1,4 +1,6 @@ #include "g1.hpp" +#include "barretenberg/circuit_checker/circuit_checker.hpp" +#include "barretenberg/ecc/groups/precomputed_generators_bn254_impl.hpp" #include using namespace bb; @@ -418,3 +420,11 @@ TEST(g1, InitializationCheck) EXPECT_NO_THROW(write({})); } #endif + +TEST(g1, CheckPrecomputedGenerators) +{ + ASSERT_TRUE((bb::check_precomputed_generators())); + ASSERT_TRUE((bb::check_precomputed_generators())); + ASSERT_TRUE((bb::check_precomputed_generators())); + ASSERT_TRUE((bb::check_precomputed_generators())); +} diff --git a/cpp/src/barretenberg/ecc/curves/grumpkin/grumpkin.hpp b/cpp/src/barretenberg/ecc/curves/grumpkin/grumpkin.hpp index 6408159c89..b3103cf15d 100644 --- a/cpp/src/barretenberg/ecc/curves/grumpkin/grumpkin.hpp +++ b/cpp/src/barretenberg/ecc/curves/grumpkin/grumpkin.hpp @@ -78,4 +78,4 @@ class Grumpkin { // length 3 is sufficient. static constexpr uint32_t LIBRA_UNIVARIATES_LENGTH = 3; }; -} // namespace bb::curve \ No newline at end of file +} // namespace bb::curve diff --git a/cpp/src/barretenberg/ecc/curves/grumpkin/grumpkin.test.cpp b/cpp/src/barretenberg/ecc/curves/grumpkin/grumpkin.test.cpp index 5573e08ea3..86993e30a8 100644 --- a/cpp/src/barretenberg/ecc/curves/grumpkin/grumpkin.test.cpp +++ b/cpp/src/barretenberg/ecc/curves/grumpkin/grumpkin.test.cpp @@ -1,4 +1,5 @@ #include "grumpkin.hpp" +#include "barretenberg/ecc/groups/precomputed_generators_grumpkin_impl.hpp" #include #include @@ -329,3 +330,9 @@ TEST(grumpkin, BadPoints) } EXPECT_TRUE(res); } + +TEST(grumpkin, CheckPrecomputedGenerators) +{ + ASSERT_TRUE((bb::check_precomputed_generators())); + ASSERT_TRUE((bb::check_precomputed_generators())); +} diff --git a/cpp/src/barretenberg/ecc/curves/secp256k1/secp256k1.test.cpp b/cpp/src/barretenberg/ecc/curves/secp256k1/secp256k1.test.cpp index 0132643ced..32a8ab4cf0 100644 --- a/cpp/src/barretenberg/ecc/curves/secp256k1/secp256k1.test.cpp +++ b/cpp/src/barretenberg/ecc/curves/secp256k1/secp256k1.test.cpp @@ -73,7 +73,7 @@ TEST(secp256k1, TestToMontgomeryForm) #if defined(__SIZEOF_INT128__) && !defined(__wasm__) constexpr uint512_t R = uint512_t(0, 1); #else - constexpr uint512_t R = (uint512_t(1) << (29 * 9)) % uint512_t(test_fq_mod); + const uint512_t R = (uint512_t(1) << (29 * 9)) % uint512_t(test_fq_mod); #endif uint512_t aR = uint512_t(a_raw) * R; uint256_t expected = (aR % uint512_t(test_fq_mod)).lo; diff --git a/cpp/src/barretenberg/ecc/curves/secp256r1/secp256r1.test.cpp b/cpp/src/barretenberg/ecc/curves/secp256r1/secp256r1.test.cpp index 0b2befbb74..c35bf07742 100644 --- a/cpp/src/barretenberg/ecc/curves/secp256r1/secp256r1.test.cpp +++ b/cpp/src/barretenberg/ecc/curves/secp256r1/secp256r1.test.cpp @@ -1,4 +1,5 @@ #include "secp256r1.hpp" +#include "barretenberg/ecc/groups/precomputed_generators_secp256r1_impl.hpp" #include "barretenberg/numeric/random/engine.hpp" #include @@ -73,7 +74,7 @@ TEST(secp256r1, TestToMontgomeryForm) #if defined(__SIZEOF_INT128__) && !defined(__wasm__) constexpr uint512_t R = uint512_t(0, 1); #else - constexpr uint512_t R = (uint512_t(1) << (29 * 9)) % uint512_t(test_fq_mod); + const uint512_t R = (uint512_t(1) << (29 * 9)) % uint512_t(test_fq_mod); #endif uint512_t aR = uint512_t(a_raw) * R; uint256_t expected = (aR % uint512_t(test_fq_mod)).lo; @@ -450,4 +451,22 @@ TEST(secp256r1, MontgomeryMulBigBug) secp256r1::fr expected(uint256_t{ 0x57abc6aa0349c084, 0x65b21b232a4cb7a5, 0x5ba781948b0fcd6e, 0xd6e9e0644bda12f7 }); EXPECT_EQ((a_sqr == expected), true); } -#endif \ No newline at end of file +#endif + +TEST(secp256r1, CheckPrecomputedGenerators) +{ + ASSERT_TRUE((bb::check_precomputed_generators())); + ASSERT_TRUE((bb::check_precomputed_generators())); +} + +// Hacky: wasm does not properly find main() from gmock_main. +// We only want to run wasm tests specifically for ecc ops as our field handling is different. +// We need to make sure the hardcoded generators make sense. +// As this is our narrow focus, we hack this so ecc_tests can run. +#ifdef __wasm__ +GTEST_API_ int main(int argc, char** argv) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/cpp/src/barretenberg/ecc/groups/affine_element.hpp b/cpp/src/barretenberg/ecc/groups/affine_element.hpp index aae4e38b25..d5e8f68824 100644 --- a/cpp/src/barretenberg/ecc/groups/affine_element.hpp +++ b/cpp/src/barretenberg/ecc/groups/affine_element.hpp @@ -17,10 +17,11 @@ namespace bb::group_elements { template concept SupportsHashToCurve = T::can_hash_to_curve; -template class alignas(64) affine_element { +template class alignas(64) affine_element { public: using Fq = Fq_; using Fr = Fr_; + using Params = Params_; using in_buf = const uint8_t*; using vec_in_buf = const uint8_t*; diff --git a/cpp/src/barretenberg/ecc/groups/affine_element_impl.hpp b/cpp/src/barretenberg/ecc/groups/affine_element_impl.hpp index 19e5091d87..56ba0bda3e 100644 --- a/cpp/src/barretenberg/ecc/groups/affine_element_impl.hpp +++ b/cpp/src/barretenberg/ecc/groups/affine_element_impl.hpp @@ -237,7 +237,6 @@ template constexpr affine_element affine_element::hash_to_curve(const std::vector& seed, uint8_t attempt_count) noexcept requires SupportsHashToCurve - { std::vector target_seed(seed); // expand by 2 bytes to cover incremental hash attempts diff --git a/cpp/src/barretenberg/ecc/groups/element.hpp b/cpp/src/barretenberg/ecc/groups/element.hpp index b515fb32fe..5fbd7f4633 100644 --- a/cpp/src/barretenberg/ecc/groups/element.hpp +++ b/cpp/src/barretenberg/ecc/groups/element.hpp @@ -40,7 +40,7 @@ template class alignas(32) element { constexpr element(const element& other) noexcept; constexpr element(element&& other) noexcept; constexpr element(const affine_element& other) noexcept; - constexpr ~element() noexcept = default; + ~element() noexcept = default; static constexpr element one() noexcept { return { Params::one_x, Params::one_y, Fq::one() }; }; static constexpr element zero() noexcept diff --git a/cpp/src/barretenberg/ecc/groups/group.hpp b/cpp/src/barretenberg/ecc/groups/group.hpp index fd1d5ba03e..7e447066d9 100644 --- a/cpp/src/barretenberg/ecc/groups/group.hpp +++ b/cpp/src/barretenberg/ecc/groups/group.hpp @@ -17,39 +17,38 @@ #include #include #include + namespace bb { /** * @brief group class. Represents an elliptic curve group element. - * Group is parametrised by coordinate_field and subgroup_field + * Group is parametrised by Fq and Fr * * Note: Currently subgroup checks are NOT IMPLEMENTED * Our current implementation uses G1 points that have a cofactor of 1. * All G2 points are precomputed (generator [1]_2 and trusted setup point [x]_2). * Explicitly assume precomputed points are valid members of the prime-order subgroup for G2. * - * @tparam coordinate_field + * @tparam Fq * @tparam subgroup_field - * @tparam GroupParams + * @tparam Params */ -template class group { +template class group { public: - // hoist coordinate_field, subgroup_field into the public namespace - using coordinate_field = _coordinate_field; - using subgroup_field = _subgroup_field; - using element = group_elements::element; - using affine_element = group_elements::affine_element; - using Fq = coordinate_field; - using Fr = subgroup_field; - static constexpr bool USE_ENDOMORPHISM = GroupParams::USE_ENDOMORPHISM; - static constexpr bool has_a = GroupParams::has_a; + // Allow using group::Fq and group::Fr + using Fq = Fq_; + using Fr = Fr_; + using element = group_elements::element; + using affine_element = group_elements::affine_element; + static constexpr bool USE_ENDOMORPHISM = Params::USE_ENDOMORPHISM; + static constexpr bool has_a = Params::has_a; - static constexpr element one{ GroupParams::one_x, GroupParams::one_y, coordinate_field::one() }; + static constexpr element one{ Params::one_x, Params::one_y, Fq::one() }; static constexpr element point_at_infinity = one.set_infinity(); - static constexpr affine_element affine_one{ GroupParams::one_x, GroupParams::one_y }; + static constexpr affine_element affine_one{ Params::one_x, Params::one_y }; static constexpr affine_element affine_point_at_infinity = affine_one.set_infinity(); - static constexpr coordinate_field curve_a = GroupParams::a; - static constexpr coordinate_field curve_b = GroupParams::b; + static constexpr Fq curve_a = Params::a; + static constexpr Fq curve_b = Params::b; /** * @brief Derives generator points via hash-to-curve @@ -65,7 +64,7 @@ template */ - inline static constexpr std::vector derive_generators( - const std::vector& domain_separator_bytes, - const size_t num_generators, - const size_t starting_index = 0) + inline static std::vector derive_generators(const std::vector& domain_separator_bytes, + const size_t num_generators, + const size_t starting_index = 0) { std::vector result; const auto domain_hash = blake3::blake3s_constexpr(&domain_separator_bytes[0], domain_separator_bytes.size()); @@ -110,9 +108,9 @@ template derive_generators(const std::string_view& domain_separator, - const size_t num_generators, - const size_t starting_index = 0) + inline static std::vector derive_generators(const std::string_view& domain_separator, + const size_t num_generators, + const size_t starting_index = 0) { std::vector domain_bytes; for (char i : domain_separator) { diff --git a/cpp/src/barretenberg/ecc/groups/group_impl_asm.tcc b/cpp/src/barretenberg/ecc/groups/group_impl_asm.tcc index 3ea790cbfe..ad2d8b34d9 100644 --- a/cpp/src/barretenberg/ecc/groups/group_impl_asm.tcc +++ b/cpp/src/barretenberg/ecc/groups/group_impl_asm.tcc @@ -7,11 +7,11 @@ namespace bb { // copies src into dest. n.b. both src and dest must be aligned on 32 byte boundaries -// template -// inline void group::copy(const affine_element* src, affine_element* +// template +// inline void group::copy(const affine_element* src, affine_element* // dest) // { -// if constexpr (GroupParams::small_elements) { +// if constexpr (Params::small_elements) { // #if defined __AVX__ && defined USE_AVX // ASSERT((((uintptr_t)src & 0x1f) == 0)); // ASSERT((((uintptr_t)dest & 0x1f) == 0)); @@ -31,10 +31,10 @@ namespace bb { // } // // copies src into dest. n.b. both src and dest must be aligned on 32 byte boundaries -// template -// inline void group::copy(const element* src, element* dest) +// template +// inline void group::copy(const element* src, element* dest) // { -// if constexpr (GroupParams::small_elements) { +// if constexpr (Params::small_elements) { // #if defined __AVX__ && defined USE_AVX // ASSERT((((uintptr_t)src & 0x1f) == 0)); // ASSERT((((uintptr_t)dest & 0x1f) == 0)); @@ -57,19 +57,19 @@ namespace bb { // copies src into dest, inverting y-coordinate if 'predicate' is true // n.b. requires src and dest to be aligned on 32 byte boundary -template -inline void group::conditional_negate_affine(const affine_element* src, - affine_element* dest, - uint64_t predicate) +template +inline void group::conditional_negate_affine(const affine_element* src, + affine_element* dest, + uint64_t predicate) { - constexpr uint256_t twice_modulus = coordinate_field::modulus + coordinate_field::modulus; + constexpr uint256_t twice_modulus = Fq::modulus + Fq::modulus; constexpr uint64_t twice_modulus_0 = twice_modulus.data[0]; constexpr uint64_t twice_modulus_1 = twice_modulus.data[1]; constexpr uint64_t twice_modulus_2 = twice_modulus.data[2]; constexpr uint64_t twice_modulus_3 = twice_modulus.data[3]; - if constexpr (GroupParams::small_elements) { + if constexpr (Params::small_elements) { #if defined __AVX__ && defined USE_AVX ASSERT((((uintptr_t)src & 0x1f) == 0)); ASSERT((((uintptr_t)dest & 0x1f) == 0)); @@ -149,7 +149,7 @@ inline void group::conditional_ne #endif } else { if (predicate) { // NOLINT - coordinate_field::__copy(src->x, dest->x); + Fq::__copy(src->x, dest->x); dest->y = -src->y; } else { copy_affine(*src, *dest); @@ -159,4 +159,4 @@ inline void group::conditional_ne } // namespace bb -#endif \ No newline at end of file +#endif diff --git a/cpp/src/barretenberg/ecc/groups/group_impl_int128.tcc b/cpp/src/barretenberg/ecc/groups/group_impl_int128.tcc index 7f82c83037..761cbe7d13 100644 --- a/cpp/src/barretenberg/ecc/groups/group_impl_int128.tcc +++ b/cpp/src/barretenberg/ecc/groups/group_impl_int128.tcc @@ -8,27 +8,27 @@ namespace bb { // // copies src into dest. n.b. both src and dest must be aligned on 32 byte boundaries -// template -// inline void group::copy(const affine_element* src, affine_element* +// template +// inline void group::copy(const affine_element* src, affine_element* // dest) // { // *dest = *src; // } // // copies src into dest. n.b. both src and dest must be aligned on 32 byte boundaries -// template -// inline void group::copy(const element* src, element* dest) +// template +// inline void group::copy(const element* src, element* dest) // { // *dest = *src; // } -template -inline void group::conditional_negate_affine(const affine_element* src, - affine_element* dest, - uint64_t predicate) +template +inline void group::conditional_negate_affine(const affine_element* src, + affine_element* dest, + uint64_t predicate) { *dest = predicate ? -(*src) : (*src); } } // namespace bb -#endif \ No newline at end of file +#endif diff --git a/cpp/src/barretenberg/ecc/groups/precomputed_generators.hpp b/cpp/src/barretenberg/ecc/groups/precomputed_generators.hpp new file mode 100644 index 0000000000..df5fac1308 --- /dev/null +++ b/cpp/src/barretenberg/ecc/groups/precomputed_generators.hpp @@ -0,0 +1,122 @@ +#pragma once + +#include "barretenberg/common/zip_view.hpp" +#include "group.hpp" +#include +#include +#include +#include +namespace bb::detail { +// Each 'generators' array is specialized in the precomputed_generators_*_impl.hpp files. + +// Compile-time string +template struct DomainSeparator { + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) + constexpr DomainSeparator(const char (&str)[N]) + { + for (std::size_t i = 0; i < N; ++i) { + value[i] = str[i]; + } + } + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) + char value[N]; +}; + +// Interface for the generator constants. +// Each 'generators' array is specialized in the precomputed_generators_*_impl.hpp files for each type domain separator, +// type, num, starting index tuple that we have in use. +template +struct PrecomputedGenerators { + // If this is being invoked, there is a missing specialization in the _impl.hpp files. + static constexpr std::span get_generators() + { + // Add dependency on template parameters to force lazy evaluation of the static_assert. + // This will always evaluate to false if called. + static_assert(domain_separator.value[0] == '0', + "Should not be called! Relevant precomputed_generators_*_impl.hpp file not included OR does not " + "have this specialization."); + }; +}; +} // namespace bb::detail + +namespace bb { + +template +constexpr std::span get_precomputed_generators() +{ + return detail::PrecomputedGenerators::get_generators(); +} + +template +inline bool check_precomputed_generators() +{ + const auto precomputed = detail::PrecomputedGenerators::get_generators(); + const auto generators = Group::derive_generators(domain_separator.value, num_generators, starting_index); + if (precomputed.size() != generators.size()) { + info("Precomputed generators size mismatch"); + return false; + } + for (auto [p, g] : zip_view(precomputed, generators)) { + if (p != g) { + info("WARNING: Generators do not match precomputed generators! THESE SHOULD GENERALLY NOT CHANGE, " + "SOMETHING MAY BE WRONG ON A MORE FUNDAMENTAL LEVEL!"); + info("WARNING: IF YOU REALLY ARE SURE THESE NEED TO BE CHANGED: Include the below code in " + "precomputed_generators_*_impl.hpp to hardcode the generators"); + + // Demangle the AffineElement type name to get a human-readable string. + char* demangled_name_c_str = + abi::__cxa_demangle(typeid(typename Group::affine_element).name(), nullptr, nullptr, nullptr); + std::string type_name_str = + demangled_name_c_str != nullptr + ? demangled_name_c_str + : typeid(typename Group::affine_element).name(); // Fallback if demangling fails + + // Print the header of the class specialization + info("template <> class PrecomputedGenerators<\"", + domain_separator.value, // domain_separator.value is char[N] + "\", ", + type_name_str, + ", ", + num_generators, + ", ", + starting_index, + "> {"); + + // Print the public section and method signature + info("with these values for generators: "); + for (size_t i = 0; i < generators.size(); ++i) { + std::stringstream x_stream; + x_stream << generators[i].x; + std::stringstream y_stream; + y_stream << generators[i].y; + const char* suffix = (i == generators.size() - 1) ? "" : ","; + info(" { uint256_t(\"", x_stream.str(), "\"), uint256_t(\"", y_stream.str(), "\") }", suffix); + } + info(" }"); + info("};"); + + // Free the memory allocated by abi::__cxa_demangle + if (demangled_name_c_str != nullptr) { + std::free(demangled_name_c_str); // NOLINT + } + return false; + } + } + return true; +} +} // namespace bb diff --git a/cpp/src/barretenberg/ecc/groups/precomputed_generators_bn254_impl.hpp b/cpp/src/barretenberg/ecc/groups/precomputed_generators_bn254_impl.hpp new file mode 100644 index 0000000000..9ac10a6ec0 --- /dev/null +++ b/cpp/src/barretenberg/ecc/groups/precomputed_generators_bn254_impl.hpp @@ -0,0 +1,45 @@ +#pragma once +#include "barretenberg/ecc/curves/bn254/g1.hpp" +#include "group.hpp" +#include "precomputed_generators.hpp" +// NOTE: Must be included before using get_precomputed_generators if using bn254 g1! +namespace bb::detail { +template <> class PrecomputedGenerators<"biggroup table offset generator", g1::affine_element, 1, 0> { + public: + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) + static constexpr g1::affine_element generators[1] = { + { uint256_t("0x240d420bc60418af2206bdf32238eee77a8c46772f2679881a1858aab7b8927f"), + uint256_t("0x04ffcf276f8bc77315c2674207a3f55861b09acebd1ea9623883613f538e3822") } + }; + static constexpr std::span get_generators() { return generators; } +}; +template <> class PrecomputedGenerators<"biggroup offset generator", g1::affine_element, 1, 0> { + public: + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) + static constexpr g1::affine_element generators[1] = { + { uint256_t("0x169b33374f53b95f16edf369c34509da6485297ee10452a62af4bd2820d6fb33"), + uint256_t("0x019d6e473e9b638cfe2b8f232288a075050a381b745cffaa9f9264121567315b") } + }; + static constexpr std::span get_generators() { return generators; } +}; +template <> class PrecomputedGenerators<"ECCVM_OFFSET_GENERATOR", g1::affine_element, 1, 0> { + public: + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) + static constexpr g1::affine_element generators[1] = { + { uint256_t("0x2728608c9bfb52035a3f2f1d18e4c604d4da7611b3e265566265e9b7d36642b2"), + uint256_t("0x0451a4da5a6303859c4755dac222ae1d164db7ca52a19321f46a7b88a64f7742") } + }; + static constexpr std::span get_generators() { return generators; } +}; +template <> class PrecomputedGenerators<"test generators", g1::affine_element, 2, 0> { + public: + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) + static constexpr g1::affine_element generators[2] = { + { uint256_t("0x08777a8c0abf512ca2ddd6a1de3ff3c76788ceabefad95079784c425f260ea7d"), + uint256_t("0x1172b72b11c4eb0e2be55499c03bd7fd92b4416c6bb286790018ae51d7e1a755") }, + { uint256_t("0x1a934324fa18c1d0ebc2f212a62813ae269ce204e44d1152f9b42190f23926d1"), + uint256_t("0x1949167f938661c05783512d44d88e81da1edb8dc1923572880d861de2a65d39") } + }; + static constexpr std::span get_generators() { return generators; } +}; +}; // namespace bb::detail diff --git a/cpp/src/barretenberg/ecc/groups/precomputed_generators_grumpkin_impl.hpp b/cpp/src/barretenberg/ecc/groups/precomputed_generators_grumpkin_impl.hpp new file mode 100644 index 0000000000..35cb50b680 --- /dev/null +++ b/cpp/src/barretenberg/ecc/groups/precomputed_generators_grumpkin_impl.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp" +#include "group.hpp" +#include "precomputed_generators.hpp" + +// NOTE: Must be included before using get_precomputed_generators if using grumpkin g1! +namespace bb::detail { + +template <> class PrecomputedGenerators<"pedersen_hash_length", bb::grumpkin::g1::affine_element, 1, 0> { + public: + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) + static constexpr curve::Grumpkin::AffineElement generators[1] = { + { uint256_t("0x2df8b940e5890e4e1377e05373fae69a1d754f6935e6a780b666947431f2cdcd"), + uint256_t("0x2ecd88d15967bc53b885912e0d16866154acb6aac2d3f85e27ca7eefb2c19083") } + }; + static constexpr std::span get_generators() { return generators; } +}; + +template <> class PrecomputedGenerators<"DEFAULT_DOMAIN_SEPARATOR", bb::grumpkin::g1::affine_element, 8, 0> { + public: + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) + static constexpr grumpkin::g1::affine_element generators[8] = { + { uint256_t("0x083e7911d835097629f0067531fc15cafd79a89beecb39903f69572c636f4a5a"), + uint256_t("0x1a7f5efaad7f315c25a918f30cc8d7333fccab7ad7c90f14de81bcc528f9935d") }, + { uint256_t("0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402"), + uint256_t("0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126") }, + { uint256_t("0x1c44f2a5207c81c28a8321a5815ce8b1311024bbed131819bbdaf5a2ada84748"), + uint256_t("0x03aaee36e6422a1d0191632ac6599ae9eba5ac2c17a8c920aa3caf8b89c5f8a8") }, + { uint256_t("0x26d8b1160c6821a30c65f6cb47124afe01c29f4338f44d4a12c9fccf22fb6fb2"), + uint256_t("0x05c70c3b9c0d25a4c100e3a27bf3cc375f8af8cdd9498ec4089a823d7464caff") }, + { uint256_t("0x20ed9c6a1d27271c4498bfce0578d59db1adbeaa8734f7facc097b9b994fcf6e"), + uint256_t("0x29cd7d370938b358c62c4a00f73a0d10aba7e5aaa04704a0713f891ebeb92371") }, + { uint256_t("0x0224a8abc6c8b8d50373d64cd2a1ab1567bf372b3b1f7b861d7f01257052d383"), + uint256_t("0x2358629b90eafb299d6650a311e79914b0215eb0a790810b26da5a826726d711") }, + { uint256_t("0x0f106f6d46bc904a5290542490b2f238775ff3c445b2f8f704c466655f460a2a"), + uint256_t("0x29ab84d472f1d33f42fe09c47b8f7710f01920d6155250126731e486877bcf27") }, + { uint256_t("0x0298f2e42249f0519c8a8abd91567ebe016e480f219b8c19461d6a595cc33696"), + uint256_t("0x035bec4b8520a4ece27bd5aafabee3dfe1390d7439c419a8c55aceb207aac83b") } + }; + static constexpr std::span get_generators() { return generators; } +}; + +}; // namespace bb::detail diff --git a/cpp/src/barretenberg/ecc/groups/precomputed_generators_secp256r1_impl.hpp b/cpp/src/barretenberg/ecc/groups/precomputed_generators_secp256r1_impl.hpp new file mode 100644 index 0000000000..bfad462104 --- /dev/null +++ b/cpp/src/barretenberg/ecc/groups/precomputed_generators_secp256r1_impl.hpp @@ -0,0 +1,27 @@ +#pragma once +#include "barretenberg/ecc/curves/secp256r1/secp256r1.hpp" +#include "precomputed_generators.hpp" + +// NOTE: Must be included before using get_precomputed_generators if using secp g1! +namespace bb::detail { + +template <> class PrecomputedGenerators<"biggroup table offset generator", secp256r1::g1::affine_element, 1UL, 0UL> { + public: + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) + static constexpr secp256r1::g1::affine_element generators[1] = { + { uint256_t("0x12f1907bc0f7caa93716082e67e3466f525281c6a2cd95990b6d3582b5c1375f"), + uint256_t("0x3111b47a8c982605786143f3d7b4f4c754a1b83aeaa81a7af6b90176b7328d08") } + }; + static constexpr std::span get_generators() { return generators; }; +}; +template <> class PrecomputedGenerators<"biggroup offset generator", secp256r1::g1::affine_element, 1UL, 0UL> { + public: + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) + static constexpr secp256r1::g1::affine_element generators[1] = { + { uint256_t("0xb61bd0f5671bc04ec041799e87e735af4ed40920c6ca71e63c8010ff162bd90a"), + uint256_t("0x338540b43f94cbfe32a1e62d192ea7d5827f4a4a66bb781a02321033110e492b") } + }; + static constexpr std::span get_generators() { return generators; }; +}; + +} // namespace bb::detail diff --git a/cpp/src/barretenberg/eccvm/eccvm_circuit_builder.hpp b/cpp/src/barretenberg/eccvm/eccvm_circuit_builder.hpp index fa030630f7..96ce9c4999 100644 --- a/cpp/src/barretenberg/eccvm/eccvm_circuit_builder.hpp +++ b/cpp/src/barretenberg/eccvm/eccvm_circuit_builder.hpp @@ -26,7 +26,7 @@ class ECCVMCircuitBuilder { using FF = grumpkin::fr; using Polynomial = bb::Polynomial; - using CycleScalar = typename CycleGroup::subgroup_field; + using CycleScalar = typename CycleGroup::Fr; using Element = typename CycleGroup::element; using AffineElement = typename CycleGroup::affine_element; diff --git a/cpp/src/barretenberg/eccvm/msm_builder.hpp b/cpp/src/barretenberg/eccvm/msm_builder.hpp index ab8b994462..ed10c53e42 100644 --- a/cpp/src/barretenberg/eccvm/msm_builder.hpp +++ b/cpp/src/barretenberg/eccvm/msm_builder.hpp @@ -9,6 +9,7 @@ #include #include "./eccvm_builder_types.hpp" +#include "barretenberg/ecc/groups/precomputed_generators_bn254_impl.hpp" #include "barretenberg/op_queue/ecc_op_queue.hpp" namespace bb { @@ -214,8 +215,8 @@ class ECCVMMSMMBuilder { // accumulator_trace tracks the value of the ECCVM accumulator for each row std::span accumulator_trace(&points_to_normalize[num_point_adds_and_doubles * 3], num_accumulators); - // we start the accumulator at the offset generator point. This ensures we can support an MSM that produces a - constexpr auto offset_generator = bb::g1::derive_generators("ECCVM_OFFSET_GENERATOR", 1)[0]; + // we start the accumulator at the offset generator point + constexpr auto offset_generator = get_precomputed_generators()[0]; accumulator_trace[0] = offset_generator; // TODO(https://github.com/AztecProtocol/barretenberg/issues/973): Reinstate multitreading? diff --git a/cpp/src/barretenberg/eccvm/transcript_builder.hpp b/cpp/src/barretenberg/eccvm/transcript_builder.hpp index 166f7faa6e..518462b00e 100644 --- a/cpp/src/barretenberg/eccvm/transcript_builder.hpp +++ b/cpp/src/barretenberg/eccvm/transcript_builder.hpp @@ -7,6 +7,8 @@ #pragma once #include "./eccvm_builder_types.hpp" +#include "barretenberg/ecc/groups/precomputed_generators_bn254_impl.hpp" +#include "barretenberg/op_queue/ecc_ops_table.hpp" namespace bb { @@ -72,7 +74,8 @@ class ECCVMTranscriptBuilder { */ static AffineElement offset_generator() { - static constexpr auto offset_generator_base = CycleGroup::derive_generators("ECCVM_OFFSET_GENERATOR", 1)[0]; + static constexpr auto offset_generator_base = + get_precomputed_generators()[0]; static const AffineElement result = AffineElement(Element(offset_generator_base) * grumpkin::fq(uint256_t(1) << 124)); return result; diff --git a/cpp/src/barretenberg/numeric/uintx/uintx.cpp b/cpp/src/barretenberg/numeric/uintx/uintx.cpp new file mode 100644 index 0000000000..dd5e263aad --- /dev/null +++ b/cpp/src/barretenberg/numeric/uintx/uintx.cpp @@ -0,0 +1,17 @@ +#include "barretenberg/numeric/uintx/uintx.hpp" +#include "uintx_impl.hpp" + +namespace bb::numeric { + +template class uintx; +template class uintx; + +// NOTE: this instantiation is only used to maintain a 1024 barrett reduction test. +// The simpler route would have been to delete that test as this modulus is otherwise not used, but this was more +// conservative. +constexpr uint512_t TEST_MODULUS(uint256_t{ "0x04689e957a1242c84a50189c6d96cadca602072d09eac1013b5458a2275d69b1" }, + uint256_t{ "0x0925c4b8763cbf9c599a6f7c0348d21cb00b85511637560626edfa5c34c6b38d" }); + +template std::pair uintx::barrett_reduction() const; + +} // namespace bb::numeric diff --git a/cpp/src/barretenberg/numeric/uintx/uintx.hpp b/cpp/src/barretenberg/numeric/uintx/uintx.hpp index 1bf3661ac7..134463d0f9 100644 --- a/cpp/src/barretenberg/numeric/uintx/uintx.hpp +++ b/cpp/src/barretenberg/numeric/uintx/uintx.hpp @@ -28,11 +28,17 @@ namespace bb::numeric { template class uintx { public: - constexpr uintx(const uint64_t data = 0) + constexpr uintx(const uint64_t& data = 0) : lo(data) , hi(base_uint(0)) {} + constexpr uintx(const uint256_t& data) + requires(!std::is_same_v) + : lo(data) + , hi(base_uint(0)) + + {} constexpr uintx(const base_uint input_lo) : lo(input_lo) , hi(base_uint(0)) @@ -43,130 +49,235 @@ template class uintx { , hi(input_hi) {} - constexpr uintx(const uintx& other) - : lo(other.lo) - , hi(other.hi) - {} - + constexpr uintx(const uintx& other) = default; constexpr uintx(uintx&& other) noexcept = default; static constexpr size_t length() { return 2 * base_uint::length(); } - constexpr uintx& operator=(const uintx& other) = default; - constexpr uintx& operator=(uintx&& other) noexcept = default; + uintx& operator=(const uintx& other) = default; + uintx& operator=(uintx&& other) noexcept = default; - constexpr ~uintx() = default; - explicit constexpr operator bool() const { return static_cast(lo.data[0]); }; - explicit constexpr operator uint8_t() const { return static_cast(lo.data[0]); }; - explicit constexpr operator uint16_t() const { return static_cast(lo.data[0]); }; - explicit constexpr operator uint32_t() const { return static_cast(lo.data[0]); }; - explicit constexpr operator uint64_t() const { return static_cast(lo.data[0]); }; + ~uintx() = default; + constexpr explicit operator bool() const { return static_cast(lo); }; + constexpr explicit operator uint8_t() const { return static_cast(lo); }; + constexpr explicit operator uint16_t() const { return static_cast(lo); }; + constexpr explicit operator uint32_t() const { return static_cast(lo); }; + constexpr explicit operator uint64_t() const { return static_cast(lo); }; - explicit constexpr operator base_uint() const { return lo; } + constexpr explicit operator base_uint() const { return lo; } - [[nodiscard]] constexpr bool get_bit(uint64_t bit_index) const; - [[nodiscard]] constexpr uint64_t get_msb() const; - constexpr uintx slice(uint64_t start, uint64_t end) const; + [[nodiscard]] bool get_bit(uint64_t bit_index) const; + [[nodiscard]] constexpr uint64_t get_msb() const + { + uint64_t hi_idx = hi.get_msb(); + uint64_t lo_idx = lo.get_msb(); + return (hi_idx || (hi > base_uint(0))) ? (hi_idx + base_uint::length()) : lo_idx; + } + + /** + * Viewing `this` as a bit string, and counting bits from 0, slices a substring. + * @returns the uintx equal to the substring of bits from (and including) the `start`-th bit, to (but excluding) the + * `end`-th bit of `this`. + * constexpr to be used in constant calculation. + */ + constexpr uintx slice(const uint64_t start, const uint64_t end) const + { + const uint64_t range = end - start; + const uintx mask = range == base_uint::length() ? -uintx(1) : (uintx(1) << range) - 1; + return ((*this) >> start) & mask; + } - constexpr uintx operator+(const uintx& other) const; - constexpr uintx operator-(const uintx& other) const; - constexpr uintx operator-() const; + // constexpr to be used in constant calculation. + constexpr uintx operator-(const uintx& other) const + { + base_uint res_lo = lo - other.lo; + bool borrow = res_lo > lo; + base_uint res_hi = hi - other.hi - ((borrow) ? base_uint(1) : base_uint(0)); + return { res_lo, res_hi }; + } + + // constexpr to be used in constant calculation. + constexpr uintx operator<<(const uint64_t other) const + { + const uint64_t total_shift = other; + if (total_shift >= length()) { + return uintx(0); + } + if (total_shift == 0) { + return *this; + } + const uint64_t num_shifted_limbs = total_shift >> (base_uint(base_uint::length()).get_msb()); + const uint64_t limb_shift = total_shift & static_cast(base_uint::length() - 1); + + std::array shifted_limbs = { 0, 0 }; + if (limb_shift == 0) { + shifted_limbs[0] = lo; + shifted_limbs[1] = hi; + } else { + const uint64_t remainder_shift = static_cast(base_uint::length()) - limb_shift; + + shifted_limbs[0] = lo << limb_shift; + + base_uint remainder = lo >> remainder_shift; + + shifted_limbs[1] = (hi << limb_shift) + remainder; + } + uintx result(0); + if (num_shifted_limbs == 0) { + result.hi = shifted_limbs[1]; + result.lo = shifted_limbs[0]; + } else { + result.hi = shifted_limbs[0]; + } + return result; + } + + // constexpr to be used in constant calculation. + constexpr uintx operator>>(const uint64_t other) const + { + const uint64_t total_shift = other; + if (total_shift >= length()) { + return uintx(0); + } + if (total_shift == 0) { + return *this; + } + const uint64_t num_shifted_limbs = total_shift >> (base_uint(base_uint::length()).get_msb()); + + const uint64_t limb_shift = total_shift & static_cast(base_uint::length() - 1); + + std::array shifted_limbs = { 0, 0 }; + if (limb_shift == 0) { + shifted_limbs[0] = lo; + shifted_limbs[1] = hi; + } else { + const uint64_t remainder_shift = static_cast(base_uint::length()) - limb_shift; + + shifted_limbs[1] = hi >> limb_shift; + + base_uint remainder = (hi) << remainder_shift; + + shifted_limbs[0] = (lo >> limb_shift) + remainder; + } + uintx result(0); + if (num_shifted_limbs == 0) { + result.hi = shifted_limbs[1]; + result.lo = shifted_limbs[0]; + } else { + result.lo = shifted_limbs[1]; + } + return result; + } + + // constexpr to be used in constant calculation. + constexpr uintx operator+(const uintx& other) const + { + base_uint res_lo = lo + other.lo; + bool carry = res_lo < lo; + base_uint res_hi = hi + other.hi + ((carry) ? base_uint(1) : base_uint(0)); + return { res_lo, res_hi }; + }; + uintx operator-() const; - constexpr uintx operator*(const uintx& other) const; - constexpr uintx operator/(const uintx& other) const; - constexpr uintx operator%(const uintx& other) const; + uintx operator*(const uintx& other) const; + uintx operator/(const uintx& other) const; + uintx operator%(const uintx& other) const; - constexpr std::pair mul_extended(const uintx& other) const; + std::pair mul_extended(const uintx& other) const; - constexpr uintx operator>>(uint64_t other) const; - constexpr uintx operator<<(uint64_t other) const; + // constexpr to be used in constant calculation. + constexpr uintx operator&(const uintx& other) const { return { lo & other.lo, hi & other.hi }; } - constexpr uintx operator&(const uintx& other) const; - constexpr uintx operator^(const uintx& other) const; - constexpr uintx operator|(const uintx& other) const; - constexpr uintx operator~() const; + uintx operator^(const uintx& other) const; + uintx operator|(const uintx& other) const; + uintx operator~() const; - constexpr bool operator==(const uintx& other) const; - constexpr bool operator!=(const uintx& other) const; - constexpr bool operator!() const; + bool operator==(const uintx& other) const; + bool operator!=(const uintx& other) const; + bool operator!() const; - constexpr bool operator>(const uintx& other) const; - constexpr bool operator<(const uintx& other) const; - constexpr bool operator>=(const uintx& other) const; - constexpr bool operator<=(const uintx& other) const; + bool operator>(const uintx& other) const; + bool operator<(const uintx& other) const; + bool operator>=(const uintx& other) const; + bool operator<=(const uintx& other) const; - constexpr uintx& operator+=(const uintx& other) + uintx& operator+=(const uintx& other) { *this = *this + other; return *this; }; - constexpr uintx& operator-=(const uintx& other) + uintx& operator-=(const uintx& other) { *this = *this - other; return *this; }; - constexpr uintx& operator*=(const uintx& other) + uintx& operator*=(const uintx& other) { *this = *this * other; return *this; }; - constexpr uintx& operator/=(const uintx& other) + uintx& operator/=(const uintx& other) + { *this = *this / other; return *this; }; - constexpr uintx& operator%=(const uintx& other) + uintx& operator%=(const uintx& other) + { *this = *this % other; return *this; }; - constexpr uintx& operator++() + uintx& operator++() { *this += uintx(1); return *this; }; - constexpr uintx& operator--() + uintx& operator--() { *this -= uintx(1); return *this; }; - constexpr uintx& operator&=(const uintx& other) + uintx& operator&=(const uintx& other) { *this = *this & other; return *this; }; - constexpr uintx& operator^=(const uintx& other) + uintx& operator^=(const uintx& other) { *this = *this ^ other; return *this; }; - constexpr uintx& operator|=(const uintx& other) + uintx& operator|=(const uintx& other) { *this = *this | other; return *this; }; - constexpr uintx& operator>>=(const uint64_t other) + uintx& operator>>=(const uint64_t other) { *this = *this >> other; return *this; }; - constexpr uintx& operator<<=(const uint64_t other) + uintx& operator<<=(const uint64_t other) { *this = *this << other; return *this; }; - constexpr uintx invmod(const uintx& modulus) const; - constexpr uintx unsafe_invmod(const uintx& modulus) const; + uintx invmod(const uintx& modulus) const; + uintx unsafe_invmod(const uintx& modulus) const; base_uint lo; base_uint hi; - template constexpr std::pair barrett_reduction() const; - constexpr std::pair divmod(const uintx& b) const; - constexpr std::pair divmod_base(const uintx& b) const; + template std::pair barrett_reduction() const; + + // This only works (and is only used) for uint256_t + std::pair divmod(const uintx& b) const; + // This only works (and is only used) for uint256_t + std::pair divmod_base(const uintx& b) const; }; template inline void read(B& it, uintx& value) @@ -192,12 +303,12 @@ template inline std::ostream& operator<<(std::ostream& os, uin return os; } -using uint512_t = uintx; +extern template class uintx; +using uint512_t = uintx; +extern template class uintx; using uint1024_t = uintx; } // namespace bb::numeric -#include "./uintx_impl.hpp" - using bb::numeric::uint1024_t; // NOLINT using bb::numeric::uint512_t; // NOLINT diff --git a/cpp/src/barretenberg/numeric/uintx/uintx.test.cpp b/cpp/src/barretenberg/numeric/uintx/uintx.test.cpp index b6122cbcd3..2b0a66d337 100644 --- a/cpp/src/barretenberg/numeric/uintx/uintx.test.cpp +++ b/cpp/src/barretenberg/numeric/uintx/uintx.test.cpp @@ -1,5 +1,6 @@ #include "./uintx.hpp" #include "../random/engine.hpp" +#include "barretenberg/numeric/uint256/uint256.hpp" #include using namespace bb; @@ -28,12 +29,9 @@ TEST(uintx, BarrettReduction1024) { uint1024_t x = engine.get_random_uint1024(); - static constexpr uint64_t modulus_0 = 0x3C208C16D87CFD47UL; - static constexpr uint64_t modulus_1 = 0x97816a916871ca8dUL; - static constexpr uint64_t modulus_2 = 0xb85045b68181585dUL; - static constexpr uint64_t modulus_3 = 0x30644e72e131a029UL; - constexpr uint256_t modulus_partial(modulus_0, modulus_1, modulus_2, modulus_3); - constexpr uint512_t modulus = uint512_t(modulus_partial) * uint512_t(modulus_partial); + constexpr uint256_t modulus_lo{ "0x04689e957a1242c84a50189c6d96cadca602072d09eac1013b5458a2275d69b1" }; + constexpr uint256_t modulus_hi{ "0x0925c4b8763cbf9c599a6f7c0348d21cb00b85511637560626edfa5c34c6b38d" }; + constexpr uint512_t modulus{ modulus_lo, modulus_hi }; const auto [quotient_result, remainder_result] = x.barrett_reduction(); const auto [quotient_expected, remainder_expected] = x.divmod_base(uint1024_t(modulus)); @@ -294,4 +292,4 @@ TEST(uintx, DISABLEDRInv) uint64_t result = q_inv.data[0]; EXPECT_EQ(result, Bn254FrParams::r_inv); */ -} \ No newline at end of file +} diff --git a/cpp/src/barretenberg/numeric/uintx/uintx_impl.hpp b/cpp/src/barretenberg/numeric/uintx/uintx_impl.hpp index acc5f2b00d..cd29214b12 100644 --- a/cpp/src/barretenberg/numeric/uintx/uintx_impl.hpp +++ b/cpp/src/barretenberg/numeric/uintx/uintx_impl.hpp @@ -10,7 +10,8 @@ namespace bb::numeric { template -constexpr std::pair, uintx> uintx::divmod_base(const uintx& b) const +std::pair, uintx> uintx::divmod_base(const uintx& b) const + { ASSERT(b != 0); if (*this == 0) { @@ -68,7 +69,7 @@ constexpr std::pair, uintx> uintx::divmod * * @return The inverse of *this modulo modulus **/ -template constexpr uintx uintx::unsafe_invmod(const uintx& modulus) const +template uintx uintx::unsafe_invmod(const uintx& modulus) const { uintx t1 = 0; @@ -100,7 +101,7 @@ template constexpr uintx uintx::unsafe_i * @param modulus The modulus * @return The inverse of *this modulo modulus **/ -template constexpr uintx uintx::invmod(const uintx& modulus) const +template uintx uintx::invmod(const uintx& modulus) const { ASSERT((*this) != 0); if (modulus == 0) { @@ -114,20 +115,7 @@ template constexpr uintx uintx::invmod(c return this->unsafe_invmod(modulus); } -/** - * Viewing `this` as a bit string, and counting bits from 0, slices a substring. - * @returns the uintx equal to the substring of bits from (and including) the `start`-th bit, to (but excluding) the - * `end`-th bit of `this`. - */ -template -constexpr uintx uintx::slice(const uint64_t start, const uint64_t end) const -{ - const uint64_t range = end - start; - const uintx mask = range == base_uint::length() ? -uintx(1) : (uintx(1) << range) - 1; - return ((*this) >> start) & mask; -} - -template constexpr bool uintx::get_bit(const uint64_t bit_index) const +template bool uintx::get_bit(const uint64_t bit_index) const { if (bit_index >= base_uint::length()) { return hi.get_bit(bit_index - base_uint::length()); @@ -135,35 +123,12 @@ template constexpr bool uintx::get_bit(const uint64 return lo.get_bit(bit_index); } -template constexpr uint64_t uintx::get_msb() const -{ - uint64_t hi_idx = hi.get_msb(); - uint64_t lo_idx = lo.get_msb(); - return (hi_idx || (hi > base_uint(0))) ? (hi_idx + base_uint::length()) : lo_idx; -} - -template constexpr uintx uintx::operator+(const uintx& other) const -{ - base_uint res_lo = lo + other.lo; - bool carry = res_lo < lo; - base_uint res_hi = hi + other.hi + ((carry) ? base_uint(1) : base_uint(0)); - return { res_lo, res_hi }; -}; - -template constexpr uintx uintx::operator-(const uintx& other) const -{ - base_uint res_lo = lo - other.lo; - bool borrow = res_lo > lo; - base_uint res_hi = hi - other.hi - ((borrow) ? base_uint(1) : base_uint(0)); - return { res_lo, res_hi }; -} - -template constexpr uintx uintx::operator-() const +template uintx uintx::operator-() const { return uintx(0) - *this; } -template constexpr uintx uintx::operator*(const uintx& other) const +template uintx uintx::operator*(const uintx& other) const { const auto lolo = lo.mul_extended(other.lo); const auto lohi = lo.mul_extended(other.hi); @@ -175,7 +140,7 @@ template constexpr uintx uintx::operator } template -constexpr std::pair, uintx> uintx::mul_extended(const uintx& other) const +std::pair, uintx> uintx::mul_extended(const uintx& other) const { const auto lolo = lo.mul_extended(other.lo); const auto lohi = lo.mul_extended(other.hi); @@ -202,53 +167,49 @@ constexpr std::pair, uintx> uintx::mul_ex return { uintx(t0, t1), uintx(t2, t3) }; } -template constexpr uintx uintx::operator/(const uintx& other) const +template uintx uintx::operator/(const uintx& other) const + { return divmod(other).first; } -template constexpr uintx uintx::operator%(const uintx& other) const +template uintx uintx::operator%(const uintx& other) const + { return divmod(other).second; } -// 0x2af0296feca4188a80fd373ebe3c64da87a232934abb3a99f9c4cd59e6758a65 -// 0x1182c6cdb54193b51ca27c1932b95c82bebac691e3996e5ec5e1d4395f3023e3 -template constexpr uintx uintx::operator&(const uintx& other) const -{ - return { lo & other.lo, hi & other.hi }; -} -template constexpr uintx uintx::operator^(const uintx& other) const +template uintx uintx::operator^(const uintx& other) const { return { lo ^ other.lo, hi ^ other.hi }; } -template constexpr uintx uintx::operator|(const uintx& other) const +template uintx uintx::operator|(const uintx& other) const { return { lo | other.lo, hi | other.hi }; } -template constexpr uintx uintx::operator~() const +template uintx uintx::operator~() const { return { ~lo, ~hi }; } -template constexpr bool uintx::operator==(const uintx& other) const +template bool uintx::operator==(const uintx& other) const { return ((lo == other.lo) && (hi == other.hi)); } -template constexpr bool uintx::operator!=(const uintx& other) const +template bool uintx::operator!=(const uintx& other) const { return !(*this == other); } -template constexpr bool uintx::operator!() const +template bool uintx::operator!() const { return *this == uintx(0ULL); } -template constexpr bool uintx::operator>(const uintx& other) const +template bool uintx::operator>(const uintx& other) const { bool hi_gt = hi > other.hi; bool lo_gt = lo > other.lo; @@ -257,94 +218,23 @@ template constexpr bool uintx::operator>(const uint return gt; } -template constexpr bool uintx::operator>=(const uintx& other) const +template bool uintx::operator>=(const uintx& other) const { return (*this > other) || (*this == other); } -template constexpr bool uintx::operator<(const uintx& other) const +template bool uintx::operator<(const uintx& other) const { return other > *this; } -template constexpr bool uintx::operator<=(const uintx& other) const +template bool uintx::operator<=(const uintx& other) const { return (*this < other) || (*this == other); } -template constexpr uintx uintx::operator>>(const uint64_t other) const -{ - const uint64_t total_shift = other; - if (total_shift >= length()) { - return uintx(0); - } - if (total_shift == 0) { - return *this; - } - const uint64_t num_shifted_limbs = total_shift >> (base_uint(base_uint::length()).get_msb()); - - const uint64_t limb_shift = total_shift & static_cast(base_uint::length() - 1); - - std::array shifted_limbs = { 0, 0 }; - if (limb_shift == 0) { - shifted_limbs[0] = lo; - shifted_limbs[1] = hi; - } else { - const uint64_t remainder_shift = static_cast(base_uint::length()) - limb_shift; - - shifted_limbs[1] = hi >> limb_shift; - - base_uint remainder = (hi) << remainder_shift; - - shifted_limbs[0] = (lo >> limb_shift) + remainder; - } - uintx result(0); - if (num_shifted_limbs == 0) { - result.hi = shifted_limbs[1]; - result.lo = shifted_limbs[0]; - } else { - result.lo = shifted_limbs[1]; - } - return result; -} - -template constexpr uintx uintx::operator<<(const uint64_t other) const -{ - const uint64_t total_shift = other; - if (total_shift >= length()) { - return uintx(0); - } - if (total_shift == 0) { - return *this; - } - const uint64_t num_shifted_limbs = total_shift >> (base_uint(base_uint::length()).get_msb()); - const uint64_t limb_shift = total_shift & static_cast(base_uint::length() - 1); - - std::array shifted_limbs = { 0, 0 }; - if (limb_shift == 0) { - shifted_limbs[0] = lo; - shifted_limbs[1] = hi; - } else { - const uint64_t remainder_shift = static_cast(base_uint::length()) - limb_shift; - - shifted_limbs[0] = lo << limb_shift; - - base_uint remainder = lo >> remainder_shift; +template std::pair, uintx> uintx::divmod(const uintx& b) const - shifted_limbs[1] = (hi << limb_shift) + remainder; - } - uintx result(0); - if (num_shifted_limbs == 0) { - result.hi = shifted_limbs[1]; - result.lo = shifted_limbs[0]; - } else { - result.hi = shifted_limbs[0]; - } - return result; -} - -template -constexpr std::pair, uintx> uintx::divmod(const uintx& b) const { constexpr uint256_t BN254FQMODULUS256 = uint256_t(0x3C208C16D87CFD47UL, 0x97816a916871ca8dUL, 0xb85045b68181585dUL, 0x30644e72e131a029UL); @@ -375,18 +265,18 @@ constexpr std::pair, uintx> uintx::divmod * * @tparam base_uint * @tparam modulus - * @return constexpr std::pair, uintx> + * @return std::pair, uintx> */ template template -constexpr std::pair, uintx> uintx::barrett_reduction() const +std::pair, uintx> uintx::barrett_reduction() const { // N.B. k could be modulus.get_msb() + 1 if we have strong bounds on the max value of (*self) // (a smaller k would allow us to fit `redc_parameter` into `base_uint` and not `uintx`) constexpr size_t k = base_uint::length() - 1; // N.B. computation of redc_parameter requires division operation - if this cannot be precomputed (or amortized over // multiple reductions over the same modulus), barrett_reduction is much slower than divmod - constexpr uintx redc_parameter = ((uintx(1) << (k * 2)).divmod_base(uintx(modulus))).first; + static const uintx redc_parameter = ((uintx(1) << (k * 2)).divmod_base(uintx(modulus))).first; const auto x = *this; @@ -425,4 +315,4 @@ constexpr std::pair, uintx> uintx::barret } return std::make_pair(quotient, remainder); } -} // namespace bb::numeric \ No newline at end of file +} // namespace bb::numeric diff --git a/cpp/src/barretenberg/op_queue/ecc_ops_table.hpp b/cpp/src/barretenberg/op_queue/ecc_ops_table.hpp index b2eaf13b98..0b08a27b5e 100644 --- a/cpp/src/barretenberg/op_queue/ecc_ops_table.hpp +++ b/cpp/src/barretenberg/op_queue/ecc_ops_table.hpp @@ -74,7 +74,7 @@ template struct VMOperation { typename CycleGroup::affine_element base_point = typename CycleGroup::affine_element{ 0, 0 }; uint256_t z1 = 0; uint256_t z2 = 0; - typename CycleGroup::subgroup_field mul_scalar_full = 0; + typename CycleGroup::Fr mul_scalar_full = 0; bool operator==(const VMOperation& other) const = default; }; using ECCVMOperation = VMOperation; diff --git a/cpp/src/barretenberg/relations/ecc_vm/ecc_msm_relation_impl.hpp b/cpp/src/barretenberg/relations/ecc_vm/ecc_msm_relation_impl.hpp index b837eda277..fc66f0b795 100644 --- a/cpp/src/barretenberg/relations/ecc_vm/ecc_msm_relation_impl.hpp +++ b/cpp/src/barretenberg/relations/ecc_vm/ecc_msm_relation_impl.hpp @@ -6,6 +6,7 @@ #pragma once #include "barretenberg/ecc/curves/bn254/g1.hpp" +#include "barretenberg/ecc/groups/precomputed_generators_bn254_impl.hpp" #include "ecc_msm_relation.hpp" namespace bb { @@ -217,7 +218,7 @@ void ECCVMMSMRelationImpl::accumulate(ContainerOverSubrelations& accumulator auto& relation, auto& collision_relation) { // N.B. this is brittle - should be curve agnostic but we don't propagate the curve parameter into relations! - constexpr auto offset_generator = bb::g1::derive_generators("ECCVM_OFFSET_GENERATOR", 1)[0]; + constexpr auto offset_generator = get_precomputed_generators()[0]; constexpr uint256_t oxu = offset_generator.x; constexpr uint256_t oyu = offset_generator.y; const Accumulator xo(oxu); diff --git a/cpp/src/barretenberg/relations/ecc_vm/ecc_transcript_relation_impl.hpp b/cpp/src/barretenberg/relations/ecc_vm/ecc_transcript_relation_impl.hpp index 1aa98584dc..2c15ca6f0b 100644 --- a/cpp/src/barretenberg/relations/ecc_vm/ecc_transcript_relation_impl.hpp +++ b/cpp/src/barretenberg/relations/ecc_vm/ecc_transcript_relation_impl.hpp @@ -46,7 +46,7 @@ void ECCVMTranscriptRelationImpl::accumulate(ContainerOverSubrelations& accu using View = typename Accumulator::View; static const auto offset_generator = [&]() { - static constexpr auto offset_generator_base = bb::g1::derive_generators("ECCVM_OFFSET_GENERATOR", 1)[0]; + static constexpr auto offset_generator_base = get_precomputed_generators()[0]; static bb::g1::affine_element result = bb::g1::affine_element(bb::g1::element(offset_generator_base) * grumpkin::fq(uint256_t(1) << 124)); static const FF qx = result.x; diff --git a/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation_impl.hpp b/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation_impl.hpp index 2fd6768e76..6e5ed427ee 100644 --- a/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation_impl.hpp +++ b/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation_impl.hpp @@ -88,7 +88,7 @@ void TranslatorNonNativeFieldRelationImpl::accumulate(ContainerOverSubrelati 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 = { + static const 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), diff --git a/cpp/src/barretenberg/relations/translator_vm/translator_relation_consistency.test.cpp b/cpp/src/barretenberg/relations/translator_vm/translator_relation_consistency.test.cpp index 08ae90eacc..d834910252 100644 --- a/cpp/src/barretenberg/relations/translator_vm/translator_relation_consistency.test.cpp +++ b/cpp/src/barretenberg/relations/translator_vm/translator_relation_consistency.test.cpp @@ -1031,14 +1031,14 @@ TEST_F(TranslatorRelationConsistency, ZeroConstraintsRelation) TEST_F(TranslatorRelationConsistency, NonNativeFieldRelation) { const auto run_test = [](bool random_inputs) { - constexpr size_t NUM_LIMB_BITS = 68; - constexpr FF shift = FF(uint256_t(1) << NUM_LIMB_BITS); - constexpr FF shiftx2 = FF(uint256_t(1) << (NUM_LIMB_BITS * 2)); - constexpr FF shiftx3 = FF(uint256_t(1) << (NUM_LIMB_BITS * 3)); - constexpr uint512_t MODULUS_U512 = uint512_t(curve::BN254::BaseField::modulus); - constexpr uint512_t BINARY_BASIS_MODULUS = uint512_t(1) << (NUM_LIMB_BITS << 2); - constexpr uint512_t NEGATIVE_PRIME_MODULUS = BINARY_BASIS_MODULUS - MODULUS_U512; - constexpr std::array NEGATIVE_MODULUS_LIMBS = { + const size_t NUM_LIMB_BITS = 68; + const FF shift = FF(uint256_t(1) << NUM_LIMB_BITS); + const FF shiftx2 = FF(uint256_t(1) << (NUM_LIMB_BITS * 2)); + const FF shiftx3 = FF(uint256_t(1) << (NUM_LIMB_BITS * 3)); + const uint512_t MODULUS_U512 = uint512_t(curve::BN254::BaseField::modulus); + const uint512_t BINARY_BASIS_MODULUS = uint512_t(1) << (NUM_LIMB_BITS << 2); + const uint512_t NEGATIVE_PRIME_MODULUS = BINARY_BASIS_MODULUS - MODULUS_U512; + const 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), @@ -1180,4 +1180,4 @@ TEST_F(TranslatorRelationConsistency, NonNativeFieldRelation) }; run_test(/*random_inputs=*/false); run_test(/*random_inputs=*/true); -}; \ No newline at end of file +}; diff --git a/cpp/src/barretenberg/stdlib/encryption/ecdsa/ecdsa_impl.hpp b/cpp/src/barretenberg/stdlib/encryption/ecdsa/ecdsa_impl.hpp index f9c5e24321..f42989066f 100644 --- a/cpp/src/barretenberg/stdlib/encryption/ecdsa/ecdsa_impl.hpp +++ b/cpp/src/barretenberg/stdlib/encryption/ecdsa/ecdsa_impl.hpp @@ -6,6 +6,7 @@ #pragma once +#include "barretenberg/ecc/groups/precomputed_generators_secp256r1_impl.hpp" #include "barretenberg/stdlib/encryption/ecdsa/ecdsa.hpp" #include "barretenberg/stdlib/hash/sha256/sha256.hpp" #include "barretenberg/stdlib/primitives//bit_array/bit_array.hpp" @@ -283,4 +284,4 @@ template void generate_ecdsa_verification_test_circuit(Builde } } -} // namespace bb::stdlib \ No newline at end of file +} // namespace bb::stdlib diff --git a/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.cpp b/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.cpp index d0ed8993e2..2bbbde00de 100644 --- a/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.cpp +++ b/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.cpp @@ -138,10 +138,6 @@ UltraRecursiveVerifier_::Output UltraRecursiveVerifier_::verify_ sumcheck_output.claimed_libra_evaluation); auto pairing_points = PCS::reduce_verify_batch_opening_claim(opening_claim, transcript); - - // TODO(https://github.com/AztecProtocol/barretenberg/issues/1352): Investigate if normalize() calls are needed. - pairing_points[0] = pairing_points[0].normalize(); - pairing_points[1] = pairing_points[1].normalize(); output.points_accumulator.aggregate(pairing_points); // Extract the IPA claim from the public inputs diff --git a/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp b/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp index cabb4b9647..a20d14763f 100644 --- a/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp +++ b/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp @@ -249,7 +249,7 @@ template class RecursiveVerifierTest : public testing } // Check the size of the recursive verifier if constexpr (std::same_as>) { - uint32_t NUM_GATES_EXPECTED = 871733; + uint32_t NUM_GATES_EXPECTED = 871531; BB_ASSERT_EQ(static_cast(outer_circuit.get_num_finalized_gates()), NUM_GATES_EXPECTED, "MegaZKHonk Recursive verifier changed in Ultra gate count! Update this value if you " diff --git a/cpp/src/barretenberg/stdlib/pairing_points.hpp b/cpp/src/barretenberg/stdlib/pairing_points.hpp index df2cdc9a1b..f494eae653 100644 --- a/cpp/src/barretenberg/stdlib/pairing_points.hpp +++ b/cpp/src/barretenberg/stdlib/pairing_points.hpp @@ -119,13 +119,36 @@ template struct PairingPoints { Group P1 = Group::reconstruct_from_public(P1_limbs); return { P0, P1 }; } + + static std::array construct_dummy() + { + // We just biggroup here instead of Group (which is either biggroup or biggroup_goblin) because this is the most + // efficient way of setting the default pairing points. If we use biggroup_goblin elements, we have to convert + // them back to biggroup elements anyway to add them to the public inputs... + using BigGroup = element_default:: + element, field_t, curve::BN254::Group>; + std::array dummy_pairing_points_values; + size_t idx = 0; + for (size_t i = 0; i < 2; i++) { + std::array element_vals = BigGroup::construct_dummy(); + for (auto& val : element_vals) { + dummy_pairing_points_values[idx++] = val; + } + } + + return dummy_pairing_points_values; + } + /** - * @brief Constructs an arbitrary but valid aggregation state from a valid set of pairing inputs. + * @brief Adds default public inputs to the builder. + * @details This should cost exactly 20 gates because there's 4 bigfield elements and each have 5 total + * witnesses including the prime limb. * * @param builder - * @return PairingPoints */ - static PairingPoints construct_default(typename Curve::Builder& builder) + // TODO(https://github.com/AztecProtocol/barretenberg/issues/984): Check how many gates this costs and if they're + // necessary. + static void add_default_to_public_inputs(Builder& builder) { using BaseField = typename Curve::BaseField; // TODO(https://github.com/AztecProtocol/barretenberg/issues/911): These are pairing points extracted from a @@ -138,15 +161,7 @@ template struct PairingPoints { BaseField y0 = BaseField::from_witness(&builder, y0_val); BaseField x1 = BaseField::from_witness(&builder, x1_val); BaseField y1 = BaseField::from_witness(&builder, y1_val); - // PairingPoints points_accumulator{ Group(x0, y0), Group(x1, y1) }; - return { Group(x0, y0), Group(x1, y1) }; - } - - // TODO(https://github.com/AztecProtocol/barretenberg/issues/984): Check how many gates this costs and if they're - // necessary. - static void add_default_to_public_inputs(Builder& builder) - { - PairingPoints points_accumulator = construct_default(builder); + PairingPoints points_accumulator{ Group(x0, y0), Group(x1, y1) }; points_accumulator.set_public(); } }; diff --git a/cpp/src/barretenberg/stdlib/pairing_points.test.cpp b/cpp/src/barretenberg/stdlib/pairing_points.test.cpp new file mode 100644 index 0000000000..227b6fbb90 --- /dev/null +++ b/cpp/src/barretenberg/stdlib/pairing_points.test.cpp @@ -0,0 +1,25 @@ +#include "barretenberg/stdlib/pairing_points.hpp" +#include "barretenberg/srs/global_crs.hpp" +#include + +namespace bb::stdlib::recursion { + +template class PairingPointsTests : public testing::Test { + public: + static void SetUpTestSuite() { bb::srs::init_file_crs_factory(bb::srs::bb_crs_path()); } +}; + +using Builders = testing::Types; +TYPED_TEST_SUITE(PairingPointsTests, Builders); + +TYPED_TEST(PairingPointsTests, ConstructDefault) +{ + TypeParam builder; + info("Num gates: ", builder.num_gates); + PairingPoints::add_default_to_public_inputs(builder); + info("Num gates after add_default_to_public_inputs: ", builder.num_gates); + builder.finalize_circuit(/*ensure_nonzero=*/true); + info("Num gates: ", builder.num_gates); + EXPECT_TRUE(CircuitChecker::check(builder)); +} +} // namespace bb::stdlib::recursion diff --git a/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp b/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp index 8388519c7b..d83bd56ae5 100644 --- a/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp +++ b/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp @@ -62,7 +62,7 @@ template class bigfield { static constexpr size_t NUM_LIMBS = 4; Builder* context; - mutable Limb binary_basis_limbs[NUM_LIMBS]; + mutable std::array binary_basis_limbs; mutable field_t prime_basis_limb; bigfield(const field_t& low_bits, @@ -159,7 +159,7 @@ template class bigfield { .add_two(result.binary_basis_limbs[2].element * shift_2, result.binary_basis_limbs[1].element * shift_1); result.prime_basis_limb += (result.binary_basis_limbs[0].element); - const size_t num_last_limb_bits = (can_overflow) ? NUM_LIMB_BITS : NUM_LAST_LIMB_BITS; + const size_t num_last_limb_bits = (can_overflow) ? NUM_LIMB_BITS : static_cast(NUM_LAST_LIMB_BITS); if constexpr (HasPlookup) { ctx->range_constrain_two_limbs(result.binary_basis_limbs[0].element.get_normalized_witness_index(), result.binary_basis_limbs[1].element.get_normalized_witness_index(), @@ -232,7 +232,7 @@ template class bigfield { // The quotient reduction checks currently only support >=250 bit moduli and moduli >256 have never been tested // (Check zkSecurity audit report issue #12 for explanation) static_assert(modulus_u512.get_msb() + 1 >= 250 && modulus_u512.get_msb() + 1 <= 256); - static constexpr uint1024_t DEFAULT_MAXIMUM_REMAINDER = + inline static const uint1024_t DEFAULT_MAXIMUM_REMAINDER = (uint1024_t(1) << (NUM_LIMB_BITS * 3 + NUM_LAST_LIMB_BITS)) - uint1024_t(1); static constexpr uint256_t DEFAULT_MAXIMUM_LIMB = (uint256_t(1) << NUM_LIMB_BITS) - uint256_t(1); static constexpr uint256_t DEFAULT_MAXIMUM_MOST_SIGNIFICANT_LIMB = @@ -248,7 +248,7 @@ template class bigfield { uint256_t(modulus_u512.slice(NUM_LIMB_BITS * (NUM_LIMBS - 1), NUM_LIMB_BITS* NUM_LIMBS)); static constexpr Basis prime_basis{ uint512_t(bb::fr::modulus), bb::fr::modulus.get_msb() + 1 }; static constexpr Basis binary_basis{ uint512_t(1) << LOG2_BINARY_MODULUS, LOG2_BINARY_MODULUS }; - static constexpr Basis target_basis{ modulus_u512, modulus_u512.get_msb() + 1 }; + static constexpr Basis target_basis{ modulus_u512, static_cast(modulus_u512.get_msb() + 1) }; static constexpr bb::fr shift_1 = bb::fr(uint256_t(1) << NUM_LIMB_BITS); static constexpr bb::fr shift_2 = bb::fr(uint256_t(1) << (NUM_LIMB_BITS * 2)); static constexpr bb::fr shift_3 = bb::fr(uint256_t(1) << (NUM_LIMB_BITS * 3)); @@ -594,7 +594,7 @@ template class bigfield { for (const auto& add : to_add) { add_term += add.get_maximum_value(); } - constexpr uint1024_t maximum_default_bigint = uint1024_t(1) << (NUM_LIMB_BITS * 6 + NUM_LAST_LIMB_BITS * 2); + static const uint1024_t maximum_default_bigint = uint1024_t(1) << (NUM_LIMB_BITS * 6 + NUM_LAST_LIMB_BITS * 2); // check that the add terms alone cannot overflow the crt modulus. v. unlikely so just forbid circuits that // trigger this case @@ -704,5 +704,3 @@ template inline std::ostream& operator<<(std::ostream& } } // namespace bb::stdlib - -#include "bigfield_impl.hpp" diff --git a/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_bn254.cpp b/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_bn254.cpp new file mode 100644 index 0000000000..07a51adcd3 --- /dev/null +++ b/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_bn254.cpp @@ -0,0 +1,13 @@ +#include "barretenberg/ecc/curves/bn254/fq.hpp" +#include "barretenberg/ecc/curves/secp256k1/secp256k1.hpp" +#include "barretenberg/ecc/curves/secp256r1/secp256r1.hpp" +#include "barretenberg/stdlib/primitives/circuit_builders/circuit_builders_fwd.hpp" +#include "bigfield_impl.hpp" + +namespace bb::stdlib { +// 2 builders x (Fr, Fq) +template class bigfield; +template class bigfield; +template class bigfield; +template class bigfield; +} // namespace bb::stdlib diff --git a/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_impl.hpp b/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_impl.hpp index d66de74856..55bdb326e7 100644 --- a/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_impl.hpp +++ b/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_impl.hpp @@ -13,6 +13,7 @@ #include #include "../circuit_builders/circuit_builders.hpp" +#include "bigfield.hpp" #include "../bit_array/bit_array.hpp" #include "../field/field.hpp" diff --git a/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_secp256k1.cpp b/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_secp256k1.cpp new file mode 100644 index 0000000000..e40f59f402 --- /dev/null +++ b/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_secp256k1.cpp @@ -0,0 +1,13 @@ +#include "barretenberg/ecc/curves/bn254/fq.hpp" +#include "barretenberg/ecc/curves/secp256k1/secp256k1.hpp" +#include "barretenberg/ecc/curves/secp256r1/secp256r1.hpp" +#include "barretenberg/stdlib/primitives/circuit_builders/circuit_builders_fwd.hpp" +#include "bigfield_impl.hpp" + +namespace bb::stdlib { +// 2 builders x (Fr, Fq) +template class bigfield; +template class bigfield; +template class bigfield; +template class bigfield; +} // namespace bb::stdlib diff --git a/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_secp256r1.cpp b/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_secp256r1.cpp new file mode 100644 index 0000000000..80310bcd79 --- /dev/null +++ b/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_secp256r1.cpp @@ -0,0 +1,13 @@ +#include "barretenberg/ecc/curves/bn254/fq.hpp" +#include "barretenberg/ecc/curves/secp256k1/secp256k1.hpp" +#include "barretenberg/ecc/curves/secp256r1/secp256r1.hpp" +#include "barretenberg/stdlib/primitives/circuit_builders/circuit_builders_fwd.hpp" +#include "bigfield_impl.hpp" + +namespace bb::stdlib { +// 2 builders x (Fr, Fq) +template class bigfield; +template class bigfield; +template class bigfield; +template class bigfield; +} // namespace bb::stdlib diff --git a/cpp/src/barretenberg/stdlib/primitives/bigfield/goblin_field.hpp b/cpp/src/barretenberg/stdlib/primitives/bigfield/goblin_field.hpp index 40ce53209d..86eaeb9c78 100644 --- a/cpp/src/barretenberg/stdlib/primitives/bigfield/goblin_field.hpp +++ b/cpp/src/barretenberg/stdlib/primitives/bigfield/goblin_field.hpp @@ -27,11 +27,12 @@ namespace bb::stdlib { */ template class goblin_field { public: - static constexpr uint1024_t DEFAULT_MAXIMUM_REMAINDER = + inline static const uint1024_t DEFAULT_MAXIMUM_REMAINDER = bigfield::DEFAULT_MAXIMUM_REMAINDER; static constexpr size_t NUM_LIMBS = bigfield::NUM_LIMBS; static constexpr size_t NUM_LIMB_BITS = bigfield::NUM_LIMB_BITS; - static constexpr size_t NUM_LAST_LIMB_BITS = bigfield::NUM_LAST_LIMB_BITS; + static constexpr size_t NUM_LAST_LIMB_BITS = + static_cast(bigfield::NUM_LAST_LIMB_BITS); using field_ct = stdlib::field_t; using bool_ct = stdlib::bool_t; diff --git a/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.hpp b/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.hpp index 6fbae5e28d..92a3cbb359 100644 --- a/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.hpp +++ b/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.hpp @@ -48,6 +48,21 @@ template class element { element(const element& other); element(element&& other) noexcept; + static std::array construct_dummy() + { + const typename NativeGroup::affine_element& native_val = NativeGroup::affine_element::one(); + element val(native_val); + size_t idx = 0; + std::array limb_vals; + for (auto& limb : val.x.binary_basis_limbs) { + limb_vals[idx++] = limb.element.get_value(); + } + for (auto& limb : val.y.binary_basis_limbs) { + limb_vals[idx++] = limb.element.get_value(); + } + BB_ASSERT_EQ(idx, PUBLIC_INPUTS_SIZE); + return limb_vals; + } /** * @brief Set the witness indices for the x and y coordinates to public * diff --git a/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_batch_mul.hpp b/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_batch_mul.hpp index 9a227425d2..1fc35b1489 100644 --- a/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_batch_mul.hpp +++ b/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_batch_mul.hpp @@ -68,4 +68,4 @@ element element::wnaf_batch_mul(const std::vector element::bn254_endo_batch_mul(const std::vec // Return our scalar mul output return accumulator; } -} // namespace bb::stdlib::element_default \ No newline at end of file +} // namespace bb::stdlib::element_default diff --git a/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_edgecase_handling.hpp b/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_edgecase_handling.hpp index cab11ce045..877f591e35 100644 --- a/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_edgecase_handling.hpp +++ b/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_edgecase_handling.hpp @@ -5,6 +5,8 @@ // ===================== #pragma once +#include "barretenberg/ecc/groups/precomputed_generators_bn254_impl.hpp" +#include "barretenberg/ecc/groups/precomputed_generators_secp256r1_impl.hpp" #include "barretenberg/stdlib/primitives/biggroup/biggroup.hpp" namespace bb::stdlib::element_default { @@ -22,7 +24,7 @@ template typename G::affine_element element::compute_table_offset_generator() { constexpr typename G::affine_element offset_generator = - G::derive_generators("biggroup table offset generator", 1)[0]; + get_precomputed_generators()[0]; return offset_generator; } diff --git a/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_goblin_impl.hpp b/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_goblin_impl.hpp index 0b97fe6c5b..2a0ae041a2 100644 --- a/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_goblin_impl.hpp +++ b/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_goblin_impl.hpp @@ -85,7 +85,7 @@ goblin_element goblin_element::batch_mul(const std:: if (!scalar_is_constant_equal_one) { auto z_1 = Fr::from_witness_index(builder, op_tuple.z_1); auto z_2 = Fr::from_witness_index(builder, op_tuple.z_2); - auto beta = G::subgroup_field::cube_root_of_unity(); + auto beta = G::Fr::cube_root_of_unity(); scalar.assert_equal(z_1 - z_2 * beta); } } diff --git a/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_impl.hpp b/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_impl.hpp index b75aba7f8d..9925540fb9 100644 --- a/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_impl.hpp +++ b/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_impl.hpp @@ -8,6 +8,7 @@ #include "../bit_array/bit_array.hpp" #include "../circuit_builders/circuit_builders.hpp" +#include "barretenberg/ecc/groups/precomputed_generators.hpp" #include "barretenberg/stdlib/primitives/biggroup/biggroup.hpp" #include "barretenberg/transcript/origin_tag.hpp" @@ -740,7 +741,8 @@ template std::pair, element> element::compute_offset_generators( const size_t num_rounds) { - constexpr typename G::affine_element offset_generator = G::derive_generators("biggroup offset generator", 1)[0]; + constexpr typename G::affine_element offset_generator = + get_precomputed_generators()[0]; const uint256_t offset_multiplier = uint256_t(1) << uint256_t(num_rounds - 1); diff --git a/cpp/src/barretenberg/stdlib/primitives/group/cycle_group.test.cpp b/cpp/src/barretenberg/stdlib/primitives/group/cycle_group.test.cpp index 0a4730b8a4..9999e14162 100644 --- a/cpp/src/barretenberg/stdlib/primitives/group/cycle_group.test.cpp +++ b/cpp/src/barretenberg/stdlib/primitives/group/cycle_group.test.cpp @@ -765,7 +765,7 @@ TYPED_TEST(CycleGroupTest, TestBatchMul) for (size_t i = 0; i < num_muls; ++i) { auto element = TestFixture::generators[i]; - typename Group::subgroup_field scalar = Group::subgroup_field::random_element(&engine); + typename Group::Fr scalar = Group::Fr::random_element(&engine); // 1: add entry where point, scalar are witnesses expected += (element * scalar); @@ -803,7 +803,7 @@ TYPED_TEST(CycleGroupTest, TestBatchMul) std::vector scalars; auto element = TestFixture::generators[0]; - typename Group::subgroup_field scalar = Group::subgroup_field::random_element(&engine); + typename Group::Fr scalar = Group::Fr::random_element(&engine); points.emplace_back(cycle_group_ct::from_witness(&builder, element)); scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&builder, scalar)); @@ -824,7 +824,7 @@ TYPED_TEST(CycleGroupTest, TestBatchMul) std::vector scalars; auto element = TestFixture::generators[0]; - typename Group::subgroup_field scalar = 0; + typename Group::Fr scalar = 0; points.emplace_back(cycle_group_ct::from_witness(&builder, element)); scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&builder, scalar)); @@ -840,7 +840,7 @@ TYPED_TEST(CycleGroupTest, TestBatchMul) std::vector scalars; auto element = TestFixture::generators[0]; - typename Group::subgroup_field scalar = Group::subgroup_field::random_element(&engine); + typename Group::Fr scalar = Group::Fr::random_element(&engine); // is_infinity = witness { @@ -868,11 +868,11 @@ TYPED_TEST(CycleGroupTest, TestBatchMul) { std::vector points; std::vector scalars; - std::vector scalars_native; + std::vector scalars_native; Element expected = Group::point_at_infinity; for (size_t i = 0; i < num_muls; ++i) { - auto element = plookup::fixed_base::table::LHS_GENERATOR_POINT; - typename Group::subgroup_field scalar = Group::subgroup_field::random_element(&engine); + auto element = plookup::fixed_base::table::lhs_generator_point(); + typename Group::Fr scalar = Group::Fr::random_element(&engine); // 1: add entry where point is constant, scalar is witness expected += (element * scalar); @@ -881,7 +881,7 @@ TYPED_TEST(CycleGroupTest, TestBatchMul) scalars_native.emplace_back(uint256_t(scalar)); // 2: add entry where point is constant, scalar is constant - element = plookup::fixed_base::table::RHS_GENERATOR_POINT; + element = plookup::fixed_base::table::rhs_generator_point(); expected += (element * scalar); points.emplace_back(element); scalars.emplace_back(typename cycle_group_ct::cycle_scalar(scalar)); @@ -899,11 +899,11 @@ TYPED_TEST(CycleGroupTest, TestBatchMul) { std::vector points; std::vector scalars; - std::vector scalars_native; + std::vector scalars_native; Element expected = Group::point_at_infinity; for (size_t i = 0; i < num_muls; ++i) { - auto element = plookup::fixed_base::table::LHS_GENERATOR_POINT; - typename Group::subgroup_field scalar = Group::subgroup_field::random_element(&engine); + auto element = plookup::fixed_base::table::lhs_generator_point(); + typename Group::Fr scalar = Group::Fr::random_element(&engine); // 1: add entry where point is constant, scalar is witness expected += (element * scalar); @@ -912,15 +912,15 @@ TYPED_TEST(CycleGroupTest, TestBatchMul) scalars_native.emplace_back(scalar); // 2: add entry where point is constant, scalar is constant - element = plookup::fixed_base::table::RHS_GENERATOR_POINT; + element = plookup::fixed_base::table::rhs_generator_point(); expected += (element * scalar); points.emplace_back(element); scalars.emplace_back(typename cycle_group_ct::cycle_scalar(scalar)); scalars_native.emplace_back(scalar); // // 3: add entry where point is constant, scalar is witness - scalar = Group::subgroup_field::random_element(&engine); - element = Group::one * Group::subgroup_field::random_element(&engine); + scalar = Group::Fr::random_element(&engine); + element = Group::one * Group::Fr::random_element(&engine); expected += (element * scalar); points.emplace_back(element); scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&builder, scalar)); @@ -938,8 +938,8 @@ TYPED_TEST(CycleGroupTest, TestBatchMul) std::vector scalars; for (size_t i = 0; i < num_muls; ++i) { - auto element = plookup::fixed_base::table::LHS_GENERATOR_POINT; - typename Group::subgroup_field scalar = 0; + auto element = plookup::fixed_base::table::lhs_generator_point(); + typename Group::Fr scalar = 0; // 1: add entry where point is constant, scalar is witness points.emplace_back((element)); @@ -973,7 +973,7 @@ TYPED_TEST(CycleGroupTest, TestMul) cycle_group_ct result; for (size_t i = 0; i < num_muls; ++i) { auto element = TestFixture::generators[i]; - typename Group::subgroup_field native_scalar = Group::subgroup_field::random_element(&engine); + typename Group::Fr native_scalar = Group::Fr::random_element(&engine); auto expected_result = element * native_scalar; // 1: add entry where point, scalar are witnesses diff --git a/cpp/src/barretenberg/stdlib/primitives/safe_uint/safe_uint.hpp b/cpp/src/barretenberg/stdlib/primitives/safe_uint/safe_uint.hpp index 52d818554f..c40de33877 100644 --- a/cpp/src/barretenberg/stdlib/primitives/safe_uint/safe_uint.hpp +++ b/cpp/src/barretenberg/stdlib/primitives/safe_uint/safe_uint.hpp @@ -21,11 +21,11 @@ namespace bb::stdlib { template class safe_uint_t { private: - typedef field_t field_ct; - typedef bool_t bool_ct; + using field_ct = field_t; + using bool_ct = bool_t; // this constructor is private since we only want the operators to be able to define a positive int without a range // check. - safe_uint_t(field_ct const& value, uint256_t current_max, size_t safety) + safe_uint_t(field_ct const& value, const uint256_t& current_max, size_t safety) : value(value) , current_max(current_max) { @@ -41,8 +41,6 @@ template class safe_uint_t { static constexpr size_t MAX_BIT_NUM = bb::fr::modulus.get_msb(); static constexpr uint256_t MAX_VALUE = bb::fr::modulus - 1; static constexpr size_t IS_UNSAFE = 143; // weird constant to make it hard to use accidentally - // Make sure our uint256 values don't wrap - add_two function sums three of these - static_assert((uint512_t)MAX_VALUE * 3 < (uint512_t)1 << 256); field_ct value; uint256_t current_max; diff --git a/cpp/src/barretenberg/stdlib_circuit_builders/circuit_builder_base.hpp b/cpp/src/barretenberg/stdlib_circuit_builders/circuit_builder_base.hpp index 30d2ec0ff5..be494f5ba3 100644 --- a/cpp/src/barretenberg/stdlib_circuit_builders/circuit_builder_base.hpp +++ b/cpp/src/barretenberg/stdlib_circuit_builders/circuit_builder_base.hpp @@ -22,7 +22,7 @@ static constexpr uint32_t DUMMY_TAG = 0; template class CircuitBuilderBase { public: using FF = FF_; - using EmbeddedCurve = std::conditional_t, curve::BN254, curve::Grumpkin>; + using EmbeddedCurve = std::conditional_t, curve::BN254, curve::Grumpkin>; size_t num_gates = 0; // true if we have dummy witnesses (in the write_vk case) diff --git a/cpp/src/barretenberg/stdlib_circuit_builders/databus.hpp b/cpp/src/barretenberg/stdlib_circuit_builders/databus.hpp index 9881bea6ff..288cce0e3e 100644 --- a/cpp/src/barretenberg/stdlib_circuit_builders/databus.hpp +++ b/cpp/src/barretenberg/stdlib_circuit_builders/databus.hpp @@ -13,8 +13,9 @@ namespace bb { // We assume all kernels have space for two return data commitments on their public inputs +constexpr uint32_t NUM_DATABUS_COMMITMENTS = 2; constexpr uint32_t PROPAGATED_DATABUS_COMMITMENT_SIZE = 8; -constexpr uint32_t PROPAGATED_DATABUS_COMMITMENTS_SIZE = PROPAGATED_DATABUS_COMMITMENT_SIZE * 2; // Two databus comms +constexpr uint32_t PROPAGATED_DATABUS_COMMITMENTS_SIZE = PROPAGATED_DATABUS_COMMITMENT_SIZE * NUM_DATABUS_COMMITMENTS; /** * @brief A DataBus column diff --git a/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/fixed_base/fixed_base.cpp b/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/fixed_base/fixed_base.cpp index 1e34c131e1..7b4fca41f3 100644 --- a/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/fixed_base/fixed_base.cpp +++ b/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/fixed_base/fixed_base.cpp @@ -110,7 +110,7 @@ grumpkin::g1::affine_element table::generate_generator_offset(const grumpkin::g1 */ bool table::lookup_table_exists_for_point(const affine_element& input) { - return (input == LHS_GENERATOR_POINT || input == RHS_GENERATOR_POINT); + return (input == lhs_generator_point() || input == rhs_generator_point()); } /** @@ -123,10 +123,10 @@ bool table::lookup_table_exists_for_point(const affine_element& input) std::optional> table::get_lookup_table_ids_for_point( const grumpkin::g1::affine_element& input) { - if (input == LHS_GENERATOR_POINT) { + if (input == lhs_generator_point()) { return { { FIXED_BASE_LEFT_LO, FIXED_BASE_LEFT_HI } }; } - if (input == RHS_GENERATOR_POINT) { + if (input == rhs_generator_point()) { return { { FIXED_BASE_RIGHT_LO, FIXED_BASE_RIGHT_HI } }; } return {}; @@ -284,10 +284,10 @@ template MultiTable table::get_fixed_base_table<3, table::BITS_PER_HI_SCALAR>(Mu const table::all_multi_tables& table::fixed_base_tables() { static const table::all_multi_tables tables = { - table::generate_tables(lhs_base_point_lo), - table::generate_tables(lhs_base_point_hi), - table::generate_tables(rhs_base_point_lo), - table::generate_tables(rhs_base_point_hi), + table::generate_tables(lhs_base_point_lo()), + table::generate_tables(lhs_base_point_hi()), + table::generate_tables(rhs_base_point_lo()), + table::generate_tables(rhs_base_point_hi()), }; return tables; } @@ -300,10 +300,10 @@ const table::all_multi_tables& table::fixed_base_tables() const std::array& table::fixed_base_table_offset_generators() { static const std::array tables = { - table::generate_generator_offset(lhs_base_point_lo), - table::generate_generator_offset(lhs_base_point_hi), - table::generate_generator_offset(rhs_base_point_lo), - table::generate_generator_offset(rhs_base_point_hi), + table::generate_generator_offset(lhs_base_point_lo()), + table::generate_generator_offset(lhs_base_point_hi()), + table::generate_generator_offset(rhs_base_point_lo()), + table::generate_generator_offset(rhs_base_point_hi()), }; return tables; } diff --git a/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/fixed_base/fixed_base.hpp b/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/fixed_base/fixed_base.hpp index 048783b7cf..003887d74c 100644 --- a/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/fixed_base/fixed_base.hpp +++ b/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/fixed_base/fixed_base.hpp @@ -11,6 +11,7 @@ #include "barretenberg/crypto/generators/generator_data.hpp" #include "barretenberg/crypto/pedersen_hash/pedersen.hpp" #include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp" +#include "barretenberg/ecc/groups/precomputed_generators_grumpkin_impl.hpp" namespace bb::plookup::fixed_base { @@ -26,13 +27,16 @@ class table : public FixedBaseParams { using fixed_base_scalar_mul_tables = std::vector; using all_multi_tables = std::array; - static constexpr affine_element LHS_GENERATOR_POINT = - crypto::generator_data::precomputed_generators[0]; - - static constexpr affine_element RHS_GENERATOR_POINT = - crypto::generator_data::precomputed_generators[1]; + static constexpr affine_element lhs_generator_point() + { + return crypto::generator_data::precomputed_generators[0]; + } + static constexpr affine_element rhs_generator_point() + { + return crypto::generator_data::precomputed_generators[1]; + } - static inline single_lookup_table generate_single_lookup_table(const affine_element& base_point, + inline static single_lookup_table generate_single_lookup_table(const affine_element& base_point, const affine_element& offset_generator); template static fixed_base_scalar_mul_tables generate_tables(const affine_element& input); @@ -44,10 +48,18 @@ class table : public FixedBaseParams { // i.e. we treat 1 scalar mul as two independent scalar muls over (roughly) half-width input scalars. // The base_point members describe the fixed-base points that correspond to the two independent scalar muls, // for our two supported points - inline static const affine_element lhs_base_point_lo = LHS_GENERATOR_POINT; - inline static const affine_element lhs_base_point_hi = element(lhs_base_point_lo) * MAX_LO_SCALAR; - inline static const affine_element rhs_base_point_lo = RHS_GENERATOR_POINT; - inline static const affine_element rhs_base_point_hi = element(rhs_base_point_lo) * MAX_LO_SCALAR; + static affine_element lhs_base_point_lo() { return lhs_generator_point(); }; + static affine_element lhs_base_point_hi() + { + static auto constant = element(lhs_base_point_lo()) * MAX_LO_SCALAR; + return constant; + }; + static affine_element rhs_base_point_lo() { return rhs_generator_point(); }; + static affine_element rhs_base_point_hi() + { + static auto constant = element(rhs_base_point_lo()) * MAX_LO_SCALAR; + return constant; + }; // fixed_base_tables = lookup tables of precomputed base points required for our lookup arguments. // N.B. these "tables" are not plookup tables, just regular ol' software lookup tables. diff --git a/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/non_native_group_generator.hpp b/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/non_native_group_generator.hpp index e17c09e86e..0755971b0c 100644 --- a/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/non_native_group_generator.hpp +++ b/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/non_native_group_generator.hpp @@ -16,7 +16,7 @@ namespace bb::plookup::ecc_generator_tables { template class ecc_generator_table { public: - typedef typename G1::element element; + using element = typename G1::element; /** * Store arrays of precomputed 8-bit lookup tables for generator point coordinates (and their endomorphism *equivalents) diff --git a/cpp/src/barretenberg/translator_vm/translator_circuit_builder.hpp b/cpp/src/barretenberg/translator_vm/translator_circuit_builder.hpp index 441815e29f..cd361479e5 100644 --- a/cpp/src/barretenberg/translator_vm/translator_circuit_builder.hpp +++ b/cpp/src/barretenberg/translator_vm/translator_circuit_builder.hpp @@ -239,7 +239,7 @@ class TranslatorCircuitBuilder : public CircuitBuilderBase { static constexpr auto MAX_HIGH_WIDE_LIMB_SIZE = (uint256_t(1) << (NUM_LIMB_BITS + NUM_LAST_LIMB_BITS)) - 1; // Index at which the evaluation result is stored in the circuit - static constexpr const size_t RESULT_ROW = 2; + static constexpr size_t RESULT_ROW = 2; // How much you'd need to multiply a value by to perform a shift to a higher binary limb static constexpr auto SHIFT_1 = uint256_t(1) << NUM_LIMB_BITS; diff --git a/cpp/src/barretenberg/translator_vm/translator_flavor.hpp b/cpp/src/barretenberg/translator_vm/translator_flavor.hpp index adcd3fc985..4bc1f703a5 100644 --- a/cpp/src/barretenberg/translator_vm/translator_flavor.hpp +++ b/cpp/src/barretenberg/translator_vm/translator_flavor.hpp @@ -87,7 +87,10 @@ class TranslatorFlavor { static constexpr size_t MICRO_LIMB_BITS = CircuitBuilder::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 = CircuitBuilder::NEGATIVE_MODULUS_LIMBS; + static constexpr const std::array& negative_modulus_limbs() + { + return CircuitBuilder::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 diff --git a/cpp/src/barretenberg/ultra_honk/decider_prover.cpp b/cpp/src/barretenberg/ultra_honk/decider_prover.cpp index 7edd30479b..7ab670d1a0 100644 --- a/cpp/src/barretenberg/ultra_honk/decider_prover.cpp +++ b/cpp/src/barretenberg/ultra_honk/decider_prover.cpp @@ -115,7 +115,7 @@ template HonkProof DeciderProver_::construct_ // Fiat-Shamir: rho, y, x, z // Execute Shplemini PCS execute_pcs_rounds(); - + vinfo("finished decider proving."); return export_proof(); } diff --git a/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp b/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp index 0d4ad6986a..7b23931bb7 100644 --- a/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp +++ b/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp @@ -173,8 +173,8 @@ template class DeciderProvingKey_ { // Set the pairing point accumulator indices. This should exist for all flavors. ASSERT(circuit.pairing_inputs_public_input_key.is_set() && - "Honk circuit must output a pairing point accumulator. If this is a test, you might need to add a " - "default one through a method in PairingPoints."); + "Honk circuit must output a pairing point accumulator. If this is a test, you might need to add a \ + default one through a method in PairingPoints."); proving_key.pairing_inputs_public_input_key = circuit.pairing_inputs_public_input_key; if constexpr (HasIPAAccumulator) { // Set the IPA claim indices diff --git a/cpp/src/barretenberg/ultra_honk/decider_verifier.hpp b/cpp/src/barretenberg/ultra_honk/decider_verifier.hpp index 4e6d4a1c1b..2863b0d12c 100644 --- a/cpp/src/barretenberg/ultra_honk/decider_verifier.hpp +++ b/cpp/src/barretenberg/ultra_honk/decider_verifier.hpp @@ -27,7 +27,14 @@ template class DeciderVerifier_ { bool libra_evals_verified; PairingPoints pairing_points; - bool check() { return sumcheck_verified && libra_evals_verified && pairing_points.check(); } + bool check() + { + bool pairing_check_verified = pairing_points.check(); + vinfo("sumcheck_verified: ", sumcheck_verified); + vinfo("libra_evals_verified: ", libra_evals_verified); + vinfo("pairing_check_verified: ", pairing_check_verified); + return sumcheck_verified && libra_evals_verified && pairing_check_verified; + } }; public: diff --git a/cpp/src/barretenberg/ultra_honk/ultra_honk.test.cpp b/cpp/src/barretenberg/ultra_honk/ultra_honk.test.cpp index 86a727f299..e6a4a19a07 100644 --- a/cpp/src/barretenberg/ultra_honk/ultra_honk.test.cpp +++ b/cpp/src/barretenberg/ultra_honk/ultra_honk.test.cpp @@ -216,7 +216,7 @@ TYPED_TEST(UltraHonkTests, CreateGatesFromPlookupAccumulators) { const auto mask = plookup::fixed_base::table::MAX_TABLE_SIZE - 1; - grumpkin::g1::affine_element base_point = plookup::fixed_base::table::LHS_GENERATOR_POINT; + grumpkin::g1::affine_element base_point = plookup::fixed_base::table::lhs_generator_point(); std::vector input_buf; write(input_buf, base_point); const auto offset_generators = diff --git a/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp b/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp index 84e5c1268a..ec67c0ecfc 100644 --- a/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp +++ b/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp @@ -75,6 +75,14 @@ template bool UltraVerifier_::verify_proof(const HonkP DeciderVerifier decider_verifier{ verification_key, transcript }; auto decider_output = decider_verifier.verify(); + if (!decider_output.sumcheck_verified) { + info("Sumcheck failed!"); + return false; + } + if (!decider_output.libra_evals_verified) { + info("Libra evals failed!"); + return false; + } // Extract nested pairing points from the proof // TODO(https://github.com/AztecProtocol/barretenberg/issues/1094): Handle pairing points in keccak flavors. diff --git a/cpp/src/barretenberg/vm2/common/field.hpp b/cpp/src/barretenberg/vm2/common/field.hpp index 5c3674b2d3..51051a029a 100644 --- a/cpp/src/barretenberg/vm2/common/field.hpp +++ b/cpp/src/barretenberg/vm2/common/field.hpp @@ -8,7 +8,7 @@ namespace bb::avm2 { using FF = AvmFlavorSettings::FF; -using Fq = AvmFlavorSettings::G1::coordinate_field; +using Fq = AvmFlavorSettings::G1::Fq; using EmbeddedCurvePoint = StandardAffinePoint; } // namespace bb::avm2 diff --git a/cpp/src/barretenberg/vm2/constraining/flavor_settings.hpp b/cpp/src/barretenberg/vm2/constraining/flavor_settings.hpp index 4bc7ba0dbd..08e602c2b0 100644 --- a/cpp/src/barretenberg/vm2/constraining/flavor_settings.hpp +++ b/cpp/src/barretenberg/vm2/constraining/flavor_settings.hpp @@ -16,7 +16,7 @@ class AvmFlavorSettings { using G1 = Curve::Group; using PCS = KZG; - using FF = G1::subgroup_field; + using FF = G1::Fr; using Polynomial = bb::Polynomial; using PolynomialHandle = std::span; using GroupElement = G1::element; diff --git a/cpp/src/barretenberg/vm2/constraining/recursion/recursive_verifier.cpp b/cpp/src/barretenberg/vm2/constraining/recursion/recursive_verifier.cpp index 39b4b255d2..95f9982b08 100644 --- a/cpp/src/barretenberg/vm2/constraining/recursion/recursive_verifier.cpp +++ b/cpp/src/barretenberg/vm2/constraining/recursion/recursive_verifier.cpp @@ -5,9 +5,11 @@ #include #include "barretenberg/commitment_schemes/shplonk/shplemini.hpp" +#include "barretenberg/honk/proof_system/types/proof.hpp" #include "barretenberg/honk/types/aggregation_object_type.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/shared_shifted_virtual_zeroes_array.hpp" +#include "barretenberg/stdlib/primitives/bool/bool.hpp" #include "barretenberg/stdlib/primitives/field/field.hpp" #include "barretenberg/stdlib/primitives/padding_indicator_array/padding_indicator_array.hpp" #include "barretenberg/transcript/transcript.hpp" @@ -69,9 +71,10 @@ AvmRecursiveVerifier_::PairingPoints AvmRecursiveVerifier_::veri } // TODO(#991): (see https://github.com/AztecProtocol/barretenberg/issues/991) +// TODO(#14234)[Unconditional PIs validation]: rename stdlib_proof_with_pi_flag to stdlib_proof template AvmRecursiveVerifier_::PairingPoints AvmRecursiveVerifier_::verify_proof( - const StdlibProof& stdlib_proof, const std::vector>& public_inputs) + const StdlibProof& stdlib_proof_with_pi_flag, const std::vector>& public_inputs) { using Curve = typename Flavor::Curve; using PCS = typename Flavor::PCS; @@ -81,6 +84,12 @@ AvmRecursiveVerifier_::PairingPoints AvmRecursiveVerifier_::veri using Shplemini = ShpleminiVerifier_; using ClaimBatcher = ClaimBatcher_; using ClaimBatch = ClaimBatcher::Batch; + using stdlib::bool_t; + + // TODO(#14234)[Unconditional PIs validation]: Remove the next 3 lines + StdlibProof stdlib_proof = stdlib_proof_with_pi_flag; + bool_t pi_validation = !bool_t(stdlib_proof.at(0)); + stdlib_proof.erase(stdlib_proof.begin()); if (public_inputs.size() != AVM_NUM_PUBLIC_INPUT_COLUMNS) { throw_or_abort("AvmRecursiveVerifier::verify_proof: public inputs size mismatch"); @@ -140,10 +149,12 @@ AvmRecursiveVerifier_::PairingPoints AvmRecursiveVerifier_::veri output.claimed_evaluations.public_inputs_cols_3_, }; + // TODO(#14234)[Unconditional PIs validation]: Inside of loop, replace pi_validation.must_imply() by + // public_input_evaluation.assert_equal(claimed_evaluations[i] for (size_t i = 0; i < AVM_NUM_PUBLIC_INPUT_COLUMNS; i++) { FF public_input_evaluation = evaluate_public_input_column(public_inputs[i], mle_challenge); vinfo("public_input_evaluation failed, public inputs col ", i); - public_input_evaluation.assert_equal(claimed_evaluations[i], "public_input_evaluation failed"); + pi_validation.must_imply(public_input_evaluation == claimed_evaluations[i], "public_input_evaluation failed"); } // Execute Shplemini rounds. @@ -155,10 +166,6 @@ AvmRecursiveVerifier_::PairingPoints AvmRecursiveVerifier_::veri padding_indicator_array, claim_batcher, output.challenge, Commitment::one(&builder), transcript); auto pairing_points = PCS::reduce_verify_batch_opening_claim(opening_claim, transcript); - - // TODO(https://github.com/AztecProtocol/barretenberg/issues/1352): Investigate if normalize() calls are needed. - pairing_points[0] = pairing_points[0].normalize(); - pairing_points[1] = pairing_points[1].normalize(); return pairing_points; } diff --git a/cpp/src/barretenberg/vm2/constraining/recursion/recursive_verifier.hpp b/cpp/src/barretenberg/vm2/constraining/recursion/recursive_verifier.hpp index d40d9083a9..75e02dfeaa 100644 --- a/cpp/src/barretenberg/vm2/constraining/recursion/recursive_verifier.hpp +++ b/cpp/src/barretenberg/vm2/constraining/recursion/recursive_verifier.hpp @@ -31,7 +31,9 @@ template class AvmRecursiveVerifier_ { [[nodiscard("IPA claim and Pairing points should be accumulated")]] PairingPoints verify_proof( const HonkProof& proof, const std::vector>& public_inputs_vec_nt); [[nodiscard("IPA claim and Pairing points should be accumulated")]] PairingPoints verify_proof( - const StdlibProof& stdlib_proof, const std::vector>& public_inputs); + const StdlibProof& stdlib_proof_with_pi_flag, // TODO(#14234)[Unconditional PIs validation]: rename + // stdlib_proof_with_pi_flag to stdlib_proof + const std::vector>& public_inputs); std::shared_ptr key; Builder& builder; diff --git a/cpp/src/barretenberg/vm2/constraining/recursion/recursive_verifier.test.cpp b/cpp/src/barretenberg/vm2/constraining/recursion/recursive_verifier.test.cpp index f1306d0322..230929fd19 100644 --- a/cpp/src/barretenberg/vm2/constraining/recursion/recursive_verifier.test.cpp +++ b/cpp/src/barretenberg/vm2/constraining/recursion/recursive_verifier.test.cpp @@ -77,6 +77,7 @@ TEST_F(AvmRecursiveTests, StandardRecursion) ASSERT_NO_FATAL_FAILURE({ create_and_verify_native_proof(proof_result); }); auto [proof, verification_key, public_inputs_cols] = proof_result; + proof.insert(proof.begin(), 0); // TODO(#14234)[Unconditional PIs validation]: remove this // Create the outer verifier, to verify the proof OuterBuilder outer_circuit; @@ -162,6 +163,7 @@ TEST_F(AvmRecursiveTests, GoblinRecursion) ASSERT_NO_FATAL_FAILURE({ create_and_verify_native_proof(proof_result); }); auto [proof, verification_key, public_inputs_cols] = proof_result; + proof.insert(proof.begin(), 0); // TODO(#14234)[Unconditional PIs validation]: remove this // Construct stdlib representations of the proof, public inputs and verification key OuterBuilder outer_circuit; diff --git a/cpp/src/barretenberg/world_state/world_state.cpp b/cpp/src/barretenberg/world_state/world_state.cpp index 6892c65f83..3011b71e46 100644 --- a/cpp/src/barretenberg/world_state/world_state.cpp +++ b/cpp/src/barretenberg/world_state/world_state.cpp @@ -743,19 +743,27 @@ WorldStateStatusFull WorldState::unwind_blocks(const index_t& toBlockNumber) populate_status_summary(status); return status; } + WorldStateStatusFull WorldState::remove_historical_blocks(const index_t& toBlockNumber) { WorldStateRevision revision{ .forkId = CANONICAL_FORK_ID, .blockNumber = 0, .includeUncommitted = false }; - TreeMetaResponse archive_state = get_tree_info(revision, MerkleTreeId::ARCHIVE); - if (toBlockNumber <= archive_state.meta.oldestHistoricBlock) { + std::array responses; + get_all_tree_info(revision, responses); + std::array historicalBlockNumbers{ responses[NULLIFIER_TREE].oldestHistoricBlock, + responses[NOTE_HASH_TREE].oldestHistoricBlock, + responses[PUBLIC_DATA_TREE].oldestHistoricBlock, + responses[L1_TO_L2_MESSAGE_TREE].oldestHistoricBlock, + responses[ARCHIVE].oldestHistoricBlock }; + auto* const it = std::min_element(std::begin(historicalBlockNumbers), std::end(historicalBlockNumbers)); + index_t oldestHistoricBlock = *it; + if (toBlockNumber <= oldestHistoricBlock) { throw std::runtime_error(format("Unable to remove historical blocks to block number ", toBlockNumber, ", blocks not found. Current oldest block: ", - archive_state.meta.oldestHistoricBlock)); + oldestHistoricBlock)); } WorldStateStatusFull status; - for (block_number_t blockNumber = archive_state.meta.oldestHistoricBlock; blockNumber < toBlockNumber; - blockNumber++) { + for (block_number_t blockNumber = oldestHistoricBlock; blockNumber < toBlockNumber; blockNumber++) { // This will throw if it fails remove_historical_block(blockNumber, status); }