def find_min_complexity(params): """ For each valid and solving triple (bkz_dim, svp_dim, d) determines an approximate (!) cost and minimises. :param params: a list of all solving (bkz_dim, svp_dim, d) triples """ min_cost = None min_cost_param = None expo = .349 for param in params: bkz_block_size = param[0] - default_dim4free_fun(param[0]) svp_dim = param[1] - default_dim4free_fun(param[1]) d = param[2] bkz_cost = 2 * d * (2**(expo * bkz_block_size)) finisher_svp_cost = 2**((expo * svp_dim)) new_cost = bkz_cost + finisher_svp_cost if min_cost is None or new_cost < min_cost: min_cost = new_cost min_cost_param = param return min_cost_param
def sim_params(n, alpha): A, c, q = load_lwe_challenge(n, alpha) stddev = alpha * q winning_params = [] for m in range(60, min(2 * n + 1, A.nrows + 1)): B = primal_lattice_basis(A, c, q, m=m) M = GSO.Mat(B) M.update_gso() beta_bound = min(m + 1, 110 + default_dim4free_fun(110) + 1) svp_bound = min(m + 1, 151) rs = [M.get_r(i, i) for i in range(M.B.nrows)] for beta in range(40, beta_bound): rs, _ = simulate(rs, fplll_bkz.EasyParam(beta, max_loops=1)) for svp_dim in range(40, svp_bound): gh = gaussian_heuristic(rs[M.B.nrows - svp_dim:]) if svp_dim * (stddev**2) < gh: winning_params.append([beta, svp_dim, m + 1]) break min_param = find_min_complexity(winning_params) return min_param
def decoupler(decouple, n, samples, q, stddev, d): """ Creates valid (bkz_dim, svp_dim, d) triples, as determined by ``primal_parameters`` and determines which succeed in the recovery of the embedded error. :param decouple: if True the BKZ dimension and SVP dimension may differ :param n: the dimension of the LWE secret :param samples: maximum number of LWE samples to use for the embedding lattice. ``None`` means ``5*n`` :param q: the modulus of the LWE instance :param stddev: the standard deviation of the distribution from which the error vector components were uniformly and indepedently drawn :param d: find best parameters for dimension ``d`` embedding lattice """ params = [] if d is not None: ms = [d - 1] else: ms = list(range(n, min(5 * n + 1, samples + 1))) for m in ms: beta_bound = min(m + 1, 110 + default_dim4free_fun(110)) svp_bound = min(m + 1, 156) for bkz_block_size in range(40, beta_bound): delta_0 = delta_0f(bkz_block_size) if decouple: svp_dims = list(range(40, svp_bound)) else: svp_dims = [min(bkz_block_size, svp_bound)] for svp_dim in svp_dims: d = float(m + 1) rhs = log_gh_svp(d, delta_0, svp_dim, n, q) if rhs - log(stddev) - log(svp_dim) / 2. >= 0: params.append([bkz_block_size, svp_dim, m + 1]) return params