Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add EIP-5843: EVM Modular Arithmetic Extensions #5843

Closed
wants to merge 78 commits into from

Conversation

jwasinger
Copy link
Contributor

No description provided.

@github-actions github-actions bot added c-new Creates a brand new proposal s-draft This EIP is a Draft labels Oct 27, 2022
@eth-bot
Copy link
Collaborator

eth-bot commented Oct 27, 2022

Hi! I'm a bot, and I wanted to automerge your PR, but couldn't because of the following issue(s):


(fail) eip-5843.md

classification
newEIPFile

@jwasinger jwasinger changed the title EVMMAX Add EIP-5843: EVM Modular Arithmetic Extensions Oct 27, 2022
EIPS/eip-5843.md Outdated Show resolved Hide resolved
EIPS/eip-5843.md Outdated

### `SETMODX`

`SETMODX` takes two stack inputs: `(top of stack) mod_offset, mod_limb_count` where `mod_offset` refers to an EVM memory offset where a modulus represented in `mod_limb_count * 8` bytes with little-endian ordering is expected. If `(mod_offset + mod_limb_count * 8) - 1` falls outside the bounds of allocated memory, consume all call gas and return to the caller in an exceptional state. Charge `gas_setmodx(mod_limb_count)` return to the caller in an exceptional state if there was insufficient gas remaining:
Copy link
Contributor

Choose a reason for hiding this comment

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

It is unclear what a limb is here.
Usually on 32-bit platforms it's a 32-bit word, on a 64-bit platform it's a 64-bit word.

Here the * 8 suggests a byte to bit conversion to compute the costs but mod_limb_count * 8 is a number of bytes according to the text.

Furthermore the little-endian ordering is a bit unclear, are we talking about word endianness or limb-endianness (more on that below).

EIPS/eip-5843.md Outdated Show resolved Hide resolved
EIPS/eip-5843.md Outdated Show resolved Hide resolved
EIPS/eip-5843.md Outdated

#### Conversion between Montgomery and normal forms

Conversion of a normal value to Montgomery form can be computed with `mulmont(norm_val, evmmax_state.r_squared, mod) == norm_val * R % mod`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Conversion of a normal value to Montgomery form can be computed with `mulmont(norm_val, evmmax_state.r_squared, mod) == norm_val * R % mod`.
Conversion of a canonical value to Montgomery representation can be computed with `mulmont(canon_val, evmmax_state.r_squared, mod) == canon_val * R % mod`.

EIPS/eip-5843.md Outdated Show resolved Hide resolved
EIPS/eip-5843.md Outdated
```

TODO:
* Some derivation of complexity for extended euclidean (https://www.scaler.com/topics/data-structures/extended-euclidean-algorithm/ claims `O(log(min(x, y))`.
Copy link
Contributor

Choose a reason for hiding this comment

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

The rational is that at each iteration you divide by 2 the number of bits left to process, hence logarithmic. And you stop as soon as one input reaches 1.

EIPS/eip-5843.md Outdated
# first two bytes are the mod limb count
# mod = mod_params_bytes[2:2 + mod_limb_count * 8]
offset += mod_limb_count * 8
# mod_inv = mod_params_bytes[offset:offset + elem_size]
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not needed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can you elaborate? Are you saying that it should be represented more concisely in the spec?

Copy link
Contributor

Choose a reason for hiding this comment

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

mod_inv is not needed for Montgomery conversion or compute, only mod_inv_small (the 64-bit value is).

Though if it is wanted I forgot that you can compute in O(log(log(n))) as it is a power of 2, see https://github.com/mratsim/constantine/blob/master/constantine/math/arithmetic/limbs_exgcd.nim#L44-L77

Explanation p11 "Dumas iterations" based on Newton-Raphson:

EIPS/eip-5843.md Outdated

TODO:
* Some derivation of complexity for extended euclidean (https://www.scaler.com/topics/data-structures/extended-euclidean-algorithm/ claims `O(log(min(x, y))`.
* investigate go standard library which uses Lehmer's algorithm as part of calculating inverse.
Copy link
Contributor

Choose a reason for hiding this comment

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

The bigint modular inverse is not needed for addmodx or mulmodx.
The only inverse that is needed fits in a word and it's cheap to compute it.

Now if an EIP needs full blown modular inverse, Bernstein-Yang and Pornin's GCDs from 2019 and 2020 are significantly faster (like 5x to 10x) than any other algorithm like Lehmer's, see mratsim/constantine#172

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The "full" mod_inv is needed for generic mulmont which is used at larger bit-widths. I think it would be sensible to modify the spec to not compute it if the bitwidth is below a certain cutoff.

Copy link
Contributor

Choose a reason for hiding this comment

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

Here are 2 implementations of mulmont using CIOS and FIPS, mod_inv is not needed:

https://github.com/mratsim/constantine/blob/928f5155827252c01ee0c7a5c58c8b9deecc928f/constantine/math/arithmetic/limbs_montgomery.nim#L217-L307

m0ninv is the -1/M[0] the negative modular multiplicative inverse of the first limb of the prime modulus.

The way modular reduction works is by multiplying with it you can zero put the bottom bits and then shift by a whole word, one word at a time, you don't need to multiply by the full inverse.

@jwasinger
Copy link
Contributor Author

Hi @mratsim, thanks for the feedback on this work-in-progress draft. I'm working on completing an initial version of the EIP along with a Geth implementation, EVMMAX support in Huff, and a few other resources.

I have some other things on my plate right now that take precedence but hope to get these out very soon 🤞

@github-actions github-actions bot added w-ci Waiting on CI to pass and removed w-ci Waiting on CI to pass labels Jan 16, 2023
@github-actions github-actions bot added w-ci Waiting on CI to pass and removed w-ci Waiting on CI to pass labels Jan 16, 2023
@github-actions github-actions bot removed the w-ci Waiting on CI to pass label Jan 16, 2023
@github-actions github-actions bot added the w-ci Waiting on CI to pass label Jan 16, 2023
@github-actions github-actions bot removed the w-ci Waiting on CI to pass label Jan 16, 2023
@github-actions github-actions bot added the w-ci Waiting on CI to pass label Jan 16, 2023
@github-actions
Copy link

The commit efad4b1 (as a parent of 4d749ee) contains errors.
Please inspect the Run Summary for details.

@github-actions
Copy link

github-actions bot commented Feb 1, 2023

There has been no activity on this pull request for 2 weeks. It will be closed after 3 months of inactivity. If you would like to move this PR forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review.

@github-actions github-actions bot added the w-stale Waiting on activity label Feb 1, 2023
@jwasinger
Copy link
Contributor Author

Superseded by #6601

@jwasinger jwasinger closed this Mar 2, 2023
chfast added a commit to ethereum/evmone that referenced this pull request Jul 31, 2023
Add evmmax library with prototype C++ API for Montgomery-based modular arithmetic. This does not implement all aspects of the EVMMAX spec, but is a good starting point for prototyping EVMMAX usage in C++.

See these EIP drafts for more information about EVMMAX:

- ethereum/EIPs#5843
- ethereum/EIPs#6601
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c-new Creates a brand new proposal s-draft This EIP is a Draft t-core w-ci Waiting on CI to pass w-stale Waiting on activity
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants