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

1.1.1.9 ! 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 dependencies.  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 - Implement new VAX/VMS primitive support.
        !            25:        Modified 29 Nov 92 - Thad Smith
        !            26: */
        !            27: 
        !            28: #include <string.h>
        !            29: #include "usuals.h"  /* typedefs for byte, word16, boolean, etc. */
        !            30: #include "platform.h" /* customization for different environments */
        !            31: 
        !            32: /* Platform customization:
        !            33:  * A version which runs on almost any computer can be implemented by
        !            34:  * defining PORTABLE and MPORTABLE, preferably as a command line
        !            35:  * parameter.  Faster versions can be generated by specifying specific
        !            36:  * parameters, such as size of unit and MULTUNIT, and by supplying some
        !            37:  * of the critical in assembly.  See the file platform.h for more 
        !            38:  * details on customization.
        !            39:  *
        !            40:  * The symbol HIGHFIRST, designating that integers and longs are stored
        !            41:  * with the most significant bit in the lowest address, should be defined
        !            42:  * on the command line for compiling all files, since it is used by files
        !            43:  * other than the mpilib routines.
        !            44:  */
        !            45:  
        !            46: #ifndef ALIGN
        !            47: #define ALIGN
        !            48: #endif
        !            49: 
        !            50: #ifndef PEASANT /* if not Russian peasant modulo multiply algorithm */
        !            51: #ifndef MERRITT /* if not Merritt's modmult */
        !            52: #ifndef UPTON   /* if not Upton's modmult */
        !            53: #ifndef SMITH
        !            54: #define SMITH   /* default: use Smith's modmult algorithm */
        !            55: #endif
        !            56: #endif
        !            57: #endif
        !            58: #endif
        !            59: 
        !            60: #ifdef SMITH
        !            61: #define UPTON_OR_SMITH  /* enable common code */
        !            62: #endif
        !            63: #ifdef UPTON
        !            64: #define UPTON_OR_SMITH  /* enable common code */
        !            65: #endif
        !            66: 
        !            67: #ifndef UNIT32
        !            68: #ifndef UNIT8
        !            69: #define UNIT16                 /* default--use 16-bit units */
        !            70: #endif
        !            71: #endif
        !            72: 
        !            73: /***   CAUTION:  If your machine has an unusual word size that is not a
        !            74:        power of 2 (8, 16, 32, or 64) bits wide, then the macros here that
        !            75:        use the symbol "LOG_UNITSIZE" must be changed.
        !            76: ***/
        !            77: 
        !            78: #ifdef UNIT8
        !            79: typedef unsigned char unit;
        !            80: typedef signed char signedunit;
        !            81: #define UNITSIZE 8 /* number of bits in a unit */
        !            82: #define LOG_UNITSIZE 3
        !            83: #define uppermostbit ((unit) 0x80)
        !            84: #define BYTES_PER_UNIT 1 /* number of bytes in a unit */
        !            85: #define units2bits(n) ((n) << 3) /* fast multiply by UNITSIZE */
        !            86: #define units2bytes(n) (n)
        !            87: #define bits2units(n) (((n)+7) >> 3)
        !            88: #define bytes2units(n) (n)
        !            89: #endif
        !            90: 
        !            91: #ifdef UNIT16
        !            92: typedef word16 unit;
        !            93: typedef short signedunit;
        !            94: #define UNITSIZE 16 /* number of bits in a unit */
        !            95: #define LOG_UNITSIZE 4
        !            96: #define uppermostbit ((unit) 0x8000)
        !            97: #define BYTES_PER_UNIT 2 /* number of bytes in a unit */
        !            98: #define units2bits(n) ((n) << 4) /* fast multiply by UNITSIZE */
        !            99: #define units2bytes(n) ((n) << 1)
        !           100: #define bits2units(n) (((n)+15) >> 4)
        !           101: #define bytes2units(n) (((n)+1) >> 1)
        !           102: #endif
        !           103: 
        !           104: #ifdef UNIT32
        !           105: typedef word32 unit;
        !           106: typedef long signedunit;
        !           107: #define UNITSIZE 32 /* number of bits in a unit */
        !           108: #define LOG_UNITSIZE 5
        !           109: #define uppermostbit ((unit) 0x80000000L)
        !           110: #define BYTES_PER_UNIT 4 /* number of bytes in a unit */
        !           111: #define units2bits(n) ((n) << 5) /* fast multiply by UNITSIZE */
        !           112: #define units2bytes(n) ((n) << 2)
        !           113: #define bits2units(n) (((n)+31) >> 5)
        !           114: #define bytes2units(n) (((n)+3) >> 2)
        !           115: #endif
        !           116: 
        !           117: #define power_of_2(b) ((unit) 1 << (b)) /* computes power-of-2 bit masks */
        !           118: #define bits2bytes(n) (((n)+7) >> 3)
        !           119: /*     Some C compilers (like the ADSP2101) will not always collapse constant 
        !           120:        expressions at compile time if the expressions contain shift
        !           121:        operators. */
        !           122: /* #define uppermostbit power_of_2(UNITSIZE-1) */
        !           123: /* #define UNITSIZE units2bits(1) */ /* number of bits in a unit */
        !           124: /* #define bytes2units(n) bits2units((n)<<3) */
        !           125: /* #define BYTES_PER_UNIT (UNITSIZE >> 3) */
        !           126: /* LOG_UNITSIZE is the log base 2 of UNITSIZE, ie: 4 for 16-bit units */
        !           127: /* #define units2bits(n) ((n) << LOG_UNITSIZE) */ /* fast multiply by
        !           128:                                                     UNITSIZE */
        !           129: /* #define units2bytes(n) ((n) << (LOG_UNITSIZE-3)) */
        !           130: /* #define bits2units(n) (((n)+(UNITSIZE-1)) >> LOG_UNITSIZE) */
        !           131: /* #define bytes2units(n) (((n)+(BYTES_PER_UNIT-1)) >> (LOG_UNITSIZE-3)) */
        !           132: 
        !           133: typedef unit *unitptr;
        !           134: 
        !           135: 
        !           136: /*--------------------- Byte ordering stuff -------------------*/
        !           137: #ifdef HIGHFIRST
        !           138: 
        !           139: /* these definitions assume MSB comes first */
        !           140: #define tohigher(n)            (-(n))  /* offset towards higher unit */
        !           141: #define pre_higherunit(r)      (--(r))
        !           142: #define pre_lowerunit(r)       (++(r))
        !           143: #define post_higherunit(r)     ((r)--)
        !           144: #define post_lowerunit(r)      ((r)++)
        !           145: #define bit_index(n)           (global_precision-bits2units((n)+1))
        !           146: #define lsbptr(r,prec)         ((r)+(prec)-1)
        !           147: #define make_lsbptr(r,prec)    (r) = lsbptr(r,prec)  
        !           148: #define unmake_lsbptr(r,prec) (r) = ((r)-(prec)+1) 
        !           149: #define msbptr(r,prec)         (r)
        !           150: #define make_msbptr(r,prec)    /* (r) = msbptr(r,prec) */
        !           151: 
        !           152: /* The macro rescale(r,current_precision,new_precision) rescales
        !           153:    a multiprecision integer by adjusting r and its precision to new values.
        !           154:    It can be used to reverse the effects of the normalize
        !           155:    routine given above.  See the comments in normalize concerning
        !           156:    Intel vs. Motorola LSB/MSB conventions.
        !           157:    WARNING:  You can only safely call rescale on registers that
        !           158:    you have previously normalized with the above normalize routine,
        !           159:    or are known to be big enough for the new precision.  You may
        !           160:    specify a new precision that is smaller than the current precision.
        !           161:    You must be careful not to specify a new_precision value that is
        !           162:    too big, or which adjusts the r pointer out of range.
        !           163: */
        !           164: #define rescale(r,currentp,newp) r -= ((newp) - (currentp))
        !           165: 
        !           166: /* The macro normalize(r,precision) "normalizes" a multiprecision integer
        !           167:    by adjusting r and precision to new values.  For Motorola-style processors
        !           168:    (MSB-first), r is a pointer to the MSB of the register, and must
        !           169:    be adjusted to point to the first nonzero unit.  For Intel/VAX-style
        !           170:    (LSB-first) processors, r is a  pointer to the LSB of the register,
        !           171:    and must be left unchanged.  The precision counter is always adjusted,
        !           172:    regardless of processor type.  In the case of precision = 0,
        !           173:    r becomes undefined.
        !           174: */
        !           175: #define normalize(r,prec) \
        !           176:   { prec = significance(r); r += (global_precision-(prec)); }
        !           177: 
        !           178: #else  /* LOWFIRST byte order */
        !           179: 
        !           180: /* these definitions assume LSB comes first */
        !           181: #define tohigher(n)            (n)     /* offset towards higher unit */
        !           182: #define pre_higherunit(r)      (++(r))
        !           183: #define pre_lowerunit(r)       (--(r))
        !           184: #define post_higherunit(r)     ((r)++)
        !           185: #define post_lowerunit(r)      ((r)--)
        !           186: #define bit_index(n)           (bits2units((n)+1)-1)
        !           187: #define lsbptr(r,prec)         (r)
        !           188: #define make_lsbptr(r,prec)    /* (r) = lsbptr(r,prec) */  
        !           189: #define unmake_lsbptr(r,prec) /* (r) = (r) */  
        !           190: #define msbptr(r,prec)         ((r)+(prec)-1)
        !           191: #define make_msbptr(r,prec)    (r) = msbptr(r,prec)
        !           192: 
        !           193: #define rescale(r,currentp,newp) /* nil statement */
        !           194: #define normalize(r,prec) prec = significance(r) 
        !           195: 
        !           196: #endif /* LOWFIRST byte order */
        !           197: /*------------------ End byte ordering stuff -------------------*/
        !           198: 
        !           199: /*     Note that the address calculations require that lsbptr, msbptr, 
        !           200:        make_lsbptr, make_msbptr, mp_tstbit, mp_setbit, mp_clrbit, 
        !           201:        and bitptr all have unitptr arguments, not byte pointer arguments.
        !           202: */
        !           203: #define bitptr(r,n) &((r)[bit_index(n)])
        !           204: #define bitmsk(n) power_of_2((n) & (UNITSIZE-1))
        !           205:        /* bitmsk() assumes UNITSIZE is a power of 2 */
        !           206: #define mp_tstbit(r,n) (*bitptr(r,n) &   bitmsk(n))
        !           207: #define mp_setbit(r,n) (*bitptr(r,n) |=  bitmsk(n))
        !           208: #define mp_clrbit(r,n) (*bitptr(r,n) &= ~bitmsk(n))
        !           209: #define msunit(r) (*msbptr(r,global_precision))
        !           210: #define lsunit(r) (*lsbptr(r,global_precision))
        !           211: /* #define mp_tstminus(r) ((msunit(r) & uppermostbit)!=0) */
        !           212: #define mp_tstminus(r) ((signedunit) msunit(r) < 0)
        !           213: 
        !           214: 
        !           215:        /* set working precision to specified number of bits. */
        !           216: #ifdef mp_setp
        !           217: void mp_setp(short nbits);
        !           218: #define set_precision(prec)    mp_setp(units2bits(global_precision=(prec)))
        !           219: #else
        !           220: #define set_precision(prec) (global_precision = (prec))
        !           221: #endif
        !           222: 
        !           223: /* We'll pull in the assembler code here if asked to. */
        !           224: #ifdef WIN32
        !           225: #ifdef USE_WIN32_ASSEMBLER
        !           226: #include "mpw32asm.h"
        !           227: #endif /* USE_WIN32_ASSEMBLER */
        !           228: #endif /* WIN32 */
        !           229: 
        !           230: #ifdef PEASANT
        !           231: 
        !           232: /* Define C names for Russian peasant modmult primitives. */
        !           233: #define stage_modulus  stage_peasant_modulus
        !           234: #define mp_modmult     peasant_modmult
        !           235: #define modmult_burn   peasant_burn
        !           236: #define SLOP_BITS      PEASANT_SLOP_BITS
        !           237: 
        !           238: #else  /* not PEASANT */
        !           239: #ifdef MERRITT
        !           240: /* Define C names for Merritt's modmult primitives. */
        !           241: #define stage_modulus  stage_merritt_modulus
        !           242: #define mp_modmult     merritt_modmult
        !           243: #define modmult_burn   merritt_burn
        !           244: #define SLOP_BITS      MERRITT_SLOP_BITS
        !           245: 
        !           246: #else  /* not PEASANT, MERRITT */
        !           247: #ifdef UPTON
        !           248: /* Define C names for Upton's modmult primitives. */
        !           249: #define stage_modulus  stage_upton_modulus
        !           250: #define mp_modmult     upton_modmult
        !           251: #define modmult_burn   upton_burn
        !           252: #define SLOP_BITS      UPTON_SLOP_BITS
        !           253: 
        !           254: #else  /* not PEASANT, MERRITT, UPTON */
        !           255: #ifdef SMITH
        !           256: /* Define C names for Smith's modmult primitives. */
        !           257: #define stage_modulus  stage_smith_modulus
        !           258: #define mp_modmult     smith_modmult
        !           259: #define modmult_burn   smith_burn
        !           260: #define SLOP_BITS      SMITH_SLOP_BITS
        !           261: 
        !           262: #endif /* SMITH */
        !           263: #endif /* UPTON */
        !           264: #endif /* MERRITT */
        !           265: #endif /* PEASANT */
        !           266: 
        !           267: 
        !           268: #define mp_shift_left(r1) mp_rotate_left(r1,(boolean)0)
        !           269:        /* multiprecision shift left 1 bit */
        !           270: 
        !           271: #if !defined(mp_add)
        !           272: #define mp_add(r1,r2) mp_addc(r1,r2,(boolean)0)
        !           273:        /* multiprecision add with no carry */
        !           274: #endif
        !           275: 
        !           276: #define mp_sub(r1,r2) mp_subb(r1,r2,(boolean)0)
        !           277:        /* multiprecision subtract with no borrow */
        !           278: 
        !           279: #define mp_abs(r) (mp_tstminus(r) ? (mp_neg(r),TRUE) : FALSE)
        !           280: 
        !           281: #define msub(r,m) if (mp_compare(r,m) >= 0) mp_sub(r,m)
        !           282:        /* Prevents r from getting bigger than modulus m */
        !           283: 
        !           284: #define testeq(r,i)    \
        !           285:        ( (lsunit(r)==(i)) && (significance(r)<=1) )
        !           286: 
        !           287: #define testne(r,i)    \
        !           288:        ( (lsunit(r)!=(i)) || (significance(r)>1) )
        !           289: 
        !           290: #define testge(r,i)    \
        !           291:        ( (lsunit(r)>=(i)) || (significance(r)>1) )
        !           292: 
        !           293: #define testle(r,i)    \
        !           294:        ( (lsunit(r)<=(i)) && (significance(r)<=1) )
        !           295: 
        !           296: #define mp_square(r1,r2) mp_mult(r1,r2,r2)
        !           297:        /* Square r2, returning product in r1 */
        !           298: 
        !           299: #define mp_modsquare(r1,r2) mp_modmult(r1,r2,r2)
        !           300:        /* Square r2, returning modulo'ed product in r1 */
        !           301: 
        !           302: #define countbytes(r) ((countbits(r)+7)>>3)
        !           303: 
        !           304: /*     SLOP_BITS is how many "carry bits" to allow for intermediate
        !           305:        calculation results to exceed the size of the modulus.
        !           306:        It is used by modexp to give some overflow elbow room for
        !           307:        modmult to use to perform modulo operations with the modulus.
        !           308:        The number of slop bits required is determined by the modmult
        !           309:        algorithm.  The Russian peasant modmult algorithm only requires
        !           310:        1 slop bit, for example.  Note that if we use an external assembly
        !           311:        modmult routine, SLOP_BITS may be meaningless or may be defined in a
        !           312:        non-constant manner.
        !           313: */
        !           314: #define PEASANT_SLOP_BITS      1
        !           315: #define MERRITT_SLOP_BITS      UNITSIZE
        !           316: #define UPTON_SLOP_BITS        (UNITSIZE/2)
        !           317: #ifdef  mp_smul /* old version requires MS word = 0 */
        !           318: #define SMITH_SLOP_BITS        UNITSIZE
        !           319: #else           /* mp_smula or C version of mp_smul */
        !           320: #define SMITH_SLOP_BITS        0
        !           321: #endif /* mp_smul */
        !           322: 
        !           323: #define MIN_KEY_BITS  384
        !           324: #define MAX_KEY_BITS 2048
        !           325: 
        !           326: /*     MAX_BIT_PRECISION is upper limit that assembly primitives can handle.
        !           327:        It must be less than 32704 bits, or 4088 bytes.  It should be an
        !           328:        integer multiple of UNITSIZE*2.
        !           329: */
        !           330: #define MAX_BIT_PRECISION (MAX_KEY_BITS+(2*UNITSIZE))
        !           331: #define MAX_BYTE_PRECISION (MAX_BIT_PRECISION/8)
        !           332: #define MAX_UNIT_PRECISION (MAX_BIT_PRECISION/UNITSIZE)
        !           333: 
        !           334: 
        !           335: /* global_precision is the unit precision last set by set_precision */
        !           336: #if defined(WIN32)
        !           337: /* For Win32 we want this to be 32-bit, for compatibility with the assembler code */
        !           338: extern unsigned int global_precision;
        !           339: #else
        !           340: extern short global_precision;
        !           341: #endif
        !           342: 
        !           343: 
        !           344: /*     The "bit sniffer" macros all begin sniffing at the MSB.
        !           345:        They are used internally by all the various multiply, divide, 
        !           346:        modulo, exponentiation, and square root functions.
        !           347: */
        !           348: #define sniff_bit(bptr,bitmask)        (*(bptr) & bitmask)
        !           349: 
        !           350: #define init_bitsniffer(bptr,bitmask,prec,bits) \
        !           351: { normalize(bptr,prec); \
        !           352:   if (!prec) \
        !           353:     return(0); \
        !           354:   bits = units2bits(prec); \
        !           355:   make_msbptr(bptr,prec); bitmask = uppermostbit; \
        !           356:   while (!sniff_bit(bptr,bitmask)) \
        !           357:   { bitmask >>= 1; bits--; \
        !           358:   } \
        !           359: }
        !           360: 
        !           361: #define bump_bitsniffer(bptr,bitmask) \
        !           362: { if (!(bitmask >>= 1)) \
        !           363:   { bitmask = uppermostbit; \
        !           364:        post_lowerunit(bptr); \
        !           365:   } \
        !           366: }
        !           367: 
        !           368: /* bump_2bitsniffers is used internally by mp_udiv. */
        !           369: #define bump_2bitsniffers(bptr,bptr2,bitmask) \
        !           370: { if (!(bitmask >>= 1)) \
        !           371:   { bitmask = uppermostbit; \
        !           372:     post_lowerunit(bptr); \
        !           373:     post_lowerunit(bptr2); \
        !           374:   } \
        !           375: }
        !           376: 
        !           377: /* stuff_bit is used internally by mp_udiv and mp_sqrt. */
        !           378: #define stuff_bit(bptr,bitmask)        *(bptr) |= bitmask
        !           379: 
        !           380: 
        !           381: boolean mp_addc
        !           382:        (register unitptr r1,register unitptr r2,register boolean carry);
        !           383:        /* multiprecision add with carry r2 to r1, result in r1 */
        !           384: 
        !           385: boolean mp_subb
        !           386:        (register unitptr r1,register unitptr r2,register boolean borrow);
        !           387:        /* multiprecision subtract with borrow, r2 from r1, result in r1 */
        !           388: 
        !           389: boolean mp_rotate_left(register unitptr r1,register boolean carry);
        !           390:        /* multiprecision rotate left 1 bit with carry, result in r1. */
        !           391: 
        !           392: void mp_shift_right_bits(register unitptr r1,register short bits);
        !           393:        /* multiprecision shift right bits, result in r1. */
        !           394: 
        !           395: short mp_compare(register unitptr r1,register unitptr r2);
        !           396:        /* Compares registers *r1, *r2, and returns -1, 0, or 1 */
        !           397: 
        !           398: boolean mp_inc(register unitptr r);
        !           399:        /* Increment multiprecision integer r. */
        !           400: 
        !           401: boolean mp_dec(register unitptr r);
        !           402:        /* Decrement multiprecision integer r. */
        !           403: 
        !           404: void mp_neg(register unitptr r);
        !           405:        /* Compute 2's complement, the arithmetic negative, of r */
        !           406: 
        !           407: #ifndef mp_move
        !           408: #define mp_move(d,s)    memcpy((void*)(d), (void*)(s), \
        !           409:                units2bytes(global_precision))
        !           410: #endif  
        !           411: #ifndef unitfill0
        !           412: #define unitfill0(r,ct) memset((void*)(r), 0, units2bytes(ct))
        !           413: #endif
        !           414: 
        !           415: #ifndef mp_burn
        !           416: #define mp_burn(r) mp_init(r,0) /* for burning the evidence */
        !           417: #define mp_init0(r) mp_init(r,0)
        !           418: #endif
        !           419: 
        !           420: #define empty_array(r)  unitfill0(r, sizeof(r)/sizeof(r[0])/sizeof(unit))
        !           421: 
        !           422: void mp_init(register unitptr r, word16 value);
        !           423:        /* Init multiprecision register r with short value. */
        !           424: 
        !           425: short significance(register unitptr r);
        !           426:        /* Returns number of significant units in r */
        !           427: 
        !           428: int mp_udiv(register unitptr remainder,register unitptr quotient,
        !           429:        register unitptr dividend,register unitptr divisor);
        !           430:        /* Unsigned divide, treats both operands as positive. */
        !           431: 
        !           432: int mp_recip(register unitptr quotient,register unitptr divisor);
        !           433:        /* Compute reciprocal as 1/divisor.  Used by faster modmult. */
        !           434: 
        !           435: int mp_div(register unitptr remainder,register unitptr quotient,
        !           436:        register unitptr dividend,register unitptr divisor);
        !           437:        /* Signed divide, either or both operands may be negative. */
        !           438: 
        !           439: word16 mp_shortdiv(register unitptr quotient,
        !           440:        register unitptr dividend,register word16 divisor);
        !           441:        /* Returns short remainder of unsigned divide. */
        !           442: 
        !           443: int mp_mod(register unitptr remainder,
        !           444:        register unitptr dividend,register unitptr divisor);
        !           445:        /* Unsigned divide, treats both operands as positive. */
        !           446: 
        !           447: word16 mp_shortmod(register unitptr dividend,register word16 divisor);
        !           448:        /* Just returns short remainder of unsigned divide. */
        !           449: 
        !           450: int mp_mult(register unitptr prod,
        !           451:        register unitptr multiplicand,register unitptr multiplier);
        !           452:        /* Computes multiprecision prod = multiplicand * multiplier */
        !           453: 
        !           454: int countbits(unitptr r);
        !           455:        /* Returns number of significant bits in r. */
        !           456: 
        !           457: int stage_peasant_modulus(unitptr n);
        !           458: int stage_merritt_modulus(unitptr n);
        !           459: int stage_upton_modulus(unitptr n);
        !           460: int stage_smith_modulus(unitptr n);
        !           461:        /* Must pass modulus to stage_modulus before calling modmult. */
        !           462: 
        !           463: int peasant_modmult(register unitptr prod,
        !           464:        unitptr multiplicand,register unitptr multiplier);
        !           465: int merritt_modmult(register unitptr prod,
        !           466:        unitptr multiplicand,register unitptr multiplier);
        !           467: int upton_modmult(register unitptr prod,
        !           468:        unitptr multiplicand,register unitptr multiplier);
        !           469: int smith_modmult(register unitptr prod,
        !           470:        unitptr multiplicand,register unitptr multiplier);
        !           471:        /* Performs combined multiply/modulo operation, with global modulus */
        !           472:  
        !           473:  
        !           474: 
        !           475: int mp_modexp(register unitptr expout,register unitptr expin,
        !           476:        register unitptr exponent,register unitptr modulus);
        !           477:        /* Combined exponentiation/modulo algorithm. */
        !           478: 
        !           479: int mp_modexp_crt(unitptr expout, unitptr expin,
        !           480:        unitptr p, unitptr q, unitptr ep, unitptr eq, unitptr u);
        !           481:        /* exponentiation and modulo using Chinese Remainder Theorem */
        !           482: 
        !           483: /****************** 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.