Skip to content

Commit

Permalink
Commit to Wires Using Lagrange SRS (#94)
Browse files Browse the repository at this point in the history
* Proof system works by using lagrange srs.

* Prover c_bind changes.

* Circuit c binds.

* fixes.

* Download more lagrange transcripts.

* fix.

* Add comment.

* Add `commit_lagrange` in commitment key.

---------

Co-authored-by: Suyash Bagad <[email protected]>
  • Loading branch information
dbanks12 and suyash67 authored Feb 12, 2023
1 parent 12e8ae8 commit 756d717
Show file tree
Hide file tree
Showing 23 changed files with 203 additions and 100 deletions.
2 changes: 1 addition & 1 deletion cpp/bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion cpp/scripts/run_tests
Original file line number Diff line number Diff line change
Expand Up @@ -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"
4 changes: 2 additions & 2 deletions cpp/src/aztec/benchmark/pippenger_bench/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::chrono::microseconds>(time_end - time_start);
std::cout << "run time: " << diff.count() << "us" << std::endl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<g1::affine_element>(num_points);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
20 changes: 18 additions & 2 deletions cpp/src/aztec/honk/pcs/commitment_key.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <srs/reference_string/file_reference_string.hpp>
#include <ecc/curves/bn254/scalar_multiplication/scalar_multiplication.hpp>
#include <ecc/curves/bn254/pairing.hpp>
#include <numeric/bitop/pow.hpp>

#include <string_view>
#include <memory>
Expand Down Expand Up @@ -59,9 +60,24 @@ class CommitmentKey {
C commit(std::span<const Fr> 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<Fr*>(polynomial.data()), srs.get_monomials(), degree, pippenger_runtime_state);
const_cast<Fr*>(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<const Fr> 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<Fr*>(polynomial.data()), srs.get_lagrange_points(), degree, pippenger_runtime_state);
};

private:
Expand Down
2 changes: 1 addition & 1 deletion cpp/src/aztec/honk/proof_system/verifier.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ template <class FF> 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));
}
Expand Down
6 changes: 4 additions & 2 deletions cpp/src/aztec/join_split_example/proofs/join_split/c_bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<waffle::PippengerReferenceStringFactory>(
reinterpret_cast<scalar_multiplication::Pippenger*>(pippenger), g2x);
reinterpret_cast<scalar_multiplication::Pippenger*>(pippenger),
reinterpret_cast<scalar_multiplication::Pippenger*>(pippenger_lagrange),
g2x);
init_verification_key(std::move(crs_factory));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ int main(int argc, char** argv)
auto reference_string = std::make_shared<waffle::FileReferenceString>(subgroup_size, srs_path);
std::vector<barretenberg::g1::affine_element> 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<waffle::VerifierFileReferenceString>(srs_path);
Expand Down
5 changes: 5 additions & 0 deletions cpp/src/aztec/numeric/bitop/pow.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
10 changes: 5 additions & 5 deletions cpp/src/aztec/plonk/composer/composer_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,11 +327,11 @@ std::shared_ptr<verification_key> 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 });
}
Expand Down
5 changes: 5 additions & 0 deletions cpp/src/aztec/plonk/proof_system/prover/c_bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions cpp/src/aztec/plonk/proof_system/prover/c_bind_unrolled.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
59 changes: 33 additions & 26 deletions cpp/src/aztec/plonk/proof_system/prover/prover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ template <typename settings> ProverBase<settings>& ProverBase<settings>::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.
* */
Expand All @@ -77,9 +78,9 @@ template <typename settings> void ProverBase<settings>::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
Expand Down Expand Up @@ -136,7 +137,7 @@ template <typename settings> void ProverBase<settings>::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);
}
}
Expand Down Expand Up @@ -206,15 +207,6 @@ template <typename settings> void ProverBase<settings>::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,
});
}
}

Expand Down Expand Up @@ -251,6 +243,20 @@ template <typename settings> void ProverBase<settings>::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);
}
Expand Down Expand Up @@ -285,30 +291,31 @@ template <typename settings> void ProverBase<settings>::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,
});
}
Expand Down
5 changes: 5 additions & 0 deletions cpp/src/aztec/plonk/proof_system/prover/prover.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ template <typename settings> 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);
Expand Down
10 changes: 5 additions & 5 deletions cpp/src/aztec/plonk/proof_system/verifier/verifier.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ waffle::Verifier generate_verifier(std::shared_ptr<proving_key> 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<waffle::VerifierFileReferenceString>("../srs_db/ignition");
Expand Down
5 changes: 3 additions & 2 deletions cpp/src/aztec/proof_system/proving_key/proving_key.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<ProverReferenceString> reference_string;

barretenberg::polynomial quotient_polynomial_parts[NUM_QUOTIENT_PARTS];
Expand Down
Loading

0 comments on commit 756d717

Please sign in to comment.