コード例 #1
0
 def mul_Y(self, X, Y):
     ret = Vector(self.nbits)
     i = 0
     for i in range(0, self.nbits):
         Yi_vec = Vector(self.nbits, Y[i])
         self.iadd_Y(ret, self.lshift_n(X, i) * Yi_vec)
     return ret
コード例 #2
0
 def __init__(self, nbits):
     self.__set_nbits(nbits)
     self.gen_x = Vector(nbits)
     self.use_esf = False
     self.use_opt_mba = True
     for i in range(0, nbits):
         self.gen_x[i] = symbol("__gen_X_%d" % i)
コード例 #3
0
 def rol_n(self, X, n):
     # rol(0b(d b c a), 1) = 0b(b c a d)
     # rol(vec(a,b,c,d), 1) = vec(d,a,c,b))
     ret = Vector(self.nbits)
     for i in range(self.nbits):
         ret[i] = X[(i - n) % self.nbits]
     return ret
コード例 #4
0
def flatten_vec(V):
    n = 8 * len(V)
    ret = Vector(n)
    for i in range(len(V)):
        for j in range(8):
            ret[i * 8 + j] = V[i][j].copy()
    return ret
コード例 #5
0
ファイル: stribog.py プロジェクト: whb224117/arybo
def flat_vec(L):
    lv = len(L[0].vec)
    s = lv * len(L)
    ret = Vector(s)
    for i in range(s):
        ret[i] = L[i // lv][i % lv]
    return ret
コード例 #6
0
ファイル: identify.py プロジェクト: whb224117/arybo
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
ファイル: mba_impl_petanque.py プロジェクト: heruix/arybo
 def sub_n_mba(self, X, n):
     null = Vector(self.nbits)
     n = self.get_vector_from_cst(n)
     while (n != null):
         X = simplify_inplace(self.xor_Y(X, n))
         n = simplify_inplace(self.and_Y(self.lshift_n(X, 1), self.lshift_n(n, 1)))
     return (X)
コード例 #8
0
 def and_n(self, X, n):
     if n < 0:
         n = n & self.max_uint
     ret = Vector(self.nbits)
     for i in range(self.nbits):
         if n & (1 << i):
             ret[i] = X[i]
     return ret
コード例 #9
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
コード例 #10
0
def eval_expr(e, use_esf=False):
    ectx = init_ctxes(e)

    ret = Vector(e.nbits)
    for i in range(e.nbits):
        ret[i] = ectx.eval(ret, i, use_esf)
    mba = MBA(len(ret))
    return mba.from_vec(ret)
コード例 #11
0
 def iadd_n_mba(self, X, n):
     null = Vector(self.nbits)
     n = self.get_vector_from_cst(n)
     while (n != null):
         carry = simplify_inplace(self.and_Y(X, n))
         self.ixor_Y(X, n)
         simplify_inplace(X)
         n = self.lshift_n(carry, 1)
     return X
コード例 #12
0
 def symbpermut2expr(self, P, X):
     ret = Vector(self.nbits)
     nbits_in = (len(P) - 1).bit_length()
     for k, v in enumerate(P):
         test = test_N(nbits_in, X, k)
         for i in range(self.nbits):
             ret[i] += v[i] * test
     simplify_inplace(ret)
     return ret
コード例 #13
0
 def mul_n_org(self, X, n):
     n = n & self.max_uint
     ret = Vector(self.nbits)
     i = 0
     while n > 0:
         if (n & 1) == 1:
             self.iadd_lshifted_Y(ret, X, i)
         n >>= 1
         i += 1
     return ret
コード例 #14
0
 def div_n(self, X, n):
     ret = Vector(self.nbits * 2 + 1)
     for i in range(self.nbits):
         ret[i] = X[i]
     nc = (2**self.nbits / n) * n - 1
     for p in range(self.nbits, 2 * self.nbits + 1):
         if (2**p > nc * (n - 1 - ((2**p - 1) % n))):
             break
     else:
         raise RuntimeError("division: unable to find the shifting count")
     m = (2**p + n - 1 - ((2**p - 1) % n)) // n
     self.__set_nbits(2 * self.nbits + 1)
     ret = self.mul_n(ret, m)
     ret = self.rshift_n(ret, p)
     self.__set_nbits((self.nbits - 1) // 2)
     final_ret = Vector(self.nbits)
     for i in range(self.nbits):
         final_ret[i] = ret[i]
     return final_ret
コード例 #15
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
コード例 #16
0
ファイル: mba_if.py プロジェクト: hartl3y94/arybo
def flatten(vars_):
    vecs = [v.vec if isinstance(v, MBAVariable) else v for v in vars_]
    total_len = sum((len(v) for v in vecs))
    ret = Vector(total_len)
    i = 0
    for v in vecs:
        for j in range(len(v)):
            ret[i] = v[j]
            i += 1
    mba = MBA(total_len)
    return mba.from_vec(ret)
コード例 #17
0
    def mul_n(self, X, n):
        if (n == 1):
            return X
        ret = Vector(self.nbits)
        if (n == 0):
            return ret
        n = n & self.max_uint
        i = 0
        final_sum = 0
        not_x = None

        def compute_not_x(not_x):
            if not_x is None:
                not_x = self.not_X(X)
            return not_x

        while n > 0:
            # Optimisations from the Hacker's delight
            nz = next_zero_bit(n)
            if (nz >= 3):
                not_x = compute_not_x(not_x)
                self.iadd_lshifted_Y(ret, X, nz + i)
                self.iadd_lshifted_Y(ret, not_x, i)
                final_sum += 1 << i
                n >>= nz
                i += nz
            else:
                bits4 = n & 0b1111
                if bits4 == 0b1011:
                    not_x = compute_not_x(not_x)
                    self.iadd_lshifted_Y(ret, X, 4 + i)
                    self.iadd_lshifted_Y(ret, not_x, 2 + i)
                    self.iadd_lshifted_Y(ret, not_x, i)
                    final_sum += 1 << (i + 2)
                    final_sum += 1 << i
                    n >>= 4
                    i += 4
                elif bits4 == 0b1101:
                    not_x = compute_not_x(not_x)
                    self.iadd_lshifted_Y(ret, X, 4 + i)
                    self.iadd_lshifted_Y(ret, not_x, 1 + i)
                    self.iadd_lshifted_Y(ret, not_x, i)
                    final_sum += 1 << (i + 1)
                    final_sum += 1 << i
                    n >>= 4
                    i += 4
                else:
                    if (n & 1) == 1:
                        self.iadd_lshifted_Y(ret, X, i)
                    n >>= 1
                    i += 1
        if final_sum > 0:
            self.iadd_n(ret, final_sum & self.max_uint)
        return ret
コード例 #18
0
 def add_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], 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] * Y[i] + (carry * sum_XY))
     return ret
