예제 #1
0
def full_sieve_kernel(arg0, params=None, seed=None):
    # Pool.map only supports a single parameter
    if params is None and seed is None:
        n, params, seed = arg0
    else:
        n = arg0

    pump_params = pop_prefixed_params("pump", params)
    workout_params = pop_prefixed_params("workout", params)
    verbose = params.pop("verbose")
    load_matrix = params.pop("load_matrix")
    pre_bkz = params.pop("pre_bkz")
    trace = params.pop("trace")

    reserved_n = n
    params = params.new(reserved_n=reserved_n, otf_lift=False)

    if load_matrix is None:
        A, bkz = load_svpchallenge_and_randomize(n, s=0, seed=seed)
        if verbose:
            print("Loaded challenge dim %d" % n)
        if pre_bkz is not None:
            par = BKZ_FPYLLL.Param(pre_bkz,
                                   strategies=BKZ_FPYLLL.DEFAULT_STRATEGY,
                                   max_loops=1)
            bkz(par)

    else:
        A, _ = load_matrix_file(load_matrix, doLLL=False, high_prec=False)
        if verbose:
            print("Loaded file '%s'" % load_matrix)

    g6k = Siever(A, params, seed=seed)
    if trace:
        tracer = SieveTreeTracer(g6k,
                                 root_label=("full-sieve", n),
                                 start_clocks=True)
    else:
        tracer = dummy_tracer

    # Actually runs a workout with very large decrements, so that the basis is kind-of reduced
    # for the final full-sieve
    workout(g6k,
            tracer,
            0,
            n,
            dim4free_min=0,
            dim4free_dec=15,
            pump_params=pump_params,
            verbose=verbose,
            **workout_params)

    g6k.output_bench()

    tracer.exit()

    if hasattr(tracer, "trace"):
        return tracer.trace
    else:
        return None
예제 #2
0
def hkz_kernel(arg0, params=None, seed=None):
    # Pool.map only supports a single parameter
    if params is None and seed is None:
        n, params, seed = arg0
    else:
        n = arg0

    reserved_n = n
    params = params.new(reserved_n=reserved_n, otf_lift=False)
    verbose = params.pop("verbose")

    pump_params = pop_prefixed_params("pump", params)
    workout_params = pop_prefixed_params("workout", params)

    verbose = params.pop("verbose")
    if verbose:
        workout_params["verbose"] = True
    challenge_seed = params.pop("challenge_seed")

    A, _ = load_svpchallenge_and_randomize(n, s=challenge_seed, seed=seed)

    g6k = Siever(A, params, seed=seed)
    tracer = SieveTreeTracer(g6k, root_label=("hkz", n), start_clocks=True)

    # runs a workout woth pump-down down until the end
    workout(g6k, tracer, 0, n, pump_params=pump_params, verbose=verbose, **workout_params)
    #Just making sure
    pump(g6k, tracer, 15, n-15, 0, **pump_params)
    g6k.lll(0, n)

    return tracer.exit()
예제 #3
0
파일: svp_challenge.py 프로젝트: tell/g6k
def asvp_kernel(arg0, params=None, seed=None):
    logger = logging.getLogger('asvp')

    # Pool.map only supports a single parameter
    if params is None and seed is None:
        n, params, seed = arg0
    else:
        n = arg0

    params = copy.copy(params)

    load_matrix = params.pop("load_matrix")
    pump_params = pop_prefixed_params("pump", params)
    workout_params = pop_prefixed_params("workout", params)
    verbose = params.pop("verbose")
    if verbose:
        workout_params["verbose"] = True
    challenge_seed = params.pop("challenge_seed")

    if load_matrix is None:
        A, _ = load_svpchallenge_and_randomize(n, s=challenge_seed, seed=seed)
        if verbose:
            print(("Loaded challenge dim %d" % n))
    else:
        A, _ = load_matrix_file(load_matrix)
        if verbose:
            print(("Loaded file '%s'" % load_matrix))

    g6k = Siever(A, params, seed=seed)
    tracer = SieveTreeTracer(g6k,
                             root_label=("svp-challenge", n),
                             start_clocks=True)

    gh = gaussian_heuristic([g6k.M.get_r(i, i) for i in range(n)])
    goal_r0 = (1.05**2) * gh
    if verbose:
        print(("gh = %f, goal_r0/gh = %f, r0/gh = %f" %
               (gh, goal_r0 / gh, sum([x * x for x in A[0]]) / gh)))

    flast = workout(g6k,
                    tracer,
                    0,
                    n,
                    goal_r0=goal_r0,
                    pump_params=pump_params,
                    **workout_params)

    tracer.exit()
    stat = tracer.trace
    stat.data["flast"] = flast

    if verbose:
        logger.info("sol %d, %s" % (n, A[0]))

    norm = sum([x * x for x in A[0]])
    if verbose:
        logger.info("norm %.1f ,hf %.5f" % (norm**.5, (norm / gh)**.5))

    return tracer.trace
예제 #4
0
def svp_kernel(arg0, params=None, seed=None):
    # Pool.map only supports a single parameter
    if params is None and seed is None:
        n, params, seed = arg0
    else:
        n = arg0

    params = copy.copy(params)
    challenge_seed = params.pop("challenge_seed")
    alg = params.pop("svp/alg")
    workout_params = pop_prefixed_params("workout/", params)
    pump_params = pop_prefixed_params("pump/", params)

    goal_r0 = 1.001 * load_svpchallenge_norm(n, s=challenge_seed)
    A, bkz = load_svpchallenge_and_randomize(n, s=challenge_seed, seed=seed)
    g6k = Siever(A, params, seed=seed)
    tracer = SieveTreeTracer(g6k,
                             root_label=("svp-exact", n),
                             start_clocks=True)

    if alg == "enum":
        assert len(workout_params) + len(pump_params) == 0
        bkz_params = fplll_bkz.Param(
            block_size=n,
            max_loops=1,
            strategies=fplll_bkz.DEFAULT_STRATEGY,
            flags=fplll_bkz.GH_BND,
        )
        svp_enum(bkz, bkz_params, goal_r0)
        flast = 0
    elif alg == "duc18":
        assert len(workout_params) + len(pump_params) == 0
        flast = ducas18(g6k, tracer, goal=goal_r0)
    elif alg == "workout":
        flast = workout(g6k,
                        tracer,
                        0,
                        n,
                        goal_r0=goal_r0,
                        pump_params=pump_params,
                        **workout_params)
    else:
        raise ValueError("Unrecognized algorithm for SVP")

    r0 = bkz.M.get_r(0, 0) if alg == "enum" else g6k.M.get_r(0, 0)
    if r0 > goal_r0:
        raise ValueError("Did not reach the goal")
    if 1.002 * r0 < goal_r0:
        raise ValueError(
            "Found a vector shorter than the goal for n=%d s=%d." %
            (n, challenge_seed))

    tracer.exit()
    stat = tracer.trace
    stat.data["flast"] = flast
    return stat
예제 #5
0
def svp_kernel_trial(arg0, params=None, seed=None, goal_r0=None):
    # Pool.map only supports a single parameter
    if params is None and seed is None:
        n, params, seed = arg0
    else:
        n = arg0

    params = copy.copy(params)
    dim4free_dec = params.pop("workout/dim4free_dec")
    pump_params = pop_prefixed_params("pump", params)
    challenge_seed = params.pop("challenge_seed")

    A, _ = load_svpchallenge_and_randomize(n, s=challenge_seed, seed=seed)
    g6k = Siever(A, params, seed=seed)
    tracer = SieveTreeTracer(g6k,
                             root_label=("svp-challenge", n),
                             start_clocks=True)

    gh = gaussian_heuristic([g6k.M.get_r(i, i) for i in range(n)])
    ds = list(range(0, n - 40, dim4free_dec))[::-1] + 10 * [0]

    if goal_r0 is None:
        goal_r0 = 1.1 * gh

    for d in ds:
        workout(g6k,
                tracer,
                0,
                n,
                dim4free_dec=dim4free_dec,
                goal_r0=goal_r0 * 1.001,
                pump_params=pump_params)

    tracer.exit()
    return int(g6k.M.get_r(0, 0)), gh
예제 #6
0
def full_sieve_kernel(arg0, params=None, seed=None):
    # Pool.map only supports a single parameter
    if params is None and seed is None:
        n, params, seed = arg0
    else:
        n = arg0

    pump_params = pop_prefixed_params("pump", params)
    verbose = params.pop("verbose")

    reserved_n = n
    params = params.new(reserved_n=reserved_n, otf_lift=False)

    challenge_seed = params.pop("challenge_seed")
    A, _ = load_svpchallenge_and_randomize(n, s=challenge_seed, seed=seed)

    g6k = Siever(A, params, seed=seed)
    tracer = SieveTreeTracer(g6k,
                             root_label=("full-sieve", n),
                             start_clocks=True)

    # Actually runs a workout with very large decrements, so that the basis is kind-of reduced
    # for the final full-sieve
    workout(
        g6k,
        tracer,
        0,
        n,
        dim4free_min=0,
        dim4free_dec=15,
        pump_params=pump_params,
        verbose=verbose,
    )

    return tracer.exit()
