fix modexp

This commit is contained in:
andri lim 2019-05-08 21:37:09 +07:00 committed by zah
parent a86979eaa3
commit cd7143e9af
2 changed files with 20 additions and 13 deletions

View File

@ -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.} =

View File

@ -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: