Allow gcry_mpi_dump to print opaque MPIs.
[libgcrypt.git] / tests / mpitests.c
1 /* mpitests.c  -  basic mpi tests
2  *      Copyright (C) 2001, 2002, 2003, 2006 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, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19  * USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <stdarg.h>
29
30 #ifdef _GCRYPT_IN_LIBGCRYPT
31 # include "../src/gcrypt-int.h"
32 #else
33 # include <gcrypt.h>
34 #endif
35
36 static int verbose;
37 static int debug;
38
39
40 static void
41 die (const char *format, ...)
42 {
43   va_list arg_ptr;
44
45   va_start (arg_ptr, format);
46   vfprintf (stderr, format, arg_ptr);
47   va_end (arg_ptr);
48   exit (1);
49 }
50
51
52
53 /* Set up some test patterns */
54
55 /* 48 bytes with value 1: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
56 unsigned char ones[] = {
57   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
58   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
59   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
60 };
61
62 /* 48 bytes with value 2: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
63 unsigned char twos[] = {
64   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
65   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
66   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02
67 };
68
69 /* 48 bytes with value 3: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
70 unsigned char threes[] = {
71   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
72   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
73   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
74 };
75
76 /* 48 bytes with value 0x80: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
77 unsigned char eighties[] = {
78   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
79   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
80   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
81 };
82
83 /* 48 bytes with value 0xff: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
84 unsigned char manyff[] = {
85   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
86   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
87   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
88 };
89
90
91 static int
92 test_const_and_immutable (void)
93 {
94   gcry_mpi_t one, second_one;
95
96   one = gcry_mpi_set_ui (NULL, 1);
97   if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE)
98       || gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
99     die ("immutable or const flag initially set\n");
100
101   second_one = gcry_mpi_copy (one);
102   if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
103     die ("immutable flag set after copy\n");
104   if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
105     die ("const flag set after copy\n");
106   gcry_mpi_release (second_one);
107
108   gcry_mpi_set_flag (one, GCRYMPI_FLAG_IMMUTABLE);
109   if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
110     die ("failed to set immutable flag\n");
111   if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
112     die ("const flag unexpectly set\n");
113
114   second_one = gcry_mpi_copy (one);
115   if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
116     die ("immutable flag not cleared after copy\n");
117   if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
118     die ("const flag unexpectly set after copy\n");
119   gcry_mpi_release (second_one);
120
121   gcry_mpi_clear_flag (one, GCRYMPI_FLAG_IMMUTABLE);
122   if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
123     die ("failed to clear immutable flag\n");
124   if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
125     die ("const flag unexpectly set\n");
126
127   gcry_mpi_set_flag (one, GCRYMPI_FLAG_CONST);
128   if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
129     die ("failed to set const flag\n");
130   if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
131     die ("failed to set immutable flag with const flag\n");
132
133   second_one = gcry_mpi_copy (one);
134   if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
135     die ("immutable flag not cleared after copy\n");
136   if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
137     die ("const flag not cleared after copy\n");
138   gcry_mpi_release (second_one);
139
140   gcry_mpi_clear_flag (one, GCRYMPI_FLAG_IMMUTABLE);
141   if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
142     die ("clearing immutable flag not ignored for a constant MPI\n");
143   if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
144     die ("const flag unexpectly cleared\n");
145
146   /* Due to the the constant flag the release below should be a NOP
147      and will leak memory.  */
148   gcry_mpi_release (one);
149   return 1;
150 }
151
152
153 static void
154 test_opaque (void)
155 {
156   gcry_mpi_t a;
157   char *p;
158   unsigned int nbits;
159
160   p = gcry_xstrdup ("This is a test buffer");
161   a = gcry_mpi_set_opaque (NULL, p, 21*8+1); /* (a non byte aligned length) */
162
163   if (!gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
164     die ("opaque flag not set\n");
165
166   p = gcry_mpi_get_opaque (a, &nbits);
167   if (!p)
168     die ("gcry_mpi_get_opaque returned NULL\n");
169   if (nbits != 21*8+1)
170     die ("gcry_mpi_get_opaque returned a changed bit size\n");
171   if (strcmp (p, "This is a test buffer"))
172     die ("gcry_mpi_get_opaque returned a changed buffer\n");
173
174   if (verbose)
175     {
176       fprintf (stderr, "mpi: ");
177       gcry_mpi_dump (a);
178       putc ('\n', stderr);
179     }
180
181   gcry_mpi_release (a);
182 }
183
184
185 static int
186 test_add (void)
187 {
188   gcry_mpi_t one;
189   gcry_mpi_t two;
190   gcry_mpi_t ff;
191   gcry_mpi_t result;
192   unsigned char* pc;
193
194   gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
195   gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
196   gcry_mpi_scan(&ff, GCRYMPI_FMT_USG, manyff, sizeof(manyff), NULL);
197   result = gcry_mpi_new(0);
198
199   gcry_mpi_add(result, one, two);
200   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
201   if (verbose)
202     printf("Result of one plus two:\n%s\n", pc);
203   gcry_free(pc);
204
205   gcry_mpi_add(result, ff, one);
206   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
207   if (verbose)
208     printf("Result of ff plus one:\n%s\n", pc);
209   gcry_free(pc);
210
211   gcry_mpi_release(one);
212   gcry_mpi_release(two);
213   gcry_mpi_release(ff);
214   gcry_mpi_release(result);
215   return 1;
216 }
217
218
219 static int
220 test_sub (void)
221 {
222   gcry_mpi_t one;
223   gcry_mpi_t two;
224   gcry_mpi_t result;
225   unsigned char* pc;
226
227   gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
228   gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
229   result = gcry_mpi_new(0);
230   gcry_mpi_sub(result, two, one);
231
232   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
233   if (verbose)
234     printf("Result of two minus one:\n%s\n", pc);
235   gcry_free(pc);
236
237   gcry_mpi_release(one);
238   gcry_mpi_release(two);
239   gcry_mpi_release(result);
240   return 1;
241 }
242
243
244 static int
245 test_mul (void)
246 {
247   gcry_mpi_t two;
248   gcry_mpi_t three;
249   gcry_mpi_t result;
250   unsigned char* pc;
251
252   gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
253   gcry_mpi_scan(&three, GCRYMPI_FMT_USG, threes, sizeof(threes), NULL);
254   result = gcry_mpi_new(0);
255   gcry_mpi_mul(result, two, three);
256
257   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
258   if (verbose)
259     printf("Result of two mul three:\n%s\n", pc);
260   gcry_free(pc);
261
262   gcry_mpi_release(two);
263   gcry_mpi_release(three);
264   gcry_mpi_release(result);
265   return 1;
266 }
267
268
269 /* What we test here is that we don't overwrite our args and that
270    using thne same mpi for several args works.  */
271 static int
272 test_powm (void)
273 {
274   int b_int = 17;
275   int e_int = 3;
276   int m_int = 19;
277   gcry_mpi_t base = gcry_mpi_set_ui (NULL, b_int);
278   gcry_mpi_t exp = gcry_mpi_set_ui (NULL, e_int);
279   gcry_mpi_t mod = gcry_mpi_set_ui (NULL, m_int);
280   gcry_mpi_t res = gcry_mpi_new (0);
281
282   gcry_mpi_powm (res, base, exp, mod);
283   if (gcry_mpi_cmp_ui (base, b_int))
284     die ("test_powm failed for base at %d\n", __LINE__);
285   if (gcry_mpi_cmp_ui (exp, e_int))
286     die ("test_powm_ui failed for exp at %d\n", __LINE__);
287   if (gcry_mpi_cmp_ui (mod, m_int))
288     die ("test_powm failed for mod at %d\n", __LINE__);
289
290   /* Check using base for the result.  */
291   gcry_mpi_set_ui (base, b_int);
292   gcry_mpi_set_ui (exp, e_int);
293   gcry_mpi_set_ui(mod, m_int);
294   gcry_mpi_powm (base, base, exp, mod);
295   if (gcry_mpi_cmp (res, base))
296     die ("test_powm failed at %d\n", __LINE__);
297   if (gcry_mpi_cmp_ui (exp, e_int))
298     die ("test_powm_ui failed for exp at %d\n", __LINE__);
299   if (gcry_mpi_cmp_ui (mod, m_int))
300     die ("test_powm failed for mod at %d\n", __LINE__);
301
302   /* Check using exp for the result.  */
303   gcry_mpi_set_ui (base, b_int);
304   gcry_mpi_set_ui (exp, e_int);
305   gcry_mpi_set_ui(mod, m_int);
306   gcry_mpi_powm (exp, base, exp, mod);
307   if (gcry_mpi_cmp (res, exp))
308     die ("test_powm failed at %d\n", __LINE__);
309   if (gcry_mpi_cmp_ui (base, b_int))
310     die ("test_powm failed for base at %d\n", __LINE__);
311   if (gcry_mpi_cmp_ui (mod, m_int))
312     die ("test_powm failed for mod at %d\n", __LINE__);
313
314   /* Check using mod for the result.  */
315   gcry_mpi_set_ui (base, b_int);
316   gcry_mpi_set_ui (exp, e_int);
317   gcry_mpi_set_ui(mod, m_int);
318   gcry_mpi_powm (mod, base, exp, mod);
319   if (gcry_mpi_cmp (res, mod))
320     die ("test_powm failed at %d\n", __LINE__);
321   if (gcry_mpi_cmp_ui (base, b_int))
322     die ("test_powm failed for base at %d\n", __LINE__);
323   if (gcry_mpi_cmp_ui (exp, e_int))
324     die ("test_powm_ui failed for exp at %d\n", __LINE__);
325
326   /* Now check base ^ base mod mod.  */
327   gcry_mpi_set_ui (base, b_int);
328   gcry_mpi_set_ui(mod, m_int);
329   gcry_mpi_powm (res, base, base, mod);
330   if (gcry_mpi_cmp_ui (base, b_int))
331     die ("test_powm failed for base at %d\n", __LINE__);
332   if (gcry_mpi_cmp_ui (mod, m_int))
333     die ("test_powm failed for mod at %d\n", __LINE__);
334
335   /* Check base ^ base mod mod with base as result.  */
336   gcry_mpi_set_ui (base, b_int);
337   gcry_mpi_set_ui(mod, m_int);
338   gcry_mpi_powm (base, base, base, mod);
339   if (gcry_mpi_cmp (res, base))
340     die ("test_powm failed at %d\n", __LINE__);
341   if (gcry_mpi_cmp_ui (mod, m_int))
342     die ("test_powm failed for mod at %d\n", __LINE__);
343
344   /* Check base ^ base mod mod with mod as result.  */
345   gcry_mpi_set_ui (base, b_int);
346   gcry_mpi_set_ui(mod, m_int);
347   gcry_mpi_powm (mod, base, base, mod);
348   if (gcry_mpi_cmp (res, mod))
349     die ("test_powm failed at %d\n", __LINE__);
350   if (gcry_mpi_cmp_ui (base, b_int))
351     die ("test_powm failed for base at %d\n", __LINE__);
352
353   /* Now check base ^ base mod base.  */
354   gcry_mpi_set_ui (base, b_int);
355   gcry_mpi_powm (res, base, base, base);
356   if (gcry_mpi_cmp_ui (base, b_int))
357     die ("test_powm failed for base at %d\n", __LINE__);
358
359   /* Check base ^ base mod base with base as result.  */
360   gcry_mpi_set_ui (base, b_int);
361   gcry_mpi_powm (base, base, base, base);
362   if (gcry_mpi_cmp (res, base))
363     die ("test_powm failed at %d\n", __LINE__);
364
365   /* Fixme: We should add the rest of the cases of course.  */
366
367
368
369   return 1;
370 }
371
372
373 int
374 main (int argc, char* argv[])
375 {
376   if (argc > 1 && !strcmp (argv[1], "--verbose"))
377     verbose = 1;
378   else if (argc > 1 && !strcmp (argv[1], "--debug"))
379     verbose = debug = 1;
380
381   if (!gcry_check_version (GCRYPT_VERSION))
382     {
383       fputs ("version mismatch\n", stderr);
384       exit (1);
385     }
386   gcry_control(GCRYCTL_DISABLE_SECMEM);
387
388   test_const_and_immutable ();
389   test_opaque ();
390   test_add ();
391   test_sub ();
392   test_mul ();
393   test_powm ();
394
395   return 0;
396 }