Пример #1
0
 def compute_logical(vec, X, Y, ctx, use_esf):
     nbits = X.nbits
     e = imm(1)
     for i in range(nbits):
         e *= X.eval(vec, i, use_esf) + Y.eval(vec, i, use_esf) + imm(1)
         simplify_inplace(e)
     return e
Пример #2
0
def test_N(nbits, X, n):
    ret = imm(1)
    for i in range(nbits):
        if ((n >> i) & 1) == 1:
            ret *= X[i]
        else:
            ret *= X[i] + imm(1)
    simplify_inplace(ret)
    return ret
Пример #3
0
 def matrix_v(i, j):
     if i == j:
         return imm(1)
     if i < j:
         return imm(0)
     if i > j:
         mask = (~((1 << (j)) - 1)) & self.max_uint
         mask2 = ((1 << (i)) - 1) & self.max_uint
         mask &= mask2
         return imm((n & mask) == mask)
Пример #4
0
 def sub_Y(self, X, Y):
     carry = imm(0)
     ret = Vector(self.nbits)
     if self.use_esf:
         for i in range(0, self.nbits):
             ret[i] = simplify_inplace(X[i]+Y[i]+carry)
             carry = esf(2, [X[i]+imm(1), Y[i], carry])
     else:
         for i in range(0, self.nbits):
             sum_XY = simplify_inplace(X[i]+Y[i])
             ret[i] = simplify_inplace(sum_XY+carry)
             carry = simplify_inplace((X[i]+imm(1))*Y[i] + (carry * (sum_XY+imm(1))))
     return ret
Пример #5
0
def evaluate_expr(E, nbits, map_):
    # keys of map_ can be mba variables or symbols
    #   => an mba variable must map to an integer
    #   => a symbol must map to an expression
    keys = []
    values = []
    for k,v in six.iteritems(map_):
        # TOFIX: not a clean test
        if hasattr(k, "vec"):
            if not isinstance(v, six.integer_types):
                raise ValueError("an MBAVariable must map to an integer value!")
            keys.extend(k.vec)
            values.extend(imm((v>>i)&1) for i in range(k.nbits))
        elif isinstance(k, Expr):
            if not k.is_sym():
                raise ValueError("only symbols or MBAVariable can be a key")
            if not isinstance(v, Expr):
                raise ValueError("a symbol can only be mapped to an expression")
            keys.append(k)
            values.append(v)

    E = expand_esf(E)
    simplify_inplace(E)
    subs_exprs_inplace(E, keys, values)
    simplify_inplace(E)
    try:
        return E.get_int_be()
    except RuntimeError:
        return E
Пример #6
0
def __identify(app, in_name):
    # TODO: identify number of independant inputs
    NL = app.nl().vector()
    M = app.matrix()
    nbits_in = M.ncols()
    nbits_out = M.nlines()
    if nbits_in != nbits_out:
        raise ValueError("do not yet support application with a different\
                number of input and output bits!")
    mba = MBA(nbits_in)
    var_in = mba.var(in_name)

    if NL != Vector(len(NL)):
        return _identify_nonaffine(app, var_in)
    C = EX.ExprCst(mba.from_vec(app.cst()).to_cst(), nbits_out)
    if M == Matrix(nbits_out, nbits_in):
        # This is just a constant
        return C

    ret = EX.ExprBV(var_in)
    matrix_empty = 0
    # Find empty columns in the matrix.
    for j in range(nbits_in):
        is_zero = reduce(operator.and_, (M.at(i, j) == imm(0)
                                         for i in range(nbits_out)), True)
        if is_zero:
            matrix_empty |= 1 << j
    matrix_and_mask = (~matrix_empty) % (2**nbits_out)
    if matrix_empty != 0:
        ret = EX.ExprAnd(ret, EX.ExprCst(matrix_and_mask, nbits_out))
    if mba.from_vec(M * var_in.vec) ^ (var_in & matrix_empty) == var_in:
        # This is a XOR
        return EX.ExprXor(ret, C)
    raise ValueError("unable to identify an expression")
Пример #7
0
 def or_n(self, X, n):
     ret = Vector(self.nbits)
     for i in range(self.nbits):
         if n & (1 << i):
             ret[i] = imm(1)
         else:
             ret[i] = X[i]
     return ret
Пример #8
0
 def iadd_lshifted_Y(self, X, Y, offset):
     if self.use_esf:
         self.iadd_Y(X, self.lshift_n(Y, offset))
         simplify_inplace(X)
         return
     carry = imm(0)
     for i in range(0, self.nbits):
         if i < offset:
             Yi = imm(0)
         else:
             Yi = Y[i - offset]
         Xi = X[i]
         mul_XY = simplify_inplace(Xi * Yi)
         Xi += Yi
         simplify_inplace(Xi)
         carry_new = simplify_inplace(mul_XY + (carry * Xi))
         Xi += carry
         simplify_inplace(Xi)
         carry = carry_new
