Fix bug 977.
[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 #include "../src/gcrypt.h"
31
32
33 static int verbose;
34 static int debug;
35
36
37 static void
38 die (const char *format, ...)
39 {
40   va_list arg_ptr;
41
42   va_start (arg_ptr, format);
43   vfprintf (stderr, format, arg_ptr);
44   va_end (arg_ptr);
45   exit (1);
46 }
47
48
49
50 /* Set up some test patterns */
51
52 /* 48 bytes with value 1: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
53 unsigned char ones[] = {
54   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
55   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
56   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
57 };
58
59 /* 48 bytes with value 2: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
60 unsigned char twos[] = {
61   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
62   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
63   0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02
64 };
65
66 /* 48 bytes with value 3: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
67 unsigned char threes[] = {
68   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
69   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
70   0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
71 };
72
73 /* 48 bytes with value 0x80: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
74 unsigned char eighties[] = {
75   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
76   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
77   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
78 };
79
80 /* 48 bytes with value 0xff: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
81 unsigned char manyff[] = {
82   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
83   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
84   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
85 };
86
87
88
89 static int 
90 test_add (void)
91 {
92   gcry_mpi_t one;
93   gcry_mpi_t two;
94   gcry_mpi_t ff;
95   gcry_mpi_t result;
96   unsigned char* pc;
97   
98   gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
99   gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
100   gcry_mpi_scan(&ff, GCRYMPI_FMT_USG, manyff, sizeof(manyff), NULL);
101   result = gcry_mpi_new(0);
102   
103   gcry_mpi_add(result, one, two);
104   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
105   if (verbose)
106     printf("Result of one plus two:\n%s\n", pc);
107   gcry_free(pc);
108
109   gcry_mpi_add(result, ff, one);
110   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
111   if (verbose)
112     printf("Result of ff plus one:\n%s\n", pc);
113   gcry_free(pc);
114   
115   gcry_mpi_release(one);
116   gcry_mpi_release(two);
117   gcry_mpi_release(ff);
118   gcry_mpi_release(result);
119   return 1;
120 }
121
122
123 static int 
124 test_sub (void)
125 {
126   gcry_mpi_t one;
127   gcry_mpi_t two;
128   gcry_mpi_t result;
129   unsigned char* pc;
130   
131   gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
132   gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
133   result = gcry_mpi_new(0);
134   gcry_mpi_sub(result, two, one);
135   
136   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
137   if (verbose)
138     printf("Result of two minus one:\n%s\n", pc);
139   gcry_free(pc);
140   
141   gcry_mpi_release(one);
142   gcry_mpi_release(two);
143   gcry_mpi_release(result);
144   return 1;
145 }
146
147
148 static int 
149 test_mul (void)
150 {
151   gcry_mpi_t two;
152   gcry_mpi_t three;
153   gcry_mpi_t result;
154   unsigned char* pc;
155   
156   gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
157   gcry_mpi_scan(&three, GCRYMPI_FMT_USG, threes, sizeof(threes), NULL);
158   result = gcry_mpi_new(0);
159   gcry_mpi_mul(result, two, three);
160   
161   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
162   if (verbose)
163     printf("Result of two mul three:\n%s\n", pc);
164   gcry_free(pc);
165   
166   gcry_mpi_release(two);
167   gcry_mpi_release(three);
168   gcry_mpi_release(result);
169   return 1;
170 }
171
172
173 /* What we test here is that we don't overwrite our args and that
174    using thne same mpi for several args works.  */
175 static int
176 test_powm (void)
177 {
178   int b_int = 17;
179   int e_int = 3;
180   int m_int = 19;  
181   gcry_mpi_t base = gcry_mpi_set_ui (NULL, b_int);
182   gcry_mpi_t exp = gcry_mpi_set_ui (NULL, e_int);
183   gcry_mpi_t mod = gcry_mpi_set_ui (NULL, m_int);
184   gcry_mpi_t res = gcry_mpi_new (0);
185
186   gcry_mpi_powm (res, base, exp, mod);
187   if (gcry_mpi_cmp_ui (base, b_int))
188     die ("test_powm failed for base at %d\n", __LINE__);
189   if (gcry_mpi_cmp_ui (exp, e_int))
190     die ("test_powm_ui failed for exp at %d\n", __LINE__);
191   if (gcry_mpi_cmp_ui (mod, m_int))
192     die ("test_powm failed for mod at %d\n", __LINE__);
193
194   /* Check using base for the result.  */
195   gcry_mpi_set_ui (base, b_int);
196   gcry_mpi_set_ui (exp, e_int);
197   gcry_mpi_set_ui(mod, m_int);
198   gcry_mpi_powm (base, base, exp, mod);
199   if (gcry_mpi_cmp (res, base))
200     die ("test_powm failed at %d\n", __LINE__);
201   if (gcry_mpi_cmp_ui (exp, e_int))
202     die ("test_powm_ui failed for exp at %d\n", __LINE__);
203   if (gcry_mpi_cmp_ui (mod, m_int))
204     die ("test_powm failed for mod at %d\n", __LINE__);
205
206   /* Check using exp for the result.  */
207   gcry_mpi_set_ui (base, b_int);
208   gcry_mpi_set_ui (exp, e_int);
209   gcry_mpi_set_ui(mod, m_int);
210   gcry_mpi_powm (exp, base, exp, mod);
211   if (gcry_mpi_cmp (res, exp))
212     die ("test_powm failed at %d\n", __LINE__);
213   if (gcry_mpi_cmp_ui (base, b_int))
214     die ("test_powm failed for base at %d\n", __LINE__);
215   if (gcry_mpi_cmp_ui (mod, m_int))
216     die ("test_powm failed for mod at %d\n", __LINE__);
217
218   /* Check using mod for the result.  */
219   gcry_mpi_set_ui (base, b_int);
220   gcry_mpi_set_ui (exp, e_int);
221   gcry_mpi_set_ui(mod, m_int);
222   gcry_mpi_powm (mod, base, exp, mod);
223   if (gcry_mpi_cmp (res, mod))
224     die ("test_powm failed at %d\n", __LINE__);
225   if (gcry_mpi_cmp_ui (base, b_int))
226     die ("test_powm failed for base at %d\n", __LINE__);
227   if (gcry_mpi_cmp_ui (exp, e_int))
228     die ("test_powm_ui failed for exp at %d\n", __LINE__);
229
230   /* Now check base ^ base mod mod.  */
231   gcry_mpi_set_ui (base, b_int);
232   gcry_mpi_set_ui(mod, m_int);
233   gcry_mpi_powm (res, base, base, mod);
234   if (gcry_mpi_cmp_ui (base, b_int))
235     die ("test_powm failed for base at %d\n", __LINE__);
236   if (gcry_mpi_cmp_ui (mod, m_int))
237     die ("test_powm failed for mod at %d\n", __LINE__);
238
239   /* Check base ^ base mod mod with base as result.  */
240   gcry_mpi_set_ui (base, b_int);
241   gcry_mpi_set_ui(mod, m_int);
242   gcry_mpi_powm (base, base, base, mod);
243   if (gcry_mpi_cmp (res, base))
244     die ("test_powm failed at %d\n", __LINE__);
245   if (gcry_mpi_cmp_ui (mod, m_int))
246     die ("test_powm failed for mod at %d\n", __LINE__);
247
248   /* Check base ^ base mod mod with mod as result.  */
249   gcry_mpi_set_ui (base, b_int);
250   gcry_mpi_set_ui(mod, m_int);
251   gcry_mpi_powm (mod, base, base, mod);
252   if (gcry_mpi_cmp (res, mod))
253     die ("test_powm failed at %d\n", __LINE__);
254   if (gcry_mpi_cmp_ui (base, b_int))
255     die ("test_powm failed for base at %d\n", __LINE__);
256
257   /* Now check base ^ base mod base.  */
258   gcry_mpi_set_ui (base, b_int);
259   gcry_mpi_powm (res, base, base, base);
260   if (gcry_mpi_cmp_ui (base, b_int))
261     die ("test_powm failed for base at %d\n", __LINE__);
262
263   /* Check base ^ base mod base with base as result.  */
264   gcry_mpi_set_ui (base, b_int);
265   gcry_mpi_powm (base, base, base, base);
266   if (gcry_mpi_cmp (res, base))
267     die ("test_powm failed at %d\n", __LINE__);
268
269   /* Fixme: We should add the rest of the cases of course.  */
270
271
272
273   return 1;
274 }
275
276
277 int 
278 main (int argc, char* argv[])
279 {
280   if (argc > 1 && !strcmp (argv[1], "--verbose"))
281     verbose = 1;
282   else if (argc > 1 && !strcmp (argv[1], "--debug"))
283     verbose = debug = 1;
284
285   if (!gcry_check_version (GCRYPT_VERSION))
286     {
287       fputs ("version mismatch\n", stderr);
288       exit (1);
289     }
290   gcry_control(GCRYCTL_DISABLE_SECMEM);
291
292   test_add ();
293   test_sub ();
294   test_mul ();
295   test_powm ();
296
297   return 0;
298 }
299