Beispiel #1
0
static void
do_encrypt(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey )
{
  gcry_mpi_t k;

  /* Note: maybe we should change the interface, so that it
   * is possible to check that input is < p and return an
   * error code.
   */

  k = gen_k( pkey->p, 1 );
  gcry_mpi_powm( a, pkey->g, k, pkey->p );
  /* b = (y^k * input) mod p
   *	 = ((y^k mod p) * (input mod p)) mod p
   * and because input is < p
   *	 = ((y^k mod p) * input) mod p
   */
  gcry_mpi_powm( b, pkey->y, k, pkey->p );
  gcry_mpi_mulm( b, b, input, pkey->p );
#if 0
  if( DBG_CIPHER )
    {
      log_mpidump("elg encrypted y= ", pkey->y);
      log_mpidump("elg encrypted p= ", pkey->p);
      log_mpidump("elg encrypted k= ", k);
      log_mpidump("elg encrypted M= ", input);
      log_mpidump("elg encrypted a= ", a);
      log_mpidump("elg encrypted b= ", b);
    }
#endif
  mpi_free(k);
}
int32_t ZrtpDH::computeSecretKey(uint8_t *pubKeyBytes, uint8_t *secret) {

    int32_t length = getDhSize();
    gcryptCtx* tmpCtx = static_cast<gcryptCtx*>(ctx);

    gcry_mpi_t pubKeyOther;
    gcry_mpi_t sec = gcry_mpi_new(0);
    gcry_mpi_scan(&pubKeyOther, GCRYMPI_FMT_USG, pubKeyBytes, length, NULL);

    if (pkType == DH2K) {
        gcry_mpi_powm(sec, pubKeyOther, tmpCtx->privKey, bnP2048);
    }
    else if (pkType == DH3K) {
        gcry_mpi_powm(sec, pubKeyOther, tmpCtx->privKey, bnP3072);
    }
    else {
//	gcry_mpi_powm(sec, pubKeyOther, tmpCtx->privKey, bnP4096);
        return 0;
    }
    gcry_mpi_release(pubKeyOther);

    size_t result;
    gcry_mpi_print(GCRYMPI_FMT_USG, secret, length, &result, sec);
    gcry_mpi_release(sec);

    return result;
}
Beispiel #3
0
int main(int argc, char *argv[]) {
	gcry_mpi_t g,p,M,N,pw,t1,t2;
	size_t scanned;
	int iterations, keySize;

	g = gcry_mpi_new(0);
	p = gcry_mpi_new(0);
	M = gcry_mpi_new(0);
	N = gcry_mpi_new(0);
	pw = gcry_mpi_new(0);
	t1 = gcry_mpi_new(0);
	t2 = gcry_mpi_new(0);

	/* MODP_2048 */
	const char* pString = "00FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF";
	const char* gString = "2";

	/* password */
	const char* pwd = "My$Very=Secure;Password";
	const char* salt = "abcdefghijklmno";
	iterations = 1000;
	keySize = 32;	
	
	/* read p and g */
	gcry_mpi_scan(&g, GCRYMPI_FMT_HEX, gString, 0, &scanned);
	gcry_mpi_scan(&p, GCRYMPI_FMT_HEX, pString, 0, &scanned);

	/* hash password */
	char* result = calloc(keySize, sizeof(char));
	gcry_kdf_derive(pwd, strlen(pwd), GCRY_KDF_PBKDF2, GCRY_MD_SHA256, salt, strlen(salt), iterations, keySize, result);
	gcry_mpi_scan(&pw, GCRYMPI_FMT_STD, result, strlen((const char*)result), &scanned);

	/* create M and N */
	gen_rand(t1, p);
	gen_rand(t2, p);
	gcry_mpi_powm(M, g, t1, p);
	gcry_mpi_powm(N, g, t2, p);

	/* run test ... */
	struct spake_session client = spake_init(0, g, p, M, N, pw, keySize); /* client */
	struct spake_session server = spake_init(1, g, p, M, N, pw, keySize); /* server */

	spake_next(&client, server.X);
	spake_next(&server, client.X);

	print_key(client.k, keySize, "k1");
	print_key(server.k, keySize, "k2");

	if (strncmp(client.k, server.k, keySize) == 0)
		printf("Successful SPAKE session :)\n");
	else
		printf("Sorry, error in SPAKE session :(\n");
	
	return 0;
}
Beispiel #4
0
/****************
 * Returns true if the signature composed of A and B is valid.
 */
