예제 #1
0
    def test_SearchCh(self):
        for diff_type in [XorDiff, RXDiff]:
            for bv_function in [MyFunction]:
                for option in CH_OPTIONS:
                    btor_ch_found = test_search_ch_skch(
                        bvf_cipher=bv_function,
                        diff_type=diff_type,
                        initial_weight=0,
                        solver_name="btor",
                        rounds=None,
                        der_mode=option.der_mode,
                        search_mode=option.search_mode,
                        check=True,
                        verbose_level=VERBOSE_LEVEL,
                        filename=None)

                    if btor_ch_found is not None:
                        btor_weight = int(btor_ch_found.ch_weight)
                        btor_id = [
                            value.val
                            for var, value in btor_ch_found.input_diff
                        ]
                        self.assertFalse(
                            BvComp(functools.reduce(Concat, btor_id), 0))
                    else:
                        btor_weight = math.inf

                    if diff_type == XorDiff:
                        self.assertEqual(0, btor_weight)
                    elif diff_type == RXDiff:
                        if option.der_mode == DerMode.ProbabilityOne:
                            self.assertEqual(math.inf, btor_weight)
                        else:
                            self.assertLessEqual(1, btor_weight)
                            self.assertLessEqual(btor_weight, 3)

                    yices_ch_found = test_search_ch_skch(
                        bvf_cipher=bv_function,
                        diff_type=diff_type,
                        initial_weight=0,
                        solver_name="yices",
                        rounds=None,
                        der_mode=option.der_mode,
                        search_mode=option.search_mode,
                        check=True,
                        verbose_level=1 if VERBOSE_LEVEL >= 2 else 0,
                        filename=None)

                    if yices_ch_found is not None:
                        yices_weight = int(yices_ch_found.ch_weight)
                        yices_id = [
                            value.val
                            for var, value in yices_ch_found.input_diff
                        ]
                        self.assertFalse(
                            BvComp(functools.reduce(Concat, yices_id), 0))
                    else:
                        yices_weight = math.inf

                    self.assertEqual(btor_weight, yices_weight)
예제 #2
0
    def has_probability_one(self, output_diff):
        """Return whether the input diff propagates to the output diff with probability one.

            >>> from arxpy.bitvector.core import Constant, Variable
            >>> from arxpy.differential.difference import XorDiff
            >>> alpha = XorDiff(Constant(0, 16))
            >>> f = XDSimonRF(alpha)
            >>> f.has_probability_one(XorDiff(Constant(0, 16)))
            0b1

        """
        a, b, c = self.op.a, self.op.b, self.op.c
        n = self.input_diff[0].val.width
        assert math.gcd(n, a - b) == 1 and a > b and n % 2 == 0

        alpha = self.input_diff[0].val
        Rol = RotateLeft
        varibits = Rol(alpha, a) | Rol(alpha, b)
        r = (2 * a - b) % n
        doublebits = (Rol(alpha, b) & (~Rol(alpha, a)) & Rol(alpha, r))

        beta = output_diff.val
        gamma = beta ^ Rol(alpha, c)

        case2 = BvComp(Constant(0, n), (gamma & (~varibits)) |
                       ((gamma ^ Rol(gamma, a - b)) & doublebits))

        hw = varibits ^ doublebits  # no need to PopCount

        condition = ~BvComp(alpha, ~Constant(0, n))
        condition &= case2
        condition &= BvComp(hw, Constant(0, hw.width))

        return condition
예제 #3
0
    def test_search_Ch(self):
        diff_type = XorDiff

        for bvf in BV_FUNCTIONS:
            if bvf.rounds is None:
                continue
            for rounds in range(bvf.rounds, bvf.rounds + 2):
                bvf.function.set_rounds(rounds)
                for option in OPTIONS:
                    if bvf.function == PiPermutation and option == ChSearchMode.Optimal:
                        continue

                    btor_ch_found = test_search_ch_skch(
                        bvf_cipher=bvf.function,
                        diff_type=diff_type,
                        initial_weight=0,
                        solver_name="btor",
                        rounds=rounds,
                        der_mode=option.der_mode,
                        search_mode=option.search_mode,
                        check=False
                        if option.search_mode in NoCheckModes else CHECK,
                        verbose_level=VERBOSE_LEVEL,
                        filename=self.filename)

                    if btor_ch_found is not None:
                        btor_weight = int(btor_ch_found.ch_weight)
                        btor_id = [
                            value.val
                            for var, value in btor_ch_found.input_diff
                        ]
                        self.assertFalse(
                            BvComp(functools.reduce(Concat, btor_id), 0))
                    else:
                        btor_weight = math.inf

                    yices_ch_found = test_search_ch_skch(
                        bvf_cipher=bvf.function,
                        diff_type=diff_type,
                        initial_weight=0,
                        solver_name="yices",
                        rounds=rounds,
                        der_mode=option.der_mode,
                        search_mode=option.search_mode,
                        check=False,
                        verbose_level=1 if VERBOSE_LEVEL >= 2 else 0,
                        filename=self.filename)

                    if yices_ch_found is not None:
                        yices_weight = int(yices_ch_found.ch_weight)
                        yices_id = [
                            value.val
                            for var, value in yices_ch_found.input_diff
                        ]
                        self.assertFalse(
                            BvComp(functools.reduce(Concat, yices_id), 0))
                    else:
                        yices_weight = math.inf

                    self.assertEqual(btor_weight, yices_weight)
