예제 #1
0
파일: kex.c 프로젝트: gpg/gsti
static void
dump_gex_group (gsti_ctx_t ctx, MSG_gexdh_group * gex)
{
  _gsti_log_debug (ctx, "MSG_gex_group:\n");
  _gsti_log_debug (ctx, "prime %d bits, generator %d bits\n",
                   gcry_mpi_get_nbits (gex->p), gcry_mpi_get_nbits (gex->g));
}
예제 #2
0
char *ssh_gcry_bn2dec(bignum bn) {
  bignum bndup, num, ten;
  char *ret;
  int count, count2;
  int size, rsize;
  char decnum;

  size = gcry_mpi_get_nbits(bn) * 3;
  rsize = size / 10 + size / 1000 + 2;

  ret = malloc(rsize + 1);
  if (ret == NULL) {
    return NULL;
  }

  if (!gcry_mpi_cmp_ui(bn, 0)) {
    strcpy(ret, "0");
  } else {
    ten = bignum_new();
    if (ten == NULL) {
      SAFE_FREE(ret);
      return NULL;
    }

    num = bignum_new();
    if (num == NULL) {
      SAFE_FREE(ret);
      bignum_safe_free(ten);
      return NULL;
    }

    for (bndup = gcry_mpi_copy(bn), bignum_set_word(ten, 10), count = rsize;
        count; count--) {
      gcry_mpi_div(bndup, num, bndup, ten, 0);
      for (decnum = 0, count2 = gcry_mpi_get_nbits(num); count2;
          decnum *= 2, decnum += (gcry_mpi_test_bit(num, count2 - 1) ? 1 : 0),
          count2--)
        ;
      ret[count - 1] = decnum + '0';
    }
    for (count = 0; count < rsize && ret[count] == '0'; count++)
      ;
    for (count2 = 0; count2 < rsize - count; ++count2) {
      ret[count2] = ret[count2 + count];
    }
    ret[count2] = 0;
    bignum_safe_free(num);
    bignum_safe_free(bndup);
    bignum_safe_free(ten);
  }

  return ret;
}
예제 #3
0
파일: kex.c 프로젝트: 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;
}
예제 #4
0
파일: certcheck.c 프로젝트: 0ndorio/gnupg
/* Return the number of bits of the Q parameter from the DSA key
   KEY.  */
static unsigned int
get_dsa_qbits (gcry_sexp_t key)
{
  gcry_sexp_t l1, l2;
  gcry_mpi_t q;
  unsigned int nbits;

  l1 = gcry_sexp_find_token (key, "public-key", 0);
  if (!l1)
    return 0; /* Does not contain a key object.  */
  l2 = gcry_sexp_cadr (l1);
  gcry_sexp_release  (l1);
  l1 = gcry_sexp_find_token (l2, "q", 1);
  gcry_sexp_release (l2);
  if (!l1)
    return 0; /* Invalid object.  */
  q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
  gcry_sexp_release (l1);
  if (!q)
    return 0; /* Missing value.  */
  nbits = gcry_mpi_get_nbits (q);
  gcry_mpi_release (q);

  return nbits;
}
예제 #5
0
/*
 * Write the mpi A to OUT.
 */
gpg_error_t
gpg_mpi_write (iobuf_t out, gcry_mpi_t a)
{
  int rc;

  if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
    {
      unsigned int nbits;
      const void *p;

      p = gcry_mpi_get_opaque (a, &nbits);
      rc = iobuf_write (out, p, (nbits+7)/8);
    }
  else
    {
      char buffer[(MAX_EXTERN_MPI_BITS+7)/8+2]; /* 2 is for the mpi length. */
      size_t nbytes;

      nbytes = DIM(buffer);
      rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, &nbytes, a );
      if( !rc )
        rc = iobuf_write( out, buffer, nbytes );
      else if (gpg_err_code(rc) == GPG_ERR_TOO_SHORT )
        {
          log_info ("mpi too large (%u bits)\n", gcry_mpi_get_nbits (a));
          /* The buffer was too small. We better tell the user about the MPI. */
          rc = gpg_error (GPG_ERR_TOO_LARGE);
        }
    }

  return rc;
}
예제 #6
0
/**
 * cdk_pk_get_nbits:
 * @pk: the public key
 * 
 * Return the length of the public key in bits.
 * The meaning of length is actually the size of the 'prime'
 * object in the key. For RSA keys the modulus, for ElG/DSA
 * the size of the public prime.
 **/
int
cdk_pk_get_nbits (cdk_pubkey_t pk)
{
  if (!pk || !pk->mpi[0])
    return 0;
  return gcry_mpi_get_nbits (pk->mpi[0]);
}
예제 #7
0
gboolean
egg_dh_default_params (const gchar *name, gcry_mpi_t *prime, gcry_mpi_t *base)
{
	const DHGroup *group;
	gcry_error_t gcry;

	g_return_val_if_fail (name, FALSE);

	for (group = dh_groups; group->name; ++group) {
		if (g_str_equal (group->name, name)) {
			if (prime) {
				gcry = gcry_mpi_scan (prime, GCRYMPI_FMT_USG, group->prime, group->n_prime, NULL);
				g_return_val_if_fail (gcry == 0, FALSE);
				g_return_val_if_fail (gcry_mpi_get_nbits (*prime) == group->bits, FALSE);
			}
			if (base) {
				gcry = gcry_mpi_scan (base, GCRYMPI_FMT_USG, group->base, group->n_base, NULL);
				g_return_val_if_fail (gcry == 0, FALSE);
			}
			return TRUE;
		}
	}

	return FALSE;
}
예제 #8
0
/*
 * Write the sexp A to OUT.
 */
static int
sexp_write (iobuf_t out, gcry_sexp_t a)
{
	int max_len = 2000;
  char buffer[max_len];
  size_t nbytes;
  int rc;
  int len;

  len = gcry_sexp_sprint (a, 1, buffer, max_len);
  printf("after sexp sprint %d \n", len);
  if( len!=0 )
  {
	  nbytes = 0;
	  while(buffer[nbytes]!=0)
	  {
		  printf("%c",buffer[nbytes]);
		  nbytes++;
	  }
	  rc = iobuf_write( out, buffer, len );
	  printf("\n finished writing buf\n");
  }
  else if (gpg_err_code(rc) == GPG_ERR_TOO_SHORT )
    {
      log_info ("mpi too large (%u bits)\n", gcry_mpi_get_nbits (a));
      /* The buffer was too small. We better tell the user about the MPI. */
      rc = gpg_error (GPG_ERR_TOO_LARGE);
    }

  return rc;
}
예제 #9
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;
}
예제 #10
0
파일: fsprg.c 프로젝트: poettering/fsprg
static void mpi_export(void *buf, size_t buflen, const gcry_mpi_t x) {
        unsigned len;
        size_t nwritten;

        assert(gcry_mpi_cmp_ui(x, 0) >= 0);
        len = (gcry_mpi_get_nbits(x) + 7) / 8;
        assert(len <= buflen);
        memset(buf, 0, buflen);
        gcry_mpi_print(GCRYMPI_FMT_USG, buf + (buflen - len), len, &nwritten, x);
        assert(nwritten == len);
}
예제 #11
0
파일: fsprg.c 프로젝트: poettering/fsprg
static gcry_mpi_t mpi_import(const void *buf, size_t buflen) {
        gcry_mpi_t h;
        unsigned len;

        gcry_mpi_scan(&h, GCRYMPI_FMT_USG, buf, buflen, NULL);
        len = (gcry_mpi_get_nbits(h) + 7) / 8;
        assert(len <= buflen);
        assert(gcry_mpi_cmp_ui(h, 0) >= 0);

        return h;
}
예제 #12
0
파일: protocol.c 프로젝트: asciimoo/PyECC
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;
}
예제 #13
0
/* Allocate a bit string consisting of '0' and '1' from the MPI A.  Do
   not return any leading zero bits. Caller needs to xfree the
   result. */
