mpi/ec: fix when 'unsigned long' is 32-bit but limb size is 64-bit
[libgcrypt.git] / tests / bench-slope.c
index 2679556..75e6e43 100644 (file)
 #endif
 
 #define PGM "bench-slope"
+#include "t-common.h"
 
 static int verbose;
 static int csv_mode;
+static int unaligned_mode;
 static int num_measurement_repetitions;
 
 /* CPU Ghz value provided by user, allows constructing cycles/byte and other
@@ -411,12 +413,14 @@ do_slope_benchmark (struct bench_obj *obj)
       obj->max_bufsize < 1 || obj->min_bufsize > obj->max_bufsize)
     goto err_free;
 
-  real_buffer = malloc (obj->max_bufsize + 128);
+  real_buffer = malloc (obj->max_bufsize + 128 + unaligned_mode);
   if (!real_buffer)
     goto err_free;
   /* Get aligned buffer */
   buffer = real_buffer;
   buffer += 128 - ((real_buffer - (unsigned char *) 0) & (128 - 1));
+  if (unaligned_mode)
+    buffer += unaligned_mode; /* Make buffer unaligned */
 
   for (i = 0; i < obj->max_bufsize; i++)
     buffer[i] = 0x55 ^ (-i);
@@ -520,8 +524,6 @@ bench_print_result_std (double nsecs_per_byte)
   char mbpsec_buf[16];
   char cpbyte_buf[16];
 
-  strcpy (cpbyte_buf, "-");
-
   double_to_str (nsecpbyte_buf, sizeof (nsecpbyte_buf), nsecs_per_byte);
 
   /* If user didn't provide CPU speed, we cannot show cycles/byte results.  */
@@ -530,16 +532,15 @@ bench_print_result_std (double nsecs_per_byte)
       cycles_per_byte = nsecs_per_byte * cpu_ghz;
       double_to_str (cpbyte_buf, sizeof (cpbyte_buf), cycles_per_byte);
     }
+  else
+    strcpy (cpbyte_buf, "-");
 
   mbytes_per_sec =
     (1000.0 * 1000.0 * 1000.0) / (nsecs_per_byte * 1024 * 1024);
   double_to_str (mbpsec_buf, sizeof (mbpsec_buf), mbytes_per_sec);
 
-  strncat (nsecpbyte_buf, " ns/B", sizeof (nsecpbyte_buf) - 1);
-  strncat (mbpsec_buf, " MiB/s", sizeof (mbpsec_buf) - 1);
-  strncat (cpbyte_buf, " c/B", sizeof (cpbyte_buf) - 1);
-
-  printf ("%14s %15s %13s\n", nsecpbyte_buf, mbpsec_buf, cpbyte_buf);
+  printf ("%9s ns/B %9s MiB/s %9s c/B\n",
+          nsecpbyte_buf, mbpsec_buf, cpbyte_buf);
 }
 
 static void
@@ -741,7 +742,126 @@ static struct bench_ops decrypt_ops = {
 };
 
 
