Пример #1
0
/*
 ****************************************************************
 *	Imprime uma tabela sobre a biblioteca			*
 ****************************************************************
 */
int
do_table (const char *argv[])
{
	const MOD	*mp;
	const char	*mod_nm;

	/*
	 *	Lê o arquivo de sinopse
	 */
	read_sinop_file (0);

	/*
	 *	Verifica se foram dados nomes de módulos
	 */
	if (*argv == NOSTR)
	{
		for (mp = mod_first; mp != NOMOD; mp = mp->m_next)
			list_mod (mp);
	}
	else	 	/* Lista apenas os modulos dados */
	{
		while ((mod_nm = *argv++) != NOSTR)
		{
			if ((mp = mod_search (mod_nm)) == NOMOD)
				error ("Não encontrei o módulo \"%s\"", mod_nm);
			else
				list_mod (mp);
		}
	}

	vflag = 0;	/* Não escreve a mensagem sobre a sinopse */

	return (0);	/* Não escreve a sinopse */

}	/* end do_table */
Пример #2
0
/* puts in G[0]..G[k-1] the coefficients from (x+a[0])...(x+a[k-1])
   Warning: doesn't fill the coefficient 1 of G[k], which is implicit.
   Needs k + list_mul_mem(k/2) cells in T.
   The product tree is stored in:
   G[0..k-1]       (degree k)
   Tree[0][0..k-1] (degree k/2)
   Tree[1][0..k-1] (degree k/4), ...,
   Tree[lgk-1][0..k-1] (degree 1)
   (then we should have initially Tree[lgk-1] = a).

   The parameter dolvl signals that only level 'dolvl' of
   the tree should be computed (dolvl < 0 means all levels).

   Either Tree <> NULL and TreeFile == NULL, and we write the tree to memory,
   or Tree == NULL and TreeFile <> NULL, and we write the tree to disk.
*/
int
PolyFromRoots_Tree (listz_t G, listz_t a, unsigned int k, listz_t T, 
               int dolvl, mpz_t n, listz_t *Tree, FILE *TreeFile, 
               unsigned int sh)
{
  unsigned int l, m;
  listz_t H1, *NextTree;

  ASSERT (k >= 1);

  if (k == 1)
    {
      /* we consider x + a[0], which mean we consider negated roots */
      mpz_mod (G[0], a[0], n);
      return 0;
    }

  if (Tree == NULL) /* -treefile case */
    {
      H1 = G;
      NextTree = NULL;
    }
  else
    {
      H1 = Tree[0] + sh;
      NextTree = Tree + 1;
    }

  m = k / 2;
  l = k - m;
  
  if (dolvl != 0) /* either dolvl < 0 and we need to compute all levels,
                     or dolvl > 0 and we need first to compute lower levels */
    {
      PolyFromRoots_Tree (H1, a, l, T, dolvl - 1, n, NextTree, TreeFile, sh);
      PolyFromRoots_Tree (H1 + l, a + l, m, T, dolvl - 1, n, NextTree, 
                          TreeFile, sh + l);
    }
  if (dolvl <= 0)
    {
      /* Write this level to disk, if requested */
      if (TreeFile != NULL)
        {
          if (list_out_raw (TreeFile, H1, l) == ECM_ERROR ||
              list_out_raw (TreeFile, H1 + l, m) == ECM_ERROR)
            {
              outputf (OUTPUT_ERROR, "Error writing product tree of F\n");
              return ECM_ERROR;
            }
        }
      list_mul (T, H1, l, 1, H1 + l, m, 1, T + k);
      list_mod (G, T, k, n);
    }
  
  return 0; 
}
Пример #3
0
/*
  Multiplies b[0..k-1] by c[0..k-1], stores the result in a[0..2k-2],
  and stores the reduced product in a2[0..2k-2].
  (Here, there is no implicit monic leading monomial.)
  Requires at least list_mul_mem(k) cells in t.
 */
