1 /*	$NetBSD: mtest.c,v 1.1.1.2 2014/04/24 12:45:39 pettai Exp $	*/
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 
7 operation
8 operand1
9 operand2
10 [... operandN]
11 result1
12 result2
13 [... resultN]
14 
15 So for example "a * b mod n" would be
16 
17 mulmod
18 a
19 b
20 n
21 a*b mod n
22 
23 e.g. if a=3, b=4 n=11 then
24 
25 mulmod
26 3
27 4
28 11
29 1
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 
44 FILE *rng;
45 
rand_num(mp_int * a)46 void 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 
rand_num2(mp_int * a)58 void 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 
main(void)72 int 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