Exemplo n.º 1
0
void jacobian_double(struct jacobian_point *p, const struct domain_params *dp)
{
  if (gcry_mpi_cmp_ui(p->z, 0)) {
    if (gcry_mpi_cmp_ui(p->y, 0)) {
      gcry_mpi_t t1, t2;
      t1 = gcry_mpi_snew(0);
      t2 = gcry_mpi_snew(0);
      gcry_mpi_mulm(t1, p->x, p->x, dp->m);
      gcry_mpi_addm(t2, t1, t1, dp->m);
      gcry_mpi_addm(t2, t2, t1, dp->m);
      gcry_mpi_mulm(t1, p->z, p->z, dp->m);
      gcry_mpi_mulm(t1, t1, t1, dp->m);
      gcry_mpi_mulm(t1, t1, dp->a, dp->m);
      gcry_mpi_addm(t1, t1, t2, dp->m);
      gcry_mpi_mulm(p->z, p->z, p->y, dp->m);
      gcry_mpi_addm(p->z, p->z, p->z, dp->m);
      gcry_mpi_mulm(p->y, p->y, p->y, dp->m);
      gcry_mpi_addm(p->y, p->y, p->y, dp->m);
      gcry_mpi_mulm(t2, p->x, p->y, dp->m);
      gcry_mpi_addm(t2, t2, t2, dp->m);
      gcry_mpi_mulm(p->x, t1, t1, dp->m);
      gcry_mpi_subm(p->x, p->x, t2, dp->m);
      gcry_mpi_subm(p->x, p->x, t2, dp->m);
      gcry_mpi_subm(t2, t2, p->x, dp->m);
      gcry_mpi_mulm(t1, t1, t2, dp->m);
      gcry_mpi_mulm(t2, p->y, p->y, dp->m);
      gcry_mpi_addm(t2, t2, t2, dp->m);
      gcry_mpi_subm(p->y, t1, t2, dp->m);
      gcry_mpi_release(t1);
      gcry_mpi_release(t2);
    }
    else
      gcry_mpi_set_ui(p->z, 0);
  }
}
Exemplo n.º 2
0
int point_decompress(struct affine_point *p, const gcry_mpi_t x, int yflag, 
		     const struct domain_params *dp)
{
  gcry_mpi_t h, y;
  int res;
  h = gcry_mpi_snew(0);
  y = gcry_mpi_snew(0);
  gcry_mpi_mulm(h, x, x, dp->m);
  gcry_mpi_addm(h, h, dp->a, dp->m);
  gcry_mpi_mulm(h, h, x, dp->m);
  gcry_mpi_addm(h, h, dp->b, dp->m);
  if ((res = mod_root(y, h, dp->m)))
    if ((res = (gcry_mpi_cmp_ui(y, 0) || ! yflag))) {
      p->x = gcry_mpi_snew(0);
      p->y = gcry_mpi_snew(0);
      gcry_mpi_set(p->x, x);
      if (gcry_mpi_test_bit(y, 0) == yflag)
	gcry_mpi_set(p->y, y);
      else
	gcry_mpi_sub(p->y, dp->m, y);
      assert(point_on_curve(p, dp));
    }
  gcry_mpi_release(h);
  gcry_mpi_release(y);
  return res;
}
Exemplo n.º 3
0
struct affine_point point_new(void)
{
  struct affine_point r;
  r.x = gcry_mpi_snew(0);
  r.y = gcry_mpi_snew(0);
  return r;
}
Exemplo n.º 4
0
struct jacobian_point jacobian_new(void)
{
  struct jacobian_point r;
  r.x = gcry_mpi_snew(0);
  r.y = gcry_mpi_snew(0);
  r.z = gcry_mpi_snew(0);
  return r;
}
Exemplo n.º 5
0
void point_add(struct affine_point *p1, const struct affine_point *p2,
	       const struct domain_params *dp)
{
  if (! point_is_zero(p2)) {
    if (! point_is_zero(p1)) {
      if (! gcry_mpi_cmp(p1->x, p2->x)) {
	if (! gcry_mpi_cmp(p1->y, p2->y))
	  point_double(p1, dp);
	else
	  point_load_zero(p1);
      }
      else {
	gcry_mpi_t t;
	t = gcry_mpi_snew(0);
	gcry_mpi_subm(t, p1->y, p2->y, dp->m);
	gcry_mpi_subm(p1->y, p1->x, p2->x, dp->m);
	gcry_mpi_invm(p1->y, p1->y, dp->m);
	gcry_mpi_mulm(p1->y, t, p1->y, dp->m);
	gcry_mpi_mulm(t, p1->y, p1->y, dp->m);
	gcry_mpi_addm(p1->x, p1->x, p2->x, dp->m);
	gcry_mpi_subm(p1->x, t, p1->x, dp->m);
	gcry_mpi_subm(t, p2->x, p1->x, dp->m);
	gcry_mpi_mulm(p1->y, p1->y, t, dp->m);
	gcry_mpi_subm(p1->y, p1->y, p2->y, dp->m);
	gcry_mpi_release(t);
      }
    }
    else
      point_set(p1, p2);
  }
}
Exemplo n.º 6
0
/*output this number*/
void mpiOut2(gcry_mpi_t value)

