Skip to content

refactor(stark): uniform Coset trait, fallible LiftedDomain constructors#993

Draft
adr1anh wants to merge 2 commits intonextfrom
adr1anh/uniform-coset
Draft

refactor(stark): uniform Coset trait, fallible LiftedDomain constructors#993
adr1anh wants to merge 2 commits intonextfrom
adr1anh/uniform-coset

Conversation

@adr1anh
Copy link
Copy Markdown
Contributor

@adr1anh adr1anh commented May 5, 2026

Summary

Reshapes the lifted-STARK domain layer (miden-lifted-stark) into a small hierarchy with explicit fallibility, eliminating ambient panic risk in the verifier path.

Coset hierarchy (commit 1, 65b7ef9c7):

  • New domain.rs module with TwoAdicSubgroup<F>TwoAdicCoset<F>LiftedDomain<F>.
  • Coset trait owns the shared (log_size, shift, generator) interface and provides default bodies for points, bit_reversed_points, vanishing_at, contains, point_at, size, generator_inverse, shift_inverse (cached).
  • LiftedDomain deliberately does not implement Coset — it composes a trace subgroup and an LDE coset; callers say domain.trace_subgroup() or domain.lde_coset() to disambiguate vanishing polynomials.
  • Drops dead/redundant LiftedDomain accessors that silently picked the LDE side.
  • Selector logic moved from the math types into LiftedDomain where the lift ratio lives.

Fallible constructors + statically-validated batch domains (commit 2, 29f2584a9):

  • LiftedDomain::canonical, sub_domain, evaluation_coset, selectors now return Result<_, DomainError>. Holding a LiftedDomain<F> is the validation evidence.
  • InstanceShapes::validate (renamed from validate_inputs) returns the validated max log trace height; LDE-bound checks moved to LiftedDomain::canonical.
  • LiftedDomain::sub_domains(impl IntoIterator<Item = u8>) collapses the per-instance sub-domain construction to one accessor.
  • commit_traces takes &[LiftedDomain<F>] instead of re-deriving sub-domain shifts internally.
  • Verifier path is panic-free against adversarial proof shapes; DomainError flows into both VerifierError and ProverError via #[from].

Test plan

  • cargo test -p miden-lifted-stark (92 tests pass)
  • cargo check -p miden-lifted-stark --benches --features testing
  • make doc
  • make lint (clippy + fmt + taplo + typos all clean; cargo shear step skipped — tool not installed locally)

🤖 Generated with Claude Code

adr1anh and others added 2 commits May 1, 2026 17:06
Adds a `Coset<F>` trait with required `(log_size, shift, generator)` plus
defaults for `size`, `point_at`, `points`, `bit_reversed_points`,
`vanishing_at`, `contains`, `generator_inverse`, and a cached
`shift_inverse` (`F::ONE` for subgroup; stored field on coset). Both
`TwoAdicSubgroup` and `TwoAdicCoset` impl the trait; `LiftedDomain` does
not — composing a trace subgroup and an LDE coset, it disambiguates via
explicit `trace_subgroup()` / `lde_coset()` accessors rather than
silently picking one vanishing polynomial.

Drops dead/redundant `LiftedDomain` methods (`points`,
`bit_reversed_points`, `point_at`, `lde_subgroup`, `is_in_*`,
`is_lifted`, `blowup`, `max_lde_height`, `log_max_lde_height`,
`log_lift_ratio` getter, `lifted_trace_vanishing_at`); call sites now
go through `domain.lde_coset()`. Selector logic (`selectors`,
`selectors_at`) moves from the coset/subgroup types into `LiftedDomain`
where the lift-ratio context lives. `log_blowup` returns `u8` to match
its sibling `log_*` accessors.

Also renames `*coset` bindings/params/fields holding `LiftedDomain` to
`*domain` for consistency, and threads `Committed::max_domain` /
`FriTranscript<&TwoAdicSubgroup>` to keep the type-driven height
metadata flowing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…domains

`LiftedDomain::canonical`, `sub_domain`, `evaluation_coset`, and
`selectors` now return `Result<_, DomainError>`. Construction success is
the validation evidence: holding a `LiftedDomain<F>` means its
parameters are bounds-checked. Verifier and prover entry points
propagate errors via `?`; downstream sites that derive from validated
inputs use `.expect()` with strings documenting the upstream check.

Added `LiftedDomain::sub_domains(impl IntoIterator<Item = u8>)` for the
common "build per-instance sub-domains from a list of heights" pattern,
collapsing a 5-line `iter().map().collect::<Result<_, _>>()` chain to
one accessor.

`commit_traces` now takes `&[LiftedDomain<F>]` instead of a separate
`max_domain` and re-deriving sub-domain shifts internally — the prover
already builds the per-instance domains, so threading them through
removes a fragile `sub_domain(h).expect().lde_shift()` chain and the
`assert_eq!(traces.last().height(), max_domain.trace_height())` check
(now per-trace, stronger).

Renamed `instance::validate_inputs` to the method
`InstanceShapes::validate`, returning the validated max log trace
height. AIR/instance-contract checks live there; LDE-bound checks moved
to `LiftedDomain::canonical`. Added `LogTraceHeightTooLarge` variant to
`InstanceValidationError` to keep `validate` panic-free against
adversarial `1usize << log_h` overflow.

`DomainError` is wired into both `VerifierError` and `ProverError` via
`#[from]`. New tests: `canonical_too_large_returns_error`,
`sub_domain_too_large_returns_error`,
`evaluation_coset_too_large_returns_error`, and
`malformed_log_trace_heights_is_rejected` updated to distinguish the
two failure paths.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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