Annotation of pgp/rsaref/source/prime.c, revision 1.1.1.1

1.1       root        1: /* PRIME.C - primality-testing routines
                      2:  */
                      3: 
                      4: /* Copyright (C) RSA Laboratories, a division of RSA Data Security,
                      5:      Inc., created 1991. All rights reserved.
                      6:  */
                      7: 
                      8: #include "global.h"
                      9: #include "rsaref.h"
                     10: #include "r_random.h"
                     11: #include "nn.h"
                     12: #include "prime.h"
                     13: 
                     14: static unsigned int SMALL_PRIMES[] = { 3, 5, 7, 11 };
                     15: #define SMALL_PRIME_COUNT 4
                     16: 
                     17: static int ProbablePrime PROTO_LIST ((NN_DIGIT *, unsigned int));
                     18: static int SmallFactor PROTO_LIST ((NN_DIGIT *, unsigned int));
                     19: static int FermatTest PROTO_LIST ((NN_DIGIT *, unsigned int));
                     20: 
                     21: /* Generates a probable prime a between b and c such that a-1 is
                     22:    divisible by d.
                     23: 
                     24:    Lengths: a[digits], b[digits], c[digits], d[digits].
                     25:    Assumes b < c, digits < MAX_NN_DIGITS.
                     26:    
                     27:    Returns RE_NEED_RANDOM if randomStruct not seeded, RE_DATA if
                     28:    unsuccessful.
                     29:  */
                     30: int GeneratePrime (a, b, c, d, digits, randomStruct)
                     31: NN_DIGIT *a, *b, *c, *d;
                     32: unsigned int digits;
                     33: R_RANDOM_STRUCT *randomStruct;
                     34: {
                     35:   int status;
                     36:   unsigned char block[MAX_NN_DIGITS * NN_DIGIT_LEN];
                     37:   NN_DIGIT t[MAX_NN_DIGITS], u[MAX_NN_DIGITS];
                     38: 
                     39:   /* Generate random number between b and c.
                     40:    */
                     41:   if (status = R_GenerateBytes (block, digits * NN_DIGIT_LEN, randomStruct))
                     42:     return (status);
                     43:   NN_Decode (a, digits, block, digits * NN_DIGIT_LEN);
                     44:   NN_Sub (t, c, b, digits);
                     45:   NN_ASSIGN_DIGIT (u, 1, digits);
                     46:   NN_Add (t, t, u, digits);
                     47:   NN_Mod (a, a, digits, t, digits);
                     48:   NN_Add (a, a, b, digits);
                     49: 
                     50:   /* Adjust so that a-1 is divisible by d.
                     51:    */
                     52:   NN_Mod (t, a, digits, d, digits);
                     53:   NN_Sub (a, a, t, digits);
                     54:   NN_Add (a, a, u, digits);
                     55:   if (NN_Cmp (a, b, digits) < 0)
                     56:     NN_Add (a, a, d, digits);
                     57:   if (NN_Cmp (a, c, digits) > 0)
                     58:     NN_Sub (a, a, d, digits);
                     59: 
                     60:   /* Search to c in steps of d.
                     61:    */
                     62:   NN_Assign (t, c, digits);
                     63:   NN_Sub (t, t, d, digits);
                     64: 
                     65:   while (! ProbablePrime (a, digits)) {
                     66:     if (NN_Cmp (a, t, digits) > 0)
                     67:       return (RE_DATA);
                     68:     NN_Add (a, a, d, digits);
                     69:   }
                     70: 
                     71:   return (0);
                     72: }
                     73: 
                     74: /* Returns nonzero iff a is a probable prime.
                     75: 
                     76:    Lengths: a[aDigits].
                     77:    Assumes aDigits < MAX_NN_DIGITS.
                     78:  */
                     79: static int ProbablePrime (a, aDigits)
                     80: NN_DIGIT *a;
                     81: unsigned int aDigits;
                     82: {
                     83:   return (! SmallFactor (a, aDigits) && FermatTest (a, aDigits));
                     84: }
                     85: 
                     86: /* Returns nonzero iff a has a prime factor in SMALL_PRIMES.
                     87: 
                     88:    Lengths: a[aDigits].
                     89:    Assumes aDigits < MAX_NN_DIGITS.
                     90:  */
                     91: static int SmallFactor (a, aDigits)
                     92: NN_DIGIT *a;
                     93: unsigned int aDigits;
                     94: {
                     95:   int status;
                     96:   NN_DIGIT t[1];
                     97:   unsigned int i;
                     98:   
                     99:   status = 0;
                    100:   
                    101:   for (i = 0; i < SMALL_PRIME_COUNT; i++) {
                    102:     NN_ASSIGN_DIGIT (t, SMALL_PRIMES[i], 1);
                    103:     if ((aDigits == 1) && ! NN_Cmp (a, t, 1))
                    104:       break;
                    105:     NN_Mod (t, a, aDigits, t, 1);
                    106:     if (NN_Zero (t, 1)) {
                    107:       status = 1;
                    108:       break;
                    109:     }
                    110:   }
                    111:   
                    112:   /* Zeroize sensitive information.
                    113:    */
                    114:   i = 0;
                    115:   R_memset ((POINTER)t, 0, sizeof (t));
                    116: 
                    117:   return (status);
                    118: }
                    119: 
                    120: /* Returns nonzero iff a passes Fermat's test for witness 2.
                    121:    (All primes pass the test, and nearly all composites fail.)
                    122:      
                    123:    Lengths: a[aDigits].
                    124:    Assumes aDigits < MAX_NN_DIGITS.
                    125:  */
                    126: static int FermatTest (a, aDigits)
                    127: NN_DIGIT *a;
                    128: unsigned int aDigits;
                    129: {
                    130:   int status;
                    131:   NN_DIGIT t[MAX_NN_DIGITS], u[MAX_NN_DIGITS];
                    132:   
                    133:   NN_ASSIGN_DIGIT (t, 2, aDigits);
                    134:   NN_ModExp (u, t, a, aDigits, a, aDigits);
                    135:   
                    136:   status = NN_EQUAL (t, u, aDigits);
                    137:   
                    138:   /* Zeroize sensitive information.
                    139:    */
                    140:   R_memset ((POINTER)u, 0, sizeof (u));
                    141:   
                    142:   return (status);
                    143: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.