Example #1
0
    def test_rx_deterministic_propagation(self, width, x1, y1, x2, y2):
        x1 = Constant(x1 % (2**width), width)
        y1 = Constant(y1 % (2**width), width)
        d1 = RXDiff.get_difference(x1, y1)
        x2 = Constant(x2 % (2**width), width)
        y2 = Constant(y2 % (2**width), width)
        d2 = RXDiff.get_difference(x2, y2)
        vd1 = DiffVar("in1", width)
        vd2 = DiffVar("in2", width)

        d3 = RXDiff.get_difference(~x1, ~y1)
        vd3 = RXDiff.propagate(BvNot, vd1)
        self.assertEqual(d3, vd3.xreplace({vd1: d1}))

        d3 = RXDiff.get_difference(x1 ^ x2, y1 ^ y2)
        vd3 = RXDiff.propagate(BvXor, [vd1, vd2])
        self.assertEqual(d3, vd3.xreplace({vd1: d1, vd2: d2}))

        d3 = RXDiff.get_difference(x1 ^ x2, y1 ^ x2)  # Xor with a constant
        vd3 = RXDiff.propagate(BvXor, [vd1, x2])
        self.assertEqual(d3, vd3.xreplace({vd1: d1}))

        r = int(x2) % x1.width
        d3 = RXDiff.get_difference(RotateLeft(x1, r), RotateLeft(y1, r))
        vd3 = RXDiff.propagate(RotateLeft, [vd1, r])
        self.assertEqual(d3, vd3.xreplace({vd1: d1}))

        d3 = RXDiff.get_difference(RotateRight(x1, r), RotateRight(y1, r))
        vd3 = RXDiff.propagate(RotateRight, [vd1, r])
        self.assertEqual(d3, vd3.xreplace({vd1: d1}))
Example #2
0
    def test_rx_linear_op(self, width, x1, y1, x2, y2):
        x1 = Constant(x1 % (2**width), width)
        y1 = Constant(y1 % (2**width), width)
        d1 = RXDiff.from_pair(x1, y1)
        x2 = Constant(x2 % (2**width), width)
        y2 = Constant(y2 % (2**width), width)
        d2 = RXDiff.from_pair(x2, y2)

        self.assertEqual(RXDiff.from_pair(~x1, ~y1),
                         RXDiff.derivative(BvNot, d1))

        self.assertEqual(RXDiff.from_pair(x1 ^ x2, y1 ^ y2),
                         RXDiff.derivative(BvXor, [d1, d2]))

        cte = x2
        BvXor_fix = make_partial_operation(BvXor, tuple([None, cte]))
        self.assertEqual(RXDiff.from_pair(x1 ^ cte, y1 ^ cte),
                         RXDiff.derivative(BvXor_fix, [d1]))

        cte = Variable("c", width)
        BvXor_fix = make_partial_operation(BvShl, tuple([None, cte]))
        with self.assertRaises(ValueError):
            XorDiff.derivative(BvXor_fix, d1)

        r = int(x2) % x1.width
        RotateLeft_fix = make_partial_operation(RotateLeft, tuple([None, r]))
        RotateRight_fix = make_partial_operation(RotateRight, tuple([None, r]))
        self.assertEqual(
            RXDiff.from_pair(RotateLeft(x1, r), RotateLeft(y1, r)),
            RXDiff.derivative(RotateLeft_fix, d1))
        self.assertEqual(
            RXDiff.from_pair(RotateRight(x1, r), RotateRight(y1, r)),
            RXDiff.derivative(RotateRight_fix, d1))
