Skip to content

Spec

Documentation for tests/constantinople/eip145_bitwise_shift/spec.py@0c700940.

Defines EIP-145 specification constants and functions.

Spec dataclass

Parameters from the EIP-145 specifications as defined at https://eips.ethereum.org/EIPS/eip-145.

Source code in tests/constantinople/eip145_bitwise_shift/spec.py
 17
 18
 19
 20
 21
 22
 23
 24
 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
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
@dataclass(frozen=True)
class Spec:
    """
    Parameters from the EIP-145 specifications as defined at
    https://eips.ethereum.org/EIPS/eip-145.
    """

    # Below are GPT o4-mini-high implementation of shift functions
    # It can contain bugs, treat it with caution and refer to EVM implementations
    @staticmethod
    def sar(shift: int, value: int) -> int:
        """
        Simulate the EVM SAR (Signed Arithmetic Right shift) operation.

        Parameters
        ----------
        shift : int
            Number of bits to shift to the right (interpreted as full unsigned;
            no low-8-bit truncation here).
        value : int
            The 256-bit value to shift, interpreted as a signed integer.

        Returns
        -------
        int
            The result of the arithmetic right shift, pushed as an unsigned
            256-bit integer on the EVM stack.

        """
        mask256 = (1 << 256) - 1  # Clamp value to 256 bits

        # Interpret as signed
        v = value & mask256
        if v >> 255:
            v_signed = v - (1 << 256)
        else:
            v_signed = v

        # If shift >= 256, spec says:
        #   • result = 0   if v_signed >= 0
        #   • result = -1  if v_signed <  0
        if shift >= 256:
            result_signed = -1 if v_signed < 0 else 0
        else:
            # Normal arithmetic right shift
            result_signed = v_signed >> shift

        # Wrap back to unsigned 256-bit
        return result_signed & mask256

    @staticmethod
    def shl(shift: int, value: int) -> int:
        """
        Simulate the EVM SHL (Logical Left shift) operation.

        Parameters
        ----------
        shift : int
            Number of bits to shift to the left.
        value : int
            The 256-bit value to shift, interpreted as an unsigned integer.

        Returns
        -------
        int
            The result of the logical left shift, pushed as an unsigned
            256-bit integer on the EVM stack.

        """
        mask256 = (1 << 256) - 1
        # Clamp input to 256 bits
        v = value & mask256

        # If shift >= 256, spec returns 0
        if shift >= 256:
            return 0

        # Logical left shift and wrap to 256 bits
        return (v << shift) & mask256

    @staticmethod
    def shr(shift: int, value: int) -> int:
        """
        Simulate the EVM SHR (Logical Right shift) operation.

        Parameters
        ----------
        shift : int
            Number of bits to shift to the right.
        value : int
            The 256-bit value to shift, interpreted as an unsigned integer.

        Returns
        -------
        int
            The result of the logical right shift, pushed as an unsigned
            256-bit integer on the EVM stack.

        """
        mask256 = (1 << 256) - 1
        # Clamp input to 256 bits
        v = value & mask256

        # If shift >= 256, the EVM spec returns 0
        if shift >= 256:
            return 0

        # Logical right shift and mask back to 256 bits
        return (v >> shift) & mask256