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