Exemple #1
0
template <typename FT> void EnumerationDyn<FT>::reset(enumf cur_dist, int cur_depth)
{
  // FPLLL_TRACE("Reset level " << cur_depth);
  int new_dim = cur_depth + 1;

  vector<enumxt> partial_sol(d - cur_depth - 1);
  for (int i                       = cur_depth + 1; i < d; ++i)
    partial_sol[i - cur_depth - 1] = x[i];

  FT new_dist = 0.0;
  for (int i = 0; i < new_dim; i++)
    new_dist.add(new_dist, _gso.get_r_exp(i, i));

  FastEvaluator<FT> new_evaluator;
  Enumeration<FT> enumobj(_gso, new_evaluator, _max_indices);
  enumobj.enumerate(0, d, new_dist, 0, target, partial_sol, pruning_bounds, false, true);

  if (!new_evaluator.empty())
  {
    FT sol_dist2 = new_evaluator.begin()->first;
    sol_dist2.mul_2si(sol_dist2, -new_evaluator.normExp);
    enumf sol_dist = sol_dist2.get_d();
    // FPLLL_TRACE("Recovering sub-solution at level: " << cur_depth <<" soldist: " << sol_dist);

    if (sol_dist + cur_dist < partdistbounds[0])
    {
      // FPLLL_TRACE("Saving it.");
      for (int i = 0; i < new_dim; ++i)
        x[i]     = new_evaluator.begin()->second[i].get_d();
      process_solution(sol_dist + cur_dist);
    }
  }
}
Exemple #2
0
static bool enumerate_svp(int d, MatGSO<Integer, Float> &gso, Float &max_dist,
                          Evaluator<Float> &evaluator, const vector<enumf> &pruning, int flags)
{
  Enumeration<Float> enumobj(gso, evaluator);
  bool dual = (flags & SVP_DUAL);
  if (d == 1 || !pruning.empty() || dual)
  {
    enumobj.enumerate(0, d, max_dist, 0, vector<Float>(), vector<enumxt>(), pruning, dual);
  }
  else
  {
    Enumerator enumerator(d, gso.get_mu_matrix(), gso.get_r_matrix());
    while (enumerator.enum_next(max_dist))
    {
      if (flags & SVP_VERBOSE)
      {
        evaluator.new_sol_flag = false;
        cerr << enumerator.get_sub_tree();
        if (evaluator.eval_mode != EVALMODE_SV)
          cerr << " (count=2*" << evaluator.sol_count << ")";
      }

      /* Enumerates short vectors only in enumerator.get_sub_tree()
        (about maxVolume iterations or less) */
      enumobj.enumerate(0, d, max_dist, 0, FloatVect(), enumerator.get_sub_tree(), pruning);

      if (flags & SVP_VERBOSE)
      {
        cerr << "\r" << (char)27 << "[K";
        if (evaluator.eval_mode == EVALMODE_SV && evaluator.new_sol_flag)
          cerr << "Solution norm^2=" << evaluator.last_partial_dist
               << " value=" << evaluator.sol_coord << endl;
      }
    }
  }
  return !evaluator.sol_coord.empty();
}
Exemple #3
0
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;
}