diff --git a/.test_patterns.yml b/.test_patterns.yml index 9a2cd8cedf8a..649878bc20df 100644 --- a/.test_patterns.yml +++ b/.test_patterns.yml @@ -181,6 +181,10 @@ tests: error_regex: "Exceeded timeout of 120000" owners: - *sean + - regex: "p2p/src/services/reqresp/reqresp.test.ts" + error_regex: "CodeError: writable end state is .writing. not .ready." + owners: + - *sean - regex: "p2p/src/services/reqresp/reqresp.test.ts" error_regex: "✕ should stop after max retry attempts" owners: diff --git a/barretenberg/cpp/CMakePresets.json b/barretenberg/cpp/CMakePresets.json index a5e2e32a646c..bf03c207a7cd 100644 --- a/barretenberg/cpp/CMakePresets.json +++ b/barretenberg/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/barretenberg/cpp/bootstrap.sh b/barretenberg/cpp/bootstrap.sh index bd2b9418e923..c34886bf2edc 100755 --- a/barretenberg/cpp/bootstrap.sh +++ b/barretenberg/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/barretenberg/cpp/cmake/module.cmake b/barretenberg/cpp/cmake/module.cmake index 0f9d1a8a468d..053ea81e0d87 100644 --- a/barretenberg/cpp/cmake/module.cmake +++ b/barretenberg/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/barretenberg/cpp/scripts/ci_benchmark_ivc_flows.sh b/barretenberg/cpp/scripts/ci_benchmark_ivc_flows.sh index 6d9eb7cd68f0..8d80518fc251 100755 --- a/barretenberg/cpp/scripts/ci_benchmark_ivc_flows.sh +++ b/barretenberg/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/barretenberg/cpp/scripts/wasmtime.sh b/barretenberg/cpp/scripts/wasmtime.sh index 430081372c6a..439cb5a43649 100755 --- a/barretenberg/cpp/scripts/wasmtime.sh +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/benchmark/client_ivc_bench/client_ivc.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/client_ivc_bench/client_ivc.bench.cpp index 8992d29b20ee..63e24424ea0e 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/client_ivc_bench/client_ivc.bench.cpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/benchmark/goblin_bench/eccvm.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/goblin_bench/eccvm.bench.cpp index 3895a29ccae2..c22516f00e5d 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/goblin_bench/eccvm.bench.cpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/circuit_checker/translator_circuit_checker.cpp b/barretenberg/cpp/src/barretenberg/circuit_checker/translator_circuit_checker.cpp index 4de39a698079..9c16cb0c33d4 100644 --- a/barretenberg/cpp/src/barretenberg/circuit_checker/translator_circuit_checker.cpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/circuit_checker/ultra_circuit_builder.test.cpp b/barretenberg/cpp/src/barretenberg/circuit_checker/ultra_circuit_builder.test.cpp index ee0eaecd232a..00606c511b52 100644 --- a/barretenberg/cpp/src/barretenberg/circuit_checker/ultra_circuit_builder.test.cpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/crypto/generators/generator_data.hpp b/barretenberg/cpp/src/barretenberg/crypto/generators/generator_data.hpp index c561167fbad5..37d9585512a5 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/generators/generator_data.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/crypto/generators/generator_data.test.cpp b/barretenberg/cpp/src/barretenberg/crypto/generators/generator_data.test.cpp index c3bea7555f30..ae5dbe2fa4ce 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/generators/generator_data.test.cpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/crypto/pedersen_hash/pedersen.hpp b/barretenberg/cpp/src/barretenberg/crypto/pedersen_hash/pedersen.hpp index a171d190a5d2..ca1133900232 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/pedersen_hash/pedersen.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/crypto/schnorr/multisig.hpp b/barretenberg/cpp/src/barretenberg/crypto/schnorr/multisig.hpp index 911e0455796e..5f671650f958 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/schnorr/multisig.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/crypto/schnorr/proof_of_possession.hpp b/barretenberg/cpp/src/barretenberg/crypto/schnorr/proof_of_possession.hpp index 5953a9d88879..92bf21de3112 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/schnorr/proof_of_possession.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/crypto/schnorr/schnorr.tcc b/barretenberg/cpp/src/barretenberg/crypto/schnorr/schnorr.tcc index efd6bc035185..0dc691ea7e3d 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/schnorr/schnorr.tcc +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/fq.test.cpp b/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/fq.test.cpp index 7281257356df..eb7c91434544 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/fq.test.cpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/g1.test.cpp b/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/g1.test.cpp index e2171981250d..dec5d260d9d4 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/g1.test.cpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/ecc/curves/grumpkin/grumpkin.hpp b/barretenberg/cpp/src/barretenberg/ecc/curves/grumpkin/grumpkin.hpp index 6408159c893b..b3103cf15d73 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/curves/grumpkin/grumpkin.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/ecc/curves/grumpkin/grumpkin.test.cpp b/barretenberg/cpp/src/barretenberg/ecc/curves/grumpkin/grumpkin.test.cpp index 5573e08ea389..86993e30a8ee 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/curves/grumpkin/grumpkin.test.cpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/ecc/curves/secp256k1/secp256k1.test.cpp b/barretenberg/cpp/src/barretenberg/ecc/curves/secp256k1/secp256k1.test.cpp index 0132643ced54..32a8ab4cf085 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/curves/secp256k1/secp256k1.test.cpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/ecc/curves/secp256r1/secp256r1.test.cpp b/barretenberg/cpp/src/barretenberg/ecc/curves/secp256r1/secp256r1.test.cpp index 0b2befbb745b..c35bf07742d4 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/curves/secp256r1/secp256r1.test.cpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/ecc/groups/affine_element.hpp b/barretenberg/cpp/src/barretenberg/ecc/groups/affine_element.hpp index aae4e38b2558..d5e8f68824dc 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/groups/affine_element.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/ecc/groups/affine_element_impl.hpp b/barretenberg/cpp/src/barretenberg/ecc/groups/affine_element_impl.hpp index 19e5091d8712..56ba0bda3e5a 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/groups/affine_element_impl.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/ecc/groups/element.hpp b/barretenberg/cpp/src/barretenberg/ecc/groups/element.hpp index b515fb32fe22..5fbd7f463387 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/groups/element.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/ecc/groups/group.hpp b/barretenberg/cpp/src/barretenberg/ecc/groups/group.hpp index fd1d5ba03ed4..7e447066d9ef 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/groups/group.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/ecc/groups/group_impl_asm.tcc b/barretenberg/cpp/src/barretenberg/ecc/groups/group_impl_asm.tcc index 3ea790cbfe67..ad2d8b34d995 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/groups/group_impl_asm.tcc +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/ecc/groups/group_impl_int128.tcc b/barretenberg/cpp/src/barretenberg/ecc/groups/group_impl_int128.tcc index 7f82c830375e..761cbe7d1334 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/groups/group_impl_int128.tcc +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/ecc/groups/precomputed_generators.hpp b/barretenberg/cpp/src/barretenberg/ecc/groups/precomputed_generators.hpp new file mode 100644 index 000000000000..df5fac1308e6 --- /dev/null +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/ecc/groups/precomputed_generators_bn254_impl.hpp b/barretenberg/cpp/src/barretenberg/ecc/groups/precomputed_generators_bn254_impl.hpp new file mode 100644 index 000000000000..9ac10a6ec022 --- /dev/null +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/ecc/groups/precomputed_generators_grumpkin_impl.hpp b/barretenberg/cpp/src/barretenberg/ecc/groups/precomputed_generators_grumpkin_impl.hpp new file mode 100644 index 000000000000..35cb50b68007 --- /dev/null +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/ecc/groups/precomputed_generators_secp256r1_impl.hpp b/barretenberg/cpp/src/barretenberg/ecc/groups/precomputed_generators_secp256r1_impl.hpp new file mode 100644 index 000000000000..bfad462104de --- /dev/null +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/eccvm/eccvm_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_circuit_builder.hpp index fa030630f7c2..96ce9c499969 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_circuit_builder.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/eccvm/msm_builder.hpp b/barretenberg/cpp/src/barretenberg/eccvm/msm_builder.hpp index ab8b99446215..ed10c53e421c 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/msm_builder.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/eccvm/transcript_builder.hpp b/barretenberg/cpp/src/barretenberg/eccvm/transcript_builder.hpp index 166f7faa6ead..518462b00ee5 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/transcript_builder.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/numeric/uintx/uintx.cpp b/barretenberg/cpp/src/barretenberg/numeric/uintx/uintx.cpp new file mode 100644 index 000000000000..dd5e263aad51 --- /dev/null +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/numeric/uintx/uintx.hpp b/barretenberg/cpp/src/barretenberg/numeric/uintx/uintx.hpp index 1bf3661ac755..134463d0f99b 100644 --- a/barretenberg/cpp/src/barretenberg/numeric/uintx/uintx.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/numeric/uintx/uintx.test.cpp b/barretenberg/cpp/src/barretenberg/numeric/uintx/uintx.test.cpp index b6122cbcd34d..2b0a66d337df 100644 --- a/barretenberg/cpp/src/barretenberg/numeric/uintx/uintx.test.cpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/numeric/uintx/uintx_impl.hpp b/barretenberg/cpp/src/barretenberg/numeric/uintx/uintx_impl.hpp index acc5f2b00d69..cd29214b12b8 100644 --- a/barretenberg/cpp/src/barretenberg/numeric/uintx/uintx_impl.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/op_queue/ecc_ops_table.hpp b/barretenberg/cpp/src/barretenberg/op_queue/ecc_ops_table.hpp index b2eaf13b9877..0b08a27b5e3c 100644 --- a/barretenberg/cpp/src/barretenberg/op_queue/ecc_ops_table.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_msm_relation_impl.hpp b/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_msm_relation_impl.hpp index b837eda277db..fc66f0b795aa 100644 --- a/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_msm_relation_impl.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_transcript_relation_impl.hpp b/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_transcript_relation_impl.hpp index 1aa98584dcc6..2c15ca6f0be7 100644 --- a/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_transcript_relation_impl.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation_impl.hpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation_impl.hpp index 2fd6768e76a1..6e5ed427eee4 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_non_native_field_relation_impl.hpp @@ -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/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_relation_consistency.test.cpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_relation_consistency.test.cpp index 08ae90eacc01..d834910252e3 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_relation_consistency.test.cpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/translator_relation_consistency.test.cpp @@ -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/barretenberg/cpp/src/barretenberg/stdlib/encryption/ecdsa/ecdsa_impl.hpp b/barretenberg/cpp/src/barretenberg/stdlib/encryption/ecdsa/ecdsa_impl.hpp index f9c5e2432178..f42989066f09 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/encryption/ecdsa/ecdsa_impl.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp index 8388519c7b68..230097b95afc 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp @@ -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/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_bn254.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_bn254.cpp new file mode 100644 index 000000000000..07a51adcd31f --- /dev/null +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_impl.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_impl.hpp index d66de748567f..55bdb326e750 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_impl.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_secp256k1.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_secp256k1.cpp new file mode 100644 index 000000000000..e40f59f4024e --- /dev/null +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_secp256r1.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_secp256r1.cpp new file mode 100644 index 000000000000..80310bcd7928 --- /dev/null +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/goblin_field.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/goblin_field.hpp index 40ce53209da6..86eaeb9c7856 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/goblin_field.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_batch_mul.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_batch_mul.hpp index 9a227425d280..1fc35b14899c 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_batch_mul.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_edgecase_handling.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_edgecase_handling.hpp index cab11ce0450d..877f591e3516 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_edgecase_handling.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_goblin_impl.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_goblin_impl.hpp index 0b97fe6c5b31..2a0ae041a275 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_goblin_impl.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_impl.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_impl.hpp index b75aba7f8d9b..9925540fb942 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_impl.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/stdlib/primitives/group/cycle_group.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/group/cycle_group.test.cpp index 0a4730b8a490..9999e14162f8 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/group/cycle_group.test.cpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/stdlib/primitives/safe_uint/safe_uint.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/safe_uint/safe_uint.hpp index 52d818554ff4..c40de33877e4 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/safe_uint/safe_uint.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/circuit_builder_base.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/circuit_builder_base.hpp index 30d2ec0ff54c..be494f5ba301 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/circuit_builder_base.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/fixed_base/fixed_base.cpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/fixed_base/fixed_base.cpp index 1e34c131e107..7b4fca41f34f 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/fixed_base/fixed_base.cpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/fixed_base/fixed_base.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/fixed_base/fixed_base.hpp index 048783b7cfd6..003887d74c64 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/fixed_base/fixed_base.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/non_native_group_generator.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/non_native_group_generator.hpp index e17c09e86e3a..0755971b0cd2 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/non_native_group_generator.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/translator_vm/translator_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_circuit_builder.hpp index 441815e29f88..cd361479e5d3 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_circuit_builder.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp index adcd3fc98549..4bc1f703a56f 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_honk.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_honk.test.cpp index 86a727f299ed..e6a4a19a07ed 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_honk.test.cpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/vm2/common/field.hpp b/barretenberg/cpp/src/barretenberg/vm2/common/field.hpp index 5c3674b2d329..51051a029afa 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/common/field.hpp +++ b/barretenberg/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/barretenberg/cpp/src/barretenberg/vm2/constraining/flavor_settings.hpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/flavor_settings.hpp index 4bc7ba0dbdec..08e602c2b00f 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/flavor_settings.hpp +++ b/barretenberg/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;