Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: constify eccvm and translator #9661

Merged
merged 14 commits into from
Nov 7, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "barretenberg/commitment_schemes/commitment_key.hpp"
#include "barretenberg/commitment_schemes/verification_key.hpp"
#include "barretenberg/constants.hpp"
#include "barretenberg/ecc/curves/bn254/g1.hpp"
#include "barretenberg/srs/factories/file_crs_factory.hpp"
#include "claim.hpp"
Expand All @@ -10,20 +11,21 @@

namespace bb {

constexpr size_t COMMITMENT_TEST_NUM_POINTS = 4096;
constexpr size_t COMMITMENT_TEST_NUM_BN254_POINTS = 4096;
constexpr size_t COMMITMENT_TEST_NUM_GRUMPKIN_POINTS = 1 << CONST_ECCVM_LOG_N;

template <class CK> inline std::shared_ptr<CK> CreateCommitmentKey();

template <> inline std::shared_ptr<CommitmentKey<curve::BN254>> CreateCommitmentKey<CommitmentKey<curve::BN254>>()
{
srs::init_crs_factory("../srs_db/ignition");
return std::make_shared<CommitmentKey<curve::BN254>>(COMMITMENT_TEST_NUM_POINTS);
return std::make_shared<CommitmentKey<curve::BN254>>(COMMITMENT_TEST_NUM_BN254_POINTS);
}
// For IPA
template <> inline std::shared_ptr<CommitmentKey<curve::Grumpkin>> CreateCommitmentKey<CommitmentKey<curve::Grumpkin>>()
{
srs::init_grumpkin_crs_factory("../srs_db/grumpkin");
return std::make_shared<CommitmentKey<curve::Grumpkin>>(COMMITMENT_TEST_NUM_POINTS);
return std::make_shared<CommitmentKey<curve::Grumpkin>>(COMMITMENT_TEST_NUM_GRUMPKIN_POINTS);
}

template <typename CK> inline std::shared_ptr<CK> CreateCommitmentKey()
Expand All @@ -45,9 +47,9 @@ template <>
inline std::shared_ptr<VerifierCommitmentKey<curve::Grumpkin>> CreateVerifierCommitmentKey<
VerifierCommitmentKey<curve::Grumpkin>>()
{
auto crs_factory = std::make_shared<srs::factories::FileCrsFactory<curve::Grumpkin>>("../srs_db/grumpkin",
COMMITMENT_TEST_NUM_POINTS);
return std::make_shared<VerifierCommitmentKey<curve::Grumpkin>>(COMMITMENT_TEST_NUM_POINTS, crs_factory);
auto crs_factory = std::make_shared<srs::factories::FileCrsFactory<curve::Grumpkin>>(
"../srs_db/grumpkin", COMMITMENT_TEST_NUM_GRUMPKIN_POINTS);
return std::make_shared<VerifierCommitmentKey<curve::Grumpkin>>(COMMITMENT_TEST_NUM_GRUMPKIN_POINTS, crs_factory);
}
template <typename VK> inline std::shared_ptr<VK> CreateVerifierCommitmentKey()
// requires std::default_initializable<VK>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ template <typename Curve> class GeminiVerifier_ {

if constexpr (Curve::is_stdlib_type) {
auto builder = evaluation_point[0].get_context();
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1114): insecure!
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1114): insecure dummy_round derivation!
stdlib::bool_t dummy_round = stdlib::witness_t(builder, l > num_variables);
batched_eval_accumulator =
Fr::conditional_assign(dummy_round, batched_eval_accumulator, batched_eval_round_acc);
Expand Down
113 changes: 74 additions & 39 deletions barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,9 @@ template <typename Curve_> class IPA {

// Iterate for log(poly_degree) rounds to compute the round commitments.
auto log_poly_length = static_cast<size_t>(numeric::get_msb(poly_length));
if (log_poly_length > CONST_ECCVM_LOG_N) {
throw_or_abort("IPA log_poly_length is too large");
}

// Allocate space for L_i and R_i elements
GroupElement L_i;
Expand Down Expand Up @@ -235,7 +238,7 @@ template <typename Curve_> class IPA {

// Step 6.c
// Send commitments to the verifier
std::string index = std::to_string(log_poly_length - i - 1);
std::string index = std::to_string(CONST_ECCVM_LOG_N - i - 1);
transcript->send_to_verifier("IPA:L_" + index, Commitment(L_i));
transcript->send_to_verifier("IPA:R_" + index, Commitment(R_i));

Expand Down Expand Up @@ -271,6 +274,14 @@ template <typename Curve_> class IPA {
}, thread_heuristics::FF_ADDITION_COST * 2 + thread_heuristics::FF_MULTIPLICATION_COST * 2);
}

