--- pgp/src/genprime.c 2018/04/24 16:38:58 1.1.1.2 +++ pgp/src/genprime.c 2018/04/24 16:42:41 1.1.1.6 @@ -2,11 +2,24 @@ 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. - 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. + (c) Copyright 1990-1994 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. + + Note that while most PGP source modules bear Philip Zimmermann's + copyright notice, many of them have been revised or entirely written + by contributors who frequently failed to put their names in their + code. Code that has been incorporated into PGP from other authors + was either originally published in the public domain or is used with + permission from the various authors. + + PGP is available for free to the public under certain restrictions. + See the PGP User's Guide (included in the release package) for + important information about licensing, patent restrictions on + certain algorithms, trademarks, copyrights, and export controls. These functions are for the generation of large prime integers and for other functions related to factoring and key generation for @@ -45,19 +58,62 @@ #include "mpilib.h" #include "genprime.h" -/* if PSEUDORANDOM is defined, it disables truly random numbers in random.h */ -/* #define PSEUDORANDOM */ +#if defined(MSDOS) && !defined(__GO32__) +#include +#endif + #include "random.h" /* #define STRONGPRIMES */ /* if defined, generate "strong" primes for key */ -/* "Strong" primes may no longer be advantageous, due to the new - elliptical curve method of factoring. Randomly selected primes - are as good as any. See "Factoring", by Duncan A. Buell, Journal - of Supercomputing 1 (1987), pages 191-216. - This justifies disabling the lengthy search for strong primes. +/* + *"Strong" primes are no longer advantageous, due to the new + * elliptical curve method of factoring. Randomly selected primes + * are as good as any. See "Factoring", by Duncan A. Buell, Journal + * of Supercomputing 1 (1987), pages 191-216. + * This justifies disabling the lengthy search for strong primes. + * + * The advice about strong primes in the early RSA literature applies + * to 256-bit moduli where the attacks were the Pollard rho and P-1 + * factoring algorithms. Later developments in factoring have entirely + * supplanted these methods. The later algorithms are always faster + * (so we need bigger primes), and don't care about STRONGPRIMES. + * + * The early literature was saying that you can get away with small + * moduli if you choose the primes carefully. The later developments + * say you can't get away with small moduli, period. And it doesn't + * matter how you choose the primes. + * + * It's just taking a heck of a long time for the advice on "strong primes" + * to disappear from the books. Authors keep going back to the original + * documents and repeating what they read there, even though it's out + * of date. + */ + +#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 +128,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, @@ -112,7 +168,6 @@ word16 primetable[] = { 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, -#ifdef BIGSIEVE /* use giant sieve */ 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, @@ -204,7 +259,6 @@ word16 primetable[] = { 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, 8167, 8171, 8179, 8191, -#endif /* BIGSIEVE */ #endif /* not EMBEDDED, use larger table */ 0 } ; /* null-terminated list, with only one null at end */ @@ -212,10 +266,11 @@ word16 primetable[] = { #ifdef UNIT8 static word16 bottom16(unitptr r) -/* Called from nextprime and primetest. Returns low 16 bits of r. */ -{ make_lsbptr(r,(global_precision-((2/BYTES_PER_UNIT)-1))); - return( *((word16 *)(r)) ); -} /* bottom16 */ +/* Called from nextprime and primetest. Returns low 16 bits of r. */ +{ + make_lsbptr(r,(global_precision-((2/BYTES_PER_UNIT)-1))); + return *(word16 *)r; +} /* bottom16 */ #else /* UNIT16 or UNIT32 */ #define bottom16(r) ((word16) lsunit(r)) /* or UNIT32 could mask off lower 16 bits, instead of typecasting it. */ @@ -223,32 +278,34 @@ static word16 bottom16(unitptr r) static boolean slowtest(unitptr p) -/* This routine tests p for primality by applying Fermat's theorem: - For any x, if ((x**(p-1)) mod p) != 1, then p is not prime. - By trying a few values for x, we can determine if p is "probably" prime. - - Because this test is so slow, it is recommended that p be sieved first - to weed out numbers that are obviously not prime. - - Contrary to what you may have read in the literature, empirical evidence - shows this test weeds out a LOT more than 50% of the composite candidates - for each trial x. Each test catches nearly all the composites. -*/ -{ unit x[MAX_UNIT_PRECISION], is_one[MAX_UNIT_PRECISION]; +/* + * This routine tests p for primality by applying Fermat's theorem: + * For any x, if ((x**(p-1)) mod p) != 1, then p is not prime. + * By trying a few values for x, we can determine if p is "probably" prime. + * + * Because this test is so slow, it is recommended that p be sieved first + * to weed out numbers that are obviously not prime. + * + * Contrary to what you may have read in the literature, empirical evidence + * shows this test weeds out a LOT more than 50% of the composite candidates + * for each trial x. Each test catches nearly all the composites. + */ +{ + unit x[MAX_UNIT_PRECISION], is_one[MAX_UNIT_PRECISION]; unit pminus1[MAX_UNIT_PRECISION]; short i; mp_move(pminus1,p); mp_dec(pminus1); - for (i=0; i<4; i++) /* Just do a few tests. */ - { poll_for_break(); /* polls keyboard, allows ctrl-C to abort program */ + for (i=0; i<4; i++) { /* Just do a few tests. */ + poll_for_break(); /* polls keyboard, allows ctrl-C to abort program */ mp_init(x,primetable[i]); /* Use any old random trial x */ /* if ((x**(p-1)) mod p) != 1, then p is not prime */ if (mp_modexp(is_one,x,pminus1,p) < 0) /* modexp error? */ - return(FALSE); /* error means return not prime status */ + return FALSE; /* error means return not prime status */ if (testne(is_one,1)) /* then p is not prime */ - return(FALSE); /* return not prime status */ + return FALSE; /* return not prime status */ #ifdef SHOWPROGRESS putchar('+'); /* let user see how we are progressing */ fflush(stdout); @@ -259,24 +316,28 @@ static boolean slowtest(unitptr p) mp_burn(x); /* burn the evidence on the stack...*/ mp_burn(is_one); mp_burn(pminus1); - return(TRUE); -} /* slowtest -- fermattest */ + return TRUE; +} /* slowtest -- fermattest */ -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, - and p passes through the sieve, then p is definitely a prime. - If p is large and p passes through the sieve and may be a prime, - then p is further tested for primality with a slower test. -*/ -{ short i; +#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, + * and p passes through the sieve, then p is definitely a prime. + * If p is large and p passes through the sieve and may be a prime, + * then p is further tested for primality with a slower test. + */ +{ + short i; static word16 lastprime = 0; /* last prime in primetable */ word16 sqrt_p; /* to limit sieving past sqrt(p), for small p's */ - if (!lastprime) /* lastprime still undefined. So define it. */ - { /* executes this code only once, then skips it next time */ + if (!lastprime) { /* lastprime still undefined. So define it. */ + /* executes this code only once, then skips it next time */ for (i=0; primetable[i]; i++) ; /* seek end of primetable */ lastprime = primetable[i-1]; /* get last prime in table */ @@ -285,60 +346,67 @@ boolean primetest(unitptr p) if (significance(p) <= (2/BYTES_PER_UNIT)) /* if p <= 16 bits */ /* p may be in primetable. Search it. */ if (bottom16(p) <= lastprime) - for (i=0; primetable[i]; i++) /* scan until null-terminator */ - { if (primetable[i] == bottom16(p)) - return(TRUE); /* yep, definitely a prime. */ + for (i=0; primetable[i]; i++) { + /* scan until null-terminator */ + if (primetable[i] == bottom16(p)) + return TRUE; /* yep, definitely a prime. */ if (primetable[i] > bottom16(p)) /* we missed. */ - return(FALSE); /* definitely NOT a prime. */ - } /* We got past the whole primetable without a hit. */ + return FALSE; /* definitely NOT a prime. */ + } /* We got past the whole primetable without a hit. */ /* p is bigger than any prime in primetable, so let's sieve. */ if (!(lsunit(p) & 1)) /* if least significant bit is 0... */ - return(FALSE); /* divisible by 2, not prime */ + return FALSE; /* divisible by 2, not prime */ if (mp_tstminus(p)) /* error if p<0 */ - return(FALSE); /* not prime if p<0 */ + return FALSE; /* not prime if p<0 */ - /* Optimization for small (32 bits or less) p's. - If p is small, compute sqrt_p = sqrt(p), or else - if p is >32 bits then just set sqrt_p to something - at least as big as the largest primetable entry. - */ - if (significance(p) <= (4/BYTES_PER_UNIT)) /* if p <= 32 bits */ - { unit sqrtp[MAX_UNIT_PRECISION]; + /* + * Optimization for small (32 bits or less) p's. + * If p is small, compute sqrt_p = sqrt(p), or else + * if p is >32 bits then just set sqrt_p to something + * at least as big as the largest primetable entry. + */ + if (significance(p) <= (4/BYTES_PER_UNIT)) { /* if p <= 32 bits */ + unit sqrtp[MAX_UNIT_PRECISION]; /* Just sieve up to sqrt(p) */ if (mp_sqrt(sqrtp,p) == 0) /* 0 means p is a perfect square */ - return(FALSE); /* perfect square is not a prime */ + return FALSE; /* perfect square is not a prime */ /* we know that sqrtp <= 16 bits because p <= 32 bits */ sqrt_p = bottom16(sqrtp); - } /* if p <= 32 bits */ - else /* p > 32 bits, so obviate sqrt(p) test. */ + } else { + /* p > 32 bits, so obviate sqrt(p) test. */ sqrt_p = lastprime; /* ensures that we do ENTIRE sieve. */ + } - for (i=1; primetable[i]; i++) /* p is assumed odd, so begin sieve at 3 */ - { /* Compute p mod (primetable[i]). If it divides evenly...*/ + /* p is assumed odd, so begin sieve at 3 */ + for (i=1; primetable[i]; i++) { + /* Compute p mod (primetable[i]). If it divides evenly...*/ if (mp_shortmod(p,primetable[i]) == 0) - return(FALSE); /* then p is definitely NOT prime */ + return FALSE; /* then p is definitely NOT prime */ if (primetable[i] > sqrt_p) /* fully sieved p? */ - return(TRUE); /* yep, fully passed sieve, definitely a prime. */ + return TRUE; /* yep, fully passed sieve, definitely a prime. */ } /* It passed the sieve, so p is a suspected prime. */ /* Now try slow complex primality test on suspected prime. */ - return(slowtest(p)); /* returns TRUE or FALSE */ + 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 - relative to the random starting point p, so that fastsieve can - sequentially sieve for suspected primes quickly. Call buildsieve - once, then call fastsieve for consecutive prime candidates. - Note that p must be odd, because the sieve begins at 3. -*/ -{ short i; - for (i=1; primetable[i]; i++) - { remainders[i] = mp_shortmod(p,primetable[i]); +/* + * Used in conjunction with fastsieve. Builds a table of remainders + * relative to the random starting point p, so that fastsieve can + * sequentially sieve for suspected primes quickly. Call buildsieve + * once, then call fastsieve for consecutive prime candidates. + * Note that p must be odd, because the sieve begins at 3. + */ +{ + short i; + for (i=1; primetable[i]; i++) { + remainders[i] = mp_shortmod(p,primetable[i]); } } /* buildsieve */ @@ -382,54 +450,64 @@ static boolean fastsieve(word16 pdelta, may be a prime. Note that p must be odd, because the sieve begins at 3. */ -{ short i; - for (i=1; primetable[i]; i++) - { /* If pdelta plus a remainders table entry is evenly - divisible by the corresponding primetable entry, - then p+pdelta is factorable by that primetable entry, - which means p+pdelta is not prime. - */ - if (( (pdelta + remainders[i]) % primetable[i] ) == 0) - return(FALSE); /* then p+pdelta is not prime */ +{ + short i; + for (i=1; primetable[i]; i++) { + /* + * If pdelta plus a remainders table entry is evenly + * divisible by the corresponding primetable entry, + * then p+pdelta is factorable by that primetable entry, + * which means p+pdelta is not prime. + */ + if ( (pdelta+remainders[i]) % primetable[i] == 0) + return FALSE; /* then p+pdelta is not prime */ } /* It passed the sieve. It is now a suspected prime. */ - return(TRUE); + return TRUE; } /* fastsieve */ #define numberof(x) (sizeof(x)/sizeof(x[0])) /* number of table entries */ -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. - */ -{ word16 pdelta, range; +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. + */ +{ + word16 pdelta, range; short oldprecision; short i, suspects; /* start search at candidate p */ mp_inc(p); /* remember, it's the NEXT prime from p, noninclusive. */ - if (significance(p) <= 1) - { /* p might be smaller than the largest prime in primetable. - We can't sieve for primes that are already in primetable. - We will have to directly search the table. - */ - for (i=0; primetable[i]; i++) /* scan until null-terminator */ - { if (primetable[i] >= lsunit(p)) - { mp_init(p,primetable[i]); - return(0); /* return next higher prime from primetable */ + if (significance(p) <= 1) { + /* + * p might be smaller than the largest prime in primetable. + * We can't sieve for primes that are already in primetable. + * We will have to directly search the table. + */ + /* scan until null-terminator */ + for (i=0; primetable[i]; i++) { + if (primetable[i] >= lsunit(p)) { + mp_init(p,primetable[i]); + return 0; /* return next higher prime from primetable */ } } /* We got past the whole primetable without a hit. */ } /* p is bigger than any prime in primetable, so let's sieve. */ - if (mp_tstminus(p)) /* error if p<0 */ - { mp_init(p,2); /* next prime >0 is 2 */ - return(0); /* normal completion status */ + if (mp_tstminus(p)) { /* error if p<0 */ + mp_init(p,2); /* next prime >0 is 2 */ + 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,13 +532,17 @@ 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) - { + for (;;) { /* equivalent to: if (primetest(p)) break; */ - if (fastsieve(pdelta,remainders)) /* found suspected prime */ - { suspects++; /* tally for statistical purposes */ + if (fastsieve(pdelta,remainders)) { /* found suspected prime */ + suspects++; /* tally for statistical purposes */ #ifdef SHOWPROGRESS putchar('.'); /* let user see how we are progressing */ fflush(stdout); @@ -468,7 +550,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? */ @@ -489,12 +576,12 @@ int nextprime(unitptr p) set_precision(oldprecision); /* restore precision */ - if (pdelta > range) /* searched too many candidates? */ - { if (suspects < 1) /* unreasonable to have found no suspects */ - return(NOSUSPECTS); /* fastsieve failed, probably */ - return(NOPRIMEFOUND); /* return error status */ + if (pdelta > range) { /* searched too many candidates? */ + if (suspects < 1) /* unreasonable to have found no suspects */ + return NOSUSPECTS; /* fastsieve failed, probably */ + return NOPRIMEFOUND; /* return error status */ } - return(0); /* return normal completion status */ + return 0; /* return normal completion status */ } /* nextprime */ @@ -503,57 +590,60 @@ int nextprime(unitptr p) In most implementations, our random number supply is derived from random keyboard delays rather than a hardware random number chip. So we will have to ensure we have a large enough pool of - accumulated random numbers from the keyboard. Later, randombyte - will return bytes one at a time from the accumulated pool of - random numbers. For ergonomic reasons, we may want to prefill - this random pool all at once initially. Subroutine randaccum prefills - a pool of random bits. + accumulated random numbers from the keyboard. trueRandAccum() + performs this operation. */ static unit randomunit(void) - /* Fills 1 unit with random bytes, and returns unit. */ -{ unit u = 0; +/* Fills 1 unit with random bytes, and returns unit. */ +{ + unit u = 0; byte i; i = BYTES_PER_UNIT; do - u = (u << 8) + randombyte(); - while (--i); - return(u); + u = (u << 8) + trueRandByte(); + while (--i != 0); + return u; } /* randomunit */ -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. -*/ -{ /* Fill a unit array with exactly nbits of random bits... */ - short nunits; /* units of precision */ - mp_init(p,0); - nunits = bits2units(nbits); /* round up to units */ - make_lsbptr(p,global_precision); - *p = randomunit(); - while (--nunits) - { *pre_higherunit(p) = randomunit(); +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. + */ +{ + mp_init(p, 0); + make_lsbptr(p, global_precision); + + /* Add whole units of randomness */ + while (nbits >= UNITSIZE) { + *post_higherunit(p) = randomunit(); nbits -= UNITSIZE; } - *p &= (power_of_2(nbits)-1); /* clear the top unused bits remaining */ + + /* Add most-significant partial unit (if any) */ + if (nbits) + *p = randomunit() & (power_of_2(nbits)-1); } /* randombits */ int randomprime(unitptr p,short nbits) - /* Makes a "random" prime p with nbits significant bits of precision. - Since these primes are used to compute a modulus of a guaranteed - length, the top 2 bits of the prime are set to 1, so that the - product of 2 primes (the modulus) is of a deterministic length. - Returns 0 for normal completion status, < 0 for failure status. - */ -{ DEBUGprintf2("\nGenerating a %d-bit random prime. ",nbits); +/* + * Makes a "random" prime p with nbits significant bits of precision. + * Since these primes are used to compute a modulus of a guaranteed + * length, the top 2 bits of the prime are set to 1, so that the + * product of 2 primes (the modulus) is of a deterministic length. + * Returns 0 for normal completion status, < 0 for failure status. + */ +{ + DEBUGprintf2("\nGenerating a %d-bit random prime. ",nbits); /* Get an initial random candidate p to start search. */ randombits(p,nbits-2); /* 2 less random bits for nonrandom top bits */ /* To guarantee exactly nbits of significance, set the top 2 bits to 1 */ mp_setbit(p,nbits-1); /* highest bit is nonrandom */ mp_setbit(p,nbits-2); /* next highest bit is also nonrandom */ - return(nextprime(p)); /* search for next higher prime from starting point p */ + return nextprime(p); /* search for next higher prime from starting point p */ } /* randomprime */ @@ -568,7 +658,8 @@ static boolean tryprime(unitptr p,unitpt significance. Prime p1 must be less than maxbits-log_1stprime in length. This routine is called only from goodprime. */ -{ int i; +{ + int i; unit i2[MAX_UNIT_PRECISION]; /* Generate p such that p = (i*2*p1)+1, for i=1,2,3,5,7,11,13,17... and test p for primality for each small prime i. @@ -576,12 +667,12 @@ static boolean tryprime(unitptr p,unitpt because then p grows slower in significance. Start looking for small primes that are > firstprime... */ - if ((countbits(p1)+log_1stprime)>=maxbits) - { DEBUGprintf1("\007[Error: overconstrained prime]"); - return(FALSE); /* failed to make a good prime */ + if ((countbits(p1)+log_1stprime)>=maxbits) { + DEBUGprintf1("\007[Error: overconstrained prime]"); + return FALSE; /* failed to make a good prime */ } - for (i=0; primetable[i]; i++) - { if (primetable[i]32767 */ mp_init(i2,primetable[i]<<1); @@ -589,22 +680,25 @@ static boolean tryprime(unitptr p,unitpt if (countbits(p)>maxbits) break; DEBUGprintf1("."); if (primetest(p)) - return(TRUE); + return TRUE; } - return(FALSE); /* failed to make a good prime */ + return FALSE; /* failed to make a good prime */ } /* tryprime */ int goodprime(unitptr p,short maxbits,short minbits) -/* Make a "strong" prime p with at most maxbits and at least minbits of - significant bits of precision. This algorithm is called to generate - a high-quality prime p for key generation purposes. It must have - special characteristics for making a modulus n that is hard to factor. - Returns 0 for normal completion status, < 0 for failure status. -*/ -{ unit p1[MAX_UNIT_PRECISION]; +/* + * Make a "strong" prime p with at most maxbits and at least minbits of + * significant bits of precision. This algorithm is called to generate + * a high-quality prime p for key generation purposes. It must have + * special characteristics for making a modulus n that is hard to factor. + * Returns 0 for normal completion status, < 0 for failure status. + */ +{ + unit p1[MAX_UNIT_PRECISION]; short oldprecision,midbits; int status; + mp_init(p,0); /* Adjust the global_precision downward to the optimum size for p...*/ oldprecision = global_precision; /* save global_precision */ @@ -617,11 +711,11 @@ int goodprime(unitptr p,short maxbits,sh midbits = (maxbits+minbits)/2; /* length of p' */ DEBUGprintf3("\nGenerating a %d-%d bit refined prime. ", minbits+2*log_1stprime,maxbits); - do - { do - { status = randomprime(p,minbits-1); + do { + do { + status = randomprime(p,minbits-1); if (status < 0) - return(status); /* failed to find a random prime */ + return status; /* failed to find a random prime */ DEBUGprintf2("\n(p\042=%d bits)",countbits(p)); } while (!tryprime(p1,p,midbits)); DEBUGprintf2("(p'=%d bits)",countbits(p1)); @@ -629,7 +723,7 @@ int goodprime(unitptr p,short maxbits,sh DEBUGprintf2("\n\007(p=%d bits) ",countbits(p)); mp_burn(p1); /* burn the evidence on the stack */ set_precision(oldprecision); /* restore precision */ - return(0); /* normal completion status */ + return 0; /* normal completion status */ } /* goodprime */ #endif /* STRONGPRIMES */ @@ -639,32 +733,35 @@ int goodprime(unitptr p,short maxbits,sh #define iminus1 ( i==0 ? 2 : i-1 ) /* used by Euclid algorithms */ void mp_gcd(unitptr result,unitptr a,unitptr n) - /* Computes greatest common divisor via Euclid's algorithm. */ -{ short i; +/* Computes greatest common divisor via Euclid's algorithm. */ +{ + short i; unit gcopies[3][MAX_UNIT_PRECISION]; #define g(i) ( &(gcopies[i][0]) ) mp_move(g(0),n); mp_move(g(1),a); i=1; - while (testne(g(i),0)) - { mp_mod( g(iplus1),g(iminus1),g(i) ); + while (testne(g(i),0)) { + mp_mod( g(iplus1),g(iminus1),g(i) ); i = iplus1; } mp_move(result,g(iminus1)); mp_burn(g(iminus1)); /* burn the evidence on the stack...*/ mp_burn(g(iplus1)); #undef g -} /* mp_gcd */ +} /* mp_gcd */ void mp_inv(unitptr x,unitptr a,unitptr n) - /* Euclid's algorithm extended to compute multiplicative inverse. - Computes x such that a*x mod n = 1, where 0= 0) - { mp_sub(remainder,divisor); + if (mp_compare(remainder,divisor) >= 0) { + mp_sub(remainder,divisor); stuff_bit(quotient,qbitmask); mp_rotate_left(rjq,1); - } - else + } else { mp_rotate_left(rjq,0); + } bump_bitsniffer(quotient,qbitmask); } notperfect = testne(remainder,0); /* not a perfect square? */ set_precision(oldprecision); /* restore original precision */ - return(notperfect); /* normal return */ - + return notperfect; /* normal return */ } /* mp_sqrt */ +#endif /*------------------- End of keygen.c -----------------------------*/