{	int i=0;
	char  buffer[1024/8],buffer2[1024/8]; //buffer for the output
	gcry_randomize (buffer, 1024/8, GCRY_STRONG_RANDOM);
	printf("\n random buffer: ");
	for (i = 0; i<1024/8; i++){
		if(i%32==0)
			printf("\n");
		printf("%0u", (unsigned char)buffer[i]);
	}
	printf("\n");
	gcry_mpi_t test;
	test=gcry_mpi_snew(1024/8);
	gcry_mpi_scan(&test,GCRYMPI_FMT_STD,buffer,sizeof(buffer),NULL);

	gcry_mpi_print(GCRYMPI_FMT_STD,buffer2,sizeof(buffer2),NULL,test); //converts the MPI to a writable buffer
	printf("\n random buffer2:\n");
	for (i = 0; i<1024/8; i++){
			if(i%32==0)
				printf("\n");
			printf("%0u", (unsigned char)buffer2[i]);
		}

	printf("\n test");

}
Exemplo n.º 7
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;
}
Exemplo n.º 8
0
Arquivo: kex.c Projeto: gpg/gsti
/* Choose a random value x and calculate e = g^x mod p.  Returns e and
   if ret_x is not NULL x.  */
static gcry_mpi_t
calc_dh_secret (gcry_mpi_t gex_g, gcry_mpi_t gex_p, gcry_mpi_t * ret_x)
{
  gcry_mpi_t e, g, x, prime;
  size_t n = sizeof diffie_hellman_group1_prime;

  if (gex_p)
    prime = gcry_mpi_copy (gex_p);
  else if (gcry_mpi_scan (&prime, GCRYMPI_FMT_STD,
                          diffie_hellman_group1_prime, n, NULL))
    abort ();
  /*_gsti_dump_mpi( "prime=", prime );*/

  if (gex_g)
    g = gcry_mpi_copy (gex_g);
  else
    g = gcry_mpi_set_ui (NULL, 2);

  /* FIXME: we n bits for the private exponent,
     where n is 2*derrived_key_material */
  x = gcry_mpi_snew (200);
  gcry_mpi_randomize (x, 200, GCRY_STRONG_RANDOM);

  n = gcry_mpi_get_nbits (prime);
  e = gcry_mpi_new (n+1);
  gcry_mpi_powm (e, g, x, prime);
  if (ret_x)
    *ret_x = x;
  else
    gcry_mpi_release (x);
  gcry_mpi_release (g);
  gcry_mpi_release (prime);
  return e;
}
Exemplo n.º 9
0
int point_on_curve(const struct affine_point *p, const struct domain_params *dp)
{
  int res;
  if (! (res = point_is_zero(p))) {
    gcry_mpi_t h1, h2;
    h1 = gcry_mpi_snew(0);
    h2 = gcry_mpi_snew(0);
    gcry_mpi_mulm(h1, p->x, p->x, dp->m);
    gcry_mpi_addm(h1, h1, dp->a, dp->m);
    gcry_mpi_mulm(h1, h1, p->x, dp->m);
    gcry_mpi_addm(h1, h1, dp->b, dp->m);
    gcry_mpi_mulm(h2, p->y, p->y, dp->m);
    res = ! gcry_mpi_cmp(h1, h2);
    gcry_mpi_release(h1);
    gcry_mpi_release(h2);
  }
  return res;
}
Exemplo n.º 10
0
/* Algorithms 4.29 and 4.30 in the "Guide to Elliptic Curve Cryptography"     */
gcry_mpi_t ECDSA_sign(const char *msg, const gcry_mpi_t d,
		      const struct curve_params *cp)
{
  struct affine_point p1;
  gcry_mpi_t e, k, r, s;

#if ECDSA_DETERMINISTIC
  struct aes256cprng *cprng;
  cprng = ecdsa_cprng_init(msg, d, cp);
#endif
  r = gcry_mpi_snew(0);
  s = gcry_mpi_snew(0);
 Step1:
#if ECDSA_DETERMINISTIC
  k = ecdsa_cprng_get_exponent(cprng, cp);
#else
  k = get_random_exponent(cp);
#endif
  p1 = pointmul(&cp->dp.base, k, &cp->dp);
  gcry_mpi_mod(r, p1.x, cp->dp.order);
  point_release(&p1);
  if (! gcry_mpi_cmp_ui(r, 0)) {
    gcry_mpi_release(k);
    goto Step1;
  }
  gcry_mpi_scan(&e, GCRYMPI_FMT_USG, msg, 64, NULL);
  gcry_mpi_set_flag(e, GCRYMPI_FLAG_SECURE);
  gcry_mpi_mod(e, e, cp->dp.order);
  gcry_mpi_mulm(s, d, r, cp->dp.order);
  gcry_mpi_addm(s, s, e, cp->dp.order);
  gcry_mpi_invm(e, k, cp->dp.order);
  gcry_mpi_mulm(s, s, e, cp->dp.order);
  gcry_mpi_release(e);
  gcry_mpi_release(k);
  if (! gcry_mpi_cmp_ui(s, 0))
    goto Step1;
  gcry_mpi_mul(s, s, cp->dp.order);
  gcry_mpi_add(s, s, r);
  gcry_mpi_release(r);
#if ECDSA_DETERMINISTIC
  ecdsa_cprng_done(cprng);
#endif
  return s;
}
Exemplo n.º 11
0
void jacobian_affine_point_add(struct jacobian_point *p1, 
			       const struct affine_point *p2,
			       const struct domain_params *dp)
{
  if (! point_is_zero(p2)) {
    if (gcry_mpi_cmp_ui(p1->z, 0)) {
      gcry_mpi_t t1, t2, t3;
      t1 = gcry_mpi_snew(0);
      t2 = gcry_mpi_snew(0);
      gcry_mpi_mulm(t1, p1->z, p1->z, dp->m);
      gcry_mpi_mulm(t2, t1, p2->x, dp->m);
      gcry_mpi_mulm(t1, t1, p1->z, dp->m);
      gcry_mpi_mulm(t1, t1, p2->y, dp->m);
      if (! gcry_mpi_cmp(p1->x, t2)) {
	if (! gcry_mpi_cmp(p1->y, t1))
	  jacobian_double(p1, dp);
	else
	  jacobian_load_zero(p1);
      }
      else {
	t3 = gcry_mpi_snew(0);
	gcry_mpi_subm(p1->x, p1->x, t2, dp->m);
	gcry_mpi_subm(p1->y, p1->y, t1, dp->m);
	gcry_mpi_mulm(p1->z, p1->z, p1->x, dp->m);
	gcry_mpi_mulm(t3, p1->x, p1->x, dp->m);
	gcry_mpi_mulm(t2, t2, t3, dp->m);
	gcry_mpi_mulm(t3, t3, p1->x, dp->m);
	gcry_mpi_mulm(t1, t1, t3, dp->m);
	gcry_mpi_mulm(p1->x, p1->y, p1->y, dp->m);
	gcry_mpi_subm(p1->x, p1->x, t3, dp->m);
	gcry_mpi_subm(p1->x, p1->x, t2, dp->m);
	gcry_mpi_subm(p1->x, p1->x, t2, dp->m);
	gcry_mpi_subm(t2, t2, p1->x, dp->m);
	gcry_mpi_mulm(p1->y, p1->y, t2, dp->m);
	gcry_mpi_subm(p1->y, p1->y, t1, dp->m);
	gcry_mpi_release(t3);
      }
      gcry_mpi_release(t1);
      gcry_mpi_release(t2);
    }
    else
      jacobian_load_affine(p1, p2);
  }
}
Exemplo n.º 12
0
gcry_mpi_t get_random_exponent(const struct curve_params *cp)
{
  int bits = gcry_mpi_get_nbits(cp->dp.order);
  gcry_mpi_t a;
  a = gcry_mpi_snew(0);
  do {
    gcry_mpi_randomize(a, bits, GCRY_STRONG_RANDOM);
    gcry_mpi_clear_highbit(a, bits);
  } while (! gcry_mpi_cmp_ui(a, 0) || gcry_mpi_cmp(a, cp->dp.order) >= 0);
  return a;
}
Exemplo n.º 13
0
GkmDataResult
gkm_data_der_read_private_key_dsa_parts (const guchar *keydata, gsize n_keydata,
                                         const guchar *params, gsize n_params,
                                         gcry_sexp_t *s_key)
{
	gcry_mpi_t p, q, g, y, x;
	GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
	int res;
	GNode *asn_params = NULL;
	GNode *asn_key = NULL;

	p = q = g = y = x = NULL;

	asn_params = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAParameters", params, n_params);
	asn_key = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPrivatePart", keydata, n_keydata);
	if (!asn_params || !asn_key)
		goto done;

	ret = GKM_DATA_FAILURE;

	if (!gkm_data_asn1_read_mpi (egg_asn1x_node (asn_params, "p", NULL), &p) ||
	    !gkm_data_asn1_read_mpi (egg_asn1x_node (asn_params, "q", NULL), &q) ||
	    !gkm_data_asn1_read_mpi (egg_asn1x_node (asn_params, "g", NULL), &g))
		goto done;

	if (!gkm_data_asn1_read_mpi (asn_key, &x))
		goto done;

	/* Now we calculate y */
	y = gcry_mpi_snew (1024);
	gcry_mpi_powm (y, g, x, p);

	res = gcry_sexp_build (s_key, NULL, SEXP_PRIVATE_DSA, p, q, g, y, x);
	if (res)
		goto done;

	g_assert (*s_key);
	ret = GKM_DATA_SUCCESS;

done:
	egg_asn1x_destroy (asn_key);
	egg_asn1x_destroy (asn_params);
	gcry_mpi_release (p);
	gcry_mpi_release (q);
	gcry_mpi_release (g);
	gcry_mpi_release (y);
	gcry_mpi_release (x);

	if (ret == GKM_DATA_FAILURE)
		g_message ("invalid DSA key");

	return ret;
}
Exemplo n.º 14
0
void compress_to_string(char *buf, enum disp_format df,
			const struct affine_point *P, 
			const struct curve_params *cp)
{
  int outlen = (df == DF_COMPACT) ? cp->pk_len_compact : cp->pk_len_bin;
  if (point_compress(P)) {
    gcry_mpi_t x;
    x = gcry_mpi_snew(0);
    gcry_mpi_add(x, P->x, cp->dp.m);
    serialize_mpi(buf, outlen, df, x);
    gcry_mpi_release(x);
  }
  else
    serialize_mpi(buf, outlen, df, P->x);
}
Exemplo n.º 15
0
struct affine_point jacobian_to_affine(const struct jacobian_point *p,
				       const struct domain_params *dp)
{
  struct affine_point r = point_new();
  if (gcry_mpi_cmp_ui(p->z, 0)) {
    gcry_mpi_t h;
    h = gcry_mpi_snew(0);
    gcry_mpi_invm(h, p->z, dp->m);
    gcry_mpi_mulm(r.y, h, h, dp->m);
    gcry_mpi_mulm(r.x, p->x, r.y, dp->m);
    gcry_mpi_mulm(r.y, r.y, h, dp->m);
    gcry_mpi_mulm(r.y, r.y, p->y, dp->m);
    gcry_mpi_release(h);
  }
  return r;
}
Exemplo n.º 16
0
int ECIES_decryption(char *key, const struct affine_point *R,
		     const gcry_mpi_t d, const struct curve_params *cp)
{
  struct affine_point Z;
  gcry_mpi_t e;
  int res = 0;
  if (! embedded_key_validation(R, &cp->dp))
    return 0;
  e = gcry_mpi_snew(0);
  gcry_mpi_mul_ui(e, d, cp->dp.cofactor);
  Z = pointmul(R, e, &cp->dp);
  gcry_mpi_release(e);
  if ((res = ! point_is_zero(&Z)))
    ECIES_KDF(key, Z.x, R, cp->elem_len_bin);
  point_release(&Z);
  return res;
}
Exemplo n.º 17
0
gpointer
egg_dh_gen_secret (gcry_mpi_t peer, gcry_mpi_t priv,
                   gcry_mpi_t prime, gsize *bytes)
{
	gcry_error_t gcry;
	guchar *value;
	gsize n_value;
	gcry_mpi_t k;
	gint bits;

	g_return_val_if_fail (peer, NULL);
	g_return_val_if_fail (priv, NULL);
	g_return_val_if_fail (prime, NULL);

	bits = gcry_mpi_get_nbits (prime);
	g_return_val_if_fail (bits >= 0, NULL);

	k = gcry_mpi_snew (bits);
	g_return_val_if_fail (k, NULL);
	gcry_mpi_powm (k, peer, priv, prime);

	/* Write out the secret */
	gcry = gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &n_value, k);
	g_return_val_if_fail (gcry == 0, NULL);
	value = egg_secure_alloc (n_value);
	gcry = gcry_mpi_print (GCRYMPI_FMT_USG, value, n_value, &n_value, k);
	g_return_val_if_fail (gcry == 0, NULL);