// For dummy rounds, send commitments of zero()
for (size_t i = log_poly_length; i < CONST_ECCVM_LOG_N; i++) {
std::string index = std::to_string(CONST_ECCVM_LOG_N - i - 1);
transcript->send_to_verifier("IPA:L_" + index, Commitment::one());
transcript->send_to_verifier("IPA:R_" + index, Commitment::one());
transcript->template get_challenge<Fr>("IPA:round_challenge_" + index);
}

// Step 7
// Send a_0 to the verifier
transcript->send_to_verifier("IPA:a_0", a_vec[0]);
Expand Down Expand Up @@ -324,20 +335,23 @@ template <typename Curve_> class IPA {
Commitment aux_generator = Commitment::one() * generator_challenge;

auto log_poly_length = static_cast<size_t>(numeric::get_msb(poly_length));
if (log_poly_length > CONST_ECCVM_LOG_N) {
throw_or_abort("IPA log_poly_length is too large");
}
// Step 3.
// Compute C' = C + f(\beta) ⋅ U
GroupElement C_prime = opening_claim.commitment + (aux_generator * opening_claim.opening_pair.evaluation);

auto pippenger_size = 2 * log_poly_length;
std::vector<Fr> round_challenges(log_poly_length);
std::vector<Fr> round_challenges_inv(log_poly_length);
std::vector<Fr> round_challenges(CONST_ECCVM_LOG_N);
std::vector<Fr> round_challenges_inv(CONST_ECCVM_LOG_N);
std::vector<Commitment> msm_elements(pippenger_size);
std::vector<Fr> msm_scalars(pippenger_size);

// Step 4.
// Receive all L_i and R_i and prepare for MSM
for (size_t i = 0; i < log_poly_length; i++) {
std::string index = std::to_string(log_poly_length - i - 1);
for (size_t i = 0; i < CONST_ECCVM_LOG_N; i++) {
std::string index = std::to_string(CONST_ECCVM_LOG_N - i - 1);
auto element_L = transcript->template receive_from_prover<Commitment>("IPA:L_" + index);
auto element_R = transcript->template receive_from_prover<Commitment>("IPA:R_" + index);
round_challenges[i] = transcript->template get_challenge<Fr>("IPA:round_challenge_" + index);
Expand All @@ -346,11 +360,13 @@ template <typename Curve_> class IPA {
}
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1140): Use batch_invert.
round_challenges_inv[i] = round_challenges[i].invert();
if (i < log_poly_length) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for native verifier, we only need to look at the log_poly_length elements that matter


msm_elements[2 * i] = element_L;
msm_elements[2 * i + 1] = element_R;
msm_scalars[2 * i] = round_challenges_inv[i];
msm_scalars[2 * i + 1] = round_challenges[i];
msm_elements[2 * i] = element_L;
msm_elements[2 * i + 1] = element_R;
msm_scalars[2 * i] = round_challenges_inv[i];
msm_scalars[2 * i + 1] = round_challenges[i];
}
}