예제 #7
0
def asvp_kernel(arg0, params=None, seed=None):
    logger = logging.getLogger('asvp')

    # Pool.map only supports a single parameter
    if params is None and seed is None:
        n, params, seed = arg0
    else:
        n = arg0

    params = copy.copy(params)

    load_matrix = params.pop("load_matrix")
    pump_params = pop_prefixed_params("pump", params)
    workout_params = pop_prefixed_params("workout", params)
    verbose = params.pop("verbose")
    if verbose:
        workout_params["verbose"] = True
    challenge_seed = params.pop("challenge_seed")

    if load_matrix is None:
        A, _ = load_svpchallenge_and_randomize(n, s=challenge_seed, seed=seed)
        if verbose:
            print("Loaded challenge dim %d" % n)
    else:
        A, _ = load_matrix_file(load_matrix)
        if verbose:
            print("Loaded file '%s'" % load_matrix)

    g6k = Siever(A, params, seed=seed)
    tracer = SieveTreeTracer(g6k, root_label=("svp-challenge", n), start_clocks=True)

    gh = gaussian_heuristic([g6k.M.get_r(i, i) for i in range(n)])

    flast = workout(g6k, tracer, 0, n, pump_params=pump_params, **workout_params)

    tracer.exit()
    stat = tracer.trace

    f = workout_params["dim4free_min"]
    gh2 = gaussian_heuristic([g6k.M.get_r(i, i) for i in range(f, n)])
    quality = (gh * (n - f)) / (gh2 * n)

    stat.data["quality"] = quality

    print >> sys.stderr, g6k.M.B

    return tracer.trace
예제 #8
0
def asvp_kernel(arg0, params=None, seed=None):
    # Pool.map only supports a single parameter
    if params is None and seed is None:
        n, params, seed = arg0
    else:
        n = arg0

    params = copy.copy(params)

    load_matrix = params.pop("load_matrix")
    goal_r0__gh = params.pop('goal_r0__gh')
    pump_params = pop_prefixed_params("pump", params)
    workout_params = pop_prefixed_params("workout", params)
    verbose = params.pop("verbose")
    if verbose:
        workout_params["verbose"] = True

    A, _ = load_matrix_file(load_matrix, randomize=False, seed=None, float_type="double")
    if verbose:
        print(("Loaded file '%s'" % load_matrix))

    g6k = Siever(A, params, seed=seed)
    tracer = SieveTreeTracer(g6k, root_label=("svp-challenge", n), start_clocks=True)

    gh = gaussian_heuristic([g6k.M.get_r(i, i) for i in range(n)])
    goal_r0 = (goal_r0__gh**2) * gh
    if verbose:
        print(("gh = %f, goal_r0/gh = %f, r0/gh = %f" % (gh, goal_r0/gh, sum([x*x for x in A[0]])/gh)))
 
    flast = workout(g6k, tracer, 0, n, goal_r0=goal_r0, **workout_params)

    tracer.exit()
    stat = tracer.trace
    sol = tuple(A[0])
    stat.data["flast"] = flast
    tracer.trace.data['res'] = A

    if verbose:
        print(f"svp: sol {sol}")

    norm = sum([x*x for x in sol])
    if verbose:
        print("svp: norm %.1f ,hf %.5f" % (norm**.5, (norm/gh)**.5))

    return tracer.trace
예제 #9
0
def find_norm_kernel_trial(arg0, params=None, seed=None, goal_r0=None):
    # Pool.map only supports a single parameter
    if params is None and seed is None:
        n, params, seed = arg0
    else:
        n = arg0

    params = copy.copy(params)
    dim4free_dec = params.pop("workout/dim4free_dec")
    pump_params = pop_prefixed_params("pump", params)
    load_matrix = params.pop("load_matrix")
    verbose = params.pop("verbose")

    A, _ = load_matrix_file(load_matrix,
                            randomize=True,
                            seed=None,
                            float_type="double")

    if A.nrows != n:
        raise ValueError(
            f"wrong dimension:: Expected dim(A) = {A.nrows}, got n = {n}")

    g6k = Siever(A, params, seed=seed)
    tracer = SieveTreeTracer(g6k,
                             root_label=("svp-challenge", n),
                             start_clocks=True)

    gh = gaussian_heuristic([g6k.M.get_r(i, i) for i in range(n)])
    ds = list(range(0, n - 40, dim4free_dec))[::-1] + 10 * [0]

    if goal_r0 is None:
        goal_r0 = 1.1 * gh

    if verbose and n < 90:
        verbose = False

    for d in ds:
        workout(g6k,
                tracer,
                0,
                n,
                dim4free_dec=dim4free_dec,
                goal_r0=goal_r0 * 1.001,
                pump_params=pump_params,
                verbose=verbose)

    tracer.exit()
    return int(g6k.M.get_r(0, 0)), gh
