Skip to content

Conversation

@jsemldonado
Copy link

coeff_form_uni_hyperkzg_verify was discarding the result of the pairing check and returning true unconditionally.

coeff_form_uni_kzg_verify(...);  // result discarded
true                              // always passed

This meant any proof would pass verification.

Fixed by returning the actual result. Added regression test that corrupts a proof and verifies it gets rejected.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @jsemldonado, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical bug in the HyperKZG polynomial commitment scheme's verification process, where the coeff_form_uni_hyperkzg_verify function was inadvertently ignoring the result of its core pairing check and always returning a successful verification. The fix ensures that the actual verification outcome is respected, restoring the cryptographic security of the system. Additionally, a robust regression test has been added to validate this fix and safeguard against similar issues in the future.

Highlights

  • Critical Bug Fix in HyperKZG Verification: The coeff_form_uni_hyperkzg_verify function was incorrectly returning true unconditionally, effectively bypassing the actual pairing check and allowing any proof to pass verification.
  • Corrected Verification Logic: The function now correctly returns the result of the pairing check, ensuring that only valid proofs are accepted.
  • Added Regression Test: A new test case has been introduced to explicitly verify that the HyperKZG system rejects intentionally corrupted proofs, preventing future regressions of this critical bug.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request addresses a critical vulnerability in coeff_form_uni_hyperkzg_verify where proof verification was being skipped entirely. The fix correctly propagates the result of the pairing check, ensuring proofs are actually verified. The inclusion of a regression test that confirms a corrupted proof is rejected is a great addition. My review includes a minor suggestion to improve the readability of the new test code by reducing repetition.

I am having trouble creating individual review comments. Click here to see my feedback.

poly_commit/src/kzg/uni_kzg/hyper_kzg.rs (255-257)

critical

This change fixes a critical bug where the result of the pairing check was discarded and true was always returned, effectively bypassing proof verification. Returning the result of coeff_form_uni_kzg_verify directly is the correct fix.

poly_commit/tests/test_uni_kzg.rs (108-145)

medium

To improve readability and reduce repetition, you could introduce a type alias for HyperUniKZGPCS<Bn256>. This would make the repeated calls to the PolynomialCommitmentScheme trait methods cleaner and easier to read.

    type PCS = HyperUniKZGPCS<Bn256>;
    let mut rng = test_rng();
    let num_vars = 4;

    let (srs, _) =
        <PCS as PolynomialCommitmentScheme<Fr>>::gen_srs_for_testing(
            &num_vars, &mut rng,
        );
    let (proving_key, verification_key) = srs.into_keys();

    let poly = MultiLinearPoly::<Fr>::random(num_vars, &mut rng);
    let x: Vec<Fr> = (0..num_vars).map(|_| Fr::random_unsafe(&mut rng)).collect();

    let mut scratch_pad = ();
    let commitment =
        <PCS as PolynomialCommitmentScheme<Fr>>::commit(
            &num_vars, &proving_key, &poly, &mut scratch_pad,
        );

    let mut transcript = BytesHashTranscript::<Keccak256hasher>::new();
    let (eval, opening) = <PCS as PolynomialCommitmentScheme<Fr>>::open(
        &num_vars, &proving_key, &poly, &x, &scratch_pad, &mut transcript,
    );

    // Valid proof should pass
    let mut transcript_v = BytesHashTranscript::<Keccak256hasher>::new();
    assert!(<PCS as PolynomialCommitmentScheme<Fr>>::verify(
        &num_vars, &verification_key, &commitment, &x, eval, &opening, &mut transcript_v,
    ));

    // Corrupted proof should fail
    let mut corrupted = opening.clone();
    corrupted.quotient_delta_x_commitment =
        (corrupted.quotient_delta_x_commitment.to_curve() * Fr::from(2u64)).to_affine();

    let mut transcript_c = BytesHashTranscript::<Keccak256hasher>::new();
    assert!(!<PCS as PolynomialCommitmentScheme<Fr>>::verify(
        &num_vars, &verification_key, &commitment, &x, eval, &corrupted, &mut transcript_c,
    ));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant