api: New function gcry_get_config.
[libgcrypt.git] / tests / t-mpi-bit.c
index 208a127..91116ca 100644 (file)
@@ -15,7 +15,7 @@
  *
  * 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, 
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  * MA 02110-1301, USA.
  */
 
 #include <assert.h>
 #include <stdarg.h>
 
-#include "../src/gcrypt.h"
-
 #define PGM "t-mpi-bit"
+#include "t-common.h"
 
-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
@@ -91,7 +39,7 @@ 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';
@@ -108,13 +56,20 @@ mpi2bitstr_nlz (gcry_mpi_t a)
 {
   char *p, *buf;
   size_t length = gcry_mpi_get_nbits (a);
-  
-  buf = p = xmalloc (length + 1);
-  while (length-- > 1)
-    *p++ = gcry_mpi_test_bit (a, length) ? '1':'0';
-  *p++ = gcry_mpi_test_bit (a, 0) ? '1':'0';
-  *p = 0;
 
+  if (!length)
+    {
+      buf = p = xmalloc (2);
+      *p++ = '0';
+    }
+  else
+    {
+      buf = p = xmalloc (length + 1);
+      while (length-- > 1)
+        *p++ = gcry_mpi_test_bit (a, length) ? '1':'0';
+      *p++ = gcry_mpi_test_bit (a, 0) ? '1':'0';
+    }
+  *p = 0;
   return buf;
 }
 
@@ -140,7 +95,7 @@ lshiftbitstring (const char *string, size_t n)
 
   if (len+n+1 < len)
     die ("internal overflow\n");
-  /* Allocate enough space. */ 
+  /* Allocate enough space. */
   result = xmalloc (len+n+1);
   for (; *string == '0' && string[1]; string++, len--)
     ;
@@ -164,7 +119,7 @@ one_bit_only (int highbit)
   int i;
 
   wherestr = "one_bit_only";
-  show ("checking that set_%sbit does only set one bit\n", highbit?"high":"");
+  info ("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);
@@ -190,7 +145,7 @@ one_bit_only (int highbit)
   gcry_mpi_release (a);
 }
 
-/* Check that the shifting actually works for an amount larger than
+/* Check that right shifting actually works for an amount larger than
    the number of bits per limb. */
 static void
 test_rshift (int pass)
@@ -200,7 +155,7 @@ test_rshift (int pass)
   int i;
 
   wherestr = "test_rshift";
-  show ("checking that rshift works as expected (pass %d)\n", pass);
+  info ("checking that rshift works as expected (pass %d)\n", pass);
 
   a = gcry_mpi_new (0);
   b = gcry_mpi_new (0);
@@ -215,8 +170,8 @@ test_rshift (int pass)
       rshiftbitstring (result2, i);
       if (strcmp (result, result2))
         {
-          show ("got =%s\n", result);
-          show ("want=%s\n", result2);
+          info ("got =%s\n", result);
+          info ("want=%s\n", result2);
           fail ("rshift by %d failed\n", i);
         }
       xfree (result);
@@ -237,8 +192,8 @@ test_rshift (int pass)
       rshiftbitstring (result2, i);
       if (strcmp (result, result2))
         {
-          show ("got =%s\n", result);
-          show ("want=%s\n", result2);
+          info ("got =%s\n", result);
+          info ("want=%s\n", result2);
           fail ("in-place rshift by %d failed\n", i);
         }
       xfree (result2);
@@ -249,7 +204,7 @@ test_rshift (int pass)
   gcry_mpi_release (a);
 }
 
