예제 #1
0
    def __init__(self, oracle_cir, obf_cir):
        self.oracle_cir = oracle_cir
        self.obf_cir = obf_cir

        # generate solver formulas
        for w in self.oracle_cir.wire_objs:
            lst = []
            for op in w.operands:
                lst.append(Symbol(op.name))
            r = self.get_wire_formulas(w, lst)
            w.formula = Iff(Symbol(w.name), r)

        # generate formulas for two copies of obfuscated circuit
        ckt1 = self.gen_dip_chk('dc1', '_0', None)
        ckt2 = self.gen_dip_chk('dc2', '_1', None)
        output_xors = []
        for w in self.obf_cir.output_wires:
            output_xors.append(
                Xor(Symbol(w.name + '@dc1'), Symbol(w.name + '@dc2')))
        self.dip_gen_ckt = And(Or(output_xors), ckt1, ckt2)

        # key inequality circuit
        key_symbols1 = []
        key_symbols2 = []
        for w in self.obf_cir.wire_objs:
            if 'keyinput' in w.name:
                key_symbols1.append(Symbol(w.name + '_0'))
                key_symbols2.append(Symbol(w.name + '_1'))
        output_xors = []
        for i in range(self.obf_cir.k_inputs):
            output_xors.append(Xor(key_symbols1[i], key_symbols2[i]))
        self.key_inequality_ckt = Or(output_xors)
예제 #2
0
 def get_wire_formulas(w, lst):
     r = None
     if w.type == Wire.INPUT:
         r = Symbol(w.name)
     elif w.type == 'not':
         r = Not(lst[0])
     elif w.type == 'buf':
         r = lst[0]
     elif w.type == 'buff':
         r = lst[0]
     elif w.type == 'and':
         r = And(lst)
     elif w.type == 'nand':
         r = And(lst)
         r = Not(r)
     elif w.type == 'or':
         r = Or(lst)
     elif w.type == 'nor':
         r = Or(lst)
         r = Not(r)
     elif w.type == 'xor':
         assert (len(lst) == 2)
         r = Xor(lst[0], lst[1])
     elif w.type == 'xnor':
         assert (len(lst) == 2)
         r = Xor(lst[0], lst[1])
         r = Not(r)
     elif w.type == 'mux':
         assert (len(lst) == 3)
         r = Or(And(Not(lst[0]), lst[1]), And(lst[0], lst[2]))
     else:
         logging.critical('unspecified gate type')
         exit()
     return r
예제 #3
0
    def __init__(self, oracle_cir, obf_cir):
        self.orcl_cir = oracle_cir
        self.obf_cir = obf_cir
        self.key_subs = [{}, {}]

        orcl_wires = self.orcl_cir.wire_objs
        obf_wires = self.obf_cir.wire_objs

        # generate solver formulas
        self.gen_wire_formulas(self.orcl_cir)
        self.gen_wire_formulas(self.obf_cir)

        # create key substitution dictionary
        for w in self.obf_cir.key_wires:
            self.key_subs[0][Symbol(w)] = Symbol(w + '_0')
            self.key_subs[1][Symbol(w)] = Symbol(w + '_1')

        # generate formulas for two copies of obfuscated circuit
        ckt1 = []
        ckt2 = []
        for w in self.obf_cir.output_wires:
            ckt1.append(substitute(obf_wires[w].formula, self.key_subs[0]))
            ckt2.append(substitute(obf_wires[w].formula, self.key_subs[1]))
        output_xors = []
        for i in range(len(self.obf_cir.output_wires)):
            output_xors.append(Xor(ckt1[i], ckt2[i]))
        self.dip_gen_ckt = Or(output_xors)

        # key inequality circuit
        key_symbols1 = []
        key_symbols2 = []
        for w in self.obf_cir.key_wires:
            key_symbols1.append(Symbol(w + '_0'))
            key_symbols2.append(Symbol(w + '_1'))

        output_xors = []
        for i in range(len(key_symbols1)):
            output_xors.append(Xor(key_symbols1[i], key_symbols2[i]))
        self.key_inequality_ckt = Or(output_xors)

        # dip checker circuit
        self.dip_chk1 = []
        self.dip_chk2 = []
        for w in self.obf_cir.output_wires:
            self.dip_chk1.append(substitute(obf_wires[w].formula, self.key_subs[0]))
            self.dip_chk2.append(substitute(obf_wires[w].formula, self.key_subs[1]))
