]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 A |
1 | /************************************************************** |
2 | * | |
3 | * factor.c | |
4 | * | |
5 | * General purpose factoring program | |
6 | * | |
7 | * Updates: | |
8 | * 18 May 97 REC - invoked new, fast divide functions | |
9 | * 26 Apr 97 RDW - fixed tabs and unix EOL | |
10 | * 20 Apr 97 RDW - conversion to TC4.5 | |
11 | * | |
12 | * c. 1997 Perfectly Scientific, Inc. | |
13 | * All Rights Reserved. | |
14 | * | |
15 | * | |
16 | *************************************************************/ | |
17 | ||
18 | /* include files */ | |
19 | ||
20 | #include <stdio.h> | |
21 | #include <math.h> | |
22 | #include <stdlib.h> | |
23 | #include <time.h> | |
24 | #ifdef _WIN32 | |
25 | ||
26 | #include <process.h> | |
27 | ||
28 | #endif | |
29 | ||
30 | #include <string.h> | |
31 | #include "giants.h" | |
32 | ||
33 | ||
34 | /* definitions */ | |
35 | ||
36 | #define D 100 | |
37 | #define NUM_PRIMES 6542 /* PrimePi[2^16]. */ | |
38 | ||
39 | ||
40 | /* compiler options */ | |
41 | ||
42 | #ifdef _WIN32 | |
43 | #pragma warning( disable : 4127 4706 ) /* disable conditional is constant warning */ | |
44 | #endif | |
45 | ||
46 | ||
47 | /* global variables */ | |
48 | ||
49 | extern giant scratch2; | |
50 | int pr[NUM_PRIMES]; | |
51 | giant xr = NULL, xs = NULL, zs = NULL, zr = NULL, xorg = NULL, | |
52 | zorg = NULL, t1 = NULL, t2 = NULL, t3 = NULL, N = NULL, | |
53 | gg = NULL, An = NULL, Ad = NULL; | |
54 | giant xb[D+2], zb[D+2], xzb[D+2]; | |
55 | int modmode = 0, Q, modcount = 0; | |
56 | ||
57 | ||
58 | /* function prototypes */ | |
59 | ||
60 | void ell_even(giant x1, giant z1, giant x2, giant z2, giant An, | |
61 | giant Ad, giant N); | |
62 | void ell_odd(giant x1, giant z1, giant x2, giant z2, giant xor, | |
63 | giant zor, giant N); | |
64 | void ell_mul(giant xx, giant zz, int n, giant An, giant Ad, giant N); | |
65 | int least_2(int n); | |
66 | void dot(void); | |
67 | int psi_rand(); | |
68 | ||
69 | ||
70 | /************************************************************** | |
71 | * | |
72 | * Functions | |
73 | * | |
74 | **************************************************************/ | |
75 | ||
76 | ||
77 | int | |
78 | psi_rand( | |
79 | void | |
80 | ) | |
81 | { | |
82 | unsigned short hi; | |
83 | unsigned short low; | |
84 | time_t tp; | |
85 | int result; | |
86 | ||
87 | time(&tp); | |
88 | low = (unsigned short)rand(); | |
89 | hi = (unsigned short)rand(); | |
90 | result = ((hi << 16) | low) ^ ((int)tp); | |
91 | ||
92 | return (result & 0x7fffffff); | |
93 | } | |
94 | ||
95 | ||
96 | void | |
97 | set_random_seed( | |
98 | void | |
99 | ) | |
100 | { | |
101 | /* Start the random number generator at a new position. */ | |
102 | time_t tp; | |
103 | ||
104 | time(&tp); | |
105 | srand((int)tp + (int)getpid()); | |
106 | } | |
107 | ||
108 | ||
109 | int | |
110 | isprime( | |
111 | int odd | |
112 | ) | |
113 | { | |
114 | int j; | |
115 | int p; | |
116 | ||
117 | for (j=1; ; j++) | |
118 | { | |
119 | p = pr[j]; | |
120 | if (p*p > odd) | |
121 | return(1); | |
122 | if (odd % p == 0) | |
123 | return(0); | |
124 | } | |
125 | } | |
126 | ||
127 | ||
128 | int | |
129 | primeq( | |
130 | int p | |
131 | ) | |
132 | { | |
133 | register int j=3; | |
134 | ||
135 | if ((p&1)==0) | |
136 | return ((p==2)?1:0); | |
137 | if (j>=p) | |
138 | return (1); | |
139 | while ((p%j)!=0) | |
140 | { | |
141 | j+=2; | |
142 | if (j*j>p) | |
143 | return(1); | |
144 | } | |
145 | return(0); | |
146 | } | |
147 | ||
148 | ||
149 | void | |
150 | s_modg( | |
151 | giant N, | |
152 | giant t | |
153 | ) | |
154 | { | |
155 | ++modcount; | |
156 | switch (modmode) | |
157 | { | |
158 | case 0: | |
159 | modg(N, t); | |
160 | break; | |
161 | case -1: | |
162 | mersennemod(Q, t); | |
163 | break; | |
164 | case 1: | |
165 | fermatmod(Q, t); | |
166 | break; | |
167 | } | |
168 | } | |
169 | ||
170 | ||
171 | void | |
172 | reset_mod( | |
173 | giant x, | |
174 | giant N | |
175 | ) | |
176 | /* Perform a divide (by the discovered factor) and switch back | |
177 | to non-Fermat-non-Mersenne (i.e. normal) mod mode. */ | |
178 | { | |
179 | divg(x, N); | |
180 | modmode = 0; | |
181 | } | |
182 | ||
183 | void | |
184 | ell_even( | |
185 | giant x1, | |
186 | giant z1, | |
187 | giant x2, | |
188 | giant z2, | |
189 | giant An, | |
190 | giant Ad, | |
191 | giant N | |
192 | ) | |
193 | { | |
194 | gtog(x1, t1); | |
195 | addg(z1, t1); | |
196 | squareg(t1); | |
197 | s_modg(N, t1); | |
198 | gtog(x1, t2); | |
199 | subg(z1, t2); | |
200 | squareg(t2); | |
201 | s_modg(N, t2); | |
202 | gtog(t1, t3); | |
203 | subg(t2, t3); | |
204 | gtog(t2, x2); | |
205 | mulg(t1, x2); | |
206 | gshiftleft(2, x2); | |
207 | s_modg(N, x2); | |
208 | mulg(Ad, x2); | |
209 | s_modg(N, x2); | |
210 | mulg(Ad, t2); | |
211 | gshiftleft(2, t2); | |
212 | s_modg(N, t2); | |
213 | gtog(t3, t1); | |
214 | mulg(An, t1); | |
215 | s_modg(N, t1); | |
216 | addg(t1, t2); | |
217 | mulg(t3, t2); | |
218 | s_modg(N, t2); | |
219 | gtog(t2,z2); | |
220 | } | |
221 | ||
222 | ||
223 | void | |
224 | ell_odd( | |
225 | giant x1, | |
226 | giant z1, | |
227 | giant x2, | |
228 | giant z2, | |
229 | giant xor, | |
230 | giant zor, | |
231 | giant N | |
232 | ) | |
233 | { | |
234 | gtog(x1, t1); | |
235 | subg(z1, t1); | |
236 | gtog(x2, t2); | |
237 | addg(z2, t2); | |
238 | mulg(t1, t2); | |
239 | s_modg(N, t2); | |
240 | gtog(x1, t1); | |
241 | addg(z1, t1); | |
242 | gtog(x2, t3); | |
243 | subg(z2, t3); | |
244 | mulg(t3, t1); | |
245 | s_modg(N, t1); | |
246 | gtog(t2, x2); | |
247 | addg(t1, x2); | |
248 | squareg(x2); | |
249 | s_modg(N, x2); | |
250 | gtog(t2, z2); | |
251 | subg(t1, z2); | |
252 | squareg(z2); | |
253 | s_modg(N, z2); | |
254 | mulg(zor, x2); | |
255 | s_modg(N, x2); | |
256 | mulg(xor, z2); | |
257 | s_modg(N, z2); | |
258 | } | |
259 | ||
260 | ||
261 | void | |
262 | ell_mul( | |
263 | giant xx, | |
264 | giant zz, | |
265 | int n, | |
266 | giant An, | |
267 | giant Ad, | |
268 | giant N | |
269 | ) | |
270 | { | |
271 | unsigned int c = (unsigned int)0x80000000; | |
272 | ||
273 | if (n==1) | |
274 | return; | |
275 | if (n==2) | |
276 | { | |
277 | ell_even(xx, zz, xx, zz, An, Ad, N); | |
278 | return; | |
279 | } | |
280 | gtog(xx, xorg); | |
281 | gtog(zz, zorg); | |
282 | ell_even(xx, zz, xs, zs, An, Ad, N); | |
283 | ||
284 | while((c&n) == 0) | |
285 | { | |
286 | c >>= 1; | |
287 | } | |
288 | ||
289 | c>>=1; | |
290 | do | |
291 | { | |
292 | if (c&n) | |
293 | { | |
294 | ell_odd(xs, zs, xx, zz, xorg, zorg, N); | |
295 | ell_even(xs, zs, xs, zs, An, Ad, N); | |
296 | } | |
297 | else | |
298 | { | |
299 | ell_odd(xx, zz, xs, zs, xorg, zorg, N); | |
300 | ell_even(xx, zz, xx, zz, An, Ad, N); | |
301 | } | |
302 | c >>= 1; | |
303 | } while(c); | |
304 | } | |
305 | ||
306 | ||
307 | ||
308 | /* From R. P. Brent, priv. comm. 1996: | |
309 | Let s > 5 be a pseudo-random seed (called $\sigma$ in the Tech. Report), | |
310 | ||
311 | u/v = (s^2 - 5)/(4s) | |
312 | ||
313 | Then starting point is (x_1, y_1) where | |
314 | ||
315 | x_1 = (u/v)^3 | |
316 | and | |
317 | a = (v-u)^3(3u+v)/(4u^3 v) - 2 | |
318 | */ | |
319 | ||
320 | void | |
321 | choose12( | |
322 | giant x, | |
323 | giant z, | |
324 | int k, | |
325 | giant An, | |
326 | giant Ad, | |
327 | giant N | |
328 | ) | |
329 | { | |
330 | itog(k, zs); | |
331 | gtog(zs, xs); | |
332 | squareg(xs); | |
333 | itog(5, t2); | |
334 | subg(t2, xs); | |
335 | s_modg(N, xs); | |
336 | addg(zs, zs); | |
337 | addg(zs, zs); | |
338 | s_modg(N, zs); | |
339 | gtog(xs, x); | |
340 | squareg(x); | |
341 | s_modg(N, x); | |
342 | mulg(xs, x); | |
343 | s_modg(N, x); | |
344 | gtog(zs, z); | |
345 | squareg(z); | |
346 | s_modg(N, z); | |
347 | mulg(zs, z); | |
348 | s_modg(N, z); | |
349 | ||
350 | /* Now for A. */ | |
351 | gtog(zs, t2); | |
352 | subg(xs, t2); | |
353 | gtog(t2, t3); | |
354 | squareg(t2); | |
355 | s_modg(N, t2); | |
356 | mulg(t3, t2); | |
357 | s_modg(N, t2); /* (v-u)^3. */ | |
358 | gtog(xs, t3); | |
359 | addg(t3, t3); | |
360 | addg(xs, t3); | |
361 | addg(zs, t3); | |
362 | s_modg(N, t3); | |
363 | mulg(t3, t2); | |
364 | s_modg(N, t2); /* (v-u)^3 (3u+v). */ | |
365 | gtog(zs, t3); | |
366 | mulg(xs, t3); | |
367 | s_modg(N, t3); | |
368 | squareg(xs); | |
369 | s_modg(N, xs); | |
370 | mulg(xs, t3); | |
371 | s_modg(N, t3); | |
372 | addg(t3, t3); | |
373 | addg(t3, t3); | |
374 | s_modg(N, t3); | |
375 | gtog(t3, Ad); | |
376 | gtog(t2, An); /* An/Ad is now A + 2. */ | |
377 | } | |
378 | ||
379 | ||
380 | void | |
381 | ensure( | |
382 | int q | |
383 | ) | |
384 | { | |
385 | int nsh, j; | |
386 | ||
387 | N = newgiant(INFINITY); | |
388 | if(!q) | |
389 | { | |
390 | gread(N,stdin); | |
391 | q = bitlen(N) + 1; | |
392 | } | |
393 | nsh = q/4; /* Allowing (easily) enough space per giant, | |
394 | since N is about 2^q, which is q bits, or | |
395 | q/16 shorts. But squaring, etc. is allowed, | |
396 | so we need at least q/8, and we choose q/4 | |
397 | to be conservative. */ | |
398 | if (!xr) | |
399 | xr = newgiant(nsh); | |
400 | if (!zr) | |
401 | zr = newgiant(nsh); | |
402 | if (!xs) | |
403 | xs = newgiant(nsh); | |
404 | if (!zs) | |
405 | zs = newgiant(nsh); | |
406 | if (!xorg) | |
407 | xorg = newgiant(nsh); | |
408 | if (!zorg) | |
409 | zorg = newgiant(nsh); | |
410 | if (!t1) | |
411 | t1 = newgiant(nsh); | |
412 | if (!t2) | |
413 | t2 = newgiant(nsh); | |
414 | if (!t3) | |
415 | t3 = newgiant(nsh); | |
416 | if (!gg) | |
417 | gg = newgiant(nsh); | |
418 | if (!An) | |
419 | An = newgiant(nsh); | |
420 | if (!Ad) | |
421 | Ad = newgiant(nsh); | |
422 | for (j=0;j<D+2;j++) | |
423 | { | |
424 | xb[j] = newgiant(nsh); | |
425 | zb[j] = newgiant(nsh); | |
426 | xzb[j] = newgiant(nsh); | |
427 | } | |
428 | } | |
429 | ||
430 | int | |
431 | bigprimeq( | |
432 | giant x | |
433 | ) | |
434 | { | |
435 | itog(1, t1); | |
436 | gtog(x, t2); | |
437 | subg(t1, t2); | |
438 | itog(5, t1); | |
439 | powermodg(t1, t2, x); | |
440 | if (isone(t1)) | |
441 | return(1); | |
442 | return(0); | |
443 | } | |
444 | ||
445 | ||
446 | void | |
447 | dot( | |
448 | void | |
449 | ) | |
450 | { | |
451 | printf("."); | |
452 | fflush(stdout); | |
453 | } | |
454 | ||
455 | /************************************************************** | |
456 | * | |
457 | * Main Function | |
458 | * | |
459 | **************************************************************/ | |
460 | ||
461 | main( | |
462 | int argc, | |
463 | char *argv[] | |
464 | ) | |
465 | { | |
466 | int j, k, C, nshorts, cnt, count, | |
467 | limitbits = 0, pass, npr, rem; | |
468 | long B; | |
469 | int randmode = 0; | |
470 | ||
471 | if (!strcmp(argv[argc-1], "-r")) | |
472 | { | |
473 | randmode = 1; | |
474 | if (argc > 4) | |
475 | /* This segment only takes effect in random mode. */ | |
476 | limitbits = atoi(argv[argc-2]); | |
477 | } | |
478 | else | |
479 | { | |
480 | randmode = 0; | |
481 | } | |
482 | ||
483 | modmode = 0; | |
484 | if (argc > 2) | |
485 | { | |
486 | modmode = atoi(argv[1]); | |
487 | Q = atoi(argv[2]); | |
488 | } | |
489 | if (modmode==0) | |
490 | Q = 0; | |
491 | ensure(Q); | |
492 | if (modmode) | |
493 | { | |
494 | itog(1, N); | |
495 | gshiftleft(Q, N); | |
496 | itog(modmode, t1); | |
497 | addg(t1, N); | |
498 | } | |
499 | pr[0] = 2; | |
500 | for (k=0, npr=1;; k++) | |
501 | { | |
502 | if (primeq(3+2*k)) | |
503 | { | |
504 | pr[npr++] = 3+2*k; | |
505 | if (npr >= NUM_PRIMES) | |
506 | break; | |
507 | } | |
508 | } | |
509 | ||
510 | if (randmode == 0) | |
511 | { | |
512 | printf("Sieving...\n"); | |
513 | fflush(stdout); | |
514 | for (j=0; j < NUM_PRIMES; j++) | |
515 | { | |
516 | gtog(N, t1); | |
517 | rem = idivg(pr[j], t1); | |
518 | if (rem == 0) | |
519 | { | |
520 | printf("%d ", pr[j]); | |
521 | gtog(t1, N); | |
522 | if (isone(N)) | |
523 | { | |
524 | printf("\n"); | |
525 | exit(0); | |
526 | } | |
527 | else | |
528 | { | |
529 | printf("* "); | |
530 | fflush(stdout); | |
531 | } | |
532 | --j; | |
533 | } | |
534 | } | |
535 | ||
536 | if (bigprimeq(N)) | |
537 | { | |
538 | gout(N); | |
539 | exit(0); | |
540 | } | |
541 | ||
542 | printf("\n"); | |
543 | printf("Commencing Pollard rho...\n"); | |
544 | fflush(stdout); | |
545 | itog(1, gg); | |
546 | itog(3, t1); itog(3, t2); | |
547 | ||
548 | for (j=0; j < 15000; j++) | |
549 | { | |
550 | if((j%100) == 0) | |
551 | { | |
552 | dot(); | |
553 | gcdg(N, gg); | |
554 | if (!isone(gg)) | |
555 | break; | |
556 | } | |
557 | squareg(t1); | |
558 | iaddg(2, t1); | |
559 | s_modg(N, t1); | |
560 | squareg(t2); | |
561 | iaddg(2, t2); | |
562 | s_modg(N, t2); | |
563 | squareg(t2); | |
564 | iaddg(2, t2); | |
565 | s_modg(N, t2); | |
566 | gtog(t2, t3); | |
567 | subg(t1, t3); | |
568 | t3->sign = abs(t3->sign); | |
569 | mulg(t3, gg); | |
570 | s_modg(N, gg); | |
571 | } | |
572 | gcdg(N, gg); | |
573 | ||
574 | if ((gcompg(N,gg) != 0) && (!isone(gg))) | |
575 | { | |
576 | fprintf(stdout,"\n"); | |
577 | gout(gg); | |
578 | reset_mod(gg, N); | |
579 | if (isone(N)) | |
580 | { | |
581 | printf("\n"); | |
582 | exit(0); | |
583 | } | |
584 | else | |
585 | { | |
586 | printf("* "); | |
587 | fflush(stdout); | |
588 | } | |
589 | if (bigprimeq(N)) | |
590 | { | |
591 | gout(N); | |
592 | exit(0); | |
593 | } | |
594 | } | |
595 | ||
596 | printf("\n"); | |
597 | printf("Commencing Pollard (p-1)...\n"); | |
598 | fflush(stdout); | |
599 | itog(1, gg); | |
600 | itog(3, t1); | |
601 | for (j=0; j< NUM_PRIMES; j++) | |
602 | { | |
603 | cnt = (int)(8*log(2.0)/log(1.0*pr[j])); | |
604 | if (cnt < 2) | |
605 | cnt = 1; | |
606 | for (k=0; k< cnt; k++) | |
607 | { | |
608 | powermod(t1, pr[j], N); | |
609 | } | |
610 | itog(1, t2); | |
611 | subg(t1, t2); | |
612 | mulg(t2, gg); | |
613 | s_modg(N, gg); | |
614 | ||
615 | if (j % 100 == 0) | |
616 | { | |
617 | dot(); | |
618 | gcdg(N, gg); | |
619 | if (!isone(gg)) | |
620 | break; | |
621 | } | |
622 | } | |
623 | gcdg(N, gg); | |
624 | if ((gcompg(N,gg) != 0) && (!isone(gg))) | |
625 | { | |
626 | fprintf(stdout,"\n"); | |
627 | gout(gg); | |
628 | reset_mod(gg, N); | |
629 | if (isone(N)) | |
630 | { | |
631 | printf("\n"); | |
632 | exit(0); | |
633 | } | |
634 | else | |
635 | { | |
636 | printf("* "); | |
637 | fflush(stdout); | |
638 | } | |
639 | if (bigprimeq(N)) | |
640 | { | |
641 | gout(N); | |
642 | exit(0); | |
643 | } | |
644 | } | |
645 | } /* This is the end of (randmode == 0) */ | |
646 | ||
647 | printf("\n"); | |
648 | printf("Commencing ECM...\n"); | |
649 | fflush(stdout); | |
650 | ||
651 | if (randmode) | |
652 | set_random_seed(); | |
653 | pass = 0; | |
654 | while (++pass) | |
655 | { | |
656 | if (randmode == 0) | |
657 | { | |
658 | if (pass <= 3) | |
659 | { | |
660 | B = 1000; | |
661 | } | |
662 | else if (pass <= 10) | |
663 | { | |
664 | B = 10000; | |
665 | } | |
666 | else if (pass <= 100) | |
667 | { | |
668 | B = 100000L; | |
669 | } else | |
670 | { | |
671 | B = 1000000L; | |
672 | } | |
673 | } | |
674 | else | |
675 | { | |
676 | B = 2000000L; | |
677 | } | |
678 | C = 50*((int)B); | |
679 | ||
680 | /* Next, choose curve with order divisible by 16 and choose | |
681 | * a point (xr/zr) on said curve. | |
682 | */ | |
683 | ||
684 | /* Order-div-12 case. | |
685 | * cnt = 8020345; Brent's parameter for stage one discovery | |
686 | * of 27-digit factor of F_13. | |
687 | */ | |
688 | ||
689 | cnt = psi_rand(); /* cnt = 8020345; */ | |
690 | choose12(xr, zr, cnt, An, Ad, N); | |
691 | printf("Choosing curve %d, with s = %d, B = %d, C = %d:\n", pass,cnt, B, C); fflush(stdout); | |
692 | cnt = 0; | |
693 | nshorts = 1; | |
694 | count = 0; | |
695 | for (j=0;j<nshorts;j++) | |
696 | { | |
697 | ell_mul(xr, zr, 1<<16, An, Ad, N); | |
698 | ell_mul(xr, zr, 3*3*3*3*3*3*3*3*3*3*3, An, Ad, N); | |
699 | ell_mul(xr, zr, 5*5*5*5*5*5*5, An, Ad, N); | |
700 | ell_mul(xr, zr, 7*7*7*7*7*7, An, Ad, N); | |
701 | ell_mul(xr, zr, 11*11*11*11, An, Ad, N); | |
702 | ell_mul(xr, zr, 13*13*13*13, An, Ad, N); | |
703 | ell_mul(xr, zr, 17*17*17, An, Ad, N); | |
704 | } | |
705 | k = 19; | |
706 | while (k<B) | |
707 | { | |
708 | if (isprime(k)) | |
709 | { | |
710 | ell_mul(xr, zr, k, An, Ad, N); | |
711 | if (k<100) | |
712 | ell_mul(xr, zr, k, An, Ad, N); | |
713 | if (cnt++ %100==0) | |
714 | dot(); | |
715 | } | |
716 | k += 2; | |
717 | } | |
718 | count = 0; | |
719 | ||
720 | gtog(zr, gg); | |
721 | gcdg(N, gg); | |
722 | if ((!isone(gg))&&(bitlen(gg)>limitbits)) | |
723 | { | |
724 | fprintf(stdout,"\n"); | |
725 | gwriteln(gg, stdout); | |
726 | fflush(stdout); | |
727 | reset_mod(gg, N); | |
728 | if (isone(N)) | |
729 | { | |
730 | printf("\n"); | |
731 | exit(0); | |
732 | } | |
733 | else | |
734 | { | |
735 | printf("* "); | |
736 | fflush(stdout); | |
737 | } | |
738 | if (bigprimeq(N)) | |
739 | { | |
740 | gout(N); | |
741 | exit(0); | |
742 | } | |
743 | continue; | |
744 | } | |
745 | else | |
746 | { | |
747 | printf("\n"); | |
748 | fflush(stdout); | |
749 | } | |
750 | ||
751 | /* Continue; Invoke, to test Stage 1 only. */ | |
752 | k = ((int)B)/D; | |
753 | gtog(xr, xb[0]); | |
754 | gtog(zr, zb[0]); | |
755 | ell_mul(xb[0], zb[0], k*D+1 , An, Ad, N); | |
756 | gtog(xr, xb[D+1]); | |
757 | gtog(zr, zb[D+1]); | |
758 | ell_mul(xb[D+1], zb[D+1], (k+2)*D+1 , An, Ad, N); | |
759 | ||
760 | for (j=1; j <= D; j++) | |
761 | { | |
762 | gtog(xr, xb[j]); | |
763 | gtog(zr, zb[j]); | |
764 | ell_mul(xb[j], zb[j], 2*j , An, Ad, N); | |
765 | gtog(zb[j], xzb[j]); | |
766 | mulg(xb[j], xzb[j]); | |
767 | s_modg(N, xzb[j]); | |
768 | } | |
769 | modcount = 0; | |
770 | printf("\nCommencing second stage, curve %d...\n",pass); fflush(stdout); | |
771 | count = 0; | |
772 | itog(1, gg); | |
773 | ||
774 | while (1) | |
775 | { | |
776 | gtog(zb[0], xzb[0]); | |
777 | mulg(xb[0], xzb[0]); | |
778 | s_modg(N, xzb[0]); | |
779 | mulg(zb[0], gg); | |
780 | s_modg(N,gg); /* Accumulate. */ | |
781 | for (j = 1; j < D; j++) | |
782 | { | |
783 | if (!isprime(k*D+1+ 2*j)) | |
784 | continue; | |
785 | ||
786 | /* Next, accumulate (xa - xb)(za + zb) - xa za + xb zb. */ | |
787 | gtog(xb[0], t1); | |
788 | subg(xb[j], t1); | |
789 | gtog(zb[0], t2); | |
790 | addg(zb[j], t2); | |
791 | mulg(t1, t2); | |
792 | s_modg(N, t1); | |
793 | subg(xzb[0], t2); | |
794 | addg(xzb[j], t2); | |
795 | s_modg(N, t2); | |
796 | --modcount; | |
797 | mulg(t2, gg); | |
798 | s_modg(N, gg); | |
799 | if((++count)%1000==0) | |
800 | dot(); | |
801 | } | |
802 | ||
803 | k += 2; | |
804 | if(k*D > C) | |
805 | break; | |
806 | gtog(xb[D+1], xs); | |
807 | gtog(zb[D+1], zs); | |
808 | ell_odd(xb[D], zb[D], xb[D+1], zb[D+1], xb[0], zb[0], N); | |
809 | gtog(xs, xb[0]); | |
810 | gtog(zs, zb[0]); | |
811 | } | |
812 | ||
813 | gcdg(N, gg); | |
814 | if((!isone(gg))&&(bitlen(gg)>limitbits)) | |
815 | { | |
816 | fprintf(stdout,"\n"); | |
817 | gwriteln(gg, stdout); | |
818 | fflush(stdout); | |
819 | reset_mod(gg, N); | |
820 | if (isone(N)) | |
821 | { | |
822 | printf("\n"); | |
823 | exit(0); | |
824 | } | |
825 | else | |
826 | { | |
827 | printf("* "); | |
828 | fflush(stdout); | |
829 | } | |
830 | if (bigprimeq(N)) | |
831 | { | |
832 | gout(N); | |
833 | exit(0); | |
834 | } | |
835 | continue; | |
836 | } | |
837 | ||
838 | printf("\n"); | |
839 | fflush(stdout); | |
840 | } | |
841 | ||
842 | return 0; | |
843 | } | |
844 |