-/* Check that the left shifting.  */
+/* Check that left shifting works correctly.  */
 static void
 test_lshift (int pass)
 {
@@ -260,7 +215,7 @@ test_lshift (int pass)
   int i;
 
   wherestr = "test_lshift";
-  show ("checking that lshift works as expected (pass %d)\n", pass);
+  info ("checking that lshift works as expected (pass %d)\n", pass);
 
   for (size_idx=0; size_list[size_idx]; size_idx++)
     {
@@ -275,25 +230,25 @@ test_lshift (int pass)
       for (i=0; i < 75; i++)
         {
           gcry_mpi_lshift (b, a, i);
-          
+
           result = mpi2bitstr_nlz (b);
           tmpstr = mpi2bitstr_nlz (a);
           result2 = lshiftbitstring (tmpstr, i);
           xfree (tmpstr);
           if (strcmp (result, result2))
             {
-              show ("got =%s\n", result);
-              show ("want=%s\n", result2);
+              info ("got =%s\n", result);
+              info ("want=%s\n", result2);
               fail ("lshift by %d failed\n", i);
             }
           xfree (result);
           xfree (result2);
         }
-      
+
       /* Again. This time using in-place operation. */
       gcry_mpi_randomize (a, size_list[size_idx], GCRY_WEAK_RANDOM);
       gcry_mpi_clear_highbit (a, size_list[size_idx]);
-      
+
       for (i=0; i < 75; i++)
         {
           gcry_mpi_release (b);
@@ -306,8 +261,8 @@ test_lshift (int pass)
           xfree (tmpstr);
           if (strcmp (result, result2))
             {
-              show ("got =%s\n", result);
-              show ("want=%s\n", result2);
+              info ("got =%s\n", result);
+              info ("want=%s\n", result2);
               fail ("in-place lshift by %d failed\n", i);
             }
           xfree (result2);
@@ -320,10 +275,61 @@ test_lshift (int pass)
 }
 
 
+/* Bug fixed on 2014-05-09:
+      a = gcry_mpi_new (1523);
+      gcry_mpi_set_bit (a, 1536);
+      didn't initialized all limbs in A.  */
+static void
+set_bit_with_resize (void)
+{
+  gcry_mpi_t a;
+  int i;
+
+  wherestr = "set_bit_with_resize";
+  info ("checking that set_bit initializes all limbs\n");
+
+  a = gcry_mpi_new (1536);
+  gcry_mpi_set_bit (a, 1536);
+
+  if (!gcry_mpi_test_bit (a, 1536))
+    fail ("failed to set a bit\n");
+  for (i=0; i < 1536; i++)
+    {
+      if (gcry_mpi_test_bit (a, i))
+        {
+          fail ("spurious bit detected\n");
+          break;
+        }
+    }
+  if (gcry_mpi_test_bit (a, 1537))
+    fail ("more bits set than expected\n");
+  gcry_mpi_release (a);
+
+  wherestr = "set_highbit_with_resize";
+  info ("checking that set_highbit initializes all limbs\n");
+
+  a = gcry_mpi_new (1536);
+  gcry_mpi_set_highbit (a, 1536);
+
+  if (!gcry_mpi_test_bit (a, 1536))
+    fail ("failed to set a bit\n");
+  for (i=0; i < 1536; i++)
+    {
+      if (gcry_mpi_test_bit (a, i))
+        {
+          fail ("spurious bit detected\n");
+          break;
+        }
+    }
+  if (gcry_mpi_test_bit (a, 1537))
+    fail ("more bits set than expected\n");
+  gcry_mpi_release (a);
+}
+
+
 int
 main (int argc, char **argv)
 {
-  int debug = 0;
   int i;
 
   if (argc > 1 && !strcmp (argv[1], "--verbose"))
@@ -334,12 +340,12 @@ main (int argc, char **argv)
   if (!gcry_check_version (GCRYPT_VERSION))
     die ("version mismatch\n");
 
-  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
-  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+  xgcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+  xgcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
   if (debug)
-    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+    xgcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
 
-  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+  xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
 
   one_bit_only (0);
   one_bit_only (1);
@@ -348,7 +354,9 @@ main (int argc, char **argv)
 
   for (i=0; i < 5; i++)
     test_lshift (i); /* Run several times due to random initializations. */
-  
-  show ("All tests completed. Errors: %d\n", error_count);
+
+  set_bit_with_resize ();
+
+  info ("All tests completed. Errors: %d\n", error_count);
   return error_count ? 1 : 0;
 }