static int
verify(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey )
{
  int rc;
  gcry_mpi_t t1;
  gcry_mpi_t t2;
  gcry_mpi_t base[4];
  gcry_mpi_t ex[4];

  if( !(mpi_cmp_ui( a, 0 ) > 0 && mpi_cmp( a, pkey->p ) < 0) )
    return 0; /* assertion	0 < a < p  failed */

  t1 = mpi_alloc( mpi_get_nlimbs(a) );
  t2 = mpi_alloc( mpi_get_nlimbs(a) );

#if 0
  /* t1 = (y^a mod p) * (a^b mod p) mod p */
  gcry_mpi_powm( t1, pkey->y, a, pkey->p );
  gcry_mpi_powm( t2, a, b, pkey->p );
  mpi_mulm( t1, t1, t2, pkey->p );

  /* t2 = g ^ input mod p */
  gcry_mpi_powm( t2, pkey->g, input, pkey->p );

  rc = !mpi_cmp( t1, t2 );
#elif 0
  /* t1 = (y^a mod p) * (a^b mod p) mod p */
  base[0] = pkey->y; ex[0] = a;
  base[1] = a;       ex[1] = b;
  base[2] = NULL;    ex[2] = NULL;
  mpi_mulpowm( t1, base, ex, pkey->p );

  /* t2 = g ^ input mod p */
  gcry_mpi_powm( t2, pkey->g, input, pkey->p );

  rc = !mpi_cmp( t1, t2 );
#else
  /* t1 = g ^ - input * y ^ a * a ^ b  mod p */
  mpi_invm(t2, pkey->g, pkey->p );
  base[0] = t2     ; ex[0] = input;
  base[1] = pkey->y; ex[1] = a;
  base[2] = a;       ex[2] = b;
  base[3] = NULL;    ex[3] = NULL;
  mpi_mulpowm( t1, base, ex, pkey->p );
  rc = !mpi_cmp_ui( t1, 1 );

#endif

  mpi_free(t1);
  mpi_free(t2);
  return rc;
}
Beispiel #5
0
Datei: kex.c Projekt: 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;
}
Beispiel #6
0
static void
do_powm ( const char *n_str, const char *e_str, const char *m_str)
{
  gcry_mpi_t e, n, msg, cip;
  gcry_error_t err;
  int i;

  err = gcry_mpi_scan (&n, GCRYMPI_FMT_HEX, n_str, 0, 0);
  if (err) BUG ();
  err = gcry_mpi_scan (&e, GCRYMPI_FMT_HEX, e_str, 0, 0);
  if (err) BUG ();
  err = gcry_mpi_scan (&msg, GCRYMPI_FMT_HEX, m_str, 0, 0);
  if (err) BUG ();

  cip = gcry_mpi_new (0);

  start_timer ();
  for (i=0; i < 1000; i++)
    gcry_mpi_powm (cip, msg, e, n);
  stop_timer ();
  printf (" %s", elapsed_time ()); fflush (stdout);
/*    { */
/*      char *buf; */

/*      if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, (void**)&buf, NULL, cip)) */
/*        BUG (); */
/*      printf ("result: %s\n", buf); */
/*      gcry_free (buf); */
/*    } */
  gcry_mpi_release (cip);
  gcry_mpi_release (msg);
  gcry_mpi_release (n);
  gcry_mpi_release (e);
}
int32_t ZrtpDH::generatePublicKey()
{
    gcryptCtx* tmpCtx = static_cast<gcryptCtx*>(ctx);

    tmpCtx->pubKey = gcry_mpi_new(0);
    if (pkType == DH2K) {
        gcry_mpi_powm(tmpCtx->pubKey, two, tmpCtx->privKey, bnP2048);
    }
    else if (pkType == DH3K) {
        gcry_mpi_powm(tmpCtx->pubKey, two, tmpCtx->privKey, bnP3072);
    }
    else {
//	gcry_mpi_powm(tmpCtx->pubKey, two, tmpCtx->privKey, bnP4096);
        return 0;
    }
    return 1;
}
Beispiel #8
0
/****************
 * Test whether the secret key is valid.
 * Returns: if this is a valid key.
 */
