static std::shared_ptr<SQLObject<T> > newObject_static(SQLStore_impl& ss, SQLContext *ctx, Name name, const T& init){ constexpr Table t = (std::is_same<T,int>::value ? Table::IntStore : Table::BlobStore); std::size_t size = mutils::bytes_size(init); std::vector<char> v(size); whendebug(std::size_t tb_size = ) mutils::to_bytes(init,v.data()); assert(mutils::bytes_size(init) == size); assert(size == tb_size); GSQLObject gso(ctx->i.get(),ss,t,name,v); return std::make_shared<SQLObject<T> >(std::move(gso),mutils::heap_copy(init)); }
auto existingObject(SQLContext *, Name name){ static constexpr Table t = (std::is_same<T,int>::value ? Table::IntStore : Table::BlobStore); GSQLObject gso(*this,t,name); return SQLHandle<T>{std::shared_ptr<SQLObject<T> > { new SQLObject<T>{std::move(gso),nullptr}},*this}; }
static int shortest_vector_ex(IntMatrix &b, IntVect &sol_coord, SVPMethod method, const vector<double> &pruning, int flags, EvaluatorMode eval_mode, long long &sol_count, vector<IntVect> *subsol_coord = nullptr, vector<enumf> *subsol_dist = nullptr) { bool findsubsols = (subsol_coord != nullptr) && (subsol_dist != nullptr); // d = lattice dimension (note that it might decrease during preprocessing) int d = b.get_rows(); // n = dimension of the space int n = b.get_cols(); FPLLL_CHECK(d > 0 && n > 0, "shortestVector: empty matrix"); FPLLL_CHECK(d <= n, "shortestVector: number of vectors > size of the vectors"); // Sets the floating-point precision // Error bounds on GSO are valid if prec >= minprec double rho; int min_prec = gso_min_prec(rho, d, LLL_DEF_DELTA, LLL_DEF_ETA); int prec = max(53, min_prec + 10); int old_prec = Float::set_prec(prec); // Allocates space for vectors and matrices in constructors IntMatrix empty_mat; MatGSO<Integer, Float> gso(b, empty_mat, empty_mat, GSO_INT_GRAM); Float max_dist; Integer int_max_dist; Integer itmp1; // Computes the Gram-Schmidt orthogonalization in floating-point gso.update_gso(); gen_zero_vect(sol_coord, d); // If the last b_i* are too large, removes them to avoid an underflow int new_d = last_useful_index(gso.get_r_matrix()); if (new_d < d) { // FPLLL_TRACE("Ignoring the last " << d - new_d << " vector(s)"); d = new_d; } if (flags & SVP_DUAL) { max_dist = 1.0 / gso.get_r_exp(d - 1, d - 1); if (flags & SVP_VERBOSE) { cout << "max_dist = " << max_dist << endl; } } else { /* Computes a bound for the enumeration. This bound would work for an exact algorithm, but we will increase it later to ensure that the fp algorithm finds a solution */ get_basis_min(int_max_dist, b, 0, d); max_dist.set_z(int_max_dist, GMP_RNDU); } // Initializes the evaluator of solutions Evaluator<Float> *evaluator; if (method == SVPM_FAST) { evaluator = new FastEvaluator<Float>(d, gso.get_mu_matrix(), gso.get_r_matrix(), eval_mode, 0, findsubsols); } else if (method == SVPM_PROVED) { ExactEvaluator *p = new ExactEvaluator(d, b, gso.get_mu_matrix(), gso.get_r_matrix(), eval_mode, 0, findsubsols); p->int_max_dist = int_max_dist; evaluator = p; } else { FPLLL_ABORT("shortestVector: invalid evaluator type"); } evaluator->init_delta_def(prec, rho, true); if (!(flags & SVP_OVERRIDE_BND) && (eval_mode == EVALMODE_SV || method == SVPM_PROVED)) { Float ftmp1; bool result = evaluator->get_max_error_aux(max_dist, true, ftmp1); FPLLL_CHECK(result, "shortestVector: cannot compute an initial bound"); max_dist.add(max_dist, ftmp1, GMP_RNDU); } // Main loop of the enumeration enumerate_svp(d, gso, max_dist, *evaluator, pruning, flags); int result = RED_ENUM_FAILURE; if (eval_mode != EVALMODE_SV) { result = RED_SUCCESS; sol_count = evaluator->sol_count * 2; } else if (!evaluator->sol_coord.empty()) { /*Float fMaxError; validMaxError = evaluator->get_max_error(fMaxError); max_error = fMaxError.get_d(GMP_RNDU);*/ for (int i = 0; i < d; i++) { itmp1.set_f(evaluator->sol_coord[i]); sol_coord[i].add(sol_coord[i], itmp1); } result = RED_SUCCESS; } if (findsubsols) { subsol_coord->clear(); subsol_dist->clear(); subsol_dist->resize(evaluator->sub_sol_coord.size()); for (size_t i = 0; i < evaluator->sub_sol_coord.size(); ++i) { (*subsol_dist)[i] = evaluator->sub_sol_dist[i]; IntVect ss_c; for (size_t j = 0; j < evaluator->sub_sol_coord[i].size(); ++j) { itmp1.set_f(evaluator->sub_sol_coord[i][j]); ss_c.emplace_back(itmp1); } subsol_coord->emplace_back(std::move(ss_c)); } } delete evaluator; Float::set_prec(old_prec); return result; }
int closest_vector(IntMatrix &b, const IntVect &int_target, IntVect &sol_coord, int method, int flags) { // d = lattice dimension (note that it might decrease during preprocessing) int d = b.get_rows(); // n = dimension of the space int n = b.get_cols(); FPLLL_CHECK(d > 0 && n > 0, "closestVector: empty matrix"); FPLLL_CHECK(d <= n, "closestVector: number of vectors > size of the vectors"); // Sets the floating-point precision // Error bounds on GSO are valid if prec >= minprec double rho; int min_prec = gso_min_prec(rho, d, LLL_DEF_DELTA, LLL_DEF_ETA); int prec = max(53, min_prec + 10); int old_prec = Float::set_prec(prec); // Allocates space for vectors and matrices in constructors IntMatrix empty_mat; MatGSO<Integer, Float> gso(b, empty_mat, empty_mat, GSO_INT_GRAM); FloatVect target_coord; Float max_dist; Integer itmp1; // Computes the Gram-Schmidt orthogonalization in floating-point gso.update_gso(); gen_zero_vect(sol_coord, d); /* Applies Babai's algorithm. Because we use fp, it might be necessary to do it several times (if ||target|| >> ||b_i||) */ FloatMatrix float_matrix(d, n); FloatVect target(n), babai_sol; IntVect int_new_target = int_target; for (int i = 0; i < d; i++) for (int j = 0; j < n; j++) float_matrix(i, j).set_z(b(i, j)); for (int loop_idx = 0;; loop_idx++) { if (loop_idx >= 0x100 && ((loop_idx & (loop_idx - 1)) == 0)) FPLLL_INFO("warning: possible infinite loop in Babai's algorithm"); for (int i = 0; i < n; i++) { target[i].set_z(int_new_target[i]); } babai(float_matrix, gso.get_mu_matrix(), gso.get_r_matrix(), target, babai_sol); int idx; for (idx = 0; idx < d && babai_sol[idx] >= -1 && babai_sol[idx] <= 1; idx++) { } if (idx == d) break; for (int i = 0; i < d; i++) { itmp1.set_f(babai_sol[i]); sol_coord[i].add(sol_coord[i], itmp1); for (int j = 0; j < n; j++) int_new_target[j].submul(itmp1, b(i, j)); } } // FPLLL_TRACE("BabaiSol=" << sol_coord); get_gscoords(float_matrix, gso.get_mu_matrix(), gso.get_r_matrix(), target, target_coord); /* Computes a very large bound to make the algorithm work until the first solution is found */ max_dist = 0.0; for (int i = 1; i < d; i++) { // get_r_exp(i, i) = r(i, i) because gso is initialized without GSO_ROW_EXPO max_dist.add(max_dist, gso.get_r_exp(i, i)); } vector<int> max_indices; if (method & CVPM_PROVED) { // For Exact CVP, we need to reset enum below depth with maximal r_i max_indices = vector<int>(d); int cur, max_index, previous_max_index; previous_max_index = max_index = d-1; Float max_val; while (max_index > 0) { max_val = gso.get_r_exp(max_index, max_index); for (cur = previous_max_index - 1 ; cur >= 0 ; --cur) { if (max_val <= gso.get_r_exp(cur, cur)) { max_val = gso.get_r_exp(cur, cur); max_index = cur; } } for (cur = max_index ; cur < previous_max_index ; ++cur) max_indices[cur] = max_index; max_indices[previous_max_index] = previous_max_index; previous_max_index = max_index; --max_index; } } FPLLL_TRACE("max_indices " << max_indices); FastEvaluator<Float> evaluator(n, gso.get_mu_matrix(), gso.get_r_matrix(), EVALMODE_CV); // Main loop of the enumeration Enumeration<Float> enumobj(gso, evaluator, max_indices); enumobj.enumerate(0, d, max_dist, 0, target_coord); int result = RED_ENUM_FAILURE; if (!evaluator.sol_coord.empty()) { FPLLL_TRACE("evaluator.sol_coord=" << evaluator.sol_coord); if (flags & CVP_VERBOSE) FPLLL_INFO("max_dist=" << max_dist); for (int i = 0; i < d; i++) { itmp1.set_f(evaluator.sol_coord[i]); sol_coord[i].add(sol_coord[i], itmp1); } result = RED_SUCCESS; } Float::set_prec(old_prec); return result; }