Skip to content

refactor(stm): combine pairing checks ivc verify - #3454

Open
damrobi wants to merge 6 commits into
mainfrom
damrobi/msnark/3420-combine-pairing-checks
Open

refactor(stm): combine pairing checks ivc verify#3454
damrobi wants to merge 6 commits into
mainfrom
damrobi/msnark/3420-combine-pairing-checks

Conversation

@damrobi

@damrobi damrobi commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Content

This PR includes an update to the verification function of the recursive proof to combine the two pairing checks (dual MSM and accumulator) into one to speed up the verification.

Changes

  • Convert the accumulator into an MSM
  • Select a random scalar r to combine as: combined_msm = dual_msm + r * acc_msm
  • Perform one pairing check instead of two
  • Keep one pairing check in case of failure to identify the source of the failure and return the correct error

Measured gain

  • with separated: 7.266ms
  • with combined: 6.682ms
  • Gain: ~8%

Pre-submit checklist

  • Branch
    • Tests are provided (if possible)
    • Crates versions are updated (if relevant)
    • CHANGELOG file is updated (if relevant)
    • Commit sequence broadly makes sense
    • Key commits have useful messages
  • PR
    • All check jobs of the CI have succeeded
    • Self-reviewed the diff
    • Useful pull request description
    • Reviewer requested
  • Documentation
    • No new TODOs introduced

Issue(s)

Closes #3420

@damrobi damrobi self-assigned this Aug 4, 2026
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

Test Results

     5 files  ± 0     209 suites  ±0   1h 20m 18s ⏱️ + 13m 52s
 3 340 tests + 4   3 340 ✅ + 4  0 💤 ±0  0 ❌ ±0 
11 116 runs  +10  11 116 ✅ +10  0 💤 ±0  0 ❌ ±0 

Results for commit b75f104. ± Comparison against base commit cfb446a.

♻️ This comment has been updated with latest results.

@damrobi
damrobi temporarily deployed to testing-preview August 4, 2026 08:48 — with GitHub Actions Inactive
@damrobi
damrobi temporarily deployed to testing-2-preview August 4, 2026 08:48 — with GitHub Actions Inactive
@damrobi
damrobi force-pushed the damrobi/msnark/3420-combine-pairing-checks branch from 2a4c47e to 5433b3a Compare August 4, 2026 14:25
@damrobi
damrobi temporarily deployed to testing-preview August 4, 2026 15:16 — with GitHub Actions Inactive
@damrobi
damrobi temporarily deployed to testing-2-preview August 4, 2026 15:16 — with GitHub Actions Inactive
@damrobi
damrobi temporarily deployed to testing-2-preview August 4, 2026 16:29 — with GitHub Actions Inactive
@damrobi
damrobi temporarily deployed to testing-preview August 4, 2026 16:29 — with GitHub Actions Inactive
Comment thread mithril-stm/src/proof_system/ivc_halo2_snark/errors.rs Outdated
@damrobi
damrobi force-pushed the damrobi/msnark/3420-combine-pairing-checks branch from cd079a5 to b75f104 Compare August 5, 2026 15:19
@damrobi
damrobi marked this pull request as ready for review August 5, 2026 15:33
@damrobi
damrobi requested review from jpraynaud and kitounliu August 5, 2026 15:34
@jpraynaud
jpraynaud requested a lite review from Copilot August 5, 2026 15:35

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors IvcProof::verify to batch the dual MSM (KZG opening) and folded accumulator pairing equations into a single combined pairing check, reducing verifier time by avoiding a second multi-Miller loop + final exponentiation.

Changes:

  • Convert the folded accumulator equation into a DualMSM, scale it by a transcript-derived challenge r, and add it to the proof’s dual_msm before running a single pairing check.
  • Replace the two distinct verification failure variants with a single IvcProofError::MsmPairingCheckFailed.
  • Update verification tests and add a test asserting the combined check holds for multiple candidate scalars.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
mithril-stm/src/proof_system/ivc_halo2_snark/proof.rs Implements the combined pairing check in verify and updates/adds tests accordingly.
mithril-stm/src/proof_system/ivc_halo2_snark/errors.rs Collapses prior error variants into MsmPairingCheckFailed for the new combined check path.
Suppressed comments (6)

