示例#1
0
 def order_geq_lex(c1: int, c2: int):
     pairs_c1, pairs_c2 = pairs(c1), pairs(c2)
     assert len(pairs_c1) == len(pairs_c2)
     constraints = smt.TRUE()
     for j in range(len(pairs_c1)):
         condition = smt.TRUE()
         for i in range(j):
             condition &= order_equal(pairs_c1[i], pairs_c2[i])
         constraints &= smt.Implies(condition,
                                    order_geq(pairs_c1[j], pairs_c2[j]))
     return constraints
示例#2
0
    def query_oracle(self, dis_formula):
        self.solver_oracle.reset_assertions()
        c0 = self.attack_formulas.oracle_ckt_at_frame(0)
        for i in range(len(c0)):
            self.solver_oracle.add_assertion(c0[i])

        dis_out = []
        for d in range(1, self.unroll_depth + 1):
            c0 = self.attack_formulas.oracle_ckt_at_frame(d)
            for i in range(len(c0)):
                self.solver_oracle.add_assertion(c0[i])

            self.solver_oracle.add_assertion(pystm.And(dis_formula[d - 1]))
            if not self.solver_oracle.is_sat(pystm.TRUE()):
                logging.critical('something is wrong in oracle query')
                exit()
            else:
                dip_out = []
                # for w in self.oracle_cir.output_wires:
                for w in self.obf_cir.output_wires:
                    f = pystm.Symbol(w + '@{}'.format(d))
                    dip_out.append(self.solver_oracle.get_value(f))
                dis_out.append(dip_out)
        logging.info(dis_out)
        return dis_out
def import_xadd_mspn(filename):
    # type: (str) -> Density
    name = os.path.basename(filename)
    parts = name.split("_")
    real_vars = int(parts[1])
    bool_vars = int(parts[2])

    domain = Domain.make(["A_{}".format(i) for i in range(bool_vars)],
                         {"x_{}".format(i): [0, 1] for i in range(real_vars)})

    support = smt.TRUE()
    with open(filename) as f:
        weight = nested_to_smt(f.readlines()[0])
    queries = [smt.TRUE()]

    return Density(domain, support, weight, queries)
 def weight(self, a):
     var = self.literals.inv_numbered[abs(a)]
     abstraction = self.literals[var]
     if isinstance(abstraction, str):
         return [(smt.TRUE(), {abstraction})]
     else:
         if a < 0:
             abstraction = ~abstraction
         return [(abstraction, set())]
示例#5
0
def make_distinct_bounds(domain):
    base_lower_bound = 0.13
    base_upper_bound = 0.89
    step = 0.01
    variables = domain.get_symbols(domain.real_vars)

    bounds = smt.TRUE()
    for i in range(len(variables)):
        bounds &= variables[i] >= base_lower_bound + i * step  # - i * step
        bounds &= variables[i] <= base_upper_bound - i * step  # + i * step

    return bounds
def import_smt_synthetic(filename):
    # type: (str) -> Density

    with open(filename) as f:
        flat = json.load(f)

    domain = Domain.from_state(flat["synthetic_problem"]["problem"]["domain"])
    queries = [smt.TRUE()]
    support = nested_to_smt(flat["synthetic_problem"]["problem"]["theory"]) & domain.get_bounds()
    weights = smt.Real(1)

    return Density(domain, support, weights, queries)
示例#7
0
    def query_dip_generator(self):
        dis_boolean = []

        for d in range(1, self.unroll_depth + 1):
            dip_boolean = []
            for w in self.obf_cir.input_wires:
                f = pystm.Symbol(w + '@{}'.format(d))
                if self.solver_obf.get_py_value(f):
                    dip_boolean.append(pystm.TRUE())
                else:
                    dip_boolean.append(pystm.FALSE())
            dis_boolean.append(dip_boolean)

        return dis_boolean
示例#8
0
文件: encoder.py 项目: tmeywerk/SHREC
def find_iter(data, domain, idx, finder, *finder_args):
    strat = RandomViolationsStrategy(10)
    excluded = [i for i in range(len(data)) if i not in idx]
    active_indices = random.sample(idx, min(20, len(idx)))
    excluded += active_indices
    result = smt.TRUE()  #will be replaced
    while len(active_indices) > 0 and result is not None:
        result = finder(data, domain, active_indices, *finder_args)
        if result is None:
            break
        active_indices = list(
            strat.select_active(domain, data, result, excluded))
        excluded += active_indices
    return result
