Example #1
0
int deserialize_mpi(gcry_mpi_t *x, enum disp_format df, const char *buf, 
		    int inlen)
{
  switch(df) {
  case DF_BIN:
    gcry_mpi_scan(x, GCRYMPI_FMT_USG, buf, inlen, NULL);
    gcry_mpi_set_flag(*x, GCRYMPI_FLAG_SECURE);
    break;
  case DF_COMPACT:
  case DF_BASE36:
    do {
    const char *digits = get_digits(df);
    unsigned int digit_count = get_digit_count(df);
    char *d;
    int i;
    *x = gcry_mpi_snew(0);
    for(i = 0; i < inlen; i++) {
        if (! (d = memchr(digits, buf[i], digit_count))) {
          gcry_mpi_release(*x);
          return 0;
        }
        gcry_mpi_mul_ui(*x, *x, digit_count);
        gcry_mpi_add_ui(*x, *x, d - digits);
    }
    } while (0);
    break;
  default: 
    assert(0);
  }
  return 1;
}
Example #2
0
static void
check_primes (void)
{
  gcry_error_t err = GPG_ERR_NO_ERROR;
  gcry_mpi_t *factors = NULL;
  gcry_mpi_t prime = NULL;
  gcry_mpi_t g;
  unsigned int i = 0;
  struct prime_spec
  {
    unsigned int prime_bits;
    unsigned int factor_bits;
    unsigned int flags;
  } prime_specs[] =
    {
      { 1024, 100, GCRY_PRIME_FLAG_SPECIAL_FACTOR },
      { 128, 0, 0 },
      { 0 },
    };

  for (i = 0; prime_specs[i].prime_bits; i++)
    {
      err = gcry_prime_generate (&prime,
				 prime_specs[i].prime_bits,
				 prime_specs[i].factor_bits,
				 &factors,
				 NULL, NULL,
				 GCRY_WEAK_RANDOM,
				 prime_specs[i].flags);
      assert (! err);
      if (verbose)
        {
          fprintf (stderr, "test %d: p = ", i);
          gcry_mpi_dump (prime);
          putc ('\n', stderr);
        }

      err = gcry_prime_check (prime, 0);
      assert (! err);

      err = gcry_prime_group_generator (&g, prime, factors, NULL);
      assert (!err);
      gcry_prime_release_factors (factors); factors = NULL;
      
      if (verbose)
        {
          fprintf (stderr, "     %d: g = ", i);
          gcry_mpi_dump (g);
          putc ('\n', stderr);
        }
      gcry_mpi_release (g);


      gcry_mpi_add_ui (prime, prime, 1);
      err = gcry_prime_check (prime, 0);
      assert (err);
    }
}
Example #3
0
gcry_mpi_t buf_to_exponent(const char *buf, int buflen,
			   const struct curve_params *cp)
{
  gcry_mpi_t a, b;
  gcry_mpi_scan(&a, GCRYMPI_FMT_USG, buf, buflen, NULL);
  gcry_mpi_set_flag(a, GCRYMPI_FLAG_SECURE);
  b = gcry_mpi_new(0);
  gcry_mpi_sub_ui(b, cp->dp.order, 1);
  gcry_mpi_mod(a, a, b);
  gcry_mpi_add_ui(a, a, 1);
  gcry_mpi_release(b);
  return a;
}
Example #4
0
static bigint_t
wrap_gcry_mpi_add_ui (bigint_t w, const bigint_t a, unsigned long b)
{
  if (w == NULL)
    w = _gnutls_mpi_alloc_like (a);

  if (w == NULL)
    return NULL;

  gcry_mpi_add_ui (w, a, b);

  return w;
}
Example #5
0
int ssh_gcry_dec2bn(bignum *bn, const char *data) {
  int count;

  *bn = bignum_new();
  if (*bn == NULL) {
    return 0;
  }
  gcry_mpi_set_ui(*bn, 0);
  for (count = 0; data[count]; count++) {
    gcry_mpi_mul_ui(*bn, *bn, 10);
    gcry_mpi_add_ui(*bn, *bn, data[count] - '0');
  }

  return count;
}
Example #6
0
/* deterministically generate from seed/idx a prime of length `bits' that is 3 (mod 4) */
static gcry_mpi_t genprime3mod4(int bits, const void *seed, size_t seedlen, uint32_t idx) {
        size_t buflen = bits / 8;
        uint8_t buf[buflen];
        gcry_mpi_t p;

        assert(bits % 8 == 0);
        assert(buflen > 0);

        det_randomize(buf, buflen, seed, seedlen, idx);
        buf[0] |= 0xc0; /* set upper two bits, so that n=pq has maximum size */
        buf[buflen - 1] |= 0x03; /* set lower two bits, to have result 3 (mod 4) */

        p = mpi_import(buf, buflen);
        while (gcry_prime_check(p, 0))
                gcry_mpi_add_ui(p, p, 4);

        return p;
}
/**
 * Iterator to copy over messages from the hash map
 * into an array for sorting.
 *
 * @param cls the `struct BobServiceSession *`
 * @param key the key (unused)
 * @param value the `struct GNUNET_SCALARPRODUCT_Element *`
 * TODO: code duplication with Alice!
 */