예제 #10
0
파일: bkz.py 프로젝트: mickeyUcas/g6k
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
예제 #11
0
def asvp_kernel(arg0, params=None, seed=None):
    logger = logging.getLogger('asvp')

    # Pool.map only supports a single parameter
    if params is None and seed is None:
        n, params, seed = arg0
    else:
        n = arg0

    params = copy.copy(params)

    load_matrix = params.pop("load_matrix")
    pre_bkz = params.pop("pre_bkz")
    pump_params = pop_prefixed_params("pump", params)
    workout_params = pop_prefixed_params("workout", params)
    verbose = params.pop("verbose")
    if verbose:
        workout_params["verbose"] = True
    challenge_seed = params.pop("challenge_seed")
    high_prec = params.pop("high_prec")
    trace = params.pop("trace")

    if load_matrix is None:
        A, bkz = load_svpchallenge_and_randomize(n,
                                                 s=challenge_seed,
                                                 seed=seed)
        if verbose:
            print("Loaded challenge dim %d" % n)
        if pre_bkz is not None:
            par = BKZ_FPYLLL.Param(pre_bkz,
                                   strategies=BKZ_FPYLLL.DEFAULT_STRATEGY,
                                   max_loops=1)
            bkz(par)

    else:
        A, _ = load_matrix_file(load_matrix, doLLL=False, high_prec=high_prec)
        if verbose:
            print("Loaded file '%s'" % load_matrix)

    g6k = Siever(A, params, seed=seed)

    if trace:
        tracer = SieveTreeTracer(g6k,
                                 root_label=("svp-challenge", n),
                                 start_clocks=True)
    else:
        tracer = dummy_tracer

    gh = gaussian_heuristic([g6k.M.get_r(i, i) for i in range(n)])

    gamma = params.pop("gamma")

    if gamma is None:
        goal_r0 = (1.05**2) * gh
    else:
        goal_r0 = gamma**2 * gh

    if verbose:
        print("gh = %f, goal_r0/gh = %f, r0/gh = %f" %
              (gh, goal_r0 / gh, sum([x * x for x in A[0]]) / gh))

    flast = workout(g6k,
                    tracer,
                    0,
                    n,
                    goal_r0=goal_r0,
                    pump_params=pump_params,
                    **workout_params)
    if verbose:
        logger.info("sol %d, %s" % (n, A[0]))

    norm = sum([x * x for x in A[0]])
    if verbose:
        logger.info("norm %.1f ,hf %.5f" % (norm**.5, (norm / gh)**.5))

    tracer.exit()

    if hasattr(tracer, "trace"):
        stat = tracer.trace
        stat.data["flast"] = flast
        return stat
    else:
        return None