Пример #9
0
    def solve(self, X):
        nbits = len(X.vec)
        idx_base = X[0].sym_idx()
        for I0 in self.I0s:
            I0.difference_update(self.I1)
            if (len(I0) == 0):
                return []
        self.I0s = [I0 for I0 in self.I0s if len(I0) > 0]

        fix1 = Vector(X.vec)
        for idx in self.I1:
            idx = self.__idx(idx, idx_base, nbits)
            fix1[idx] = imm(1)
        if (len(self.I0s) == 0):
            return [fix1]

        ret = []
        def iter_zeros(idxes, I0s):
            if len(I0s) == 0:
                yield idxes
                return

            for i,I0 in enumerate(I0s):
                if I0.isdisjoint(idxes):
                    next_I0 = I0
                    next_idx = i
                    break
            else:
                yield idxes
                return

            for idx in next_I0:
                new_idxes = idxes + [idx]
                for z in iter_zeros(new_idxes, I0s[next_idx+1:]):
                    yield z

        for idxes in iter_zeros([], self.I0s):
            new = Vector(fix1)
            for idx in idxes:
                new[self.__idx(idx, idx_base, nbits)] = imm(0)
            ret.append(new)
        return ret
Пример #10
0
 def compute(self, vec, i, args, ctx, use_esf):
     if ((self.mask >> i) & 1) == 1:
         return imm(1)
     args = list(args)
     ret = esf(1, args)
     for i in range(2, len(args) + 1):
         ret += esf(i, args)
     if not use_esf:
         expand_esf_inplace(ret)
         simplify_inplace(ret)
     return ret
Пример #11
0
    def compute_binop_(vec, i, X, Y, CC, use_esf):
        carry = CC.carry

        sum_args = simplify_inplace(X + Y)
        ret = simplify_inplace(sum_args + carry)
        carry = esf(2, [X + imm(1), Y, carry])
        if not use_esf:
            expand_esf_inplace(carry)
            carry = simplify_inplace(carry)

        CC.carry = carry
        return ret
Пример #12
0
 def iadd_Y(self, X, Y):
     carry = imm(0)
     ret = Vector(self.nbits)
     if self.use_esf:
         for i in range(0, self.nbits):
             new_carry = esf(2, [X[i], Y[i], carry])
             X[i] += simplify_inplace(Y[i] + carry)
             carry = new_carry
     else:
         for i in range(0, self.nbits):
             sum_XY = simplify_inplace(X[i] + Y[i])
             new_carry = simplify_inplace(X[i] * Y[i] + (carry * sum_XY))
             X[i] = sum_XY + carry
             carry = new_carry
     return ret
Пример #13
0
 def permut2expr(self, P, X):
     ret = Vector(self.nbits)
     v0 = P[0]
     nbits_in = (len(P) - 1).bit_length()
     for k, v in enumerate(P[1:]):
         v ^= v0
         if v == 0:
             continue
         k += 1
         test = test_N(nbits_in, X, k)
         for i in range(self.nbits):
             if ((v >> i) & 1) == 1:
                 ret[i] += test
     for i in range(self.nbits):
         ret[i] += imm((v0 >> i) & 1)
     simplify_inplace(ret)
     return ret
Пример #14
0
 def eval(self, vec, i, ctx, args, use_esf):
     return imm((self.n >> i) & 1)
Пример #15
0
 def compute_logical(vec, X, Y, ctx, use_esf):
     return simplify_inplace(
         ExprCmpEq.compute_logical(vec, X, Y, ctx, use_esf) + imm(1))
Пример #16
0
 def __init__(self, nbits):
     self.cache = [CtxUninitialized] * nbits
     self.last_bit = -1
     self.carry = imm(0)
Пример #17
0
 def eval(self, vec, i, ctx, args, use_esf):
     if (i >= self.arg_nbits):
         return imm(0)
     return args[0].eval(vec, i, use_esf)
Пример #18
0
 def eval(self, vec, i, ctx, args, use_esf):
     if i >= self.nbits - self.n:
         return imm(False)
     return args[0].eval(vec, i + self.n, use_esf)
Пример #19
0
 def compute(self, vec, i, args, ctx, use_esf):
     if ((self.mask >> i) & 1) == 0:
         return imm(0)
     return reduce(lambda x, y: x * y, args)
Пример #20
0
 def compute(self, vec, i, args, ctx, use_esf):
     return sum(args, imm(0))
Пример #21
0
 def eval(self, vec, i, ctx, args, use_esf):
     return args[0].eval(vec, i, use_esf) + imm(True)
Пример #22
0
 def f(i, j):
     if i != j:
         return imm(0)
     return X[i]
Пример #23
0
 def from_bytes(self, s):
     ret = Vector(self.nbits)
     for i, c in enumerate(six.iterbytes(s)):
         for j in range(8):
             ret[i * 8 + j] = imm((c >> j) & 1)
     return ret