Source code for mythril.laser.ethereum.function_managers.exponent_function_manager

import logging
from typing import Tuple


from mythril.laser.smt import And, BitVec, Bool, Function, URem, symbol_factory

log = logging.getLogger(__name__)


[docs]class ExponentFunctionManager: """ Uses an uninterpreted function for exponentiation with the following properties: 1) power(a, b) > 0 2) if a = 256 => forall i if b = i then power(a, b) = (256 ^ i) % (2^256) Only these two properties are added as to handle indexing of boolean arrays. Caution should be exercised when increasing the conditions since it severely affects the solving time. """ def __init__(self): power = Function("Power", [256, 256], 256) NUMBER_256 = symbol_factory.BitVecVal(256, 256) self.concrete_constraints = And( *[ power(NUMBER_256, symbol_factory.BitVecVal(i, 256)) == symbol_factory.BitVecVal(256**i, 256) for i in range(0, 32) ] )
[docs] def create_condition(self, base: BitVec, exponent: BitVec) -> Tuple[BitVec, Bool]: """ Creates a condition for exponentiation :param base: The base of exponentiation :param exponent: The exponent of the exponentiation :return: Tuple of condition and the exponentiation result """ power = Function("Power", [256, 256], 256) exponentiation = power(base, exponent) if exponent.symbolic is False and base.symbolic is False: const_exponentiation = symbol_factory.BitVecVal( pow(base.value, exponent.value, 2**256), 256, annotations=base.annotations.union(exponent.annotations), ) constraint = const_exponentiation == exponentiation return const_exponentiation, constraint constraint = exponentiation > 0 constraint = And(constraint, self.concrete_constraints) if base.value == 256: constraint = And( constraint, power(base, URem(exponent, symbol_factory.BitVecVal(32, 256))) == power(base, exponent), ) return exponentiation, constraint
exponent_function_manager = ExponentFunctionManager()