bench-slope: add KDF/PBKDF2 benchmark
authorJussi Kivilinna <jussi.kivilinna@iki.fi>
Fri, 23 Oct 2015 19:24:47 +0000 (22:24 +0300)
committerJussi Kivilinna <jussi.kivilinna@iki.fi>
Wed, 28 Oct 2015 18:08:39 +0000 (20:08 +0200)
* tests/bench-slope.c (bench_kdf_mode, bench_kdf_init, bench_kdf_free)
(bench_kdf_do_bench, kdf_ops, kdf_bench_one, kdf_bench): New.
(print_help): Add 'kdf'.
(main): Add KDF benchmarks.
--

Introduce KDF benchmarking to bench-slope. Output is given as
nanosecs/iter (and cycles/iter if --cpu-mhz used). Only PBKDF2
is support with this initial patch.

For example, below shows output of KDF bench-slope before
and after commit "md: keep contexts for HMAC in GcryDigestEntry",
on Intel Core i5-4570 @ 3.2 Ghz:

Before:

$ tests/bench-slope --cpu-mhz 3201 kdf
KDF:
                          |  nanosecs/iter   cycles/iter
 PBKDF2-HMAC-MD5          |          882.4        2824.7
 PBKDF2-HMAC-SHA1         |          832.6        2665.0
 PBKDF2-HMAC-RIPEMD160    |         1148.3        3675.6
 PBKDF2-HMAC-TIGER192     |         1339.6        4288.2
 PBKDF2-HMAC-SHA256       |         1460.5        4675.1
 PBKDF2-HMAC-SHA384       |         1723.2        5515.8
 PBKDF2-HMAC-SHA512       |         1729.1        5534.7
 PBKDF2-HMAC-SHA224       |         1424.0        4558.3
 PBKDF2-HMAC-WHIRLPOOL    |         2459.7        7873.5
 PBKDF2-HMAC-TIGER        |         1350.2        4322.1
 PBKDF2-HMAC-TIGER2       |         1348.7        4317.3
 PBKDF2-HMAC-GOSTR3411_94 |         7374.1       23604.4
 PBKDF2-HMAC-STRIBOG256   |         6060.0       19398.1
 PBKDF2-HMAC-STRIBOG512   |         7512.8       24048.3
 PBKDF2-HMAC-GOSTR3411_CP |         7378.3       23618.0
 PBKDF2-HMAC-SHA3-224     |         2789.6        8929.5
 PBKDF2-HMAC-SHA3-256     |         2785.1        8915.0
 PBKDF2-HMAC-SHA3-384     |         2955.5        9460.5
 PBKDF2-HMAC-SHA3-512     |         2859.7        9153.9
                          =

After:

$ tests/bench-slope --cpu-mhz 3201 kdf
KDF:
                          |  nanosecs/iter   cycles/iter
 PBKDF2-HMAC-MD5          |          405.9        1299.2
 PBKDF2-HMAC-SHA1         |          392.1        1255.0
 PBKDF2-HMAC-RIPEMD160    |          540.9        1731.5
 PBKDF2-HMAC-TIGER192     |          637.1        2039.4
 PBKDF2-HMAC-SHA256       |          691.8        2214.3
 PBKDF2-HMAC-SHA384       |          848.0        2714.3
 PBKDF2-HMAC-SHA512       |          875.7        2803.1
 PBKDF2-HMAC-SHA224       |          689.2        2206.0
 PBKDF2-HMAC-WHIRLPOOL    |         1535.6        4915.5
 PBKDF2-HMAC-TIGER        |          636.3        2036.7
 PBKDF2-HMAC-TIGER2       |          636.6        2037.7
 PBKDF2-HMAC-GOSTR3411_94 |         5311.5       17002.2
 PBKDF2-HMAC-STRIBOG256   |         4308.0       13790.0
 PBKDF2-HMAC-STRIBOG512   |         5767.4       18461.4
 PBKDF2-HMAC-GOSTR3411_CP |         5309.4       16995.4
 PBKDF2-HMAC-SHA3-224     |         1333.1        4267.2
 PBKDF2-HMAC-SHA3-256     |         1327.8        4250.4
 PBKDF2-HMAC-SHA3-384     |         1392.8        4458.3
 PBKDF2-HMAC-SHA3-512     |         1428.5        4572.7
                          =

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
tests/bench-slope.c

index 394d7fc..2679556 100644 (file)
@@ -1571,13 +1571,176 @@ mac_bench (char **argv, int argc)
 }
 
 