Example #3
0
    def test_xor_linear_op(self, width, x1, y1, x2, y2):
        x1 = Constant(x1 % (2**width), width)
        y1 = Constant(y1 % (2**width), width)
        d1 = XorDiff.from_pair(x1, y1)
        x2 = Constant(x2 % (2**width), width)
        y2 = Constant(y2 % (2**width), width)
        d2 = XorDiff.from_pair(x2, y2)

        self.assertEqual(XorDiff.from_pair(~x1, ~y1),
                         XorDiff.derivative(BvNot, d1))

        self.assertEqual(XorDiff.from_pair(x1 ^ x2, y1 ^ y2),
                         XorDiff.derivative(BvXor, [d1, d2]))

        cte = x2
        BvXor_fix = make_partial_operation(BvXor, tuple([None, cte]))
        self.assertEqual(XorDiff.from_pair(x1 ^ cte, y1 ^ cte),
                         XorDiff.derivative(BvXor_fix, [d1]))

        cte = Variable("c", width)
        BvXor_fix = make_partial_operation(BvXor, tuple([None, cte]))
        self.assertEqual(
            XorDiff.from_pair(x1 ^ cte, y1 ^ cte),
            XorDiff.derivative(BvXor, [d1, XorDiff.from_pair(cte, cte)]))
        self.assertEqual(XorDiff.from_pair(x1 ^ cte, y1 ^ cte),
                         XorDiff.derivative(BvXor_fix, [d1]))

        cte = x2
        BvAnd_fix = make_partial_operation(BvAnd, tuple([None, cte]))
        self.assertEqual(XorDiff.from_pair(x1 & cte, y1 & cte),
                         XorDiff.derivative(BvAnd_fix, [d1]))

        r = int(x2) % x1.width
        RotateLeft_fix = make_partial_operation(RotateLeft, tuple([None, r]))
        RotateRight_fix = make_partial_operation(RotateRight, tuple([None, r]))
        self.assertEqual(
            XorDiff.from_pair(RotateLeft(x1, r), RotateLeft(y1, r)),
            XorDiff.derivative(RotateLeft_fix, d1))
        self.assertEqual(
            XorDiff.from_pair(RotateRight(x1, r), RotateRight(y1, r)),
            XorDiff.derivative(RotateRight_fix, d1))

        r = Constant(int(x2) % x1.width, width)
        BvShl_fix = make_partial_operation(BvShl, tuple([None, r]))
        BvLshr_fix = make_partial_operation(BvLshr, tuple([None, r]))
        self.assertEqual(XorDiff.from_pair(x1 << r, y1 << r),
                         XorDiff.derivative(BvShl_fix, d1))
        self.assertEqual(XorDiff.from_pair(x1 >> r, y1 >> r),
                         XorDiff.derivative(BvLshr_fix, d1))

        i = int(x2) % x1.width
        j = int(y2) % (i + 1)
        Extract_fix = make_partial_operation(Extract, tuple([None, i, j]))
        self.assertEqual(XorDiff.from_pair(x1[i:j], y1[i:j]),
                         XorDiff.derivative(Extract_fix, d1))

        self.assertEqual(XorDiff.from_pair(Concat(x1, x2), Concat(y1, y2)),
                         XorDiff.derivative(Concat, [d1, d2]))
Example #4
0
    def eval(cls, k3, k2, k1, k0):
        if cls.rounds <= 4:
            return [k0, k1, k2, k3][:cls.rounds]

        k = [None for i in range(cls.rounds)]
        k[:4] = [k0, k1, k2, k3]
        m = 4
        z = "11111010001001010110000111001101111101000100101011000011100110"

        for i in range(4, cls.rounds):
            tmp = RotateRight(k[i - 1], 3) ^ k[i - 3]
            tmp ^= RotateRight(tmp, 1)
            k[i] = ~k[i - m] ^ tmp ^ int(z[(i - m) % 62]) ^ 3

        return k
Example #5
0
        def eval(cls, *master_key):
            if cls.rounds <= m:
                return list(reversed(master_key))[:cls.rounds]

            k = [None for i in range(cls.rounds)]
            k[:m] = list(reversed(master_key))

            for i in range(m, cls.rounds):
                tmp = RotateRight(k[i - 1], 3)
                if m == 4:
                    tmp ^= k[i - 3]
                tmp ^= RotateRight(tmp, 1)
                k[i] = ~k[i - m] ^ tmp ^ int(z[(i - m) % 62]) ^ 3

            return k
