def phi_X(self, X): def f(i, j): if i != j: return imm(0) return X[i] return Matrix(self.nbits, self.nbits, f)
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")
def add_n_matrix(self, n): 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) return Matrix(self.nbits, self.nbits, matrix_v)
def null_matrix(self): return Matrix(self.nbits, self.nbits)
def cst_matrix(self, cst): return Matrix(self.nbits, self.nbits, lambda i, j: cst)
def identity(self): return Matrix.identity(self.nbits)