#if DEBUG_DH_SECRET
	g_printerr ("DH SECRET: ");
	gcry_mpi_dump (k);
	gcry_mpi_release (k);
#endif

	*bytes = n_value;

#if DEBUG_DH_SECRET
	gcry_mpi_scan (&k, GCRYMPI_FMT_USG, value, bytes, NULL);
	g_printerr ("RAW SECRET: ");
	gcry_mpi_dump (k);
	gcry_mpi_release (k);
#endif

	return value;
}
Exemplo n.º 18
0
Arquivo: kex.c Projeto: gpg/gsti
static gcry_mpi_t
calc_dh_key (gcry_mpi_t gex_p, gcry_mpi_t f, gcry_mpi_t x)
{
  gcry_mpi_t k, prime;
  size_t n = sizeof diffie_hellman_group1_prime;

  if (gex_p)
      prime = gcry_mpi_copy (gex_p);
  else if (gcry_mpi_scan (&prime, GCRYMPI_FMT_STD,
                          diffie_hellman_group1_prime, n, NULL))
    abort ();

  n = gcry_mpi_get_nbits (prime);
  k = gcry_mpi_snew (n+1);
  gcry_mpi_powm (k, f, x, prime);
  gcry_mpi_release (prime);
  return k;
}
Exemplo n.º 19
0
gboolean
egg_dh_gen_pair (gcry_mpi_t prime, gcry_mpi_t base, guint bits,
                 gcry_mpi_t *pub, gcry_mpi_t *priv)
{
	guint pbits;

	g_return_val_if_fail (prime, FALSE);
	g_return_val_if_fail (base, FALSE);
	g_return_val_if_fail (pub, FALSE);
	g_return_val_if_fail (priv, FALSE);

	pbits = gcry_mpi_get_nbits (prime);
	g_return_val_if_fail (pbits > 1, FALSE);

	if (bits == 0) {
		bits = pbits;
	} else if (bits > pbits) {
		g_return_val_if_reached (FALSE);
	}

	/*
	 * Generate a strong random number of bits, and not zero.
	 * gcry_mpi_randomize bumps up to the next byte. Since we
	 * need to have a value less than half of prime, we make sure
	 * we bump down.
	 */
	*priv = gcry_mpi_snew (bits);
	g_return_val_if_fail (*priv, FALSE);
	while (gcry_mpi_cmp_ui (*priv, 0) == 0)
		gcry_mpi_randomize (*priv, bits, GCRY_STRONG_RANDOM);

	/* Secret key value must be less than half of p */
	if (gcry_mpi_get_nbits (*priv) > bits)
		gcry_mpi_clear_highbit (*priv, bits);
	if (gcry_mpi_get_nbits (*priv) > pbits - 1)
		gcry_mpi_clear_highbit (*priv, pbits - 1);
	g_assert (gcry_mpi_cmp (prime, *priv) > 0);

	*pub = gcry_mpi_new (gcry_mpi_get_nbits (*priv));
	g_return_val_if_fail (*pub, FALSE);
	gcry_mpi_powm (*pub, base, *priv, prime);

	return TRUE;
}
Exemplo n.º 20
0
static gboolean
dsa_subject_public_key_from_private (GNode *key_asn,
                                     const GckAttribute *ap,
                                     const GckAttribute *aq,
                                     const GckAttribute *ag,
                                     const GckAttribute *ax)
{
	gcry_mpi_t mp, mq, mg, mx, my;
	size_t n_buffer;
	gcry_error_t gcry;
	unsigned char *buffer;

	gcry = gcry_mpi_scan (&mp, GCRYMPI_FMT_USG, ap->value, ap->length, NULL);
	g_return_val_if_fail (gcry == 0, FALSE);

	gcry = gcry_mpi_scan (&mq, GCRYMPI_FMT_USG, aq->value, aq->length, NULL);
	g_return_val_if_fail (gcry == 0, FALSE);

	gcry = gcry_mpi_scan (&mg, GCRYMPI_FMT_USG, ag->value, ag->length, NULL);
	g_return_val_if_fail (gcry == 0, FALSE);

	gcry = gcry_mpi_scan (&mx, GCRYMPI_FMT_USG, ax->value, ax->length, NULL);
	g_return_val_if_fail (gcry == 0, FALSE);

	/* Calculate the public part from the private */
	my = gcry_mpi_snew (gcry_mpi_get_nbits (mx));
	g_return_val_if_fail (my, FALSE);
	gcry_mpi_powm (my, mg, mx, mp);

	gcry = gcry_mpi_aprint (GCRYMPI_FMT_STD, &buffer, &n_buffer, my);
	g_return_val_if_fail (gcry == 0, FALSE);
	egg_asn1x_take_integer_as_raw (key_asn, g_bytes_new_with_free_func (buffer, n_buffer,
	                                                                      gcry_free, buffer));

	gcry_mpi_release (mp);
	gcry_mpi_release (mq);
	gcry_mpi_release (mg);
	gcry_mpi_release (mx);
	gcry_mpi_release (my);

	return TRUE;
}
Exemplo n.º 21
0
void serialize_mpi(char *outbuf, int outlen, enum disp_format df, 
		   const gcry_mpi_t x)
{
  switch(df) {
  case DF_BIN: do {
      int len = (gcry_mpi_get_nbits(x) + 7) / 8;
      assert(len <= outlen);
      memset(outbuf, 0, outlen - len);
      gcry_mpi_print(GCRYMPI_FMT_USG, (unsigned char*)outbuf + (outlen - len), 
		     len, NULL, x);
    } while (0);
    break;
    
  case DF_COMPACT:
  case DF_BASE36: do {
    const char *digits = get_digits(df);
    unsigned int digit_count = get_digit_count(df);
    gcry_mpi_t base, Q, R;
    int i;
    base = gcry_mpi_set_ui(NULL, digit_count);
    Q = gcry_mpi_copy(x);
    R = gcry_mpi_snew(0);
    for(i = outlen - 1; i >= 0; i--) {
        unsigned char digit = 0;
        gcry_mpi_div(Q, R, Q, base, 0);        
        gcry_mpi_print(GCRYMPI_FMT_USG, &digit, 1, NULL, R);
        assert(digit < digit_count);
        outbuf[i] = digits[digit];
    }    
    assert(! gcry_mpi_cmp_ui(Q, 0));
    gcry_mpi_release(base);
    gcry_mpi_release(Q);
    gcry_mpi_release(R);
    } while(0);
    break;
  default: 
    assert(0);
  }
}
Exemplo n.º 22
0
/* Check that the RSA secret key SKEY is valid.  Swap parameters to
   the libgcrypt standard.  */
