@@ -22,6 +22,38 @@ function multComplexity(x: BN): BN {
22
22
}
23
23
}
24
24
25
+ function calculateGasEIP2565 (
26
+ baseLength : BN ,
27
+ modulusLength : BN ,
28
+ exponentLength : BN ,
29
+ exponent : BN
30
+ ) : BN {
31
+ console . log (
32
+ baseLength . toNumber ( ) ,
33
+ modulusLength . toNumber ( ) ,
34
+ exponentLength . toNumber ( ) ,
35
+ exponent . toNumber ( )
36
+ )
37
+ const maxLength = BN . max ( baseLength , modulusLength )
38
+ const words = maxLength . divn ( 8 )
39
+ // Ceil operation
40
+ if ( maxLength . mod ( new BN ( 8 ) ) . gtn ( 0 ) ) {
41
+ words . iaddn ( 1 )
42
+ }
43
+ const multiplicationComplexity = words . pow ( new BN ( 2 ) )
44
+ let iterationCount
45
+ if ( exponentLength . lten ( 32 ) && exponent . eqn ( 0 ) ) {
46
+ iterationCount = new BN ( 0 )
47
+ } else if ( exponentLength . lten ( 32 ) ) {
48
+ iterationCount = new BN ( exponent . bitLength ( ) - 1 )
49
+ } else {
50
+ const expMask = exponent . and ( new BN ( Buffer . alloc ( 32 , 0xff ) ) )
51
+ iterationCount = new BN ( 8 ) . mul ( exponentLength . subn ( 32 ) ) . addn ( expMask . bitLength ( ) - 1 )
52
+ }
53
+ iterationCount = BN . max ( new BN ( 1 ) , iterationCount )
54
+ return BN . max ( new BN ( 200 ) , multiplicationComplexity . mul ( iterationCount ) . divn ( 3 ) )
55
+ }
56
+
25
57
function getAdjustedExponentLength ( data : Buffer ) : BN {
26
58
let expBytesStart
27
59
try {
@@ -86,7 +118,35 @@ export default function (opts: PrecompileInput): ExecResult {
86
118
maxLen = mLen
87
119
}
88
120
const Gquaddivisor = opts . _common . param ( 'gasPrices' , 'modexpGquaddivisor' )
89
- const gasUsed = adjustedELen . mul ( multComplexity ( maxLen ) ) . divn ( Gquaddivisor )
121
+ let gasUsed
122
+
123
+ const bStart = new BN ( 96 )
124
+ const bEnd = bStart . add ( bLen )
125
+ const eStart = bEnd
126
+ const eEnd = eStart . add ( eLen )
127
+ const mStart = eEnd
128
+ const mEnd = mStart . add ( mLen )
129
+
130
+ const maxInt = new BN ( Number . MAX_SAFE_INTEGER )
131
+ const maxSize = new BN ( 2147483647 ) // ethereumjs-util setLengthRight limitation
132
+
133
+ if ( bLen . gt ( maxSize ) || eLen . gt ( maxSize ) || mLen . gt ( maxSize ) ) {
134
+ return OOGResult ( opts . gasLimit )
135
+ }
136
+
137
+ if ( mEnd . gt ( maxInt ) ) {
138
+ return OOGResult ( opts . gasLimit )
139
+ }
140
+
141
+ const B = new BN ( setLengthRight ( data . slice ( bStart . toNumber ( ) , bEnd . toNumber ( ) ) , bLen . toNumber ( ) ) )
142
+ const E = new BN ( setLengthRight ( data . slice ( eStart . toNumber ( ) , eEnd . toNumber ( ) ) , eLen . toNumber ( ) ) )
143
+ const M = new BN ( setLengthRight ( data . slice ( mStart . toNumber ( ) , mEnd . toNumber ( ) ) , mLen . toNumber ( ) ) )
144
+
145
+ if ( ! opts . _common . eips ( ) . includes ( 2565 ) ) {
146
+ gasUsed = adjustedELen . mul ( multComplexity ( maxLen ) ) . divn ( Gquaddivisor )
147
+ } else {
148
+ gasUsed = calculateGasEIP2565 ( bLen , eLen , mLen , E )
149
+ }
90
150
91
151
if ( opts . gasLimit . lt ( gasUsed ) ) {
92
152
return OOGResult ( opts . gasLimit )
@@ -106,28 +166,6 @@ export default function (opts: PrecompileInput): ExecResult {
106
166
}
107
167
}
108
168
109
- const maxInt = new BN ( Number . MAX_SAFE_INTEGER )
110
- const maxSize = new BN ( 2147483647 ) // ethereumjs-util setLengthRight limitation
111
-
112
- if ( bLen . gt ( maxSize ) || eLen . gt ( maxSize ) || mLen . gt ( maxSize ) ) {
113
- return OOGResult ( opts . gasLimit )
114
- }
115
-
116
- const bStart = new BN ( 96 )
117
- const bEnd = bStart . add ( bLen )
118
- const eStart = bEnd
119
- const eEnd = eStart . add ( eLen )
120
- const mStart = eEnd
121
- const mEnd = mStart . add ( mLen )
122
-
123
- if ( mEnd . gt ( maxInt ) ) {
124
- return OOGResult ( opts . gasLimit )
125
- }
126
-
127
- const B = new BN ( setLengthRight ( data . slice ( bStart . toNumber ( ) , bEnd . toNumber ( ) ) , bLen . toNumber ( ) ) )
128
- const E = new BN ( setLengthRight ( data . slice ( eStart . toNumber ( ) , eEnd . toNumber ( ) ) , eLen . toNumber ( ) ) )
129
- const M = new BN ( setLengthRight ( data . slice ( mStart . toNumber ( ) , mEnd . toNumber ( ) ) , mLen . toNumber ( ) ) )
130
-
131
169
let R
132
170
if ( M . isZero ( ) ) {
133
171
R = new BN ( 0 )
0 commit comments