1/*	$NetBSD$	*/
2
3/* makes a bignum test harness with NUM tests per operation
4 *
5 * the output is made in the following format [one parameter per line]
6
7operation
8operand1
9operand2
10[... operandN]
11result1
12result2
13[... resultN]
14
15So for example "a * b mod n" would be
16
17mulmod
18a
19b
20n
21a*b mod n
22
23e.g. if a=3, b=4 n=11 then
24
25mulmod
263
274
2811
291
30
31 */
32
33#ifdef MP_8BIT
34#define THE_MASK 127
35#else
36#define THE_MASK 32767
37#endif
38
39#include <stdio.h>
40#include <stdlib.h>
41#include <time.h>
42#include "mpi.c"
43
44FILE *rng;
45
46void rand_num(mp_int *a)
47{
48   int n, size;
49   unsigned char buf[2048];
50
51   size = 1 + ((fgetc(rng)<<8) + fgetc(rng)) % 101;
52   buf[0] = (fgetc(rng)&1)?1:0;
53   fread(buf+1, 1, size, rng);
54   while (buf[1] == 0) buf[1] = fgetc(rng);
55   mp_read_raw(a, buf, 1+size);
56}
57
58void rand_num2(mp_int *a)
59{
60   int n, size;
61   unsigned char buf[2048];
62
63   size = 10 + ((fgetc(rng)<<8) + fgetc(rng)) % 101;
64   buf[0] = (fgetc(rng)&1)?1:0;
65   fread(buf+1, 1, size, rng);
66   while (buf[1] == 0) buf[1] = fgetc(rng);
67   mp_read_raw(a, buf, 1+size);
68}
69
70#define mp_to64(a, b) mp_toradix(a, b, 64)
71
72int main(void)
73{
74   int n, tmp;
75   mp_int a, b, c, d, e;
76   clock_t t1;
77   char buf[4096];
78
79   mp_init(&a);
80   mp_init(&b);
81   mp_init(&c);
82   mp_init(&d);
83   mp_init(&e);
84
85
86   /* initial (2^n - 1)^2 testing, makes sure the comba multiplier works [it has the new carry code] */
87/*
88   mp_set(&a, 1);
89   for (n = 1; n < 8192; n++) {
90       mp_mul(&a, &a, &c);
91       printf("mul\n");
92       mp_to64(&a, buf);
93       printf("%s\n%s\n", buf, buf);
94       mp_to64(&c, buf);
95       printf("%s\n", buf);
96
97       mp_add_d(&a, 1, &a);
98       mp_mul_2(&a, &a);
99       mp_sub_d(&a, 1, &a);
100   }
101*/
102
103   rng = fopen("/dev/urandom", "rb");
104   if (rng == NULL) {
105      rng = fopen("/dev/random", "rb");
106      if (rng == NULL) {
107         fprintf(stderr, "\nWarning:  stdin used as random source\n\n");
108         rng = stdin;
109      }
110   }
111
112   t1 = clock();
113   for (;;) {
114#if 0
115      if (clock() - t1 > CLOCKS_PER_SEC) {
116         sleep(2);
117         t1 = clock();
118      }
119#endif
120       n = fgetc(rng) % 15;
121
122   if (n == 0) {
123       /* add tests */
124       rand_num(&a);
125       rand_num(&b);
126       mp_add(&a, &b, &c);
127       printf("add\n");
128       mp_to64(&a, buf);
129       printf("%s\n", buf);
130       mp_to64(&b, buf);
131       printf("%s\n", buf);
132       mp_to64(&c, buf);
133       printf("%s\n", buf);
134   } else if (n == 1) {
135      /* sub tests */
136       rand_num(&a);
137       rand_num(&b);
138       mp_sub(&a, &b, &c);
139       printf("sub\n");
140       mp_to64(&a, buf);
141       printf("%s\n", buf);
142       mp_to64(&b, buf);
143       printf("%s\n", buf);
144       mp_to64(&c, buf);
145       printf("%s\n", buf);
146   } else if (n == 2) {
147       /* mul tests */
148       rand_num(&a);
149       rand_num(&b);
150       mp_mul(&a, &b, &c);
151       printf("mul\n");
152       mp_to64(&a, buf);
153       printf("%s\n", buf);
154       mp_to64(&b, buf);
155       printf("%s\n", buf);
156       mp_to64(&c, buf);
157       printf("%s\n", buf);
158   } else if (n == 3) {
159      /* div tests */
160       rand_num(&a);
161       rand_num(&b);
162       mp_div(&a, &b, &c, &d);
163       printf("div\n");
164       mp_to64(&a, buf);
165       printf("%s\n", buf);
166       mp_to64(&b, buf);
167       printf("%s\n", buf);
168       mp_to64(&c, buf);
169       printf("%s\n", buf);
170       mp_to64(&d, buf);
171       printf("%s\n", buf);
172   } else if (n == 4) {
173      /* sqr tests */
174       rand_num(&a);
175       mp_sqr(&a, &b);
176       printf("sqr\n");
177       mp_to64(&a, buf);
178       printf("%s\n", buf);
179       mp_to64(&b, buf);
180       printf("%s\n", buf);
181   } else if (n == 5) {
182      /* mul_2d test */
183      rand_num(&a);
184      mp_copy(&a, &b);
185      n = fgetc(rng) & 63;
186      mp_mul_2d(&b, n, &b);
187      mp_to64(&a, buf);
188      printf("mul2d\n");
189      printf("%s\n", buf);
190      printf("%d\n", n);
191      mp_to64(&b, buf);
192      printf("%s\n", buf);
193   } else if (n == 6) {
194      /* div_2d test */
195      rand_num(&a);
196      mp_copy(&a, &b);
197      n = fgetc(rng) & 63;
198      mp_div_2d(&b, n, &b, NULL);
199      mp_to64(&a, buf);
200      printf("div2d\n");
201      printf("%s\n", buf);
202      printf("%d\n", n);
203      mp_to64(&b, buf);
204      printf("%s\n", buf);
205   } else if (n == 7) {
206      /* gcd test */
207      rand_num(&a);
208      rand_num(&b);
209      a.sign = MP_ZPOS;
210      b.sign = MP_ZPOS;
211      mp_gcd(&a, &b, &c);
212      printf("gcd\n");
213      mp_to64(&a, buf);
214      printf("%s\n", buf);
215      mp_to64(&b, buf);
216      printf("%s\n", buf);
217      mp_to64(&c, buf);
218      printf("%s\n", buf);
219   } else if (n == 8) {
220      /* lcm test */
221      rand_num(&a);
222      rand_num(&b);
223      a.sign = MP_ZPOS;
224      b.sign = MP_ZPOS;
225      mp_lcm(&a, &b, &c);
226      printf("lcm\n");
227      mp_to64(&a, buf);
228      printf("%s\n", buf);
229      mp_to64(&b, buf);
230      printf("%s\n", buf);
231      mp_to64(&c, buf);
232      printf("%s\n", buf);
233   } else if (n == 9) {
234      /* exptmod test */
235      rand_num2(&a);
236      rand_num2(&b);
237      rand_num2(&c);
238//      if (c.dp[0]&1) mp_add_d(&c, 1, &c);
239      a.sign = b.sign = c.sign = 0;
240      mp_exptmod(&a, &b, &c, &d);
241      printf("expt\n");
242      mp_to64(&a, buf);
243      printf("%s\n", buf);
244      mp_to64(&b, buf);
245      printf("%s\n", buf);
246      mp_to64(&c, buf);
247      printf("%s\n", buf);
248      mp_to64(&d, buf);
249      printf("%s\n", buf);
250   } else if (n == 10) {
251      /* invmod test */
252      rand_num2(&a);
253      rand_num2(&b);
254      b.sign = MP_ZPOS;
255      a.sign = MP_ZPOS;
256      mp_gcd(&a, &b, &c);
257      if (mp_cmp_d(&c, 1) != 0) continue;
258      if (mp_cmp_d(&b, 1) == 0) continue;
259      mp_invmod(&a, &b, &c);
260      printf("invmod\n");
261      mp_to64(&a, buf);
262      printf("%s\n", buf);
263      mp_to64(&b, buf);
264      printf("%s\n", buf);
265      mp_to64(&c, buf);
266      printf("%s\n", buf);
267   } else if (n == 11) {
268      rand_num(&a);
269      mp_mul_2(&a, &a);
270      mp_div_2(&a, &b);
271      printf("div2\n");
272      mp_to64(&a, buf);
273      printf("%s\n", buf);
274      mp_to64(&b, buf);
275      printf("%s\n", buf);
276   } else if (n == 12) {
277      rand_num2(&a);
278      mp_mul_2(&a, &b);
279      printf("mul2\n");
280      mp_to64(&a, buf);
281      printf("%s\n", buf);
282      mp_to64(&b, buf);
283      printf("%s\n", buf);
284   } else if (n == 13) {
285      rand_num2(&a);
286      tmp = abs(rand()) & THE_MASK;
287      mp_add_d(&a, tmp, &b);
288      printf("add_d\n");
289      mp_to64(&a, buf);
290      printf("%s\n%d\n", buf, tmp);
291      mp_to64(&b, buf);
292      printf("%s\n", buf);
293   } else if (n == 14) {
294      rand_num2(&a);
295      tmp = abs(rand()) & THE_MASK;
296      mp_sub_d(&a, tmp, &b);
297      printf("sub_d\n");
298      mp_to64(&a, buf);
299      printf("%s\n%d\n", buf, tmp);
300      mp_to64(&b, buf);
301      printf("%s\n", buf);
302   }
303   }
304   fclose(rng);
305   return 0;
306}
307
308/* Source: /cvs/libtom/libtommath/mtest/mtest.c,v */
309/* Revision: 1.2 */
310/* Date: 2005/05/05 14:38:47 */
311