summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoritz Schulte <mo@g10code.com>2003-11-02 10:22:19 +0000
committerMoritz Schulte <mo@g10code.com>2003-11-02 10:22:19 +0000
commitadc044a039bfd68ec4127df3061b2199200ae25d (patch)
tree13b7b2d0c34eac6dc0cf776bd764e8243a9dd68a
parent233f7d936da2de3f43a96c8fac1248346ffb041d (diff)
downloadlibgcrypt-adc044a039bfd68ec4127df3061b2199200ae25d.tar.gz
2003-11-02 Moritz Schulte <mo@g10code.com>
* benchmark.c: Rewritten, with support for ac.
-rw-r--r--tests/ChangeLog4
-rw-r--r--tests/benchmark.c932
2 files changed, 685 insertions, 251 deletions
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 4eed23f8..7665016b 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,7 @@
+2003-11-02 Moritz Schulte <mo@g10code.com>
+
+ * benchmark.c: Rewritten, with support for ac.
+
2003-10-28 Moritz Schulte <mo@g10code.com>
* Makefile.am (TESTS): Added: encoding.
diff --git a/tests/benchmark.c b/tests/benchmark.c
index 1b467408..5a196300 100644
--- a/tests/benchmark.c
+++ b/tests/benchmark.c
@@ -1,298 +1,664 @@
-/* benchmark.c - for libgcrypt
- * Copyright (C) 2002 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
+/* benchmark.c - Benchmarking for Libgcrypt
+ Copyright (C) 2002, 2003 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/times.h>
#include <gcrypt.h>
+#include <stdarg.h>
+#include <string.h>
+#include <assert.h>
+#include <unistd.h>
+
+
+
+#define dim(array) (sizeof (array) / sizeof (*array))
-#define PGM "benchmark"
-#define BUG() do {fprintf ( stderr, "Ooops at %s:%d\n", __FILE__ , __LINE__ );\
- exit(2);} while(0)
+
+/* Timestamp holders. */
+static clock_t timestamp_start, timestamp_stop;
+static char *program_name;
-/* Helper for the start and stop timer. */
-static clock_t started_at, stopped_at;
+
+
+typedef gcry_error_t (*benchmark_action_func_t) (void *context);
+typedef gcry_error_t (*benchmark_func_t) (int argc, char **argv);
+typedef const char *(*benchmark_help_get_t) (void);
+
+typedef struct benchmark_action
+{
+ char *comment;
+ benchmark_action_func_t func;
+ void *context;
+} benchmark_action_t;
+
+typedef struct benchmark_function
+{
+ const char *identifier;
+ benchmark_func_t func;
+ benchmark_help_get_t help_get;
+} benchmark_function_t;
+
static void
-start_timer (void)
+timer_start (void)
{
struct tms tmp;
times (&tmp);
- started_at = stopped_at = tmp.tms_utime;
+ timestamp_start = tmp.tms_utime;
}
static void
-stop_timer (void)
+timer_stop (void)
{
struct tms tmp;
times (&tmp);
- stopped_at = tmp.tms_utime;
+ timestamp_stop = tmp.tms_utime;
}
static const char *
-elapsed_time (void)
+timer_delta (void)
{
static char buf[50];
sprintf (buf, "%5.0fms",
- (((double) (stopped_at - started_at))/CLOCKS_PER_SEC)*10000000);
+ (((double) (timestamp_stop - timestamp_start)) / CLOCKS_PER_SEC) * 10000000);
+
return buf;
}
+static gcry_error_t
+timer_exec (benchmark_action_t action, const char **time_delta)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+
+ timer_start ();
+ err = (*action.func) (action.context);
+ timer_stop ();
+ *time_delta = timer_delta ();
-static void
-random_bench (void)
+ return err;
+}
+
+
+
+static gcry_error_t
+benchmark_action_process (benchmark_action_t action, unsigned int index)
{
- char buf[128];
- int i;
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ const char *time_delta = NULL;
+
+ err = timer_exec (action, &time_delta);
+ printf ("\t#%i%s%s%s: \t%s%s%s%s\n",
+ index,
+ action.comment ? " (" : "",
+ action.comment ? action.comment : "",
+ action.comment ? ")" : "",
+ time_delta,
+ err ? " (" : "", err ? gcry_strerror (err) : "", err ? ")" : "");
+
+ return err;
+}
+
+static gcry_error_t
+benchmark_actions_process (benchmark_action_t *actions, size_t actions_n)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ unsigned int i = 0;
- printf ("%-10s", "random");
+ for (i = 0; i < actions_n; i++)
+ benchmark_action_process (actions[i], i);
- start_timer ();
- for (i=0; i < 100; i++)
- gcry_randomize (buf, sizeof buf, GCRY_STRONG_RANDOM);
- stop_timer ();
- printf (" %s", elapsed_time ());
+ return err;
+}
- start_timer ();
- for (i=0; i < 100; i++)
- gcry_randomize (buf, 8, GCRY_STRONG_RANDOM);
- stop_timer ();
- printf (" %s", elapsed_time ());
+
- putchar ('\n');
+typedef struct benchmark_context_random
+{
+ char *buffer;
+ size_t size;
+ gcry_random_level_t random_level;
+ unsigned int loop;
+} benchmark_context_random_t;
+
+static gcry_error_t
+benchmark_random_randomize (void *ctx)
+{
+ benchmark_context_random_t *context = (benchmark_context_random_t *) ctx;
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ unsigned int i = 0;
+
+ for (i = 0; i < context->loop; i++)
+ gcry_randomize (context->buffer, context->size, context->random_level);
+
+ return err;
}
+static gcry_error_t
+benchmark_random (int argc, char **argv)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ char buffer[128];
+ benchmark_context_random_t context_randomize_100 = { buffer, sizeof (buffer),
+ GCRY_STRONG_RANDOM, 100 };
+ benchmark_context_random_t context_randomize_8 = { buffer, 8,
+ GCRY_STRONG_RANDOM, 100 };
+ benchmark_action_t actions[] =
+ {
+ { "128", benchmark_random_randomize, (void *) &context_randomize_100 },
+ { "8", benchmark_random_randomize, (void *) &context_randomize_8 },
+ };
+
+ printf ("random\n");
+
+ err = benchmark_actions_process (actions, dim (actions));
+ return err;
+}
-static void
-md_bench ( const char *algoname )
+
+
+typedef struct benchmark_context_md
{
- int algo = gcry_md_map_name (algoname);
- gcry_md_hd_t hd;
- int i;
- char buf[1000];
+ gcry_md_hd_t handle;
+ char *buffer;
+ size_t size;
+ unsigned int loop;
+} benchmark_context_md_t;
+
+static gcry_error_t
+benchmark_md_default (void *ctx)
+{
+ benchmark_context_md_t *context = (benchmark_context_md_t *) ctx;
gcry_error_t err = GPG_ERR_NO_ERROR;
+ unsigned int i = 0;
+
+ gcry_md_reset (context->handle);
+ for (i = 0; i < context->loop; i++)
+ gcry_md_write (context->handle, context->buffer, context->size);
+ gcry_md_final (context->handle);
+
+ return err;
+}
- if (!algo)
+static gcry_error_t
+benchmark_md_one (const char *algorithm_name)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ gcry_md_hd_t handle = NULL;
+ int algorithm_id = 0;
+ unsigned int i = 0;
+ char buffer[1000];
+ benchmark_context_md_t context_0 = { NULL, buffer, sizeof (buffer), 1000 };
+ benchmark_context_md_t context_1 = { NULL, buffer, sizeof (buffer) / 10, 10000 };
+ benchmark_context_md_t context_2 = { NULL, "", 1, 1000000 };
+ benchmark_action_t actions[] =
{
- fprintf (stderr, PGM ": invalid hash algorithm `%s'\n", algoname);
- exit (1);
- }
+ { "1000", benchmark_md_default, (void *) &context_0 },
+ { "10000", benchmark_md_default, (void *) &context_1 },
+ { "1000000", benchmark_md_default, (void *) &context_2 },
+ };
- err = gcry_md_open (&hd, algo, 0);
- if (err)
+ printf ("md: %s\n", algorithm_name);
+
+ algorithm_id = gcry_md_map_name (algorithm_name);
+ if (! algorithm_id)
+ err = GPG_ERR_DIGEST_ALGO;
+
+ if (! err)
+ err = gcry_md_open (&handle, algorithm_id, 0);
+
+ if (! err)
{
- fprintf (stderr, PGM ": error opeing hash algorithm `%s'/n", algoname);
- exit (1);
+ for (i = 0; i < sizeof (buffer); i++)
+ buffer[i] = i & 0xFF;
+
+ context_0.handle = handle;
+ context_1.handle = handle;
+ context_2.handle = handle;
+
+ err = benchmark_actions_process (actions, dim (actions));
}
- for (i=0; i < sizeof buf; i++)
- buf[i] = i;
+ if (handle)
+ gcry_md_close (handle);
- printf ("%-10s", gcry_md_algo_name (algo));
+ return err;
+}
- start_timer ();
- for (i=0; i < 1000; i++)
- gcry_md_write (hd, buf, sizeof buf);
- gcry_md_final (hd);
- stop_timer ();
- printf (" %s", elapsed_time ());
+static gcry_error_t
+benchmark_md (int argc, char **argv)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ unsigned int i = 0;
- gcry_md_reset (hd);
- start_timer ();
- for (i=0; i < 10000; i++)
- gcry_md_write (hd, buf, sizeof buf/10);
- gcry_md_final (hd);
- stop_timer ();
- printf (" %s", elapsed_time ());
+ for (i = 0; (i < argc) && (! err); i++)
+ err = benchmark_md_one (argv[i]);
- gcry_md_reset (hd);
- start_timer ();
- for (i=0; i < 1000000; i++)
- gcry_md_write (hd, "", 1);
- gcry_md_final (hd);
- stop_timer ();
- printf (" %s", elapsed_time ());
+ return err;
+}
- gcry_md_close (hd);
- putchar ('\n');
+static const char *
+benchmark_md_get_help (void)
+{
+ return "<algorithms>";
}
-static void
-cipher_bench ( const char *algoname )
+
+
+typedef struct benchmark_context_cipher
{
- static int header_printed;
- int algo = gcry_cipher_map_name (algoname);
- gcry_cipher_hd_t hd;
- int i;
- int keylen, blklen;
- char key[128];
- char outbuf[1000], buf[1000];
- size_t buflen;
- static struct { int mode; const char *name; int blocked; } modes[] = {
- { GCRY_CIPHER_MODE_ECB, "ECB", 1 },
- { GCRY_CIPHER_MODE_CBC, "CBC", 1 },
- { GCRY_CIPHER_MODE_CFB, "CFB", 0 },
- { GCRY_CIPHER_MODE_CTR, "CTR", 0 },
- { GCRY_CIPHER_MODE_STREAM, "STREAM", 0 },
- {0}
- };
- int modeidx;
+ gcry_cipher_hd_t handle;
+ char *buffer;
+ size_t buffer_length;
+ char *buffer_out;
+ unsigned int loop;
+} benchmark_context_cipher_t;
+
+static gcry_error_t
+benchmark_cipher_one_encrypt (void *ctx)
+{
+ benchmark_context_cipher_t *context = (benchmark_context_cipher_t *) ctx;
gcry_error_t err = GPG_ERR_NO_ERROR;
+ unsigned int i = 0;
- if (!header_printed)
+ for (i = 0; (i < context->loop) && (! err); i++)
+ err = gcry_cipher_encrypt (context->handle,
+ context->buffer_out, context->buffer_length,
+ context->buffer, context->buffer_length);
+
+ return err;
+}
+
+static gcry_error_t
+benchmark_cipher_one_decrypt (void *ctx)
+{
+ benchmark_context_cipher_t *context = (benchmark_context_cipher_t *) ctx;
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ unsigned int i = 0;
+
+ for (i = 0; (i < context->loop) && (! err); i++)
+ err = gcry_cipher_decrypt (context->handle,
+ context->buffer_out, context->buffer_length,
+ context->buffer, context->buffer_length);
+
+ return err;
+}
+
+static gcry_error_t
+benchmark_cipher_one (const char *algorithm_name)
+{
+ char key[128], buffer[1000], buffer_out[1000];
+ size_t buffer_length = sizeof (buffer);
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ gcry_cipher_hd_t handle = NULL;
+ unsigned int block_length = 0;
+ unsigned int key_length = 0;
+ unsigned int mode_index = 0;
+ int algorithm_id = 0;
+ unsigned int i = 0;
+ char comment[15];
+ benchmark_context_cipher_t context = { NULL, buffer, 0, buffer_out, 0 };
+ benchmark_action_t action = { comment, NULL, (void *) &context };
+ struct
+ {
+ unsigned int mode;
+ const char *name;
+ int blocked;
+ } modes[] =
{
- printf ("%-10s", "Algo");
- for (modeidx=0; modes[modeidx].mode; modeidx++)
- printf (" %-15s", modes[modeidx].name );
- putchar ('\n');
- printf ( "----------");
- for (modeidx=0; modes[modeidx].mode; modeidx++)
- printf (" ---------------" );
- putchar ('\n');
- header_printed = 1;
- }
+ { GCRY_CIPHER_MODE_ECB, "ECB", 1 },
+ { GCRY_CIPHER_MODE_CBC, "CBC", 1 },
+ { GCRY_CIPHER_MODE_CFB, "CFB", 0 },
+ { GCRY_CIPHER_MODE_CTR, "CTR", 0 },
+ { GCRY_CIPHER_MODE_STREAM, "STREAM", 0 },
+ };
+
+ printf ("cipher: %s\n", algorithm_name);
- if (!algo)
+ algorithm_id = gcry_cipher_map_name (algorithm_name);
+ if (! algorithm_id)
+ err = GPG_ERR_CIPHER_ALGO;
+
+ if (! err)
{
- fprintf (stderr, PGM ": invalid cipher algorithm `%s'\n", algoname);
- exit (1);
+ key_length = gcry_cipher_get_algo_keylen (algorithm_id);
+ if (! key_length)
+ err = GPG_ERR_CIPHER_ALGO;
+ else
+ {
+ assert (key_length <= sizeof (key));
+
+ for (i = 0; i < key_length; i++)
+ key[i] = i + (clock () & 0xFF);
+ }
}
- keylen = gcry_cipher_get_algo_keylen (algo);
- if (!keylen)
+ if (! err)
{
- fprintf (stderr, PGM ": failed to get key length for algorithm `%s'\n",
- algoname);
- exit (1);
+ block_length = gcry_cipher_get_algo_blklen (algorithm_id);
+ if (! block_length)
+ err = GPG_ERR_CIPHER_ALGO;
}
- if ( keylen > sizeof key )
+
+ for (mode_index = 0; (mode_index < dim (modes)) && (! err); mode_index++)
{
- fprintf (stderr, PGM ": algo %d, keylength problem (%d)\n",
- algo, keylen );
- exit (1);
+ if (((block_length > 1) && (modes[mode_index].mode == GCRY_CIPHER_MODE_STREAM))
+ || ((block_length == 1) && modes[mode_index].mode != GCRY_CIPHER_MODE_STREAM))
+ continue;
+
+ for (i = 0; i < sizeof (buffer); i++)
+ buffer[i] = i & 0xFF;
+
+ err = gcry_cipher_open (&handle, algorithm_id, modes[mode_index].mode, 0);
+ if (! err)
+ err = gcry_cipher_setkey (handle, key, key_length);
+ if (! err)
+ if (modes[mode_index].blocked)
+ buffer_length = (buffer_length / block_length) * block_length;
+
+ if (! err)
+ {
+ context.handle = handle;
+ context.buffer_length = buffer_length;
+ context.loop = 1000;
+
+ action.func = benchmark_cipher_one_encrypt;
+ snprintf (action.comment, sizeof (action.comment), "%s-encrypt",
+ modes[mode_index].name);
+ err = benchmark_action_process (action, mode_index);
+
+ if (! err)
+ err = gcry_cipher_reset (handle);
+
+ if (! err)
+ {
+ action.func = benchmark_cipher_one_decrypt;
+ snprintf (action.comment, sizeof (action.comment), "%s-decrypt",
+ modes[mode_index].name);
+ err = benchmark_action_process (action, mode_index);
+ }
+ }
}
- for (i=0; i < keylen; i++)
- key[i] = i + (clock () & 0xff);
- blklen = gcry_cipher_get_algo_blklen (algo);
- if (!blklen)
+ return err;
+}
+
+static gcry_error_t
+benchmark_cipher (int argc, char **argv)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ unsigned int i = 0;
+
+ for (i = 0; (i < argc) && (! err); i++)
+ err = benchmark_cipher_one (argv[i]);
+
+ return err;
+}
+
+static const char *
+benchmark_cipher_get_help (void)
+{
+ return "<algorithms>";
+}
+
+
+
+#define KEY_TYPE_PUBLIC (1 << 0)
+#define KEY_TYPE_SECRET (1 << 1)
+
+typedef struct key_spec
+{
+ const char *name;
+ unsigned int flags;
+ const char *mpi_string;
+} key_spec_t;
+
+static key_spec_t key_specs[] =
+ {
+ { "n", KEY_TYPE_PUBLIC | KEY_TYPE_SECRET,
+ "e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+ "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+ "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+ "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251" },
+ { "e", KEY_TYPE_PUBLIC | KEY_TYPE_SECRET,
+ "010001" },
+ { "d", KEY_TYPE_SECRET,
+ "046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
+ "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
+ "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
+ "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781" },
+ { "p", KEY_TYPE_SECRET,
+ "00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
+ "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1" },
+ { "q", KEY_TYPE_SECRET,
+ "00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
+ "35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361" },
+ { "u", KEY_TYPE_SECRET,
+ "304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
+ "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b" },
+ { NULL },
+ };
+
+static gcry_error_t
+key_init (key_spec_t *key_specs, gcry_ac_key_type_t type, gcry_ac_key_t *key)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ gcry_ac_data_t key_data = NULL;
+ gcry_ac_key_t key_new = NULL;
+ gcry_mpi_t mpi = NULL;
+ unsigned int i = 0;
+
+ err = gcry_ac_data_new (&key_data);
+ for (i = 0; key_specs[i].name && (! err); i++)
{
- fprintf (stderr, PGM ": failed to get block length for algorithm `%s'\n",
- algoname);
- exit (1);
+ if (((type == GCRY_AC_KEY_PUBLIC) && (key_specs[i].flags & KEY_TYPE_PUBLIC))
+ || ((type == GCRY_AC_KEY_SECRET) && (key_specs[i].flags & KEY_TYPE_SECRET)))
+ {
+ mpi = gcry_mpi_new (0);
+ err = gcry_mpi_scan (&mpi, GCRYMPI_FMT_HEX, key_specs[i].mpi_string, 0, NULL);
+
+ if (! err)
+ gcry_ac_data_set (key_data, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
+ key_specs[i].name, mpi);
+ if (mpi)
+ gcry_mpi_release (mpi);
+ }
}
+ if (! err)
+ err = gcry_ac_key_init (&key_new, NULL, type, key_data);
+
+ if (key_data)
+ gcry_ac_data_destroy (key_data);
+
+ if (! err)
+ *key = key_new;
- printf ("%-10s", gcry_cipher_algo_name (algo));
- fflush (stdout);
+ return err;
+}
+
+typedef struct benchmark_context_ac
+{
+ gcry_ac_handle_t handle;
+ gcry_ac_scheme_t scheme;
+ void *opts;
+ gcry_ac_key_t key;
+ unsigned char *m;
+ size_t m_n;
+ unsigned char **m2;
+ size_t *m2_n;
+ unsigned int loop;
+} benchmark_context_ac_t;
+
+static gcry_error_t
+benchmark_ac_one_encrypt (void *ctx)
+{
+ benchmark_context_ac_t *context = (benchmark_context_ac_t *) ctx;
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ unsigned int i = 0;
- for (modeidx=0; modes[modeidx].mode; modeidx++)
+ for (i = 0; (i < context->loop) && (! err); i++)
+ err = gcry_ac_data_encrypt_scheme (context->handle, context->scheme, 0, context->opts,
+ context->key, context->m, context->m_n,
+ context->m2, context->m2_n);
+
+ return err;
+}
+
+static gcry_error_t
+benchmark_ac_one_decrypt (void *ctx)
+{
+ benchmark_context_ac_t *context = (benchmark_context_ac_t *) ctx;
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ unsigned int i = 0;
+
+ for (i = 0; (i < context->loop) && (! err); i++)
+ err = gcry_ac_data_decrypt_scheme (context->handle, context->scheme, 0, context->opts,
+ context->key, context->m, context->m_n,
+ context->m2, context->m2_n);
+
+ return err;
+}
+
+static gcry_error_t
+benchmark_ac_one (const char *algorithm_name)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ gcry_ac_key_t key_public = NULL;
+ gcry_ac_key_t key_secret = NULL;
+ gcry_ac_handle_t handle = NULL;
+ gcry_ac_id_t algorithm_id = 0;
+ unsigned char *buffer_encrypted;
+ size_t buffer_encrypted_n;
+ unsigned char *buffer_decrypted;
+ size_t buffer_decrypted_n;
+ char comment[15];
+ benchmark_context_ac_t context;
+ benchmark_action_t action = { comment, NULL, (void *) &context };
+ struct
+ {
+ gcry_ac_scheme_t scheme;
+ void *opts;
+ char *m;
+ size_t m_n;
+ unsigned int loop;
+ } ac_specs[] =
+ {
+#define FILL(scheme, opts, m, loop) \
+ { scheme, opts, m, sizeof (m), loop }
+ FILL (GCRY_AC_ES_PKCS_V1_5, NULL, "One ring to rule them all", 100),
+ };
+ unsigned int i = 0;
+
+ printf ("ac: %s\n", algorithm_name);
+
+ err = gcry_ac_name_to_id (algorithm_name, &algorithm_id);
+ if (! err)
+ err = gcry_ac_open (&handle, algorithm_id, 0);
+ if (! err)
+ err = key_init (key_specs, GCRY_AC_KEY_PUBLIC, &key_public);
+ if (! err)
+ err = key_init (key_specs, GCRY_AC_KEY_SECRET, &key_secret);
+
+ if (! err)
{
- if ((blklen > 1 && modes[modeidx].mode == GCRY_CIPHER_MODE_STREAM)
- | (blklen == 1 && modes[modeidx].mode != GCRY_CIPHER_MODE_STREAM))
- {
- printf (" " );
- continue;
- }
-
- for (i=0; i < sizeof buf; i++)
- buf[i] = i;
-
- err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0);
- if (err)
- {
- fprintf (stderr, PGM ": error opening cipher `%s'\n", algoname);
- exit (1);
- }
-
- err = gcry_cipher_setkey (hd, key, keylen);
- if (err)
- {
- fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
- gpg_strerror (err));
- gcry_cipher_close (hd);
- exit (1);
- }
-
- buflen = sizeof buf;
- if (modes[modeidx].blocked)
- buflen = (buflen / blklen) * blklen;
-
- start_timer ();
- for (i=err=0; !err && i < 1000; i++)
- err = gcry_cipher_encrypt ( hd, outbuf, buflen, buf, buflen);
- stop_timer ();
- printf (" %s", elapsed_time ());
- fflush (stdout);
- gcry_cipher_close (hd);
- if (err)
- {
- fprintf (stderr, "gcry_cipher_encrypt failed: %s\n",
- gpg_strerror (err) );
- exit (1);
- }
-
- err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0);
- if (err)
- {
- fprintf (stderr, PGM ": error opening cipher `%s'/n", algoname);
- exit (1);
- }
-
- err = gcry_cipher_setkey (hd, key, keylen);
- if (err)
- {
- fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
- gpg_strerror (err));
- gcry_cipher_close (hd);
- exit (1);
- }
-
- start_timer ();
- for (i=err=0; !err && i < 1000; i++)
- err = gcry_cipher_decrypt ( hd, outbuf, buflen, buf, buflen);
- stop_timer ();
- printf (" %s", elapsed_time ());
- fflush (stdout);
- gcry_cipher_close (hd);
- if (err)
- {
- fprintf (stderr, "gcry_cipher_decrypt failed: %s\n",
- gpg_strerror (err) );
- exit (1);
- }
+ context.handle = handle;
+
+ for (i = 0; (i < dim (ac_specs)) && (! err); i++)
+ {
+ context.scheme = ac_specs[i].scheme;
+ context.opts = ac_specs[i].opts;
+ context.loop = ac_specs[i].loop;
+
+ if (! err)
+ {
+ context.m = ac_specs[i].m;
+ context.m_n = ac_specs[i].m_n;
+ context.m2 = &buffer_encrypted;
+ context.m2_n = &buffer_encrypted_n;
+ context.key = key_public;
+ action.func = benchmark_ac_one_encrypt;
+ snprintf (comment, sizeof (comment), "encrypt");
+
+ err = benchmark_action_process (action, i);
+ }
+
+ if (! err)
+ {
+ context.m = buffer_encrypted;
+ context.m_n = buffer_encrypted_n;
+ context.m2 = &buffer_decrypted;
+ context.m2_n = &buffer_decrypted_n;
+ context.key = key_secret;
+ action.func = benchmark_ac_one_decrypt;
+ snprintf (comment, sizeof (comment), "decrypt");
+
+ err = benchmark_action_process (action, i);
+ }
+
+ if (buffer_encrypted)
+ gcry_free (buffer_encrypted);
+ if (buffer_decrypted)
+ gcry_free (buffer_decrypted);
+ }
}
- putchar ('\n');
+ if (key_public)
+ gcry_ac_key_destroy (key_public);
+ if (key_secret)
+ gcry_ac_key_destroy (key_secret);
+ if (handle)
+ gcry_ac_close (handle);
+
+ return err;
}
+static gcry_error_t
+benchmark_ac (int argc, char **argv)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ unsigned int i = 0;
+ for (i = 0; (i < argc) && (! err); i++)
+ err = benchmark_ac_one (argv[i]);
+
+ return err;
+}
+
+static const char *
+benchmark_ac_get_help (void)
+{
+ return "<algorithms>";
+}
+
+#if 0
static void
do_powm ( const char *n_str, const char *e_str, const char *m_str)
{
@@ -314,14 +680,14 @@ do_powm ( const char *n_str, const char *e_str, const char *m_str)
gcry_mpi_powm (cip, msg, e, n);
stop_timer ();
printf (" %s", elapsed_time ()); fflush (stdout);
-/* { */
-/* char *buf; */
-
-/* if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, (void**)&buf, NULL, cip)) */
-/* BUG (); */
-/* printf ("result: %s\n", buf); */
-/* gcry_free (buf); */
-/* } */
+ /* { */
+ /* char *buf; */
+
+ /* if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, (void**)&buf, NULL, cip)) */
+ /* BUG (); */
+ /* printf ("result: %s\n", buf); */
+ /* gcry_free (buf); */
+ /* } */
gcry_mpi_release (cip);
gcry_mpi_release (msg);
gcry_mpi_release (n);
@@ -335,9 +701,9 @@ mpi_bench (void)
printf ("%-10s", "powm"); fflush (stdout);
do_powm (
-"20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E4",
+ "20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E4",
"29",
-"B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8"
+ "B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8"
);
do_powm (
"20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA40716",
@@ -354,43 +720,107 @@ mpi_bench (void)
}
+#endif
+
-int
-main( int argc, char **argv )
+benchmark_function_t benchmark_functions[] =
+ {
+ { "random", benchmark_random, NULL },
+ { "md", benchmark_md, benchmark_md_get_help },
+ { "cipher", benchmark_cipher, benchmark_cipher_get_help },
+ { "ac", benchmark_ac, benchmark_ac_get_help },
+ };
+
+
+
+void
+print_version (void)
{
- if (argc < 2 )
- {
- fprintf (stderr, "usage: benchmark md|cipher|random|mpi [algonames]\n");
- return 1;
- }
- argc--; argv++;
-
- if ( !strcmp (*argv, "random"))
- {
- random_bench ();
- }
- else if ( !strcmp (*argv, "md"))
- {
- for (argc--, argv++; argc; argc--, argv++)
- md_bench ( *argv );
- }
- else if ( !strcmp (*argv, "cipher"))
+ printf ("Libgcrypt %s\n", gcry_check_version (NULL));
+}
+
+void
+print_help (int status)
+{
+ unsigned int i = 0;
+
+ if (status != EXIT_SUCCESS)
+ fprintf (stderr, "Try `%s --help' or `%s -h' for more information.\n",
+ program_name, program_name);
+ else
{
- for (argc--, argv++; argc; argc--, argv++)
- cipher_bench ( *argv );
+ printf ("\
+Usage: %s <category> [OPTIONS ...]\n\
+Benchmark Libgcrypt\n\n",
+ program_name);
+
+ fprintf (stderr, "Categories:\n");
+ for (i = 0; i < dim (benchmark_functions); i++)
+ fprintf (stderr, " %s%s%s\n",
+ benchmark_functions[i].identifier,
+ benchmark_functions[i].help_get
+ ? " "
+ : "",
+ benchmark_functions[i].help_get
+ ? (*benchmark_functions[i].help_get) ()
+ : "");
+
+ fprintf (stderr, "\n\
+ --help display this help and exit\n\
+ --version output version information and exit\n\
+\n\
+Report bugs to %s.\n",
+ PACKAGE_BUGREPORT);
+ exit (status);
}
- else if ( !strcmp (*argv, "mpi"))
+}
+
+int
+main (int argc, char **argv)
+{
+ const char *getopt_spec_short = "Vh";
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ const char *category = NULL;
+ unsigned int i = 0;
+ int c = 0;
+
+ program_name = argv[0];
+
+ opterr = 0;
+ while ((c = getopt (argc, argv, getopt_spec_short)) != -1)
+ switch (c)
+ {
+ case 'V':
+ print_version ();
+ return EXIT_SUCCESS;
+
+ case 'h':
+ print_help (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
+ }
+
+ if (optind < argc)
+ for (i = 0; (i < dim (benchmark_functions)) && (! category); i++)
+ if (! strcmp (argv[optind], benchmark_functions[i].identifier))
+ {
+ category = argv[optind];
+ break;
+ }
+
+ if (category)
{
- mpi_bench ();
+ gcry_check_version (NULL);
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+
+ optind++;
+ err = (*benchmark_functions[i].func) (argc - optind, argv + optind);
}
else
- {
- fprintf (stderr, PGM ": bad arguments\n");
- return 1;
- }
-
- return 0;
-}
+ print_help (EXIT_FAILURE);
+ if (err)
+ fprintf (stderr, "Error: %s\n", gcry_strerror (err));
+ return err ? EXIT_FAILURE : EXIT_SUCCESS;
+}