Example #6
0
    def test_pysmt_operations(self, width, x, y):
        try:
            from pysmt import shortcuts as sc
        except ImportError:
            return

        modulus = 2 ** width
        x = x % modulus
        y = y % modulus
        bvx = Constant(x, width)
        bvy = Constant(y, width)
        psx = sc.BV(x, width)
        psy = sc.BV(y, width)

        def eval_pysmt(pysmt_var):
            return pysmt_var.simplify().constant_value()

        self.assertEqual(~bvx, eval_pysmt(sc.BVNot(psx)))
        self.assertEqual(bvx & bvy, eval_pysmt(sc.BVAnd(psx, psy)))
        self.assertEqual(bvx | bvy, eval_pysmt(sc.BVOr(psx, psy)))
        self.assertEqual(bvx ^ bvy, eval_pysmt(sc.BVXor(psx, psy)))

        self.assertEqual(BvComp(bvx, bvy), eval_pysmt(sc.BVComp(psx, psy)))
        self.assertEqual((bvx < bvy), eval_pysmt(sc.BVULT(psx, psy)))
        self.assertEqual((bvx <= bvy), eval_pysmt(sc.BVULE(psx, psy)))
        self.assertEqual((bvx > bvy), eval_pysmt(sc.BVUGT(psx, psy)))
        self.assertEqual((bvx >= bvy), eval_pysmt(sc.BVUGE(psx, psy)))

        r = y % bvx.width
        self.assertEqual(bvx << bvy, eval_pysmt(sc.BVLShl(psx, psy)))
        self.assertEqual(bvx >> bvy, eval_pysmt(sc.BVLShr(psx, psy)))
        self.assertEqual(RotateLeft(bvx, r), eval_pysmt(sc.BVRol(psx, r)))
        self.assertEqual(RotateRight(bvx, r), eval_pysmt(sc.BVRor(psx, r)))

        bvb = Constant(y % 2, 1)
        psb = sc.Bool(bool(bvb))
        self.assertEqual(Ite(bvb, bvx, bvy), eval_pysmt(sc.Ite(psb, psx, psy)))
        j = y % bvx.width
        self.assertEqual(bvx[:j], eval_pysmt(sc.BVExtract(psx, start=j)))
        self.assertEqual(bvx[j:], eval_pysmt(sc.BVExtract(psx, end=j)))
        self.assertEqual(Concat(bvx, bvy), eval_pysmt(sc.BVConcat(psx, psy)))
        self.assertEqual(ZeroExtend(bvx, j), eval_pysmt(sc.BVZExt(psx, j)))
        self.assertEqual(Repeat(bvx, 1 + j), eval_pysmt(psx.BVRepeat(1 + j)))

        self.assertEqual(-bvx, eval_pysmt(sc.BVNeg(psx)))
        self.assertEqual(bvx + bvy, eval_pysmt(sc.BVAdd(psx, psy)))
        self.assertEqual(bvx - bvy, eval_pysmt(sc.BVSub(psx, psy)))
        self.assertEqual(bvx * bvy, eval_pysmt(sc.BVMul(psx, psy)))
        if bvy > 0:
            self.assertEqual(bvx / bvy, eval_pysmt(sc.BVUDiv(psx, psy)))
            self.assertEqual(bvx % bvy, eval_pysmt(sc.BVURem(psx, psy)))
