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