Esempio n. 1
0
g6k.lll(0, n)

# Run a progressive sieve, to get an initial database saturating the 4/3 *gh^2 ball.
# This makes the final computation saturating a larger ball faster than directly
# running such a large sieve.
#
# G6K will use a database of size db_size_base * db_size_base^dim with default values
#               db_size_base = sqrt(4./3) and db_size_factor = 3.2
#
# The sieve stops when a
#               0.5 * saturation_ratio * saturation_radius^(dim/2)
#
# distinct vectors (modulo negation) of length less than saturation_radius have
# been found

g6k.initialize_local(0, n / 2, n)
while g6k.l > 0:
    # Extend the lift context to the left
    g6k.extend_left(1)
    # Sieve
    g6k()

# Increase db_size, saturation radius and saturation ratio to find almost all
# the desired vectors.
# We need to increase db_size to at least
#               0.5 * saturation_ratio * saturation_radius^(dim/2)
#
# for this to be possible, but a significant margin is recommended

with g6k.temp_params(saturation_ratio=.95,
                     saturation_radius=1.7,
Esempio n. 2
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,
        )