Example #7
0
    def test_bv2pysmt(self):
        bvx, bvy = Variable("x", 8), Variable("y", 8)
        psx, psy = bv2pysmt(bvx), bv2pysmt(bvy)

        self.assertEqual(bv2pysmt(Constant(0, 8)), sc.BV(0, 8))
        self.assertEqual(psx, sc.Symbol("x", typing.BVType(8)))

        self.assertEqual(bv2pysmt(~bvx), sc.BVNot(psx))
        self.assertEqual(bv2pysmt(bvx & bvy), sc.BVAnd(psx, psy))
        self.assertEqual(bv2pysmt(bvx | bvy), sc.BVOr(psx, psy))
        self.assertEqual(bv2pysmt(bvx ^ bvy), sc.BVXor(psx, psy))

        self.assertEqual(bv2pysmt(BvComp(bvx, bvy)), sc.Equals(psx, psy))
        self.assertEqual(bv2pysmt(BvNot(BvComp(bvx, bvy))),
                         sc.Not(sc.Equals(psx, psy)))

        self.assertEqual(bv2pysmt(bvx < bvy), sc.BVULT(psx, psy))
        self.assertEqual(bv2pysmt(bvx <= bvy), sc.BVULE(psx, psy))
        self.assertEqual(bv2pysmt(bvx > bvy), sc.BVUGT(psx, psy))
        self.assertEqual(bv2pysmt(bvx >= bvy), sc.BVUGE(psx, psy))

        self.assertEqual(bv2pysmt(bvx << bvy), sc.BVLShl(psx, psy))
        self.assertEqual(bv2pysmt(bvx >> bvy), sc.BVLShr(psx, psy))
        self.assertEqual(bv2pysmt(RotateLeft(bvx, 1)), sc.BVRol(psx, 1))
        self.assertEqual(bv2pysmt(RotateRight(bvx, 1)), sc.BVRor(psx, 1))

        self.assertEqual(bv2pysmt(bvx[4:2]), sc.BVExtract(psx, 2, 4))
        self.assertEqual(bv2pysmt(Concat(bvx, bvy)), sc.BVConcat(psx, psy))
        # zeroextend reduces to Concat
        # self.assertEqual(bv2pysmt(ZeroExtend(bvx, 2)), sc.BVZExt(psx, 2))
        self.assertEqual(bv2pysmt(Repeat(bvx, 2)), psx.BVRepeat(2))

        self.assertEqual(bv2pysmt(-bvx), sc.BVNeg(psx))
        self.assertEqual(bv2pysmt(bvx + bvy), sc.BVAdd(psx, psy))
        # bvsum reduces to add
        # self.assertEqual(bv2pysmt(bvx - bvy), sc.BVSub(psx, psy))
        self.assertEqual(bv2pysmt(bvx * bvy), sc.BVMul(psx, psy))
        self.assertEqual(bv2pysmt(bvx / bvy), sc.BVUDiv(psx, psy))
        self.assertEqual(bv2pysmt(bvx % bvy), sc.BVURem(psx, psy))
Example #8
0
def rf(x, y, k):
    """Round function of Speck32/64."""
    x = (RotateRight(x, 7) + y) ^ k
    y = RotateLeft(y, 2) ^ x
    return x, y
Example #9
0
File: speck.py Project: ranea/ArxPy
 def rf(x, y, k):
     """Round function."""
     x = (RotateRight(x, alpha) + y) ^ k
     y = RotateLeft(y, beta) ^ x
     return x, y
