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