def import_wmi_mspn(filename):
    # type: (str) -> Density
    q_file, s_file, w_file = ("{}.{}".format(filename, ext) for ext in ["query", "support", "weight"])
    queries = [smt.TRUE()] if not os.path.exists(q_file) else [smt.read_smtlib(q_file)]
    support = smt.read_smtlib(s_file)
    if os.path.exists(w_file):
        weights = smt.read_smtlib(w_file)
    else:
        weights = smt.Real(1)
    name = os.path.basename(filename)
    parts = name.split("_")
    real_vars = int(parts[1])
    bool_vars = int(parts[2])

    domain = Domain.make(["A_{}".format(i) for i in range(bool_vars)],
                         {"x_{}".format(i): [0, 1] for i in range(real_vars)})

    return Density(domain, support, weights, queries)
示例#10
0
def mutual_exclusive(n):
    domain = make_domain(n)

    symbols = domain.get_symbols(domain.real_vars)
    x, symbols = symbols[0], symbols[1:]

    bounds = make_distinct_bounds(domain)

    terms = [x <= v for v in symbols]
    disjunction = smt.TRUE()
    for i in range(n):
        for j in range(i + 1, n):
            disjunction &= ~terms[i] | ~terms[j]

    disjunction = smt.simplify(disjunction) & smt.Or(*terms)

    flipped_domain = Domain(list(reversed([v for v in domain.variables if v != "x"])) + ["x"], domain.var_types, domain.var_domains)
    return FileDensity(flipped_domain, disjunction & bounds, smt.Real(1.0))
def test_rejection_iff_bool():
    domain = Domain.make(["a", "b"])
    a, b = domain.get_symbols()

    print(domain)
    vol_t = RejectionEngine(domain, smt.TRUE(), smt.Real(1.0),
                            100000).compute_volume()
    vol1 = RejectionEngine(domain, (a | b) & (~a | ~b), smt.Real(1.0),
                           100000).compute_volume()
    vol2 = RejectionEngine(domain, smt.Iff(a, ~b), smt.Real(1.0),
                           100000).compute_volume()
    vol3 = RejectionEngine(domain, ~smt.Iff(a, b), smt.Real(1.0),
                           100000).compute_volume()

    print(vol1, vol2, vol3, vol_t)

    # print(PredicateAbstractionEngine(domain, a | b, smt.Real(1.0)).compute_volume())
    print(XaddEngine(domain, a | b, smt.Real(1.0)).compute_volume())

    quit()
    def integrate(self, domain, convex_bounds: List[LinearInequality], polynomial: Polynomial):
        # TODO Use power of linear forms?
        b_geq_a = []
        formula = smt.TRUE()
        for bound in convex_bounds:
            integer_bound = bound.scale_to_integer()
            formula &= integer_bound.to_smt()
            b_geq_a.append([integer_bound.b()] + [-integer_bound.a(v) for v in domain.real_vars])

        monomials = [(Fraction(value).limit_denominator(), self.key_to_exponents(domain, key))
                     for key, value in polynomial.poly_dict.items()]

        with TemporaryFile(suffix=".hrep.latte") as bounds_file:
            with TemporaryFile(suffix=".poly.latte") as poly_file:
                with open(bounds_file, "w") as bounds_ref:
                    print("{} {}".format(len(b_geq_a), len(domain.real_vars) + 1), file=bounds_ref)
                    print(*[" ".join(map(str, e)) for e in b_geq_a], sep="\n", file=bounds_ref)

                with open(poly_file, "w") as poly_ref:
                    print("[{}]".format(",".join("[{},[{}]]".format(m[0], ",".join(map(str, m[1])))
                                                 for m in monomials)), file=poly_ref)

                command = "integrate --valuation=integrate {} --monomials={} {}"\
                    .format(self.algorithm, poly_file, bounds_file)
                try:
                    output = check_output(command, shell=True, stderr=DEVNULL).decode()
                except CalledProcessError:
                    with smt.Solver() as solver:
                        solver.add_assertion(formula)
                        solver.solve()
                        try:
                            solver.get_model()
                        except InternalSolverError:
                            return 0.0
                    raise
                match = re.search(self.pattern, output)
                if not match:
                    return 0.0
                return float(Fraction(int(match.group(1)), int(match.group(2))))