// Step 5.
Expand All @@ -371,7 +387,7 @@ template <typename Curve_> class IPA {

// Step 7.
// Construct vector s
Polynomial<Fr> s_poly(construct_poly_from_u_challenges_inv(round_challenges_inv));
Polynomial<Fr> s_poly(construct_poly_from_u_challenges_inv(log_poly_length, std::span(round_challenges_inv).subspan(0, log_poly_length)));

std::span<const Commitment> srs_elements = vk->get_monomial_points();
if (poly_length * 2 > srs_elements.size()) {
Expand Down Expand Up @@ -440,29 +456,35 @@ template <typename Curve_> class IPA {
// Step 2.
// Receive generator challenge u and compute auxiliary generator
const Fr generator_challenge = transcript->template get_challenge<Fr>("IPA:generator_challenge");
auto builder = generator_challenge.get_context();
typename Curve::Builder* builder = generator_challenge.get_context();

const auto log_poly_length = numeric::get_msb(static_cast<uint32_t>(poly_length));
auto pippenger_size = 2 * log_poly_length;
std::vector<Fr> round_challenges(log_poly_length);
std::vector<Fr> round_challenges_inv(log_poly_length);
if (log_poly_length > CONST_ECCVM_LOG_N) {
throw_or_abort("IPA log_poly_length is too large");
}
auto pippenger_size = 2 * CONST_ECCVM_LOG_N;
std::vector<Fr> round_challenges(CONST_ECCVM_LOG_N);
std::vector<Fr> round_challenges_inv(CONST_ECCVM_LOG_N);
std::vector<Commitment> msm_elements(pippenger_size);
std::vector<Fr> msm_scalars(pippenger_size);


// Step 3.
// Receive all L_i and R_i and prepare for MSM
for (size_t i = 0; i < log_poly_length; i++) {
std::string index = std::to_string(log_poly_length - i - 1);
for (size_t i = 0; i < CONST_ECCVM_LOG_N; i++) {
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1114): insecure dummy_round derivation!
stdlib::bool_t<typename Curve::Builder> dummy_round = stdlib::witness_t(builder, i >= log_poly_length);

std::string index = std::to_string(CONST_ECCVM_LOG_N - i - 1);
auto element_L = transcript->template receive_from_prover<Commitment>("IPA:L_" + index);
auto element_R = transcript->template receive_from_prover<Commitment>("IPA:R_" + index);
round_challenges[i] = transcript->template get_challenge<Fr>("IPA:round_challenge_" + index);
round_challenges_inv[i] = round_challenges[i].invert();

msm_elements[2 * i] = element_L;
msm_elements[2 * i + 1] = element_R;
msm_scalars[2 * i] = round_challenges_inv[i];
msm_scalars[2 * i + 1] = round_challenges[i];
msm_scalars[2 * i] = Fr::conditional_assign(dummy_round, Fr(0), round_challenges_inv[i]);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the dummy rounds, put 0s as the scalars.

msm_scalars[2 * i + 1] = Fr::conditional_assign(dummy_round, Fr(0), round_challenges[i]);
}

// Step 4.
Expand All @@ -472,11 +494,14 @@ template <typename Curve_> class IPA {

Fr b_zero = Fr(1);
Fr challenge = opening_claim.opening_pair.challenge;
for (size_t i = 0; i < log_poly_length; i++) {
b_zero *= Fr(1) + (round_challenges_inv[log_poly_length - 1 - i] * challenge);
if (i != log_poly_length - 1)
for (size_t i = 0; i < CONST_ECCVM_LOG_N; i++) {
stdlib::bool_t<typename Curve::Builder> dummy_round = stdlib::witness_t(builder, i < CONST_ECCVM_LOG_N - log_poly_length);

Fr monomial = Fr::conditional_assign(dummy_round, Fr(0), round_challenges_inv[CONST_ECCVM_LOG_N - 1 - i] * challenge);
b_zero *= Fr(1) + monomial;
if (i != CONST_ECCVM_LOG_N - 1) // this if statement is fine because the number of iterations is constant
{
challenge = challenge * challenge;
challenge = Fr::conditional_assign(dummy_round, challenge, challenge * challenge);
}
}

Expand Down Expand Up @@ -532,8 +557,9 @@ template <typename Curve_> class IPA {
ipa_relation.assert_equal(-opening_claim.commitment);

ASSERT(ipa_relation.get_value() == -opening_claim.commitment.get_value());
// This should return an actual VerifierAccumulator
return {round_challenges_inv, G_zero};
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1144): Add proper constraints for taking the log of a field_t.
Fr stdlib_log_poly_length(static_cast<uint256_t>(log_poly_length));
lucasxia01 marked this conversation as resolved.
Show resolved Hide resolved
return {stdlib_log_poly_length, round_challenges_inv, G_zero};
}

public:
Expand Down Expand Up @@ -664,13 +690,23 @@ template <typename Curve_> class IPA {
* @param r
* @return Fr
*/
static Fr evaluate_challenge_poly(const std::vector<Fr>& u_challenges_inv, Fr r) {
static Fr evaluate_challenge_poly(Fr log_poly_length, const std::vector<Fr>& u_challenges_inv, Fr r) {
using Builder = typename Curve::Builder;

Builder* builder = r.get_context();
Fr challenge_poly_eval = 1;
Fr r_pow = r;
size_t len = u_challenges_inv.size();
for (size_t i = 0; i < len; i++) {
challenge_poly_eval *= (Fr(1) + u_challenges_inv[len - 1 - i] * r_pow);
r_pow *= r_pow;
if (uint32_t(log_poly_length.get_value()) > CONST_ECCVM_LOG_N) {
throw_or_abort("IPA log_poly_length is too large");
}
for (size_t i = 0; i < CONST_ECCVM_LOG_N; i++) {
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1114): insecure dummy_round derivation!
stdlib::bool_t<typename Curve::Builder> dummy_round = stdlib::witness_t(builder, i < CONST_ECCVM_LOG_N - uint32_t(log_poly_length.get_value()));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this sort of stuff is not secure. Will need to figure out a way to fix it, like the rest of the dummy_round stuff in sumcheck


Fr monomial = Fr::conditional_assign(dummy_round, Fr(0), u_challenges_inv[CONST_ECCVM_LOG_N - 1 - i] * r_pow);

challenge_poly_eval *= (Fr(1) + monomial);
r_pow = Fr::conditional_assign(dummy_round, r_pow, r_pow * r_pow);
}
return challenge_poly_eval;
}
Expand All @@ -684,8 +720,8 @@ template <typename Curve_> class IPA {
* @param alpha
* @return Fr
*/
static Fr evaluate_and_accumulate_challenge_polys(std::vector<Fr> u_challenges_inv_1, std::vector<Fr> u_challenges_inv_2, Fr r, Fr alpha) {
auto result = evaluate_challenge_poly(u_challenges_inv_1, r) + alpha * evaluate_challenge_poly(u_challenges_inv_2, r);
static Fr evaluate_and_accumulate_challenge_polys(Fr log_poly_length_1, std::vector<Fr> u_challenges_inv_1, Fr log_poly_length_2, std::vector<Fr> u_challenges_inv_2, Fr r, Fr alpha) {
auto result = evaluate_challenge_poly(log_poly_length_1, u_challenges_inv_1, r) + alpha * evaluate_challenge_poly(log_poly_length_2, u_challenges_inv_2, r);
return result;
}

Expand All @@ -695,9 +731,8 @@ template <typename Curve_> class IPA {
* @param u_challenges_inv
* @return Polynomial<bb::fq>
*/
static Polynomial<bb::fq> construct_poly_from_u_challenges_inv(const std::vector<bb::fq>& u_challenges_inv) {
const size_t poly_length = (1 << u_challenges_inv.size());
const size_t log_poly_length = u_challenges_inv.size();
static Polynomial<bb::fq> construct_poly_from_u_challenges_inv(const size_t log_poly_length, const std::span<const bb::fq>& u_challenges_inv) {
const size_t poly_length = (1 << log_poly_length);

// Construct vector s in linear time.
std::vector<bb::fq> s_vec(poly_length, bb::fq::one());
Expand Down Expand Up @@ -735,9 +770,9 @@ template <typename Curve_> class IPA {
* @param alpha
* @return Polynomial<bb::fq>
*/
static Polynomial<bb::fq> create_challenge_poly(const std::vector<bb::fq>& u_challenges_inv_1, const std::vector<bb::fq>& u_challenges_inv_2, bb::fq alpha) {
Polynomial challenge_poly = construct_poly_from_u_challenges_inv(u_challenges_inv_1);
Polynomial challenge_poly_2 = construct_poly_from_u_challenges_inv(u_challenges_inv_2);
static Polynomial<bb::fq> create_challenge_poly(const size_t log_poly_length_1, const std::vector<bb::fq>& u_challenges_inv_1, const size_t log_poly_length_2, const std::vector<bb::fq>& u_challenges_inv_2, bb::fq alpha) {
Polynomial challenge_poly = construct_poly_from_u_challenges_inv(log_poly_length_1, u_challenges_inv_1);
Polynomial challenge_poly_2 = construct_poly_from_u_challenges_inv(log_poly_length_2, u_challenges_inv_2);
challenge_poly.add_scaled(challenge_poly_2, alpha);
return challenge_poly;
}
Expand Down Expand Up @@ -776,7 +811,7 @@ template <typename Curve_> class IPA {
output_claim.commitment = pair_1.comm + pair_2.comm * alpha;
output_claim.opening_pair.challenge = r;
// Evaluate the challenge_poly polys at r and linearly combine them with alpha challenge
output_claim.opening_pair.evaluation = evaluate_and_accumulate_challenge_polys(pair_1.u_challenges_inv, pair_2.u_challenges_inv, r, alpha);
output_claim.opening_pair.evaluation = evaluate_and_accumulate_challenge_polys(pair_1.log_poly_length, pair_1.u_challenges_inv, pair_2.log_poly_length, pair_2.u_challenges_inv, r, alpha);

// Step 4: Compute the new polynomial
std::vector<bb::fq> native_u_challenges_inv_1;
Expand All @@ -787,7 +822,7 @@ template <typename Curve_> class IPA {
for (Fr u_inv_i : pair_2.u_challenges_inv) {
native_u_challenges_inv_2.push_back(bb::fq(u_inv_i.get_value()));
}
return {output_claim, create_challenge_poly(native_u_challenges_inv_1, native_u_challenges_inv_2, fq(alpha.get_value()))};
return {output_claim, create_challenge_poly(uint32_t(pair_1.log_poly_length.get_value()), native_u_challenges_inv_1, uint32_t(pair_2.log_poly_length.get_value()), native_u_challenges_inv_2, fq(alpha.get_value()))};
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ TEST_F(IPATest, AIsZeroAfterOneRound)

// initialize an empty mock transcript
auto transcript = std::make_shared<MockTranscript>();
const size_t num_challenges = numeric::get_msb(n) + 1;
const size_t num_challenges = CONST_ECCVM_LOG_N + 1;
std::vector<uint256_t> random_vector(num_challenges);

// Generate a random element vector with challenges
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@ template <typename Curve> class ZeroMorphVerifier_ {
if constexpr (Curve::is_stdlib_type) {
auto builder = x_challenge.get_context();
FF zero = FF(0);
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1114): insecure dummy_round derivation!
stdlib::bool_t dummy_round = stdlib::witness_t(builder, is_dummy_round);
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1039): is it kosher to reassign like this?
scalar = FF::conditional_assign(dummy_round, zero, scalar);
Expand Down Expand Up @@ -589,6 +590,8 @@ template <typename Curve> class ZeroMorphVerifier_ {
const FF circuit_size,
const std::vector<RefVector<Commitment>>& concatenation_groups_commitments = {})
{
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1144): Add proper constraints for taking the log of
// a field_t.
size_t N{ 0 };
size_t log_N{ 0 };
if constexpr (Curve::is_stdlib_type) {
Expand Down
Loading
Loading