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
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
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) # TODO: optimize this like in mba_if carry = esf(2, [X, Y, carry]) if not use_esf: expand_esf_inplace(carry) simplify_inplace(carry) CC.carry = carry return ret
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 find_one_esf(e, d): h = SymbolsHist() h.compute(e, d) #for v in h: print(v) # "Invert" the histogram hinv = collections.defaultdict(list) max_count = 0 for v in h: c = v.count() hinv[c].append(v.sym()) if max_count < c: max_count = c #print(hinv) # Compute the maximum number of arguments for this degree nterms = 0 for a in e.args(): if a.is_mul() and a.args().size() == d: nterms += 1 max_args = solve_binomial(d, nterms) #print("max_args: %d" % max_args) # Compute the exact counts we will search from counts_args = filter(lambda v: v[0] <= max_count, ((int(binom(A - 1, d - 1)), A) for A in reversed(range(d + 1, max_args + 1)))) for ca in counts_args: c, nargs = ca #print(d,c) cur_args = [] for i in range(c, max_count + 1): cur_args += hinv.get(i, []) if len(cur_args) < nargs: continue for A in reversed(range(nargs, max_args + 1)): #print(d, "test %d args among %d (%d)" % (A, len(cur_args), binom(len(cur_args),A))) # TODO: optimize this for args in itertools.combinations(cur_args, A): args = sorted(args) test_esf = esf(d, list(args)) anf_esf = simplify_inplace(expand_esf(test_esf)) if e.contains(anf_esf): #print("[+] found", test_esf) return test_esf, anf_esf return None, None