static gpg_error_t
rsa_key_check (struct rsa_secret_key_s *skey)
{
  int err = 0;
  gcry_mpi_t t = gcry_mpi_snew (0);
  gcry_mpi_t t1 = gcry_mpi_snew (0);
  gcry_mpi_t t2 = gcry_mpi_snew (0);
  gcry_mpi_t phi = gcry_mpi_snew (0);

  /* Check that n == p * q.  */
  gcry_mpi_mul (t, skey->p, skey->q);
  if (gcry_mpi_cmp( t, skey->n) )
    {
      log_error ("RSA oops: n != p * q\n");
      err++;
    }

  /* Check that p is less than q.  */
  if (gcry_mpi_cmp (skey->p, skey->q) > 0)
    {
      gcry_mpi_t tmp;

      log_info ("swapping secret primes\n");
      tmp = gcry_mpi_copy (skey->p);
      gcry_mpi_set (skey->p, skey->q);
      gcry_mpi_set (skey->q, tmp);
      gcry_mpi_release (tmp);
      /* Recompute u.  */
      gcry_mpi_invm (skey->u, skey->p, skey->q);
    }

  /* Check that e divides neither p-1 nor q-1.  */
  gcry_mpi_sub_ui (t, skey->p, 1 );
  gcry_mpi_div (NULL, t, t, skey->e, 0);
  if (!gcry_mpi_cmp_ui( t, 0) )
    {
      log_error ("RSA oops: e divides p-1\n");
      err++;
    }
  gcry_mpi_sub_ui (t, skey->q, 1);
  gcry_mpi_div (NULL, t, t, skey->e, 0);
  if (!gcry_mpi_cmp_ui( t, 0))
    {
      log_info ("RSA oops: e divides q-1\n" );
      err++;
    }

  /* Check that d is correct.  */
  gcry_mpi_sub_ui (t1, skey->p, 1);
  gcry_mpi_sub_ui (t2, skey->q, 1);
  gcry_mpi_mul (phi, t1, t2);
  gcry_mpi_invm (t, skey->e, phi);
  if (gcry_mpi_cmp (t, skey->d))
    {
      /* No: try universal exponent. */
      gcry_mpi_gcd (t, t1, t2);
      gcry_mpi_div (t, NULL, phi, t, 0);
      gcry_mpi_invm (t, skey->e, t);
      if (gcry_mpi_cmp (t, skey->d))
        {
          log_error ("RSA oops: bad secret exponent\n");
          err++;
        }
    }

  /* Check for correctness of u.  */
  gcry_mpi_invm (t, skey->p, skey->q);
  if (gcry_mpi_cmp (t, skey->u))
    {
      log_info ("RSA oops: bad u parameter\n");
      err++;
    }

  if (err)
    log_info ("RSA secret key check failed\n");

  gcry_mpi_release (t);
  gcry_mpi_release (t1);
  gcry_mpi_release (t2);
  gcry_mpi_release (phi);

  return err? gpg_error (GPG_ERR_BAD_SECKEY):0;
}
Exemplo n.º 23
0
guchar*
gkm_data_der_write_private_key_rsa (gcry_sexp_t s_key, gsize *n_key)
{
	GNode *asn = NULL;
	gcry_mpi_t n, e, d, p, q, u, e1, e2, tmp;
	guchar *result = NULL;

	n = e = d = p = q = u = e1 = e2 = tmp = NULL;

	asn = egg_asn1x_create (pk_asn1_tab, "RSAPrivateKey");
	g_return_val_if_fail (asn, NULL);

	if (!gkm_sexp_extract_mpi (s_key, &n, "rsa", "n", NULL) ||
	    !gkm_sexp_extract_mpi (s_key, &e, "rsa", "e", NULL) ||
	    !gkm_sexp_extract_mpi (s_key, &d, "rsa", "d", NULL) ||
	    !gkm_sexp_extract_mpi (s_key, &p, "rsa", "p", NULL) ||
	    !gkm_sexp_extract_mpi (s_key, &q, "rsa", "q", NULL) ||
	    !gkm_sexp_extract_mpi (s_key, &u, "rsa", "u", NULL))
		goto done;

	if (!gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "modulus", NULL), n) ||
	    !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "publicExponent", NULL), e) ||
	    !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "privateExponent", NULL), d) ||
	    !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "prime1", NULL), p) ||
	    !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "prime2", NULL), q) ||
	    !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "coefficient", NULL), u))
		goto done;

	/* Calculate e1 and e2 */
	tmp = gcry_mpi_snew (1024);
	gcry_mpi_sub_ui (tmp, p, 1);
	e1 = gcry_mpi_snew (1024);
	gcry_mpi_mod (e1, d, tmp);
	gcry_mpi_sub_ui (tmp, q, 1);
	e2 = gcry_mpi_snew (1024);
	gcry_mpi_mod (e2, d, tmp);

	/* Write out calculated */
	if (!gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "exponent1", NULL), e1) ||
	    !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "exponent2", NULL), e2))
		goto done;

	/* Write out the version */
	if (!egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), 0))
		goto done;

	result = egg_asn1x_encode (asn, egg_secure_realloc, n_key);
	if (result == NULL)
		g_warning ("couldn't encode private rsa key: %s", egg_asn1x_message (asn));

