fix modexp
This commit is contained in:
parent
a86979eaa3
commit
cd7143e9af
|
@ -54,21 +54,30 @@ func cleanMemRef*(x: UInt256): int {.inline.} =
|
|||
return high(int32) shr 2
|
||||
return x.toInt
|
||||
|
||||
proc rangeToPadded*[T: StUint](x: openarray[byte], first, last: int): T =
|
||||
proc rangeToPadded*[T: StUint](x: openarray[byte], first, last: int, toLen = 0): T =
|
||||
## Convert take a slice of a sequence of bytes interpret it as the big endian
|
||||
## representation of an Uint256. Use padding for sequence shorter than 32 bytes
|
||||
## including 0-length sequences.
|
||||
const N = T.bits div 8
|
||||
|
||||
let lo = max(0, first)
|
||||
let hi = min(min(x.high, last), (lo+T.bits div 8)-1)
|
||||
let hi = min(min(x.high, last), (lo+N)-1)
|
||||
|
||||
if not(lo <= hi):
|
||||
return # 0
|
||||
|
||||
result = T.fromBytesBE(
|
||||
x.toOpenArray(lo, hi),
|
||||
allowPadding = true
|
||||
)
|
||||
if toLen > hi-lo+1:
|
||||
var temp: array[N, byte]
|
||||
temp[0..hi-lo] = x.toOpenArray(lo, hi)
|
||||
result = T.fromBytesBE(
|
||||
temp,
|
||||
allowPadding = true
|
||||
)
|
||||
else:
|
||||
result = T.fromBytesBE(
|
||||
x.toOpenArray(lo, hi),
|
||||
allowPadding = true
|
||||
)
|
||||
|
||||
# calculates the memory size required for a step
|
||||
func calcMemSize*(offset, length: int): int {.inline.} =
|
||||
|
|
|
@ -133,11 +133,10 @@ proc identity*(computation: BaseComputation) =
|
|||
proc modExpInternal(computation: BaseComputation, base_len, exp_len, mod_len: int, T: type StUint) =
|
||||
template rawMsg: untyped {.dirty.} =
|
||||
computation.msg.data
|
||||
|
||||
let
|
||||
base = rawMsg.rangeToPadded[:T](96, 95 + base_len)
|
||||
exp = rawMsg.rangeToPadded[:T](96 + base_len, 95 + base_len + exp_len)
|
||||
modulo = rawMsg.rangeToPadded[:T](96 + base_len + exp_len, 95 + base_len + exp_len + mod_len)
|
||||
base = rawMsg.rangeToPadded[:T](96, 95 + base_len, base_len)
|
||||
exp = rawMsg.rangeToPadded[:T](96 + base_len, 95 + base_len + exp_len, exp_len)
|
||||
modulo = rawMsg.rangeToPadded[:T](96 + base_len + exp_len, 95 + base_len + exp_len + mod_len, mod_len)
|
||||
|
||||
block: # Gas cost
|
||||
func gasModExp_f(x: Natural): int =
|
||||
|
@ -179,9 +178,9 @@ proc modExpInternal(computation: BaseComputation, base_len, exp_len, mod_len: in
|
|||
func zero(): static array[T.bits div 8, byte] = discard
|
||||
func one(): static array[T.bits div 8, byte] =
|
||||
when cpuEndian == bigEndian:
|
||||
result[^1] = 1
|
||||
else:
|
||||
result[0] = 1
|
||||
else:
|
||||
result[^1] = 1
|
||||
|
||||
# Start with EVM special cases
|
||||
let output = if modulo <= 1:
|
||||
|
@ -216,7 +215,6 @@ proc modExp*(computation: BaseComputation) =
|
|||
mod_len = rawMsg.rangeToPadded[:Uint256](64, 95).safeInt
|
||||
|
||||
let maxBytes = max(base_len, max(exp_len, mod_len))
|
||||
|
||||
if maxBytes <= 32:
|
||||
computation.modExpInternal(base_len, exp_len, mod_len, UInt256)
|
||||
elif maxBytes <= 64:
|
||||
|
|
Loading…
Reference in New Issue