コード例 #1
0
ファイル: t-mpi-point.c プロジェクト: Distrotech/libgcrypt
static void
context_alloc (void)
{
  gpg_error_t err;
  gcry_ctx_t ctx;
  gcry_mpi_t p, a;

  wherestr = "context_alloc";
  show ("checking context functions\n");

  p = gcry_mpi_set_ui (NULL, 1);
  a = gcry_mpi_set_ui (NULL, 1);
  err = ec_p_new (&ctx, p, a);
  if (err)
    die ("ec_p_new returned an error: %s\n", gpg_strerror (err));
  gcry_mpi_release (p);
  gcry_mpi_release (a);
  gcry_ctx_release (ctx);

  p = NULL;
  a = gcry_mpi_set_ui (NULL, 0);

  err = ec_p_new (&ctx, p, a);
  if (!err || gpg_err_code (err) != GPG_ERR_EINVAL)
    fail ("ec_p_new: bad parameter detection failed (1)\n");

  gcry_mpi_release (a);
  a = NULL;
  err = ec_p_new (&ctx, p, a);
  if (!err || gpg_err_code (err) != GPG_ERR_EINVAL)
    fail ("ec_p_new: bad parameter detection failed (2)\n");

}
コード例 #2
0
ファイル: crypto_ecc_dlog.c プロジェクト: muggenhor/GNUnet
/**
 * Multiply the generator g of the elliptic curve by @a val
 * to obtain the point on the curve representing @a val.
 * Afterwards, point addition will correspond to integer
 * addition.  #GNUNET_CRYPTO_ecc_dlog() can be used to
 * convert a point back to an integer (as long as the
 * integer is smaller than the MAX of the @a edc context).
 *
 * @param edc calculation context for ECC operations
 * @param val value to encode into a point
 * @return representation of the value as an ECC point,
 *         must be freed using #GNUNET_CRYPTO_ecc_free()
 */
gcry_mpi_point_t
GNUNET_CRYPTO_ecc_dexp (struct GNUNET_CRYPTO_EccDlogContext *edc,
			int val)
{
  gcry_mpi_t fact;
  gcry_mpi_t n;
  gcry_mpi_point_t g;
  gcry_mpi_point_t r;

  g = gcry_mpi_ec_get_point ("g", edc->ctx, 0);
  GNUNET_assert (NULL != g);
  fact = gcry_mpi_new (0);
  if (val < 0)
  {
    n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1);
    gcry_mpi_set_ui (fact, - val);
    gcry_mpi_sub (fact, n, fact);
    gcry_mpi_release (n);
  }
  else
  {
    gcry_mpi_set_ui (fact, val);
  }
  r = gcry_mpi_point_new (0);
  gcry_mpi_ec_mul (r, fact, g, edc->ctx);
  gcry_mpi_release (fact);
  gcry_mpi_point_release (g);
  return r;
}
コード例 #3
0
ファイル: crypto_ecc_dlog.c プロジェクト: muggenhor/GNUnet
/**
 * Do pre-calculation for ECC discrete logarithm for small factors.
 *
 * @param max maximum value the factor can be
 * @param mem memory to use (should be smaller than @a max), must not be zero.
 * @return @a max if dlog failed, otherwise the factor
 */
struct GNUNET_CRYPTO_EccDlogContext *
GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max,
				unsigned int mem)
{
  struct GNUNET_CRYPTO_EccDlogContext *edc;
  unsigned int K = ((max + (mem-1)) / mem);
  gcry_mpi_point_t g;
  struct GNUNET_PeerIdentity key;
  gcry_mpi_point_t gKi;
  gcry_mpi_t fact;
  gcry_mpi_t n;
  unsigned int i;

  GNUNET_assert (max < INT32_MAX);
  edc = GNUNET_new (struct GNUNET_CRYPTO_EccDlogContext);
  edc->max = max;
  edc->mem = mem;

  edc->map = GNUNET_CONTAINER_multipeermap_create (mem * 2,
						   GNUNET_NO);

  GNUNET_assert (0 == gcry_mpi_ec_new (&edc->ctx,
				       NULL,
				       CURVE));
  g = gcry_mpi_ec_get_point ("g", edc->ctx, 0);
  GNUNET_assert (NULL != g);
  fact = gcry_mpi_new (0);
  gKi = gcry_mpi_point_new (0);
  for (i=0;i<=mem;i++)
  {
    gcry_mpi_set_ui (fact, i * K);
    gcry_mpi_ec_mul (gKi, fact, g, edc->ctx);
    extract_pk (gKi, edc->ctx, &key);
    GNUNET_assert (GNUNET_OK ==
		   GNUNET_CONTAINER_multipeermap_put (edc->map,
						      &key,
						      (void*) (long) i + max,
						      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
  }
  /* negative values */
  n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1);
  for (i=1;i<mem;i++)
  {
    gcry_mpi_set_ui (fact, i * K);
    gcry_mpi_sub (fact, n, fact);
    gcry_mpi_ec_mul (gKi, fact, g, edc->ctx);
    extract_pk (gKi, edc->ctx, &key);
    GNUNET_assert (GNUNET_OK ==
		   GNUNET_CONTAINER_multipeermap_put (edc->map,
						      &key,
						      (void*) (long) max - i,
						      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
  }
  gcry_mpi_release (fact);
  gcry_mpi_release (n);
  gcry_mpi_point_release (gKi);
  gcry_mpi_point_release (g);
  return edc;
}
コード例 #4
0
/**
 * Do some DLOG operations for testing.
 *
 * @param edc context for ECC operations
 * @param do_dlog #GNUNET_YES if we want to actually do the bencharked operation
 */
static void
test_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc, 
           int do_dlog)
{
  gcry_mpi_t fact;
  gcry_mpi_t n;
  gcry_ctx_t ctx;
  gcry_mpi_point_t q;
  gcry_mpi_point_t g;
  unsigned int i;
  int x;
  int iret;

  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
  g = gcry_mpi_ec_get_point ("g", ctx, 0);
  GNUNET_assert (NULL != g);
  n = gcry_mpi_ec_get_mpi ("n", ctx, 0);
  q = gcry_mpi_point_new (0);
  fact = gcry_mpi_new (0);
  for (i=0;i<TEST_ITER;i++)
  {
    fprintf (stderr, ".");
    x = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
				  MAX_FACT);
    if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
				       2))
    {
      gcry_mpi_set_ui (fact, x);
      gcry_mpi_sub (fact, n, fact);
      x = - x;
    }
    else 
    {
      gcry_mpi_set_ui (fact, x);
    }
    gcry_mpi_ec_mul (q, fact, g, ctx);
    if ( (GNUNET_YES == do_dlog) &&
	 (x !=
	  (iret = GNUNET_CRYPTO_ecc_dlog (edc,
					  q))) )
    {
      fprintf (stderr, 
	       "DLOG failed for value %d (%d)\n", 
	       x,
	       iret);
      GNUNET_assert (0);
    }
  }
  gcry_mpi_release (fact);
  gcry_mpi_release (n);
  gcry_mpi_point_release (g);
  gcry_mpi_point_release (q);
  gcry_ctx_release (ctx);
  fprintf (stderr, "\n");
}
コード例 #5
0
ファイル: ecc.c プロジェクト: HarryR/ffff-dnsp2p
void jacobian_load_affine(struct jacobian_point *p1,
			  const struct affine_point *p2)
{
  if (! point_is_zero(p2)) {
    gcry_mpi_set(p1->x, p2->x);
    gcry_mpi_set(p1->y, p2->y);
    gcry_mpi_set_ui(p1->z, 1);
  }
  else
    gcry_mpi_set_ui(p1->z, 0);
}
コード例 #6
0
ファイル: privkey.c プロジェクト: adhux/libotr-3.2.1
/* Verify a signature on data using a public key.  The data must be
 * small enough to be signed (i.e. already hashed, if necessary). */