static char *
mpi2bitstr_nlz (gcry_mpi_t a)
{
  char *p, *buf;
  size_t length = gcry_mpi_get_nbits (a);
  
  buf = p = xmalloc (length + 1);
  while (length-- > 1)
    *p++ = gcry_mpi_test_bit (a, length) ? '1':'0';
  *p++ = gcry_mpi_test_bit (a, 0) ? '1':'0';
  *p = 0;

  return buf;
}
예제 #14
0
파일: ecc.c 프로젝트: HarryR/ffff-dnsp2p
struct affine_point pointmul(const struct affine_point *p,
			     const gcry_mpi_t exp, 
			     const struct domain_params *dp)
{
  struct affine_point r = point_new();
  int n = gcry_mpi_get_nbits(exp);
  while (n) {
    point_double(&r, dp);
    if (gcry_mpi_test_bit(exp, --n))
      point_add(&r, p, dp);
  }
  assert(point_on_curve(&r, dp));
  return r;
}
예제 #15
0
static unsigned long
mpz_trailing_zeroes (gcry_mpi_t n)
{
  unsigned int idx, cnt;

  cnt = gcry_mpi_get_nbits (n);
  for (idx = 0; idx < cnt; idx++)
  {
    if (gcry_mpi_test_bit (n, idx) == 0)
      return idx;
  }

  return ULONG_MAX;
}
예제 #16
0
파일: ecc.c 프로젝트: HarryR/ffff-dnsp2p
struct affine_point pointmul(const struct affine_point *p,
			     const gcry_mpi_t exp, 
			     const struct domain_params *dp)
{
  struct jacobian_point r = jacobian_new();
  struct affine_point R;
  int n = gcry_mpi_get_nbits(exp);
  while (n) {
    jacobian_double(&r, dp);
    if (gcry_mpi_test_bit(exp, --n))
      jacobian_affine_point_add(&r, p, dp);
  }
  R = jacobian_to_affine(&r, dp);
  jacobian_release(&r);
  assert(point_on_curve(&R, dp));
  return R;
}
예제 #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;
}
예제 #18
0
파일: crypto_rsa.c 프로젝트: tg-x/gnunet
/**
 * Obtain the length of the RSA key in bits.
 *
 * @param key the public key to introspect
 * @return length of the key in bits
 */
unsigned int
GNUNET_CRYPTO_rsa_public_key_len (const struct GNUNET_CRYPTO_rsa_PublicKey *key)
{
  gcry_mpi_t n;
  int ret;
  unsigned int rval;

  ret = key_from_sexp (&n, key->sexp, "rsa", "n");
  if (0 != ret)
  {
    /* this is no public RSA key */
    GNUNET_break (0);
    return 0;
  }
  rval = gcry_mpi_get_nbits (n);
  gcry_mpi_release (n);
  return rval;
}
예제 #19
0
파일: kex.c 프로젝트: 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;
}
예제 #20
0
static cdk_error_t
mpi_to_buffer (gcry_mpi_t a, byte *buf, size_t buflen,
	       size_t *r_nwritten, size_t *r_nbits)
{
  size_t nbits;
  
  if (!a || !buf || !r_nwritten)
    return CDK_Inv_Value;
  
  nbits = gcry_mpi_get_nbits (a);
  if (r_nbits)
    *r_nbits = nbits;
  if ((nbits+7)/8+2 > buflen)
    return CDK_Too_Short;
  *r_nwritten = (nbits+7)/8+2;
  if (gcry_mpi_print (GCRYMPI_FMT_PGP, buf, buflen, r_nwritten, a))
    return CDK_Wrong_Format;
  return 0;
}
예제 #21
0
파일: keygen.c 프로젝트: uvbs/SupportCenter
static int
gcry_mpi_to_native( cdk_keygen_ctx_t hd, size_t nkey, int type,
                    cdk_pkt_pubkey_t pk, cdk_pkt_seckey_t sk )
{
    gcry_mpi_t * resarr;
    cdk_mpi_t a = NULL;
    size_t nbytes;
    int i = 0, j = 0, nbits;
    int rc = 0;

    if( !hd )
        return CDK_Inv_Value;
    if( !pk && !sk )
        return CDK_Inv_Value;
    if( type < 0 || type > 1 )
        return CDK_Inv_Value;

    resarr = hd->key[type].resarr;
    if( sk )
        i += cdk_pk_get_npkey( sk->pubkey_algo );
    while( j != nkey ) {
        nbits = gcry_mpi_get_nbits( resarr[i] );
        if( pk )
            a = cdk_calloc( 1, sizeof * a + (nbits + 7) / 8 + 2 + 1 );
        else if( sk )
            a = cdk_salloc( sizeof * a + (nbits + 7) / 8 + 2 + 1, 1 );
        a->bits = nbits;
        a->bytes = ( nbits + 7 ) / 8;
        nbytes = a->bytes;
        a->data[0] = nbits >> 8;
        a->data[1] = nbits;
        rc = gcry_mpi_print( GCRYMPI_FMT_USG, a->data+2, nbytes, &nbytes, resarr[i] );
        if( rc )
            break;
        if( pk )
            pk->mpi[j++] = a;
        else if( sk )
            sk->mpi[j++] = a;
        i++;
    }
    return rc;
}
예제 #22
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;
}
예제 #23
0
/*
 * Write the mpi A to OUT.
 */