コード例 #19
0
ファイル: mba_if.py プロジェクト: hartl3y94/arybo
    def vectorial_decomp(self, symbols):
        ''' Compute the vectorial decomposition of the expression according to the given symbols.

        symbols is a list that represents the input of the resulting
        application. They are considerated as a flatten vector of bits.

        Args:
            symbols: TODO

        Returns:
            An :class:`pytanque.App` object

        Example:
            >>> mba = MBA(4)
            >>> x = mba.var('x')
            >>> y = mba.var('y')
            >>> e = x^y^6
            >>> e.vectorial_decomp([x,y])
            App NL = Vec([
            0,
            0,
            0,
            0
            ])
            AffApp matrix = Mat([
                [1, 0, 0, 0, 1, 0, 0, 0]
                [0, 1, 0, 0, 0, 1, 0, 0]
                [0, 0, 1, 0, 0, 0, 1, 0]
                [0, 0, 0, 1, 0, 0, 0, 1]
                ])
            AffApp cst = Vec([
                0,
                1,
                1,
                0
                ])
        '''
        try:
            symbols = [s.vec for s in symbols]
            N = sum(map(lambda s: len(s), symbols))
            symbols_ = Vector(N)
            i = 0
            for v in symbols:
                for s in v:
                    symbols_[i] = s
                    i += 1
            symbols = symbols_
        except TypeError:
            pass
        return self.mba.vectorial_decomp(symbols, self.vec)
コード例 #20
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
コード例 #21
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
コード例 #22
0
ファイル: petanque.py プロジェクト: heruix/arybo
def app_inverse(A):
    M = A.matrix()
    NL = A.nl()
    V = A.cst()
    Minv = M.inverse()
    if Minv.ncols() == 0:
        return None

    N = V.size()
    mba = MBA(N)
    Y = mba.var('Y')
    G0 = Minv * Y.vec + Minv * V
    G1nl = simplify_inplace(Minv * NL(Y.vec))

    # Check if G1 is inversible through a dependency graph
    DG = nx.DiGraph()
    idx_base = Y[0].sym_idx()
    for i, e in enumerate(G1nl):
        for d in get_depends_as_set(e):
            DG.add_edge(Y[i].sym_idx() - idx_base, d.sym_idx() - idx_base)

    if not nx.is_directed_acyclic_graph(DG):
        return None

    # Use the graph to get the inverse of G1
    X = mba.var('X')
    resolve_order = nx.topological_sort(DG, reverse=True)
    solved = dict()
    for i in resolve_order:
        e = G1nl[i]
        if e.is_imm() and e.imm_value() == 0:
            solved[i] = X[i]
        else:
            # Doing this in the reversed topological order should make this always work!
            solved[i] = simplify_inplace(X[i] + simplify_inplace(
                subs_exprs(G1nl[i], [Y[j] for j in six.iterkeys(solved)],
                           list(six.itervalues(solved)))))
    G1inv = Vector(N)
    for i in range(N):
        G1inv[i] = solved.get(i, X[i])
    G1inv = MBAVariable(mba, G1inv)
    Finv = G1inv.eval({X: G0})
    Finv = MBAVariable(mba, Finv)
    return Finv.vectorial_decomp([Y])
コード例 #23
0
def get_vector_from_cst(nbits, n):
    vec = Vector(nbits)
    vec.set_int_be(n, nbits)
    return vec
コード例 #24
0
 def var_symbols(self, name):
     symbols = [symbol("%s%d" % (name, i)) for i in range(0, self.nbits)]
     M = Vector(self.nbits)
     for i in range(0, self.nbits):
         M[i] = symbols[i]
     return M
コード例 #25
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
コード例 #26
0
 def ror_n(self, X, n):
     ret = Vector(self.nbits)
     for i in range(self.nbits):
         ret[i] = X[(i + n) % self.nbits]
     return ret
コード例 #27
0
 def or_exp(self, X, e):
     if self.use_esf:
         E = Vector(self.nbits, e)
         return self.or_Y(X, E)
     else:
         return self.xor_exp(self.and_exp(X, e), self.xor_exp(X, e))