Make gpg-error replacement defines more robust.
[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 int
154 test_add (void)
155 {
156   gcry_mpi_t one;
157   gcry_mpi_t two;
158   gcry_mpi_t ff;
159   gcry_mpi_t result;
160   unsigned char* pc;
161
162   gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
163   gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
164   gcry_mpi_scan(&ff, GCRYMPI_FMT_USG, manyff, sizeof(manyff), NULL);
165   result = gcry_mpi_new(0);
166
167   gcry_mpi_add(result, one, two);
168   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
169   if (verbose)
170     printf("Result of one plus two:\n%s\n", pc);
171   gcry_free(pc);
172
173   gcry_mpi_add(result, ff, one);
174   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
175   if (verbose)
176     printf("Result of ff plus one:\n%s\n", pc);
177   gcry_free(pc);
178
179   gcry_mpi_release(one);
180   gcry_mpi_release(two);
181   gcry_mpi_release(ff);
182   gcry_mpi_release(result);
183   return 1;
184 }
185
186
187 static int
188 test_sub (void)
189 {
190   gcry_mpi_t one;
191   gcry_mpi_t two;
192   gcry_mpi_t result;
193   unsigned char* pc;
194
195   gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
196   gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
197   result = gcry_mpi_new(0);
198   gcry_mpi_sub(result, two, one);
199
200   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
201   if (verbose)
202     printf("Result of two minus one:\n%s\n", pc);
203   gcry_free(pc);
204
205   gcry_mpi_release(one);
206   gcry_mpi_release(two);
207   gcry_mpi_release(result);
208   return 1;
209 }
210
211
212 static int
213 test_mul (void)
214 {
215   gcry_mpi_t two;
216   gcry_mpi_t three;
217   gcry_mpi_t result;
218   unsigned char* pc;
219
220   gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
221   gcry_mpi_scan(&three, GCRYMPI_FMT_USG, threes, sizeof(threes), NULL);
222   result = gcry_mpi_new(0);
223   gcry_mpi_mul(result, two, three);
224
225   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
226   if (verbose)
227     printf("Result of two mul three:\n%s\n", pc);
228   gcry_free(pc);
229
230   gcry_mpi_release(two);
231   gcry_mpi_release(three);
232   gcry_mpi_release(result);
233   return 1;
234 }
235
236
237 /* What we test here is that we don't overwrite our args and that
238    using thne same mpi for several args works.  */
239 static int
240 test_powm (void)
241 {
242   int b_int = 17;
243   int e_int = 3;
244   int m_int = 19;
245   gcry_mpi_t base = gcry_mpi_set_ui (NULL, b_int);
246   gcry_mpi_t exp = gcry_mpi_set_ui (NULL, e_int);
247   gcry_mpi_t mod = gcry_mpi_set_ui (NULL, m_int);
248   gcry_mpi_t res = gcry_mpi_new (0);
249
250   gcry_mpi_powm (res, base, exp, mod);
251   if (gcry_mpi_cmp_ui (base, b_int))
252     die ("test_powm failed for base at %d\n", __LINE__);
253   if (gcry_mpi_cmp_ui (exp, e_int))
254     die ("test_powm_ui failed for exp at %d\n", __LINE__);
255   if (gcry_mpi_cmp_ui (mod, m_int))
256     die ("test_powm failed for mod at %d\n", __LINE__);
257
258   /* Check using base for the result.  */
259   gcry_mpi_set_ui (base, b_int);
260   gcry_mpi_set_ui (exp, e_int);
261   gcry_mpi_set_ui(mod, m_int);
262   gcry_mpi_powm (base, base, exp, mod);
263   if (gcry_mpi_cmp (res, base))
264     die ("test_powm failed at %d\n", __LINE__);
265   if (gcry_mpi_cmp_ui (exp, e_int))
266     die ("test_powm_ui failed for exp at %d\n", __LINE__);
267   if (gcry_mpi_cmp_ui (mod, m_int))
268     die ("test_powm failed for mod at %d\n", __LINE__);
269
270   /* Check using exp for the result.  */
271   gcry_mpi_set_ui (base, b_int);
272   gcry_mpi_set_ui (exp, e_int);
273   gcry_mpi_set_ui(mod, m_int);
274   gcry_mpi_powm (exp, base, exp, mod);
275   if (gcry_mpi_cmp (res, exp))
276     die ("test_powm failed at %d\n", __LINE__);
277   if (gcry_mpi_cmp_ui (base, b_int))
278     die ("test_powm failed for base at %d\n", __LINE__);
279   if (gcry_mpi_cmp_ui (mod, m_int))
280     die ("test_powm failed for mod at %d\n", __LINE__);
281
282   /* Check using mod for the result.  */
283   gcry_mpi_set_ui (base, b_int);
284   gcry_mpi_set_ui (exp, e_int);
285   gcry_mpi_set_ui(mod, m_int);
286   gcry_mpi_powm (mod, base, exp, mod);
287   if (gcry_mpi_cmp (res, mod))
288     die ("test_powm failed at %d\n", __LINE__);
289   if (gcry_mpi_cmp_ui (base, b_int))
290     die ("test_powm failed for base at %d\n", __LINE__);
291   if (gcry_mpi_cmp_ui (exp, e_int))
292     die ("test_powm_ui failed for exp at %d\n", __LINE__);
293
294   /* Now check base ^ base mod mod.  */
295   gcry_mpi_set_ui (base, b_int);
296   gcry_mpi_set_ui(mod, m_int);
297   gcry_mpi_powm (res, base, base, mod);
298   if (gcry_mpi_cmp_ui (base, b_int))
299     die ("test_powm failed for base at %d\n", __LINE__);
300   if (gcry_mpi_cmp_ui (mod, m_int))
301     die ("test_powm failed for mod at %d\n", __LINE__);
302
303   /* Check base ^ base mod mod with base as result.  */
304   gcry_mpi_set_ui (base, b_int);
305   gcry_mpi_set_ui(mod, m_int);
306   gcry_mpi_powm (base, base, base, mod);
307   if (gcry_mpi_cmp (res, base))
308     die ("test_powm failed at %d\n", __LINE__);
309   if (gcry_mpi_cmp_ui (mod, m_int))
310     die ("test_powm failed for mod at %d\n", __LINE__);
311
312   /* Check base ^ base mod mod with mod as result.  */
313   gcry_mpi_set_ui (base, b_int);
314   gcry_mpi_set_ui(mod, m_int);
315   gcry_mpi_powm (mod, base, base, mod);
316   if (gcry_mpi_cmp (res, mod))
317     die ("test_powm failed at %d\n", __LINE__);
318   if (gcry_mpi_cmp_ui (base, b_int))
319     die ("test_powm failed for base at %d\n", __LINE__);
320
321   /* Now check base ^ base mod base.  */
322   gcry_mpi_set_ui (base, b_int);
323   gcry_mpi_powm (res, base, base, base);
324   if (gcry_mpi_cmp_ui (base, b_int))
325     die ("test_powm failed for base at %d\n", __LINE__);
326
327   /* Check base ^ base mod base with base as result.  */
328   gcry_mpi_set_ui (base, b_int);
329   gcry_mpi_powm (base, base, base, base);
330   if (gcry_mpi_cmp (res, base))
331     die ("test_powm failed at %d\n", __LINE__);
332
333   /* Fixme: We should add the rest of the cases of course.  */
334
335
336
337   return 1;
338 }
339
340
341 int
342 main (int argc, char* argv[])
343 {
344   if (argc > 1 && !strcmp (argv[1], "--verbose"))
345     verbose = 1;
346   else if (argc > 1 && !strcmp (argv[1], "--debug"))
347     verbose = debug = 1;
348
349   if (!gcry_check_version (GCRYPT_VERSION))
350     {
351       fputs ("version mismatch\n", stderr);
352       exit (1);
353     }
354   gcry_control(GCRYCTL_DISABLE_SECMEM);
355
356   test_const_and_immutable ();
357   test_add ();
358   test_sub ();
359   test_mul ();
360   test_powm ();
361
362   return 0;
363 }