]> wagner.pp.ru Git - openssl-gost/engine.git/blob - benchmark/sign.c
Don't put test results or intermediary files in the source tree
[openssl-gost/engine.git] / benchmark / sign.c
1 /**********************************************************************
2  *             Simple benchmarking for gost-engine                    *
3  *                                                                    *
4  *             Copyright (c) 2018 Cryptocom LTD                       *
5  *             Copyright (c) 2018 <vt@altlinux.org>.                  *
6  *       This file is distributed under the same license as OpenSSL   *
7  **********************************************************************/
8
9 #define _GNU_SOURCE
10 #include <stdio.h>
11 #include <string.h>
12 #include <time.h>
13 #include <sys/time.h>
14 #include <getopt.h>
15 #include <openssl/rand.h>
16 #include <openssl/conf.h>
17 #include <openssl/err.h>
18 #include <openssl/evp.h>
19 #include <openssl/pem.h>
20 #include <openssl/engine.h>
21
22 const char *tests[] = {
23     "md_gost12_256", "gost2012_256", "A",
24     "md_gost12_256", "gost2012_256", "B",
25     "md_gost12_256", "gost2012_256", "C",
26     "md_gost12_256", "gost2012_256", "TCA",
27     "md_gost12_256", "gost2012_256", "TCB",
28     "md_gost12_256", "gost2012_256", "TCC",
29     "md_gost12_256", "gost2012_256", "TCD",
30
31     "md_gost12_512", "gost2012_512", "A",
32     "md_gost12_512", "gost2012_512", "B",
33     "md_gost12_512", "gost2012_512", "C",
34
35     NULL,
36 };
37
38 static EVP_PKEY *create_key(const char *algname, const char *param)
39 {
40         EVP_PKEY *key1 = EVP_PKEY_new(), *newkey = NULL;
41         EVP_PKEY_CTX *ctx = NULL;
42
43         if (EVP_PKEY_set_type_str(key1, algname, strlen(algname)) <= 0)
44                   goto err;
45
46         if (!(ctx = EVP_PKEY_CTX_new(key1, NULL)))
47                   goto err;
48
49         if (EVP_PKEY_keygen_init(ctx) == 0)
50                   goto err;
51
52         if (ERR_peek_last_error())
53                   goto err;
54
55         if (EVP_PKEY_CTX_ctrl_str(ctx, "paramset", param) <= 0)
56                   goto err;
57
58         if (EVP_PKEY_keygen(ctx, &newkey) <= 0)
59                   goto err;
60
61 err:
62         if(ctx)
63                 EVP_PKEY_CTX_free(ctx);
64         EVP_PKEY_free(key1);
65         return newkey;
66 }
67
68 void usage(char *name)
69 {
70         fprintf(stderr, "usage: %s [-l data_len] [-c cycles]\n", name);
71         exit(1);
72 }
73
74 int main(int argc, char **argv)
75 {
76         unsigned int data_len = 1;
77         unsigned int cycles = 100;
78         int option;
79         clockid_t clock_type = CLOCK_MONOTONIC;
80         int test, test_count = 0;
81
82         opterr = 0;
83         while((option = getopt(argc, argv, "l:c:C")) >= 0)
84         {
85                 switch (option)
86                 {
87                         case 'l':
88                                 data_len = atoi(optarg);
89                                 break;
90                         case 'c':
91                                 cycles = atoi(optarg);
92                                 break;
93                         case 'C':
94                                 clock_type = CLOCK_PROCESS_CPUTIME_ID;
95                                 break;
96                         default:
97                                 usage(argv[0]);
98                                 break;
99                 }
100         }
101         if (optind < argc) usage(argv[0]);
102         if (cycles < 100) { printf("cycles too low\n"); exit(1); }
103
104         OPENSSL_add_all_algorithms_conf();
105         ERR_load_crypto_strings();
106
107         for (test = 0; tests[test]; test += 3) {
108             double diff[2]; /* sign, verify */
109             const char *digest = tests[test];
110             const char *algo   = tests[test + 1];
111             const char *param  = tests[test + 2];
112             const EVP_MD *mdtype;
113             EVP_MD_CTX *md_ctx;
114             unsigned int siglen;
115             unsigned char *sigbuf;
116             EVP_PKEY *pkey;
117             unsigned char *data;
118             int pass;
119
120             md_ctx = EVP_MD_CTX_new();
121             mdtype = EVP_get_digestbyname(digest);
122             if (!mdtype)
123                 continue;
124             pkey = create_key(algo, param);
125             data = (unsigned char *) malloc(data_len);
126             if (!pkey)
127                 continue;
128
129             test_count++;
130             printf("wait...");
131             fflush(stdout);
132             siglen = EVP_PKEY_size(pkey);
133             sigbuf = malloc(siglen * cycles);
134         if (!sigbuf) {
135             fprintf(stderr, "No tests were run, malloc failure.\n");
136             exit(1);
137         }
138
139             for (pass = 0; pass < 2; pass++) {
140                 struct timespec ts;
141                 struct timeval debut, fin, delta;
142                 int err;
143                 unsigned int i;
144
145                 clock_gettime(clock_type, &ts);
146                 TIMESPEC_TO_TIMEVAL(&debut, &ts);
147
148                 if (pass == 0) { /* sign */
149                     for (i = 0; i < cycles; i++) {
150                         EVP_SignInit(md_ctx, mdtype);
151                         err = EVP_SignUpdate(md_ctx, data, data_len)
152                            && EVP_SignFinal(md_ctx, &sigbuf[siglen * i],
153                             (unsigned int *)&siglen, pkey);
154                         if (err != 1)
155                             printf("!");
156                         EVP_MD_CTX_reset(md_ctx);
157                     }
158                 } else { /* verify */
159                     for (i = 0; i < cycles; i++) {
160                         EVP_VerifyInit(md_ctx, mdtype);
161                         err = EVP_VerifyUpdate(md_ctx, data, data_len)
162                            && EVP_VerifyFinal(md_ctx, &sigbuf[siglen * i],
163                             siglen, pkey);
164                         EVP_MD_CTX_reset(md_ctx);
165                         if (err != 1)
166                             printf("!");
167                     }
168                 }
169
170                 clock_gettime(clock_type, &ts);
171                 TIMESPEC_TO_TIMEVAL(&fin, &ts);
172                 timersub(&fin, &debut, &delta);
173                 diff[pass] = (double)delta.tv_sec + (double)delta.tv_usec / 1000000;
174             }
175             printf("\r%s %s: sign: %.1f/s, verify: %.1f/s\n", algo, param,
176                 (double)cycles / diff[0], (double)cycles / diff[1]);
177             EVP_PKEY_free(pkey);
178             free(sigbuf);
179             free(data);
180         }
181
182         if (!test_count) {
183             fprintf(stderr, "No tests were run, something is wrong.\n");
184             exit(1);
185         }
186         exit(0);
187 }