예제 #4
0
    def test_SearchSkCh(self):
        diff_type = XorDiff

        for cipher in [Cipher1, Cipher2]:
            cipher.set_rounds(1)
            for option in SKCH_OPTIONS:
                btor_ch_found = test_search_ch_skch(
                    bvf_cipher=cipher,
                    diff_type=diff_type,
                    initial_weight=0,
                    solver_name="btor",
                    rounds=1,
                    der_mode=option.der_mode,
                    search_mode=option.search_mode,
                    check=True,
                    verbose_level=VERBOSE_LEVEL,
                    filename=None)

                if btor_ch_found is not None:
                    btor_weight = int(btor_ch_found.ch_weight)
                    btor_id = [
                        value.val for var, value in btor_ch_found.input_diff
                    ]
                    self.assertFalse(
                        BvComp(functools.reduce(Concat, btor_id), 0))
                else:
                    btor_weight = math.inf

                self.assertEqual(0, btor_weight)

                yices_ch_found = test_search_ch_skch(
                    bvf_cipher=cipher,
                    diff_type=diff_type,
                    initial_weight=0,
                    solver_name="yices",
                    rounds=1,
                    der_mode=option.der_mode,
                    search_mode=option.search_mode,
                    check=True,
                    verbose_level=1 if VERBOSE_LEVEL >= 2 else 0,
                    filename=None)

                if yices_ch_found is not None:
                    yices_weight = int(yices_ch_found.ch_weight)
                    yices_id = [
                        value.val for var, value in yices_ch_found.input_diff
                    ]
                    self.assertFalse(
                        BvComp(functools.reduce(Concat, yices_id), 0))
                else:
                    yices_weight = math.inf

                self.assertEqual(btor_weight, yices_weight)
예제 #5
0
    def is_possible(self, output_diff):
        """Return whether the given output `XorDiff` is possible.

            >>> from arxpy.bitvector.core import Constant, Variable
            >>> from arxpy.bitvector.context import NotEvaluation
            >>> from arxpy.bitvector.printing import BvWrapPrinter
            >>> from arxpy.differential.difference import XorDiff
            >>> alpha = XorDiff(Constant(0, 16))
            >>> f = XDSimonRF(alpha)
            >>> f.is_possible(XorDiff(Constant(0, 16)))
            0b1
            >>> u, v = Variable("u", 16), Variable("v", 16)
            >>> f = XDSimonRF(XorDiff(u))
            >>> with NotEvaluation([PopCount]):
            ...     result = f.is_possible(XorDiff(v))
            >>> print(BvWrapPrinter().doprint(result))
            Ite(0xffff == u,
                0b0 == (PopCount(v ^ (u <<< 2))[0]),
                ==(0x0000,
                   |(~(u <<< 8) & (u <<< 1) & (u <<< 15) & (v ^ (u <<< 2) ^ ((v ^ (u <<< 2)) <<< 7)),
                     ~((u <<< 1) | (u <<< 8)) & (v ^ (u <<< 2))
            >>> result.xreplace({u: Constant(0, 16), v: Constant(0, 16)})
            0b1

        See `Derivative.is_possible` for more information.
        """
        a, b, c = self.op.a, self.op.b, self.op.c
        n = self.input_diff[0].val.width
        assert math.gcd(n, a - b) == 1 and a > b and n % 2 == 0

        alpha = self.input_diff[0].val
        Rol = RotateLeft
        varibits = Rol(alpha, a) | Rol(alpha, b)
        r = (2 * a - b) % n
        doublebits = (Rol(alpha, b) & (~Rol(alpha, a)) & Rol(alpha, r))

        beta = output_diff.val
        gamma = beta ^ Rol(alpha, c)

        def is_even(x):
            return BvComp(x[0], Constant(0, 1))

        case2 = BvComp(Constant(0, n), (gamma & (~varibits)) |
                       ((gamma ^ Rol(gamma, a - b)) & doublebits))

        condition = Ite(BvComp(alpha, ~Constant(0, n)),
                        is_even(PopCount(gamma)), case2)

        return condition
