Skip to content

Accelerate eth_evm_modexp by 25x by dividing input size by 8 - #249

Merged
mratsim merged 6 commits into
masterfrom
fuzz-6-modexp-slow
Jul 2, 2023
Merged

mratsim merged 6 commits into
masterfrom
fuzz-6-modexp-slow

Conversation

@mratsim

@mratsim mratsim commented Jul 2, 2023

Copy link
Copy Markdown
Owner

Found by @guidovranken in the Ethereum Foundation sponsored fuzzing campaign,

eth_evm_modexp is very slow on some input.

The issue is located here:

  1. We read the length in bytes here:
    let
    baseLen = cast[int](bL.limbs[0])
    exponentLen = cast[int](eL.limbs[0])
    modulusLen = cast[int](mL.limbs[0])
  2. But we allocated as many 64-bit words as there were bytes instead of dividing by 8:
    template base(): untyped = baseBuf.toOpenArray(0, baseLen-1)
    template modulus(): untyped = modulusBuf.toOpenArray(0, modulusLen-1)
    template output(): untyped = outputBuf.toOpenArray(0, modulusLen-1)

The issue is that multiplication scales quadratically, about 1.5n² with the number of words. In our case the ratio before/after is 25x leading to a DOS vulnerability

@mratsim

mratsim commented Jul 2, 2023

Copy link
Copy Markdown
Owner Author

Exponentiation with even base and power-of-two modulus is now instant for a lot more moduli.

In particular the DOS vector has been accelerated by 2310x.

Before:
image

After generic fix (i.e. dividing input size by 8) - 28x acceleration.
image

Using special structure - 2370x acceleration.
image

@mratsim
mratsim merged commit b7687dd into master Jul 2, 2023
@mratsim
mratsim deleted the fuzz-6-modexp-slow branch July 2, 2023 23:45
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.

1 participant