Пример #1
0
void
mpi_set_highbit( MPI a, unsigned n )
{
    /* This seems whacky, but what do I know. */
    mpz_fdiv_r_2exp(a, a, n+1);
    mpz_setbit(a, n);
}
Пример #2
0
static PyObject *
GMPy_MPZ_f_mod_2exp(PyObject *self, PyObject *args)
{
    mp_bitcnt_t nbits;
    MPZ_Object *result, *tempx;

    if (PyTuple_GET_SIZE(args) != 2) {
        TYPE_ERROR("f_mod_2exp() requires 'mpz','int' arguments");
        return NULL;
    }

    nbits = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1));
    if (nbits == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
        return NULL;
    }

    tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL);
    result = GMPy_MPZ_New(NULL);
    if (!tempx || !result) {
        Py_XDECREF((PyObject*)result);
        Py_XDECREF((PyObject*)tempx);
        return NULL;
    }

    mpz_fdiv_r_2exp(result->z, tempx->z, nbits);
    Py_DECREF((PyObject*)tempx);
    return (PyObject*)result;
}
Пример #3
0
void
gmp_randseed (gmp_randstate_t rstate,
	      mpz_srcptr seed)
{
  mpz_fdiv_r_2exp (rstate->_mp_seed, seed,
                   rstate->_mp_algdata._mp_lc->_mp_m2exp);

}
Пример #4
0
static void
randseed_lc (gmp_randstate_t rstate, mpz_srcptr seed)
{
  gmp_rand_lc_struct *p = (gmp_rand_lc_struct *) RNG_STATE (rstate);
  mpz_ptr seedz = p->_mp_seed;
  mp_size_t seedn = BITS_TO_LIMBS (p->_mp_m2exp);

  /* Store p->_mp_seed as an unnormalized integer with size enough
     for numbers up to 2^m2exp-1.  That size can't be zero.  */
  mpz_fdiv_r_2exp (seedz, seed, p->_mp_m2exp);
  MPN_ZERO (&PTR (seedz)[SIZ (seedz)], seedn - SIZ (seedz));
  SIZ (seedz) = seedn;
}
Пример #5
0
static void
hash(mpz_t x, uint8_t *digest)
{
  mpz_t t;
  uint8_t data[SEED_LENGTH];
  struct sha1_ctx ctx;
  
  mpz_init_set(t, x);
  mpz_fdiv_r_2exp(t, t, SEED_BITS);
  
  nettle_mpz_get_str_256(SEED_LENGTH, data, t);
  mpz_clear(t);

  sha1_init(&ctx);
  sha1_update(&ctx, SEED_LENGTH, data);
  sha1_digest(&ctx, SHA1_DIGEST_SIZE, digest);
}
Пример #6
0
void
gmp_randinit_lc_2exp (gmp_randstate_t rstate,
		      mpz_srcptr a,
		      unsigned long int c,
		      mp_bitcnt_t m2exp)
{
  gmp_rand_lc_struct *p;
  mp_size_t seedn = BITS_TO_LIMBS (m2exp);

  ASSERT_ALWAYS (m2exp != 0);

  p = __GMP_ALLOCATE_FUNC_TYPE (1, gmp_rand_lc_struct);
  RNG_STATE (rstate) = (void *) p;
  RNG_FNPTR (rstate) = (void *) &Linear_Congruential_Generator;

  /* allocate m2exp bits of space for p->_mp_seed, and initial seed "1" */
  mpz_init2 (p->_mp_seed, m2exp);
  MPN_ZERO (PTR (p->_mp_seed), seedn);
  SIZ (p->_mp_seed) = seedn;
  PTR (p->_mp_seed)[0] = 1;

  /* "a", forced to 0 to 2^m2exp-1 */
  mpz_init (p->_mp_a);
  mpz_fdiv_r_2exp (p->_mp_a, a, m2exp);

  /* Avoid SIZ(a) == 0 to avoid checking for special case in lc().  */
  if (SIZ (p->_mp_a) == 0)
    {
      SIZ (p->_mp_a) = 1;
      PTR (p->_mp_a)[0] = CNST_LIMB (0);
    }

  MPN_SET_UI (p->_cp, p->_cn, c);

  /* Internally we may discard any bits of c above m2exp.  The following
     code ensures that __GMPN_ADD in lc() will always work.  */
  if (seedn < p->_cn)
    p->_cn = (p->_cp[0] != 0);

  p->_mp_m2exp = m2exp;
}
Пример #7
0
ecl_int64_t
ecl_to_int64_t(cl_object x) {
	if (ECL_FIXNUMP(x)) {
		return (ecl_int64_t)ecl_fixnum(x);
	} else if (!ECL_BIGNUMP(x)) {
		(void)0;
	} else if (mpz_fits_slong_p(x->big.big_num)) {
		return (ecl_int64_t)mpz_get_si(x->big.big_num);
	} else {
		cl_object copy = _ecl_big_register0();
		mpz_fdiv_q_2exp(copy->big.big_num, x->big.big_num, 32);
		if (mpz_fits_slong_p(copy->big.big_num)) {
			ecl_int64_t output;
			output = (ecl_int64_t)mpz_get_si(copy->big.big_num);
			mpz_fdiv_r_2exp(copy->big.big_num, x->big.big_num, 32);
			return (output << 32) + mpz_get_ui(copy->big.big_num);
		}
	}
	FEwrong_type_argument(cl_list(3,ECL_SYM("INTEGER",437),
				      ecl_negate(ecl_ash(ecl_make_fixnum(1), 63)),
				      ecl_one_minus(ecl_ash(ecl_make_fixnum(1), 63))),
			      x);
}
Пример #8
0
void
hex_random_bit_op (enum hex_random_op op, unsigned long maxbits,
		   char **ap, unsigned long *b, char **rp)
{
  mpz_t a, r;
  unsigned long abits, bbits;
  unsigned signs;

  mpz_init (a);
  mpz_init (r);

  abits = gmp_urandomb_ui (state, 32) % maxbits;
  bbits = gmp_urandomb_ui (state, 32) % (maxbits + 100);

  mpz_rrandomb (a, state, abits);

  signs = gmp_urandomb_ui (state, 1);
  if (signs & 1)
    mpz_neg (a, a);

  switch (op)
    {
    default:
      abort ();

    case OP_SETBIT:
      mpz_set (r, a);
      mpz_setbit (r, bbits);
      break;
    case OP_CLRBIT:
      mpz_set (r, a);
      mpz_clrbit (r, bbits);
      break;
    case OP_COMBIT:
      mpz_set (r, a);
      mpz_combit (r, bbits);
      break;
    case OP_CDIV_Q_2:
      mpz_cdiv_q_2exp (r, a, bbits);
      break;
    case OP_CDIV_R_2:
      mpz_cdiv_r_2exp (r, a, bbits);
      break;
    case OP_FDIV_Q_2:
      mpz_fdiv_q_2exp (r, a, bbits);
      break;
    case OP_FDIV_R_2:
      mpz_fdiv_r_2exp (r, a, bbits);
      break;
    case OP_TDIV_Q_2:
      mpz_tdiv_q_2exp (r, a, bbits);
      break;
    case OP_TDIV_R_2:
      mpz_tdiv_r_2exp (r, a, bbits);
      break;
    }

  gmp_asprintf (ap, "%Zx", a);
  *b = bbits;
  gmp_asprintf (rp, "%Zx", r);

  mpz_clear (a);
  mpz_clear (r);
}
Пример #9
0
int main() {
  int32_t i, j, n;

  alloc_constants();

  printf("a = ");
  bvconst_print(stdout, a, 128);
  printf("\n");
  printf("iszero(a) = %d\n", bvconst_is_zero(a, 4));

  bvconst_add_one(a, 4);
  printf("a+1 = ");
  bvconst_print(stdout, a, 128);
  printf("\n");
  printf("iszero(a+1) = %d\n", bvconst_is_zero(a, 4));

  bvconst_sub_one(a, 4);
  printf("a+1-1 = ");
  bvconst_print(stdout, a, 128);
  printf("\n");
  printf("iszero(a+1-1) = %d\n", bvconst_is_zero(a, 4));

  bvconst_sub_one(a, 4);
  printf("a+1-2 = ");
  bvconst_print(stdout, a, 128);
  printf("\n");
  printf("iszero(a+1-2) = %d\n", bvconst_is_zero(a, 4));


  printf("b = ");
  bvconst_print(stdout, b, 128);
  printf("\n");
  printf("iszero(b) = %d\n", bvconst_is_zero(b, 4));

  bvconst_add_one(b, 4);
  printf("b+1 = ");
  bvconst_print(stdout, b, 128);
  printf("\n");
  printf("iszero(b+1) = %d\n", bvconst_is_zero(b, 4));

  bvconst_sub_one(b, 4);
  bvconst_sub_one(b, 4);
  printf("b-1 = ");
  bvconst_print(stdout, b, 128);
  printf("\n");
  printf("iszero(b-1) = %d\n", bvconst_is_zero(b, 4));


  printf("c = ");
  bvconst_print(stdout, c, 128);
  printf("\n");
  printf("iszero(c) = %d\n", bvconst_is_zero(c, 4));

  printf("d = ");
  bvconst_print(stdout, d, 128);
  printf("\n");
  printf("iszero(d) = %d\n", bvconst_is_zero(d, 4));

  printf("e = ");
  bvconst_print(stdout, e, 128);
  printf("\n");
  printf("iszero(e) = %d\n", bvconst_is_zero(e, 4));

  printf("e := a * b\n");
  bvconst_mul2(e, 4, a, b);
  printf("e = ");
  bvconst_print(stdout, e, 128);
  printf("\n\n");

  random_vector(vector, 32);
  bvconst_set_array(a, vector, 32);
  printf("a            = ");
  bvconst_print(stdout, a, 32);
  printf("\n");
  random_vector(vector, 73);
  bvconst_set_array(b, vector, 73);
  printf("b            = ");
  bvconst_print(stdout, b, 73);
  printf("\n");
  bvconst_concat(c, a, 32, b, 73);
  printf("conc(a, b)   = ");
  bvconst_print(stdout, c, 105);
  printf("\n");
  bvconst_concat(d, b, 73, a, 32);
  printf("conc(b, a)   = ");
  bvconst_print(stdout, d, 105);
  printf("\n\n");

  //  random_vector(vector, 63);
  bvconst_set_minus_one(a, 4);
  //  random_vector(vector, 63);
  bvconst_clear(b, 4);
  for (n=2; n<=128; n++) {
    for (i=1; i<n; i++) {
      printf("--- n = %"PRId32", i = %"PRId32" ---\n", n, i);
      printf("a          = ");
      bvconst_print(stdout, a, i);
      printf("\n");
      printf("b          = ");
      bvconst_print(stdout, b, n - i);
      printf("\n");
      bvconst_concat(c, a, i, b, n - i);
      bvconst_concat(d, b, n - i, a, i);
      printf("conc(a, b) = ");
      bvconst_print(stdout, c, n);
      printf("\n");
      printf("conc(b, a) = ");
      bvconst_print(stdout, d, n);
      printf("\n\n");
    }
  }


  //  exit(0);

  for (n=20; n>0; n--) {
    random_vector(vector, 20);
    bvconst_set_array(a, vector, 20);
    printf("a             = ");
    bvconst_print(stdout, a, 20);
    printf("\n");

    for (i=0; i<=20-n; i++) {
      bvconst_extract(b, a, i, i+n);
      printf("a[%2"PRId32", %2"PRId32")     = ", i, i+n);
      bvconst_print(stdout, b, n);
      printf("\n");
    }
    printf("\n");
  }


  for (n=50; n>20; n--) {
    random_vector(vector, 62);
    bvconst_set_array(a, vector, 62);
    printf("a             = ");
    bvconst_print(stdout, a, 62);
    printf("\n");

    for (i=0; i<=62-n; i++) {
      bvconst_extract(b, a, i, i+n);
      printf("a[%2"PRId32", %2"PRId32")     = ", i, i+n);
      bvconst_print(stdout, b, n);
      printf("\n");
    }
    printf("\n");
  }

  random_vector(vector, 20);
  bvconst_set_array(a, vector, 20);
  printf("a             = ");
  bvconst_print(stdout, a, 20);
  printf("\n");
  bvconst_set_extend(b, 31, a, 20, 0);
  printf("ext(a, 31, 0) = ");
  bvconst_print(stdout, b, 31);
  printf("\n");
  bvconst_set_extend(b, 31, a, 20, 1);
  printf("ext(a, 31, 1) = ");
  bvconst_print(stdout, b, 31);
  printf("\n");
  bvconst_set_extend(b, 31, a, 20, -1);
  printf("sgnext(a, 31) = ");
  bvconst_print(stdout, b, 31);
  printf("\n\n");


  random_vector(vector, 20);
  bvconst_set_array(a, vector, 20);
  printf("a             = ");
  bvconst_print(stdout, a, 20);
  printf("\n");
  bvconst_set_extend(b, 31, a, 20, 0);
  printf("ext(a, 31, 0) = ");
  bvconst_print(stdout, b, 31);
  printf("\n");
  bvconst_set_extend(b, 31, a, 20, 1);
  printf("ext(a, 31, 1) = ");
  bvconst_print(stdout, b, 31);
  printf("\n");
  bvconst_set_extend(b, 31, a, 20, -1);
  printf("sgnext(a, 31) = ");
  bvconst_print(stdout, b, 31);
  printf("\n\n");


  random_vector(vector, 20);
  bvconst_set_array(a, vector, 20);
  printf("a             = ");
  bvconst_print(stdout, a, 20);
  printf("\n");
  bvconst_set_extend(b, 31, a, 20, 0);
  printf("ext(a, 31, 0) = ");
  bvconst_print(stdout, b, 31);
  printf("\n");
  bvconst_set_extend(b, 31, a, 20, 1);
  printf("ext(a, 31, 1) = ");
  bvconst_print(stdout, b, 31);
  printf("\n");
  bvconst_set_extend(b, 31, a, 20, -1);
  printf("sgnext(a, 31) = ");
  bvconst_print(stdout, b, 31);
  printf("\n\n");


  random_vector(vector, 20);
  bvconst_set_array(a, vector, 20);
  printf("a             = ");
  bvconst_print(stdout, a, 20);
  printf("\n");
  bvconst_set_extend(b, 31, a, 20, 0);
  printf("ext(a, 31, 0) = ");
  bvconst_print(stdout, b, 31);
  printf("\n");
  bvconst_set_extend(b, 31, a, 20, 1);
  printf("ext(a, 31, 1) = ");
  bvconst_print(stdout, b, 31);
  printf("\n");
  bvconst_set_extend(b, 31, a, 20, -1);
  printf("sgnext(a, 31) = ");
  bvconst_print(stdout, b, 31);
  printf("\n\n");


  for (i=20; i<=99; i++) {
    random_vector(vector, 20);
    bvconst_set_array(a, vector, 20);
    printf("a             = ");
    bvconst_print(stdout, a, 20);
    printf("\n");
    bvconst_set_extend(b, i, a, 20, 0);
    printf("ext(a, %2"PRId32", 0) = ", i);
    bvconst_print(stdout, b, i);
    printf("\n");
    bvconst_set_extend(b, i, a, 20, 1);
    printf("ext(a, %2"PRId32", 1) = ", i);
    bvconst_print(stdout, b, i);
    printf("\n");
    bvconst_set_extend(b, i, a, 20, -1);
    printf("sgnext(a, %2"PRId32") = ", i);
    bvconst_print(stdout, b, i);
    printf("\n\n");
  }


  for (i=32; i<=99; i++) {
    random_vector(vector, 32);
    bvconst_set_array(a, vector, 32);
    printf("a             = ");
    bvconst_print(stdout, a, 32);
    printf("\n");
    bvconst_set_extend(b, i, a, 32, 0);
    printf("ext(a, %2"PRId32", 0) = ", i);
    bvconst_print(stdout, b, i);
    printf("\n");
    bvconst_set_extend(b, i, a, 32, 1);
    printf("ext(a, %2"PRId32", 1) = ", i);
    bvconst_print(stdout, b, i);
    printf("\n");
    bvconst_set_extend(b, i, a, 32, -1);
    printf("sgnext(a, %2"PRId32") = ", i);
    bvconst_print(stdout, b, i);
    printf("\n\n");
  }


  random_vector(vector, 120);
  bvconst_set_array(a, vector, 120);
  printf("a         = ");
  bvconst_print(stdout, a, 120);
  printf("\n");
  for (i=0; i<=120; i++) {
    printf("rshift %3"PRId32": ", i);
    bvconst_shift_right(a, 120, i, 0);
    bvconst_print(stdout, a, 120);
    printf("\n");
    bvconst_set_array(a, vector, 120);
  }
  printf("\n");

  random_vector(vector, 120);
  bvconst_set_array(a, vector, 120);
  printf("a         = ");
  bvconst_print(stdout, a, 120);
  printf("\n");
  for (i=0; i<=120; i++) {
    printf("rshift %3"PRId32": ", i);
    bvconst_shift_right(a, 120, i, 1);
    bvconst_print(stdout, a, 120);
    printf("\n");
    bvconst_set_array(a, vector, 120);
  }
  printf("\n");


  random_vector(vector, 120);
  bvconst_set_array(a, vector, 120);
  printf("a         = ");
  bvconst_print(stdout, a, 120);
  printf("\n");
  for (i=0; i<=120; i++) {
    printf("lshift %3"PRId32": ", i);
    bvconst_shift_left(a, 120, i, 0);
    bvconst_print(stdout, a, 120);
    printf("\n");
    bvconst_set_array(a, vector, 120);
  }
  printf("\n");

  random_vector(vector, 120);
  bvconst_set_array(a, vector, 120);
  printf("a         = ");
  bvconst_print(stdout, a, 120);
  printf("\n");
  for (i=0; i<=120; i++) {
    printf("lshift %3"PRId32": ", i);
    bvconst_shift_left(a, 120, i, 1);
    bvconst_print(stdout, a, 120);
    printf("\n");
    bvconst_set_array(a, vector, 120);
  }
  printf("\n");
  //  exit(0);


  printf("c = ");
  bvconst_print(stdout, c, 128);
  printf("\n");
  printf("d = ");
  bvconst_print(stdout, d, 128);
  printf("\n");
  printf("e := c * d\n");
  bvconst_mul2(e, 4, c, d);
  printf("e = ");
  bvconst_print(stdout, e, 128);
  printf("\n");
  printf("e := d * c\n");
  bvconst_mul2(e, 4, d, c);
  printf("e = ");
  bvconst_print(stdout, e, 128);
  printf("\n\n");

  printf("b = ");
  bvconst_print(stdout, b, 128);
  printf("\n");
  printf("d = ");
  bvconst_print(stdout, d, 128);
  printf("\n");
  printf("e := b * d\n");
  bvconst_mul2(e, 4, b, d);
  printf("e = ");
  bvconst_print(stdout, e, 128);
  printf("\n\n");



  bvconst_set64(a, 4, 1372919719782793ULL);
  bvconst_set32(b, 4, 12670371);
  printf("a = ");
  bvconst_print(stdout, a, 128);
  printf("\n");
  printf("b = ");
  bvconst_print(stdout, b, 128);
  printf("\n");
  printf("e := a * b\n");
  bvconst_set(c, 4, a);
  printf("c = ");
  bvconst_print(stdout, c, 128);
  printf("\n");
  bvconst_mul(c, 4, b);
  printf("c = ");
  bvconst_print(stdout, c, 128);
  printf("\n");
  bvconst_mul2(e, 4, a, b);
  printf("e = ");
  bvconst_print(stdout, e, 128);
  printf("\n\n");

  mpz_init(z0);
  mpz_init(z1);
  mpz_init(z2);

  bvconst_get_mpz(a, 4, z0);
  printf("--> conversion a to mpz: ");
  mpz_out_str(stdout, 10, z0);
  printf("\n");
  bvconst_get_mpz(b, 4, z0);
  printf("--> conversion b to mpz: ");
  mpz_out_str(stdout, 10, z0);
  printf("\n");
  bvconst_get_mpz(e, 4, z0);
  printf("--> conversion e to mpz: ");
  mpz_out_str(stdout, 10, z0);
  printf("\n\n");

  printf("e -= a * b\n");
  bvconst_submul(e, 4, a, b);
  printf("e = ");
  bvconst_print(stdout, e, 128);
  printf("\n");
  bvconst_get_mpz(e, 4, z0);
  printf("--> conversion e to mpz: ");
  mpz_out_str(stdout, 10, z0);
  printf("\n\n");

  for (i=0; i<10; i++) {
    printf("test %"PRId32": e *= a\n", i);
    random_vector(vector, 128);
    bvconst_set_array(a, vector, 128);
    random_vector(vector, 128);
    bvconst_set_array(e, vector, 128);
    bvconst_get_mpz(e, 4, z1);

    printf("a  = ");
    bvconst_print(stdout, a, 128);
    printf("\n");
    printf("e  = ");
    bvconst_print(stdout, e, 128);
    printf("\n");
    bvconst_mul(e, 4, a);
    printf("e' = ");
    bvconst_print(stdout, e, 128);
    printf("\n");

    bvconst_get_mpz(a, 4, z0);
    printf("--> conversion a  to mpz: ");
    mpz_out_str(stdout, 10, z0);
    printf("\n");
    printf("--> conversion e  to mpz: ");
    mpz_out_str(stdout, 10, z1);
    printf("\n");
    bvconst_get_mpz(e, 4, z2);
    printf("--> conversion e' to mpz: ");
    mpz_out_str(stdout, 10, z2);
    printf("\n");

    mpz_mul(z0, z0, z1);
    mpz_fdiv_r_2exp(z0, z0, 128);
    printf("--> check:                ");
    mpz_out_str(stdout, 10, z0);
    printf("\n\n");
    assert(mpz_cmp(z0, z2) == 0);
  }

  for (i=0; i<10; i++) {
    printf("test %"PRId32", a := - a\n", i);
    random_vector(vector, 128);
    bvconst_set_array(a, vector, 128);
    bvconst_get_mpz(a, 4, z0);

    printf("a = ");
    bvconst_print(stdout, a, 128);
    printf("\n");
    bvconst_negate(a, 4);
    printf("a = ");
    bvconst_print(stdout, a, 128);
    printf("\n");

    printf("--> conversion  a to mpz: ");
    mpz_out_str(stdout, 10, z0);
    printf("\n");
    bvconst_get_mpz(a, 4, z1);
    printf("--> conversion -a to mpz: ");
    mpz_out_str(stdout, 10, z1);
    printf("\n");

    mpz_neg(z0, z0);
    mpz_fdiv_r_2exp(z0, z0, 128);
    printf("--> check:                ");
    mpz_out_str(stdout, 10, z0);
    printf("\n\n");
    assert(mpz_cmp(z0, z1) == 0);
  }

  for (i=0; i<10; i++) {
    printf("test %"PRId32": e := - a\n", i);
    random_vector(vector, 128);
    bvconst_set_array(a, vector, 128);
    printf("a = ");
    bvconst_print(stdout, a, 128);
    printf("\n");
    bvconst_negate2(e, 4, a);
    printf("e = ");
    bvconst_print(stdout, e, 128);
    printf("\n");

    printf("--> conversion a to mpz: ");
    bvconst_get_mpz(a, 4, z0);
    mpz_out_str(stdout, 10, z0);
    printf("\n");
    bvconst_get_mpz(e, 4, z1);
    printf("--> conversion e to mpz: ");
    mpz_out_str(stdout, 10, z1);
    printf("\n");

    mpz_neg(z0, z0);
    mpz_fdiv_r_2exp(z0, z0, 128);
    printf("--> check:               ");
    mpz_out_str(stdout, 10, z0);
    printf("\n\n");
    assert(mpz_cmp(z0, z1) == 0);
  }

  for (i=0; i<10; i++) {
    printf("test %"PRId32", e = a * b\n", i);
    random_vector(vector, 128);
    bvconst_set_array(a, vector, 128);
    random_vector(vector, 128);
    bvconst_set_array(b, vector, 128);

    printf("a = ");
    bvconst_print(stdout, a, 128);
    printf("\n");
    printf("b = ");
    bvconst_print(stdout, b, 128);
    printf("\n");
    bvconst_mul2(e, 4, a, b);
    printf("e = ");
    bvconst_print(stdout, e, 128);
    printf("\n");

    bvconst_get_mpz(a, 4, z0);
    printf("--> conversion a to mpz: ");
    mpz_out_str(stdout, 10, z0);
    printf("\n");
    bvconst_get_mpz(b, 4, z1);
    printf("--> conversion b to mpz: ");
    mpz_out_str(stdout, 10, z1);
    printf("\n");
    bvconst_get_mpz(e, 4, z2);
    printf("--> conversion e to mpz: ");
    mpz_out_str(stdout, 10, z2);
    printf("\n");

    mpz_mul(z0, z0, z1);
    mpz_fdiv_r_2exp(z0, z0, 128);
    printf("--> check:               ");
    mpz_out_str(stdout, 10, z0);
    printf("\n\n");
    assert(mpz_cmp(z0, z2) == 0);
  }

  for (i=0; i<10; i++) {
    printf("test %"PRId32": e = - (a * b)\n", i);
    random_vector(vector, 128);
    bvconst_set_array(a, vector, 128);
    random_vector(vector, 128);
    bvconst_set_array(b, vector, 128);

    printf("a = ");
    bvconst_print(stdout, a, 128);
    printf("\n");
    printf("b = ");
    bvconst_print(stdout, b, 128);
    printf("\n");
    bvconst_clear(e, 4);
    bvconst_submul(e, 4, a, b);
    printf("e = ");
    bvconst_print(stdout, e, 128);
    printf("\n");

    bvconst_get_mpz(a, 4, z0);
    printf("--> conversion a to mpz: ");
    mpz_out_str(stdout, 10, z0);
    printf("\n");
    bvconst_get_mpz(b, 4, z1);
    printf("--> conversion b to mpz: ");
    mpz_out_str(stdout, 10, z1);
    printf("\n");
    bvconst_get_mpz(d, 4, z2);
    printf("--> conversion d to mpz: ");
    mpz_out_str(stdout, 10, z2);
    printf("\n");
    bvconst_get_mpz(e, 4, z2);
    printf("--> conversion e to mpz: ");
    mpz_out_str(stdout, 10, z2);
    printf("\n");

    mpz_mul(z0, z0, z1);
    mpz_neg(z0, z0);
    mpz_fdiv_r_2exp(z0, z0, 128);
    printf("--> check:               ");
    mpz_out_str(stdout, 10, z0);
    printf("\n\n");
    assert(mpz_cmp(z0, z2) == 0);
  }

  for (i=0; i<10; i++) {
    printf("test %"PRId32": e = a + b\n", i);
    random_vector(vector, 128);
    bvconst_set_array(a, vector, 128);
    random_vector(vector, 128);
    bvconst_set_array(b, vector, 128);

    printf("a = ");
    bvconst_print(stdout, a, 128);
    printf("\n");
    printf("b = ");
    bvconst_print(stdout, b, 128);
    printf("\n");
    bvconst_add2(e, 4, a, b);
    printf("e = ");
    bvconst_print(stdout, e, 128);
    printf("\n");

    bvconst_get_mpz(a, 4, z0);
    printf("--> conversion a to mpz: ");
    mpz_out_str(stdout, 10, z0);
    printf("\n");
    bvconst_get_mpz(b, 4, z1);
    printf("--> conversion b to mpz: ");
    mpz_out_str(stdout, 10, z1);
    printf("\n");
    bvconst_get_mpz(e, 4, z2);
    printf("--> conversion e to mpz: ");
    mpz_out_str(stdout, 10, z2);
    printf("\n");

    mpz_add(z0, z0, z1);
    mpz_fdiv_r_2exp(z0, z0, 128);
    printf("--> check:               ");
    mpz_out_str(stdout, 10, z0);
    printf("\n\n");
    assert(mpz_cmp(z0, z2) == 0);
  }

  for (i=0; i<10; i++) {
    printf("test %"PRId32": e = a - b\n", i);
    random_vector(vector, 128);
    bvconst_set_array(a, vector, 128);
    random_vector(vector, 128);
    bvconst_set_array(b, vector, 128);

    printf("a = ");
    bvconst_print(stdout, a, 128);
    printf("\n");
    printf("b = ");
    bvconst_print(stdout, b, 128);
    printf("\n");
    bvconst_sub2(e, 4, a, b);
    printf("e = ");
    bvconst_print(stdout, e, 128);
    printf("\n");

    bvconst_get_mpz(a, 4, z0);
    printf("--> conversion a to mpz: ");
    mpz_out_str(stdout, 10, z0);
    printf("\n");
    bvconst_get_mpz(b, 4, z1);
    printf("--> conversion b to mpz: ");
    mpz_out_str(stdout, 10, z1);
    printf("\n");
    bvconst_get_mpz(e, 4, z2);
    printf("--> conversion e to mpz: ");
    mpz_out_str(stdout, 10, z2);
    printf("\n");

    mpz_sub(z0, z0, z1);
    mpz_fdiv_r_2exp(z0, z0, 128);
    printf("--> check:               ");
    mpz_out_str(stdout, 10, z0);
    printf("\n\n");
    assert(mpz_cmp(z0, z2) == 0);
  }

  for (i=0; i<10; i++) {
    printf("\ntest %"PRId32": comparisons\n", i);
    random_vector(vector, 25);
    bvconst_set_array(a, vector, 25);
    random_vector(vector, 25);
    bvconst_set_array(b, vector, 25);

    printf("a = ");
    bvconst_print(stdout, a, 25);
    printf("\n");
    printf("b = ");
    bvconst_print(stdout, b, 25);
    printf("\n");

    bvconst_normalize(a, 25);
    bvconst_normalize(b, 25);
    printf("Unsigned tests\n");
    printf(" a le b: %d\n", bvconst_le(a, b, 25));
    printf(" a ge b: %d\n", bvconst_ge(a, b, 25));
    printf(" a lt b: %d\n", bvconst_lt(a, b, 25));
    printf(" a gt b: %d\n", bvconst_gt(a, b, 25));

    printf("Signed tests\n");
    printf(" a sle b: %d\n", bvconst_sle(a, b, 25));
    printf(" a sge b: %d\n", bvconst_sge(a, b, 25));
    printf(" a slt b: %d\n", bvconst_slt(a, b, 25));
    printf(" a sgt b: %d\n", bvconst_sgt(a, b, 25));
  }


  for (i=0; i<10; i++) {
    printf("\ntest %"PRId32": comparisons\n", i);
    random_vector(vector, 32);
    bvconst_set_array(a, vector, 32);
    random_vector(vector, 32);
    bvconst_set_array(b, vector, 32);

    printf("a = ");
    bvconst_print(stdout, a, 32);
    printf("\n");
    printf("b = ");
    bvconst_print(stdout, b, 32);
    printf("\n");

    bvconst_normalize(a, 32);
    bvconst_normalize(b, 32);
    printf("Unsigned tests\n");
    printf(" a le b: %d\n", bvconst_le(a, b, 32));
    printf(" a ge b: %d\n", bvconst_ge(a, b, 32));
    printf(" a lt b: %d\n", bvconst_lt(a, b, 32));
    printf(" a gt b: %d\n", bvconst_gt(a, b, 32));

    printf("Signed tests\n");
    printf(" a sle b: %d\n", bvconst_sle(a, b, 32));
    printf(" a sge b: %d\n", bvconst_sge(a, b, 32));
    printf(" a slt b: %d\n", bvconst_slt(a, b, 32));
    printf(" a sgt b: %d\n", bvconst_sgt(a, b, 32));
  }

  for (i=0; i<10; i++) {
    printf("\ntest %"PRId32": comparisons\n", i);
    random_vector(vector, 33);
    bvconst_set_array(a, vector, 33);
    random_vector(vector, 33);
    bvconst_set_array(b, vector, 33);

    printf("a = ");
    bvconst_print(stdout, a, 33);
    printf("\n");
    printf("b = ");
    bvconst_print(stdout, b, 33);
    printf("\n");

    bvconst_normalize(a, 33);
    bvconst_normalize(b, 33);
    printf("Unsigned tests\n");
    printf(" a le b: %d\n", bvconst_le(a, b, 33));
    printf(" a ge b: %d\n", bvconst_ge(a, b, 33));
    printf(" a lt b: %d\n", bvconst_lt(a, b, 33));
    printf(" a gt b: %d\n", bvconst_gt(a, b, 33));

    printf("Signed tests\n");
    printf(" a sle b: %d\n", bvconst_sle(a, b, 33));
    printf(" a sge b: %d\n", bvconst_sge(a, b, 33));
    printf(" a slt b: %d\n", bvconst_slt(a, b, 33));
    printf(" a sgt b: %d\n", bvconst_sgt(a, b, 33));
  }

  for (i=0; i<10; i++) {
    printf("\ntest %"PRId32": comparisons\n", i);
    random_vector(vector, 63);
    bvconst_set_array(a, vector, 63);
    random_vector(vector, 63);
    bvconst_set_array(b, vector, 63);

    printf("a = ");
    bvconst_print(stdout, a, 63);
    printf("\n");
    printf("b = ");
    bvconst_print(stdout, b, 63);
    printf("\n");

    bvconst_normalize(a, 63);
    bvconst_normalize(b, 63);
    printf("Unsigned tests\n");
    printf(" a le b: %d\n", bvconst_le(a, b, 63));
    printf(" a ge b: %d\n", bvconst_ge(a, b, 63));
    printf(" a lt b: %d\n", bvconst_lt(a, b, 63));
    printf(" a gt b: %d\n", bvconst_gt(a, b, 63));

    printf("Signed tests\n");
    printf(" a sle b: %d\n", bvconst_sle(a, b, 63));
    printf(" a sge b: %d\n", bvconst_sge(a, b, 63));
    printf(" a slt b: %d\n", bvconst_slt(a, b, 63));
    printf(" a sgt b: %d\n", bvconst_sgt(a, b, 63));
  }

  for (i=0; i<10; i++) {
    printf("\ntest %"PRId32": comparisons\n", i);
    random_vector(vector, 64);
    bvconst_set_array(a, vector, 64);
    random_vector(vector, 64);
    bvconst_set_array(b, vector, 64);

    printf("a = ");
    bvconst_print(stdout, a, 64);
    printf("\n");
    printf("b = ");
    bvconst_print(stdout, b, 64);
    printf("\n");

    bvconst_normalize(a, 64);
    bvconst_normalize(b, 64);
    printf("Unsigned tests\n");
    printf(" a le b: %d\n", bvconst_le(a, b, 64));
    printf(" a ge b: %d\n", bvconst_ge(a, b, 64));
    printf(" a lt b: %d\n", bvconst_lt(a, b, 64));
    printf(" a gt b: %d\n", bvconst_gt(a, b, 64));

    printf("Signed tests\n");
    printf(" a sle b: %d\n", bvconst_sle(a, b, 64));
    printf(" a sge b: %d\n", bvconst_sge(a, b, 64));
    printf(" a slt b: %d\n", bvconst_slt(a, b, 64));
    printf(" a sgt b: %d\n", bvconst_sgt(a, b, 64));
  }

  printf("\nMore comparisons\n");
  random_vector(vector, 64);
  bvconst_set_array(a, vector, 64);
  bvconst_set_array(b, vector, 64);
  printf("a = ");
  bvconst_print(stdout, a, 64);
  printf("\n");
  printf("b = ");
  bvconst_print(stdout, b, 64);
  printf("\n");

  bvconst_normalize(a, 64);
  bvconst_normalize(b, 64);
  printf("Unsigned tests\n");
  printf(" a le b: %d\n", bvconst_le(a, b, 64));
  printf(" a ge b: %d\n", bvconst_ge(a, b, 64));
  printf(" a lt b: %d\n", bvconst_lt(a, b, 64));
  printf(" a gt b: %d\n", bvconst_gt(a, b, 64));

  printf("Signed tests\n");
  printf(" a sle b: %d\n", bvconst_sle(a, b, 64));
  printf(" a sge b: %d\n", bvconst_sge(a, b, 64));
  printf(" a slt b: %d\n", bvconst_slt(a, b, 64));
  printf(" a sgt b: %d\n", bvconst_sgt(a, b, 64));


  random_vector(vector, 65);
  bvconst_set_array(a, vector, 65);
  bvconst_set_array(b, vector, 65);
  printf("a = ");
  bvconst_print(stdout, a, 65);
  printf("\n");
  printf("b = ");
  bvconst_print(stdout, b, 65);
  printf("\n");

  bvconst_normalize(a, 65);
  bvconst_normalize(b, 65);
  printf("Unsigned tests\n");
  printf(" a le b: %d\n", bvconst_le(a, b, 65));
  printf(" a ge b: %d\n", bvconst_ge(a, b, 65));
  printf(" a lt b: %d\n", bvconst_lt(a, b, 65));
  printf(" a gt b: %d\n", bvconst_gt(a, b, 65));

  printf("Signed tests\n");
  printf(" a sle b: %d\n", bvconst_sle(a, b, 65));
  printf(" a sge b: %d\n", bvconst_sge(a, b, 65));
  printf(" a slt b: %d\n", bvconst_slt(a, b, 65));
  printf(" a sgt b: %d\n", bvconst_sgt(a, b, 65));

  random_vector(vector, 63);
  bvconst_set_array(a, vector, 63);
  bvconst_set_array(b, vector, 63);
  printf("a = ");
  bvconst_print(stdout, a, 63);
  printf("\n");
  printf("b = ");
  bvconst_print(stdout, b, 63);
  printf("\n");

  bvconst_normalize(a, 63);
  bvconst_normalize(b, 63);
  printf("Unsigned tests\n");
  printf(" a le b: %d\n", bvconst_le(a, b, 63));
  printf(" a ge b: %d\n", bvconst_ge(a, b, 63));
  printf(" a lt b: %d\n", bvconst_lt(a, b, 63));
  printf(" a gt b: %d\n", bvconst_gt(a, b, 63));

  printf("Signed tests\n");
  printf(" a sle b: %d\n", bvconst_sle(a, b, 63));
  printf(" a sge b: %d\n", bvconst_sge(a, b, 63));
  printf(" a slt b: %d\n", bvconst_slt(a, b, 63));
  printf(" a sgt b: %d\n", bvconst_sgt(a, b, 63));

  printf("\nTest powers of two\n");
  mpz_set_ui(z0, 1);
  for (i=0; i<128; i++) {
    printf("z0 = ");
    mpz_out_str(stdout, 10, z0);
    printf("\n");
    bvconst_set_mpz(a, 4, z0);
    printf("a = ");
    bvconst_print(stdout, a, 128);
    printf("\n");

    n = bvconst_is_power_of_two(a, 4);
    if (n < 0) {
      printf("--> not a power of 2\n\n");
    } else {
      printf("--> a = 2^%"PRId32"\n\n", n);
    }
    mpz_add(z0, z0, z0);
  }


  a[0] = 0;
  a[1] = 1024;
  a[2] = 0;
  a[3] = 36136287;
  printf("a = ");
  bvconst_print(stdout, a, 128);
  printf("\n");
  n = bvconst_is_power_of_two(a, 4);
  if (n < 0) {
    printf("--> not a power of 2\n\n");
  } else {
    printf("--> a = 2^%"PRId32"\n\n", n);
  }

  a[0] = 0;
  a[1] = 1024;
  a[2] = 31209;
  a[3] = 0;
  printf("a = ");
  bvconst_print(stdout, a, 128);
  printf("\n");
  n = bvconst_is_power_of_two(a, 4);
  if (n < 0) {
    printf("--> not a power of 2\n\n");
  } else {
    printf("--> a = 2^%"PRId32"\n\n", n);
  }


  a[0] = 0;
  a[1] = 1024;
  a[2] = 0;
  a[3] = 0;
  printf("a = ");
  bvconst_print(stdout, a, 128);
  printf("\n");
  n = bvconst_is_power_of_two(a, 4);
  if (n < 0) {
    printf("--> not a power of 2\n\n");
  } else {
    printf("--> a = 2^%"PRId32"\n\n", n);
  }


  a[0] = 128;
  a[1] = 1024;
  a[2] = 0;
  a[3] = 0;
  printf("a = ");
  bvconst_print(stdout, a, 128);
  printf("\n");
  n = bvconst_is_power_of_two(a, 4);
  if (n < 0) {
    printf("--> not a power of 2\n\n");
  } else {
    printf("--> a = 2^%"PRId32"\n\n", n);
  }




  bvconst_clear(a, 4);
  for (i=0; i<256; i++) {
    printf("a = ");
    bvconst_print(stdout, a, 128);
    printf("\n");

    n = bvconst_is_power_of_two(a, 4);
    if (n < 0) {
      printf("--> not a power of 2\n\n");
    } else {
      printf("--> a = 2^%"PRId32"\n\n", n);
    }
    bvconst_add_one(a, 4);
  }

  for (i=0; i<10; i++) {
    printf("test %"PRId32": power of two\n", i);
    random_vector(vector, 128);
    bvconst_set_array(a, vector, 128);

    for (j=0; j<64; j++) {
      printf("a = ");
      bvconst_print(stdout, a, 128);
      printf("\n");
      n = bvconst_is_power_of_two(a, 4);
      if (n < 0) {
	printf("--> not a power of 2\n\n");
      } else {
	printf("--> a = 2^%"PRId32"\n\n", n);
      }
      bvconst_clr_bit(a, j);
      bvconst_clr_bit(a, 127 - j);
    }
  }


  // test mulpower
  for (i=0; i<130; i++) {
    bvconst_set_one(a, 4);    // a = 1
    bvconst_set32(b, 4, 2);   // b = 2
    // compute a * b^i = 2^i
    bvconst_mulpower(a, 4, b, i);
    printf("---> mulpower: a = b^%"PRIu32" = 2^%"PRIu32"\n", i, i);
    printf("     b = ");
    bvconst_print(stdout, b, 128);
    printf("\n");
    printf("     a = ");
    bvconst_print(stdout, a, 128);
    printf("\n");
  }

  // test mulpower
  for (i=0; i<40; i++) {
    bvconst_set32(a, 4, 4);       // a = 0b0..00100
    bvconst_set_minus_one(b, 4);  // b = 0b11..1111
    // compute a * b^i = -4 or +4
    bvconst_mulpower(a, 4, b, i);
    printf("---> mulpower: a = 4 * b^%"PRIu32" = 4 * (-1)^%"PRIu32"\n", i, i);
    printf("     b = ");
    bvconst_print(stdout, b, 128);
    printf("\n");
    printf("     a = ");
    bvconst_print(stdout, a, 128);
    printf("\n");
  }

  // test mulpower
  for (i=0; i<40; i++) {
    bvconst_set32(a, 4, 4);     // a = 0b0..00100
    bvconst_clear(b, 4);        // b = 0
    // compute a * b^i = 0
    bvconst_mulpower(a, 4, b, i);
    printf("---> mulpower: a = 4 * b^%"PRIu32"\n", i);
    printf("     b = ");
    bvconst_print(stdout, b, 128);
    printf("\n");
    printf("     a = ");
    bvconst_print(stdout, a, 128);
    printf("\n");
  }


  // test is_one and is_minus_one
  printf("\n\n");
  for (i=1; i<=128; i++) {
    bvconst_set_one(a, 4);         // a = 1
    bvconst_set_minus_one(b, 4);   // b = -1
    bvconst_clear(c, 4);           // c = 0
    random_vector(vector, i);
    bvconst_set_array(d, vector, i); // d = random

    // make all i-bit length constant
    bvconst_normalize(a, i);
    bvconst_normalize(b, i);
    bvconst_normalize(c, i);
    bvconst_normalize(d, i);

    n = (i+31) >> 5;  // number of words
    printf("---> %"PRIu32" bits\n", i);
    printf("a = ");
    bvconst_print(stdout, a, i);
    printf(": is_one = %s, is_minus_one = %s\n", b2str(bvconst_is_one(a, n)), b2str(bvconst_is_minus_one(a, i)));

    printf("b = ");
    bvconst_print(stdout, b, i);
    printf(": is_one = %s, is_minus_one = %s\n", b2str(bvconst_is_one(b, n)), b2str(bvconst_is_minus_one(b, i)));

    printf("c = ");
    bvconst_print(stdout, c, i);
    printf(": is_one = %s, is_minus_one = %s\n", b2str(bvconst_is_one(c, n)), b2str(bvconst_is_minus_one(c, i)));

    printf("d = ");
    bvconst_print(stdout, d, i);
    printf(": is_one = %s, is_minus_one = %s\n", b2str(bvconst_is_one(d, n)), b2str(bvconst_is_minus_one(d, i)));

    printf("\n");
    fflush(stdout);
  }

  // test is_min_signed and is_max_signed
  printf("\n\n");
  for (i=1; i<=128; i++) {
    bvconst_clear(a, 4);           // a = 0
    bvconst_set_minus_one(b, 4);   // b = -1
    bvconst_clear(c, 4);
    bvconst_set_bit(c, i-1);       // c = 0b10000000 (smallest negative integer)
    bvconst_set_minus_one(d, 4);
    bvconst_clr_bit(d, i-1);       // d = 0b01111111 (largest positive integer)
    random_vector(vector, i);
    bvconst_set_array(e, vector, i); // e = random

    // make all i-bit length constant
    bvconst_normalize(a, i);
    bvconst_normalize(b, i);
    bvconst_normalize(c, i);
    bvconst_normalize(d, i);
    bvconst_normalize(e, i);

    printf("---> %"PRIu32" bits\n", i);
    printf("a = ");
    bvconst_print(stdout, a, i);
    printf(": is_min_signed = %s, is_max_signed = %s\n", b2str(bvconst_is_min_signed(a, i)), b2str(bvconst_is_max_signed(a, i)));

    printf("b = ");
    bvconst_print(stdout, b, i);
    printf(": is_min_signed = %s, is_max_signed = %s\n", b2str(bvconst_is_min_signed(b, i)), b2str(bvconst_is_max_signed(b, i)));

    printf("c = ");
    bvconst_print(stdout, c, i);
    printf(": is_min_signed = %s, is_max_signed = %s\n", b2str(bvconst_is_min_signed(c, i)), b2str(bvconst_is_max_signed(c, i)));

    printf("d = ");
    bvconst_print(stdout, d, i);
    printf(": is_min_signed = %s, is_max_signed = %s\n", b2str(bvconst_is_min_signed(d, i)), b2str(bvconst_is_max_signed(d, i)));

    printf("e = ");
    bvconst_print(stdout, e, i);
    printf(": is_min_signed = %s, is_max_signed = %s\n", b2str(bvconst_is_min_signed(e, i)), b2str(bvconst_is_max_signed(e, i)));

    printf("\n");
    fflush(stdout);
  }

  for (i=100; i<256; i += 10) {
    for (j=1; j<=i; j += 9) {
      test_set_extend(i, j);
    }
  }

  mpz_clear(z0);
  mpz_clear(z1);
  mpz_clear(z2);


  free_constants();

  return 0;
}
Пример #10
0
void
mpi_clear_highbit( MPI a, unsigned n )
{
    /* This seems whacky, but what do I know. */
    mpz_fdiv_r_2exp(a, a, n);
}
Пример #11
0
static void
dsa_nist_gen(mpz_t p, mpz_t q,
	     void *random_ctx, nettle_random_func random,
	     void *progress_ctx, nettle_progress_func progress,
	     unsigned L)
{
  unsigned n;
  unsigned b;
  mpz_t s;
  mpz_t t;
  mpz_t c;

  /* For NIS keysizes, we should have L = 512 + 64 * l */
  n = (L-1) / 160; b = (L-1) % 160;

  mpz_init(s);
  mpz_init(t);
  mpz_init(c);
  
  for (;;)
    {
      { /* Generate q */
	uint8_t h1[SHA1_DIGEST_SIZE];
	uint8_t h2[SHA1_DIGEST_SIZE];

	if (progress)
	  progress(progress_ctx, '.');
	
	nettle_mpz_random_size(s, random_ctx, random, SEED_BITS);
	
	hash(s, h1);
	
	mpz_set(t, s);
	mpz_add_ui(t, t, 1);
	
	hash(t, h2);
	
	memxor(h1, h2, SHA1_DIGEST_SIZE);
	
	h1[0] |= 0x80;
	h1[SHA1_DIGEST_SIZE - 1] |= 1;

	nettle_mpz_set_str_256_u(q, SHA1_DIGEST_SIZE, h1);

	/* The spec says that we should use 18 iterations of
	 * miller-rabin. For performance, we want to do some trial
	 * divisions first. The curent version of mpz_probab_prime_p
	 * does exactly that. */
	if (!mpz_probab_prime_p(q, 18))
	  /* Try new seed. */
	  continue;
      }
      /* q is a prime, with overwhelming probability. */

      if (progress)
	progress(progress_ctx, '\n');
      
      {
	/* Official maximum key size: L = 1024 => n = 6 */
	TMP_DECL(buffer, uint8_t, (6 + 1) * SHA1_DIGEST_SIZE);
	unsigned size = (n+1) * SHA1_DIGEST_SIZE;
	unsigned i, j;

	TMP_ALLOC(buffer, size);
	
	for (i = 0, j = 2; i<4096; i++, j+= n+1)
	  {
	    unsigned k;

	    if (progress)
	      progress(progress_ctx, ',');
	    for (k = 0; k<=n ; k++)
	      {
		mpz_set(t, s);
		mpz_add_ui(t, t, j + k);
		hash(t, buffer + ( (n-k) * SHA1_DIGEST_SIZE));
	      }
	    nettle_mpz_set_str_256_u(p, size, buffer);

	    mpz_fdiv_r_2exp(p, p, L);
	    mpz_setbit(p, L-1);

	    mpz_set(t, q);
	    mpz_mul_2exp(t, t, 1);

	    mpz_fdiv_r(c, p, t);

	    mpz_sub_ui(c, c, 1);

	    mpz_sub(p, p, c);

	    if (mpz_probab_prime_p(p, 5))
	      {
		/* Done! */
		if (progress)
		  progress(progress_ctx, '\n');
		
		mpz_clear(s);
		mpz_clear(t);
		mpz_clear(c);

		return;
	      }
	  }
	if (progress)
	  progress(progress_ctx, '+');
      }
    }
}