Exemple #1
0
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
Exemple #2
0
    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