static int
copy_element_cb (void *cls,
                 const struct GNUNET_HashCode *key,
                 void *value)
{
  struct BobServiceSession *s = cls;
  struct GNUNET_SCALARPRODUCT_Element *e = value;
  gcry_mpi_t mval;
  int64_t val;

  mval = gcry_mpi_new (0);
  val = (int64_t) GNUNET_ntohll (e->value);
  if (0 > val)
    gcry_mpi_sub_ui (mval, mval, -val);
  else
    gcry_mpi_add_ui (mval, mval, val);
  s->sorted_elements [s->used_element_count].value = mval;
  s->sorted_elements [s->used_element_count].key = &e->key;
  s->used_element_count++;
  return GNUNET_OK;
}
Example #8
0
static void
mpz_randomize (gcry_mpi_t n, unsigned int nbits, struct GNUNET_HashCode * rnd)
{
  struct GNUNET_HashCode hc;
  struct GNUNET_HashCode tmp;
  int bits_per_hc = sizeof (struct GNUNET_HashCode) * 8;
  int cnt;
  int i;

  GNUNET_assert (nbits > 0);
  cnt = (nbits + bits_per_hc - 1) / bits_per_hc;
  gcry_mpi_set_ui (n, 0);

  tmp = *rnd;
  for (i = 0; i < cnt; i++)
  {
    int j;

    if (i > 0)
      GNUNET_CRYPTO_hash (&hc, sizeof (struct GNUNET_HashCode), &tmp);
    for (j = 0; j < sizeof (struct GNUNET_HashCode) / sizeof (uint32_t); j++)
    {
#if HAVE_GCRY_MPI_LSHIFT
      gcry_mpi_lshift (n, n, sizeof (uint32_t) * 8);
#else
      gcry_mpi_mul_ui (n, n, 1 << (sizeof (uint32_t) * 4));
      gcry_mpi_mul_ui (n, n, 1 << (sizeof (uint32_t) * 4));
#endif
      gcry_mpi_add_ui (n, n, ntohl (((uint32_t *) & tmp)[j]));
    }
    hc = tmp;
  }
  GNUNET_CRYPTO_hash (&hc, sizeof (struct GNUNET_HashCode), rnd);
  i = gcry_mpi_get_nbits (n);
  while (i > nbits)
    gcry_mpi_clear_bit (n, --i);
}
static int
generate_key_or_iv(unsigned int id, tvbuff_t *salt_tvb, unsigned int iter,
		       const char *pw, unsigned int req_keylen, char * keybuf)
{
  int rc;
  unsigned int i, j;
  gcry_md_hd_t md;
  gcry_mpi_t num_b1 = NULL;
  size_t pwlen;
  char hash[20], buf_b[64], buf_i[128], *p;
  char *salt_p;
  int salt_size;
  size_t cur_keylen;
  size_t n;
  gcry_error_t	err;

  cur_keylen = 0;

  salt_size = tvb_captured_length(salt_tvb);
  salt_p = (char *)tvb_memdup(wmem_packet_scope(), salt_tvb, 0, salt_size);

  if (pw == NULL)
    pwlen = 0;
  else
    pwlen = strlen(pw);

  if (pwlen > 63 / 2)
    {
      return FALSE;
    }

  /* Store salt and password in BUF_I */
  p = buf_i;
  for (i = 0; i < 64; i++)
    *p++ = salt_p[i % salt_size];
  if (pw)
    {
      for (i = j = 0; i < 64; i += 2)
	{
	  *p++ = 0;
	  *p++ = pw[j];
	  if (++j > pwlen)	/* Note, that we include the trailing zero */
	    j = 0;
	}
    }
  else
    memset (p, 0, 64);

  for (;;) {
      err = gcry_md_open(&md, GCRY_MD_SHA1, 0);
      if (gcry_err_code(err))
        {
          return FALSE;
        }
      for (i = 0; i < 64; i++)
        {
          unsigned char lid = id & 0xFF;
          gcry_md_write (md, &lid, 1);
	}

      gcry_md_write(md, buf_i, pw ? 128 : 64);

      gcry_md_final (md);
      memcpy (hash, gcry_md_read (md, 0), 20);

      gcry_md_close (md);

      for (i = 1; i < iter; i++)
        gcry_md_hash_buffer (GCRY_MD_SHA1, hash, hash, 20);

      for (i = 0; i < 20 && cur_keylen < req_keylen; i++)
        keybuf[cur_keylen++] = hash[i];

      if (cur_keylen == req_keylen)
      {
        gcry_mpi_release (num_b1);
        return TRUE;		/* ready */
      }

      /* need more bytes. */
      for (i = 0; i < 64; i++)
        buf_b[i] = hash[i % 20];

      n = 64;

      rc = gcry_mpi_scan (&num_b1, GCRYMPI_FMT_USG, buf_b, n, &n);

      if (rc != 0)
        {
          return FALSE;
        }

      gcry_mpi_add_ui (num_b1, num_b1, 1);

      for (i = 0; i < 128; i += 64)
        {
          gcry_mpi_t num_ij;

          n = 64;
          rc = gcry_mpi_scan (&num_ij, GCRYMPI_FMT_USG, buf_i + i, n, &n);

          if (rc != 0)
            {
              return FALSE;
            }

          gcry_mpi_add (num_ij, num_ij, num_b1);
          gcry_mpi_clear_highbit (num_ij, 64 * 8);

          n = 64;

          rc = gcry_mpi_print (GCRYMPI_FMT_USG, buf_i + i, n, &n, num_ij);
          if (rc != 0)
            {
              return FALSE;
            }

          gcry_mpi_release (num_ij);
        }
  }
}
Example #10
0
/* Find a generator for PRIME where the factorization of (prime-1) is
   in the NULL terminated array FACTORS. Return the generator as a
   newly allocated MPI in R_G.  If START_G is not NULL, use this as s
   atart for the search. Returns 0 on success.*/