done:
	egg_asn1x_destroy (asn);
	gcry_mpi_release (n);
	gcry_mpi_release (e);
	gcry_mpi_release (d);
	gcry_mpi_release (p);
	gcry_mpi_release (q);
	gcry_mpi_release (u);

	gcry_mpi_release (tmp);
	gcry_mpi_release (e1);
	gcry_mpi_release (e2);

	return result;
}
Exemplo n.º 24
0
static gcry_mpi_t
gen_prime (unsigned int nbits, int secret, int randomlevel, 
           int (*extra_check)(void *, gcry_mpi_t), void *extra_check_arg)
{
  gcry_mpi_t prime, ptest, pminus1, val_2, val_3, result;
  int i;
  unsigned int x, step;
  unsigned int count1, count2;
  int *mods;
  
/*   if (  DBG_CIPHER ) */
/*     log_debug ("generate a prime of %u bits ", nbits ); */

  if (nbits < 16)
    log_fatal ("can't generate a prime with less than %d bits\n", 16);

  mods = gcry_xmalloc( no_of_small_prime_numbers * sizeof *mods );
  /* Make nbits fit into gcry_mpi_t implementation. */
  val_2  = mpi_alloc_set_ui( 2 );
  val_3 = mpi_alloc_set_ui( 3);
  prime  = secret? gcry_mpi_snew ( nbits ): gcry_mpi_new ( nbits );
  result = mpi_alloc_like( prime );
  pminus1= mpi_alloc_like( prime );
  ptest  = mpi_alloc_like( prime );
  count1 = count2 = 0;
  for (;;)
    {  /* try forvever */
      int dotcount=0;
      
      /* generate a random number */
      gcry_mpi_randomize( prime, nbits, randomlevel );
      
      /* 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. */
      mpi_set_highbit (prime, nbits-1);
      if (secret)
        mpi_set_bit (prime, nbits-2);
      mpi_set_bit(prime, 0);
      
      /* Calculate all remainders. */
      for (i=0; (x = small_prime_numbers[i]); i++ )
        mods[i] = mpi_fdiv_r_ui(NULL, prime, x);
      
      /* Now try some primes starting with prime. */
      for(step=0; step < 20000; step += 2 ) 
        {
          /* Check against all the small primes we have in mods. */
          count1++;
          for (i=0; (x = small_prime_numbers[i]); i++ ) 
            {
              while ( mods[i] + step >= x )
                mods[i] -= x;
              if ( !(mods[i] + step) )
                break;
	    }
          if ( x )
            continue;   /* Found a multiple of an already known prime. */
          
          mpi_add_ui( ptest, prime, step );

          /* Do a fast Fermat test now. */
          count2++;
          mpi_sub_ui( pminus1, ptest, 1);
          gcry_mpi_powm( result, val_2, pminus1, ptest );
          if ( !mpi_cmp_ui( result, 1 ) )
            { 
              /* Not composite, perform stronger tests */
              if (is_prime(ptest, 5, &count2 ))
                {
                  if (!mpi_test_bit( ptest, nbits-1-secret ))
                    {
                      progress('\n');
                      log_debug ("overflow in prime generation\n");
                      break; /* Stop loop, continue with a new prime. */
                    }

                  if (extra_check && extra_check (extra_check_arg, ptest))
                    { 
                      /* The extra check told us that this prime is
                         not of the caller's taste. */
                      progress ('/');
                    }
                  else
                    { 
                      /* Got it. */
                      mpi_free(val_2);
                      mpi_free(val_3);
                      mpi_free(result);
                      mpi_free(pminus1);
                      mpi_free(prime);
                      gcry_free(mods);
                      return ptest; 
                    }
                }
	    }
          if (++dotcount == 10 )
            {
              progress('.');
              dotcount = 0;
	    }
	}
      progress(':'); /* restart with a new random value */
    }
}
Exemplo n.º 25
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;
      }
    }
  }
}
Exemplo n.º 26
0
/*create a new MPI number with this many bytes*/
void mpiNew(int bytes,gcry_mpi_t output)
{
	output = gcry_mpi_snew(bytes);

}
Exemplo n.º 27
0
/****************
 * Generate a key pair with a key of size NBITS
 * Returns: 2 structures filled with all needed values
 *	    and an array with n-1 factors of (p-1)
 */
