diff options
author | Werner Koch <wk@gnupg.org> | 2003-12-19 09:20:41 +0000 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2003-12-19 09:20:41 +0000 |
commit | f2541aa8a390d5f26512135bc2079c3aa0f5cc47 (patch) | |
tree | f4e48ff1d0b50253d922d04bf0b6707e5b690855 /cipher/primegen.c | |
parent | adf881257f924c201555476be103f5920618fc8e (diff) | |
download | libgcrypt-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.c | 858 |
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 |