-
Notifications
You must be signed in to change notification settings - Fork 310
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
Changes from all commits
216e1af
f691529
7b45285
4870b02
6ac3e20
b8ff552
3ad3760
9582fee
f67dd2d
3e96479
cd7e947
91dff5d
7332009
f4ba9e7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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; | ||
|
@@ -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)); | ||
|
||
|
@@ -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]); | ||
|
@@ -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); | ||
|
@@ -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) { | ||
|
||
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. | ||
|
@@ -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()) { | ||
|
@@ -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]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. | ||
|
@@ -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); | ||
} | ||
} | ||
|
||
|
@@ -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: | ||
|
@@ -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())); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
} | ||
|
@@ -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; | ||
} | ||
|
||
|
@@ -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()); | ||
|
@@ -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; | ||
} | ||
|
@@ -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; | ||
|
@@ -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()))}; | ||
} | ||
}; | ||
|
||
|
There was a problem hiding this comment.
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