gcry_error_t
gcry_prime_group_generator (gcry_mpi_t *r_g,
                            gcry_mpi_t prime, gcry_mpi_t *factors,
                            gcry_mpi_t start_g)
{
  gcry_mpi_t tmp = gcry_mpi_new (0);
  gcry_mpi_t b = gcry_mpi_new (0);
  gcry_mpi_t pmin1 = gcry_mpi_new (0);
  gcry_mpi_t g = start_g? gcry_mpi_copy (start_g) : gcry_mpi_set_ui (NULL, 3);
  int first = 1;
  int i, n;

  if (!factors || !r_g || !prime)
    return gpg_error (GPG_ERR_INV_ARG);
  *r_g = NULL; 

  for (n=0; factors[n]; n++)
    ;
  if (n < 2)
    return gpg_error (GPG_ERR_INV_ARG);

  /* Extra sanity check - usually disabled. */  
/*   mpi_set (tmp, factors[0]); */
/*   for(i = 1; i < n; i++) */
/*     mpi_mul (tmp, tmp, factors[i]); */
/*   mpi_add_ui (tmp, tmp, 1); */
/*   if (mpi_cmp (prime, tmp)) */
/*     return gpg_error (GPG_ERR_INV_ARG); */
  
  gcry_mpi_sub_ui (pmin1, prime, 1);      
  do         
    {
      if (first)
        first = 0;
      else
        gcry_mpi_add_ui (g, g, 1);
      
      if (DBG_CIPHER)
        {
          log_debug ("checking g:");
          gcry_mpi_dump (g);
          log_debug ("\n");
        }
      else
        progress('^');
      
      for (i = 0; i < n; i++)
        {
          mpi_fdiv_q (tmp, pmin1, factors[i]);
          gcry_mpi_powm (b, g, tmp, prime);
          if (! mpi_cmp_ui (b, 1))
            break;
        }
      if (DBG_CIPHER)
        progress('\n');
    }
  while (i < n);
  
  gcry_mpi_release (tmp);
  gcry_mpi_release (b); 
  gcry_mpi_release (pmin1); 
  *r_g = g; 

  return 0; 
}
Example #11
0
/**
 * Generate a key pair with a key of size NBITS.
 * @param sk where to store the key
 * @param nbits the number of bits to use
 * @param hc the HC to use for PRNG (modified!)
 */
