Skip to content

refactor: genericize the WHIR-R1CS scheme builder + add provekit-fixtures#459

Open
BornPsych wants to merge 2 commits into
worldfnd:sl/goldilocks-field-abstractionfrom
BornPsych:ys/generic-scheme-builder-and-fixtures
Open

refactor: genericize the WHIR-R1CS scheme builder + add provekit-fixtures#459
BornPsych wants to merge 2 commits into
worldfnd:sl/goldilocks-field-abstractionfrom
BornPsych:ys/generic-scheme-builder-and-fixtures

Conversation

@BornPsych

@BornPsych BornPsych commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

Moves WHIR-R1CS scheme construction into the field-generic spine. The scheme parameters (witness commitment domain size, sumcheck rounds, blinding room, zkWHIR config) are now derived generically over the proof field in provekit-common, instead of living in r1cs-compiler welded to bn254's FieldElement. The only genuinely bn254-specific constructor — building a scheme from a Mavros artifact — stays in r1cs-compiler as a thin adapter. bn254 parameter selection is unchanged.

Also adds a new provekit-fixtures crate: a field-generic prove→verify harness plus soundness, roundtrip, and proving-time benchmark tests that exercise the spine on synthetic R1CS instances, independently of any frontend.

This builds on the field-generic spine (<P: ProofField>, #458). Since that work is not yet on main, this PR's commit list includes it; the changes specific to this PR are the final two commits.

Why

#458 made the proof types generic over the field, but scheme construction still lived in r1cs-compiler and took R1CS<FieldElement> / returned a bn254 WhirZkConfig. A Goldilocks backend has to build a scheme without depending on the Noir/mavros compiler (the goldilocks build excludes r1cs-compiler entirely). So the field-generic half of the builder has to move down into the spine, next to the WhirR1CSScheme<P> type it constructs, leaving only the field-specific Mavros adapter behind.

The fixtures crate exists because the generic spine needs coverage that does not route through the bn254 Noir frontend — building R1CS instances with the R1CS API alone lets the same prove→verify path run over any FieldHash proof field once a second backend lands.

What changed

  • provekit-common: WhirR1CSScheme<P> gains field-generic constructors new_for_r1cs / new_from_dimensions / new_whir_zk_config_for_size, derived purely from R1CS dimensions and the committed/extension fields of P. The MIN_WHIR_NUM_VARIABLES / MIN_SUMCHECK_NUM_VARIABLES floors move here too. For bn254 (Identity<Fr>, base == ext) the parameters monomorphize to exactly what shipped before.
  • provekit-r1cs-compiler: trimmed to a bn254-only MavrosSchemeBuilder adapter. Mavros artifacts are bn254-specific, so this can't move to the spine; it just forwards the instance's dimensions into the generic new_from_dimensions. Call sites spell the field explicitly (WhirR1CSScheme::<Bn254Field>::…).
  • provekit-prover: comment cleanup only — the base→ext witness lift is a no-op under any Identity embedding (bn254 and pre-v3 goldilocks), not a bn254-specific fact.
  • provekit-fixtures (new): field-generic R1CS builders + a prove→verify harness, pinned to Sha256 so a roundtrip needs no field-specific hash-engine setup. Tests cover R1CS satisfaction, public-input binding (N=1 and N=2), instance binding, scale boundaries, and a small seed fuzz, plus #[ignore]d proving-time benches.

Scope

The fixtures are functional only — they assert that honest proofs verify and that malformed witnesses / public inputs are rejected. They deliberately do not assert bn254 byte-identity; that equivalence is owned by the field-generic spine's regression gate, and the exact m / m_0 / security-level parameter regression stays in the r1cs-compiler builder tests.

Verification

  • cargo build / cargo test green over common, r1cs-compiler, prover, and fixtures.
  • provekit-fixtures: 6 roundtrip + 4 soundness pass; 2 benches ignored.
  • Scaled dual-commit benchmark path runs end-to-end without panic.

Commits

  • refactor: genericize the WHIR-R1CS scheme builder in the spine
  • test: add provekit-fixtures field-generic prove/verify harness

@vercel

vercel Bot commented Jun 23, 2026

Copy link
Copy Markdown

@BornPsych is attempting to deploy a commit to the World Foundation Team on Vercel.

A member of the Team first needs to authorize it.

@BornPsych BornPsych changed the base branch from main to sl/goldilocks-field-abstraction June 24, 2026 04:43

@shreyas-londhe shreyas-londhe left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the PR @BornPsych. Clean continuation of the field-generic work. The scheme-builder move keeps bn254 parameter selection identical, splitting the generic constructors from the Mavros adapter is the right line to draw, and the fixtures finally give the spine real frontend-independent coverage with negative tests that actually reject. Left two minor nits inline; neither blocks.

full_witness.len(), // w1_size: the whole witness, no challenge phase
0,
Vec::new(),
true,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

derive has_public_inputs instead of hardcoding true. prove always passes true, so a no-public-input instance routed through it would make the prover emit a public eval the verifier never reads (transcript desync, spurious failure). No current caller hits this — sized_r1cs (N=0) goes through time_dual_commit_prove, which sets false — but since prove is the crate's public harness entry, deriving it removes the footgun:

has_public_inputs: !public_inputs.is_empty(),

use {super::*, provekit_backend_bn254::FieldElement, provekit_common::R1CS};

/// Matches the witness-domain floor used by the scheme builder.
const MIN_WHIR_NUM_VARIABLES: usize = 13;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

duplicated floor constant. The test redeclares const MIN_WHIR_NUM_VARIABLES = 13 because the real one is now private in common (whir_r1cs.rs:22). It can silently drift from the source of truth. Either make the common const pub(crate)/pub and import it, or drop a paired comment on both so a change to one updates the other.

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.

2 participants