-
Notifications
You must be signed in to change notification settings - Fork 5.3k
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
Conversation
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
|
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: |
There was a problem hiding this comment.
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
|
||
#### 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`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
``` | ||
|
||
TODO: | ||
* Some derivation of complexity for extended euclidean (https://www.scaler.com/topics/data-structures/extended-euclidean-algorithm/ claims `O(log(min(x, y))`. |
There was a problem hiding this comment.
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] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not needed
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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:
-
Cetin Kaya Koc (2017), https://eprint.iacr.org/2017/411
-
Jean-Guillaume Dumas (2012), https://arxiv.org/pdf/1209.6626v2.pdf
-
Colin Plumb (1994), http://groups.google.com/groups?selm=1994Apr6.093116.27805%40mnemosyne.cs.du.edu
Other sources: -
https://mumble.net/~campbell/2015/01/21/inverse-mod-power-of-two
-
http://marc-b-reynolds.github.io/math/2017/09/18/ModInverse.html
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. |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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:
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.
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 🤞 |
The commit efad4b1 (as a parent of 4d749ee) contains errors. |
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. |
Superseded by #6601 |
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
No description provided.