Skip to content

fix: public input binding verification#321

Open
ashpect wants to merge 3 commits intomainfrom
ash/hotfix
Open

fix: public input binding verification#321
ashpect wants to merge 3 commits intomainfrom
ash/hotfix

Conversation

@ashpect
Copy link
Collaborator

@ashpect ashpect commented Mar 12, 2026

Problem

The verifier hashes public_inputs to derive the Fiat-Shamir challenge x, but the check for public_eval, the inner product ⟨[1, x, x², …], committed_poly⟩ matching those inputs was missing. The prover sends public_eval as a prover_hint_ark (not absorbed into the transcript), so a malicious prover can commit to one set of values and claim another as public output. Verification passes because WHIR only checks the evaluation claims it receives, not where they came from.

Two bugs:

  1. public_eval was not transcript-bound. Sent via prover_hint_ark instead of prover_message, so it was never absorbed into Fiat-Shamir. A prover could swap it without affecting subsequent challenges.

  2. Off-by-one in public weight length. make_public_weight and compute_public_eval received public_inputs.len() but the witness layout has an R1CS constant 1 at position 0 before the public inputs, so the weight vector was one element short.

Fix

Changed prover_hint_ark to prover_message for public_eval in both prover and verifier so the value is absorbed into the Fiat-Shamir transcript.

make_public_weight / compute_public_eval now internally add +1 to account for the R1CS constant at position 0. Parameter renamed to num_public_inputs to clarify semantics.

Added verify_public_input_binding() in the verifier that recomputes the expected evaluation from known public inputs and rejects if it doesn't match the prover's claim.

Added test_public_input_binding_exploit that proves honestly, then tampers public_inputs to a wrong value and asserts the verifier rejects.

@ashpect ashpect changed the title fix: soundness issue in public input binding verification fix: public input binding verification Mar 12, 2026
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