|
|
1.1 root 1: /* C include file for RSA library math routines
2:
3: Boulder Software Engineering
4: 3021 Eleventh Street
5: Boulder, CO 80304
6: (303) 444-4541
7:
8: (c) Copyright 1986 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 RSA public key cryptography.
15:
16: Although originally developed in Microsoft C for the IBM PC, this code
17: contains few machine dependancies. It assumes 2's complement
18: arithmetic. It can be adapted to 8-bit, 16-bit, or 32-bit machines,
19: lowbyte-highbyte order or highbyte-lowbyte order. This version
20: has been converted to ANSI C.
21: */
22:
23: /* Elaborate protection mechanisms to assure no redefinitions of types...*/
24: #ifndef BOOLSTUFF
25: #define BOOLSTUFF
26: #ifndef TRUE
27: #define FALSE 0
28: #define TRUE (!FALSE)
29: #endif /* if TRUE not already defined */
30: typedef unsigned char boolean; /* values are TRUE or FALSE */
31: #endif /* if BOOLSTUFF not already defined */
32: #ifndef BYTESTUFF
33: #define BYTESTUFF
34: typedef unsigned char byte; /* values are 0-255 */
35: typedef byte *byteptr; /* pointer to byte */
36: typedef char *string; /* pointer to ASCII character string */
37: #endif /* if BYTESTUFF not already defined */
38: #ifndef WORDSTUFF
39: #define WORDSTUFF
40: typedef unsigned short word16; /* values are 0-65536 */
41: typedef unsigned long word32; /* values are 0-4294967296 */
42: #endif /* if WORDSTUFF not already defined */
43: #ifndef min /* if min macro not already defined */
44: #define min(a,b) ( (a)<(b) ? (a) : (b) )
45: #define max(a,b) ( (a)>(b) ? (a) : (b) )
46: #endif /* if min macro not already defined */
47:
48:
49: /* #define PORTABLE */ /* determines if we use C primitives */
50: /* #define STEWART */ /* determines if we use Stewart's modmult */
51: /* #define ASM_MODMULT */ /* determines if we use assembly modmult */
52: /* #define UNIT8 */ /* use 8-bit units */
53: /* #define UNIT16 */ /* use 16-bit units */
54: /* #define UNIT32 */ /* use 32-bit units */
55: /* #define HIGHFIRST */ /* determines if Motorola or Intel internal format */
56:
57:
58: #ifndef STEWART /* if not Stewart's modmult algorithm */
59: #ifndef ASM_MODMULT /* if not assembly modmult algorithm */
60: #ifndef PEASANT /* if not Russian peasant modulo multiply algorithm */
61: #define MERRITT /* default: use Merritt's modmult algorithm */
62: #endif
63: #endif
64: #endif
65:
66: #ifndef UNIT32
67: #ifndef UNIT8
68: #define UNIT16 /* default--use 16-bit units */
69: #endif
70: #endif
71:
72: /*** CAUTION: If your machine has an unusual word size that is not a
73: power of 2 (8, 16, 32, or 64) bits wide, then the macros here that
74: use the symbol "LOG_UNITSIZE" must be changed.
75: ***/
76:
77: #ifdef UNIT8
78: typedef unsigned char unit;
79: typedef signed char signedunit;
80: #define UNITSIZE 8 /* number of bits in a unit */
81: #define uppermostbit ((unit) 0x80)
82: #define BYTES_PER_UNIT 1 /* number of bytes in a unit */
83: #define units2bits(n) ((n) << 3) /* fast multiply by UNITSIZE */
84: #define units2bytes(n) (n)
85: #define bits2units(n) (((n)+7) >> 3)
86: #define bytes2units(n) (n)
87: #endif
88:
89: #ifdef UNIT16
90: typedef word16 unit;
91: typedef short signedunit;
92: #define UNITSIZE 16 /* number of bits in a unit */
93: #define uppermostbit ((unit) 0x8000)
94: #define BYTES_PER_UNIT 2 /* number of bytes in a unit */
95: #define units2bits(n) ((n) << 4) /* fast multiply by UNITSIZE */
96: #define units2bytes(n) ((n) << 1)
97: #define bits2units(n) (((n)+15) >> 4)
98: #define bytes2units(n) (((n)+1) >> 1)
99: #endif
100:
101: #ifdef UNIT32
102: typedef word32 unit;
103: typedef long signedunit;
104: #define UNITSIZE 32 /* number of bits in a unit */
105: #define uppermostbit ((unit) 0x80000000)
106: #define BYTES_PER_UNIT 4 /* number of bytes in a unit */
107: #define units2bits(n) ((n) << 5) /* fast multiply by UNITSIZE */
108: #define units2bytes(n) ((n) << 2)
109: #define bits2units(n) (((n)+31) >> 5)
110: #define bytes2units(n) (((n)+3) >> 2)
111: #undef PORTABLE /* can't use our C versions if 32 bits. */
112: #endif
113:
114: #define power_of_2(b) ((unit) 1 << (b)) /* computes power-of-2 bit masks */
115: #define bits2bytes(n) (((n)+7) >> 3)
116: /* Some C compilers (like the ADSP2101) will not always collapse constant
117: expressions at compile time if the expressions contain shift operators. */
118: /* #define uppermostbit power_of_2(UNITSIZE-1) */
119: /* #define UNITSIZE units2bits(1) */ /* number of bits in a unit */
120: /* #define bytes2units(n) bits2units((n)<<3) */
121: /* #define BYTES_PER_UNIT (UNITSIZE >> 3) */
122: /* LOG_UNITSIZE is the log base 2 of UNITSIZE, ie: 4 for 16-bit units */
123: /* #define units2bits(n) ((n) << LOG_UNITSIZE) */ /* fast multiply by UNITSIZE */
124: /* #define units2bytes(n) ((n) << (LOG_UNITSIZE-3)) */
125: /* #define bits2units(n) (((n)+(UNITSIZE-1)) >> LOG_UNITSIZE) */
126: /* #define bytes2units(n) (((n)+(BYTES_PER_UNIT-1)) >> (LOG_UNITSIZE-3)) */
127:
128: typedef unit *unitptr;
129:
130:
131: /*--------------------- Byte ordering stuff -------------------*/
132: #ifdef HIGHFIRST
133:
134: /* these definitions assume MSB comes first */
135: #define pre_higherunit(r) (--(r))
136: #define pre_lowerunit(r) (++(r))
137: #define post_higherunit(r) ((r)--)
138: #define post_lowerunit(r) ((r)++)
139: #define bit_index(n) (global_precision-bits2units((n)+1))
140: #define lsbptr(r,prec) ((r)+(prec)-1)
141: #define make_lsbptr(r,prec) (r) = lsbptr(r,prec)
142: #define unmake_lsbptr(r,prec) (r) = ((r)-(prec)+1)
143: #define msbptr(r,prec) (r)
144: #define make_msbptr(r,prec) /* (r) = msbptr(r,prec) */
145:
146: #define rescale(r,currentp,newp) r -= ((newp) - (currentp))
147: #define normalize(r,prec) \
148: { prec = significance(r); r += (global_precision-(prec)); }
149:
150: #else /* LOWFIRST byte order */
151:
152: /* these definitions assume LSB comes first */
153: #define pre_higherunit(r) (++(r))
154: #define pre_lowerunit(r) (--(r))
155: #define post_higherunit(r) ((r)++)
156: #define post_lowerunit(r) ((r)--)
157: #define bit_index(n) (bits2units((n)+1)-1)
158: #define lsbptr(r,prec) (r)
159: #define make_lsbptr(r,prec) /* (r) = lsbptr(r,prec) */
160: #define unmake_lsbptr(r,prec) /* (r) = (r) */
161: #define msbptr(r,prec) ((r)+(prec)-1)
162: #define make_msbptr(r,prec) (r) = msbptr(r,prec)
163:
164: #define rescale(r,currentp,newp) /* nil statement */
165: #define normalize(r,prec) prec = significance(r)
166:
167: #endif /* LOWFIRST byte order */
168: /*------------------ End byte ordering stuff -------------------*/
169:
170: /* Note that the address calculations require that lsbptr, msbptr,
171: make_lsbptr, make_msbptr, mp_tstbit, mp_setbit, mp_clrbit,
172: and bitptr all have unitptr arguments, not byteptr arguments. */
173: #define bitptr(r,n) &((r)[bit_index(n)])
174: #define mp_tstbit(r,n) (*bitptr(r,n) & power_of_2((n) & (UNITSIZE-1)))
175: #define mp_setbit(r,n) (*bitptr(r,n) |= power_of_2((n) & (UNITSIZE-1)))
176: #define mp_clrbit(r,n) (*bitptr(r,n) &= ~power_of_2((n) & (UNITSIZE-1)))
177: #define msunit(r) (*msbptr(r,global_precision))
178: #define lsunit(r) (*lsbptr(r,global_precision))
179: /* #define mp_tstminus(r) ((msunit(r) & uppermostbit)!=0) */
180: #define mp_tstminus(r) ((signedunit) msunit(r) < 0)
181:
182: /* MAX_BIT_PRECISION is upper limit that assembly primitives can handle.
183: It must be less than 32704 bits, or 4088 bytes. It should be an
184: integer multiple of UNITSIZE*2.
185: */
186: #define MAX_BIT_PRECISION 1024 /* limit for current 8086 primitives */
187: /* #define MAX_BIT_PRECISION 544 /* 544 is limit for ADSP2101 primitives */
188: #define MAX_BYTE_PRECISION (MAX_BIT_PRECISION/8)
189: #define MAX_UNIT_PRECISION (MAX_BIT_PRECISION/UNITSIZE)
190:
191:
192: /*************** multiprecision library primitives ****************/
193: #ifdef PORTABLE /* using slow portable C primitives */
194:
195: #define set_precision(prec) (global_precision = (prec))
196:
197: #else /* not PORTABLE - not using portable C primitives */
198: /*
199: The following primitives should be coded in assembly.
200: Functions P_ADDC, P_SUBB, and P_ROTL return a carry flag as their
201: functional return, and the result of the operation is placed in r1.
202: These assembly primitives are externally defined, unless PORTABLE
203: is defined.
204: */
205:
206: void P_SETP(short nbits);
207: /* sets working precision to specified number of bits. */
208:
209: boolean P_ADDC(unitptr r1, unitptr r2, boolean carry);
210: /* multiprecision add with carry r2 to r1, result in r1 */
211:
212: boolean P_SUBB(unitptr r1, unitptr r2, boolean borrow);
213: /* multiprecision subtract with borrow, r2 from r1, result in r1 */
214:
215: boolean P_ROTL(unitptr r1, boolean carry);
216: /* multiprecision rotate left 1 bit with carry, result in r1. */
217:
218: /* Define C primitive names as the equivalent calls to assembly primitives. */
219: #define set_precision(prec) P_SETP(units2bits(global_precision=(prec)))
220: #define mp_addc P_ADDC
221: #define mp_subb P_SUBB
222: #define mp_rotate_left P_ROTL
223:
224: #endif /* not PORTABLE */
225: /************** end of primitives that should be in assembly *************/
226:
227: #ifdef ASM_MODMULT /* use assembly primitive modmult */
228:
229: /* The following modmult-related primitives can be coded in assembly.
230: These assembly primitives are externally defined,
231: if ASM_MODMULT is defined.
232: */
233:
234: /* Define C names for assembly modmult primitives. */
235: #define stage_modulus P_STAGEMOD
236: #define mp_modmult P_MMULT
237: #define modmult_burn P_MMBURN
238:
239: #endif /* ASM_MODMULT */
240:
241: #ifdef PEASANT
242:
243: /* Define C names for Russian peasant modmult primitives. */
244: #define stage_modulus stage_peasant_modulus
245: #define mp_modmult peasant_modmult
246: #define modmult_burn peasant_burn
247:
248: #endif /* PEASANT */
249:
250: #ifdef MERRITT
251: /* Define C names for Merritt's modmult primitives. */
252: #define stage_modulus stage_merritt_modulus
253: #define mp_modmult merritt_modmult
254: #define modmult_burn merritt_burn
255:
256: #endif /* MERRITT */
257:
258: #ifdef STEWART
259: /* Define C names for Stewart's modmult primitives. */
260: #define stage_modulus stage_stewart_modulus
261: #define mp_modmult P_MMULT
262: #define modmult_burn stewart_burn
263:
264: #endif /* STEWART */
265:
266:
267: #define mp_shift_left(r1) mp_rotate_left(r1,(boolean)0)
268: /* multiprecision shift left 1 bit */
269:
270: #define mp_shift_right(r1) mp_rotate_right(r1,(boolean)0)
271: /* multiprecision shift right 1 bit */
272:
273: #define mp_add(r1,r2) mp_addc(r1,r2,(boolean)0)
274: /* multiprecision add with no carry */
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 mp_burn(r) mp_init(r,0) /* for burning the evidence */
285:
286: #define testeq(r,i) \
287: ( (lsunit(r)==(i)) && (significance(r)<=1) )
288:
289: #define testne(r,i) \
290: ( (lsunit(r)!=(i)) || (significance(r)>1) )
291:
292: #define mp_square(r1,r2) mp_mult(r1,r2,r2)
293: /* Square r2, returning product in r1 */
294:
295: #define mp_modsquare(r1,r2) mp_modmult(r1,r2,r2)
296: /* Square r2, returning modulo'ed product in r1 */
297:
298: #define countbytes(r) ((countbits(r)+7)>>3)
299:
300: /* SLOP_BITS is how many "carry bits" to allow for intermediate
301: calculation results to exceed the size of the modulus.
302: It is used by modexp to give some overflow elbow room for
303: modmult to use to perform modulo operations with the modulus.
304: The number of slop bits required is determined by the modmult
305: algorithm. The Russian peasant modmult algorithm only requires
306: 1 slop bit, for example. Note that if ASM_MODMULT is
307: defined, SLOP_BITS may be meaningless or may be defined in a
308: non-constant manner.
309: */
310: #ifdef MERRITT /* use Merritt's modmult algorithm */
311: #define SLOP_BITS (UNITSIZE+1)
312: #define MERRITT_KEY /* cause keygen to generate unnormalized keys */
313: #endif /* MERRITT */
314: #ifdef PEASANT /* use Russian peasant modmult algorithm */
315: #define SLOP_BITS 1
316: #endif /* PEASANT */
317: #ifdef ASM_MODMULT /* use external assembly modmult algorithm */
318: /* SLOP_BITS is likely either 1, UNITSIZE+1, non-constant or meaningless. */
319: #define SLOP_BITS 0
320: #endif /* ASM_MODMULT */
321: #ifdef STEWART /* use Stewart's modmult modmult algorithm */
322: #define SLOP_BITS 0
323: #define STEWART_KEY /* cause keygen to generate normalized keys */
324: #endif /* STEWART */
325:
326:
327: #ifndef RSALIB /* not compiling RSALIB */
328: /* global_precision is the unit precision last set by set_precision */
329: extern short global_precision;
330: #endif /* not compiling RSALIB */
331:
332:
333: #ifndef RSALIB /* not compiling RSALIB */
334: /* Bug in DSP2101 C compiler -- no function protypes
335: allowed when compiling those same functions. */
336:
337: #ifdef PORTABLE /* these slow C primitives should be recoded in assembly */
338:
339: boolean mp_addc
340: (register unitptr r1,register unitptr r2,register boolean carry);
341: /* multiprecision add with carry r2 to r1, result in r1 */
342:
343: boolean mp_subb
344: (register unitptr r1,register unitptr r2,register boolean borrow);
345: /* multiprecision subtract with borrow, r2 from r1, result in r1 */
346:
347: boolean mp_rotate_left(register unitptr r1,register boolean carry);
348: /* multiprecision rotate left 1 bit with carry, result in r1. */
349:
350: #endif /* PORTABLE */
351:
352: boolean mp_rotate_right(register unitptr r1,register boolean carry);
353: /* multiprecision rotate right 1 bit with carry, r1. */
354:
355: short mp_compare(register unitptr r1,register unitptr r2);
356: /* Compares registers *r1, *r2, and returns -1, 0, or 1 */
357:
358: boolean mp_inc(register unitptr r);
359: /* Increment multiprecision integer r. */
360:
361: boolean mp_dec(register unitptr r);
362: /* Decrement multiprecision integer r. */
363:
364: void mp_neg(register unitptr r);
365: /* Compute 2's complement, the arithmetic negative, of r */
366:
367: void mp_move(register unitptr dst,register unitptr src);
368:
369: void mp_init(register unitptr r, word16 value);
370: /* Init multiprecision register r with short value. */
371:
372: short significance(register unitptr r);
373: /* Returns number of significant units in r */
374:
375: int mp_udiv(register unitptr remainder,register unitptr quotient,
376: register unitptr dividend,register unitptr divisor);
377: /* Unsigned divide, treats both operands as positive. */
378:
379: int mp_div(register unitptr remainder,register unitptr quotient,
380: register unitptr dividend,register unitptr divisor);
381: /* Signed divide, either or both operands may be negative. */
382:
383: word16 mp_shortdiv(register unitptr quotient,
384: register unitptr dividend,register word16 divisor);
385: /* Returns short remainder of unsigned divide. */
386:
387: int mp_mod(register unitptr remainder,
388: register unitptr dividend,register unitptr divisor);
389: /* Unsigned divide, treats both operands as positive. */
390:
391: word16 mp_shortmod(register unitptr dividend,register word16 divisor);
392: /* Just returns short remainder of unsigned divide. */
393:
394: int mp_mult(register unitptr prod,
395: register unitptr multiplicand,register unitptr multiplier);
396: /* Computes multiprecision prod = multiplicand * multiplier */
397:
398: void stage_modulus(unitptr n);
399: /* Must pass modulus to stage_modulus before calling modmult. */
400:
401: int mp_modmult(register unitptr prod,
402: unitptr multiplicand,register unitptr multiplier);
403: /* Performs combined multiply/modulo operation, with global modulus */
404:
405: int countbits(unitptr r);
406: /* Returns number of significant bits in r. */
407:
408: int mp_modexp(register unitptr expout,register unitptr expin,
409: register unitptr exponent,register unitptr modulus);
410: /* Combined exponentiation/modulo algorithm. */
411:
412: int rsa_decrypt(unitptr M, unitptr C,
413: unitptr d, unitptr p, unitptr q, unitptr u);
414: /* Uses Chinese Remainder Theorem shortcut for RSA decryption. */
415:
416: int mp_sqrt(unitptr quotient,unitptr dividend);
417: /* Quotient is returned as the square root of dividend. */
418:
419: #endif /* not compiling RSALIB */
420:
421: /****************** end of RSA library ****************************/
422:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.