From e2edda6866f01a1a9051abedc91c6d5a9d6aa2d8 Mon Sep 17 00:00:00 2001 From: mdw Date: Wed, 21 Apr 2004 00:37:32 +0000 Subject: [PATCH] Performance measuring program. For my embarassment, really. --- Makefile.m4 | 7 +- gcipher.h | 4 +- perftest.c | 573 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rspit.c | 4 +- 4 files changed, 582 insertions(+), 6 deletions(-) create mode 100644 perftest.c diff --git a/Makefile.m4 b/Makefile.m4 index 066ef52..04d03f6 100644 --- a/Makefile.m4 +++ b/Makefile.m4 @@ -1,6 +1,6 @@ ## -*-m4-*- ## -## $Id: Makefile.m4,v 1.82 2004/04/17 09:58:36 mdw Exp $ +## $Id: Makefile.m4,v 1.83 2004/04/21 00:37:32 mdw Exp $ ## ## Makefile for Catacomb ## @@ -245,10 +245,12 @@ patsubst(MP_SOURCES, `\.c\>', `.lo') dsig.o keyutil.o rspit.o: \ ## --- Utility programs --- -bin_PROGRAMS = dsig key pixie rspit factorial hashsum mkphrase catcrypt +bin_PROGRAMS = \ + dsig key pixie rspit factorial hashsum mkphrase catcrypt bin_SCRIPTS = catacomb-config xpixie noinst_PROGRAMS = \ genprimes mptypes serpent-check bittest mpdump \ + perftest \ addsuffix(`gen_tables', `-mktab') LDADD = libcatacomb.la @@ -258,6 +260,7 @@ key_SOURCES = keyutil.c getdate.y getdate.h hashsum_SOURCES = hashsum.c rspit_SOURCES = rspit.c factorial_SOURCES = factorial.c +perftest_SOURCES = perftest.c pixie_SOURCES = pixie.c pixie-common.c lmem.c arena.c pixie_LDADD = mkphrase_SOURCES = mkphrase.c diff --git a/gcipher.h b/gcipher.h index 97c3047..17df4c4 100644 --- a/gcipher.h +++ b/gcipher.h @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: gcipher.h,v 1.4 2004/04/08 01:36:15 mdw Exp $ + * $Id: gcipher.h,v 1.5 2004/04/21 00:37:32 mdw Exp $ * * Generic symmetric cipher interface * @@ -65,7 +65,7 @@ typedef struct gccipher { } gccipher; #define GC_INIT(cc, k, sz) (cc)->init((k), (sz)) -#define GC_CLASS(c) (c)->ops->c +#define GC_CLASS(cc) (cc)->ops->c #define GC_ENCRYPT(c, s, t, sz) (c)->ops->encrypt((c), (s), (t), (sz)) #define GC_DECRYPT(c, s, t, sz) (c)->ops->decrypt((c), (s), (t), (sz)) #define GC_DESTROY(c) (c)->ops->destroy((c)) diff --git a/perftest.c b/perftest.c new file mode 100644 index 0000000..4b8d158 --- /dev/null +++ b/perftest.c @@ -0,0 +1,573 @@ +/* -*-c-*- + * + * $Id: perftest.c,v 1.1 2004/04/21 00:37:32 mdw Exp $ + * + * Measure performance of various operations (Unix-specific) + * + * (c) 2004 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Catacomb 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +/*----- Header files ------------------------------------------------------*/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "rand.h" +#include "mp.h" +#include "mprand.h" +#include "fibrand.h" +#include "rsa.h" +#include "mpmont.h" +#include "mpbarrett.h" +#include "dh.h" +#include "pgen.h" +#include "ec.h" +#include "group.h" + +#include "gcipher.h" +#include "ghash.h" +#include "gmac.h" + +/*----- Options -----------------------------------------------------------*/ + +typedef struct opts { + const char *name; /* Pre-configured named thing */ + unsigned fbits; /* Field size bits */ + unsigned gbits; /* Group size bits */ + unsigned n; /* Number of factors */ + unsigned i; /* Number of intervals (or zero) */ + double t; /* Time for each interval (secs) */ +} opts; + +/*----- Job switch --------------------------------------------------------*/ + +/* --- Barrett exponentiation --- */ + +typedef struct bar_ctx { + size_t n; + mpbarrett b; + mp_expfactor *e; +} bar_ctx; + +static void *bar_init(opts *o) +{ + bar_ctx *c = CREATE(bar_ctx); + gprime_param gp; + qd_parse qd; + size_t i; + + if (o->name) { + qd.p = o->name; + if (dh_parse(&qd, &gp)) + die(1, "bad prime group: %s", qd.e); + } else { + if (!o->fbits) o->fbits = 1024; + dh_gen(&gp, o->gbits, o->fbits, 0, &rand_global, pgen_evspin, 0); + } + mpbarrett_create(&c->b, gp.p); + if (!o->n) o->n = 1; + c->n = o->n; + c->e = xmalloc(c->n * sizeof(group_expfactor)); + for (i = 0; i < c->n; i++) { + c->e[i].base = mprand_range(MP_NEW, gp.p, &rand_global, 0); + c->e[i].exp = mprand_range(MP_NEW, gp.q, &rand_global, 0); + } + dh_paramfree(&gp); + return (c); +} + +static void bar_run(void *cc) +{ + bar_ctx *c = cc; + mp *d = mpbarrett_exp(&c->b, MP_NEW, c->e[0].base, c->e[0].exp); + MP_DROP(d); +} + +static void barsim_run(void *cc) +{ + bar_ctx *c = cc; + mp *d = mpbarrett_mexp(&c->b, MP_NEW, c->e, c->n); + MP_DROP(d); +} + +/* --- Montgomery exponentiation --- */ + +typedef struct mont_ctx { + size_t n; + mpmont m; + mp_expfactor *e; +} mont_ctx; + +static void *mont_init(opts *o) +{ + mont_ctx *c = CREATE(mont_ctx); + gprime_param gp; + qd_parse qd; + size_t i; + + if (o->name) { + qd.p = o->name; + if (dh_parse(&qd, &gp)) + die(1, "bad prime group: %s", qd.e); + } else { + if (!o->fbits) o->fbits = 1024; + dh_gen(&gp, o->gbits, o->fbits, 0, &rand_global, pgen_evspin, 0); + } + mpmont_create(&c->m, gp.p); + if (!o->n) o->n = 1; + c->n = o->n; + c->e = xmalloc(c->n * sizeof(mp_expfactor)); + for (i = 0; i < c->n; i++) { + c->e[i].base = mprand_range(MP_NEW, gp.p, &rand_global, 0); + c->e[i].exp = mprand_range(MP_NEW, gp.q, &rand_global, 0); + } + dh_paramfree(&gp); + return (c); +} + +static void mont_run(void *cc) +{ + mont_ctx *c = cc; + mp *d = mpmont_expr(&c->m, MP_NEW, c->e[0].base, c->e[0].exp); + MP_DROP(d); +} + +static void montsim_run(void *cc) +{ + mont_ctx *c = cc; + mp *d = mpmont_mexpr(&c->m, MP_NEW, c->e, c->n); + MP_DROP(d); +} + +/* --- Group exponentiation --- */ + +typedef struct gr_ctx { + size_t n; + group *g; + group_expfactor *e; +} gr_ctx; + +static void *grp_init(opts *o) +{ + gr_ctx *c = CREATE(gr_ctx); + const char *e; + gprime_param gp; + qd_parse qd; + size_t i; + + if (o->name) { + qd.p = o->name; + if (dh_parse(&qd, &gp)) + die(1, "bad prime group: %s", qd.e); + } else { + if (!o->fbits) o->fbits = 1024; + dh_gen(&gp, o->gbits, o->fbits, 0, &rand_global, pgen_evspin, 0); + } + c->g = group_prime(&gp); + if ((e = G_CHECK(c->g, &rand_global)) != 0) + die(1, "bad group: %s", e); + if (!o->n) o->n = 1; + c->n = o->n; + c->e = xmalloc(c->n * sizeof(group_expfactor)); + for (i = 0; i < c->n; i++) { + c->e[i].base = G_CREATE(c->g); + G_FROMINT(c->g, c->e[i].base, + mprand_range(MP_NEW, gp.p, &rand_global, 0)); + c->e[i].exp = mprand_range(MP_NEW, gp.q, &rand_global, 0); + } + dh_paramfree(&gp); + return (c); +} + +static void *grec_init(opts *o) +{ + gr_ctx *c = CREATE(gr_ctx); + const char *e; + ec_info ei; + ec p = EC_INIT; + size_t i; + + if (!o->name) + die(1, "can't generate elliptic curves"); + if ((e = ec_getinfo(&ei, o->name)) != 0) + die(1, "bad curve: %s", e); + c->g = group_ec(&ei); + if ((e = G_CHECK(c->g, &rand_global)) != 0) + die(1, "bad group: %s", e); + if (!o->n) o->n = 1; + c->n = o->n; + c->e = xmalloc(c->n * sizeof(group_expfactor)); + for (i = 0; i < c->n; i++) { + c->e[i].base = G_CREATE(c->g); + ec_rand(ei.c, &p, &rand_global); + G_FROMEC(c->g, c->e[i].base, &p); + c->e[i].exp = mprand_range(MP_NEW, ei.r, &rand_global, 0); + } + EC_DESTROY(&p); + return (c); +} + +static void gr_run(void *cc) +{ + gr_ctx *c = cc; + ge *x = G_CREATE(c->g); + G_EXP(c->g, x, c->e[0].base, c->e[0].exp); + G_DESTROY(c->g, x); +} + +static void grsim_run(void *cc) +{ + gr_ctx *c = cc; + ge *x = G_CREATE(c->g); + G_MEXP(c->g, x, c->e, c->n); + G_DESTROY(c->g, x); +} + +/* --- RSA --- */ + +typedef struct rsapriv_ctx { + rsa_priv rp; + rsa_privctx rpc; + mp *m; +} rsapriv_ctx; + +static void *rsapriv_init(opts *o) +{ + rsapriv_ctx *c = CREATE(rsapriv_ctx); + + if (!o->fbits) o->fbits = 1024; + rsa_gen(&c->rp, o->fbits, &rand_global, 0, pgen_evspin, 0); + rsa_privcreate(&c->rpc, &c->rp, 0); + c->m = mprand_range(MP_NEW, c->rp.n, &rand_global, 0); + return (c); +} + +static void *rsaprivblind_init(opts *o) +{ + rsapriv_ctx *c = CREATE(rsapriv_ctx); + + if (!o->fbits) o->fbits = 1024; + rsa_gen(&c->rp, o->fbits, &rand_global, 0, pgen_evspin, 0); + rsa_privcreate(&c->rpc, &c->rp, fibrand_create(0)); + c->m = mprand_range(MP_NEW, c->rp.n, &rand_global, 0); + return (c); +} + +static void rsapriv_run(void *cc) +{ + rsapriv_ctx *c = cc; + mp *d = rsa_privop(&c->rpc, MP_NEW, c->m); + MP_DROP(d); +} + +typedef struct rsapub_ctx { + rsa_pub rp; + rsa_pubctx rpc; + mp *m; +} rsapub_ctx; + +static void *rsapub_init(opts *o) +{ + rsapub_ctx *c = CREATE(rsapub_ctx); + rsa_priv rp; + + if (!o->fbits) o->fbits = 1024; + rsa_gen(&rp, o->fbits, &rand_global, 0, pgen_evspin, 0); + c->rp.n = MP_COPY(rp.n); + c->rp.e = MP_COPY(rp.e); + rsa_privfree(&rp); + rsa_pubcreate(&c->rpc, &c->rp); + c->m = mprand_range(MP_NEW, c->rp.n, &rand_global, 0); + return (c); +} + +static void rsapub_run(void *cc) +{ + rsapub_ctx *c = cc; + mp *d = rsa_pubop(&c->rpc, MP_NEW, c->m); + MP_DROP(d); +} + +/* --- Symmetric encryption --- */ + +typedef struct ksched_ctx { + const gccipher *c; + octet *k; + size_t ksz; +} ksched_ctx; + +static void *ksched_init(opts *o) +{ + ksched_ctx *c = CREATE(ksched_ctx); + if (!o->name) + die(1, "must specify encryption scheme name"); + if ((c->c = gcipher_byname(o->name)) == 0) + die(1, "encryption scheme `%s' not known", o->name); + c->ksz = keysz(o->gbits/8, c->c->keysz); + c->k = xmalloc(c->ksz); + rand_get(RAND_GLOBAL, c->k, c->ksz); + return (c); +} + +static void ksched_run(void *cc) +{ + ksched_ctx *c = cc; + gcipher *gc = GC_INIT(c->c, c->k, c->ksz); + GC_DESTROY(gc); +} + +typedef struct enc_ctx { + gcipher *c; + octet *m; + size_t sz; + size_t n; +} enc_ctx; + +static void *enc_init(opts *o) +{ + enc_ctx *c = CREATE(enc_ctx); + const gccipher *cc; + size_t ksz; + octet *k; + if (!o->name) + die(1, "must specify encryption scheme name"); + if ((cc = gcipher_byname(o->name)) == 0) + die(1, "encryption scheme `%s' not known", o->name); + ksz = keysz(0, cc->keysz); + k = xmalloc(ksz); + rand_get(RAND_GLOBAL, k, ksz); + c->c = GC_INIT(cc, k, ksz); + xfree(k); + c->sz = o->gbits ? o->gbits : 65536; + c->n = o->n ? o->n : 16; + c->m = xmalloc(c->sz); + return (c); +} + +static void enc_run(void *cc) +{ + enc_ctx *c = cc; + size_t i; + for (i = 0; i < c->n; i++) + GC_ENCRYPT(c->c, c->m, c->m, c->sz); +} + +/* --- Hashing --- */ + +typedef struct hash_ctx { + const gchash *h; + octet *m; + size_t sz; + size_t n; +} hash_ctx; + +static void *hash_init(opts *o) +{ + hash_ctx *c = CREATE(hash_ctx); + if (!o->name) + die(1, "must specify hash function name"); + if ((c->h = ghash_byname(o->name)) == 0) + die(1, "hash function `%s' not known", o->name); + c->sz = o->gbits ? o->gbits : 65536; + c->n = o->n ? o->n : 16; + c->m = xmalloc(c->sz); + return (c); +} + +static void hash_run(void *cc) +{ + hash_ctx *c = cc; + size_t i; + ghash *h = GH_INIT(c->h); + for (i = 0; i < c->n; i++) + GH_HASH(h, c->m, c->sz); + GH_DONE(h, 0); + GH_DESTROY(h); +} + +/* --- Job table --- */ + +typedef struct jobobs { + const char *name; + void *(*init)(opts *); + void (*run)(void *); +} jobops; + +static const jobops jobtab[] = { + { "g-prime-exp", grp_init, gr_run }, + { "g-ec-mul", grec_init, gr_run }, + { "g-prime-exp-sim", grp_init, grsim_run }, + { "g-ec-mul-sim", grec_init, grsim_run }, + { "barrett-exp", bar_init, bar_run }, + { "barrett-exp-sim", bar_init, barsim_run }, + { "mont-exp", mont_init, mont_run }, + { "mont-exp-sim", mont_init, montsim_run }, + { "rsa-priv", rsapriv_init, rsapriv_run }, + { "rsa-priv-blind", rsaprivblind_init, rsapriv_run }, + { "rsa-pub", rsapub_init, rsapub_run }, + { "ksched", ksched_init, ksched_run }, + { "enc", enc_init, enc_run }, + { "hash", hash_init, hash_run }, + { 0, 0, 0 } +}; + +/*----- Main code ---------------------------------------------------------*/ + +static void version(FILE *fp) +{ + pquis(fp, "$, Catacomb " VERSION "\n"); +} + +static void usage(FILE *fp) +{ + pquis(fp, "Usage: $ [-options] job\n"); +} + +static void help(FILE *fp) +{ + version(fp); + putc('\n', fp); + usage(fp); + pquis(fp, "\n\ +Various performance tests.\n\ +"); +} + +static unsigned uarg(const char *what, const char *p) +{ + char *q; + unsigned long u; + errno = 0; + u = strtoul(p, &q, 0); + if (*q || u > UINT_MAX || q == p || errno) + die(1, "bad %s `%s'", what, p); + return (u); +} + +static double farg(const char *what, const char *p) +{ + char *q; + double f; + errno = 0; + f = strtod(p, &q); + if (*q || q == p || errno) + die(1, "bad %s `%s'", what, p); + return (f); +} + +int main(int argc, char *argv[]) +{ + int i; + opts o = { 0 }; + const jobops *j; + struct timeval tv_next, tv_now; + double t, ttot; + unsigned n; + unsigned long ii; + clock_t c_start, c_stop; + double itot; + void *p; + + ego(argv[0]); + o.t = 1; + for (;;) { + static const struct option opts[] = { + { "help", 0, 0, 'h' }, + { "version", 0, 0, 'v' }, + { "usage", 0, 0, 'u' }, + { "name", OPTF_ARGREQ, 0, 'C' }, + { "field-bits", OPTF_ARGREQ, 0, 'b' }, + { "group-bits", OPTF_ARGREQ, 0, 'B' }, + { "factors", OPTF_ARGREQ, 0, 'n' }, + { "intervals", OPTF_ARGREQ, 0, 'i' }, + { "time", OPTF_ARGREQ, 0, 't' }, + { 0, 0, 0, 0 } + }; + + i = mdwopt(argc, argv, "hvuC:b:B:n:i:t:", opts, 0, 0, 0); + if (i < 0) break; + switch (i) { + case 'h': help(stdout); exit(0); + case 'v': version(stdout); exit(0); + case 'u': usage(stdout); exit(0); + case 'C': o.name = optarg; break; + case 'b': o.fbits = uarg("field bits", optarg); break; + case 'B': o.gbits = uarg("subgroup bits", optarg); break; + case 'n': o.n = uarg("factor count", optarg); break; + case 'i': o.i = uarg("interval count", optarg); break; + case 't': o.t = farg("interval length", optarg); break; + default: usage(stderr); exit(1); + } + } + if (optind + 1 != argc) { usage(stderr); exit(1); } + + for (j = jobtab; j->name; j++) + if (strcmp(j->name, argv[optind]) == 0) break; + if (!j->name) die(1, "unknown job type `%s'", argv[optind]); + p = j->init(&o); + + n = 0; + ttot = itot = 0; + gettimeofday(&tv_now, 0); + do { + tv_addl(&tv_next, &tv_now, o.t, fmod(o.t * MILLION, MILLION)); + ii = 0; + c_start = clock(); + do { + j->run(p); + ii++; + gettimeofday(&tv_now, 0); + } while (TV_CMP(&tv_now, <, &tv_next)); + c_stop = clock(); + t = (double)(c_stop - c_start)/CLOCKS_PER_SEC; + itot += ii; + ttot += t; + printf("%5u: did = %5lu; /sec = %5f; avg /sec = %5f\n", + n, ii, ii/t, itot/ttot); + fflush(stdout); + n++; + } while (!o.i || n < o.i); + + return (0); +} + +/*----- That's all, folks -------------------------------------------------*/ diff --git a/rspit.c b/rspit.c index e9d5c29..34abb11 100644 --- a/rspit.c +++ b/rspit.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: rspit.c,v 1.20 2004/04/08 01:36:15 mdw Exp $ + * $Id: rspit.c,v 1.21 2004/04/21 00:37:32 mdw Exp $ * * Spit out random numbers * @@ -624,7 +624,7 @@ static grand *gen_bbs(unsigned i) if ((kd = key_structfind(&kk->k, "n")) == 0) die(EXIT_FAILURE, "key has no subkey `n'"); if ((kd->e & KF_ENCMASK) != KENC_MP) - die(EXIT_FAILURE, "incomatible subkey encoding"); + die(EXIT_FAILURE, "incompatible subkey encoding"); m = MP_COPY(kd->u.m); key_close(&kf); } else { -- 2.11.0