Exemple #1
0
 def Function(self, *args):
     return z3.Function(*args)
Exemple #2
0
def z3_set_interface(vertex):
    """Assign an interface to a router"""
    return z3.Function('SetInterface', vertex, vertex, z3.BoolSort())
Exemple #3
0
def z3_set_link(vertex):
    """Creates a physical ethernet link between two interfaces"""
    return z3.Function('SetLink', vertex, vertex, z3.BoolSort())
Exemple #4
0
def z3_is_interface(vertex):
    """Returns True if the vertex is of type interface"""
    return z3.Function('IsInterface', vertex, z3.BoolSort())
Exemple #5
0
def z3_is_bgp_node(vertex):
    """Returns True if the vertex is configured to be BGP router"""
    return z3.Function('IsBGPNode', vertex, z3.BoolSort())
Exemple #6
0
def native_symbol(sym):
    if isinstance(sym.sort, ConstantSort):
        return z3.Const(sym.rep, name.sort.to_z3())
    return z3.Function(sym.rep, *(name.sort.to_z3()))
Exemple #7
0
 def reset(self):
     args = []
     for _ in range(self.arity):
         args.append(z3.BoolSort())
     args.append(z3.BoolSort())
     self.__z3__ = z3.Function(self.name, *args)  # e.g. continuous(x)
# expr = exprparse('IsTruthy(isint(c) and isint(d))')
# rewritten = basic_simplifier.rewrite(expr)
# print('rewrite engine test', unparse(expr), unparse(rewritten))

PyFunc = z3.DeclareSort('PyFunc')
Unk = z3.Datatype('Unk')
Unk.declare('none')
Unk.declare('bool', ('tobool', z3.BoolSort()))
Unk.declare('int', ('toint', z3.IntSort()))
Unk.declare('string', ('tostring', z3.StringSort()))
Unk.declare('func', ('tofunc', PyFunc))
Unk.declare('app', ('tl', Unk), ('hd', Unk))
Unk.declare('_')  # empty tuple
Unk.declare('undef')  # error value
(Unk, ) = z3.CreateDatatypes(Unk)
App = z3.Function('.', Unk, Unk, Unk)


class ZHolder():
    pass


Z = ZHolder()
Z.Wrapbool = Unk.bool
Z.Wrapint = Unk.int
Z.Wrapstring = Unk.string
Z.Wrapfunc = Unk.func
Z.Wrapnone = Unk.none
Z.Bool = Unk.tobool
Z.Int = Unk.toint
Z.String = Unk.tostring
Exemple #9
0
    return ret

static_strings = ["redpwn", "ctf2020"]
static_longs = [8248156489741230770, -5342668067454976247, -889275714, -559038737]

static_nums = [calc_sum(l) for l in static_strings]

flag = []
for i in range(32 + 6): # we know flag is at most 32 chars
    flag.append(z3.BitVec(f'flag_{i}', 8)) # char is 8 bits

begin = "flag{"

s = z3.Solver()

parse_byte = z3.Function('parse_byte', z3.BitVecSort(16), z3.BitVecSort(8))

def hex_nibble(num, large):
    if large:
        return ord(f"{num:X}")
    return ord(f"{num:x}")

for i in range(256):
    upper = (i >> 4)
    lower = i & 0xf
    for ul in [False, True]:
        for ll in [False, True]:
            a = hex_nibble(upper, ul)
            b = hex_nibble(lower, ll)
            inp = z3.BitVecVal((a << 8) | b, 16)
            s.add(parse_byte(inp) == i)
Exemple #10
0
 def _toZ3sHelper(self, prefix, rfun):
     isort = z3.BitVecSort(self.iwidth)
     osort = z3.BitVecSort(self.owidth)
     return z3.Function(self._getName(prefix), isort, osort)
Exemple #11
0
    OP_POOL2D_AVG: ('pool2d_avg', ((PM_KERNEL_H, {3}), (PM_KERNEL_W, {3}), (PM_STRIDE_H, {1, 2}), (PM_STRIDE_W, {1,2}), (PM_PAD, {0,1})), 1, 1, {4}),
    OP_RELU: ('relu', (), 1, 1, {2, 3, 4}),
    OP_CONCAT: ('concat', ((PM_AXIS, {0, 1, 2, 3}),), 2, 1, {2,3,4}),
    OP_SPLIT: ('split', ((PM_AXIS, {0, 1, 2, 3}),), 1, 2, {2,3,4}),
    OP_TRANSPOSE: ('transpose', (), 1, 1, {2}),
    OP_ENLARGE: ('enlarge', ((PM_KERNEL_H, {3}), (PM_KERNEL_W, {3})), 1, 1, {4}),
    OP_EW_ADD: ('ewadd', (), 2, 1, {2,3,4}),
    OP_EW_MUL: ('ewmul', (), 2, 1, {2,3,4}),
    OP_MATMUL: ('matmul', (), 2, 1, {2}),
    OP_MUL: ('scalar_mul', (), 2, 1, {2, 3, 4}) # multiply a tensor (first argument) with a scalar (0-D tensor)
}