static int
check_secret_key( ELG_secret_key *sk )
{
  int rc;
  gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) );

  gcry_mpi_powm( y, sk->g, sk->x, sk->p );
  rc = !mpi_cmp( y, sk->y );
  mpi_free( y );
  return rc;
}
Beispiel #9
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;
}
Beispiel #10
0
void FSPRG_Seek(void *state, uint64_t epoch, const void *msk, const void *seed, size_t seedlen) {
        gcry_mpi_t p, q, n, x, xp, xq, kp, kq, xm;
        uint16_t secpar;

        initialize_libgcrypt();

        secpar = read_secpar(msk + 0);
        p  = mpi_import(msk + 2 + 0 * (secpar / 2) / 8, (secpar / 2) / 8);
        q  = mpi_import(msk + 2 + 1 * (secpar / 2) / 8, (secpar / 2) / 8);

        n = gcry_mpi_new(0);
        gcry_mpi_mul(n, p, q);

        x = gensquare(n, seed, seedlen, RND_GEN_X, secpar);
        CRT_decompose(&xp, &xq, x, p, q); /* split (mod n) into (mod p) and (mod q) using CRT */

        kp = twopowmodphi(epoch, p); /* compute 2^epoch (mod phi(p)) */
        kq = twopowmodphi(epoch, q); /* compute 2^epoch (mod phi(q)) */

        gcry_mpi_powm(xp, xp, kp, p); /* compute x^(2^epoch) (mod p) */
        gcry_mpi_powm(xq, xq, kq, q); /* compute x^(2^epoch) (mod q) */

        CRT_compose(&xm, xp, xq, p, q); /* combine (mod p) and (mod q) to (mod n) using CRT */

        store_secpar(state + 0, secpar);
        mpi_export(state + 2 + 0 * secpar / 8, secpar / 8, n);
        mpi_export(state + 2 + 1 * secpar / 8, secpar / 8, xm);
        uint64_export(state + 2 + 2 * secpar / 8, 8, epoch);

        gcry_mpi_release(p);
        gcry_mpi_release(q);
        gcry_mpi_release(n);
        gcry_mpi_release(x);
        gcry_mpi_release(xp);
        gcry_mpi_release(xq);
        gcry_mpi_release(kp);
        gcry_mpi_release(kq);
        gcry_mpi_release(xm);
}
unsigned char* modPow(unsigned char* x, unsigned char* y, unsigned char* z){
	size_t scanned;
	unsigned char *result;
	gcry_mpi_t a = gcry_mpi_new(0);
	gcry_mpi_t b = gcry_mpi_new(0);
	gcry_mpi_t c = gcry_mpi_new(0);
	gcry_mpi_scan(&a, GCRYMPI_FMT_HEX, x, 0, &scanned);
	gcry_mpi_scan(&b, GCRYMPI_FMT_HEX, y, 0, &scanned);
	gcry_mpi_scan(&c, GCRYMPI_FMT_HEX, z, 0, &scanned);
	gcry_mpi_powm(a, a, b, c);
	gcry_mpi_aprint(GCRYMPI_FMT_HEX, &result, NULL, a);
	return result;
}
Beispiel #12
0
static bigint_t
wrap_gcry_mpi_powm (bigint_t w, const bigint_t b, const bigint_t e,
		    const bigint_t m)
{
  if (w == NULL)
    w = _gnutls_mpi_alloc_like (m);

  if (w == NULL)
    return NULL;

  gcry_mpi_powm (w, b, e, m);

  return w;
}
Beispiel #13
0
/****************
 * Returns: true if this may be a prime
 */