-#ifdef HAVE_U64_TYPEDEF
+static int
+bench_xts_encrypt_init (struct bench_obj *obj)
+{
+  struct bench_cipher_mode *mode = obj->priv;
+  gcry_cipher_hd_t hd;
+  int err, keylen;
+
+  /* For XTS, benchmark with typical data-unit size (512 byte sectors). */
+  obj->min_bufsize = 512;
+  obj->max_bufsize = 16 * obj->min_bufsize;
+  obj->step_size = obj->min_bufsize;
+  obj->num_measure_repetitions = num_measurement_repetitions;
+
+  err = gcry_cipher_open (&hd, mode->algo, mode->mode, 0);
+  if (err)
+    {
+      fprintf (stderr, PGM ": error opening cipher `%s'\n",
+              gcry_cipher_algo_name (mode->algo));
+      exit (1);
+    }
+
+  /* Double key-length for XTS. */
+  keylen = gcry_cipher_get_algo_keylen (mode->algo) * 2;
+  if (keylen)
+    {
+      char key[keylen];
+      int i;
+
+      for (i = 0; i < keylen; i++)
+       key[i] = 0x33 ^ (11 - i);
+
+      err = gcry_cipher_setkey (hd, key, keylen);
+      if (err)
+       {
+         fprintf (stderr, PGM ": gcry_cipher_setkey failed: %s\n",
+                  gpg_strerror (err));
+         gcry_cipher_close (hd);
+         exit (1);
+       }
+    }
+  else
+    {
+      fprintf (stderr, PGM ": failed to get key length for algorithm `%s'\n",
+              gcry_cipher_algo_name (mode->algo));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+
+  obj->priv = hd;
+
+  return 0;
+}
+
+static void
+bench_xts_encrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
+{
+  gcry_cipher_hd_t hd = obj->priv;
+  unsigned int pos;
+  static const char tweak[16] = { 0xff, 0xff, 0xfe, };
+  size_t sectorlen = obj->step_size;
+  char *cbuf = buf;
+  int err;
+
+  gcry_cipher_setiv (hd, tweak, sizeof (tweak));
+
+  /* Process each sector separately. */
+
+  for (pos = 0; pos < buflen; pos += sectorlen, cbuf += sectorlen)
+    {
+      err = gcry_cipher_encrypt (hd, cbuf, sectorlen, cbuf, sectorlen);
+      if (err)
+       {
+         fprintf (stderr, PGM ": gcry_cipher_encrypt failed: %s\n",
+                 gpg_strerror (err));
+         gcry_cipher_close (hd);
+         exit (1);
+       }
+    }
+}
+
+static void
+bench_xts_decrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
+{
+  gcry_cipher_hd_t hd = obj->priv;
+  unsigned int pos;
+  static const char tweak[16] = { 0xff, 0xff, 0xfe, };
+  size_t sectorlen = obj->step_size;
+  char *cbuf = buf;
+  int err;
+
+  gcry_cipher_setiv (hd, tweak, sizeof (tweak));
+
+  /* Process each sector separately. */
+
+  for (pos = 0; pos < buflen; pos += sectorlen, cbuf += sectorlen)
+    {
+      err = gcry_cipher_decrypt (hd, cbuf, sectorlen, cbuf, sectorlen);
+      if (err)
+       {
+         fprintf (stderr, PGM ": gcry_cipher_encrypt failed: %s\n",
+                 gpg_strerror (err));
+         gcry_cipher_close (hd);
+         exit (1);
+       }
+    }
+}
+
+static struct bench_ops xts_encrypt_ops = {
+  &bench_xts_encrypt_init,
+  &bench_encrypt_free,
+  &bench_xts_encrypt_do_bench
+};
+
+static struct bench_ops xts_decrypt_ops = {
+  &bench_xts_encrypt_init,
+  &bench_encrypt_free,
+  &bench_xts_decrypt_do_bench
+};
+
+
 static void
 bench_ccm_encrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
 {
@@ -904,7 +1024,6 @@ static struct bench_ops ccm_authenticate_ops = {
   &bench_encrypt_free,
   &bench_ccm_authenticate_do_bench
 };
-#endif /*HAVE_U64_TYPEDEF*/
 
 
 static void
@@ -1167,11 +1286,11 @@ static struct bench_cipher_mode cipher_modes[] = {
   {GCRY_CIPHER_MODE_OFB, "OFB dec", &decrypt_ops},
   {GCRY_CIPHER_MODE_CTR, "CTR enc", &encrypt_ops},
   {GCRY_CIPHER_MODE_CTR, "CTR dec", &decrypt_ops},
-#ifdef HAVE_U64_TYPEDEF
+  {GCRY_CIPHER_MODE_XTS, "XTS enc", &xts_encrypt_ops},
+  {GCRY_CIPHER_MODE_XTS, "XTS dec", &xts_decrypt_ops},
   {GCRY_CIPHER_MODE_CCM, "CCM enc", &ccm_encrypt_ops},
   {GCRY_CIPHER_MODE_CCM, "CCM dec", &ccm_decrypt_ops},
   {GCRY_CIPHER_MODE_CCM, "CCM auth", &ccm_authenticate_ops},
-#endif
   {GCRY_CIPHER_MODE_GCM, "GCM enc", &gcm_encrypt_ops},
   {GCRY_CIPHER_MODE_GCM, "GCM dec", &gcm_decrypt_ops},
   {GCRY_CIPHER_MODE_GCM, "GCM auth", &gcm_authenticate_ops},
@@ -1222,8 +1341,12 @@ cipher_bench_one (int algo, struct bench_cipher_mode *pmode)
   if (mode.mode == GCRY_CIPHER_MODE_GCM && blklen != GCRY_GCM_BLOCK_LEN)
     return;
 
-  /* Our OCB implementaion has restrictions for block-size.  */
-  if (mode.mode == GCRY_CIPHER_MODE_OCB && blklen != 16)
+  /* XTS has restrictions for block-size */
+  if (mode.mode == GCRY_CIPHER_MODE_XTS && blklen != GCRY_XTS_BLOCK_LEN)
+    return;
+
+  /* Our OCB implementation has restrictions for block-size.  */
+  if (mode.mode == GCRY_CIPHER_MODE_OCB && blklen != GCRY_OCB_BLOCK_LEN)
     return;
 
   bench_print_mode (14, mode.name);
@@ -1651,6 +1774,12 @@ kdf_bench_one (int algo, int subalgo)
       return;
     }
 
+  if (gcry_md_get_algo_dlen (subalgo) == 0)
+    {
+      /* Skip XOFs */
+      return;
+    }
+
   *algo_name = 0;
 
   if (algo == GCRY_KDF_PBKDF2)
@@ -1749,6 +1878,7 @@ print_help (void)
     "                             for benchmarking.",
     "   --repetitions <n>         Use N repetitions (default "
                                      STR2(NUM_MEASUREMENT_REPETITIONS) ")",
+    "   --unaligned               Use unaligned input buffers.",
     "   --csv                     Use CSV output format",
     NULL
   };
@@ -1778,7 +1908,6 @@ int
 main (int argc, char **argv)
 {
   int last_argc = -1;
-  int debug = 0;
 
   if (argc)
     {
@@ -1833,6 +1962,12 @@ main (int argc, char **argv)
          argc--;
          argv++;
        }
+      else if (!strcmp (*argv, "--unaligned"))
+       {
+         unaligned_mode = 1;
+         argc--;
+         argv++;
+       }
       else if (!strcmp (*argv, "--disable-hwf"))
        {
          argc--;
@@ -1882,7 +2017,7 @@ main (int argc, char **argv)
        }
     }
 
-  gcry_control (GCRYCTL_SET_VERBOSITY, (int) verbose);
+  xgcry_control (GCRYCTL_SET_VERBOSITY, (int) verbose);
 
   if (!gcry_check_version (GCRYPT_VERSION))
     {
@@ -1892,11 +2027,11 @@ main (int argc, char **argv)
     }
 
   if (debug)
-    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+    xgcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
 
-  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
-  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
-  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+  xgcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+  xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+  xgcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
 
   if (in_regression_test)
     fputs ("Note: " PGM " running in quick regression test mode.\n", stdout);