def prepare_deepest(self, path): deepest = [None] * (self.D + 2) deepest_index = [None] * (self.D + 2) src = Value() stash_empty = self.stash.ram.is_empty() level, _, index = find_deepest(self.stash.ram.get_value_array(0), path, 0, self.D) goal = if_else(stash_empty, ValueTuple([0] * len(level)), unary_to_binary(level)) src = if_else(stash_empty, src, Value(0)) src_index = if_else(stash_empty, 0, index) buckets = [self.get_bucket_ram(path, i) for i in range(self.L + 1)] bucket_deepest = [(goal, src, src_index, None)] for i in range(1, self.L): l, _, index = find_deepest(buckets[i].get_value_array(0), path, i - 1, self.D) bucket_deepest.append((unary_to_binary(l), Value(i), index, i)) def op(left, right, void=None): goal, src, src_index, _ = left l, secret_i, index, i = right high, low = comp_binary(l, goal) replace = high * (1 - low) * (1 - buckets[i].is_empty()) goal = if_else(replace, bit_compose(l), \ bit_compose(goal)).bit_decompose(len(goal)) src = if_else(replace, secret_i, src) src_index = if_else(replace, index, src_index) return goal, src, src_index, i preop_bucket_deepest = floatingpoint.PreOpL(op, bucket_deepest) for i in range(1, self.L + 1): goal, src, src_index, _ = preop_bucket_deepest[i-1] high, low = comp_binary(goal, bit_decompose(i, len(goal))) cond = 1 - low * (1 - high) deepest[i] = if_else(cond, src, Value()) deepest_index[i] = if_else(cond, src_index, 0) return deepest, deepest_index
def p_eval(p_c, x): degree = len(p_c) - 1 if type(x) is types.sfix: # ignore coefficients smaller than precision for c in reversed(p_c): if c < 2**-(x.f + 1): degree -= 1 else: break pre_mults = floatingpoint.PreOpL(lambda a, b, _: a * b, [x] * degree) local_aggregation = 0 # Evaluation of the Polynomial for i, pre_mult in zip(p_c[1:], pre_mults): local_aggregation += pre_mult.mul_no_reduce(x.coerce(i)) return local_aggregation.reduce_after_mul() + p_c[0]