Skip to content

Spec

Documentation for tests/osaka/eip7883_modexp_gas_increase/spec.py@0c700940.

Defines EIP-7883 specification constants and functions.

Spec dataclass

Constants and helpers for the ModExp gas cost calculation.

Source code in tests/osaka/eip7883_modexp_gas_increase/spec.py
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
@dataclass(frozen=True)
class Spec:
    """Constants and helpers for the ModExp gas cost calculation."""

    MODEXP_ADDRESS = 0x05
    MIN_GAS = 200

    LARGE_BASE_MODULUS_MULTIPLIER = 1
    MAX_LENGTH_THRESHOLD = 32
    EXPONENT_BYTE_MULTIPLIER = 8

    WORD_SIZE = 8
    EXPONENT_THRESHOLD = 32
    GAS_DIVISOR = 3

    @classmethod
    def calculate_multiplication_complexity(cls, base_length: int, modulus_length: int) -> int:
        """Calculate the multiplication complexity of the ModExp precompile."""
        max_length = max(base_length, modulus_length)
        words = ceiling_division(max_length, cls.WORD_SIZE)
        if max_length <= cls.MAX_LENGTH_THRESHOLD:
            return words**2
        return cls.LARGE_BASE_MODULUS_MULTIPLIER * words**2

    @classmethod
    def calculate_iteration_count(cls, exponent_length: int, exponent: bytes) -> int:
        """Calculate the iteration count of the ModExp precompile."""
        iteration_count = 0
        exponent_value = int.from_bytes(exponent, byteorder="big")
        if exponent_length <= cls.EXPONENT_THRESHOLD and exponent_value == 0:
            iteration_count = 0
        elif exponent_length <= cls.EXPONENT_THRESHOLD:
            iteration_count = exponent_value.bit_length() - 1
        elif exponent_length > cls.EXPONENT_THRESHOLD:
            exponent_head = int.from_bytes(exponent[0:32], byteorder="big")
            length_part = cls.EXPONENT_BYTE_MULTIPLIER * (exponent_length - 32)
            bits_part = exponent_head.bit_length()
            if bits_part > 0:
                bits_part -= 1
            iteration_count = length_part + bits_part
        return max(iteration_count, 1)

    @classmethod
    def calculate_gas_cost(
        cls, base_length: int, modulus_length: int, exponent_length: int, exponent: bytes
    ) -> int:
        """Calculate the ModExp gas cost according to EIP-7883 specification."""
        multiplication_complexity = cls.calculate_multiplication_complexity(
            base_length, modulus_length
        )
        iteration_count = cls.calculate_iteration_count(exponent_length, exponent)
        return max(cls.MIN_GAS, (multiplication_complexity * iteration_count // cls.GAS_DIVISOR))

Spec7883 dataclass

Bases: Spec

Constants and helpers for the ModExp gas cost increase EIP.

Source code in tests/osaka/eip7883_modexp_gas_increase/spec.py
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
@dataclass(frozen=True)
class Spec7883(Spec):
    """Constants and helpers for the ModExp gas cost increase EIP."""

    MODEXP_ADDRESS = 0x05
    MIN_GAS = 500

    LARGE_BASE_MODULUS_MULTIPLIER = 2
    EXPONENT_BYTE_MULTIPLIER = 16

    @classmethod
    def calculate_multiplication_complexity(cls, base_length: int, modulus_length: int) -> int:
        """Calculate the multiplication complexity of the ModExp precompile for EIP-7883."""
        max_length = max(base_length, modulus_length)
        words = ceiling_division(max_length, cls.WORD_SIZE)
        complexity = 16
        if max_length > cls.MAX_LENGTH_THRESHOLD:
            complexity = cls.LARGE_BASE_MODULUS_MULTIPLIER * words**2
        return complexity