Skip to content
This repository has been archived by the owner on Jan 9, 2025. It is now read-only.

Commit

Permalink
opti: inline unsigned_div_rem and div_rem (#1342)
Browse files Browse the repository at this point in the history
<!--- Please provide a general summary of your changes in the title
above -->

<!-- Give an estimate of the time you spent on this PR in terms of work
days.
Did you spend 0.5 days on this PR or rather 2 days?  -->

Time spent on this PR:

## Pull request type

<!-- Please try to limit your pull request to one type,
submit multiple pull requests if needed. -->

Please check the type of change your PR introduces:

- [ ] Bugfix
- [ ] Feature
- [ ] Code style update (formatting, renaming)
- [ ] Refactoring (no functional changes, no api changes)
- [ ] Build related changes
- [ ] Documentation content changes
- [x] Other (please describe): opti

## What is the current behavior?

<!-- Please describe the current behavior that you are modifying,
or link to a relevant issue. -->

Resolves #1302

## What is the new behavior?
- div_rem and unsigned_div_rem are inlined

From 141777 to 141574
Before:

![main](https://github.com/user-attachments/assets/777a6d51-1a9f-4118-a0b7-929c20c5b3de)

After:

![profile004](https://github.com/user-attachments/assets/856dea61-c400-4523-8702-6c84eb3ad068)

<!-- Reviewable:start -->
- - -
This change is [<img src="https://reviewable.io/review_button.svg"
height="34" align="absmiddle"
alt="Reviewable"/>](https://reviewable.io/reviews/kkrt-labs/kakarot/1342)
<!-- Reviewable:end -->
  • Loading branch information
obatirou authored Aug 19, 2024
1 parent 9dc1ce4 commit 1beb379
Show file tree
Hide file tree
Showing 20 changed files with 76 additions and 31 deletions.
3 changes: 1 addition & 2 deletions src/backend/starknet.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ from starkware.cairo.common.bool import FALSE, TRUE
from starkware.cairo.common.cairo_builtins import HashBuiltin
from starkware.cairo.common.dict_access import DictAccess
from starkware.cairo.common.uint256 import Uint256
from starkware.cairo.common.math import unsigned_div_rem
from starkware.cairo.common.math_cmp import is_nn
from starkware.cairo.common.memset import memset
from starkware.starknet.common.syscalls import (
Expand All @@ -23,7 +22,6 @@ from kakarot.account import Account
from kakarot.precompiles.precompiles_helpers import PrecompilesHelpers
from kakarot.constants import Constants
from kakarot.interfaces.interfaces import IERC20, IAccount

from kakarot.model import model
from kakarot.state import State
from kakarot.storages import (
Expand All @@ -36,6 +34,7 @@ from kakarot.storages import (
Kakarot_block_gas_limit,
Kakarot_prev_randao,
)
from utils.maths import unsigned_div_rem

namespace Starknet {
// @notice Commit the current state to the underlying data backend (here, Starknet)
Expand Down
3 changes: 2 additions & 1 deletion src/kakarot/accounts/account_contract.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from openzeppelin.access.ownable.library import Ownable
from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.cairo_builtins import HashBuiltin, BitwiseBuiltin, SignatureBuiltin
from starkware.cairo.common.math import assert_le, unsigned_div_rem
from starkware.cairo.common.math import assert_le
from starkware.cairo.common.math_cmp import is_nn
from starkware.cairo.common.uint256 import Uint256
from starkware.starknet.common.syscalls import (
Expand All @@ -25,6 +25,7 @@ from kakarot.accounts.model import CallArray, OutsideExecution
from kakarot.interfaces.interfaces import IKakarot, IAccount
from kakarot.errors import Errors
from utils.utils import Helpers
from utils.maths import unsigned_div_rem

const GET_STARKNET_ADDRESS_SELECTOR = 0x03e5d65a345b3857ca9d72edca702b8e56c1923c118867752345f710d595b3cf;

Expand Down
3 changes: 2 additions & 1 deletion src/kakarot/accounts/library.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.bool import FALSE, TRUE
from starkware.cairo.common.dict_access import DictAccess
from starkware.cairo.common.cairo_builtins import HashBuiltin, BitwiseBuiltin
from starkware.cairo.common.math import unsigned_div_rem, split_int, split_felt
from starkware.cairo.common.math import split_int, split_felt
from starkware.cairo.common.memcpy import memcpy
from starkware.cairo.common.uint256 import Uint256, uint256_not, uint256_le
from starkware.cairo.common.math_cmp import is_nn, is_le_felt
Expand Down Expand Up @@ -33,6 +33,7 @@ from utils.uint256 import uint256_add
from utils.bytes import bytes_to_bytes8_little_endian
from utils.signature import Signature
from utils.utils import Helpers
from utils.maths import unsigned_div_rem

// @dev: should always be zero for EOAs
@storage_var
Expand Down
3 changes: 2 additions & 1 deletion src/kakarot/gas.cairo
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from starkware.cairo.common.math import split_felt, unsigned_div_rem
from starkware.cairo.common.math import split_felt
from starkware.cairo.common.math_cmp import is_not_zero, is_nn, is_le_felt
from starkware.cairo.common.bool import FALSE
from starkware.cairo.common.uint256 import Uint256, uint256_lt

from kakarot.model import model
from utils.uint256 import uint256_eq
from utils.utils import Helpers
from utils.maths import unsigned_div_rem

namespace Gas {
const JUMPDEST = 1;
Expand Down
3 changes: 2 additions & 1 deletion src/kakarot/instructions/environmental_information.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.bool import FALSE
from starkware.cairo.common.cairo_builtins import HashBuiltin, BitwiseBuiltin
from starkware.cairo.common.memset import memset
from starkware.cairo.common.math import unsigned_div_rem, split_felt
from starkware.cairo.common.math import split_felt
from starkware.cairo.common.math_cmp import is_not_zero, is_nn
from starkware.cairo.common.uint256 import Uint256, uint256_le

Expand All @@ -23,6 +23,7 @@ from utils.array import slice
from utils.bytes import bytes_to_bytes8_little_endian
from utils.uint256 import uint256_to_uint160, uint256_add, uint256_eq
from utils.utils import Helpers
from utils.maths import unsigned_div_rem

// @title Environmental information opcodes.
// @notice This file contains the functions to execute for environmental information opcodes.
Expand Down
2 changes: 1 addition & 1 deletion src/kakarot/instructions/memory_operations.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ from starkware.cairo.common.bool import FALSE, TRUE
from starkware.cairo.common.cairo_builtins import HashBuiltin, BitwiseBuiltin
from starkware.cairo.common.uint256 import Uint256
from starkware.cairo.common.math_cmp import is_nn, is_not_zero
from starkware.cairo.common.math import unsigned_div_rem

from kakarot.errors import Errors
from kakarot.account import Account
Expand All @@ -19,6 +18,7 @@ from kakarot.stack import Stack
from kakarot.state import State
from utils.utils import Helpers
from utils.uint256 import uint256_unsigned_div_rem, uint256_eq
from utils.maths import unsigned_div_rem

namespace MemoryOperations {
func exec_mload{
Expand Down
3 changes: 2 additions & 1 deletion src/kakarot/instructions/sha3.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.bool import FALSE
from starkware.cairo.common.math import split_felt, unsigned_div_rem
from starkware.cairo.common.math import split_felt
from starkware.cairo.common.cairo_builtins import HashBuiltin, BitwiseBuiltin
from starkware.cairo.common.uint256 import Uint256
from starkware.cairo.common.math_cmp import is_not_zero
Expand All @@ -17,6 +17,7 @@ from kakarot.model import model
from kakarot.stack import Stack
from kakarot.storages import Kakarot_cairo1_helpers_class_hash
from utils.bytes import bytes_to_bytes8_little_endian
from utils.maths import unsigned_div_rem

namespace Sha3 {
func exec_sha3{
Expand Down
3 changes: 2 additions & 1 deletion src/kakarot/instructions/system_operations.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.bool import TRUE, FALSE
from starkware.cairo.common.cairo_builtins import HashBuiltin, BitwiseBuiltin
from starkware.cairo.common.math import split_felt, unsigned_div_rem
from starkware.cairo.common.math import split_felt
from starkware.cairo.common.math_cmp import is_nn, is_not_zero
from starkware.cairo.common.uint256 import Uint256, uint256_lt, uint256_le
from starkware.cairo.common.default_dict import default_dict_new
Expand All @@ -31,6 +31,7 @@ from utils.bytes import (
uint256_to_bytes32,
)
from utils.uint256 import uint256_to_uint160, uint256_eq
from utils.maths import unsigned_div_rem

using bool = felt;

Expand Down
2 changes: 1 addition & 1 deletion src/kakarot/interpreter.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ from starkware.cairo.common.default_dict import default_dict_new
from starkware.cairo.common.dict import DictAccess
from starkware.cairo.lang.compiler.lib.registers import get_fp_and_pc, get_ap
from starkware.cairo.common.uint256 import Uint256, uint256_le
from starkware.cairo.common.math import unsigned_div_rem

// Internal dependencies
from kakarot.account import Account
Expand All @@ -39,6 +38,7 @@ from kakarot.gas import Gas
from utils.utils import Helpers
from utils.array import count_not_zero
from utils.uint256 import uint256_sub, uint256_add
from utils.maths import unsigned_div_rem

// @title EVM instructions processing.
// @notice This file contains functions related to the processing of EVM instructions.
Expand Down
2 changes: 1 addition & 1 deletion src/kakarot/memory.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
from starkware.cairo.common.cairo_builtins import HashBuiltin, BitwiseBuiltin
from starkware.cairo.common.default_dict import default_dict_new, default_dict_finalize
from starkware.cairo.common.dict import DictAccess, dict_read, dict_write
from starkware.cairo.common.math import unsigned_div_rem
from starkware.cairo.common.uint256 import Uint256

from kakarot.model import model
from utils.utils import Helpers
from utils.maths import unsigned_div_rem

// @title Memory related functions.
// @notice This file contains functions related to the memory.
Expand Down
2 changes: 1 addition & 1 deletion src/kakarot/precompiles/blake2f.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.cairo_builtins import HashBuiltin
from starkware.cairo.common.cairo_builtins import BitwiseBuiltin
from starkware.cairo.common.math import unsigned_div_rem
from starkware.cairo.common.registers import get_fp_and_pc, get_label_location
from starkware.cairo.common.math_cmp import is_nn
from starkware.cairo.common.bool import FALSE

// Internal dependencies
from kakarot.errors import Errors
from utils.utils import Helpers
from utils.maths import unsigned_div_rem

// @title Blake2f Precompile related functions.
// @notice This file contains the logic required to run the blake2f precompile
Expand Down
6 changes: 3 additions & 3 deletions src/kakarot/precompiles/ec_recover.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.cairo_builtins import HashBuiltin, BitwiseBuiltin
from starkware.cairo.common.cairo_keccak.keccak import finalize_keccak
from starkware.cairo.common.bool import FALSE
from starkware.cairo.common.math import unsigned_div_rem
from starkware.cairo.common.math_cmp import RC_BOUND
from starkware.cairo.common.cairo_secp.ec import EcPoint
from starkware.cairo.common.cairo_secp.bigint import BigInt3
Expand All @@ -16,11 +15,12 @@ from starkware.cairo.common.uint256 import Uint256, uint256_reverse_endian
from starkware.cairo.common.cairo_secp.bigint import bigint_to_uint256
from starkware.cairo.common.keccak_utils.keccak_utils import keccak_add_uint256s
from starkware.cairo.common.memset import memset
from utils.utils import Helpers
from utils.array import slice
from kakarot.errors import Errors
from kakarot.storages import Kakarot_cairo1_helpers_class_hash
from kakarot.interfaces.interfaces import ICairo1Helpers
from utils.utils import Helpers
from utils.array import slice
from utils.maths import unsigned_div_rem

// @title EcRecover Precompile related functions.
// @notice This file contains the logic required to run the ec_recover precompile
Expand Down
5 changes: 3 additions & 2 deletions src/kakarot/precompiles/ripemd160.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// Starkware dependencies
from starkware.cairo.common.cairo_builtins import BitwiseBuiltin, HashBuiltin
from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.math import unsigned_div_rem, assert_nn_le
from starkware.cairo.common.math import assert_nn_le
from starkware.cairo.common.math_cmp import is_nn_le, is_nn
from starkware.cairo.common.bitwise import bitwise_and, bitwise_xor, bitwise_or
from starkware.cairo.common.dict_access import DictAccess
Expand All @@ -18,9 +18,10 @@ from starkware.cairo.common.memset import memset

// Internal dependencies
from kakarot.model import model
from utils.utils import Helpers
from kakarot.memory import Memory
from kakarot.evm import EVM
from utils.utils import Helpers
from utils.maths import unsigned_div_rem

// @title RIPEMD-160 precompile
// @custom:precompile
Expand Down
3 changes: 2 additions & 1 deletion src/kakarot/precompiles/sha256.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.registers import get_fp_and_pc
from starkware.cairo.common.cairo_builtins import HashBuiltin, BitwiseBuiltin
from starkware.cairo.common.math import assert_nn_le, unsigned_div_rem
from starkware.cairo.common.math import assert_nn_le
from starkware.cairo.common.math_cmp import is_le_felt
from starkware.cairo.common.memcpy import memcpy
from starkware.cairo.common.memset import memset
Expand All @@ -22,6 +22,7 @@ from utils.sha_256.packed_sha256 import (
get_round_constants,
)
from utils.utils import Helpers
from utils.maths import unsigned_div_rem

// @title SHA2-256 Precompile related functions.
// @notice This file contains the logic required to run the SHA2-256 precompile
Expand Down
1 change: 0 additions & 1 deletion src/kakarot/stack.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.bool import FALSE, TRUE
from starkware.cairo.common.default_dict import default_dict_new, default_dict_finalize
from starkware.cairo.common.dict import DictAccess, dict_read, dict_write
from starkware.cairo.common.math import assert_le, unsigned_div_rem
from starkware.cairo.lang.compiler.lib.registers import get_fp_and_pc
from starkware.cairo.common.uint256 import Uint256

Expand Down
9 changes: 2 additions & 7 deletions src/utils/bytes.cairo
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.math import (
unsigned_div_rem,
split_int,
split_felt,
assert_le_felt,
assert_nn_le,
)
from starkware.cairo.common.math import split_int, split_felt, assert_le_felt, assert_nn_le
from starkware.cairo.common.uint256 import Uint256
from starkware.cairo.common.memcpy import memcpy
from starkware.cairo.common.memset import memset
from starkware.cairo.common.registers import get_label_location

from utils.array import reverse
from utils.maths import unsigned_div_rem

func felt_to_ascii{range_check_ptr}(dst: felt*, n: felt) -> felt {
alloc_locals;
Expand Down
2 changes: 1 addition & 1 deletion src/utils/dict.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ from starkware.cairo.common.default_dict import default_dict_new
from starkware.cairo.common.dict import dict_write, dict_squash
from starkware.cairo.common.math_cmp import is_not_zero
from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.math import unsigned_div_rem
from starkware.cairo.common.uint256 import Uint256
from utils.maths import unsigned_div_rem

func dict_keys{range_check_ptr}(dict_start: DictAccess*, dict_end: DictAccess*) -> (
keys_len: felt, keys: felt*
Expand Down
34 changes: 34 additions & 0 deletions src/utils/maths.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// @dev Inlined version of unsigned_div_rem
// Returns q and r such that:
// 0 <= q < rc_bound, 0 <= r < div and value = q * div + r.
//
// Assumption: 0 < div <= PRIME / rc_bound.
// Prover assumption: value / div < rc_bound.
//
// The value of div is restricted to make sure there is no overflow.
// q * div + r < (q + 1) * div <= rc_bound * (PRIME / rc_bound) = PRIME.
func unsigned_div_rem{range_check_ptr}(value, div) -> (q: felt, r: felt) {
let r = [range_check_ptr];
let q = [range_check_ptr + 1];
let range_check_ptr = range_check_ptr + 2;
%{
from starkware.cairo.common.math_utils import assert_integer
assert_integer(ids.div)
assert 0 < ids.div <= PRIME // range_check_builtin.bound, \
f'div={hex(ids.div)} is out of the valid range.'
ids.q, ids.r = divmod(ids.value, ids.div)
%}

// equivalent to assert_le(r, div - 1);
tempvar a = div - 1 - r;
%{
from starkware.cairo.common.math_utils import assert_integer
assert_integer(ids.a)
assert 0 <= ids.a % PRIME < range_check_builtin.bound, f'a = {ids.a} is out of range.'
%}
a = [range_check_ptr];
let range_check_ptr = range_check_ptr + 1;

assert value = q * div + r;
return (q, r);
}
2 changes: 1 addition & 1 deletion src/utils/uint256.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ from starkware.cairo.common.uint256 import (
uint256_lt,
uint256_not,
)
from starkware.cairo.common.math import unsigned_div_rem
from starkware.cairo.common.bool import FALSE
from starkware.cairo.common.math_cmp import is_nn
from utils.maths import unsigned_div_rem

// Adds two integers. Returns the result as a 256-bit integer and the (1-bit) carry.
// Strictly equivalent and faster version of common.uint256.uint256_add using the same whitelisted hint.
Expand Down
16 changes: 13 additions & 3 deletions src/utils/utils.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

// StarkWare dependencies
from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.math import assert_le, split_felt, assert_nn_le, unsigned_div_rem
from starkware.cairo.common.math import assert_le, split_felt, assert_nn_le
from starkware.cairo.common.math_cmp import is_nn, is_not_zero
from starkware.cairo.common.memcpy import memcpy
from starkware.cairo.common.dict_access import DictAccess
Expand All @@ -18,6 +18,7 @@ from starkware.starknet.common.syscalls import get_tx_info

from kakarot.model import model
from utils.bytes import uint256_to_bytes32, felt_to_bytes32
from utils.maths import unsigned_div_rem

// @title Helper Functions
// @notice This file contains a selection of helper function that simplify tasks such as type conversion and bit manipulation
Expand Down Expand Up @@ -382,7 +383,7 @@ namespace Helpers {

// @notice Divides a 128-bit number with remainder.
// @dev This is almost identical to cairo.common.math.unsigned_dev_rem, but supports the case
// @dev of div == 2**128 as well.
// @dev of div == 2**128 as well. assert_le is also inlined.
// @param value: 128bit value to divide.
// @param div: divisor.
// @return: quotient and remainder.
Expand All @@ -402,7 +403,16 @@ namespace Helpers {
f'div={hex(ids.div)} is out of the valid range.'
ids.q, ids.r = divmod(ids.value, ids.div)
%}
assert_le(r, div - 1);

// equivalent to assert_le(r, div - 1);
tempvar a = div - 1 - r;
%{
from starkware.cairo.common.math_utils import assert_integer
assert_integer(ids.a)
assert 0 <= ids.a % PRIME < range_check_builtin.bound, f'a = {ids.a} is out of range.'
%}
a = [range_check_ptr];
let range_check_ptr = range_check_ptr + 1;

assert value = q * div + r;
return (q, r);
Expand Down

0 comments on commit 1beb379

Please sign in to comment.