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 : #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 1 : test_const_and_immutable (void)
79 : {
80 : gcry_mpi_t one, second_one;
81 :
82 1 : one = gcry_mpi_set_ui (NULL, 1);
83 1 : if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE)
84 1 : || gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
85 0 : die ("immutable or const flag initially set\n");
86 :
87 1 : second_one = gcry_mpi_copy (one);
88 1 : if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
89 0 : die ("immutable flag set after copy\n");
90 1 : if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
91 0 : die ("const flag set after copy\n");
92 1 : gcry_mpi_release (second_one);
93 :
94 1 : gcry_mpi_set_flag (one, GCRYMPI_FLAG_IMMUTABLE);
95 1 : if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
96 0 : die ("failed to set immutable flag\n");
97 1 : if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
98 0 : die ("const flag unexpectly set\n");
99 :
100 1 : second_one = gcry_mpi_copy (one);
101 1 : if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
102 0 : die ("immutable flag not cleared after copy\n");
103 1 : if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
104 0 : die ("const flag unexpectly set after copy\n");
105 1 : gcry_mpi_release (second_one);
106 :
107 1 : gcry_mpi_clear_flag (one, GCRYMPI_FLAG_IMMUTABLE);
108 1 : if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
109 0 : die ("failed to clear immutable flag\n");
110 1 : if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
111 0 : die ("const flag unexpectly set\n");
112 :
113 1 : gcry_mpi_set_flag (one, GCRYMPI_FLAG_CONST);
114 1 : if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
115 0 : die ("failed to set const flag\n");
116 1 : if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
117 0 : die ("failed to set immutable flag with const flag\n");
118 :
119 1 : second_one = gcry_mpi_copy (one);
120 1 : if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
121 0 : die ("immutable flag not cleared after copy\n");
122 1 : if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
123 0 : die ("const flag not cleared after copy\n");
124 1 : gcry_mpi_release (second_one);
125 :
126 1 : gcry_mpi_clear_flag (one, GCRYMPI_FLAG_IMMUTABLE);
127 1 : if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
128 0 : die ("clearing immutable flag not ignored for a constant MPI\n");
129 1 : if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
130 0 : die ("const flag unexpectly cleared\n");
131 :
132 :
133 1 : second_one = gcry_mpi_set (NULL, GCRYMPI_CONST_ONE);
134 1 : if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
135 0 : die ("immutable flag not cleared by mpi_set (NULL,x)\n");
136 1 : if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
137 0 : die ("const flag not cleared by mpi_set (NULL,x)\n");
138 1 : gcry_mpi_release (second_one);
139 :
140 1 : second_one = gcry_mpi_set_ui (NULL, 42);
141 1 : gcry_mpi_set (second_one, GCRYMPI_CONST_ONE);
142 1 : if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
143 0 : die ("immutable flag not cleared after mpi_set (a,x)\n");
144 1 : if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
145 0 : die ("const flag not cleared mpi_set (a,x)\n");
146 1 : 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 1 : gcry_mpi_release (one);
152 1 : return 1;
153 : }
154 :
155 :
156 : static void
157 1 : test_opaque (void)
158 : {
159 : gcry_mpi_t a;
160 : char *p;
161 : unsigned int nbits;
162 :
163 1 : p = gcry_xstrdup ("This is a test buffer");
164 1 : a = gcry_mpi_set_opaque (NULL, p, 21*8+1); /* (a non byte aligned length) */
165 :
166 1 : if (!gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
167 0 : die ("opaque flag not set\n");
168 :
169 1 : p = gcry_mpi_get_opaque (a, &nbits);
170 1 : if (!p)
171 0 : die ("gcry_mpi_get_opaque returned NULL\n");
172 1 : if (nbits != 21*8+1)
173 0 : die ("gcry_mpi_get_opaque returned a changed bit size\n");
174 1 : if (strcmp (p, "This is a test buffer"))
175 0 : die ("gcry_mpi_get_opaque returned a changed buffer\n");
176 :
177 1 : if (debug)
178 0 : gcry_log_debugmpi ("mpi", a);
179 1 : gcry_mpi_release (a);
180 :
181 1 : p = gcry_xstrdup ("This is a test buffer");
182 1 : a = gcry_mpi_set_opaque_copy (NULL, p, 21*8+1);
183 1 : gcry_free (p);
184 :
185 1 : if (!gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
186 0 : die ("opaque flag not set\n");
187 :
188 1 : p = gcry_mpi_get_opaque (a, &nbits);
189 1 : if (!p)
190 0 : die ("gcry_mpi_get_opaque returned NULL\n");
191 1 : if (nbits != 21*8+1)
192 0 : die ("gcry_mpi_get_opaque returned a changed bit size\n");
193 1 : if (strcmp (p, "This is a test buffer"))
194 0 : die ("gcry_mpi_get_opaque returned a changed buffer\n");
195 :
196 1 : if (debug)
197 0 : gcry_log_debugmpi ("mpi", a);
198 :
199 1 : gcry_mpi_release (a);
200 1 : }
201 :
202 :
203 : static void
204 1 : 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 1 : 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 1 : err = gcry_mpi_scan (&a, GCRYMPI_FMT_USG, buffer, 16*1024*1024 +1, NULL);
218 1 : if (gpg_err_code (err) != GPG_ERR_INV_OBJ)
219 0 : 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 1 : buffer[0] = (16385 >> 8);
224 1 : buffer[1] = (16385 & 0xff);
225 1 : err = gcry_mpi_scan (&a, GCRYMPI_FMT_PGP, buffer, sizeof buffer, NULL);
226 1 : if (gpg_err_code (err) != GPG_ERR_INV_OBJ)
227 0 : die ("gcry_mpi_scan does not detect the PGP input limit\n");
228 :
229 1 : buffer[0] = (16384 >> 8);
230 1 : buffer[1] = (16384 & 0xff);
231 :
232 1 : err = gcry_mpi_scan (&a, GCRYMPI_FMT_PGP, buffer, sizeof buffer, NULL);
233 1 : if (err)
234 0 : die ("gcry_mpi_scan did not parse a large PGP: %s\n", gpg_strerror (err));
235 1 : gcry_mpi_release (a);
236 1 : }
237 :
238 :
239 : static void
240 1 : 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 1 : zero = gcry_mpi_new (0);
252 1 : zero2= gcry_mpi_set_ui (NULL, 0);
253 1 : one = gcry_mpi_set_ui (NULL, 1);
254 1 : two = gcry_mpi_set_ui (NULL, 2);
255 1 : rc = gcry_mpi_scan (&all_ones, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
256 1 : if (rc)
257 0 : die ("scanning number failed at line %d", __LINE__);
258 1 : opa0 = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("a"), 0);
259 1 : opa02 = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("b"), 0);
260 1 : opa1 = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("aaaaaaaaaaaaaaaa"), 16*8);
261 1 : opa1s = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("a"), 1*8);
262 1 : opa2 = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("bbbbbbbbbbbbbbbb"), 16*8);
263 1 : opa2s = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("b"), 1*8);
264 :
265 :
266 : /* Single limb test with cmp_ui */
267 1 : if (gcry_mpi_cmp_ui (zero, 0))
268 0 : fail ("mpi_cmp_ui failed at line %d", __LINE__);
269 1 : if (!(gcry_mpi_cmp_ui (zero, 1) < 0))
270 0 : fail ("mpi_cmp_ui failed at line %d", __LINE__);
271 1 : if (!(gcry_mpi_cmp_ui (zero, (-1)) < 0))
272 0 : fail ("mpi_cmp_ui failed at line %d", __LINE__);
273 :
274 1 : if (gcry_mpi_cmp_ui (two, 2))
275 0 : fail ("mpi_cmp_ui failed at line %d", __LINE__);
276 1 : if (!(gcry_mpi_cmp_ui (two, 3) < 0))
277 0 : fail ("mpi_cmp_ui failed at line %d", __LINE__);
278 1 : if (!(gcry_mpi_cmp_ui (two, 1) > 0))
279 0 : fail ("mpi_cmp_ui failed at line %d", __LINE__);
280 :
281 : /* Multi limb tests with cmp_ui. */
282 1 : if (!(gcry_mpi_cmp_ui (all_ones, 0) > 0))
283 0 : fail ("mpi_cmp_ui failed at line %d", __LINE__);
284 1 : if (!(gcry_mpi_cmp_ui (all_ones, (-1)) > 0))
285 0 : fail ("mpi_cmp_ui failed at line %d", __LINE__);
286 :
287 : /* Single limb test with cmp */
288 1 : if (gcry_mpi_cmp (zero, zero2))
289 0 : fail ("mpi_cmp failed at line %d", __LINE__);
290 1 : if (!(gcry_mpi_cmp (zero, one) < 0))
291 0 : fail ("mpi_cmp failed at line %d", __LINE__);
292 1 : if (!(gcry_mpi_cmp (one, zero) > 0))
293 0 : fail ("mpi_cmp failed at line %d", __LINE__);
294 :
295 1 : gcry_mpi_neg (one, one);
296 1 : if (!(gcry_mpi_cmp (zero, one) > 0))
297 0 : fail ("mpi_cmp failed at line %d", __LINE__);
298 1 : if (!(gcry_mpi_cmp (one, zero) < 0))
299 0 : fail ("mpi_cmp failed at line %d", __LINE__);
300 1 : if (!(gcry_mpi_cmp (one, two) < 0))
301 0 : fail ("mpi_cmp failed at line %d", __LINE__);
302 1 : gcry_mpi_neg (one, one);
303 :
304 1 : if (!(gcry_mpi_cmp (one, two) < 0))
305 0 : fail ("mpi_cmp failed at line %d", __LINE__);
306 1 : if (!(gcry_mpi_cmp (two, one) > 0))
307 0 : fail ("mpi_cmp failed at line %d", __LINE__);
308 1 : if (!(gcry_mpi_cmp (one, all_ones) < 0))
309 0 : fail ("mpi_cmp failed at line %d", __LINE__);
310 :
311 : /* Tests with opaque values. */
312 1 : if (!(gcry_mpi_cmp (opa1, one) < 0))
313 0 : fail ("mpi_cmp failed at line %d", __LINE__);
314 1 : if (!(gcry_mpi_cmp (one, opa1) > 0))
315 0 : fail ("mpi_cmp failed at line %d", __LINE__);
316 1 : if (!(gcry_mpi_cmp (opa0, opa02) == 0))
317 0 : fail ("mpi_cmp failed at line %d", __LINE__);
318 1 : if (!(gcry_mpi_cmp (opa1s, opa1) < 0))
319 0 : fail ("mpi_cmp failed at line %d", __LINE__);
320 1 : if (!(gcry_mpi_cmp (opa2, opa1s) > 0))
321 0 : fail ("mpi_cmp failed at line %d", __LINE__);
322 1 : if (!(gcry_mpi_cmp (opa1, opa2) < 0))
323 0 : fail ("mpi_cmp failed at line %d", __LINE__);
324 1 : if (!(gcry_mpi_cmp (opa2, opa1) > 0))
325 0 : fail ("mpi_cmp failed at line %d", __LINE__);
326 1 : if (!(gcry_mpi_cmp (opa1, opa1) == 0))
327 0 : fail ("mpi_cmp failed at line %d", __LINE__);
328 :
329 :
330 1 : gcry_mpi_release(opa2s);
331 1 : gcry_mpi_release(opa2);
332 1 : gcry_mpi_release(opa1s);
333 1 : gcry_mpi_release(opa1);
334 1 : gcry_mpi_release(opa02);
335 1 : gcry_mpi_release(opa0);
336 1 : gcry_mpi_release(all_ones);
337 1 : gcry_mpi_release(two);
338 1 : gcry_mpi_release(one);
339 1 : gcry_mpi_release(zero2);
340 1 : gcry_mpi_release(zero);
341 1 : }
342 :
343 :
344 : static int
345 1 : 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 1 : gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
354 1 : gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
355 1 : gcry_mpi_scan(&ff, GCRYMPI_FMT_USG, manyff, sizeof(manyff), NULL);
356 1 : result = gcry_mpi_new(0);
357 :
358 1 : gcry_mpi_add(result, one, two);
359 1 : gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
360 1 : if (debug)
361 0 : gcry_log_debug ("Result of one plus two:\n%s\n", pc);
362 1 : gcry_free(pc);
363 :
364 1 : gcry_mpi_add(result, ff, one);
365 1 : gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
366 1 : if (debug)
367 0 : gcry_log_debug ("Result of ff plus one:\n%s\n", pc);
368 1 : gcry_free(pc);
369 :
370 1 : gcry_mpi_release(one);
371 1 : gcry_mpi_release(two);
372 1 : gcry_mpi_release(ff);
373 1 : gcry_mpi_release(result);
374 1 : return 1;
375 : }
376 :
377 :
378 : static int
379 1 : 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 1 : gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
387 1 : gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
388 1 : result = gcry_mpi_new(0);
389 1 : gcry_mpi_sub(result, two, one);
390 :
391 1 : gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
392 1 : if (debug)
393 0 : gcry_log_debug ("Result of two minus one:\n%s\n", pc);
394 1 : gcry_free(pc);
395 :
396 1 : gcry_mpi_release(one);
397 1 : gcry_mpi_release(two);
398 1 : gcry_mpi_release(result);
399 1 : return 1;
400 : }
401 :
402 :
403 : static int
404 1 : 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 1 : gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
412 1 : gcry_mpi_scan(&three, GCRYMPI_FMT_USG, threes, sizeof(threes), NULL);
413 1 : result = gcry_mpi_new(0);
414 1 : gcry_mpi_mul(result, two, three);
415 :
416 1 : gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
417 1 : if (debug)
418 0 : gcry_log_debug ("Result of two mul three:\n%s\n", pc);
419 1 : gcry_free(pc);
420 :
421 1 : gcry_mpi_release(two);
422 1 : gcry_mpi_release(three);
423 1 : gcry_mpi_release(result);
424 1 : 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 1 : test_powm (void)
432 : {
433 1 : int b_int = 17;
434 1 : int e_int = 3;
435 1 : int m_int = 19;
436 1 : gcry_mpi_t base = gcry_mpi_set_ui (NULL, b_int);
437 1 : gcry_mpi_t exp = gcry_mpi_set_ui (NULL, e_int);
438 1 : gcry_mpi_t mod = gcry_mpi_set_ui (NULL, m_int);
439 1 : gcry_mpi_t res = gcry_mpi_new (0);
440 :
441 1 : gcry_mpi_powm (res, base, exp, mod);
442 1 : if (gcry_mpi_cmp_ui (base, b_int))
443 0 : die ("test_powm failed for base at %d\n", __LINE__);
444 1 : if (gcry_mpi_cmp_ui (exp, e_int))
445 0 : die ("test_powm_ui failed for exp at %d\n", __LINE__);
446 1 : if (gcry_mpi_cmp_ui (mod, m_int))
447 0 : die ("test_powm failed for mod at %d\n", __LINE__);
448 :
449 : /* Check using base for the result. */
450 1 : gcry_mpi_set_ui (base, b_int);
451 1 : gcry_mpi_set_ui (exp, e_int);
452 1 : gcry_mpi_set_ui(mod, m_int);
453 1 : gcry_mpi_powm (base, base, exp, mod);
454 1 : if (gcry_mpi_cmp (res, base))
455 0 : die ("test_powm failed at %d\n", __LINE__);
456 1 : if (gcry_mpi_cmp_ui (exp, e_int))
457 0 : die ("test_powm_ui failed for exp at %d\n", __LINE__);
458 1 : if (gcry_mpi_cmp_ui (mod, m_int))
459 0 : die ("test_powm failed for mod at %d\n", __LINE__);
460 :
461 : /* Check using exp for the result. */
462 1 : gcry_mpi_set_ui (base, b_int);
463 1 : gcry_mpi_set_ui (exp, e_int);
464 1 : gcry_mpi_set_ui(mod, m_int);
465 1 : gcry_mpi_powm (exp, base, exp, mod);
466 1 : if (gcry_mpi_cmp (res, exp))
467 0 : die ("test_powm failed at %d\n", __LINE__);
468 1 : if (gcry_mpi_cmp_ui (base, b_int))
469 0 : die ("test_powm failed for base at %d\n", __LINE__);
470 1 : if (gcry_mpi_cmp_ui (mod, m_int))
471 0 : die ("test_powm failed for mod at %d\n", __LINE__);
472 :
473 : /* Check using mod for the result. */
474 1 : gcry_mpi_set_ui (base, b_int);
475 1 : gcry_mpi_set_ui (exp, e_int);
476 1 : gcry_mpi_set_ui(mod, m_int);
477 1 : gcry_mpi_powm (mod, base, exp, mod);
478 1 : if (gcry_mpi_cmp (res, mod))
479 0 : die ("test_powm failed at %d\n", __LINE__);
480 1 : if (gcry_mpi_cmp_ui (base, b_int))
481 0 : die ("test_powm failed for base at %d\n", __LINE__);
482 1 : if (gcry_mpi_cmp_ui (exp, e_int))
483 0 : die ("test_powm_ui failed for exp at %d\n", __LINE__);
484 :
485 : /* Now check base ^ base mod mod. */
486 1 : gcry_mpi_set_ui (base, b_int);
487 1 : gcry_mpi_set_ui(mod, m_int);
488 1 : gcry_mpi_powm (res, base, base, mod);
489 1 : if (gcry_mpi_cmp_ui (base, b_int))
490 0 : die ("test_powm failed for base at %d\n", __LINE__);
491 1 : if (gcry_mpi_cmp_ui (mod, m_int))
492 0 : die ("test_powm failed for mod at %d\n", __LINE__);
493 :
494 : /* Check base ^ base mod mod with base as result. */
495 1 : gcry_mpi_set_ui (base, b_int);
496 1 : gcry_mpi_set_ui(mod, m_int);
497 1 : gcry_mpi_powm (base, base, base, mod);
498 1 : if (gcry_mpi_cmp (res, base))
499 0 : die ("test_powm failed at %d\n", __LINE__);
500 1 : if (gcry_mpi_cmp_ui (mod, m_int))
501 0 : die ("test_powm failed for mod at %d\n", __LINE__);
502 :
503 : /* Check base ^ base mod mod with mod as result. */
504 1 : gcry_mpi_set_ui (base, b_int);
505 1 : gcry_mpi_set_ui(mod, m_int);
506 1 : gcry_mpi_powm (mod, base, base, mod);
507 1 : if (gcry_mpi_cmp (res, mod))
508 0 : die ("test_powm failed at %d\n", __LINE__);
509 1 : if (gcry_mpi_cmp_ui (base, b_int))
510 0 : die ("test_powm failed for base at %d\n", __LINE__);
511 :
512 : /* Now check base ^ base mod base. */
513 1 : gcry_mpi_set_ui (base, b_int);
514 1 : gcry_mpi_powm (res, base, base, base);
515 1 : if (gcry_mpi_cmp_ui (base, b_int))
516 0 : die ("test_powm failed for base at %d\n", __LINE__);
517 :
518 : /* Check base ^ base mod base with base as result. */
519 1 : gcry_mpi_set_ui (base, b_int);
520 1 : gcry_mpi_powm (base, base, base, base);
521 1 : if (gcry_mpi_cmp (res, base))
522 0 : die ("test_powm failed at %d\n", __LINE__);
523 :
524 : /* Check for a case: base is negative and expo is even. */
525 1 : gcry_mpi_set_ui (base, b_int);
526 1 : gcry_mpi_neg (base, base);
527 1 : gcry_mpi_set_ui (exp, e_int * 2);
528 1 : gcry_mpi_set_ui(mod, m_int);
529 1 : gcry_mpi_powm (res, base, exp, mod);
530 : /* Result should be positive and it's 7 = (-17)^6 mod 19. */
531 1 : if (gcry_mpi_is_neg (res) || gcry_mpi_cmp_ui (res, 7))
532 : {
533 0 : if (verbose)
534 : {
535 0 : fprintf (stderr, "is_neg: %d\n", gcry_mpi_is_neg (res));
536 0 : fprintf (stderr, "mpi: ");
537 0 : gcry_mpi_dump (res);
538 0 : putc ('\n', stderr);
539 : }
540 0 : die ("test_powm failed for negative base at %d\n", __LINE__);
541 : }
542 :
543 1 : gcry_mpi_release (base);
544 1 : gcry_mpi_release (exp);
545 1 : gcry_mpi_release (mod);
546 1 : gcry_mpi_release (res);
547 : /* Fixme: We should add the rest of the cases of course. */
548 :
549 :
550 :
551 1 : return 1;
552 : }
553 :
554 :
555 : int
556 1 : main (int argc, char* argv[])
557 : {
558 1 : if (argc > 1 && !strcmp (argv[1], "--verbose"))
559 0 : verbose = 1;
560 1 : else if (argc > 1 && !strcmp (argv[1], "--debug"))
561 0 : verbose = debug = 1;
562 :
563 1 : if (!gcry_check_version (GCRYPT_VERSION))
564 : {
565 0 : fputs ("version mismatch\n", stderr);
566 0 : exit (1);
567 : }
568 1 : xgcry_control(GCRYCTL_DISABLE_SECMEM);
569 :
570 1 : test_const_and_immutable ();
571 1 : test_opaque ();
572 1 : test_maxsize ();
573 1 : test_cmp ();
574 1 : test_add ();
575 1 : test_sub ();
576 1 : test_mul ();
577 1 : test_powm ();
578 :
579 1 : return !!error_count;
580 : }
|