]>
git.saurik.com Git - apple/security.git/blob - Security/libsecurity_cryptkit/lib/CurveParamDocs/fmodule.c
1 /**************************************************************
8 * 13 Apr 98 REC - creation
10 * c. 1998 Perfectly Scientific, Inc.
11 * All Rights Reserved.
14 *************************************************************/
33 #define NUM_PRIMES 6542 /* PrimePi[2^16]. */
36 #define MERSENNE_MOD (-1)
37 #define D 100 /* A decimation parameter for stage-2 ECM factoring. */
39 /* compiler options */
42 #pragma warning( disable : 4127 4706 ) /* disable conditional is constant warning */
46 /* global variables */
48 extern int pr
[NUM_PRIMES
]; /* Primes array from tools.c. */
50 unsigned short factors
[NUM_PRIMES
], exponents
[NUM_PRIMES
];
51 int modmode
= GENERAL_MOD
;
53 static giant t1
= NULL
, t2
= NULL
, t3
= NULL
, t4
= NULL
;
54 static giant An
= NULL
, Ad
= NULL
;
55 static point_mont pt1
, pt2
;
59 static int verbosity
= 0;
61 /**************************************************************
65 **************************************************************/
68 init_fmodule(int shorts
) {
70 pb
[0] = NULL
; /* To guarantee proper ECM initialization. */
71 t1
= newgiant(shorts
);
72 t2
= newgiant(shorts
);
73 t3
= newgiant(shorts
);
74 t4
= newgiant(shorts
);
75 An
= newgiant(shorts
);
76 Ad
= newgiant(shorts
);
77 pt1
= new_point_mont(shorts
);
78 pt2
= new_point_mont(shorts
);
83 /* Call verbose(1) for output during factoring processes,
84 call verbose(0) to silence all that.
98 set_mod_mode(int mode
)
99 /* Call this with mode := 1, 0, -1, for Fermat-mod, general mod, and Mersenne mod,
100 respectively; the point being that the special cases of
101 Fermat- and Mersenne-mod are much faster than
102 general mod. If all mods will be with respect to a number-to-be-factored,
103 of the form N = 2^m + 1, use Fermat mod; while if N = 2^m-1, use Mersenne mod.
118 mersennemod(bitlen(N
), t
);
121 fermatmod(bitlen(N
)-1, t
);
136 return(&exponents
[0]);
140 sieve(giant N
, int sievelim
)
141 /* Returns number of N's prime factors < min(sievelim, 2^16),
142 with N reduced accordingly by said factors.
143 The n-th entry of factors[] becomes the n-th prime
144 factor of N, with corresponding exponent
145 becoming the n-th element of exponents[].
147 { int j
, pcount
, rem
;
152 for (j
=0; j
< NUM_PRIMES
; j
++)
155 if(pri
> sievelim
) break;
158 rem
= idivg(pri
, t1
);
164 if(exponents
[pcount
] > 0) {
165 factors
[pcount
] = pr
[j
];
167 exponents
[pcount
] = 0;
174 pollard_rho(giant N
, giant fact
, int steps
, int abort
)
175 /* Perform Pollard-rho x:= 3; loop(x:= x^2 + 2), a total of steps times.
176 Parameter fact will be a nontrivial factor found, in which case
177 N is also modified as: N := N/fact.
178 The function returns 0 if no nontrivial factor found, else returns 1.
179 The abort parameter, when set, causes the factorer to exit on the
180 first nontrivial factor found (the requisite GCD is checked
181 every 1000 steps). If abort := 0, the full number
182 of steps are always performed, then one solitary GCD is taken,
191 for(j
=0; j
< steps
; j
++) {
192 squareg(t1
); iaddg(2, t1
); special_modg(N
, t1
);
193 squareg(t2
); iaddg(2, t2
); special_modg(N
, t2
);
194 squareg(t2
); iaddg(2, t2
); special_modg(N
, t2
);
195 gtog(t2
, t3
); subg(t1
,t3
); mulg(t3
, fact
); special_modg(N
, fact
);
196 if(((j
% 1000 == 999) && abort
) || (j
== steps
-1)) {
200 found
= (gcompg(N
, fact
) == 0) ? 0 : 1;
205 if(verbosity
) { printf("\n"); fflush(stdout
); }
215 pollard_pminus1(giant N
, giant fact
, int lim
, int abort
)
216 /* Perform Pollard-(p-1); where we test
220 where P is an accumulation of primes <= min(lim, 2^16),
221 to appropriate powers.
222 Parameter fact will be a nontrivial factor found, in which case
223 N is also modified as: N := N/fact.
224 The function returns 0 if no nontrivial factor found, else returns 1.
225 The abort parameter, when set, causes the factorer to exit on the
226 first nontrivial factor found (the requisite GCD is checked
227 every 100 steps). If abort := 0, the full number
228 of steps are always performed, then one solitary GCD is taken,
231 { int cnt
, j
, k
, pri
, found
= 0;
234 for (j
=0; j
< NUM_PRIMES
; j
++)
237 if((pri
> lim
) || (j
== NUM_PRIMES
-1) || (abort
&& (j
% 100 == 99))) {
245 found
= (gcompg(N
, t1
) == 0) ? 0 : 1;
250 if(pri
< 19) { cnt
= 20-pri
; /* Smaller primes get higher powers. */
251 } else if(pri
< 100) {
254 for (k
=0; k
< cnt
; k
++)
256 powermod(fact
, pri
, N
);
259 if(verbosity
) { printf("\n"); fflush(stdout
); }
270 ecm(giant N
, giant fact
, int S
, unsigned int B
, unsigned int C
)
271 /* Perform elliptic curve method (ECM), with:
272 Brent seed parameter = S
276 returns 1 if nontrivial factor is found in stage 1 of ECM;
277 returns 2 if nontrivial factor is found in stage 2 of ECM;
279 In the positive return, parameter fact is the factor and N := N/fact.
281 { unsigned int pri
, q
;
282 int j
, cnt
, count
, k
;
285 printf("Finding curve and point, B = %u, C = %u, seed = %d...", B
, C
, S
);
288 find_curve_point_brent(pt1
, S
, An
, Ad
, N
);
291 printf("Commencing stage 1 of ECM...\n");
295 q
= pr
[NUM_PRIMES
-1];
302 if(primeq(q
)) pri
= q
;
305 if(verbosity
) if((++count
) % 100 == 0) dot();
307 if(pri
< 19) { cnt
= 20-pri
;
308 } else if(pri
< 100) {
311 for(k
= 0; k
< cnt
; k
++)
312 ell_mul_int_brent(pt1
, pri
, An
, Ad
, N
);
319 ell_mul_int_brent(pt1
, k
, An
, Ad
, N
);
321 ell_mul_int_brent(pt1
, k
, An
, Ad
, N
);
327 if(verbosity
) { printf("\n"); fflush(stdout
); }
329 /* Next, test stage-1 attempt. */
332 if((!isone(fact
)) && (gcompg(N
, fact
) != 0)) {
336 if(B
>= C
) { /* No stage 2 planned. */
341 /* Commence second stage of ECM. */
344 printf("Commencing stage 2 of ECM...\n");
348 for(k
=0; k
< D
+2; k
++) {
349 pb
[k
] = new_point_mont(curshorts
);
350 xzb
[k
] = newgiant(curshorts
);
355 ptop_mont(pt1
, pb
[0]);
356 ell_mul_int_brent(pb
[0], k
*D
+1 , An
, Ad
, N
);
357 ptop_mont(pt1
, pb
[D
+1]);
358 ell_mul_int_brent(pb
[D
+1], (k
+2)*D
+1 , An
, Ad
, N
);
360 for (j
=1; j
<= D
; j
++)
362 ptop_mont(pt1
, pb
[j
]);
363 ell_mul_int_brent(pb
[j
], 2*j
, An
, Ad
, N
);
364 gtog(pb
[j
]->z
, xzb
[j
]);
365 mulg(pb
[j
]->x
, xzb
[j
]);
366 special_modg(N
, xzb
[j
]);
371 if(verbosity
) if((++count
) % 10 == 0) dot();
372 gtog(pb
[0]->z
, xzb
[0]);
373 mulg(pb
[0]->x
, xzb
[0]);
374 special_modg(N
, xzb
[0]);
375 mulg(pb
[0]->z
, fact
);
376 special_modg(N
, fact
); /* Accumulate. */
377 for (j
= 1; j
< D
; j
++) {
378 if (!primeq(k
*D
+1+2*j
)) continue;
379 /* Next, accumulate (xa - xb)(za + zb) - xa za + xb zb. */
390 special_modg(N
, fact
);
395 ptop_mont(pb
[D
+1], pt2
);
396 ell_odd_brent(pb
[D
], pb
[D
+1], pb
[0], N
);
397 ptop_mont(pt2
, pb
[0]);
399 if(verbosity
) { printf("\n"); fflush(stdout
); }
402 if((!isone(fact
)) && (gcompg(N
, fact
) != 0)) {
404 return(2); /* Return value of 2 for stage-2 success! */