static int
mpi_write (iobuf_t out, gcry_mpi_t a)
{
  char buffer[(MAX_EXTERN_MPI_BITS+7)/8+2]; /* 2 is for the mpi length. */
  size_t nbytes;
  int rc;

  nbytes = DIM(buffer);
  rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, &nbytes, a );
  if( !rc )
    rc = iobuf_write( out, buffer, nbytes );
  else if (gpg_err_code(rc) == GPG_ERR_TOO_SHORT )
    {
      log_info ("mpi too large (%u bits)\n", gcry_mpi_get_nbits (a));
      /* The buffer was too small. We better tell the user about the MPI. */
      rc = gpg_error (GPG_ERR_TOO_LARGE);
    }

  return rc;
}
예제 #24
0
파일: kex.c 프로젝트: gpg/gsti
static gsti_error_t
check_dh_mpi_range (gcry_mpi_t gex_p, gcry_mpi_t chk)
{
  gsti_error_t err = 0;
  gcry_mpi_t p;

  /* A value which is not in the range [1, p-1] is considered as a
     protocol violation.  */
  if (gex_p)
      p = gcry_mpi_copy (gex_p);
  else if (gcry_mpi_scan (&p, GCRYMPI_FMT_STD, diffie_hellman_group1_prime,
                          sizeof diffie_hellman_group1_prime, NULL))
#warning why abort?
    abort ();
  if (gcry_mpi_cmp (chk, p) > 0 || gcry_mpi_get_nbits (chk) < 2)
    err = gsti_error (GPG_ERR_PROTOCOL_VIOLATION);
  gcry_mpi_release (p);
  
  return err;
}
예제 #25
0
파일: fsprg.c 프로젝트: poettering/fsprg
void FSPRG_GenMK(void *msk, void *mpk, const void *seed, size_t seedlen, unsigned _secpar) {
        uint8_t iseed[FSPRG_RECOMMENDED_SEEDLEN];
        gcry_mpi_t n, p, q;
        uint16_t secpar;

        VALIDATE_SECPAR(_secpar);
        secpar = _secpar;

        initialize_libgcrypt();

        if (!seed) {
                gcry_randomize(iseed, FSPRG_RECOMMENDED_SEEDLEN, GCRY_STRONG_RANDOM);
                seed = iseed;
                seedlen = FSPRG_RECOMMENDED_SEEDLEN;
        }

        p = genprime3mod4(secpar / 2, seed, seedlen, RND_GEN_P);
        q = genprime3mod4(secpar / 2, seed, seedlen, RND_GEN_Q);

        if (msk) {
                store_secpar(msk + 0, secpar);
                mpi_export(msk + 2 + 0 * (secpar / 2) / 8, (secpar / 2) / 8, p);
                mpi_export(msk + 2 + 1 * (secpar / 2) / 8, (secpar / 2) / 8, q);
        }

        if (mpk) {
                n = gcry_mpi_new(0);
                gcry_mpi_mul(n, p, q);
                assert(gcry_mpi_get_nbits(n) == secpar);

                store_secpar(mpk + 0, secpar);
                mpi_export(mpk + 2, secpar / 8, n);

                gcry_mpi_release(n);
        }

        gcry_mpi_release(p);
        gcry_mpi_release(q);
}
예제 #26
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);
  }
}
예제 #27
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);
}
예제 #28
0
int get_serialization_len(const gcry_mpi_t x, enum disp_format df)
{
  int res;
  switch(df) {
  case DF_BIN:
    res = (gcry_mpi_get_nbits(x) + 7) / 8;
    break;
  case DF_BASE36:
  case DF_COMPACT:  
    do {
      gcry_mpi_t base, Q;
      base = gcry_mpi_set_ui(NULL, get_digit_count(df));
      Q = gcry_mpi_copy(x);
      for(res = 0; gcry_mpi_cmp_ui(Q, 0); res++)
	gcry_mpi_div(Q, NULL, Q, base, 0);
      gcry_mpi_release(base);
      gcry_mpi_release(Q);
    } while (0);
    break;
  default:
    assert(0);
  }
  return res;
}
예제 #29
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);
}
예제 #30
0
/**
 * Return true if n is probably a prime
 */