static void
generate_kblock_key (KBlock_secret_key *sk, unsigned int nbits,
                     struct GNUNET_HashCode * hc)
{
  gcry_mpi_t t1, t2;
  gcry_mpi_t phi;               /* helper: (p-1)(q-1) */
  gcry_mpi_t g;
  gcry_mpi_t f;

  /* make sure that nbits is even so that we generate p, q of equal size */
  if ((nbits & 1))
    nbits++;

  sk->e = gcry_mpi_set_ui (NULL, 257);
  sk->n = gcry_mpi_new (0);
  sk->p = gcry_mpi_new (0);
  sk->q = gcry_mpi_new (0);
  sk->d = gcry_mpi_new (0);
  sk->u = gcry_mpi_new (0);

  t1 = gcry_mpi_new (0);
  t2 = gcry_mpi_new (0);
  phi = gcry_mpi_new (0);
  g = gcry_mpi_new (0);
  f = gcry_mpi_new (0);

  do
  {
    do
    {
      gcry_mpi_release (sk->p);
      gcry_mpi_release (sk->q);
      gen_prime (&sk->p, nbits / 2, hc);
      gen_prime (&sk->q, nbits / 2, hc);

      if (gcry_mpi_cmp (sk->p, sk->q) > 0)      /* p shall be smaller than q (for calc of u) */
        gcry_mpi_swap (sk->p, sk->q);
      /* calculate the modulus */
      gcry_mpi_mul (sk->n, sk->p, sk->q);
    }
    while (gcry_mpi_get_nbits (sk->n) != nbits);

    /* calculate Euler totient: phi = (p-1)(q-1) */
    gcry_mpi_sub_ui (t1, sk->p, 1);
    gcry_mpi_sub_ui (t2, sk->q, 1);
    gcry_mpi_mul (phi, t1, t2);
    gcry_mpi_gcd (g, t1, t2);
    gcry_mpi_div (f, NULL, phi, g, 0);
    while (0 == gcry_mpi_gcd (t1, sk->e, phi))
    {                           /* (while gcd is not 1) */
      gcry_mpi_add_ui (sk->e, sk->e, 2);
    }

    /* calculate the secret key d = e^1 mod phi */
  }
  while ((0 == gcry_mpi_invm (sk->d, sk->e, f)) ||
         (0 == gcry_mpi_invm (sk->u, sk->p, sk->q)));