예제 #12
0
def lwe_kernel(arg0, params=None, seed=None):
    """
    Run the primal attack against Darmstadt LWE instance (n, alpha).

    :param n: the dimension of the LWE-challenge secret
    :param params: parameters for LWE:

        - lwe/alpha: the noise rate of the LWE-challenge

        - lwe/m: the number of samples to use for the primal attack

        - lwe/goal_margin: accept anything that is
          goal_margin * estimate(length of embedded vector)
          as an lwe solution

        - lwe/svp_bkz_time_factor: if > 0, run a larger pump when
          svp_bkz_time_factor * time(BKZ tours so far) is expected
          to be enough time to find a solution

        - bkz/blocksizes: given as low:high:inc perform BKZ reduction
          with blocksizes in range(low, high, inc) (after some light)
          prereduction

        - bkz/tours: the number of tours to do for each blocksize

        - bkz/jump: the number of blocks to jump in a BKZ tour after
          each pump

        - bkz/extra_dim4free: lift to indices extra_dim4free earlier in
          the lattice than the currently sieved block

        - bkz/fpylll_crossover: use enumeration based BKZ from fpylll
          below this blocksize

        - 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

        - dummy_tracer: use a dummy tracer which captures less information

        - verbose: print information throughout the lwe challenge attempt

    """

    # Pool.map only supports a single parameter
    if params is None and seed is None:
        n, params, seed = arg0
    else:
        n = arg0

    params = copy.copy(params)

    # params for underlying BKZ
    extra_dim4free = params.pop("bkz/extra_dim4free")
    jump = params.pop("bkz/jump")
    dim4free_fun = params.pop("bkz/dim4free_fun")
    pump_params = pop_prefixed_params("pump", params)
    fpylll_crossover = params.pop("bkz/fpylll_crossover")
    blocksizes = params.pop("bkz/blocksizes")
    tours = params.pop("bkz/tours")

    # flow of the lwe solver
    svp_bkz_time_factor = params.pop("lwe/svp_bkz_time_factor")
    goal_margin = params.pop("lwe/goal_margin")

    # generation of lwe instance and Kannan's embedding
    alpha = params.pop("lwe/alpha")
    m = params.pop("lwe/m")
    decouple = svp_bkz_time_factor > 0

    # misc
    dont_trace = params.pop("dummy_tracer")
    verbose = params.pop("verbose")

    A, c, q = load_lwe_challenge(n=n, alpha=alpha)
    print "-------------------------"
    print "Primal attack, LWE challenge n=%d, alpha=%.4f" % (n, alpha)

    if m is None:
        try:
            min_cost_param = gsa_params(n=A.ncols, alpha=alpha, q=q,
                                        samples=A.nrows, decouple=decouple)
            (b, s, m) = min_cost_param
        except TypeError:
            raise TypeError("No winning parameters.")
    else:
        try:
            min_cost_param = gsa_params(n=A.ncols, alpha=alpha, q=q, samples=m,
                                        decouple=decouple)
            (b, s, _) = min_cost_param
        except TypeError:
            raise TypeError("No winning parameters.")
    print "Chose %d samples. Predict solution at bkz-%d + svp-%d" % (m, b, s)
    print

    target_norm = goal_margin * (alpha*q)**2 * m + 1

    if blocksizes is not None:
        blocksizes = range(10, 40) + eval("range(%s)" % re.sub(":", ",", blocksizes)) # noqa
    else:
        blocksizes = range(10, 50) + [b-20, b-17] + range(b - 14, b + 25, 2)

    B = primal_lattice_basis(A, c, q, m=m)

    g6k = Siever(B, params)
    print "GSO precision: ", g6k.M.float_type

    if dont_trace:
        tracer = dummy_tracer
    else:
        tracer = SieveTreeTracer(g6k, root_label=("lwe"), start_clocks=True)

    d = g6k.full_n
    g6k.lll(0, g6k.full_n)
    slope = basis_quality(g6k.M)["/"]
    print "Intial Slope = %.5f\n" % slope

    T0 = time.time()
    T0_BKZ = time.time()
    for blocksize in blocksizes:
        for tt in range(tours):
            # BKZ tours

            if blocksize < fpylll_crossover:
                if verbose:
                    print "Starting a fpylll BKZ-%d tour. " % (blocksize),
                    sys.stdout.flush()
                bkz = BKZReduction(g6k.M)
                par = fplll_bkz.Param(blocksize,
                                      strategies=fplll_bkz.DEFAULT_STRATEGY,
                                      max_loops=1)
                bkz(par)

            else:
                if verbose:
                    print "Starting a pnjBKZ-%d tour. " % (blocksize)

                pump_n_jump_bkz_tour(g6k, tracer, blocksize, jump=jump,
                                     verbose=verbose,
                                     extra_dim4free=extra_dim4free,
                                     dim4free_fun=dim4free_fun,
                                     goal_r0=target_norm,
                                     pump_params=pump_params)

            T_BKZ = time.time() - T0_BKZ

            if verbose:
                slope = basis_quality(g6k.M)["/"]
                fmt = "slope: %.5f, walltime: %.3f sec"
                print fmt % (slope, time.time() - T0)

            g6k.lll(0, g6k.full_n)

            if g6k.M.get_r(0, 0) <= target_norm:
                break

            # overdoing n_max would allocate too much memory, so we are careful
            svp_Tmax = svp_bkz_time_factor * T_BKZ
            n_max = int(58 + 2.85 * log(svp_Tmax * params.threads)/log(2.))

            rr = [g6k.M.get_r(i, i) for i in range(d)]
            for n_expected in range(2, d-2):
                x = (target_norm/goal_margin) * n_expected/(1.*d)
                if 4./3 * gaussian_heuristic(rr[d-n_expected:]) > x:
                    break

            print "Without otf, would expect solution at pump-%d. n_max=%d in the given time." % (n_expected, n_max) # noqa
            if n_expected >= n_max - 1:
                continue

            n_max += 1

            # Larger SVP

            llb = d - blocksize
            while gaussian_heuristic([g6k.M.get_r(i, i) for i in range(llb, d)]) < target_norm * (d - llb)/(1.*d): # noqa
                llb -= 1

            f = d-llb-n_max
            if verbose:
                print "Starting svp pump_{%d, %d, %d}, n_max = %d, Tmax= %.2f sec" % (llb, d-llb, f, n_max, svp_Tmax) # noqa
            pump(g6k, tracer, llb, d-llb, f, verbose=verbose,
                 goal_r0=target_norm * (d - llb)/(1.*d))

            if verbose:
                slope = basis_quality(g6k.M)["/"]
                fmt = "\n slope: %.5f, walltime: %.3f sec"
                print fmt % (slope, time.time() - T0)
                print

            g6k.lll(0, g6k.full_n)
            T0_BKZ = time.time()
            if g6k.M.get_r(0, 0) <= target_norm:
                break

        if g6k.M.get_r(0, 0) <= target_norm:
            print "Finished! TT=%.2f sec" % (time.time() - T0)
            print g6k.M.B[0]
            alpha_ = int(alpha*1000)
            filename = 'lwechallenge/%03d-%03d-solution.txt' % (n, alpha_)
            fn = open(filename, "w")
            fn.write(str(g6k.M.B[0]))
            fn.close()
            return

    raise ValueError("No solution found.")
