Nuked almost all trailing whitespace.
[libgcrypt.git] / tests / benchmark.c
1 /* benchmark.c - for libgcrypt
2  * Copyright (C) 2002, 2004, 2005, 2006, 2008 Free Software Foundation, Inc.
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser general Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <time.h>
26 #include <stdarg.h>
27 #ifdef _WIN32
28 #include <windows.h>
29 #else
30 #include <sys/times.h>
31 #endif
32
33 #ifdef _GCRYPT_IN_LIBGCRYPT
34 # include "../src/gcrypt.h"
35 # include "../compat/libcompat.h"
36 #else
37 # include <gcrypt.h>
38 #endif
39
40
41 #define PGM "benchmark"
42
43 static int verbose;
44
45 /* Do encryption tests with large buffers.  */
46 static int large_buffers;
47
48 /* Number of cipher repetitions.  */
49 static int cipher_repetitions;
50
51 /* Number of hash repetitions.  */
52 static int hash_repetitions;
53
54 /* Whether fips mode was active at startup.  */
55 static int in_fips_mode;
56
57
58 static const char sample_private_dsa_key_1024[] =
59 "(private-key\n"
60 "  (dsa\n"
61 "   (p #00A126202D592214C5A8F6016E2C3F4256052ACB1CB17D88E64B1293FAF08F5E4685"
62        "03E6F68366B326A56284370EB2103E92D8346A163E44A08FDC422AC8E9E44268557A"
63        "853539A6AF39353A59CE5E78FD98B57D0F3E3A7EBC8A256AC9A775BA59689F3004BF"
64        "C3035730C4C0C51626C5D7F5852637EC589BB29DAB46C161572E4B#)\n"
65 "   (q #00DEB5A296421887179ECA1762884DE2AF8185AFC5#)\n"
66 "   (g #3958B34AE7747194ECBD312F8FEE8CBE3918E94DF9FD11E2912E56318F33BDC38622"
67        "B18DDFF393074BCA8BAACF50DF27AEE529F3E8AEECE55C398DAB3A5E04C2EA142312"
68        "FACA2FE7F0A88884F8DAC3979EE67598F9A383B2A2325F035C796F352A5C3CDF2CB3"
69        "85AD24EC52A6E55247E1BB37D260F79E617D2A4446415B6AD79A#)\n"
70 "   (y #519E9FE9AB0545A6724E74603B7B04E48DC1437E0284A11EA605A7BA8AB1CF354FD4"
71        "ECC93880AC293391C69B558AD84E7AAFA88F11D028CF3A378F241D6B056A90C588F6"
72        "66F68D27262B4DA84657D15057D371BCEC1F6504032507D5B881E45FC93A1B973155"
73        "D91C57219D090C3ACD75E7C2B9F1176A208AC03D6C12AC28A271#)\n"
74 "   (x #4186F8A58C5DF46C5BCFC7006BEEBF05E93C0CA7#)\n"
75 "))\n";
76
77 static const char sample_public_dsa_key_1024[] =
78 "(public-key\n"
79 "  (dsa\n"
80 "   (p #00A126202D592214C5A8F6016E2C3F4256052ACB1CB17D88E64B1293FAF08F5E4685"
81        "03E6F68366B326A56284370EB2103E92D8346A163E44A08FDC422AC8E9E44268557A"
82        "853539A6AF39353A59CE5E78FD98B57D0F3E3A7EBC8A256AC9A775BA59689F3004BF"
83        "C3035730C4C0C51626C5D7F5852637EC589BB29DAB46C161572E4B#)\n"
84 "   (q #00DEB5A296421887179ECA1762884DE2AF8185AFC5#)\n"
85 "   (g #3958B34AE7747194ECBD312F8FEE8CBE3918E94DF9FD11E2912E56318F33BDC38622"
86        "B18DDFF393074BCA8BAACF50DF27AEE529F3E8AEECE55C398DAB3A5E04C2EA142312"
87        "FACA2FE7F0A88884F8DAC3979EE67598F9A383B2A2325F035C796F352A5C3CDF2CB3"
88        "85AD24EC52A6E55247E1BB37D260F79E617D2A4446415B6AD79A#)\n"
89 "   (y #519E9FE9AB0545A6724E74603B7B04E48DC1437E0284A11EA605A7BA8AB1CF354FD4"
90        "ECC93880AC293391C69B558AD84E7AAFA88F11D028CF3A378F241D6B056A90C588F6"
91        "66F68D27262B4DA84657D15057D371BCEC1F6504032507D5B881E45FC93A1B973155"
92        "D91C57219D090C3ACD75E7C2B9F1176A208AC03D6C12AC28A271#)\n"
93 "))\n";
94
95
96 static const char sample_private_dsa_key_2048[] =
97 "(private-key\n"
98 "  (dsa\n"
99 "   (p #00B54636673962B64F7DC23C71ACEF6E7331796F607560B194DFCC0CA370E858A365"
100        "A413152FB6EB8C664BD171AC316FE5B381CD084D07377571599880A068EF1382D85C"
101        "308B4E9DEAC12D66DE5C4A826EBEB5ED94A62E7301E18927E890589A2F230272A150"
102        "C118BC3DC2965AE0D05BE4F65C6137B2BA7EDABB192C3070D202C10AA3F534574970"
103        "71454DB8A73DDB6511A5BA98EF1450FD90DE5BAAFC9FD3AC22EBEA612DD075BB7405"
104        "D56866D125E33982C046808F7CEBA8E5C0B9F19A6FE451461660A1CBA9EF68891179"
105        "0256A573D3B8F35A5C7A0C6C31F2DB90E25A26845252AD9E485EF2D339E7B5890CD4"
106        "2F9C9F315ED409171EC35CA04CC06B275577B3#)\n"
107 "   (q #00DA67989167FDAC4AE3DF9247A716859A30C0CF9C5A6DBA01EABA3481#)\n"
108 "   (g #48E35DA584A089D05142AA63603FDB00D131B07A0781E2D5A8F9614D2B33D3E40A78"
109        "98A9E10CDBB612CF093F95A3E10D09566726F2C12823836B2D9CD974BB695665F3B3"
110        "5D219A9724B87F380BD5207EDA0AE38C79E8F18122C3F76E4CEB0ABED3250914987F"
111        "B30D4B9E19C04C28A5D4F45560AF586F6A1B41751EAD90AE7F044F4E2A4A50C1F508"
112        "4FC202463F478F678B9A19392F0D2961C5391C546EF365368BB46410C9C1CEE96E9F"
113        "0C953570C2ED06328B11C90E86E57CAA7FA5ABAA278E22A4C8C08E16EE59F484EC44"
114        "2CF55535BAA2C6BEA8833A555372BEFE1E665D3C7DAEF58061D5136331EF4EB61BC3"
115        "6EE4425A553AF8885FEA15A88135BE133520#)\n"
116 "   (y #66E0D1A69D663466F8FEF2B7C0878DAC93C36A2FB2C05E0306A53B926021D4B92A1C"
117        "2FA6860061E88E78CBBBA49B0E12700F07DBF86F72CEB2927EDAC0C7E3969C3A47BB"
118        "4E0AE93D8BB3313E93CC7A72DFEEE442EFBC81B3B2AEC9D8DCBE21220FB760201D79"
119        "328C41C773866587A44B6954767D022A88072900E964089D9B17133603056C985C4F"
120        "8A0B648F297F8D2C3CB43E4371DC6002B5B12CCC085BDB2CFC5074A0587566187EE3"
121        "E11A2A459BD94726248BB8D6CC62938E11E284C2C183576FBB51749EB238C4360923"
122        "79C08CE1C8CD77EB57404CE9B4744395ACF721487450BADE3220576F2F816248B0A7"
123        "14A264330AECCB24DE2A1107847B23490897#)\n"
124 "   (x #477BD14676E22563C5ABA68025CEBA2A48D485F5B2D4AD4C0EBBD6D0#)\n"
125 "))\n";
126
127
128 static const char sample_public_dsa_key_2048[] =
129 "(public-key\n"
130 "  (dsa\n"
131 "   (p #00B54636673962B64F7DC23C71ACEF6E7331796F607560B194DFCC0CA370E858A365"
132        "A413152FB6EB8C664BD171AC316FE5B381CD084D07377571599880A068EF1382D85C"
133        "308B4E9DEAC12D66DE5C4A826EBEB5ED94A62E7301E18927E890589A2F230272A150"
134        "C118BC3DC2965AE0D05BE4F65C6137B2BA7EDABB192C3070D202C10AA3F534574970"
135        "71454DB8A73DDB6511A5BA98EF1450FD90DE5BAAFC9FD3AC22EBEA612DD075BB7405"
136        "D56866D125E33982C046808F7CEBA8E5C0B9F19A6FE451461660A1CBA9EF68891179"
137        "0256A573D3B8F35A5C7A0C6C31F2DB90E25A26845252AD9E485EF2D339E7B5890CD4"
138        "2F9C9F315ED409171EC35CA04CC06B275577B3#)\n"
139 "   (q #00DA67989167FDAC4AE3DF9247A716859A30C0CF9C5A6DBA01EABA3481#)\n"
140 "   (g #48E35DA584A089D05142AA63603FDB00D131B07A0781E2D5A8F9614D2B33D3E40A78"
141        "98A9E10CDBB612CF093F95A3E10D09566726F2C12823836B2D9CD974BB695665F3B3"
142        "5D219A9724B87F380BD5207EDA0AE38C79E8F18122C3F76E4CEB0ABED3250914987F"
143        "B30D4B9E19C04C28A5D4F45560AF586F6A1B41751EAD90AE7F044F4E2A4A50C1F508"
144        "4FC202463F478F678B9A19392F0D2961C5391C546EF365368BB46410C9C1CEE96E9F"
145        "0C953570C2ED06328B11C90E86E57CAA7FA5ABAA278E22A4C8C08E16EE59F484EC44"
146        "2CF55535BAA2C6BEA8833A555372BEFE1E665D3C7DAEF58061D5136331EF4EB61BC3"
147        "6EE4425A553AF8885FEA15A88135BE133520#)\n"
148 "   (y #66E0D1A69D663466F8FEF2B7C0878DAC93C36A2FB2C05E0306A53B926021D4B92A1C"
149        "2FA6860061E88E78CBBBA49B0E12700F07DBF86F72CEB2927EDAC0C7E3969C3A47BB"
150        "4E0AE93D8BB3313E93CC7A72DFEEE442EFBC81B3B2AEC9D8DCBE21220FB760201D79"
151        "328C41C773866587A44B6954767D022A88072900E964089D9B17133603056C985C4F"
152        "8A0B648F297F8D2C3CB43E4371DC6002B5B12CCC085BDB2CFC5074A0587566187EE3"
153        "E11A2A459BD94726248BB8D6CC62938E11E284C2C183576FBB51749EB238C4360923"
154        "79C08CE1C8CD77EB57404CE9B4744395ACF721487450BADE3220576F2F816248B0A7"
155        "14A264330AECCB24DE2A1107847B23490897#)\n"
156 "))\n";
157
158
159 static const char sample_private_dsa_key_3072[] =
160 "(private-key\n"
161 "  (dsa\n"
162 "   (p #00BA73E148AEA5E8B64878AF5BE712B8302B9671C5F3EEB7722A9D0D9868D048C938"
163        "877C91C335C7819292E69C7D34264F1578E32EC2DA8408DF75D0EB76E0D3030B84B5"
164        "62D8EF93AB53BAB6B8A5DE464F5CA87AEA43BDCF0FB0B7815AA3114CFC84FD916A83"
165        "B3D5FD78390189332232E9D037D215313FD002FF46C048B66703F87FAE092AAA0988"
166        "AC745336EBE672A01DEDBD52395783579B67CF3AE1D6F1602CCCB12154FA0E00AE46"
167        "0D9B289CF709194625BCB919B11038DEFC50ADBBA20C3F320078E4E9529B4F6848E2"
168        "AB5E6278DB961FE226F2EEBD201E071C48C5BEF98B4D9BEE42C1C7102D893EBF8902"
169        "D7A91266340AFD6CE1D09E52282FFF5B97EAFA3886A3FCF84FF76D1E06538D0D8E60"
170        "B3332145785E07D29A5965382DE3470D1D888447FA9C00A2373378FC3FA7B9F7D17E"
171        "95A6A5AE1397BE46D976EF2C96E89913AC4A09351CA661BF6F67E30407DA846946C7"
172        "62D9BAA6B77825097D3E7B886456BB32E3E74516BF3FD93D71B257AA8F723E01CE33"
173        "8015353D3778B02B892AF7#)\n"
174 "   (q #00BFF3F3CC18FA018A5B8155A8695E1E4939660D5E4759322C39D50F3B93E5F68B#)\n"
175 "   (g #6CCFD8219F5FCE8EF2BEF3262929787140847E38674B1EF8DB20255E212CB6330EC4"
176        "DFE8A26AB7ECC5760DEB9BBF59A2B2821D510F1868172222867558B8D204E889C474"
177        "7CA30FBF9D8CF41AE5D5BD845174641101593849FF333E6C93A6550931B2B9D56B98"
178        "9CAB01729D9D736FA6D24A74D2DDE1E9E648D141473E443DD6BBF0B3CAB64F9FE4FC"
179        "134B2EB57437789F75C744DF1FA67FA8A64603E5441BC7ECE29E00BDF262BDC81E8C"
180        "7330A18A412DE38E7546D342B89A0AF675A89E6BEF00540EB107A2FE74EA402B0D89"
181        "F5C02918DEEEAF8B8737AC866B09B50810AB8D8668834A1B9E1E53866E2B0A926FAB"
182        "120A0CDE5B3715FFFE6ACD1AB73588DCC1EC4CE9392FE57F8D1D35811200CB07A0E6"
183        "374E2C4B0AEB7E3D077B8545C0E438DCC0F1AE81E186930E99EBC5B91B77E92803E0"
184        "21602887851A4FFDB3A7896AC655A0901218C121C5CBB0931E7D5EAC243F37711B5F"
185        "D5A62B1B38A83F03D8F6703D8B98DF367FC8A76990335F62173A5391836F0F2413EC"
186        "4997AF9EB55C6660B01A#)\n"
187 "   (y #2320B22434C5DB832B4EC267CC52E78DD5CCFA911E8F0804E7E7F32B186B2D4167AE"
188        "4AA6869822E76400492D6A193B0535322C72B0B7AA4A87E33044FDC84BE24C64A053"
189        "A37655EE9EABDCDC1FDF63F3F1C677CEB41595DF7DEFE9178D85A3D621B4E4775492"
190        "8C0A58D2458D06F9562E4DE2FE6129A64063A99E88E54485B97484A28188C4D33F15"
191        "DDC903B6CEA0135E3E3D27B4EA39319696305CE93D7BA7BE00367DBE3AAF43491E71"
192        "CBF254744A5567F5D70090D6139E0C990239627B3A1C5B20B6F9F6374B8D8D8A8997"
193        "437265BE1E3B4810D4B09254400DE287A0DFFBAEF339E48D422B1D41A37E642BC026"
194        "73314701C8FA9792845C129351A87A945A03E6C895860E51D6FB8B7340A94D1A8A7B"
195        "FA85AC83B4B14E73AB86CB96C236C8BFB0978B61B2367A7FE4F7891070F56C78D5DD"
196        "F5576BFE5BE4F333A4E2664E79528B3294907AADD63F4F2E7AA8147B928D8CD69765"
197        "3DB98C4297CB678046ED55C0DBE60BF7142C594603E4D705DC3D17270F9F086EC561"
198        "2703D518D8D49FF0EBE6#)\n"
199 "   (x #00A9FFFC88E67D6F7B810E291C050BAFEA7FC4A75E8D2F16CFED3416FD77607232#)\n"
200 "))\n";
201
202 static const char sample_public_dsa_key_3072[] =
203 "(public-key\n"
204 "  (dsa\n"
205 "   (p #00BA73E148AEA5E8B64878AF5BE712B8302B9671C5F3EEB7722A9D0D9868D048C938"
206        "877C91C335C7819292E69C7D34264F1578E32EC2DA8408DF75D0EB76E0D3030B84B5"
207        "62D8EF93AB53BAB6B8A5DE464F5CA87AEA43BDCF0FB0B7815AA3114CFC84FD916A83"
208        "B3D5FD78390189332232E9D037D215313FD002FF46C048B66703F87FAE092AAA0988"
209        "AC745336EBE672A01DEDBD52395783579B67CF3AE1D6F1602CCCB12154FA0E00AE46"
210        "0D9B289CF709194625BCB919B11038DEFC50ADBBA20C3F320078E4E9529B4F6848E2"
211        "AB5E6278DB961FE226F2EEBD201E071C48C5BEF98B4D9BEE42C1C7102D893EBF8902"
212        "D7A91266340AFD6CE1D09E52282FFF5B97EAFA3886A3FCF84FF76D1E06538D0D8E60"
213        "B3332145785E07D29A5965382DE3470D1D888447FA9C00A2373378FC3FA7B9F7D17E"
214        "95A6A5AE1397BE46D976EF2C96E89913AC4A09351CA661BF6F67E30407DA846946C7"
215        "62D9BAA6B77825097D3E7B886456BB32E3E74516BF3FD93D71B257AA8F723E01CE33"
216        "8015353D3778B02B892AF7#)\n"
217 "   (q #00BFF3F3CC18FA018A5B8155A8695E1E4939660D5E4759322C39D50F3B93E5F68B#)\n"
218 "   (g #6CCFD8219F5FCE8EF2BEF3262929787140847E38674B1EF8DB20255E212CB6330EC4"
219        "DFE8A26AB7ECC5760DEB9BBF59A2B2821D510F1868172222867558B8D204E889C474"
220        "7CA30FBF9D8CF41AE5D5BD845174641101593849FF333E6C93A6550931B2B9D56B98"
221        "9CAB01729D9D736FA6D24A74D2DDE1E9E648D141473E443DD6BBF0B3CAB64F9FE4FC"
222        "134B2EB57437789F75C744DF1FA67FA8A64603E5441BC7ECE29E00BDF262BDC81E8C"
223        "7330A18A412DE38E7546D342B89A0AF675A89E6BEF00540EB107A2FE74EA402B0D89"
224        "F5C02918DEEEAF8B8737AC866B09B50810AB8D8668834A1B9E1E53866E2B0A926FAB"
225        "120A0CDE5B3715FFFE6ACD1AB73588DCC1EC4CE9392FE57F8D1D35811200CB07A0E6"
226        "374E2C4B0AEB7E3D077B8545C0E438DCC0F1AE81E186930E99EBC5B91B77E92803E0"
227        "21602887851A4FFDB3A7896AC655A0901218C121C5CBB0931E7D5EAC243F37711B5F"
228        "D5A62B1B38A83F03D8F6703D8B98DF367FC8A76990335F62173A5391836F0F2413EC"
229        "4997AF9EB55C6660B01A#)\n"
230 "   (y #2320B22434C5DB832B4EC267CC52E78DD5CCFA911E8F0804E7E7F32B186B2D4167AE"
231        "4AA6869822E76400492D6A193B0535322C72B0B7AA4A87E33044FDC84BE24C64A053"
232        "A37655EE9EABDCDC1FDF63F3F1C677CEB41595DF7DEFE9178D85A3D621B4E4775492"
233        "8C0A58D2458D06F9562E4DE2FE6129A64063A99E88E54485B97484A28188C4D33F15"
234        "DDC903B6CEA0135E3E3D27B4EA39319696305CE93D7BA7BE00367DBE3AAF43491E71"
235        "CBF254744A5567F5D70090D6139E0C990239627B3A1C5B20B6F9F6374B8D8D8A8997"
236        "437265BE1E3B4810D4B09254400DE287A0DFFBAEF339E48D422B1D41A37E642BC026"
237        "73314701C8FA9792845C129351A87A945A03E6C895860E51D6FB8B7340A94D1A8A7B"
238        "FA85AC83B4B14E73AB86CB96C236C8BFB0978B61B2367A7FE4F7891070F56C78D5DD"
239        "F5576BFE5BE4F333A4E2664E79528B3294907AADD63F4F2E7AA8147B928D8CD69765"
240        "3DB98C4297CB678046ED55C0DBE60BF7142C594603E4D705DC3D17270F9F086EC561"
241        "2703D518D8D49FF0EBE6#)\n"
242 "))\n";
243
244
245 #define DIM(v)               (sizeof(v)/sizeof((v)[0]))
246 #define DIMof(type,member)   DIM(((type *)0)->member)
247 #define BUG() do {fprintf ( stderr, "Ooops at %s:%d\n", __FILE__ , __LINE__ );\
248                   exit(2);} while(0)
249
250
251 /* Helper for the start and stop timer. */
252 #ifdef _WIN32
253 struct {
254   FILETIME creation_time, exit_time, kernel_time, user_time;
255 } started_at, stopped_at;
256 #else
257 static clock_t started_at, stopped_at;
258 #endif
259
260 static void
261 die (const char *format, ...)
262 {
263   va_list arg_ptr ;
264
265   va_start( arg_ptr, format ) ;
266   putchar ('\n');
267   fputs ( PGM ": ", stderr);
268   vfprintf (stderr, format, arg_ptr );
269   va_end(arg_ptr);
270   exit (1);
271 }
272
273 static void
274 show_sexp (const char *prefix, gcry_sexp_t a)
275 {
276   char *buf;
277   size_t size;
278
279   fputs (prefix, stderr);
280   size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
281   buf = malloc (size);
282   if (!buf)
283     die ("out of core\n");
284
285   gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
286   fprintf (stderr, "%.*s", (int)size, buf);
287 }
288
289
290 static void
291 start_timer (void)
292 {
293 #ifdef _WIN32
294 #ifdef __MINGW32CE__
295   GetThreadTimes (GetCurrentThread (),
296                    &started_at.creation_time, &started_at.exit_time,
297                    &started_at.kernel_time, &started_at.user_time);
298 #else
299   GetProcessTimes (GetCurrentProcess (),
300                    &started_at.creation_time, &started_at.exit_time,
301                    &started_at.kernel_time, &started_at.user_time);
302 #endif
303   stopped_at = started_at;
304 #else
305   struct tms tmp;
306
307   times (&tmp);
308   started_at = stopped_at = tmp.tms_utime;
309 #endif
310 }
311
312 static void
313 stop_timer (void)
314 {
315 #ifdef _WIN32
316 #ifdef __MINGW32CE__
317   GetThreadTimes (GetCurrentThread (),
318                    &stopped_at.creation_time, &stopped_at.exit_time,
319                    &stopped_at.kernel_time, &stopped_at.user_time);
320 #else
321   GetProcessTimes (GetCurrentProcess (),
322                    &stopped_at.creation_time, &stopped_at.exit_time,
323                    &stopped_at.kernel_time, &stopped_at.user_time);
324 #endif
325 #else
326   struct tms tmp;
327
328   times (&tmp);
329   stopped_at = tmp.tms_utime;
330 #endif
331 }
332
333 static const char *
334 elapsed_time (void)
335 {
336   static char buf[50];
337 #if _WIN32
338   unsigned long long t1, t2, t;
339
340   t1 = (((unsigned long long)started_at.kernel_time.dwHighDateTime << 32)
341         + started_at.kernel_time.dwLowDateTime);
342   t1 += (((unsigned long long)started_at.user_time.dwHighDateTime << 32)
343         + started_at.user_time.dwLowDateTime);
344   t2 = (((unsigned long long)stopped_at.kernel_time.dwHighDateTime << 32)
345         + stopped_at.kernel_time.dwLowDateTime);
346   t2 += (((unsigned long long)stopped_at.user_time.dwHighDateTime << 32)
347         + stopped_at.user_time.dwLowDateTime);
348   t = (t2 - t1)/10000;
349   snprintf (buf, sizeof buf, "%5.0fms", (double)t );
350 #else
351   snprintf (buf, sizeof buf, "%5.0fms",
352             (((double) (stopped_at - started_at))/CLOCKS_PER_SEC)*10000000);
353 #endif
354   return buf;
355 }
356
357
358 static void
359 progress_cb (void *cb_data, const char *what, int printchar,
360              int current, int total)
361 {
362   (void)cb_data;
363
364   fprintf (stderr, PGM ": progress (%s %c %d %d)\n",
365            what, printchar, current, total);
366   fflush (stderr);
367 }
368
369
370 static void
371 random_bench (int very_strong)
372 {
373   char buf[128];
374   int i;
375
376   printf ("%-10s", "random");
377
378   if (!very_strong)
379     {
380       start_timer ();
381       for (i=0; i < 100; i++)
382         gcry_randomize (buf, sizeof buf, GCRY_STRONG_RANDOM);
383       stop_timer ();
384       printf (" %s", elapsed_time ());
385     }
386
387   start_timer ();
388   for (i=0; i < 100; i++)
389     gcry_randomize (buf, 8,
390                     very_strong? GCRY_VERY_STRONG_RANDOM:GCRY_STRONG_RANDOM);
391   stop_timer ();
392   printf (" %s", elapsed_time ());
393
394   putchar ('\n');
395   if (verbose)
396     gcry_control (GCRYCTL_DUMP_RANDOM_STATS);
397 }
398
399
400
401 static void
402 md_bench ( const char *algoname )
403 {
404   int algo;
405   gcry_md_hd_t hd;
406   int i, repcount;
407   char buf[1000];
408   char *largebuf;
409   char digest[512/8];
410   gcry_error_t err = GPG_ERR_NO_ERROR;
411
412   if (!algoname)
413     {
414       for (i=1; i < 400; i++)
415         if (in_fips_mode && i == GCRY_MD_MD5)
416           ; /* Don't use MD5 in fips mode.  */
417         else if ( !gcry_md_test_algo (i) )
418           md_bench (gcry_md_algo_name (i));
419       return;
420     }
421
422   algo = gcry_md_map_name (algoname);
423   if (!algo)
424     {
425       fprintf (stderr, PGM ": invalid hash algorithm `%s'\n", algoname);
426       exit (1);
427     }
428
429   err = gcry_md_open (&hd, algo, 0);
430   if (err)
431     {
432       fprintf (stderr, PGM ": error opening hash algorithm `%s'\n", algoname);
433       exit (1);
434     }
435
436   for (i=0; i < sizeof buf; i++)
437     buf[i] = i;
438
439   printf ("%-12s", gcry_md_algo_name (algo));
440
441   start_timer ();
442   for (repcount=0; repcount < hash_repetitions; repcount++)
443     for (i=0; i < 1000; i++)
444       gcry_md_write (hd, buf, sizeof buf);
445   gcry_md_final (hd);
446   stop_timer ();
447   printf (" %s", elapsed_time ());
448   fflush (stdout);
449
450   gcry_md_reset (hd);
451   start_timer ();
452   for (repcount=0; repcount < hash_repetitions; repcount++)
453     for (i=0; i < 10000; i++)
454       gcry_md_write (hd, buf, sizeof buf/10);
455   gcry_md_final (hd);
456   stop_timer ();
457   printf (" %s", elapsed_time ());
458   fflush (stdout);
459
460   gcry_md_reset (hd);
461   start_timer ();
462   for (repcount=0; repcount < hash_repetitions; repcount++)
463     for (i=0; i < 1000000; i++)
464       gcry_md_write (hd, "", 1);
465   gcry_md_final (hd);
466   stop_timer ();
467   printf (" %s", elapsed_time ());
468   fflush (stdout);
469
470   gcry_md_close (hd);
471
472   /* Now 100 hash operations on 10000 bytes using the fast function.
473      We initialize the buffer so that all memory pages are committed
474      and we have repeatable values.  */
475   if (gcry_md_get_algo_dlen (algo) > sizeof digest)
476     die ("digest buffer too short\n");
477
478   largebuf = malloc (10000);
479   if (!largebuf)
480     die ("out of core\n");
481   for (i=0; i < 10000; i++)
482     largebuf[i] = i;
483   start_timer ();
484   for (repcount=0; repcount < hash_repetitions; repcount++)
485     for (i=0; i < 100; i++)
486       gcry_md_hash_buffer (algo, digest, largebuf, 10000);
487   stop_timer ();
488   printf (" %s", elapsed_time ());
489   free (largebuf);
490
491   putchar ('\n');
492   fflush (stdout);
493 }
494
495 static void
496 cipher_bench ( const char *algoname )
497 {
498   static int header_printed;
499   int algo;
500   gcry_cipher_hd_t hd;
501   int i;
502   int keylen, blklen;
503   char key[128];
504   char *outbuf, *buf;
505   size_t allocated_buflen, buflen;
506   int repetitions;
507   static struct { int mode; const char *name; int blocked; } modes[] = {
508     { GCRY_CIPHER_MODE_ECB, "   ECB/Stream", 1 },
509     { GCRY_CIPHER_MODE_CBC, "      CBC", 1 },
510     { GCRY_CIPHER_MODE_CFB, "      CFB", 0 },
511     { GCRY_CIPHER_MODE_OFB, "      OFB", 0 },
512     { GCRY_CIPHER_MODE_CTR, "      CTR", 0 },
513     { GCRY_CIPHER_MODE_STREAM, "", 0 },
514     {0}
515   };
516   int modeidx;
517   gcry_error_t err = GPG_ERR_NO_ERROR;
518
519
520   if (!algoname)
521     {
522       for (i=1; i < 400; i++)
523         if ( !gcry_cipher_test_algo (i) )
524           cipher_bench (gcry_cipher_algo_name (i));
525       return;
526     }
527
528   if (large_buffers)
529     {
530       allocated_buflen = 1024 * 100;
531       repetitions = 10;
532     }
533   else
534     {
535       allocated_buflen = 1024;
536       repetitions = 1000;
537     }
538   repetitions *= cipher_repetitions;
539
540   buf = gcry_xmalloc (allocated_buflen);
541   outbuf = gcry_xmalloc (allocated_buflen);
542
543   if (!header_printed)
544     {
545       if (cipher_repetitions != 1)
546         printf ("Running each test %d times.\n", cipher_repetitions);
547       printf ("%-12s", "");
548       for (modeidx=0; modes[modeidx].mode; modeidx++)
549         if (*modes[modeidx].name)
550           printf (" %-15s", modes[modeidx].name );
551       putchar ('\n');
552       printf ("%-12s", "");
553       for (modeidx=0; modes[modeidx].mode; modeidx++)
554         if (*modes[modeidx].name)
555           printf (" ---------------" );
556       putchar ('\n');
557       header_printed = 1;
558     }
559
560   algo = gcry_cipher_map_name (algoname);
561   if (!algo)
562     {
563       fprintf (stderr, PGM ": invalid cipher algorithm `%s'\n", algoname);
564       exit (1);
565     }
566
567   keylen = gcry_cipher_get_algo_keylen (algo);
568   if (!keylen)
569     {
570       fprintf (stderr, PGM ": failed to get key length for algorithm `%s'\n",
571                algoname);
572       exit (1);
573     }
574   if ( keylen > sizeof key )
575     {
576         fprintf (stderr, PGM ": algo %d, keylength problem (%d)\n",
577                  algo, keylen );
578         exit (1);
579     }
580   for (i=0; i < keylen; i++)
581     key[i] = i + (clock () & 0xff);
582
583   blklen = gcry_cipher_get_algo_blklen (algo);
584   if (!blklen)
585     {
586       fprintf (stderr, PGM ": failed to get block length for algorithm `%s'\n",
587                algoname);
588       exit (1);
589     }
590
591   printf ("%-12s", gcry_cipher_algo_name (algo));
592   fflush (stdout);
593
594   for (modeidx=0; modes[modeidx].mode; modeidx++)
595     {
596       if ((blklen > 1 && modes[modeidx].mode == GCRY_CIPHER_MODE_STREAM)
597           | (blklen == 1 && modes[modeidx].mode != GCRY_CIPHER_MODE_STREAM))
598         continue;
599
600       for (i=0; i < sizeof buf; i++)
601         buf[i] = i;
602
603       err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0);
604       if (err)
605         {
606           fprintf (stderr, PGM ": error opening cipher `%s'\n", algoname);
607           exit (1);
608         }
609
610       err = gcry_cipher_setkey (hd, key, keylen);
611       if (err)
612       {
613           fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
614                    gpg_strerror (err));
615           gcry_cipher_close (hd);
616           exit (1);
617         }
618
619       buflen = allocated_buflen;
620       if (modes[modeidx].blocked)
621         buflen = (buflen / blklen) * blklen;
622
623       start_timer ();
624       for (i=err=0; !err && i < repetitions; i++)
625         err = gcry_cipher_encrypt ( hd, outbuf, buflen, buf, buflen);
626       stop_timer ();
627
628       printf (" %s", elapsed_time ());
629       fflush (stdout);
630       gcry_cipher_close (hd);
631       if (err)
632         {
633           fprintf (stderr, "gcry_cipher_encrypt failed: %s\n",
634                    gpg_strerror (err) );
635           exit (1);
636         }
637
638       err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0);
639       if (err)
640         {
641           fprintf (stderr, PGM ": error opening cipher `%s'/n", algoname);
642           exit (1);
643         }
644
645       err = gcry_cipher_setkey (hd, key, keylen);
646       if (err)
647         {
648           fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
649                    gpg_strerror (err));
650           gcry_cipher_close (hd);
651           exit (1);
652         }
653
654       start_timer ();
655       for (i=err=0; !err && i < repetitions; i++)
656         err = gcry_cipher_decrypt ( hd, outbuf, buflen,  buf, buflen);
657       stop_timer ();
658       printf (" %s", elapsed_time ());
659       fflush (stdout);
660       gcry_cipher_close (hd);
661       if (err)
662         {
663           fprintf (stderr, "gcry_cipher_decrypt failed: %s\n",
664                    gpg_strerror (err) );
665           exit (1);
666         }
667     }
668
669   putchar ('\n');
670   gcry_free (buf);
671   gcry_free (outbuf);
672 }
673
674
675
676 static void
677 rsa_bench (int iterations, int print_header, int no_blinding)
678 {
679   gpg_error_t err;
680   int p_sizes[] = { 1024, 2048, 3072, 4096 };
681   int testno;
682
683   if (print_header)
684     printf ("Algorithm         generate %4d*sign %4d*verify\n"
685             "------------------------------------------------\n",
686             iterations, iterations );
687   for (testno=0; testno < DIM (p_sizes); testno++)
688     {
689       gcry_sexp_t key_spec, key_pair, pub_key, sec_key;
690       gcry_mpi_t x;
691       gcry_sexp_t data;
692       gcry_sexp_t sig = NULL;
693       int count;
694
695       printf ("RSA %3d bit    ", p_sizes[testno]);
696       fflush (stdout);
697
698       err = gcry_sexp_build (&key_spec, NULL,
699                              gcry_fips_mode_active ()
700                              ? "(genkey (RSA (nbits %d)))"
701                              : "(genkey (RSA (nbits %d)(transient-key)))",
702                              p_sizes[testno]);
703       if (err)
704         die ("creating S-expression failed: %s\n", gcry_strerror (err));
705
706       start_timer ();
707       err = gcry_pk_genkey (&key_pair, key_spec);
708       if (err)
709         die ("creating %d bit RSA key failed: %s\n",
710              p_sizes[testno], gcry_strerror (err));
711
712       pub_key = gcry_sexp_find_token (key_pair, "public-key", 0);
713       if (! pub_key)
714         die ("public part missing in key\n");
715       sec_key = gcry_sexp_find_token (key_pair, "private-key", 0);
716       if (! sec_key)
717         die ("private part missing in key\n");
718       gcry_sexp_release (key_pair);
719       gcry_sexp_release (key_spec);
720
721       stop_timer ();
722       printf ("   %s", elapsed_time ());
723       fflush (stdout);
724
725       x = gcry_mpi_new (p_sizes[testno]);
726       gcry_mpi_randomize (x, p_sizes[testno]-8, GCRY_WEAK_RANDOM);
727       err = gcry_sexp_build (&data, NULL,
728                              "(data (flags raw) (value %m))", x);
729       gcry_mpi_release (x);
730       if (err)
731         die ("converting data failed: %s\n", gcry_strerror (err));
732
733       start_timer ();
734       for (count=0; count < iterations; count++)
735         {
736           gcry_sexp_release (sig);
737           err = gcry_pk_sign (&sig, data, sec_key);
738           if (err)
739             die ("signing failed (%d): %s\n", count, gpg_strerror (err));
740         }
741       stop_timer ();
742       printf ("   %s", elapsed_time ());
743       fflush (stdout);
744
745       start_timer ();
746       for (count=0; count < iterations; count++)
747         {
748           err = gcry_pk_verify (sig, data, pub_key);
749           if (err)
750             {
751               putchar ('\n');
752               show_sexp ("seckey:\n", sec_key);
753               show_sexp ("data:\n", data);
754               show_sexp ("sig:\n", sig);
755               die ("verify failed (%d): %s\n", count, gpg_strerror (err));
756             }
757         }
758       stop_timer ();
759       printf ("     %s", elapsed_time ());
760
761       if (no_blinding)
762         {
763           fflush (stdout);
764           x = gcry_mpi_new (p_sizes[testno]);
765           gcry_mpi_randomize (x, p_sizes[testno]-8, GCRY_WEAK_RANDOM);
766           err = gcry_sexp_build (&data, NULL,
767                                  "(data (flags no-blinding) (value %m))", x);
768           gcry_mpi_release (x);
769           if (err)
770             die ("converting data failed: %s\n", gcry_strerror (err));
771
772           start_timer ();
773           for (count=0; count < iterations; count++)
774             {
775               gcry_sexp_release (sig);
776               err = gcry_pk_sign (&sig, data, sec_key);
777               if (err)
778                 die ("signing failed (%d): %s\n", count, gpg_strerror (err));
779             }
780           stop_timer ();
781           printf ("   %s", elapsed_time ());
782           fflush (stdout);
783         }
784
785       putchar ('\n');
786       fflush (stdout);
787
788       gcry_sexp_release (sig);
789       gcry_sexp_release (data);
790       gcry_sexp_release (sec_key);
791       gcry_sexp_release (pub_key);
792     }
793 }
794
795
796
797 static void
798 dsa_bench (int iterations, int print_header)
799 {
800   gpg_error_t err;
801   gcry_sexp_t pub_key[3], sec_key[3];
802   int p_sizes[3] = { 1024, 2048, 3072 };
803   int q_sizes[3] = { 160, 224, 256 };
804   gcry_sexp_t data;
805   gcry_sexp_t sig;
806   int i, j;
807
808   err = gcry_sexp_sscan (pub_key+0, NULL, sample_public_dsa_key_1024,
809                          strlen (sample_public_dsa_key_1024));
810   if (!err)
811     err = gcry_sexp_sscan (sec_key+0, NULL, sample_private_dsa_key_1024,
812                            strlen (sample_private_dsa_key_1024));
813   if (!err)
814     err = gcry_sexp_sscan (pub_key+1, NULL, sample_public_dsa_key_2048,
815                            strlen (sample_public_dsa_key_2048));
816   if (!err)
817     err = gcry_sexp_sscan (sec_key+1, NULL, sample_private_dsa_key_2048,
818                            strlen (sample_private_dsa_key_2048));
819   if (!err)
820     err = gcry_sexp_sscan (pub_key+2, NULL, sample_public_dsa_key_3072,
821                            strlen (sample_public_dsa_key_3072));
822   if (!err)
823     err = gcry_sexp_sscan (sec_key+2, NULL, sample_private_dsa_key_3072,
824                            strlen (sample_private_dsa_key_3072));
825   if (err)
826     {
827       fprintf (stderr, PGM ": converting sample keys failed: %s\n",
828                gcry_strerror (err));
829       exit (1);
830     }
831
832   if (print_header)
833     printf ("Algorithm         generate %4d*sign %4d*verify\n"
834             "------------------------------------------------\n",
835             iterations, iterations );
836   for (i=0; i < DIM (q_sizes); i++)
837     {
838       gcry_mpi_t x;
839
840       x = gcry_mpi_new (q_sizes[i]);
841       gcry_mpi_randomize (x, q_sizes[i], GCRY_WEAK_RANDOM);
842       err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x);
843       gcry_mpi_release (x);
844       if (err)
845         {
846           fprintf (stderr, PGM ": converting data failed: %s\n",
847                    gcry_strerror (err));
848           exit (1);
849         }
850
851       printf ("DSA %d/%d             -", p_sizes[i], q_sizes[i]);
852       fflush (stdout);
853
854       start_timer ();
855       for (j=0; j < iterations; j++)
856         {
857           err = gcry_pk_sign (&sig, data, sec_key[i]);
858           if (err)
859             {
860               putchar ('\n');
861               fprintf (stderr, PGM ": signing failed: %s\n",
862                        gpg_strerror (err));
863               exit (1);
864             }
865         }
866       stop_timer ();
867       printf ("   %s", elapsed_time ());
868       fflush (stdout);
869
870       start_timer ();
871       for (j=0; j < iterations; j++)
872         {
873           err = gcry_pk_verify (sig, data, pub_key[i]);
874           if (err)
875             {
876               putchar ('\n');
877               fprintf (stderr, PGM ": verify failed: %s\n",
878                        gpg_strerror (err));
879               exit (1);
880             }
881         }
882       stop_timer ();
883       printf ("     %s\n", elapsed_time ());
884       fflush (stdout);
885
886       gcry_sexp_release (sig);
887       gcry_sexp_release (data);
888     }
889
890
891   for (i=0; i < DIM (q_sizes); i++)
892     {
893       gcry_sexp_release (sec_key[i]);
894       gcry_sexp_release (pub_key[i]);
895     }
896 }
897
898
899 static void
900 ecc_bench (int iterations, int print_header)
901 {
902 #if USE_ECC
903   gpg_error_t err;
904   int p_sizes[] = { 192, 224, 256, 384, 521 };
905   int testno;
906
907   if (print_header)
908     printf ("Algorithm         generate %4d*sign %4d*verify\n"
909             "------------------------------------------------\n",
910             iterations, iterations );
911   for (testno=0; testno < DIM (p_sizes); testno++)
912     {
913       gcry_sexp_t key_spec, key_pair, pub_key, sec_key;
914       gcry_mpi_t x;
915       gcry_sexp_t data;
916       gcry_sexp_t sig = NULL;
917       int count;
918
919       printf ("ECDSA %3d bit ", p_sizes[testno]);
920       fflush (stdout);
921
922       err = gcry_sexp_build (&key_spec, NULL,
923                              "(genkey (ECDSA (nbits %d)))", p_sizes[testno]);
924       if (err)
925         die ("creating S-expression failed: %s\n", gcry_strerror (err));
926
927       start_timer ();
928       err = gcry_pk_genkey (&key_pair, key_spec);
929       if (err)
930         die ("creating %d bit ECC key failed: %s\n",
931              p_sizes[testno], gcry_strerror (err));
932
933       pub_key = gcry_sexp_find_token (key_pair, "public-key", 0);
934       if (! pub_key)
935         die ("public part missing in key\n");
936       sec_key = gcry_sexp_find_token (key_pair, "private-key", 0);
937       if (! sec_key)
938         die ("private part missing in key\n");
939       gcry_sexp_release (key_pair);
940       gcry_sexp_release (key_spec);
941
942       stop_timer ();
943       printf ("     %s", elapsed_time ());
944       fflush (stdout);
945
946       x = gcry_mpi_new (p_sizes[testno]);
947       gcry_mpi_randomize (x, p_sizes[testno], GCRY_WEAK_RANDOM);
948       err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x);
949       gcry_mpi_release (x);
950       if (err)
951         die ("converting data failed: %s\n", gcry_strerror (err));
952
953       start_timer ();
954       for (count=0; count < iterations; count++)
955         {
956           gcry_sexp_release (sig);
957           err = gcry_pk_sign (&sig, data, sec_key);
958           if (err)
959             die ("signing failed: %s\n", gpg_strerror (err));
960         }
961       stop_timer ();
962       printf ("   %s", elapsed_time ());
963       fflush (stdout);
964
965       start_timer ();
966       for (count=0; count < iterations; count++)
967         {
968           err = gcry_pk_verify (sig, data, pub_key);
969           if (err)
970             {
971               putchar ('\n');
972               show_sexp ("seckey:\n", sec_key);
973               show_sexp ("data:\n", data);
974               show_sexp ("sig:\n", sig);
975               die ("verify failed: %s\n", gpg_strerror (err));
976             }
977         }
978       stop_timer ();
979       printf ("     %s\n", elapsed_time ());
980       fflush (stdout);
981
982       gcry_sexp_release (sig);
983       gcry_sexp_release (data);
984       gcry_sexp_release (sec_key);
985       gcry_sexp_release (pub_key);
986     }
987 #endif /*USE_ECC*/
988 }
989
990
991
992 static void
993 do_powm ( const char *n_str, const char *e_str, const char *m_str)
994 {
995   gcry_mpi_t e, n, msg, cip;
996   gcry_error_t err;
997   int i;
998
999   err = gcry_mpi_scan (&n, GCRYMPI_FMT_HEX, n_str, 0, 0);
1000   if (err) BUG ();
1001   err = gcry_mpi_scan (&e, GCRYMPI_FMT_HEX, e_str, 0, 0);
1002   if (err) BUG ();
1003   err = gcry_mpi_scan (&msg, GCRYMPI_FMT_HEX, m_str, 0, 0);
1004   if (err) BUG ();
1005
1006   cip = gcry_mpi_new (0);
1007
1008   start_timer ();
1009   for (i=0; i < 1000; i++)
1010     gcry_mpi_powm (cip, msg, e, n);
1011   stop_timer ();
1012   printf (" %s", elapsed_time ()); fflush (stdout);
1013 /*    { */
1014 /*      char *buf; */
1015
1016 /*      if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, (void**)&buf, NULL, cip)) */
1017 /*        BUG (); */
1018 /*      printf ("result: %s\n", buf); */
1019 /*      gcry_free (buf); */
1020 /*    } */
1021   gcry_mpi_release (cip);
1022   gcry_mpi_release (msg);
1023   gcry_mpi_release (n);
1024   gcry_mpi_release (e);
1025 }
1026
1027
1028 static void
1029 mpi_bench (void)
1030 {
1031   printf ("%-10s", "powm"); fflush (stdout);
1032
1033   do_powm (
1034 "20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E4",
1035            "29",
1036 "B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8"
1037            );
1038   do_powm (
1039            "20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA40716",
1040            "29",
1041            "B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8FC4EE4BB446B83E48ABED7DB81CBF5E81DE4759E8D68AC985846D999F96B0D8A80E5C69D272C766AB8A23B40D50A4FA889FBC2BD2624222D8EB297F4BAEF8593847"
1042            );
1043   do_powm (
1044            "20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA4071620A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA40716",
1045            "29",
1046            "B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8FC4EE4BB446B83E48ABED7DB81CBF5E81DE4759E8D68AC985846D999F96B0D8A80E5C69D272C766AB8A23B40D50A4FA889FBC2BD2624222D8EB297F4BAEF8593847B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8FC4EE4BB446B83E48ABED7DB81CBF5E81DE4759E8D68AC985846D999F96B0D8A80E5C69D272C766AB8A23B40D50A4FA889FBC2BD2624222D8EB297F4BAEF8593847"
1047            );
1048
1049   putchar ('\n');
1050
1051
1052 }
1053
1054
1055 int
1056 main( int argc, char **argv )
1057 {
1058   int last_argc = -1;
1059   int no_blinding = 0;
1060   int use_random_daemon = 0;
1061   int with_progress = 0;
1062
1063   if (argc)
1064     { argc--; argv++; }
1065
1066   while (argc && last_argc != argc )
1067     {
1068       last_argc = argc;
1069       if (!strcmp (*argv, "--"))
1070         {
1071           argc--; argv++;
1072           break;
1073         }
1074       else if (!strcmp (*argv, "--help"))
1075         {
1076           fputs ("usage: benchmark "
1077                  "[md|cipher|random|mpi|rsa|dsa|ecc [algonames]]\n",
1078                  stdout);
1079           exit (0);
1080         }
1081       else if (!strcmp (*argv, "--verbose"))
1082         {
1083           verbose++;
1084           argc--; argv++;
1085         }
1086       else if (!strcmp (*argv, "--use-random-daemon"))
1087         {
1088           use_random_daemon = 1;
1089           argc--; argv++;
1090         }
1091       else if (!strcmp (*argv, "--no-blinding"))
1092         {
1093           no_blinding = 1;
1094           argc--; argv++;
1095         }
1096       else if (!strcmp (*argv, "--large-buffers"))
1097         {
1098           large_buffers = 1;
1099           argc--; argv++;
1100         }
1101       else if (!strcmp (*argv, "--cipher-repetitions"))
1102         {
1103           argc--; argv++;
1104           if (argc)
1105             {
1106               cipher_repetitions = atoi(*argv);
1107               argc--; argv++;
1108             }
1109         }
1110       else if (!strcmp (*argv, "--hash-repetitions"))
1111         {
1112           argc--; argv++;
1113           if (argc)
1114             {
1115               hash_repetitions = atoi(*argv);
1116               argc--; argv++;
1117             }
1118         }
1119       else if (!strcmp (*argv, "--fips"))
1120         {
1121           argc--; argv++;
1122           /* This command needs to be called before gcry_check_version.  */
1123           gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
1124         }
1125       else if (!strcmp (*argv, "--progress"))
1126         {
1127           argc--; argv++;
1128           with_progress = 1;
1129         }
1130     }
1131
1132   gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
1133
1134   if (!gcry_check_version (GCRYPT_VERSION))
1135     {
1136       fprintf (stderr, PGM ": version mismatch\n");
1137       exit (1);
1138     }
1139
1140   if (gcry_fips_mode_active ())
1141     in_fips_mode = 1;
1142   else
1143     gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
1144
1145   if (use_random_daemon)
1146     gcry_control (GCRYCTL_USE_RANDOM_DAEMON, 1);
1147
1148   if (with_progress)
1149     gcry_set_progress_handler (progress_cb, NULL);
1150
1151   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
1152
1153   if (cipher_repetitions < 1)
1154     cipher_repetitions = 1;
1155   if (hash_repetitions < 1)
1156     hash_repetitions = 1;
1157
1158   if ( !argc )
1159     {
1160       gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
1161       md_bench (NULL);
1162       putchar ('\n');
1163       cipher_bench (NULL);
1164       putchar ('\n');
1165       rsa_bench (100, 1, no_blinding);
1166       dsa_bench (100, 0);
1167       ecc_bench (100, 0);
1168       putchar ('\n');
1169       mpi_bench ();
1170       putchar ('\n');
1171       random_bench (0);
1172     }
1173   else if ( !strcmp (*argv, "random") || !strcmp (*argv, "strongrandom"))
1174     {
1175       if (argc == 1)
1176         random_bench ((**argv == 's'));
1177       else if (argc == 2)
1178         {
1179           gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, argv[1]);
1180           random_bench ((**argv == 's'));
1181           gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE);
1182         }
1183       else
1184         fputs ("usage: benchmark [strong]random [seedfile]\n", stdout);
1185     }
1186   else if ( !strcmp (*argv, "md"))
1187     {
1188       if (argc == 1)
1189         md_bench (NULL);
1190       else
1191         for (argc--, argv++; argc; argc--, argv++)
1192           md_bench ( *argv );
1193     }
1194   else if ( !strcmp (*argv, "cipher"))
1195     {
1196       if (argc == 1)
1197         cipher_bench (NULL);
1198       else
1199         for (argc--, argv++; argc; argc--, argv++)
1200           cipher_bench ( *argv );
1201     }
1202   else if ( !strcmp (*argv, "mpi"))
1203     {
1204         mpi_bench ();
1205     }
1206   else if ( !strcmp (*argv, "rsa"))
1207     {
1208         gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
1209         rsa_bench (100, 1, no_blinding);
1210     }
1211   else if ( !strcmp (*argv, "dsa"))
1212     {
1213         gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
1214         dsa_bench (100, 1);
1215     }
1216   else if ( !strcmp (*argv, "ecc"))
1217     {
1218         gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
1219         ecc_bench (100, 1);
1220     }
1221   else
1222     {
1223       fprintf (stderr, PGM ": bad arguments\n");
1224       return 1;
1225     }
1226
1227
1228   if (in_fips_mode && !gcry_fips_mode_active ())
1229     fprintf (stderr, PGM ": FIPS mode is not anymore active\n");
1230
1231   return 0;
1232 }