d5b0a7ce90cf74b6321596f984bd66089156bf24
[libgcrypt.git] / tests / pubkey.c
1 /* pubkey.c - Public key encryption/decryption tests
2  *      Copyright (C) 2001, 2002, 2003, 2005 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 <stdarg.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28
29 #include "../src/gcrypt.h"
30
31 /* Sample RSA keys, taken from basic.c.  */
32
33 static const char sample_private_key_1[] =
34 "(private-key\n"
35 " (openpgp-rsa\n"
36 "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
37       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
38       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
39       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
40 "  (e #010001#)\n"
41 "  (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
42       "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
43       "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
44       "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
45 "  (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
46       "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
47 "  (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
48       "35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)\n"
49 "  (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
50       "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n"
51 " )\n"
52 ")\n";
53
54 /* The same key as above but without p, q and u to test the non CRT case. */
55 static const char sample_private_key_1_1[] =
56 "(private-key\n"
57 " (openpgp-rsa\n"
58 "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
59       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
60       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
61       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
62 "  (e #010001#)\n"
63 "  (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
64       "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
65       "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
66       "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
67 " )\n"
68 ")\n";
69
70 /* The same key as above but just without q to test the non CRT case.  This
71    should fail. */
72 static const char sample_private_key_1_2[] =
73 "(private-key\n"
74 " (openpgp-rsa\n"
75 "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
76       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
77       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
78       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
79 "  (e #010001#)\n"
80 "  (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
81       "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
82       "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
83       "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
84 "  (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
85       "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
86 "  (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
87       "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n"
88 " )\n"
89 ")\n";
90
91 static const char sample_public_key_1[] =
92 "(public-key\n"
93 " (rsa\n"
94 "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
95       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
96       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
97       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
98 "  (e #010001#)\n"
99 " )\n"
100 ")\n";
101
102
103 static int verbose;
104
105 static void
106 die (const char *format, ...)
107 {
108   va_list arg_ptr ;
109
110   va_start( arg_ptr, format ) ;
111   vfprintf (stderr, format, arg_ptr );
112   va_end(arg_ptr);
113   exit (1);
114 }
115
116 static void
117 show_sexp (const char *prefix, gcry_sexp_t a)
118 {
119   char *buf;
120   size_t size;
121
122   if (prefix)
123     fputs (prefix, stderr);
124   size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
125   buf = gcry_xmalloc (size);
126
127   gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
128   fprintf (stderr, "%.*s", (int)size, buf);
129   gcry_free (buf);
130 }
131
132
133 static void
134 check_keys_crypt (gcry_sexp_t pkey, gcry_sexp_t skey,
135                   gcry_sexp_t plain0, gpg_err_code_t decrypt_fail_code)
136 {
137   gcry_sexp_t plain1, cipher, l;
138   gcry_mpi_t x0, x1;
139   int rc;
140   int have_flags;
141
142   /* Extract data from plaintext.  */
143   l = gcry_sexp_find_token (plain0, "value", 0);
144   x0 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
145
146   /* Encrypt data.  */
147   rc = gcry_pk_encrypt (&cipher, plain0, pkey);
148   if (rc)
149     die ("encryption failed: %s\n", gcry_strerror (rc));
150
151   l = gcry_sexp_find_token (cipher, "flags", 0);
152   have_flags = !!l;
153   gcry_sexp_release (l);
154
155   /* Decrypt data.  */
156   rc = gcry_pk_decrypt (&plain1, cipher, skey);
157   gcry_sexp_release (cipher);
158   if (rc)
159     {
160       if (decrypt_fail_code && gpg_err_code (rc) == decrypt_fail_code)
161         return; /* This is the expected failure code.  */
162       die ("decryption failed: %s\n", gcry_strerror (rc));
163     }
164
165   /* Extract decrypted data.  Note that for compatibility reasons, the
166      output of gcry_pk_decrypt depends on whether a flags lists (even
167      if empty) occurs in its input data.  Because we passed the output
168      of encrypt directly to decrypt, such a flag value won't be there
169      as of today.  We check it anyway. */
170   l = gcry_sexp_find_token (plain1, "value", 0);
171   if (l)
172     {
173       if (!have_flags)
174         die ("compatibility mode of pk_decrypt broken\n");
175       gcry_sexp_release (plain1);
176       x1 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
177       gcry_sexp_release (l);
178     }
179   else
180     {
181       if (have_flags)
182         die ("compatibility mode of pk_decrypt broken\n");
183       x1 = gcry_sexp_nth_mpi (plain1, 0, GCRYMPI_FMT_USG);
184       gcry_sexp_release (plain1);
185     }
186
187   /* Compare.  */
188   if (gcry_mpi_cmp (x0, x1))
189     die ("data corrupted\n");
190 }
191
192 static void
193 check_keys (gcry_sexp_t pkey, gcry_sexp_t skey, unsigned int nbits_data,
194             gpg_err_code_t decrypt_fail_code)
195 {
196   gcry_sexp_t plain;
197   gcry_mpi_t x;
198   int rc;
199   
200   /* Create plain text.  */
201   x = gcry_mpi_new (nbits_data);
202   gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM);
203   
204   rc = gcry_sexp_build (&plain, NULL, "(data (flags raw) (value %m))", x);
205   if (rc)
206     die ("converting data for encryption failed: %s\n",
207          gcry_strerror (rc));
208
209   check_keys_crypt (pkey, skey, plain, decrypt_fail_code);
210   gcry_sexp_release (plain);
211   gcry_mpi_release (x);
212
213   /* Create plain text.  */
214   x = gcry_mpi_new (nbits_data);
215   gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM);
216   
217   rc = gcry_sexp_build (&plain, NULL, 
218                         "(data (flags raw no-blinding) (value %m))", x);
219   if (rc)
220     die ("converting data for encryption failed: %s\n",
221          gcry_strerror (rc));
222
223   check_keys_crypt (pkey, skey, plain, decrypt_fail_code);
224   gcry_sexp_release (plain);
225 }
226
227 static void
228 get_keys_sample (gcry_sexp_t *pkey, gcry_sexp_t *skey, int secret_variant)
229 {
230   gcry_sexp_t pub_key, sec_key;
231   int rc;
232   static const char *secret;
233
234
235   switch (secret_variant)
236     {
237     case 0: secret = sample_private_key_1; break;
238     case 1: secret = sample_private_key_1_1; break;
239     case 2: secret = sample_private_key_1_2; break;
240     default: die ("BUG\n");
241     }
242
243   rc = gcry_sexp_sscan (&pub_key, NULL, sample_public_key_1,
244                         strlen (sample_public_key_1));
245   if (!rc)
246     rc = gcry_sexp_sscan (&sec_key, NULL, secret, strlen (secret));
247   if (rc)
248     die ("converting sample keys failed: %s\n", gcry_strerror (rc));
249
250   *pkey = pub_key;
251   *skey = sec_key;
252 }
253
254 static void
255 get_keys_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
256 {
257   gcry_sexp_t key_spec, key, pub_key, sec_key;
258   int rc;
259   
260   rc = gcry_sexp_new (&key_spec,
261                       "(genkey (rsa (nbits 4:1024)))", 0, 1);
262   if (rc)
263     die ("error creating S-expression: %s\n", gcry_strerror (rc));
264   rc = gcry_pk_genkey (&key, key_spec);
265   gcry_sexp_release (key_spec);
266   if (rc)
267     die ("error generating RSA key: %s\n", gcry_strerror (rc));
268     
269   pub_key = gcry_sexp_find_token (key, "public-key", 0);
270   if (! pub_key)
271     die ("public part missing in key\n");
272
273   sec_key = gcry_sexp_find_token (key, "private-key", 0);
274   if (! sec_key)
275     die ("private part missing in key\n");
276
277   gcry_sexp_release (key);
278   *pkey = pub_key;
279   *skey = sec_key;
280 }
281
282
283 static void
284 get_elg_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int fixed_x)
285 {
286   gcry_sexp_t key_spec, key, pub_key, sec_key;
287   int rc;
288
289   rc = gcry_sexp_new 
290     (&key_spec, 
291      (fixed_x
292       ? "(genkey (elg (nbits 4:1024)(xvalue my.not-so-secret.key)))"
293       : "(genkey (elg (nbits 3:512)))"),
294      0, 1);
295
296   if (rc)
297     die ("error creating S-expression: %s\n", gcry_strerror (rc));
298   rc = gcry_pk_genkey (&key, key_spec);
299   gcry_sexp_release (key_spec);
300   if (rc)
301     die ("error generating Elgamal key: %s\n", gcry_strerror (rc));
302     
303   pub_key = gcry_sexp_find_token (key, "public-key", 0);
304   if (!pub_key)
305     die ("public part missing in key\n");
306
307   sec_key = gcry_sexp_find_token (key, "private-key", 0);
308   if (!sec_key)
309     die ("private part missing in key\n");
310
311   gcry_sexp_release (key);
312   *pkey = pub_key;
313   *skey = sec_key;
314 }
315
316
317 static void
318 check_run (void)
319 {
320   gpg_error_t err;
321   gcry_sexp_t pkey, skey;
322   int variant;
323
324   for (variant=0; variant < 3; variant++)
325     {
326       if (verbose)
327         fprintf (stderr, "Checking sample key (%d).\n", variant);
328       get_keys_sample (&pkey, &skey, variant);
329       /* Check gcry_pk_testkey which requires all elements.  */
330       err = gcry_pk_testkey (skey);
331       if ((variant == 0 && err)
332           || (variant > 0 && gpg_err_code (err) != GPG_ERR_NO_OBJ))
333           die ("gcry_pk_testkey failed: %s\n", gpg_strerror (err));
334       /* Run the usual check but expect an error from variant 2.  */
335       check_keys (pkey, skey, 800, variant == 2? GPG_ERR_NO_OBJ : 0);
336       gcry_sexp_release (pkey);
337       gcry_sexp_release (skey);
338     }
339
340   if (verbose)
341     fprintf (stderr, "Checking generated RSA key.\n");
342   get_keys_new (&pkey, &skey);
343   check_keys (pkey, skey, 800, 0);
344   gcry_sexp_release (pkey);
345   gcry_sexp_release (skey);
346
347   if (verbose)
348     fprintf (stderr, "Checking generated Elgamal key.\n");
349   get_elg_key_new (&pkey, &skey, 0);
350   check_keys (pkey, skey, 400, 0);
351   gcry_sexp_release (pkey);
352   gcry_sexp_release (skey);
353
354   if (verbose)
355     fprintf (stderr, "Checking passphrase generated Elgamal key.\n");
356   get_elg_key_new (&pkey, &skey, 1);
357   check_keys (pkey, skey, 800, 0);
358   gcry_sexp_release (pkey);
359   gcry_sexp_release (skey);
360 }
361
362
363
364 static gcry_mpi_t
365 key_param_from_sexp (gcry_sexp_t sexp, const char *topname, const char *name)
366 {
367   gcry_sexp_t l1, l2;
368   gcry_mpi_t result;
369
370   l1 = gcry_sexp_find_token (sexp, topname, 0);
371   if (!l1)
372     return NULL;
373
374   l2 = gcry_sexp_find_token (l1, name, 0);
375   if (!l2)
376     {
377       gcry_sexp_release (l1);
378       return NULL;
379     }
380   result = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
381   gcry_sexp_release (l2);
382   gcry_sexp_release (l1);
383   return result;
384 }
385
386
387 static void
388 check_x931_derived_key (int what)
389 {
390   static struct {
391     const char *param;
392     const char *expected_d;
393   } testtable[] = {
394     { /* First example from X9.31 (D.1.1).  */
395       "(genkey\n"
396       "  (rsa\n"
397       "    (nbits 4:1024)\n"
398       "    (rsa-use-e 1:3)\n"
399       "    (derive-parms\n"
400       "      (Xp1 #1A1916DDB29B4EB7EB6732E128#)\n"
401       "      (Xp2 #192E8AAC41C576C822D93EA433#)\n"
402       "      (Xp  #D8CD81F035EC57EFE822955149D3BFF70C53520D\n"
403       "            769D6D76646C7A792E16EBD89FE6FC5B605A6493\n"
404       "            39DFC925A86A4C6D150B71B9EEA02D68885F5009\n"
405       "            B98BD984#)\n"
406       "      (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)\n"
407       "      (Xq2 #134E4CAA16D2350A21D775C404#)\n"
408       "      (Xq  #CC1092495D867E64065DEE3E7955F2EBC7D47A2D\n"
409       "            7C9953388F97DDDC3E1CA19C35CA659EDC2FC325\n"
410       "            6D29C2627479C086A699A49C4C9CEE7EF7BD1B34\n"
411       "            321DE34A#))))\n",
412       "1CCDA20BCFFB8D517EE9666866621B11822C7950D55F4BB5BEE37989A7D173"
413       "12E326718BE0D79546EAAE87A56623B919B1715FFBD7F16028FC4007741961"
414       "C88C5D7B4DAAAC8D36A98C9EFBB26C8A4A0E6BC15B358E528A1AC9D0F042BE"
415       "B93BCA16B541B33F80C933A3B769285C462ED5677BFE89DF07BED5C127FD13"
416       "241D3C4B"
417     },
418     
419     { /* Second example from X9.31 (D.2.1).  */
420       "(genkey\n"
421       "  (rsa\n"
422       "    (nbits 4:1536)\n"
423       "    (rsa-use-e 1:3)\n"
424       "    (derive-parms\n"
425       "      (Xp1 #18272558B61316348297EACA74#)\n"
426       "      (Xp2 #1E970E8C6C97CEF91F05B0FA80#)\n"
427       "      (Xp  #F7E943C7EF2169E930DCF23FE389EF7507EE8265\n"
428       "            0D42F4A0D3A3CEFABE367999BB30EE680B2FE064\n"
429       "            60F707F46005F8AA7CBFCDDC4814BBE7F0F8BC09\n"
430       "            318C8E51A48D134296E40D0BBDD282DCCBDDEE1D\n"
431       "            EC86F0B1C96EAFF5CDA70F9AEB6EE31E#)\n"
432       "      (Xq1 #11FDDA6E8128DC1629F75192BA#)\n"
433       "      (Xq2 #18AB178ECA907D72472F65E480#)\n"
434       "      (Xq  #C47560011412D6E13E3E7D007B5C05DBF5FF0D0F\n"
435       "            CFF1FA2070D16C7ABA93EDFB35D8700567E5913D\n"
436       "            B734E3FBD15862EBC59FA0425DFA131E549136E8\n"
437       "            E52397A8ABE4705EC4877D4F82C4AAC651B33DA6\n"
438       "            EA14B9D5F2A263DC65626E4D6CEAC767#))))\n",
439       "1FB56069985F18C4519694FB71055721A01F14422DC901C35B03A64D4A5BD1"
440       "259D573305F5B056AC931B82EDB084E39A0FD1D1A86CC5B147A264F7EF4EB2"
441       "0ED1E7FAAE5CAE4C30D5328B7F74C3CAA72C88B70DED8EDE207B8629DA2383"
442       "B78C3CE1CA3F9F218D78C938B35763AF2A8714664CC57F5CECE2413841F5E9"
443       "EDEC43B728E25A41BF3E1EF8D9EEE163286C9F8BF0F219D3B322C3E4B0389C"
444       "2E8BB28DC04C47DA2BF38823731266D2CF6CC3FC181738157624EF051874D0"
445       "BBCCB9F65C83"
446       /* Note that this example in X9.31 gives this value for D:
447
448         "7ED581A6617C6311465A53EDC4155C86807C5108B724070D6C0E9935296F44"
449         "96755CCC17D6C15AB24C6E0BB6C2138E683F4746A1B316C51E8993DFBD3AC8"
450         "3B479FEAB972B930C354CA2DFDD30F2A9CB222DC37B63B7881EE18A7688E0E"
451         "DE30F38728FE7C8635E324E2CD5D8EBCAA1C51993315FD73B38904E107D7A7"
452         "B7B10EDCA3896906FCF87BE367BB858CA1B27E2FC3C8674ECC8B0F92C0E270"
453         "BA2ECA3701311F68AFCE208DCC499B4B3DB30FF0605CE055D893BC1461D342"
454         "EF32E7D9720B" 
455
456         This is a bug in X9.31, obviously introduced by using
457
458            d = e^{-1} mod (p-1)(q-1)
459           
460          instead of using the universal exponent as required by 4.1.3:
461
462            d = e^{-1} mod lcm(p-1,q-1)
463
464          The examples in X9.31 seem to be pretty buggy, see
465          cipher/primegen.c for another bug.  Not only that I had to
466          spend 100 USD for the 66 pages of the document, it also took
467          me several hours to figure out that the bugs are in the
468          document and not in my code.
469        */
470     },  
471
472     { /* First example from NIST RSAVS (B.1.1).  */
473       "(genkey\n"
474       "  (rsa\n"
475       "    (nbits 4:1024)\n"
476       "    (rsa-use-e 1:3)\n"
477       "    (derive-parms\n"
478       "      (Xp1 #1ed3d6368e101dab9124c92ac8#)\n"
479       "      (Xp2 #16e5457b8844967ce83cab8c11#)\n"
480       "      (Xp  #b79f2c2493b4b76f329903d7555b7f5f06aaa5ea\n"
481       "            ab262da1dcda8194720672a4e02229a0c71f60ae\n"
482       "            c4f0d2ed8d49ef583ca7d5eeea907c10801c302a\n"
483       "            cab44595#)\n"
484       "      (Xq1 #1a5d9e3fa34fb479bedea412f6#)\n"
485       "      (Xq2 #1f9cca85f185341516d92e82fd#)\n"
486       "      (Xq  #c8387fd38fa33ddcea6a9de1b2d55410663502db\n"
487       "            c225655a9310cceac9f4cf1bce653ec916d45788\n"
488       "            f8113c46bc0fa42bf5e8d0c41120c1612e2ea8bb\n"
489       "            2f389eda#))))\n",
490       "17ef7ad4fd96011b62d76dfb2261b4b3270ca8e07bc501be954f8719ef586b"
491       "f237e8f693dd16c23e7adecc40279dc6877c62ab541df5849883a5254fccfd"
492       "4072a657b7f4663953930346febd6bbd82f9a499038402cbf97fd5f068083a"
493       "c81ad0335c4aab0da19cfebe060a1bac7482738efafea078e21df785e56ea0"
494       "dc7e8feb"
495     },
496
497     { /* Second example from NIST RSAVS (B.1.1).  */
498       "(genkey\n"
499       "  (rsa\n"
500       "    (nbits 4:1536)\n"
501       "    (rsa-use-e 1:3)\n"
502       "    (derive-parms\n"
503       "      (Xp1 #1e64c1af460dff8842c22b64d0#)\n"
504       "      (Xp2 #1e948edcedba84039c81f2ac0c#)\n"
505       "      (Xp  #c8c67df894c882045ede26a9008ab09ea0672077\n"
506       "            d7bc71d412511cd93981ddde8f91b967da404056\n"
507       "            c39f105f7f239abdaff92923859920f6299e82b9\n"
508       "            5bd5b8c959948f4a034d81613d6235a3953b49ce\n"
509       "            26974eb7bb1f14843841281b363b9cdb#)\n"
510       "      (Xq1 #1f3df0f017ddd05611a97b6adb#)\n"
511       "      (Xq2 #143edd7b22d828913abf24ca4d#)\n"
512       "      (Xq  #f15147d0e7c04a1e3f37adde802cdc610999bf7a\n"
513       "            b0088434aaeda0c0ab3910b14d2ce56cb66bffd9\n"
514       "            7552195fae8b061077e03920814d8b9cfb5a3958\n"
515       "            b3a82c2a7fc97e55db543948d3396289245336ec\n"
516       "            9e3cb308cc655aebd766340da8921383#))))\n",
517       "1f8b19f3f5f2ac9fc599f110cad403dcd9bdf5f7f00fb2790e78e820398184"
518       "1f3fb3dd230fb223d898f45719d9b2d3525587ff2b8bcc7425e40550a5b536"
519       "1c8e9c1d26e83fbd9c33c64029c0e878b829d55def12912b73d94fd758c461"
520       "0f473e230c41b5e4c86e27c5a5029d82c811c88525d0269b95bd2ff272994a"
521       "dbd80f2c2ecf69065feb8abd8b445b9c6d306b1585d7d3d7576d49842bc7e2"
522       "8b4a2f88f4a47e71c3edd35fdf83f547ea5c2b532975c551ed5268f748b2c4"
523       "2ccf8a84835b"
524     }
525   };
526   gpg_error_t err;
527   gcry_sexp_t key_spec, key, pub_key, sec_key;
528   gcry_mpi_t d_expected, d_have;
529
530   if (what < 0 && what >= sizeof testtable)
531     die ("invalid WHAT value\n");
532
533   err = gcry_sexp_new (&key_spec, testtable[what].param, 0, 1);
534   if (err)
535     die ("error creating S-expression [%d]: %s\n", what, gpg_strerror (err));
536
537   err = gcry_pk_genkey (&key, key_spec);
538   gcry_sexp_release (key_spec);
539   if (err)
540     die ("error generating RSA key [%d]: %s\n", what, gpg_strerror (err));
541     
542   pub_key = gcry_sexp_find_token (key, "public-key", 0);
543   if (!pub_key)
544     die ("public part missing in key [%d]\n", what);
545
546   sec_key = gcry_sexp_find_token (key, "private-key", 0);
547   if (!sec_key)
548     die ("private part missing in key [%d]\n", what);
549
550   err = gcry_mpi_scan 
551     (&d_expected, GCRYMPI_FMT_HEX, testtable[what].expected_d, 0, NULL);
552   if (err)
553     die ("error converting string [%d]\n", what);
554
555   if (verbose)
556     show_sexp ("generated private key:\n", sec_key);
557   d_have = key_param_from_sexp (sec_key, "rsa", "d");
558   if (!d_have)
559     die ("parameter d not found in RSA secret key [%d]\n", what);
560   if (gcry_mpi_cmp (d_expected, d_have))
561     {
562       show_sexp (NULL, sec_key);
563       die ("parameter d does match expected value [%d]\n", what); 
564     }
565   gcry_mpi_release (d_expected);
566   gcry_mpi_release (d_have);
567
568   gcry_sexp_release (key);
569   gcry_sexp_release (pub_key);
570   gcry_sexp_release (sec_key);
571 }
572
573
574
575
576 int
577 main (int argc, char **argv)
578 {
579   int debug = 0;
580   int i;
581
582   if (argc > 1 && !strcmp (argv[1], "--verbose"))
583     verbose = 1;
584   else if (argc > 1 && !strcmp (argv[1], "--debug"))
585     verbose = debug = 1;
586
587   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
588   if (!gcry_check_version (GCRYPT_VERSION))
589     die ("version mismatch\n");
590   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
591   if (debug)
592     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
593   /* No valuable keys are create, so we can speed up our RNG. */
594   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
595
596   for (i=0; i < 2; i++)
597     check_run ();
598
599   for (i=0; i < 4; i++) 
600     check_x931_derived_key (i);
601   
602   return 0;
603 }