util-vserver 0.30.215.
[util-vserver.git] / lib_internal / testsuite / crypto-speed.c
1 /*      --*- c -*--
2  * Copyright (C) 2008 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 2 and/or 3 of the License.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  */
16
17 #define ENSC_TESTSUITE
18
19 #ifdef HAVE_CONFIG_H
20 #  include <config.h>
21 #endif
22
23 #include <lib_internal/crypto-wrapper.h>
24 #include <lib_internal/coreassert.h>
25 #include <time.h>
26 #include <locale.h>
27
28
29 static void
30 do_benchmark(char const *meth_name)
31 {
32         struct {
33                 size_t          block_size;
34                 size_t          blocks;
35         } const                 DATA_SIZES[] = {
36                 { 0,  1 },
37                 { 0,  1024*1024 },
38                 { 16, 1 },
39                 { 16, 1024*1024 },
40                 { 1024, 16 },
41                 { 1024, 16*1024 },
42                 { 1024*1024, 16 },
43                 { 1024*1024, 100 },
44                 { 1024*1024, 1000 }
45         };
46                 
47         ensc_hash_method const  *m = ensc_crypto_hash_find(meth_name);
48         ensc_hash_context       ctx;
49         size_t                  d_len = m ? ensc_crypto_hash_get_digestsize(m) : 0;
50         char                    digest[d_len];
51         char *                  buf;
52         size_t                  i;
53
54         assert(m);
55         assert(ensc_crypto_hashctx_init(&ctx, m)==0);
56
57         for (i=0; i<sizeof(DATA_SIZES)/sizeof(DATA_SIZES[0]); ++i) {
58                 size_t          cnt = DATA_SIZES[i].blocks;
59                 size_t const    bs  = DATA_SIZES[i].block_size;
60                 struct timespec tm_start, tm_end, delta;
61                 uint64_t        bps;
62
63                 buf = malloc(bs+1);     /* avoid malloc-0 confusions */
64                 assert(buf);
65
66                 memset(buf, 0x11, bs);
67
68                 ensc_crypto_hashctx_reset(&ctx);
69
70                 /* benchmarked code starts here... */
71                 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tm_start);
72                 while (cnt--)
73                         ensc_crypto_hashctx_update(&ctx, buf, bs);
74
75                 ensc_crypto_hashctx_get_digest(&ctx, digest, NULL, d_len);
76                 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tm_end);
77                 /* ... and ends here */
78
79                 delta.tv_sec = tm_end.tv_sec - tm_start.tv_sec;
80                 if (tm_end.tv_nsec < tm_start.tv_nsec) {
81                         --delta.tv_sec;
82                         tm_end.tv_nsec += 1000000000l;
83                 }
84                 delta.tv_nsec = tm_end.tv_nsec - tm_start.tv_nsec;
85
86                 if (delta.tv_nsec==0 && delta.tv_sec==0)
87                         delta.tv_nsec = 1;
88
89                 bps = (uint64_t)(DATA_SIZES[i].blocks) * bs * 1000000000;
90                 bps /= (uint64_t)(delta.tv_sec) * 1000000000 + delta.tv_nsec;
91
92                 printf("%6s: %7zu x %-7zu -> %2lu.%09lus, %'15llu bytes/s\n",
93                        meth_name, DATA_SIZES[i].blocks, bs,
94                        delta.tv_sec, delta.tv_nsec, (unsigned long long)(bps));
95         }
96
97         ensc_crypto_hashctx_free(&ctx);
98 }
99
100 int main()
101 {
102         char const * const      METHS[] = {
103                 "md5", "sha1", "sha256", "sha512", NULL
104         };
105         char const * const *    meth;
106         
107         ensc_crypto_init();
108         setlocale(LC_NUMERIC, "");      /* needed for the thousands grouping */
109
110         for (meth=METHS+0; *meth; ++meth)
111                 do_benchmark(*meth);
112 }