mithril-stm/src/proof_system/ivc_halo2_snark/proof.rs:222

  • The PR description says to keep (or rerun) an individual pairing check on failure to identify whether the dual MSM or the accumulator caused the failure. The current implementation always returns MsmPairingCheckFailed without re-checking individual equations, so the error source is lost and the PR behavior no longer matches the stated intent/issue acceptance criteria.
        if !combined.check(verifier_setup.verifier_params()) {
            return Err(IvcProofError::MsmPairingCheckFailed.into());
        }

mithril-stm/src/proof_system/ivc_halo2_snark/proof.rs:751

  • This assertion message still claims the failure is specifically the “KZG opening check”, but the error is now MsmPairingCheckFailed from the combined pairing check. Update the message to match the new behavior.
            Some(&IvcProofError::MsmPairingCheckFailed),
            "different protocol message must fail the KZG opening check, got: {err}"

mithril-stm/src/proof_system/ivc_halo2_snark/proof.rs:778

  • This assertion message still refers to the “KZG opening check”, but the code now reports MsmPairingCheckFailed from the combined pairing check. Adjust the message to prevent confusion when the test fails.
            Some(&IvcProofError::MsmPairingCheckFailed),
            "mismatched state corrupts public inputs and must fail the KZG opening check, got: {err}"

mithril-stm/src/proof_system/ivc_halo2_snark/proof.rs:805

  • This assertion message still refers to the “KZG opening check”, but verification now reports MsmPairingCheckFailed from the combined pairing check. Update the message to match the new error semantics.
            Some(&IvcProofError::MsmPairingCheckFailed),
            "mismatched accumulator corrupts public inputs and must fail the KZG opening check, got: {err}"

mithril-stm/src/proof_system/ivc_halo2_snark/proof.rs:830

  • This assertion message still mentions the “KZG opening check”, but the code now fails via the combined pairing check and returns MsmPairingCheckFailed. Update the message to reflect the combined-check behavior.
            Some(&IvcProofError::MsmPairingCheckFailed),
            "Poseidon bytes via Blake2b path must fail the KZG opening check, got: {err}"

mithril-stm/src/proof_system/ivc_halo2_snark/proof.rs:874

  • This assertion message still claims the failure is specifically the “accumulator check (not the KZG check)”, but verification now returns a single MsmPairingCheckFailed for the combined check, so the distinction no longer exists. Update the message to avoid implying separate error paths.
            Some(&IvcProofError::MsmPairingCheckFailed),
            "wrong fixed bases must fail the accumulator check (not the KZG check), got: {err}"

/// `global` and `verifier_setup` must be built from the same certificate and IVC verifying
/// keys. If they differ, the public inputs fed to the KZG opening check will not match the
/// proof transcript and verification will return [`IvcProofError::KzgOpeningFailed`].
/// proof transcript and verification will return [`IvcProofError::MsmPairingCheckFailed`].
verifier_setup.combined_fixed_bases(),
) {
return Err(IvcProofError::AccumulatorFailed.into());
// `r` must depend both `dual_msm` and `self.accumulator` to make sure the combination can't be manipulated.
}
transcript.common(&accumulator_lhs)?;
transcript.common(&accumulator_rhs)?;
let r: CircuitBase = transcript.squeeze_challenge();
Comment on lines +15 to +17
/// Combined accumulator and dual MSM pairing equation did not verify.
#[error("IVC proof rejected: combined accumulator and dual MSM pairing check failed")]
MsmPairingCheckFailed,
Comment on lines +699 to 700
Some(&IvcProofError::MsmPairingCheckFailed),
"tampered bytes must fail the KZG opening check, got: {err}"
}

#[test]
fn ivc_proof_verify_combined_check_holds_for_any_scalar_r() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We probably need a test to make sure we don't use any value for r (the golden test we were talking about). This means that its computation will need to be extracted to a pub(crate) function so that it can be easily tested.

@damrobi
damrobi temporarily deployed to testing-preview August 5, 2026 16:10 — with GitHub Actions Inactive
@damrobi
damrobi temporarily deployed to testing-2-preview August 5, 2026 16:10 — with GitHub Actions Inactive
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.

Combine the dual MSM and accumulator pairing checks in IVC proof verification

3 participants