Skip to content

Conversation

@ashpect
Copy link
Collaborator

@ashpect ashpect commented Oct 13, 2025

Support for public_witness opening

@ashpect ashpect force-pushed the ash/witness_split branch 3 times, most recently from a35db76 to 67cae81 Compare November 5, 2025 05:47
@ashpect ashpect changed the base branch from main to sl/witness-split November 6, 2025 08:47
@ashpect ashpect changed the base branch from sl/witness-split to main November 9, 2025 22:07
@ashpect ashpect changed the base branch from main to sl/witness-split November 11, 2025 01:17
@ashpect ashpect marked this pull request as ready for review November 11, 2025 01:17
@ashpect ashpect force-pushed the ash/witness_split branch 3 times, most recently from 69ba9b3 to 857db9b Compare December 12, 2025 07:59
@shreyas-londhe shreyas-londhe force-pushed the sl/witness-split branch 2 times, most recently from da0ce79 to 52b6528 Compare December 23, 2025 08:45
Base automatically changed from sl/witness-split to main December 24, 2025 07:15
@ashpect ashpect requested a review from Copilot January 1, 2026 17:36
Copy link

Copilot AI left a comment

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 adds support for public witness opening in the WHIR R1CS proof system. The implementation introduces a new PublicInputs struct to handle public values, updates both the prover and verifier to compute and verify public input hashes, and modifies the witness scheduling to ensure public inputs are correctly ordered in the witness commitment.

Key Changes:

  • Introduced PublicInputs struct with SHA-256 hashing for commitment
  • Modified prover and verifier to handle public weights and verify public input consistency
  • Updated witness scheduling to place public inputs in w1 (pre-challenge) layer with proper ordering

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 22 comments.

Show a summary per file
File Description
provekit/common/src/witness/mod.rs Adds PublicInputs struct with hashing and serialization support
provekit/common/src/utils/serde_ark_vec.rs New module for serializing vectors of field elements
provekit/common/src/utils/mod.rs Exports new serde_ark_vec module
provekit/common/src/utils/sumcheck.rs Adds add_public_inputs() method to IO pattern for public input hash and randomness
provekit/common/src/whir_r1cs.rs Updates constraint counts and IO pattern to include public weights verification
provekit/common/src/noir_proof_scheme.rs Adds public_inputs field to NoirProof struct
provekit/common/src/lib.rs Exports PublicInputs type
provekit/common/Cargo.toml Adds sha2 dependency for hashing
provekit/common/src/witness/witness_builder.rs Passes public input indices to witness splitting logic
provekit/common/src/witness/scheduling/splitter.rs Ensures public inputs are placed in w1 and properly ordered after constant builder
provekit/r1cs-compiler/src/noir_proof_scheme.rs Extracts ACIR public input indices for witness splitting
provekit/prover/src/lib.rs Extracts public inputs from witness and passes to proof generation
provekit/prover/src/whir_r1cs.rs Implements public weights computation and statement updates for both single and batch commitment cases
provekit/verifier/src/lib.rs Passes public inputs to verification
provekit/verifier/src/whir_r1cs.rs Verifies public input hash and updates statements with public weights constraints

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}

// hashPublicInputs computes the hash of public inputs as field elements sequentially
func hashPublicInputs(sc *skyscraper.Skyscraper, publicInputs PublicInputs) (frontend.Variable, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

The following must produce identical results:

  • Rust: PublicInputs::hash() using SkyscraperCRH::evaluate()
  • Go: hashPublicInputs() using sc.CompressV2()

Add a cross-language test with known test vectors.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ref in : #257

let num_witnesses = 2;
let num_ood_constraints = num_witnesses * self.whir_witness.committment_ood_samples;
let num_statement_constraints = 6; // 2 statements × 3 constraints
let num_statement_constraints = 7;
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is hardcoded and assumes:

  • Batch mode: 3 constraints for statement1 + 1 public weights + 3 for statement2 = 7
  • But what if public inputs are empty in batch mode?
    The Go verifier calculates this dynamically:
if !cfg.PublicInputs.IsEmpty() {
    witnessLinearStatementEvalsSize = 7
} else {
    witnessLinearStatementEvalsSize = 6
}

.test_witness_satisfaction(&witness.iter().map(|w| w.unwrap()).collect::<Vec<_>>())
.context("While verifying R1CS instance")?;

// Gather public inputs from witness
Copy link
Collaborator

Choose a reason for hiding this comment

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

No validation that the public inputs extracted from witness match what the circuit expects. If acir_public_inputs indices are wrong, proof will be valid but verify wrong values.

whir_public_weights_query_answer: (FieldElement, FieldElement),
) {
let (public_f_sum, public_g_sum) = whir_public_weights_query_answer;
let public_weight = Weights::linear(EvaluationsList::new(vec![FieldElement::zero(); 1 << m]));
Copy link
Collaborator

Choose a reason for hiding this comment

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

The verifier creates dummy zero-weight vectors. This is correct because the verifier doesn't know the actual weights (only the prover does), but:

  1. This should be commented explaining why zeros are OK
  2. Verify that the WHIR protocol handles this correctly (the actual weighted sum comes from the hint)

.hint()
.context("failed to read WHIR public weights query answer")?;

if !public_inputs.is_empty() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

When public inputs are empty, the hint whir_public_weights_query_answer is still read from the transcript but never validated. A malicious prover could put garbage here and it would be ignored.

merlin.hint::<(Vec<FieldElement>, Vec<FieldElement>)>(&(f_sums, g_sums))?;

// VERIFY the size given by self.m
let public_weight = get_public_weights(public_inputs, &mut merlin, self.m);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Duplicate Logic Between Single/Batch Paths. Same pattern in the verifier, the public input hash verification and statement extension logic is copy-pasted between the two branches.

@Bisht13
Copy link
Collaborator

Bisht13 commented Jan 21, 2026

Please add unit tests for testing all cases of public inputs.

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.

3 participants