-
Notifications
You must be signed in to change notification settings - Fork 129
Ad/IPA uses Fiat-Shamir #244
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
Changes from all commits
fc708b2
e8aaba6
770b12b
11b6d89
cefc50e
99ea987
2442348
ee538fa
f1cf202
28aa6bf
44a3ce8
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 | ||
|---|---|---|---|---|
|
|
@@ -32,44 +32,48 @@ template <typename Params> class InnerProductArgument { | |||
| std::vector<affine_element> R_vec; | ||||
| Fr a_zero; | ||||
| }; | ||||
| // To contain the public inputs for IPA proof | ||||
| // For now we are including the aux_generator and round_challenges in public input. They will be computed by the | ||||
| // prover and the verifier by Fiat-Shamir when the challengeGenerator is defined. | ||||
| struct PubInput { | ||||
| element commitment; | ||||
| Fr challenge_point; | ||||
| Fr evaluation; | ||||
| size_t poly_degree; | ||||
| element aux_generator; // To be removed | ||||
| std::vector<Fr> round_challenges; // To be removed | ||||
| }; | ||||
|
|
||||
| /** | ||||
| * @brief Compute a proof for opening a single polynomial at a single evaluation point | ||||
| * | ||||
| * @param ck The commitment key containing srs and pippenger_runtime_state for computing MSM | ||||
| * @param pub_input Data required to compute the opening proof. See spec for more details | ||||
| * @param ck Commitment key contains srs and pippenger_runtime_state for computing MSM | ||||
| * @param opening_pair OpeningPair = {challenge_point, evaluation = polynomial(challenge_point)} | ||||
| * @param polynomial The witness polynomial whose opening proof needs to be computed | ||||
| * | ||||
| * @return a Proof, containing information required to verify whether the commitment is computed correctly and | ||||
| * @return a Proof, contains information required to verify whether the commitment is computed correctly and | ||||
| * the polynomial evaluation is correct in the given challenge point. | ||||
| */ | ||||
| static Proof reduce_prove(std::shared_ptr<CK> ck, const PubInput& pub_input, const Polynomial& polynomial) | ||||
| static Proof reduce_prove(std::shared_ptr<CK> ck, | ||||
| const OpeningPair<Params>& opening_pair, | ||||
| const Polynomial& polynomial, | ||||
| const auto& transcript) | ||||
| { | ||||
| Proof proof; | ||||
| auto& challenge_point = pub_input.challenge_point; | ||||
| auto& challenge_point = opening_pair.query; | ||||
| ASSERT(challenge_point != 0 && "The challenge point should not be zero"); | ||||
| const size_t poly_degree = pub_input.poly_degree; | ||||
| const size_t poly_degree = polynomial.size(); | ||||
| // To check poly_degree is greater than zero and a power of two | ||||
| // TODO(#220)(Arijit): To accomodate non power of two poly_degree | ||||
|
|
||||
| ASSERT((poly_degree > 0) && (!(poly_degree & (poly_degree - 1))) && | ||||
| "The poly_degree should be positive and a power of two"); | ||||
| auto& aux_generator = pub_input.aux_generator; | ||||
| auto a_vec = polynomial; | ||||
| // TODO(#220)(Arijit): to make it more efficient by directly using G_vector for the input points when i = 0 and write the | ||||
| // output points to G_vec_local. Then use G_vec_local for rounds where i>0, this can be done after we use SRS | ||||
| // instead of G_vector. | ||||
|
|
||||
| auto commitment = ck->commit(polynomial); | ||||
| auto& evaluation = opening_pair.evaluation; | ||||
| transcript->add_element("ipa_commitment", static_cast<affine_element>(commitment).to_buffer()); | ||||
| transcript->add_element("ipa_challenge_point", static_cast<Fr>(challenge_point).to_buffer()); | ||||
| transcript->add_element("ipa_eval", static_cast<Fr>(evaluation).to_buffer()); | ||||
| transcript->apply_fiat_shamir("ipa_aux"); | ||||
|
|
||||
| const Fr aux_challenge = Fr::serialize_from_buffer(transcript->get_challenge("ipa_aux").begin()); | ||||
| auto srs_elements = ck->srs.get_monomial_points(); | ||||
| const auto aux_generator = srs_elements[poly_degree] * aux_challenge; | ||||
|
|
||||
| auto a_vec = polynomial; | ||||
| // TODO(#220)(Arijit): to make it more efficient by directly using G_vector for the input points when i = 0 and | ||||
| // write the output points to G_vec_local. Then use G_vec_local for rounds where i>0, this can be done after we | ||||
| // use SRS instead of G_vector. | ||||
|
|
||||
| std::vector<affine_element> G_vec_local(poly_degree); | ||||
| for (size_t i = 0; i < poly_degree; i++) { | ||||
| G_vec_local[i] = srs_elements[i]; | ||||
|
|
@@ -111,9 +115,13 @@ template <typename Params> class InnerProductArgument { | |||
|
|
||||
| L_elements[i] = affine_element(partial_L); | ||||
| R_elements[i] = affine_element(partial_R); | ||||
|
|
||||
| // Generate the round challenge. TODO(#220)(Arijit): Use Fiat-Shamir | ||||
| const Fr round_challenge = pub_input.round_challenges[i]; | ||||
| // Using Fiat-Shamir | ||||
| auto label = std::to_string(i); | ||||
| transcript->add_element("L_" + label, static_cast<affine_element>(partial_L).to_buffer()); | ||||
| transcript->add_element("R_" + label, static_cast<affine_element>(partial_R).to_buffer()); | ||||
| transcript->apply_fiat_shamir("ipa_round_" + label); | ||||
| const Fr round_challenge = | ||||
| Fr::serialize_from_buffer(transcript->get_challenge("ipa_round_" + label).begin()); | ||||
| const Fr round_challenge_inv = round_challenge.invert(); | ||||
|
|
||||
| // Update the vectors a_vec, b_vec and G_vec. | ||||
|
|
@@ -156,34 +164,41 @@ template <typename Params> class InnerProductArgument { | |||
| /** | ||||
| * @brief Verify the correctness of a Proof | ||||
| * | ||||
| * @param vk Verification_key containing srs and pippenger_runtime_state to be used for MSM | ||||
| * @param proof The proof containg L_vec, R_vec and a_zero | ||||
| * @param pub_input Data required to verify the proof | ||||
| * @param vk Verification_key contains the srs and pippenger_runtime_state to be used for MSM | ||||
| * @param claim OpeningClaim contains the commitment, challenge, and the evaluation | ||||
| * @param proof Proof contains L_vec, R_vec, and a_zero | ||||
| * @param transcript Transcript contains the round challenges and the aux challenge | ||||
| * | ||||
| * @return true/false depending on if the proof verifies | ||||
| */ | ||||
| static bool reduce_verify(std::shared_ptr<VK> vk, const Proof& proof, const PubInput& pub_input) | ||||
| static bool reduce_verify(std::shared_ptr<VK> vk, | ||||
|
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. To follow the idiom established in KZG, we would use a class
Author
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 problem stems from the fact that
ipa::reduce_verify for MSM unlike other PCSs. These parameter are set by calling a constructor in commitment_key.test.cpp here. Under this settings, we access these parameters by passing the vk shared ptr as argument to ipa::reduce_verify in ipa_test.cpp here.This was a due point in PR #205, and we decided to go with this keeping this as an issue (#236). In the current PR, we somehow solved the issue with reduce_prove by using the transcript. But I could not see a path to resolve it for reduce_verify. Please let me know if this makes sense. I shall record this in the issue #236.
|
||||
| const OpeningClaim<Params>& claim, | ||||
| const Proof& proof, | ||||
| const auto& transcript) | ||||
| { | ||||
| // Local copies of public inputs | ||||
| auto& a_zero = proof.a_zero; | ||||
| auto& commitment = pub_input.commitment; | ||||
| auto& challenge_point = pub_input.challenge_point; | ||||
| auto& evaluation = pub_input.evaluation; | ||||
| auto& poly_degree = pub_input.poly_degree; | ||||
| auto& aux_generator = pub_input.aux_generator; | ||||
| auto& commitment = claim.commitment; | ||||
| auto& challenge_point = claim.opening_pair.query; | ||||
| auto& evaluation = claim.opening_pair.evaluation; | ||||
| const auto& log_poly_degree = static_cast<size_t>(proof.L_vec.size()); | ||||
| const auto& poly_degree = static_cast<size_t>(static_cast<uint64_t>(Fr(2).pow(log_poly_degree))); | ||||
|
|
||||
| const Fr aux_challenge = Fr::serialize_from_buffer(transcript->get_challenge("ipa_aux").begin()); | ||||
| auto srs_elements = vk->srs.get_monomial_points(); | ||||
| const auto aux_generator = srs_elements[poly_degree] * aux_challenge; | ||||
|
|
||||
| // Compute C_prime | ||||
| element C_prime = commitment + (aux_generator * evaluation); | ||||
|
|
||||
| // Compute the round challeneges and their inverses. | ||||
| const size_t log_poly_degree = static_cast<size_t>(numeric::get_msb(poly_degree)); | ||||
| std::vector<Fr> round_challenges(log_poly_degree); | ||||
| for (size_t i = 0; i < log_poly_degree; i++) { | ||||
| round_challenges[i] = pub_input.round_challenges[i]; | ||||
| auto label = std::to_string(i); | ||||
| round_challenges[i] = Fr::serialize_from_buffer(transcript->get_challenge("ipa_round_" + label).begin()); | ||||
| } | ||||
| std::vector<Fr> round_challenges_inv(log_poly_degree); | ||||
| for (size_t i = 0; i < log_poly_degree; i++) { | ||||
| round_challenges_inv[i] = pub_input.round_challenges[i]; | ||||
| round_challenges_inv[i] = round_challenges[i]; | ||||
| } | ||||
| Fr::batch_invert(&round_challenges_inv[0], log_poly_degree); | ||||
| std::vector<affine_element> L_vec(log_poly_degree); | ||||
|
|
@@ -236,14 +251,9 @@ template <typename Params> class InnerProductArgument { | |||
| } | ||||
| s_vec[i] = s_vec_scalar; | ||||
| } | ||||
| auto srs_elements = vk->srs.get_monomial_points(); | ||||
| // Copy the G_vector to local memory. | ||||
| std::vector<affine_element> G_vec_local(poly_degree); | ||||
| for (size_t i = 0; i < poly_degree; i++) { | ||||
| G_vec_local[i] = srs_elements[i]; | ||||
| } | ||||
|
|
||||
| auto G_zero = barretenberg::scalar_multiplication::pippenger_without_endomorphism_basis_points( | ||||
| &s_vec[0], &G_vec_local[0], poly_degree, vk->pippenger_runtime_state); | ||||
| &s_vec[0], &srs_elements[0], poly_degree, vk->pippenger_runtime_state); | ||||
| element right_hand_side = G_zero * a_zero; | ||||
| Fr a_zero_b_zero = a_zero * b_zero; | ||||
| right_hand_side += aux_generator * a_zero_b_zero; | ||||
|
|
||||
Uh oh!
There was an error while loading. Please reload this page.