Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /*
2 * mpprime.c
3 *
4 * Utilities for finding and working with prime and pseudo-prime
5 * integers
6 *
7 * This Source Code Form is subject to the terms of the Mozilla Public
8 * License, v. 2.0. If a copy of the MPL was not distributed with this
9 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
11 #include "mpi-priv.h"
12 #include "mpprime.h"
13 #include "mplogic.h"
14 #include <stdlib.h>
15 #include <string.h>
17 #define SMALL_TABLE 0 /* determines size of hard-wired prime table */
19 #define RANDOM() rand()
21 #include "primes.c" /* pull in the prime digit table */
23 /*
24 Test if any of a given vector of digits divides a. If not, MP_NO
25 is returned; otherwise, MP_YES is returned and 'which' is set to
26 the index of the integer in the vector which divided a.
27 */
28 mp_err s_mpp_divp(mp_int *a, const mp_digit *vec, int size, int *which);
30 /* {{{ mpp_divis(a, b) */
32 /*
33 mpp_divis(a, b)
35 Returns MP_YES if a is divisible by b, or MP_NO if it is not.
36 */
38 mp_err mpp_divis(mp_int *a, mp_int *b)
39 {
40 mp_err res;
41 mp_int rem;
43 if((res = mp_init(&rem)) != MP_OKAY)
44 return res;
46 if((res = mp_mod(a, b, &rem)) != MP_OKAY)
47 goto CLEANUP;
49 if(mp_cmp_z(&rem) == 0)
50 res = MP_YES;
51 else
52 res = MP_NO;
54 CLEANUP:
55 mp_clear(&rem);
56 return res;
58 } /* end mpp_divis() */
60 /* }}} */
62 /* {{{ mpp_divis_d(a, d) */
64 /*
65 mpp_divis_d(a, d)
67 Return MP_YES if a is divisible by d, or MP_NO if it is not.
68 */
70 mp_err mpp_divis_d(mp_int *a, mp_digit d)
71 {
72 mp_err res;
73 mp_digit rem;
75 ARGCHK(a != NULL, MP_BADARG);
77 if(d == 0)
78 return MP_NO;
80 if((res = mp_mod_d(a, d, &rem)) != MP_OKAY)
81 return res;
83 if(rem == 0)
84 return MP_YES;
85 else
86 return MP_NO;
88 } /* end mpp_divis_d() */
90 /* }}} */
92 /* {{{ mpp_random(a) */
94 /*
95 mpp_random(a)
97 Assigns a random value to a. This value is generated using the
98 standard C library's rand() function, so it should not be used for
99 cryptographic purposes, but it should be fine for primality testing,
100 since all we really care about there is good statistical properties.
102 As many digits as a currently has are filled with random digits.
103 */
105 mp_err mpp_random(mp_int *a)
107 {
108 mp_digit next = 0;
109 unsigned int ix, jx;
111 ARGCHK(a != NULL, MP_BADARG);
113 for(ix = 0; ix < USED(a); ix++) {
114 for(jx = 0; jx < sizeof(mp_digit); jx++) {
115 next = (next << CHAR_BIT) | (RANDOM() & UCHAR_MAX);
116 }
117 DIGIT(a, ix) = next;
118 }
120 return MP_OKAY;
122 } /* end mpp_random() */
124 /* }}} */
126 /* {{{ mpp_random_size(a, prec) */
128 mp_err mpp_random_size(mp_int *a, mp_size prec)
129 {
130 mp_err res;
132 ARGCHK(a != NULL && prec > 0, MP_BADARG);
134 if((res = s_mp_pad(a, prec)) != MP_OKAY)
135 return res;
137 return mpp_random(a);
139 } /* end mpp_random_size() */
141 /* }}} */
143 /* {{{ mpp_divis_vector(a, vec, size, which) */
145 /*
146 mpp_divis_vector(a, vec, size, which)
148 Determines if a is divisible by any of the 'size' digits in vec.
149 Returns MP_YES and sets 'which' to the index of the offending digit,
150 if it is; returns MP_NO if it is not.
151 */
153 mp_err mpp_divis_vector(mp_int *a, const mp_digit *vec, int size, int *which)
154 {
155 ARGCHK(a != NULL && vec != NULL && size > 0, MP_BADARG);
157 return s_mpp_divp(a, vec, size, which);
159 } /* end mpp_divis_vector() */
161 /* }}} */
163 /* {{{ mpp_divis_primes(a, np) */
165 /*
166 mpp_divis_primes(a, np)
168 Test whether a is divisible by any of the first 'np' primes. If it
169 is, returns MP_YES and sets *np to the value of the digit that did
170 it. If not, returns MP_NO.
171 */
172 mp_err mpp_divis_primes(mp_int *a, mp_digit *np)
173 {
174 int size, which;
175 mp_err res;
177 ARGCHK(a != NULL && np != NULL, MP_BADARG);
179 size = (int)*np;
180 if(size > prime_tab_size)
181 size = prime_tab_size;
183 res = mpp_divis_vector(a, prime_tab, size, &which);
184 if(res == MP_YES)
185 *np = prime_tab[which];
187 return res;
189 } /* end mpp_divis_primes() */
191 /* }}} */
193 /* {{{ mpp_fermat(a, w) */
195 /*
196 Using w as a witness, try pseudo-primality testing based on Fermat's
197 little theorem. If a is prime, and (w, a) = 1, then w^a == w (mod
198 a). So, we compute z = w^a (mod a) and compare z to w; if they are
199 equal, the test passes and we return MP_YES. Otherwise, we return
200 MP_NO.
201 */
202 mp_err mpp_fermat(mp_int *a, mp_digit w)
203 {
204 mp_int base, test;
205 mp_err res;
207 if((res = mp_init(&base)) != MP_OKAY)
208 return res;
210 mp_set(&base, w);
212 if((res = mp_init(&test)) != MP_OKAY)
213 goto TEST;
215 /* Compute test = base^a (mod a) */
216 if((res = mp_exptmod(&base, a, a, &test)) != MP_OKAY)
217 goto CLEANUP;
220 if(mp_cmp(&base, &test) == 0)
221 res = MP_YES;
222 else
223 res = MP_NO;
225 CLEANUP:
226 mp_clear(&test);
227 TEST:
228 mp_clear(&base);
230 return res;
232 } /* end mpp_fermat() */
234 /* }}} */
236 /*
237 Perform the fermat test on each of the primes in a list until
238 a) one of them shows a is not prime, or
239 b) the list is exhausted.
240 Returns: MP_YES if it passes tests.
241 MP_NO if fermat test reveals it is composite
242 Some MP error code if some other error occurs.
243 */
244 mp_err mpp_fermat_list(mp_int *a, const mp_digit *primes, mp_size nPrimes)
245 {
246 mp_err rv = MP_YES;
248 while (nPrimes-- > 0 && rv == MP_YES) {
249 rv = mpp_fermat(a, *primes++);
250 }
251 return rv;
252 }
254 /* {{{ mpp_pprime(a, nt) */
256 /*
257 mpp_pprime(a, nt)
259 Performs nt iteration of the Miller-Rabin probabilistic primality
260 test on a. Returns MP_YES if the tests pass, MP_NO if one fails.
261 If MP_NO is returned, the number is definitely composite. If MP_YES
262 is returned, it is probably prime (but that is not guaranteed).
263 */
265 mp_err mpp_pprime(mp_int *a, int nt)
266 {
267 mp_err res;
268 mp_int x, amo, m, z; /* "amo" = "a minus one" */
269 int iter;
270 unsigned int jx;
271 mp_size b;
273 ARGCHK(a != NULL, MP_BADARG);
275 MP_DIGITS(&x) = 0;
276 MP_DIGITS(&amo) = 0;
277 MP_DIGITS(&m) = 0;
278 MP_DIGITS(&z) = 0;
280 /* Initialize temporaries... */
281 MP_CHECKOK( mp_init(&amo));
282 /* Compute amo = a - 1 for what follows... */
283 MP_CHECKOK( mp_sub_d(a, 1, &amo) );
285 b = mp_trailing_zeros(&amo);
286 if (!b) { /* a was even ? */
287 res = MP_NO;
288 goto CLEANUP;
289 }
291 MP_CHECKOK( mp_init_size(&x, MP_USED(a)) );
292 MP_CHECKOK( mp_init(&z) );
293 MP_CHECKOK( mp_init(&m) );
294 MP_CHECKOK( mp_div_2d(&amo, b, &m, 0) );
296 /* Do the test nt times... */
297 for(iter = 0; iter < nt; iter++) {
299 /* Choose a random value for 1 < x < a */
300 s_mp_pad(&x, USED(a));
301 mpp_random(&x);
302 MP_CHECKOK( mp_mod(&x, a, &x) );
303 if(mp_cmp_d(&x, 1) <= 0) {
304 iter--; /* don't count this iteration */
305 continue; /* choose a new x */
306 }
308 /* Compute z = (x ** m) mod a */
309 MP_CHECKOK( mp_exptmod(&x, &m, a, &z) );
311 if(mp_cmp_d(&z, 1) == 0 || mp_cmp(&z, &amo) == 0) {
312 res = MP_YES;
313 continue;
314 }
316 res = MP_NO; /* just in case the following for loop never executes. */
317 for (jx = 1; jx < b; jx++) {
318 /* z = z^2 (mod a) */
319 MP_CHECKOK( mp_sqrmod(&z, a, &z) );
320 res = MP_NO; /* previous line set res to MP_YES */
322 if(mp_cmp_d(&z, 1) == 0) {
323 break;
324 }
325 if(mp_cmp(&z, &amo) == 0) {
326 res = MP_YES;
327 break;
328 }
329 } /* end testing loop */
331 /* If the test passes, we will continue iterating, but a failed
332 test means the candidate is definitely NOT prime, so we will
333 immediately break out of this loop
334 */
335 if(res == MP_NO)
336 break;
338 } /* end iterations loop */
340 CLEANUP:
341 mp_clear(&m);
342 mp_clear(&z);
343 mp_clear(&x);
344 mp_clear(&amo);
345 return res;
347 } /* end mpp_pprime() */
349 /* }}} */
351 /* Produce table of composites from list of primes and trial value.
352 ** trial must be odd. List of primes must not include 2.
353 ** sieve should have dimension >= MAXPRIME/2, where MAXPRIME is largest
354 ** prime in list of primes. After this function is finished,
355 ** if sieve[i] is non-zero, then (trial + 2*i) is composite.
356 ** Each prime used in the sieve costs one division of trial, and eliminates
357 ** one or more values from the search space. (3 eliminates 1/3 of the values
358 ** alone!) Each value left in the search space costs 1 or more modular
359 ** exponentations. So, these divisions are a bargain!
360 */
361 mp_err mpp_sieve(mp_int *trial, const mp_digit *primes, mp_size nPrimes,
362 unsigned char *sieve, mp_size nSieve)
363 {
364 mp_err res;
365 mp_digit rem;
366 mp_size ix;
367 unsigned long offset;
369 memset(sieve, 0, nSieve);
371 for(ix = 0; ix < nPrimes; ix++) {
372 mp_digit prime = primes[ix];
373 mp_size i;
374 if((res = mp_mod_d(trial, prime, &rem)) != MP_OKAY)
375 return res;
377 if (rem == 0) {
378 offset = 0;
379 } else {
380 offset = prime - (rem / 2);
381 }
382 for (i = offset; i < nSieve ; i += prime) {
383 sieve[i] = 1;
384 }
385 }
387 return MP_OKAY;
388 }
390 #define SIEVE_SIZE 32*1024
392 mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong,
393 unsigned long * nTries)
394 {
395 mp_digit np;
396 mp_err res;
397 int i = 0;
398 mp_int trial;
399 mp_int q;
400 mp_size num_tests;
401 unsigned char *sieve;
403 ARGCHK(start != 0, MP_BADARG);
404 ARGCHK(nBits > 16, MP_RANGE);
406 sieve = malloc(SIEVE_SIZE);
407 ARGCHK(sieve != NULL, MP_MEM);
409 MP_DIGITS(&trial) = 0;
410 MP_DIGITS(&q) = 0;
411 MP_CHECKOK( mp_init(&trial) );
412 MP_CHECKOK( mp_init(&q) );
413 /* values taken from table 4.4, HandBook of Applied Cryptography */
414 if (nBits >= 1300) {
415 num_tests = 2;
416 } else if (nBits >= 850) {
417 num_tests = 3;
418 } else if (nBits >= 650) {
419 num_tests = 4;
420 } else if (nBits >= 550) {
421 num_tests = 5;
422 } else if (nBits >= 450) {
423 num_tests = 6;
424 } else if (nBits >= 400) {
425 num_tests = 7;
426 } else if (nBits >= 350) {
427 num_tests = 8;
428 } else if (nBits >= 300) {
429 num_tests = 9;
430 } else if (nBits >= 250) {
431 num_tests = 12;
432 } else if (nBits >= 200) {
433 num_tests = 15;
434 } else if (nBits >= 150) {
435 num_tests = 18;
436 } else if (nBits >= 100) {
437 num_tests = 27;
438 } else
439 num_tests = 50;
441 if (strong)
442 --nBits;
443 MP_CHECKOK( mpl_set_bit(start, nBits - 1, 1) );
444 MP_CHECKOK( mpl_set_bit(start, 0, 1) );
445 for (i = mpl_significant_bits(start) - 1; i >= nBits; --i) {
446 MP_CHECKOK( mpl_set_bit(start, i, 0) );
447 }
448 /* start sieveing with prime value of 3. */
449 MP_CHECKOK(mpp_sieve(start, prime_tab + 1, prime_tab_size - 1,
450 sieve, SIEVE_SIZE) );
452 #ifdef DEBUG_SIEVE
453 res = 0;
454 for (i = 0; i < SIEVE_SIZE; ++i) {
455 if (!sieve[i])
456 ++res;
457 }
458 fprintf(stderr,"sieve found %d potential primes.\n", res);
459 #define FPUTC(x,y) fputc(x,y)
460 #else
461 #define FPUTC(x,y)
462 #endif
464 res = MP_NO;
465 for(i = 0; i < SIEVE_SIZE; ++i) {
466 if (sieve[i]) /* this number is composite */
467 continue;
468 MP_CHECKOK( mp_add_d(start, 2 * i, &trial) );
469 FPUTC('.', stderr);
470 /* run a Fermat test */
471 res = mpp_fermat(&trial, 2);
472 if (res != MP_OKAY) {
473 if (res == MP_NO)
474 continue; /* was composite */
475 goto CLEANUP;
476 }
478 FPUTC('+', stderr);
479 /* If that passed, run some Miller-Rabin tests */
480 res = mpp_pprime(&trial, num_tests);
481 if (res != MP_OKAY) {
482 if (res == MP_NO)
483 continue; /* was composite */
484 goto CLEANUP;
485 }
486 FPUTC('!', stderr);
488 if (!strong)
489 break; /* success !! */
491 /* At this point, we have strong evidence that our candidate
492 is itself prime. If we want a strong prime, we need now
493 to test q = 2p + 1 for primality...
494 */
495 MP_CHECKOK( mp_mul_2(&trial, &q) );
496 MP_CHECKOK( mp_add_d(&q, 1, &q) );
498 /* Test q for small prime divisors ... */
499 np = prime_tab_size;
500 res = mpp_divis_primes(&q, &np);
501 if (res == MP_YES) { /* is composite */
502 mp_clear(&q);
503 continue;
504 }
505 if (res != MP_NO)
506 goto CLEANUP;
508 /* And test with Fermat, as with its parent ... */
509 res = mpp_fermat(&q, 2);
510 if (res != MP_YES) {
511 mp_clear(&q);
512 if (res == MP_NO)
513 continue; /* was composite */
514 goto CLEANUP;
515 }
517 /* And test with Miller-Rabin, as with its parent ... */
518 res = mpp_pprime(&q, num_tests);
519 if (res != MP_YES) {
520 mp_clear(&q);
521 if (res == MP_NO)
522 continue; /* was composite */
523 goto CLEANUP;
524 }
526 /* If it passed, we've got a winner */
527 mp_exch(&q, &trial);
528 mp_clear(&q);
529 break;
531 } /* end of loop through sieved values */
532 if (res == MP_YES)
533 mp_exch(&trial, start);
534 CLEANUP:
535 mp_clear(&trial);
536 mp_clear(&q);
537 if (nTries)
538 *nTries += i;
539 if (sieve != NULL) {
540 memset(sieve, 0, SIEVE_SIZE);
541 free (sieve);
542 }
543 return res;
544 }
546 /*========================================================================*/
547 /*------------------------------------------------------------------------*/
548 /* Static functions visible only to the library internally */
550 /* {{{ s_mpp_divp(a, vec, size, which) */
552 /*
553 Test for divisibility by members of a vector of digits. Returns
554 MP_NO if a is not divisible by any of them; returns MP_YES and sets
555 'which' to the index of the offender, if it is. Will stop on the
556 first digit against which a is divisible.
557 */
559 mp_err s_mpp_divp(mp_int *a, const mp_digit *vec, int size, int *which)
560 {
561 mp_err res;
562 mp_digit rem;
564 int ix;
566 for(ix = 0; ix < size; ix++) {
567 if((res = mp_mod_d(a, vec[ix], &rem)) != MP_OKAY)
568 return res;
570 if(rem == 0) {
571 if(which)
572 *which = ix;
573 return MP_YES;
574 }
575 }
577 return MP_NO;
579 } /* end s_mpp_divp() */
581 /* }}} */
583 /*------------------------------------------------------------------------*/
584 /* HERE THERE BE DRAGONS */