gcry_error_t otrl_privkey_verify(const unsigned char *sigbuf, size_t siglen,
	unsigned short pubkey_type, gcry_sexp_t pubs,
	const unsigned char *data, size_t len)
{
    gcry_error_t err;
    gcry_mpi_t datampi,r,s;
    gcry_sexp_t datas, sigs;

    if (pubkey_type != OTRL_PUBKEY_TYPE_DSA || siglen != 40)
	return gcry_error(GPG_ERR_INV_VALUE);

    if (len) {
	gcry_mpi_scan(&datampi, GCRYMPI_FMT_USG, data, len, NULL);
    } else {
	datampi = gcry_mpi_set_ui(NULL, 0);
    }
    gcry_sexp_build(&datas, NULL, "(%m)", datampi);
    gcry_mpi_release(datampi);
    gcry_mpi_scan(&r, GCRYMPI_FMT_USG, sigbuf, 20, NULL);
    gcry_mpi_scan(&s, GCRYMPI_FMT_USG, sigbuf+20, 20, NULL);
    gcry_sexp_build(&sigs, NULL, "(sig-val (dsa (r %m)(s %m)))", r, s);
    gcry_mpi_release(r);
    gcry_mpi_release(s);

    err = gcry_pk_verify(sigs, datas, pubs);
    gcry_sexp_release(datas);
    gcry_sexp_release(sigs);

    return err;
}
コード例 #7
0
ファイル: t-mpi-bit.c プロジェクト: Chronic-Dev/libgcrypt
/* This is to check a bug reported by bpgcrypt at itaparica.org on
   2006-07-31 against libgcrypt 1.2.2.  */