static int
check_prime( gcry_mpi_t prime, gcry_mpi_t val_2,
             gcry_prime_check_func_t cb_func, void *cb_arg)
{
  int i;
  unsigned int x;
  unsigned int count=0;

  /* Check against small primes. */
  for (i=0; (x = small_prime_numbers[i]); i++ )
    {
      if ( mpi_divisible_ui( prime, x ) )
        return 0;
    }

  /* A quick Fermat test. */
  {
    gcry_mpi_t result = mpi_alloc_like( prime );
    gcry_mpi_t pminus1 = mpi_alloc_like( prime );
    mpi_sub_ui( pminus1, prime, 1);
    gcry_mpi_powm( result, val_2, pminus1, prime );
    mpi_free( pminus1 );
    if ( mpi_cmp_ui( result, 1 ) )
      { 
        /* Is composite. */
        mpi_free( result );
        progress('.');
        return 0;
      }
    mpi_free( result );
  }

  if (!cb_func || cb_func (cb_arg, GCRY_PRIME_CHECK_AT_MAYBE_PRIME, prime))
    {
      /* Perform stronger tests. */
      if ( is_prime( prime, 5, &count ) )
        {
          if (!cb_func
              || cb_func (cb_arg, GCRY_PRIME_CHECK_AT_GOT_PRIME, prime))
            return 1; /* Probably a prime. */
        }
    }
  progress('.');
  return 0;
}
Beispiel #14
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;
}
Beispiel #15
0
Datei: kex.c Projekt: 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;
}
Beispiel #16
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;
}
Beispiel #17
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;
}
Beispiel #18
0
static void
decrypt(gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b, ELG_secret_key *skey )
{
  gcry_mpi_t t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) );

  /* output = b/(a^x) mod p */
  gcry_mpi_powm( t1, a, skey->x, skey->p );
  mpi_invm( t1, t1, skey->p );
  mpi_mulm( output, b, t1, skey->p );
#if 0
  if( DBG_CIPHER ) 
    {
      log_mpidump("elg decrypted x= ", skey->x);
      log_mpidump("elg decrypted p= ", skey->p);
      log_mpidump("elg decrypted a= ", a);
      log_mpidump("elg decrypted b= ", b);
      log_mpidump("elg decrypted M= ", output);
    }
#endif
  mpi_free(t1);
}
Beispiel #19
0
static void
sign(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_secret_key *skey )
{
    gcry_mpi_t k;
    gcry_mpi_t t   = mpi_alloc( mpi_get_nlimbs(a) );
    gcry_mpi_t inv = mpi_alloc( mpi_get_nlimbs(a) );
    gcry_mpi_t p_1 = mpi_copy(skey->p);

   /*
    * b = (t * inv) mod (p-1)
    * b = (t * inv(k,(p-1),(p-1)) mod (p-1)
    * b = (((M-x*a) mod (p-1)) * inv(k,(p-1),(p-1))) mod (p-1)
    *
    */
    mpi_sub_ui(p_1, p_1, 1);
    k = gen_k( skey->p, 0 /* no small K ! */ );
    gcry_mpi_powm( a, skey->g, k, skey->p );
    mpi_mul(t, skey->x, a );
    mpi_subm(t, input, t, p_1 );
    mpi_invm(inv, k, p_1 );
    mpi_mulm(b, t, inv, p_1 );

#if 0
    if( DBG_CIPHER ) 
      {
	log_mpidump("elg sign p= ", skey->p);
	log_mpidump("elg sign g= ", skey->g);
	log_mpidump("elg sign y= ", skey->y);
	log_mpidump("elg sign x= ", skey->x);
	log_mpidump("elg sign k= ", k);
	log_mpidump("elg sign M= ", input);
	log_mpidump("elg sign a= ", a);
	log_mpidump("elg sign b= ", b);
      }
#endif
    mpi_free(k);
    mpi_free(t);
    mpi_free(inv);
    mpi_free(p_1);
}
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);
}
Beispiel #21
0
/* Generate a key pair with a key of size NBITS not using a random
   value for the secret key but the one given as X.  This is useful to
   implement a passphrase based decryption for a public key based
   encryption.  It has appliactions in backup systems.
 
   Returns: A structure filled with all needed values and an array
 	    with n-1 factors of (p-1).  */
