from mythril . laser . smt import Solver , symbol_factory , UGT , UGE , ULT , ULE
import z3
import pytest
import operator
@pytest . mark . parametrize (
" operation,expected " ,
[
( operator . add , z3 . unsat ) ,
( operator . sub , z3 . unsat ) ,
( operator . and_ , z3 . sat ) ,
( operator . or_ , z3 . sat ) ,
( operator . xor , z3 . unsat ) ,
] ,
)
def test_bitvecfunc_arithmetic ( operation , expected ) :
# Arrange
s = Solver ( )
input_ = symbol_factory . BitVecVal ( 1 , 8 )
bvf = symbol_factory . BitVecFuncSym ( " bvf " , " sha3 " , 256 , input_ = input_ )
x = symbol_factory . BitVecSym ( " x " , 256 )
y = symbol_factory . BitVecSym ( " y " , 256 )
# Act
s . add ( x != y )
s . add ( operation ( bvf , x ) == operation ( y , bvf ) )
# Assert
assert s . check ( ) == expected
@pytest . mark . parametrize (
" operation,expected " ,
[
( operator . eq , z3 . sat ) ,
( operator . ne , z3 . unsat ) ,
( operator . lt , z3 . unsat ) ,
( operator . le , z3 . sat ) ,
( operator . gt , z3 . unsat ) ,
( operator . ge , z3 . sat ) ,
( UGT , z3 . unsat ) ,
( UGE , z3 . sat ) ,
( ULT , z3 . unsat ) ,
( ULE , z3 . sat ) ,
] ,
)
def test_bitvecfunc_bitvecfunc_comparison ( operation , expected ) :
# Arrange
s = Solver ( )
input1 = symbol_factory . BitVecSym ( " input1 " , 256 )
input2 = symbol_factory . BitVecSym ( " input2 " , 256 )
bvf1 = symbol_factory . BitVecFuncSym ( " bvf1 " , " sha3 " , 256 , input_ = input1 )
bvf2 = symbol_factory . BitVecFuncSym ( " bvf2 " , " sha3 " , 256 , input_ = input2 )
# Act
s . add ( operation ( bvf1 , bvf2 ) )
s . add ( input1 == input2 )
# Assert
assert s . check ( ) == expected
def test_bitvecfunc_bitvecfuncval_comparison ( ) :
# Arrange
s = Solver ( )
input1 = symbol_factory . BitVecSym ( " input1 " , 256 )
input2 = symbol_factory . BitVecVal ( 1337 , 256 )
bvf1 = symbol_factory . BitVecFuncSym ( " bvf1 " , " sha3 " , 256 , input_ = input1 )
bvf2 = symbol_factory . BitVecFuncVal ( 12345678910 , " sha3 " , 256 , input_ = input2 )
# Act
s . add ( bvf1 == bvf2 )
# Assert
assert s . check ( ) == z3 . sat
assert s . model ( ) . eval ( input2 . raw ) == 1337
def test_bitvecfunc_nested_comparison ( ) :
# arrange
s = Solver ( )
input1 = symbol_factory . BitVecSym ( " input1 " , 256 )
input2 = symbol_factory . BitVecSym ( " input2 " , 256 )
bvf1 = symbol_factory . BitVecFuncSym ( " bvf1 " , " sha3 " , 256 , input_ = input1 )
bvf2 = symbol_factory . BitVecFuncSym ( " bvf2 " , " sha3 " , 256 , input_ = bvf1 )
bvf3 = symbol_factory . BitVecFuncSym ( " bvf3 " , " sha3 " , 256 , input_ = input2 )
bvf4 = symbol_factory . BitVecFuncSym ( " bvf4 " , " sha3 " , 256 , input_ = bvf3 )
# Act
s . add ( input1 == input2 )
s . add ( bvf2 == bvf4 )
# Assert
assert s . check ( ) == z3 . sat
def test_bitvecfunc_unequal_nested_comparison ( ) :
# arrange
s = Solver ( )
input1 = symbol_factory . BitVecSym ( " input1 " , 256 )
input2 = symbol_factory . BitVecSym ( " input2 " , 256 )
bvf1 = symbol_factory . BitVecFuncSym ( " bvf1 " , " sha3 " , 256 , input_ = input1 )
bvf2 = symbol_factory . BitVecFuncSym ( " bvf2 " , " sha3 " , 256 , input_ = bvf1 )
bvf3 = symbol_factory . BitVecFuncSym ( " bvf3 " , " sha3 " , 256 , input_ = input2 )
bvf4 = symbol_factory . BitVecFuncSym ( " bvf4 " , " sha3 " , 256 , input_ = bvf3 )
# Act
s . add ( input1 != input2 )
s . add ( bvf2 == bvf4 )
# Assert
assert s . check ( ) == z3 . unsat
def test_bitvecfunc_ext_nested_comparison ( ) :
# arrange
s = Solver ( )
input1 = symbol_factory . BitVecSym ( " input1 " , 256 )
input2 = symbol_factory . BitVecSym ( " input2 " , 256 )
input3 = symbol_factory . BitVecSym ( " input3 " , 256 )
input4 = symbol_factory . BitVecSym ( " input4 " , 256 )
bvf1 = symbol_factory . BitVecFuncSym ( " bvf1 " , " sha3 " , 256 , input_ = input1 )
bvf2 = symbol_factory . BitVecFuncSym ( " bvf2 " , " sha3 " , 256 , input_ = bvf1 + input3 )
bvf3 = symbol_factory . BitVecFuncSym ( " bvf3 " , " sha3 " , 256 , input_ = input2 )
bvf4 = symbol_factory . BitVecFuncSym ( " bvf4 " , " sha3 " , 256 , input_ = bvf3 + input4 )
# Act
s . add ( input1 == input2 )
s . add ( input3 == input4 )
s . add ( bvf2 == bvf4 )
# Assert
assert s . check ( ) == z3 . sat
def test_bitvecfunc_ext_unequal_nested_comparison ( ) :
# Arrange
s = Solver ( )
input1 = symbol_factory . BitVecSym ( " input1 " , 256 )
input2 = symbol_factory . BitVecSym ( " input2 " , 256 )
input3 = symbol_factory . BitVecSym ( " input3 " , 256 )
input4 = symbol_factory . BitVecSym ( " input4 " , 256 )
bvf1 = symbol_factory . BitVecFuncSym ( " bvf1 " , " sha3 " , 256 , input_ = input1 )
bvf2 = symbol_factory . BitVecFuncSym ( " bvf2 " , " sha3 " , 256 , input_ = bvf1 + input3 )
bvf3 = symbol_factory . BitVecFuncSym ( " bvf3 " , " sha3 " , 256 , input_ = input2 )
bvf4 = symbol_factory . BitVecFuncSym ( " bvf4 " , " sha3 " , 256 , input_ = bvf3 + input4 )
# Act
s . add ( input1 == input2 )
s . add ( input3 != input4 )
s . add ( bvf2 == bvf4 )
# Assert
assert s . check ( ) == z3 . unsat
def test_bitvecfunc_ext_unequal_nested_comparison_f ( ) :
# Arrange
s = Solver ( )
input1 = symbol_factory . BitVecSym ( " input1 " , 256 )
input2 = symbol_factory . BitVecSym ( " input2 " , 256 )
input3 = symbol_factory . BitVecSym ( " input3 " , 256 )
input4 = symbol_factory . BitVecSym ( " input4 " , 256 )
bvf1 = symbol_factory . BitVecFuncSym ( " bvf1 " , " sha3 " , 256 , input_ = input1 )
bvf2 = symbol_factory . BitVecFuncSym ( " bvf2 " , " sha3 " , 256 , input_ = bvf1 + input3 )
bvf3 = symbol_factory . BitVecFuncSym ( " bvf3 " , " sha3 " , 256 , input_ = input2 )
bvf4 = symbol_factory . BitVecFuncSym ( " bvf4 " , " sha3 " , 256 , input_ = bvf3 + input4 )
# Act
s . add ( input1 != input2 )
s . add ( input3 == input4 )
s . add ( bvf2 == bvf4 )
# Assert
assert s . check ( ) == z3 . unsat
def test_bitvecfunc_find_input ( ) :
# Arrange
s = Solver ( )
input1 = symbol_factory . BitVecSym ( " input1 " , 256 )
input2 = symbol_factory . BitVecSym ( " input2 " , 256 )
bvf1 = symbol_factory . BitVecFuncSym ( " bvf1 " , " sha3 " , 256 , input_ = input1 )
bvf2 = symbol_factory . BitVecFuncSym ( " bvf3 " , " sha3 " , 256 , input_ = input2 )
# Act
s . add ( input1 == symbol_factory . BitVecVal ( 1 , 256 ) )
s . add ( bvf1 == bvf2 )
# Assert
assert s . check ( ) == z3 . sat
assert s . model ( ) [ input2 . raw ] == 1
def test_bitvecfunc_nested_find_input ( ) :
# Arrange
s = Solver ( )
input1 = symbol_factory . BitVecSym ( " input1 " , 256 )
input2 = symbol_factory . BitVecSym ( " input2 " , 256 )
bvf1 = symbol_factory . BitVecFuncSym ( " bvf1 " , " sha3 " , 256 , input_ = input1 )
bvf2 = symbol_factory . BitVecFuncSym ( " bvf2 " , " sha3 " , 256 , input_ = bvf1 )
bvf3 = symbol_factory . BitVecFuncSym ( " bvf3 " , " sha3 " , 256 , input_ = input2 )
bvf4 = symbol_factory . BitVecFuncSym ( " bvf4 " , " sha3 " , 256 , input_ = bvf3 )
# Act
s . add ( input1 == symbol_factory . BitVecVal ( 123 , 256 ) )
s . add ( bvf2 == bvf4 )
# Assert
assert s . check ( ) == z3 . sat
assert s . model ( ) [ input2 . raw ] == 123