--- pgp/src/genprime.c 2018/04/24 16:38:58 1.1.1.2 +++ pgp/src/genprime.c 2018/04/24 16:40:31 1.1.1.4 @@ -2,8 +2,9 @@ used by public-key key generation routines. First version 17 Mar 87 Last revised 2 Jun 91 by PRZ + 24 Apr 93 by CP - (c) Copyright 1987 by Philip Zimmermann. All rights reserved. + (c) Copyright 1987,1993 by Philip Zimmermann. All rights reserved. The author assumes no liability for damages resulting from the use of this software, even if the damage results from defects in this software. No warranty is expressed or implied. @@ -45,6 +46,10 @@ #include "mpilib.h" #include "genprime.h" +#if defined(MSDOS) && !defined(__GO32__) +#include +#endif + /* if PSEUDORANDOM is defined, it disables truly random numbers in random.h */ /* #define PSEUDORANDOM */ #include "random.h" @@ -58,6 +63,30 @@ This justifies disabling the lengthy search for strong primes. */ +#define BLUM +/* If BLUM is defined, this looks for prines congruent to 3 modulo 4. + The product of two of these is a Blum integer. You can uniquely define + a square root Cmodulo a Blum integer, which leads to some extra + possibilities for encryption algorithms. This shrinks the key space by + 2 bits, which is not considered significant. +*/ + +#ifdef STRONGPRIMES + +static boolean primetest(unitptr p); + /* Returns TRUE iff p is a prime. */ + +static int mp_sqrt(unitptr quotient,unitptr dividend); + /* Quotient is returned as the square root of dividend. */ + +#endif + +static int nextprime(unitptr p); + /* Find next higher prime starting at p, returning result in p. */ + +static void randombits(unitptr p,short nbits); + /* Make a random unit array p with nbits of precision. */ + #ifdef DEBUG #define DEBUGprintf1(x) printf(x) #define DEBUGprintf2(x,y) printf(x,y) @@ -72,7 +101,7 @@ /* primetable is a table of 16-bit prime numbers used for sieving and for other aspects of public-key cryptographic key generation */ -word16 primetable[] = { +static word16 primetable[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, @@ -263,7 +292,9 @@ static boolean slowtest(unitptr p) } /* slowtest -- fermattest */ -boolean primetest(unitptr p) +#ifdef STRONGPRIMES + +static boolean primetest(unitptr p) /* Returns TRUE iff p is a prime. If p doesn't pass through the sieve, then p is definitely NOT a prime. If p is small enough for the sieve to prove primality or not, @@ -328,6 +359,7 @@ boolean primetest(unitptr p) return(slowtest(p)); /* returns TRUE or FALSE */ } /* primetest */ +#endif static void buildsieve(unitptr p, word16 remainders[]) /* Used in conjunction with fastsieve. Builds a table of remainders @@ -400,7 +432,7 @@ static boolean fastsieve(word16 pdelta, #define numberof(x) (sizeof(x)/sizeof(x[0])) /* number of table entries */ -int nextprime(unitptr p) +static int nextprime(unitptr p) /* Find next higher prime starting at p, returning result in p. Uses fast prime sieving algorithm to search sequentially. Returns 0 for normal completion status, < 0 for failure status. @@ -429,7 +461,11 @@ int nextprime(unitptr p) return(0); /* normal completion status */ } +#ifndef BLUM lsunit(p) |= 1; /* set candidate's lsb - make it odd */ +#else + lsunit(p) |= 3; /* Make candidate ==3 mod 4 */ +#endif /* Adjust the global_precision downward to the optimum size for p...*/ oldprecision = global_precision; /* save global_precision */ @@ -454,7 +490,12 @@ int nextprime(unitptr p) /* slowtest will not be called unless fastsieve is true */ /* range is how far to search before giving up. */ +#ifndef BLUM range = 4 * units2bits(global_precision); +#else + /* Twice as many because step size is twice as large, */ + range = 8 * units2bits(global_precision); +#endif suspects = 0; /* number of suspected primes and slowtest trials */ while (TRUE) { @@ -468,7 +509,12 @@ int nextprime(unitptr p) if (slowtest(p)) break; /* found a prime */ } +#ifndef BLUM pdelta += 2; /* try next odd number */ +#else + pdelta += 4; + mp_inc(p); mp_inc(p); +#endif mp_inc(p); mp_inc(p); if (pdelta > range) /* searched too many candidates? */ @@ -517,12 +563,12 @@ static unit randomunit(void) i = BYTES_PER_UNIT; do u = (u << 8) + randombyte(); - while (--i); + while (--i != 0); return(u); } /* randomunit */ -void randombits(unitptr p, short nbits) +static void randombits(unitptr p, short nbits) /* Make a random unit array p with nbits of precision. Used mainly to generate large random numbers to search for primes. */ @@ -697,6 +743,7 @@ void mp_inv(unitptr x,unitptr a,unitptr #undef v } /* mp_inv */ +#ifdef STRONGPRIMES /* mp_sqrt - returns square root of a number. returns -1 for error, 0 for perfect square, 1 for not perfect square. @@ -728,7 +775,7 @@ void mp_inv(unitptr x,unitptr a,unitptr 6) Proceed in this manner until all periods are used. If there is still a remainder, it's not a perfect square. */ -int mp_sqrt(unitptr quotient,unitptr dividend) +static int mp_sqrt(unitptr quotient,unitptr dividend) /* Quotient is returned as the square root of dividend. */ { register short next2bits; /* "period", or group of 2 bits of dividend */ @@ -826,6 +873,7 @@ int mp_sqrt(unitptr quotient,unitptr div return(notperfect); /* normal return */ } /* mp_sqrt */ +#endif /*------------------- End of keygen.c -----------------------------*/