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