예제 #4
0
 def gen_wire_formulas(self, circuit):
     wires = circuit.wire_objs
     for w in circuit.sorted_wires:
         wire = wires[w]
         lst = []
         r = None
         for op in wire.operands:
             if op in (circuit.input_wires + circuit.key_wires):
                 lst.append(Symbol(op))
             else:
                 lst.append(wires[op].formula)
         if wire.type == 'not':
             r = Not(lst[0])
         elif wire.type == 'buf':
             r = lst[0]
         elif wire.type == 'and':
             r = And(lst)
         elif wire.type == 'nand':
             r = And(lst)
             r = Not(r)
         elif wire.type == 'or':
             r = Or(lst)
         elif wire.type == 'nor':
             r = Or(lst)
             r = Not(r)
         elif wire.type == 'xor':
             assert (len(lst) == 2)
             r = Xor(lst[0], lst[1])
             # r = And(Or(lst[0], lst[1]), Not(And(lst[0], lst[1])))
         elif wire.type == 'xnor':
             assert (len(lst) == 2)
             r = Xor(lst[0], lst[1])
             # r = And(Or(lst[0], lst[1]), Not(And(lst[0], lst[1])))
             r = Not(r)
         else:
             logging.critical('unspecified gate type: {}'.format(wire.type))
             exit()
         wire.formula = r
예제 #5
0
    def test_infix_extended(self):
        p, r, x, y = self.p, self.r, self.x, self.y
        get_env().enable_infix_notation = True

        self.assertEqual(Plus(p, Int(1)), p + 1)
        self.assertEqual(Plus(r, Real(1)), r + 1)
        self.assertEqual(Times(r, Real(1)), r * 1)

        self.assertEqual(Minus(p, Int(1)), p - 1)
        self.assertEqual(Minus(r, Real(1)), r - 1)
        self.assertEqual(Times(r, Real(1)), r * 1)

        self.assertEqual(Plus(r, Real(1.5)), r + 1.5)
        self.assertEqual(Minus(r, Real(1.5)), r - 1.5)
        self.assertEqual(Times(r, Real(1.5)), r * 1.5)

        self.assertEqual(Plus(r, Real(1.5)), 1.5 + r)
        self.assertEqual(Times(r, Real(1.5)), 1.5 * r)

        with self.assertRaises(TypeError):
            foo = p + 1.5

        self.assertEqual(Not(x), ~x)

        self.assertEqual(Times(r, Real(-1)), -r)
        self.assertEqual(Times(p, Int(-1)), -p)

        self.assertEqual(Xor(x, y), x ^ y)
        self.assertEqual(And(x, y), x & y)
        self.assertEqual(Or(x, y), x | y)

        self.assertEqual(Or(x, TRUE()), x | True)
        self.assertEqual(Or(x, TRUE()), True | x)

        self.assertEqual(And(x, TRUE()), x & True)
        self.assertEqual(And(x, TRUE()), True & x)

        get_env().enable_infix_notation = False