예제 #13
0
파일: test_lwe.py 프로젝트: obqq/g6k
def ntru_kernel(n, params):
    # params for underlying BKZ
    extra_dim4free = params.get("bkz/extra_dim4free")
    jump = params.get("bkz/jump")
    dim4free_fun = params.get("bkz/dim4free_fun")
    pump_params = pop_prefixed_params("pump", params)
    fpylll_crossover = params.get("bkz/fpylll_crossover")
    blocksizes = params.get("bkz/blocksizes")
    tours = params.get("bkz/tours")

    print("params:", extra_dim4free, jump, dim4free_fun, pump_params,
          fpylll_crossover, blocksizes, tours)

    # flow of the lwe solver
    svp_bkz_time_factor = params.get("lwe/svp_bkz_time_factor")
    goal_margin = params.get("lwe/goal_margin")

    # generation of lwe instance and Kannan's embedding

    # misc
    dont_trace = params.get("dummy_tracer")
    verbose = params.get("verbose")

    #
    # Loading pregenerated LWE instance
    #

    A, b, s, e, q = read_lwe_from_file(n)

    print("Hybrid attack on LWE n=%d" % n)

    # compute the attack parameters
    w = 2 * (n / 3.)
    paramset_NTRU1 = {'n': n, 'q': q, 'w': w}
    print('paramset_NTRU', paramset_NTRU1)

    #
    # Preprocessing
    #

    beta, g, rt, nsamples, GSA = plain_hybrid_complexity(paramset_NTRU1,
                                                         verbose=True)
    print('beta, g, rt, nsamples predicted:', beta, g, rt, nsamples)

    # if g is too small to help, recompute BKZ params
    """
    if g <= 4:
        g = 0
        beta, nsamples,rt, GSA = find_beta(n, q, n)
    """
    #force g = 6 for testing the hybrid

    print(type(g))

    if n < 50 or g == 0:
        g = 6

    g = 6

    beta, nsamples, rt, GSA = find_beta(n, q, n)
    print('beta, g, rt, nsamples:', beta, g, rt, nsamples)
    # print('GSA predicted:')
    # print([exp(GSA[i]) for i in range(len(GSA))])

    return A, b, s, q, g, beta, nsamples