static gcry_err_code_t
generate_using_x (ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t x,
                  gcry_mpi_t **ret_factors )
{
  gcry_mpi_t p;      /* The prime.  */
  gcry_mpi_t p_min1; /* The prime minus 1.  */
  gcry_mpi_t g;      /* The generator.  */
  gcry_mpi_t y;      /* g^x mod p.  */
  unsigned int qbits;
  unsigned int xbits;

  sk->p = NULL;
  sk->g = NULL;
  sk->y = NULL;
  sk->x = NULL;

  /* Do a quick check to see whether X is suitable.  */
  xbits = mpi_get_nbits (x);
  if ( xbits < 64 || xbits >= nbits )
    return GPG_ERR_INV_VALUE;

  p_min1 = gcry_mpi_new ( nbits );
  qbits  = wiener_map ( nbits );
  if ( (qbits & 1) ) /* Better have an 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);

  if (DBG_CIPHER)
    log_debug ("using a supplied x of size %u", xbits );
  if ( !(mpi_cmp_ui ( x, 0 ) > 0 && mpi_cmp ( x, p_min1 ) <0 ) )
    {
      gcry_mpi_release ( p_min1 );
      gcry_mpi_release ( p );
      gcry_mpi_release ( g );
      return GPG_ERR_INV_VALUE;
    }

  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 = gcry_mpi_copy (x);

  gcry_mpi_release ( p_min1 );

  /* Now we can test our keys. */
  if ( test_keys ( sk, nbits - 64, 1 ) )
    {
      gcry_mpi_release ( sk->p ); sk->p = NULL;
      gcry_mpi_release ( sk->g ); sk->g = NULL;
      gcry_mpi_release ( sk->y ); sk->y = NULL;
      gcry_mpi_release ( sk->x ); sk->x = NULL;
      return GPG_ERR_BAD_SECKEY;
    }

  return 0;
}
Beispiel #22
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 );
}
Beispiel #23
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; 
}
Beispiel #24
0
/*
 * Return true if n is probably a prime
 */
