# Plonky3 MultiField32Challenger: transcript malleability and challenge entropy loss

Plonky3 MultiField32Challenger's Fiat-Shamir sponge absorbs/squeezes non-injectively, letting a prover craft distinct transcripts yielding identical challenges and forge proofs.

- Payout: Research
- Severity: high
- Program: Plonky3
- Found by: jonathanpwang, zlangley
- Disclosed: 2026-05-21
- CVE: CVE-2026-46654
- Write-up quality: 8/10
- Original: https://github.com/advisories/GHSA-vj64-rjf3-w3v7
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-vj64-rjf3-w3v7
- Tags: area:web3 domain:web3 impact:integrity kind:research platform:ghsa sev:high tech:rust technique:source-review vuln:crypto

**Target:** Rust Fiat-Shamir challenger (p3-challenger) sponge over multi-field elements
**Root cause:** Absorb uses reduce_32 (base 2^32) with no length marker or zeroing of unused rate slots, while squeeze uses split_32 (base 2^64) with TF::from_u64 modular reduction; limb count PF::bits()/64 floor-divides, dropping high bits of digests.
**Steps:**
1. Absorb aliasing: observe `[x]` then sample; compare to observing `[x, 0, ..., 0]` padded to `num_f_elms` then sample — sponge states match because `reduce_32` folds `acc * 2^32 + digit` with no padding/tag.
2. Squeeze collision: pick two PF rate cells whose base-2^64 digits differ only in upper 33 bits; `split_32` + `TF::from_u64` mod F::ORDER collapses them to identical F challenge sequences.
3. Hash truncation: for BN254, `num_f_elms = PF::bits()/64 = 3` covers 192 bits; find two BN254 digests differing only in bits 192–253 and observe interchangeably.
4. Craft distinct prover transcripts producing identical challenges to break Fiat-Shamir binding.
**How found:** Code review of duplexing() spotted incompatible radices between absorb (reduce_32, base 2^32) and squeeze (split_32, base 2^64), absence of length domain separation, and floor division in limb count dropping high bits.
**Exploitation:** Attacker controlling prover-side observations extends/truncates observation batch tails, collides squeeze digits, or swaps high-bit-differing digests to produce identical challenges for distinct transcripts, enabling selective forgery of Fiat-Shamir proofs.
**Insight:** In Fiat-Shamir sponges, check that absorb and squeeze use the same radix, that unused rate slots are zeroed or length-tagged, and that limb count uses ceil not floor — mismatched radices and floor division silently create transcript collisions.