static void
generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors )
{
  gcry_mpi_t p;    /* the prime */
  gcry_mpi_t p_min1;
  gcry_mpi_t g;
  gcry_mpi_t x;    /* the secret exponent */
  gcry_mpi_t y;
  unsigned int qbits;
  unsigned int xbits;
  byte *rndbuf;

  p_min1 = gcry_mpi_new ( nbits );
  qbits = wiener_map( nbits );
  if( qbits & 1 ) /* better have a even one */
    qbits++;
  g = mpi_alloc(1);
  p = _gcry_generate_elg_prime( 0, nbits, qbits, g, ret_factors );
  mpi_sub_ui(p_min1, p, 1);


  /* Select a random number which has these properties:
   *	 0 < x < p-1
   * This must be a very good random number because this is the
   * secret part.  The prime is public and may be shared anyway,
   * so a random generator level of 1 is used for the prime.
   *
   * I don't see a reason to have a x of about the same size
   * as the p.  It should be sufficient to have one about the size
   * of q or the later used k plus a large safety margin. Decryption
   * will be much faster with such an x.
   */
  xbits = qbits * 3 / 2;
  if( xbits >= nbits )
    BUG();
  x = gcry_mpi_snew ( xbits );
  if( DBG_CIPHER )
    log_debug("choosing a random x of size %u", xbits );
  rndbuf = NULL;
  do 
    {
      if( DBG_CIPHER )
        progress('.');
      if( rndbuf )
        { /* Change only some of the higher bits */
          if( xbits < 16 ) /* should never happen ... */
            {
              gcry_free(rndbuf);
              rndbuf = gcry_random_bytes_secure( (xbits+7)/8,
                                                 GCRY_VERY_STRONG_RANDOM );
            }
          else
            {
              char *r = gcry_random_bytes_secure( 2,
                                                  GCRY_VERY_STRONG_RANDOM );
              memcpy(rndbuf, r, 2 );
              gcry_free(r);
            }
	}
      else 
        {
          rndbuf = gcry_random_bytes_secure( (xbits+7)/8,
                                             GCRY_VERY_STRONG_RANDOM );
	}
      _gcry_mpi_set_buffer( x, rndbuf, (xbits+7)/8, 0 );
      mpi_clear_highbit( x, xbits+1 );
    } 
  while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) );
  gcry_free(rndbuf);

  y = gcry_mpi_new (nbits);
  gcry_mpi_powm( y, g, x, p );

  if( DBG_CIPHER ) 
    {
      progress('\n');
      log_mpidump("elg  p= ", p );
      log_mpidump("elg  g= ", g );
      log_mpidump("elg  y= ", y );
      log_mpidump("elg  x= ", x );
    }

  /* Copy the stuff to the key structures */
  sk->p = p;
  sk->g = g;
  sk->y = y;
  sk->x = x;

  gcry_mpi_release ( p_min1 );

  /* Now we can test our keys (this should never fail!) */
  test_keys ( sk, nbits - 64, 0 );
}
Exemplo n.º 28
0
/* Parse a private key S-expression and retutn a malloced array with
   the RSA paramaters in pkcs#12 order.  The caller needs to
   deep-release this array.  */
