|
|
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 ****************************/
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.