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
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)
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
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
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
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
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
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
def exprEqual(self, expr, e): expr = EX.eval_expr(expr, self.use_esf) if self.use_esf: expand_esf_inplace(expr.vec) simplify_inplace(expr.vec) simplify_inplace(e.vec) simplify_inplace(expr.vec) self.assertEqual(expr, e)
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