rsaaux.cxx

Go to the documentation of this file.
00001 /* @(#)root/auth:$Id: rsaaux.cxx 36147 2010-10-07 11:03:25Z ganis $ */
00002 /* Author: Martin Nicolay  22/11/1988 */
00003 
00004 /******************************************************************************
00005 Copyright (C) 2006 Martin Nicolay <m.nicolay@osm-gmbh.de>
00006 
00007 This library is free software; you can redistribute it and/or
00008 modify it under the terms of the GNU Lesser General Public
00009 License as published by the Free Software Foundation; either
00010 version 2.1 of the License, or (at your option) any later
00011 version.
00012 
00013 This library is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 GNU Lesser General Public License for more details.
00017 
00018 You should have received a copy of the GNU Lesser General Public
00019 License along with this library; if not, write to the Free
00020 Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
00021 MA  02110-1301  USA
00022 ******************************************************************************/
00023 
00024 /*******************************************************************************
00025 *                                                                                                                      *
00026 *       Simple RSA public key code.                                            *
00027 *       Adaptation in library for ROOT by G. Ganis, July 2003                  *
00028 *       (gerardo.ganis@cern.ch)                                                *
00029 *                                                                                                                           *
00030 *******************************************************************************/
00031 
00032 #include <stdio.h>
00033 #include <ctype.h>
00034 #include <string.h>
00035 #include <stdlib.h>
00036 #include <time.h>
00037 #include <sys/types.h>
00038 #include <sys/stat.h>
00039 #include <fcntl.h>
00040 
00041 #ifdef WIN32
00042 #  include <io.h>
00043 typedef long off_t;
00044 #else
00045 #  include <unistd.h>
00046 #  include <sys/time.h>
00047 #endif
00048 
00049 #include "rsaaux.h"
00050 #include "rsalib.h"
00051 
00052 /********************************************************************************
00053  *                                                                                                                      *
00054  * arith.c                                                                      *
00055  *                                                                              *
00056  ********************************************************************************/
00057 
00058 /*
00059  *      !!!!!!!!!!!!!!!!!!!!!!!!!!!! ACHTUNG !!!!!!!!!!!!!!!!!!!!!!!!!!!!
00060  *      Es findet keinerlei Ueberpruefung auf Bereichsueberschreitung
00061  *      statt. Alle Werte muessen natuerliche Zahlen aus dem Bereich
00062  *              0 ... (rsa_MAXINT+1)^rsa_MAXLEN-1 sein.
00063  *
00064  *
00065  *      Bei keiner Funktion oder Hilsfunktion werden Annahmen getroffen,
00066  *      ueber die Verschiedenheit von Eingabe- & Ausgabe-Werten.
00067  *
00068  *
00069  *              Funktionen:
00070  *
00071  *      a_add( s1, s2, d )
00072  *              rsa_NUMBER *s1,*s2,*d;
00073  *                      *d = *s1 + *s2;
00074  *
00075  *      a_assign( *d, *s )
00076  *              rsa_NUMBER *d,*s;
00077  *                      *d = *s;
00078  *
00079  * int  a_cmp( c1, c2 )
00080  *              rsa_NUMBER *c1,*c2;
00081  *                       1 :    falls *c1 >  *c2
00082  *                       0 :    falls *c1 == *c2
00083  *                      -1 :    falls *c1 <  *c2
00084  *
00085  *      a_div( d1, d2, q, r )
00086  *              rsa_NUMBER *d1,*d2,*q,*r;
00087  *                      *q = *d1 / *d2 Rest *r;
00088  *
00089  *      a_div2( n )
00090  *              rsa_NUMBER *n;
00091  *                      *n /= 2;
00092  *
00093  *      a_ggt( a, b, f )
00094  *              rsa_NUMBER *a,*b,*f;
00095  *                      *f = ( *a, *b );
00096  *
00097  *      a_imult( n, m, d )
00098  *              rsa_NUMBER *n;
00099  *              rsa_INT m;
00100  *              rsa_NUMBER *d;
00101  *                      *d = *n * m
00102  *
00103  *      a_mult( m1, m2, d )
00104  *              rsa_NUMBER *m1,*m2,*d;
00105  *                      *d = *m1 * *m2;
00106  *
00107  *      a_sub( s1, s2, d )
00108  *              rsa_NUMBER *s1,*s2,*d;
00109  *                      *d = *s1 - *s2;
00110  *
00111  *              Modulare Funktionen
00112  *      m_init( n, o )
00113  *              rsa_NUMBER *n,*o;
00114  *                      Initialsierung der Modularen Funktionen
00115  *                      o != 0 : *o = alter Wert
00116  *
00117  *      m_add( s1, s2, d )
00118  *              rsa_NUMBER *s1, *s2, *d;
00119  *                      *d = *s1 + *s2;
00120  *
00121  *      m_mult( m1, m2, d )
00122  *              rsa_NUMBER *m1,*m2,*d;
00123  *
00124  *      m_exp( x, n, z )
00125  *              rsa_NUMBER *x,*n,*z;
00126  *                      *z = *x exp *n;
00127  *
00128  *
00129  *              Hilfs-Funktionen:
00130  *
00131  * int  n_bits( n, b )
00132  *              rsa_NUMBER *n;
00133  *              int b;
00134  *                      return( unterste b Bits der Dualdarstellung von n)
00135  *
00136  *      n_div( d1, z2, q, r )
00137  *              rsa_NUMBER *d1,z2[rsa_MAXBIT],*q,*r;
00138  *                      *q = *d1 / z2[0] Rest *r;
00139  *                      z2[i] = z2[0] * 2^i,  i=0..rsa_MAXBIT-1
00140  *
00141  * int  n_cmp( i1, i2, l )
00142  *              rsa_INT i1[l], i2[l];
00143  *                       1 :    falls i1 >  i2
00144  *                       0 :    falls i1 == i2
00145  *                      -1 :    falls i1 <  i2
00146  *
00147  * int  n_mult( n, m, d, l)
00148  *              rsa_INT n[l], m, d[];
00149  *                      d = m * n;
00150  *                      return( sizeof(d) ); d.h. 'l' oder 'l+1'
00151  *
00152  * int  n_sub( p1, p2, p3, l, lo )
00153  *              rsa_INT p1[l], p2[lo], p3[];
00154  *                      p3 = p1 - p2;
00155  *                      return( sizeof(p3) ); d.h. '<= min(l,lo)'
00156  *
00157  * int  n_bitlen( n )
00158  *              rsa_NUMBER *n;
00159  *                      return( sizeof(n) in bits )
00160  *
00161  */
00162 
00163 
00164 //______________________________________________________________________________
00165 static int aux_rand()
00166 {
00167    // rand() implementation using /udev/random or /dev/random, if available
00168 
00169 #ifndef WIN32
00170    int frnd = open("/dev/urandom", O_RDONLY);
00171    if (frnd < 0) frnd = open("/dev/random", O_RDONLY);
00172    int r;
00173    if (frnd >= 0) {
00174       ssize_t rs = read(frnd, (void *) &r, sizeof(int));
00175       close(frnd);
00176       if (r < 0) r = -r;
00177       if (rs == sizeof(int)) return r;
00178    }
00179    printf("+++ERROR+++ : aux_rand: neither /dev/urandom nor /dev/random are available or readable!\n");
00180    struct timeval tv;
00181    if (gettimeofday(&tv,0) == 0) {
00182       int t1, t2;
00183       memcpy((void *)&t1, (void *)&tv.tv_sec, sizeof(int));
00184       memcpy((void *)&t2, (void *)&tv.tv_usec, sizeof(int));
00185       r = t1 + t2;
00186       if (r < 0) r = -r;
00187       return r;
00188    }
00189    return -1;
00190 #else
00191    // No special random device available: use rand()
00192    return rand();
00193 #endif
00194 }
00195 
00196 /*
00197  * Konstante 1, 2
00198  */
00199 rsa_NUMBER a_one = {
00200    1,
00201    { (rsa_INT)1, },
00202 };
00203 
00204 rsa_NUMBER a_two = {
00205 #if rsa_MAXINT == 1
00206    2,
00207    { 0, (rsa_INT)1, },
00208 #else
00209    1,
00210    { (rsa_INT)2, },
00211 #endif
00212 };
00213 
00214 
00215 /*
00216  * Vergleiche zwei rsa_INT arrays der Laenge l
00217  */
00218 int n_cmp(rsa_INT *i1, rsa_INT *i2, int l)
00219 {
00220    i1 += (l-1);                 /* Pointer ans Ende             */
00221    i2 += (l-1);
00222 
00223    for (;l--;)
00224       if ( *i1-- != *i2-- )
00225          return( i1[1] > i2[1] ? 1 : -1 );
00226 
00227    return(0);
00228 }
00229 
00230 /*
00231  * Vergleiche zwei rsa_NUMBER
00232  */
00233 int a_cmp(rsa_NUMBER *c1, rsa_NUMBER *c2)
00234 {
00235    int l;
00236    /* bei verschiedener Laenge klar*/
00237    if ( (l=c1->n_len) != c2->n_len)
00238       return( l - c2->n_len);
00239 
00240    /* vergleiche als arrays     */
00241    return( n_cmp( c1->n_part, c2->n_part, l) );
00242 }
00243 
00244 /*
00245  * Zuweisung einer rsa_NUMBER (d = s)
00246  */
00247 void a_assign(rsa_NUMBER *d, rsa_NUMBER *s)
00248 {
00249    int l;
00250 
00251    if (s == d)                  /* nichts zu kopieren           */
00252       return;
00253 
00254    if ((l=s->n_len))
00255       memcpy( d->n_part, s->n_part, sizeof(rsa_INT)*l);
00256 
00257    d->n_len = l;
00258 }
00259 
00260 /*
00261  * Addiere zwei rsa_NUMBER (d = s1 + s2)
00262  */
00263 void a_add(rsa_NUMBER *s1, rsa_NUMBER *s2, rsa_NUMBER *d)
00264 {
00265    int l,lo,ld,same;
00266    register rsa_LONG sum;
00267    register rsa_INT *p1,*p2,*p3;
00268    register rsa_INT b;
00269 
00270    /* setze s1 auch die groessere Zahl  */
00271    l = s1->n_len;
00272    if ( (l=s1->n_len) < s2->n_len) {
00273       rsa_NUMBER *tmp = s1;
00274 
00275       s1 = s2;
00276       s2 = tmp;
00277 
00278       l = s1->n_len;
00279    }
00280 
00281    ld = l;
00282    lo = s2->n_len;
00283    p1 = s1->n_part;
00284    p2 = s2->n_part;
00285    p3 = d->n_part;
00286    same = (s1 == d);
00287    sum = 0;
00288 
00289    while (l --) {
00290       if (lo) {         /* es ist noch was von s2 da    */
00291          lo--;
00292          b = *p2++;
00293       }
00294       else
00295          b = 0;         /* ansonten 0 nehmen            */
00296 
00297       sum += (rsa_LONG)*p1++ + (rsa_LONG)b;
00298       *p3++ = rsa_TOINT(sum);
00299 
00300       if (sum > (rsa_LONG)rsa_MAXINT) { /* carry merken         */
00301          sum = 1;
00302       }
00303       else
00304          sum = 0;
00305 
00306       if (!lo && same && !sum)  /* nichts mehr zu tuen  */
00307          break;
00308    }
00309 
00310    if (sum) {           /* letztes carry beruecksichtigen       */
00311       ld++;
00312       *p3 = sum;
00313    }
00314 
00315    d->n_len = ld;                       /* Laenge setzen                */
00316 }
00317 
00318 /*
00319  * Subtrahiere zwei rsa_INT arrays. return( Laenge Ergebniss )
00320  * l == Laenge p1
00321  * lo== Laenge p3
00322  */
00323 int n_sub(rsa_INT *p1, rsa_INT *p2, rsa_INT *p3, int l, int lo)
00324 {
00325    int ld,lc,same;
00326    int over = 0;
00327    register rsa_LONG dif;
00328    rsa_LONG a,b;
00329 
00330    same = (p1 == p3);                   /* frueher Abbruch moeglich */
00331 
00332    for (lc=1, ld=0; l--; lc++) {
00333       a = (rsa_LONG)*p1++;
00334       if (lo) {                 /* ist noch was von p2 da ? */
00335          lo--;
00336          b = (rsa_LONG)*p2++;
00337       }
00338       else
00339          b=0;                   /* ansonten 0 nehmen    */
00340 
00341       if (over)                 /* frueherer Overflow   */
00342          b++;
00343       if ( b > a) {                     /* jetzt Overflow ?     */
00344          over = 1;
00345          dif = (rsa_MAXINT +1) + a;
00346       }
00347       else {
00348          over = 0;
00349          dif = a;
00350       }
00351       dif -= b;
00352       *p3++ = (rsa_INT)dif;
00353 
00354       if (dif)                  /* Teil != 0 : Laenge neu */
00355          ld = lc;
00356       if (!lo && same && !over) {       /* nichts mehr zu tuen  */
00357          if (l > 0)             /* Laenge korrigieren   */
00358             ld = lc + l;
00359          break;
00360       }
00361    }
00362 
00363    return( ld );
00364 }
00365 
00366 /*
00367  * Subtrahiere zwei rsa_NUMBER (d= s1 - s2)
00368  */
00369 void a_sub(rsa_NUMBER *s1, rsa_NUMBER *s2, rsa_NUMBER *d)
00370 {
00371    d->n_len = n_sub( s1->n_part, s2->n_part, d->n_part
00372                      ,s1->n_len, s2->n_len );
00373 }
00374 
00375 /*
00376  * Mulitipliziere rsa_INT array der Laenge l mit einer rsa_INT (d = n * m)
00377  * return neue Laenge
00378  */
00379 int n_mult(rsa_INT *n, rsa_INT m, rsa_INT *d, int l)
00380 {
00381    int i;
00382    register rsa_LONG mul;
00383 
00384    for (i=l,mul=0; i; i--) {
00385       mul += (rsa_LONG)m * (rsa_LONG)*n++;
00386       *d++ = rsa_TOINT(mul);
00387       mul  = rsa_DIVMAX1( mul );
00388    }
00389 
00390    if (mul) {           /* carry  ? */
00391       l++;
00392       *d = mul;
00393    }
00394 
00395    return( l );
00396 }
00397 
00398 /*
00399  * Mulitipliziere eine rsa_NUMBER mit einer rsa_INT (d = n * m)
00400  */
00401 void a_imult(rsa_NUMBER *n, rsa_INT m, rsa_NUMBER *d)
00402 {
00403    if (m == 0)
00404       d->n_len=0;
00405    else if (m == 1)
00406       a_assign( d, n );
00407    else
00408       d->n_len = n_mult( n->n_part, m, d->n_part, n->n_len );
00409 }
00410 
00411 /*
00412  * Multipliziere zwei rsa_NUMBER (d = m1 * m2)
00413  */
00414 void a_mult(rsa_NUMBER *m1, rsa_NUMBER *m2, rsa_NUMBER *d)
00415 {
00416    static rsa_INT id[ rsa_MAXLEN ];             /* Zwischenspeicher     */
00417    register rsa_INT *vp;                        /* Pointer darin        */
00418    register rsa_LONG sum;                       /* Summe fuer jede Stelle */
00419    register rsa_LONG tp1;                       /* Zwischenspeicher fuer m1 */
00420    register rsa_INT *p2;
00421    rsa_INT *p1;
00422    int l1,l2,ld,lc,l,i,j;
00423 
00424    l1 = m1->n_len;
00425    l2 = m2->n_len;
00426    l = l1 + l2;
00427    if (l >= rsa_MAXLEN)
00428       abort();
00429 
00430    for (i=l, vp=id; i--;)
00431       *vp++ = 0;
00432 
00433    /* ohne Uebertrag in Zwischenspeicher multiplizieren */
00434    for ( p1 = m1->n_part, i=0; i < l1 ; i++, p1++) {
00435 
00436       tp1 = (rsa_LONG)*p1;
00437       vp = &id[i];
00438       sum = 0;
00439       for ( p2 = m2->n_part, j = l2; j--;) {
00440          sum += (rsa_LONG)*vp + (tp1 * (rsa_LONG)*p2++);
00441          *vp++ = rsa_TOINT( sum );
00442          sum = rsa_DIVMAX1(sum);
00443       }
00444       *vp++ += (rsa_INT)sum;
00445    }
00446 
00447    /* jetzt alle Uebertraege beruecksichtigen   */
00448    ld = 0;
00449    for (lc=0, vp=id, p1=d->n_part; lc++ < l;) {
00450       if ( (*p1++ = *vp++))
00451          ld = lc;
00452    }
00453 
00454    d->n_len = ld;
00455 }
00456 
00457 
00458 /*
00459  * Dividiere Zwei rsa_NUMBER mit Rest (q= d1 / z2[0] Rest r)
00460  * z2[i] = z2[0] * 2^i,  i=0..rsa_MAXBIT-1
00461  * r = 0 : kein Rest
00462  * q = 0 : kein Quotient
00463  */
00464 void n_div(rsa_NUMBER *d1, rsa_NUMBER *z2, rsa_NUMBER *q, rsa_NUMBER *r)
00465 {
00466    static       rsa_NUMBER dummy_rest;  /* Dummy Variable, falls r = 0 */
00467    static       rsa_NUMBER dummy_quot;  /* Dummy Variable, falla q = 0 */
00468    rsa_INT *i1,*i1e,*i3;
00469    int l2,ld,l,lq;
00470 #if rsa_MAXINT != 1
00471    rsa_INT z;
00472    int pw,l2t;
00473 #endif
00474 
00475    if (!z2->n_len)
00476       abort();
00477 
00478    if (!r)
00479       r = &dummy_rest;
00480    if (!q)
00481       q = &dummy_quot;
00482 
00483    a_assign( r, d1 );   /* Kopie von d1 in den Rest             */
00484 
00485    l2= z2->n_len;               /* Laenge von z2[0]                     */
00486    l = r->n_len - l2;   /* Laenge des noch ''rechts'' liegenden
00487                            Stuecks von d1                       */
00488    lq= l +1;            /* Laenge des Quotienten                */
00489    i3= q->n_part + l;
00490    i1= r->n_part + l;
00491    ld = l2;             /* aktuelle Laenge des ''Vergleichsstuecks''
00492                            von d1                               */
00493    i1e= i1 + (ld-1);
00494 
00495    for (; l >= 0; ld++, i1--, i1e--, l--, i3--) {
00496       *i3 = 0;
00497 
00498       if (ld == l2 && ! *i1e) {
00499          ld--;
00500          continue;
00501       }
00502 
00503       if ( ld > l2 || (ld == l2 && n_cmp( i1, z2->n_part, l2) >= 0) ) {
00504 #if rsa_MAXINT != 1
00505          /* nach 2er-Potenzen zerlegen  */
00506          for (pw=rsa_MAXBIT-1, z=(rsa_INT)rsa_HIGHBIT; pw >= 0; pw--, z /= 2) {
00507             if ( ld > (l2t= z2[pw].n_len)
00508                  || (ld == l2t
00509                      && n_cmp( i1, z2[pw].n_part, ld) >= 0)) {
00510                ld = n_sub( i1, z2[pw].n_part, i1, ld, l2t );
00511                (*i3) += z;
00512             }
00513          }
00514 #else
00515          /* bei rsa_MAXINT == 1 alles viel einfacher    */
00516          ld = n_sub( i1, z2->n_part, i1, ld, l2 );
00517          (*i3) ++;
00518 #endif
00519       }
00520    }
00521 
00522    /* Korrektur, falls l von Anfang an Negativ war */
00523    l ++;
00524    lq -= l;
00525    ld += l;
00526 
00527    if (lq>0 && !q->n_part[lq -1])       /* evtl. Laenge korrigieren     */
00528       lq--;
00529 
00530    q->n_len = lq;
00531    r->n_len = ld -1;
00532 }
00533 
00534 /*
00535  * Dividiere Zwei rsa_NUMBER mit Rest (q= d1 / z2[0] Rest r)
00536  * z2[i] = z2[0] * 2^i,  i=0..rsa_MAXBIT-1
00537  * r = 0 : kein Rest
00538  * q = 0 : kein Quotient
00539  */
00540 void a_div(rsa_NUMBER *d1, rsa_NUMBER *d2, rsa_NUMBER *q, rsa_NUMBER *r)
00541 {
00542 #if rsa_MAXINT != 1
00543    rsa_NUMBER z2[rsa_MAXBIT];
00544    rsa_INT z;
00545    int i;
00546 
00547    a_assign( &z2[0], d2 );
00548    for (i=1,z=2; i < rsa_MAXBIT; i++, z *= 2)
00549       a_imult( d2, z, &z2[i] );
00550 
00551    d2 = z2;
00552 #endif
00553 
00554    n_div( d1, d2, q, r );
00555 }
00556 
00557 /*
00558  * Dividiere eine rsa_NUMBER durch 2
00559  */
00560 void a_div2(rsa_NUMBER *n)
00561 {
00562 #if rsa_MAXBIT == rsa_LOWBITS
00563    register rsa_INT *p;
00564    int i;
00565 
00566 #if rsa_MAXINT != 1
00567    register rsa_INT h;
00568    register int c;
00569 
00570    c=0;
00571    i= n->n_len;
00572    p= &n->n_part[i-1];
00573 
00574    for (; i--;) {
00575       if (c) {
00576          c = (h= *p) & 1;
00577          h /= 2;
00578          h |= rsa_HIGHBIT;
00579       }
00580       else {
00581          c = (h= *p) & 1;
00582          h /= 2;
00583       }
00584 
00585       *p-- = h;
00586    }
00587 
00588    if ( (i= n->n_len) && n->n_part[i-1] == 0 )
00589       n->n_len = i-1;
00590 
00591 #else  /* rsa_MAXBIT != 1 */
00592    p = n->n_part;
00593    i = n->n_len;
00594 
00595    if (i) {
00596       n->n_len = i-1;
00597       for (; --i ; p++)
00598          p[0] = p[1];
00599    }
00600 #endif /* rsa_MAXBIT != 1 */
00601 #else  /* rsa_MAXBIT == rsa_LOWBITS */
00602    a_div( n, &a_two, n, rsa_NUM0P );
00603 #endif /* rsa_MAXBIT == rsa_LOWBITS */
00604 }
00605 
00606 
00607 /*
00608  *      MODULO-FUNKTIONEN
00609  */
00610 
00611 static rsa_NUMBER g_mod_z2[ rsa_MAXBIT ];
00612 
00613 /*
00614  * Init
00615  */
00616 void m_init(rsa_NUMBER *n, rsa_NUMBER *o)
00617 {
00618    rsa_INT z;
00619    int i;
00620 
00621    if (o)
00622       a_assign( o, &g_mod_z2[0] );
00623 
00624    if (! a_cmp( n, &g_mod_z2[0]) )
00625       return;
00626 
00627    for (i=0,z=1; i < rsa_MAXBIT; i++, z *= 2)
00628       a_imult( n, z, &g_mod_z2[i] );
00629 }
00630 
00631 void m_add(rsa_NUMBER *s1, rsa_NUMBER *s2, rsa_NUMBER *d)
00632 {
00633    a_add( s1, s2, d );
00634    if (a_cmp( d, g_mod_z2) >= 0)
00635       a_sub( d, g_mod_z2, d );
00636 }
00637 
00638 void m_mult(rsa_NUMBER *m1, rsa_NUMBER *m2, rsa_NUMBER *d)
00639 {
00640    a_mult( m1, m2, d );
00641    n_div( d, g_mod_z2, rsa_NUM0P, d );
00642 }
00643 
00644 /*
00645  * Restklassen Exponent
00646  */
00647 void m_exp(rsa_NUMBER *x, rsa_NUMBER *n, rsa_NUMBER *z)
00648 {
00649    rsa_NUMBER xt,nt;
00650 
00651    a_assign( &nt, n );
00652    a_assign( &xt, x );
00653    a_assign( z, &a_one );
00654 
00655    while (nt.n_len) {
00656       while ( ! (nt.n_part[0] & 1)) {
00657          m_mult( &xt, &xt, &xt );
00658          a_div2( &nt );
00659       }
00660       m_mult( &xt, z, z );
00661       a_sub( &nt, &a_one, &nt );
00662    }
00663 }
00664 
00665 /*
00666  * GGT
00667  */
00668 void a_ggt(rsa_NUMBER *a, rsa_NUMBER *b, rsa_NUMBER *f)
00669 {
00670    rsa_NUMBER t[2];
00671    int at,bt, tmp;
00672 
00673    a_assign( &t[0], a ); at= 0;
00674    a_assign( &t[1], b ); bt= 1;
00675 
00676    if ( a_cmp( &t[at], &t[bt]) < 0) {
00677       tmp= at; at= bt; bt= tmp;
00678    }
00679    /* euklidischer Algorithmus          */
00680    while ( t[bt].n_len) {
00681       a_div( &t[at], &t[bt], rsa_NUM0P, &t[at] );
00682       tmp= at; at= bt; bt= tmp;
00683    }
00684 
00685    a_assign( f, &t[at] );
00686 }
00687 
00688 /*
00689  * die untersten b bits der Dualdarstellung von n
00690  * die bits muessen in ein int passen
00691  */
00692 int n_bits(rsa_NUMBER *n, int b)
00693 {
00694    rsa_INT *p;
00695    int l;
00696    unsigned r;
00697    int m = (1<<b) -1;
00698 
00699    if ( n->n_len == 0)
00700       return(0);
00701 
00702    if (rsa_LOWBITS >= b)
00703       return( n->n_part[0] & m );
00704 
00705 #if rsa_LOWBITS != 0
00706    l = (b-1) / rsa_LOWBITS;
00707 #else
00708    l = n->n_len -1;
00709 #endif
00710    for (p= &n->n_part[l],r=0; l-- >= 0 && b > 0; b-= rsa_LOWBITS, p--) {
00711       r  = rsa_MULMAX1( r );
00712       r += (unsigned)*p;
00713    }
00714 
00715    return( r & m );
00716 }
00717 
00718 /*
00719  * Anzahl der bits von n bei Dualdarstellung
00720  */
00721 int n_bitlen(rsa_NUMBER *n)
00722 {
00723    rsa_NUMBER b;
00724    int i;
00725 
00726    a_assign( &b, &a_one );
00727 
00728    for (i=0; a_cmp( &b, n) <= 0; a_mult( &b, &a_two, &b ), i++)
00729       ;
00730 
00731    return(i);
00732 }
00733 
00734 
00735 /*******************************************************************************
00736  *                                                                             *
00737  * prim.c                                                                       *
00738  *                                                                              *
00739  ********************************************************************************/
00740 
00741 /*
00742  *              RSA
00743  *
00744  *      p,q prim
00745  *      p != q
00746  *      n = p*q
00747  *      phi = (p -1)*(q -1)
00748  *      e,d aus 0...n-1
00749  *      e*d == 1 mod phi
00750  *
00751  *      m aus 0...n-1 sei eine Nachricht
00752  *
00753  *      Verschluesseln:
00754  *              E(x) = x^e mod n                ( n,e oeffendlich )
00755  *
00756  *      Entschluesseln:
00757  *              D(x) = x^d mod n                ( d geheim )
00758  *
00759  *
00760  *      Sicherheit:
00761  *
00762  *              p,q sollten bei mind. 10^100 liegen.
00763  *              (d,phi) == 1, das gilt fuer alle Primzahlen > max(p,q).
00764  *              Allerdings sollte d moeglichst gross sein ( d < phi-1 )
00765  *              um direktes Suchen zu verhindern.
00766  */
00767 
00768 
00769 /*
00770  *              FUNKTIONEN um RSA Schluessel zu generieren.
00771  *
00772  * int  p_prim( n, m )
00773  *              rsa_NUMBER *n;
00774  *              int m;
00775  *                      0 : n ist nicht prim
00776  *                      1 : n ist mit Wahrscheinlichkeit (1-1/2^m) prim
00777  *              ACHTUNG !!!!
00778  *              p_prim benutzt m_init
00779  *
00780  *      inv( d, phi, e )
00781  *              rsa_NUMBER *d,*phi,*e;
00782  *                      *e = *d^-1 (mod phi)
00783  *              ACHTUNG !!!!
00784  *              p_prim benutzt m_init
00785  */
00786 
00787 /*
00788  * Prototypes
00789  */
00790 static int      jak_f( rsa_NUMBER* );
00791 static int      jak_g( rsa_NUMBER*, rsa_NUMBER* );
00792 static int      jakobi( rsa_NUMBER*, rsa_NUMBER* );
00793 
00794 /*
00795  * Hilfs-Funktion fuer jakobi
00796  */
00797 static int jak_f(rsa_NUMBER *n)
00798 {
00799    int f,ret;
00800 
00801    f = n_bits( n, 3 );
00802 
00803    ret = ((f == 1) || (f == 7)) ? 1 : -1;
00804 
00805    return(ret);
00806 }
00807 
00808 /*
00809  * Hilfs-Funktuion fuer jakobi
00810  */
00811 static int jak_g(rsa_NUMBER *a, rsa_NUMBER *n)
00812 {
00813    int ret;
00814 
00815    if ( n_bits( n, 2) == 1 ||
00816         n_bits( a, 2) == 1 )
00817       ret = 1;
00818    else
00819       ret = -1;
00820 
00821    return(ret);
00822 }
00823 
00824 /*
00825  * Jakobi-Symbol
00826  */
00827 static int jakobi(rsa_NUMBER *a, rsa_NUMBER *n)
00828 {
00829    rsa_NUMBER t[2];
00830    int at,nt, ret;
00831 
00832    a_assign( &t[0], a ); at = 0;
00833    a_assign( &t[1], n ); nt = 1;
00834 
00835    /*
00836     * b > 1
00837     *
00838     * J( a, b) =
00839     * a == 1    :       1
00840     * a == 2    :       f(n)
00841     * a == 2*b  :       J(b,n)*J(2,n) ( == J(b,n)*f(n) )
00842     * a == 2*b -1       :       J(n % a,a)*g(a,n)
00843     *
00844     */
00845 
00846    ret = 1;
00847    while (1) {
00848       if (! a_cmp(&t[at],&a_one)) {
00849          break;
00850       }
00851       if (! a_cmp(&t[at],&a_two)) {
00852          ret *= jak_f( &t[nt] );
00853          break;
00854       }
00855       if ( ! t[at].n_len )              /* Fehler :-)   */
00856          abort();
00857       if ( t[at].n_part[0] & 1) {       /* a == 2*b -1  */
00858          int tmp;
00859 
00860          ret *= jak_g( &t[at], &t[nt] );
00861          a_div( &t[nt], &t[at], rsa_NUM0P, &t[nt] );
00862          tmp = at; at = nt; nt = tmp;
00863       }
00864       else {                            /* a == 2*b     */
00865          ret *= jak_f( &t[nt] );
00866          a_div2( &t[at] );
00867       }
00868 
00869    }
00870 
00871    return(ret);
00872 }
00873 
00874 /*
00875  * Probabilistischer Primzahltest
00876  *
00877  *  0 -> n nicht prim
00878  *  1 -> n prim mit  (1-1/2^m) Wahrscheinlichkeit.
00879  *
00880  *      ACHTUNG !!!!!!
00881  *      p_prim benutzt m_init !!
00882  *
00883  */
00884 int p_prim(rsa_NUMBER *n, int m)
00885 {
00886    rsa_NUMBER gt,n1,n2,a;
00887    rsa_INT *p;
00888    int i,w,j;
00889 
00890    if (a_cmp(n,&a_two) <= 0 || m <= 0)
00891       abort();
00892 
00893    a_sub( n, &a_one, &n1 );     /* n1 = -1    mod n             */
00894    a_assign( &n2, &n1 );
00895    a_div2( &n2 );                       /* n2 = ( n -1) / 2             */
00896 
00897    m_init( n, rsa_NUM0P );
00898 
00899    w = 1;
00900    for (; w && m; m--) {
00901       /* ziehe zufaellig a aus 2..n-1           */
00902       do {
00903          for (i=n->n_len-1, p=a.n_part; i; i--)
00904             *p++ = (rsa_INT)aux_rand();
00905          if ((i=n->n_len) )
00906             *p = (rsa_INT)( aux_rand() % ((unsigned long)n->n_part[i-1] +1) );
00907          while ( i && ! *p )
00908             p--,i--;
00909          a.n_len = i;
00910       } while ( a_cmp( &a, n) >= 0 || a_cmp( &a, &a_two) < 0 );
00911 
00912       /* jetzt ist a fertig                     */
00913 
00914       /*
00915        * n ist nicht prim wenn gilt:
00916        *        (a,n) != 1
00917        * oder
00918        *        a^( (n-1)/2) != J(a,n)   mod n
00919        *
00920        */
00921 
00922       a_ggt( &a, n, &gt );
00923       if ( a_cmp( &gt, &a_one) == 0) {
00924 
00925          j= jakobi( &a, n );
00926          m_exp( &a, &n2, &a );
00927 
00928          if  (   ( a_cmp( &a, &a_one) == 0 && j ==  1 )
00929                  || ( a_cmp( &a, &n1   ) == 0 && j == -1) )
00930             w = 1;
00931          else
00932             w = 0;
00933       }
00934       else
00935          w = 0;
00936    }
00937 
00938    return( w );
00939 }
00940 
00941 /*
00942  * Berechne mulitiplikatives Inverses zu d (mod phi)
00943  *      d relativ prim zu phi ( d < phi )
00944  *      d.h. (d,phi) == 1
00945  *
00946  *      ACHTUNG !!!!
00947  *      inv benutzt m_init
00948  */
00949 void inv(rsa_NUMBER *d, rsa_NUMBER *phi, rsa_NUMBER *e)
00950 {
00951    int k, i0, i1, i2;
00952    rsa_NUMBER r[3],p[3],c;
00953 
00954    /*
00955     * Berlekamp-Algorithmus
00956     *   ( fuer diesen Spezialfall vereinfacht )
00957     */
00958 
00959    if (a_cmp(phi,d) <= 0)
00960       abort();
00961 
00962    m_init( phi, rsa_NUM0P );
00963 
00964    p[1].n_len = 0;
00965    a_assign( &p[2], &a_one );
00966    a_assign( &r[1], phi );
00967    a_assign( &r[2], d );
00968 
00969    k = -1;
00970    do {
00971       k++;
00972       i0=k%3; i1=(k+2)%3; i2=(k+1)%3;
00973       a_div( &r[i2], &r[i1], &c, &r[i0] );
00974       m_mult( &c, &p[i1], &p[i0] );
00975       m_add( &p[i0], &p[i2], &p[i0] );
00976    } while (r[i0].n_len);
00977 
00978    if ( a_cmp( &r[i1], &a_one) )        /* r[i1] == (d,phi) muss 1 sein */
00979       abort();
00980 
00981    if ( k & 1 ) /* falsches ''Vorzeichen''      */
00982       a_sub( phi, &p[i1], e );
00983    else
00984       a_assign( e, &p[i1] );
00985 }
00986 
00987 
00988 /*******************************************************************************
00989  *                                                                             *
00990  * rnd.c                                                                       *
00991  *                                                                              *
00992  ********************************************************************************/
00993 
00994 void gen_number(int len, rsa_NUMBER *n)
00995 {
00996    const char *hex = "0123456789ABCDEF" ;
00997    char num[ rsa_STRLEN +1 ];
00998    char *p;
00999    int i,l;
01000 
01001    p=&num[ sizeof(num) -1];
01002    *p-- = '\0';
01003 
01004    for (l=len; l--; p--) {
01005       i = aux_rand() % 16;
01006       *p = hex[ i ];
01007    }
01008    p++;
01009 
01010    while (len-- && *p == '0')
01011       p++;
01012 
01013    rsa_num_sget( n, p );
01014 }
01015 
01016 void init_rnd()
01017 {
01018    const char *randdev = "/dev/urandom";
01019 
01020    int fd;
01021    unsigned int seed;
01022    if ((fd = open(randdev, O_RDONLY)) != -1) {
01023       if (read(fd, &seed, sizeof(seed))) {;}
01024       close(fd);
01025    } else {
01026       seed = (unsigned int)time(0);   //better use times() + win32 equivalent
01027    }
01028    srand( seed );
01029 }
01030 
01031 
01032 /*******************************************************************************
01033  *                                                                             *
01034  * aux.c                                                                       *
01035  *                                                                              *
01036  ********************************************************************************/
01037 
01038 /* These are not needed, for the moment
01039 
01040 int get_clear(char *p, FILE *fp)
01041 {
01042 int n;
01043 
01044 n = fread( p, 1, clear_siz, fp );
01045 
01046 if (n <= 0)
01047 return(0);
01048 
01049 memset( p + n, 0, enc_siz - n );
01050 
01051 return(1);
01052 }
01053 
01054 int get_enc(char *p, FILE *fp)
01055 {
01056    int n;
01057 
01058    n = fread( p, 1, enc_siz, fp );
01059 
01060    if (n != enc_siz)
01061       return(0);
01062 
01063    return(1);
01064 }
01065 
01066 int put_clear(char *p, FILE *fp)
01067 {
01068    int n;
01069 
01070    n = fwrite( p, 1, clear_siz, fp );
01071 
01072    if (n != clear_siz)
01073       return(0);
01074 
01075    return(1);
01076 }
01077 
01078 int put_enc(char *p, FILE *fp)
01079 {
01080    int n;
01081 
01082    n = fwrite( p, 1, enc_siz, fp );
01083 
01084    if (n != enc_siz)
01085       return(0);
01086 
01087    return(1);
01088 }
01089 
01090 */
01091 
01092 void do_crypt(char *s, char *d, int len, rsa_NUMBER *e)
01093 {
01094    static char hex[] = "0123456789ABCDEF";
01095    rsa_NUMBER n;
01096    char buf[ rsa_STRLEN + 1 ];
01097    char *ph;
01098    int i,c;
01099 
01100    ph = buf + rsa_STRLEN - 1;
01101    ph[1] = '\0';
01102 
01103    for (i=len; i; i--) {
01104       c = *s++;
01105       *ph-- = hex[ (c >> 4) & 0xF ];
01106       *ph-- = hex[ c & 0xF ];
01107    }
01108    ph++;
01109 
01110    rsa_num_sget( &n, ph );
01111 
01112    m_exp( &n, e, &n );
01113 
01114    rsa_num_sput( &n, buf, rsa_STRLEN +1 );
01115 
01116    ph = buf + (i=strlen(buf)) -1;
01117 
01118    for (; len; len--) {
01119       if (i-- > 0) {
01120          c = (strchr( hex, *ph) - hex) << 4;
01121          ph--;
01122       }
01123       else
01124          c=0;
01125       if (i-- > 0) {
01126          c |= strchr( hex, *ph) - hex;
01127          ph--;
01128       }
01129 
01130       *d++ = c;
01131    }
01132 }
01133 

Generated on Tue Jul 5 14:45:37 2011 for ROOT_528-00b_version by  doxygen 1.5.1