示例#13
0
 def accuracy_approx(experiment):
     key = "accuracy_approx:{}".format(experiment.imported_from_file)
     if Properties.db.exists(key):
         return Properties.db.get(key)
     else:
         pysmt.environment.push_env()
         pysmt.environment.get_env().enable_infix_notation = True
         if os.path.basename(experiment.imported_from_file).startswith("synthetic"):
             db = Properties.get_db_synthetic(experiment)
             name = Properties.to_synthetic_name(experiment.imported_from_file)
             entry = db.get(name)
             domain = import_domain(json.loads(entry["domain"]))
             true_formula = nested_to_smt(entry["formula"])
         else:
             density = Density.import_from(experiment.parameters.original_values["domain"])
             domain = Domain(density.domain.variables, density.domain.var_types, Properties.get_bound(experiment))
             true_formula = density.support
         learned_formula = nested_to_smt(experiment.results.formula)
         engine = RejectionEngine(domain, smt.TRUE(), smt.Real(1.0), 100000)
         accuracy = engine.compute_probability(smt.Iff(true_formula, learned_formula))
         pysmt.environment.pop_env()
         print(accuracy)
         Properties.db.set(key, accuracy)
     return accuracy
示例#14
0
    def learn_partial(self, solver, domain, data, new_active_indices):
        # Constants
        n_b_original = len(domain.bool_vars)
        n_b = n_b_original * 2
        n_r = len(domain.real_vars)

        n_h_original = self.half_space_count if n_r > 0 else 0
        n_h = n_h_original * 2 if self.allow_negations else n_h_original

        n_c = self.conjunction_count
        n_d = len(data)

        real_features = [[row[v] for v in domain.real_vars] for row, _ in data]
        bool_features = [[row[v] for v in domain.bool_vars] for row, _ in data]
        labels = [row[1] for row in data]

        # Variables
        a_hr = [[
            smt.Symbol("a_hr[{}][{}]".format(h, r), REAL) for r in range(n_r)
        ] for h in range(n_h_original)]
        b_h = [
            smt.Symbol("b_h[{}]".format(h), REAL) for h in range(n_h_original)
        ]
        s_ch = [[smt.Symbol("s_ch[{}][{}]".format(c, h)) for h in range(n_h)]
                for c in range(n_c)]
        s_cb = [[smt.Symbol("s_cb[{}][{}]".format(c, b)) for b in range(n_b)]
                for c in range(n_c)]

        # Aux variables
        s_ih = [[smt.Symbol("s_ih[{}][{}]".format(i, h)) for h in range(n_h)]
                for i in range(n_d)]
        s_ic = [[smt.Symbol("s_ic[{}][{}]".format(i, c)) for c in range(n_c)]
                for i in range(n_d)]

        # Constraints
        for i in new_active_indices:
            x_r, x_b, label = real_features[i], bool_features[i], labels[i]

            for h in range(n_h_original):
                sum_coefficients = smt.Plus(
                    [a_hr[h][r] * smt.Real(x_r[r]) for r in range(n_r)])
                solver.add_assertion(
                    smt.Iff(s_ih[i][h], sum_coefficients <= b_h[h]))

            for h in range(n_h_original, n_h):
                solver.add_assertion(
                    smt.Iff(s_ih[i][h], ~s_ih[i][h - n_h_original]))

            for c in range(n_c):
                solver.add_assertion(
                    smt.Iff(
                        s_ic[i][c],
                        smt.And([smt.TRUE()] + [(~s_ch[c][h] | s_ih[i][h])
                                                for h in range(n_h)] +
                                [
                                    ~s_cb[c][b]
                                    for b in range(n_b_original) if not x_b[b]
                                ] + [
                                    ~s_cb[c][b]
                                    for b in range(n_b_original, n_b)
                                    if x_b[b - n_b_original]
                                ])))

            if label:
                solver.add_assertion(smt.Or([s_ic[i][c] for c in range(n_c)]))
            else:
                solver.add_assertion(smt.And([~s_ic[i][c]
                                              for c in range(n_c)]))

        solver.solve()
        model = solver.get_model()

        x_vars = [domain.get_symbol(domain.real_vars[r]) for r in range(n_r)]
        half_spaces = [
            smt.Plus(
                [model.get_value(a_hr[h][r]) * x_vars[r]
                 for r in range(n_r)]) <= model.get_value(b_h[h])
            for h in range(n_h_original)
        ] + [
            smt.Plus(
                [model.get_value(a_hr[h][r]) * x_vars[r]
                 for r in range(n_r)]) > model.get_value(b_h[h])
            for h in range(n_h - n_h_original)
        ]

        b_vars = [
            domain.get_symbol(domain.bool_vars[b]) for b in range(n_b_original)
        ]
        bool_literals = [b_vars[b] for b in range(n_b_original)]
        bool_literals += [~b_vars[b] for b in range(n_b - n_b_original)]

        conjunctions = [[
            half_spaces[h]
            for h in range(n_h) if model.get_py_value(s_ch[c][h])
        ] + [
            bool_literals[b]
            for b in range(n_b) if model.get_py_value(s_cb[c][b])
        ] for c in range(n_c)]

        return smt.Or([smt.And(conjunction) for conjunction in conjunctions])
