예제 #1
0
파일: gmprandstate.c 프로젝트: sagmor/gmp
/*
 * call-seq:
 *   GMP::RandState.new()
 *   GMP::RandState.new(:mt) #=> uses gmp_randinit_mt
 *   GMP::RandState.new(:lc_2exp, a, c, m2exp) #=> uses gmp_randinit_lc_2exp
 *   GMP::RandState.new(:lc_2exp_size, size) #=> uses gmp_randinit_lc_2exp_size
 *
 * Initializes a new Random State object. Multiple GMP::RandState objects can
 * be instantiated. They may use different generators and the states
 * are kept separate.
 */
VALUE r_gmprandstatesg_new(int argc, VALUE *argv, VALUE klass)
{
  MP_RANDSTATE *rs_val;
  VALUE rs;
  VALUE algorithm, arg2, arg3, arg4;
  ID algorithm_id = rb_intern("default");
  MP_INT *a_val;
  unsigned long c_val, m2exp_val;
  unsigned long size_val;
  int free_a_val = 0;

  ID default_algorithm      = rb_intern("default");
  ID mt_algorithm           = rb_intern("mt");
  ID lc_2exp_algorithm      = rb_intern("lc_2exp");
  ID lc_2exp_size_algorithm = rb_intern("lc_2exp_size");

  (void)klass;

  mprandstate_make_struct(rs, rs_val);
  rb_scan_args(argc, argv, "04", &algorithm, &arg2, &arg3, &arg4);
  if (NIL_P(algorithm))    { algorithm_id = rb_intern("default"); }  /* default value */
  if (SYMBOL_P(algorithm)) { algorithm_id = rb_to_id(algorithm); }
  if (algorithm_id == default_algorithm ||
      algorithm_id == mt_algorithm) {
    if (argc > 1)
      rb_raise(rb_eArgError, "wrong # of arguments (%d for 0 or 1)", argc);
    gmp_randinit_default(rs_val);
  } else if (algorithm_id == lc_2exp_algorithm) {
    if (argc != 4)
      rb_raise(rb_eArgError, "wrong # of arguments (%d for 4)", argc);
    if (GMPZ_P(arg2)) {
      mpz_get_struct(arg2, a_val);
    } else if (FIXNUM_P(arg2)) {
      mpz_temp_alloc(a_val);
      mpz_init_set_ui(a_val, FIX2INT(arg2));
      free_a_val = 1;
    } else if (BIGNUM_P(arg2)) {
      mpz_temp_from_bignum(a_val, arg2);
      free_a_val = 1;
    } else {
      typeerror_as(ZXB, "b");
    }
    c_val     = NUM2LONG(arg3);
    m2exp_val = NUM2LONG(arg4);
    gmp_randinit_lc_2exp(rs_val, a_val, c_val, m2exp_val);
  } else if (algorithm_id == lc_2exp_size_algorithm) {
    if (argc != 2)
      rb_raise(rb_eArgError, "wrong # of arguments (%d for 2)", argc);
    size_val = NUM2LONG(arg2);
    if (size_val > 128)
      rb_raise(rb_eArgError, "size must be within [0..128]");
    if (gmp_randinit_lc_2exp_size (rs_val, size_val) == 0)
      rb_raise(rb_eArgError, "could not gmp_randinit_lc_2exp_size with %lu", size_val);
  }

  if (free_a_val) { mpz_temp_free(a_val); }
  rb_obj_call_init(rs, argc, argv);

  return rs;
}
예제 #2
0
파일: misc.c 프로젝트: Cl3Kener/gmp
/* Call (*func)() with various random number generators. */
void
call_rand_algs (void (*func) (const char *, gmp_randstate_ptr))
{
  gmp_randstate_t  rstate;
  mpz_t            a;

  mpz_init (a);

  gmp_randinit_default (rstate);
  (*func) ("gmp_randinit_default", rstate);
  gmp_randclear (rstate);

  gmp_randinit_mt (rstate);
  (*func) ("gmp_randinit_mt", rstate);
  gmp_randclear (rstate);

  gmp_randinit_lc_2exp_size (rstate, 8L);
  (*func) ("gmp_randinit_lc_2exp_size 8", rstate);
  gmp_randclear (rstate);

  gmp_randinit_lc_2exp_size (rstate, 16L);
  (*func) ("gmp_randinit_lc_2exp_size 16", rstate);
  gmp_randclear (rstate);

  gmp_randinit_lc_2exp_size (rstate, 128L);
  (*func) ("gmp_randinit_lc_2exp_size 128", rstate);
  gmp_randclear (rstate);

  /* degenerate always zeros */
  mpz_set_ui (a, 0L);
  gmp_randinit_lc_2exp (rstate, a, 0L, 8L);
  (*func) ("gmp_randinit_lc_2exp a=0 c=0 m=8", rstate);
  gmp_randclear (rstate);

  /* degenerate always FFs */
  mpz_set_ui (a, 0L);
  gmp_randinit_lc_2exp (rstate, a, 0xFFL, 8L);
  (*func) ("gmp_randinit_lc_2exp a=0 c=0xFF m=8", rstate);
  gmp_randclear (rstate);

  mpz_clear (a);
}
예제 #3
0
파일: randlc2s.c 프로젝트: mahdiz/mpclib
int
gmp_randinit_lc_2exp_size (gmp_randstate_t rstate, unsigned long size)
{
  const struct __gmp_rand_lc_scheme_struct *sp;
  mpz_t a;

  /* Pick a scheme.  */
  for (sp = __gmp_rand_lc_scheme; sp->m2exp != 0; sp++)
    if (sp->m2exp / 2 >= size)
      goto found;
  return 0;

 found:
  /* Install scheme.  */
  mpz_init_set_str (a, sp->astr, 16);
  gmp_randinit_lc_2exp (rstate, a, sp->c, sp->m2exp);
  mpz_clear (a);
  return 1;
}
예제 #4
0
int
check_params (void)
{
  gmp_randstate_t r1, r2;
  mpz_t a, b, m;
  int i;
  int result;

  result = TRUE;

  mpz_init (a);
  mpz_init (b);
  mpz_init (m);

  if (result)
    {
      /* Test the consistency between urandomm and urandomb. */
      gmp_randinit_default (r1);
      gmp_randinit_default (r2);
      gmp_randseed_ui (r1, 85L);
      gmp_randseed_ui (r2, 85L);
      mpz_set_ui (m, 0L);
      mpz_setbit (m, 80L);
      for (i = 0; i < 100; i++)
	{
	  mpz_urandomm (a, r1, m);
	  mpz_urandomb (b, r2, 80L);
	  if (mpz_cmp (a, b) != 0)
	    {
	      result = FALSE;
	      printf ("mpz_urandomm != mpz_urandomb\n");
	      break;
	    }
	}
      gmp_randclear (r1);
      gmp_randclear (r2);
    }

  if (result)
    {
      /* Test that mpz_urandomm returns the correct result with a
	 broken LC.  */
      mpz_set_ui (a, 0L);
      gmp_randinit_lc_2exp (r1, a, 0xffL, 8L);
      mpz_set_ui (m, 5L);
      /* Warning: This code hangs in gmp 4.1 and below */
      for (i = 0; i < 100; i++)
	{
	  mpz_urandomm (a, r1, m);
	  if (mpz_cmp_ui (a, 2L) != 0)
	    {
	      result = FALSE;
	      gmp_printf ("mpz_urandomm returns %Zd instead of 2\n", a);
	      break;
	    }
	}
      gmp_randclear (r1);
    }

  if (result)
    {
      /* Test that the results are always in range for either
         positive or negative values of m.  */
      gmp_randinit_default (r1);
      mpz_set_ui (m, 5L);
      mpz_set_si (b, -5L);
      for (i = 0; i < 100; i++)
	{
	  mpz_urandomm (a, r1, m);
	  if (mpz_cmp_ui (a, 5L) >= 0 || mpz_sgn (a) < 0)
	    {
	      result = FALSE;
	      gmp_printf ("Out-of-range or non-positive value: %Zd\n", a);
	      break;
	    }
	  mpz_urandomm (a, r1, b);
	  if (mpz_cmp_ui (a, 5L) >= 0 || mpz_sgn (a) < 0)
	    {
	      result = FALSE;
	      gmp_printf ("Out-of-range or non-positive value (from negative modulus): %Zd\n", a);
	      break;
	    }
	}
      gmp_randclear (r1);
    }

  if (result)
    {
      /* Test that m=1 forces always result=0.  */
      gmp_randinit_default (r1);
      mpz_set_ui (m, 1L);
      for (i = 0; i < 100; i++)
	{
	  mpz_urandomm (a, r1, m);
	  if (mpz_sgn (a) != 0)
	    {
	      result = FALSE;
	      gmp_printf ("mpz_urandomm fails with m=1 (result=%Zd)\n", a);
	      break;
	    }
	}
      gmp_randclear (r1);
    }

  mpz_clear (a);
  mpz_clear (b);
  mpz_clear (m);
  return result;
}