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