static void
one_bit_only (int highbit)
{
  gcry_mpi_t a;
  char *result;
  int i;

  wherestr = "one_bit_only";
  show ("checking that set_%sbit does only set one bit\n", highbit?"high":"");

  a = gcry_mpi_new (0);
  gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM);
  gcry_mpi_set_ui (a, 0);

  if (highbit)
    gcry_mpi_set_highbit (a, 42);
  else
    gcry_mpi_set_bit (a, 42);
  if (!gcry_mpi_test_bit (a, 42))
    fail ("failed to set a bit\n");
  gcry_mpi_clear_bit (a, 42);
  if (gcry_mpi_test_bit (a, 42))
    fail ("failed to clear a bit\n");
  result = mpi2bitstr (a, 70);
  assert (strlen (result) == 70);
  for (i=0; result[i]; i++)
    if ( result[i] != '0' )
      break;
  if (result[i])
    fail ("spurious bits detected\n");
  xfree (result);
  gcry_mpi_release (a);
}
コード例 #8
0
ファイル: ecc.c プロジェクト: HarryR/ffff-dnsp2p
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);
  }
}
コード例 #9
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;
}
コード例 #10
0
ファイル: kex.c プロジェクト: gpg/gsti
gsti_error_t
_gsti_kex_send_gex_group (gsti_ctx_t ctx)
{
  gsti_error_t err;
  MSG_gexdh_group gex;
  const byte *mod;
  size_t n;

  memset (&gex, 0, sizeof gex);

  gex.g = gcry_mpi_set_ui (NULL, 2);
  mod = select_dh_modulus (ctx->gex.n, &n);
  err = gcry_mpi_scan (&gex.p, GCRYMPI_FMT_USG, mod, n, NULL);
  if (!err)
    err = build_gex_group (&gex, &ctx->pkt);
  if (!err)
    err = _gsti_packet_write (ctx, &ctx->pkt);
  if (!err)
    err = _gsti_packet_flush (ctx);
  
  /*free_gex_group (&gex);
    We store the DH group exchange values for later use */
  ctx->kex.p = gex.p;
  ctx->kex.g = gex.g;
  
  return err;
}
コード例 #11
0
ファイル: fsprg.c プロジェクト: poettering/fsprg
/* compute 2^m (mod phi(p)), for a prime p */
static gcry_mpi_t twopowmodphi(uint64_t m, const gcry_mpi_t p) {
        gcry_mpi_t phi, r;
        int n;

        phi = gcry_mpi_new(0);
        gcry_mpi_sub_ui(phi, p, 1);

        /* count number of used bits in m */
        for (n = 0; ((uint64_t)1 << n) <= m; n++)
                ;

        r = gcry_mpi_new(0);
        gcry_mpi_set_ui(r, 1);
        while (n) { /* square and multiply algorithm for fast exponentiation */
                n--;
                gcry_mpi_mulm(r, r, r, phi);
                if (m & ((uint64_t)1 << n)) {
                        gcry_mpi_add(r, r, r);
                        if (gcry_mpi_cmp(r, phi) >= 0)
                                gcry_mpi_sub(r, r, phi);
                }
        }

        gcry_mpi_release(phi);
        return r;
}
コード例 #12
0
ファイル: gka.c プロジェクト: totakura/gotr
void gotr_ecbd_gen_flake_key(gcry_mpi_point_t *ret,
							 gcry_mpi_point_t y0,
							 gcry_mpi_t r1,
							 gcry_mpi_point_t R1,
							 gcry_mpi_point_t R0,
							 gcry_mpi_point_t V1)
{
	gcry_mpi_point_t tmp = gcry_mpi_point_new(0);
	gcry_mpi_t n = gcry_mpi_new(0);

	gcry_mpi_point_release(*ret);
	*ret = gcry_mpi_point_new(0);

	gcry_mpi_mul_ui(n, r1, 4);
	gcry_mpi_ec_mul(*ret, n, y0, edctx);

	gcry_mpi_set_ui(n, 3);
	gcry_mpi_ec_mul(tmp, n, R1, edctx);
	gcry_mpi_ec_add(*ret, *ret, tmp, edctx);

	gcry_mpi_ec_dup(tmp, R0, edctx);
	gcry_mpi_ec_add(*ret, *ret, tmp, edctx);

	gcry_mpi_ec_add(*ret, *ret, V1, edctx);

	gcry_mpi_point_release(tmp);
	gcry_mpi_release(n);
}
コード例 #13
0
ファイル: t-mpi-point.c プロジェクト: Greenchik/libgcrypt
static void
set_get_point (void)
{
  gcry_mpi_point_t point;
  gcry_mpi_t x, y, z;

  wherestr = "set_get_point";
  show ("checking point setting functions\n");

  point = gcry_mpi_point_new (0);
  x = gcry_mpi_set_ui (NULL, 17);
  y = gcry_mpi_set_ui (NULL, 42);
  z = gcry_mpi_set_ui (NULL, 11371);
  gcry_mpi_point_get (x, y, z, point);
  if (gcry_mpi_cmp_ui (x, 0)
      || gcry_mpi_cmp_ui (y, 0) || gcry_mpi_cmp_ui (z, 0))
    fail ("new point not initialized to (0,0,0)\n");
  gcry_mpi_point_snatch_get (x, y, z, point);
  point = NULL;
  if (gcry_mpi_cmp_ui (x, 0)
      || gcry_mpi_cmp_ui (y, 0) || gcry_mpi_cmp_ui (z, 0))
    fail ("snatch_get failed\n");
  gcry_mpi_release (x);
  gcry_mpi_release (y);
  gcry_mpi_release (z);

  point = gcry_mpi_point_new (0);
  x = gcry_mpi_set_ui (NULL, 17);
  y = gcry_mpi_set_ui (NULL, 42);
  z = gcry_mpi_set_ui (NULL, 11371);
  gcry_mpi_point_set (point, x, y, z);
  gcry_mpi_set_ui (x, 23);
  gcry_mpi_set_ui (y, 24);
  gcry_mpi_set_ui (z, 25);
  gcry_mpi_point_get (x, y, z, point);
  if (gcry_mpi_cmp_ui (x, 17)
      || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371))
    fail ("point_set/point_get failed\n");
  gcry_mpi_point_snatch_set (point, x, y, z);
  x = gcry_mpi_new (0);
  y = gcry_mpi_new (0);
  z = gcry_mpi_new (0);
  gcry_mpi_point_get (x, y, z, point);
  if (gcry_mpi_cmp_ui (x, 17)
      || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371))
    fail ("point_snatch_set/point_get failed\n");

  gcry_mpi_point_release (point);
  gcry_mpi_release (x);
  gcry_mpi_release (y);
  gcry_mpi_release (z);
}
コード例 #14
0
int
main (int argc, char *argv[])
{
  struct GNUNET_TIME_Absolute start;
  struct GNUNET_CRYPTO_PaillierPublicKey public_key;
  struct GNUNET_CRYPTO_PaillierPrivateKey private_key;
  struct GNUNET_CRYPTO_PaillierCiphertext c1;
  gcry_mpi_t m1;
  unsigned int i;

  start = GNUNET_TIME_absolute_get ();
  for (i=0;i<10;i++)
    GNUNET_CRYPTO_paillier_create (&public_key,
                                   &private_key);
  printf ("10x key generation took %s\n",
          GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start),
						  GNUNET_YES));
  GAUGER ("UTIL", "Paillier key generation",
          64 * 1024 / (1 +
		       GNUNET_TIME_absolute_get_duration
		       (start).rel_value_us / 1000LL), "keys/ms");

  m1 = gcry_mpi_new (0);
  m1 = gcry_mpi_set_ui (m1, 1);
  /* m1 = m1 * 2 ^ (GCPB - 3) */
  gcry_mpi_mul_2exp (m1,
                     m1,
                     GNUNET_CRYPTO_PAILLIER_BITS - 3);
  start = GNUNET_TIME_absolute_get ();
  for (i=0;i<10;i++)
    GNUNET_CRYPTO_paillier_encrypt (&public_key,
                                    m1,
                                    2,
                                    &c1);
  printf ("10x encryption took %s\n",
          GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start),
						  GNUNET_YES));
  GAUGER ("UTIL", "Paillier encryption",
          64 * 1024 / (1 +
		       GNUNET_TIME_absolute_get_duration
		       (start).rel_value_us / 1000LL), "ops/ms");

  start = GNUNET_TIME_absolute_get ();
  for (i=0;i<10;i++)
    GNUNET_CRYPTO_paillier_decrypt (&private_key,
                                    &public_key,
                                    &c1,
                                    m1);
  printf ("10x decryption took %s\n",
          GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start),
						  GNUNET_YES));
  GAUGER ("UTIL", "Paillier decryption",
          64 * 1024 / (1 +
		       GNUNET_TIME_absolute_get_duration
		       (start).rel_value_us / 1000LL), "ops/ms");


  return 0;
}
コード例 #15
0
ファイル: curve25519.c プロジェクト: ljakab/wireshark
int
crypto_scalarmult_curve25519_base(unsigned char *q, const unsigned char *n)
{
    gcry_mpi_t mpi_basepoint_x = gcry_mpi_set_ui(NULL, 9);
    int r = x25519_mpi(q, n, mpi_basepoint_x);
    gcry_mpi_release(mpi_basepoint_x);
    return r;
}
コード例 #16
0
ファイル: crypto_ksk.c プロジェクト: amatus/gnunet-debian
static void
mpz_tdiv_q_2exp (gcry_mpi_t q, gcry_mpi_t n, unsigned int b)
{
  gcry_mpi_t u, d;

  u = gcry_mpi_set_ui (NULL, 1);
  d = gcry_mpi_new (0);
  gcry_mpi_mul_2exp (d, u, b);
  gcry_mpi_div (q, NULL, n, d, 0);
}
コード例 #17
0
void* mod_exp(void* mod_exp_operands)
{
	struct mod_exp_operands* op = (struct mod_exp_operands*) mod_exp_operands;
	
        unsigned long int g = op->g;
        unsigned long int e = op->e;
        unsigned long int n = op->n;
	unsigned long int ans;
	
	gcry_mpi_t ans_mpi = gcry_mpi_new(10);
	gcry_mpi_t g_mpi = gcry_mpi_new(10);
	gcry_mpi_t e_mpi = gcry_mpi_new(10);
	gcry_mpi_t n_mpi = gcry_mpi_new(10);

	printf("Value of g: %lu\n",g);
	g_mpi = gcry_mpi_set_ui(g_mpi, g);
	printf("Value of e: %lu\n",e);
	e_mpi = gcry_mpi_set_ui(e_mpi, e);
	printf("Value of n: %lu\n",n);
	n_mpi = gcry_mpi_set_ui(n_mpi, n);
	gcry_mpi_powm(ans_mpi, g_mpi,e_mpi,n_mpi);
}
コード例 #18
0
ZrtpDH::ZrtpDH(const char* type){

    // Well - the algo type is only 4 char thus cast to int32 and compare
    if (*(int32_t*)type == *(int32_t*)dh2k) {
        pkType = DH2K;
    }
    else if (*(int32_t*)type == *(int32_t*)dh3k) {
        pkType = DH3K;
    }
    else {
        fprintf(stderr, "Unknown pubkey algo: %d\n", pkType);
    }
    ctx = static_cast<void*>(new gcryptCtx);
    gcryptCtx* tmpCtx = static_cast<gcryptCtx*>(ctx);
    tmpCtx->privKey = NULL;
    tmpCtx->pubKey = NULL;

    initializeGcrypt();

    if (!dhinit) {
	gcry_mpi_scan(&bnP2048, GCRYMPI_FMT_USG, P2048, sizeof(P2048), NULL);
        gcry_mpi_scan(&bnP3072, GCRYMPI_FMT_USG, P3072, sizeof(P3072), NULL);
//        gcry_mpi_scan(&bnP4096, GCRYMPI_FMT_USG, P4096, sizeof(P4096), NULL);
        two = gcry_mpi_set_ui(NULL, 2);

        bnP2048MinusOne = gcry_mpi_new(sizeof(P2048)*8);
        gcry_mpi_sub_ui(bnP2048MinusOne, bnP2048, 1);

        bnP3072MinusOne = gcry_mpi_new(sizeof(P3072)*8);
        gcry_mpi_sub_ui(bnP3072MinusOne, bnP3072, 1);

//        bnP4096MinusOne = gcry_mpi_new(sizeof(P4096)*8);
//        gcry_mpi_sub_ui(bnP4096MinusOne, bnP4096, 1);
        dhinit = 1;
    }

    if (pkType == DH3K) {
        tmpCtx->privKey = gcry_mpi_new(256);
        gcry_mpi_randomize(tmpCtx->privKey, 256, GCRY_STRONG_RANDOM);
    }
    else if (pkType == DH2K) {
        tmpCtx->privKey = gcry_mpi_new(512);
        gcry_mpi_randomize(tmpCtx->privKey, 512, GCRY_STRONG_RANDOM);
    }
//    else {
//        tmpCtx->privKey = gcry_mpi_new(512);
//        gcry_mpi_randomize(tmpCtx->privKey, 512, GCRY_STRONG_RANDOM);
//    }
}
コード例 #19
0
ファイル: gcrypt_missing.c プロジェクト: Paxxi/libssh
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;
}
コード例 #20
0
ファイル: privkey.c プロジェクト: adhux/libotr-3.2.1
/* Sign data using a private key.  The data must be small enough to be
 * signed (i.e. already hashed, if necessary).  The signature will be
 * returned in *sigp, which the caller must free().  Its length will be
 * returned in *siglenp. */