static gcry_mpi_t *
sexp_to_kparms (gcry_sexp_t sexp)
{
  gcry_sexp_t list, l2;
  const char *name;
  const char *s;
  size_t n;
  int idx;
  const char *elems;
  gcry_mpi_t *array;

  list = gcry_sexp_find_token (sexp, "private-key", 0 );
  if(!list)
    return NULL;
  l2 = gcry_sexp_cadr (list);
  gcry_sexp_release (list);
  list = l2;
  name = gcry_sexp_nth_data (list, 0, &n);
  if(!name || n != 3 || memcmp (name, "rsa", 3))
    {
      gcry_sexp_release (list);
      return NULL;
    }

  /* Parameter names used with RSA in the pkcs#12 order. */
  elems = "nedqp--u";
  array = xtrycalloc (strlen(elems) + 1, sizeof *array);
  if (!array)
    {
      gcry_sexp_release (list);
      return NULL;
    }
  for (idx=0, s=elems; *s; s++, idx++ )
    {
      if (*s == '-')
        continue; /* Computed below  */
      l2 = gcry_sexp_find_token (list, s, 1);
      if (l2)
        {
          array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
          gcry_sexp_release (l2);
        }
      if (!array[idx]) /* Required parameter not found or invalid.  */
        {
          for (idx=0; array[idx]; idx++)
            gcry_mpi_release (array[idx]);
          xfree (array);
          gcry_sexp_release (list);
          return NULL;
        }
    }
  gcry_sexp_release (list);

  array[5] = gcry_mpi_snew (0);  /* compute d mod (q-1) */
  gcry_mpi_sub_ui (array[5], array[3], 1);
  gcry_mpi_mod (array[5], array[2], array[5]);

  array[6] = gcry_mpi_snew (0);  /* compute d mod (p-1) */
  gcry_mpi_sub_ui (array[6], array[4], 1);
  gcry_mpi_mod (array[6], array[3], array[6]);

  return array;
}