示例#15
0
文件: encoder.py 项目: tmeywerk/SHREC
def find_clause(data, domain, active_indices, solver, n_h):
    # Constants
    n_b_original = len(domain.bool_vars)
    n_b = n_b_original * 2
    n_r = len(domain.real_vars)
    n_d = len(data)

    real_features = [[row[v] for v in domain.real_vars] for row, _ in data]
    bool_features = [[row[v] for v in domain.bool_vars] for row, _ in data]
    labels = [row[1] for row in data]

    # Variables
    a_hr = [[
        smt.Symbol("a_hr[{}][{}]".format(h, r), REAL) for r in range(n_r)
    ] for h in range(n_h)]
    b_h = [smt.Symbol("b_h[{}]".format(h), REAL) for h in range(n_h)]
    s_b = [smt.Symbol("s_b[{}]".format(b)) for b in range(n_b)]

    # Aux variables
    s_ih = [[smt.Symbol("s_ih[{}][{}]".format(i, h)) for h in range(n_h)]
            for i in range(n_d)]

    # Constraints
    for i in active_indices:
        x_r, x_b, label = real_features[i], bool_features[i], labels[i]

        for h in range(n_h):
            sum_coefficients = smt.Plus(
                [a_hr[h][r] * smt.Real(x_r[r]) for r in range(n_r)])
            if label:
                solver.add_assertion(
                    smt.Iff(s_ih[i][h], sum_coefficients + DELTA <= b_h[h]))
            else:
                solver.add_assertion(
                    smt.Iff(s_ih[i][h], sum_coefficients - DELTA <= b_h[h]))

        if label:
            solver.add_assertion(
                smt.Or([smt.FALSE()] + [s_ih[i][h] for h in range(n_h)] +
                       [s_b[b] for b in range(n_b_original) if x_b[b]] + [
                           s_b[b] for b in range(n_b_original, n_b)
                           if not x_b[b - n_b_original]
                       ]))
        else:
            solver.add_assertion(
                smt.And([smt.TRUE()] + [~s_ih[i][h] for h in range(n_h)] +
                        [~s_b[b] for b in range(n_b_original) if x_b[b]] + [
                            ~s_b[b] for b in range(n_b_original, n_b)
                            if not x_b[b - n_b_original]
                        ]))

    if not solver.solve():
        return None
    model = solver.get_model()

    x_vars = [domain.get_symbol(domain.real_vars[r]) for r in range(n_r)]
    half_spaces = [
        smt.Plus([model.get_value(a_hr[h][r]) * x_vars[r]
                  for r in range(n_r)]) <= model.get_value(b_h[h])
        for h in range(n_h)
    ]

    b_vars = [
        domain.get_symbol(domain.bool_vars[b]) for b in range(n_b_original)
    ]
    bool_literals = [b_vars[b] for b in range(n_b_original)]
    bool_literals += [~b_vars[b] for b in range(n_b - n_b_original)]

    return smt.Or(
        [half_spaces[h] for h in range(n_h)] +
        [bool_literals[b] for b in range(n_b) if model.get_py_value(s_b[b])])
示例#16
0
 def __init__(self, domain, support, weight, queries=None):
     self.domain = domain
     self.support = support
     self.weight = weight
     self.queries = queries if queries is not None else [smt.TRUE()]
