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