Skip to content

Fix : Unbound LogUp Transcript Challenges Let the Prover Choose Lookup Randomness [LA-G]#359

Draft
ocdbytes wants to merge 1 commit intomainfrom
aj/main/fix-unbound-logup-challanges
Draft

Fix : Unbound LogUp Transcript Challenges Let the Prover Choose Lookup Randomness [LA-G]#359
ocdbytes wants to merge 1 commit intomainfrom
aj/main/fix-unbound-logup-challanges

Conversation

@ocdbytes
Copy link
Collaborator

Summary

  • Fix a soundness vulnerability where the verifier samples Fiat-Shamir challenges for LogUp
    lookups but never verifies that the committed w2 polynomial contains them. A malicious prover
    could substitute arbitrary challenge values in w2 without detection, breaking the LogUp
    argument's soundness.
  • Add challenge binding that mirrors the existing public input binding pattern: prover sends
    challenge_eval as a transcript-bound prover_message, verifier independently recomputes
    from sampled challenges and checks equality, and a SparseCovector weight is included in the
    WHIR verification for w2.

Changes

Core fix (prover + verifier transcript consistency):

  • provekit/prover/src/whir_r1cs.rs — Compute challenge_eval = Σ xⁱ · w2[offset_i] and
    send as prover_message (transcript-bound). Add SparseCovector challenge weight to w2's
    WHIR prove call.
  • provekit/verifier/src/whir_r1cs.rs — Retain sampled challenges (was discarded via let _logup_challenges). Read challenge_eval from transcript, verify against independently
    computed expectation via verify_challenge_binding(). Add matching challenge weight to w2's
    WHIR verify call.

Supporting infrastructure:

  • provekit/common/src/prefix_covector.rs — Add SparseCovector (implements LinearForm
    for non-contiguous positions), make_challenge_weight(), and compute_challenge_eval().
    Includes 6 unit tests.
  • provekit/common/src/whir_r1cs.rs — Add challenge_offsets: Vec<usize> field to
    WhirR1CSScheme so the verifier knows where challenges sit in w2.
  • provekit/common/src/witness/witness_builder.rssplit_and_prepare_layers now
    returns Vec<usize> challenge offsets (was usize count) extracted from remapped Challenge
    builders.
  • provekit/r1cs-compiler/src/whir_r1cs.rs — All WhirR1CSSchemeBuilder constructors
    accept challenge_offsets. Added debug_assert_eq! enforcing num_challenges == challenge_offsets.len().
  • provekit/r1cs-compiler/src/noir_proof_scheme.rs — Noir path destructures offsets from
    split_and_prepare_layers; Mavros path generates (0..challenges_size).collect().

Why SparseCovector?

Noir circuits can produce non-contiguous challenge offsets in w2 (the layer scheduler may interleave non-challenge builders between challenge builders). Neither PrefixCovector contiguous prefix) nor OffsetCovector (contiguous block) can represent scattered positions. Mavros always has contiguous offsets but SparseCovector handles both cases uniformly.

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