]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - benchmark/sign.c
Merge pull request #101 from vt-alt/master
[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
27     "md_gost12_512", "gost2012_512", "A",
28     "md_gost12_512", "gost2012_512", "B",
29
30     NULL,
31 };
32
33 static EVP_PKEY *create_key(const char *algname, const char *param)
34 {
35         EVP_PKEY *key1 = EVP_PKEY_new(), *newkey = NULL;
36         EVP_PKEY_CTX *ctx = NULL;
37
38         if(EVP_PKEY_set_type_str(key1, algname, strlen(algname)) <= 0)
39         {
40                 goto err;
41         }
42         if(!(ctx = EVP_PKEY_CTX_new(key1, NULL)))
43         {
44                 goto err;
45         }
46         EVP_PKEY_keygen_init(ctx);
47         if(ERR_peek_last_error())
48         {
49                 goto err;
50         }
51         if(EVP_PKEY_CTX_ctrl_str(ctx, "paramset", param) <= 0)
52         {
53                 goto err;
54         }
55         if(EVP_PKEY_keygen(ctx, &newkey) <= 0)
56         {
57                 goto err;
58         }
59 err:
60         if(ctx)
61                 EVP_PKEY_CTX_free(ctx);
62         EVP_PKEY_free(key1);
63         return newkey;
64 }
65
66 void usage(char *name)
67 {
68         fprintf(stderr, "usage: %s [-l data_len] [-c cycles]\n", name);
69         exit(1);
70 }
71
72 int main(int argc, char **argv)
73 {
74         unsigned int data_len = 1;
75         unsigned int cycles = 100;
76         int option;
77         clockid_t clock_type = CLOCK_MONOTONIC;
78         int test, test_count = 0;
79
80         opterr = 0;
81         while((option = getopt(argc, argv, "l:c:C")) >= 0)
82         {
83                 if(option == ':') option = optopt;
84                 if(optarg && (optarg[0] == '-')) { optind--; optarg = NULL; }
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
135             for (pass = 0; pass < 2; pass++) {
136                 struct timespec ts;
137                 struct timeval debut, fin, delta;
138                 int err;
139                 unsigned int i;
140
141                 clock_gettime(clock_type, &ts);
142                 TIMESPEC_TO_TIMEVAL(&debut, &ts);
143
144                 if (pass == 0) { /* sign */
145                     for (i = 0; i < cycles; i++) {
146                         EVP_SignInit(md_ctx, mdtype);
147                         EVP_SignUpdate(md_ctx, data, data_len);
148                         err = EVP_SignFinal(md_ctx, &sigbuf[siglen * i],
149                             (unsigned int *)&siglen, pkey);
150                         if (err != 1)
151                             printf("!");
152                         EVP_MD_CTX_reset(md_ctx);
153                     }
154                 } else { /* verify */
155                     for (i = 0; i < cycles; i++) {
156                         EVP_VerifyInit(md_ctx, mdtype);
157                         EVP_VerifyUpdate(md_ctx, data, data_len);
158                         err = EVP_VerifyFinal(md_ctx, &sigbuf[siglen * i],
159                             siglen, pkey);
160                         EVP_MD_CTX_reset(md_ctx);
161                         if (err != 1)
162                             printf("!");
163                     }
164                 }
165
166                 clock_gettime(clock_type, &ts);
167                 TIMESPEC_TO_TIMEVAL(&fin, &ts);
168                 timersub(&fin, &debut, &delta);
169                 diff[pass] = (double)delta.tv_sec + (double)delta.tv_usec / 1000000;
170             }
171             printf("\r%s %s: sign: %.1f/s, verify: %.1f/s\n", algo, param,
172                 (double)cycles / diff[0], (double)cycles / diff[1]);
173             EVP_PKEY_free(pkey);
174             free(sigbuf);
175             free(data);
176         }
177
178         if (!test_count) {
179             fprintf(stderr, "No tests were run, something is wrong.\n");
180             exit(1);
181         }
182         exit(0);
183 }