e1c51d166f2f891a18104f455dfb60aacc37b8c3
[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
147   second_one = gcry_mpi_set (NULL, GCRYMPI_CONST_ONE);
148   if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
149     die ("immutable flag not cleared by mpi_set (NULL,x)\n");
150   if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
151     die ("const flag not cleared by mpi_set (NULL,x)\n");
152   gcry_mpi_release (second_one);
153
154   second_one = gcry_mpi_set_ui (NULL, 42);
155   gcry_mpi_set (second_one, GCRYMPI_CONST_ONE);
156   if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
157     die ("immutable flag not cleared after mpi_set (a,x)\n");
158   if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
159     die ("const flag not cleared mpi_set (a,x)\n");
160   gcry_mpi_release (second_one);
161
162
163   /* Due to the the constant flag the release below should be a NOP
164      and will leak memory.  */
165   gcry_mpi_release (one);
166   return 1;
167 }
168
169
170 static void
171 test_opaque (void)
172 {
173   gcry_mpi_t a;
174   char *p;
175   unsigned int nbits;
176
177   p = gcry_xstrdup ("This is a test buffer");
178   a = gcry_mpi_set_opaque (NULL, p, 21*8+1); /* (a non byte aligned length) */
179
180   if (!gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
181     die ("opaque flag not set\n");
182
183   p = gcry_mpi_get_opaque (a, &nbits);
184   if (!p)
185     die ("gcry_mpi_get_opaque returned NULL\n");
186   if (nbits != 21*8+1)
187     die ("gcry_mpi_get_opaque returned a changed bit size\n");
188   if (strcmp (p, "This is a test buffer"))
189     die ("gcry_mpi_get_opaque returned a changed buffer\n");
190
191   if (verbose)
192     {
193       fprintf (stderr, "mpi: ");
194       gcry_mpi_dump (a);
195       putc ('\n', stderr);
196     }
197
198   gcry_mpi_release (a);
199 }
200
201
202 static int
203 test_add (void)
204 {
205   gcry_mpi_t one;
206   gcry_mpi_t two;
207   gcry_mpi_t ff;
208   gcry_mpi_t result;
209   unsigned char* pc;
210
211   gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
212   gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
213   gcry_mpi_scan(&ff, GCRYMPI_FMT_USG, manyff, sizeof(manyff), NULL);
214   result = gcry_mpi_new(0);
215
216   gcry_mpi_add(result, one, two);
217   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
218   if (verbose)
219     printf("Result of one plus two:\n%s\n", pc);
220   gcry_free(pc);
221
222   gcry_mpi_add(result, ff, one);
223   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
224   if (verbose)
225     printf("Result of ff plus one:\n%s\n", pc);
226   gcry_free(pc);
227
228   gcry_mpi_release(one);
229   gcry_mpi_release(two);
230   gcry_mpi_release(ff);
231   gcry_mpi_release(result);
232   return 1;
233 }
234
235
236 static int
237 test_sub (void)
238 {
239   gcry_mpi_t one;
240   gcry_mpi_t two;
241   gcry_mpi_t result;
242   unsigned char* pc;
243
244   gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
245   gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
246   result = gcry_mpi_new(0);
247   gcry_mpi_sub(result, two, one);
248
249   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
250   if (verbose)
251     printf("Result of two minus one:\n%s\n", pc);
252   gcry_free(pc);
253
254   gcry_mpi_release(one);
255   gcry_mpi_release(two);
256   gcry_mpi_release(result);
257   return 1;
258 }
259
260
261 static int
262 test_mul (void)
263 {
264   gcry_mpi_t two;
265   gcry_mpi_t three;
266   gcry_mpi_t result;
267   unsigned char* pc;
268
269   gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
270   gcry_mpi_scan(&three, GCRYMPI_FMT_USG, threes, sizeof(threes), NULL);
271   result = gcry_mpi_new(0);
272   gcry_mpi_mul(result, two, three);
273
274   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
275   if (verbose)
276     printf("Result of two mul three:\n%s\n", pc);
277   gcry_free(pc);
278
279   gcry_mpi_release(two);
280   gcry_mpi_release(three);
281   gcry_mpi_release(result);
282   return 1;
283 }
284
285
286 /* What we test here is that we don't overwrite our args and that
287    using thne same mpi for several args works.  */
288 static int
289 test_powm (void)
290 {
291   int b_int = 17;
292   int e_int = 3;
293   int m_int = 19;
294   gcry_mpi_t base = gcry_mpi_set_ui (NULL, b_int);
295   gcry_mpi_t exp = gcry_mpi_set_ui (NULL, e_int);
296   gcry_mpi_t mod = gcry_mpi_set_ui (NULL, m_int);
297   gcry_mpi_t res = gcry_mpi_new (0);
298
299   gcry_mpi_powm (res, base, exp, mod);
300   if (gcry_mpi_cmp_ui (base, b_int))
301     die ("test_powm failed for base at %d\n", __LINE__);
302   if (gcry_mpi_cmp_ui (exp, e_int))
303     die ("test_powm_ui failed for exp at %d\n", __LINE__);
304   if (gcry_mpi_cmp_ui (mod, m_int))
305     die ("test_powm failed for mod at %d\n", __LINE__);
306
307   /* Check using base for the result.  */
308   gcry_mpi_set_ui (base, b_int);
309   gcry_mpi_set_ui (exp, e_int);
310   gcry_mpi_set_ui(mod, m_int);
311   gcry_mpi_powm (base, base, exp, mod);
312   if (gcry_mpi_cmp (res, base))
313     die ("test_powm failed at %d\n", __LINE__);
314   if (gcry_mpi_cmp_ui (exp, e_int))
315     die ("test_powm_ui failed for exp at %d\n", __LINE__);
316   if (gcry_mpi_cmp_ui (mod, m_int))
317     die ("test_powm failed for mod at %d\n", __LINE__);
318
319   /* Check using exp for the result.  */
320   gcry_mpi_set_ui (base, b_int);
321   gcry_mpi_set_ui (exp, e_int);
322   gcry_mpi_set_ui(mod, m_int);
323   gcry_mpi_powm (exp, base, exp, mod);
324   if (gcry_mpi_cmp (res, exp))
325     die ("test_powm failed at %d\n", __LINE__);
326   if (gcry_mpi_cmp_ui (base, b_int))
327     die ("test_powm failed for base at %d\n", __LINE__);
328   if (gcry_mpi_cmp_ui (mod, m_int))
329     die ("test_powm failed for mod at %d\n", __LINE__);
330
331   /* Check using mod for the result.  */
332   gcry_mpi_set_ui (base, b_int);
333   gcry_mpi_set_ui (exp, e_int);
334   gcry_mpi_set_ui(mod, m_int);
335   gcry_mpi_powm (mod, base, exp, mod);
336   if (gcry_mpi_cmp (res, mod))
337     die ("test_powm failed at %d\n", __LINE__);
338   if (gcry_mpi_cmp_ui (base, b_int))
339     die ("test_powm failed for base at %d\n", __LINE__);
340   if (gcry_mpi_cmp_ui (exp, e_int))
341     die ("test_powm_ui failed for exp at %d\n", __LINE__);
342
343   /* Now check base ^ base mod mod.  */
344   gcry_mpi_set_ui (base, b_int);
345   gcry_mpi_set_ui(mod, m_int);
346   gcry_mpi_powm (res, base, base, mod);
347   if (gcry_mpi_cmp_ui (base, b_int))
348     die ("test_powm failed for base at %d\n", __LINE__);
349   if (gcry_mpi_cmp_ui (mod, m_int))
350     die ("test_powm failed for mod at %d\n", __LINE__);
351
352   /* Check base ^ base mod mod with base as result.  */
353   gcry_mpi_set_ui (base, b_int);
354   gcry_mpi_set_ui(mod, m_int);
355   gcry_mpi_powm (base, base, base, mod);
356   if (gcry_mpi_cmp (res, base))
357     die ("test_powm failed at %d\n", __LINE__);
358   if (gcry_mpi_cmp_ui (mod, m_int))
359     die ("test_powm failed for mod at %d\n", __LINE__);
360
361   /* Check base ^ base mod mod with mod as result.  */
362   gcry_mpi_set_ui (base, b_int);
363   gcry_mpi_set_ui(mod, m_int);
364   gcry_mpi_powm (mod, base, base, mod);
365   if (gcry_mpi_cmp (res, mod))
366     die ("test_powm failed at %d\n", __LINE__);
367   if (gcry_mpi_cmp_ui (base, b_int))
368     die ("test_powm failed for base at %d\n", __LINE__);
369
370   /* Now check base ^ base mod base.  */
371   gcry_mpi_set_ui (base, b_int);
372   gcry_mpi_powm (res, base, base, base);
373   if (gcry_mpi_cmp_ui (base, b_int))
374     die ("test_powm failed for base at %d\n", __LINE__);
375
376   /* Check base ^ base mod base with base as result.  */
377   gcry_mpi_set_ui (base, b_int);
378   gcry_mpi_powm (base, base, base, base);
379   if (gcry_mpi_cmp (res, base))
380     die ("test_powm failed at %d\n", __LINE__);
381
382   gcry_mpi_release (base);
383   gcry_mpi_release (exp);
384   gcry_mpi_release (mod);
385   gcry_mpi_release (res);
386   /* Fixme: We should add the rest of the cases of course.  */
387
388
389
390   return 1;
391 }
392
393
394 int
395 main (int argc, char* argv[])
396 {
397   if (argc > 1 && !strcmp (argv[1], "--verbose"))
398     verbose = 1;
399   else if (argc > 1 && !strcmp (argv[1], "--debug"))
400     verbose = debug = 1;
401
402   if (!gcry_check_version (GCRYPT_VERSION))
403     {
404       fputs ("version mismatch\n", stderr);
405       exit (1);
406     }
407   gcry_control(GCRYCTL_DISABLE_SECMEM);
408
409   test_const_and_immutable ();
410   test_opaque ();
411   test_add ();
412   test_sub ();
413   test_mul ();
414   test_powm ();
415
416   return 0;
417 }