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}))
def weight(self): """Return the weight of the differential. >>> from arxpy.bitvector.core import Constant >>> from arxpy.diffcrypt.difference import DiffVar >>> from arxpy.ciphers.simon32_64 import RXDF >>> x, y = DiffVar("x", 16), DiffVar("y", 16) >>> d = RXDF(x, y) >>> d.weight() # doctest: +ELLIPSIS Ite(0xffff == (x <<< 1), 0b01111, ((0x00ff & ((0x0f0f & ((0x3333 ... >>> zero = Constant(0, 16) >>> d.weight().xreplace({x: zero, y: zero}) 0b00000 """ width = self.input_diff[0].width x = DiffVar("x", width) y = DiffVar("y", width) return self.op.differential(XorDiff)(x, y).weight().xreplace({ x: RotateLeft(self.input_diff[0], 1), y: RotateLeft(self.output_diff, 1) })
def is_valid(self): """Return the bv expression for non-zero propagation probability. >>> from arxpy.bitvector.core import Constant >>> from arxpy.diffcrypt.difference import DiffVar >>> from arxpy.ciphers.simon32_64 import RXDF >>> x, y = DiffVar("x", 16), DiffVar("y", 16) >>> d = RXDF(x, y) >>> d.is_valid() # doctest: +ELLIPSIS Ite(0xffff == (x <<< 1), 0b0 == (((0x00ff & ((0x0f0f & ((0x3333 ... >>> zero = Constant(0, 16) >>> d.is_valid().xreplace({x: zero, y: zero}) 0b1 """ width = self.input_diff[0].width x = DiffVar("x", width) y = DiffVar("y", width) return self.op.differential(XorDiff)(x, y).is_valid().xreplace({ x: RotateLeft(self.input_diff[0], 1), y: RotateLeft(self.output_diff, 1) })
def pi4(R, k_i): if REFERENCE_VERSION: x = RotateLeft(R + k_i, 2) + (R + k_i) + Constant(1, 32) else: assert isinstance(k_i, list) x = RotateLeft(R + k_i[0], 2) + (R + k_i[1]) return x
def pi2(R, k_i): if REFERENCE_VERSION: x = RotateLeft(R + k_i, 1) + (R + k_i) + (-Constant(1, 32)) else: assert isinstance(k_i, list) x = RotateLeft(R + k_i[0], 1) + (R + k_i[1]) return RotateLeft(x, 4) ^ x
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))
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]))
def eval(cls, *master_key): k = master_key num_rk = min(cls.rounds, 2 * kappa // w) rk = [None for _ in range(num_rk)] for i in range(kappa // w): if i < num_rk: rk[i] = k[i] ^ RotateLeft(k[i], 1) ^ RotateLeft(k[i], 8) if ((i + (kappa // w)) ^ 1) < num_rk: rk[(i + (kappa // w)) ^ 1] = k[i] ^ RotateLeft( k[i], 1) ^ RotateLeft(k[i], 11) return rk
def eval(cls, p0, p1, p2, p3): x = [p0, p1, p2, p3] for i in range(cls.rounds): y = [None for _ in range(4)] rk = cls.round_keys[i % (2 * kappa // w)] if i % 2 == 0: y[3] = RotateLeft((x[0] ^ i) + (RotateLeft(x[1], 1) ^ rk), 8) else: y[3] = RotateLeft((x[0] ^ i) + (RotateLeft(x[1], 8) ^ rk), 1) for j in range(2 + 1): y[j] = x[j + 1] x = y return x
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)))
def pi3(L, k_i, k_j): if REFERENCE_VERSION: y = RotateLeft(L + k_i, 2) + (L + k_i) + Constant(1, 32) else: assert isinstance(k_i, list) y = RotateLeft(L + k_i[0], 2) + (L + k_i[1]) x = RotateLeft(RotateLeft(y, 8) ^ (y + k_j), 1) - (RotateLeft(y, 8) ^ (y + k_j)) return RotateLeft(x, 16) ^ (BvOr(x, L))
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))
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
def S1(X1, X2): return RotateLeft(X1 + X2 + Constant(1, 8), 2)
def f_inverse(x, y): y = RotateRight(x ^ y, 2) x = RotateLeft((x ^ k) - y, 7) return x, y
def f(x, y): x = (RotateRight(x, 7) + y) ^ k y = RotateLeft(y, 2) ^ x return x, y
def eval(cls, x): if isinstance(x, Constant): return (RotateLeft(x, cls.a) & RotateLeft(x, cls.b)) ^ RotateLeft( x, cls.c)
def eval(cls, x, y): x = RotateLeft(x ^ Constant(1, 8), 1) y = ~y return tuple([x + y])
def eval(cls, x, y): x ^= cls.round_keys[0] x = (x + y) y = x ^ RotateLeft(cls.round_keys[1], 1) return x, y
def eval(cls, x, y): x = (x + y) ^ cls.round_keys[0] y = RotateLeft(x, 1) + Constant(1, 8) return x, y
def S0(X1, X2): return RotateLeft(X1 + X2, 2)
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))
def rf(x, y, k): """Round function.""" x = (RotateRight(x, alpha) + y) ^ k y = RotateLeft(y, beta) ^ x return x, y
def rf(x, y, k): """Round function of Speck32/64.""" x = (RotateRight(x, 7) + y) ^ k y = RotateLeft(y, 2) ^ x return x, y
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 )