Conversation
|
/claude-review |
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
|
@claude what does this PR change? |
|
/claude-review |
|
Claude finished @Bisht13's task in 41s —— View job What this PR changesThis PR fixes a soundness vulnerability in the WHIR-based R1CS proof system where a malicious prover could substitute arbitrary public outputs without detection. Bug 1:
|
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
|
/claude-review |
1 similar comment
|
/claude-review |
|
Code Review - Summary: This PR fixes two genuine soundness vulnerabilities in the public-input binding protocol. (1) public_eval was not Fiat-Shamir bound - sent via prover_hint_ark, letting a malicious prover commit to one polynomial and claim a different evaluation without detection. (2) Off-by-one in public weight - make_public_weight and compute_public_eval received public_inputs.len() but the R1CS witness layout places a constant 1 at position 0, so the weight vector was one element short. Review - Correctness and Soundness: The fix is correct. prover_hint_ark to prover_message for public_eval and public_1 in both prover and verifier now absorbs these values into the Fiat-Shamir sponge. n = num_public_inputs + 1 in make_public_weight and compute_public_eval correctly covers poly[0] through poly[num_public_inputs]. verify_public_input_binding recomputes the expected evaluation from known public inputs and rejects mismatches. Both single-commitment and two-commitment paths are fixed symmetrically. Test coverage note: test_public_input_binding_exploit covers the primary attack by tampering proof.public_inputs. The transcript-binding half of the fix is not directly tested - a test forging narg_string with a swapped public_eval would close that gap. Non-blocking. Code Quality: verify_public_input_binding is private, has a doc comment, uses ensure! with anyhow::Result, no unwrap in library code. Parameter rename public_inputs_len to num_public_inputs clarifies semantics. The evals vectors staying as prover_hint_ark are correct. Minor: error message omits actual vs expected values. Suggestions (non-blocking): (1) Add actual vs expected to the binding error message. (2) Add a test forging the raw transcript to directly test the Fiat-Shamir binding change. Verdict: Approve - Clean, well-scoped fix for real soundness vulnerabilities. Math is correct, both code paths addressed, regression test included, CLAUDE.md conventions respected. |
|
/claude-review |
Code ReviewSummaryThis PR fixes two soundness bugs in the public input binding verification. First, ReviewCorrectness & Soundness The fixes are sound and correctly implemented.
Code Quality
Testing
Suggestions
Verdict✅ Approve — both bugs are real, the fixes are correct and consistent across prover and verifier, and a meaningful exploit regression test is included. |
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.