/** @brief Test sieve by checking if function returns correct vector. @param A input lattice @param b shortest vector @return */ template <class ZT> int test_sieve_alg(ZZ_mat<ZT> &A, IntVect &b, int alg) { GaussSieve<ZT, FP_NR<double>> gsieve(A, alg, 0, 0); Z_NR<ZT> goal_norm; goal_norm = 0; gsieve.set_goal_norm2(goal_norm); if (gsieve.alg == 3) gsieve.run_3sieve(); else if (gsieve.alg == 4) gsieve.run_4sieve(); else gsieve.run_2sieve(); NumVect<Z_NR<ZT>> v = gsieve.return_first(); Z_NR<ZT> tmp; Z_NR<ZT> norm_s; Z_NR<ZT> norm_b; for (int i = 0; i < A.get_cols(); i++) { tmp.mul(v[i], v[i]); norm_s.add(norm_s, tmp); tmp.mul(b[i], b[i]); norm_b.add(norm_b, tmp); } if (norm_s != norm_b) return 1; return 0; }
template <> int hkz(Options &o, ZZ_mat<mpz_t> &b) { const char *format = o.output_format ? o.output_format : "b"; int flags = 0; if (o.verbose) flags |= HKZ_VERBOSE; string dump_gso_filename; if (o.bkz_flags & BKZ_DUMP_GSO) { dump_gso_filename = o.bkz_dump_gso_filename; flags |= BKZ_DUMP_GSO; } //int status = hkz_reduction(b, flags, o.float_type, o.precision, dump_gso_filename); int status = hkz_reduction(b, flags, o.float_type, o.precision); for (int i = 0; format[i]; i++) { if (format[i] == 'b') { if (format[i + 1] == 'k') { b.print_comma(cout); i++; } else cout << b << endl; } } if (status != RED_SUCCESS) { cerr << "Failure: " << get_red_status_str(status) << endl; } return status; }
/** @brief Test if dual SVP reduction returns reduced basis. @param A input lattice @param b shortest dual vector @return */ template <class ZT> int test_dsvp_reduce(ZZ_mat<ZT> &A, IntVect &b) { IntMatrix u; int d = A.get_rows(); Float normb; if (dual_length(normb, A, b)) { return 1; } int status = lll_reduction(A, u, LLL_DEF_DELTA, LLL_DEF_ETA, LM_WRAPPER, FT_DEFAULT, 0, LLL_DEFAULT); if (status != RED_SUCCESS) { cerr << "LLL reduction failed: " << get_red_status_str(status) << endl; return status; } IntMatrix empty_mat; MatGSO<Integer, Float> gso(A, empty_mat, empty_mat, GSO_INT_GRAM); LLLReduction<Integer, Float> lll_obj(gso, LLL_DEF_DELTA, LLL_DEF_ETA, LLL_DEFAULT); vector<Strategy> strategies; BKZParam dummy(d, strategies); BKZReduction<Float> bkz_obj(gso, lll_obj, dummy); bool clean = true; bkz_obj.svp_reduction_ex(0, d, dummy, clean, true); status = bkz_obj.status; if (status != RED_SUCCESS) { cerr << "Failure: " << get_red_status_str(status) << endl; return status; } Float norm_sol; Integer zero; zero = 0; IntVect e_n(d, zero); e_n[d - 1] = 1; if (dual_length(norm_sol, A, e_n)) { return 1; } Float error; error = 1; error.mul_2si(error, -(int)error.get_prec()); normb += error; if (norm_sol > normb) { cerr << "Last dual vector too long by more than " << error << endl; return 1; } return 0; }
/** @brief Compute the norm of a dual vector (specified by coefficients in the dual basis). @param A input lattice @param b coefficients of shortest dual vector @return */ template <class ZT> int dual_length(Float &norm, ZZ_mat<ZT> &A, const IntVect &coords) { int d = coords.size(); if (A.get_rows() != d) { cerr << "DSVP length error: Coefficient vector has wrong dimension: "; cerr << A.get_rows() << " vs " << d << endl; return 1; } FloatVect coords_d(d); for (int i = 0; i < d; i++) { coords_d[i] = coords[i].get_d(); } IntMatrix empty_mat; MatGSO<Integer, Float> gso(A, empty_mat, empty_mat, GSO_INT_GRAM); if (!gso.update_gso()) { cerr << "GSO Failure." << endl; return 1; } Float tmp; gso.get_r(tmp, d - 1, d - 1); tmp.pow_si(tmp, -1); FloatVect alpha(d); Float mu, alpha2, r_inv; norm = 0.0; for (int i = 0; i < d; i++) { alpha[i] = coords_d[i]; for (int j = 0; j < i; j++) { gso.get_mu(mu, i, j); alpha[i] -= mu * alpha[j]; } gso.get_r(r_inv, i, i); r_inv.pow_si(r_inv, -1); alpha2.pow_si(alpha[i], 2); norm += alpha2 * r_inv; } return 0; }
template <class ZT> int test_svp(ZZ_mat<ZT> &A, IntVect &b) { IntVect sol_coord; // In the LLL-reduced basis IntVect sol_coord2; // In the initial basis IntVect solution; IntMatrix u; int status = lll_reduction(A, u, LLL_DEF_DELTA, LLL_DEF_ETA, LM_WRAPPER, FT_DEFAULT, 0, LLL_DEFAULT); if (status != RED_SUCCESS) { cerr << "LLL reduction failed: " << get_red_status_str(status) << endl; return status; } status = shortest_vector(A, sol_coord, SVPM_PROVED, SVP_DEFAULT); if (status != RED_SUCCESS) { cerr << "Failure: " << get_red_status_str(status) << endl; return status; } vector_matrix_product(sol_coord2, sol_coord, u); vector_matrix_product(solution, sol_coord, A); Z_NR<ZT> tmp; Z_NR<ZT> norm_s; Z_NR<ZT> norm_b; for (int i = 0; i < A.get_cols(); i++) { tmp.mul(solution[i], solution[i]); norm_s.add(norm_s, tmp); tmp.mul(b[i], b[i]); norm_b.add(norm_b, tmp); } if (norm_s != norm_b) return 1; return 0; }
template <class ZT> void zeros_last(ZZ_mat<ZT> &b, ZZ_mat<ZT> &u, ZZ_mat<ZT> &u_inv_t) { int i, d = b.get_rows(); for (i = 0; i < d && b[i].is_zero(); i++) { } if (i > 0 && i < d) { b.rotate(0, i, d - 1); if (!u.empty()) u.rotate(0, i, d - 1); if (!u_inv_t.empty()) u_inv_t.rotate(0, i, d - 1); } }
template <class ZT> int lll(Options &o, ZZ_mat<ZT> &b) { // Stupid initialization of u and u_inv to be not empty. ZZ_mat<ZT> u(1, 1), u_inv(1, 1); const char *format = o.output_format ? o.output_format : "b"; int status, flags = 0; if (o.verbose) flags |= LLL_VERBOSE; if (o.early_red) flags |= LLL_EARLY_RED; if (o.siegel) flags |= LLL_SIEGEL; if (strchr(format, 'v') != NULL) { // LLL-reduction with transform and inverse transform status = lll_reduction(b, u, u_inv, o.delta, o.eta, o.method, o.float_type, o.precision, flags); } else if (strchr(format, 'u') != NULL) { // LLL-reduction with transform status = lll_reduction(b, u, o.delta, o.eta, o.method, o.float_type, o.precision, flags); } else { status = lll_reduction(b, o.delta, o.eta, o.method, o.float_type, o.precision, flags); } for (int i = 0; format[i]; i++) { switch (format[i]) { case 'b': if (format[i + 1] == 'k') { b.print_comma(cout); i++; } else cout << b << endl; break; case 'u': if (format[i + 1] == 'k') { u.print_comma(cout); i++; } else cout << u << endl; break; case 'v': if (format[i + 1] == 'k') { u_inv.print_comma(cout); i++; } else cout << u_inv << endl; break; case 't': cout << status << endl; break; case ' ': cout << endl; break; } } if (status != RED_SUCCESS) { cerr << "Failure: " << get_red_status_str(status) << endl; } return status; }
template <> int bkz(Options &o, ZZ_mat<mpz_t> &b) { CHECK(o.block_size > 0, "Option -b is missing"); vector<Strategy> strategies; if (!o.bkz_strategy_file.empty()) { strategies = load_strategies_json(strategy_full_path(o.bkz_strategy_file)); } BKZParam param(o.block_size, strategies); // Stupid initialization of u to be not empty. ZZ_mat<mpz_t> u(1, 1); const char *format = o.output_format ? o.output_format : "b"; int status; param.delta = o.delta; param.flags = o.bkz_flags; if (o.bkz_flags & BKZ_DUMP_GSO) param.dump_gso_filename = o.bkz_dump_gso_filename; if (o.bkz_flags & BKZ_GH_BND) param.gh_factor = o.bkz_gh_factor; if (o.bkz_flags & BKZ_MAX_LOOPS) param.max_loops = o.bkz_max_loops; if (o.verbose) param.flags |= BKZ_VERBOSE; if (o.no_lll) param.flags |= BKZ_NO_LLL; status = bkz_reduction(&b, strchr(format, 'u') ? &u : NULL, param, o.float_type, o.precision); for (int i = 0; format[i]; i++) { switch (format[i]) { case 'b': if (format[i + 1] == 'k') { b.print_comma(cout); i++; } else cout << b << endl; break; case 'u': if (format[i + 1] == 'k') { u.print_comma(cout); i++; } else cout << u << endl; break; case 't': cout << status << endl; break; case ' ': cout << endl; break; } } if (status != RED_SUCCESS) { cerr << "Failure: " << get_red_status_str(status) << endl; } return status; }