mpi/ec: fix when 'unsigned long' is 32-bit but limb size is 64-bit
[libgcrypt.git] / tests / mpitests.c
1 /* mpitests.c  -  basic mpi tests
2  *      Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
3  * Copyright (C) 2013 g10 Code GmbH
4  *
5  * This file is part of Libgcrypt.
6  *
7  * Libgcrypt is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * Libgcrypt is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdarg.h>
28
29 #ifdef _GCRYPT_IN_LIBGCRYPT
30 # include "../src/gcrypt-int.h"
31 #else
32 # include <gcrypt.h>
33 #endif
34
35 #define PGM "mpitests"
36 #include "t-common.h"
37
38
39 /* Set up some test patterns */
40
41 /* 48 bytes with value 1: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
42 unsigned char ones[] = {
43   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
44   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
45   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
46 };
47
48 /* 48 bytes with value 2: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
49 unsigned char twos[] = {
50   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
51   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
52   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02
53 };
54
55 /* 48 bytes with value 3: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
56 unsigned char threes[] = {
57   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
58   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
59   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
60 };
61
62 /* 48 bytes with value 0x80: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
63 unsigned char eighties[] = {
64   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
65   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
66   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
67 };
68
69 /* 48 bytes with value 0xff: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
70 unsigned char manyff[] = {
71   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
72   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
73   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
74 };
75
76
77 static int
78 test_const_and_immutable (void)
79 {
80   gcry_mpi_t one, second_one;
81
82   one = gcry_mpi_set_ui (NULL, 1);
83   if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE)
84       || gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
85     die ("immutable or const flag initially set\n");
86
87   second_one = gcry_mpi_copy (one);
88   if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
89     die ("immutable flag set after copy\n");
90   if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
91     die ("const flag set after copy\n");
92   gcry_mpi_release (second_one);
93
94   gcry_mpi_set_flag (one, GCRYMPI_FLAG_IMMUTABLE);
95   if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
96     die ("failed to set immutable flag\n");
97   if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
98     die ("const flag unexpectly set\n");
99
100   second_one = gcry_mpi_copy (one);
101   if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
102     die ("immutable flag not cleared after copy\n");
103   if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
104     die ("const flag unexpectly set after copy\n");
105   gcry_mpi_release (second_one);
106
107   gcry_mpi_clear_flag (one, GCRYMPI_FLAG_IMMUTABLE);
108   if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
109     die ("failed to clear immutable flag\n");
110   if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
111     die ("const flag unexpectly set\n");
112
113   gcry_mpi_set_flag (one, GCRYMPI_FLAG_CONST);
114   if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
115     die ("failed to set const flag\n");
116   if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
117     die ("failed to set immutable flag with const flag\n");
118
119   second_one = gcry_mpi_copy (one);
120   if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
121     die ("immutable flag not cleared after copy\n");
122   if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
123     die ("const flag not cleared after copy\n");
124   gcry_mpi_release (second_one);
125
126   gcry_mpi_clear_flag (one, GCRYMPI_FLAG_IMMUTABLE);
127   if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
128     die ("clearing immutable flag not ignored for a constant MPI\n");
129   if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
130     die ("const flag unexpectly cleared\n");
131
132
133   second_one = gcry_mpi_set (NULL, GCRYMPI_CONST_ONE);
134   if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
135     die ("immutable flag not cleared by mpi_set (NULL,x)\n");
136   if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
137     die ("const flag not cleared by mpi_set (NULL,x)\n");
138   gcry_mpi_release (second_one);
139
140   second_one = gcry_mpi_set_ui (NULL, 42);
141   gcry_mpi_set (second_one, GCRYMPI_CONST_ONE);
142   if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
143     die ("immutable flag not cleared after mpi_set (a,x)\n");
144   if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
145     die ("const flag not cleared mpi_set (a,x)\n");
146   gcry_mpi_release (second_one);
147
148
149   /* Due to the the constant flag the release below should be a NOP
150      and will leak memory.  */
151   gcry_mpi_release (one);
152   return 1;
153 }
154
155
156 static void
157 test_opaque (void)
158 {
159   gcry_mpi_t a;
160   char *p;
161   unsigned int nbits;
162
163   p = gcry_xstrdup ("This is a test buffer");
164   a = gcry_mpi_set_opaque (NULL, p, 21*8+1); /* (a non byte aligned length) */
165
166   if (!gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
167     die ("opaque flag not set\n");
168
169   p = gcry_mpi_get_opaque (a, &nbits);
170   if (!p)
171     die ("gcry_mpi_get_opaque returned NULL\n");
172   if (nbits != 21*8+1)
173     die ("gcry_mpi_get_opaque returned a changed bit size\n");
174   if (strcmp (p, "This is a test buffer"))
175     die ("gcry_mpi_get_opaque returned a changed buffer\n");
176
177   if (debug)
178     gcry_log_debugmpi ("mpi", a);
179   gcry_mpi_release (a);
180
181   p = gcry_xstrdup ("This is a test buffer");
182   a = gcry_mpi_set_opaque_copy (NULL, p, 21*8+1);
183   gcry_free (p);
184
185   if (!gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
186     die ("opaque flag not set\n");
187
188   p = gcry_mpi_get_opaque (a, &nbits);
189   if (!p)
190     die ("gcry_mpi_get_opaque returned NULL\n");
191   if (nbits != 21*8+1)
192     die ("gcry_mpi_get_opaque returned a changed bit size\n");
193   if (strcmp (p, "This is a test buffer"))
194     die ("gcry_mpi_get_opaque returned a changed buffer\n");
195
196   if (debug)
197     gcry_log_debugmpi ("mpi", a);
198
199   gcry_mpi_release (a);
200 }
201
202
203 static void
204 test_maxsize (void)
205 {
206   gpg_error_t err;
207   gcry_mpi_t a;
208   unsigned int val;
209   char buffer[2+2048]; /* For PGP: 2 length bytes and 16384 bits.  */
210
211   memset (buffer, 0x55, sizeof buffer);
212
213   /* We use a short buffer but a give a too large length to simulate a
214    * programming error.  In case this test fails (i.e. die() is
215    * called) the scan function may have access data outside of BUFFER
216    * which may result in a segv but we ignore that to avoid actually
217    * allocating such a long buffer.  */
218   err = gcry_mpi_scan (&a, GCRYMPI_FMT_USG, buffer, 16*1024*1024 +1, NULL);
219   if (gpg_err_code (err) != GPG_ERR_INV_OBJ)
220     die ("gcry_mpi_scan does not detect its generic input limit\n");
221
222   /* Now test the PGP limit.  The scan code check the two length bytes
223    * from the buffer and thus it is sufficient to fake them.  */
224   buffer[0] = (16385 >> 8);
225   buffer[1] = (16385 & 0xff);
226   err = gcry_mpi_scan (&a, GCRYMPI_FMT_PGP, buffer, sizeof buffer, NULL);
227   if (gpg_err_code (err) != GPG_ERR_INV_OBJ)
228     die ("gcry_mpi_scan does not detect the PGP input limit\n");
229
230   buffer[0] = (16384 >> 8);
231   buffer[1] = (16384 & 0xff);
232
233   err = gcry_mpi_scan (&a, GCRYMPI_FMT_PGP, buffer, sizeof buffer, NULL);
234   if (err)
235     die ("gcry_mpi_scan did not parse a large PGP: %s\n", gpg_strerror (err));
236
237   /* Let's also test get_ui.  */
238   gcry_mpi_set_ui (a, 0);
239   val = 4711;
240   err = gcry_mpi_get_ui (&val, a);
241   if (err || val != 0)
242     die ("gcry_mpi_get_ui failed at %d: %s\n", __LINE__, gpg_strerror (err));
243
244   gcry_mpi_sub_ui (a, a, 1);
245   val = 4711;
246   err = gcry_mpi_get_ui (&val, a);
247   if (gpg_err_code (err) != GPG_ERR_ERANGE || val != 4711)
248     die ("gcry_mpi_get_ui failed at %d: %s\n", __LINE__, gpg_strerror (err));
249
250   gcry_mpi_set_ui (a, 0xffffffff);
251   val = 4711;
252   err = gcry_mpi_get_ui (&val, a);
253   if (err || val != 0xffffffff)
254     die ("gcry_mpi_get_ui failed at %d: %s\n", __LINE__, gpg_strerror (err));
255
256   if (sizeof (val) == 4)
257     {
258       gcry_mpi_add_ui (a, a, 1);
259       err = gcry_mpi_get_ui (&val, a);
260       if (gpg_err_code (err) != GPG_ERR_ERANGE)
261         die ("gcry_mpi_get_ui failed at %d: %s\n", __LINE__,gpg_strerror (err));
262     }
263
264   gcry_mpi_release (a);
265
266 }
267
268
269 static void
270 test_cmp (void)
271 {
272   gpg_error_t rc;
273   gcry_mpi_t zero, zero2;
274   gcry_mpi_t one;
275   gcry_mpi_t two;
276   gcry_mpi_t all_ones;
277   gcry_mpi_t opa1, opa2;
278   gcry_mpi_t opa1s, opa2s;
279   gcry_mpi_t opa0, opa02;
280
281   zero = gcry_mpi_new (0);
282   zero2= gcry_mpi_set_ui (NULL, 0);
283   one  = gcry_mpi_set_ui (NULL, 1);
284   two  = gcry_mpi_set_ui (NULL, 2);
285   rc = gcry_mpi_scan (&all_ones, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
286   if (rc)
287     die ("scanning number failed at line %d", __LINE__);
288   opa0  = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("a"), 0);
289   opa02 = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("b"), 0);
290   opa1  = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("aaaaaaaaaaaaaaaa"), 16*8);
291   opa1s = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("a"), 1*8);
292   opa2  = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("bbbbbbbbbbbbbbbb"), 16*8);
293   opa2s = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("b"), 1*8);
294
295
296   /* Single limb test with cmp_ui */
297   if (gcry_mpi_cmp_ui (zero, 0))
298     fail ("mpi_cmp_ui failed at line %d", __LINE__);
299   if (!(gcry_mpi_cmp_ui (zero, 1) < 0))
300     fail ("mpi_cmp_ui failed at line %d", __LINE__);
301   if (!(gcry_mpi_cmp_ui (zero, (-1)) < 0))
302     fail ("mpi_cmp_ui failed at line %d", __LINE__);
303
304   if (gcry_mpi_cmp_ui (two, 2))
305     fail ("mpi_cmp_ui failed at line %d", __LINE__);
306   if (!(gcry_mpi_cmp_ui (two, 3) < 0))
307     fail ("mpi_cmp_ui failed at line %d", __LINE__);
308   if (!(gcry_mpi_cmp_ui (two, 1) > 0))
309     fail ("mpi_cmp_ui failed at line %d", __LINE__);
310
311   /* Multi limb tests with cmp_ui.  */
312   if (!(gcry_mpi_cmp_ui (all_ones, 0) > 0))
313     fail ("mpi_cmp_ui failed at line %d", __LINE__);
314   if (!(gcry_mpi_cmp_ui (all_ones, (-1)) > 0))
315     fail ("mpi_cmp_ui failed at line %d", __LINE__);
316
317   /* Single limb test with cmp */
318   if (gcry_mpi_cmp (zero, zero2))
319     fail ("mpi_cmp failed at line %d", __LINE__);
320   if (!(gcry_mpi_cmp (zero, one) < 0))
321     fail ("mpi_cmp failed at line %d", __LINE__);
322   if (!(gcry_mpi_cmp (one, zero) > 0))
323     fail ("mpi_cmp failed at line %d", __LINE__);
324
325   gcry_mpi_neg (one, one);
326   if (!(gcry_mpi_cmp (zero, one) > 0))
327     fail ("mpi_cmp failed at line %d", __LINE__);
328   if (!(gcry_mpi_cmp (one, zero) < 0))
329     fail ("mpi_cmp failed at line %d", __LINE__);
330   if (!(gcry_mpi_cmp (one, two) < 0))
331     fail ("mpi_cmp failed at line %d", __LINE__);
332   gcry_mpi_neg (one, one);
333
334   if (!(gcry_mpi_cmp (one, two) < 0))
335     fail ("mpi_cmp failed at line %d", __LINE__);
336   if (!(gcry_mpi_cmp (two, one) > 0))
337     fail ("mpi_cmp failed at line %d", __LINE__);
338   if (!(gcry_mpi_cmp (one, all_ones) < 0))
339     fail ("mpi_cmp failed at line %d", __LINE__);
340
341   /* Tests with opaque values.  */
342   if (!(gcry_mpi_cmp (opa1, one) < 0))
343     fail ("mpi_cmp failed at line %d", __LINE__);
344   if (!(gcry_mpi_cmp (one, opa1) > 0))
345     fail ("mpi_cmp failed at line %d", __LINE__);
346   if (!(gcry_mpi_cmp (opa0, opa02) == 0))
347     fail ("mpi_cmp failed at line %d", __LINE__);
348   if (!(gcry_mpi_cmp (opa1s, opa1) < 0))
349     fail ("mpi_cmp failed at line %d", __LINE__);
350   if (!(gcry_mpi_cmp (opa2, opa1s) > 0))
351     fail ("mpi_cmp failed at line %d", __LINE__);
352   if (!(gcry_mpi_cmp (opa1, opa2) < 0))
353     fail ("mpi_cmp failed at line %d", __LINE__);
354   if (!(gcry_mpi_cmp (opa2, opa1) > 0))
355     fail ("mpi_cmp failed at line %d", __LINE__);
356   if (!(gcry_mpi_cmp (opa1, opa1) == 0))
357     fail ("mpi_cmp failed at line %d", __LINE__);
358
359
360   gcry_mpi_release(opa2s);
361   gcry_mpi_release(opa2);
362   gcry_mpi_release(opa1s);
363   gcry_mpi_release(opa1);
364   gcry_mpi_release(opa02);
365   gcry_mpi_release(opa0);
366   gcry_mpi_release(all_ones);
367   gcry_mpi_release(two);
368   gcry_mpi_release(one);
369   gcry_mpi_release(zero2);
370   gcry_mpi_release(zero);
371 }
372
373
374 static int
375 test_add (void)
376 {
377   gcry_mpi_t one;
378   gcry_mpi_t two;
379   gcry_mpi_t ff;
380   gcry_mpi_t result;
381   unsigned char* pc;
382
383   gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
384   gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
385   gcry_mpi_scan(&ff, GCRYMPI_FMT_USG, manyff, sizeof(manyff), NULL);
386   result = gcry_mpi_new(0);
387
388   gcry_mpi_add(result, one, two);
389   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
390   if (debug)
391     gcry_log_debug ("Result of one plus two:\n%s\n", pc);
392   gcry_free(pc);
393
394   gcry_mpi_add(result, ff, one);
395   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
396   if (debug)
397     gcry_log_debug ("Result of ff plus one:\n%s\n", pc);
398   gcry_free(pc);
399
400   gcry_mpi_release(one);
401   gcry_mpi_release(two);
402   gcry_mpi_release(ff);
403   gcry_mpi_release(result);
404   return 1;
405 }
406
407
408 static int
409 test_sub (void)
410 {
411   gcry_mpi_t one;
412   gcry_mpi_t two;
413   gcry_mpi_t result;
414   unsigned char* pc;
415
416   gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
417   gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
418   result = gcry_mpi_new(0);
419   gcry_mpi_sub(result, two, one);
420
421   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
422   if (debug)
423     gcry_log_debug ("Result of two minus one:\n%s\n", pc);
424   gcry_free(pc);
425
426   gcry_mpi_release(one);
427   gcry_mpi_release(two);
428   gcry_mpi_release(result);
429   return 1;
430 }
431
432
433 static int
434 test_mul (void)
435 {
436   gcry_mpi_t two;
437   gcry_mpi_t three;
438   gcry_mpi_t result;
439   unsigned char* pc;
440
441   gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
442   gcry_mpi_scan(&three, GCRYMPI_FMT_USG, threes, sizeof(threes), NULL);
443   result = gcry_mpi_new(0);
444   gcry_mpi_mul(result, two, three);
445
446   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
447   if (debug)
448     gcry_log_debug ("Result of two mul three:\n%s\n", pc);
449   gcry_free(pc);
450
451   gcry_mpi_release(two);
452   gcry_mpi_release(three);
453   gcry_mpi_release(result);
454   return 1;
455 }
456
457
458 /* What we test here is that we don't overwrite our args and that
459    using the same mpi for several args works.  */
460 static int
461 test_powm (void)
462 {
463   int b_int = 17;
464   int e_int = 3;
465   int m_int = 19;
466   gcry_mpi_t base = gcry_mpi_set_ui (NULL, b_int);
467   gcry_mpi_t exp = gcry_mpi_set_ui (NULL, e_int);
468   gcry_mpi_t mod = gcry_mpi_set_ui (NULL, m_int);
469   gcry_mpi_t res = gcry_mpi_new (0);
470
471   gcry_mpi_powm (res, base, exp, mod);
472   if (gcry_mpi_cmp_ui (base, b_int))
473     die ("test_powm failed for base at %d\n", __LINE__);
474   if (gcry_mpi_cmp_ui (exp, e_int))
475     die ("test_powm_ui failed for exp at %d\n", __LINE__);
476   if (gcry_mpi_cmp_ui (mod, m_int))
477     die ("test_powm failed for mod at %d\n", __LINE__);
478
479   /* Check using base for the result.  */
480   gcry_mpi_set_ui (base, b_int);
481   gcry_mpi_set_ui (exp, e_int);
482   gcry_mpi_set_ui(mod, m_int);
483   gcry_mpi_powm (base, base, exp, mod);
484   if (gcry_mpi_cmp (res, base))
485     die ("test_powm failed at %d\n", __LINE__);
486   if (gcry_mpi_cmp_ui (exp, e_int))
487     die ("test_powm_ui failed for exp at %d\n", __LINE__);
488   if (gcry_mpi_cmp_ui (mod, m_int))
489     die ("test_powm failed for mod at %d\n", __LINE__);
490
491   /* Check using exp for the result.  */
492   gcry_mpi_set_ui (base, b_int);
493   gcry_mpi_set_ui (exp, e_int);
494   gcry_mpi_set_ui(mod, m_int);
495   gcry_mpi_powm (exp, base, exp, mod);
496   if (gcry_mpi_cmp (res, exp))
497     die ("test_powm failed at %d\n", __LINE__);
498   if (gcry_mpi_cmp_ui (base, b_int))
499     die ("test_powm failed for base at %d\n", __LINE__);
500   if (gcry_mpi_cmp_ui (mod, m_int))
501     die ("test_powm failed for mod at %d\n", __LINE__);
502
503   /* Check using mod for the result.  */
504   gcry_mpi_set_ui (base, b_int);
505   gcry_mpi_set_ui (exp, e_int);
506   gcry_mpi_set_ui(mod, m_int);
507   gcry_mpi_powm (mod, base, exp, mod);
508   if (gcry_mpi_cmp (res, mod))
509     die ("test_powm failed at %d\n", __LINE__);
510   if (gcry_mpi_cmp_ui (base, b_int))
511     die ("test_powm failed for base at %d\n", __LINE__);
512   if (gcry_mpi_cmp_ui (exp, e_int))
513     die ("test_powm_ui failed for exp at %d\n", __LINE__);
514
515   /* Now check base ^ base mod mod.  */
516   gcry_mpi_set_ui (base, b_int);
517   gcry_mpi_set_ui(mod, m_int);
518   gcry_mpi_powm (res, base, base, mod);
519   if (gcry_mpi_cmp_ui (base, b_int))
520     die ("test_powm failed for base at %d\n", __LINE__);
521   if (gcry_mpi_cmp_ui (mod, m_int))
522     die ("test_powm failed for mod at %d\n", __LINE__);
523
524   /* Check base ^ base mod mod with base as result.  */
525   gcry_mpi_set_ui (base, b_int);
526   gcry_mpi_set_ui(mod, m_int);
527   gcry_mpi_powm (base, base, base, mod);
528   if (gcry_mpi_cmp (res, base))
529     die ("test_powm failed at %d\n", __LINE__);
530   if (gcry_mpi_cmp_ui (mod, m_int))
531     die ("test_powm failed for mod at %d\n", __LINE__);
532
533   /* Check base ^ base mod mod with mod as result.  */
534   gcry_mpi_set_ui (base, b_int);
535   gcry_mpi_set_ui(mod, m_int);
536   gcry_mpi_powm (mod, base, base, mod);
537   if (gcry_mpi_cmp (res, mod))
538     die ("test_powm failed at %d\n", __LINE__);
539   if (gcry_mpi_cmp_ui (base, b_int))
540     die ("test_powm failed for base at %d\n", __LINE__);
541
542   /* Now check base ^ base mod base.  */
543   gcry_mpi_set_ui (base, b_int);
544   gcry_mpi_powm (res, base, base, base);
545   if (gcry_mpi_cmp_ui (base, b_int))
546     die ("test_powm failed for base at %d\n", __LINE__);
547
548   /* Check base ^ base mod base with base as result.  */
549   gcry_mpi_set_ui (base, b_int);
550   gcry_mpi_powm (base, base, base, base);
551   if (gcry_mpi_cmp (res, base))
552     die ("test_powm failed at %d\n", __LINE__);
553
554   /* Check for a case: base is negative and expo is even.  */
555   gcry_mpi_set_ui (base, b_int);
556   gcry_mpi_neg (base, base);
557   gcry_mpi_set_ui (exp, e_int * 2);
558   gcry_mpi_set_ui(mod, m_int);
559   gcry_mpi_powm (res, base, exp, mod);
560   /* Result should be positive and it's 7 = (-17)^6 mod 19.  */
561   if (gcry_mpi_is_neg (res) || gcry_mpi_cmp_ui (res, 7))
562     {
563       if (verbose)
564         {
565           fprintf (stderr, "is_neg: %d\n", gcry_mpi_is_neg (res));
566           fprintf (stderr, "mpi: ");
567           gcry_mpi_dump (res);
568           putc ('\n', stderr);
569         }
570       die ("test_powm failed for negative base at %d\n", __LINE__);
571     }
572
573   gcry_mpi_release (base);
574   gcry_mpi_release (exp);
575   gcry_mpi_release (mod);
576   gcry_mpi_release (res);
577   /* Fixme: We should add the rest of the cases of course.  */
578
579
580
581   return 1;
582 }
583
584
585 int
586 main (int argc, char* argv[])
587 {
588   if (argc > 1 && !strcmp (argv[1], "--verbose"))
589     verbose = 1;
590   else if (argc > 1 && !strcmp (argv[1], "--debug"))
591     verbose = debug = 1;
592
593   if (!gcry_check_version (GCRYPT_VERSION))
594     {
595       fputs ("version mismatch\n", stderr);
596       exit (1);
597     }
598   xgcry_control(GCRYCTL_DISABLE_SECMEM);
599
600   test_const_and_immutable ();
601   test_opaque ();
602   test_maxsize ();
603   test_cmp ();
604   test_add ();
605   test_sub ();
606   test_mul ();
607   test_powm ();
608
609   return !!error_count;
610 }