summaryrefslogtreecommitdiff
path: root/plugins/MirOTR/Libgcrypt/cipher/primegen.c
diff options
context:
space:
mode:
authorRené Schümann <white06tiger@gmail.com>2015-03-20 12:32:29 +0000
committerRené Schümann <white06tiger@gmail.com>2015-03-20 12:32:29 +0000
commit539705d58fc39a28388ff18c695dd406f4ffd1d9 (patch)
tree51db7a37a66c09f41734ba5573d972aae9f30d71 /plugins/MirOTR/Libgcrypt/cipher/primegen.c
parent90171f125f36488dc08f5cfe0b0d4b78d995f08d (diff)
MirOTR: Libgcrypt and Libgpg-error update
Libgcrypt 1.4.6 => 1.6.3 Libgpg-error 1.9 => 1.18 git-svn-id: http://svn.miranda-ng.org/main/trunk@12449 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/MirOTR/Libgcrypt/cipher/primegen.c')
-rw-r--r--plugins/MirOTR/Libgcrypt/cipher/primegen.c515
1 files changed, 260 insertions, 255 deletions
diff --git a/plugins/MirOTR/Libgcrypt/cipher/primegen.c b/plugins/MirOTR/Libgcrypt/cipher/primegen.c
index b869bee839..e46bf184e0 100644
--- a/plugins/MirOTR/Libgcrypt/cipher/primegen.c
+++ b/plugins/MirOTR/Libgcrypt/cipher/primegen.c
@@ -31,7 +31,7 @@
#include "cipher.h"
#include "ath.h"
-static gcry_mpi_t gen_prime (unsigned int nbits, int secret, int randomlevel,
+static gcry_mpi_t gen_prime (unsigned int nbits, int secret, int randomlevel,
int (*extra_check)(void *, gcry_mpi_t),
void *extra_check_arg);
static int check_prime( gcry_mpi_t prime, gcry_mpi_t val_2, int rm_rounds,
@@ -132,7 +132,7 @@ static int no_of_small_prime_numbers = DIM (small_prime_numbers) - 1;
/* An object and a list to build up a global pool of primes. See
save_pool_prime and get_pool_prime. */
-struct primepool_s
+struct primepool_s
{
struct primepool_s *next;
gcry_mpi_t prime; /* If this is NULL the entry is not used. */
@@ -141,9 +141,20 @@ struct primepool_s
};
struct primepool_s *primepool;
/* Mutex used to protect access to the primepool. */
-static ath_mutex_t primepool_lock = ATH_MUTEX_INITIALIZER;
+static ath_mutex_t primepool_lock;
+gcry_err_code_t
+_gcry_primegen_init (void)
+{
+ gcry_err_code_t ec;
+
+ ec = ath_mutex_init (&primepool_lock);
+ if (ec)
+ return gpg_err_code_from_errno (ec);
+ return ec;
+}
+
/* Save PRIME which has been generated at RANDOMLEVEL for later
use. Needs to be called while primepool_lock is being hold. Note
@@ -163,12 +174,12 @@ save_pool_prime (gcry_mpi_t prime, gcry_random_level_t randomlevel)
/* Remove some of the entries. Our strategy is removing
the last third from the list. */
int i;
-
+
for (i=0, item2 = primepool; item2; item2 = item2->next)
{
if (i >= n/3*2)
{
- gcry_mpi_release (item2->prime);
+ _gcry_mpi_release (item2->prime);
item2->prime = NULL;
if (!item)
item = item2;
@@ -177,12 +188,12 @@ save_pool_prime (gcry_mpi_t prime, gcry_random_level_t randomlevel)
}
if (!item)
{
- item = gcry_calloc (1, sizeof *item);
+ item = xtrycalloc (1, sizeof *item);
if (!item)
{
/* Out of memory. Silently giving up. */
- gcry_mpi_release (prime);
- return;
+ _gcry_mpi_release (prime);
+ return;
}
item->next = primepool;
primepool = item;
@@ -195,7 +206,7 @@ save_pool_prime (gcry_mpi_t prime, gcry_random_level_t randomlevel)
/* Return a prime for the prime pool or NULL if none has been found.
The prime needs to match NBITS and randomlevel. This function needs
- to be called why the primepool_look is being hold. */
+ to be called with the primepool_look is being hold. */
static gcry_mpi_t
get_pool_prime (unsigned int nbits, gcry_random_level_t randomlevel)
{
@@ -359,13 +370,13 @@ prime_generate_internal (int need_q_factor,
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);
/* Allocate an integer to old the new prime. */
- prime = gcry_mpi_new (pbits);
+ prime = mpi_new (pbits);
/* Generate first prime factor. */
q = gen_prime (qbits, is_secret, randomlevel, NULL, NULL);
@@ -373,9 +384,9 @@ prime_generate_internal (int need_q_factor,
/* Generate a specific Q-Factor if requested. */
if (need_q_factor)
q_factor = gen_prime (req_qbits, is_secret, randomlevel, NULL, NULL);
-
+
/* Allocate an array to hold all factors + 2 for later usage. */
- factors = gcry_calloc (n + 2, sizeof (*factors));
+ factors = xtrycalloc (n + 2, sizeof (*factors));
if (!factors)
{
err = gpg_err_code_from_errno (errno);
@@ -383,7 +394,7 @@ prime_generate_internal (int need_q_factor,
}
/* Allocate an array to track pool usage. */
- pool_in_use = gcry_malloc (n * sizeof *pool_in_use);
+ pool_in_use = xtrymalloc (n * sizeof *pool_in_use);
if (!pool_in_use)
{
err = gpg_err_code_from_errno (errno);
@@ -391,10 +402,10 @@ prime_generate_internal (int need_q_factor,
}
for (i=0; i < n; i++)
pool_in_use[i] = -1;
-
+
/* Make a pool of 3n+5 primes (this is an arbitrary value). We
- require at least 30 primes for are useful selection process.
-
+ require at least 30 primes for are useful selection process.
+
Fixme: We need to research the best formula for sizing the pool.
*/
m = n * 3 + 5;
@@ -402,7 +413,7 @@ prime_generate_internal (int need_q_factor,
m += 5;
if (m < 30)
m = 30;
- pool = gcry_calloc (m , sizeof (*pool));
+ pool = xtrycalloc (m , sizeof (*pool));
if (! pool)
{
err = gpg_err_code_from_errno (errno);
@@ -428,7 +439,7 @@ prime_generate_internal (int need_q_factor,
}
/* Init m_out_of_n(). */
- perms = gcry_calloc (1, m);
+ perms = xtrycalloc (1, m);
if (!perms)
{
err = gpg_err_code_from_errno (errno);
@@ -443,7 +454,7 @@ prime_generate_internal (int need_q_factor,
is_locked = 1;
for (i = 0; i < n; i++)
{
- perms[i] = 1;
+ perms[i] = 1;
/* At a maximum we use strong random for the factors.
This saves us a lot of entropy. Given that Q and
possible Q-factor are also used in the final prime
@@ -520,15 +531,15 @@ prime_generate_internal (int need_q_factor,
if (i == n)
{
/* Ran out of permutations: Allocate new primes. */
- gcry_free (perms);
+ xfree (perms);
perms = NULL;
progress ('!');
- goto next_try;
+ goto next_try;
}
}
/* 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);
@@ -553,7 +564,7 @@ prime_generate_internal (int need_q_factor,
}
else
count1 = 0;
-
+
if (nprime > pbits)
{
if (++count2 > 20)
@@ -575,25 +586,25 @@ prime_generate_internal (int need_q_factor,
if (DBG_CIPHER)
{
progress ('\n');
- log_mpidump ("prime : ", prime);
- log_mpidump ("factor q: ", q);
+ log_mpidump ("prime ", prime);
+ log_mpidump ("factor q", q);
if (need_q_factor)
- log_mpidump ("factor q0: ", q_factor);
+ log_mpidump ("factor q0", q_factor);
for (i = 0; i < n; i++)
- log_mpidump ("factor pi: ", factors[i]);
+ log_mpidump ("factor pi", factors[i]);
log_debug ("bit sizes: prime=%u, q=%u",
mpi_get_nbits (prime), mpi_get_nbits (q));
if (need_q_factor)
- log_debug (", q0=%u", mpi_get_nbits (q_factor));
+ log_printf (", 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');
+ log_printf (", p%d=%u", i, mpi_get_nbits (factors[i]));
+ log_printf ("\n");
}
if (ret_factors)
{
/* Caller wants the factors. */
- factors_new = gcry_calloc (n + 4, sizeof (*factors_new));
+ factors_new = xtrycalloc (n + 4, sizeof (*factors_new));
if (! factors_new)
{
err = gpg_err_code_from_errno (errno);
@@ -603,7 +614,7 @@ prime_generate_internal (int need_q_factor,
if (all_factors)
{
i = 0;
- factors_new[i++] = gcry_mpi_set_ui (NULL, 2);
+ factors_new[i++] = mpi_set_ui (NULL, 2);
factors_new[i++] = mpi_copy (q);
if (need_q_factor)
factors_new[i++] = mpi_copy (q_factor);
@@ -624,14 +635,14 @@ prime_generate_internal (int need_q_factor,
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 (need_q_factor)
err = GPG_ERR_NOT_IMPLEMENTED;
else
@@ -644,11 +655,7 @@ prime_generate_internal (int need_q_factor,
{
mpi_add_ui (g, g, 1);
if (DBG_CIPHER)
- {
- log_debug ("checking g:");
- gcry_mpi_dump (g);
- log_printf ("\n");
- }
+ log_printmpi ("checking g", g);
else
progress('^');
for (i = 0; i < n + 2; i++)
@@ -656,13 +663,13 @@ prime_generate_internal (int need_q_factor,
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);
+ 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]);
@@ -671,7 +678,7 @@ prime_generate_internal (int need_q_factor,
mpi_free (pmin1);
}
}
-
+
if (! DBG_CIPHER)
progress ('\n');
@@ -699,13 +706,13 @@ prime_generate_internal (int need_q_factor,
if (is_locked && ath_mutex_unlock (&primepool_lock))
err = GPG_ERR_INTERNAL;
is_locked = 0;
- gcry_free (pool);
+ xfree (pool);
}
- gcry_free (pool_in_use);
+ xfree (pool_in_use);
if (factors)
- gcry_free (factors); /* Factors are shallow copies. */
+ xfree (factors); /* Factors are shallow copies. */
if (perms)
- gcry_free (perms);
+ xfree (perms);
mpi_free (val_2);
mpi_free (q);
@@ -723,7 +730,7 @@ prime_generate_internal (int need_q_factor,
{
for (i = 0; factors_new[i]; i++)
mpi_free (factors_new[i]);
- gcry_free (factors_new);
+ xfree (factors_new);
}
mpi_free (prime);
}
@@ -733,24 +740,27 @@ prime_generate_internal (int need_q_factor,
/* Generate a prime used for discrete logarithm algorithms; i.e. this
- prime will be public and no strong random is required. */
-gcry_mpi_t
+ prime will be public and no strong random is required. On success
+ R_PRIME receives a new MPI with the prime. On error R_PRIME is set
+ to NULL and an error code is returned. If RET_FACTORS is not NULL
+ it is set to an allocated array of factors on success or to NULL on
+ error. */
+gcry_err_code_t
_gcry_generate_elg_prime (int mode, unsigned pbits, unsigned qbits,
- gcry_mpi_t g, gcry_mpi_t **ret_factors)
+ gcry_mpi_t g,
+ gcry_mpi_t *r_prime, gcry_mpi_t **ret_factors)
{
- gcry_err_code_t err = GPG_ERR_NO_ERROR;
- gcry_mpi_t prime = NULL;
-
- err = prime_generate_internal ((mode == 1), &prime, pbits, qbits, g,
- ret_factors, GCRY_WEAK_RANDOM, 0, 0,
- NULL, NULL);
-
- return prime;
+ *r_prime = NULL;
+ if (ret_factors)
+ *ret_factors = NULL;
+ return prime_generate_internal ((mode == 1), r_prime, pbits, qbits, g,
+ ret_factors, GCRY_WEAK_RANDOM, 0, 0,
+ NULL, NULL);
}
static gcry_mpi_t
-gen_prime (unsigned int nbits, int secret, int randomlevel,
+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;
@@ -758,18 +768,18 @@ gen_prime (unsigned int nbits, int secret, int randomlevel,
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 );
+ mods = 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 );
+ prime = secret? mpi_snew (nbits): mpi_new (nbits);
result = mpi_alloc_like( prime );
pminus1= mpi_alloc_like( prime );
ptest = mpi_alloc_like( prime );
@@ -777,10 +787,10 @@ gen_prime (unsigned int nbits, int secret, int randomlevel,
for (;;)
{ /* try forvever */
int dotcount=0;
-
+
/* generate a random number */
- gcry_mpi_randomize( prime, nbits, randomlevel );
-
+ _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
@@ -789,17 +799,17 @@ gen_prime (unsigned int nbits, int secret, int randomlevel,
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 )
+ 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++ )
+ for (i=0; (x = small_prime_numbers[i]); i++ )
{
while ( mods[i] + step >= x )
mods[i] -= x;
@@ -808,15 +818,15 @@ gen_prime (unsigned int nbits, int secret, int randomlevel,
}
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 );
+ mpi_powm( result, val_2, pminus1, ptest );
if ( !mpi_cmp_ui( result, 1 ) )
- {
+ {
/* Not composite, perform stronger tests */
if (is_prime(ptest, 5, &count2 ))
{
@@ -828,21 +838,21 @@ gen_prime (unsigned int nbits, int secret, int randomlevel,
}
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;
+ xfree(mods);
+ return ptest;
}
}
}
@@ -872,7 +882,7 @@ check_prime( gcry_mpi_t prime, gcry_mpi_t val_2, int rm_rounds,
for (i=0; (x = small_prime_numbers[i]); i++ )
{
if ( mpi_divisible_ui( prime, x ) )
- return 0;
+ return !mpi_cmp_ui (prime, x);
}
/* A quick Fermat test. */
@@ -880,10 +890,10 @@ check_prime( gcry_mpi_t prime, gcry_mpi_t val_2, int rm_rounds,
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_powm( result, val_2, pminus1, prime );
mpi_free( pminus1 );
if ( mpi_cmp_ui( result, 1 ) )
- {
+ {
/* Is composite. */
mpi_free( result );
progress('.');
@@ -924,7 +934,7 @@ is_prime (gcry_mpi_t n, int steps, unsigned int *count)
unsigned nbits = mpi_get_nbits( n );
if (steps < 5) /* Make sure that we do at least 5 rounds. */
- steps = 5;
+ steps = 5;
mpi_sub_ui( nminus1, n, 1 );
@@ -942,7 +952,7 @@ is_prime (gcry_mpi_t n, int steps, unsigned int *count)
}
else
{
- gcry_mpi_randomize( x, nbits, GCRY_WEAK_RANDOM );
+ _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. */
@@ -957,12 +967,12 @@ is_prime (gcry_mpi_t n, int steps, unsigned int *count)
}
gcry_assert (mpi_cmp (x, nminus1) < 0 && mpi_cmp_ui (x, 1) > 0);
}
- gcry_mpi_powm ( y, x, q, n);
+ 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);
+ mpi_powm(y, y, a2, n);
if( !mpi_cmp_ui( y, 1 ) )
goto leave; /* Not a prime. */
}
@@ -988,7 +998,7 @@ is_prime (gcry_mpi_t n, int steps, unsigned int *count)
/* Given ARRAY of size N with M elements set to true produce a
modified array with the next permutation of M elements. Note, that
ARRAY is used in a one-bit-per-byte approach. To detected the last
- permutation it is useful to intialize the array with the first M
+ permutation it is useful to initialize the array with the first M
element set to true and use this test:
m_out_of_n (array, m, n);
for (i = j = 0; i < n && j < m; i++)
@@ -996,7 +1006,7 @@ is_prime (gcry_mpi_t n, int steps, unsigned int *count)
j++;
if (j == m)
goto ready;
-
+
This code is based on the algorithm 452 from the "Collected
Algorithms From ACM, Volume II" by C. N. Liu and D. T. Tang.
*/
@@ -1010,7 +1020,7 @@ m_out_of_n ( char *array, int m, int n )
/* Need to handle this simple case separately. */
if( m == 1 )
- {
+ {
for (i=0; i < n; i++ )
{
if ( array[i] )
@@ -1060,7 +1070,7 @@ m_out_of_n ( char *array, int m, int n )
else
k1 = k2 + 1;
}
- else
+ else
{
/* M is even. */
if( !array[n-1] )
@@ -1069,7 +1079,7 @@ m_out_of_n ( char *array, int m, int n )
k2 = k1 + 1;
goto leave;
}
-
+
if( !(j1 & 1) )
{
k1 = n - j1;
@@ -1080,7 +1090,7 @@ m_out_of_n ( char *array, int m, int n )
}
scan:
jp = n - j1 - 1;
- for (i=1; i <= jp; i++ )
+ for (i=1; i <= jp; i++ )
{
i1 = jp + 2 - i;
if( array[i1-1] )
@@ -1114,135 +1124,131 @@ m_out_of_n ( char *array, int m, int n )
non-zero, allocate a new, NULL-terminated array holding the prime
factors and store it in FACTORS. FLAGS might be used to influence
the prime number generation process. */
-gcry_error_t
-gcry_prime_generate (gcry_mpi_t *prime, unsigned int prime_bits,
- unsigned int factor_bits, gcry_mpi_t **factors,
- gcry_prime_check_func_t cb_func, void *cb_arg,
- gcry_random_level_t random_level,
- unsigned int flags)
+gcry_err_code_t
+_gcry_prime_generate (gcry_mpi_t *prime, unsigned int prime_bits,
+ unsigned int factor_bits, gcry_mpi_t **factors,
+ gcry_prime_check_func_t cb_func, void *cb_arg,
+ gcry_random_level_t random_level,
+ unsigned int flags)
{
- gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ gcry_err_code_t rc = 0;
gcry_mpi_t *factors_generated = NULL;
gcry_mpi_t prime_generated = NULL;
unsigned int mode = 0;
if (!prime)
- return gpg_error (GPG_ERR_INV_ARG);
- *prime = NULL;
+ return GPG_ERR_INV_ARG;
+ *prime = NULL;
if (flags & GCRY_PRIME_FLAG_SPECIAL_FACTOR)
mode = 1;
/* Generate. */
- err = prime_generate_internal ((mode==1), &prime_generated, prime_bits,
- factor_bits, NULL,
- factors? &factors_generated : NULL,
- random_level, flags, 1,
- cb_func, cb_arg);
+ rc = prime_generate_internal ((mode==1), &prime_generated, prime_bits,
+ factor_bits, NULL,
+ factors? &factors_generated : NULL,
+ random_level, flags, 1,
+ cb_func, cb_arg);
- if (! err)
- if (cb_func)
- {
- /* Additional check. */
- if ( !cb_func (cb_arg, GCRY_PRIME_CHECK_AT_FINISH, prime_generated))
- {
- /* Failed, deallocate resources. */
- unsigned int i;
+ if (!rc && cb_func)
+ {
+ /* Additional check. */
+ if ( !cb_func (cb_arg, GCRY_PRIME_CHECK_AT_FINISH, prime_generated))
+ {
+ /* Failed, deallocate resources. */
+ unsigned int i;
- mpi_free (prime_generated);
- if (factors)
- {
- for (i = 0; factors_generated[i]; i++)
- mpi_free (factors_generated[i]);
- gcry_free (factors_generated);
- }
- err = GPG_ERR_GENERAL;
- }
- }
+ mpi_free (prime_generated);
+ if (factors)
+ {
+ for (i = 0; factors_generated[i]; i++)
+ mpi_free (factors_generated[i]);
+ xfree (factors_generated);
+ }
+ rc = GPG_ERR_GENERAL;
+ }
+ }
- if (! err)
+ if (!rc)
{
if (factors)
*factors = factors_generated;
*prime = prime_generated;
}
- return gcry_error (err);
+ return rc;
}
-/* Check wether the number X is prime. */
-gcry_error_t
-gcry_prime_check (gcry_mpi_t x, unsigned int flags)
+/* Check whether the number X is prime. */
+gcry_err_code_t
+_gcry_prime_check (gcry_mpi_t x, unsigned int flags)
{
- gcry_err_code_t err = GPG_ERR_NO_ERROR;
- gcry_mpi_t val_2 = mpi_alloc_set_ui (2); /* Used by the Fermat test. */
-
(void)flags;
+ switch (mpi_cmp_ui (x, 2))
+ {
+ case 0: return 0; /* 2 is a prime */
+ case -1: return GPG_ERR_NO_PRIME; /* Only numbers > 1 are primes. */
+ }
+
/* We use 64 rounds because the prime we are going to test is not
guaranteed to be a random one. */
- if (! check_prime (x, val_2, 64, NULL, NULL))
- err = GPG_ERR_NO_PRIME;
-
- mpi_free (val_2);
+ if (check_prime (x, mpi_const (MPI_C_TWO), 64, NULL, NULL))
+ return 0;
- return gcry_error (err);
+ return GPG_ERR_NO_PRIME;
}
/* 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_err_code_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);
+ gcry_mpi_t tmp = mpi_new (0);
+ gcry_mpi_t b = mpi_new (0);
+ gcry_mpi_t pmin1 = mpi_new (0);
+ gcry_mpi_t g = start_g? mpi_copy (start_g) : 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;
+ return GPG_ERR_INV_ARG;
+ *r_g = NULL;
for (n=0; factors[n]; n++)
;
if (n < 2)
- return gpg_error (GPG_ERR_INV_ARG);
+ return GPG_ERR_INV_ARG;
- /* Extra sanity check - usually disabled. */
+ /* 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
+
+ mpi_sub_ui (pmin1, prime, 1);
+ do
{
if (first)
first = 0;
else
- gcry_mpi_add_ui (g, g, 1);
-
+ mpi_add_ui (g, g, 1);
+
if (DBG_CIPHER)
- {
- log_debug ("checking g:");
- gcry_mpi_dump (g);
- log_debug ("\n");
- }
+ log_printmpi ("checking g", g);
else
progress('^');
-
+
for (i = 0; i < n; i++)
{
mpi_fdiv_q (tmp, pmin1, factors[i]);
- gcry_mpi_powm (b, g, tmp, prime);
+ mpi_powm (b, g, tmp, prime);
if (! mpi_cmp_ui (b, 1))
break;
}
@@ -1250,26 +1256,26 @@ gcry_prime_group_generator (gcry_mpi_t *r_g,
progress('\n');
}
while (i < n);
-
- gcry_mpi_release (tmp);
- gcry_mpi_release (b);
- gcry_mpi_release (pmin1);
- *r_g = g;
- return 0;
+ _gcry_mpi_release (tmp);
+ _gcry_mpi_release (b);
+ _gcry_mpi_release (pmin1);
+ *r_g = g;
+
+ return 0;
}
/* Convenience function to release the factors array. */
void
-gcry_prime_release_factors (gcry_mpi_t *factors)
+_gcry_prime_release_factors (gcry_mpi_t *factors)
{
if (factors)
{
int i;
-
+
for (i=0; factors[i]; i++)
mpi_free (factors[i]);
- gcry_free (factors);
+ xfree (factors);
}
}
@@ -1279,11 +1285,11 @@ gcry_prime_release_factors (gcry_mpi_t *factors)
static gcry_mpi_t
find_x931_prime (const gcry_mpi_t pfirst)
{
- gcry_mpi_t val_2 = mpi_alloc_set_ui (2);
+ gcry_mpi_t val_2 = mpi_alloc_set_ui (2);
gcry_mpi_t prime;
-
- prime = gcry_mpi_copy (pfirst);
- /* If P is even add 1. */
+
+ prime = mpi_copy (pfirst);
+ /* If P is even add 1. */
mpi_set_bit (prime, 0);
/* We use 64 Rabin-Miller rounds which is better and thus
@@ -1299,7 +1305,7 @@ find_x931_prime (const gcry_mpi_t pfirst)
}
-/* Generate a prime using the algorithm from X9.31 appendix B.4.
+/* Generate a prime using the algorithm from X9.31 appendix B.4.
This function requires that the provided public exponent E is odd.
XP, XP1 and XP2 are the seed values. All values are mandatory.
@@ -1308,7 +1314,7 @@ find_x931_prime (const gcry_mpi_t pfirst)
internal values P1 and P2 are saved at these addresses. On error
NULL is returned. */
gcry_mpi_t
-_gcry_derive_x931_prime (const gcry_mpi_t xp,
+_gcry_derive_x931_prime (const gcry_mpi_t xp,
const gcry_mpi_t xp1, const gcry_mpi_t xp2,
const gcry_mpi_t e,
gcry_mpi_t *r_p1, gcry_mpi_t *r_p2)
@@ -1327,20 +1333,20 @@ _gcry_derive_x931_prime (const gcry_mpi_t xp,
{
gcry_mpi_t r1, tmp;
-
+
/* r1 = (p2^{-1} mod p1)p2 - (p1^{-1} mod p2) */
tmp = mpi_alloc_like (p1);
mpi_invm (tmp, p2, p1);
mpi_mul (tmp, tmp, p2);
r1 = tmp;
-
+
tmp = mpi_alloc_like (p2);
mpi_invm (tmp, p1, p2);
mpi_mul (tmp, tmp, p1);
mpi_sub (r1, r1, tmp);
/* Fixup a negative value. */
- if (mpi_is_neg (r1))
+ if (mpi_has_sign (r1))
mpi_add (r1, r1, p1p2);
/* yp0 = xp + (r1 - xp mod p1*p2) */
@@ -1350,7 +1356,7 @@ _gcry_derive_x931_prime (const gcry_mpi_t xp,
mpi_free (r1);
/* Fixup a negative value. */
- if (mpi_cmp (yp0, xp) < 0 )
+ if (mpi_cmp (yp0, xp) < 0 )
mpi_add (yp0, yp0, p1p2);
}
@@ -1378,15 +1384,15 @@ _gcry_derive_x931_prime (const gcry_mpi_t xp,
*/
{
- gcry_mpi_t val_2 = mpi_alloc_set_ui (2);
+ gcry_mpi_t val_2 = mpi_alloc_set_ui (2);
gcry_mpi_t gcdtmp = mpi_alloc_like (yp0);
int gcdres;
-
+
mpi_sub_ui (p1p2, p1p2, 1); /* Adjust for loop body. */
mpi_sub_ui (yp0, yp0, 1); /* Ditto. */
for (;;)
{
- gcdres = gcry_mpi_gcd (gcdtmp, e, yp0);
+ gcdres = mpi_gcd (gcdtmp, e, yp0);
mpi_add_ui (yp0, yp0, 1);
if (!gcdres)
progress ('/'); /* gcd (e, yp0-1) != 1 */
@@ -1453,9 +1459,9 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits,
; /* No seed value given: We are asked to generate it. */
else if (!seed || seedlen < qbits/8)
return GPG_ERR_INV_ARG;
-
+
/* Allocate a buffer to later compute SEED+some_increment. */
- seed_plus = gcry_malloc (seedlen < 20? 20:seedlen);
+ seed_plus = xtrymalloc (seedlen < 20? 20:seedlen);
if (!seed_plus)
{
ec = gpg_err_code_from_syserror ();
@@ -1465,10 +1471,10 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits,
val_2 = mpi_alloc_set_ui (2);
value_n = (pbits - 1) / qbits;
value_b = (pbits - 1) - value_n * qbits;
- value_w = gcry_mpi_new (pbits);
- value_x = gcry_mpi_new (pbits);
+ value_w = mpi_new (pbits);
+ value_x = mpi_new (pbits);
- restart:
+ restart:
/* Generate Q. */
for (;;)
{
@@ -1476,10 +1482,10 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits,
if (!seed)
{
seedlen = sizeof seed_help_buffer;
- gcry_create_nonce (seed_help_buffer, seedlen);
+ _gcry_create_nonce (seed_help_buffer, seedlen);
seed = seed_help_buffer;
}
-
+
/* Step 2: U = sha1(seed) ^ sha1((seed+1) mod 2^{qbits}) */
memcpy (seed_plus, seed, seedlen);
for (i=seedlen-1; i >= 0; i--)
@@ -1488,20 +1494,20 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits,
if (seed_plus[i])
break;
}
- gcry_md_hash_buffer (GCRY_MD_SHA1, value_u, seed, seedlen);
- gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
+ _gcry_md_hash_buffer (GCRY_MD_SHA1, value_u, seed, seedlen);
+ _gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
for (i=0; i < sizeof value_u; i++)
value_u[i] ^= digest[i];
-
+
/* Step 3: Form q from U */
- gcry_mpi_release (prime_q); prime_q = NULL;
- ec = gpg_err_code (gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG,
- value_u, sizeof value_u, NULL));
+ _gcry_mpi_release (prime_q); prime_q = NULL;
+ ec = _gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG,
+ value_u, sizeof value_u, NULL);
if (ec)
goto leave;
mpi_set_highbit (prime_q, qbits-1 );
mpi_set_bit (prime_q, 0);
-
+
/* Step 4: Test whether Q is prime using 64 round of Rabin-Miller. */
if (check_prime (prime_q, val_2, 64, NULL, NULL))
break; /* Yes, Q is prime. */
@@ -1509,21 +1515,21 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits,
/* Step 5. */
seed = NULL; /* Force a new seed at Step 1. */
}
-
+
/* Step 6. Note that we do no use an explicit offset but increment
SEED_PLUS accordingly. SEED_PLUS is currently SEED+1. */
counter = 0;
/* Generate P. */
- prime_p = gcry_mpi_new (pbits);
+ prime_p = mpi_new (pbits);
for (;;)
{
- /* Step 7: For k = 0,...n let
- V_k = sha1(seed+offset+k) mod 2^{qbits}
- Step 8: W = V_0 + V_1*2^160 +
- ...
+ /* Step 7: For k = 0,...n let
+ V_k = sha1(seed+offset+k) mod 2^{qbits}
+ Step 8: W = V_0 + V_1*2^160 +
+ ...
+ V_{n-1}*2^{(n-1)*160}
- + (V_{n} mod 2^b)*2^{n*160}
+ + (V_{n} mod 2^b)*2^{n*160}
*/
mpi_set_ui (value_w, 0);
for (value_k=0; value_k <= value_n; value_k++)
@@ -1541,11 +1547,11 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits,
if (seed_plus[i])
break;
}
- gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
-
- gcry_mpi_release (tmpval); tmpval = NULL;
- ec = gpg_err_code (gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG,
- digest, sizeof digest, NULL));
+ _gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
+
+ _gcry_mpi_release (tmpval); tmpval = NULL;
+ ec = _gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG,
+ digest, sizeof digest, NULL);
if (ec)
goto leave;
if (value_k == value_n)
@@ -1607,13 +1613,13 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits,
leave:
- gcry_mpi_release (tmpval);
- gcry_mpi_release (value_x);
- gcry_mpi_release (value_w);
- gcry_mpi_release (prime_p);
- gcry_mpi_release (prime_q);
- gcry_free (seed_plus);
- gcry_mpi_release (val_2);
+ _gcry_mpi_release (tmpval);
+ _gcry_mpi_release (value_x);
+ _gcry_mpi_release (value_w);
+ _gcry_mpi_release (prime_p);
+ _gcry_mpi_release (prime_q);
+ xfree (seed_plus);
+ _gcry_mpi_release (val_2);
return ec;
}
@@ -1631,7 +1637,7 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits,
value is stored at R_COUNTER and the seed actually used for
generation is stored at R_SEED and R_SEEDVALUE. The hash algorithm
used is stored at R_HASHALGO.
-
+
Note that this function is very similar to the fips186_2 code. Due
to the minor differences, other buffer sizes and for documentarion,
we use a separate function.
@@ -1652,7 +1658,7 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
gcry_mpi_t tmpval = NULL; /* Helper variable. */
int hashalgo; /* The id of the Approved Hash Function. */
int i;
-
+
unsigned char value_u[256/8];
int value_n, value_b, value_j;
int counter;
@@ -1678,11 +1684,11 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
return GPG_ERR_INV_KEYLEN;
/* Also check that the hash algorithm is available. */
- ec = gpg_err_code (gcry_md_test_algo (hashalgo));
+ ec = _gcry_md_test_algo (hashalgo);
if (ec)
return ec;
gcry_assert (qbits/8 <= sizeof digest);
- gcry_assert (gcry_md_get_algo_dlen (hashalgo) == qbits/8);
+ gcry_assert (_gcry_md_get_algo_dlen (hashalgo) == qbits/8);
/* Step 2: Check seedlen. */
@@ -1690,26 +1696,26 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
; /* No seed value given: We are asked to generate it. */
else if (!seed || seedlen < qbits/8)
return GPG_ERR_INV_ARG;
-
+
/* Allocate a buffer to later compute SEED+some_increment and a few
helper variables. */
- seed_plus = gcry_malloc (seedlen < sizeof seed_help_buffer?
- sizeof seed_help_buffer : seedlen);
+ seed_plus = xtrymalloc (seedlen < sizeof seed_help_buffer?
+ sizeof seed_help_buffer : seedlen);
if (!seed_plus)
{
ec = gpg_err_code_from_syserror ();
goto leave;
}
val_2 = mpi_alloc_set_ui (2);
- value_w = gcry_mpi_new (pbits);
- value_x = gcry_mpi_new (pbits);
+ value_w = mpi_new (pbits);
+ value_x = mpi_new (pbits);
/* Step 3: n = \lceil L / outlen \rceil - 1 */
value_n = (pbits + qbits - 1) / qbits - 1;
/* Step 4: b = L - 1 - (n * outlen) */
value_b = pbits - 1 - (value_n * qbits);
- restart:
+ restart:
/* Generate Q. */
for (;;)
{
@@ -1718,12 +1724,12 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
{
seedlen = qbits/8;
gcry_assert (seedlen <= sizeof seed_help_buffer);
- gcry_create_nonce (seed_help_buffer, seedlen);
+ _gcry_create_nonce (seed_help_buffer, seedlen);
seed = seed_help_buffer;
}
-
+
/* Step 6: U = hash(seed) */
- gcry_md_hash_buffer (hashalgo, value_u, seed, seedlen);
+ _gcry_md_hash_buffer (hashalgo, value_u, seed, seedlen);
/* Step 7: q = 2^{N-1} + U + 1 - (U mod 2) */
if ( !(value_u[qbits/8-1] & 0x01) )
@@ -1735,13 +1741,13 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
break;
}
}
- gcry_mpi_release (prime_q); prime_q = NULL;
- ec = gpg_err_code (gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG,
- value_u, sizeof value_u, NULL));
+ _gcry_mpi_release (prime_q); prime_q = NULL;
+ ec = _gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG,
+ value_u, sizeof value_u, NULL);
if (ec)
goto leave;
mpi_set_highbit (prime_q, qbits-1 );
-
+
/* Step 8: Test whether Q is prime using 64 round of Rabin-Miller.
According to table C.1 this is sufficient for all
supported prime sizes (i.e. up 3072/256). */
@@ -1751,22 +1757,22 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
/* Step 8. */
seed = NULL; /* Force a new seed at Step 5. */
}
-
+
/* Step 11. Note that we do no use an explicit offset but increment
SEED_PLUS accordingly. */
memcpy (seed_plus, seed, seedlen);
counter = 0;
/* Generate P. */
- prime_p = gcry_mpi_new (pbits);
+ prime_p = mpi_new (pbits);
for (;;)
{
- /* Step 11.1: For j = 0,...n let
- V_j = hash(seed+offset+j)
- Step 11.2: W = V_0 + V_1*2^outlen +
- ...
+ /* Step 11.1: For j = 0,...n let
+ V_j = hash(seed+offset+j)
+ Step 11.2: W = V_0 + V_1*2^outlen +
+ ...
+ V_{n-1}*2^{(n-1)*outlen}
- + (V_{n} mod 2^b)*2^{n*outlen}
+ + (V_{n} mod 2^b)*2^{n*outlen}
*/
mpi_set_ui (value_w, 0);
for (value_j=0; value_j <= value_n; value_j++)
@@ -1782,11 +1788,11 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
if (seed_plus[i])
break;
}
- gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
-
- gcry_mpi_release (tmpval); tmpval = NULL;
- ec = gpg_err_code (gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG,
- digest, sizeof digest, NULL));
+ _gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
+
+ _gcry_mpi_release (tmpval); tmpval = NULL;
+ ec = _gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG,
+ digest, sizeof digest, NULL);
if (ec)
goto leave;
if (value_j == value_n)
@@ -1813,7 +1819,7 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
if (mpi_get_nbits (prime_p) >= pbits-1
&& check_prime (prime_p, val_2, 64, NULL, NULL) )
break; /* Yes, P is prime, continue with Step 15. */
-
+
/* Step 11.9: counter = counter + 1, offset = offset + n + 1.
If counter >= 4L goto Step 5. */
counter++;
@@ -1824,9 +1830,9 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
/* Step 12: Save p, q, counter and seed. */
log_debug ("fips186-3 pbits p=%u q=%u counter=%d\n",
mpi_get_nbits (prime_p), mpi_get_nbits (prime_q), counter);
- log_printhex("fips186-3 seed:", seed, seedlen);
- log_mpidump ("fips186-3 prime p", prime_p);
- log_mpidump ("fips186-3 prime q", prime_q);
+ log_printhex ("fips186-3 seed", seed, seedlen);
+ log_printmpi ("fips186-3 p", prime_p);
+ log_printmpi ("fips186-3 q", prime_q);
if (r_q)
{
*r_q = prime_q;
@@ -1850,13 +1856,12 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
*r_hashalgo = hashalgo;
leave:
- gcry_mpi_release (tmpval);
- gcry_mpi_release (value_x);
- gcry_mpi_release (value_w);
- gcry_mpi_release (prime_p);
- gcry_mpi_release (prime_q);
- gcry_free (seed_plus);
- gcry_mpi_release (val_2);
+ _gcry_mpi_release (tmpval);
+ _gcry_mpi_release (value_x);
+ _gcry_mpi_release (value_w);
+ _gcry_mpi_release (prime_p);
+ _gcry_mpi_release (prime_q);
+ xfree (seed_plus);
+ _gcry_mpi_release (val_2);
return ec;
}
-