refactor(akita-field): Land Solinas field from akita-field in Jolt's jolt-field - #307
refactor(akita-field): Land Solinas field from akita-field in Jolt's jolt-field#307Acentelles wants to merge 11 commits into
akita-field in Jolt's jolt-field#307Conversation
Introduce the akita-error crate owning the protocol error type (AkitaError) ahead of the akita-field removal, with a conversion from jolt_field::FieldError at the repository boundary. Move the field serialization implementations into akita-serialization/src/field_impls.rs, implementing the existing wire traits for the shared jolt-field Solinas types. Wire bytes are unchanged and pinned by stability fixtures. Additive only: the pre-cutover akita-field crate remains in place and building until the workspace cutover lands.
Replace every akita_field import with direct jolt_field imports across source, tests, examples, and benchmarks, and replace every akita-field manifest edge with the pinned shared jolt-field package (solinas feature; parallel only through Akita's existing parallel features). Protocol errors now come from akita-error. Also delete the duplicate field arithmetic benchmark, which imports akita_field and cannot outlive this commit; its successor lives in jolt-field as benches/solinas_field_arith. Mechanical rewrite only; no semantic changes. akita-field itself is removed in the next commit.
The shared jolt-field package now owns the Solinas field stack; nothing in the workspace depends on akita-field. Remove the crate and its workspace membership.
Replace the jolt-compat CI job with a shared-field identity check requiring exactly one jolt-field package identity and no akita-field in the integrated graph. Update the crate graph, verifier contract, book chapters, README, and specs for the jolt-field cutover.
Record the opened Jolt PR A, the bootstrap-edge retention and freeze steps, the jolt_akita::AkitaField transparent-alias policy, and the revised PR C scope. Re-open the adapter-deletion checklist item, which completes only when PR C lands.
|
We need to wait for a16z/jolt#1684 to be merged first |
|
The architectural direction looks right: I am requesting changes because the current branch is an intermediate migration snapshot rather than a mergeable Akita change. This review is against Akita head Required before this can merge1. Land and freeze the Jolt field source firstThis PR currently pins: That is appropriate for stacked review, but not as Akita’s landed production dependency. Please:
If the Jolt PR changes after this review, please identify the arithmetic/trait delta from 2. Rebase onto current Akita
|
Rebind every crate from the pre-consolidation 46-trait jolt-field surface
(rev 09b2f7b6) to the rebuilt 15-trait spine, and bump all 18 manifest pins
to rev 46e2ce8f7525364c69b5534d2d3918bdcf0684d3 (feat/jolt-field-replacement,
pushed to Acentelles/jolt as feat/solinas-field-stack).
Mapping applied (old -> new):
- FieldCore -> Field; RingCore -> Ring; FromPrimitiveInt/Invertible/
RandomSampling/HalvingField absorbed into Ring/Field (same method names).
- CanonicalField -> Field + CanonicalEncoding: modulus_bits() ->
MODULUS_BITS, from_canonical_u128_{checked,reduced} ->
from_u128_{checked,reduced}; generic to_canonical_u128() ->
to_u128_checked().expect(...) (65 call sites); concrete Fp128 call sites
keep the inherent to_canonical_u128.
- CanonicalBytes/ReducingBytes/FixedByteSize/CanonicalU64/
CanonicalBitLength/TranscriptChallenge -> CanonicalBytes +
CanonicalEncoding (transcript byte behavior unchanged).
- PseudoMersenneField -> PseudoMersenne (MODULUS_OFFSET -> OFFSET,
MODULUS_BITS now on CanonicalEncoding).
- LiftBase/MulBase/FrobeniusExtField -> ExtField (EXT_DEGREE -> DEGREE);
FpExt2Config -> Ext2Config; FpExt4MulBackend/FpExt8MulBackend -> the
PseudoMersenne ext hooks.
- HasUnreducedOps + HasWide -> Unreduced (MulU64Accum -> SmallProduct,
ProductAccum -> Product, mul_to_product_accum -> mul_unreduced,
reduce_product_accum -> reduce_product, reduce_mul_u64_accum ->
reduce_small_product, mul_small_to_wide -> scale_wide,
DELAYED_PRODUCT_SUM_IS_EXACT -> SUM_IS_EXACT); ReduceTo dropped in favor
of Unreduced::reduce_wide; HasOptimizedFold -> Fold (FoldCtx -> Ctx,
precompute_fold -> precompute).
- packed::PackedField/HasPacking -> Packed/WithPacking (root re-exports);
jolt_field::parallel -> jolt_field::solinas::parallel;
jolt_field::unreduced::*/packed::* -> crate root.
Ported akita-side (deleted from jolt-field with no replacement):
- akita-algebra gains `fft` (mixed-radix smooth-domain FFT, RS-extend) and
the SmoothFftField trait with the Prime128Offset2355/Prime128OffsetA7F7
SMOOTH_OMEGA literals, taken verbatim from the pre-rebuild jolt-field and
rebound to the new spine; akita-pcs re-exports it (`akita_pcs::fft`).
- CyclotomicRing: RandomSampling impl became an inherent `random`; the Ring
impl now embeds integers into the constant coefficient (new Ring
requirement).
- WideCyclotomicRing::reduce now takes F: Unreduced<Wide = W>.
- akita-pcs no longer re-exports the jolt-field `packed`/`unreduced`
modules or BalancedDigitLookup (module paths gone; the digit LUT is the
free fn jolt_field::balanced_digit_lut; nothing consumed them).
- The LossyField delayed-product-sum test fixture implements the fused
Ring/Field/Unreduced traits (including the previously absent Wide shape).
Validation (rustc 1.95.0, gates that are green at the base commit):
- cargo check --workspace --all-targets --no-default-features
--features parallel: clean.
- cargo clippy --all --all-targets --no-default-features
--features parallel -- -D warnings: clean.
- cargo fmt --all --check: clean.
- scripts/check-rust-file-lines.sh --no-baseline: pass.
- cargo nextest run --lib --bins --tests --cargo-profile ci-test
--no-default-features --features parallel:
local-path override: 1038 tests run: 1038 passed (15 slow), 14 skipped
real git pin: 1038 tests run: 1038 passed (14 slow), 14 skipped
- fuzz workspace and profile/akita-recursion glue+artifact cargo check:
clean (guest/host not built; they need the RISC-V jolt toolchain).
Pre-existing breakage NOT introduced here (identical at base 57276e9):
the `disk-persistence` feature fails to compile (missing AkitaDeserialize
bound in akita-setup::load_prover_setup) and the plain
--no-default-features config fails in akita-prover ring_switch/finalize.rs
(E0282 type inference in the non-parallel arm). Both fail at the same
points before and after this change.
46e2ce8f7 -> 505d8ebcb (a merge of jolt main that does not touch crates/jolt-field; content-identical field crate, pin now matches the PR head exactly). Workspace check green against the new rev.
Merges 25 upstream commits (e7aa598..e5351ad: chunk-major witnesses, bounded per-matrix ring-dimension search, per-group opening points, compressed-commitment kernels, fold-path cutover, mixed-D multi-group openings, typed fold schedules, akita-schedules runtime resolution, Stage 1/2 sum-check unification, exact large-digit NTT infrastructure, Quantum128BitADPS16 SIS cutover, and more) into the jolt-field cutover branch. Resolution policy: for files where our side's changes were purely the jolt-field rebind renames, the upstream version was taken and the rebind mapping (35c9f6d) was re-applied mechanically: akita_field -> jolt_field paths, FieldCore/RingCore/FromPrimitiveInt/Invertible/ RandomSampling/HalvingField -> Field/Ring, CanonicalField -> Field + CanonicalEncoding (modulus_bits() -> MODULUS_BITS, generic to_canonical_u128() -> to_u128_checked().expect(...)), PseudoMersenneField -> PseudoMersenne (MODULUS_OFFSET -> OFFSET), HasUnreducedOps/HasWide -> Unreduced (MulU64Accum -> SmallProduct, ProductAccum -> Product, method renames), ReduceTo -> Unreduced::reduce_wide, HasOptimizedFold -> Fold, LiftBase/MulBase/ FrobeniusExtField -> ExtField (EXT_DEGREE -> DEGREE), AkitaError -> the akita-error crate, akita_field::parallel -> jolt_field::solinas::parallel. Files upstream deleted or moved (the planner generated tables, the akita_stage1/akita_stage2 sumcheck modules, the direct/quotient proof paths, the setup_contribution split) follow upstream's structure with the moved content rebound. Upstream deltas reconciled against the deleted akita-field crate: - AkitaError::UnsupportedSchedule (new upstream variant) is ported to akita-error. - cfg_try_fold_reduce! (new upstream macro in akita_field::parallel) is ported to akita-algebra, since the pinned jolt-field does not provide it; the two akita-types consumers import it from there. - akita-verifier gains an optional rayon dependency under its parallel feature because jolt-field's cfg_join! expands to a bare rayon::join (upstream solved this inside akita-field with a __rayon_join re-export); machete-ignored with a comment. - Upstream's packed fp64 kernel/test renames (reduce128_small_k -> reduce128_sub_word etc.) are cosmetic-only and the code now lives in jolt-field; nothing to port. - akita-schedules' generated fp*.rs tables are no longer checked in upstream; they are bootstrapped via scripts/generate-schedule-tables.sh (gitignored) and were regenerated here after the rebind. Manifest edits: upstream's new akita-field dependency edges in akita-config, akita-planner, and akita-schedules are rebound to the shared jolt-field pin (rev 505d8ebc) plus akita-error; the resurrected field_arith bench section is dropped (the bench moved to jolt-field); the recursion guest gains the akita-error path dep its AkitaError import now needs; AGENTS.md drops the stale `cargo clippy -p akita-field --features jolt-compat` line; book/src/foundations/spec-index.md keeps `jolt-field-unification` in the live-spec list; docs/crate-graph.md planner/schedules bullets say jolt-field. Validation (rustc 1.95.0): - cargo fmt --all --check: clean. - cargo clippy --all --all-targets --no-default-features --features parallel -- -D warnings: clean. - cargo nextest run --cargo-profile ci-test --no-default-features --features parallel: Summary [ 184.916s] 1072 tests run: 1072 passed (5 slow), 19 skipped (baseline before the merge: 1038 passed, 14 skipped; upstream added the difference). - scripts/check-shared-field-identity.sh: pass. - scripts/check-rust-file-lines.sh --no-baseline: pass (512 files). - profile/akita-recursion glue+artifact+host cargo check: clean (the guest still needs the RISC-V jolt toolchain, unchanged); fuzz not re-checked. The two configs pre-broken at both bases (--features parallel,disk-persistence; bare --no-default-features) remain skipped.
The previous cargo tree text parse broke under CARGO_TERM_COLOR=always (the workflow's actual environment): the colorized (*) dedup marker survived the sed strip, so one package identity counted as two. Package IDs from cargo metadata are rendering-independent; the worst-case color environment is now forced inside the script as a regression guard. Matches the same fix in Jolt's copy of the check.
|
Saving the merge conflicts, I've addressed your comments @quangvdao |
Merges LayerZero-Labs/akita main at 0f49d0a (heterogeneous commitment groups, chunk-major witnesses, public-claim binding, flattened public matrix with exact NTT caches, compressed prefix payloads, x86 CRT/NTT kernels, planner schedule-entry restore) into the jolt-field cutover. Resolution policy: upstream semantics with post-cutover names (jolt_field traits, akita_error::AkitaError). akita-field stays deleted; its one upstream change in this range, exact-uniform canonical rejection sampling (03f2908), is ported to the shared jolt-field as Acentelles/jolt@eb93a031, and every manifest and lockfile pin moves to that revision (the previous pin 505d8ebc is no longer fetchable after the PR A rebuild). Workspace check, clippy -D warnings, the full test suite, and the shared-field identity gate all pass.
Summary
This PR integrates
akita-fieldcrate into the Jolt'sjolt-fieldcrate. It updates every Akita crate, test, example, benchmark, fuzz target, and profiling workspace accordingly.The purpose is to reduce the field arithmetic audit surface. Field arithmetic moves to
jolt-field, while Akita continues to own its protocol errors, validation policy, and optimized serialization format.Changes
akita_fieldimports and manifest dependencies with directjolt_fieldimports.jolt-field/solinasfor Akita consumers and propagatejolt-field/parallelonly through Akita's existingparallelfeatures.akita-errorcrate and moveAkitaErrorinto it. Convertjolt_field::FieldErrortoAkitaErrorat the protocol boundary.akita-serialization/src/field_impls.rs.crates/akita-field, its compatibility facade, and Akita's duplicate field arithmetic benchmark.akita-field/jolt-compatadapter test job.Testing
cargo test.cargo test -p akita-serialization.cargo clippy --all --message-format=short -q -- -D warningspasses.cargo fmt --all --checkpasses../scripts/check-doc-guardrails.shpasses../scripts/check-shared-field-identity.shreports exactly onejolt-fieldidentity and noakita-fieldpackage.git diff --checkpasses.The completed test suite includes Akita's unit, integration, end-to-end, and documentation tests. Serialization coverage checks fixed prime-field bytes, extension coefficient order, validated decoding, reported size, and round-trip behavior.
Security Considerations
This PR changes the ownership and dependency path of security-sensitive field arithmetic used by the Akita prover and verifier. It does not intentionally change the arithmetic: field moduli, canonical representations, extension bases, reductions, FFT parameters, and packed kernels come from the same implementation moved into
jolt-fieldby a16z/jolt#1684.Akita's optimized field serialization remains Akita-owned.
The new
akita-errorcrate preserves the existing protocol error variants.The package identity CI guard prevents both field implementations from re-entering the dependency graph. This PR does not intentionally change proof soundness, verifier acceptance rules, private-input handling, proof bytes, or the Akita transcript schedule.
Breaking Changes
akita-fieldpackage and itsjolt-compatfeature.akita_field::*tojolt_field::*.akita_field::AkitaErrortoakita_error::AkitaError.jolt-fieldpackage and enable the required Solinas feature.