Skip to content

zkevm: keccak worst-case #1497

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

Merged
merged 8 commits into from
May 2, 2025
Merged

zkevm: keccak worst-case #1497

merged 8 commits into from
May 2, 2025

Conversation

jsign
Copy link
Contributor

@jsign jsign commented Apr 25, 2025

This PR adds a test that builds a block to maximize the number of keccak permutations for a given gas limit (considering the max contract size).

There are two main aspects of the test design.

Find the optimal input size

The metric we care about is gas per permutation, not simply max opcode calls. Although the dynamic cost of KECCAK256 is linear in input length, memory expansion is quadratic, so there is a sweet spot for minimal cost per permutation.

Instead of baking magic numbers, the test does a scan for the optimal cost and then does the attack with it. This is much more transparent on how this optimal length is found, plus it sounds also more future-proof.

Another way of understanding the above is by looking at this chart I created from that same script, with a more detailed output:
image

The “attack” loop

Once the optimal length is known, I create a loop that drives as many permutations as the block gas limit allows. The loop shouldn't be a tight loop, but quite the opposite -- run as many calls as possible within the max contract size, so the "JUMP"-like gas overhead is amortized as much as possible.

The general structure is:

JUMPDEST
 (PUSH+PUSH+KECCAK256+POP)
 ...
PUSH0
JUMP

Note that for 36M you can fit the (....) without a loop since the max you can add fits within 24KiB contract limit. But for bigger gas limits, you run short with 24KiB and need the loop!


zkVM cycles: 36m gas -> 632 million cycles

@marioevz marioevz force-pushed the jsign-zkvm-bytecode-worstcase branch from 55853d2 to a672724 Compare April 30, 2025 22:19
Base automatically changed from jsign-zkvm-bytecode-worstcase to main April 30, 2025 22:37
Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>
@jsign jsign force-pushed the jsign-zkvm-keccak branch from c0398f4 to c35f259 Compare May 1, 2025 17:56
Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>
@jsign jsign requested a review from marioevz May 1, 2025 18:00
@jsign jsign marked this pull request as ready for review May 1, 2025 18:01
@jsign jsign requested a review from kevaundray May 1, 2025 18:15
jsign added 2 commits May 1, 2025 15:31
Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>
Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>
@jsign jsign mentioned this pull request May 1, 2025
Copy link
Member

@marioevz marioevz left a comment

Choose a reason for hiding this comment

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

Overall looks good and just have a few comments, thanks!

jsign and others added 4 commits May 1, 2025 17:04
Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>
Co-authored-by: Mario Vega <marioevz@gmail.com>
Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>
Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>
@jsign jsign requested a review from marioevz May 1, 2025 20:30
Copy link
Member

@marioevz marioevz left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

@marioevz marioevz merged commit fce88dd into main May 2, 2025
22 checks passed
@marioevz marioevz deleted the jsign-zkvm-keccak branch May 2, 2025 18:51
felix314159 pushed a commit to felix314159/execution-spec-tests that referenced this pull request May 5, 2025
* zkEVM: add keccak attack

Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>

* lints

Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>

* only leave 36M gas limit

Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>

* lints

Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>

* feedback

Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>

* Update tests/zkevm/test_worst_compute.py

Co-authored-by: Mario Vega <marioevz@gmail.com>

* cleanup

Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>

* lints

Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>

---------

Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>
Co-authored-by: Mario Vega <marioevz@gmail.com>
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.

3 participants