|
|
1.1.1.6 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
1.1.1.7 root 120: expressions at compile time if the expressions contain shift
121: operators. */
1.1.1.6 root 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 */
1.1.1.7 root 127: /* #define units2bits(n) ((n) << LOG_UNITSIZE) */ /* fast multiply by
128: UNITSIZE */
1.1.1.6 root 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,
1.1.1.7 root 201: and bitptr all have unitptr arguments, not byte pointer arguments.
202: */
1.1.1.6 root 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:
224: #ifdef PEASANT
225:
226: /* Define C names for Russian peasant modmult primitives. */
227: #define stage_modulus stage_peasant_modulus
228: #define mp_modmult peasant_modmult
229: #define modmult_burn peasant_burn
230: #define SLOP_BITS PEASANT_SLOP_BITS
231:
232: #else /* not PEASANT */
233: #ifdef MERRITT
234: /* Define C names for Merritt's modmult primitives. */
235: #define stage_modulus stage_merritt_modulus
236: #define mp_modmult merritt_modmult
237: #define modmult_burn merritt_burn
238: #define SLOP_BITS MERRITT_SLOP_BITS
239:
240: #else /* not PEASANT, MERRITT */
241: #ifdef UPTON
242: /* Define C names for Upton's modmult primitives. */
243: #define stage_modulus stage_upton_modulus
244: #define mp_modmult upton_modmult
245: #define modmult_burn upton_burn
246: #define SLOP_BITS UPTON_SLOP_BITS
247:
248: #else /* not PEASANT, MERRITT, UPTON */
249: #ifdef SMITH
250: /* Define C names for Smith's modmult primitives. */
251: #define stage_modulus stage_smith_modulus
252: #define mp_modmult smith_modmult
253: #define modmult_burn smith_burn
254: #define SLOP_BITS SMITH_SLOP_BITS
255:
256: #endif /* SMITH */
257: #endif /* UPTON */
258: #endif /* MERRITT */
259: #endif /* PEASANT */
260:
261:
262: #define mp_shift_left(r1) mp_rotate_left(r1,(boolean)0)
263: /* multiprecision shift left 1 bit */
264:
265: #define mp_add(r1,r2) mp_addc(r1,r2,(boolean)0)
266: /* multiprecision add with no carry */
267:
268: #define mp_sub(r1,r2) mp_subb(r1,r2,(boolean)0)
269: /* multiprecision subtract with no borrow */
270:
271: #define mp_abs(r) (mp_tstminus(r) ? (mp_neg(r),TRUE) : FALSE)
272:
273: #define msub(r,m) if (mp_compare(r,m) >= 0) mp_sub(r,m)
274: /* Prevents r from getting bigger than modulus m */
275:
276: #define testeq(r,i) \
277: ( (lsunit(r)==(i)) && (significance(r)<=1) )
278:
279: #define testne(r,i) \
280: ( (lsunit(r)!=(i)) || (significance(r)>1) )
281:
282: #define testge(r,i) \
283: ( (lsunit(r)>=(i)) || (significance(r)>1) )
284:
285: #define testle(r,i) \
286: ( (lsunit(r)<=(i)) && (significance(r)<=1) )
287:
288: #define mp_square(r1,r2) mp_mult(r1,r2,r2)
289: /* Square r2, returning product in r1 */
290:
291: #define mp_modsquare(r1,r2) mp_modmult(r1,r2,r2)
292: /* Square r2, returning modulo'ed product in r1 */
293:
294: #define countbytes(r) ((countbits(r)+7)>>3)
295:
296: /* SLOP_BITS is how many "carry bits" to allow for intermediate
297: calculation results to exceed the size of the modulus.
298: It is used by modexp to give some overflow elbow room for
299: modmult to use to perform modulo operations with the modulus.
300: The number of slop bits required is determined by the modmult
301: algorithm. The Russian peasant modmult algorithm only requires
302: 1 slop bit, for example. Note that if we use an external assembly
303: modmult routine, SLOP_BITS may be meaningless or may be defined in a
304: non-constant manner.
305: */
306: #define PEASANT_SLOP_BITS 1
307: #define MERRITT_SLOP_BITS UNITSIZE
308: #define UPTON_SLOP_BITS (UNITSIZE/2)
309: #ifdef mp_smul /* old version requires MS word = 0 */
310: #define SMITH_SLOP_BITS UNITSIZE
311: #else /* mp_smula or C version of mp_smul */
312: #define SMITH_SLOP_BITS 0
313: #endif /* mp_smul */
314:
315: /* MAX_BIT_PRECISION is upper limit that assembly primitives can handle.
316: It must be less than 32704 bits, or 4088 bytes. It should be an
317: integer multiple of UNITSIZE*2.
318: */
319: #if (SLOP_BITS > 0)
1.1.1.8 ! root 320: #define MAX_BIT_PRECISION (2048+(2*UNITSIZE))
1.1.1.6 root 321: #else
1.1.1.8 ! root 322: #define MAX_BIT_PRECISION 2048
1.1.1.6 root 323: #endif
324: #define MAX_BYTE_PRECISION (MAX_BIT_PRECISION/8)
325: #define MAX_UNIT_PRECISION (MAX_BIT_PRECISION/UNITSIZE)
326:
327:
328: /* global_precision is the unit precision last set by set_precision */
329: extern short global_precision;
330:
331:
332: /* The "bit sniffer" macros all begin sniffing at the MSB.
333: They are used internally by all the various multiply, divide,
334: modulo, exponentiation, and square root functions.
335: */
336: #define sniff_bit(bptr,bitmask) (*(bptr) & bitmask)
337:
338: #define init_bitsniffer(bptr,bitmask,prec,bits) \
339: { normalize(bptr,prec); \
340: if (!prec) \
341: return(0); \
342: bits = units2bits(prec); \
343: make_msbptr(bptr,prec); bitmask = uppermostbit; \
344: while (!sniff_bit(bptr,bitmask)) \
345: { bitmask >>= 1; bits--; \
346: } \
347: }
348:
349: #define bump_bitsniffer(bptr,bitmask) \
350: { if (!(bitmask >>= 1)) \
351: { bitmask = uppermostbit; \
352: post_lowerunit(bptr); \
353: } \
354: }
355:
356: /* bump_2bitsniffers is used internally by mp_udiv. */
357: #define bump_2bitsniffers(bptr,bptr2,bitmask) \
358: { if (!(bitmask >>= 1)) \
359: { bitmask = uppermostbit; \
360: post_lowerunit(bptr); \
361: post_lowerunit(bptr2); \
362: } \
363: }
364:
365: /* stuff_bit is used internally by mp_udiv and mp_sqrt. */
366: #define stuff_bit(bptr,bitmask) *(bptr) |= bitmask
367:
368:
369: boolean mp_addc
370: (register unitptr r1,register unitptr r2,register boolean carry);
371: /* multiprecision add with carry r2 to r1, result in r1 */
372:
373: boolean mp_subb
374: (register unitptr r1,register unitptr r2,register boolean borrow);
375: /* multiprecision subtract with borrow, r2 from r1, result in r1 */
376:
377: boolean mp_rotate_left(register unitptr r1,register boolean carry);
378: /* multiprecision rotate left 1 bit with carry, result in r1. */
379:
380: void mp_shift_right_bits(register unitptr r1,register short bits);
381: /* multiprecision shift right bits, result in r1. */
382:
383: short mp_compare(register unitptr r1,register unitptr r2);
384: /* Compares registers *r1, *r2, and returns -1, 0, or 1 */
385:
386: boolean mp_inc(register unitptr r);
387: /* Increment multiprecision integer r. */
388:
389: boolean mp_dec(register unitptr r);
390: /* Decrement multiprecision integer r. */
391:
392: void mp_neg(register unitptr r);
393: /* Compute 2's complement, the arithmetic negative, of r */
394:
395: #ifndef mp_move
396: #define mp_move(d,s) memcpy((void*)(d), (void*)(s), \
397: units2bytes(global_precision))
398: #endif
399: #ifndef unitfill0
400: #define unitfill0(r,ct) memset((void*)(r), 0, units2bytes(ct))
401: #endif
402:
403: #ifndef mp_burn
404: #define mp_burn(r) mp_init(r,0) /* for burning the evidence */
405: #define mp_init0(r) mp_init(r,0)
406: #endif
407:
408: #define empty_array(r) unitfill0(r, sizeof(r)/sizeof(r[0])/sizeof(unit))
409:
410: void mp_init(register unitptr r, word16 value);
411: /* Init multiprecision register r with short value. */
412:
413: short significance(register unitptr r);
414: /* Returns number of significant units in r */
415:
416: int mp_udiv(register unitptr remainder,register unitptr quotient,
417: register unitptr dividend,register unitptr divisor);
418: /* Unsigned divide, treats both operands as positive. */
419:
420: int mp_recip(register unitptr quotient,register unitptr divisor);
421: /* Compute reciprocal as 1/divisor. Used by faster modmult. */
422:
423: int mp_div(register unitptr remainder,register unitptr quotient,
424: register unitptr dividend,register unitptr divisor);
425: /* Signed divide, either or both operands may be negative. */
426:
427: word16 mp_shortdiv(register unitptr quotient,
428: register unitptr dividend,register word16 divisor);
429: /* Returns short remainder of unsigned divide. */
430:
431: int mp_mod(register unitptr remainder,
432: register unitptr dividend,register unitptr divisor);
433: /* Unsigned divide, treats both operands as positive. */
434:
435: word16 mp_shortmod(register unitptr dividend,register word16 divisor);
436: /* Just returns short remainder of unsigned divide. */
437:
438: int mp_mult(register unitptr prod,
439: register unitptr multiplicand,register unitptr multiplier);
440: /* Computes multiprecision prod = multiplicand * multiplier */
441:
442: int countbits(unitptr r);
443: /* Returns number of significant bits in r. */
444:
445: int stage_peasant_modulus(unitptr n);
446: int stage_merritt_modulus(unitptr n);
447: int stage_upton_modulus(unitptr n);
448: int stage_smith_modulus(unitptr n);
449: /* Must pass modulus to stage_modulus before calling modmult. */
450:
451: int peasant_modmult(register unitptr prod,
452: unitptr multiplicand,register unitptr multiplier);
453: int merritt_modmult(register unitptr prod,
454: unitptr multiplicand,register unitptr multiplier);
455: int upton_modmult(register unitptr prod,
456: unitptr multiplicand,register unitptr multiplier);
457: int smith_modmult(register unitptr prod,
458: unitptr multiplicand,register unitptr multiplier);
459: /* Performs combined multiply/modulo operation, with global modulus */
460:
461:
462:
463: int mp_modexp(register unitptr expout,register unitptr expin,
464: register unitptr exponent,register unitptr modulus);
465: /* Combined exponentiation/modulo algorithm. */
466:
467: int mp_modexp_crt(unitptr expout, unitptr expin,
468: unitptr p, unitptr q, unitptr ep, unitptr eq, unitptr u);
469: /* exponentiation and modulo using Chinese Remainder Theorem */
470:
471: /****************** end of MPI library ****************************/
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.