def bkz_kernel(arg0, params=None, seed=None): """ Run the BKZ algorithm with different parameters. :param d: the dimension of the lattices to BKZ reduce :param params: parameters for BKZ: - bkz/alg: choose the underlying BKZ from {fpylll, naive, pump_n_jump, slide} - bkz/blocksizes: given as low:high:inc perform BKZ reduction with blocksizes in range(low, high, inc) (after some light) prereduction - bkz/pre_blocksize: prereduce lattice with fpylll BKZ up to this blocksize - bkz/tours: the number of tours to do for each blocksize - bkz/extra_dim4free: lift to indices extra_dim4free earlier in the lattice than the currently sieved block - bkz/jump: the number of blocks to jump in a BKZ tour after each pump - bkz/dim4free_fun: in blocksize x, try f(x) dimensions for free, give as 'lambda x: f(x)', e.g. 'lambda x: 11.5 + 0.075*x' - pump/down_sieve: sieve after each insert in the pump-down phase of the pump - slide/overlap: shift of the dual blocks when running slide reduction - challenge_seed: a seed to randomise the generated lattice - dummy_tracer: use a dummy tracer which capture less information - verbose: print tracer information throughout BKZ run """ # Pool.map only supports a single parameter if params is None and seed is None: d, params, seed = arg0 else: d = arg0 # params for underlying BKZ/workout/pump dim4free_fun = params.pop("bkz/dim4free_fun") extra_dim4free = params.pop("bkz/extra_dim4free") jump = params.pop("bkz/jump") overlap = params.pop("slide/overlap") pump_params = pop_prefixed_params("pump", params) workout_params = pop_prefixed_params("workout", params) # flow of the bkz experiment algbkz = params.pop("bkz/alg") blocksizes = params.pop("bkz/blocksizes") blocksizes = eval("range(%s)" % re.sub(":", ",", blocksizes)) pre_blocksize = params.pop("bkz/pre_blocksize") tours = params.pop("bkz/tours") # misc verbose = params.pop("verbose") dont_trace = params.pop("dummy_tracer", False) if blocksizes[-1] > d: print('set a smaller maximum blocksize with --blocksizes') return challenge_seed = params.pop("challenge_seed") A, bkz = load_prebkz(d, s=challenge_seed, blocksize=pre_blocksize) MM = GSO.Mat(A, float_type="double", U=IntegerMatrix.identity(A.nrows, int_type=A.int_type), UinvT=IntegerMatrix.identity(A.nrows, int_type=A.int_type)) g6k = Siever(MM, params, seed=seed) if dont_trace: tracer = dummy_tracer else: tracer = SieveTreeTracer(g6k, root_label=("bkz", d), start_clocks=True) if algbkz == "fpylll": M = bkz.M else: M = g6k.M T0 = time.time() for blocksize in blocksizes: for t in range(tours): with tracer.context("tour", t, dump_gso=True): if algbkz == "fpylll": par = BKZ_FPYLLL.Param( blocksize, strategies=BKZ_FPYLLL.DEFAULT_STRATEGY, max_loops=1) bkz(par) elif algbkz == "naive": naive_bkz_tour(g6k, tracer, blocksize, extra_dim4free=extra_dim4free, dim4free_fun=dim4free_fun, workout_params=workout_params, pump_params=pump_params) elif algbkz == "pump_and_jump": pump_n_jump_bkz_tour(g6k, tracer, blocksize, jump=jump, dim4free_fun=dim4free_fun, extra_dim4free=extra_dim4free, pump_params=pump_params) elif algbkz == "slide": slide_tour(g6k, dummy_tracer, blocksize, overlap=overlap, dim4free_fun=dim4free_fun, extra_dim4free=extra_dim4free, workout_params=workout_params, pump_params=pump_params) else: raise ValueError("bkz/alg=%s not recognized." % algbkz) if verbose: slope = basis_quality(M)["/"] fmt = "{'alg': '%25s', 'jump':%2d, 'pds':%d, 'extra_d4f': %2d, 'beta': %2d, 'slope': %.5f, 'total walltime': %.3f}" # noqa print(fmt % (algbkz + "+" + ("enum" if algbkz == "fpylll" else g6k.params.default_sieve), jump, pump_params["down_sieve"], extra_dim4free, blocksize, slope, time.time() - T0)) tracer.exit() slope = basis_quality(M)["/"] stat = tracer.trace try: stat.data["slope"] = np.array(slope) return stat except AttributeError: return None
def gen_lattice(self, d=None): """FIXME! briefly describe function :param d: """ try: I = self.indices[self.nbases] # noqa self.nbases += 1 except ValueError: raise StopIteration("No more bases to sample.") p = self.ecdsa.n # w = 2 ** (self.klen - 1) w_list = [2 ** (klen - 1) for klen in self.klen_list] r_list = [self.r_list[i] for i in I] s_list = [self.s_list[i] for i in I] h_list = [self.h_list[i] for i in I] rm = r_list[-1] sm = s_list[-1] hm = h_list[-1] wm = w_list[-1] a_list = [ lift( wi - mod(r, p) * inverse_mod(s, p) * inverse_mod(rm, p) * mod(sm, p) * wm - inverse_mod(s, p) * mod(h, p) + mod(r, p) * inverse_mod(s, p) * mod(hm, p) * inverse_mod(rm, p) ) for wi, h, r, s in zip(w_list[:-1], h_list[:-1], r_list[:-1], s_list[:-1]) ] t_list = [ -lift(mod(r, p) * inverse_mod(s, p) * inverse_mod(rm, p) * sm) for r, s in zip(r_list[:-1], s_list[:-1]) ] d = self.d A = IntegerMatrix(d, d) f_list = [Integer(max(w_list) / w) for w in w_list] for i in range(d - 2): A[i, i] = p * f_list[i] for i in range(d - 2): A[d - 2, i] = t_list[i] * f_list[i] A[d - 2, d - 2] = f_list[-1] for i in range(d - 2): A[d - 1, i] = a_list[i] * f_list[i] A[d - 1, d - 1] = max(w_list) if self.ecdsa.nbits > 384: M = GSO.Mat( A, U=IntegerMatrix.identity(A.nrows, int_type=A.int_type), UinvT=IntegerMatrix.identity(A.nrows, int_type=A.int_type), float_type="ld", flags=GSO.ROW_EXPO, ) else: M = GSO.Mat( A, U=IntegerMatrix.identity(A.nrows, int_type=A.int_type), UinvT=IntegerMatrix.identity(A.nrows, int_type=A.int_type), flags=GSO.ROW_EXPO, ) M.update_gso() return M