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

1.1       root        1: /* PRIME.C - primality-testing routines
                      2:  */
                      3: 
                      4: /* Copyright (C) 1991-2 RSA Laboratories, a division of RSA Data
                      5:    Security, Inc. All rights reserved.
                      6:  */
                      7: 
                      8: #include "global.h"
                      9: #include "rsaref.h"
                     10: #include "nn.h"
                     11: #include "prime.h"
                     12: 
                     13: static unsigned int SMALL_PRIMES[] = { 3, 5, 7, 11 };
                     14: #define SMALL_PRIME_COUNT 4
                     15: 
                     16: static int RSAPrime PROTO_LIST
                     17:   ((NN_DIGIT *, unsigned int, NN_DIGIT *, unsigned int));
                     18: static int ProbablePrime PROTO_LIST ((NN_DIGIT *, unsigned int));
                     19: static int SmallFactor PROTO_LIST ((NN_DIGIT *, unsigned int));
                     20: static int FermatTest PROTO_LIST ((NN_DIGIT *, unsigned int));
                     21: static int RelativelyPrime PROTO_LIST
                     22:   ((NN_DIGIT *, unsigned int, NN_DIGIT *, unsigned int));
                     23: 
                     24: /* Find a probable prime a between 3*2^(b-2) and 2^b-1, starting at
                     25:    3*2^(b-2) + (c mod 2^(b-2)), such that gcd (a-1, d) = 1.
                     26: 
                     27:    Lengths: a[cDigits], c[cDigits], d[dDigits].
                     28:    Assumes b > 2, b < cDigits * NN_DIGIT_BITS, d is odd,
                     29:            cDigits < MAX_NN_DIGITS, dDigits < MAX_NN_DIGITS, and a
                     30:            probable prime can be found.
                     31:  */
                     32: void FindRSAPrime (a, b, c, cDigits, d, dDigits)
                     33: NN_DIGIT *a, *c, *d;
                     34: unsigned int b, cDigits, dDigits;
                     35: {
                     36:   NN_DIGIT t[MAX_NN_DIGITS], u[MAX_NN_DIGITS], v[MAX_NN_DIGITS],
                     37:     w[MAX_NN_DIGITS];
                     38:   
                     39:   /* Compute t = 2^(b-2), u = 3*2^(b-2).
                     40:    */
                     41:   NN_Assign2Exp (t, b-2, cDigits);
                     42:   NN_Assign2Exp (u, b-1, cDigits);
                     43:   NN_Add (u, u, t, cDigits);
                     44:   
                     45:   /* Compute v = 3*2^(b-2) + (c mod 2^(b-2)); add one if even.
                     46:    */
                     47:   NN_Mod (v, c, cDigits, t, cDigits);
                     48:   NN_Add (v, v, u, cDigits);
                     49:   if (NN_EVEN (v, cDigits)) {
                     50:     NN_ASSIGN_DIGIT (w, 1, cDigits);
                     51:     NN_Add (v, v, w, cDigits);
                     52:   }
                     53:   
                     54:   /* Compute w = 2, u = 2^b - 2.
                     55:    */
                     56:   NN_ASSIGN_DIGIT (w, 2, cDigits);
                     57:   NN_Sub (u, u, w, cDigits);
                     58:   NN_Add (u, u, t, cDigits);
                     59: 
                     60:   /* Search to 2^b-1 from starting point, then from 3*2^(b-2)+1.
                     61:    */
                     62:   while (! RSAPrime (v, cDigits, d, dDigits)) {
                     63:     if (NN_Cmp (v, u, cDigits) > 0)
                     64:       NN_Sub (v, v, t, cDigits);
                     65:     NN_Add (v, v, w, cDigits);
                     66:   }
                     67:   
                     68:   NN_Assign (a, v, cDigits);
                     69:   
                     70:   /* Zeroize sensitive information.
                     71:    */
                     72:   R_memset ((POINTER)v, 0, sizeof (v));
                     73: }
                     74: 
                     75: /* Returns nonzero iff a is a probable prime and GCD (a-1, b) = 1.
                     76: 
                     77:    Lengths: a[aDigits], b[bDigits].
                     78:    Assumes aDigits < MAX_NN_DIGITS, bDigits < MAX_NN_DIGITS.
                     79:  */
                     80: static int RSAPrime (a, aDigits, b, bDigits)
                     81: NN_DIGIT *a, *b;
                     82: unsigned int aDigits, bDigits;
                     83: {
                     84:   int status;
                     85:   NN_DIGIT aMinus1[MAX_NN_DIGITS], t[MAX_NN_DIGITS];
                     86:   
                     87:   NN_ASSIGN_DIGIT (t, 1, aDigits);
                     88:   NN_Sub (aMinus1, a, t, aDigits);
                     89:   
                     90:   status = ProbablePrime (a, aDigits) &&
                     91:     RelativelyPrime (aMinus1, aDigits, b, bDigits);
                     92: 
                     93:   /* Zeroize sensitive information.
                     94:    */
                     95:   R_memset ((POINTER)aMinus1, 0, sizeof (aMinus1));
                     96:   
                     97:   return (status);
                     98: }
                     99: 
                    100: /* Returns nonzero iff a is a probable prime.
                    101: 
                    102:    Lengths: a[aDigits].
                    103:    Assumes aDigits < MAX_NN_DIGITS.
                    104:  */
                    105: static int ProbablePrime (a, aDigits)
                    106: NN_DIGIT *a;
                    107: unsigned int aDigits;
                    108: {
                    109:   return (! SmallFactor (a, aDigits) && FermatTest (a, aDigits));
                    110: }
                    111: 
                    112: /* Returns nonzero iff a has a prime factor in SMALL_PRIMES.
                    113: 
                    114:    Lengths: a[aDigits].
                    115:    Assumes aDigits < MAX_NN_DIGITS.
                    116:  */
                    117: static int SmallFactor (a, aDigits)
                    118: NN_DIGIT *a;
                    119: unsigned int aDigits;
                    120: {
                    121:   int status;
                    122:   NN_DIGIT t[1];
                    123:   unsigned int i;
                    124:   
                    125:   status = 0;
                    126:   
                    127:   for (i = 0; i < SMALL_PRIME_COUNT; i++) {
                    128:     NN_ASSIGN_DIGIT (t, SMALL_PRIMES[i], 1);
                    129:     NN_Mod (t, a, aDigits, t, 1);
                    130:     if (NN_Zero (t, 1)) {
                    131:       status = 1;
                    132:       break;
                    133:     }
                    134:   }
                    135:   
                    136:   /* Zeroize sensitive information.
                    137:    */
                    138:   i = 0;
                    139:   R_memset ((POINTER)t, 0, sizeof (t));
                    140: 
                    141:   return (status);
                    142: }
                    143: 
                    144: /* Returns nonzero iff a passes Fermat's test for witness 2.
                    145:    (All primes pass the test, and nearly all composites fail.)
                    146:      
                    147:    Lengths: a[aDigits].
                    148:    Assumes aDigits < MAX_NN_DIGITS.
                    149:  */
                    150: static int FermatTest (a, aDigits)
                    151: NN_DIGIT *a;
                    152: unsigned int aDigits;
                    153: {
                    154:   int status;
                    155:   NN_DIGIT t[MAX_NN_DIGITS], u[MAX_NN_DIGITS];
                    156:   
                    157:   NN_ASSIGN_DIGIT (t, 2, aDigits);
                    158:   NN_ModExp (u, t, a, aDigits, a, aDigits);
                    159:   
                    160:   status = NN_EQUAL (t, u, aDigits);
                    161:   
                    162:   /* Zeroize sensitive information.
                    163:    */
                    164:   R_memset ((POINTER)u, 0, sizeof (u));
                    165:   
                    166:   return (status);
                    167: }
                    168: 
                    169: /* Returns nonzero iff a and b are relatively prime.
                    170: 
                    171:    Lengths: a[aDigits], b[bDigits].
                    172:    Assumes aDigits >= bDigits, aDigits < MAX_NN_DIGITS.
                    173:  */
                    174: static int RelativelyPrime (a, aDigits, b, bDigits)
                    175: NN_DIGIT *a, *b;
                    176: unsigned int aDigits, bDigits;
                    177: {
                    178:   int status;
                    179:   NN_DIGIT t[MAX_NN_DIGITS], u[MAX_NN_DIGITS];
                    180:   
                    181:   NN_AssignZero (t, aDigits);
                    182:   NN_Assign (t, b, bDigits);
                    183:   NN_Gcd (t, a, t, aDigits);
                    184:   NN_ASSIGN_DIGIT (u, 1, aDigits);
                    185: 
                    186:   status = NN_EQUAL (t, u, aDigits);
                    187:   
                    188:   /* Zeroize sensitive information.
                    189:    */
                    190:   R_memset ((POINTER)t, 0, sizeof (t));
                    191:   
                    192:   return (status);
                    193: }

unix.superglobalmegacorp.com

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