diff options
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | cipher/ChangeLog | 12 | ||||
-rw-r--r-- | cipher/random-daemon.c | 70 | ||||
-rw-r--r-- | cipher/random.c | 15 | ||||
-rw-r--r-- | cipher/random.h | 12 | ||||
-rw-r--r-- | mpi/ChangeLog | 12 | ||||
-rw-r--r-- | mpi/mpi-bit.c | 127 | ||||
-rw-r--r-- | mpi/mpiutil.c | 21 | ||||
-rw-r--r-- | tests/ChangeLog | 4 | ||||
-rw-r--r-- | tests/Makefile.am | 2 | ||||
-rw-r--r-- | tests/t-mpi-bit.c | 241 |
12 files changed, 446 insertions, 76 deletions
@@ -12,9 +12,11 @@ Noteworthy changes in version 1.3.0 (unreleased) * Support for SHA-224 and HMAC using SHA-384 and SHA-512. + * gcry_mpi_rshift does not anymore truncate the shift count. + * Interface changes relative to the 1.2.0 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - gcry_fast_random_poll NEW + gcry_fast_random_poll NEW gcry_pk_algo_name CHANGED (minor change in respect to return value) gcry_cipher_algo_name CHANGED (minor change in respect to return value) GCRY_MD_SHA224 NEW @@ -1,5 +1,7 @@ What's left to do -*- outline -*- +* Updated the FSF's directory. + * Add more tests. * udiv-qrnbd.o should get build as *.lo [HPUX] diff --git a/cipher/ChangeLog b/cipher/ChangeLog index a6cb45b4..c921a1a5 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,15 @@ +2006-08-03 Werner Koch <wk@g10code.com> + + * random-daemon.c (_gcry_daemon_initialize_basics): Don't + initialize the socket. Remove arg SOCKETNAME. + (connect_to_socket): Make sure that daemon is set to -1 on error. + (call_daemon): Initialize the socket on the first call. + (_gcry_daemon_randomize, _gcry_daemon_get_random_bytes) + (_gcry_daemon_create_nonce): New arg SOCKETNAME. + * random.c (initialize): Call new daemon initializator. + (get_random_bytes, gcry_randomize, gcry_create_nonce): Pass socket + name to daemon call and reset allow_daemon on failure. + 2006-07-26 Werner Koch <wk@g10code.com> * rmd160.c (_gcry_rmd160_mixblock): Add cast to transform call. diff --git a/cipher/random-daemon.c b/cipher/random-daemon.c index 6a42d551..95d76f7d 100644 --- a/cipher/random-daemon.c +++ b/cipher/random-daemon.c @@ -24,7 +24,7 @@ gcryptrnd. Such a daemon is useful to keep a persistent pool in memory over invocations of a single application and to allow prioritizing access to the actual entropy sources. The drawback is - that we need to use IPC (i.e. unxi domain socket) to convey + that we need to use IPC (i.e. unix domain socket) to convey sensitive data. */ @@ -111,20 +111,22 @@ connect_to_socket (const char *socketname, int *sock) out: - *sock = fd; gcry_free (srvr_addr); - if (err) - close (fd); + { + close (fd); + fd = -1; + } + *sock = fd; return err; } /* Initialize basics of this module. This should be viewed as a - constroctur to prepare locking. */ + constructor to prepare locking. */ void -_gcry_daemon_initialize_basics (const char *socketname) +_gcry_daemon_initialize_basics (void) { static int initialized; int err; @@ -135,15 +137,10 @@ _gcry_daemon_initialize_basics (const char *socketname) err = ath_mutex_init (&daemon_lock); if (err) log_fatal ("failed to create the daemon lock: %s\n", strerror (err) ); - - err = connect_to_socket (socketname ? socketname : RANDOM_DAEMON_SOCKET, - &daemon_socket); - if (err) - log_info ("not using random daemon\n"); } } - + /* Send LENGTH bytes of BUFFER to file descriptor FD. Returns 0 on success or another value on write error. */ @@ -201,22 +198,47 @@ readn (int fd, void *buf, size_t buflen, size_t *ret_nread) data of random level LEVEL will be generated. The retrieved random data will be stored in BUFFER. Returns error code. */ static gcry_error_t -call_daemon (void *buffer, size_t req_nbytes, int nonce, +call_daemon (const char *socketname, + void *buffer, size_t req_nbytes, int nonce, enum gcry_random_level level) { + static int initialized; unsigned char buf[255]; - gcry_error_t err; + gcry_error_t err = 0; size_t nbytes; size_t nread; int rc; - err = 0; - - if (! req_nbytes) + if (!req_nbytes) return 0; ath_mutex_lock (&daemon_lock); + /* Open the socket if that has not been done. */ + if (!initialized) + { + initialized = 1; + err = connect_to_socket (socketname ? socketname : RANDOM_DAEMON_SOCKET, + &daemon_socket); + if (err) + { + daemon_socket = -1; + log_info ("not using random daemon\n"); + ath_mutex_unlock (&daemon_lock); + return err; + } + } + + /* Check that we have a valid socket descriptor. */ + if ( daemon_socket == -1 ) + { + ath_mutex_unlock (&daemon_lock); + return gcry_error (GPG_ERR_INTERNAL); + } + + + /* Do the real work. */ + do { /* Process in chunks. */ @@ -311,12 +333,13 @@ call_daemon (void *buffer, size_t req_nbytes, int nonce, support GCRY_STRONG_RANDOM and GCRY_VERY_STRONG_RANDOM here. Return 0 on success. */ int -_gcry_daemon_randomize (void *buffer, size_t length, +_gcry_daemon_randomize (const char *socketname, + void *buffer, size_t length, enum gcry_random_level level) { gcry_error_t err; - err = call_daemon (buffer, length, 0, level); + err = call_daemon (socketname, buffer, length, 0, level); return err ? -1 : 0; } @@ -327,7 +350,8 @@ _gcry_daemon_randomize (void *buffer, size_t length, that the IPC mechanism might have not stored it there. Return a pointer to a newly alloced memory or NULL if it failed. */ void * -_gcry_daemon_get_random_bytes (size_t nbytes, int level, int secure) +_gcry_daemon_get_random_bytes (const char *socketname, + size_t nbytes, int level, int secure) { gcry_error_t err; void *p; @@ -336,7 +360,7 @@ _gcry_daemon_get_random_bytes (size_t nbytes, int level, int secure) if (err) goto out; - err = call_daemon (p, nbytes, 0, level); + err = call_daemon (socketname, p, nbytes, 0, level); out: @@ -353,11 +377,11 @@ _gcry_daemon_get_random_bytes (size_t nbytes, int level, int secure) /* Internal function to fill BUFFER with NBYTES of data usable for a nonce. Returns 0 on success. */ int -_gcry_daemon_create_nonce (void *buffer, size_t length) +_gcry_daemon_create_nonce (const char *socketname, void *buffer, size_t length) { gcry_error_t err; - err = call_daemon (buffer, length, 1, 0); + err = call_daemon (socketname, buffer, length, 1, 0); return err ? -1 : 0; } diff --git a/cipher/random.c b/cipher/random.c index e38b8773..528111af 100644 --- a/cipher/random.c +++ b/cipher/random.c @@ -161,7 +161,7 @@ initialize_basics(void) if (err) log_fatal ("failed to create the nonce buffer lock: %s\n", strerror (err) ); - _gcry_daemon_initialize_basics (daemon_socket_name); + _gcry_daemon_initialize_basics (); } } @@ -304,8 +304,11 @@ get_random_bytes ( size_t nbytes, int level, int secure) /* Make sure the requested level is in range. */ MASK_LEVEL(level); - if (allow_daemon && (p=_gcry_daemon_get_random_bytes (nbytes, level,secure))) + if (allow_daemon && + (p=_gcry_daemon_get_random_bytes (daemon_socket_name, + nbytes, level,secure))) return p; /* The daemon succeeded. */ + allow_daemon = 0; /* Daemon failed - switch off. */ /* Lock the pool. */ err = ath_mutex_lock (&pool_lock); @@ -417,8 +420,10 @@ gcry_randomize (byte *buffer, size_t length, enum gcry_random_level level) /* Make sure the level is okay. */ MASK_LEVEL(level); - if (allow_daemon && !_gcry_daemon_randomize (buffer, length, level)) + if (allow_daemon + && !_gcry_daemon_randomize (daemon_socket_name, buffer, length, level)) return; /* The daemon succeeded. */ + allow_daemon = 0; /* Daemon failed - switch off. */ /* Acquire the pool lock. */ err = ath_mutex_lock (&pool_lock); @@ -1233,8 +1238,10 @@ gcry_create_nonce (unsigned char *buffer, size_t length) if (!is_initialized) initialize (); - if (allow_daemon && !_gcry_daemon_create_nonce (buffer, length)) + if (allow_daemon + && !_gcry_daemon_create_nonce (daemon_socket_name, buffer, length)) return; /* The daemon succeeded. */ + allow_daemon = 0; /* Daemon failed - switch off. */ /* Acquire the nonce buffer lock. */ err = ath_mutex_lock (&nonce_buffer_lock); diff --git a/cipher/random.h b/cipher/random.h index afed64c7..3c9c75f3 100644 --- a/cipher/random.h +++ b/cipher/random.h @@ -37,12 +37,14 @@ byte *_gcry_get_random_bits( size_t nbits, int level, int secure ); void _gcry_fast_random_poll( void ); /*-- random-daemon.c (only used from random.c) --*/ -void _gcry_set_random_daemon_socket (const char *socketname); -void _gcry_daemon_initialize_basics (const char *socketname); -int _gcry_daemon_randomize (void *buffer, size_t length, +void _gcry_daemon_initialize_basics (void); +int _gcry_daemon_randomize (const char *socketname, + void *buffer, size_t length, enum gcry_random_level level); -void *_gcry_daemon_get_random_bytes (size_t nbytes, int level, int secure); -int _gcry_daemon_create_nonce (void *buffer, size_t length); +void *_gcry_daemon_get_random_bytes (const char *socketname, + size_t nbytes, int level, int secure); +int _gcry_daemon_create_nonce (const char *socketname, + void *buffer, size_t length); #endif /*G10_RANDOM_H*/ diff --git a/mpi/ChangeLog b/mpi/ChangeLog index c82cc6c6..176ccf22 100644 --- a/mpi/ChangeLog +++ b/mpi/ChangeLog @@ -1,3 +1,15 @@ +2006-08-04 Werner Koch <wk@g10code.com> + + * mpi-bit.c (gcry_mpi_rshift): Rewritten to remove the limitation + on N (which used to be less than BITS_PER_MPI_LIMB). + +2006-08-03 Werner Koch <wk@g10code.com> + + * mpi-bit.c (gcry_mpi_set_bit, gcry_mpi_set_highbit): Fixed + allocation. Reported by bpgcrypt at itaparica.org. + * mpiutil.c (_gcry_mpi_resize): Clear the new part of the resized + limb space. + 2006-07-26 Werner Koch <wk@g10code.com> * mpiutil.c (gcry_mpi_randomize): Changed P to unsigned char*. diff --git a/mpi/mpi-bit.c b/mpi/mpi-bit.c index 2d917995..d16eaae1 100644 --- a/mpi/mpi-bit.c +++ b/mpi/mpi-bit.c @@ -1,5 +1,5 @@ /* mpi-bit.c - MPI bit level fucntions - * Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2001, 2002, 2006 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * @@ -116,17 +116,17 @@ gcry_mpi_test_bit( gcry_mpi_t a, unsigned int n ) void gcry_mpi_set_bit( gcry_mpi_t a, unsigned int n ) { - unsigned int limbno, bitno; + unsigned int limbno, bitno; - limbno = n / BITS_PER_MPI_LIMB; - bitno = n % BITS_PER_MPI_LIMB; + limbno = n / BITS_PER_MPI_LIMB; + bitno = n % BITS_PER_MPI_LIMB; - if( limbno >= a->nlimbs ) { /* resize */ - if( a->alloced >= limbno ) - mpi_resize(a, limbno+1 ); - a->nlimbs = limbno+1; + if ( limbno >= a->nlimbs ) + { + mpi_resize (a, limbno+1 ); + a->nlimbs = limbno+1; } - a->d[limbno] |= (A_LIMB_1<<bitno); + a->d[limbno] |= (A_LIMB_1<<bitno); } /**************** @@ -135,20 +135,20 @@ gcry_mpi_set_bit( gcry_mpi_t a, unsigned int n ) void gcry_mpi_set_highbit( gcry_mpi_t a, unsigned int n ) { - unsigned int limbno, bitno; - - limbno = n / BITS_PER_MPI_LIMB; - bitno = n % BITS_PER_MPI_LIMB; - - if( limbno >= a->nlimbs ) { /* resize */ - if( a->alloced >= limbno ) - mpi_resize(a, limbno+1 ); - a->nlimbs = limbno+1; + unsigned int limbno, bitno; + + limbno = n / BITS_PER_MPI_LIMB; + bitno = n % BITS_PER_MPI_LIMB; + + if ( limbno >= a->nlimbs ) + { + mpi_resize (a, limbno+1 ); + a->nlimbs = limbno+1; } - a->d[limbno] |= (A_LIMB_1<<bitno); - for( bitno++; bitno < BITS_PER_MPI_LIMB; bitno++ ) - a->d[limbno] &= ~(A_LIMB_1 << bitno); - a->nlimbs = limbno+1; + a->d[limbno] |= (A_LIMB_1<<bitno); + for ( bitno++; bitno < BITS_PER_MPI_LIMB; bitno++ ) + a->d[limbno] &= ~(A_LIMB_1 << bitno); + a->nlimbs = limbno+1; } /**************** @@ -188,26 +188,77 @@ gcry_mpi_clear_bit( gcry_mpi_t a, unsigned int n ) } -/**************** - * Shift A by N bits to the right - * FIXME: should use alloc_limb if X and A are same. +/* + * Shift A by N bits to the right. */ void -gcry_mpi_rshift( gcry_mpi_t x, gcry_mpi_t a, unsigned n ) +gcry_mpi_rshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n ) { - mpi_ptr_t xp; - mpi_size_t xsize; - - xsize = a->nlimbs; - x->sign = a->sign; - RESIZE_IF_NEEDED(x, xsize); - xp = x->d; - - if( xsize ) { - _gcry_mpih_rshift( xp, a->d, xsize, n); - MPN_NORMALIZE( xp, xsize); + mpi_size_t xsize; + unsigned int i; + unsigned int nlimbs = (n/BITS_PER_MPI_LIMB); + unsigned int nbits = (n%BITS_PER_MPI_LIMB); + + if ( x == a ) + { + /* In-place operation. */ + if ( nlimbs >= x->nlimbs ) + { + x->nlimbs = 0; + return; + } + + if (nlimbs) + { + for (i=0; i < x->nlimbs - nlimbs; i++ ) + x->d[i] = x->d[i+nlimbs]; + x->d[i] = 0; + x->nlimbs -= nlimbs; + + } + if ( x->nlimbs && nbits ) + _gcry_mpih_rshift ( x->d, x->d, x->nlimbs, nbits ); + } + else if ( nlimbs ) + { + /* Copy and shift by more or equal bits than in a limb. */ + xsize = a->nlimbs; + x->sign = a->sign; + RESIZE_IF_NEEDED (x, xsize); + x->nlimbs = xsize; + for (i=0; i < a->nlimbs; i++ ) + x->d[i] = a->d[i]; + x->nlimbs = i; + + if ( nlimbs >= x->nlimbs ) + { + x->nlimbs = 0; + return; + } + + if (nlimbs) + { + for (i=0; i < x->nlimbs - nlimbs; i++ ) + x->d[i] = x->d[i+nlimbs]; + x->d[i] = 0; + x->nlimbs -= nlimbs; + } + + if ( x->nlimbs && nbits ) + _gcry_mpih_rshift ( x->d, x->d, x->nlimbs, nbits ); + } + else + { + /* Copy and shift by less than bits in a limb. */ + xsize = a->nlimbs; + x->sign = a->sign; + RESIZE_IF_NEEDED (x, xsize); + x->nlimbs = xsize; + + if ( xsize ) + _gcry_mpih_rshift (x->d, a->d, x->nlimbs, nbits ); } - x->nlimbs = xsize; + MPN_NORMALIZE (x->d, x->nlimbs); } diff --git a/mpi/mpiutil.c b/mpi/mpiutil.c index f6f9a8b2..fe1b7617 100644 --- a/mpi/mpiutil.c +++ b/mpi/mpiutil.c @@ -115,17 +115,30 @@ _gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap, unsigned int nlimbs ) /**************** - * Resize the array of A to NLIMBS. the additional space is cleared - * (set to 0) [done by gcry_realloc()] + * Resize the array of A to NLIMBS. The additional space is cleared + * (set to 0). */ void _gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs) { + size_t i; + if (nlimbs <= a->alloced) - return; /* no need to do it */ + { + /* We only need to clear the new space (this is a nop if the + limb space is already of the correct size. */ + for (i=a->nlimbs; i < a->alloced; i++) + a->d[i] = 0; + return; + } + /* Actually resize the limb space. */ if (a->d) - a->d = gcry_xrealloc (a->d, nlimbs * sizeof (mpi_limb_t)); + { + a->d = gcry_xrealloc (a->d, nlimbs * sizeof (mpi_limb_t)); + for (i=a->alloced; i < nlimbs; i++) + a->d[i] = 0; + } else { if (a->flags & 1) diff --git a/tests/ChangeLog b/tests/ChangeLog index 154bd5e2..af66e6ed 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,7 @@ +2006-08-03 Werner Koch <wk@g10code.com> + + * t-mpi-bit.c: New. + 2006-07-06 Werner Koch <wk@g10code.com> * benchmark.c (main): New option --use-random-daemon. New command diff --git a/tests/Makefile.am b/tests/Makefile.am index 945ce5d0..e4a922ac 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -18,7 +18,7 @@ ## Process this file with automake to produce Makefile.in -TESTS = prime register ac ac-schemes ac-data basic \ +TESTS = t-mpi-bit prime register ac ac-schemes ac-data basic \ tsexp keygen pubkey benchmark pkbench hmac keygrip INCLUDES = -I$(top_srcdir)/src diff --git a/tests/t-mpi-bit.c b/tests/t-mpi-bit.c new file mode 100644 index 00000000..2465a8fd --- /dev/null +++ b/tests/t-mpi-bit.c @@ -0,0 +1,241 @@ +/* t-mpi-bit.c - Tests for bit level functions + * Copyright (C) 2006 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <stdarg.h> + +#include "../src/gcrypt.h" + +#define PGM "t-mpi-bit" + +static const char *wherestr; +static int verbose; +static int error_count; + +#define xmalloc(a) gcry_xmalloc ((a)) +#define xcalloc(a,b) gcry_xcalloc ((a),(b)) +#define xfree(a) gcry_free ((a)) +#define pass() do { ; } while (0) + +static void +show (const char *format, ...) +{ + va_list arg_ptr; + + if (!verbose) + return; + fprintf (stderr, "%s: ", PGM); + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); +} + +static void +fail (const char *format, ...) +{ + va_list arg_ptr; + + fflush (stdout); + fprintf (stderr, "%s: ", PGM); + if (wherestr) + fprintf (stderr, "%s: ", wherestr); + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + error_count++; +} + +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + fflush (stdout); + fprintf (stderr, "%s: ", PGM); + if (wherestr) + fprintf (stderr, "%s: ", wherestr); + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + exit (1); +} + +/* Allocate a bit string consisting of '0' and '1' from the MPI + A. Return the LENGTH least significant bits. Caller needs to xfree + the result. */ +static char * +mpi2bitstr (gcry_mpi_t a, size_t length) +{ + char *p, *buf; + + buf = p = xmalloc (length+1); + while (length--) + *p++ = gcry_mpi_test_bit (a, length) ? '1':'0'; + *p = 0; + + return buf; +} + +/* Shift a bit string to the right. */ +static void +rshiftbitstring (char *string, size_t n) +{ + size_t len = strlen (string); + + if (n > len) + n = len; + + memmove (string+n, string, len-n); + memset (string, '0', n); +} + + +/* This is to check a bug reported by bpgcrypt at itaparica.org on + 2006-07-31 against libgcrypt 1.2.2. */ +static void +one_bit_only (int highbit) +{ + gcry_mpi_t a; + char *result; + int i; + + wherestr = "one_bit_only"; + show ("checking that set_%sbit does only set one bit\n", highbit?"high":""); + + a = gcry_mpi_new (0); + gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM); + gcry_mpi_set_ui (a, 0); + + if (highbit) + gcry_mpi_set_highbit (a, 42); + else + gcry_mpi_set_bit (a, 42); + if (!gcry_mpi_test_bit (a, 42)) + fail ("failed to set a bit\n"); + gcry_mpi_clear_bit (a, 42); + if (gcry_mpi_test_bit (a, 42)) + fail ("failed to clear a bit\n"); + result = mpi2bitstr (a, 70); + assert (strlen (result) == 70); + show ("r=%s\n", result); + for (i=0; result[i]; i++) + if ( result[i] != '0' ) + break; + if (result[i]) + fail ("spurious bits detected\n"); + xfree (result); + gcry_mpi_release (a); +} + +/* Check that the shifting actually works for an amount larger than + the number of bits per limb. */ +static void +test_rshift (int pass) +{ + gcry_mpi_t a, b; + char *result, *result2; + int i; + + wherestr = "test_rshift"; + show ("checking that rshift works as expected (pass %d)\n", pass); + + a = gcry_mpi_new (0); + b = gcry_mpi_new (0); + gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM); + + for (i=0; i < 75; i++) + { + gcry_mpi_rshift (b, a, i); + + result = mpi2bitstr (b, 72); + result2 = mpi2bitstr (a, 72); + rshiftbitstring (result2, i); + if (strcmp (result, result2)) + { + show ("got =%s\n", result); + show ("want=%s\n", result2); + fail ("rshift by %d failed\n", i); + } + xfree (result); + xfree (result2); + } + + /* Again. This time using in-place operation. */ + gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM); + + for (i=0; i < 75; i++) + { + gcry_mpi_release (b); + b = gcry_mpi_copy (a); + gcry_mpi_rshift (b, b, i); + + result = mpi2bitstr (b, 72); + result2 = mpi2bitstr (a, 72); + rshiftbitstring (result2, i); + if (strcmp (result, result2)) + { + show ("got =%s\n", result); + show ("want=%s\n", result2); + fail ("in-place rshift by %d failed\n", i); + } + xfree (result2); + xfree (result); + } + + gcry_mpi_release (b); + gcry_mpi_release (a); +} + + +int +main (int argc, char **argv) +{ + int debug = 0; + int i; + + if (argc > 1 && !strcmp (argv[1], "--verbose")) + verbose = 1; + else if (argc > 1 && !strcmp (argv[1], "--debug")) + verbose = debug = 1; + + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); + gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + + one_bit_only (0); + one_bit_only (1); + for (i=0; i < 5; i++) + test_rshift (i); /* Run several times due to random initializations. */ + + show ("All tests completed. Errors: %d\n", error_count); + return error_count ? 1 : 0; +} |