for d in operator_data.values():
    for i in range(d[3]):
        name = '{}_{}'.format(d[0], i)
        globals()[name] = z3.Function(name, *( len(d[1]) * [P] + d[2] * [T] + [T]))

x,y,z,w, one = z3.Consts('x y z w one', T)
sx, sy, kx, ky, pad, acti, ax = z3.Consts('sx sy kx ky pad acti ax', P)

N = [1,2,3,4] # change this to control number of combinations for symbolic validation, e.g., [1,2], [1,3] or [3,4] each provide a reasonable experiment to run and go for coffee (assuming 8 cores)
D = [1,3]

# list of axioms with list of possible values for verify_axioms.py. possible values are actual values for parameters, and shapes for tensors
axioms = [

    # ewadd and ewmul are associative, commutative and distributive

    # ewadd is associative
    (ForAll([x,y,z], ewadd_0(x,ewadd_0(y, z)) == ewadd_0(ewadd_0(x,y),z)),
     lambda : [(s,s,s) for dim in [2,3,4] for s in product(N, repeat=dim)] ),
Exemple #12
0
def FreshFunction(name, *args, **kwargs):
    return z3.Function(fresh_name(name), *args, **kwargs)
Exemple #13
0
 def as_z3(self):
     return z3.Function(self.name, *self.sorts, z3.BoolSort())(
         *(a.as_z3() for a in self.arguments)
     )
Exemple #14
0
def process_configuration_smt (configuration, port):
  """For now this just focuses on one port, will worry about ports later (actually multiple ports could probably just
  be done by first running one port at a time then optimizing to combine into ranges"""
  # Get all security groups
  secgroup_all = configuration.secgroup_map.keys()
  # Create a finite type over security groups
  sg_node, sg_nodes = z3.EnumSort ("sg", secgroup_all)
  nodes = dict(zip(secgroup_all, sg_nodes))
  # Two reachability function: d_reach is for immediate reachability, reach is for indirect reachabilty.
  d_reach = z3.Function('d_reach', sg_node, sg_node, z3.BoolSort())
  reach = z3.Function('reach', sg_node, sg_node, z3.BoolSort())

  # Some axioms for what is allowed
  axioms = []
  sg1 = z3.Const('s1', sg_node)
  sg2 = z3.Const('s2', sg_node)
  sg3 = z3.Const('s3', sg_node)
  previously_unallowed = []
  
  max_hops = len(secgroup_all) + 1
  closure_properties = []
  for i in xrange(0, max_hops):
    temp = [z3.Const('s_%d'%j, sg_node) for j in xrange(i)]
    vals = list(temp)
    temp.append(sg2)
    temp = [sg1] + temp
    path = map(lambda (a, b): d_reach(a, b), zip(temp, temp[1:]))
    print path
    if vals:
      closure_properties.append(z3.Exists(vals, z3.And(path)))
    else:
      closure_properties.append(z3.And(path))

  axioms.append(z3.ForAll([sg1, sg2], z3.Implies(reach(sg1, sg2), \
      z3.Or(sg1 == sg2, \
            *closure_properties))))
  axioms.append(z3.ForAll([sg1, sg2, sg3], z3.Implies(z3.And(reach(sg1, sg2), reach(sg2, sg3)),\
                                                       reach(sg1, sg3))))
  axioms.append(z3.ForAll([sg1, sg2], z3.Implies(d_reach(sg1, sg2), reach(sg1, sg2))))
  axioms.append(z3.ForAll([sg1], reach(sg1, sg1)))
  axioms.append(z3.ForAll([sg1], z3.Or(map(lambda s: sg1 == s, sg_nodes))))

  ints = []
  # Look at the combination of things that are or are not allowed.
  for (s1, s2) in combinations(secgroup_all, 2):
    if configuration.connection_allowed_secgroups(s1, s2, port): 
      axioms.append(d_reach(nodes[s1], nodes[s2])) 
    else:
      var = z3.Int('c_%s_%s'%(s1, s2))
      axioms.append(z3.Not(d_reach(nodes[s1], nodes[s2])) == (var == 0))
      axioms.append(d_reach(nodes[s1], nodes[s2]) == (var == 1))
      ints.append(var)
      previously_unallowed.append((s1, s2))
    if configuration.connection_allowed_secgroups(s2, s1, port): 
      axioms.append(d_reach(nodes[s2], nodes[s1])) 
    else:
      var = z3.Int('c_%s_%s'%(s2, s1))
      axioms.append(d_reach(nodes[s2], nodes[s1]) == (var == 1))
      axioms.append(z3.Not(d_reach(nodes[s2], nodes[s1])) == (var == 0))
      ints.append(var)
      previously_unallowed.append((s2, s1))
  new_rules = z3.Int('rule')
  axioms.append(new_rules == z3.Sum(ints))
  solver = z3.Solver()
  solver.append(axioms)
  class SolverInstance (object):
    """ The object returned after processing the configuration that can be queried to find solutions"""
    def __init__(self):
      self.solver = solver
      self.nodes = nodes
      self.reach = reach
      self.d_reach = d_reach
      self.axioms = axioms
      self.port = port
      self.solver.push()
      self.configuration = configuration
      self.previously_unallowed = previously_unallowed
      self.ints = ints
      self.new_rules = new_rules
    def reset_new_conditions (self):
      """Forget about any of the requirements specified thus far"""
      self.solver.pop()
      self.solver.push()

    def require_direct_connection (self, sg1, sg2):
      """Require that the configuration allows direct connection between two groups"""
      self.solver.append(self.d_reach(self.nodes[sg1], self.nodes[sg2]))

    def require_indirect_connection (self, sg1, sg2):
      """Require that their exist some path that allows connectivity between two groups"""
      self.solver.append(self.reach(self.nodes[sg1], self.nodes[sg2]))

    def disallow_direct_connection (self, sg1, sg2):
      """Disallow any form of direct connectivity between two security groups"""
      self.solver.append(z3.Not(self.d_reach(self.nodes[sg1], self.nodes[sg2])))

    def disallow_indirect_connection (self, sg1, sg2):
      """Disallow indirect connectivity, i.e., make sure there is no indirect reachability"""
      self.solver.append(z3.Not(self.reach(self.nodes[sg1], self.nodes[sg2])))
    
    def disallow_new_direct_inbound_connections (self, sg):
      """Disallow any new direct connections to this security group (basically don't consider solutions where one would
      allow new connections to this group"""
      consider = filter(lambda (a, b): b == sg, self.previously_unallowed)
      for (a, b) in consider:
        self.disallow_direct_connection(a, b)
    
    def disallow_new_indirect_inbound_connections (self, sg):
      """Disallow any new indirect connections to this security group (basically don't consider solutions where one 
      would allow new connections to this group"""
      consider = filter(lambda (a, b): b == sg, self.previously_unallowed)
      for (a, b) in consider:
        self.disallow_indirect_connection(a, b)
    
    def disallow_new_direct_outbound_connections (self, sg):
      consider = filter(lambda (a, b): a == sg, self.previously_unallowed)
      for (a, b) in consider:
        self.disallow_direct_connection(a, b)
    
    def disallow_new_indirect_outbound_connections (self, sg):
      consider = filter(lambda (a, b): a == sg, self.previously_unallowed)
      for (a, b) in consider:
        self.disallow_indirect_connection(a, b)

    def check_and_interpret (self):
      """Synthesize configuration based on current parameters"""
      #result = self.solver.check()
      for i in xrange(1, len(self.previously_unallowed) + 1):
          solver.push()
          solver.append(self.new_rules < i)
          result = solver.check()
          if result == z3.sat:
            print "Found a result at %d"%(i)
            break
          else:
            solver.pop()
            print "Trying with %d rule changes"%(i)
      if result != z3.sat:
        print "Failed to check" # Really in this case we should be extracting the unsat core and trying to figure out
                                # what is conflicting. This seems useful for users (also maybe allows us to deal with
                                # deletions).
        return
      model = self.solver.model()
      solver.pop()
      fixes = []
      for (sg1, sg2) in self.previously_unallowed:
        if z3.is_true(model.evaluate(self.d_reach(self.nodes[sg1], self.nodes[sg2]))):
          print "Result will connect %s ---> %s directly"%(sg1, sg2)
          fixes.append(self.configuration.direct_connection_fix_sg(sg1, sg2, self.port))
      print "Fix is thus\n\t%s"%('\n\t'.join(map(str, fixes)))

  return SolverInstance()
Exemple #15
0
import sys
import fractions

Forall, And, Implies = z3.ForAll, z3.And, z3.Implies

####################################################################################################
#
# These are the examples discussed in section 6 of the paper.
#
####################################################################################################

a, b, c, d, e, i, K, m, n = z3.Reals('a b c d e i K m n')
r, s, t, u, v, w, x, y, z = z3.Reals('r s t u v w x y z')
eps = z3.Real('eps')

f = z3.Function('f', z3.RealSort(), z3.RealSort())
h = z3.Function('h', z3.RealSort(), z3.RealSort(), z3.RealSort())
g = z3.Function('g', z3.RealSort(), z3.RealSort(), z3.RealSort(),
                z3.RealSort())
log = z3.Function('log', z3.RealSort(), z3.RealSort())
exp = z3.Function('exp', z3.RealSort(), z3.RealSort())
ceil = z3.Function('ceil', z3.RealSort(), z3.RealSort())
abs = z3.Function('abs', z3.RealSort(), z3.RealSort())

# #mins = [z3.Function('min2', z3.RealSort(), z3.RealSort(), z3.RealSort()),
#         z3.Function('min2', z3.RealSort(), z3.RealSort(), z3.RealSort(), z3.RealSort()),
#         z3.Function('min2', z3.RealSort(), z3.RealSort(), z3.RealSort(), z3.RealSort(),
#                     z3.RealSort()),
#         z3.Function('min2', z3.RealSort(), z3.RealSort(), z3.RealSort(), z3.RealSort(),
#                     z3.RealSort(), z3.RealSort())
#  #       ]
Exemple #16
0
def Function(name, *params):
    return z3.Function(name, *params)
Exemple #17
0
    z3_sorts[us.rep] = s
    z3_sorts_inv[get_id(s)] = us
    return s


def functionsort(fs):
    #    print "fs.rng = {!r}".format(fs.rng)
    if fs.is_relational():
        return [s.to_z3() for s in fs.dom] + [z3.BoolSort()]
    return [s.to_z3() for s in fs.dom] + [fs.rng.to_z3()]


ivy_logic.UninterpretedSort.to_z3 = uninterpretedsort
ivy_logic.FunctionSort.to_z3 = functionsort
ivy_logic.Symbol.to_z3 = lambda s: z3.Const(s.name, s.sort.to_z3(
)) if s.sort.dom == [] else z3.Function(s.name, s.sort.to_z3())


def lookup_native(name, table, kind):
    z3name = ivy_logic.sig.interp.get(name)
    if z3name == None:
        return None
    z3val = table.get(z3name)
    if z3val == None:
        raise iu.IvyError(None,
                          '{} is not a supported Z3 {}'.format(name, kind))
    return z3val


# TODO: this seems wrong: why return a constant?
def native_symbol(sym):
Exemple #18
0
    def _eval_sep(self, state: State,
                  st_prefix: str) -> Tuple[List[z3.ExprRef], z3.ExprRef]:
        '''
        create new state variable add assertions enforcing its value
        '''
        def p(st: str, must_be_new: bool = True) -> str:
            st = st_prefix + '_' + st
            assert (not must_be_new) or st not in self.seen, (st, self.seen)
            self.seen.add(st)
            return st

        assertions: List[z3.ExprRef] = []  # will be added to the solver
        state_models_sep = z3.Bool(
            p('models_sep'))  # will become self.state_vs[i]

        # create z3 symbols for all relations, functions, and constants, and assert their meaning

        # create universe unary relations
        scope = max(len(elems) for elems in state.univs.values())
        V = z3.Datatype(p('elements'))

        def e(i: int) -> str:
            return f'e{i}'

        for i in range(scope):
            V.declare(e(i))
        V = V.create()

        def is_e(i: int) -> z3.FuncDeclRef:
            return getattr(V, 'is_' + e(i))

        def ee(i: int) -> z3.ExprRef:
            return getattr(V, e(i))

        universes = {
            s.name: z3.Function(p(s.name), V, z3.BoolSort())
            for s in state.univs
        }
        elem_to_z3: Dict[str, z3.ExprRef] = {}
        for s, elems in state.univs.items():
            assertions.extend(universes[s.name](ee(i))
                              for i in range(len(elems)))
            assertions.extend(
                z3.Not(universes[s.name](ee(i)))
                for i in range(len(elems), scope))
            for i, elem in enumerate(elems):
                assert elem not in elem_to_z3
                elem_to_z3[elem] = ee(i)

        # create relations
        def lit(e: z3.ExprRef, polarity: bool) -> z3.ExprRef:
            return e if polarity else z3.Not(e)

        relations: Dict[str, Union[z3.ExprRef, z3.FuncDeclRef]] = {
            r.name:
            z3.Function(p(r.name), *repeat(V, len(r.arity)), z3.BoolSort())
            if len(r.arity) > 0 else z3.Bool(p(r.name))
            for r in state.rel_interps
        }
        for r, ri in state.rel_interps.items():
            if len(r.arity) == 0:
                assert len(ri) == 1 and () in ri, (r, ri)
                a = relations[r.name]
                assert isinstance(a, z3.ExprRef)
                assertions.append(lit(a, ri[()]))
            else:
                for tup, polarity in ri.items():
                    a = relations[r.name]
                    assert isinstance(a, z3.FuncDeclRef)
                    args = [elem_to_z3[x] for x in tup]
                    assertions.append(lit(a(*args), polarity))

        # create functions
        assert all(len(f.arity) > 0 for f in state.func_interps)
        functions: Dict[str, z3.FuncDeclRef] = {
            f.name: z3.Function(p(f.name), *repeat(V, len(f.arity)), V)
            for f in state.func_interps
        }
        for f, fi in state.func_interps.items():
            for tup, img in fi.items():
                args = [elem_to_z3[x] for x in tup]
                assertions.append(functions[f.name](*args) == elem_to_z3[img])

        # create constants
        constants: Dict[str, z3.ExprRef] = {
            c.name: z3.Const(p(c.name), V)
            for c in state.const_interps
        }
        for c, ci in state.const_interps.items():
            assertions.append(constants[c.name] == elem_to_z3[ci])

        # now force state_models_sep
        z3_vs = [z3.Const(p(f'V{i}'), V) for i in range(len(self.vs))]

        def to_z3(e: Expr) -> z3.ExprRef:
            if isinstance(e, Id):
                if e.name in self.var_names:
                    return z3_vs[self.var_names.index(e.name)]
                elif e.name in constants:
                    return constants[e.name]
                elif e.name in relations and isinstance(
                        r := relations[e.name], z3.ExprRef):
                    return r
                else:
                    assert False, e
            elif isinstance(e, AppExpr) and e.callee in functions:
                return functions[e.callee](*(map(to_z3, e.args)))
Exemple #19
0
def Function(name: str, *params: z3.SortRef) -> z3.FuncDeclRef:
    return z3.Function(name, *params)
Exemple #20
0
def _handleNum(state,left,right,op):
    # Match our object types
    leftZ3Object,rightZ3Object = pyState.z3Helpers.z3_matchLeftAndRight(left,right,op)

    # Figure out what the op is and add constraint
    if type(op) == ast.Add:
        if type(left) is BitVec:
            # Check for over and underflows
            state.solver.add(pyState.z3Helpers.bvadd_safe(leftZ3Object,rightZ3Object))

        # Keep this out of the Z3 solver!
        if left.isStatic() and right.isStatic():
            ret = left.getValue() + right.getValue()

        else:
            ret = leftZ3Object + rightZ3Object

    elif type(op) == ast.Sub:
        if type(left) is BitVec:
            state.solver.add(pyState.z3Helpers.bvsub_safe(leftZ3Object,rightZ3Object))

        # Keep this out of the Z3 solver!
        if left.isStatic() and right.isStatic():
            ret = left.getValue() - right.getValue()

        else:
            ret = leftZ3Object - rightZ3Object

    elif type(op) == ast.Mult:
        if type(left) is BitVec:
            state.solver.add(pyState.z3Helpers.bvmul_safe(leftZ3Object,rightZ3Object))

        # Keep this out of the Z3 solver!
        if left.isStatic() and right.isStatic():
            ret = left.getValue() * right.getValue()

        else:
            ret = leftZ3Object * rightZ3Object

    elif type(op) == ast.Div:
        if type(left) is BitVec:
            state.solver.add(pyState.z3Helpers.bvdiv_safe(leftZ3Object,rightZ3Object))

        # Keep this out of the Z3 solver!
        if left.isStatic() and right.isStatic():
            ret = left.getValue() / right.getValue()

        else:
            ret = leftZ3Object / rightZ3Object

    elif type(op) == ast.Mod:
        # Z3 doesn't have native support for Real type modular arithmetic
        if z3.is_real(leftZ3Object):
            constraint = []
            if z3.is_real(rightZ3Object):
                mod = z3.Function('mod', z3.RealSort(),z3.RealSort(), z3.RealSort())
                quot = z3.Function('quot', z3.RealSort(),z3.RealSort(), z3.RealSort())
                constraint += [pyState.z3Helpers.isInt(rightZ3Object)]
            else:
                mod = z3.Function('mod', z3.RealSort(),z3.IntSort(), z3.RealSort())
                quot = z3.Function('quot', z3.RealSort(),z3.IntSort(), z3.RealSort())
            constraint.append(0 <= mod(leftZ3Object,rightZ3Object))
            constraint.append(mod(leftZ3Object,rightZ3Object) < rightZ3Object)
            constraint.append(rightZ3Object * quot(leftZ3Object,rightZ3Object) + mod(leftZ3Object,rightZ3Object) == leftZ3Object)
            constraint.append(pyState.z3Helpers.isInt(quot(leftZ3Object,rightZ3Object)))
            constraint.append(pyState.z3Helpers.isInt(leftZ3Object))
            constraint.append(leftZ3Object >= 0)
            state.addConstraint(z3.And(constraint))
            """
            state.addConstraint(0 <= mod(leftZ3Object,rightZ3Object))
            state.addConstraint(mod(leftZ3Object,rightZ3Object) < rightZ3Object)
            state.addConstraint(rightZ3Object * quot(leftZ3Object,rightZ3Object) + mod(leftZ3Object,rightZ3Object) == leftZ3Object)
            state.addConstraint(pyState.z3Helpers.isInt(quot(leftZ3Object,rightZ3Object)))
            state.addConstraint(pyState.z3Helpers.isInt(leftZ3Object))
            state.addConstraint(leftZ3Object >= 0)
            """
            ret = mod(leftZ3Object,rightZ3Object)

        else:

            # Keep this out of the Z3 solver!
            if left.isStatic() and right.isStatic():
                ret = left.getValue() % right.getValue()

            else:
                ret = leftZ3Object % rightZ3Object

    elif type(op) == ast.BitXor:

        # Keep this out of the Z3 solver!
        if left.isStatic() and right.isStatic():
            ret = left.getValue() ^ right.getValue()

        else:
            ret = leftZ3Object ^ rightZ3Object

    elif type(op) == ast.BitOr:

        # Keep this out of the Z3 solver!
        if left.isStatic() and right.isStatic():
            ret = left.getValue() | right.getValue()

        else:
            ret = leftZ3Object | rightZ3Object

    elif type(op) == ast.BitAnd:
        # Keep this out of the Z3 solver!
        if left.isStatic() and right.isStatic():
            ret = left.getValue() & right.getValue()

        else:
            ret = leftZ3Object & rightZ3Object

    elif type(op) == ast.LShift:
        # Keep this out of the Z3 solver!
        if left.isStatic() and right.isStatic():
            ret = left.getValue() << right.getValue()

        else:
            ret = leftZ3Object << rightZ3Object

    elif type(op) == ast.RShift:

        # Keep this out of the Z3 solver!
        if left.isStatic() and right.isStatic():
            ret = left.getValue() >> right.getValue()

        else:
            ret = leftZ3Object >> rightZ3Object

    # TODO: This one will fail if we use BitVecs.. Maybe think about check/convert?
    elif type(op) == ast.Pow:

        # Keep this out of the Z3 solver!
        if left.isStatic() and right.isStatic():
            ret = left.getValue() ** right.getValue()

        # Z3 has some problems with forms of x ** 0.5, let's try to change it for Z3...
        elif type(rightZ3Object) is z3.RatNumRef and rightZ3Object.numerator().as_long() == 1 and rightZ3Object.denominator().as_long() > 1:
            tmp = state.getVar("tempRootVar",ctx=1,varType=Real)
            # Rewrite as x ** 2 == y form
            state.addConstraint(tmp.getZ3Object(increment=True) ** float(rightZ3Object.denominator().as_long()) == leftZ3Object)
            # Because we're dealing with square, let's make sure it's positive
            state.addConstraint(tmp.getZ3Object() >= 0)
            ret = tmp.getZ3Object()

        else:
            ret = leftZ3Object ** rightZ3Object
            #ret = leftZ3Object ** rightZ3Object

    else:
        err = "BinOP: Don't know how to handle op type {0} at line {1} col {2}".format(type(op),op.lineno,op.col_offset)
        logger.error(err)
        raise Exception(err)

    # TODO: Clean up code below...
    # Duplicate the object and create a pyObjectManager object
    left_t,left_args = pyState.duplicateSort(leftZ3Object)
    right_t,right_args = pyState.duplicateSort(rightZ3Object)
    if left_t in [Int,Real,BitVec] and right_t in [Int, Real, BitVec]:
        # Not handling this case well right now
        if left_t is Real or right_t is Real:
            args = left_args if left_t is Real else right_args
            # We want variables, not constants
            args.pop("value",None) if args is not None else None
            retVar = state.getVar(varName='BinOpTemp',varType=Real,kwargs = args)

        else:
            left_args.pop("value",None) if left_args is not None else None
            retVar = state.getVar(varName='BinOpTemp',varType=left_t,kwargs = left_args)

        retVar.increment()

        # Now that we have a clean variable to return, add constraints and return it
        logger.debug("Adding constraint {0} == {1}".format(retVar.getZ3Object(),ret))

        # If it turns out we're dealing with constants, just set it directly.
        if type(ret) in [int,float]:
            retVar.setTo(ret)
        else:
            state.addConstraint(retVar.getZ3Object() == ret)

        #print([x for x in state.solver.assertions()])
        return [retVar.copy()]

    else:
        err = "BinOP: Don't know how to handle variable type {0} at line {1} col {2}".format(t,op.lineno,op.col_offset)
        logger.error(err)
        raise Exception(err)
Exemple #21
0
def z3_is_node(vertex):
    """Returns True if the vertex is of type node (aka router)"""
    return z3.Function('IsNode', vertex, z3.BoolSort())
Exemple #22
0
def SolveWithConstraintSolver(rows, columns):
  s = z3.Solver()
  grid = z3.Function('grid', z3.IntSort(), z3.IntSort(), z3.BoolSort())

  blocks_by_row = [list() for r in range(len(rows))]
  for r, row in enumerate(rows):
    if not row:
      for c in range(len(columns)):
        s.add(grid(r, c) == False)
      continue
    # Make the blocks.
    for i, clue in enumerate(row):
      block = z3.Int(f'{i} block of {clue} in row {r}')
      block.clue = clue
      blocks_by_row[r].append(block)

    first_block = blocks_by_row[r][0]
    # First block is >= 0.
    s.add(first_block >= 0)
    # Squares before the first block are off.
    for c in range(len(columns)):
      s.add(z3.Implies(c < blocks_by_row[r][0], grid(r, c) == False))

    last_block = blocks_by_row[r][-1]
    # Last block doesn't run off the grid.
    s.add(last_block <= len(columns) - last_block.clue)
    # Squares after the last block are off.
    for c in range(len(columns)):
      s.add(z3.Implies(c >= last_block + last_block.clue, grid(r, c) == False))

    # Tiles in the block are on.
    for block in blocks_by_row[r]:
      for offset in range(block.clue):
        s.add(grid(r, block + offset))
    # Set invariants between pairs of adjacent blocks.
    for i in range(len(blocks_by_row[r]) - 1):
      current_block = blocks_by_row[r][i]
      next_block = blocks_by_row[r][i + 1]
      # The next block is sufficiently far after the current block.
      s.add(next_block > current_block + current_block.clue)
      # Squares between the end of the current block and the start of the next
      # block are off.
      for c in range(len(columns)):
        s.add(
            z3.Implies(
                z3.And(c >= current_block + current_block.clue, c < next_block),
                grid(r, c) == False))

  blocks_by_column = [list() for c in range(len(columns))]
  for c, column in enumerate(columns):
    if not column:
      for r in range(len(rows)):
        s.add(grid(r, c) == False)
      continue
    # Make the blocks.
    for i, clue in enumerate(column):
      block = z3.Int(f'{i} block of {clue} in column {c}')
      block.clue = clue
      blocks_by_column[c].append(block)

    first_block = blocks_by_column[c][0]
    # First block is >= 0.
    s.add(first_block >= 0)
    # Squares before the first block are off.
    for r in range(len(rows)):
      s.add(z3.Implies(r < first_block, grid(r, c) == False))

    last_block = blocks_by_column[c][-1]
    # Last block doesn't run off the grid.
    s.add(last_block <= len(rows) - last_block.clue)
    # Squares after the last block are off.
    for r in range(len(rows)):
      s.add(z3.Implies(r >= last_block + last_block.clue, grid(r, c) == False))

    # Tiles in the block are on.
    for block in blocks_by_column[c]:
      for offset in range(block.clue):
        s.add(grid(block + offset, c))
    # Set invariants between pairs of adjacent blocks.
    for i in range(len(blocks_by_column[c]) - 1):
      current_block = blocks_by_column[c][i]
      next_block = blocks_by_column[c][i + 1]
      # The next block is sufficiently far after the current block.
      s.add(next_block > current_block + current_block.clue)
      # Squares between the end of the current block and the start of the next
      # block are off.
      for r in range(len(rows)):
        s.add(
            z3.Implies(
                z3.And(r >= current_block + current_block.clue, r < next_block),
                grid(r, c) == False))

  answer = s.check()
  if answer != z3.sat:
    print(answer)
    sys.exit(0)

  m = s.model()
  for r in range(len(rows)):
    for c in range(len(columns)):
      if m.eval(grid(r, c)):
        print('██', end='')
      else:
        print('  ', end='')
    print()
Exemple #23
0
def z3_is_network(vertex):
    """Returns True if the vertex is of type network"""
    return z3.Function('IsNetwork', vertex, z3.BoolSort())
Exemple #24
0
ip_b = addresses['ip_b']
ip_f1 = addresses['ip_f1']
ip_f2 = addresses['ip_f2']

packet = z3.DeclareSort('packets')
port = z3.DeclareSort('ports')
body = z3.DeclareSort('body')
time = z3.IntSort()
event = z3.DeclareSort('event')

#src : E -> N
#dst : E -> N
#p : E -> P
#t : E -> T

src = z3.Function('src', event, node)
dst = z3.Function('dst', event, node)
p = z3.Function('p', event, packet)
t = z3.Function('t', event, time)

#src_P : E -> IP
#dst_P : E -> IP
src_P = z3.Function('src_p', event, address)
dst_P = z3.Function('dst_p', event, address)

#sport : E -> Po
#dport : E -> Po
#addrToNode : IP -> N
sport = z3.Function('sport', event, port)
dport = z3.Function('dport', event, port)
addrToNode = z3.Function('addrToNode', address, node)
Exemple #25
0
def z3_set_node(vertex):
    """Add a node"""
    return z3.Function('SetNode', vertex, z3.BoolSort())
Exemple #26
0
    def __init__(
        self,
        physical_address_bits,
        allow_misaligned_atomics=False,
        arbitrary_initial_values=False,
        big_endian=False,
        sc_address_must_match=False,
    ):
        self._physical_address_bits = physical_address_bits
        self._allow_misaligned_atomics = allow_misaligned_atomics
        self._arbitrary_initial_values = arbitrary_initial_values
        self._big_endian = big_endian
        self._sc_address_must_match = sc_address_must_match

        self._model = RelationalModel()

        # Sets (arity-1 relations)

        self.Hart = RelationBuilder()
        "All hardware threads"

        self.Thread = RelationBuilder()
        "All software threads"

        self.Op = RelationBuilder()
        "All operations (memory operations plus fences)"

        self.MemoryOp = RelationBuilder()
        "All memory operations"

        self.DummyMemoryOp = RelationBuilder()
        """All dummy memory operations

        DummyMemoryOps are used to define inter-thread ordering constraints
        without building up some non-trivial locking protocol within the model.
        """

        self.Read = RelationBuilder()
        """All read operations (including implicit reads, load-reserve
        operations, and AMOs)"""

        self.Write = RelationBuilder()
        """All write operations (including implicit writes for A/D bit updates
        and AMOs)"""

        self.ImplicitOp = RelationBuilder()
        "All implicit reads of the address-translation data structures"

        self.LoadReserve = RelationBuilder()
        """All load-reserve operations (including implicit reads for A/D bit
        updates"""

        self.StoreConditional = RelationBuilder()
        """All store-conditional operations (including implicit writes for A/D
        bit updates"""

        self.AMO = RelationBuilder()
        "All AMO operations"

        self.Aq = RelationBuilder()
        "All operations marked .aq"

        self.Rl = RelationBuilder()
        "All operations marked .rl"

        self.RCsc = RelationBuilder()
        "All RCsc operations"

        self.Fence = RelationBuilder()
        "All fences (not counting sfences)"

        self.FencePR = RelationBuilder()
        "All fences with .pr"

        self.FencePW = RelationBuilder()
        "All fences with .pw"

        self.FenceSR = RelationBuilder()
        "All fences with .sr"

        self.FenceSW = RelationBuilder()
        "All fences with .sw"

        self.FenceTSO = RelationBuilder()
        "All fences with .tso"

        self.SFenceVMA = RelationBuilder()
        "All sfence.vmas"

        # Edges (arity-2 relations)

        self.thread_ops = RelationBuilder()
        "Relates a (software) Thread to all ops in that thread"

        self.threads = RelationBuilder()
        "Relates each Hart to the software Threads scheduled on it"

        self.po = RelationBuilder()
        "Program order"

        self.addrdep = RelationBuilder()
        "Syntactic address dependencies"

        self.ctrldep = RelationBuilder()
        "Syntactic control dependencies"

        self.datadep = RelationBuilder()
        "Syntactic data dependencies"

        self.implicit_pair = RelationBuilder()
        """LR/SC pairs for implicit address-translation accesses

        Normal LR/SC pairs use the _pair() calculation and program order, but
        implicit address-translation accesses aren't inserted into program
        order, and so we need another way to get them to be paired properly
        """

        self.translation_order = RelationBuilder()
        """The sequence of address-translation reads, in order, and then
        pointing to the parent Explicit Op"""

        self.hart_order = RelationBuilder()
        """An ordering between Harts, such that for (a, b) in `hart_order`,
        MemoryOps in `a` are ordered before MemoryOps in `b` in the global
        memory order.  This can be used to set up harts that set up the
        initial condition or check the final condition, for example.
        """

        self.force = RelationBuilder()
        """MemoryOp pairs where the first is forced before the second in gmo.

        This is used for things like forcing operations in the initial thread
        to appear in gmo before operations in the main thread, and forcing
        remote SFENCE.VMA instructions to be ordered in the right place wrt
        operations in the thread issuing an sbi_remote_sfence_vma() (as would
        in reality be ordered via IPIs).
        """

        self.implicit_program_order = RelationBuilder()
        """Like program order, but includes ImplicitOps as well."""

        # Other dictionaries tracking per-Op information

        self.base_address = {}
        "For each MemoryOp or SFenceVMA, the base address"

        self.width_bytes = {}
        "For each MemoryOp or SFenceVMA, the width of the operation"

        self.return_value = {}
        "For each Read, the value returned (of size width_bytes)"

        self.write_value = {}
        "For each Write, the value written (of size matching width_bytes)"

        self.satp_asid = {}
        "For each SFenceVMA or ImplicitOp, the value of satp.asid"

        self.meta = {}
        "For each Op, the parsing metadata that generated it"

        self.initial_values = {}
        "For each byte address, a preset initial value for that address."

        self.label = {}
        "For each Op, a string label"

        # Builder internal variables

        self._initial_value = z3.Function(
            "initial_value",
            z3.BitVecSort(self._physical_address_bits),
            z3.BitVecSort(8),
        )
        "For each byte address, the initial value of that address"

        self._latest_cache = {}
        """For each (read, address), a Relation representing the Write from
Exemple #27
0
def z3_set_network(vertex):
    """Add a network"""
    return z3.Function('SetNetwork', vertex, vertex, z3.BoolSort())
 def __init__(self):
     # a rename of 'inode_nlink'
     self.inode_nlink = z3.Function(fresh_name('inode_nlink'), z3.IntSort(),
                                    z3.IntSort())
     self.fname_inode = z3.Function(fresh_name('fname_inode'), z3.IntSort(),
                                    z3.IntSort())
Exemple #29
0
def z3_edge(vertex):
    """True is an edge exists between two vertices"""
    return z3.Function('Edge', vertex, vertex, z3.BoolSort())
Exemple #30
0
        smt.add(z3.And([p != pp for (j, pp) in enumerate(perm_x) if i < j]))

    # --------------------------------------------------------------------------
    # Step 2: Create a symbolic function for indices.
    # 
    # We want to use a symbolic variable as an index in the LCG. Since we are
    # using only the first 80 blocks from the LCG, we can enumerate all possible
    # values for indices in the LCG and create a symbolic function.
    # --------------------------------------------------------------------------
    print('[+] Adding constraints to make solution a valid permutation ...')

    def lcg_idx(i, j):
        return lcg(i).index(j)

    # create a symbolic function for zz
    sym_lcg_idx = z3.Function("lcg_idx", z3.IntSort(), z3.IntSort(), z3.IntSort())

    # add all possible values for zz
    for i in range(40):
        for j in range(40):
            smt.add(sym_lcg_idx(i, j) == lcg_idx(i, j))

    # --------------------------------------------------------------------------
    # Step 3: Add all the constraints.
    #
    # Here we have another problem: We want to find perm_x.index(j), where `j`
    # is a constant number. However `perm_x` is an array of symbolic variables.
    # To solve this problem we have to notice that if `perm_x.index(j) == k`
    # then it means that the symbolic variable `P_j` (located at the j-th
    # position of the array must be `k`.
    #