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
|