--- pgp/src/rsagen.c 2018/04/24 16:40:22 1.1.1.4 +++ pgp/src/rsagen.c 2018/04/24 16:42:31 1.1.1.6 @@ -1,10 +1,10 @@ /* rsagen.c - C source code for RSA public-key key generation routines. First version 17 Mar 87 - (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 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. RSA-specific routines follow. These are the only functions that are specific to the RSA public key cryptosystem. The other @@ -27,7 +27,6 @@ #include "mpilib.h" #include "genprime.h" #include "rsagen.h" -/* Define symbol PSEUDORANDOM in random.h to disable truly random numbers. */ #include "random.h" #include "rsaglue.h" @@ -35,20 +34,6 @@ static void derive_rsakeys(unitptr n,uni unitptr p,unitptr q,unitptr u,short ebits); /* Given primes p and q, derive RSA key components n, e, d, and u. */ -/* The following #ifdefs determine constraints on key sizes... */ - -#ifdef WHOLEWORD_KEY /* some modmult algorithms are faster this way */ -#ifdef MERRITT_KEY -#undef MERRITT_KEY /* ensures MERRITT_KEY is undefined */ -#endif -#endif /* WHOLEWORD_KEY */ - -#ifdef MERRITT_KEY /* if using Merritt's modmult algorithm */ -#ifdef WHOLEWORD_KEY -#undef WHOLEWORD_KEY /* ensures WHOLEWORD_KEY is undefined */ -#endif -#endif /* MERRITT_KEY */ - /* Define some error status returns for RSA keygen... */ #define KEYFAILED -15 /* key failed final test */ @@ -59,16 +44,18 @@ static void derive_rsakeys(unitptr n,uni static void derive_rsakeys(unitptr n, unitptr e, unitptr d, unitptr p, unitptr q, unitptr u, short ebits) -/* Given primes p and q, derive RSA key components n, e, d, and u. - The global_precision must have already been set large enough for n. - Note that p must be < q. - Primes p and q must have been previously generated elsewhere. - The bit precision of e will be >= ebits. The search for a usable - exponent e will begin with an ebits-sized number. The recommended - value for ebits is 5, for efficiency's sake. This could yield - an e as small as 17. -*/ -{ unit F[MAX_UNIT_PRECISION]; +/* + * Given primes p and q, derive RSA key components n, e, d, and u. + * The global_precision must have already been set large enough for n. + * Note that p must be < q. + * Primes p and q must have been previously generated elsewhere. + * The bit precision of e will be >= ebits. The search for a usable + * exponent e will begin with an ebits-sized number. The recommended + * value for ebits is 5, for efficiency's sake. This could yield + * an e as small as 17. + */ +{ + unit F[MAX_UNIT_PRECISION]; unitptr ptemp, qtemp, phi, G; /* scratchpads */ /* For strong prime generation only, latitude is the amount @@ -102,20 +89,21 @@ static void derive_rsakeys(unitptr n, un mp_udiv(ptemp,qtemp,phi,G); /* F(n) = phi(n)/G(n) */ mp_move(F,qtemp); - /* We now have phi and F. Next, compute e... - Strictly speaking, we might get slightly faster results by - testing all small prime e's greater than 2 until we hit a - good e. But we can do just about as well by testing all - odd e's greater than 2. - We could begin searching for a candidate e anywhere, perhaps - using a random 16-bit starting point value for e, or even - larger values. But the most efficient value for e would be 3, - if it satisfied the gcd test with phi. - Parameter ebits specifies the number of significant bits e - should have to begin search for a workable e. - Make e at least 2 bits long, and no longer than one bit - shorter than the length of phi. - */ + /* + * We now have phi and F. Next, compute e... + * Strictly speaking, we might get slightly faster results by + * testing all small prime e's greater than 2 until we hit a + * good e. But we can do just about as well by testing all + * odd e's greater than 2. + * We could begin searching for a candidate e anywhere, perhaps + * using a random 16-bit starting point value for e, or even + * larger values. But the most efficient value for e would be 3, + * if it satisfied the gcd test with phi. + * Parameter ebits specifies the number of significant bits e + * should have to begin search for a workable e. + * Make e at least 2 bits long, and no longer than one bit + * shorter than the length of phi. + */ ebits = min(ebits,countbits(phi)-1); if (ebits==0) ebits=5; /* default is 5 bits long */ ebits = max(ebits,2); @@ -123,8 +111,8 @@ static void derive_rsakeys(unitptr n, un mp_setbit(e,ebits-1); lsunit(e) |= 1; /* set e candidate's lsb - make it odd */ mp_dec(e); mp_dec(e); /* precompensate for preincrements of e */ - do - { mp_inc(e); mp_inc(e); /* try odd e's until we get it. */ + do { + mp_inc(e); mp_inc(e); /* try odd e's until we get it. */ mp_gcd(ptemp,e,phi); /* look for e such that gcd(e,phi(n)) = 1 */ } while (testne(ptemp,1)); @@ -142,26 +130,29 @@ static void derive_rsakeys(unitptr n, un int rsa_keygen(unitptr n, unitptr e, unitptr d, unitptr p, unitptr q, unitptr u, short keybits, short ebits) -/* Generate RSA key components p, q, n, e, d, and u. - This routine sets the global_precision appropriate for n, - where keybits is desired precision of modulus n. - The precision of exponent e will be >= ebits. - It will generate a p that is < q. - Returns 0 for succcessful keygen, negative status otherwise. -*/ -{ short pbits,qbits,separation; +/* + * Generate RSA key components p, q, n, e, d, and u. + * This routine sets the global_precision appropriate for n, + * where keybits is desired precision of modulus n. + * The precision of exponent e will be >= ebits. + * It will generate a p that is < q. + * Returns 0 for succcessful keygen, negative status otherwise. + */ +{ + short pbits, qbits; boolean too_close_together; /* TRUE iff p and q are too close */ int status; int slop; - /* Don't let keybits get any smaller than 2 units, because - some parts of the math package require at least 2 units - for global_precision. - Nor any smaller than the 32 bits of preblocking overhead. - Nor any bigger than MAX_BIT_PRECISION - SLOP_BITS. - Also, if generating "strong" primes, don't let keybits get - any smaller than 64 bits, because of the search latitude. - */ + /* + * Don't let keybits get any smaller than 2 units, because + * some parts of the math package require at least 2 units + * for global_precision. + * Nor any smaller than the 32 bits of preblocking overhead. + * Nor any bigger than MAX_BIT_PRECISION - SLOP_BITS. + * Also, if generating "strong" primes, don't let keybits get + * any smaller than 64 bits, because of the search latitude. + */ slop = max(SLOP_BITS,1); /* allow at least 1 slop bit for sign bit */ keybits = min(keybits,(MAX_BIT_PRECISION-slop)); keybits = max(keybits,UNITSIZE*2); @@ -169,18 +160,6 @@ int rsa_keygen(unitptr n, unitptr e, uni #ifdef STRONGPRIMES keybits = max(keybits,64); /* for strong prime search latitude */ #endif /* STRONGPRIMES */ -#ifdef WHOLEWORD_KEY /* some modmults run faster this way */ - /* Some modmult algorithms run faster if both primes and - the modulus are an exact multiple of UNITSIZE bits long, - in other words, they completely fill the most significant - unit. So we will "round up" keybits to the next multiple - of UNITSIZE*2. - */ -#define roundup(x,m) (((x)+(m)-1)/(m))*(m) - keybits = roundup(keybits,UNITSIZE*2); - if (keybits==MAX_BIT_PRECISION) /* allow head room for sign bit */ - keybits -= UNITSIZE*2; -#endif /* WHOLEWORD_KEY */ set_precision(bits2units(keybits + slop)); @@ -190,100 +169,67 @@ int rsa_keygen(unitptr n, unitptr e, uni Since we now know how many random bits we will need, this is the place to prefill the pool of random bits. */ - randflush(); /* ensure recycled random pool is empty */ - randaccum(keybits+2*UNITSIZE); /* get this many raw random bits ready */ + trueRandAccum(keybits+2*UNITSIZE); - /* separation is the minimum number bits of difference in the - sizes of p and q. - */ -#ifdef MERRITT_KEY /* using Merritt's modmult algorithm */ - separation = 2; -#else /* not MERRITT_KEY */ - separation = 0; -#endif /* not MERRITT_KEY */ +#if 0 + /* + * If you want primes of different lengths ("separation" bits apart), + * do the following: + */ pbits = (keybits-separation)/2; qbits = keybits - pbits; +#else + pbits = keybits/2; + qbits = keybits - pbits; +#endif -#ifdef MERRITT_KEY - /* During decrypt, the primes p and q's bit length should - not be an exact multiple of UNITSIZE, because Merritt's - modmult algorithm performs slowest in that case, wasting - an extra unit of precision for overflow. - Other modmult algorithms perform differently. - Some other modmults actually performs fastest when the - modulus and primes p and q exactly fill the MS unit. - */ - { short qtrim; - qtrim = (qbits % UNITSIZE)+1; /* how many bits to trim from q */ - if (qtrim <= (separation/2)) - pbits += qtrim; /* allows qbits to be a bit shorter */ - } - if ((pbits % UNITSIZE)==0) /* inefficient to exactly fill a word */ - pbits -= 1; /* one bit shorter speeds up modmult a lot. */ -#endif /* MERRITT_KEY */ + trueRandConsume(pbits); /* "use up" this many bits */ - randload(pbits); /* get fresh load of raw random bits for p */ #ifdef STRONGPRIMES /* make a good strong prime for the key */ status = goodprime(p,pbits,pbits-latitude(pbits)); - if (status < 0) - return(status); /* failed to find a suitable prime */ #else /* just any random prime will suffice for the key */ status = randomprime(p,pbits); - if (status < 0) - return(status); /* failed to find a random prime */ #endif /* else not STRONGPRIMES */ + if (status < 0) + return(status); /* failed to find a suitable prime */ /* We now have prime p. Now generate q such that q>p... */ qbits = keybits - countbits(p); -#ifdef MERRITT_KEY - if ((qbits % UNITSIZE)==0) /* inefficient to exactly fill a word */ - qbits -= 1; /* one bit shorter speeds up modmult a lot. */ -#endif /* MERRITT_KEY */ - - randload(qbits); /* get fresh load of raw random bits for q */ + trueRandConsume(qbits); /* "use up" this many bits */ /* This load of random bits will be stirred and recycled until a good q is generated. */ - do /* Generate a q until we get one that isn't too close to p. */ - { + do { /* Generate a q until we get one that isn't too close to p. */ #ifdef STRONGPRIMES /* make a good strong prime for the key */ status = goodprime(q,qbits,qbits-latitude(qbits)); - if (status < 0) - return(status); /* failed to find a suitable prime */ #else /* just any random prime will suffice for the key */ status = randomprime(q,qbits); - if (status < 0) - return(status); /* failed to find a random prime */ #endif /* else not STRONGPRIMES */ + if (status < 0) + return(status); /* failed to find a suitable prime */ /* Note that at this point we can't be sure that q>p. */ - /* See if p and q are far enough apart. Is q-p big enough? */ + if (mp_compare(p,q) >= 0) { /* ensure that p= 0) /* ensure that p