Exemple #1
0
    def __call__(cls,
                 M,
                 predicate,
                 block_size,
                 invalidate_cache=lambda: None,
                 threads=1,
                 max_loops=8,
                 **kwds):
        params = SieverParams(threads=threads)
        g6k = Siever(M, params)
        tracer = SieveTreeTracer(g6k,
                                 root_label="bkz-sieve",
                                 start_clocks=True)
        for b in range(20, block_size + 1, 10):
            pump_n_jump_bkz_tour(g6k,
                                 tracer,
                                 b,
                                 pump_params={"down_sieve": True})

        auto_abort = BKZ.AutoAbort(M, M.d)
        found, ntests, solution = False, 0, None
        for tour in range(max_loops):
            pump_n_jump_bkz_tour(g6k,
                                 tracer,
                                 block_size,
                                 pump_params={"down_sieve": True})

            invalidate_cache()

            if auto_abort.test_abort():
                break

            with tracer.context("check"):
                for i, v in enumerate(M.B):
                    ntests += 1
                    if predicate(v, standard_basis=True):
                        solution = tuple([int(v_) for v_ in v])
                        found = True
                        break
                if found:
                    break

        tracer.exit()

        b0, b0e = M.get_r_exp(0, 0)

        return USVPPredSolverResults(
            success=found,
            ntests=ntests,
            solution=solution,
            b0=b0**(0.5) * 2**(b0e / 2.0),
            cputime=tracer.trace.data["cputime"],
            walltime=tracer.trace.data["walltime"],
            data=tracer.trace,
        )
Exemple #2
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 #3
0
    def __call__(cls,
                 M,
                 predicate,
                 invalidate_cache=lambda: None,
                 preproc_offset=20,
                 threads=1,
                 ph=0,
                 **kwds):
        # TODO bkz_sieve would be neater here
        if preproc_offset and M.d >= 40:
            bkz_res = usvp_pred_bkz_enum_solve(
                M,
                predicate,
                block_size=max(M.d - preproc_offset, 2),
                max_loops=8,
                threads=threads,
                invalidate_cache=invalidate_cache,
            )

            ntests = bkz_res.ntests
            if bkz_res.success:  # this might be enough
                return bkz_res
        else:
            bkz_res = None
            ntests = 0

        from fpylll import IntegerMatrix

        # reduce size of entries
        B = IntegerMatrix(M.B.nrows, M.B.ncols)
        for i in range(M.B.nrows):
            for j in range(M.B.ncols):
                B[i, j] = M.B[i, j] // 2**ph

        params = SieverParams(reserved_n=M.d, otf_lift=False, threads=threads)
        g6k = Siever(B, params)
        tracer = SieveTreeTracer(g6k, root_label="sieve", start_clocks=True)

        g6k.initialize_local(0, M.d // 2, M.d)

        while g6k.l:
            g6k.extend_left()
            with tracer.context("sieve"):
                try:
                    g6k()
                except SaturationError:
                    pass

        # fill the database
        with g6k.temp_params(**kwds):
            g6k()

        invalidate_cache()

        found, solution = False, None
        with tracer.context("check"):
            for v in g6k.itervalues():  # heuristic: v has very small entries
                ntests += 1
                if predicate(v, standard_basis=False):
                    found = True
                    solution = tuple(
                        [int(v_) for v_ in g6k.M.B.multiply_left(v)])
                    break
        tracer.exit()

        cputime = tracer.trace.data[
            "cputime"] + bkz_res.cputime if bkz_res else 0
        walltime = tracer.trace.data[
            "walltime"] + bkz_res.walltime if bkz_res else 0

        b0, b0e = M.get_r_exp(0, 0)

        return USVPPredSolverResults(
            success=found,
            ntests=ntests,
            solution=solution,
            b0=b0**(0.5) * 2**(b0e / 2.0),
            cputime=cputime,
            walltime=walltime,
            data=tracer.trace,
        )
Exemple #4
0
    def __call__(cls,
                 M,
                 predicate,
                 invalidate_cache=lambda: None,
                 preproc_offset=20,
                 threads=1,
                 **kwds):
        if preproc_offset and M.d >= 40:
            bkz_res = usvp_pred_bkz_sieve_solve(
                M,
                predicate,
                block_size=max(M.d - preproc_offset, 2),
                max_loops=8,
                threads=threads,
                invalidate_cache=invalidate_cache,
            )

            ntests = bkz_res.ntests
            if bkz_res.success:  # this might be enough
                return bkz_res
        else:
            bkz_res = None
            ntests = 0

        params = SieverParams(reserved_n=M.d, otf_lift=False, threads=threads)
        g6k = Siever(M, params)

        tracer = SieveTreeTracer(g6k, root_label="sieve", start_clocks=True)
        workout(g6k, tracer, 0, M.d, dim4free_min=0, dim4free_dec=15)

        invalidate_cache()

        found, solution = False, None
        with tracer.context("check"):  # check if the workout solved it for us
            for i in range(g6k.M.d):
                ntests += 1
                if predicate(g6k.M.B[i], standard_basis=True):
                    found = True
                    solution = tuple([int(v_) for v_ in g6k.M.B[i]])
                    break

        if found:
            tracer.exit()

            b0, b0e = M.get_r_exp(0, 0)

            return USVPPredSolverResults(
                success=found,
                ntests=ntests,
                solution=solution,
                b0=b0**(0.5) * 2**(b0e / 2.0),
                cputime=tracer.trace.data["cputime"],
                walltime=tracer.trace.data["walltime"],
                data=tracer.trace,
            )

        with tracer.context("sieve"):
            try:
                g6k()
            except SaturationError:
                pass

        while g6k.l:
            g6k.extend_left()
            with tracer.context("sieve"):
                try:
                    g6k()
                except SaturationError:
                    pass

        # fill the database
        with g6k.temp_params(**kwds):
            g6k()

        invalidate_cache()

        with tracer.context("check"):
            for i in range(g6k.M.d):
                ntests += 1
                if predicate(g6k.M.B[i], standard_basis=True):
                    found = True
                    solution = tuple([int(v_) for v_ in g6k.M.B[i]])
                    break

            if not found:
                for v in g6k.itervalues():
                    ntests += 1
                    if predicate(v, standard_basis=False):
                        found = True
                        solution = tuple(
                            [int(v_) for v_ in g6k.M.B.multiply_left(v)])
                        break
        tracer.exit()

        cputime = tracer.trace.data[
            "cputime"] + bkz_res.cputime if bkz_res else 0
        walltime = tracer.trace.data[
            "walltime"] + bkz_res.walltime if bkz_res else 0

        b0, b0e = M.get_r_exp(0, 0)

        return USVPPredSolverResults(
            success=found,
            ntests=ntests,
            solution=solution,
            b0=b0**(0.5) * 2**(b0e / 2.0),
            cputime=cputime,
            walltime=walltime,
            data=tracer.trace,
        )