Annotation of pgp/src/mpilib.h, revision 1.1.1.1

1.1       root        1: /*     C include file for MPI multiprecision integer math routines
                      2: 
                      3:        Boulder Software Engineering
                      4:        3021 Eleventh Street
                      5:        Boulder, CO 80304
                      6:        (303) 541-0140
                      7: 
                      8:        (c) Copyright 1986-92 by Philip Zimmermann.  All rights reserved.
                      9:        The author assumes no liability for damages resulting from the use 
                     10:        of this software, even if the damage results from defects in this 
                     11:        software.  No warranty is expressed or implied.  
                     12: 
                     13:        These routines implement all of the multiprecision arithmetic necessary
                     14:        for Rivest-Shamir-Adleman (RSA) public key cryptography, as well as 
                     15:        other number-theoretic algorithms such as ElGamal, Diffie-Hellman, 
                     16:        or Rabin.
                     17: 
                     18:        Although originally developed in Microsoft C for the IBM PC, this code 
                     19:        contains few machine dependancies.  It assumes 2's complement 
                     20:        arithmetic.  It can be adapted to 8-bit, 16-bit, or 32-bit machines, 
                     21:        lowbyte-highbyte order or highbyte-lowbyte order.  This version
                     22:        has been converted to ANSI C.
                     23: 
                     24:        Modified 8 Apr 92 - HAJK
                     25:        Implement new VAX/VMS primitive support.
                     26: */
                     27: 
                     28: #include "usuals.h"  /* typedefs for byte, word16, boolean, etc. */
                     29: 
                     30: 
                     31: /* #define PORTABLE    */ /* determines if we use C primitives */
                     32: /* #define UNIT8       */ /* use 8-bit units */
                     33: /* #define UNIT16      */ /* use 16-bit units */
                     34: /* #define UNIT32      */ /* use 32-bit units */
                     35: /* #define HIGHFIRST   */ /* determines if Motorola or Intel internal format */
                     36: 
                     37: #ifdef VMS                     /* VAX/VMS */
                     38: #ifndef PORTABLE
                     39: #define UNIT32          /* use 32-bit units */
                     40: #endif /* not PORTABLE */
                     41: #endif /* VMS */
                     42: 
                     43: #ifndef PEASANT /* if not Russian peasant modulo multiply algorithm */
                     44: #ifndef MERRITT /* if not Merritt's modmult */
                     45: #define UPTON  /* default: use Upton's modmult algorithm */
                     46: #endif
                     47: #endif
                     48: 
                     49: #ifndef UNIT32
                     50: #ifndef UNIT8
                     51: #define UNIT16                 /* default--use 16-bit units */
                     52: #endif
                     53: #endif
                     54: 
                     55: /***   CAUTION:  If your machine has an unusual word size that is not a
                     56:        power of 2 (8, 16, 32, or 64) bits wide, then the macros here that 
                     57:        use the symbol "LOG_UNITSIZE" must be changed.
                     58: ***/
                     59: 
                     60: #ifdef UNIT8
                     61: typedef unsigned char unit;
                     62: typedef signed char signedunit;
                     63: #define UNITSIZE 8 /* number of bits in a unit */
                     64: #define uppermostbit ((unit) 0x80)
                     65: #define BYTES_PER_UNIT 1 /* number of bytes in a unit */
                     66: #define units2bits(n) ((n) << 3) /* fast multiply by UNITSIZE */
                     67: #define units2bytes(n) (n)
                     68: #define bits2units(n) (((n)+7) >> 3)
                     69: #define bytes2units(n) (n)
                     70: #endif
                     71: 
                     72: #ifdef UNIT16
                     73: typedef word16 unit;
                     74: typedef short signedunit;
                     75: #define UNITSIZE 16 /* number of bits in a unit */
                     76: #define uppermostbit ((unit) 0x8000)
                     77: #define BYTES_PER_UNIT 2 /* number of bytes in a unit */
                     78: #define units2bits(n) ((n) << 4) /* fast multiply by UNITSIZE */
                     79: #define units2bytes(n) ((n) << 1)
                     80: #define bits2units(n) (((n)+15) >> 4)
                     81: #define bytes2units(n) (((n)+1) >> 1)
                     82: #endif
                     83: 
                     84: #ifdef UNIT32
                     85: typedef word32 unit;
                     86: typedef long signedunit;
                     87: #define UNITSIZE 32 /* number of bits in a unit */
                     88: #define uppermostbit ((unit) 0x80000000L)
                     89: #define BYTES_PER_UNIT 4 /* number of bytes in a unit */
                     90: #define units2bits(n) ((n) << 5) /* fast multiply by UNITSIZE */
                     91: #define units2bytes(n) ((n) << 2)
                     92: #define bits2units(n) (((n)+31) >> 5)
                     93: #define bytes2units(n) (((n)+3) >> 2)
                     94: #undef PORTABLE                        /* can't use our C versions if 32 bits. */
                     95: #endif
                     96: 
                     97: #define power_of_2(b) ((unit) 1 << (b)) /* computes power-of-2 bit masks */
                     98: #define bits2bytes(n) (((n)+7) >> 3)
                     99: /*     Some C compilers (like the ADSP2101) will not always collapse constant 
                    100:        expressions at compile time if the expressions contain shift operators. */
                    101: /* #define uppermostbit power_of_2(UNITSIZE-1) */
                    102: /* #define UNITSIZE units2bits(1) */ /* number of bits in a unit */
                    103: /* #define bytes2units(n) bits2units((n)<<3) */
                    104: /* #define BYTES_PER_UNIT (UNITSIZE >> 3) */
                    105: /* LOG_UNITSIZE is the log base 2 of UNITSIZE, ie: 4 for 16-bit units */
                    106: /* #define units2bits(n) ((n) << LOG_UNITSIZE) */ /* fast multiply by UNITSIZE */
                    107: /* #define units2bytes(n) ((n) << (LOG_UNITSIZE-3)) */
                    108: /* #define bits2units(n) (((n)+(UNITSIZE-1)) >> LOG_UNITSIZE) */
                    109: /* #define bytes2units(n) (((n)+(BYTES_PER_UNIT-1)) >> (LOG_UNITSIZE-3)) */
                    110: 
                    111: typedef unit *unitptr;
                    112: 
                    113: 
                    114: /*--------------------- Byte ordering stuff -------------------*/
                    115: #ifdef HIGHFIRST
                    116: 
                    117: /* these definitions assume MSB comes first */
                    118: #define pre_higherunit(r)      (--(r))
                    119: #define pre_lowerunit(r)       (++(r))
                    120: #define post_higherunit(r)     ((r)--)
                    121: #define post_lowerunit(r)      ((r)++)
                    122: #define bit_index(n)           (global_precision-bits2units((n)+1))
                    123: #define lsbptr(r,prec)         ((r)+(prec)-1)
                    124: #define make_lsbptr(r,prec)    (r) = lsbptr(r,prec)  
                    125: #define unmake_lsbptr(r,prec) (r) = ((r)-(prec)+1) 
                    126: #define msbptr(r,prec)         (r)
                    127: #define make_msbptr(r,prec)    /* (r) = msbptr(r,prec) */
                    128: 
                    129: #define rescale(r,currentp,newp) r -= ((newp) - (currentp))
                    130: #define normalize(r,prec) \
                    131:   { prec = significance(r); r += (global_precision-(prec)); }
                    132: 
                    133: #else  /* LOWFIRST byte order */
                    134: 
                    135: /* these definitions assume LSB comes first */
                    136: #define pre_higherunit(r)      (++(r))
                    137: #define pre_lowerunit(r)       (--(r))
                    138: #define post_higherunit(r)     ((r)++)
                    139: #define post_lowerunit(r)      ((r)--)
                    140: #define bit_index(n)           (bits2units((n)+1)-1)
                    141: #define lsbptr(r,prec)         (r)
                    142: #define make_lsbptr(r,prec)    /* (r) = lsbptr(r,prec) */  
                    143: #define unmake_lsbptr(r,prec) /* (r) = (r) */  
                    144: #define msbptr(r,prec)         ((r)+(prec)-1)
                    145: #define make_msbptr(r,prec)    (r) = msbptr(r,prec)
                    146: 
                    147: #define rescale(r,currentp,newp) /* nil statement */
                    148: #define normalize(r,prec) prec = significance(r) 
                    149: 
                    150: #endif /* LOWFIRST byte order */
                    151: /*------------------ End byte ordering stuff -------------------*/
                    152: 
                    153: /*     Note that the address calculations require that lsbptr, msbptr, 
                    154:        make_lsbptr, make_msbptr, mp_tstbit, mp_setbit, mp_clrbit, 
                    155:        and bitptr all have unitptr arguments, not byteptr arguments.  */
                    156: #define bitptr(r,n) &((r)[bit_index(n)])
                    157: #define bitmsk(n) power_of_2((n) & (UNITSIZE-1))
                    158:        /* bitmsk() assumes UNITSIZE is a power of 2 */
                    159: #define mp_tstbit(r,n) (*bitptr(r,n) &   bitmsk(n))
                    160: #define mp_setbit(r,n) (*bitptr(r,n) |=  bitmsk(n))
                    161: #define mp_clrbit(r,n) (*bitptr(r,n) &= ~bitmsk(n))
                    162: #define msunit(r) (*msbptr(r,global_precision))
                    163: #define lsunit(r) (*lsbptr(r,global_precision))
                    164: /* #define mp_tstminus(r) ((msunit(r) & uppermostbit)!=0) */
                    165: #define mp_tstminus(r) ((signedunit) msunit(r) < 0)
                    166: 
                    167: /*     MAX_BIT_PRECISION is upper limit that assembly primitives can handle.
                    168:        It must be less than 32704 bits, or 4088 bytes.  It should be an
                    169:        integer multiple of UNITSIZE*2.
                    170: */
                    171: #define MAX_BIT_PRECISION 1152
                    172: #define MAX_BYTE_PRECISION (MAX_BIT_PRECISION/8)
                    173: #define MAX_UNIT_PRECISION (MAX_BIT_PRECISION/UNITSIZE)
                    174: 
                    175: 
                    176: /*************** multiprecision library primitives ****************/
                    177: #ifdef PORTABLE        /* using slow portable C primitives */
                    178: 
                    179: #define set_precision(prec) (global_precision = (prec))
                    180: 
                    181: #else  /* not PORTABLE - not using portable C primitives */
                    182: /*
                    183:        The following primitives should be coded in assembly.
                    184:        Functions P_ADDC, P_SUBB, and P_ROTL return a carry flag as their
                    185:        functional return, and the result of the operation is placed in r1.
                    186:        These assembly primitives are externally defined, unless PORTABLE 
                    187:        is defined.
                    188: */
                    189: 
                    190: #ifdef VMS
                    191: /*
                    192:        Define Assembler Prims With Lowercase Names To Prevent GCC hacking
                    193:        them
                    194: */
                    195: #define P_SETP p_setp
                    196: #define P_ADDC p_addc
                    197: #define P_SUBB p_subb
                    198: #define P_ROTL p_rotl
                    199: 
                    200: #endif /* VMS */
                    201: 
                    202: void P_SETP(short nbits);
                    203:        /* sets working precision to specified number of bits. */
                    204: 
                    205: boolean P_ADDC(unitptr r1, unitptr r2, boolean carry);
                    206:        /* multiprecision add with carry r2 to r1, result in r1 */
                    207: 
                    208: boolean P_SUBB(unitptr r1, unitptr r2, boolean borrow);
                    209:        /* multiprecision subtract with borrow, r2 from r1, result in r1 */
                    210: 
                    211: boolean P_ROTL(unitptr r1, boolean carry);
                    212:        /* multiprecision rotate left 1 bit with carry, result in r1. */
                    213: 
                    214: /* Define C primitive names as the equivalent calls to assembly primitives. */
                    215: #define set_precision(prec)    P_SETP(units2bits(global_precision=(prec)))
                    216: #define mp_addc                P_ADDC
                    217: #define mp_subb                P_SUBB
                    218: #define mp_rotate_left  P_ROTL
                    219: 
                    220: #ifdef VMS
                    221: 
                    222: short p_cmp(register unitptr r1,register unitptr r2);
                    223:        /* Compares registers *r1, *r2, and returns -1, 0, or 1 */
                    224: 
                    225: #define mp_compare p_cmp
                    226: 
                    227: #endif /* VMS */
                    228: 
                    229: #endif /* not PORTABLE */
                    230: /************** end of primitives that should be in assembly *************/
                    231: 
                    232: #ifdef PEASANT
                    233: 
                    234: /* Define C names for Russian peasant modmult primitives. */
                    235: #define stage_modulus stage_peasant_modulus
                    236: #define mp_modmult peasant_modmult
                    237: #define modmult_burn peasant_burn
                    238: 
                    239: #endif /* PEASANT */
                    240: 
                    241: #ifdef MERRITT
                    242: /* Define C names for Merritt's modmult primitives. */
                    243: #define stage_modulus stage_merritt_modulus
                    244: #define mp_modmult merritt_modmult
                    245: #define modmult_burn merritt_burn
                    246: 
                    247: #endif /* MERRITT */
                    248: 
                    249: #ifdef UPTON
                    250: /* Define C names for Upton's modmult primitives. */
                    251: #define stage_modulus stage_upton_modulus
                    252: #define mp_modmult upton_modmult
                    253: #define modmult_burn upton_burn
                    254: 
                    255: #endif /* UPTON */
                    256: 
                    257: 
                    258: #define mp_shift_left(r1) mp_rotate_left(r1,(boolean)0)
                    259:        /* multiprecision shift left 1 bit */
                    260: 
                    261: #define mp_add(r1,r2) mp_addc(r1,r2,(boolean)0)
                    262:        /* multiprecision add with no carry */
                    263: 
                    264: #define mp_sub(r1,r2) mp_subb(r1,r2,(boolean)0)
                    265:        /* multiprecision subtract with no borrow */
                    266: 
                    267: #define mp_abs(r) (mp_tstminus(r) ? (mp_neg(r),TRUE) : FALSE)
                    268: 
                    269: #define msub(r,m) if (mp_compare(r,m) >= 0) mp_sub(r,m)
                    270:        /* Prevents r from getting bigger than modulus m */
                    271: 
                    272: #define testeq(r,i)    \
                    273:        ( (lsunit(r)==(i)) && (significance(r)<=1) )
                    274: 
                    275: #define testne(r,i)    \
                    276:        ( (lsunit(r)!=(i)) || (significance(r)>1) )
                    277: 
                    278: #define testge(r,i)    \
                    279:        ( (lsunit(r)>=(i)) || (significance(r)>1) )
                    280: 
                    281: #define testle(r,i)    \
                    282:        ( (lsunit(r)<=(i)) && (significance(r)<=1) )
                    283: 
                    284: #define mp_square(r1,r2) mp_mult(r1,r2,r2)
                    285:        /* Square r2, returning product in r1 */
                    286: 
                    287: #define mp_modsquare(r1,r2) mp_modmult(r1,r2,r2)
                    288:        /* Square r2, returning modulo'ed product in r1 */
                    289: 
                    290: #define countbytes(r) ((countbits(r)+7)>>3)
                    291: 
                    292: /*     SLOP_BITS is how many "carry bits" to allow for intermediate 
                    293:        calculation results to exceed the size of the modulus.
                    294:        It is used by modexp to give some overflow elbow room for
                    295:        modmult to use to perform modulo operations with the modulus. 
                    296:        The number of slop bits required is determined by the modmult 
                    297:        algorithm.  The Russian peasant modmult algorithm only requires 
                    298:        1 slop bit, for example.  Note that if we use an external assembly
                    299:        modmult routine, SLOP_BITS may be meaningless or may be defined in a
                    300:        non-constant manner.
                    301: */
                    302: #ifdef MERRITT /* use Merritt's modmult algorithm */
                    303: #define SLOP_BITS (UNITSIZE+1)
                    304: #define MERRITT_KEY    /* cause keygen to generate unnormalized keys */
                    305: #endif /* MERRITT */
                    306: #ifdef PEASANT /* use Russian peasant modmult algorithm */
                    307: #define SLOP_BITS 1
                    308: #endif /* PEASANT */
                    309: #ifdef UPTON   /* use Upton's modmult algorithm */
                    310: /* Not clear what SLOP_BITS needs to be */
                    311: #define SLOP_BITS UNITSIZE
                    312: #endif /* UPTON */
                    313: 
                    314: /* global_precision is the unit precision last set by set_precision */
                    315: extern short global_precision;
                    316: 
                    317: 
                    318: 
                    319: /*     The "bit sniffer" macros all begin sniffing at the MSB.
                    320:        They are used internally by all the various multiply, divide, 
                    321:        modulo, exponentiation, and square root functions.
                    322: */
                    323: #define sniff_bit(bptr,bitmask)        (*(bptr) & bitmask)
                    324: 
                    325: #define init_bitsniffer(bptr,bitmask,prec,bits) \
                    326: { normalize(bptr,prec); \
                    327:   if (!prec) \
                    328:     return(0); \
                    329:   bits = units2bits(prec); \
                    330:   make_msbptr(bptr,prec); bitmask = uppermostbit; \
                    331:   while (!sniff_bit(bptr,bitmask)) \
                    332:   { bitmask >>= 1; bits--; \
                    333:   } \
                    334: }
                    335: 
                    336: #define bump_bitsniffer(bptr,bitmask) \
                    337: { if (!(bitmask >>= 1)) \
                    338:   { bitmask = uppermostbit; \
                    339:        post_lowerunit(bptr); \
                    340:   } \
                    341: }
                    342: 
                    343: /* bump_2bitsniffers is used internally by mp_udiv. */
                    344: #define bump_2bitsniffers(bptr,bptr2,bitmask) \
                    345: { if (!(bitmask >>= 1)) \
                    346:   { bitmask = uppermostbit; \
                    347:     post_lowerunit(bptr); \
                    348:     post_lowerunit(bptr2); \
                    349:   } \
                    350: }
                    351: 
                    352: /* stuff_bit is used internally by mp_udiv and mp_sqrt. */
                    353: #define stuff_bit(bptr,bitmask)        *(bptr) |= bitmask
                    354: 
                    355: 
                    356: 
                    357: #ifdef PORTABLE        /* these slow C primitives should be recoded in assembly */
                    358: 
                    359: boolean mp_addc
                    360:        (register unitptr r1,register unitptr r2,register boolean carry);
                    361:        /* multiprecision add with carry r2 to r1, result in r1 */
                    362: 
                    363: boolean mp_subb
                    364:        (register unitptr r1,register unitptr r2,register boolean borrow);
                    365:        /* multiprecision subtract with borrow, r2 from r1, result in r1 */
                    366: 
                    367: boolean mp_rotate_left(register unitptr r1,register boolean carry);
                    368:        /* multiprecision rotate left 1 bit with carry, result in r1. */
                    369: 
                    370: #endif /* PORTABLE */
                    371: 
                    372: void mp_shift_right_bits(register unitptr r1,register short bits);
                    373:        /* multiprecision shift right bits, result in r1. */
                    374: 
                    375: short mp_compare(register unitptr r1,register unitptr r2);
                    376:        /* Compares registers *r1, *r2, and returns -1, 0, or 1 */      
                    377: 
                    378: boolean mp_inc(register unitptr r);
                    379:        /* Increment multiprecision integer r. */
                    380: 
                    381: boolean mp_dec(register unitptr r);
                    382:        /* Decrement multiprecision integer r. */
                    383: 
                    384: void mp_neg(register unitptr r);
                    385:        /* Compute 2's complement, the arithmetic negative, of r */
                    386: 
                    387: #ifdef VAXC
                    388: /*
                    389:  * A VAX is a CISC machine. Unfortunately C is at to low a level to use
                    390:  * many of the instruction set enhancements so we define some macros
                    391:  * here that implement fast moves and fast zero fills with single
                    392:  * instructions.
                    393:  */
                    394: 
                    395: #pragma builtins
                    396: #define mp_move( dst, src)       _MOVC3( global_precision*4, (char *) src, (char *) dst)
                    397: #define unitfill0( r, unitcount) _MOVC5( 0, (char *) 0, 0, unitcount*4, (char *) r)
                    398: #define mp_burn(r) _MOVC5(0, (char *) 0, 0, global_precision*4, (char *) r)
                    399: #define mp_init0(r) mp_burn(r) /* Just for documentation purposes */
                    400: 
                    401: #else /* VAXC */
                    402: 
                    403: void mp_move(register unitptr dst,register unitptr src);
                    404: 
                    405: void unitfill0(unitptr r,word16 unitcount);
                    406: #define mp_burn(r) mp_init(r,0) /* for burning the evidence */
                    407: #define mp_init0(r) mp_init(r,0)
                    408: 
                    409: #endif /* VAXC */
                    410: 
                    411: void mp_init(register unitptr r, word16 value);
                    412:        /* Init multiprecision register r with short value. */
                    413: 
                    414: short significance(register unitptr r);
                    415:        /* Returns number of significant units in r */
                    416: 
                    417: int mp_udiv(register unitptr remainder,register unitptr quotient,
                    418:        register unitptr dividend,register unitptr divisor);
                    419:        /* Unsigned divide, treats both operands as positive. */
                    420: 
                    421: int mp_recip(register unitptr quotient,register unitptr divisor);
                    422:        /* Compute reciprocal as 1/divisor.  Used by faster modmult. */
                    423: 
                    424: int mp_div(register unitptr remainder,register unitptr quotient,
                    425:        register unitptr dividend,register unitptr divisor);
                    426:        /* Signed divide, either or both operands may be negative. */
                    427: 
                    428: word16 mp_shortdiv(register unitptr quotient,
                    429:        register unitptr dividend,register word16 divisor);
                    430:        /* Returns short remainder of unsigned divide. */
                    431: 
                    432: int mp_mod(register unitptr remainder,
                    433:        register unitptr dividend,register unitptr divisor);
                    434:        /* Unsigned divide, treats both operands as positive. */
                    435: 
                    436: word16 mp_shortmod(register unitptr dividend,register word16 divisor);
                    437:        /* Just returns short remainder of unsigned divide. */
                    438: 
                    439: int mp_mult(register unitptr prod,
                    440:        register unitptr multiplicand,register unitptr multiplier);
                    441:        /* Computes multiprecision prod = multiplicand * multiplier */
                    442: 
                    443: int stage_modulus(unitptr n);
                    444:        /* Must pass modulus to stage_modulus before calling modmult. */
                    445: 
                    446: int mp_modmult(register unitptr prod,
                    447:        unitptr multiplicand,register unitptr multiplier);
                    448:        /* Performs combined multiply/modulo operation, with global modulus */
                    449: 
                    450: int countbits(unitptr r);
                    451:        /* Returns number of significant bits in r. */
                    452: 
                    453: int mp_modexp(register unitptr expout,register unitptr expin,
                    454:        register unitptr exponent,register unitptr modulus);
                    455:        /* Combined exponentiation/modulo algorithm. */
                    456: 
                    457: int rsa_decrypt(unitptr M, unitptr C,
                    458:        unitptr d, unitptr p, unitptr q, unitptr u);
                    459:        /* Uses Chinese Remainder Theorem shortcut for RSA decryption. */
                    460: 
                    461: /****************** end of MPI library ****************************/

unix.superglobalmegacorp.com

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