Skip to content

feat(jolt-poly): endianness-generic eq builders over PointLike - #2393

Draft
quangvdao wants to merge 2 commits into
mainfrom
quang/ej1-generic-eq
Draft

quangvdao wants to merge 2 commits into
mainfrom
quang/ej1-generic-eq

Conversation

@quangvdao

Copy link
Copy Markdown
Collaborator

Makes the equality-table builders in jolt-poly generic over the coordinate order of the point, so callers holding little-endian or big-endian points (Akita's sum-check stages, Jolt's own) can borrow them without copying or reversing. The builders also relax their bound from JoltField to Field. This is item E-J1 of the eq/sum-check consolidation in LayerZero-Labs/akita#120. Existing slice, array and Vec callers keep their high-to-low meaning and their arithmetic; no caller changes.

Draft: built on today's main, before the field switch (#2379). It will be rebased once that lands.

Changes

  • jolt-poly/src/point.rs: PointLike (with a borrowed range view PointRef), implemented for owned points, slices, vectors, arrays and references. Views borrow the original storage.
  • jolt-poly/src/eq/{mod,build,cached,scalar}.rs: the old module split by role. Builders and suffix queries take PointLike; new prefix_sum and a domain-checked eq_index. eq_index_msb keeps its existing low-bit aliasing contract. Coordinate selection happens once per layer, outside the inner loops, and the parallel kernel has no point-type generic.
  • jolt-poly/src/split_eq/{tensor,gruen}.rs: split tensor and Gruen files, each with from_point. Gruen's remaining bound and recovery changes are E-J3.
  • jolt-utils/src/alloc.rs and jolt-algebra: widening the builders to any Field would otherwise zero-initialize field types for which all-zero bytes are not a valid value. A ZeroBytesValid marker now gates the zero-allocation fast path; Fr, the Solinas fields and the binary fields carry it with a justification, and unmarked fields initialize safely. Allocation overflow and failure are distinct errors; the existing function keeps its signature and its panic/abort behavior.
  • Benchmarks keep their names and add both coordinate orders and cached/tensor cases over Fr, the 128-bit Solinas field and a quartic extension. Local runs on a shared Mac showed no regression; no speedup is claimed.
  • Tests: layout identities across both orders, significance ranges, borrowed storage, generic field callers, and a field containing a NonZeroU8 (all-zero bytes invalid).

Validation

  • cargo clippy -p jolt-poly --all-targets -- -D warnings, also with binary,allocative; cargo test -p jolt-poly (137 unit, 11 integration), also with --no-default-features; cargo test -p jolt-utils
  • cargo clippy --all --all-targets --features host -- -D warnings and --features host,zk
  • scripts/check_style_invariants.py; cargo tree shows no Rayon under jolt-algebra --no-default-features

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

📏 PR diff

Note

Actual code changed: 2,756 lines

🟢 +1,486 added    🔴 −1,270 removed

Tests, docs, fixtures, and helper scripts excluded.

Category 🟢 Added 🔴 Removed
⌨️ Actual code +1,486 −1,270
🧪 Tests +1,184 −661
📚 Docs +96 −78
📦 Fixtures +34 0
🔧 Helper scripts 0 0
Total diff +2,800 −2,009

Every changed line is classified once.

@github-actions

github-actions Bot commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

Benchmark comparison (crates)

Same-runner A/B: base_run = e21affa (merge target) vs pr_run = a10fe62 (PR head merged onto it). Bold = faster run; Δ colored when the difference exceeds the ±10% noise threshold.

17 of 96 benchmarks differ by more than ±10%:

