webmoney 0.0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,41 @@
1
+ #ifndef _INCLUDE_MD4
2
+ #define _INCLUDE_MD4
3
+ #include "stdafx.h"
4
+
5
+ #ifndef _WIN32
6
+ #define _NOT_WIN32
7
+ #endif
8
+
9
+ #if defined(__FreeBSD__) && __FreeBSD__ < 5 /* for FreeBSD version <= 4 */
10
+ #include <inttypes.h>
11
+ #elif defined(_NOT_WIN32)
12
+ #include <stdint.h>
13
+ #endif
14
+
15
+ #ifdef _WIN32
16
+ typedef DWORD Word32Type;
17
+ #else
18
+ typedef uint32_t Word32Type;
19
+ #endif
20
+
21
+ typedef struct {
22
+ Word32Type buffer[4];
23
+ unsigned char count[8];
24
+ unsigned int done;
25
+ } MDstruct, *MDptr;
26
+
27
+ #ifdef __cplusplus
28
+ extern "C" {
29
+ #endif
30
+ extern void MDbegin(MDptr MDp) ;
31
+
32
+ extern void MDupdate(MDptr MDp, unsigned char *X, Word32Type count) ;
33
+
34
+ extern void MDprint(MDptr MDp) ;
35
+
36
+ #ifdef __cplusplus
37
+ }
38
+ #endif
39
+
40
+ #endif
41
+ //---
@@ -0,0 +1,838 @@
1
+ #include "stdafx.h"
2
+ #ifdef _WIN32
3
+ #ifndef _CONSOLE
4
+ #endif
5
+ #endif
6
+
7
+ #include "rsalib1.h"
8
+ #include <stdio.h>
9
+
10
+ int N_NEG_VAL=-1;
11
+
12
+ CRSALib::CRSALib(short glob_pres)
13
+ {
14
+ global_precision = glob_pres;
15
+ int i, j;
16
+ for (i=0; i< 16; i++)
17
+ for (j=0; j< MAX_UNIT_PRECISION; j++)
18
+ moduli_buf[i][j]=0;
19
+ moduli[0] = 0;
20
+ for (i=1; i<16+1; i++)
21
+ moduli[i] = &moduli_buf[ i-1][0];
22
+ for (i=0;i<16+1;i++)
23
+ {
24
+ msu_moduli[i] = 0;
25
+ nmsu_moduli[i] = 0;
26
+ }
27
+ for (i=0; i< 16-1; i++)
28
+ for (j=0; j< MAX_UNIT_PRECISION; j++)
29
+ mpdbuf[i][j]=0;
30
+
31
+ mpd[0] = 0;
32
+ for (i=1; i < 16; i++)
33
+ {
34
+ mpd[i] = &mpdbuf[ i-1][0];
35
+ }
36
+ }
37
+
38
+ boolean CRSALib::mp_addc(register unitptr r1,register unitptr r2,register boolean carry)
39
+ {
40
+ register ulint x;
41
+ short precision;
42
+ precision = global_precision;
43
+
44
+ while (precision--)
45
+ {
46
+ x = (ulint) *r1 + (ulint) *((r2)++) + (ulint) carry;
47
+ *((r1)++) = (unit)x;
48
+ carry = ((x & ((ulint) 1 << 16)) != 0L);
49
+ }
50
+ return(carry);
51
+ }
52
+
53
+ boolean CRSALib::mp_subb(register unitptr r1,register unitptr r2,register boolean borrow)
54
+ {
55
+ register ulint x;
56
+ short precision;
57
+ precision = global_precision;
58
+
59
+ while (precision--)
60
+ {
61
+ x = (ulint) *r1 - (ulint) *((r2)++) - (ulint) borrow;
62
+ *((r1)++) = (unit)x;
63
+ borrow = ((x & ((ulint) 1 << 16)) != 0L);
64
+ }
65
+ return(borrow);
66
+ }
67
+
68
+ boolean CRSALib::mp_rotate_left(register unitptr r1,register boolean carry)
69
+ {
70
+ register short precision;
71
+ register boolean nextcarry;
72
+ precision = global_precision;
73
+
74
+ while (precision--)
75
+ {
76
+ nextcarry = (((signedunit) *r1) < 0);
77
+
78
+ *r1 <<= 1 ;
79
+ if (carry) *r1 |= 1;
80
+ carry = nextcarry;
81
+ (++(r1));
82
+ }
83
+ return(nextcarry);
84
+ }
85
+
86
+ boolean CRSALib::mp_rotate_right(register unitptr r1,register boolean carry)
87
+ {
88
+ register short precision;
89
+ register boolean nextcarry;
90
+ precision = global_precision;
91
+ (r1) = ((r1)+(precision)-1);
92
+ while (precision--)
93
+ {
94
+ nextcarry = *r1 & 1;
95
+ *r1 >>= 1 ;
96
+ if (carry) *r1 |= ((unit) 0x8000);
97
+ carry = nextcarry;
98
+ (--(r1));
99
+ }
100
+ return(nextcarry);
101
+ }
102
+
103
+ short CRSALib::mp_compare(register unitptr r1,register unitptr r2)
104
+ {
105
+ register short precision;
106
+ precision = global_precision;
107
+ (r1) = ((r1)+(precision)-1);
108
+ (r2) = ((r2)+(precision)-1);
109
+ do
110
+ {
111
+ if (*r1 < *r2)
112
+ return(-1);
113
+ if (*((r1)--) > *((r2)--))
114
+ return(1);
115
+ } while (--precision);
116
+ return(0);
117
+ }
118
+
119
+ boolean CRSALib::mp_inc(register unitptr r)
120
+ {
121
+ register short precision;
122
+ precision = global_precision;
123
+
124
+ do
125
+ { if ( ++(*r) ) return(0);
126
+ ((r)++);
127
+ } while (--precision);
128
+ return(1);
129
+ }
130
+
131
+ boolean CRSALib::mp_dec(register unitptr r)
132
+ {
133
+ register short precision;
134
+ precision = global_precision;
135
+
136
+ do
137
+ {
138
+ if ( (signedunit) (--(*r)) != (signedunit) -1 )
139
+ return(0);
140
+ ((r)++);
141
+ } while (--precision);
142
+ return(1);
143
+ }
144
+
145
+ void CRSALib::mp_neg(register unitptr r)
146
+ {
147
+ register short precision;
148
+ precision = global_precision;
149
+
150
+ mp_dec(r);
151
+ do
152
+ {
153
+ *r = ~(*r);
154
+ r++;
155
+ } while (--precision);
156
+ }
157
+
158
+ void CRSALib::mp_move(register unitptr dst,register unitptr src)
159
+ {
160
+ register short precision;
161
+ precision = global_precision;
162
+ do
163
+ {
164
+ *dst++ = *src++;
165
+ } while (--precision);
166
+ }
167
+
168
+ void CRSALib::mp_init(register unitptr r, word16 value)
169
+ {
170
+ register short precision;
171
+ precision = global_precision;
172
+ *((r)++) = value;
173
+ precision--;
174
+ while (precision--)
175
+ *((r)++) = 0;
176
+ }
177
+
178
+ short CRSALib::significance(register unitptr r)
179
+ {
180
+ register short precision;
181
+ precision = global_precision;
182
+ (r) = ((r)+(precision)-1);
183
+ do
184
+ {
185
+ if (*((r)--))
186
+ return(precision);
187
+ } while (--precision);
188
+ return(precision);
189
+ }
190
+
191
+ void CRSALib::unitfill0(unitptr r,word16 unitcount)
192
+ {
193
+ while (unitcount--) *r++ = 0;
194
+ }
195
+
196
+ int CRSALib::mp_udiv(register unitptr remainder,register unitptr quotient,
197
+ register unitptr dividend,register unitptr divisor)
198
+ {
199
+ int bits;
200
+ short dprec;
201
+ register unit bitmask;
202
+ if (( ((*(divisor))==(0)) && (significance(divisor)<=1) ))
203
+ return(-1);
204
+
205
+ mp_init(remainder,0);
206
+ mp_init(quotient,0);
207
+
208
+ {
209
+ dprec = significance(dividend);
210
+ if (!dprec) return(0);
211
+ bits = ((dprec) << 4);
212
+ (dividend) = ((dividend)+(dprec)-1);
213
+ bitmask = ((unit) 0x8000);
214
+ while (!(*(dividend) & bitmask))
215
+ {
216
+ bitmask >>= 1;
217
+ bits--;
218
+ }
219
+ };
220
+
221
+ (quotient) = ((quotient)+(dprec)-1);
222
+
223
+ while (bits--)
224
+ {
225
+ mp_rotate_left(remainder,(boolean)((*(dividend) & bitmask)!=0));
226
+ if (mp_compare(remainder,divisor) >= 0)
227
+ {
228
+ mp_subb(remainder,divisor,(boolean)0);
229
+ *(quotient) |= bitmask;
230
+ }
231
+ {
232
+ if (!(bitmask >>= 1))
233
+ {
234
+ bitmask = ((unit) 0x8000);
235
+ ((dividend)--); ((quotient)--);
236
+ }
237
+ };
238
+ }
239
+ return(0);
240
+ }
241
+
242
+
243
+ int CRSALib::mp_div(register unitptr remainder,register unitptr quotient,
244
+ register unitptr dividend,register unitptr divisor)
245
+ {
246
+ boolean dvdsign,dsign;
247
+ int status;
248
+ dvdsign = (((signedunit) (*((dividend)+(global_precision)-1)) < 0)!=0);
249
+ dsign = (((signedunit) (*((divisor)+(global_precision)-1)) < 0)!=0);
250
+ if (dvdsign) mp_neg(dividend);
251
+ if (dsign) mp_neg(divisor);
252
+ status = mp_udiv(remainder,quotient,dividend,divisor);
253
+ if (dvdsign) mp_neg(dividend);
254
+ if (dsign) mp_neg(divisor);
255
+ if (status<0) return(status);
256
+ if (dvdsign) mp_neg(remainder);
257
+ if (dvdsign ^ dsign) mp_neg(quotient);
258
+ return(status);
259
+ }
260
+
261
+
262
+ word16 CRSALib::mp_shortdiv(register unitptr quotient,
263
+ register unitptr dividend,register word16 divisor)
264
+ {
265
+ int bits;
266
+ short dprec;
267
+ register unit bitmask;
268
+ register word16 remainder;
269
+ if (!divisor)
270
+ return (N_NEG_VAL);
271
+ remainder=0;
272
+ mp_init(quotient,0);
273
+
274
+ {
275
+ dprec = significance(dividend);
276
+ if (!dprec) return(0);
277
+ bits = ((dprec) << 4);
278
+ (dividend) = ((dividend)+(dprec)-1);
279
+ bitmask = ((unit) 0x8000);
280
+ while (!(*(dividend) & bitmask))
281
+ {
282
+ bitmask >>= 1;
283
+ bits--;
284
+ }
285
+ };
286
+
287
+ (quotient) = ((quotient)+(dprec)-1);
288
+
289
+ while (bits--)
290
+ {
291
+ remainder <<= 1;
292
+ if ((*(dividend) & bitmask))
293
+ remainder++;
294
+ if (remainder >= divisor)
295
+ {
296
+ remainder -= divisor;
297
+ *(quotient) |= bitmask;
298
+ }
299
+ {
300
+ if (!(bitmask >>= 1))
301
+ {
302
+ bitmask = ((unit) 0x8000);
303
+ ((dividend)--);
304
+ ((quotient)--);
305
+ }
306
+ };
307
+ }
308
+ return(remainder);
309
+ }
310
+
311
+
312
+ int CRSALib::mp_mod(register unitptr remainder,
313
+ register unitptr dividend,register unitptr divisor)
314
+ {
315
+ int bits;
316
+ short dprec;
317
+ register unit bitmask;
318
+ if (( ((*(divisor))==(0)) && (significance(divisor)<=1) ))
319
+ return(-1);
320
+ mp_init(remainder,0);
321
+
322
+ { dprec = significance(dividend);
323
+ if (!dprec) return(0);
324
+ bits = ((dprec) << 4);
325
+ (dividend) = ((dividend)+(dprec)-1);
326
+ bitmask = ((unit) 0x8000);
327
+ while (!(*(dividend) & bitmask))
328
+ {
329
+ bitmask >>= 1;
330
+ bits--;
331
+ }
332
+ };
333
+
334
+ while (bits--)
335
+ {
336
+ mp_rotate_left(remainder,(boolean)((*(dividend) & bitmask)!=0));
337
+ if (mp_compare(remainder,divisor) >= 0)
338
+ mp_subb(remainder,divisor,(boolean)0);
339
+ {
340
+ if (!(bitmask >>= 1))
341
+ {
342
+ bitmask = ((unit) 0x8000);
343
+ ((dividend)--);
344
+ }
345
+ };
346
+ }
347
+ return(0);
348
+ }
349
+
350
+
351
+ word16 CRSALib::mp_shortmod(register unitptr dividend,register word16 divisor)
352
+ {
353
+ int bits;
354
+ short dprec;
355
+ register unit bitmask;
356
+ register word16 remainder;
357
+ if (!divisor)
358
+ return(N_NEG_VAL);
359
+ remainder=0;
360
+
361
+ {
362
+ dprec = significance(dividend);
363
+ if (!dprec) return(0);
364
+ bits = ((dprec) << 4);
365
+ (dividend) = ((dividend)+(dprec)-1);
366
+ bitmask = ((unit) 0x8000);
367
+ while (!(*(dividend) & bitmask))
368
+ {
369
+ bitmask >>= 1;
370
+ bits--;
371
+ }
372
+ };
373
+
374
+ while (bits--)
375
+ {
376
+ remainder <<= 1;
377
+ if ((*(dividend) & bitmask))
378
+ remainder++;
379
+ if (remainder >= divisor) remainder -= divisor;
380
+ {
381
+ if (!(bitmask >>= 1))
382
+ {
383
+ bitmask = ((unit) 0x8000); ((dividend)--);
384
+ }
385
+ };
386
+ }
387
+ return(remainder);
388
+ }
389
+
390
+ int CRSALib::mp_mult(register unitptr prod,
391
+ register unitptr multiplicand,register unitptr multiplier)
392
+ {
393
+ int bits;
394
+ register unit bitmask;
395
+ short mprec;
396
+ mp_init(prod,0);
397
+ if (( ((*(multiplicand))==(0)) && (significance(multiplicand)<=1) ))
398
+ return(0);
399
+
400
+ mprec = significance(multiplier);
401
+ if (!mprec) return(0);
402
+ bits = ((mprec) << 4);
403
+ (multiplier) = ((multiplier)+(mprec)-1);
404
+ bitmask = ((unit) 0x8000);
405
+ while (!(*(multiplier) & bitmask))
406
+ {
407
+ bitmask >>= 1;
408
+ bits--;
409
+ }
410
+
411
+ while (bits--)
412
+ {
413
+ mp_rotate_left(prod,(boolean)0);
414
+ if ((*(multiplier) & bitmask))
415
+ {
416
+ mp_addc(prod,multiplicand,(boolean)0);
417
+ }
418
+ if (!(bitmask >>= 1))
419
+ {
420
+ bitmask = ((unit) 0x8000);
421
+ ((multiplier)--);
422
+ }
423
+ }
424
+ return(0);
425
+ }
426
+
427
+ void CRSALib::mp_lshift_unit(register unitptr r1)
428
+ {
429
+ register short precision;
430
+ register unitptr r2;
431
+ precision = global_precision;
432
+ (r1) = ((r1)+(precision)-1);
433
+ r2 = r1;
434
+ while (--precision)
435
+ *((r1)--) = *(--(r2));
436
+ *r1 = 0;
437
+ }
438
+
439
+ void CRSALib::stage_mp_images(unitptr images[16],unitptr r)
440
+ {
441
+ short int i;
442
+ images[0] = r;
443
+ for (i=1; i<16; i++)
444
+ {
445
+ mp_move(images[i],images[i-1]);
446
+ mp_rotate_left(images[i],(boolean)0);
447
+ }
448
+ }
449
+ int CRSALib::stage_merritt_modulus(unitptr n)
450
+ {
451
+ short int i;
452
+ unitptr msu;
453
+ moduli[0] = n;
454
+
455
+
456
+ msu = ((n)+(global_precision)-1);
457
+ msu_moduli[0] = *((msu)--);
458
+ nmsu_moduli[0] = *msu;
459
+
460
+ for (i=1; i<16+1; i++)
461
+ {
462
+ mp_move(moduli[i],moduli[i-1]);
463
+ mp_rotate_left(moduli[i],(boolean)0);
464
+
465
+ msu = ((moduli[i])+(global_precision)-1);
466
+ msu_moduli[i] = *((msu)--);
467
+ nmsu_moduli[i] = *msu;
468
+ }
469
+ return(0);
470
+ }
471
+
472
+ int CRSALib::merritt_modmult(register unitptr prod,
473
+ unitptr multiplicand,register unitptr multiplier)
474
+ {
475
+
476
+ register signedunit p_m;
477
+ register unitptr msu_prod;
478
+ register unitptr nmsu_prod;
479
+ short mprec;
480
+
481
+
482
+ stage_mp_images(mpd,multiplicand);
483
+
484
+ msu_prod = ((prod)+(global_precision)-1);
485
+ nmsu_prod = msu_prod;
486
+ ((nmsu_prod)--);
487
+
488
+ mp_init(prod,0);
489
+
490
+ mprec = significance(multiplier);
491
+ if (mprec==0)
492
+ return(0);
493
+ (multiplier) = ((multiplier)+(mprec)-1);
494
+
495
+ while (mprec--)
496
+ {
497
+ mp_lshift_unit(prod);
498
+ if (*multiplier & ((unit) 1 << (15))) mp_addc(prod,mpd[15],(boolean)0);
499
+ if (*multiplier & ((unit) 1 << (14))) mp_addc(prod,mpd[14],(boolean)0);
500
+ if (*multiplier & ((unit) 1 << (13))) mp_addc(prod,mpd[13],(boolean)0);
501
+ if (*multiplier & ((unit) 1 << (12))) mp_addc(prod,mpd[12],(boolean)0);
502
+ if (*multiplier & ((unit) 1 << (11))) mp_addc(prod,mpd[11],(boolean)0);
503
+ if (*multiplier & ((unit) 1 << (10))) mp_addc(prod,mpd[10],(boolean)0);
504
+ if (*multiplier & ((unit) 1 << (9))) mp_addc(prod,mpd[9],(boolean)0);
505
+ if (*multiplier & ((unit) 1 << (8))) mp_addc(prod,mpd[8],(boolean)0);
506
+
507
+ if (*multiplier & ((unit) 1 << (7))) mp_addc(prod,mpd[7],(boolean)0);
508
+ if (*multiplier & ((unit) 1 << (6))) mp_addc(prod,mpd[6],(boolean)0);
509
+ if (*multiplier & ((unit) 1 << (5))) mp_addc(prod,mpd[5],(boolean)0);
510
+ if (*multiplier & ((unit) 1 << (4))) mp_addc(prod,mpd[4],(boolean)0);
511
+ if (*multiplier & ((unit) 1 << (3))) mp_addc(prod,mpd[3],(boolean)0);
512
+ if (*multiplier & ((unit) 1 << (2))) mp_addc(prod,mpd[2],(boolean)0);
513
+ if (*multiplier & ((unit) 1 << (1))) mp_addc(prod,mpd[1],(boolean)0);
514
+ if (*multiplier & ((unit) 1 << (0))) mp_addc(prod,mpd[0],(boolean)0);
515
+
516
+ if (((p_m = *msu_prod-msu_moduli[16])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[16]) || ( (*nmsu_prod==nmsu_moduli[16]) && ((mp_compare(prod,moduli[16]) >= 0)) ))) ) mp_subb(prod,moduli[16],(boolean)0);
517
+ if (((p_m = *msu_prod-msu_moduli[15])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[15]) || ( (*nmsu_prod==nmsu_moduli[15]) && ((mp_compare(prod,moduli[15]) >= 0)) ))) ) mp_subb(prod,moduli[15],(boolean)0);
518
+ if (((p_m = *msu_prod-msu_moduli[14])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[14]) || ( (*nmsu_prod==nmsu_moduli[14]) && ((mp_compare(prod,moduli[14]) >= 0)) ))) ) mp_subb(prod,moduli[14],(boolean)0);
519
+ if (((p_m = *msu_prod-msu_moduli[13])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[13]) || ( (*nmsu_prod==nmsu_moduli[13]) && ((mp_compare(prod,moduli[13]) >= 0)) ))) ) mp_subb(prod,moduli[13],(boolean)0);
520
+ if (((p_m = *msu_prod-msu_moduli[12])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[12]) || ( (*nmsu_prod==nmsu_moduli[12]) && ((mp_compare(prod,moduli[12]) >= 0)) ))) ) mp_subb(prod,moduli[12],(boolean)0);
521
+ if (((p_m = *msu_prod-msu_moduli[11])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[11]) || ( (*nmsu_prod==nmsu_moduli[11]) && ((mp_compare(prod,moduli[11]) >= 0)) ))) ) mp_subb(prod,moduli[11],(boolean)0);
522
+ if (((p_m = *msu_prod-msu_moduli[10])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[10]) || ( (*nmsu_prod==nmsu_moduli[10]) && ((mp_compare(prod,moduli[10]) >= 0)) ))) ) mp_subb(prod,moduli[10],(boolean)0);
523
+ if (((p_m = *msu_prod-msu_moduli[9])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[9]) || ( (*nmsu_prod==nmsu_moduli[9]) && ((mp_compare(prod,moduli[9]) >= 0)) ))) ) mp_subb(prod,moduli[9],(boolean)0);
524
+
525
+ if (((p_m = *msu_prod-msu_moduli[8])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[8]) || ( (*nmsu_prod==nmsu_moduli[8]) && ((mp_compare(prod,moduli[8]) >= 0)) ))) ) mp_subb(prod,moduli[8],(boolean)0);
526
+ if (((p_m = *msu_prod-msu_moduli[7])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[7]) || ( (*nmsu_prod==nmsu_moduli[7]) && ((mp_compare(prod,moduli[7]) >= 0)) ))) ) mp_subb(prod,moduli[7],(boolean)0);
527
+ if (((p_m = *msu_prod-msu_moduli[6])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[6]) || ( (*nmsu_prod==nmsu_moduli[6]) && ((mp_compare(prod,moduli[6]) >= 0)) ))) ) mp_subb(prod,moduli[6],(boolean)0);
528
+ if (((p_m = *msu_prod-msu_moduli[5])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[5]) || ( (*nmsu_prod==nmsu_moduli[5]) && ((mp_compare(prod,moduli[5]) >= 0)) ))) ) mp_subb(prod,moduli[5],(boolean)0);
529
+ if (((p_m = *msu_prod-msu_moduli[4])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[4]) || ( (*nmsu_prod==nmsu_moduli[4]) && ((mp_compare(prod,moduli[4]) >= 0)) ))) ) mp_subb(prod,moduli[4],(boolean)0);
530
+ if (((p_m = *msu_prod-msu_moduli[3])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[3]) || ( (*nmsu_prod==nmsu_moduli[3]) && ((mp_compare(prod,moduli[3]) >= 0)) ))) ) mp_subb(prod,moduli[3],(boolean)0);
531
+ if (((p_m = *msu_prod-msu_moduli[2])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[2]) || ( (*nmsu_prod==nmsu_moduli[2]) && ((mp_compare(prod,moduli[2]) >= 0)) ))) ) mp_subb(prod,moduli[2],(boolean)0);
532
+ if (((p_m = *msu_prod-msu_moduli[1])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[1]) || ( (*nmsu_prod==nmsu_moduli[1]) && ((mp_compare(prod,moduli[1]) >= 0)) ))) ) mp_subb(prod,moduli[1],(boolean)0);
533
+ if (((p_m = *msu_prod-msu_moduli[0])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[0]) || ( (*nmsu_prod==nmsu_moduli[0]) && ((mp_compare(prod,moduli[0]) >= 0)) ))) ) mp_subb(prod,moduli[0],(boolean)0);
534
+
535
+ ((multiplier)--);
536
+ }
537
+ return(0);
538
+ }
539
+
540
+ void CRSALib::merritt_burn(void)
541
+
542
+ {
543
+ unitfill0(&(mpdbuf[0][0]),(16-1)*(MAX_UNIT_PRECISION));
544
+ unitfill0(&(moduli_buf[0][0]),(16)*(MAX_UNIT_PRECISION));
545
+ unitfill0(msu_moduli,16+1);
546
+ unitfill0(nmsu_moduli,16+1);
547
+ }
548
+
549
+
550
+ int CRSALib::countbits(unitptr r)
551
+ {
552
+ int bits;
553
+ short prec;
554
+ register unit bitmask;
555
+ {
556
+ prec = significance(r);
557
+ if (!prec) return(0);
558
+ bits = ((prec) << 4);
559
+ (r) = ((r)+(prec)-1);
560
+ bitmask = ((unit) 0x8000);
561
+ while (!(*(r) & bitmask))
562
+ {
563
+ bitmask >>= 1; bits--;
564
+ }
565
+ };
566
+ return(bits);
567
+ }
568
+
569
+
570
+ int CRSALib::mp_modexp(register unitptr expout,register unitptr expin,
571
+ register unitptr exponent,register unitptr modulus)
572
+ {
573
+ int bits;
574
+ short oldprecision;
575
+ register unit bitmask;
576
+ unit product[(MAX_UNIT_PRECISION)];
577
+ short eprec;
578
+
579
+ mp_init(expout,1);
580
+ if (( ((*(exponent))==(0)) && (significance(exponent)<=1) ))
581
+ {
582
+ if (( ((*(expin))==(0)) && (significance(expin)<=1) ))
583
+ return(-1);
584
+ return(0);
585
+ }
586
+ if (( ((*(modulus))==(0)) && (significance(modulus)<=1) ))
587
+ return(-2);
588
+
589
+ if (((signedunit) (*((modulus)+(global_precision)-1)) < 0))
590
+ return(-2);
591
+
592
+ if (mp_compare(expin,modulus) >= 0)
593
+ return(-3);
594
+ if (mp_compare(exponent,modulus) >= 0)
595
+ return(-4);
596
+
597
+ oldprecision = global_precision;
598
+
599
+ (global_precision = ((((countbits(modulus)+(16+1))+15) >> 4)));
600
+
601
+
602
+ if (stage_merritt_modulus(modulus))
603
+ {
604
+ (global_precision = (oldprecision));
605
+ return(-5);
606
+ }
607
+ {
608
+ eprec = significance(exponent);
609
+ if (!eprec) return(0);
610
+ bits = ((eprec) << 4);
611
+ (exponent) = ((exponent)+(eprec)-1);
612
+ bitmask = ((unit) 0x8000);
613
+ while (!(*(exponent) & bitmask))
614
+ {
615
+ bitmask >>= 1;
616
+ bits--;
617
+ }
618
+ };
619
+
620
+ bits--;
621
+ mp_move(expout,expin);
622
+ { if (!(bitmask >>= 1)) { bitmask = ((unit) 0x8000); ((exponent)--); } };
623
+
624
+ while (bits--)
625
+ {
626
+ merritt_modmult(product,expout,expout);
627
+ mp_move(expout,product);
628
+ if ((*(exponent) & bitmask))
629
+ {
630
+ merritt_modmult(product,expout,expin);
631
+ mp_move(expout,product);
632
+ }
633
+ if (!(bitmask >>= 1))
634
+ {
635
+ bitmask = ((unit) 0x8000);
636
+ ((exponent)--);
637
+ }
638
+ }
639
+ mp_init(product,0);
640
+ merritt_burn();
641
+
642
+ (global_precision = (oldprecision));
643
+ return(0);
644
+ }
645
+
646
+ int CRSALib::rsa_decrypt(unitptr M, unitptr C,
647
+ unitptr d, unitptr p, unitptr q, unitptr u)
648
+ {
649
+ unit p2[(MAX_UNIT_PRECISION)];
650
+ unit q2[(MAX_UNIT_PRECISION)];
651
+ unit temp1[(MAX_UNIT_PRECISION)];
652
+ unit temp2[(MAX_UNIT_PRECISION)];
653
+ int status;
654
+
655
+ mp_init(M,1);
656
+
657
+ if (mp_compare(p,q) >= 0)
658
+ {
659
+ unitptr t;
660
+ t = p; p = q; q = t;
661
+ }
662
+
663
+ mp_move(temp1,p);
664
+ mp_dec(temp1);
665
+ mp_mod(temp2,d,temp1);
666
+ mp_mod(temp1,C,p);
667
+ status = mp_modexp(p2,temp1,temp2,p);
668
+ if (status < 0)
669
+ return(status);
670
+
671
+ mp_move(temp1,q);
672
+ mp_dec(temp1);
673
+ mp_mod(temp2,d,temp1);
674
+ mp_mod(temp1,C,q);
675
+ status = mp_modexp(q2,temp1,temp2,q);
676
+ if (status < 0)
677
+ return(status);
678
+
679
+ if (mp_compare(p2,q2) == 0)
680
+ mp_move(M,p2);
681
+ else
682
+ {
683
+ if (mp_subb(q2,p2,(boolean)0))
684
+ mp_addc(q2,q,(boolean)0);
685
+
686
+ mp_mult(temp1,q2,u);
687
+ mp_mod(temp2,temp1,q);
688
+ mp_mult(temp1,p,temp2);
689
+ mp_addc(temp1,p2,(boolean)0);
690
+ mp_move(M,temp1);
691
+ }
692
+
693
+ mp_init(p2,0);
694
+ mp_init(q2,0);
695
+ mp_init(temp1,0);
696
+ mp_init(temp2,0);
697
+
698
+ return(0);
699
+ }
700
+
701
+ int CRSALib::mp_sqrt(unitptr quotient,unitptr dividend)
702
+ {
703
+ register char next2bits;
704
+ register unit dvdbitmask,qbitmask;
705
+ unit remainder[(MAX_UNIT_PRECISION)],rjq[(MAX_UNIT_PRECISION)],
706
+ divisor[(MAX_UNIT_PRECISION)];
707
+ unsigned int qbits,qprec,dvdbits,dprec,oldprecision;
708
+ int notperfect;
709
+
710
+ mp_init(quotient,0);
711
+ if (((signedunit) (*((dividend)+(global_precision)-1)) < 0))
712
+ {
713
+ mp_dec(quotient);
714
+ return(-1);
715
+ }
716
+
717
+ {
718
+ dprec = significance(dividend);
719
+ if (!dprec) return(0);
720
+ dvdbits = ((dprec) << 4);
721
+ (dividend) = ((dividend)+(dprec)-1);
722
+ dvdbitmask = ((unit) 0x8000);
723
+ while (!(*(dividend) & dvdbitmask))
724
+ {
725
+ dvdbitmask >>= 1;
726
+ dvdbits--;
727
+ }
728
+ };
729
+
730
+ if (dvdbits==1)
731
+ {
732
+ mp_init(quotient,1);
733
+ return(0);
734
+ }
735
+
736
+
737
+ qbits = (dvdbits+1) >> 1;
738
+ qprec = (((qbits)+15) >> 4);
739
+
740
+ (quotient) = ((quotient)+(qprec)-1);
741
+ qbitmask = ((unit) 1 << ((qbits-1) & (16-1))) ;
742
+
743
+ oldprecision = global_precision;
744
+ (global_precision = ((((qbits+3)+15) >> 4)));
745
+
746
+ *(quotient) |= qbitmask;
747
+ {
748
+ if (!(qbitmask >>= 1))
749
+ {
750
+ qbitmask = ((unit) 0x8000);
751
+ ((quotient)--);
752
+ }
753
+ };
754
+
755
+ mp_init(rjq,1);
756
+
757
+ if (!(dvdbits & 1))
758
+ {
759
+ next2bits = 2;
760
+ {
761
+ if (!(dvdbitmask >>= 1))
762
+ {
763
+ dvdbitmask = ((unit) 0x8000);
764
+ ((dividend)--);
765
+ }
766
+ };
767
+ dvdbits--;
768
+ if ((*(dividend) & dvdbitmask))
769
+ next2bits++;
770
+ {
771
+ if (!(dvdbitmask >>= 1))
772
+ {
773
+ dvdbitmask = ((unit) 0x8000);
774
+ ((dividend)--);
775
+ }
776
+ };
777
+ dvdbits--;
778
+ }
779
+ else
780
+ {
781
+ next2bits = 1;
782
+ {
783
+ if (!(dvdbitmask >>= 1))
784
+ {
785
+ dvdbitmask = ((unit) 0x8000);
786
+ ((dividend)--);
787
+ }
788
+ };
789
+ dvdbits--;
790
+ }
791
+
792
+ mp_init(remainder,next2bits-1);
793
+
794
+ while (dvdbits)
795
+ {
796
+ next2bits=0;
797
+ if ((*(dividend) & dvdbitmask)) next2bits=2;
798
+ {
799
+ if (!(dvdbitmask >>= 1))
800
+ {
801
+ dvdbitmask = ((unit) 0x8000);
802
+ ((dividend)--);
803
+ }
804
+ };
805
+ dvdbits--;
806
+ if ((*(dividend) & dvdbitmask))
807
+ next2bits++;
808
+ if (!(dvdbitmask >>= 1))
809
+ {
810
+ dvdbitmask = ((unit) 0x8000);
811
+ ((dividend)--);
812
+ }
813
+ dvdbits--;
814
+ mp_rotate_left(remainder,(boolean)((next2bits&2)!=0));
815
+ mp_rotate_left(remainder,(boolean)((next2bits&1)!=0));
816
+
817
+ mp_move(divisor,rjq);
818
+ mp_rotate_left(divisor,0);
819
+ mp_rotate_left(divisor,1);
820
+ if (mp_compare(remainder,divisor) >= 0)
821
+ {
822
+ mp_subb(remainder,divisor,(boolean)0);
823
+ *(quotient) |= qbitmask;
824
+ mp_rotate_left(rjq,1);
825
+ }
826
+ else
827
+ mp_rotate_left(rjq,0);
828
+ if (!(qbitmask >>= 1))
829
+ {
830
+ qbitmask = ((unit) 0x8000);
831
+ ((quotient)--);
832
+ }
833
+ }
834
+ notperfect = ( ((*(remainder))!=(0)) || (significance(remainder)>1) );
835
+ (global_precision = (oldprecision));
836
+ return(notperfect);
837
+ }
838
+ //----