| 
									
										
										
										
											2003-02-28 16:06:22 +00:00
										 |  |  | /* Generates provable primes
 | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2006-04-06 19:49:59 +00:00
										 |  |  |  * See http://gmail.com:8080/papers/pp.pdf for more info.
 | 
					
						
							| 
									
										
										
										
											2003-02-28 16:06:22 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2006-04-06 19:49:59 +00:00
										 |  |  |  * Tom St Denis, tomstdenis@gmail.com, http://tom.gmail.com
 | 
					
						
							| 
									
										
										
										
											2003-02-28 16:06:22 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | #include <time.h>
 | 
					
						
							| 
									
										
										
										
											2003-02-28 16:09:08 +00:00
										 |  |  | #include "tommath.h"
 | 
					
						
							| 
									
										
										
										
											2003-02-28 16:06:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-01 22:28:43 +01:00
										 |  |  | static int   n_prime; | 
					
						
							|  |  |  | static FILE *primes; | 
					
						
							| 
									
										
										
										
											2003-07-16 00:26:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-28 16:06:22 +00:00
										 |  |  | /* fast square root */ | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  | static mp_digit i_sqrt(mp_word x) | 
					
						
							| 
									
										
										
										
											2003-02-28 16:06:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    mp_word x1, x2; | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    x2 = x; | 
					
						
							|  |  |  |    do { | 
					
						
							|  |  |  |       x1 = x2; | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |       x2 = x1 - ((x1 * x1) - x) / (2u * x1); | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    } while (x1 != x2); | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-10 10:19:11 +01:00
										 |  |  |    if ((x1 * x1) > x) { | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |       --x1; | 
					
						
							|  |  |  |    } | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    return x1; | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-28 16:06:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* generates a prime digit */ | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  | static void gen_prime(void) | 
					
						
							| 
									
										
										
										
											2003-02-28 16:06:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    mp_digit r, x, y, next; | 
					
						
							|  |  |  |    FILE *out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    out = fopen("pprime.dat", "wb"); | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |    if (out != NULL) { | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |       /* write first set of primes */ | 
					
						
							| 
									
										
										
										
											2018-02-02 11:55:01 +01:00
										 |  |  |       /* *INDENT-OFF* */ | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |       r = 3uL; fwrite(&r, 1uL, sizeof(mp_digit), out); | 
					
						
							|  |  |  |       r = 5uL; fwrite(&r, 1uL, sizeof(mp_digit), out); | 
					
						
							|  |  |  |       r = 7uL; fwrite(&r, 1uL, sizeof(mp_digit), out); | 
					
						
							|  |  |  |       r = 11uL; fwrite(&r, 1uL, sizeof(mp_digit), out); | 
					
						
							|  |  |  |       r = 13uL; fwrite(&r, 1uL, sizeof(mp_digit), out); | 
					
						
							|  |  |  |       r = 17uL; fwrite(&r, 1uL, sizeof(mp_digit), out); | 
					
						
							|  |  |  |       r = 19uL; fwrite(&r, 1uL, sizeof(mp_digit), out); | 
					
						
							|  |  |  |       r = 23uL; fwrite(&r, 1uL, sizeof(mp_digit), out); | 
					
						
							|  |  |  |       r = 29uL; fwrite(&r, 1uL, sizeof(mp_digit), out); | 
					
						
							|  |  |  |       r = 31uL; fwrite(&r, 1uL, sizeof(mp_digit), out); | 
					
						
							| 
									
										
										
										
											2018-02-02 11:55:01 +01:00
										 |  |  |       /* *INDENT-ON* */ | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |       /* get square root, since if 'r' is composite its factors must be < than this */ | 
					
						
							|  |  |  |       y = i_sqrt(r); | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |       next = (y + 1uL) * (y + 1uL); | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |       for (;;) { | 
					
						
							|  |  |  |          do { | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |             r += 2uL;       /* next candidate */ | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |             r &= MP_MASK; | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |             if (r < 31uL) break; | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |             /* update sqrt ? */ | 
					
						
							|  |  |  |             if (next <= r) { | 
					
						
							|  |  |  |                ++y; | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |                next = (y + 1uL) * (y + 1uL); | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |             /* loop if divisible by 3,5,7,11,13,17,19,23,29  */ | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |             if ((r % 3uL) == 0uL) { | 
					
						
							|  |  |  |                x = 0uL; | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |                continue; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |             if ((r % 5uL) == 0uL) { | 
					
						
							|  |  |  |                x = 0uL; | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |                continue; | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |             if ((r % 7uL) == 0uL) { | 
					
						
							|  |  |  |                x = 0uL; | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |                continue; | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |             if ((r % 11uL) == 0uL) { | 
					
						
							|  |  |  |                x = 0uL; | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |                continue; | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |             if ((r % 13uL) == 0uL) { | 
					
						
							|  |  |  |                x = 0uL; | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |                continue; | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |             if ((r % 17uL) == 0uL) { | 
					
						
							|  |  |  |                x = 0uL; | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |                continue; | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |             if ((r % 19uL) == 0uL) { | 
					
						
							|  |  |  |                x = 0uL; | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |                continue; | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |             if ((r % 23uL) == 0uL) { | 
					
						
							|  |  |  |                x = 0uL; | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |                continue; | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |             if ((r % 29uL) == 0uL) { | 
					
						
							|  |  |  |                x = 0uL; | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |                continue; | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             /* now check if r is divisible by x + k={1,7,11,13,17,19,23,29} */ | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |             for (x = 30uL; x <= y; x += 30uL) { | 
					
						
							|  |  |  |                if ((r % (x + 1uL)) == 0uL) { | 
					
						
							|  |  |  |                   x = 0uL; | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |                   break; | 
					
						
							|  |  |  |                } | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |                if ((r % (x + 7uL)) == 0uL) { | 
					
						
							|  |  |  |                   x = 0uL; | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |                   break; | 
					
						
							|  |  |  |                } | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |                if ((r % (x + 11uL)) == 0uL) { | 
					
						
							|  |  |  |                   x = 0uL; | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |                   break; | 
					
						
							|  |  |  |                } | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |                if ((r % (x + 13uL)) == 0uL) { | 
					
						
							|  |  |  |                   x = 0uL; | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |                   break; | 
					
						
							|  |  |  |                } | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |                if ((r % (x + 17uL)) == 0uL) { | 
					
						
							|  |  |  |                   x = 0uL; | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |                   break; | 
					
						
							|  |  |  |                } | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |                if ((r % (x + 19uL)) == 0uL) { | 
					
						
							|  |  |  |                   x = 0uL; | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |                   break; | 
					
						
							|  |  |  |                } | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |                if ((r % (x + 23uL)) == 0uL) { | 
					
						
							|  |  |  |                   x = 0uL; | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |                   break; | 
					
						
							|  |  |  |                } | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |                if ((r % (x + 29uL)) == 0uL) { | 
					
						
							|  |  |  |                   x = 0uL; | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |                   break; | 
					
						
							|  |  |  |                } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |          } while (x == 0uL); | 
					
						
							|  |  |  |          if (r > 31uL) { | 
					
						
							|  |  |  |             fwrite(&r, 1uL, sizeof(mp_digit), out); | 
					
						
							| 
									
										
										
										
											2018-12-27 08:56:32 +01:00
										 |  |  |             printf("%9lu\r", r); | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |             fflush(stdout); | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |          } | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |          if (r < 31uL) break; | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-10 10:12:09 +01:00
										 |  |  |       fclose(out); | 
					
						
							|  |  |  |    } | 
					
						
							| 
									
										
										
										
											2003-02-28 16:06:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-01 22:28:43 +01:00
										 |  |  | static void load_tab(void) | 
					
						
							| 
									
										
										
										
											2003-07-16 00:26:58 +00:00
										 |  |  | { | 
					
						
							|  |  |  |    primes = fopen("pprime.dat", "rb"); | 
					
						
							|  |  |  |    if (primes == NULL) { | 
					
						
							|  |  |  |       gen_prime(); | 
					
						
							|  |  |  |       primes = fopen("pprime.dat", "rb"); | 
					
						
							|  |  |  |    } | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |    fseek(primes, 0L, SEEK_END); | 
					
						
							| 
									
										
										
										
											2003-07-16 00:26:58 +00:00
										 |  |  |    n_prime = ftell(primes) / sizeof(mp_digit); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-01 22:28:43 +01:00
										 |  |  | static mp_digit prime_digit(void) | 
					
						
							| 
									
										
										
										
											2003-07-16 00:26:58 +00:00
										 |  |  | { | 
					
						
							|  |  |  |    int n; | 
					
						
							|  |  |  |    mp_digit d; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    n = abs(rand()) % n_prime; | 
					
						
							|  |  |  |    fseek(primes, n * sizeof(mp_digit), SEEK_SET); | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |    fread(&d, 1uL, sizeof(mp_digit), primes); | 
					
						
							| 
									
										
										
										
											2003-07-16 00:26:58 +00:00
										 |  |  |    return d; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-28 16:06:22 +00:00
										 |  |  | /* makes a prime of at least k bits */ | 
					
						
							| 
									
										
										
										
											2018-02-01 22:28:43 +01:00
										 |  |  | static int pprime(int k, int li, mp_int *p, mp_int *q) | 
					
						
							| 
									
										
										
										
											2003-02-28 16:06:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    mp_int  a, b, c, n, x, y, z, v; | 
					
						
							|  |  |  |    int     res, ii; | 
					
						
							|  |  |  |    static const mp_digit bases[] = { 2, 3, 5, 7, 11, 13, 17, 19 }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    /* single digit ? */ | 
					
						
							|  |  |  |    if (k <= (int) DIGIT_BIT) { | 
					
						
							|  |  |  |       mp_set(p, prime_digit()); | 
					
						
							|  |  |  |       return MP_OKAY; | 
					
						
							|  |  |  |    } | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    if ((res = mp_init(&c)) != MP_OKAY) { | 
					
						
							|  |  |  |       return res; | 
					
						
							|  |  |  |    } | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    if ((res = mp_init(&v)) != MP_OKAY) { | 
					
						
							|  |  |  |       goto LBL_C; | 
					
						
							|  |  |  |    } | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    /* product of first 50 primes */ | 
					
						
							|  |  |  |    if ((res = | 
					
						
							|  |  |  |            mp_read_radix(&v, | 
					
						
							|  |  |  |                          "19078266889580195013601891820992757757219839668357012055907516904309700014933909014729740190", | 
					
						
							|  |  |  |                          10)) != MP_OKAY) { | 
					
						
							|  |  |  |       goto LBL_V; | 
					
						
							|  |  |  |    } | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    if ((res = mp_init(&a)) != MP_OKAY) { | 
					
						
							|  |  |  |       goto LBL_V; | 
					
						
							|  |  |  |    } | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    /* set the prime */ | 
					
						
							|  |  |  |    mp_set(&a, prime_digit()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    if ((res = mp_init(&b)) != MP_OKAY) { | 
					
						
							|  |  |  |       goto LBL_A; | 
					
						
							|  |  |  |    } | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    if ((res = mp_init(&n)) != MP_OKAY) { | 
					
						
							|  |  |  |       goto LBL_B; | 
					
						
							|  |  |  |    } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    if ((res = mp_init(&x)) != MP_OKAY) { | 
					
						
							|  |  |  |       goto LBL_N; | 
					
						
							|  |  |  |    } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    if ((res = mp_init(&y)) != MP_OKAY) { | 
					
						
							|  |  |  |       goto LBL_X; | 
					
						
							|  |  |  |    } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    if ((res = mp_init(&z)) != MP_OKAY) { | 
					
						
							|  |  |  |       goto LBL_Y; | 
					
						
							|  |  |  |    } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    /* now loop making the single digit */ | 
					
						
							|  |  |  |    while (mp_count_bits(&a) < k) { | 
					
						
							|  |  |  |       fprintf(stderr, "prime has %4d bits left\r", k - mp_count_bits(&a)); | 
					
						
							|  |  |  |       fflush(stderr); | 
					
						
							|  |  |  | top: | 
					
						
							|  |  |  |       mp_set(&b, prime_digit()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* now compute z = a * b * 2 */ | 
					
						
							|  |  |  |       if ((res = mp_mul(&a, &b, &z)) != MP_OKAY) {   /* z = a * b */ | 
					
						
							|  |  |  |          goto LBL_Z; | 
					
						
							| 
									
										
										
										
											2003-02-28 16:06:22 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |       if ((res = mp_copy(&z, &c)) != MP_OKAY) {   /* c = a * b */ | 
					
						
							|  |  |  |          goto LBL_Z; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |       if ((res = mp_mul_2(&z, &z)) != MP_OKAY) {  /* z = 2 * a * b */ | 
					
						
							|  |  |  |          goto LBL_Z; | 
					
						
							| 
									
										
										
										
											2003-02-28 16:06:22 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |       /* n = z + 1 */ | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |       if ((res = mp_add_d(&z, 1uL, &n)) != MP_OKAY) {  /* n = z + 1 */ | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |          goto LBL_Z; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |       /* check (n, v) == 1 */ | 
					
						
							|  |  |  |       if ((res = mp_gcd(&n, &v, &y)) != MP_OKAY) {   /* y = (n, v) */ | 
					
						
							|  |  |  |          goto LBL_Z; | 
					
						
							| 
									
										
										
										
											2003-02-28 16:07:32 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |       if (mp_cmp_d(&y, 1uL) != MP_EQ) | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |          goto top; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* now try base x=bases[ii]  */ | 
					
						
							|  |  |  |       for (ii = 0; ii < li; ii++) { | 
					
						
							|  |  |  |          mp_set(&x, bases[ii]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          /* compute x^a mod n */ | 
					
						
							|  |  |  |          if ((res = mp_exptmod(&x, &a, &n, &y)) != MP_OKAY) {  /* y = x^a mod n */ | 
					
						
							|  |  |  |             goto LBL_Z; | 
					
						
							|  |  |  |          } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          /* if y == 1 loop */ | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |          if (mp_cmp_d(&y, 1uL) == MP_EQ) | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          /* now x^2a mod n */ | 
					
						
							|  |  |  |          if ((res = mp_sqrmod(&y, &n, &y)) != MP_OKAY) {    /* y = x^2a mod n */ | 
					
						
							|  |  |  |             goto LBL_Z; | 
					
						
							|  |  |  |          } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |          if (mp_cmp_d(&y, 1uL) == MP_EQ) | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          /* compute x^b mod n */ | 
					
						
							|  |  |  |          if ((res = mp_exptmod(&x, &b, &n, &y)) != MP_OKAY) {  /* y = x^b mod n */ | 
					
						
							|  |  |  |             goto LBL_Z; | 
					
						
							|  |  |  |          } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          /* if y == 1 loop */ | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |          if (mp_cmp_d(&y, 1uL) == MP_EQ) | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          /* now x^2b mod n */ | 
					
						
							|  |  |  |          if ((res = mp_sqrmod(&y, &n, &y)) != MP_OKAY) {    /* y = x^2b mod n */ | 
					
						
							|  |  |  |             goto LBL_Z; | 
					
						
							|  |  |  |          } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |          if (mp_cmp_d(&y, 1uL) == MP_EQ) | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          /* compute x^c mod n == x^ab mod n */ | 
					
						
							|  |  |  |          if ((res = mp_exptmod(&x, &c, &n, &y)) != MP_OKAY) {  /* y = x^ab mod n */ | 
					
						
							|  |  |  |             goto LBL_Z; | 
					
						
							|  |  |  |          } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          /* if y == 1 loop */ | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |          if (mp_cmp_d(&y, 1uL) == MP_EQ) | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          /* now compute (x^c mod n)^2 */ | 
					
						
							|  |  |  |          if ((res = mp_sqrmod(&y, &n, &y)) != MP_OKAY) {    /* y = x^2ab mod n */ | 
					
						
							|  |  |  |             goto LBL_Z; | 
					
						
							|  |  |  |          } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          /* y should be 1 */ | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |          if (mp_cmp_d(&y, 1uL) != MP_EQ) | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |             continue; | 
					
						
							|  |  |  |          break; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |       /* no bases worked? */ | 
					
						
							|  |  |  |       if (ii == li) | 
					
						
							|  |  |  |          goto top; | 
					
						
							| 
									
										
										
										
											2003-02-28 16:06:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |       { | 
					
						
							|  |  |  |          char buf[4096]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          mp_toradix(&n, buf, 10); | 
					
						
							|  |  |  |          printf("Certificate of primality for:\n%s\n\n", buf); | 
					
						
							|  |  |  |          mp_toradix(&a, buf, 10); | 
					
						
							|  |  |  |          printf("A == \n%s\n\n", buf); | 
					
						
							|  |  |  |          mp_toradix(&b, buf, 10); | 
					
						
							| 
									
										
										
										
											2018-12-27 08:56:32 +01:00
										 |  |  |          printf("B == \n%s\n\nG == %lu\n", buf, bases[ii]); | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |          printf("----------------------------------------------------------------\n"); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* a = n */ | 
					
						
							|  |  |  |       mp_copy(&n, &a); | 
					
						
							|  |  |  |    } | 
					
						
							| 
									
										
										
										
											2003-07-16 00:26:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    /* get q to be the order of the large prime subgroup */ | 
					
						
							| 
									
										
										
										
											2018-02-13 19:04:25 +01:00
										 |  |  |    mp_sub_d(&n, 1uL, q); | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    mp_div_2(q, q); | 
					
						
							|  |  |  |    mp_div(q, &b, q, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    mp_exch(&n, p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    res = MP_OKAY; | 
					
						
							|  |  |  | LBL_Z: | 
					
						
							|  |  |  |    mp_clear(&z); | 
					
						
							|  |  |  | LBL_Y: | 
					
						
							|  |  |  |    mp_clear(&y); | 
					
						
							|  |  |  | LBL_X: | 
					
						
							|  |  |  |    mp_clear(&x); | 
					
						
							|  |  |  | LBL_N: | 
					
						
							|  |  |  |    mp_clear(&n); | 
					
						
							|  |  |  | LBL_B: | 
					
						
							|  |  |  |    mp_clear(&b); | 
					
						
							|  |  |  | LBL_A: | 
					
						
							|  |  |  |    mp_clear(&a); | 
					
						
							|  |  |  | LBL_V: | 
					
						
							|  |  |  |    mp_clear(&v); | 
					
						
							|  |  |  | LBL_C: | 
					
						
							|  |  |  |    mp_clear(&c); | 
					
						
							|  |  |  |    return res; | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2003-02-28 16:06:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  | int main(void) | 
					
						
							| 
									
										
										
										
											2003-02-28 16:06:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    mp_int  p, q; | 
					
						
							|  |  |  |    char    buf[4096]; | 
					
						
							|  |  |  |    int     k, li; | 
					
						
							|  |  |  |    clock_t t1; | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    srand(time(NULL)); | 
					
						
							|  |  |  |    load_tab(); | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    printf("Enter # of bits: \n"); | 
					
						
							|  |  |  |    fgets(buf, sizeof(buf), stdin); | 
					
						
							|  |  |  |    sscanf(buf, "%d", &k); | 
					
						
							| 
									
										
										
										
											2003-02-28 16:06:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    printf("Enter number of bases to try (1 to 8):\n"); | 
					
						
							|  |  |  |    fgets(buf, sizeof(buf), stdin); | 
					
						
							|  |  |  |    sscanf(buf, "%d", &li); | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    mp_init(&p); | 
					
						
							|  |  |  |    mp_init(&q); | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    t1 = clock(); | 
					
						
							|  |  |  |    pprime(k, li, &p, &q); | 
					
						
							|  |  |  |    t1 = clock() - t1; | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    printf("\n\nTook %ld ticks, %d bits\n", t1, mp_count_bits(&p)); | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    mp_toradix(&p, buf, 10); | 
					
						
							|  |  |  |    printf("P == %s\n", buf); | 
					
						
							|  |  |  |    mp_toradix(&q, buf, 10); | 
					
						
							|  |  |  |    printf("Q == %s\n", buf); | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-18 10:44:06 +02:00
										 |  |  |    return 0; | 
					
						
							| 
									
										
										
										
											2003-02-28 16:08:34 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2005-08-01 16:37:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-28 16:27:26 +02:00
										 |  |  | /* ref:         $Format:%D$ */ | 
					
						
							|  |  |  | /* git commit:  $Format:%H$ */ | 
					
						
							|  |  |  | /* commit time: $Format:%ai$ */ |