Example #10
0
    def test_bv2pysmt(self):
        bv2pysmt = functools.partial(_bv2pysmt, env=self.env)
        fm = self.env.formula_manager
        tm = self.env.type_manager

        bx, by = Variable("x", 8), Variable("y", 8)
        b1x, b1y = Variable("x1", 1), Variable("y1", 1)
        b6x, b6y = Variable("x6", 6), Variable("y6", 6)
        px, py = bv2pysmt(bx), bv2pysmt(by)
        p1x, p1y = bv2pysmt(b1x, True), bv2pysmt(b1y, True)
        p6x, p6y = bv2pysmt(b6x), bv2pysmt(b6y)

        self.assertEqual(bv2pysmt(Constant(0, 8)), fm.BV(0, 8))
        self.assertEqual(px, fm.Symbol("x", tm.BVType(8)))
        self.assertEqual(p1x, fm.Symbol("x1", tm.BOOL()))

        self.assertEqual(bv2pysmt(~bx), fm.BVNot(px))
        self.assertEqual(bv2pysmt(~b1x, True), fm.Not(p1x))
        self.assertEqual(bv2pysmt(bx & by), fm.BVAnd(px, py))
        self.assertEqual(bv2pysmt(b1x & b1y, True), fm.And(p1x, p1y))
        self.assertEqual(bv2pysmt(bx | by), fm.BVOr(px, py))
        self.assertEqual(bv2pysmt(b1x | b1y, True), fm.Or(p1x, p1y))
        self.assertEqual(bv2pysmt(bx ^ by), fm.BVXor(px, py))
        self.assertEqual(bv2pysmt(b1x ^ b1y, True), fm.Xor(p1x, p1y))

        self.assertEqual(bv2pysmt(BvComp(bx, by)), fm.BVComp(px, py))
        self.assertEqual(bv2pysmt(BvComp(bx, by), True), fm.Equals(px, py))
        self.assertEqual(bv2pysmt(BvNot(BvComp(bx, by))),
                         fm.BVNot(fm.BVComp(px, py)))
        self.assertEqual(bv2pysmt(BvNot(BvComp(bx, by)), True),
                         fm.Not(fm.Equals(px, py)))

        self.assertEqual(bv2pysmt(bx < by), fm.BVULT(px, py))
        self.assertEqual(bv2pysmt(bx <= by), fm.BVULE(px, py))
        self.assertEqual(bv2pysmt(bx > by), fm.BVUGT(px, py))
        self.assertEqual(bv2pysmt(bx >= by), fm.BVUGE(px, py))

        self.assertEqual(bv2pysmt(bx << by), fm.BVLShl(px, py))
        self.assertEqual(bv2pysmt(bx >> by), fm.BVLShr(px, py))
        self.assertEqual(bv2pysmt(RotateLeft(bx, 1)), fm.BVRol(px, 1))
        self.assertEqual(bv2pysmt(RotateRight(bx, 1)), fm.BVRor(px, 1))

        def zext(pysmt_type, offset):
            # zero_extend reduces to Concat
            return fm.BVConcat(fm.BV(0, offset), pysmt_type)

        self.assertEqual(
            bv2pysmt(b6x << b6y, strict_shift=True),
            fm.BVExtract(fm.BVLShl(zext(p6x, 2), zext(p6y, 2)), 0, 5))
        self.assertEqual(
            bv2pysmt(RotateRight(b6x, 1), strict_shift=True),
            fm.BVConcat(fm.BVExtract(p6x, 0, 0), fm.BVExtract(p6x, 1, 5)))

        self.assertEqual(bv2pysmt(bx[4:2]), fm.BVExtract(px, 2, 4))
        self.assertEqual(bv2pysmt(Concat(bx, by)), fm.BVConcat(px, py))

        self.assertEqual(bv2pysmt(ZeroExtend(bx, 2)), zext(px, 2))
        self.assertEqual(bv2pysmt(Repeat(bx, 2)), px.BVRepeat(2))
        self.assertEqual(bv2pysmt(-bx), fm.BVNeg(px))
        self.assertEqual(bv2pysmt(bx + by), fm.BVAdd(px, py))
        # bv_sum reduces to add
        self.assertEqual(bv2pysmt(bx - by), fm.BVSub(px, py))
        self.assertEqual(bv2pysmt(bx * by), fm.BVMul(px, py))
        self.assertEqual(bv2pysmt(bx / by), fm.BVUDiv(px, py))
        self.assertEqual(bv2pysmt(bx % by), fm.BVURem(px, py))

        # cannot reuse Bool and BV{1} variable with the same name
        bxx, byy = Variable("xx", 8), Variable("yy", 8)
        b1xx, b1yy, b1zz = Variable("xx1", 1), Variable("yy1",
                                                        1), Variable("zz1", 1)
        pxx, pyy = bv2pysmt(bxx), bv2pysmt(byy)
        p1xx, p1yy, p1zz = bv2pysmt(b1xx, False), bv2pysmt(b1yy,
                                                           True), bv2pysmt(
                                                               b1zz, True)
        self.assertEqual(bv2pysmt(Ite(b1xx, bxx, byy)),
                         fm.Ite(fm.Equals(p1xx, fm.BV(1, 1)), pxx, pyy))
        self.assertEqual(bv2pysmt(Ite(b1xx, b1yy, b1zz), True),
                         fm.Ite(fm.Equals(p1xx, fm.BV(1, 1)), p1yy, p1zz))
Example #11
0
 def eval(cls, mk):
     return tuple([RotateRight(mk, 1) + Constant(3, 8)])
Example #12
0
 def f_inverse(x, y):
     y = RotateRight(x ^ y, 2)
     x = RotateLeft((x ^ k) - y, 7)
     return x, y