예제 #6
0
파일: test_formula.py 프로젝트: mitar/pysmt
    def test_infix_extended(self):
        p, r, x, y = self.p, self.r, self.x, self.y
        get_env().enable_infix_notation = True

        self.assertEqual(Plus(p, Int(1)), p + 1)
        self.assertEqual(Plus(r, Real(1)), r + 1)
        self.assertEqual(Times(r, Real(1)), r * 1)

        self.assertEqual(Minus(p, Int(1)), p - 1)
        self.assertEqual(Minus(r, Real(1)), r - 1)
        self.assertEqual(Times(r, Real(1)), r * 1)

        self.assertEqual(Plus(r, Real(1.5)), r + 1.5)
        self.assertEqual(Minus(r, Real(1.5)), r - 1.5)
        self.assertEqual(Times(r, Real(1.5)), r * 1.5)

        self.assertEqual(Plus(r, Real(1.5)), 1.5 + r)
        self.assertEqual(Times(r, Real(1.5)), 1.5 * r)

        with self.assertRaises(PysmtTypeError):
            foo = p + 1.5

        self.assertEqual(Not(x), ~x)

        self.assertEqual(Times(r, Real(-1)), -r)
        self.assertEqual(Times(p, Int(-1)), -p)

        self.assertEqual(Xor(x, y), x ^ y)
        self.assertEqual(And(x, y), x & y)
        self.assertEqual(Or(x, y), x | y)

        self.assertEqual(Or(x, TRUE()), x | True)
        self.assertEqual(Or(x, TRUE()), True | x)

        self.assertEqual(And(x, TRUE()), x & True)
        self.assertEqual(And(x, TRUE()), True & x)

        self.assertEqual(Iff(x, y), x.Iff(y))
        self.assertEqual(And(x, y), x.And(y))
        self.assertEqual(Or(x, y), x.Or(y))

        self.assertEqual(Ite(x, TRUE(), FALSE()), x.Ite(TRUE(), FALSE()))
        with self.assertRaises(Exception):
            x.Ite(1, 2)

        self.assertEqual(6 - r, Plus(Times(r, Real(-1)), Real(6)))

        # BVs

        # BV_CONSTANT: We use directly python numbers
        #
        # Note: In this case, the width is implicit (yikes!)  The
        #       width of the constant is inferred by the use of a
        #       symbol or operator that enforces a bit_width.
        #
        #       This works in very simple cases. For complex
        #       expressions it is advisable to create a shortcut for
        #       the given BVType.
        const1 = 3
        const2 = 0b011
        const3 = 0x3
        # Since these are python numbers, the following holds
        self.assertEqual(const1, const2)
        self.assertEqual(const1, const3)

        # However, we cannot use infix pySMT Equals, since const1 is a
        # python int!!!
        with self.assertRaises(AttributeError):
            const1.Equals(const2)

        # We use the usual syntax to build a constant with a fixed width
        const1_8 = self.mgr.BV(3, width=8)

        # In actual code, one can simply create a macro for this:
        _8bv = lambda v: self.mgr.BV(v, width=8)
        const1_8b = _8bv(3)
        self.assertEqual(const1_8, const1_8b)

        # Equals forces constants to have the width of the operand
        self.assertEqual(const1_8.Equals(const1),
                         self.mgr.Equals(const1_8, const1_8b))

        # Symbols
        bv8 = self.mgr.FreshSymbol(BV8)
        bv7 = self.mgr.FreshSymbol(BVType(7))

        self.assertEqual(bv8.Equals(const1), bv8.Equals(const1_8))

        # BV_AND,
        self.assertEqual(bv8 & const1, self.mgr.BVAnd(bv8, const1_8))

        self.assertEqual(const1 & bv8, self.mgr.BVAnd(bv8, const1_8))

        self.assertEqual(const1 & bv8, self.mgr.BVAnd(bv8, const1_8))
        # BV_XOR,
        self.assertEqual(bv8 ^ const1, self.mgr.BVXor(bv8, const1_8))
        self.assertEqual(const1 ^ bv8, self.mgr.BVXor(bv8, const1_8))
        # BV_OR,
        self.assertEqual(bv8 | const1, self.mgr.BVOr(bv8, const1_8))
        self.assertEqual(const1 | bv8, self.mgr.BVOr(bv8, const1_8))
        # BV_ADD,
        self.assertEqual(bv8 + const1, self.mgr.BVAdd(bv8, const1_8))
        self.assertEqual(const1 + bv8, self.mgr.BVAdd(bv8, const1_8))
        # BV_SUB,
        self.assertEqual(bv8 - const1, self.mgr.BVSub(bv8, const1_8))
        self.assertEqual(const1 - bv8, self.mgr.BVSub(const1_8, bv8))
        # BV_MUL,
        self.assertEqual(bv8 * const1, self.mgr.BVMul(bv8, const1_8))
        self.assertEqual(const1 * bv8, self.mgr.BVMul(bv8, const1_8))

        # BV_NOT:
        # !!!WARNING!!! Cannot be applied to python constants!!
        # This results in a negative number
        with self.assertRaises(PysmtValueError):
            _8bv(~const1)

        # For symbols and expressions this works as expected
        self.assertEqual(~bv8, self.mgr.BVNot(bv8))

        # BV_NEG -- Cannot be applied to 'infix' constants
        self.assertEqual(-bv8, self.mgr.BVNeg(bv8))

        # BV_EXTRACT -- Cannot be applied to 'infix' constants
        self.assertEqual(bv8[0:7], self.mgr.BVExtract(bv8, 0, 7))
        self.assertEqual(bv8[:7], self.mgr.BVExtract(bv8, end=7))
        self.assertEqual(bv8[0:], self.mgr.BVExtract(bv8, start=0))
        self.assertEqual(bv8[7], self.mgr.BVExtract(bv8, start=7, end=7))
        # BV_ULT,
        self.assertEqual(bv8 < const1, self.mgr.BVULT(bv8, const1_8))
        # BV_ULE,
        self.assertEqual(bv8 <= const1, self.mgr.BVULE(bv8, const1_8))
        # BV_UGT
        self.assertEqual(bv8 > const1, self.mgr.BVUGT(bv8, const1_8))
        # BV_UGE
        self.assertEqual(bv8 >= const1, self.mgr.BVUGE(bv8, const1_8))
        # BV_LSHL,
        self.assertEqual(bv8 << const1, self.mgr.BVLShl(bv8, const1_8))
        # BV_LSHR,
        self.assertEqual(bv8 >> const1, self.mgr.BVLShr(bv8, const1_8))
        # BV_UDIV,
        self.assertEqual(bv8 / const1, self.mgr.BVUDiv(bv8, const1_8))
        # BV_UREM,
        self.assertEqual(bv8 % const1, self.mgr.BVURem(bv8, const1_8))

        # The following operators use the infix syntax left.Operator.right
        # These includes all signed operators

        # BVSLT,
        self.assertEqual(self.mgr.BVSLT(bv8, const1_8), bv8.BVSLT(const1_8))

        #BVSLE,
        self.assertEqual(self.mgr.BVSLE(bv8, const1_8), bv8.BVSLE(const1_8))

        #BVComp
        self.assertEqual(self.mgr.BVComp(bv8, const1_8), bv8.BVComp(const1_8))

        #BVSDiv
        self.assertEqual(self.mgr.BVSDiv(bv8, const1_8), bv8.BVSDiv(const1_8))

        #BVSRem
        self.assertEqual(self.mgr.BVSRem(bv8, const1_8), bv8.BVSRem(const1_8))

        #BVAShr
        self.assertEqual(self.mgr.BVAShr(bv8, const1_8), bv8.BVAShr(const1_8))

        #BVNand
        self.assertEqual(self.mgr.BVNand(bv8, const1_8), bv8.BVNand(const1_8))

        #BVNor
        self.assertEqual(self.mgr.BVNor(bv8, const1_8), bv8.BVNor(const1_8))

        #BVXnor
        self.assertEqual(self.mgr.BVXnor(bv8, const1_8), bv8.BVXnor(const1_8))

        #BVSGT
        self.assertEqual(self.mgr.BVSGT(bv8, const1_8), bv8.BVSGT(const1_8))

        #BVSGE
        self.assertEqual(self.mgr.BVSGE(bv8, const1_8), bv8.BVSGE(const1_8))

        #BVSMod
        self.assertEqual(self.mgr.BVSMod(bv8, const1_8), bv8.BVSMod(const1_8))

        #BVRol,
        self.assertEqual(self.mgr.BVRol(bv8, steps=5), bv8.BVRol(5))

        #BVRor,
        self.assertEqual(self.mgr.BVRor(bv8, steps=5), bv8.BVRor(5))

        #BVZExt,
        self.assertEqual(self.mgr.BVZExt(bv8, increase=4), bv8.BVZExt(4))

        #BVSExt,
        self.assertEqual(self.mgr.BVSExt(bv8, increase=4), bv8.BVSExt(4))

        #BVRepeat,
        self.assertEqual(self.mgr.BVRepeat(bv8, count=5), bv8.BVRepeat(5))
from pysmt.shortcuts import Symbol, is_sat, Xor

Q = Symbol('Q')
P = Symbol('P')

prop1 = Xor(Q, P)

print is_sat(prop1)