static int
is_prime (gcry_mpi_t n, int steps, unsigned int *count)
{
  gcry_mpi_t x = mpi_alloc( mpi_get_nlimbs( n ) );
  gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs( n ) );
  gcry_mpi_t z = mpi_alloc( mpi_get_nlimbs( n ) );
  gcry_mpi_t nminus1 = mpi_alloc( mpi_get_nlimbs( n ) );
  gcry_mpi_t a2 = mpi_alloc_set_ui( 2 );
  gcry_mpi_t q;
  unsigned i, j, k;
  int rc = 0;
  unsigned nbits = mpi_get_nbits( n );

  mpi_sub_ui( nminus1, n, 1 );

  /* Find q and k, so that n = 1 + 2^k * q . */
  q = mpi_copy ( nminus1 );
  k = mpi_trailing_zeros ( q );
  mpi_tdiv_q_2exp (q, q, k);

  for (i=0 ; i < steps; i++ )
    {
      ++*count;
      if( !i )
        {
          mpi_set_ui( x, 2 );
        }
      else
        {
          gcry_mpi_randomize( x, nbits, GCRY_WEAK_RANDOM );

          /* Make sure that the number is smaller than the prime and
             keep the randomness of the high bit. */
          if ( mpi_test_bit ( x, nbits-2) )
            {
              mpi_set_highbit ( x, nbits-2); /* Clear all higher bits. */
            }
          else
            {
              mpi_set_highbit( x, nbits-2 );
              mpi_clear_bit( x, nbits-2 );
            }
          assert ( mpi_cmp( x, nminus1 ) < 0 && mpi_cmp_ui( x, 1 ) > 0 );
	}
      gcry_mpi_powm ( y, x, q, n);
      if ( mpi_cmp_ui(y, 1) && mpi_cmp( y, nminus1 ) )
        {
          for ( j=1; j < k && mpi_cmp( y, nminus1 ); j++ )
            {
              gcry_mpi_powm(y, y, a2, n);
              if( !mpi_cmp_ui( y, 1 ) )
                goto leave; /* Not a prime. */
            }
          if (mpi_cmp( y, nminus1 ) )
            goto leave; /* Not a prime. */
	}
      progress('+');
    }
  rc = 1; /* May be a prime. */

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

  return rc;
}
Beispiel #25
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 */
    }
}
Beispiel #26
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;
}
Beispiel #27
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;
      }
    }
  }
}
Beispiel #28
0
int
irc_sasl_dh (const char *data_base64,
             unsigned char **public_bin, unsigned char **secret_bin,
             int *length_key)
{
    char *data;
    unsigned char *ptr_data;
    int length_data, size, num_bits_prime_number, rc;
    size_t num_written;
    gcry_mpi_t data_prime_number, data_generator_number, data_server_pub_key;
    gcry_mpi_t pub_key, priv_key, secret_mpi;

    rc = 0;

    data = NULL;
    data_prime_number = NULL;
    data_generator_number = NULL;
    data_server_pub_key = NULL;
    pub_key = NULL;
    priv_key = NULL;
    secret_mpi = NULL;

    /* decode data */
    data = malloc (strlen (data_base64) + 1);
    length_data = weechat_string_decode_base64 (data_base64, data);
    ptr_data = (unsigned char *)data;

    /* extract prime number */
    size = ntohs ((((unsigned int)ptr_data[1]) << 8) | ptr_data[0]);
    ptr_data += 2;
    length_data -= 2;
    if (size > length_data)
        goto dhend;
    data_prime_number = gcry_mpi_new (size * 8);
    gcry_mpi_scan (&data_prime_number, GCRYMPI_FMT_USG, ptr_data, size, NULL);
    num_bits_prime_number = gcry_mpi_get_nbits (data_prime_number);
    ptr_data += size;
    length_data -= size;

    /* extract generator number */
    size = ntohs ((((unsigned int)ptr_data[1]) << 8) | ptr_data[0]);
    ptr_data += 2;
    length_data -= 2;
    if (size > length_data)
        goto dhend;
    data_generator_number = gcry_mpi_new (size * 8);
    gcry_mpi_scan (&data_generator_number, GCRYMPI_FMT_USG, ptr_data, size, NULL);
    ptr_data += size;
    length_data -= size;

    /* extract server-generated public key */
    size = ntohs ((((unsigned int)ptr_data[1]) << 8) | ptr_data[0]);
    ptr_data += 2;
    length_data -= 2;
    if (size > length_data)
        goto dhend;
    data_server_pub_key = gcry_mpi_new (size * 8);
    gcry_mpi_scan (&data_server_pub_key, GCRYMPI_FMT_USG, ptr_data, size, NULL);

    /* generate keys */
    pub_key = gcry_mpi_new (num_bits_prime_number);
    priv_key = gcry_mpi_new (num_bits_prime_number);
    gcry_mpi_randomize (priv_key, num_bits_prime_number, GCRY_STRONG_RANDOM);
    /* pub_key = (g ^ priv_key) % p */
    gcry_mpi_powm (pub_key, data_generator_number, priv_key, data_prime_number);

    /* compute secret_bin */
    *length_key = num_bits_prime_number / 8;
    *secret_bin = malloc (*length_key);
    secret_mpi = gcry_mpi_new (num_bits_prime_number);
    /* secret_mpi = (y ^ priv_key) % p */
    gcry_mpi_powm (secret_mpi, data_server_pub_key, priv_key, data_prime_number);
    gcry_mpi_print (GCRYMPI_FMT_USG, *secret_bin, *length_key,
                    &num_written, secret_mpi);

    /* create public_bin */
    *public_bin = malloc (*length_key);
    gcry_mpi_print (GCRYMPI_FMT_USG, *public_bin, *length_key,
                    &num_written, pub_key);
    rc = 1;

dhend:
    if (data)
        free (data);
    if (data_prime_number)
        gcry_mpi_release (data_prime_number);
    if (data_generator_number)
        gcry_mpi_release (data_generator_number);
    if (data_server_pub_key)
        gcry_mpi_release (data_server_pub_key);
    if (pub_key)
        gcry_mpi_release (pub_key);
    if (priv_key)
        gcry_mpi_release (priv_key);
    if (secret_mpi)
        gcry_mpi_release (secret_mpi);

    return rc;
}
Beispiel #29
0
nuts_mpi_t nuts_mpi_powm(const nuts_mpi_t b, const nuts_mpi_t e, const nuts_mpi_t m) {
  gcry_mpi_t w = gcry_mpi_new(0);
  gcry_mpi_powm(w, b->mpi, e->mpi, m->mpi);
  return nuts_mpi_alloc(w);
}
Beispiel #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;
}