Example #13
0
 def f(x, y):
     x = (RotateRight(x, 7) + y) ^ k
     y = RotateLeft(y, 2) ^ x
     return x, y
Example #14
0
    def _simple_properties(self, x):
        width = x.width

        allones = BvNot(Constant(0, width))

        assert ~~x == x
        # assert ~(x & y) == (~x) | (~y)
        # assert ~(x | y) == (~x) & (~y)

        assert x & 0 == 0 & x == 0
        assert x & allones == allones & x == x
        assert x & x == x
        assert x & (~x) == 0

        assert x | 0 == 0 | x == x
        assert x | allones == allones | x == allones
        assert x | x == x
        assert x | (~x) == allones

        assert x ^ 0 == 0 ^ x == x
        assert x ^ allones == allones ^ x == ~x
        assert x ^ x == 0
        assert x ^ (~x) == allones

        assert x << 0 == x >> 0 == x
        assert 0 << x == 0 >> x == 0
        if isinstance(x, Constant):
            r = min(2 * int(x), x.width)
            assert (x << x) << x == x << r
            assert (x >> x) >> x == x >> r
        elif isinstance(x, Variable) and x.width >= 2:
            assert (x << 1) << 1 == x << 2
            assert (x >> 1) >> 1 == x >> 2

        n = x.width
        assert RotateLeft(x, 0) == RotateRight(x, 0) == x
        if x.width > 2:
            assert RotateLeft(RotateLeft(x, 1), 1) == RotateLeft(x, 2)
            assert RotateRight(RotateRight(x, 1), 1) == RotateRight(x, 2)
        if x.width > 3:
            assert RotateLeft(RotateRight(x, 1), 2) == RotateRight(x, n - 1)
            assert RotateRight(RotateLeft(x, 1), 2) == RotateLeft(x, n - 1)

        if isinstance(x, Constant):
            i = int(x) % (width - 1)
        elif isinstance(x, Variable) and x.width >= 2:
            i = width - 2
        n = x.width
        assert x[:] == x
        assert x[:i][1:0] == x[i + 1:i]
        assert Concat(x, x)[n - 1:i] == x[:i]  # n - 1 <= x.width - 1
        assert Concat(x, x)[n + i:n] == x[i:]  # n >= x.wdith
        assert (x << i)[:i] == x[n - 1 - i:]  # i <= i
        assert RotateLeft(x, i)[:i + 1] == x[n - 1 - i: 1]  # i <= i + 1
        assert (x >> i)[n - i - 1:] == x[n - 1:i]  # n - i - 1 < n - i
        assert RotateRight(x, i)[n - i - 1:] == x[n - 1:i]
        # assert (x & y)[0] == x[0] & y[0]

        if isinstance(x, Constant):
            i = int(x) % (width - 1)
        else:
            assert x.width >= 2
            i = width - 2
        assert Concat(x[:i + 1], x[i:]) == x

        assert -(-x) == x
        # assert -(x + y) == -(x) + -(y)
        # assert -(x * y) == -(x) * y
        # assert -(x / y) == -(x) / y
        # assert -(x % y) == -(x) % y
        # assert -(x ^ y) == BvNot(x ^ y, evaluate=False)

        assert x + 0 == 0 + x == x
        assert x + (-x) == 0

        assert x - 0 == x
        assert 0 - x == -x
        assert x - x == 0

        assert x * 0 == 0 * x == 0
        assert x * 1 == 1 * x == x

        if x != 0:
            assert x / x == 1
            assert 0 / x == 0
            assert x / 1 == x

            assert x % x == 0 % x == x % 1 == 0