示例#17
0
 def run_internal(self):
     density = Density.from_file(self["filename"])
     solver = get_engine(self["solver"], density.domain, density.support, density.weight)
     if not density.queries or (len(density.queries) == 1 and density.queries[0] == smt.TRUE()):
         self["volumes"] = [solver.compute_volume()]
     else:
         self["volumes"] = [solver.compute_probabilities(density.queries)]
示例#18
0
    def perform(self):
        # process inputs
        if '.bench' in self.args.b:
            self.obf_cir = bench2circuit(self.args.o)
            self.oracle_cir = bench2circuit(self.args.b)
        else:
            logging.critical('verilog input is disabled! use main_formal')
            exit()
        #     self.oracle_ast = ASTWrapper(parse_verilog(self.args.b), self.args.b)
        #     self.obf_ast = ASTWrapper(parse_verilog(self.args.o), self.args.o)
        #
        #     self.oracle_cir = self.oracle_ast.get_circuit(check_correctness=False, correct_order=False)
        #     self.obf_cir = self.obf_ast.get_circuit(check_correctness=False, correct_order=False)

        self.oracle_cir.create_ce_circuit()
        self.obf_cir.create_ce_circuit()
        sort_circuits(self.oracle_cir, self.obf_cir)

        # perform attack
        self.solver_obf = pystm.Solver(name=self.solver_name)
        self.solver_key = pystm.Solver(name=self.solver_name)
        self.solver_oracle = pystm.Solver(name=self.solver_name)

        logging.warning('initial value for boundary={}, step={}, stop={}'.format(self.boundary, self.step, self.stop))
        logging.warning('solver={}'.format(self.solver_name))

        self.attack_formulas = FormulaGenerator(self.oracle_cir, self.obf_cir)

        # add k0 != k1
        self.solver_obf.add_assertion(self.attack_formulas.key_inequality_ckt)

        # assumptions for inequality of dip generator outputs
        assumptions = self.attack_formulas.dip_gen_assumption(1)

        # get initial states and the first copy of the circuit
        for i in range(2):
            c0, c1 = self.attack_formulas.obf_ckt_at_frame(i)
            for j in range(len(c0)):
                self.solver_obf.add_assertion(c0[j])
                self.solver_obf.add_assertion(c1[j])

        while 1:
            # query dip generator
            if self.solver_obf.is_sat(assumptions):
                dis_boolean = self.query_dip_generator()

                dis_formula = []
                for i in range(1, len(dis_boolean) + 1):
                    dis_formula.append(get_formulas(self.obf_cir.input_wires, dis_boolean[i-1], '@{}'.format(i)))
                logging.info(dis_formula)

                dis_out = self.query_oracle(dis_formula)
                self.add_dip_checker(dis_boolean, dis_out)

                self.iteration += 1
                logging.warning('iteration={}, depth={}'.format(self.iteration, self.unroll_depth))
                self.highest_depth = self.unroll_depth
            else:
                if (self.solver_obf.is_sat(pystm.TRUE()) or self.iteration == 0) and self.unroll_depth < self.stop:
                    # two agreeing keys are found, but no dip can be found
                    # also it should keep unrolling the circuit until at least one dip is found
                    #  then it can decide on uc success
                    if self.unroll_depth == self.boundary:
                        logging.warning('uc failed')

                        # check ce
                        if self.ce_check():
                            return True
                        elif self.umc_check():
                            continue
                        else:
                            # increase boundary
                            # self.unroll_depth += 1
                            self.boundary += self.step
                    else:
                        # increase unroll depth
                        self.unroll_depth += 1
                        assumptions = self.attack_formulas.dip_gen_assumption(self.unroll_depth)

                        c0, c1 = self.attack_formulas.obf_ckt_at_frame(self.unroll_depth)
                        for i in range(len(c0)):
                            self.solver_obf.add_assertion(c0[i])
                            self.solver_obf.add_assertion(c1[i])
                        logging.warning('increasing unroll depth to {}'.format(self.unroll_depth))
                elif self.unroll_depth >= self.stop:
                    logging.warning('stopped at {}'.format(self.stop))
                    self.print_keys()
                    return True
                else:
                    # key is unique
                    logging.warning('uc successful')
                    self.print_keys()
                    return True
示例#19
0
 def times_neutral(self):
     return [(smt.TRUE(), set())]