summaryrefslogtreecommitdiff
path: root/cipher/primegen.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2003-12-19 09:20:41 +0000
committerWerner Koch <wk@gnupg.org>2003-12-19 09:20:41 +0000
commitf2541aa8a390d5f26512135bc2079c3aa0f5cc47 (patch)
treef4e48ff1d0b50253d922d04bf0b6707e5b690855 /cipher/primegen.c
parentadf881257f924c201555476be103f5920618fc8e (diff)
downloadlibgcrypt-f2541aa8a390d5f26512135bc2079c3aa0f5cc47.tar.gz
* ac.c (gcry_ac_open): Make sure HANDLE gets initialized even when
the function is not successful. (gcry_ac_close): Allow a NULL handle. (gcry_ac_key_destroy, gcry_ac_key_pair_destroy): Ditto. (gcry_ac_key_get_grip): Return INV_OBJ on error. * primegen.c (prime_generate_internal): Fixed error code for failed malloc. Replaced the !err if chain by gotos. (gcry_prime_group_generator): Remove the extra sanity check. * md.c: Minor code and comment cleanups.
Diffstat (limited to 'cipher/primegen.c')
-rw-r--r--cipher/primegen.c858
1 files changed, 444 insertions, 414 deletions
diff --git a/cipher/primegen.c b/cipher/primegen.c
index 0fd869e1..7f82f422 100644
--- a/cipher/primegen.c
+++ b/cipher/primegen.c
@@ -29,13 +29,15 @@
#include <stdlib.h>
#include <string.h>
#include <assert.h>
+#include <errno.h>
#include "g10lib.h"
#include "mpi.h"
#include "cipher.h"
static gcry_mpi_t gen_prime (unsigned int nbits, int secret, int randomlevel,
- int (*extra_check)(void *, gcry_mpi_t), void *extra_check_arg);
+ int (*extra_check)(void *, gcry_mpi_t),
+ void *extra_check_arg);
static int check_prime( gcry_mpi_t prime, gcry_mpi_t val_2 );
static int is_prime( gcry_mpi_t n, int steps, int *count );
static void m_out_of_n( char *array, int m, int n );
@@ -130,10 +132,11 @@ static ushort small_prime_numbers[] = {
static int no_of_small_prime_numbers = DIM (small_prime_numbers) - 1;
void
-_gcry_register_primegen_progress ( void (*cb)(void *,const char*,int,int,int), void *cb_data )
+_gcry_register_primegen_progress ( void (*cb)(void *,const char*,int,int,int),
+ void *cb_data )
{
- progress_cb = cb;
- progress_cb_data = cb_data;
+ progress_cb = cb;
+ progress_cb_data = cb_data;
}
@@ -153,11 +156,11 @@ _gcry_generate_secret_prime (unsigned int nbits,
int (*extra_check)(void*, gcry_mpi_t),
void *extra_check_arg)
{
- gcry_mpi_t prime;
+ gcry_mpi_t prime;
- prime = gen_prime( nbits, 1, 2, extra_check, extra_check_arg);
- progress('\n');
- return prime;
+ prime = gen_prime( nbits, 1, 2, extra_check, extra_check_arg);
+ progress('\n');
+ return prime;
}
gcry_mpi_t
@@ -165,11 +168,11 @@ _gcry_generate_public_prime( unsigned int nbits,
int (*extra_check)(void*, gcry_mpi_t),
void *extra_check_arg)
{
- gcry_mpi_t prime;
+ gcry_mpi_t prime;
- prime = gen_prime( nbits, 0, 2, extra_check, extra_check_arg );
- progress('\n');
- return prime;
+ prime = gen_prime( nbits, 0, 2, extra_check, extra_check_arg );
+ progress('\n');
+ return prime;
}
@@ -227,111 +230,106 @@ prime_generate_internal (int mode,
val_2 = mpi_alloc_set_ui (2);
if ((! n) || ((mode == 1) && (n < 2)))
- err = GPG_ERR_INV_ARG;
-
- if (! err)
{
- 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);
+ err = GPG_ERR_INV_ARG;
+ goto leave;
+ }
- /* Generate first prime factor. */
- q = gen_prime (qbits, is_secret, randomlevel, NULL, NULL);
+ 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);
- if (mode == 1)
- q_factor = gen_prime (req_qbits, is_secret, randomlevel, NULL, NULL);
+ prime = gcry_mpi_new (pbits);
- /* Allocate an array to hold the factors + 2 for later
- usage. */
- factors = gcry_calloc (n + 2, sizeof (*factors));
- if (! factors)
- err = GPG_ERR_INTERNAL; /* FIXME. */
+ /* 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;
}
-
- if (! err)
+
+ /* 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)
{
- /* 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_INTERNAL;
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
}
- if (! err)
- /* 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_INTERNAL; /* FIXME. */
- else
- {
- for(i = 0; i < n; i++)
- {
- perms[i] = 1;
- pool[i] = gen_prime (fbits, is_secret,
- randomlevel, NULL, NULL);
- factors[i] = pool[i];
- }
- }
+ /* 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;
+ }
- if (err)
- break;
- }
- else
- {
- m_out_of_n (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. */
- }
- }
+ /* 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 (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. */
-
+ 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)
@@ -355,7 +353,7 @@ prime_generate_internal (int mode,
}
else
count1 = 0;
-
+
if (nprime > pbits)
{
if (++count2 > 20)
@@ -370,110 +368,114 @@ prime_generate_internal (int mode,
}
else
count2 = 0;
- }
- while (! ((nprime == pbits) && check_prime (prime, val_2)));
-
- if (! err)
- 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');
- }
+ }
+ while (! ((nprime == pbits) && check_prime (prime, val_2)));
- if (! err)
- if (ret_factors)
- {
- /* Caller wants the factors. */
- factors_new = gcry_calloc (n + 4, sizeof (*factors_new));
- if (! factors_new)
- err = GPG_ERR_INTERNAL; /* FIXME. */
- else 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 (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 (! err)
- 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 (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 (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 (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 (! err)
- if (! DBG_CIPHER)
- progress ('\n');
+ 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++)
@@ -530,14 +532,14 @@ gen_prime (unsigned int nbits, int secret, int randomlevel,
unsigned count1, count2;
int *mods;
- if( 0 && DBG_CIPHER )
- log_debug ("generate a prime of %u bits ", nbits );
+/* 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 */
+ /* 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 );
@@ -552,23 +554,23 @@ gen_prime (unsigned int nbits, int secret, int randomlevel,
/* generate a random number */
gcry_mpi_randomize( prime, nbits, randomlevel );
- /* Set high order bit to 1, set low order bit to 0. If we are
+ /* 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 keysize we set the 2 high order bits */
+ 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 */
+ /* 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 */
+ /* Now try some primes starting with prime. */
for(step=0; step < 20000; step += 2 )
{
- /* check against all the small primes we have in mods */
+ /* Check against all the small primes we have in mods. */
count1++;
for (i=0; (x = small_prime_numbers[i]); i++ )
{
@@ -578,41 +580,44 @@ gen_prime (unsigned int nbits, int secret, int randomlevel,
break;
}
if ( x )
- continue; /* found a multiple of an already known prime */
-
+ continue; /* Found a multiple of an already known prime. */
+
mpi_add_ui( ptest, prime, step );
- /* do a faster Fermat test */
+ /* 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;
- }
- }
+ {
+ /* 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 )
{
@@ -630,190 +635,219 @@ gen_prime (unsigned int nbits, int secret, int randomlevel,
static int
check_prime( gcry_mpi_t prime, gcry_mpi_t val_2 )
{
- int i;
- unsigned x;
- int count=0;
-
- /* check against small primes */
- for(i=0; (x = small_prime_numbers[i]); i++ ) {
- if( mpi_divisible_ui( prime, x ) )
- return 0;
- }
+ int i;
+ unsigned x;
+ int count=0;
- /* a quick fermat test */
+ /* Check against small primes. */
+ for (i=0; (x = small_prime_numbers[i]); i++ )
{
- 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 ) ) { /* if composite */
- mpi_free( result );
- progress('.');
- return 0;
- }
- mpi_free( result );
+ if ( mpi_divisible_ui( prime, x ) )
+ return 0;
}
- /* perform stronger tests */
- if( is_prime(prime, 5, &count ) )
- return 1; /* is probably a prime */
- progress('.');
- 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 );
+ }
+
+ /* perform stronger tests */
+ if ( is_prime(prime, 5, &count ) )
+ return 1; /* Probably a prime. */
+ progress('.');
+ return 0;
}
-/****************
+/*
* Return true if n is probably a prime
*/
static int
-is_prime( gcry_mpi_t n, int steps, int *count )
+is_prime (gcry_mpi_t n, int steps, 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 );
+ 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 );
+ /* 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 */
+ 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('+');
+ progress('+');
}
- rc = 1; /* may be a prime */
+ rc = 1; /* May be a prime. */
- leave:
- mpi_free( x );
- mpi_free( y );
- mpi_free( z );
- mpi_free( nminus1 );
- mpi_free( q );
+ leave:
+ mpi_free( x );
+ mpi_free( y );
+ mpi_free( z );
+ mpi_free( nminus1 );
+ mpi_free( q );
- return rc;
+ return rc;
}
static void
-m_out_of_n( char *array, int m, int n )
+m_out_of_n ( char *array, int m, int n )
{
- int i=0, i1=0, j=0, jp=0, j1=0, k1=0, k2=0;
-
- if( !m || m >= n )
- return;
-
- if( m == 1 ) { /* special case */
- for(i=0; i < n; i++ )
- if( array[i] ) {
- array[i++] = 0;
- if( i >= n )
- i = 0;
- array[i] = 1;
- return;
- }
- BUG();
- }
+ int i=0, i1=0, j=0, jp=0, j1=0, k1=0, k2=0;
+
+ if( !m || m >= n )
+ return;
- for(j=1; j < n; j++ ) {
- if( array[n-1] == array[n-j-1] )
- continue;
- j1 = j;
- break;
+ if( m == 1 )
+ {
+ /* Special case. */
+ for (i=0; i < n; i++ )
+ {
+ if( array[i] )
+ {
+ array[i++] = 0;
+ if( i >= n )
+ i = 0;
+ array[i] = 1;
+ return;
+ }
+ }
+ BUG();
}
- if( m & 1 ) { /* m is odd */
- if( array[n-1] ) {
- if( j1 & 1 ) {
- k1 = n - j1;
- k2 = k1+2;
- if( k2 > n )
- k2 = n;
- goto leave;
- }
- goto scan;
- }
- k2 = n - j1 - 1;
- if( k2 == 0 ) {
- k1 = i;
- k2 = n - j1;
- }
- else if( array[k2] && array[k2-1] )
- k1 = n;
- else
- k1 = k2 + 1;
+ for (j=1; j < n; j++ )
+ {
+ if ( array[n-1] == array[n-j-1])
+ continue;
+ j1 = j;
+ break;
}
- else { /* m is even */
- if( !array[n-1] ) {
- k1 = n - j1;
- k2 = k1 + 1;
- goto leave;
- }
- if( !(j1 & 1) ) {
- k1 = n - j1;
- k2 = k1+2;
- if( k2 > n )
- k2 = n;
- goto leave;
- }
- scan:
- jp = n - j1 - 1;
- for(i=1; i <= jp; i++ ) {
- i1 = jp + 2 - i;
- if( array[i1-1] ) {
- if( array[i1-2] ) {
- k1 = i1 - 1;
- k2 = n - j1;
- }
- else {
- k1 = i1 - 1;
- k2 = n + 1 - j1;
+ if ( (m & 1) )
+ {
+ /* M is odd. */
+ if( array[n-1] )
+ {
+ if( j1 & 1 )
+ {
+ k1 = n - j1;
+ k2 = k1+2;
+ if( k2 > n )
+ k2 = n;
+ goto leave;
+ }
+ goto scan;
+ }
+ k2 = n - j1 - 1;
+ if( k2 == 0 )
+ {
+ k1 = i;
+ k2 = n - j1;
+ }
+ else if( array[k2] && array[k2-1] )
+ k1 = n;
+ else
+ k1 = k2 + 1;
+ }
+ else
+ {
+ /* M is even. */
+ if( !array[n-1] )
+ {
+ k1 = n - j1;
+ k2 = k1 + 1;
+ goto leave;
+ }
+
+ if( !(j1 & 1) )
+ {
+ k1 = n - j1;
+ k2 = k1+2;
+ if( k2 > n )
+ k2 = n;
+ goto leave;
+ }
+ scan:
+ jp = n - j1 - 1;
+ for (i=1; i <= jp; i++ )
+ {
+ i1 = jp + 2 - i;
+ if( array[i1-1] )
+ {
+ if( array[i1-2] )
+ {
+ k1 = i1 - 1;
+ k2 = n - j1;
}
- goto leave;
- }
- }
- k1 = 1;
- k2 = n + 1 - m;
+ else
+ {
+ k1 = i1 - 1;
+ k2 = n + 1 - j1;
+ }
+ goto leave;
+ }
+ }
+ k1 = 1;
+ k2 = n + 1 - m;
}
- leave:
- array[k1-1] = !array[k1-1];
- array[k2-1] = !array[k2-1];
+ leave:
+ array[k1-1] = !array[k1-1];
+ array[k2-1] = !array[k2-1];
}
@@ -851,11 +885,10 @@ gcry_prime_generate (gcry_mpi_t *prime, unsigned int prime_bits,
if (! err)
if (cb_func)
{
- /* Additional check */
+ /* Additional check. */
if (! (*cb_func) (cb_arg, 0, prime_generated))
{
/* Failed, deallocate resources. */
-
unsigned int i;
mpi_free (prime_generated);
@@ -865,7 +898,7 @@ gcry_prime_generate (gcry_mpi_t *prime, unsigned int prime_bits,
mpi_free (factors_generated[i]);
gcry_free (factors_generated);
}
- err = GPG_ERR_INTERNAL; /* FIXME. */
+ err = GPG_ERR_GENERAL;
}
}
@@ -884,12 +917,12 @@ gcry_error_t
gcry_prime_check (gcry_mpi_t x, unsigned int flags)
{
gcry_err_code_t err = GPG_ERR_NO_ERROR;
- gcry_mpi_t test_value = mpi_alloc_set_ui (2); /* ? */
+ gcry_mpi_t val_2 = mpi_alloc_set_ui (2); /* Used by the Fermat test. */
- if (! check_prime (x, test_value))
+ if (! check_prime (x, val_2))
err = GPG_ERR_NO_PRIME;
- mpi_free (test_value);
+ mpi_free (val_2);
return gcry_error (err);
}
@@ -919,16 +952,13 @@ gcry_prime_group_generator (gcry_mpi_t *r_g,
if (n < 2)
return gpg_error (GPG_ERR_INV_ARG);
-#if 1 /* 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);
- }
-#endif /* Extra sanity check. */
+ /* 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