Example #15
0
    def _simple_properties(self, x):
        width = x.width
        allones = BvNot(Constant(0, width))

        self.assertTrue( ~~x == x )
        # self.assertTrue( ~(x & y) == (~x) | (~y) )
        # self.assertTrue( ~(x | y) == (~x) & (~y) )

        self.assertTrue( x & 0 == 0 & x == 0 )
        self.assertTrue( x & allones == allones & x == x )
        self.assertTrue( x & x == x )
        self.assertTrue( x & (~x) == 0 )

        self.assertTrue( x | 0 == 0 | x == x )
        self.assertTrue( x | allones == allones | x == allones )
        self.assertTrue( x | x == x )
        self.assertTrue( x | (~x) == allones )

        self.assertTrue( x ^ 0 == 0 ^ x == x )
        self.assertTrue( x ^ allones == allones ^ x == ~x )
        self.assertTrue( x ^ x == 0 )
        self.assertTrue( x ^ (~x) == allones )

        self.assertTrue( x << 0 == x >> 0 == x )
        self.assertTrue( 0 << x == 0 >> x == 0 )
        if isinstance(x, Constant):
            r = min(2 * int(x), x.width)
            self.assertTrue( (x << x) << x == x << r )
            self.assertTrue( (x >> x) >> x == x >> r )
        elif isinstance(x, Variable) and x.width >= 2:
            self.assertTrue( (x << 1) << 1 == x << 2 )
            self.assertTrue( (x >> 1) >> 1 == x >> 2 )

        n = x.width
        self.assertTrue( RotateLeft(x, 0) == RotateRight(x, 0) == x )
        if x.width > 2:
            self.assertTrue( RotateLeft(RotateLeft(x, 1), 1) == RotateLeft(x, 2) )
            self.assertTrue( RotateRight(RotateRight(x, 1), 1) == RotateRight(x, 2) )
        if x.width > 3:
            self.assertTrue( RotateLeft(RotateRight(x, 1), 2) == RotateRight(x, n - 1) )
            self.assertTrue( RotateRight(RotateLeft(x, 1), 2) == RotateLeft(x, n - 1) )

        if isinstance(x, Constant):
            i = int(x) % (width - 1)
        elif isinstance(x, Variable) and x.width >= 2:
            i = width - 2
        else:
            raise ValueError("invalid x: {}".format(x))
        n = x.width
        self.assertTrue( x[:] == x )
        self.assertTrue( x[:i][1:0] == x[i + 1:i] )
        self.assertTrue( Concat(x, x)[n - 1:i] == x[:i] ) # n - 1 <= x.width - 1
        self.assertTrue( Concat(x, x)[n + i:n] == x[i:] ) # n >= x.width
        self.assertTrue( (x << i)[:i] == x[n - 1 - i:] ) # i <= i
        self.assertTrue( RotateLeft(x, i)[:i + 1] == x[n - 1 - i: 1] )  # i <= i + 1
        self.assertTrue( (x >> i)[n - i - 1:] == x[n - 1:i] ) # n - i - 1 < n - i
        self.assertTrue( RotateRight(x, i)[n - i - 1:] == x[n - 1:i] )
        # assert (x & y)[0] == x[0] & y[0]

        if isinstance(x, Constant):
            i = int(x) % (width - 1)
        else:
            self.assertTrue( x.width >= 2 )
            i = width - 2
        self.assertTrue( Concat(x[:i + 1], x[i:]) == x )
        zero_bit = Constant(0, 1)
        self.assertTrue( Concat(zero_bit, Concat(zero_bit, x)) == Concat(Constant(0, 2), x) )
        self.assertTrue( Concat(Concat(x, zero_bit), zero_bit) == Concat(x, Constant(0, 2)) )

        self.assertTrue( -(-x) == x )
        # assert -(x + y) == -(x) + -(y)
        # assert -(x * y) == -(x) * y
        # assert -(x / y) == -(x) / y
        # assert -(x % y) == -(x) % y
        # assert -(x ^ y) == BvNot(x ^ y, evaluate=False)

        self.assertTrue( x + 0 == 0 + x == x )
        self.assertTrue( x + (-x) == 0 )

        self.assertTrue( x - 0 == x )
        self.assertTrue( 0 - x == -x )
        self.assertTrue( x - x == 0 )

        self.assertTrue( x * 0 == 0 * x == 0 )
        self.assertTrue( x * 1 == 1 * x == x )

        if x != 0:
            self.assertTrue( x / x == 1 )
            self.assertTrue( 0 / x == 0 )
            self.assertTrue( x / 1 == x )

            self.assertTrue( x % x == 0 % x == x % 1 == 0 )