gcry_error_t otrl_privkey_sign(unsigned char **sigp, size_t *siglenp,
	OtrlPrivKey *privkey, const unsigned char *data, size_t len)
{
    gcry_mpi_t r,s, datampi;
    gcry_sexp_t dsas, rs, ss, sigs, datas;
    size_t nr, ns;
    const enum gcry_mpi_format format = GCRYMPI_FMT_USG;

    if (privkey->pubkey_type != OTRL_PUBKEY_TYPE_DSA)
	return gcry_error(GPG_ERR_INV_VALUE);

    *sigp = malloc(40);
    if (sigp == NULL) return gcry_error(GPG_ERR_ENOMEM);
    *siglenp = 40;

    if (len) {
	gcry_mpi_scan(&datampi, GCRYMPI_FMT_USG, data, len, NULL);
    } else {
	datampi = gcry_mpi_set_ui(NULL, 0);
    }
    gcry_sexp_build(&datas, NULL, "(%m)", datampi);
    gcry_mpi_release(datampi);
    gcry_pk_sign(&sigs, datas, privkey->privkey);
    gcry_sexp_release(datas);
    dsas = gcry_sexp_find_token(sigs, "dsa", 0);
    gcry_sexp_release(sigs);
    rs = gcry_sexp_find_token(dsas, "r", 0);
    ss = gcry_sexp_find_token(dsas, "s", 0);
    gcry_sexp_release(dsas);
    r = gcry_sexp_nth_mpi(rs, 1, GCRYMPI_FMT_USG);
    gcry_sexp_release(rs);
    s = gcry_sexp_nth_mpi(ss, 1, GCRYMPI_FMT_USG);
    gcry_sexp_release(ss);
    gcry_mpi_print(format, NULL, 0, &nr, r);
    gcry_mpi_print(format, NULL, 0, &ns, s);
    memset(*sigp, 0, 40);
    gcry_mpi_print(format, (*sigp)+(20-nr), nr, NULL, r);
    gcry_mpi_print(format, (*sigp)+20+(20-ns), ns, NULL, s);
    gcry_mpi_release(r);
    gcry_mpi_release(s);

    return gcry_error(GPG_ERR_NO_ERROR);
}
コード例 #21
0
ファイル: gka.c プロジェクト: totakura/gotr
void gotr_ecbd_gen_circle_key(gcry_mpi_point_t *ret, gcry_mpi_point_t *X,
							  gcry_mpi_point_t Z, gcry_mpi_t r)
{
	gcry_mpi_point_t tmp = gcry_mpi_point_new(0);
	gcry_mpi_t n = gcry_mpi_new(0);
	unsigned int i;

	gcry_mpi_point_release(*ret);
	*ret = gcry_mpi_point_set(NULL, NULL, GCRYMPI_CONST_ONE, GCRYMPI_CONST_ONE);
	for (i = 0; X[i]; i++) {
		gcry_mpi_set_ui(n, i+1);
		gcry_mpi_ec_mul(tmp, n, X[i], edctx);
		gcry_mpi_ec_add(*ret, *ret, tmp, edctx);
	}

	gcry_mpi_mul_ui(n, r, i+1);
	gcry_mpi_ec_mul(tmp, n, Z, edctx);
	gcry_mpi_ec_add(*ret, *ret, tmp, edctx);
	gcry_mpi_release(n);
	gcry_mpi_point_release(tmp);
}
コード例 #22
0
ファイル: serialize.c プロジェクト: HarryR/ffff-dnsp2p
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);
  }
}
コード例 #23
0
ファイル: crypto_ksk.c プロジェクト: amatus/gnunet-debian
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);
}
コード例 #24
0
ファイル: serialize.c プロジェクト: HarryR/ffff-dnsp2p
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;
}
コード例 #25
0
ファイル: mpi.c プロジェクト: nuts-io/nuts-io
nuts_mpi_t nuts_mpi_new_ul(const unsigned long ul) {
  gcry_check();
  return nuts_mpi_alloc(gcry_mpi_set_ui(NULL, ul));
}
コード例 #26
0
ファイル: tsexp.c プロジェクト: Greenchik/libgcrypt
/* fixme: we need better tests */
static void
basic (void)
{
  int pass;
  gcry_sexp_t sexp;
  int idx;
  char *secure_buffer;
  size_t secure_buffer_len;
  const char *string;
  static struct {
    const char *token;
    const char *parm;
  } values[] = {
    { "public-key", NULL },
    { "dsa", NULL },
    { "dsa", "p" },
    { "dsa", "y" },
    { "dsa", "q" },
    { "dsa", "g" },
    { NULL }
  };

  info ("doing some pretty pointless tests\n");

  secure_buffer_len = 99;
  secure_buffer = gcry_xmalloc_secure (secure_buffer_len);
  memset (secure_buffer, 'G', secure_buffer_len);

  for (pass=0;;pass++)
    {
      gcry_mpi_t m;

      switch (pass)
        {
        case 0:
          string = ("(public-key (dsa (p #41424344#) (y this_is_y) "
                    "(q #61626364656667#) (g %m)))");

          m = gcry_mpi_set_ui (NULL, 42);
          if ( gcry_sexp_build (&sexp, NULL, string, m ) )
            {
              gcry_mpi_release (m);
              fail (" scanning `%s' failed\n", string);
              return;
            }
          gcry_mpi_release (m);
          break;

        case 1:
          string = ("(public-key (dsa (p #41424344#) (y this_is_y) "
                    "(q %b) (g %m)))");

          m = gcry_mpi_set_ui (NULL, 42);
          if ( gcry_sexp_build (&sexp, NULL, string,
                                15, "foo\0\x01\0x02789012345", m) )
            {
              gcry_mpi_release (m);
              fail (" scanning `%s' failed\n", string);
              return;
            }
          gcry_mpi_release (m);
          break;

        case 2:
          string = ("(public-key (dsa (p #41424344#) (y silly_y_value) "
                    "(q %b) (g %m)))");

          m = gcry_mpi_set_ui (NULL, 17);
          if ( gcry_sexp_build (&sexp, NULL, string,
                                secure_buffer_len, secure_buffer, m) )
            {
              gcry_mpi_release (m);
              fail (" scanning `%s' failed\n", string);
              return;
            }
          gcry_mpi_release (m);
          if (!gcry_is_secure (sexp))
            fail ("gcry_sexp_build did not switch to secure memory\n");
          break;

        case 3:
          {
            gcry_sexp_t help_sexp;

            if (gcry_sexp_new (&help_sexp,
                               "(foobar-parms (xp #1234#)(xq #03#))", 0, 1))
              {
                fail (" scanning fixed string failed\n");
                return;
              }

            string = ("(public-key (dsa (p #41424344#) (parm %S) "
                      "(y dummy)(q %b) (g %m)))");
            m = gcry_mpi_set_ui (NULL, 17);
            if ( gcry_sexp_build (&sexp, NULL, string, help_sexp,
                                  secure_buffer_len, secure_buffer, m) )
              {
                gcry_mpi_release (m);
                fail (" scanning `%s' failed\n", string);
                return;
              }
            gcry_mpi_release (m);
            gcry_sexp_release (help_sexp);
          }
          break;


        default:
          return; /* Ready. */
        }


      /* now find something */
      for (idx=0; values[idx].token; idx++)
        {
          const char *token = values[idx].token;
          const char *parm = values[idx].parm;
          gcry_sexp_t s1, s2;
          gcry_mpi_t a;
          const char *p;
          size_t n;

          s1 = gcry_sexp_find_token (sexp, token, strlen(token) );
          if (!s1)
            {
              fail ("didn't found `%s'\n", token);
              continue;
            }

          p = gcry_sexp_nth_data (s1, 0, &n);
          if (!p)
            {
              gcry_sexp_release (s1);
              fail ("no car for `%s'\n", token);
              continue;
            }
          info ("car=`%.*s'\n", (int)n, p);

          s2 = gcry_sexp_cdr (s1);
          if (!s2)
            {
              gcry_sexp_release (s1);
              fail ("no cdr for `%s'\n", token);
              continue;
            }

          p = gcry_sexp_nth_data (s2, 0, &n);
          gcry_sexp_release (s2);
          if (p)
            {
              gcry_sexp_release (s1);
              fail ("data at car of `%s'\n", token);
              continue;
            }

          if (parm)
            {
              s2 = gcry_sexp_find_token (s1, parm, strlen (parm));
              gcry_sexp_release (s1);
              if (!s2)
                {
                  fail ("didn't found `%s'\n", parm);
                  continue;
                }
              p = gcry_sexp_nth_data (s2, 0, &n);
              if (!p)
                {
                  gcry_sexp_release (s2);
                  fail("no car for `%s'\n", parm );
                  continue;
                }
              info ("car=`%.*s'\n", (int)n, p);
              p = gcry_sexp_nth_data (s2, 1, &n);
              if (!p)
                {
                  gcry_sexp_release (s2);
                  fail("no cdr for `%s'\n", parm );
                  continue;
                }
              info ("cdr=`%.*s'\n", (int)n, p);

              a = gcry_sexp_nth_mpi (s2, 0, GCRYMPI_FMT_USG);
              gcry_sexp_release (s2);
              if (!a)
                {
                  fail("failed to cdr the mpi for `%s'\n", parm);
                  continue;
                }
              gcry_mpi_release (a);
            }
          else
            gcry_sexp_release (s1);
        }

      gcry_sexp_release (sexp);
      sexp = NULL;
    }
  gcry_free (secure_buffer);
}
コード例 #27
0
void attack(int i, unsigned char *digest, int hash_len){
	
    void* dsa_buf; 
	
    gcry_sexp_t new_dsa_key_pair;
    gcry_sexp_t ciphertext , plaintext, ptx2, ctx2;
	
    gcry_sexp_t r_param, r_tilda_param;
    gcry_sexp_t s_param, s_tilda_param;
    gcry_sexp_t g_param;
    gcry_sexp_t p_param;
    gcry_sexp_t q_param;
    gcry_sexp_t m_param;
    gcry_sexp_t y_param;

    gcry_sexp_t x_param;
    gcry_sexp_t misc_param;
	
    gcry_error_t err;
	
    gcry_mpi_t msg_digest, m;
	
    gcry_mpi_t r , r_tilda;
    gcry_mpi_t s , s_tilda;
    gcry_mpi_t g;
    gcry_mpi_t p;
    gcry_mpi_t q;
    gcry_mpi_t y;
    gcry_mpi_t x;
	
    retrieve_key_pair(files[i]);

    //*************** CORRECT SIGNATURE ********************//

	//20 is the mdlen of sha1 as specified in https://lists.gnupg.org/pipermail/gnupg-devel/2013-September/027916.html
    //a well formatted number for the immaediate has an even number of digits
    err = gcry_sexp_build(&plaintext, NULL, "(data (flags rfc6979) (hash %s %b))" , "sha1", hash_len , digest);
	
    err = gcry_pk_sign(&ciphertext, plaintext, dsa_key_pair);

    //now let's convert the s-expression representing r into an MPI in order
    //to use it in the equation of the attack 

    //--------- CIPHERTEXT --------------

    //intercepted during some sniffing...
    
    r_param = gcry_sexp_find_token(ciphertext, "r", 0);
    r = gcry_sexp_nth_mpi ( r_param , 1, GCRYMPI_FMT_USG);
         
    s_param = gcry_sexp_find_token(ciphertext, "s", 0);
    s = gcry_sexp_nth_mpi ( s_param , 1, GCRYMPI_FMT_USG);

    //--------- PUB KEY --------------
    
    g_param = gcry_sexp_find_token(dsa_key_pair, "g", 0);
    g = gcry_sexp_nth_mpi ( g_param , 1, GCRYMPI_FMT_USG);
    
    p_param = gcry_sexp_find_token(dsa_key_pair, "p", 0);
    p = gcry_sexp_nth_mpi ( p_param , 1, GCRYMPI_FMT_USG);
    
    q_param = gcry_sexp_find_token(dsa_key_pair, "q", 0);
    q = gcry_sexp_nth_mpi ( q_param , 1, GCRYMPI_FMT_USG);

    y_param = gcry_sexp_find_token(dsa_key_pair, "y", 0);
    y = gcry_sexp_nth_mpi ( y_param , 1, GCRYMPI_FMT_USG);

    x_param = gcry_sexp_find_token(dsa_key_pair, "x", 0);
    x = gcry_sexp_nth_mpi ( x_param , 1, GCRYMPI_FMT_USG);

    misc_param = gcry_sexp_find_token(dsa_key_pair, "misc-key-info", 0);

    //*************** FAULTY SIGNATURE ********************//

    err = gcry_sexp_build(&ptx2, NULL, "(data (flags rfc6979) (hash %s %b) (attack2_byte))" , "sha1", hash_len , digest);

    err = gcry_pk_sign(&ctx2, ptx2, dsa_key_pair);

    s_tilda_param = gcry_sexp_find_token(ctx2, "s", 0);
    s_tilda = gcry_sexp_nth_mpi ( s_tilda_param , 1, GCRYMPI_FMT_USG);


    r_tilda_param = gcry_sexp_find_token(ctx2, "r", 0);
    r_tilda = gcry_sexp_nth_mpi ( r_tilda_param , 1, GCRYMPI_FMT_USG);

    m_param = gcry_sexp_find_token(ptx2, "hash", 0);
    m = gcry_sexp_nth_mpi ( m_param , 2, GCRYMPI_FMT_USG);


    //NOW LET'S START THE ATTACK 

    unsigned long e = 0;

    unsigned int qbits = mpi_get_nbits(q);
    unsigned int pbits = mpi_get_nbits(p);

    int hash_len_bits = hash_len*8;

    gcry_mpi_t one = gcry_mpi_set_ui(NULL, 1);

    gcry_mpi_t tmp = gcry_mpi_new(qbits);

    gcry_mpi_t result = gcry_mpi_new(mpi_get_nbits(s));

    gcry_mpi_invm(r,r,q); // r^-1
    

    unsigned int j;

    for(e = 0; e < qbits ; e++){

       gcry_mpi_t empi = gcry_mpi_set_ui(NULL,e);
       gcry_mpi_t twoi = gcry_mpi_new(e);
       gcry_mpi_mul_2exp(empi, one, e);   // twoi = 2^e
       
    	for( j=0; j< 256 ; j++){
            
            gcry_mpi_t jmpi = gcry_mpi_set_ui(NULL,j);
    	       gcry_mpi_mulm(twoi,jmpi,empi,q);
      
        	//retrieve k
            gcry_mpi_mulm(tmp, s_tilda, twoi, q); // s_tilda*(2^e) modq q
            gcry_mpi_subm(result, s_tilda, s, q); // s_tilda - s mod q
            gcry_mpi_invm(result, result, q); // (s_tilda - s mod q)^-1
            gcry_mpi_mulm(result,result, tmp, q); // s_tilda*(2^3)  mod q)*(s_tilda - s mod q)^-1 === k

            //retrieve x
            gcry_mpi_mulm(result, s, result,q); // s*k mod q
            gcry_mpi_subm(result, result, m, q); // s*k - m mod q
            gcry_mpi_mulm(result, result,r,q); //(s*k -m)*r^-1 mod q

            err = gcry_sexp_build(&new_dsa_key_pair,NULL,
                         "(key-data"
                         " (public-key"
                         "  (dsa(p%m)(q%m)(g%m)(y%m)))"
                         " (private-key"
                         "  (dsa(p%m)(q%m)(g%m)(y%m)(x%m))))",
                        p,q,g,y,p,q,g,y,result);

            err = gcry_pk_sign(&ctx2, plaintext, new_dsa_key_pair);

            err = gcry_pk_verify(ctx2, plaintext, dsa_key_pair);
        
            if (err) {
                //puts("gcrypt: verify failed");
    	    continue;
            }
            else{
                printf("\n[!!!]PRIVATE KEY %d %d BITS CRACKED!!\n" , pbits,qbits );
        	    printf("[DBG] BYTE : %d * 2^%d  FAULT: k-j*2^%d\n" , j , (int)e,(int)e); //DEBUG 
                DEBUG_MPI_PRINT(result,"X = ");
        	    printf("\n");
          	    return;  
            }

        }

    }
    
    for(e = 0; e < qbits; e++){

       gcry_mpi_t empi = gcry_mpi_set_ui(NULL,e);
       gcry_mpi_t twoi = gcry_mpi_new(e);
       gcry_mpi_mul_2exp(empi, one, e);   // twoi = 2^e
       
    	for( j=0; j< 256 ; j++){
            
            gcry_mpi_t jmpi = gcry_mpi_set_ui(NULL,j);
    	    gcry_mpi_mulm(twoi,jmpi,empi,q);
      
            //retrieve k
            gcry_mpi_mulm(tmp, s_tilda, twoi, q); // s_tilda*(2^e) modq q
            gcry_mpi_subm(result, s, s_tilda, q); // s_tilda - s mod q
            gcry_mpi_invm(result, result, q); // (s_tilda - s mod q)^-1
            gcry_mpi_mulm(result,result, tmp, q); // s_tilda*(2^3)  mod q)*(s_tilda - s mod q)^-1 === k

            //retrieve x
            gcry_mpi_mulm(result, s, result,q); // s*k mod q
            gcry_mpi_subm(result, result, m, q); // s*k - m mod q
            gcry_mpi_mulm(result, result,r,q); //(s*k -m)*r^-1 mod q


            err = gcry_sexp_build(&new_dsa_key_pair,NULL,
                         "(key-data"
                         " (public-key"
                         "  (dsa(p%m)(q%m)(g%m)(y%m)))"
                         " (private-key"
                         "  (dsa(p%m)(q%m)(g%m)(y%m)(x%m))))",
                        p,q,g,y,p,q,g,y,result);

            err = gcry_pk_sign(&ctx2, plaintext, new_dsa_key_pair);

            err = gcry_pk_verify(ctx2, plaintext, dsa_key_pair);
        
            if (err) {
                continue;
            }
            else{
                printf("\n[!!!]PRIVATE KEY %d %d BITS CRACKED!!\n" , pbits,qbits );
        	    printf("[DBG] BYTE : %d * 2^%d  FAULT: k+j*2^%d\n" , j , (int)e,(int)e); //DEBUG 
                DEBUG_MPI_PRINT(result,"X = ");
        	    printf("\n");
          	    return;  
            }
        }
    }    
}
コード例 #28
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; 
}
コード例 #29
0
/****************
 * We do not need to use the strongest RNG because we gain no extra
 * security from it - The prime number is public and we could also
 * offer the factors for those who are willing to check that it is
 * indeed a strong prime.  With ALL_FACTORS set to true all afcors of
 * prime-1 are returned in FACTORS.
 *
 * mode 0: Standard
 *	1: Make sure that at least one factor is of size qbits.
 */