  gcry_mpi_release (t1);
  gcry_mpi_release (t2);
  gcry_mpi_release (phi);
  gcry_mpi_release (f);
  gcry_mpi_release (g);
}
Example #12
0
static void
gen_prime (gcry_mpi_t * ptest, unsigned int nbits, struct GNUNET_HashCode * hc)
{
  /* Note: 2 is not included because it can be tested more easily by
   * looking at bit 0. The last entry in this list is marked by a zero */
  static const uint16_t small_prime_numbers[] = {
    3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
    47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
    103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
    157, 163, 167, 173, 179, 181, 191, 193, 197, 199,
    211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
    269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
    331, 337, 347, 349, 353, 359, 367, 373, 379, 383,
    389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
    449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
    509, 521, 523, 541, 547, 557, 563, 569, 571, 577,
    587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
    643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
    709, 719, 727, 733, 739, 743, 751, 757, 761, 769,
    773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
    853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
    919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
    991, 997, 1009, 1013, 1019, 1021, 1031, 1033,
    1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091,
    1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
    1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
    1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277,
    1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307,
    1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,
    1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
    1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493,
    1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559,
    1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609,
    1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667,
    1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
    1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789,
    1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
    1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931,
    1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997,
    1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
    2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111,
    2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161,
    2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243,
    2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
    2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
    2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411,
    2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473,
    2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
    2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633,
    2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
    2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729,
    2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791,
    2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851,
    2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917,
    2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
    3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061,
    3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137,
    3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209,
    3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
    3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
    3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391,
    3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467,
    3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533,
    3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583,
    3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
    3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709,
    3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779,
    3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851,
    3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917,
    3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
    4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049,
    4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111,
    4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177,
    4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243,
    4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
    4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391,
    4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457,
    4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519,
    4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597,
    4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
    4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
    4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799,
    4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889,
    4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951,
    4957, 4967, 4969, 4973, 4987, 4993, 4999,
    0
  };
#define DIM(v) (sizeof(v)/sizeof((v)[0]))
  static int no_of_small_prime_numbers = DIM (small_prime_numbers) - 1;

  gcry_mpi_t prime, pminus1, val_2, val_3, result;
  unsigned int i;
  unsigned int step;
  unsigned int mods[no_of_small_prime_numbers];
  gcry_mpi_t tmp;
  gcry_mpi_t sp;

  GNUNET_assert (nbits >= 16);

  /* Make nbits fit into mpz_t implementation. */
  val_2 = gcry_mpi_set_ui (NULL, 2);
  val_3 = gcry_mpi_set_ui (NULL, 3);
  prime = gcry_mpi_snew (0);
  result = gcry_mpi_new (0);
  pminus1 = gcry_mpi_new (0);
  *ptest = gcry_mpi_new (0);
  tmp = gcry_mpi_new (0);
  sp = gcry_mpi_new (0);
  while (1)
  {
    /* generate a random number */
    mpz_randomize (prime, nbits, hc);
    /* Set high order bit to 1, set low order bit to 1.  If we are
     * generating a secret prime we are most probably doing that
     * for RSA, to make sure that the modulus does have the
     * requested key size we set the 2 high order bits. */
    gcry_mpi_set_bit (prime, nbits - 1);
    gcry_mpi_set_bit (prime, nbits - 2);
    gcry_mpi_set_bit (prime, 0);

    /* Calculate all remainders. */
    for (i = 0; i < no_of_small_prime_numbers; i++)
    {
      size_t written;

      gcry_mpi_set_ui (sp, small_prime_numbers[i]);
      gcry_mpi_div (NULL, tmp, prime, sp, -1);
      mods[i] = 0;
      written = sizeof (unsigned int);
      GNUNET_assert (0 ==
                     gcry_mpi_print (GCRYMPI_FMT_USG,
                                     (unsigned char *) &mods[i], written,
                                     &written, tmp));
      adjust ((unsigned char *) &mods[i], written, sizeof (unsigned int));
      mods[i] = ntohl (mods[i]);
    }
    /* Now try some primes starting with prime. */
    for (step = 0; step < 20000; step += 2)
    {
      /* Check against all the small primes we have in mods. */
      for (i = 0; i < no_of_small_prime_numbers; i++)
      {
        uint16_t x = small_prime_numbers[i];

        while (mods[i] + step >= x)
          mods[i] -= x;
        if (!(mods[i] + step))
          break;
      }
      if (i < no_of_small_prime_numbers)
        continue;               /* Found a multiple of an already known prime. */

      gcry_mpi_add_ui (*ptest, prime, step);
      if (!gcry_mpi_test_bit (*ptest, nbits - 2))
        break;

      /* Do a fast Fermat test now. */
      gcry_mpi_sub_ui (pminus1, *ptest, 1);
      gcry_mpi_powm (result, val_2, pminus1, *ptest);
      if ((!gcry_mpi_cmp_ui (result, 1)) && (is_prime (*ptest, 5, hc)))
      {
        /* Got it. */
        gcry_mpi_release (sp);
        gcry_mpi_release (tmp);
        gcry_mpi_release (val_2);
        gcry_mpi_release (val_3);
        gcry_mpi_release (result);
        gcry_mpi_release (pminus1);
        gcry_mpi_release (prime);
        return;
      }
    }
  }
}