Skip to content

Conversation

@rodiazet
Copy link
Member

@rodiazet rodiazet commented Dec 2, 2025

  • Add implementation of multi-scalar multiplication for two EC points based on the Shamir trick.
  • Use it to optimize ecrecover and p256verify precompiles.
  • Handle new required cases in the EC point addition formulas.

Before:

(vvenv) rodia@MacBook-Pro-2 evmone % ./build/bin/evmone-precompiles-bench --benchmark_filter=ecrecover
Unable to determine clock rate from sysctl: hw.cpufrequency: No such file or directory
This does not affect benchmark measurements, only the metadata output.
***WARNING*** Failed to set thread affinity. Estimated CPU frequency may be incorrect.
2025-12-02T15:17:40+01:00
Running ./build/bin/evmone-precompiles-bench
Run on (12 X 24 MHz CPU s)
CPU Caches:
  L1 Data 64 KiB
  L1 Instruction 128 KiB
  L2 Unified 4096 KiB (x12)
Load Average: 3.97, 2.93, 2.75
----------------------------------------------------------------------------------------------------------
Benchmark                                                Time             CPU   Iterations UserCounters...
----------------------------------------------------------------------------------------------------------
precompile<PrecompileId::ecrecover, evmmax_cpp>     132861 ns       132855 ns         5260 gas_rate=22.581M/s gas_used=30k

After:

(vvenv) rodia@MacBook-Pro-2 evmone % ./build/bin/evmone-precompiles-bench --benchmark_filter=ecrecover
Unable to determine clock rate from sysctl: hw.cpufrequency: No such file or directory
This does not affect benchmark measurements, only the metadata output.
***WARNING*** Failed to set thread affinity. Estimated CPU frequency may be incorrect.
2025-12-03T11:10:28+01:00
Running ./build/bin/evmone-precompiles-bench
Run on (12 X 24 MHz CPU s)
CPU Caches:
  L1 Data 64 KiB
  L1 Instruction 128 KiB
  L2 Unified 4096 KiB (x12)
Load Average: 1.60, 2.24, 2.36
----------------------------------------------------------------------------------------------------------
Benchmark                                                Time             CPU   Iterations UserCounters...
----------------------------------------------------------------------------------------------------------
precompile<PrecompileId::ecrecover, evmmax_cpp>      81059 ns        81059 ns         8610 gas_rate=37.0102M/s gas_used=30k

@rodiazet rodiazet requested a review from chfast December 2, 2025 14:19
@codecov
Copy link

codecov bot commented Dec 2, 2025

Codecov Report

❌ Patch coverage is 86.95652% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.32%. Comparing base (c310365) to head (3fe2c85).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
lib/evmone_precompiles/ecc.hpp 85.71% 1 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1390      +/-   ##
==========================================
- Coverage   81.36%   81.32%   -0.04%     
==========================================
  Files         151      151              
  Lines       13360    13339      -21     
  Branches     3190     3191       +1     
==========================================
- Hits        10870    10848      -22     
  Misses        346      346              
- Partials     2144     2145       +1     
Flag Coverage Δ
eest-develop 90.18% <86.95%> (-0.10%) ⬇️
eest-develop-gmp 22.58% <0.00%> (+0.03%) ⬆️
eest-legacy 15.61% <0.00%> (+0.02%) ⬆️
eest-legacy-silkpre 24.68% <56.52%> (-0.13%) ⬇️
evmone-unittests 75.91% <86.95%> (-0.04%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
core 94.01% <86.95%> (-0.06%) ⬇️
tooling 83.43% <ø> (ø)
tests 73.12% <ø> (ø)
Files with missing lines Coverage Δ
lib/evmone_precompiles/secp256k1.cpp 100.00% <100.00%> (ø)
lib/evmone_precompiles/secp256r1.cpp 100.00% <100.00%> (ø)
test/unittests/precompiles_secp256r1_test.cpp 83.33% <ø> (ø)
lib/evmone_precompiles/ecc.hpp 94.40% <85.71%> (-1.00%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@chfast
Copy link
Member

chfast commented Dec 2, 2025

Before:

precompile<PrecompileId::ecrecover, evmmax_cpp>_mean       192513 ns       192418 ns           11 cycles=766.152k gas_rate=15.5912M/s gas_used=30k instructions=2.9161M

After:

precompile<PrecompileId::ecrecover, evmmax_cpp>_mean       156729 ns       156673 ns           11 cycles=623.843k gas_rate=19.1483M/s gas_used=30k instructions=2.6006M

rodiazet and others added 3 commits December 3, 2025 12:14
Support adding the same point for `add` jacobian and affine  overload.

Co-authored-by: Paweł Bylica <[email protected]>
@chfast
Copy link
Member

chfast commented Dec 3, 2025

Final benchmarks:

GCC15:

precompile<PrecompileId::ecrecover, evmmax_cpp>_mean                    -0.4032         -0.4032        355768        212305        355602        212219
precompile<PrecompileId::ecrecover, libsecp256k1>_mean                  -0.0030         -0.0029         33413         33315         33402         33304
precompile<PrecompileId::p256verify, evmone_cpp>_mean                   -0.4331         -0.4331        448775        254400        448662        254333

Clang 22:

precompile<PrecompileId::ecrecover, evmmax_cpp>_mean                   -0.3585         -0.3584        191613        122922        191531        122890
precompile<PrecompileId::p256verify, evmone_cpp>_mean                  -0.3908         -0.3908        199400        121472        199352        121447

@chfast chfast force-pushed the ecrecover-shamir-opt branch from 0c24f4f to 5198f9c Compare December 3, 2025 11:34
@chfast chfast changed the title Optimize ecrecover with shamir trick. Optimize ecrecover and p256verify with Shamir trick multi-scalar multiplication Dec 3, 2025
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR optimizes the ecrecover and p256verify precompiles by implementing multi-scalar multiplication using the "Straus-Shamir trick" (also known as Shamir's trick). The optimization replaces two separate scalar multiplications followed by a point addition with a single, more efficient combined operation. According to the benchmarks, this results in approximately 39% performance improvement for ecrecover (from 132,861 ns to 81,059 ns).

Key changes:

  • Added new msm function implementing Shamir's trick for computing u×P ⊕ v×Q
  • Modified the mixed point addition function to handle point doubling (when P == Q)
  • Simplified ecrecover and p256verify implementations to use the new msm function

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
lib/evmone_precompiles/ecc.hpp Added msm function for multi-scalar multiplication using Shamir's trick; updated mixed addition to handle doubling
lib/evmone_precompiles/secp256k1.cpp Replaced separate multiplications and addition with single msm call in secp256k1_ecdsa_recover
lib/evmone_precompiles/secp256r1.cpp Replaced separate multiplications and addition with single msm call in verify

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Member

@chfast chfast left a comment

Choose a reason for hiding this comment

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

Tests are failing

@chfast chfast enabled auto-merge (squash) December 3, 2025 14:20
@chfast chfast merged commit 29697e0 into master Dec 3, 2025
22 of 23 checks passed
@chfast chfast deleted the ecrecover-shamir-opt branch December 3, 2025 14:20
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.

3 participants