Benchmark base_run (merge target) pr_run (this PR) Δ
field arithmetic/square/fp128_6a23801f 11.1±0.55µs 14.5±0.59µs ${\color{red}\mathbf{+30.3\%}}$
field arithmetic/square/fp128_a7f7 11.7±0.42µs 13.8±0.55µs ${\color{red}\mathbf{+18.4\%}}$
EqPolynomial::evaluations/20 26.7±1.57ms 31.4±1.35ms ${\color{red}\mathbf{+17.4\%}}$
Polynomial::evaluate/20 36.6±1.78ms 42.2±0.91ms ${\color{red}\mathbf{+15.4\%}}$
g1_msm/1024 8.4±0.10ms 9.5±0.16ms ${\color{red}\mathbf{+13.3\%}}$
Polynomial::bind_low_to_high_in_place/Prime128OffsetA7F7/20 1.9±0.08ms 2.1±0.13ms ${\color{red}\mathbf{+13.0\%}}$
F128/accumulator/deferred 959.0±12.80ns 1.1±0.04µs ${\color{red}\mathbf{+12.8\%}}$
EqPolynomial::evaluations/18 4.5±0.12ms 5.1±0.29ms ${\color{red}\mathbf{+12.6\%}}$
g1_msm/64 1.0±0.02ms 1.2±0.02ms ${\color{red}\mathbf{+12.3\%}}$
g1_msm/256 2.8±0.11ms 3.2±0.06ms ${\color{red}\mathbf{+12.0\%}}$
F128/accumulator/naive 2.2±0.09µs 2.5±0.06µs ${\color{red}\mathbf{+11.8\%}}$
EqPolynomial::evals/22 52.5±1.98ms 58.5±1.89ms ${\color{red}\mathbf{+11.3\%}}$
Polynomial::bind/20 5.4±0.17ms 6.0±0.12ms ${\color{red}\mathbf{+11.1\%}}$
multi_pairing/8 2.4±0.09ms 2.6±0.07ms ${\color{red}\mathbf{+10.9\%}}$
Polynomial::bind_low_to_high_in_place/Fr/20 6.0±0.31ms 6.6±0.21ms ${\color{red}\mathbf{+10.3\%}}$
append_bytes/Poseidon/32B 48.5±2.07µs 43.5±0.46µs ${\color{green}\mathbf{-10.2\%}}$
pedersen_commit/1024 8.6±0.15ms 9.5±0.18ms ${\color{red}\mathbf{+10.1\%}}$
All 96 benchmarks
Benchmark base_run (merge target) pr_run (this PR) Δ
EqPolynomial::evals/17 1.4±0.08ms 1.5±0.03ms +7.4%
EqPolynomial::evals/19 5.3±0.20ms 5.7±0.09ms +8.5%
EqPolynomial::evals/20 13.4±0.38ms 14.6±0.44ms +9.1%
EqPolynomial::evals/22 52.5±1.98ms 58.5±1.89ms ${\color{red}\mathbf{+11.3\%}}$
EqPolynomial::evaluations/14 372.7±15.54µs 401.9±10.87µs +7.9%
EqPolynomial::evaluations/18 4.5±0.12ms 5.1±0.29ms ${\color{red}\mathbf{+12.6\%}}$
EqPolynomial::evaluations/20 26.7±1.57ms 31.4±1.35ms ${\color{red}\mathbf{+17.4\%}}$
F128/accumulator/deferred 959.0±12.80ns 1.1±0.04µs ${\color{red}\mathbf{+12.8\%}}$
F128/accumulator/naive 2.2±0.09µs 2.5±0.06µs ${\color{red}\mathbf{+11.8\%}}$
F128/mul 1.8±0.09ns 1.8±0.07ns +1.1%
F128/mul_slice 1.8±0.10µs 1.9±0.08µs +2.3%
F128/square 2.4±0.15ns 2.5±0.07ns +2.9%
F192/accumulator/deferred 2.2±0.07µs 2.3±0.08µs +5.7%
F192/accumulator/naive 3.4±0.15µs 3.7±0.15µs +8.2%
F192/mul 3.0±0.08ns 3.0±0.09ns +0.1%
F192/mul_slice 3.1±0.15µs 3.2±0.16µs +1.5%
F192/square 2.3±0.07ns 2.2±0.01ns -1.6%
F64/accumulator/deferred 545.3±7.08ns 579.5±24.54ns +6.3%
F64/accumulator/naive 776.9±13.41ns 837.7±28.41ns +7.8%
F64/mul 0.8±0.04ns 0.8±0.04ns +3.2%
F64/mul_slice 794.6±33.02ns 854.0±11.89ns +7.5%
F64/square 0.8±0.04ns 0.8±0.02ns +3.6%
Polynomial::bind/14 106.3±14.73µs 109.5±5.72µs +3.1%
Polynomial::bind/18 1.5±0.03ms 1.5±0.05ms +4.3%
Polynomial::bind/20 5.4±0.17ms 6.0±0.12ms ${\color{red}\mathbf{+11.1\%}}$
Polynomial::bind_low_to_high_in_place/Fr/14 162.9±4.43µs 170.1±6.25µs +4.4%
Polynomial::bind_low_to_high_in_place/Fr/20 6.0±0.31ms 6.6±0.21ms ${\color{red}\mathbf{+10.3\%}}$
Polynomial::bind_low_to_high_in_place/Fr/24 93.3±3.66ms 98.9±4.18ms +6.0%
Polynomial::bind_low_to_high_in_place/Prime128OffsetA7F7/14 52.9±0.50µs 55.6±3.18µs +5.3%
Polynomial::bind_low_to_high_in_place/Prime128OffsetA7F7/20 1.9±0.08ms 2.1±0.13ms ${\color{red}\mathbf{+13.0\%}}$
Polynomial::bind_low_to_high_in_place/Prime128OffsetA7F7/24 34.2±1.68ms 34.9±1.39ms +2.2%
Polynomial::evaluate/20 36.6±1.78ms 42.2±0.91ms ${\color{red}\mathbf{+15.4\%}}$
UnivariatePoly::from_evals/16 35.8±1.12µs 35.4±0.78µs -1.1%
UnivariatePoly::from_evals/3 4.6±0.18µs 4.7±0.18µs +3.7%
UnivariatePoly::from_evals/4 6.7±0.33µs 6.6±0.32µs -1.4%
UnivariatePoly::from_evals/8 16.7±0.70µs 16.1±0.40µs -3.8%
append_bytes/Blake2b/256B 311.0±18.70ns 288.1±6.93ns -7.4%
append_bytes/Blake2b/32B 61.6±3.77ns 66.6±7.79ns +8.0%
append_bytes/Keccak/256B 594.9±15.85ns 578.1±17.00ns -2.8%
append_bytes/Keccak/32B 58.4±4.94ns 54.3±4.43ns -7.0%
append_bytes/Poseidon/256B 148.6±7.14µs 145.1±5.93µs -2.3%
append_bytes/Poseidon/32B 48.5±2.07µs 43.5±0.46µs ${\color{green}\mathbf{-10.2\%}}$
challenge/Blake2b 663.4±23.38ns 651.5±31.76ns -1.8%
challenge/Keccak 410.6±17.85ns 404.7±16.12ns -1.5%
field arithmetic/add/fp128_6a23801f 3.6±0.08µs 3.8±0.15µs +7.2%
field arithmetic/add/fp128_a7f7 3.7±0.16µs 3.7±0.11µs +0.2%
field arithmetic/add/fp32_c99 1.8±0.12µs 1.7±0.01µs -5.6%
field arithmetic/add/fp64_c59 1.7±0.05µs 1.8±0.07µs +5.2%
field arithmetic/mul/fp128_6a23801f 10.7±0.13µs 11.6±0.47µs +8.5%
field arithmetic/mul/fp128_a7f7 9.7±0.45µs 9.9±0.31µs +2.2%
field arithmetic/mul/fp32_c99 3.5±0.16µs 3.5±0.12µs -0.2%
field arithmetic/mul/fp64_c59 4.5±0.16µs 4.5±0.07µs -0.4%
field arithmetic/square/fp128_6a23801f 11.1±0.55µs 14.5±0.59µs ${\color{red}\mathbf{+30.3\%}}$
field arithmetic/square/fp128_a7f7 11.7±0.42µs 13.8±0.55µs ${\color{red}\mathbf{+18.4\%}}$
field arithmetic/square/fp32_c99 3.2±0.14µs 3.2±0.13µs +1.6%
field arithmetic/square/fp64_c59 4.0±0.15µs 4.0±0.09µs +0.7%
field arithmetic/sub/fp128_6a23801f 3.0±0.13µs 3.1±0.11µs +3.6%
field arithmetic/sub/fp128_a7f7 3.0±0.12µs 3.2±0.14µs +9.0%
field arithmetic/sub/fp32_c99 1.2±0.06µs 1.2±0.06µs -0.3%
field arithmetic/sub/fp64_c59 1.5±0.06µs 1.5±0.04µs +1.6%
field reduction/reduce_product/fp128_a7f7 16.3±0.84µs 16.3±0.58µs -0.5%
fp64_prime63_offset259/ext2_packed_mul 16.7±0.58ns 17.8±0.63ns +6.6%
fp64_prime63_offset259/ext2_scalar_mul 3.9±0.11ns 4.0±0.11ns +2.8%
fp64_prime63_offset259/packed_mul 6.0±0.04ns 6.4±0.26ns +6.3%
fp64_prime63_offset259/scalar_mul 1.3±0.02ns 1.4±0.04ns +8.7%
fp64_prime64_offset59/ext2_dependent_mul_1024 7.7±0.36µs 7.7±0.25µs -0.8%
fp64_prime64_offset59/ext2_neg_one_scalar_mul 4.5±0.13ns 4.6±0.18ns +2.6%
fp64_prime64_offset59/ext2_packed_mul 20.9±0.35ns 21.4±0.87ns +2.3%
fp64_prime64_offset59/ext2_scalar_mul 4.9±0.19ns 5.0±0.26ns +1.2%
fp64_prime64_offset59/ext2_scalar_square 3.9±0.17ns 3.9±0.20ns +1.2%
g1_add 262.6±11.22ns 266.1±6.83ns +1.3%
g1_deserialize_bincode 5.8±0.13µs 6.2±0.15µs +7.6%
g1_double 130.6±3.82ns 140.3±4.86ns +7.4%
g1_msm/1024 8.4±0.10ms 9.5±0.16ms ${\color{red}\mathbf{+13.3\%}}$
g1_msm/16 360.8±3.18µs 382.6±14.43µs +6.0%
g1_msm/256 2.8±0.11ms 3.2±0.06ms ${\color{red}\mathbf{+12.0\%}}$
g1_msm/4 162.7±5.12µs 172.2±5.48µs +5.8%
g1_msm/64 1.0±0.02ms 1.2±0.02ms ${\color{red}\mathbf{+12.3\%}}$
g1_scalar_mul 42.6±2.20µs 42.0±1.03µs -1.4%
g1_serialize_bincode 90.1±3.40ns 97.4±2.34ns +8.1%
g2_msm/16 1.4±0.04ms 1.4±0.05ms -1.7%
g2_msm/256 11.3±0.55ms 11.0±0.31ms -2.4%
g2_msm/4 553.6±23.28µs 570.9±22.76µs +3.1%
g2_msm/64 4.0±0.14ms 3.9±0.04ms -2.0%
g2_scalar_mul 218.3±8.53µs 231.0±6.95µs +5.8%
gt_scalar_mul 436.2±26.05µs 463.7±15.97µs +6.3%
multi_pairing/16 4.3±0.23ms 4.6±0.11ms +5.6%
multi_pairing/2 921.0±23.54µs 995.3±27.74µs +8.1%
multi_pairing/4 1.4±0.04ms 1.4±0.08ms +5.1%
multi_pairing/8 2.4±0.09ms 2.6±0.07ms ${\color{red}\mathbf{+10.9\%}}$
pairing 685.3±10.59µs 691.2±16.88µs +0.9%
pedersen_commit/1024 8.6±0.15ms 9.5±0.18ms ${\color{red}\mathbf{+10.1\%}}$
pedersen_commit/16 427.5±23.38µs 452.4±17.62µs +5.8%
pedersen_commit/256 2.9±0.05ms 3.2±0.04ms +9.6%
pedersen_commit/4 206.5±7.03µs 214.1±7.43µs +3.7%
pedersen_commit/64 1.1±0.03ms 1.2±0.06ms +3.5%

54 benchmark(s) present in only one run: eq_orders/FpExt4/be/12, eq_orders/FpExt4/be/14, eq_orders/FpExt4/be/16, eq_orders/FpExt4/be/17, eq_orders/FpExt4/be/20, eq_orders/FpExt4/be/22, eq_orders/FpExt4/cached_lsb/10, eq_orders/FpExt4/cached_lsb/14, eq_orders/FpExt4/cached_msb/10, eq_orders/FpExt4/cached_msb/14, …

This branch has not been deployed

No deployments
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