static gcry_err_code_t
prime_generate_internal (int mode,
			 gcry_mpi_t *prime_generated, unsigned int pbits,
			 unsigned int qbits, gcry_mpi_t g,
			 gcry_mpi_t **ret_factors,
			 gcry_random_level_t randomlevel, unsigned int flags,
                         int all_factors,
                         gcry_prime_check_func_t cb_func, void *cb_arg)
{
  gcry_err_code_t err = 0;
  gcry_mpi_t *factors_new = NULL; /* Factors to return to the
				     caller.  */
  gcry_mpi_t *factors = NULL;	/* Current factors.  */
  gcry_mpi_t *pool = NULL;	/* Pool of primes.  */
  unsigned char *perms = NULL;	/* Permutations of POOL.  */
  gcry_mpi_t q_factor = NULL;	/* Used if QBITS is non-zero.  */
  unsigned int fbits = 0;	/* Length of prime factors.  */
  unsigned int n = 0;		/* Number of factors.  */
  unsigned int m = 0;		/* Number of primes in pool.  */
  gcry_mpi_t q = NULL;		/* First prime factor.  */
  gcry_mpi_t prime = NULL;	/* Prime candidate.  */
  unsigned int nprime = 0;	/* Bits of PRIME.  */
  unsigned int req_qbits;       /* The original QBITS value.  */
  gcry_mpi_t val_2;             /* For check_prime().  */
  unsigned int is_secret = (flags & GCRY_PRIME_FLAG_SECRET);
  unsigned int count1 = 0, count2 = 0;
  unsigned int i = 0, j = 0;

  if (pbits < 48)
    return GPG_ERR_INV_ARG;

  /* If QBITS is not given, assume a reasonable value. */
  if (!qbits)
    qbits = pbits / 3;

  req_qbits = qbits;

  /* Find number of needed prime factors.  */
  for (n = 1; (pbits - qbits - 1) / n  >= qbits; n++)
    ;
  n--;

  val_2 = mpi_alloc_set_ui (2);

  if ((! n) || ((mode == 1) && (n < 2)))
    {
      err = GPG_ERR_INV_ARG;
      goto leave;
    }

  if (mode == 1)
    {
      n--;
      fbits = (pbits - 2 * req_qbits -1) / n;
      qbits =  pbits - req_qbits - n * fbits;
    }
  else
    {
      fbits = (pbits - req_qbits -1) / n;
      qbits = pbits - n * fbits;
    }
  
  if (DBG_CIPHER)
    log_debug ("gen prime: pbits=%u qbits=%u fbits=%u/%u n=%d\n",
               pbits, req_qbits, qbits, fbits, n);

  prime = gcry_mpi_new (pbits);

  /* Generate first prime factor.  */
  q = gen_prime (qbits, is_secret, randomlevel, NULL, NULL);
  
  if (mode == 1)
    q_factor = gen_prime (req_qbits, is_secret, randomlevel, NULL, NULL);
  
  /* Allocate an array to hold the factors + 2 for later usage.  */
  factors = gcry_calloc (n + 2, sizeof (*factors));
  if (!factors)
    {
      err = gpg_err_code_from_errno (errno);
      goto leave;
    }
      
  /* Make a pool of 3n+5 primes (this is an arbitrary value).  */
  m = n * 3 + 5;
  if (mode == 1) /* Need some more (for e.g. DSA).  */
    m += 5;
  if (m < 25)
    m = 25;
  pool = gcry_calloc (m , sizeof (*pool));
  if (! pool)
    {
      err = gpg_err_code_from_errno (errno);
      goto leave;
    }

  /* Permutate over the pool of primes.  */
  do
    {
    next_try:
      if (! perms)
        {
          /* Allocate new primes.  */
          for(i = 0; i < m; i++)
            {
              mpi_free (pool[i]);
              pool[i] = NULL;
            }

          /* Init m_out_of_n().  */
          perms = gcry_calloc (1, m);
          if (! perms)
            {
              err = gpg_err_code_from_errno (errno);
              goto leave;
            }
          for(i = 0; i < n; i++)
            {
              perms[i] = 1;
              pool[i] = gen_prime (fbits, is_secret,
                                   randomlevel, NULL, NULL);
              factors[i] = pool[i];
            }
        }
      else
        {
          m_out_of_n ((char*)perms, n, m);
          for (i = j = 0; (i < m) && (j < n); i++)
            if (perms[i])
              {
                if(! pool[i])
                  pool[i] = gen_prime (fbits, 0, 1, NULL, NULL);
                factors[j++] = pool[i];
              }
          if (i == n)
            {
              gcry_free (perms);
              perms = NULL;
              progress ('!');
              goto next_try;	/* Allocate new primes.  */
            }
        }

	/* Generate next prime candidate:
	   p = 2 * q [ * q_factor] * factor_0 * factor_1 * ... * factor_n + 1. 
        */
	mpi_set (prime, q);
	mpi_mul_ui (prime, prime, 2);
	if (mode == 1)
	  mpi_mul (prime, prime, q_factor);
	for(i = 0; i < n; i++)
	  mpi_mul (prime, prime, factors[i]);
	mpi_add_ui (prime, prime, 1);
	nprime = mpi_get_nbits (prime);

	if (nprime < pbits)
	  {
	    if (++count1 > 20)
	      {
		count1 = 0;
		qbits++;
		progress('>');
		mpi_free (q);
		q = gen_prime (qbits, 0, 0, NULL, NULL);
		goto next_try;
	      }
	  }
	else
	  count1 = 0;
        
	if (nprime > pbits)
	  {
	    if (++count2 > 20)
	      {
		count2 = 0;
		qbits--;
		progress('<');
		mpi_free (q);
		q = gen_prime (qbits, 0, 0, NULL, NULL);
		goto next_try;
	      }
	  }
	else
	  count2 = 0;
    }
  while (! ((nprime == pbits) && check_prime (prime, val_2, cb_func, cb_arg)));

  if (DBG_CIPHER)
    {
      progress ('\n');
      log_mpidump ("prime    : ", prime);
      log_mpidump ("factor  q: ", q);
      if (mode == 1)
        log_mpidump ("factor q0: ", q_factor);
      for (i = 0; i < n; i++)
        log_mpidump ("factor pi: ", factors[i]);
      log_debug ("bit sizes: prime=%u, q=%u",
                 mpi_get_nbits (prime), mpi_get_nbits (q));
      if (mode == 1)
        log_debug (", q0=%u", mpi_get_nbits (q_factor));
      for (i = 0; i < n; i++)
        log_debug (", p%d=%u", i, mpi_get_nbits (factors[i]));
      progress('\n');
    }

  if (ret_factors)
    {
      /* Caller wants the factors.  */
      factors_new = gcry_calloc (n + 4, sizeof (*factors_new));
      if (! factors_new)
        {
          err = gpg_err_code_from_errno (errno);
          goto leave;
        }

      if (all_factors)
        {
          i = 0;
          factors_new[i++] = gcry_mpi_set_ui (NULL, 2);
          factors_new[i++] = mpi_copy (q);
          if (mode == 1)
            factors_new[i++] = mpi_copy (q_factor);
          for(j=0; j < n; j++)
            factors_new[i++] = mpi_copy (factors[j]);
        }
      else
        {
          i = 0;
          if (mode == 1)
            {
              factors_new[i++] = mpi_copy (q_factor);
              for (; i <= n; i++)
                factors_new[i] = mpi_copy (factors[i]);
            }
          else
            for (; i < n; i++ )
              factors_new[i] = mpi_copy (factors[i]);
        }
    }
  
  if (g)
    {
      /* Create a generator (start with 3).  */
      gcry_mpi_t tmp = mpi_alloc (mpi_get_nlimbs (prime));
      gcry_mpi_t b = mpi_alloc (mpi_get_nlimbs (prime));
      gcry_mpi_t pmin1 = mpi_alloc (mpi_get_nlimbs (prime));
      
      if (mode == 1)
        err = GPG_ERR_NOT_IMPLEMENTED;
      else
        {
          factors[n] = q;
          factors[n + 1] = mpi_alloc_set_ui (2);
          mpi_sub_ui (pmin1, prime, 1);
          mpi_set_ui (g, 2);
          do
            {
              mpi_add_ui (g, g, 1);
              if (DBG_CIPHER)
                {
                  log_debug ("checking g:");
                  gcry_mpi_dump (g);
                  log_printf ("\n");
                }
              else
                progress('^');
              for (i = 0; i < n + 2; i++)
                {
                  mpi_fdiv_q (tmp, pmin1, factors[i]);
                  /* No mpi_pow(), but it is okay to use this with mod
                     prime.  */
                  gcry_mpi_powm (b, g, tmp, prime);
                  if (! mpi_cmp_ui (b, 1))
                    break;
                }
              if (DBG_CIPHER)
                progress('\n');
            } 
          while (i < n + 2);

          mpi_free (factors[n+1]);
          mpi_free (tmp);
          mpi_free (b);
          mpi_free (pmin1);
        }
    }
  
  if (! DBG_CIPHER)
    progress ('\n');


 leave:
  if (pool)
    {
      for(i = 0; i < m; i++)
	mpi_free (pool[i]);
      gcry_free (pool);
    }
  if (factors)
    gcry_free (factors);  /* Factors are shallow copies.  */
  if (perms)
    gcry_free (perms);

  mpi_free (val_2);
  mpi_free (q);
  mpi_free (q_factor);

  if (! err)
    {
      *prime_generated = prime;
      if (ret_factors)
	*ret_factors = factors_new;
    }
  else
    {
      if (factors_new)
	{
	  for (i = 0; factors_new[i]; i++)
	    mpi_free (factors_new[i]);
	  gcry_free (factors_new);
	}
      mpi_free (prime);
    }

  return err;
}
コード例 #30
0
ファイル: crypto_ksk.c プロジェクト: amatus/gnunet-debian
/**
 * 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);
}