Skip to content

Conversation

@DavePearce
Copy link
Collaborator

@DavePearce DavePearce commented Dec 7, 2025

Note

Adds asm/bench/mod with zkASM implementation (DIV/MOD/SDIV/SMOD) and corresponding test plus accept vectors.

  • Benchmarks:
    • Add Test_AsmBench_Mod in pkg/test/assembly_bench_test.go to run asm/bench/mod.
  • zkASM:
    • Introduce testdata/asm/bench/mod.zkasm implementing mod dispatcher for EVM_INST_DIV, EVM_INST_MOD, EVM_INST_SDIV, EVM_INST_SMOD.
    • Add helpers: signed_divide, abs, negate, and a temporary recursive divide.
  • Test Vectors:
    • Add testdata/asm/bench/mod.accepts covering various inputs for unsigned/signed division and modulo.

Written by Cursor Bugbot for commit 9b64fe3. This will update automatically on new commits. Configure here.

This adds a preliminary implementation of the MOD module.  The main
outstanding issue is the fact that there is no support at this time for
division.  Realistically, this is needed since otherwise the
implementation is incredibly inefficient.
These tests have been generated from mainnet blocks.
@DavePearce DavePearce linked an issue Dec 7, 2025 that may be closed by this pull request
return
smod:
RES, tmp = signed_divide(ARG_1, ARG_2)
return
Copy link

Choose a reason for hiding this comment

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

Bug: SMOD operation returns quotient instead of remainder

The smod case incorrectly returns the quotient instead of the remainder. The signed_divide function returns (quot, rem), so RES, tmp = signed_divide(...) assigns the quotient to RES. For SMOD (signed modulo), it should be tmp, RES = signed_divide(...) to return the remainder, matching the pattern used for unsigned MOD at line 16.

Fix in Cursor Fix in Web

var abs_quot, abs_rem u256
;;
abs_num, num_s = abs(num)
abs_den, den_s = abs(num)
Copy link

Choose a reason for hiding this comment

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

Bug: Wrong variable passed to abs function

The signed_divide function has a copy-paste error where abs_den, den_s = abs(num) computes the absolute value of the numerator instead of the denominator. It should be abs(den) to get the absolute value of the den parameter for the division operation.

Fix in Cursor Fix in Web

;; negative result
quot = negate(abs_quot)
rem = negate(abs_rem)
return
Copy link

Choose a reason for hiding this comment

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

Bug: Remainder sign incorrectly follows quotient sign logic

The signed_divide function applies the same sign logic to both quotient and remainder, but EVM semantics require different rules. The quotient sign depends on num_s XOR den_s (correctly implemented), but the remainder sign must depend only on num_s (the dividend's sign). Currently, both quot and rem are negated when num_s != den_s, which produces incorrect remainder values when the dividend and divisor have opposite signs.

Fix in Cursor Fix in Web

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.

feat: add MOD benchmark

2 participants