Skip to content

evmone v0.25.0 - #7

Merged
AskAlexSharov merged 1 commit into
mainfrom
alex/evmone_v0.25.0
Oct 20, 2026
Merged

AskAlexSharov merged 1 commit into
mainfrom
alex/evmone_v0.25.0

Conversation

@AskAlexSharov

Copy link
Copy Markdown
Contributor

Re-vendor evmone/ from upstream tag v0.25.0 (main carries v0.23.0); intx/ stays v0.15.0, which v0.25.0 still pins. test/evm-benchmarks is left out as before.

One wrapper change: 0.24 removed the evmmax namespace, so capi.cpp now takes AffinePoint, validate and add_affine from evmone::crypto. modexp_link.cpp and bn254_link.cpp need nothing.

What the bump brings to the two precompiles erigon takes from here: 0.24 folds the Montgomery multiplication carries into one addition in modexp (upstream: half the 256-bit modexp time with GCC on x86-64), 0.23 the windowed exponentiation, 0.22-0.24 BN254 pairing and line-evaluation work that ecadd shares via ecc.hpp.

Verified against erigon's precompile suite (execution/vm: TestPrecompiled*, the modexp fuzz against math/big) through a local replace. Numbers follow on the erigon PR that pins this.

Re-vendor evmone/ from upstream tag v0.25.0 (was v0.23.0); intx stays v0.15.0. capi.cpp: the evmmax
namespace is gone since 0.24, the bn254 helpers live in evmone::crypto.

@domiwei domiwei left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks good. evmone/ matches upstream v0.25.0 byte for byte, apart from test/evm-benchmarks, and intx/ is exactly v0.15.0. ModExp and EcAdd matched math/big and gnark-crypto in differential tests: 150k+ ModExp cases on arm64, x86-64 and the generic and ia32 carry paths, with UBSan, and 220k+ EcAdd inputs. Both ran with 0 mismatches. The code compiles cleanly with gcc 10–14, clang and mingw, and erigon's TestPrecompiled* passes against this head. I found no correctness defects. Below are some points on the description, plus small optional follow-ups.

1. The description overstates what the bump brings

  • "0.23 the windowed exponentiation" is already on main, because main carries v0.23.0 (evmone/CHANGELOG.md:214).
  • "0.22-0.24 BN254 pairing and line-evaluation work that ecadd shares via ecc.hpp": between v0.23.0 and v0.25.0, ecc.hpp, bn254.hpp and bn254.cpp change only the namespace and one include. pairing/ is not compiled by this module, since bn254_link.cpp includes only bn254.cpp. So EcAdd gets no behavior or speed change from this bump.
  • The description does not mention the change that does reach modexp: 0.24 reduces the exponent for the power-of-two part of the modulus (modexp.cpp:536-569). This is the new code path worth pointing reviewers of the erigon pin PR to.

2. EcAdd is about 2.5x slower without -DNDEBUG

  • 0.24 added assert(x < mod); assert(y < mod); to modadd/modsub (modarith.hpp:68-69,79-80). modinv_scaled calls them in its loop, so every non-trivial addition runs them.

  • The #cgo CXXFLAGS in bn254.go/modexp.go do not define NDEBUG.

  • Measured on Apple clang, arm64, EcAdd(G,G):

    Build ns/op
    main ~1240
    this PR ~3050–3300
    this PR, -DNDEBUG at parity with main
  • With gcc 14 there was no difference, and ModExp did not regress.

  • Erigon is not affected: its Makefile sets -DNDEBUG by default, and it calls only evmone.ModExp. Other consumers, or a plain go build/go test, pay the cost. Adding #cgo CXXFLAGS: -DNDEBUG would fix that; it is your call.

3. -I./evmone/include is now dead (bn254.go:10, modexp.go:10)
Its only user was <evmmax/evmmax.hpp>, which this PR deletes. ecc.hpp now includes "modarith.hpp". All three .cpp files and go build ./... work without it, so it can be removed.

4. CI does not run the new arithmetic
There are no _test.go files, so CI only compiles the new carry folding (modexp.cpp:357, mulmod.cpp:46) and the pow2 exponent reduction. This gap is older than this PR, but a small math/big differential test in the module would guard future bumps. A follow-up is fine.

5. Speedup claim not reproduced on arm64 (FYI)
The "half the 256-bit modexp time" claim did not show up on arm64 with clang or gcc 14. We had no real x86-64 hardware, so the GCC x86-64 claim is unverified, not disproved. The carry fold itself is arithmetically equivalent to the old two-step carry.

Simplification (optional, future)
Only 9 files from lib/evmone_precompiles plus intx.hpp are compiled. Vendoring only those files and the LICENSE files builds fine and would shrink each future bump from ~178 changed files to ~8.

@domiwei domiwei left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving. The points in my earlier comment are non-blocking: the description fix and the optional -DNDEBUG / dead -I cleanup can follow. Erigon builds with -DNDEBUG and calls only ModExp, so it is not affected by the EcAdd assert cost.

@AskAlexSharov
AskAlexSharov merged commit fc5972e into main Oct 20, 2026
4 checks passed
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