/[rdesktop]/sourceforge.net/trunk/rdesktop/crypto/arith.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /sourceforge.net/trunk/rdesktop/crypto/arith.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (show annotations)
Tue Aug 15 10:32:09 2000 UTC (23 years, 9 months ago) by matty
File MIME type: text/plain
File size: 11671 byte(s)
Crypto routines.

1 /*******************************************************************************
2 * *
3 * Copyright (c) Martin Nicolay, 22. Nov. 1988 *
4 * *
5 * Wenn diese (oder sinngemaess uebersetzte) Copyright-Angabe enthalten *
6 * bleibt, darf diese Source fuer jeden nichtkomerziellen Zweck weiter *
7 * verwendet werden. *
8 * *
9 * martin@trillian.megalon.de *
10 * *
11 *******************************************************************************/
12
13 #include "arith.h"
14
15 /*
16 * !!!!!!!!!!!!!!!!!!!!!!!!!!!! ACHTUNG !!!!!!!!!!!!!!!!!!!!!!!!!!!!
17 * Es findet keinerlei Ueberpruefung auf Bereichsueberschreitung
18 * statt. Alle Werte muessen natuerliche Zahlen aus dem Bereich
19 * 0 ... (MAXINT+1)^MAXLEN-1 sein.
20 *
21 *
22 * Bei keiner Funktion oder Hilsfunktion werden Annahmen getroffen,
23 * ueber die Verschiedenheit von Eingabe- & Ausgabe-Werten.
24 *
25 *
26 * Funktionen:
27 *
28 * a_add( s1, s2, d )
29 * NUMBER *s1,*s2,*d;
30 * *d = *s1 + *s2;
31 *
32 * a_assign( *d, *s )
33 * NUMBER *d,*s;
34 * *d = *s;
35 *
36 * int a_cmp( c1, c2 )
37 * NUMBER *c1,*c2;
38 * 1 : falls *c1 > *c2
39 * 0 : falls *c1 == *c2
40 * -1 : falls *c1 < *c2
41 *
42 * a_div( d1, d2, q, r )
43 * NUMBER *d1,*d2,*q,*r;
44 * *q = *d1 / *d2 Rest *r;
45 *
46 * a_div2( n )
47 * NUMBER *n;
48 * *n /= 2;
49 *
50 * a_ggt( a, b, f )
51 * NUMBER *a,*b,*f;
52 * *f = ( *a, *b );
53 *
54 * a_imult( n, m, d )
55 * NUMBER *n;
56 * INT m;
57 * NUMBER *d;
58 * *d = *n * m
59 *
60 * a_mult( m1, m2, d )
61 * NUMBER *m1,*m2,*d;
62 * *d = *m1 * *m2;
63 *
64 * a_sub( s1, s2, d )
65 * NUMBER *s1,*s2,*d;
66 * *d = *s1 - *s2;
67 *
68 * Modulare Funktionen
69 * m_init( n, o )
70 * NUMBER *n,*o;
71 * Initialsierung der Modularen Funktionen
72 * o != 0 : *o = alter Wert
73 *
74 * m_add( s1, s2, d )
75 * NUMBER *s1, *s2, *d;
76 * *d = *s1 + *s2;
77 *
78 * m_mult( m1, m2, d )
79 * NUMBER *m1,*m2,*d;
80 *
81 * m_exp( x, n, z )
82 * NUMBER *x,*n,*z;
83 * *z = *x exp *n;
84 *
85 *
86 * Hilfs-Funktionen:
87 *
88 * int n_bits( n, b )
89 * NUMBER *n;
90 * int b;
91 * return( unterste b Bits der Dualdarstellung von n)
92 *
93 * n_div( d1, z2, q, r )
94 * NUMBER *d1,z2[MAXBIT],*q,*r;
95 * *q = *d1 / z2[0] Rest *r;
96 * z2[i] = z2[0] * 2^i, i=0..MAXBIT-1
97 *
98 * int n_cmp( i1, i2, l )
99 * INT i1[l], i2[l];
100 * 1 : falls i1 > i2
101 * 0 : falls i1 == i2
102 * -1 : falls i1 < i2
103 *
104 * int n_mult( n, m, d, l)
105 * INT n[l], m, d[];
106 * d = m * n;
107 * return( sizeof(d) ); d.h. 'l' oder 'l+1'
108 *
109 * int n_sub( p1, p2, p3, l, lo )
110 * INT p1[l], p2[lo], p3[];
111 * p3 = p1 - p2;
112 * return( sizeof(p3) ); d.h. '<= min(l,lo)'
113 *
114 * int n_bitlen( n )
115 * NUMBER *n;
116 * return( sizeof(n) in bits )
117 *
118 */
119
120
121 /*
122 * Konstante 1, 2
123 */
124 NUMBER a_one = {
125 1,
126 { (INT)1, },
127 };
128
129 NUMBER a_two = {
130 #if MAXINT == 1
131 2,
132 { 0, (INT)1, },
133 #else
134 1,
135 { (INT)2, },
136 #endif
137 };
138
139
140 /*
141 * Vergleiche zwei INT arrays der Laenge l
142 */
143 int n_cmp( i1, i2, l )
144 INT *i1,*i2;
145 {
146 i1 += (l-1); /* Pointer ans Ende */
147 i2 += (l-1);
148
149 for (;l--;)
150 if ( *i1-- != *i2-- )
151 return( i1[1] > i2[1] ? 1 : -1 );
152
153 return(0);
154 }
155
156 /*
157 * Vergleiche zwei NUMBER
158 */
159 int a_cmp( c1, c2 )
160 NUMBER *c1,*c2;
161 {
162 int l;
163 /* bei verschiedener Laenge klar*/
164 if ( (l=c1->n_len) != c2->n_len)
165 return( l - c2->n_len);
166
167 /* vergleiche als arrays */
168 return( n_cmp( c1->n_part, c2->n_part, l) );
169 }
170
171 /*
172 * Zuweisung einer NUMBER (d = s)
173 */
174 void a_assign( d, s )
175 NUMBER *d,*s;
176 {
177 int l;
178
179 if (s == d) /* nichts zu kopieren */
180 return;
181
182 if ((l=s->n_len))
183 memcpy( d->n_part, s->n_part, sizeof(INT)*l);
184
185 d->n_len = l;
186 }
187
188 /*
189 * Addiere zwei NUMBER (d = s1 + s2)
190 */
191 void a_add( s1, s2, d )
192 NUMBER *s1,*s2,*d;
193 {
194 int l,lo,ld,same;
195 register LONG sum;
196 register INT *p1,*p2,*p3;
197 register INT b;
198
199 /* setze s1 auch die groessere Zahl */
200 l = s1->n_len;
201 if ( (l=s1->n_len) < s2->n_len ) {
202 NUMBER *tmp = s1;
203
204 s1 = s2;
205 s2 = tmp;
206
207 l = s1->n_len;
208 }
209
210 ld = l;
211 lo = s2->n_len;
212 p1 = s1->n_part;
213 p2 = s2->n_part;
214 p3 = d->n_part;
215 same = (s1 == d);
216 sum = 0;
217
218 while (l --) {
219 if (lo) { /* es ist noch was von s2 da */
220 lo--;
221 b = *p2++;
222 }
223 else
224 b = 0; /* ansonten 0 nehmen */
225
226 sum += (LONG)*p1++ + (LONG)b;
227 *p3++ = TOINT(sum);
228
229 if (sum > (LONG)MAXINT) { /* carry merken */
230 sum = 1;
231 }
232 else
233 sum = 0;
234
235 if (!lo && same && !sum) /* nichts mehr zu tuen */
236 break;
237 }
238
239 if (sum) { /* letztes carry beruecksichtigen */
240 ld++;
241 *p3 = sum;
242 }
243
244 d->n_len = ld; /* Laenge setzen */
245 }
246
247 /*
248 * Subtrahiere zwei INT arrays. return( Laenge Ergebniss )
249 * l == Laenge p1
250 * lo== Laenge p3
251 */
252 int n_sub( p1, p2, p3, l, lo )
253 INT *p1,*p2,*p3;
254 int l,lo;
255 {
256 int ld,lc,same;
257 int over = 0;
258 register LONG dif;
259 LONG a,b;
260
261 same = (p1 == p3); /* frueher Abbruch moeglich */
262
263 for (lc=1, ld=0; l--; lc++) {
264 a = (LONG)*p1++;
265 if (lo) { /* ist noch was von p2 da ? */
266 lo--;
267 b = (LONG)*p2++;
268 }
269 else
270 b=0; /* ansonten 0 nehmen */
271
272 if (over) /* frueherer Overflow */
273 b++;
274 if ( b > a ) { /* jetzt Overflow ? */
275 over = 1;
276 dif = (MAXINT +1) + a;
277 }
278 else {
279 over = 0;
280 dif = a;
281 }
282 dif -= b;
283 *p3++ = (INT)dif;
284
285 if (dif) /* Teil != 0 : Laenge neu */
286 ld = lc;
287 if (!lo && same && !over) { /* nichts mehr zu tuen */
288 if (l > 0) /* Laenge korrigieren */
289 ld = lc + l;
290 break;
291 }
292 }
293
294 return( ld );
295 }
296
297 /*
298 * Subtrahiere zwei NUMBER (d= s1 - s2)
299 */
300 void a_sub( s1, s2, d )
301 NUMBER *s1,*s2,*d;
302 {
303 d->n_len = n_sub( s1->n_part, s2->n_part, d->n_part
304 ,s1->n_len, s2->n_len );
305 }
306
307 /*
308 * Mulitipliziere INT array der Laenge l mit einer INT (d = n * m)
309 * return neue Laenge
310 */
311 int n_mult( n, m, d, l)
312 register INT *n;
313 register INT m;
314 INT *d;
315 {
316 int i;
317 register LONG mul;
318
319 for (i=l,mul=0; i; i--) {
320 mul += (LONG)m * (LONG)*n++;
321 *d++ = TOINT(mul);
322 mul = DIVMAX1( mul );
323 }
324
325 if (mul) { /* carry ? */
326 l++;
327 *d = mul;
328 }
329
330 return( l );
331 }
332
333 /*
334 * Mulitipliziere eine NUMBER mit einer INT (d = n * m)
335 */
336 void a_imult( n, m, d )
337 NUMBER *n;
338 INT m;
339 NUMBER *d;
340 {
341 if (m == 0)
342 d->n_len=0;
343 else if (m == 1)
344 a_assign( d, n );
345 else
346 d->n_len = n_mult( n->n_part, m, d->n_part, n->n_len );
347 }
348
349 /*
350 * Multipliziere zwei NUMBER (d = m1 * m2)
351 */
352 void a_mult( m1, m2, d )
353 NUMBER *m1,*m2,*d;
354 {
355 static INT id[ MAXLEN ]; /* Zwischenspeicher */
356 register INT *vp; /* Pointer darin */
357 register LONG sum; /* Summe fuer jede Stelle */
358 register LONG tp1; /* Zwischenspeicher fuer m1 */
359 register INT *p2;
360 INT *p1;
361 int l1,l2,ld,lc,l,i,j;
362
363 l1 = m1->n_len;
364 l2 = m2->n_len;
365 l = l1 + l2;
366 if (l >= MAXLEN)
367 abort();
368
369 for (i=l, vp=id; i--;)
370 *vp++ = 0;
371
372 /* ohne Uebertrag in Zwischenspeicher multiplizieren */
373 for ( p1 = m1->n_part, i=0; i < l1 ; i++, p1++ ) {
374
375 tp1 = (LONG)*p1;
376 vp = &id[i];
377 sum = 0;
378 for ( p2 = m2->n_part, j = l2; j--;) {
379 sum += (LONG)*vp + (tp1 * (LONG)*p2++);
380 *vp++ = TOINT( sum );
381 sum = DIVMAX1(sum);
382 }
383 *vp++ += (INT)sum;
384 }
385
386 /* jetzt alle Uebertraege beruecksichtigen */
387 ld = 0;
388 for (lc=0, vp=id, p1=d->n_part; lc++ < l;) {
389 if (( *p1++ = *vp++ ))
390 ld = lc;
391 }
392
393 d->n_len = ld;
394 }
395
396
397 /*
398 * Dividiere Zwei NUMBER mit Rest (q= d1 / z2[0] Rest r)
399 * z2[i] = z2[0] * 2^i, i=0..MAXBIT-1
400 * r = 0 : kein Rest
401 * q = 0 : kein Quotient
402 */
403 void n_div( d1, z2, q, r )
404 NUMBER *d1,*z2,*q,*r;
405 {
406 static NUMBER dummy_rest; /* Dummy Variable, falls r = 0 */
407 static NUMBER dummy_quot; /* Dummy Variable, falla q = 0 */
408 INT *i1,*i1e,*i3;
409 int l2,ld,l,lq;
410 #if MAXINT != 1
411 INT z;
412 int pw,l2t;
413 #endif
414
415 if (!z2->n_len)
416 abort();
417
418 if (!r)
419 r = &dummy_rest;
420 if (!q)
421 q = &dummy_quot;
422
423 a_assign( r, d1 ); /* Kopie von d1 in den Rest */
424
425 l2= z2->n_len; /* Laenge von z2[0] */
426 l = r->n_len - l2; /* Laenge des noch ''rechts'' liegenden
427 Stuecks von d1 */
428 lq= l +1; /* Laenge des Quotienten */
429 i3= q->n_part + l;
430 i1= r->n_part + l;
431 ld = l2; /* aktuelle Laenge des ''Vergleichsstuecks''
432 von d1 */
433 i1e= i1 + (ld-1);
434
435 for (; l >= 0; ld++, i1--, i1e--, l--, i3--) {
436 *i3 = 0;
437
438 if (ld == l2 && ! *i1e) {
439 ld--;
440 continue;
441 }
442
443 if ( ld > l2 || (ld == l2 && n_cmp( i1, z2->n_part, l2) >= 0 ) ) {
444 #if MAXINT != 1
445 /* nach 2er-Potenzen zerlegen */
446 for (pw=MAXBIT-1, z=(INT)HIGHBIT; pw >= 0; pw--, z /= 2) {
447 if ( ld > (l2t= z2[pw].n_len)
448 || (ld == l2t
449 && n_cmp( i1, z2[pw].n_part, ld) >= 0) ) {
450 ld = n_sub( i1, z2[pw].n_part, i1, ld, l2t );
451 (*i3) += z;
452 }
453 }
454 #else
455 /* bei MAXINT == 1 alles viel einfacher */
456 ld = n_sub( i1, z2->n_part, i1, ld, l2 );
457 (*i3) ++;
458 #endif
459 }
460 }
461
462 /* Korrektur, falls l von Anfang an Negativ war */
463 l ++;
464 lq -= l;
465 ld += l;
466
467 if (lq>0 && !q->n_part[lq -1]) /* evtl. Laenge korrigieren */
468 lq--;
469
470 q->n_len = lq;
471 r->n_len = ld -1;
472 }
473
474 /*
475 * Dividiere Zwei NUMBER mit Rest (q= d1 / z2[0] Rest r)
476 * z2[i] = z2[0] * 2^i, i=0..MAXBIT-1
477 * r = 0 : kein Rest
478 * q = 0 : kein Quotient
479 */
480 void a_div( d1, d2, q, r )
481 NUMBER *d1,*d2,*q,*r;
482 {
483 #if MAXINT != 1
484 NUMBER z2[MAXBIT];
485 INT z;
486 int i;
487
488 a_assign( &z2[0], d2 );
489 for (i=1,z=2; i < MAXBIT; i++, z *= 2)
490 a_imult( d2, z, &z2[i] );
491
492 d2 = z2;
493 #endif
494
495 n_div( d1, d2, q, r );
496 }
497
498 /*
499 * Dividiere eine NUMBER durch 2
500 */
501 void a_div2( n )
502 NUMBER *n;
503 {
504 #if MAXBIT == LOWBITS
505 register INT *p;
506 int i;
507
508 #if MAXINT != 1
509 register INT h;
510 register int c;
511
512 c=0;
513 i= n->n_len;
514 p= &n->n_part[i-1];
515
516 for (; i--;) {
517 if (c) {
518 c = (h= *p) & 1;
519 h /= 2;
520 h |= HIGHBIT;
521 }
522 else {
523 c = (h= *p) & 1;
524 h /= 2;
525 }
526
527 *p-- = h;
528 }
529
530 if ( (i= n->n_len) && n->n_part[i-1] == 0 )
531 n->n_len = i-1;
532
533 #else /* MAXBIT != 1 */
534 p = n->n_part;
535 i = n->n_len;
536
537 if (i) {
538 n->n_len = i-1;
539 for (; --i ; p++)
540 p[0] = p[1];
541 }
542 #endif /* MAXBIT != 1 */
543 #else /* MAXBIT == LOWBITS */
544 a_div( n, &a_two, n, NUM0P );
545 #endif /* MAXBIT == LOWBITS */
546 }
547
548
549 /*
550 * MODULO-FUNKTIONEN
551 */
552
553 static NUMBER mod_z2[ MAXBIT ];
554
555 /*
556 * Init
557 */
558 void m_init( n, o )
559 NUMBER *n,*o;
560 {
561 INT z;
562 int i;
563
564 if (o)
565 a_assign( o, &mod_z2[0] );
566
567 if (! a_cmp( n, &mod_z2[0] ) )
568 return;
569
570 for (i=0,z=1; i < MAXBIT; i++, z *= 2)
571 a_imult( n, z, &mod_z2[i] );
572 }
573
574 void m_add( s1, s2, d )
575 NUMBER *s1, *s2, *d;
576 {
577 a_add( s1, s2, d );
578 if (a_cmp( d, mod_z2 ) >= 0)
579 a_sub( d, mod_z2, d );
580 }
581
582 void m_mult( m1, m2, d )
583 NUMBER *m1,*m2,*d;
584 {
585 a_mult( m1, m2, d );
586 n_div( d, mod_z2, NUM0P, d );
587 }
588
589 /*
590 * Restklassen Exponent
591 */
592 void m_exp( x, n, z )
593 NUMBER *x,*n,*z;
594 {
595 NUMBER xt,nt;
596
597 a_assign( &nt, n );
598 a_assign( &xt, x );
599 a_assign( z, &a_one );
600
601 while (nt.n_len) {
602 while ( ! (nt.n_part[0] & 1) ) {
603 m_mult( &xt, &xt, &xt );
604 a_div2( &nt );
605 }
606 m_mult( &xt, z, z );
607 a_sub( &nt, &a_one, &nt );
608 }
609 }
610
611 /*
612 * GGT
613 */
614 void a_ggt( a, b, f )
615 NUMBER *a,*b,*f;
616 {
617 NUMBER t[2];
618 int at,bt, tmp;
619
620 a_assign( &t[0], a ); at= 0;
621 a_assign( &t[1], b ); bt= 1;
622
623 if ( a_cmp( &t[at], &t[bt] ) < 0 ) {
624 tmp= at; at= bt; bt= tmp;
625 }
626 /* euklidischer Algorithmus */
627 while ( t[bt].n_len ) {
628 a_div( &t[at], &t[bt], NUM0P, &t[at] );
629 tmp= at; at= bt; bt= tmp;
630 }
631
632 a_assign( f, &t[at] );
633 }
634
635 /*
636 * die untersten b bits der Dualdarstellung von n
637 * die bits muessen in ein int passen
638 */
639 int n_bits(n,b)
640 NUMBER *n;
641 {
642 INT *p;
643 int l;
644 unsigned r;
645 int m = (1<<b) -1;
646
647 if ( n->n_len == 0)
648 return(0);
649
650 if (LOWBITS >= b)
651 return( n->n_part[0] & m );
652
653 #if LOWBITS != 0
654 l = (b-1) / LOWBITS;
655 #else
656 l = n->n_len -1;
657 #endif
658 for (p= &n->n_part[l],r=0; l-- >= 0 && b > 0; b-= LOWBITS, p--) {
659 r = MULMAX1( r );
660 r += (unsigned)*p;
661 }
662
663 return( r & m );
664 }
665
666 /*
667 * Anzahl der bits von n bei Dualdarstellung
668 */
669 int n_bitlen( n )
670 NUMBER *n;
671 {
672 NUMBER b;
673 int i;
674
675 a_assign( &b, &a_one );
676
677 for (i=0; a_cmp( &b, n ) <= 0; a_mult( &b, &a_two, &b ), i++)
678 ;
679
680 return(i);
681 }

  ViewVC Help
Powered by ViewVC 1.1.26