예제 #6
0
    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 XDF
            >>> x, y = DiffVar("x", 16), DiffVar("y", 16)
            >>> d = XDF(x, y)
            >>> d.weight()  # doctest: +ELLIPSIS
            Ite(0xffff == x, 0b01111, ((0x00ff & ((0x0f0f & ((0x3333 ...
            >>> zero = Constant(0, 16)
            >>> d.weight().xreplace({x: zero, y: zero})
            0b00000

        """
        a, b = self.op.a, self.op.b
        n = self.input_diff[0].width

        alpha = self.input_diff[0]
        BvRol = RotateLeft
        varibits = BvRol(alpha, a) | BvRol(alpha, b)
        doublebits = BvRol(alpha, b) & (~BvRol(alpha, a)) & BvRol(
            alpha, 2 * a - b)

        hw = _HammingWeight(varibits ^ doublebits)
        width = max((n - 1).bit_length(), hw.width)

        value = Ite(BvComp(alpha, ~Constant(0, n)), Constant(n - 1, width),
                    ZeroExtend(hw, width - hw.width))

        return value
예제 #7
0
파일: shacal1.py 프로젝트: nc26676027/ArxPy
    def is_possible(self, output_diff):
        x, y, z = [d.val for d in self.input_diff]
        w = output_diff.val
        n = x.width

        def eq(x, y, z):
            return (~x ^ y) & (~x ^ z)

        return BvComp(eq(x, y, z) & (x ^ w), Constant(0, n))
예제 #8
0
파일: multi2.py 프로젝트: ranea/ArxPy
    def is_possible(self, output_diff):
        dx, dy = [d.val for d in self.input_diff]
        dz = output_diff.val
        n = dx.width

        # (dx, dy) = (0, 0) -> dz =(1)
        bad_case = (~dx) & (~dy) & dz

        return BvComp(bad_case, Constant(0, n))
예제 #9
0
파일: multi2.py 프로젝트: ranea/ArxPy
    def has_probability_one(self, output_diff):
        dx, dy = [d.val for d in self.input_diff]
        dz = output_diff.val
        n = dx.width

        # (dx, dy) = (0, 0) -> dz =(0)
        pr1_case = (~dx) & (~dy) & (~dz)

        return BvComp(pr1_case, ~Constant(0, n))
예제 #10
0
파일: shacal1.py 프로젝트: nc26676027/ArxPy
    def has_probability_one(self, output_diff):
        x, y, z = [d.val for d in self.input_diff]
        w = output_diff.val
        n = x.width

        def eq(x, y, z, w):
            return (~x ^ y) & (~x ^ z) & (~x ^ w)

        return BvComp(eq(x, y, z, w), ~Constant(0, n))
예제 #11
0
파일: shacal1.py 프로젝트: nc26676027/ArxPy
    def is_possible(self, output_diff):
        x, y, z = [d.val for d in self.input_diff]
        w = output_diff.val
        n = x.width

        def eq(a, b):
            return ~a ^ b

        return BvComp(~x & eq(y, z) & eq(~y, w), Constant(0, n))
예제 #12
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))
예제 #13
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)))
예제 #14
0
    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 XDF
            >>> x, y = DiffVar("x", 16), DiffVar("y", 16)
            >>> d = XDF(x, y)
            >>> d.is_valid()  # doctest: +ELLIPSIS
            Ite(0xffff == x, 0b0 == (((0x00ff & ((0x0f0f & ((0x3333 ...
            >>> zero = Constant(0, 16)
            >>> d.is_valid().xreplace({x: zero, y: zero})
            0b1

        """
        a, b, c = self.op.a, self.op.b, self.op.c
        n = self.input_diff[0].width
        assert gcd(n, a - b) == 1 and a > b and n % 2 == 0

        alpha = self.input_diff[0]
        beta = self.output_diff
        BvRol = RotateLeft
        varibits = BvRol(alpha, a) | BvRol(alpha, b)
        doublebits = BvRol(alpha, b) & (~BvRol(alpha, a)) & BvRol(
            alpha, 2 * a - b)
        gamma = beta ^ BvRol(alpha, c)

        def is_even(x):
            return BvComp(x[0], Constant(0, 1))

        case2 = BvComp(Constant(0, n), (gamma & (~varibits)) |
                       ((gamma ^ BvRol(gamma, a - b)) & doublebits))

        condition = Ite(BvComp(alpha, ~Constant(0, n)),
                        is_even(_HammingWeight(gamma)), case2)

        return condition
예제 #15
0
    def weight(self, output_diff):
        """Return the weight of a possible output `XorDiff`.

            >>> from arxpy.bitvector.core import Constant, Variable
            >>> from arxpy.bitvector.context import NotEvaluation
            >>> from arxpy.bitvector.printing import BvWrapPrinter
            >>> from arxpy.bitvector.extraop import PopCount
            >>> from arxpy.differential.difference import XorDiff
            >>> alpha = XorDiff(Constant(0, 16))
            >>> f = XDSimonRF(alpha)
            >>> f.weight(XorDiff(Constant(0, 16)))
            0b00000
            >>> alpha = XorDiff(Variable("u", 16))
            >>> f = XDSimonRF(alpha)
            >>> beta = XorDiff(Variable("v", 16))
            >>> with NotEvaluation([PopCount]):
            ...     print(BvWrapPrinter().doprint(f.weight(beta)))
            Ite(0xffff == u,
                0b01111,
                PopCount((~(u <<< 8) & (u <<< 1) & (u <<< 15)) ^ ((u <<< 1) | (u <<< 8)))

        See `Derivative.weight` for more information.
        """
        a, b = self.op.a, self.op.b
        n = self.input_diff[0].val.width

        alpha = self.input_diff[0].val
        Rol = RotateLeft
        varibits = Rol(alpha, a) | Rol(alpha, b)
        r = (2 * a - b) % n
        doublebits = (Rol(alpha, b) & (~Rol(alpha, a)) & Rol(alpha, r))

        hw = PopCount(varibits ^ doublebits)
        width = max((n - 1).bit_length(), hw.width)

        value = Ite(BvComp(alpha, ~Constant(0, n)), Constant(n - 1, width),
                    ZeroExtend(hw, width - hw.width))

        return value
예제 #16
0
    def test_SearchRkCh(self):
        for diff_type in [XorDiff, RXDiff]:
            for cipher in [Cipher1, Cipher2]:
                if diff_type == RXDiff and cipher == Cipher2:
                    continue

                cipher.set_rounds(1)
                for option in RKCH_OPTIONS:
                    if diff_type == RXDiff and option.enc_der_mode == RkChSearchMode.OptimalFixEncMinKey:
                        continue

                    btor_rkch_found = test_search_related_key_ch(
                        cipher=cipher,
                        diff_type=diff_type,
                        initial_ew=option.initial_ew,
                        initial_kw=option.initial_kw,
                        solver_name="btor",
                        rounds=1,
                        key_der_mode=option.key_der_mode,
                        enc_der_mode=option.enc_der_mode,
                        allow_zero_enc_input_diff=True,
                        search_mode=option.search_mode,
                        check=True,
                        verbose_level=VERBOSE_LEVEL,
                        filename=None)

                    if btor_rkch_found is not None:
                        btor_weight = [
                            int(btor_rkch_found.key_ch_found.ch_weight),
                            int(btor_rkch_found.enc_ch_found.ch_weight)
                        ]
                        btor_id = [
                            value.val for var, value in
                            btor_rkch_found.key_ch_found.input_diff
                        ]
                        self.assertFalse(
                            BvComp(functools.reduce(Concat, btor_id), 0))
                    else:
                        btor_weight = [math.inf, math.inf]

                    if diff_type == XorDiff:
                        self.assertEqual(
                            [option.initial_kw, option.initial_ew],
                            btor_weight)
                    elif diff_type == RXDiff:
                        if option.enc_der_mode == DerMode.ProbabilityOne:
                            self.assertEqual([math.inf, math.inf], btor_weight)
                        elif option.search_mode in [
                                RkChSearchMode.FirstMinSum,
                                RkChSearchMode.FirstValidKeyMinEnc
                        ]:
                            self.assertEqual([0, 1], btor_weight)

                    yices_rkch_found = test_search_related_key_ch(
                        cipher=cipher,
                        diff_type=diff_type,
                        initial_ew=option.initial_ew,
                        initial_kw=option.initial_kw,
                        solver_name="yices",
                        rounds=1,
                        key_der_mode=option.key_der_mode,
                        enc_der_mode=option.enc_der_mode,
                        allow_zero_enc_input_diff=True,
                        search_mode=option.search_mode,
                        check=True,
                        verbose_level=1 if VERBOSE_LEVEL >= 2 else 0,
                        filename=None)

                    if yices_rkch_found is not None:
                        yices_weight = [
                            int(yices_rkch_found.key_ch_found.ch_weight),
                            int(yices_rkch_found.enc_ch_found.ch_weight)
                        ]
                        yices_id = [
                            value.val for var, value in
                            yices_rkch_found.key_ch_found.input_diff
                        ]
                        self.assertFalse(
                            BvComp(functools.reduce(Concat, yices_id), 0))
                    else:
                        yices_weight = [math.inf, math.inf]

                    if option.search_mode in [
                            RkChSearchMode.FirstValidKeyMinEnc,
                            RkChSearchMode.OptimalValidKeyMinEnc
                    ]:
                        # ignore key weights
                        self.assertEqual(btor_weight[1], yices_weight[1])
                    else:
                        self.assertEqual(btor_weight, yices_weight)
예제 #17
0
파일: test_ciphers.py 프로젝트: ranea/ArxPy
    def test_search_RkCh(self):
        diff_type = XorDiff

        for bc in BLOCK_CIPHERS:
            if bc.rk_rounds is None:
                continue
            for rounds in range(bc.rk_rounds, bc.rk_rounds + 2):
                bc.cipher.set_rounds(rounds)
                for option in RK_OPTIONS:
                    btor_rkch_found = test_search_related_key_ch(
                        cipher=bc.cipher,
                        diff_type=diff_type,
                        initial_ew=option.initial_ew,
                        initial_kw=option.initial_kw,
                        solver_name="btor",
                        rounds=rounds,
                        key_der_mode=option.key_der_mode,
                        enc_der_mode=option.enc_der_mode,
                        allow_zero_enc_input_diff=True,
                        search_mode=option.search_mode,
                        check=False
                        if option.search_mode in NoCheckModes else CHECK,
                        verbose_level=VERBOSE_LEVEL,
                        filename=self.filename)

                    if btor_rkch_found is not None:
                        btor_weight = [
                            int(btor_rkch_found.key_ch_found.ch_weight),
                            int(btor_rkch_found.enc_ch_found.ch_weight)
                        ]
                        btor_id = [
                            value.val for var, value in
                            btor_rkch_found.key_ch_found.input_diff
                        ]
                        self.assertFalse(
                            BvComp(functools.reduce(Concat, btor_id), 0))
                    else:
                        btor_weight = [math.inf, math.inf]

                    yices_rkch_found = test_search_related_key_ch(
                        cipher=bc.cipher,
                        diff_type=diff_type,
                        initial_ew=option.initial_ew,
                        initial_kw=option.initial_kw,
                        solver_name="yices",
                        rounds=rounds,
                        key_der_mode=option.key_der_mode,
                        enc_der_mode=option.enc_der_mode,
                        allow_zero_enc_input_diff=True,
                        search_mode=option.search_mode,
                        check=False,
                        verbose_level=1 if VERBOSE_LEVEL >= 2 else 0,
                        filename=self.filename)

                    if yices_rkch_found is not None:
                        yices_weight = [
                            int(yices_rkch_found.key_ch_found.ch_weight),
                            int(yices_rkch_found.enc_ch_found.ch_weight)
                        ]
                        yices_id = [
                            value.val for var, value in
                            yices_rkch_found.key_ch_found.input_diff
                        ]
                        self.assertFalse(
                            BvComp(functools.reduce(Concat, yices_id), 0))
                    else:
                        yices_weight = [math.inf, math.inf]

                    if option.search_mode in [
                            RkChSearchMode.FirstValidKeyMinEnc,
                            RkChSearchMode.OptimalValidKeyMinEnc
                    ]:
                        # ignore key weights
                        self.assertEqual(btor_weight[1], yices_weight[1])
                    else:
                        self.assertAlmostEqual(sum(btor_weight),
                                               sum(yices_weight))
예제 #18
0
 def is_even(x):
     return BvComp(x[0], Constant(0, 1))
예제 #19
0
파일: test_types.py 프로젝트: ranea/ArxPy
    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))