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

evm: fix modexp edge cases #3169

Merged
merged 9 commits into from
Nov 29, 2023
Merged

evm: fix modexp edge cases #3169

merged 9 commits into from
Nov 29, 2023

Conversation

jochem-brouwer
Copy link
Member

@jochem-brouwer jochem-brouwer commented Nov 28, 2023

Closes #3168

This PR fixes the edge cases in ModExp. Specifically, ModExp has 6 inputs, and the inputs for [0,1,2] are all tested on all inputs. These are cross-referenced against infura. (File here: 144963a)

Test files are here. The format is [input, expectedOutput]

tests.txt

Note: one of the causes is that bigIntToBytes(BigInt(0)) returns Uint8Array(1) [ 0 ] (length 1) instead of Uint8Array(0) [] (length 0). If you then setLengthLeft(r, 0) then it still outputs the array with length 1. This raises 2 questions:

  • Should bigIntToBytes on BigInt(0) return the empty array? (Note: this is super breaking so we cannot do it, we could introduce a new method?)
  • Should setLengthLeft throw if the expected length is lower than the current length? (It is unknown if we should trim left or right 🤔 )

Copy link

codecov bot commented Nov 28, 2023

Codecov Report

Merging #3169 (0ef5199) into master (9d756c2) will decrease coverage by 0.06%.
The diff coverage is 100.00%.

Additional details and impacted files

Impacted file tree graph

Flag Coverage Δ
block 88.80% <ø> (ø)
blockchain 91.61% <ø> (ø)
client 84.91% <ø> (ø)
common 98.19% <ø> (ø)
devp2p 82.09% <ø> (?)
ethash ∅ <ø> (∅)
evm 73.53% <100.00%> (+1.59%) ⬆️
statemanager 90.13% <ø> (ø)
trie 89.76% <ø> (+0.04%) ⬆️
tx 95.73% <ø> (ø)
util 88.90% <ø> (ø)
vm 81.40% <ø> (ø)

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

@jochem-brouwer
Copy link
Member Author

Have added a fuzzer which I will run now. It finds more error cases.

@jochem-brouwer
Copy link
Member Author

Fuzzer tests: run inputs [0,1,2] on the modExp inputs (6 fields: bLen, eLen, mLen, B, E, M) (729 tests). Failures: 35.

@jochem-brouwer
Copy link
Member Author

tests.txt

Test cases: array of [input, expectedOutput] retrieved from infura for all combinations [0,1,2] on the modExp inputs (6 fields: bLen, eLen, mLen, B, E, M)

@@ -151,17 +151,10 @@ export function precompile05(opts: PrecompileInput): ExecResult {
return OOGResult(opts.gasLimit)
}

if (bLen === BIGINT_0) {
if (bLen === BIGINT_0 && mLen === BigInt(0)) {
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
if (bLen === BIGINT_0 && mLen === BigInt(0)) {
if (bLen === BIGINT_0 && mLen === BIGINT_0) {

Copy link
Contributor

@acolytec3 acolytec3 left a comment

Choose a reason for hiding this comment

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

Generally looks good. I think we should definitely consider whether these utility methods (like setLengthLeft) should throw if there is under/overflow but that can be solved separately.

One nit suggestion too.

Will approve once the "fuzzer" tests are added.

Copy link
Contributor

@acolytec3 acolytec3 left a comment

Choose a reason for hiding this comment

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

LGTM!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Precompile contract modexp returns incorrect value in corner case
3 participants