diff --git a/barretenberg/cpp/bootstrap.sh b/barretenberg/cpp/bootstrap.sh index 34e54c40af7..a93a488ac87 100755 --- a/barretenberg/cpp/bootstrap.sh +++ b/barretenberg/cpp/bootstrap.sh @@ -28,7 +28,7 @@ fi # Download ignition transcripts. cd ./srs_db ./download_ignition.sh 3 -./download_ignition_lagrange.sh 12 +./download_ignition_lagrange.sh 24 cd .. # Pick native toolchain file. diff --git a/barretenberg/cpp/scripts/run_tests b/barretenberg/cpp/scripts/run_tests index 7093b414907..04f7bfcb2bb 100755 --- a/barretenberg/cpp/scripts/run_tests +++ b/barretenberg/cpp/scripts/run_tests @@ -20,6 +20,6 @@ docker run --rm -t $IMAGE_URI /bin/sh -c "\ set -e; \ cd /usr/src/barretenberg/cpp/srs_db; \ ./download_ignition.sh $NUM_TRANSCRIPTS; \ - ./download_ignition_lagrange.sh 12; \ + ./download_ignition_lagrange.sh 24; \ cd /usr/src/barretenberg/cpp/build; \ for BIN in $TESTS; do ./bin/\$BIN $@; done" diff --git a/barretenberg/cpp/src/aztec/benchmark/pippenger_bench/main.cpp b/barretenberg/cpp/src/aztec/benchmark/pippenger_bench/main.cpp index 2c59ad4d415..66b28bea8a7 100644 --- a/barretenberg/cpp/src/aztec/benchmark/pippenger_bench/main.cpp +++ b/barretenberg/cpp/src/aztec/benchmark/pippenger_bench/main.cpp @@ -65,8 +65,8 @@ int pippenger() { scalar_multiplication::pippenger_runtime_state state(NUM_POINTS); std::chrono::steady_clock::time_point time_start = std::chrono::steady_clock::now(); - g1::element result = - scalar_multiplication::pippenger_unsafe(&scalars[0], reference_string->get_monomials(), NUM_POINTS, state); + g1::element result = scalar_multiplication::pippenger_unsafe( + &scalars[0], reference_string->get_monomial_points(), NUM_POINTS, state); std::chrono::steady_clock::time_point time_end = std::chrono::steady_clock::now(); std::chrono::microseconds diff = std::chrono::duration_cast(time_end - time_start); std::cout << "run time: " << diff.count() << "us" << std::endl; diff --git a/barretenberg/cpp/src/aztec/ecc/curves/bn254/scalar_multiplication/pippenger.cpp b/barretenberg/cpp/src/aztec/ecc/curves/bn254/scalar_multiplication/pippenger.cpp index 4c4b672210a..e07c769edd3 100644 --- a/barretenberg/cpp/src/aztec/ecc/curves/bn254/scalar_multiplication/pippenger.cpp +++ b/barretenberg/cpp/src/aztec/ecc/curves/bn254/scalar_multiplication/pippenger.cpp @@ -11,7 +11,7 @@ Pippenger::Pippenger(g1::affine_element* points, size_t num_points) scalar_multiplication::generate_pippenger_point_table(monomials_, monomials_, num_points); } -Pippenger::Pippenger(uint8_t const* points, size_t num_points, bool) +Pippenger::Pippenger(uint8_t const* points, size_t num_points) : num_points_(num_points) { monomials_ = point_table_alloc(num_points); diff --git a/barretenberg/cpp/src/aztec/ecc/curves/bn254/scalar_multiplication/pippenger.hpp b/barretenberg/cpp/src/aztec/ecc/curves/bn254/scalar_multiplication/pippenger.hpp index fca62ae2f9d..2b41397c6f0 100644 --- a/barretenberg/cpp/src/aztec/ecc/curves/bn254/scalar_multiplication/pippenger.hpp +++ b/barretenberg/cpp/src/aztec/ecc/curves/bn254/scalar_multiplication/pippenger.hpp @@ -41,7 +41,7 @@ class Pippenger { */ Pippenger(g1::affine_element* points, size_t num_points); - Pippenger(uint8_t const* points, size_t num_points, bool is_lagrange = false); + Pippenger(uint8_t const* points, size_t num_points); Pippenger(std::string const& path, size_t num_points, bool is_lagrange = false); diff --git a/barretenberg/cpp/src/aztec/honk/pcs/commitment_key.hpp b/barretenberg/cpp/src/aztec/honk/pcs/commitment_key.hpp index 805bf21e5a2..b8223923423 100644 --- a/barretenberg/cpp/src/aztec/honk/pcs/commitment_key.hpp +++ b/barretenberg/cpp/src/aztec/honk/pcs/commitment_key.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -59,9 +60,24 @@ class CommitmentKey { C commit(std::span polynomial) { const size_t degree = polynomial.size(); - ASSERT(degree <= srs.get_size()); + ASSERT(degree <= srs.get_monomial_size()); return barretenberg::scalar_multiplication::pippenger_unsafe( - const_cast(polynomial.data()), srs.get_monomials(), degree, pippenger_runtime_state); + const_cast(polynomial.data()), srs.get_monomial_points(), degree, pippenger_runtime_state); + }; + + /** + * @brief Uses the ProverSRS to create a commitment to p(X) + * + * @param polynomial a univariate polynomial in its evaluation form p(X) = ∑ᵢ p(ωⁱ)⋅Lᵢ(X) + * @return Commitment computed as C = [p(x)] = ∑ᵢ p(ωⁱ)⋅[Lᵢ(x)]₁ + */ + C commit_lagrange(std::span polynomial) + { + const size_t degree = polynomial.size(); + ASSERT(degree == srs.get_lagrange_size()); + ASSERT(numeric::is_power_of_two(degree)); + return barretenberg::scalar_multiplication::pippenger_unsafe( + const_cast(polynomial.data()), srs.get_lagrange_points(), degree, pippenger_runtime_state); }; private: diff --git a/barretenberg/cpp/src/aztec/honk/proof_system/verifier.test.cpp b/barretenberg/cpp/src/aztec/honk/proof_system/verifier.test.cpp index 6ec53fdd570..413400b9bfd 100644 --- a/barretenberg/cpp/src/aztec/honk/proof_system/verifier.test.cpp +++ b/barretenberg/cpp/src/aztec/honk/proof_system/verifier.test.cpp @@ -44,7 +44,7 @@ template class VerifierTests : public testing::Test { for (size_t i = 0; i < 8; ++i) { commitments[i] = g1::affine_element( scalar_multiplication::pippenger(poly_coefficients[i], - circuit_proving_key->reference_string->get_monomials(), + circuit_proving_key->reference_string->get_monomial_points(), circuit_proving_key->circuit_size, prover)); } diff --git a/barretenberg/cpp/src/aztec/join_split_example/proofs/join_split/c_bind.cpp b/barretenberg/cpp/src/aztec/join_split_example/proofs/join_split/c_bind.cpp index 468def339af..69c59f8b233 100644 --- a/barretenberg/cpp/src/aztec/join_split_example/proofs/join_split/c_bind.cpp +++ b/barretenberg/cpp/src/aztec/join_split_example/proofs/join_split/c_bind.cpp @@ -58,10 +58,12 @@ WASM_EXPORT uint32_t join_split__get_new_proving_key_data(uint8_t** output) return len; } -WASM_EXPORT void join_split__init_verification_key(void* pippenger, uint8_t const* g2x) +WASM_EXPORT void join_split__init_verification_key(void* pippenger, void* pippenger_lagrange, uint8_t const* g2x) { auto crs_factory = std::make_unique( - reinterpret_cast(pippenger), g2x); + reinterpret_cast(pippenger), + reinterpret_cast(pippenger_lagrange), + g2x); init_verification_key(std::move(crs_factory)); } diff --git a/barretenberg/cpp/src/aztec/lagrange_base_gen/lagrange_base_processor.cpp b/barretenberg/cpp/src/aztec/lagrange_base_gen/lagrange_base_processor.cpp index 24ca874a35b..984d6398f40 100644 --- a/barretenberg/cpp/src/aztec/lagrange_base_gen/lagrange_base_processor.cpp +++ b/barretenberg/cpp/src/aztec/lagrange_base_gen/lagrange_base_processor.cpp @@ -33,7 +33,7 @@ int main(int argc, char** argv) auto reference_string = std::make_shared(subgroup_size, srs_path); std::vector monomial_srs(subgroup_size); for (size_t i = 0; i < subgroup_size; ++i) { - monomial_srs[i] = reference_string->get_monomials()[2 * i]; + monomial_srs[i] = reference_string->get_monomial_points()[2 * i]; } auto verifier_ref_string = std::make_shared(srs_path); diff --git a/barretenberg/cpp/src/aztec/numeric/bitop/pow.hpp b/barretenberg/cpp/src/aztec/numeric/bitop/pow.hpp index 49f9882f7b1..9c200944cb0 100644 --- a/barretenberg/cpp/src/aztec/numeric/bitop/pow.hpp +++ b/barretenberg/cpp/src/aztec/numeric/bitop/pow.hpp @@ -25,4 +25,9 @@ constexpr uint64_t pow64(const uint64_t input, const uint64_t exponent) return accumulator; } +constexpr bool is_power_of_two(uint64_t x) +{ + return x && !(x & (x - 1)); +} + } // namespace numeric \ No newline at end of file diff --git a/barretenberg/cpp/src/aztec/plonk/composer/composer_base.cpp b/barretenberg/cpp/src/aztec/plonk/composer/composer_base.cpp index 55ee00a14fd..3bc862dbbc2 100644 --- a/barretenberg/cpp/src/aztec/plonk/composer/composer_base.cpp +++ b/barretenberg/cpp/src/aztec/plonk/composer/composer_base.cpp @@ -327,11 +327,11 @@ std::shared_ptr ComposerBase::compute_verification_key_base( selector_poly_coefficients = proving_key->polynomial_cache.get(selector_poly_label).get_coefficients(); // Commit to the constraint selector polynomial and insert the commitment in the verification key. - auto selector_poly_commitment = - g1::affine_element(scalar_multiplication::pippenger(selector_poly_coefficients, - proving_key->reference_string->get_monomials(), - proving_key->circuit_size, - proving_key->pippenger_runtime_state)); + auto selector_poly_commitment = g1::affine_element( + scalar_multiplication::pippenger(selector_poly_coefficients, + proving_key->reference_string->get_monomial_points(), + proving_key->circuit_size, + proving_key->pippenger_runtime_state)); circuit_verification_key->commitments.insert({ selector_commitment_label, selector_poly_commitment }); } diff --git a/barretenberg/cpp/src/aztec/plonk/proof_system/prover/c_bind.cpp b/barretenberg/cpp/src/aztec/plonk/proof_system/prover/c_bind.cpp index 35bb2b30749..01d8735288a 100644 --- a/barretenberg/cpp/src/aztec/plonk/proof_system/prover/c_bind.cpp +++ b/barretenberg/cpp/src/aztec/plonk/proof_system/prover/c_bind.cpp @@ -49,6 +49,11 @@ WASM_EXPORT void prover_get_work_queue_item_info(WasmProver* prover, uint8_t* re memcpy(result, &info, sizeof(info)); } +WASM_EXPORT bool prover_get_scalar_multiplication_type(WasmProver* prover, size_t work_item_number) +{ + return prover->get_scalar_multiplication_type(work_item_number); +} + WASM_EXPORT fr* prover_get_scalar_multiplication_data(WasmProver* prover, size_t work_item_number) { return prover->get_scalar_multiplication_data(work_item_number); diff --git a/barretenberg/cpp/src/aztec/plonk/proof_system/prover/c_bind_unrolled.cpp b/barretenberg/cpp/src/aztec/plonk/proof_system/prover/c_bind_unrolled.cpp index 7dc2bf3473c..f7070acf9d1 100644 --- a/barretenberg/cpp/src/aztec/plonk/proof_system/prover/c_bind_unrolled.cpp +++ b/barretenberg/cpp/src/aztec/plonk/proof_system/prover/c_bind_unrolled.cpp @@ -26,6 +26,11 @@ WASM_EXPORT void unrolled_prover_get_work_queue_item_info(WasmUnrolledProver* pr memcpy(result, &info, sizeof(info)); } +WASM_EXPORT bool unrolled_prover_get_scalar_multiplication_type(WasmUnrolledProver* prover, size_t work_item_number) +{ + return prover->get_scalar_multiplication_type(work_item_number); +} + WASM_EXPORT fr* unrolled_prover_get_scalar_multiplication_data(WasmUnrolledProver* prover, size_t work_item_number) { return prover->get_scalar_multiplication_data(work_item_number); diff --git a/barretenberg/cpp/src/aztec/plonk/proof_system/prover/prover.cpp b/barretenberg/cpp/src/aztec/plonk/proof_system/prover/prover.cpp index 1648eca166b..abc6f1728e0 100644 --- a/barretenberg/cpp/src/aztec/plonk/proof_system/prover/prover.cpp +++ b/barretenberg/cpp/src/aztec/plonk/proof_system/prover/prover.cpp @@ -67,6 +67,7 @@ template ProverBase& ProverBase::operato /** * - Compute wire commitments and add them to the transcript. * - Add public_inputs from w_2_fft to transcript. + * - We use Lagrange srs to commit to wire polynomials (in their Lagrange form). * * @tparam settings Program settings. * */ @@ -77,9 +78,9 @@ template void ProverBase::compute_wire_commitments for (size_t i = 0; i < end; ++i) { std::string wire_tag = "w_" + std::to_string(i + 1); std::string commit_tag = "W_" + std::to_string(i + 1); - barretenberg::fr* coefficients = key->polynomial_cache.get(wire_tag).get_coefficients(); + barretenberg::fr* coefficients = key->polynomial_cache.get(wire_tag + "_lagrange").get_coefficients(); // This automatically saves the computed point to the transcript - commitment_scheme->commit(coefficients, commit_tag, work_queue::MSMSize::N, queue); + commitment_scheme->commit(coefficients, commit_tag, work_queue::MSMType::LAGRANGE_N, queue); } // add public inputs @@ -136,7 +137,7 @@ template void ProverBase::compute_quotient_commitm std::string quotient_tag = "T_" + std::to_string(i + 1); // Set flag that determines domain size (currently n or n+1) in pippenger (see process_queue()). // Note: After blinding, all t_i have size n+1 representation (degree n) except t_4 in Turbo/Ultra. - fr domain_size_flag = i > 2 ? work_queue::MSMSize::N : work_queue::MSMSize::N_PLUS_ONE; + fr domain_size_flag = i > 2 ? work_queue::MSMType::MONOMIAL_N : work_queue::MSMType::MONOMIAL_N_PLUS_ONE; commitment_scheme->commit(coefficients, quotient_tag, domain_size_flag, queue); } } @@ -206,15 +207,6 @@ template void ProverBase::execute_preamble_round() } key->polynomial_cache.put(wire_tag + "_lagrange", std::move(wire_lagrange)); - - // perfom an IFFT so that the "w_i" polynomials will contain the monomial form - queue.add_to_queue({ - .work_type = work_queue::WorkType::IFFT, - .mul_scalars = nullptr, - .tag = wire_tag, - .constant = barretenberg::fr(0), - .index = 0, - }); } } @@ -251,6 +243,20 @@ template void ProverBase::execute_first_round() start = std::chrono::steady_clock::now(); #endif compute_wire_commitments(); + + // perfom an IFFT so that the "w_i" polynomials will contain the monomial form + const size_t end = settings::is_plookup ? (settings::program_width - 1) : settings::program_width; + for (size_t i = 0; i < end; ++i) { + std::string wire_tag = "w_" + std::to_string(i + 1); + queue.add_to_queue({ + .work_type = work_queue::WorkType::IFFT, + .mul_scalars = nullptr, + .tag = wire_tag, + .constant = 0, + .index = 0, + }); + } + for (auto& widget : random_widgets) { widget->compute_round_commitments(transcript, 1, queue); } @@ -285,30 +291,31 @@ template void ProverBase::execute_second_round() add_plookup_memory_records_to_w_4(); std::string wire_tag = "w_4"; barretenberg::polynomial& w_4_lagrange = key->polynomial_cache.get(wire_tag + "_lagrange"); - // barretenberg::polynomial& wire_fft = key->polynomial_cache.get(wire_tag + "_fft"); - barretenberg::polynomial w_4(key->circuit_size); - // barretenberg::polynomial_arithmetic::copy_polynomial(&wire[0], &wire_fft[0], n, n); - barretenberg::polynomial_arithmetic::copy_polynomial(&w_4_lagrange[0], &w_4[0], circuit_size, circuit_size); - // TODO: This adds blinding to the what will become the w_4_monomial, NOT to the w_4_lagrange poly. Is this - // intentional? + // add randomness to w_4_lagrange const size_t w_randomness = 3; ASSERT(w_randomness < settings::num_roots_cut_out_of_vanishing_polynomial); for (size_t k = 0; k < w_randomness; ++k) { // Blinding - w_4.at(circuit_size - settings::num_roots_cut_out_of_vanishing_polynomial + k) = fr::random_element(); + w_4_lagrange.at(circuit_size - settings::num_roots_cut_out_of_vanishing_polynomial + k) = + fr::random_element(); } - // poly w_4 and add to cache - w_4.ifft(key->small_domain); - key->polynomial_cache.put(wire_tag, std::move(w_4)); - - // Commit to w_4: + // commit to w_4 using Lagrange srs. queue.add_to_queue({ .work_type = work_queue::WorkType::SCALAR_MULTIPLICATION, - .mul_scalars = key->polynomial_cache.get(wire_tag).get_coefficients(), + .mul_scalars = w_4_lagrange.get_coefficients(), .tag = "W_4", - .constant = barretenberg::fr(0), + .constant = work_queue::MSMType::LAGRANGE_N, + .index = 0, + }); + + // convert w_4 to the coefficient form. + queue.add_to_queue({ + .work_type = work_queue::WorkType::IFFT, + .mul_scalars = nullptr, + .tag = wire_tag, + .constant = 0, .index = 0, }); } diff --git a/barretenberg/cpp/src/aztec/plonk/proof_system/prover/prover.hpp b/barretenberg/cpp/src/aztec/plonk/proof_system/prover/prover.hpp index ee4d578427e..667d48d6323 100644 --- a/barretenberg/cpp/src/aztec/plonk/proof_system/prover/prover.hpp +++ b/barretenberg/cpp/src/aztec/plonk/proof_system/prover/prover.hpp @@ -56,6 +56,11 @@ template class ProverBase { return queue.get_scalar_multiplication_size(work_item_number); } + bool get_scalar_multiplication_type(const size_t work_item_number) const + { + return queue.get_scalar_multiplication_type(work_item_number); + } + barretenberg::fr* get_ifft_data(const size_t work_item_number) const { return queue.get_ifft_data(work_item_number); diff --git a/barretenberg/cpp/src/aztec/plonk/proof_system/verifier/verifier.test.cpp b/barretenberg/cpp/src/aztec/plonk/proof_system/verifier/verifier.test.cpp index ce3ef4d3e3e..ce3ed7f194e 100644 --- a/barretenberg/cpp/src/aztec/plonk/proof_system/verifier/verifier.test.cpp +++ b/barretenberg/cpp/src/aztec/plonk/proof_system/verifier/verifier.test.cpp @@ -68,11 +68,11 @@ waffle::Verifier generate_verifier(std::shared_ptr circuit_proving_ commitments.resize(8); for (size_t i = 0; i < 8; ++i) { - commitments[i] = - g1::affine_element(scalar_multiplication::pippenger(poly_coefficients[i], - circuit_proving_key->reference_string->get_monomials(), - circuit_proving_key->circuit_size, - state)); + commitments[i] = g1::affine_element( + scalar_multiplication::pippenger(poly_coefficients[i], + circuit_proving_key->reference_string->get_monomial_points(), + circuit_proving_key->circuit_size, + state)); } auto crs = std::make_shared("../srs_db/ignition"); diff --git a/barretenberg/cpp/src/aztec/proof_system/proving_key/proving_key.hpp b/barretenberg/cpp/src/aztec/proof_system/proving_key/proving_key.hpp index fa880495f75..f2b124fd2f1 100644 --- a/barretenberg/cpp/src/aztec/proof_system/proving_key/proving_key.hpp +++ b/barretenberg/cpp/src/aztec/proof_system/proving_key/proving_key.hpp @@ -60,8 +60,9 @@ struct proving_key { barretenberg::evaluation_domain small_domain; barretenberg::evaluation_domain large_domain; - // We are keeping only one reference string which would be monomial srs if we use the Kate based PLONK, - // and Lagrange srs if we use the SHPLONK based PLONK. + // The reference_string object contains monomial as well as lagrange SRS. We can access them using: + // Monomial SRS: reference_string->get_monomial_points() + // Lagrange SRS: reference_string->get_lagrange_points() std::shared_ptr reference_string; barretenberg::polynomial quotient_polynomial_parts[NUM_QUOTIENT_PARTS]; diff --git a/barretenberg/cpp/src/aztec/proof_system/work_queue/work_queue.cpp b/barretenberg/cpp/src/aztec/proof_system/work_queue/work_queue.cpp index 65e187ab6ac..db76e499359 100644 --- a/barretenberg/cpp/src/aztec/proof_system/work_queue/work_queue.cpp +++ b/barretenberg/cpp/src/aztec/proof_system/work_queue/work_queue.cpp @@ -50,7 +50,7 @@ size_t work_queue::get_scalar_multiplication_size(const size_t work_item_number) for (const auto& item : work_item_queue) { if (item.work_type == WorkType::SCALAR_MULTIPLICATION) { if (count == work_item_number) { - return item.constant == MSMSize::N ? key->circuit_size : key->circuit_size + 1; + return (item.constant == MSMType::MONOMIAL_N_PLUS_ONE) ? key->circuit_size + 1 : key->circuit_size; } ++count; } @@ -58,6 +58,25 @@ size_t work_queue::get_scalar_multiplication_size(const size_t work_item_number) return 0; } +/** + * Returns a boolean that denotes if the scalar multiplication is to be done with the Monomial SRS or Lagrange SRS. + * 0: MSM with Monomial SRS (size n or n + 1) + * 1: MSM with Lagrange SRS (size n) + */ +bool work_queue::get_scalar_multiplication_type(const size_t work_item_number) const +{ + size_t count = 0; + for (const auto& item : work_item_queue) { + if (item.work_type == WorkType::SCALAR_MULTIPLICATION) { + if (count == work_item_number) { + return (item.constant == MSMType::LAGRANGE_N); + } + ++count; + } + } + return false; +} + barretenberg::fr* work_queue::get_ifft_data(const size_t work_item_number) const { size_t count = 0; @@ -198,32 +217,54 @@ void work_queue::process_queue() // We use the variable work_item::constant to set the size of the multi-scalar multiplication. // Note that a size (n+1) MSM is always needed to commit to the quotient polynomial parts t_1, t_2 // and t_3 for Standard/Turbo/Ultra due to the addition of blinding factors - if (item.constant == MSMSize::N_PLUS_ONE) { - if (key->reference_string->get_size() < key->small_domain.size + 1) { - info("Reference string too small for Pippenger."); + size_t msm_size = 0; + barretenberg::g1::affine_element* srs_points; + switch (static_cast(uint256_t(item.constant))) { + case MSMType::MONOMIAL_N: { + if (key->reference_string->get_monomial_size() < key->small_domain.size) { + info("MSM: Monomial reference string size: ", + key->reference_string->get_monomial_size(), + ", required size: ", + key->small_domain.size); } - auto runtime_state = - barretenberg::scalar_multiplication::pippenger_runtime_state(key->small_domain.size + 1); - barretenberg::g1::affine_element result( - barretenberg::scalar_multiplication::pippenger_unsafe(item.mul_scalars, - key->reference_string->get_monomials(), - key->small_domain.size + 1, - runtime_state)); - - transcript->add_element(item.tag, result.to_buffer()); - } else { - ASSERT(item.constant == MSMSize::N); - if (key->reference_string->get_size() < key->small_domain.size) { - info("Reference string too small for Pippenger."); + msm_size = key->small_domain.size; + srs_points = key->reference_string->get_monomial_points(); + break; + } + case MSMType::MONOMIAL_N_PLUS_ONE: { + if (key->reference_string->get_monomial_size() < key->small_domain.size + 1) { + info("MSM: Monomial reference string size: ", + key->reference_string->get_monomial_size(), + ", required size: ", + key->small_domain.size + 1); } - barretenberg::g1::affine_element result( - barretenberg::scalar_multiplication::pippenger_unsafe(item.mul_scalars, - key->reference_string->get_monomials(), - key->small_domain.size, - key->pippenger_runtime_state)); - - transcript->add_element(item.tag, result.to_buffer()); + msm_size = key->small_domain.size + 1; + srs_points = key->reference_string->get_monomial_points(); + break; } + case MSMType::LAGRANGE_N: { + if (key->reference_string->get_lagrange_size() != key->small_domain.size) { + info("MSM: Lagrange reference string size: ", + key->reference_string->get_lagrange_size(), + ", required size: ", + key->small_domain.size); + } + msm_size = key->small_domain.size; + srs_points = key->reference_string->get_lagrange_points(); + break; + } + default: { + info("Incorrect item constant value: ", static_cast(uint256_t(item.constant))); + srs_points = key->reference_string->get_monomial_points(); + } + } + + // Run pippenger multi-scalar multiplication. + auto runtime_state = barretenberg::scalar_multiplication::pippenger_runtime_state(msm_size); + barretenberg::g1::affine_element result(barretenberg::scalar_multiplication::pippenger_unsafe( + item.mul_scalars, srs_points, msm_size, runtime_state)); + + transcript->add_element(item.tag, result.to_buffer()); break; } diff --git a/barretenberg/cpp/src/aztec/proof_system/work_queue/work_queue.hpp b/barretenberg/cpp/src/aztec/proof_system/work_queue/work_queue.hpp index 72b7aa4d006..9d708f1f507 100644 --- a/barretenberg/cpp/src/aztec/proof_system/work_queue/work_queue.hpp +++ b/barretenberg/cpp/src/aztec/proof_system/work_queue/work_queue.hpp @@ -8,7 +8,7 @@ class work_queue { public: enum WorkType { FFT, SMALL_FFT, IFFT, SCALAR_MULTIPLICATION }; - enum MSMSize { N, N_PLUS_ONE }; + enum MSMType { MONOMIAL_N, MONOMIAL_N_PLUS_ONE, LAGRANGE_N }; struct work_item_info { uint32_t num_scalar_multiplications; @@ -42,6 +42,8 @@ class work_queue { size_t get_scalar_multiplication_size(const size_t work_item_number) const; + bool get_scalar_multiplication_type(const size_t work_item_number) const; + barretenberg::fr* get_ifft_data(const size_t work_item_number) const; void put_ifft_data(barretenberg::fr* result, const size_t work_item_number); diff --git a/barretenberg/cpp/src/aztec/srs/reference_string/file_reference_string.cpp b/barretenberg/cpp/src/aztec/srs/reference_string/file_reference_string.cpp index 265c553a51f..2ad29a47d5b 100644 --- a/barretenberg/cpp/src/aztec/srs/reference_string/file_reference_string.cpp +++ b/barretenberg/cpp/src/aztec/srs/reference_string/file_reference_string.cpp @@ -5,12 +5,12 @@ namespace waffle { -VerifierFileReferenceString::VerifierFileReferenceString(std::string const& path, bool is_lagrange) +VerifierFileReferenceString::VerifierFileReferenceString(std::string const& path) : precomputed_g2_lines( (barretenberg::pairing::miller_lines*)(aligned_alloc(64, sizeof(barretenberg::pairing::miller_lines) * 2))) { - barretenberg::io::read_transcript_g2(g2_x, path, is_lagrange); + barretenberg::io::read_transcript_g2(g2_x, path); barretenberg::pairing::precompute_miller_lines(barretenberg::g2::one, precomputed_g2_lines[0]); barretenberg::pairing::precompute_miller_lines(g2_x, precomputed_g2_lines[1]); } diff --git a/barretenberg/cpp/src/aztec/srs/reference_string/file_reference_string.hpp b/barretenberg/cpp/src/aztec/srs/reference_string/file_reference_string.hpp index cd89c123331..295d9849523 100644 --- a/barretenberg/cpp/src/aztec/srs/reference_string/file_reference_string.hpp +++ b/barretenberg/cpp/src/aztec/srs/reference_string/file_reference_string.hpp @@ -21,7 +21,7 @@ using namespace barretenberg; class VerifierFileReferenceString : public VerifierReferenceString { public: - VerifierFileReferenceString(std::string const& path, bool is_lagrange = false); + VerifierFileReferenceString(std::string const& path); ~VerifierFileReferenceString(); g2::affine_element get_g2x() const override { return g2_x; } @@ -35,59 +35,62 @@ class VerifierFileReferenceString : public VerifierReferenceString { class FileReferenceString : public ProverReferenceString { public: - FileReferenceString(const size_t num_points, std::string const& path, bool is_lagrange = false) + FileReferenceString(const size_t num_points, std::string const& path) : num_points(num_points) - , pippenger_(path, num_points, is_lagrange) + , pippenger_(path, num_points, false) + , pippenger_lagrange_(path, num_points, true) {} - g1::affine_element* get_monomials() override { return pippenger_.get_point_table(); } + g1::affine_element* get_monomial_points() override { return pippenger_.get_point_table(); } - size_t get_size() const override { return num_points; } + g1::affine_element* get_lagrange_points() override { return pippenger_lagrange_.get_point_table(); } + + size_t get_monomial_size() const override { return num_points; } + + size_t get_lagrange_size() const override { return 1UL << numeric::get_msb(num_points); } private: size_t num_points; scalar_multiplication::Pippenger pippenger_; + scalar_multiplication::Pippenger pippenger_lagrange_; }; class FileReferenceStringFactory : public ReferenceStringFactory { public: - FileReferenceStringFactory(std::string path, bool is_lagrange = false) + FileReferenceStringFactory(std::string path) : path_(std::move(path)) - , is_lagrange_(is_lagrange) {} FileReferenceStringFactory(FileReferenceStringFactory&& other) = default; std::shared_ptr get_prover_crs(size_t degree) override { - return std::make_shared(degree, path_, is_lagrange_); + return std::make_shared(degree, path_); } std::shared_ptr get_verifier_crs() override { - return std::make_shared(path_, is_lagrange_); + return std::make_shared(path_); } private: std::string path_; - bool is_lagrange_; }; class DynamicFileReferenceStringFactory : public ReferenceStringFactory { public: - DynamicFileReferenceStringFactory(std::string path, size_t initial_degree = 0, bool is_lagrange = false) + DynamicFileReferenceStringFactory(std::string path, size_t initial_degree = 0) : path_(std::move(path)) , degree_(initial_degree) - , is_lagrange_(is_lagrange) - , verifier_crs_(std::make_shared(path_, is_lagrange)) + , verifier_crs_(std::make_shared(path_)) {} DynamicFileReferenceStringFactory(DynamicFileReferenceStringFactory&& other) = default; std::shared_ptr get_prover_crs(size_t degree) override { - if (degree > degree_) { - prover_crs_ = std::make_shared(degree, path_, is_lagrange_); + if (degree != degree_) { + prover_crs_ = std::make_shared(degree, path_); degree_ = degree; } return prover_crs_; @@ -98,7 +101,6 @@ class DynamicFileReferenceStringFactory : public ReferenceStringFactory { private: std::string path_; size_t degree_; - bool is_lagrange_; std::shared_ptr prover_crs_; std::shared_ptr verifier_crs_; }; diff --git a/barretenberg/cpp/src/aztec/srs/reference_string/pippenger_reference_string.hpp b/barretenberg/cpp/src/aztec/srs/reference_string/pippenger_reference_string.hpp index a0f71fc3c30..2e6b639dce9 100644 --- a/barretenberg/cpp/src/aztec/srs/reference_string/pippenger_reference_string.hpp +++ b/barretenberg/cpp/src/aztec/srs/reference_string/pippenger_reference_string.hpp @@ -15,21 +15,29 @@ using namespace barretenberg; class PippengerReferenceString : public ProverReferenceString { public: - PippengerReferenceString(scalar_multiplication::Pippenger* pippenger) + PippengerReferenceString(scalar_multiplication::Pippenger* pippenger, + scalar_multiplication::Pippenger* pippenger_lagrange) : pippenger_(pippenger) + , pippenger_lagrange_(pippenger_lagrange) {} - size_t get_size() const override { return pippenger_->get_num_points(); } - g1::affine_element* get_monomials() override { return pippenger_->get_point_table(); } + size_t get_monomial_size() const override { return pippenger_->get_num_points(); } + size_t get_lagrange_size() const override { return pippenger_lagrange_->get_num_points(); } + g1::affine_element* get_monomial_points() override { return pippenger_->get_point_table(); } + g1::affine_element* get_lagrange_points() override { return pippenger_lagrange_->get_point_table(); } private: scalar_multiplication::Pippenger* pippenger_; + scalar_multiplication::Pippenger* pippenger_lagrange_; }; class PippengerReferenceStringFactory : public ReferenceStringFactory { public: - PippengerReferenceStringFactory(scalar_multiplication::Pippenger* pippenger, uint8_t const* g2x) + PippengerReferenceStringFactory(scalar_multiplication::Pippenger* pippenger, + scalar_multiplication::Pippenger* pippenger_lagrange, + uint8_t const* g2x) : pippenger_(pippenger) + , pippenger_lagrange_(pippenger_lagrange) , g2x_(g2x) {} @@ -38,7 +46,8 @@ class PippengerReferenceStringFactory : public ReferenceStringFactory { std::shared_ptr get_prover_crs(size_t degree) override { ASSERT(degree <= pippenger_->get_num_points()); - return std::make_shared(pippenger_); + ASSERT((1UL << numeric::get_msb(degree)) == pippenger_lagrange_->get_num_points()); + return std::make_shared(pippenger_, pippenger_lagrange_); } std::shared_ptr get_verifier_crs() override @@ -48,6 +57,7 @@ class PippengerReferenceStringFactory : public ReferenceStringFactory { private: scalar_multiplication::Pippenger* pippenger_; + scalar_multiplication::Pippenger* pippenger_lagrange_; uint8_t const* g2x_; }; diff --git a/barretenberg/cpp/src/aztec/srs/reference_string/reference_string.hpp b/barretenberg/cpp/src/aztec/srs/reference_string/reference_string.hpp index 6508d12b25f..76028792375 100644 --- a/barretenberg/cpp/src/aztec/srs/reference_string/reference_string.hpp +++ b/barretenberg/cpp/src/aztec/srs/reference_string/reference_string.hpp @@ -27,8 +27,10 @@ class ProverReferenceString { virtual ~ProverReferenceString() = default; ; - virtual barretenberg::g1::affine_element* get_monomials() = 0; - virtual size_t get_size() const = 0; + virtual barretenberg::g1::affine_element* get_monomial_points() = 0; + virtual barretenberg::g1::affine_element* get_lagrange_points() = 0; + virtual size_t get_monomial_size() const = 0; + virtual size_t get_lagrange_size() const = 0; }; class ReferenceStringFactory {