void
list_mulmod (listz_t a2, listz_t a, listz_t b, listz_t c, unsigned int k,
              listz_t t, mpz_t n)
{
  int i;

  for (i = k; (i & 1) == 0; i >>= 1);
  
  ASSERTD(list_check(b,k,n));
  ASSERTD(list_check(c,k,n));
  if (i == 1 && Fermat)
    F_mul (a, b, c, k, DEFAULT, Fermat, t);
  else
    LIST_MULT_N (a, b, c, k, t); /* set a[0]...a[2l-2] */

  list_mod (a2, a, 2 * k - 1, n);
}
Пример #4
0
/* puts in G[0]..G[k-1] the coefficients from (x+a[0])...(x+a[k-1])
   Warning: doesn't fill the coefficient 1 of G[k], which is implicit.
   Needs k + list_mul_mem(k/2) cells in T.
   G == a is allowed. T must not overlap with anything else.
*/
void
PolyFromRoots (listz_t G, listz_t a, unsigned int k, listz_t T, mpz_t n)
{
  unsigned int l, m;

  ASSERT (T != G && T != a);
  ASSERT (k >= 1);

  if (k == 1)
    {
      /* we consider x + a[0], which mean we consider negated roots */
      mpz_mod (G[0], a[0], n);
      return;
    }

  m = k / 2; /* m >= 1 */
  l = k - m; /* l >= 1 */
  
  PolyFromRoots (G, a, l, T, n);
  PolyFromRoots (G + l, a + l, m, T, n);
  list_mul (T, G, l, 1, G + l, m, 1, T + k);
  list_mod (G, T, k, n);
}
Пример #5
0
/*
  Returns in a[0]+a[1]*x+...+a[K-1]*x^(K-1)
  the remainder of the division of
  A = a[0]+a[1]*x+...+a[2K-2]*x^(2K-2)
  by B = b[0]+b[1]*x+...+b[K-1]*x^(K-1)+b[K]*x^K with b[K]=1 *explicit*.
  (We have A = Q*B + R with deg(Q)=K-2 and deg(R)=K-1.)
  Assumes invb[0]+invb[1]*x+...+invb[K-2]*x^(K-2) equals Quo(x^(2K-2), B).
  Assumes K >= 2.
  Requires 2K-1 + list_mul_mem(K) cells in t.

  Notations: R = r[0..K-1], A = a[0..2K-2], low(A) = a[0..K-1],
  high(A) = a[K..2K-2], Q = t[0..K-2]
  Return non-zero iff an error occurred.
*/
int
PrerevertDivision (listz_t a, listz_t b, listz_t invb,
                   unsigned int K, listz_t t, mpz_t n)
{
  int po2, wrap;
  listz_t t2 = NULL;
#ifdef WRAP
  wrap = ks_wrapmul_m (K + 1, K + 1, n) <= 2 * K - 1 + list_mul_mem (K);
#else
  wrap = 0;
#endif

  /* Q <- high(high(A) * INVB) with a short product */
  for (po2 = K; (po2 & 1) == 0; po2 >>= 1);
  po2 = (po2 == 1);
  if (Fermat && po2)
    {
      mpz_set_ui (a[2 * K - 1], 0);
      if (K <= 4 * Fermat)
        {
          F_mul (t, a + K, invb, K, DEFAULT, Fermat, t + 2 * K);
          /* Put Q in T, as we still need high(A) later on */
          list_mod (t, t + K - 2, K, n);
        }
      else
        {
          F_mul (t, a + K, invb, K, DEFAULT, Fermat, t + 2 * K);
          list_mod (a + K, t + K - 2, K, n);
        }
    }
  else /* non-Fermat case */
    {
      list_mul_high (t, a + K, invb, K - 1, t + 2 * K - 3);
      /* the high part of A * INVB is now in {t+K-2, K-1} */
      if (wrap)
	{
	  MEMORY_TAG;
	  t2 = init_list2 (K - 1, mpz_sizeinbase (n, 2));
	  MEMORY_UNTAG;
	  if (t2 == NULL)
	    {
	      fprintf (ECM_STDERR, "Error, not enough memory\n");
	      return ECM_ERROR;
	    }
	  list_mod (t2, t + K - 2, K - 1, n);
	}
      else /* we can store in high(A) which is no longer needed */
	list_mod (a + K, t + K - 2, K - 1, n);
    }

  /* the quotient Q = trunc(A / B) has degree K-2, i.e. K-1 terms */

  /* T <- low(Q * B) with a short product */
  mpz_set_ui (a[2 * K - 1], 0);
  if (Fermat && po2)
    {
      if (K <= 4 * Fermat)
        {
          /* Multiply without zero padding, result is (mod x^K - 1) */
          F_mul (t + K, t, b, K, NOPAD, Fermat, t + 2 * K);
          /* Take the leading monomial x^K of B into account */
          list_add (t, t + K, t, K);
          /* Subtract high(A) */
          list_sub(t, t, a + K, K);
        }
      else
        F_mul (t, a + K, b, K, DEFAULT, Fermat, t + 2 * K);
    }
  else /* non-Fermat case */
    {
#ifdef KS_MULTIPLY /* ks is faster */
      if (wrap)
        /* Q = {t2, K-1}, B = {b, K+1}
           We know that Q*B vanishes with the coefficients of degree
           K to 2K-2 of {A, 2K-1} */
        {
          unsigned int m;
          m = ks_wrapmul (t, K + 1, b, K + 1, t2, K - 1, n);
          clear_list (t2, K - 1);
          /* coefficients of degree m..2K-2 wrap around,
             i.e. were subtracted to 0..2K-2-m */
          if (m < 2 * K - 1) /* otherwise product is exact */
            list_add (t, t, a + m, 2 * K - 1 - m);
        }
      else
        LIST_MULT_N (t, a + K, b, K, t + 2 * K - 1);
#else
      list_mul_low (t, a + K, b, K, t + 2 * K - 1, n);
#endif
    }

  /* now {t, K} contains the low K terms from Q*B */
  list_sub (a, a, t, K);
  list_mod (a, a, K, n);

  return 0;
}
Пример #6
0
/*
  divides a[0]+a[1]*x+...+a[2K-1]*x^(2K-1)
  By b[0]+b[1]*x+...+b[K-1]*x^(K-1)+x^K
  i.e. a polynomial of 2K coefficients divided by a monic polynomial
  with K+1 coefficients (b[K]=1 is implicit).
  Puts the quotient in q[0]+q[1]*x+...+q[K-1]*x^(K-1)
  and the remainder in a[0]+a[1]*x+...+a[K-1]*x^(K-1)
  Needs space for list_mul_mem(K) coefficients in t.
  If top is non-zero, a[0]..a[K-1] are reduced mod n.
*/
void
RecursiveDivision (listz_t q, listz_t a, listz_t b, unsigned int K,
                   listz_t t, mpz_t n, int top)
{
  if (K == 1) /* a0+a1*x = a1*(b0+x) + a0-a1*b0 */
    {
      mpz_mod (a[1], a[1], n);
      mpz_mul (q[0], a[1], b[0]);
      mpz_mod (q[0], q[0], n);
      mpz_sub (a[0], a[0], q[0]);
      if (top)
        mpz_mod (a[0], a[0], n);
      mpz_set (q[0], a[1]);
    }
  else
    {
      unsigned int k, l, i, po2;

      k = K / 2;
      l = K - k;
      for (po2 = K; (po2 && 1) == 0; po2 >>= 1);
      po2 = (po2 == 1);

      /* first perform a (2l) / l division */
      RecursiveDivision (q + k, a + 2 * k, b + k, l, t, n, 0);
      /* subtract q[k..k+l-1] * b[0..k-1] */
      ASSERTD(list_check(q+l,k,n) && list_check(b,k,n));
      if (po2 && Fermat)
        F_mul (t, q + l, b, k, DEFAULT, Fermat, t + K); /* sets t[0..2*k-2]*/
      else
        LIST_MULT_N (t, q + l, b, k, t + K - 1); /* sets t[0..2*k-2] */
      list_sub (a + l, a + l, t, 2 * k - 1);
      if (k < l) /* don't forget to subtract q[k] * b[0..k-1] */
        {
	  for (i=0; i<k; i++)
	    {
	      mpz_mul (t[0], q[k], b[i]); /* TODO: need to reduce t[0]? */
	      mpz_sub (a[k+i], a[k+i], t[0]);
	    }
        }
      /* remainder is in a[0..K+k-1] */

      /* then perform a (2k) / k division */
      RecursiveDivision (q, a + l, b + l, k, t, n, 0);
      /* subtract q[0..k-1] * b[0..l-1] */
      ASSERTD(list_check(q,k,n) && list_check(b,k,n));
      if (po2 && Fermat)
        F_mul (t, q, b, k, DEFAULT, Fermat, t + K);
      else
        LIST_MULT_N (t, q, b, k, t + K - 1);
      list_sub (a, a, t, 2 * k - 1);
      if (k < l) /* don't forget to subtract q[0..k-1] * b[k] */
        {
          for (i=0; i<k; i++)
            {
              mpz_mul (t[0], q[i], b[k]); /* TODO: need to reduce t[0]? */
              mpz_sub (a[k+i], a[k+i], t[0]);
            }
        }

      /* normalizes the remainder wrt n */
      if (top)
        list_mod (a, a, K, n);
    }
}
Пример #7
0
/* puts in q[0..K-1] the quotient of x^(2K-2) by B
   where B = b[0]+b[1]*x+...+b[K-1]*x^(K-1) with b[K-1]=1.
*/
void
PolyInvert (listz_t q, listz_t b, unsigned int K, listz_t t, mpz_t n)
{
  if (K == 1)
    {
      mpz_set_ui (q[0], 1);
      return;
    }
  else
    {
      int k, l, po2, use_middle_product = 0;

#ifdef KS_MULTIPLY
      use_middle_product = 1;
#endif

      k = K / 2;
      l = K - k;

      for (po2 = K; (po2 & 1) == 0; po2 >>= 1);
      po2 = (po2 == 1 && Fermat != 0);

      /* first determine l most-significant coeffs of Q */
      PolyInvert (q + k, b + k, l, t, n); /* Q1 = {q+k, l} */

      /* now Q1 * B = x^(2K-2) + O(x^(2K-2-l)) = x^(2K-2) + O(x^(K+k-2)).
         We need the coefficients of degree K-1 to K+k-2 of Q1*B */

      ASSERTD(list_check(q+k,l,n) && list_check(b,l,n));
      if (po2 == 0 && use_middle_product)
        {
          TMulKS (t, k - 1, q + k, l - 1, b, K - 1, n, 0);
          list_neg (t, t, k, n);
        }
      else if (po2)
        {
          list_revert (q + k, l);
          /* This expects the leading monomials explicitly in q[2k-1] and b[k+l-1] */
          F_mul_trans (t, q + k, b, K / 2, K, Fermat, t + k);
          list_revert (q + k, l);
          list_neg (t, t, k, n);
        }
      else
        {
          LIST_MULT_N (t, q + k, b, l, t + 2 * l - 1); /* t[0..2l-1] = Q1 * B0 */
          list_neg (t, t + l - 1, k, n);
      
          if (k > 1)
            {
              list_mul (t + k, q + k, l - 1, 1, b + l, k - 1, 1,
			t + k + K - 2); /* Q1 * B1 */
              list_sub (t + 1, t + 1, t + k, k - 1);
            }
        }
      list_mod (t, t, k, n); /* high(1-B*Q1) */

      ASSERTD(list_check(t,k,n) && list_check(q+l,k,n));
      if (po2)
        F_mul (t + k, t, q + l, k, DEFAULT, Fermat, t + 3 * k);
      else
        LIST_MULT_N (t + k, t, q + l, k, t + 3 * k - 1);
      list_mod (q, t + 2 * k - 1, k, n);
    }
}
Пример #8
0
int main(int argc, char **argv)
{
	/* pipe descriptors */
	int pd_rd[2], pd_wr[2];
	pid_t pid;
	char *pppd = STD_PPPD_PATH;
	char *log_path = STD_LOG_PATH;
	char *ip = NULL;
	char *mod_name = NULL;
	int mod_idx;
	int i;
	int need_arg = 0;
	int mod_argc = 0;
	char **mod_argv = NULL;

	prog_name = argv[0];

	/* parsing arguments */
	if (argc < 2)
		help(argv[0]);
	for (i = 1; i < argc; i++) {
		if (need_arg) {
			switch (need_arg) {
			case ARG_MODULE:
				mod_name = argv[i];
				break;
			case ARG_LOG_PATH:
				log_path = argv[i];
				break;
			default:
				fprintf(stderr, "there is internal problem with parsing arguments\n");
				return 1;
			}
			need_arg = 0;
			continue;
		}
		if (argv[i][0] != '-') {
			/* <local_ip>:<remote_ip> */
			ip = argv[i];
			continue;
		}
		if (!strcmp("-h", argv[i]) || !strcmp("--help", argv[i]))
			/* print help and exit */
			help(argv[0]);
		if (!strcmp("-l", argv[i]) || !strcmp("--list", argv[i]))
			/* print list of available modules and exit */
			list_mod();
		if (!strcmp("-L", argv[i])) {
			/* specify file for logging */
			need_arg = ARG_LOG_PATH;
			continue;
		}
		if (!strcmp("-m", argv[i])) {
			/* choose module */
			need_arg = ARG_MODULE;
			continue;
		}
		if (!strcmp("-q", argv[i]) || !strcmp("--quiet", argv[i])) {
			/* quiet mode */
			quiet = 1;
			continue;
		}
		if (!strcmp("--", argv[i])) {
			/* TODO: set pointer to i+1, the rest options are for pppd */
			mod_argv = argv + i;
			mod_argc = argc - i;
			break;
		}
		/* unrecognized options may be addressed for the module */
	}
	if (need_arg) {
		fprintf(stderr, "incomplete arguments, see %s --help\n", argv[0]);
		return 2;
	}
	/* check whether required arguments are set */
	if (!mod_name) {
		fprintf(stderr, "you must choose a module, see %s --help\n", argv[0]);
		return 2;
	}

	/* redirect logs to a file */
	redirect_logs(log_path);

	/* check whether module name is correct */
	if ((mod_idx = is_mod(mod_name)) < 0) {
		fprintf(stderr, "there isn't such a module: %s\n", mod_name);
		return 2;
	}

	/* create pipes for communication with pppd */
	if (pipe(pd_rd) < 0)
		err_exit("pipe");
	if (pipe(pd_wr) < 0)
		err_exit("pipe");

	/* exec pppd */
	if ((pid = fork()) < 0)
		err_exit("fork");
	if (!pid) {
		if (dup2(pd_rd[1], 1) < 0)
			err_exit("dup2");
		if (dup2(pd_wr[0], 0) < 0)
			err_exit("dup2");
		close(pd_rd[0]);
		close(pd_rd[1]);
		close(pd_wr[0]);
		close(pd_wr[1]);
		execl(pppd, pppd, "nodetach", "noauth", "notty", "passive", ip, NULL);
		err_exit("execl");
	}

	close(pd_rd[1]);
	close(pd_wr[0]);

	/* run appropriate module's function */
	return mod_tbl[mod_idx].func(mod_argc, mod_argv, pd_rd[0], pd_wr[1]);
}