Add 2-way path for SSSE3 version of ChaCha20
[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   char buffer[2+2048]; /* For PGP: 2 length bytes and 16384 bits.  */
209
210   memset (buffer, 0x55, sizeof buffer);
211
212   /* We use a short buffer but a give a too large length to simulate a
213    * programming error.  In case this test fails (i.e. die() is
214    * called) the scan function may have access data outside of BUFFER
215    * which may result in a segv but we ignore that to avoid actually
216    * allocating such a long buffer.  */
217   err = gcry_mpi_scan (&a, GCRYMPI_FMT_USG, buffer, 16*1024*1024 +1, NULL);
218   if (gpg_err_code (err) != GPG_ERR_INV_OBJ)
219     die ("gcry_mpi_scan does not detect its generic input limit\n");
220
221   /* Now test the PGP limit.  The scan code check the two length bytes
222    * from the buffer and thus it is sufficient to fake them.  */
223   buffer[0] = (16385 >> 8);
224   buffer[1] = (16385 & 0xff);
225   err = gcry_mpi_scan (&a, GCRYMPI_FMT_PGP, buffer, sizeof buffer, NULL);
226   if (gpg_err_code (err) != GPG_ERR_INV_OBJ)
227     die ("gcry_mpi_scan does not detect the PGP input limit\n");
228
229   buffer[0] = (16384 >> 8);
230   buffer[1] = (16384 & 0xff);
231
232   err = gcry_mpi_scan (&a, GCRYMPI_FMT_PGP, buffer, sizeof buffer, NULL);
233   if (err)
234     die ("gcry_mpi_scan did not parse a large PGP: %s\n", gpg_strerror (err));
235   gcry_mpi_release (a);
236 }
237
238
239 static void
240 test_cmp (void)
241 {
242   gpg_error_t rc;
243   gcry_mpi_t zero, zero2;
244   gcry_mpi_t one;
245   gcry_mpi_t two;
246   gcry_mpi_t all_ones;
247   gcry_mpi_t opa1, opa2;
248   gcry_mpi_t opa1s, opa2s;
249   gcry_mpi_t opa0, opa02;
250
251   zero = gcry_mpi_new (0);
252   zero2= gcry_mpi_set_ui (NULL, 0);
253   one  = gcry_mpi_set_ui (NULL, 1);
254   two  = gcry_mpi_set_ui (NULL, 2);
255   rc = gcry_mpi_scan (&all_ones, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
256   if (rc)
257     die ("scanning number failed at line %d", __LINE__);
258   opa0  = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("a"), 0);
259   opa02 = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("b"), 0);
260   opa1  = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("aaaaaaaaaaaaaaaa"), 16*8);
261   opa1s = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("a"), 1*8);
262   opa2  = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("bbbbbbbbbbbbbbbb"), 16*8);
263   opa2s = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("b"), 1*8);
264
265
266   /* Single limb test with cmp_ui */
267   if (gcry_mpi_cmp_ui (zero, 0))
268     fail ("mpi_cmp_ui failed at line %d", __LINE__);
269   if (!(gcry_mpi_cmp_ui (zero, 1) < 0))
270     fail ("mpi_cmp_ui failed at line %d", __LINE__);
271   if (!(gcry_mpi_cmp_ui (zero, (-1)) < 0))
272     fail ("mpi_cmp_ui failed at line %d", __LINE__);
273
274   if (gcry_mpi_cmp_ui (two, 2))
275     fail ("mpi_cmp_ui failed at line %d", __LINE__);
276   if (!(gcry_mpi_cmp_ui (two, 3) < 0))
277     fail ("mpi_cmp_ui failed at line %d", __LINE__);
278   if (!(gcry_mpi_cmp_ui (two, 1) > 0))
279     fail ("mpi_cmp_ui failed at line %d", __LINE__);
280
281   /* Multi limb tests with cmp_ui.  */
282   if (!(gcry_mpi_cmp_ui (all_ones, 0) > 0))
283     fail ("mpi_cmp_ui failed at line %d", __LINE__);
284   if (!(gcry_mpi_cmp_ui (all_ones, (-1)) > 0))
285     fail ("mpi_cmp_ui failed at line %d", __LINE__);
286
287   /* Single limb test with cmp */
288   if (gcry_mpi_cmp (zero, zero2))
289     fail ("mpi_cmp failed at line %d", __LINE__);
290   if (!(gcry_mpi_cmp (zero, one) < 0))
291     fail ("mpi_cmp failed at line %d", __LINE__);
292   if (!(gcry_mpi_cmp (one, zero) > 0))
293     fail ("mpi_cmp failed at line %d", __LINE__);
294
295   gcry_mpi_neg (one, one);
296   if (!(gcry_mpi_cmp (zero, one) > 0))
297     fail ("mpi_cmp failed at line %d", __LINE__);
298   if (!(gcry_mpi_cmp (one, zero) < 0))
299     fail ("mpi_cmp failed at line %d", __LINE__);
300   if (!(gcry_mpi_cmp (one, two) < 0))
301     fail ("mpi_cmp failed at line %d", __LINE__);
302   gcry_mpi_neg (one, one);
303
304   if (!(gcry_mpi_cmp (one, two) < 0))
305     fail ("mpi_cmp failed at line %d", __LINE__);
306   if (!(gcry_mpi_cmp (two, one) > 0))
307     fail ("mpi_cmp failed at line %d", __LINE__);
308   if (!(gcry_mpi_cmp (one, all_ones) < 0))
309     fail ("mpi_cmp failed at line %d", __LINE__);
310
311   /* Tests with opaque values.  */
312   if (!(gcry_mpi_cmp (opa1, one) < 0))
313     fail ("mpi_cmp failed at line %d", __LINE__);
314   if (!(gcry_mpi_cmp (one, opa1) > 0))
315     fail ("mpi_cmp failed at line %d", __LINE__);
316   if (!(gcry_mpi_cmp (opa0, opa02) == 0))
317     fail ("mpi_cmp failed at line %d", __LINE__);
318   if (!(gcry_mpi_cmp (opa1s, opa1) < 0))
319     fail ("mpi_cmp failed at line %d", __LINE__);
320   if (!(gcry_mpi_cmp (opa2, opa1s) > 0))
321     fail ("mpi_cmp failed at line %d", __LINE__);
322   if (!(gcry_mpi_cmp (opa1, opa2) < 0))
323     fail ("mpi_cmp failed at line %d", __LINE__);
324   if (!(gcry_mpi_cmp (opa2, opa1) > 0))
325     fail ("mpi_cmp failed at line %d", __LINE__);
326   if (!(gcry_mpi_cmp (opa1, opa1) == 0))
327     fail ("mpi_cmp failed at line %d", __LINE__);
328
329
330   gcry_mpi_release(opa2s);
331   gcry_mpi_release(opa2);
332   gcry_mpi_release(opa1s);
333   gcry_mpi_release(opa1);
334   gcry_mpi_release(opa02);
335   gcry_mpi_release(opa0);
336   gcry_mpi_release(all_ones);
337   gcry_mpi_release(two);
338   gcry_mpi_release(one);
339   gcry_mpi_release(zero2);
340   gcry_mpi_release(zero);
341 }
342
343
344 static int
345 test_add (void)
346 {
347   gcry_mpi_t one;
348   gcry_mpi_t two;
349   gcry_mpi_t ff;
350   gcry_mpi_t result;
351   unsigned char* pc;
352
353   gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
354   gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
355   gcry_mpi_scan(&ff, GCRYMPI_FMT_USG, manyff, sizeof(manyff), NULL);
356   result = gcry_mpi_new(0);
357
358   gcry_mpi_add(result, one, two);
359   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
360   if (debug)
361     gcry_log_debug ("Result of one plus two:\n%s\n", pc);
362   gcry_free(pc);
363
364   gcry_mpi_add(result, ff, one);
365   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
366   if (debug)
367     gcry_log_debug ("Result of ff plus one:\n%s\n", pc);
368   gcry_free(pc);
369
370   gcry_mpi_release(one);
371   gcry_mpi_release(two);
372   gcry_mpi_release(ff);
373   gcry_mpi_release(result);
374   return 1;
375 }
376
377
378 static int
379 test_sub (void)
380 {
381   gcry_mpi_t one;
382   gcry_mpi_t two;
383   gcry_mpi_t result;
384   unsigned char* pc;
385
386   gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
387   gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
388   result = gcry_mpi_new(0);
389   gcry_mpi_sub(result, two, one);
390
391   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
392   if (debug)
393     gcry_log_debug ("Result of two minus one:\n%s\n", pc);
394   gcry_free(pc);
395
396   gcry_mpi_release(one);
397   gcry_mpi_release(two);
398   gcry_mpi_release(result);
399   return 1;
400 }
401
402
403 static int
404 test_mul (void)
405 {
406   gcry_mpi_t two;
407   gcry_mpi_t three;
408   gcry_mpi_t result;
409   unsigned char* pc;
410
411   gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
412   gcry_mpi_scan(&three, GCRYMPI_FMT_USG, threes, sizeof(threes), NULL);
413   result = gcry_mpi_new(0);
414   gcry_mpi_mul(result, two, three);
415
416   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
417   if (debug)
418     gcry_log_debug ("Result of two mul three:\n%s\n", pc);
419   gcry_free(pc);
420
421   gcry_mpi_release(two);
422   gcry_mpi_release(three);
423   gcry_mpi_release(result);
424   return 1;
425 }
426
427
428 /* What we test here is that we don't overwrite our args and that
429    using the same mpi for several args works.  */
430 static int
431 test_powm (void)
432 {
433   int b_int = 17;
434   int e_int = 3;
435   int m_int = 19;
436   gcry_mpi_t base = gcry_mpi_set_ui (NULL, b_int);
437   gcry_mpi_t exp = gcry_mpi_set_ui (NULL, e_int);
438   gcry_mpi_t mod = gcry_mpi_set_ui (NULL, m_int);
439   gcry_mpi_t res = gcry_mpi_new (0);
440
441   gcry_mpi_powm (res, base, exp, mod);
442   if (gcry_mpi_cmp_ui (base, b_int))
443     die ("test_powm failed for base at %d\n", __LINE__);
444   if (gcry_mpi_cmp_ui (exp, e_int))
445     die ("test_powm_ui failed for exp at %d\n", __LINE__);
446   if (gcry_mpi_cmp_ui (mod, m_int))
447     die ("test_powm failed for mod at %d\n", __LINE__);
448
449   /* Check using base for the result.  */
450   gcry_mpi_set_ui (base, b_int);
451   gcry_mpi_set_ui (exp, e_int);
452   gcry_mpi_set_ui(mod, m_int);
453   gcry_mpi_powm (base, base, exp, mod);
454   if (gcry_mpi_cmp (res, base))
455     die ("test_powm failed at %d\n", __LINE__);
456   if (gcry_mpi_cmp_ui (exp, e_int))
457     die ("test_powm_ui failed for exp at %d\n", __LINE__);
458   if (gcry_mpi_cmp_ui (mod, m_int))
459     die ("test_powm failed for mod at %d\n", __LINE__);
460
461   /* Check using exp for the result.  */
462   gcry_mpi_set_ui (base, b_int);
463   gcry_mpi_set_ui (exp, e_int);
464   gcry_mpi_set_ui(mod, m_int);
465   gcry_mpi_powm (exp, base, exp, mod);
466   if (gcry_mpi_cmp (res, exp))
467     die ("test_powm failed at %d\n", __LINE__);
468   if (gcry_mpi_cmp_ui (base, b_int))
469     die ("test_powm failed for base at %d\n", __LINE__);
470   if (gcry_mpi_cmp_ui (mod, m_int))
471     die ("test_powm failed for mod at %d\n", __LINE__);
472
473   /* Check using mod for the result.  */
474   gcry_mpi_set_ui (base, b_int);
475   gcry_mpi_set_ui (exp, e_int);
476   gcry_mpi_set_ui(mod, m_int);
477   gcry_mpi_powm (mod, base, exp, mod);
478   if (gcry_mpi_cmp (res, mod))
479     die ("test_powm failed at %d\n", __LINE__);
480   if (gcry_mpi_cmp_ui (base, b_int))
481     die ("test_powm failed for base at %d\n", __LINE__);
482   if (gcry_mpi_cmp_ui (exp, e_int))
483     die ("test_powm_ui failed for exp at %d\n", __LINE__);
484
485   /* Now check base ^ base mod mod.  */
486   gcry_mpi_set_ui (base, b_int);
487   gcry_mpi_set_ui(mod, m_int);
488   gcry_mpi_powm (res, base, base, mod);
489   if (gcry_mpi_cmp_ui (base, b_int))
490     die ("test_powm failed for base at %d\n", __LINE__);
491   if (gcry_mpi_cmp_ui (mod, m_int))
492     die ("test_powm failed for mod at %d\n", __LINE__);
493
494   /* Check base ^ base mod mod with base as result.  */
495   gcry_mpi_set_ui (base, b_int);
496   gcry_mpi_set_ui(mod, m_int);
497   gcry_mpi_powm (base, base, base, mod);
498   if (gcry_mpi_cmp (res, base))
499     die ("test_powm failed 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 base ^ base mod mod with mod as result.  */
504   gcry_mpi_set_ui (base, b_int);
505   gcry_mpi_set_ui(mod, m_int);
506   gcry_mpi_powm (mod, base, base, mod);
507   if (gcry_mpi_cmp (res, mod))
508     die ("test_powm failed at %d\n", __LINE__);
509   if (gcry_mpi_cmp_ui (base, b_int))
510     die ("test_powm failed for base at %d\n", __LINE__);
511
512   /* Now check base ^ base mod base.  */
513   gcry_mpi_set_ui (base, b_int);
514   gcry_mpi_powm (res, base, base, base);
515   if (gcry_mpi_cmp_ui (base, b_int))
516     die ("test_powm failed for base at %d\n", __LINE__);
517
518   /* Check base ^ base mod base with base as result.  */
519   gcry_mpi_set_ui (base, b_int);
520   gcry_mpi_powm (base, base, base, base);
521   if (gcry_mpi_cmp (res, base))
522     die ("test_powm failed at %d\n", __LINE__);
523
524   /* Check for a case: base is negative and expo is even.  */
525   gcry_mpi_set_ui (base, b_int);
526   gcry_mpi_neg (base, base);
527   gcry_mpi_set_ui (exp, e_int * 2);
528   gcry_mpi_set_ui(mod, m_int);
529   gcry_mpi_powm (res, base, exp, mod);
530   /* Result should be positive and it's 7 = (-17)^6 mod 19.  */
531   if (gcry_mpi_is_neg (res) || gcry_mpi_cmp_ui (res, 7))
532     {
533       if (verbose)
534         {
535           fprintf (stderr, "is_neg: %d\n", gcry_mpi_is_neg (res));
536           fprintf (stderr, "mpi: ");
537           gcry_mpi_dump (res);
538           putc ('\n', stderr);
539         }
540       die ("test_powm failed for negative base at %d\n", __LINE__);
541     }
542
543   gcry_mpi_release (base);
544   gcry_mpi_release (exp);
545   gcry_mpi_release (mod);
546   gcry_mpi_release (res);
547   /* Fixme: We should add the rest of the cases of course.  */
548
549
550
551   return 1;
552 }
553
554
555 int
556 main (int argc, char* argv[])
557 {
558   if (argc > 1 && !strcmp (argv[1], "--verbose"))
559     verbose = 1;
560   else if (argc > 1 && !strcmp (argv[1], "--debug"))
561     verbose = debug = 1;
562
563   if (!gcry_check_version (GCRYPT_VERSION))
564     {
565       fputs ("version mismatch\n", stderr);
566       exit (1);
567     }
568   xgcry_control(GCRYCTL_DISABLE_SECMEM);
569
570   test_const_and_immutable ();
571   test_opaque ();
572   test_maxsize ();
573   test_cmp ();
574   test_add ();
575   test_sub ();
576   test_mul ();
577   test_powm ();
578
579   return !!error_count;
580 }