+/************************************************************ KDF benchmarks. */
+
+struct bench_kdf_mode
+{
+  struct bench_ops *ops;
+
+  int algo;
+  int subalgo;
+};
+
+
+static int
+bench_kdf_init (struct bench_obj *obj)
+{
+  struct bench_kdf_mode *mode = obj->priv;
+
+  if (mode->algo == GCRY_KDF_PBKDF2)
+    {
+      obj->min_bufsize = 2;
+      obj->max_bufsize = 2 * 32;
+      obj->step_size = 2;
+    }
+
+  obj->num_measure_repetitions = num_measurement_repetitions;
+
+  return 0;
+}
+
+static void
+bench_kdf_free (struct bench_obj *obj)
+{
+  (void)obj;
+}
+
+static void
+bench_kdf_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
+{
+  struct bench_kdf_mode *mode = obj->priv;
+  char keybuf[16];
+
+  (void)buf;
+
+  if (mode->algo == GCRY_KDF_PBKDF2)
+    {
+      gcry_kdf_derive("qwerty", 6, mode->algo, mode->subalgo, "01234567", 8,
+                     buflen, sizeof(keybuf), keybuf);
+    }
+}
+
+static struct bench_ops kdf_ops = {
+  &bench_kdf_init,
+  &bench_kdf_free,
+  &bench_kdf_do_bench
+};
+
+
+static void
+kdf_bench_one (int algo, int subalgo)
+{
+  struct bench_kdf_mode mode = { &kdf_ops };
+  struct bench_obj obj = { 0 };
+  double nsecs_per_iteration;
+  double cycles_per_iteration;
+  char algo_name[32];
+  char nsecpiter_buf[16];
+  char cpiter_buf[16];
+
+  mode.algo = algo;
+  mode.subalgo = subalgo;
+
+  switch (subalgo)
+    {
+    case GCRY_MD_CRC32:
+    case GCRY_MD_CRC32_RFC1510:
+    case GCRY_MD_CRC24_RFC2440:
+    case GCRY_MD_MD4:
+      /* Skip CRC32s. */
+      return;
+    }
+
+  *algo_name = 0;
+
+  if (algo == GCRY_KDF_PBKDF2)
+    {
+      snprintf (algo_name, sizeof(algo_name), "PBKDF2-HMAC-%s",
+               gcry_md_algo_name (subalgo));
+    }
+
+  bench_print_algo (-24, algo_name);
+
+  obj.ops = mode.ops;
+  obj.priv = &mode;
+
+  nsecs_per_iteration = do_slope_benchmark (&obj);
+
+  strcpy(cpiter_buf, csv_mode ? "" : "-");
+
+  double_to_str (nsecpiter_buf, sizeof (nsecpiter_buf), nsecs_per_iteration);
+
+  /* If user didn't provide CPU speed, we cannot show cycles/iter results.  */
+  if (cpu_ghz > 0.0)
+    {
+      cycles_per_iteration = nsecs_per_iteration * cpu_ghz;
+      double_to_str (cpiter_buf, sizeof (cpiter_buf), cycles_per_iteration);
+    }
+
+  if (csv_mode)
+    {
+      printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter\n",
+             current_section_name,
+             current_algo_name ? current_algo_name : "",
+             current_mode_name ? current_mode_name : "",
+             nsecpiter_buf,
+             cpiter_buf);
+    }
+  else
+    {
+      printf ("%14s %13s\n", nsecpiter_buf, cpiter_buf);
+    }
+}
+
+void
+kdf_bench (char **argv, int argc)
+{
+  char algo_name[32];
+  int i, j;
+
+  bench_print_section ("kdf", "KDF");
+
+  if (!csv_mode)
+    {
+      printf (" %-*s | ", 24, "");
+      printf ("%14s %13s\n", "nanosecs/iter", "cycles/iter");
+    }
+
+  if (argv && argc)
+    {
+      for (i = 0; i < argc; i++)
+       {
+         for (j = 1; j < 400; j++)
+           {
+             if (gcry_md_test_algo (j))
+               continue;
+
+             snprintf (algo_name, sizeof(algo_name), "PBKDF2-HMAC-%s",
+                       gcry_md_algo_name (j));
+
+             if (!strcmp(argv[i], algo_name))
+               kdf_bench_one (GCRY_KDF_PBKDF2, j);
+           }
+       }
+    }
+  else
+    {
+      for (i = 1; i < 400; i++)
+       if (!gcry_md_test_algo (i))
+         kdf_bench_one (GCRY_KDF_PBKDF2, i);
+    }
+
+  bench_print_footer (24);
+}
+
+
 /************************************************************** Main program. */
 
 void
 print_help (void)
 {
   static const char *help_lines[] = {
-    "usage: bench-slope [options] [hash|mac|cipher [algonames]]",
+    "usage: bench-slope [options] [hash|mac|cipher|kdf [algonames]]",
     "",
     " options:",
     "   --cpu-mhz <mhz>           Set CPU speed for calculating cycles",
@@ -1744,6 +1907,7 @@ main (int argc, char **argv)
       hash_bench (NULL, 0);
       mac_bench (NULL, 0);
       cipher_bench (NULL, 0);
+      kdf_bench (NULL, 0);
     }
   else if (!strcmp (*argv, "hash"))
     {
@@ -1769,6 +1933,14 @@ main (int argc, char **argv)
       warm_up_cpu ();
       cipher_bench ((argc == 0) ? NULL : argv, argc);
     }
+  else if (!strcmp (*argv, "kdf"))
+    {
+      argc--;
+      argv++;
+
+      warm_up_cpu ();
+      kdf_bench ((argc == 0) ? NULL : argv, argc);
+    }
   else
     {
       fprintf (stderr, PGM ": unknown argument: %s\n", *argv);