Skip to content

fix: anchor Grumpkin SRS to pinned chunk hashes on load#23587

Open
suyash67 wants to merge 2 commits into
sb/ecc-finding-2from
sb/grumpkin-srs-integrity
Open

fix: anchor Grumpkin SRS to pinned chunk hashes on load#23587
suyash67 wants to merge 2 commits into
sb/ecc-finding-2from
sb/grumpkin-srs-integrity

Conversation

@suyash67

Copy link
Copy Markdown
Contributor

The Grumpkin IPA SRS is meant to be reproducible from a fixed seed, but nothing checked the bytes we actually load against it — the loader only did an on-curve check on the first point, and the WASM ingress did nothing. A tampered CDN download or ~/.bb-crs cache file could swap in points with known discrete logs and quietly break IPA binding.

This pins per-chunk SHA-256 hashes of the canonical SRS and verifies whatever prefix gets loaded: the native cache path, the WASM ingress from bb.js, and the generator/on-disk tests. Per-chunk rather than one whole-file digest because callers load prefixes — bb.js fetches 2^16 points, the native prover its dyadic ECCVM size, and only bootstrap pulls all 2^18.

Stacked on #22908: the generator-reproducibility test only passes with that branch's canonical from_compressed fix, so this targets it as the base.

suyash67 added 2 commits May 11, 2026 11:49
The Grumpkin IPA SRS is a transparent setup, but the loader never checked the
bytes it consumed against the deterministic generator output: the cache loader
did only points[0].on_curve(), and the MemGrumpkin ctor and WASM ingress did no
validation. An attacker controlling the CDN or the ~/.bb-crs cache could
substitute on-curve points with known discrete logs and break IPA binding.

Pin per-chunk SHA-256 hashes of the canonical 2^18-point SRS (4 chunks of 2^16
points) in grumpkin_crs_data.hpp and verify whatever prefix is loaded:
- get_grumpkin_g1_data reads up to the chunk boundary covering num_points and
  anchors those chunks; sub-chunk caches fall back to the on-curve check.
- SrsInitGrumpkinSrs (WASM ingress from bb.js) anchors whole chunks of the
  buffer, so the bb.js path is covered without duplicating hashes in TS.
- MemGrumpkinCrs ctor gains an on-curve smoke check, matching MemBn254Crs.

Per-chunk hashes are required because callers load prefixes: bb.js fetches 2^16,
the native prover its dyadic ECCVM size, only bootstrap fetches all 2^18.
@ludamad ludamad force-pushed the sb/ecc-finding-2 branch from 6c52bde to c57d6e6 Compare June 10, 2026 22:06
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