예제 #14
0
def ntru_kernel(arg0, params=None, seed=None):
    """
    Run the primal attack against Darmstadt LWE instance (n, alpha).

    :param n: the dimension of the LWE-challenge secret
    :param params: parameters for LWE:

        - lwe/alpha: the noise rate of the LWE-challenge

        - lwe/m: the number of samples to use for the primal attack

        - lwe/goal_margin: accept anything that is
          goal_margin * estimate(length of embedded vector)
          as an lwe solution

        - lwe/svp_bkz_time_factor: if > 0, run a larger pump when
          svp_bkz_time_factor * time(BKZ tours so far) is expected
          to be enough time to find a solution

        - bkz/blocksizes: given as low:high:inc perform BKZ reduction
          with blocksizes in range(low, high, inc) (after some light)
          prereduction

        - bkz/tours: the number of tours to do for each blocksize

        - bkz/jump: the number of blocks to jump in a BKZ tour after
          each pump

        - bkz/extra_dim4free: lift to indices extra_dim4free earlier in
          the lattice than the currently sieved block

        - bkz/fpylll_crossover: use enumeration based BKZ from fpylll
          below this blocksize

        - 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

        - dummy_tracer: use a dummy tracer which captures less information

        - verbose: print information throughout the lwe challenge attempt

    """

    # Pool.map only supports a single parameter
    if params is None and seed is None:
        n, params, seed = arg0
    else:
        n = arg0

    params = copy.copy(params)

    # params for underlying BKZ
    extra_dim4free = params.pop("bkz/extra_dim4free")
    jump = params.pop("bkz/jump")
    dim4free_fun = params.pop("bkz/dim4free_fun")
    pump_params = pop_prefixed_params("pump", params)
    fpylll_crossover = params.pop("bkz/fpylll_crossover")
    blocksizes = params.pop("bkz/blocksizes")
    tours = params.pop("bkz/tours")

    # flow of the lwe solver
    svp_bkz_time_factor = params.pop("lwe/svp_bkz_time_factor")
    goal_margin = params.pop("lwe/goal_margin")

    # generation of lwe instance and Kannan's embedding
    alpha = params.pop("lwe/alpha")
    m = params.pop("lwe/m")
    decouple = svp_bkz_time_factor > 0

    # misc
    dont_trace = params.pop("dummy_tracer")
    verbose = params.pop("verbose")

    filename = 'ntru_n_'+str(n)+'.txt'
    H, q = read_ntru_from_file(filename)

    print("-------------------------")
    print("Hybrid attack on NTRU n=%d" %n)


    # compute the attack parameters
    paramset_NTRU1 = {'n': n, 'q': q, 'w': 2*(n/3)}
    print(paramset_NTRU1)
    beta, g, rt = plain_hybrid_compleixty(paramset_NTRU1, verbose = True)

    B = ntru_plain_hybrid_basis(A, g, q, m=m)

    g6k = Siever(B, params)
    print("GSO precision: ", g6k.M.float_type)

    if dont_trace:
        tracer = dummy_tracer
    else:
        tracer = SieveTreeTracer(g6k, root_label=("ntru"), start_clocks=True)

    d = g6k.full_n
    g6k.lll(0, g6k.full_n)
    slope = basis_quality(g6k.M)["/"]
    print("Intial Slope = %.5f\n" % slope)

    T0 = time.time()
    T0_BKZ = time.time()
    for blocksize in blocksizes:
        for tt in range(tours):
            # BKZ tours

            if blocksize < fpylll_crossover:
                if verbose:
                    print("Starting a fpylll BKZ-%d tour. " % (blocksize), end=' ')
                    sys.stdout.flush()
                bkz = BKZReduction(g6k.M)
                par = fplll_bkz.Param(blocksize,
                                      strategies=fplll_bkz.DEFAULT_STRATEGY,
                                      max_loops=1)
                bkz(par)

            else:
                if verbose:
                    print("Starting a pnjBKZ-%d tour. " % (blocksize))

                pump_n_jump_bkz_tour(g6k, tracer, blocksize, jump=jump,
                                     verbose=verbose,
                                     extra_dim4free=extra_dim4free,
                                     dim4free_fun=dim4free_fun,
                                     goal_r0=target_norm,
                                     pump_params=pump_params)

            T_BKZ = time.time() - T0_BKZ

            if verbose:
                slope = basis_quality(g6k.M)["/"]
                fmt = "slope: %.5f, walltime: %.3f sec"
                print(fmt % (slope, time.time() - T0))

            g6k.lll(0, g6k.full_n)

            if g6k.M.get_r(0, 0) <= target_norm:
                break

            # overdoing n_max would allocate too much memory, so we are careful
            svp_Tmax = svp_bkz_time_factor * T_BKZ
            n_max = int(58 + 2.85 * log(svp_Tmax * params.threads)/log(2.))

            rr = [g6k.M.get_r(i, i) for i in range(d)]
            for n_expected in range(2, d-2):
                x = (target_norm/goal_margin) * n_expected/(1.*d)
                if 4./3 * gaussian_heuristic(rr[d-n_expected:]) > x:
                    break

            print("Without otf, would expect solution at pump-%d. n_max=%d in the given time." % (n_expected, n_max)) # noqa
            if n_expected >= n_max - 1:
                continue

            n_max += 1

            # Larger SVP

            llb = d - blocksize
            while gaussian_heuristic([g6k.M.get_r(i, i) for i in range(llb, d)]) < target_norm * (d - llb)/(1.*d): # noqa
                llb -= 1

            f = d-llb-n_max
            if verbose:
                print("Starting svp pump_{%d, %d, %d}, n_max = %d, Tmax= %.2f sec" % (llb, d-llb, f, n_max, svp_Tmax)) # noqa
            pump(g6k, tracer, llb, d-llb, f, verbose=verbose,
                 goal_r0=target_norm * (d - llb)/(1.*d))

            if verbose:
                slope = basis_quality(g6k.M)["/"]
                fmt = "\n slope: %.5f, walltime: %.3f sec"
                print(fmt % (slope, time.time() - T0))
                print()

            g6k.lll(0, g6k.full_n)
            T0_BKZ = time.time()
            if g6k.M.get_r(0, 0) <= target_norm:
                break

        if g6k.M.get_r(0, 0) <= target_norm:
            print("Finished! TT=%.2f sec" % (time.time() - T0))
            print(g6k.M.B[0])
            alpha_ = int(alpha*1000)
            filename = 'lwechallenge/%03d-%03d-solution.txt' % (n, alpha_)
            fn = open(filename, "w")
            fn.write(str(g6k.M.B[0]))
            fn.close()
            return
	"""
    raise ValueError("No solution found.")

def ntru():
    """
    Attempt to solve an ntru instance.

    """
    description = ntru.__doc__

    args, all_params = parse_args(description,
                                  ntru__m=None,
                                  lwe__goal_margin=1.5,
                                  lwe__svp_bkz_time_factor=1,
                                  bkz__blocksizes=None,
                                  bkz__tours=1,
                                  bkz__jump=1,
                                  bkz__extra_dim4free=12,
                                  bkz__fpylll_crossover=51,
                                  bkz__dim4free_fun="default_dim4free_fun",
                                  pump__down_sieve=True,
                                  dummy_tracer=True,  # set to control memory
                                  verbose=True
                                  )

    stats = run_all(ntru_kernel, list(all_params.values()), # noqa
                    lower_bound=args.lower_bound,
                    upper_bound=args.upper_bound,
                    step_size=args.step_size,
                    trials=args.trials,
                    workers=args.workers,
                    seed=args.seed)
예제 #15
0
def svp_kernel(arg0, params=None, seed=None):
    # Pool.map only supports a single parameter
    if params is None and seed is None:
        n, params, seed = arg0
    else:
        n = arg0

    params = copy.copy(params)
    load_matrix = params.pop("load_matrix")
    alg = params.pop("svp/alg")
    goal_r0 = 1.001 * params.pop('goal_r0')
    workout_params = pop_prefixed_params("workout/", params)
    pump_params = pop_prefixed_params("pump/", params)
    verbose = params.pop("verbose")
    if verbose and alg == "workout":
        workout_params["verbose"] = True

    A, bkz = load_matrix_file(load_matrix,
                              randomize=True,
                              seed=seed,
                              float_type="double")
    if verbose:
        print(("Loaded file '%s'" % load_matrix))
    g6k = Siever(A, params, seed=seed)
    tracer = SieveTreeTracer(g6k,
                             root_label=("svp-exact", n),
                             start_clocks=True)

    if alg == "enum":
        assert len(workout_params) + len(pump_params) == 0
        bkz_params = fplll_bkz.Param(block_size=n,
                                     max_loops=1,
                                     strategies=fplll_bkz.DEFAULT_STRATEGY,
                                     flags=fplll_bkz.GH_BND)
        svp_enum(bkz, bkz_params, goal_r0)
        flast = -1
    elif alg == "duc18":
        assert len(workout_params) + len(pump_params) == 0
        flast = ducas18(g6k, tracer, goal=goal_r0)
    elif alg == "workout":
        flast = workout(g6k,
                        tracer,
                        0,
                        n,
                        goal_r0=goal_r0,
                        pump_params=pump_params,
                        **workout_params)
    else:
        raise ValueError("Unrecognized algorithm for SVP")

    r0 = bkz.M.get_r(0, 0) if alg == "enum" else g6k.M.get_r(0, 0)
    if r0 > goal_r0:
        raise ValueError('Did not reach the goal')
    if 1.002 * r0 < goal_r0:
        raise ValueError(
            'Found a vector(%d) shorter than the goal(%d) for n=%d.' %
            (r0, goal_r0, n))

    if verbose:
        print("sol %d, %s" % (n, A[0]))

    tracer.exit()
    stat = tracer.trace
    stat.data["flast"] = flast
    tracer.trace.data['res'] = A

    return stat