Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The verifier hashes
public_inputsto derive the Fiat-Shamir challengex, but the check forpublic_eval, the inner product⟨[1, x, x², …], committed_poly⟩matching those inputs was missing. The prover sendspublic_evalas aprover_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:
public_evalwas not transcript-bound. Sent viaprover_hint_arkinstead ofprover_message, so it was never absorbed into Fiat-Shamir. A prover could swap it without affecting subsequent challenges.Off-by-one in public weight length.
make_public_weightandcompute_public_evalreceivedpublic_inputs.len()but the witness layout has an R1CS constant1at position 0 before the public inputs, so the weight vector was one element short.Fix
Changed
prover_hint_arktoprover_messageforpublic_evalin both prover and verifier so the value is absorbed into the Fiat-Shamir transcript.make_public_weight/compute_public_evalnow internally add+1to account for the R1CS constant at position 0. Parameter renamed tonum_public_inputsto 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_exploitthat proves honestly, then tamperspublic_inputsto a wrong value and asserts the verifier rejects.