Skip to content

evmmax: Add inversion method#1142

Merged
chfast merged 1 commit into
masterfrom
evmmax-inv
Mar 12, 2025
Merged

evmmax: Add inversion method#1142
chfast merged 1 commit into
masterfrom
evmmax-inv

Conversation

@chfast

@chfast chfast commented Feb 25, 2025

Copy link
Copy Markdown
Member

Add method for computing modular inversion using extended binary Euclidean algorithm. This algorithm, even in a simple form, is significantly faster (~5x) than computing the inversion as pow(x, p-2, p) by using a dedicated addchain of MULs.

@codecov

codecov Bot commented Feb 25, 2025

Copy link
Copy Markdown

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 94.57%. Comparing base (b166b68) to head (dca1f96).
Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1142      +/-   ##
==========================================
+ Coverage   94.56%   94.57%   +0.01%     
==========================================
  Files         168      168              
  Lines       18283    18320      +37     
==========================================
+ Hits        17290    17327      +37     
  Misses        993      993              
Flag Coverage Δ
eof_execution_spec_tests 20.50% <0.00%> (-0.05%) ⬇️
ethereum_tests 28.18% <0.00%> (-0.06%) ⬇️
ethereum_tests_silkpre 20.96% <0.00%> (-0.05%) ⬇️
execution_spec_tests 20.88% <0.00%> (-0.05%) ⬇️
unittests 89.91% <100.00%> (+0.02%) ⬆️

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

Files with missing lines Coverage Δ
include/evmmax/evmmax.hpp 100.00% <100.00%> (ø)
test/unittests/evmmax_test.cpp 96.10% <100.00%> (+0.79%) ⬆️
🚀 New features to boost your workflow:
  • Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@chfast chfast self-assigned this Feb 26, 2025
@chfast chfast added the EVMMAX label Feb 26, 2025
@chfast chfast requested a review from pdobacz March 10, 2025 16:31

@pdobacz pdobacz 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.

I didn't dig into the details of the algo yet, if you want me to, lmk.

Comment thread include/evmmax/evmmax.hpp Outdated
@chfast

chfast commented Mar 11, 2025

Copy link
Copy Markdown
Member Author

I didn't dig into the details of the algo yet, if you want me to, lmk.

Checking the linked paper would be more than welcome as we plan to apply more optimizations from it. But this is not urgent.

@pdobacz pdobacz 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.

still one topic to maybe discuss, but otherwise still LGTM

Comment thread include/evmmax/evmmax.hpp
// Bézout's coefficients are originally initialized to 1 and 0. But because the input x
// is in Montgomery form XR the algorithm would compute X⁻¹R⁻¹. To get the expected X⁻¹R,
// we need to multiply the result by R². Do this by initializing u to R².
UintT u = m_r_squared;

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.

out of curiosity - not easier to correct for this at the end? Any external source to cite that this variation is equivalent?

There are a lot of modification to the linked classical algorithm, could do away with at least one. The others are kinda easier to warp head around.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

We borrowed the idea from zksync implementation of some precompiles. Maybe it would be equivalent to do this in the end, but that would be additional multiplication (here this is free). But I will try :)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

"Fixing" v after works, but it requires 2 multiplications by R² (because of the performed reduction):

        v = mul(v, m_r_squared);
        v = mul(v, m_r_squared);
        return v;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Or in other words: v = mul(v, to_mont(m_r_squared));.

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.

I'm OK with keeping as is, if we have a solid reference to cite and confidence all the edge cases are also correctly handled (and later tested).

Add method for computing modular inversion using extended binary
Euclidean algorithm. This algorithm, even in a simple form, is
significantly faster (~5x) than computing the inversion as
pow(x, p-2, p) by using a dedicated addchain of MULs.
@chfast chfast enabled auto-merge (squash) March 12, 2025 18:41
@chfast chfast merged commit 683d896 into master Mar 12, 2025
@chfast chfast deleted the evmmax-inv branch March 12, 2025 19:02
gumb0 pushed a commit that referenced this pull request Mar 20, 2025
Add method for computing modular inversion using extended binary
Euclidean algorithm. This algorithm, even in a simple form, is
significantly faster (~5x) than computing the inversion as pow(x, p-2,
p) by using a dedicated addchain of MULs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants