Пример #1
0
def svp_time(seed, params, return_queue=None):
    """Run SVP reduction of AutoBKZ on ``A`` using ``params``.

    :param A: a matrix
    :param params: AutoBKZ parameters
    :param queue: if not ``None``, the result is put on this queue.

    """
    FPLLL.set_random_seed(seed)
    FPLLL.set_threads(params["threads"])
    q = 33554393
    k = params.block_size // 2
    A = IntegerMatrix.random(params.block_size,
                             "qary",
                             q=q,
                             k=k,
                             int_type="long")

    M = GSO.Mat(A)
    bkz = BKZ2(M)
    tracer = BKZTreeTracer(bkz, start_clocks=True)

    with tracer.context(("tour", 0)):
        bkz.svp_reduction(0, params.block_size, params, tracer)
        bkz.M.update_gso()

    tracer.exit()

    log_delta = (log(A[0].norm()) - log(q) *
                 (k / float(params.block_size))) / float(params.block_size)
    tracer.trace.data["delta"] = exp(log_delta)
    if return_queue:
        return_queue.put(tracer.trace)
    else:
        return tracer.trace
Пример #2
0
def main(n=150,
         block_size=60,
         float_type="d",
         logq=40,
         verbose=False,
         seed=0xdeadbeef):
    print "= n: %3d, β: %2d, bits: %3d, float_type: %s, seed: 0x%08x =" % (
        n, block_size, logq, float_type, seed)
    print
    set_random_seed(seed)
    A = IntegerMatrix.random(n, "qary", k=n // 2, bits=logq)
    A = LLL.reduction(A)

    params = BKZ.Param(block_size=block_size,
                       max_loops=4,
                       strategies=BKZ.DEFAULT_STRATEGY,
                       flags=BKZ.MAX_LOOPS | BKZ.VERBOSE)
    bkz = BKZReduction(GSO.Mat(copy.copy(A), float_type=float_type))
    bkz(params)

    print bkz.trace

    bkz2 = BKZ2(GSO.Mat(copy.copy(A), float_type=float_type))
    bkz2(params)

    print bkz2.trace

    if verbose:
        print
        print bkz.trace.report()
Пример #3
0
def svp_time(seed, params, return_queue=None):
    """Run SVP reduction on ``A`` using ``params``.

    :param seed: random seed for matrix creation
    :param params: BKZ parameters
    :param return_queue: if not ``None``, the result is put on this queue.

    """
    from cost import sample_matrix

    A = sample_matrix(params.block_size, seed=seed)
    M = GSO.Mat(A)
    bkz = BKZ2(M)
    tracer = BKZTreeTracer(bkz, start_clocks=True)

    with tracer.context(("tour", 0)):
        bkz.svp_reduction(0, params.block_size, params, tracer)
        bkz.M.update_gso()

    tracer.exit()

    tracer.trace.data["|A_0|"] = A[0].norm()
    ppbs = params.strategies[params.block_size].preprocessing_block_sizes
    tracer.trace.data["preprocessing_block_size"] = ppbs[0] if ppbs else 2

    if return_queue:
        return_queue.put(tracer.trace)
    else:
        return tracer.trace
Пример #4
0
def update_until_v_found(M, min_block_size, max_block_size, max_tours, v,
                         prime_modulus):
    L = fpylll.IntegerMatrix.from_matrix(M)
    G = fpylll.GSO.Mat(L)
    G.update_gso()
    Y = BKZ2(G)
    block_size = min_block_size
    v = list(np.array(v) % prime_modulus)
    trial_v = list(np.array(M[0]) % prime_modulus)
    print('completed block sizes: ', sep=' ', end=' ', flush=True)
    while block_size <= max_block_size:
        o = fpylll.BKZ.Param(block_size,
                             strategies='default.json',
                             min_success_probability=0.5,
                             flags=fpylll.BKZ.AUTO_ABORT)
        #o = fpylll.BKZ.Param(block_size, min_success_probability=0.5, flags = fpylll.BKZ.AUTO_ABORT) # no preprocessing
        tour = 1
        while (tour < max_tours) & (Y.tour(o) == False):
            tour += 1
            Hold_M = [[0 for i in M] for j in M[0]]
            L.to_matrix(Hold_M)
            trial_v = list(np.array(Hold_M[0]) % prime_modulus)
            neg_trial_v = list(-1 * np.array(Hold_M[0]) % prime_modulus)
            if (trial_v != v) & (neg_trial_v != v):
                L.to_matrix(M)
            else:
                print('....v found at (tour,block size) = ' +
                      str((tour, block_size)))
                return M, block_size
        print(str(block_size), sep=' ', end=' ', flush=True)
        block_size += 1
    print('exhausted... secret not found for block size <= ' +
          str(max_block_size))
    return M, 0
Пример #5
0
def svp_time(seed, params, return_queue=None):
    """Run SVP reduction of AutoBKZ on ``A`` using ``params``.

    :param A: a matrix
    :param params: AutoBKZ parameters
    :param queue: if not ``None``, the result is put on this queue.

    """
    FPLLL.set_random_seed(seed)
    A = IntegerMatrix.random(params.block_size, "qary", bits=30,
                             k=params.block_size//2, int_type="long")

    M = GSO.Mat(A)
    bkz = BKZ2(M)
    tracer = BKZTreeTracer(bkz, start_clocks=True)

    with tracer.context(("tour", 0)):
        bkz.svp_reduction(0, params.block_size, params, tracer)
        bkz.M.update_gso()

    tracer.exit()

    tracer.trace.data["|A_0|"] = A[0].norm()

    if return_queue:
        return_queue.put(tracer.trace)
    else:
        return tracer.trace
Пример #6
0
    def insert_in_IntegerMatrix(self, A, v, kappa, block_size):
        if (list(A[kappa]) == list(v)):
            return
        n = A.nrows
        l = A.ncols

        AA = IntegerMatrix(n + 1, l, int_type="long")
        for i in xrange(kappa):
            for j in xrange(l):
                AA[i, j] = A[i, j]
        for j in xrange(l):
            AA[kappa, j] = v[j]
        for i in xrange(kappa + 1, n + 1):
            for j in xrange(l):
                AA[i, j] = A[i - 1, j]

        M = GSO.Mat(AA, float_type=TYPE)
        M.update_gso()
        bkz = BKZ2(M)
        try:
            bkz.lll_obj(kappa, kappa,
                        kappa + block_size + 1)  # longer: 1 more row
        except:
            pass

        index = 0
        for i in range(kappa, kappa + block_size + 1):
            if (AA[i].is_zero()):
                index = i - kappa
                break

        for i in xrange(kappa + index):
            for j in xrange(l):
                A[i, j] = AA[i, j]
        for i in xrange(kappa + index + 1, n + 1):
            for j in xrange(l):
                A[i - 1, j] = AA[i, j]
        """
        for i in range(n):
            bad = 0
            for j in range(l):
                if (A[i][j] == 0):
                    bad = bad + 1
                if (bad == n):
                    print " inserting ", v
                    print " <<<<<<<<<<<<<<<<<<<<<< WRONG HERE at ", kappa, block_size, i
                    print A
                    print "old A is "
                    print AA_old
                    print "old A after lll is "                    
                    print AA                    
                    sys.exit(1)
        """

        del bkz
        del AA
        del M
        return
Пример #7
0
    def __call__(cls,
                 M,
                 predicate,
                 block_size,
                 invalidate_cache=lambda: None,
                 max_loops=8,
                 threads=1,
                 **kwds):
        bkz = BKZ2(M)

        if block_size > STRATEGIES_MAX_DIM:
            warnings.warn(
                "reducing block size to {max}".format(max=STRATEGIES_MAX_DIM))
            block_size = STRATEGIES_MAX_DIM

        FPLLL.set_threads(threads)
        params = BKZ.EasyParam(block_size=block_size, **kwds)
        auto_abort = BKZ.AutoAbort(M, M.d)
        tracer = BKZTreeTracer(bkz, root_label="bkz_enum", start_clocks=True)
        found, ntests, solution = False, 0, None
        for tour in range(max_loops):
            bkz.tour(params)

            if auto_abort.test_abort():
                break

            invalidate_cache()

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

        FPLLL.set_threads(1)

        tracer.exit()

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

        return USVPPredSolverResults(
            success=found,
            solution=solution,
            ntests=ntests,
            b0=b0**(0.5) * 2**(b0e / 2.0),
            cputime=tracer.trace.data["cputime"],
            walltime=tracer.trace.data["walltime"],
            data=tracer.trace,
        )
Пример #8
0
def run_BKZ2(A, block_size=2, verbose=False):
    """
    """
    flags = BKZ.DEFAULT | BKZ.AUTO_ABORT
    if verbose:
        flags |= BKZ.VERBOSE

    A = IntegerMatrix.from_matrix(A)
    _ = BKZ2(A)(BKZ.EasyParam(block_size=block_size, flags=flags))
    B = [[A[i, j] for j in range(A.ncols)] for i in range(A.nrows)]

    return B
def main_pruning(filename, bs, cores):

    try:
        with open(filename, "rb") as f:
            mat = pickle.load(f)
            #print "len(mat)", len(mat)
            #if (len(mat) > 1):
            #   mat = mat[0]
        if isinstance(mat, IntegerMatrix):
            Ainput = mat
        else:
            Ainput = IntegerMatrix.from_matrix(mat)
    except:
        Ainput = IntegerMatrix.from_file(filename)

    Ainput_M = GSO.Mat(Ainput, float_type='double')
    Ainput_M.update_gso()
    r = [Ainput_M.get_r(i, i) for i in range(0, Ainput.nrows)]
    L_Ainput_M = LLL.Reduction(Ainput_M)
    L_Ainput_M()
    #print r

    A = IntegerMatrix.from_matrix(L_Ainput_M.M.B, int_type="long")
    M = GSO.Mat(A, float_type="double")
    bkzobj = BKZ2(M)
    bkzobj.M.update_gso()
    block_size = bs
    r = [M.get_r(i, i) for i in range(0, block_size)]
    radius = r[0] * 0.99
    preproc_cost = 5000**(rank + 1)

    pr0 = Pruning.run(radius,
                      NPS[block_size] * preproc_cost, [r],
                      0.1,
                      metric="probability",
                      float_type="double",
                      flags=Pruning.GRADIENT | Pruning.NELDER_MEAD)

    print pr0.coefficients
    """
    pruning = prune(radius, NPS[block_size] * preproc_cost, [r], 0.01,
                        metric="probability", float_type="double",
                        flags=Pruning.GRADIENT|Pruning.NELDER_MEAD)
    cost = sum(pruning.detailed_cost) / NPS[block_size]
    print "# [rank %d] cost %.1f, precost %.1f " % (rank, cost, preproc_cost)
    """

    pr0_linear = pr0.LinearPruningParams(block_size, block_size - 2)
    print pr0_linear.coefficients

    return
def run_instance(L, block_size, tours, evec):
    from fpylll import BKZ, LLL, GSO, IntegerMatrix
    from fpylll.algorithms.bkz2 import BKZReduction as BKZ2
    from sage.all import e

    A = IntegerMatrix.from_matrix(L)

    block_size = ZZ(block_size)
    par = BKZ.Param(block_size=block_size,
                    strategies=BKZ.DEFAULT_STRATEGY,
                    flags=BKZ.VERBOSE)

    block_size = ZZ(block_size)
    delta_0 = (block_size / (2 * pi * e) *
               (pi * block_size)**(1 / block_size))**(1 / (2 * block_size - 1))
    n = ZZ(L.nrows())
    alpha = delta_0**(-2 * n / (n - 1))

    if len(evec) == n - 1:
        evec = vector(list(evec) + [1])

    LLL.reduction(A)
    M = GSO.Mat(A)
    M.update_gso()

    vol = sqrt(prod([RR(M.get_r(i, i)) for i in range(n)]))

    norms = [
        map(lambda x: RR(log(x, 2)),
            [(alpha**i * delta_0**n * vol**(1 / n))**2 for i in range(n)])
    ]

    def proj(v, i):
        return v - vector(RR, M.to_canonical(list(M.from_canonical(v, 0, i))))

    # norms += [map(lambda x: RR(log(x,2)),
    #               [(stddev*sqrt(n-i))**2 for i in range(n)])]
    norms += [
        map(lambda x: RR(log(x, 2)),
            [proj(evec, i).norm()**2 for i in range(1, n - 1)])
    ]

    norms += [[log(RR(M.get_r(i, i)), 2) for i in range(n)]]

    bkz = BKZ2(M)

    for i in range(tours):
        bkz.tour(par)
        norms += [[log(M.get_r(i, i), 2) for i in range(n)]]

    return A.to_matrix(matrix(ZZ, n, n)), norms
Пример #11
0
def run_timing_test(n,
                    block_size=60,
                    bits=30,
                    ncores=8,
                    min_success_probability=0.5,
                    max_loops=4):
    A = IntegerMatrix.random(n, "qary", k=n // 2, bits=bits)
    default_strategies = load_strategies_json(BKZ.DEFAULT_STRATEGY)

    param = BKZ.Param(block_size,
                      strategies=default_strategies,
                      min_success_probability=min_success_probability,
                      max_loops=max_loops,
                      flags=BKZ.VERBOSE | BKZ.MAX_LOOPS)

    random.seed(1)
    bkz = ParallelBKZ(copy(A), ncores=ncores)
    t = time.time()
    bkz(param)
    t = time.time() - t
    trace_p = bkz.trace
    print "Parallel(%d): %.2fs" % (ncores, t)

    random.seed(1)
    param = BKZ.Param(block_size,
                      strategies=default_strategies,
                      min_success_probability=min_success_probability,
                      max_loops=max_loops,
                      flags=BKZ.VERBOSE | BKZ.MAX_LOOPS)
    t = time.time()
    bkz = BKZ2(copy(A))
    bkz(param)
    trace_s = bkz.trace

    t = time.time() - t
    print "  Sequential: %.2fs" % (t, )
    return trace_p, trace_s
Пример #12
0
def dim_error_tradeoff(A,
                       c,
                       u,
                       beta,
                       h,
                       k,
                       alpha=None,
                       tau=None,
                       float_type="mpfr",
                       use_lll=True):
    """

    :param A:    LWE matrix
    :param c:    LWE vector
    :param u:	 Uniform vector
    :param beta: BKW block size
    :param h: 	 Hamming weight of secret
    :param k:    LWE dim after tradeoff
    :param tau:  number of new samples to generate
    :param use_lll: 	If True, run BKZ only once and then run LLL
    					If False, run BKZ iteratively

    * secret vector s is used to see the error term of new LWE(-like) samples.

    """

    from fpylll import BKZ, IntegerMatrix, LLL, GSO
    from fpylll.algorithms.bkz2 import BKZReduction as BKZ2

    n = A.ncols()
    q = A.base_ring().order()
    K = GF(q, proof=False)

    if alpha is None:
        alpha = 8 / q

    if tau is None:
        tau = 30

    m = A.nrows() / n

    scale = round(alpha * q * sqrt(m) / sqrt(2 * pi * h))
    scale = ZZ(scale)

    count = 0

    A_k = matrix(ZZ, 1, k)
    c_k = []
    u_k = []
    length = 0

    while count < tau:

        r = count * m
        T = A.matrix_from_rows([i + r for i in range(m)])
        ct = c[r:r + m]
        ut = u[r:r + m]

        T1 = T.matrix_from_columns([i for i in range(n - k)])

        L = dual_instance1(T1, scale=scale)
        L = IntegerMatrix.from_matrix(L)
        L = LLL.reduction(L)
        M = GSO.Mat(L, float_type=float_type)
        bkz = BKZ2(M)
        param = BKZ.Param(block_size=beta,
                          strategies=BKZ.DEFAULT_STRATEGY,
                          auto_abort=True,
                          max_loops=16,
                          flags=BKZ.AUTO_ABORT | BKZ.MAX_LOOPS)
        bkz(param)

        H = copy(L)

        y = vector(ZZ, tuple(L[0]))
        length += y.norm()

        T2 = T.matrix_from_columns([n - k + i for i in range(k)])

        A_kt, c_kt, u_kt = apply_short1(y, T2, ct, ut, scale=scale)
        if r == 0:
            A_k[0] = A_kt
        else:
            A_k = A_k.stack(A_kt)
        c_k.append(c_kt)
        u_k.append(u_kt)

        count += 1

    length = float(length / tau)
    A_k = A_k.change_ring(K)
    c_k = vector(K, c_k)
    u_k = vector(K, u_k)

    B = float(2 + 1 / sqrt(2 * pi)) * (alpha * q)
    B = B * B * m / (m + n)
    B = sqrt(B) * length / scale

    print '(A_k, c_k) is k-dim LWE samples (with secret s[-k:]) / (A_k, u_k) is uniform samples. '

    return A_k, c_k, u_k, B
Пример #13
0
def silke(A, c, beta, h, m=None, scale=1, float_type="double"):
    """

    :param A:    LWE matrix
    :param c:    LWE vector
    :param beta: BKW block size
    :param m:    number of samples to consider
    :param scale: scale rhs of lattice by this factor

    """
    from fpylll import BKZ, IntegerMatrix, LLL, GSO
    from fpylll.algorithms.bkz2 import BKZReduction as BKZ2

    if m is None:
        m = A.nrows()

    L = dual_instance1(A, scale=scale)
    L = IntegerMatrix.from_matrix(L)
    L = LLL.reduction(L, flags=LLL.VERBOSE)
    M = GSO.Mat(L, float_type=float_type)
    bkz = BKZ2(M)
    t = 0.0
    param = BKZ.Param(block_size=beta,
                      strategies=BKZ.DEFAULT_STRATEGY,
                      auto_abort=True,
                      max_loops=16,
                      flags=BKZ.VERBOSE | BKZ.AUTO_ABORT | BKZ.MAX_LOOPS)
    bkz(param)
    t += bkz.stats.total_time

    H = copy(L)

    import pickle
    pickle.dump(L, open("L-%d-%d.sobj" % (L.nrows, beta), "wb"))

    E = []
    Y = set()
    V = set()
    y_i = vector(ZZ, tuple(L[0]))
    Y.add(tuple(y_i))
    E.append(apply_short1(y_i, A, c, scale=scale)[1])

    v = L[0].norm()
    v_ = v / sqrt(L.ncols)
    v_r = 3.2 * sqrt(L.ncols - A.ncols()) * v_ / scale
    v_l = sqrt(h) * v_

    fmt = u"{\"t\": %5.1fs, \"log(sigma)\": %5.1f, \"log(|y|)\": %5.1f, \"log(E[sigma]):\" %5.1f}"

    print
    print fmt % (t, log(abs(E[-1]), 2), log(L[0].norm(),
                                            2), log(sqrt(v_r**2 + v_l**2), 2))
    print
    for i in range(m):
        t = cputime()
        M = GSO.Mat(L, float_type=float_type)
        bkz = BKZ2(M)
        t = cputime()
        bkz.randomize_block(0, L.nrows, stats=None, density=3)
        LLL.reduction(L)
        y_i = vector(ZZ, tuple(L[0]))
        l_n = L[0].norm()
        if L[0].norm() > H[0].norm():
            L = copy(H)
        t = cputime(t)

        Y.add(tuple(y_i))
        V.add(y_i.norm())
        E.append(apply_short1(y_i, A, c, scale=scale)[1])
        if len(V) >= 2:
            fmt = u"{\"i\": %4d, \"t\": %5.1fs, \"log(|e_i|)\": %5.1f, \"log(|y_i|)\": %5.1f,"
            fmt += u"\"log(sigma)\": (%5.1f,%5.1f), \"log(|y|)\": (%5.1f,%5.1f), |Y|: %5d}"
            print fmt % (i + 2, t, log(abs(E[-1]), 2), log(
                l_n,
                2), log_mean(E), log_var(E), log_mean(V), log_var(V), len(Y))

    return E
Пример #14
0
def approx_svp_time(seed, params, return_queue=None, progressive=False):
    """Run Approx-SVP_{1.05} reduction on ``A`` using ``params``.

    :param seed: random seed for matrix creation
    :param params: BKZ preprocessing parameters, preprocessing block size is ignored
    :param return_queue: if not ``None``, the result is put on this queue.
    :param progressive: run Progressive-BKZ

    """
    from chal import load_svp_challenge
    from fpylll.algorithms.bkz import BKZReduction as BKZBase

    FPLLL.set_random_seed(seed)
    A = load_svp_challenge(params.block_size, seed=seed)
    M = GSO.Mat(A)
    M.update_gso()

    gh = gaussian_heuristic(M.r())
    target_norm = 1.05**2 * gh

    nodes_per_second = 2.0 * 10**9 / 100.0

    self = BKZ2(M)
    tracer = BKZTreeTracer(self, start_clocks=True)

    rerandomize = False
    preproc_cost = None
    with tracer.context(("tour", 0)):
        while M.get_r(0, 0) > target_norm:
            with tracer.context("preprocessing"):
                if rerandomize:
                    self.randomize_block(
                        1,
                        params.block_size,
                        density=params.rerandomization_density,
                        tracer=tracer)
                with tracer.context("reduction"):
                    BKZBase.svp_preprocessing(self, 0, params.block_size,
                                              params, tracer)  # LLL
                    preproc = round(0.9878 * params.block_size -
                                    24.12)  # curve fitted to chal.py output
                    prepar = params.__class__(block_size=preproc,
                                              strategies=params.strategies,
                                              flags=BKZ.GH_BND)
                    self.tour(prepar, 0, params.block_size, tracer=tracer)

            if preproc_cost is None:
                preproc_cost = float(
                    tracer.trace.find("preprocessing")["walltime"])
                preproc_cost *= nodes_per_second

            with tracer.context("pruner"):
                step_target = M.get_r(0,
                                      0) * 0.99 if progressive else target_norm
                pruner = Pruning.Pruner(step_target,
                                        preproc_cost, [M.r()],
                                        target=1,
                                        metric=Pruning.EXPECTED_SOLUTIONS)
                coefficients = pruner.optimize_coefficients([1.] * M.d)
            try:
                enum_obj = Enumeration(self.M)
                with tracer.context("enumeration",
                                    enum_obj=enum_obj,
                                    full=True):
                    max_dist, solution = enum_obj.enumerate(
                        0,
                        params.block_size,
                        target_norm,
                        0,
                        pruning=coefficients)[0]
                with tracer.context("postprocessing"):
                    self.svp_postprocessing(0,
                                            params.block_size,
                                            solution,
                                            tracer=tracer)
                rerandomize = False
            except EnumerationError:
                rerandomize = True

            self.M.update_gso()
            logger.debug("r_0: %7.2f, target: %7.2f, preproc: %3d" %
                         (log(M.get_r(0, 0), 2), log(target_norm, 2), preproc))

    tracer.exit()
    tracer.trace.data["|A_0|"] = A[0].norm()
    tracer.trace.data["preprocessing_block_size"] = preproc

    if return_queue:
        return_queue.put(tracer.trace)
    else:
        return tracer.trace
Пример #15
0
# -*- coding: utf-8 -*-
import copy
from fpylll import IntegerMatrix, BKZ
from fpylll.algorithms.bkz import BKZReduction as BKZ1
from fpylll.algorithms.bkz2 import BKZReduction as BKZ2

n = 100
A = IntegerMatrix.random(n, "qary", k=n//2, bits=40)
param = BKZ.Param(block_size=40, max_loops=3, strategies=BKZ.DEFAULT_STRATEGY, flags=BKZ.MAX_LOOPS|BKZ.VERBOSE)

bkz = BKZ1(copy.copy(A))
bkz(param)
print(bkz.trace.report())


bkz = BKZ2(copy.copy(A))
bkz(param)
print(bkz.trace.report())
stat = bkz.trace.tour[0].find("enumeration")["%"]
print stat.min, stat.max
Пример #16
0
FPLLL.set_random_seed(1)
n, bits = 120, 40
A = IntegerMatrix.random(n, "qary", k=n / 2, bits=bits)
beta = 60
tours = 6
par = BKZ.Param(block_size=beta, strategies=BKZ.DEFAULT_STRATEGY)

LLL.reduction(A)

M = GSO.Mat(A)
M.update_gso()

norms = [[log(M.get_r(i, i)) for i in range(n)]]

bkz = BKZ2(M)

for i in range(tours):
    bkz.tour(par)
    norms += [[log(M.get_r(i, i)) for i in range(n)]]

#CO = ["#4D4D4D", "#5DA5DA", "#FAA43A", "#60BD68",
#           "#F17CB0", "#B2912F", "#B276B2", "#DECF3F", "#F15854"]
Colors = [
    "#12035D", "#22107F", "#45349E", "#6F5FBF", "#9587DE", "#B1A5EE", "#DED8FA"
]

X = range(n)
plt.plot(X, norms[1], color=Colors[0], label="LLL")

for i, _norms in enumerate(norms[1:]):
Пример #17
0
    def __call__(cls,
                 M,
                 predicate,
                 squared_target_norm,
                 invalidate_cache=lambda: None,
                 target_prob=None,
                 preproc_offset=20,
                 ph=0,
                 threads=1,
                 **kwds):
        preproc_time = None
        ntests = 0

        if target_prob is None:
            target_prob = cls.DEFAULT_TARGET_PROB

        bkz_res = usvp_pred_bkz_enum_solve(M,
                                           predicate,
                                           block_size=min(
                                               STRATEGIES_MAX_DIM, M.d),
                                           invalidate_cache=invalidate_cache,
                                           threads=threads)

        if bkz_res.success:  # this might be enough
            return bkz_res

        FPLLL.set_threads(threads)

        M.update_gso()
        bkz = BKZ2(M)
        tracer = BKZTreeTracer(bkz, root_label="enum_pred", start_clocks=True)

        remaining_probability, rerandomize, found, solution = (1.0, False,
                                                               False, None)

        while remaining_probability > 1.0 - target_prob:
            invalidate_cache()

            with tracer.context("preprocessing"):
                if rerandomize:
                    with tracer.context("randomization"):
                        bkz.randomize_block(0, M.d, tracer=tracer, density=3)
                with tracer.context("reduction"):
                    with tracer.context("lll"):
                        bkz.lll_obj()
                    for _ in range(4):
                        bkz.tour(
                            BKZ.EasyParam(min(max(M.d - preproc_offset, 2),
                                              STRATEGIES_MAX_DIM),
                                          flags=BKZ.GH_BND),
                            tracer=tracer,
                        )

            if preproc_time is None:
                preproc_time = float(
                    tracer.trace.child("preprocessing")["cputime"])

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

            if found:
                break

            with tracer.context("pruner"):
                preproc_cost = threads * preproc_time * 2 * 10**9 / 100  # 100 cycles per node
                with SuppressStream():
                    r = []
                    for i in range(M.d):
                        r_, exp = M.get_r_exp(i, i)
                        r.append(r_ * 2**(exp - ph))
                    (cost, prob), coeffs = cls.pruning_coefficients(
                        squared_target_norm / 2**ph,
                        r,
                        preproc_cost,
                        target_prob=target_prob)

            def callbackf(v):
                nonlocal ntests
                ntests += 1
                return predicate(v, standard_basis=False)

            enum_obj = Enumeration(M, callbackf=callbackf)
            with tracer.context("enumeration",
                                enum_obj=enum_obj,
                                probability=prob,
                                full=True):
                try:
                    solutions = enum_obj.enumerate(0,
                                                   M.d,
                                                   squared_target_norm / 2**ph,
                                                   ph,
                                                   pruning=coeffs)
                    _, v = solutions[0]
                    found = True
                    solution = tuple([int(v_) for v_ in M.B.multiply_left(v)])
                    break
                except EnumerationError:
                    pass

            rerandomize = True
            remaining_probability *= 1 - prob

        tracer.exit()
        FPLLL.set_threads(1)

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

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