static int
is_prime (gcry_mpi_t n, int steps, struct GNUNET_HashCode * hc)
{
  gcry_mpi_t x;
  gcry_mpi_t y;
  gcry_mpi_t z;
  gcry_mpi_t nminus1;
  gcry_mpi_t a2;
  gcry_mpi_t q;
  unsigned int i, j, k;
  int rc = 0;
  unsigned int nbits;

  x = gcry_mpi_new (0);
  y = gcry_mpi_new (0);
  z = gcry_mpi_new (0);
  nminus1 = gcry_mpi_new (0);
  a2 = gcry_mpi_set_ui (NULL, 2);

  nbits = gcry_mpi_get_nbits (n);
  gcry_mpi_sub_ui (nminus1, n, 1);

  /* Find q and k, so that n = 1 + 2^k * q . */
  q = gcry_mpi_set (NULL, nminus1);
  k = mpz_trailing_zeroes (q);
  mpz_tdiv_q_2exp (q, q, k);

  for (i = 0; i < steps; i++)
  {
    if (!i)
    {
      gcry_mpi_set_ui (x, 2);
    }
    else
    {
      mpz_randomize (x, nbits - 1, hc);
      GNUNET_assert (gcry_mpi_cmp (x, nminus1) < 0);
      GNUNET_assert (gcry_mpi_cmp_ui (x, 1) > 0);
    }
    gcry_mpi_powm (y, x, q, n);
    if (gcry_mpi_cmp_ui (y, 1) && gcry_mpi_cmp (y, nminus1))
    {
      for (j = 1; j < k && gcry_mpi_cmp (y, nminus1); j++)
      {
        gcry_mpi_powm (y, y, a2, n);
        if (!gcry_mpi_cmp_ui (y, 1))
          goto leave;           /* Not a prime. */
      }
      if (gcry_mpi_cmp (y, nminus1))
        goto leave;             /* Not a prime. */
    }
  }
  rc = 1;                       /* May be a prime. */

leave:
  gcry_mpi_release (x);
  gcry_mpi_release (y);
  gcry_mpi_release (z);
  gcry_mpi_release (nminus1);
  gcry_mpi_release (q);
  gcry_mpi_release (a2);

  return rc;
}