Skip to content

Conversation

@quangvdao
Copy link
Contributor

@quangvdao quangvdao commented Jan 18, 2026

Summary

This PR adds GLV (Gallant-Lambert-Vanstone) scalar decomposition for Grumpkin and a modular, trait-based MSM implementation.

⚠️ Disclaimer

This code has only been lightly audited and may contain bugs. While a security review was conducted covering the critical cryptographic invariants (GLV decomposition correctness, endomorphism properties, Pippenger algorithm), the implementation has not undergone a formal third-party audit. Use with caution in production systems.

Dependencies

⚠️ Depends on #1209 (Grumpkin division inlines)

This PR builds on top of the base Grumpkin field division inlines. Please merge #1209 first.

What's New

GLV Scalar Decomposition (jolt-inlines/grumpkin/)

  • Endomorphism: GrumpkinPoint::endomorphism() — maps (x, y) → (βx, y) where β³ = 1
  • Decomposition: GrumpkinPoint::decompose_scalar(k) — splits 256-bit scalar into two ~128-bit half-scalars (k₁, k₂) where k ≡ k₁ + k₂·λ (mod n)
  • Soundness: Guest-side verifies decomposition via recomposition check; calls hcf() to spoil proof on mismatch
  • Inline instruction: New GRUMPKIN_GLVR_ADV virtual instruction for non-deterministic decomposition advice

Generic MSM Crate (examples/msm/)

  • Trait-based design: MsmGroup, WindowedScalar, GlvCapable traits for curve-agnostic MSM
  • Pippenger bucket MSM: Variable and fixed window sizes, MSB-to-LSB processing
  • GLV-accelerated MSM: Expands scalars via decomposition, then runs Pippenger on 2× half-scalar pairs
  • Fixed-base precomputation: FixedBaseTable for generator multiplication (lookups + additions only)

Security Hardening

  • Tests for cryptographic invariants: β³ = 1, λ² + λ + 1 = 0, φ³ = Id, φ(P) = [λ]P
  • GLV lattice determinant verification: n₁₁·n₂₂ − n₁₂·n₂₁ = n
  • Edge case tests for decomposition: k = 0, 1, n-1, λ, λ±1, λ²
  • Window size bounds validation (≤ 16 bits)
  • Host-side bounds check for half-scalars (≤ 128 bits)

Benchmarks (MSM_SIZE = 1024)

Method RV64IMAC Virtual Total
Pippenger (256-bit, no GLV) ~453M
GLV + Pippenger (w=8) 48.5M 55.2M 103.7M
Fixed-base table (w=14) 24.5M 26.7M 51.2M

Key results:

  • GLV+Pippenger is ~4.4× faster than naive Pippenger
  • Fixed-base is ~2× faster than GLV+Pippenger (for generator-only MSM)

Files Changed

  • jolt-inlines/grumpkin/src/sdk.rs — GLV constants, endomorphism, decompose_scalar
  • jolt-inlines/grumpkin/src/lib.rs — GLV inline opcode registration
  • jolt-inlines/grumpkin/src/sequence_builder.rs — GLV advice implementation
  • jolt-inlines/grumpkin/src/host.rs — Inline registration
  • jolt-inlines/grumpkin/src/tests.rs — Security invariant tests
  • examples/msm/ — New generic MSM crate with Grumpkin integration

mathmasterzach and others added 10 commits January 16, 2026 17:11
…ndow sweep

- Add GLV inline constants and decompose_scalar for Grumpkin
- Split PIPPENGER_WINDOW into BASELINE_WINDOW and GLV_WINDOW
- Add window sweep benchmarks: GLV_WINDOW=10 is ~2x faster than 12
- Add GLV_PROGRESS.md tracking benchmarks and findings
Window sweep results: w=8 gives 105M cycles vs 261M at w=12 (2.5x speedup)
…LV+Pippenger

- Use heap allocation (Box) for large precompute tables
- Increase guest memory to 128MB, stack to 64MB
- Document precompute sizes and full sweep results
- Add examples/msm/ with modular Pippenger, GLV, and fixed-base MSM
- Define MsmGroup, WindowedScalar, GlvCapable traits
- Implement Grumpkin curve integration in curves/grumpkin.rs
- GLV+Pippenger is ~1.2% faster than old impl (103.8M vs 105.1M cycles)
- Fixed-base has ~2% overhead due to trait indirection (acceptable)
- Update GLV_PROGRESS.md with benchmark comparison
Replaced by generic examples/msm/ with trait-based abstractions.
- Add edge case tests for GLV decomposition (k=0, k=n-1, k=λ, etc.)
- Add GLV lattice determinant verification test
- Add timing documentation for variable-time MSM operations
- Untrack GLV_PROGRESS.md (local development notes)
Adds missing assertion that half-scalar bytes.len() <= 16, matching
the check in sdk.rs. Prevents potential out-of-bounds panic during
trace generation if GLV decomposition somehow produces oversized values.
quangvdao added a commit to quangvdao/jolt that referenced this pull request Jan 23, 2026
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.

2 participants