xref: /minix3/crypto/external/bsd/heimdal/dist/lib/hcrypto/libtommath/demo/demo.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: demo.c,v 1.1.1.2 2014/04/24 12:45:39 pettai Exp $	*/
2ebfedea0SLionel Sambuc 
3ebfedea0SLionel Sambuc #include <time.h>
4ebfedea0SLionel Sambuc 
5ebfedea0SLionel Sambuc #ifdef IOWNANATHLON
6ebfedea0SLionel Sambuc #include <unistd.h>
7ebfedea0SLionel Sambuc #define SLEEP sleep(4)
8ebfedea0SLionel Sambuc #else
9ebfedea0SLionel Sambuc #define SLEEP
10ebfedea0SLionel Sambuc #endif
11ebfedea0SLionel Sambuc 
12ebfedea0SLionel Sambuc #include "tommath.h"
13ebfedea0SLionel Sambuc 
ndraw(mp_int * a,char * name)14ebfedea0SLionel Sambuc void ndraw(mp_int * a, char *name)
15ebfedea0SLionel Sambuc {
16ebfedea0SLionel Sambuc    char buf[16000];
17ebfedea0SLionel Sambuc 
18ebfedea0SLionel Sambuc    printf("%s: ", name);
19ebfedea0SLionel Sambuc    mp_toradix(a, buf, 10);
20ebfedea0SLionel Sambuc    printf("%s\n", buf);
21ebfedea0SLionel Sambuc }
22ebfedea0SLionel Sambuc 
draw(mp_int * a)23ebfedea0SLionel Sambuc static void draw(mp_int * a)
24ebfedea0SLionel Sambuc {
25ebfedea0SLionel Sambuc    ndraw(a, "");
26ebfedea0SLionel Sambuc }
27ebfedea0SLionel Sambuc 
28ebfedea0SLionel Sambuc 
29ebfedea0SLionel Sambuc unsigned long lfsr = 0xAAAAAAAAUL;
30ebfedea0SLionel Sambuc 
lbit(void)31ebfedea0SLionel Sambuc int lbit(void)
32ebfedea0SLionel Sambuc {
33ebfedea0SLionel Sambuc    if (lfsr & 0x80000000UL) {
34ebfedea0SLionel Sambuc       lfsr = ((lfsr << 1) ^ 0x8000001BUL) & 0xFFFFFFFFUL;
35ebfedea0SLionel Sambuc       return 1;
36ebfedea0SLionel Sambuc    } else {
37ebfedea0SLionel Sambuc       lfsr <<= 1;
38ebfedea0SLionel Sambuc       return 0;
39ebfedea0SLionel Sambuc    }
40ebfedea0SLionel Sambuc }
41ebfedea0SLionel Sambuc 
myrng(unsigned char * dst,int len,void * dat)42ebfedea0SLionel Sambuc int myrng(unsigned char *dst, int len, void *dat)
43ebfedea0SLionel Sambuc {
44ebfedea0SLionel Sambuc    int x;
45ebfedea0SLionel Sambuc 
46ebfedea0SLionel Sambuc    for (x = 0; x < len; x++)
47ebfedea0SLionel Sambuc       dst[x] = rand() & 0xFF;
48ebfedea0SLionel Sambuc    return len;
49ebfedea0SLionel Sambuc }
50ebfedea0SLionel Sambuc 
51ebfedea0SLionel Sambuc 
52ebfedea0SLionel Sambuc 
53ebfedea0SLionel Sambuc char cmd[4096], buf[4096];
main(void)54ebfedea0SLionel Sambuc int main(void)
55ebfedea0SLionel Sambuc {
56ebfedea0SLionel Sambuc    mp_int a, b, c, d, e, f;
57ebfedea0SLionel Sambuc    unsigned long expt_n, add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n,
58ebfedea0SLionel Sambuc       gcd_n, lcm_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n, t;
59ebfedea0SLionel Sambuc    unsigned rr;
60ebfedea0SLionel Sambuc    int i, n, err, cnt, ix, old_kara_m, old_kara_s;
61ebfedea0SLionel Sambuc    mp_digit mp;
62ebfedea0SLionel Sambuc 
63ebfedea0SLionel Sambuc 
64ebfedea0SLionel Sambuc    mp_init(&a);
65ebfedea0SLionel Sambuc    mp_init(&b);
66ebfedea0SLionel Sambuc    mp_init(&c);
67ebfedea0SLionel Sambuc    mp_init(&d);
68ebfedea0SLionel Sambuc    mp_init(&e);
69ebfedea0SLionel Sambuc    mp_init(&f);
70ebfedea0SLionel Sambuc 
71ebfedea0SLionel Sambuc    srand(time(NULL));
72ebfedea0SLionel Sambuc 
73ebfedea0SLionel Sambuc #if 0
74ebfedea0SLionel Sambuc    // test montgomery
75ebfedea0SLionel Sambuc    printf("Testing montgomery...\n");
76ebfedea0SLionel Sambuc    for (i = 1; i < 10; i++) {
77ebfedea0SLionel Sambuc       printf("Testing digit size: %d\n", i);
78ebfedea0SLionel Sambuc       for (n = 0; n < 1000; n++) {
79ebfedea0SLionel Sambuc          mp_rand(&a, i);
80ebfedea0SLionel Sambuc          a.dp[0] |= 1;
81ebfedea0SLionel Sambuc 
82ebfedea0SLionel Sambuc          // let's see if R is right
83ebfedea0SLionel Sambuc          mp_montgomery_calc_normalization(&b, &a);
84ebfedea0SLionel Sambuc          mp_montgomery_setup(&a, &mp);
85ebfedea0SLionel Sambuc 
86ebfedea0SLionel Sambuc          // now test a random reduction
87ebfedea0SLionel Sambuc          for (ix = 0; ix < 100; ix++) {
88ebfedea0SLionel Sambuc              mp_rand(&c, 1 + abs(rand()) % (2*i));
89ebfedea0SLionel Sambuc              mp_copy(&c, &d);
90ebfedea0SLionel Sambuc              mp_copy(&c, &e);
91ebfedea0SLionel Sambuc 
92ebfedea0SLionel Sambuc              mp_mod(&d, &a, &d);
93ebfedea0SLionel Sambuc              mp_montgomery_reduce(&c, &a, mp);
94ebfedea0SLionel Sambuc              mp_mulmod(&c, &b, &a, &c);
95ebfedea0SLionel Sambuc 
96ebfedea0SLionel Sambuc              if (mp_cmp(&c, &d) != MP_EQ) {
97ebfedea0SLionel Sambuc printf("d = e mod a, c = e MOD a\n");
98ebfedea0SLionel Sambuc mp_todecimal(&a, buf); printf("a = %s\n", buf);
99ebfedea0SLionel Sambuc mp_todecimal(&e, buf); printf("e = %s\n", buf);
100ebfedea0SLionel Sambuc mp_todecimal(&d, buf); printf("d = %s\n", buf);
101ebfedea0SLionel Sambuc mp_todecimal(&c, buf); printf("c = %s\n", buf);
102ebfedea0SLionel Sambuc printf("compare no compare!\n"); exit(EXIT_FAILURE); }
103ebfedea0SLionel Sambuc          }
104ebfedea0SLionel Sambuc       }
105ebfedea0SLionel Sambuc    }
106ebfedea0SLionel Sambuc    printf("done\n");
107ebfedea0SLionel Sambuc 
108ebfedea0SLionel Sambuc    // test mp_get_int
109ebfedea0SLionel Sambuc    printf("Testing: mp_get_int\n");
110ebfedea0SLionel Sambuc    for (i = 0; i < 1000; ++i) {
111ebfedea0SLionel Sambuc       t = ((unsigned long) rand() * rand() + 1) & 0xFFFFFFFF;
112ebfedea0SLionel Sambuc       mp_set_int(&a, t);
113ebfedea0SLionel Sambuc       if (t != mp_get_int(&a)) {
114ebfedea0SLionel Sambuc 	 printf("mp_get_int() bad result!\n");
115ebfedea0SLionel Sambuc 	 return 1;
116ebfedea0SLionel Sambuc       }
117ebfedea0SLionel Sambuc    }
118ebfedea0SLionel Sambuc    mp_set_int(&a, 0);
119ebfedea0SLionel Sambuc    if (mp_get_int(&a) != 0) {
120ebfedea0SLionel Sambuc       printf("mp_get_int() bad result!\n");
121ebfedea0SLionel Sambuc       return 1;
122ebfedea0SLionel Sambuc    }
123ebfedea0SLionel Sambuc    mp_set_int(&a, 0xffffffff);
124ebfedea0SLionel Sambuc    if (mp_get_int(&a) != 0xffffffff) {
125ebfedea0SLionel Sambuc       printf("mp_get_int() bad result!\n");
126ebfedea0SLionel Sambuc       return 1;
127ebfedea0SLionel Sambuc    }
128ebfedea0SLionel Sambuc    // test mp_sqrt
129ebfedea0SLionel Sambuc    printf("Testing: mp_sqrt\n");
130ebfedea0SLionel Sambuc    for (i = 0; i < 1000; ++i) {
131ebfedea0SLionel Sambuc       printf("%6d\r", i);
132ebfedea0SLionel Sambuc       fflush(stdout);
133ebfedea0SLionel Sambuc       n = (rand() & 15) + 1;
134ebfedea0SLionel Sambuc       mp_rand(&a, n);
135ebfedea0SLionel Sambuc       if (mp_sqrt(&a, &b) != MP_OKAY) {
136ebfedea0SLionel Sambuc 	 printf("mp_sqrt() error!\n");
137ebfedea0SLionel Sambuc 	 return 1;
138ebfedea0SLionel Sambuc       }
139ebfedea0SLionel Sambuc       mp_n_root(&a, 2, &a);
140ebfedea0SLionel Sambuc       if (mp_cmp_mag(&b, &a) != MP_EQ) {
141ebfedea0SLionel Sambuc 	 printf("mp_sqrt() bad result!\n");
142ebfedea0SLionel Sambuc 	 return 1;
143ebfedea0SLionel Sambuc       }
144ebfedea0SLionel Sambuc    }
145ebfedea0SLionel Sambuc 
146ebfedea0SLionel Sambuc    printf("\nTesting: mp_is_square\n");
147ebfedea0SLionel Sambuc    for (i = 0; i < 1000; ++i) {
148ebfedea0SLionel Sambuc       printf("%6d\r", i);
149ebfedea0SLionel Sambuc       fflush(stdout);
150ebfedea0SLionel Sambuc 
151ebfedea0SLionel Sambuc       /* test mp_is_square false negatives */
152ebfedea0SLionel Sambuc       n = (rand() & 7) + 1;
153ebfedea0SLionel Sambuc       mp_rand(&a, n);
154ebfedea0SLionel Sambuc       mp_sqr(&a, &a);
155ebfedea0SLionel Sambuc       if (mp_is_square(&a, &n) != MP_OKAY) {
156ebfedea0SLionel Sambuc 	 printf("fn:mp_is_square() error!\n");
157ebfedea0SLionel Sambuc 	 return 1;
158ebfedea0SLionel Sambuc       }
159ebfedea0SLionel Sambuc       if (n == 0) {
160ebfedea0SLionel Sambuc 	 printf("fn:mp_is_square() bad result!\n");
161ebfedea0SLionel Sambuc 	 return 1;
162ebfedea0SLionel Sambuc       }
163ebfedea0SLionel Sambuc 
164ebfedea0SLionel Sambuc       /* test for false positives */
165ebfedea0SLionel Sambuc       mp_add_d(&a, 1, &a);
166ebfedea0SLionel Sambuc       if (mp_is_square(&a, &n) != MP_OKAY) {
167ebfedea0SLionel Sambuc 	 printf("fp:mp_is_square() error!\n");
168ebfedea0SLionel Sambuc 	 return 1;
169ebfedea0SLionel Sambuc       }
170ebfedea0SLionel Sambuc       if (n == 1) {
171ebfedea0SLionel Sambuc 	 printf("fp:mp_is_square() bad result!\n");
172ebfedea0SLionel Sambuc 	 return 1;
173ebfedea0SLionel Sambuc       }
174ebfedea0SLionel Sambuc 
175ebfedea0SLionel Sambuc    }
176ebfedea0SLionel Sambuc    printf("\n\n");
177ebfedea0SLionel Sambuc 
178ebfedea0SLionel Sambuc    /* test for size */
179ebfedea0SLionel Sambuc    for (ix = 10; ix < 128; ix++) {
180ebfedea0SLionel Sambuc       printf("Testing (not safe-prime): %9d bits    \r", ix);
181ebfedea0SLionel Sambuc       fflush(stdout);
182ebfedea0SLionel Sambuc       err =
183ebfedea0SLionel Sambuc 	 mp_prime_random_ex(&a, 8, ix,
184ebfedea0SLionel Sambuc 			    (rand() & 1) ? LTM_PRIME_2MSB_OFF :
185ebfedea0SLionel Sambuc 			    LTM_PRIME_2MSB_ON, myrng, NULL);
186ebfedea0SLionel Sambuc       if (err != MP_OKAY) {
187ebfedea0SLionel Sambuc 	 printf("failed with err code %d\n", err);
188ebfedea0SLionel Sambuc 	 return EXIT_FAILURE;
189ebfedea0SLionel Sambuc       }
190ebfedea0SLionel Sambuc       if (mp_count_bits(&a) != ix) {
191ebfedea0SLionel Sambuc 	 printf("Prime is %d not %d bits!!!\n", mp_count_bits(&a), ix);
192ebfedea0SLionel Sambuc 	 return EXIT_FAILURE;
193ebfedea0SLionel Sambuc       }
194ebfedea0SLionel Sambuc    }
195ebfedea0SLionel Sambuc 
196ebfedea0SLionel Sambuc    for (ix = 16; ix < 128; ix++) {
197ebfedea0SLionel Sambuc       printf("Testing (   safe-prime): %9d bits    \r", ix);
198ebfedea0SLionel Sambuc       fflush(stdout);
199ebfedea0SLionel Sambuc       err =
200ebfedea0SLionel Sambuc 	 mp_prime_random_ex(&a, 8, ix,
201ebfedea0SLionel Sambuc 			    ((rand() & 1) ? LTM_PRIME_2MSB_OFF :
202ebfedea0SLionel Sambuc 			     LTM_PRIME_2MSB_ON) | LTM_PRIME_SAFE, myrng,
203ebfedea0SLionel Sambuc 			    NULL);
204ebfedea0SLionel Sambuc       if (err != MP_OKAY) {
205ebfedea0SLionel Sambuc 	 printf("failed with err code %d\n", err);
206ebfedea0SLionel Sambuc 	 return EXIT_FAILURE;
207ebfedea0SLionel Sambuc       }
208ebfedea0SLionel Sambuc       if (mp_count_bits(&a) != ix) {
209ebfedea0SLionel Sambuc 	 printf("Prime is %d not %d bits!!!\n", mp_count_bits(&a), ix);
210ebfedea0SLionel Sambuc 	 return EXIT_FAILURE;
211ebfedea0SLionel Sambuc       }
212ebfedea0SLionel Sambuc       /* let's see if it's really a safe prime */
213ebfedea0SLionel Sambuc       mp_sub_d(&a, 1, &a);
214ebfedea0SLionel Sambuc       mp_div_2(&a, &a);
215ebfedea0SLionel Sambuc       mp_prime_is_prime(&a, 8, &cnt);
216ebfedea0SLionel Sambuc       if (cnt != MP_YES) {
217ebfedea0SLionel Sambuc 	 printf("sub is not prime!\n");
218ebfedea0SLionel Sambuc 	 return EXIT_FAILURE;
219ebfedea0SLionel Sambuc       }
220ebfedea0SLionel Sambuc    }
221ebfedea0SLionel Sambuc 
222ebfedea0SLionel Sambuc    printf("\n\n");
223ebfedea0SLionel Sambuc 
224ebfedea0SLionel Sambuc    mp_read_radix(&a, "123456", 10);
225ebfedea0SLionel Sambuc    mp_toradix_n(&a, buf, 10, 3);
226ebfedea0SLionel Sambuc    printf("a == %s\n", buf);
227ebfedea0SLionel Sambuc    mp_toradix_n(&a, buf, 10, 4);
228ebfedea0SLionel Sambuc    printf("a == %s\n", buf);
229ebfedea0SLionel Sambuc    mp_toradix_n(&a, buf, 10, 30);
230ebfedea0SLionel Sambuc    printf("a == %s\n", buf);
231ebfedea0SLionel Sambuc 
232ebfedea0SLionel Sambuc 
233ebfedea0SLionel Sambuc #if 0
234ebfedea0SLionel Sambuc    for (;;) {
235ebfedea0SLionel Sambuc       fgets(buf, sizeof(buf), stdin);
236ebfedea0SLionel Sambuc       mp_read_radix(&a, buf, 10);
237ebfedea0SLionel Sambuc       mp_prime_next_prime(&a, 5, 1);
238ebfedea0SLionel Sambuc       mp_toradix(&a, buf, 10);
239ebfedea0SLionel Sambuc       printf("%s, %lu\n", buf, a.dp[0] & 3);
240ebfedea0SLionel Sambuc    }
241ebfedea0SLionel Sambuc #endif
242ebfedea0SLionel Sambuc 
243ebfedea0SLionel Sambuc    /* test mp_cnt_lsb */
244ebfedea0SLionel Sambuc    printf("testing mp_cnt_lsb...\n");
245ebfedea0SLionel Sambuc    mp_set(&a, 1);
246ebfedea0SLionel Sambuc    for (ix = 0; ix < 1024; ix++) {
247ebfedea0SLionel Sambuc       if (mp_cnt_lsb(&a) != ix) {
248ebfedea0SLionel Sambuc 	 printf("Failed at %d, %d\n", ix, mp_cnt_lsb(&a));
249ebfedea0SLionel Sambuc 	 return 0;
250ebfedea0SLionel Sambuc       }
251ebfedea0SLionel Sambuc       mp_mul_2(&a, &a);
252ebfedea0SLionel Sambuc    }
253ebfedea0SLionel Sambuc 
254ebfedea0SLionel Sambuc /* test mp_reduce_2k */
255ebfedea0SLionel Sambuc    printf("Testing mp_reduce_2k...\n");
256ebfedea0SLionel Sambuc    for (cnt = 3; cnt <= 128; ++cnt) {
257ebfedea0SLionel Sambuc       mp_digit tmp;
258ebfedea0SLionel Sambuc 
259ebfedea0SLionel Sambuc       mp_2expt(&a, cnt);
260ebfedea0SLionel Sambuc       mp_sub_d(&a, 2, &a);	/* a = 2**cnt - 2 */
261ebfedea0SLionel Sambuc 
262ebfedea0SLionel Sambuc 
263ebfedea0SLionel Sambuc       printf("\nTesting %4d bits", cnt);
264ebfedea0SLionel Sambuc       printf("(%d)", mp_reduce_is_2k(&a));
265ebfedea0SLionel Sambuc       mp_reduce_2k_setup(&a, &tmp);
266ebfedea0SLionel Sambuc       printf("(%d)", tmp);
267ebfedea0SLionel Sambuc       for (ix = 0; ix < 1000; ix++) {
268ebfedea0SLionel Sambuc 	 if (!(ix & 127)) {
269ebfedea0SLionel Sambuc 	    printf(".");
270ebfedea0SLionel Sambuc 	    fflush(stdout);
271ebfedea0SLionel Sambuc 	 }
272ebfedea0SLionel Sambuc 	 mp_rand(&b, (cnt / DIGIT_BIT + 1) * 2);
273ebfedea0SLionel Sambuc 	 mp_copy(&c, &b);
274ebfedea0SLionel Sambuc 	 mp_mod(&c, &a, &c);
275ebfedea0SLionel Sambuc 	 mp_reduce_2k(&b, &a, 2);
276ebfedea0SLionel Sambuc 	 if (mp_cmp(&c, &b)) {
277ebfedea0SLionel Sambuc 	    printf("FAILED\n");
278ebfedea0SLionel Sambuc 	    exit(0);
279ebfedea0SLionel Sambuc 	 }
280ebfedea0SLionel Sambuc       }
281ebfedea0SLionel Sambuc    }
282ebfedea0SLionel Sambuc 
283ebfedea0SLionel Sambuc /* test mp_div_3  */
284ebfedea0SLionel Sambuc    printf("Testing mp_div_3...\n");
285ebfedea0SLionel Sambuc    mp_set(&d, 3);
286ebfedea0SLionel Sambuc    for (cnt = 0; cnt < 10000;) {
287ebfedea0SLionel Sambuc       mp_digit r1, r2;
288ebfedea0SLionel Sambuc 
289ebfedea0SLionel Sambuc       if (!(++cnt & 127))
290ebfedea0SLionel Sambuc 	 printf("%9d\r", cnt);
291ebfedea0SLionel Sambuc       mp_rand(&a, abs(rand()) % 128 + 1);
292ebfedea0SLionel Sambuc       mp_div(&a, &d, &b, &e);
293ebfedea0SLionel Sambuc       mp_div_3(&a, &c, &r2);
294ebfedea0SLionel Sambuc 
295ebfedea0SLionel Sambuc       if (mp_cmp(&b, &c) || mp_cmp_d(&e, r2)) {
296ebfedea0SLionel Sambuc 	 printf("\n\nmp_div_3 => Failure\n");
297ebfedea0SLionel Sambuc       }
298ebfedea0SLionel Sambuc    }
299ebfedea0SLionel Sambuc    printf("\n\nPassed div_3 testing\n");
300ebfedea0SLionel Sambuc 
301ebfedea0SLionel Sambuc /* test the DR reduction */
302ebfedea0SLionel Sambuc    printf("testing mp_dr_reduce...\n");
303ebfedea0SLionel Sambuc    for (cnt = 2; cnt < 32; cnt++) {
304ebfedea0SLionel Sambuc       printf("%d digit modulus\n", cnt);
305ebfedea0SLionel Sambuc       mp_grow(&a, cnt);
306ebfedea0SLionel Sambuc       mp_zero(&a);
307ebfedea0SLionel Sambuc       for (ix = 1; ix < cnt; ix++) {
308ebfedea0SLionel Sambuc 	 a.dp[ix] = MP_MASK;
309ebfedea0SLionel Sambuc       }
310ebfedea0SLionel Sambuc       a.used = cnt;
311ebfedea0SLionel Sambuc       a.dp[0] = 3;
312ebfedea0SLionel Sambuc 
313ebfedea0SLionel Sambuc       mp_rand(&b, cnt - 1);
314ebfedea0SLionel Sambuc       mp_copy(&b, &c);
315ebfedea0SLionel Sambuc 
316ebfedea0SLionel Sambuc       rr = 0;
317ebfedea0SLionel Sambuc       do {
318ebfedea0SLionel Sambuc 	 if (!(rr & 127)) {
319ebfedea0SLionel Sambuc 	    printf("%9lu\r", rr);
320ebfedea0SLionel Sambuc 	    fflush(stdout);
321ebfedea0SLionel Sambuc 	 }
322ebfedea0SLionel Sambuc 	 mp_sqr(&b, &b);
323ebfedea0SLionel Sambuc 	 mp_add_d(&b, 1, &b);
324ebfedea0SLionel Sambuc 	 mp_copy(&b, &c);
325ebfedea0SLionel Sambuc 
326ebfedea0SLionel Sambuc 	 mp_mod(&b, &a, &b);
327ebfedea0SLionel Sambuc 	 mp_dr_reduce(&c, &a, (((mp_digit) 1) << DIGIT_BIT) - a.dp[0]);
328ebfedea0SLionel Sambuc 
329ebfedea0SLionel Sambuc 	 if (mp_cmp(&b, &c) != MP_EQ) {
330ebfedea0SLionel Sambuc 	    printf("Failed on trial %lu\n", rr);
331ebfedea0SLionel Sambuc 	    exit(-1);
332ebfedea0SLionel Sambuc 
333ebfedea0SLionel Sambuc 	 }
334ebfedea0SLionel Sambuc       } while (++rr < 500);
335ebfedea0SLionel Sambuc       printf("Passed DR test for %d digits\n", cnt);
336ebfedea0SLionel Sambuc    }
337ebfedea0SLionel Sambuc 
338ebfedea0SLionel Sambuc #endif
339ebfedea0SLionel Sambuc 
340ebfedea0SLionel Sambuc /* test the mp_reduce_2k_l code */
341ebfedea0SLionel Sambuc #if 0
342ebfedea0SLionel Sambuc #if 0
343ebfedea0SLionel Sambuc /* first load P with 2^1024 - 0x2A434 B9FDEC95 D8F9D550 FFFFFFFF FFFFFFFF */
344ebfedea0SLionel Sambuc    mp_2expt(&a, 1024);
345ebfedea0SLionel Sambuc    mp_read_radix(&b, "2A434B9FDEC95D8F9D550FFFFFFFFFFFFFFFF", 16);
346ebfedea0SLionel Sambuc    mp_sub(&a, &b, &a);
347ebfedea0SLionel Sambuc #elif 1
348ebfedea0SLionel Sambuc /*  p = 2^2048 - 0x1 00000000 00000000 00000000 00000000 4945DDBF 8EA2A91D 5776399B B83E188F  */
349ebfedea0SLionel Sambuc    mp_2expt(&a, 2048);
350ebfedea0SLionel Sambuc    mp_read_radix(&b,
351ebfedea0SLionel Sambuc 		 "1000000000000000000000000000000004945DDBF8EA2A91D5776399BB83E188F",
352ebfedea0SLionel Sambuc 		 16);
353ebfedea0SLionel Sambuc    mp_sub(&a, &b, &a);
354ebfedea0SLionel Sambuc #endif
355ebfedea0SLionel Sambuc 
356ebfedea0SLionel Sambuc    mp_todecimal(&a, buf);
357ebfedea0SLionel Sambuc    printf("p==%s\n", buf);
358ebfedea0SLionel Sambuc /* now mp_reduce_is_2k_l() should return */
359ebfedea0SLionel Sambuc    if (mp_reduce_is_2k_l(&a) != 1) {
360ebfedea0SLionel Sambuc       printf("mp_reduce_is_2k_l() return 0, should be 1\n");
361ebfedea0SLionel Sambuc       return EXIT_FAILURE;
362ebfedea0SLionel Sambuc    }
363ebfedea0SLionel Sambuc    mp_reduce_2k_setup_l(&a, &d);
364ebfedea0SLionel Sambuc    /* now do a million square+1 to see if it varies */
365ebfedea0SLionel Sambuc    mp_rand(&b, 64);
366ebfedea0SLionel Sambuc    mp_mod(&b, &a, &b);
367ebfedea0SLionel Sambuc    mp_copy(&b, &c);
368ebfedea0SLionel Sambuc    printf("testing mp_reduce_2k_l...");
369ebfedea0SLionel Sambuc    fflush(stdout);
370ebfedea0SLionel Sambuc    for (cnt = 0; cnt < (1UL << 20); cnt++) {
371ebfedea0SLionel Sambuc       mp_sqr(&b, &b);
372ebfedea0SLionel Sambuc       mp_add_d(&b, 1, &b);
373ebfedea0SLionel Sambuc       mp_reduce_2k_l(&b, &a, &d);
374ebfedea0SLionel Sambuc       mp_sqr(&c, &c);
375ebfedea0SLionel Sambuc       mp_add_d(&c, 1, &c);
376ebfedea0SLionel Sambuc       mp_mod(&c, &a, &c);
377ebfedea0SLionel Sambuc       if (mp_cmp(&b, &c) != MP_EQ) {
378ebfedea0SLionel Sambuc 	 printf("mp_reduce_2k_l() failed at step %lu\n", cnt);
379ebfedea0SLionel Sambuc 	 mp_tohex(&b, buf);
380ebfedea0SLionel Sambuc 	 printf("b == %s\n", buf);
381ebfedea0SLionel Sambuc 	 mp_tohex(&c, buf);
382ebfedea0SLionel Sambuc 	 printf("c == %s\n", buf);
383ebfedea0SLionel Sambuc 	 return EXIT_FAILURE;
384ebfedea0SLionel Sambuc       }
385ebfedea0SLionel Sambuc    }
386ebfedea0SLionel Sambuc    printf("...Passed\n");
387ebfedea0SLionel Sambuc #endif
388ebfedea0SLionel Sambuc 
389ebfedea0SLionel Sambuc    div2_n = mul2_n = inv_n = expt_n = lcm_n = gcd_n = add_n =
390ebfedea0SLionel Sambuc       sub_n = mul_n = div_n = sqr_n = mul2d_n = div2d_n = cnt = add_d_n =
391ebfedea0SLionel Sambuc       sub_d_n = 0;
392ebfedea0SLionel Sambuc 
393ebfedea0SLionel Sambuc    /* force KARA and TOOM to enable despite cutoffs */
394ebfedea0SLionel Sambuc    KARATSUBA_SQR_CUTOFF = KARATSUBA_MUL_CUTOFF = 8;
395ebfedea0SLionel Sambuc    TOOM_SQR_CUTOFF = TOOM_MUL_CUTOFF = 16;
396ebfedea0SLionel Sambuc 
397ebfedea0SLionel Sambuc    for (;;) {
398ebfedea0SLionel Sambuc       /* randomly clear and re-init one variable, this has the affect of triming the alloc space */
399ebfedea0SLionel Sambuc       switch (abs(rand()) % 7) {
400ebfedea0SLionel Sambuc       case 0:
401ebfedea0SLionel Sambuc 	 mp_clear(&a);
402ebfedea0SLionel Sambuc 	 mp_init(&a);
403ebfedea0SLionel Sambuc 	 break;
404ebfedea0SLionel Sambuc       case 1:
405ebfedea0SLionel Sambuc 	 mp_clear(&b);
406ebfedea0SLionel Sambuc 	 mp_init(&b);
407ebfedea0SLionel Sambuc 	 break;
408ebfedea0SLionel Sambuc       case 2:
409ebfedea0SLionel Sambuc 	 mp_clear(&c);
410ebfedea0SLionel Sambuc 	 mp_init(&c);
411ebfedea0SLionel Sambuc 	 break;
412ebfedea0SLionel Sambuc       case 3:
413ebfedea0SLionel Sambuc 	 mp_clear(&d);
414ebfedea0SLionel Sambuc 	 mp_init(&d);
415ebfedea0SLionel Sambuc 	 break;
416ebfedea0SLionel Sambuc       case 4:
417ebfedea0SLionel Sambuc 	 mp_clear(&e);
418ebfedea0SLionel Sambuc 	 mp_init(&e);
419ebfedea0SLionel Sambuc 	 break;
420ebfedea0SLionel Sambuc       case 5:
421ebfedea0SLionel Sambuc 	 mp_clear(&f);
422ebfedea0SLionel Sambuc 	 mp_init(&f);
423ebfedea0SLionel Sambuc 	 break;
424ebfedea0SLionel Sambuc       case 6:
425ebfedea0SLionel Sambuc 	 break;			/* don't clear any */
426ebfedea0SLionel Sambuc       }
427ebfedea0SLionel Sambuc 
428ebfedea0SLionel Sambuc 
429ebfedea0SLionel Sambuc       printf
430ebfedea0SLionel Sambuc 	 ("%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu ",
431ebfedea0SLionel Sambuc 	  add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, gcd_n, lcm_n,
432ebfedea0SLionel Sambuc 	  expt_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n);
433ebfedea0SLionel Sambuc       fgets(cmd, 4095, stdin);
434ebfedea0SLionel Sambuc       cmd[strlen(cmd) - 1] = 0;
435ebfedea0SLionel Sambuc       printf("%s  ]\r", cmd);
436ebfedea0SLionel Sambuc       fflush(stdout);
437ebfedea0SLionel Sambuc       if (!strcmp(cmd, "mul2d")) {
438ebfedea0SLionel Sambuc 	 ++mul2d_n;
439ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
440ebfedea0SLionel Sambuc 	 mp_read_radix(&a, buf, 64);
441ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
442ebfedea0SLionel Sambuc 	 sscanf(buf, "%d", &rr);
443ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
444ebfedea0SLionel Sambuc 	 mp_read_radix(&b, buf, 64);
445ebfedea0SLionel Sambuc 
446ebfedea0SLionel Sambuc 	 mp_mul_2d(&a, rr, &a);
447ebfedea0SLionel Sambuc 	 a.sign = b.sign;
448ebfedea0SLionel Sambuc 	 if (mp_cmp(&a, &b) != MP_EQ) {
449ebfedea0SLionel Sambuc 	    printf("mul2d failed, rr == %d\n", rr);
450ebfedea0SLionel Sambuc 	    draw(&a);
451ebfedea0SLionel Sambuc 	    draw(&b);
452ebfedea0SLionel Sambuc 	    return 0;
453ebfedea0SLionel Sambuc 	 }
454ebfedea0SLionel Sambuc       } else if (!strcmp(cmd, "div2d")) {
455ebfedea0SLionel Sambuc 	 ++div2d_n;
456ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
457ebfedea0SLionel Sambuc 	 mp_read_radix(&a, buf, 64);
458ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
459ebfedea0SLionel Sambuc 	 sscanf(buf, "%d", &rr);
460ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
461ebfedea0SLionel Sambuc 	 mp_read_radix(&b, buf, 64);
462ebfedea0SLionel Sambuc 
463ebfedea0SLionel Sambuc 	 mp_div_2d(&a, rr, &a, &e);
464ebfedea0SLionel Sambuc 	 a.sign = b.sign;
465ebfedea0SLionel Sambuc 	 if (a.used == b.used && a.used == 0) {
466ebfedea0SLionel Sambuc 	    a.sign = b.sign = MP_ZPOS;
467ebfedea0SLionel Sambuc 	 }
468ebfedea0SLionel Sambuc 	 if (mp_cmp(&a, &b) != MP_EQ) {
469ebfedea0SLionel Sambuc 	    printf("div2d failed, rr == %d\n", rr);
470ebfedea0SLionel Sambuc 	    draw(&a);
471ebfedea0SLionel Sambuc 	    draw(&b);
472ebfedea0SLionel Sambuc 	    return 0;
473ebfedea0SLionel Sambuc 	 }
474ebfedea0SLionel Sambuc       } else if (!strcmp(cmd, "add")) {
475ebfedea0SLionel Sambuc 	 ++add_n;
476ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
477ebfedea0SLionel Sambuc 	 mp_read_radix(&a, buf, 64);
478ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
479ebfedea0SLionel Sambuc 	 mp_read_radix(&b, buf, 64);
480ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
481ebfedea0SLionel Sambuc 	 mp_read_radix(&c, buf, 64);
482ebfedea0SLionel Sambuc 	 mp_copy(&a, &d);
483ebfedea0SLionel Sambuc 	 mp_add(&d, &b, &d);
484ebfedea0SLionel Sambuc 	 if (mp_cmp(&c, &d) != MP_EQ) {
485ebfedea0SLionel Sambuc 	    printf("add %lu failure!\n", add_n);
486ebfedea0SLionel Sambuc 	    draw(&a);
487ebfedea0SLionel Sambuc 	    draw(&b);
488ebfedea0SLionel Sambuc 	    draw(&c);
489ebfedea0SLionel Sambuc 	    draw(&d);
490ebfedea0SLionel Sambuc 	    return 0;
491ebfedea0SLionel Sambuc 	 }
492ebfedea0SLionel Sambuc 
493ebfedea0SLionel Sambuc 	 /* test the sign/unsigned storage functions */
494ebfedea0SLionel Sambuc 
495ebfedea0SLionel Sambuc 	 rr = mp_signed_bin_size(&c);
496ebfedea0SLionel Sambuc 	 mp_to_signed_bin(&c, (unsigned char *) cmd);
497ebfedea0SLionel Sambuc 	 memset(cmd + rr, rand() & 255, sizeof(cmd) - rr);
498ebfedea0SLionel Sambuc 	 mp_read_signed_bin(&d, (unsigned char *) cmd, rr);
499ebfedea0SLionel Sambuc 	 if (mp_cmp(&c, &d) != MP_EQ) {
500ebfedea0SLionel Sambuc 	    printf("mp_signed_bin failure!\n");
501ebfedea0SLionel Sambuc 	    draw(&c);
502ebfedea0SLionel Sambuc 	    draw(&d);
503ebfedea0SLionel Sambuc 	    return 0;
504ebfedea0SLionel Sambuc 	 }
505ebfedea0SLionel Sambuc 
506ebfedea0SLionel Sambuc 
507ebfedea0SLionel Sambuc 	 rr = mp_unsigned_bin_size(&c);
508ebfedea0SLionel Sambuc 	 mp_to_unsigned_bin(&c, (unsigned char *) cmd);
509ebfedea0SLionel Sambuc 	 memset(cmd + rr, rand() & 255, sizeof(cmd) - rr);
510ebfedea0SLionel Sambuc 	 mp_read_unsigned_bin(&d, (unsigned char *) cmd, rr);
511ebfedea0SLionel Sambuc 	 if (mp_cmp_mag(&c, &d) != MP_EQ) {
512ebfedea0SLionel Sambuc 	    printf("mp_unsigned_bin failure!\n");
513ebfedea0SLionel Sambuc 	    draw(&c);
514ebfedea0SLionel Sambuc 	    draw(&d);
515ebfedea0SLionel Sambuc 	    return 0;
516ebfedea0SLionel Sambuc 	 }
517ebfedea0SLionel Sambuc 
518ebfedea0SLionel Sambuc       } else if (!strcmp(cmd, "sub")) {
519ebfedea0SLionel Sambuc 	 ++sub_n;
520ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
521ebfedea0SLionel Sambuc 	 mp_read_radix(&a, buf, 64);
522ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
523ebfedea0SLionel Sambuc 	 mp_read_radix(&b, buf, 64);
524ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
525ebfedea0SLionel Sambuc 	 mp_read_radix(&c, buf, 64);
526ebfedea0SLionel Sambuc 	 mp_copy(&a, &d);
527ebfedea0SLionel Sambuc 	 mp_sub(&d, &b, &d);
528ebfedea0SLionel Sambuc 	 if (mp_cmp(&c, &d) != MP_EQ) {
529ebfedea0SLionel Sambuc 	    printf("sub %lu failure!\n", sub_n);
530ebfedea0SLionel Sambuc 	    draw(&a);
531ebfedea0SLionel Sambuc 	    draw(&b);
532ebfedea0SLionel Sambuc 	    draw(&c);
533ebfedea0SLionel Sambuc 	    draw(&d);
534ebfedea0SLionel Sambuc 	    return 0;
535ebfedea0SLionel Sambuc 	 }
536ebfedea0SLionel Sambuc       } else if (!strcmp(cmd, "mul")) {
537ebfedea0SLionel Sambuc 	 ++mul_n;
538ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
539ebfedea0SLionel Sambuc 	 mp_read_radix(&a, buf, 64);
540ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
541ebfedea0SLionel Sambuc 	 mp_read_radix(&b, buf, 64);
542ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
543ebfedea0SLionel Sambuc 	 mp_read_radix(&c, buf, 64);
544ebfedea0SLionel Sambuc 	 mp_copy(&a, &d);
545ebfedea0SLionel Sambuc 	 mp_mul(&d, &b, &d);
546ebfedea0SLionel Sambuc 	 if (mp_cmp(&c, &d) != MP_EQ) {
547ebfedea0SLionel Sambuc 	    printf("mul %lu failure!\n", mul_n);
548ebfedea0SLionel Sambuc 	    draw(&a);
549ebfedea0SLionel Sambuc 	    draw(&b);
550ebfedea0SLionel Sambuc 	    draw(&c);
551ebfedea0SLionel Sambuc 	    draw(&d);
552ebfedea0SLionel Sambuc 	    return 0;
553ebfedea0SLionel Sambuc 	 }
554ebfedea0SLionel Sambuc       } else if (!strcmp(cmd, "div")) {
555ebfedea0SLionel Sambuc 	 ++div_n;
556ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
557ebfedea0SLionel Sambuc 	 mp_read_radix(&a, buf, 64);
558ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
559ebfedea0SLionel Sambuc 	 mp_read_radix(&b, buf, 64);
560ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
561ebfedea0SLionel Sambuc 	 mp_read_radix(&c, buf, 64);
562ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
563ebfedea0SLionel Sambuc 	 mp_read_radix(&d, buf, 64);
564ebfedea0SLionel Sambuc 
565ebfedea0SLionel Sambuc 	 mp_div(&a, &b, &e, &f);
566ebfedea0SLionel Sambuc 	 if (mp_cmp(&c, &e) != MP_EQ || mp_cmp(&d, &f) != MP_EQ) {
567ebfedea0SLionel Sambuc 	    printf("div %lu %d, %d, failure!\n", div_n, mp_cmp(&c, &e),
568ebfedea0SLionel Sambuc 		   mp_cmp(&d, &f));
569ebfedea0SLionel Sambuc 	    draw(&a);
570ebfedea0SLionel Sambuc 	    draw(&b);
571ebfedea0SLionel Sambuc 	    draw(&c);
572ebfedea0SLionel Sambuc 	    draw(&d);
573ebfedea0SLionel Sambuc 	    draw(&e);
574ebfedea0SLionel Sambuc 	    draw(&f);
575ebfedea0SLionel Sambuc 	    return 0;
576ebfedea0SLionel Sambuc 	 }
577ebfedea0SLionel Sambuc 
578ebfedea0SLionel Sambuc       } else if (!strcmp(cmd, "sqr")) {
579ebfedea0SLionel Sambuc 	 ++sqr_n;
580ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
581ebfedea0SLionel Sambuc 	 mp_read_radix(&a, buf, 64);
582ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
583ebfedea0SLionel Sambuc 	 mp_read_radix(&b, buf, 64);
584ebfedea0SLionel Sambuc 	 mp_copy(&a, &c);
585ebfedea0SLionel Sambuc 	 mp_sqr(&c, &c);
586ebfedea0SLionel Sambuc 	 if (mp_cmp(&b, &c) != MP_EQ) {
587ebfedea0SLionel Sambuc 	    printf("sqr %lu failure!\n", sqr_n);
588ebfedea0SLionel Sambuc 	    draw(&a);
589ebfedea0SLionel Sambuc 	    draw(&b);
590ebfedea0SLionel Sambuc 	    draw(&c);
591ebfedea0SLionel Sambuc 	    return 0;
592ebfedea0SLionel Sambuc 	 }
593ebfedea0SLionel Sambuc       } else if (!strcmp(cmd, "gcd")) {
594ebfedea0SLionel Sambuc 	 ++gcd_n;
595ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
596ebfedea0SLionel Sambuc 	 mp_read_radix(&a, buf, 64);
597ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
598ebfedea0SLionel Sambuc 	 mp_read_radix(&b, buf, 64);
599ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
600ebfedea0SLionel Sambuc 	 mp_read_radix(&c, buf, 64);
601ebfedea0SLionel Sambuc 	 mp_copy(&a, &d);
602ebfedea0SLionel Sambuc 	 mp_gcd(&d, &b, &d);
603ebfedea0SLionel Sambuc 	 d.sign = c.sign;
604ebfedea0SLionel Sambuc 	 if (mp_cmp(&c, &d) != MP_EQ) {
605ebfedea0SLionel Sambuc 	    printf("gcd %lu failure!\n", gcd_n);
606ebfedea0SLionel Sambuc 	    draw(&a);
607ebfedea0SLionel Sambuc 	    draw(&b);
608ebfedea0SLionel Sambuc 	    draw(&c);
609ebfedea0SLionel Sambuc 	    draw(&d);
610ebfedea0SLionel Sambuc 	    return 0;
611ebfedea0SLionel Sambuc 	 }
612ebfedea0SLionel Sambuc       } else if (!strcmp(cmd, "lcm")) {
613ebfedea0SLionel Sambuc 	 ++lcm_n;
614ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
615ebfedea0SLionel Sambuc 	 mp_read_radix(&a, buf, 64);
616ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
617ebfedea0SLionel Sambuc 	 mp_read_radix(&b, buf, 64);
618ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
619ebfedea0SLionel Sambuc 	 mp_read_radix(&c, buf, 64);
620ebfedea0SLionel Sambuc 	 mp_copy(&a, &d);
621ebfedea0SLionel Sambuc 	 mp_lcm(&d, &b, &d);
622ebfedea0SLionel Sambuc 	 d.sign = c.sign;
623ebfedea0SLionel Sambuc 	 if (mp_cmp(&c, &d) != MP_EQ) {
624ebfedea0SLionel Sambuc 	    printf("lcm %lu failure!\n", lcm_n);
625ebfedea0SLionel Sambuc 	    draw(&a);
626ebfedea0SLionel Sambuc 	    draw(&b);
627ebfedea0SLionel Sambuc 	    draw(&c);
628ebfedea0SLionel Sambuc 	    draw(&d);
629ebfedea0SLionel Sambuc 	    return 0;
630ebfedea0SLionel Sambuc 	 }
631ebfedea0SLionel Sambuc       } else if (!strcmp(cmd, "expt")) {
632ebfedea0SLionel Sambuc 	 ++expt_n;
633ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
634ebfedea0SLionel Sambuc 	 mp_read_radix(&a, buf, 64);
635ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
636ebfedea0SLionel Sambuc 	 mp_read_radix(&b, buf, 64);
637ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
638ebfedea0SLionel Sambuc 	 mp_read_radix(&c, buf, 64);
639ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
640ebfedea0SLionel Sambuc 	 mp_read_radix(&d, buf, 64);
641ebfedea0SLionel Sambuc 	 mp_copy(&a, &e);
642ebfedea0SLionel Sambuc 	 mp_exptmod(&e, &b, &c, &e);
643ebfedea0SLionel Sambuc 	 if (mp_cmp(&d, &e) != MP_EQ) {
644ebfedea0SLionel Sambuc 	    printf("expt %lu failure!\n", expt_n);
645ebfedea0SLionel Sambuc 	    draw(&a);
646ebfedea0SLionel Sambuc 	    draw(&b);
647ebfedea0SLionel Sambuc 	    draw(&c);
648ebfedea0SLionel Sambuc 	    draw(&d);
649ebfedea0SLionel Sambuc 	    draw(&e);
650ebfedea0SLionel Sambuc 	    return 0;
651ebfedea0SLionel Sambuc 	 }
652ebfedea0SLionel Sambuc       } else if (!strcmp(cmd, "invmod")) {
653ebfedea0SLionel Sambuc 	 ++inv_n;
654ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
655ebfedea0SLionel Sambuc 	 mp_read_radix(&a, buf, 64);
656ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
657ebfedea0SLionel Sambuc 	 mp_read_radix(&b, buf, 64);
658ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
659ebfedea0SLionel Sambuc 	 mp_read_radix(&c, buf, 64);
660ebfedea0SLionel Sambuc 	 mp_invmod(&a, &b, &d);
661ebfedea0SLionel Sambuc 	 mp_mulmod(&d, &a, &b, &e);
662ebfedea0SLionel Sambuc 	 if (mp_cmp_d(&e, 1) != MP_EQ) {
663ebfedea0SLionel Sambuc 	    printf("inv [wrong value from MPI?!] failure\n");
664ebfedea0SLionel Sambuc 	    draw(&a);
665ebfedea0SLionel Sambuc 	    draw(&b);
666ebfedea0SLionel Sambuc 	    draw(&c);
667ebfedea0SLionel Sambuc 	    draw(&d);
668ebfedea0SLionel Sambuc 	    mp_gcd(&a, &b, &e);
669ebfedea0SLionel Sambuc 	    draw(&e);
670ebfedea0SLionel Sambuc 	    return 0;
671ebfedea0SLionel Sambuc 	 }
672ebfedea0SLionel Sambuc 
673ebfedea0SLionel Sambuc       } else if (!strcmp(cmd, "div2")) {
674ebfedea0SLionel Sambuc 	 ++div2_n;
675ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
676ebfedea0SLionel Sambuc 	 mp_read_radix(&a, buf, 64);
677ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
678ebfedea0SLionel Sambuc 	 mp_read_radix(&b, buf, 64);
679ebfedea0SLionel Sambuc 	 mp_div_2(&a, &c);
680ebfedea0SLionel Sambuc 	 if (mp_cmp(&c, &b) != MP_EQ) {
681ebfedea0SLionel Sambuc 	    printf("div_2 %lu failure\n", div2_n);
682ebfedea0SLionel Sambuc 	    draw(&a);
683ebfedea0SLionel Sambuc 	    draw(&b);
684ebfedea0SLionel Sambuc 	    draw(&c);
685ebfedea0SLionel Sambuc 	    return 0;
686ebfedea0SLionel Sambuc 	 }
687ebfedea0SLionel Sambuc       } else if (!strcmp(cmd, "mul2")) {
688ebfedea0SLionel Sambuc 	 ++mul2_n;
689ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
690ebfedea0SLionel Sambuc 	 mp_read_radix(&a, buf, 64);
691ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
692ebfedea0SLionel Sambuc 	 mp_read_radix(&b, buf, 64);
693ebfedea0SLionel Sambuc 	 mp_mul_2(&a, &c);
694ebfedea0SLionel Sambuc 	 if (mp_cmp(&c, &b) != MP_EQ) {
695ebfedea0SLionel Sambuc 	    printf("mul_2 %lu failure\n", mul2_n);
696ebfedea0SLionel Sambuc 	    draw(&a);
697ebfedea0SLionel Sambuc 	    draw(&b);
698ebfedea0SLionel Sambuc 	    draw(&c);
699ebfedea0SLionel Sambuc 	    return 0;
700ebfedea0SLionel Sambuc 	 }
701ebfedea0SLionel Sambuc       } else if (!strcmp(cmd, "add_d")) {
702ebfedea0SLionel Sambuc 	 ++add_d_n;
703ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
704ebfedea0SLionel Sambuc 	 mp_read_radix(&a, buf, 64);
705ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
706ebfedea0SLionel Sambuc 	 sscanf(buf, "%d", &ix);
707ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
708ebfedea0SLionel Sambuc 	 mp_read_radix(&b, buf, 64);
709ebfedea0SLionel Sambuc 	 mp_add_d(&a, ix, &c);
710ebfedea0SLionel Sambuc 	 if (mp_cmp(&b, &c) != MP_EQ) {
711ebfedea0SLionel Sambuc 	    printf("add_d %lu failure\n", add_d_n);
712ebfedea0SLionel Sambuc 	    draw(&a);
713ebfedea0SLionel Sambuc 	    draw(&b);
714ebfedea0SLionel Sambuc 	    draw(&c);
715ebfedea0SLionel Sambuc 	    printf("d == %d\n", ix);
716ebfedea0SLionel Sambuc 	    return 0;
717ebfedea0SLionel Sambuc 	 }
718ebfedea0SLionel Sambuc       } else if (!strcmp(cmd, "sub_d")) {
719ebfedea0SLionel Sambuc 	 ++sub_d_n;
720ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
721ebfedea0SLionel Sambuc 	 mp_read_radix(&a, buf, 64);
722ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
723ebfedea0SLionel Sambuc 	 sscanf(buf, "%d", &ix);
724ebfedea0SLionel Sambuc 	 fgets(buf, 4095, stdin);
725ebfedea0SLionel Sambuc 	 mp_read_radix(&b, buf, 64);
726ebfedea0SLionel Sambuc 	 mp_sub_d(&a, ix, &c);
727ebfedea0SLionel Sambuc 	 if (mp_cmp(&b, &c) != MP_EQ) {
728ebfedea0SLionel Sambuc 	    printf("sub_d %lu failure\n", sub_d_n);
729ebfedea0SLionel Sambuc 	    draw(&a);
730ebfedea0SLionel Sambuc 	    draw(&b);
731ebfedea0SLionel Sambuc 	    draw(&c);
732ebfedea0SLionel Sambuc 	    printf("d == %d\n", ix);
733ebfedea0SLionel Sambuc 	    return 0;
734ebfedea0SLionel Sambuc 	 }
735ebfedea0SLionel Sambuc       }
736ebfedea0SLionel Sambuc    }
737ebfedea0SLionel Sambuc    return 0;
738ebfedea0SLionel Sambuc }
739ebfedea0SLionel Sambuc 
740ebfedea0SLionel Sambuc /* Source: /cvs/libtom/libtommath/demo/demo.c,v  */
741ebfedea0SLionel Sambuc /* Revision: 1.3  */
742ebfedea0SLionel Sambuc /* Date: 2005/06/24 11:32:07  */
743