rsalib.cxx

Go to the documentation of this file.
00001 /* @(#)root/auth:$Id: rsalib.cxx 20882 2007-11-19 11:31:26Z rdm $ */
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        <string.h>
00034 #include        <ctype.h>
00035 #include        <stdlib.h>
00036 #include <errno.h>
00037 
00038 #include        "rsaaux.h"
00039 #include        "rsalib.h"
00040 
00041 static int      g_clear_siz;            /* clear-text blocksize         */
00042 static int      g_enc_siz;              /* encoded blocksize            */
00043                                     /* g_clear_siz < g_enc_siz      */
00044 
00045 int gLog = 0;
00046 int kMAXT = 100;
00047 
00048 rsa_NUMBER rsa_genprim(int len, int prob)
00049 {
00050    rsa_NUMBER a_three,a_four;
00051    rsa_NUMBER prim;
00052    int i;
00053 
00054    a_add( &a_one, &a_two, &a_three );
00055    a_add( &a_two, &a_two, &a_four );
00056 
00057    /* This is done elsewhere to allow different initialization of
00058       rand seed (GGa - Sep 15, 2003) */
00059    /* init_rnd(); */
00060 
00061    do {
00062       gen_number( len, &prim );
00063    } while ( !prim.n_len );
00064 
00065    a_mult( &prim, &a_two, &prim );
00066    a_mult( &prim, &a_three, &prim );
00067    a_add( &prim, &a_one, &prim );
00068 
00069    for (i=1 ;; i++) {
00070 
00071       if (p_prim( &prim, prob ))
00072          break;
00073       if (i % 2)
00074          a_add( &prim, &a_four, &prim );
00075       else
00076          a_add( &prim, &a_two, &prim );
00077    }
00078 
00079    return prim;
00080 }
00081 
00082 int rsa_genrsa(rsa_NUMBER p1, rsa_NUMBER p2, rsa_NUMBER *n, rsa_NUMBER *e, rsa_NUMBER *d)
00083 {
00084    rsa_NUMBER phi, *max_p;
00085    int len;
00086    int ii, jj;
00087 
00088    if ( !a_cmp( &p1, &p2) ) return 1;
00089 
00090    if (a_cmp( &p1, &p2) > 0)
00091       max_p = &p1;
00092    else
00093       max_p = &p2;
00094 
00095 
00096    a_mult( &p1, &p2, n );
00097    a_sub( &p1, &a_one, &phi );
00098    a_sub( &p2, &a_one, e );
00099    a_mult( &phi, e, &phi );
00100 
00101    len = n_bitlen( &phi );
00102    len = ( len + 3) / 4;
00103 
00104    a_assign( &p1, &phi );
00105    a_sub( &p1, &a_one, &p1 );
00106 
00107    /* This is done elsewhere to allow different initialization of
00108       rand seed (GGa - Sep 15, 2003) */
00109    /* init_rnd(); */
00110 
00111    ii = 0;
00112    do {
00113       ii++;
00114       jj = 0;
00115       do {
00116          jj++;
00117          gen_number( len, d );
00118       } while (((a_cmp( d, max_p) <= 0 || a_cmp( d, &p1) >= 0)) && jj < kMAXT);
00119 
00120       a_ggt( d, &phi, e );
00121    } while ( a_cmp( e, &a_one) && ii < kMAXT);
00122 
00123    if (ii >= kMAXT || jj >= kMAXT)
00124       return  2;
00125 
00126    inv( d, &phi, e );
00127 
00128    return 0;
00129 
00130 }
00131 
00132 int rsa_encode_size(rsa_NUMBER n)
00133 {
00134    // Returns length unit block of output
00135 
00136    return ( n_bitlen( &n) + 7) / 8;
00137 }
00138 
00139 int rsa_encode(char *bufin, int lin, rsa_NUMBER n, rsa_NUMBER e)
00140 {
00141    /* Encodes plain string in 'bufin' (output in 'bufin')
00142       Returns length of encoded string
00143       (key validity is not checked) */
00144 
00145    char  buf[ rsa_STRLEN*2 ];
00146    char  bufout[ rsa_STRLEN*2 ];
00147    int   i, j, lout;
00148    char *pout;
00149 
00150    g_enc_siz = ( n_bitlen( &n) + 7) / 8;
00151    g_clear_siz = g_enc_siz -1;
00152    m_init( &n, rsa_NUM0P );
00153 
00154    pout = bufout;
00155    lout = 0;
00156    for ( i = 0; i < lin; i += g_clear_siz) {
00157 
00158       memcpy(buf,bufin+i,g_clear_siz);
00159 
00160       j = ((lin-i) < g_clear_siz) ? lin-i : g_clear_siz;
00161       memset(buf+j,0,(g_enc_siz-j));
00162 
00163       do_crypt( buf, buf, g_enc_siz, &e );
00164 
00165       memcpy(pout,buf,g_enc_siz);
00166 
00167       pout += g_enc_siz;
00168       lout += g_enc_siz;
00169    }
00170 
00171    memcpy(bufin,bufout,lout);
00172 
00173    return lout;
00174 
00175 }
00176 
00177 int rsa_decode(char *bufin, int lin, rsa_NUMBER n, rsa_NUMBER e)
00178 {
00179    /* Decodes string in 'bufin' (output in 'bufin')
00180       Returns length of plaintext string
00181       (key validity is not checked) */
00182 
00183    char  buf[ rsa_STRLEN*2 ];
00184    char  bufout[ rsa_STRLEN*2 ];
00185    int   i, lout;
00186    char *pout;
00187 
00188    g_enc_siz = ( n_bitlen( &n) + 7) / 8;
00189    g_clear_siz = g_enc_siz -1;
00190    m_init( &n, rsa_NUM0P );
00191 
00192    pout = bufout;
00193    lout = 0;
00194    for ( i = 0; i < lin; i += g_enc_siz) {
00195 
00196       memcpy(buf,bufin+i,g_enc_siz);
00197 
00198       do_crypt( buf, buf, g_enc_siz, &e );
00199 
00200       memcpy(pout,buf,g_clear_siz);
00201 
00202       pout += g_clear_siz;
00203       lout += g_clear_siz;
00204    }
00205 
00206    memcpy(bufin,bufout,lout);
00207 
00208    return lout;
00209 
00210 }
00211 
00212 
00213 /*******************************************************************************
00214  *                                                                             *
00215  * nio.c                                                                        *
00216  *                                                                              *
00217  ********************************************************************************/
00218 
00219 
00220 /*
00221  *      rsa_NUMBER io
00222  */
00223 
00224 /*
00225  *              Funktionen
00226  *
00227  * int  num_sput( n, s, l)
00228  *              rsa_NUMBER *n;
00229  *              char s[l];
00230  *                      schreibt *n als Hex-Zahl in s
00231  *
00232  * int  num_fput( n, f )
00233  *              rsa_NUMBER *n;
00234  *              FILE *f;
00235  *                      schreibt *n als Hex-Zahl in File f
00236  *
00237  * int  num_sget( n, s )
00238  *              rsa_NUMBER *n;
00239  *              char *s;
00240  *                      liest Hex-Zahl s in *n ein
00241  *
00242  * int  num_fget( n, f )
00243  *              rsa_NUMBER *n;
00244  *              FILE *f;
00245  *                      liest eine Hex-Zahl von f in *n ein
00246  *
00247  */
00248 
00249 
00250 static const char *gHEX="0123456789ABCDEF";
00251 static const char *ghex="0123456789abcdef";
00252 
00253 static rsa_NUMBER gbits[9];
00254 static rsa_NUMBER gint16[16];
00255 
00256 static int ginit = 0;
00257 
00258 void num_init()
00259 {
00260    int i;
00261 
00262    if (ginit) return;
00263 
00264    a_assign( &gbits[0], &a_one );
00265    for ( i=1; i<9; i++)
00266       a_add( &gbits[i-1], &gbits[i-1], &gbits[i] );
00267 
00268    a_assign( &gint16[0], &a_one );
00269    for ( i=1; i<16; i++)
00270       a_add( &gint16[i-1], &a_one, &gint16[i] );
00271 
00272    ginit = 1;
00273 }
00274 
00275 
00276 int rsa_num_sput(rsa_NUMBER *n, char *s, int l)
00277 {
00278 #if rsa_MAXINT == ( (1 << rsa_MAXBIT) - 1 )
00279    rsa_INT *p;
00280    int bi,ab,i;
00281    long b;
00282    int first = 1;
00283 
00284    bi = rsa_MAXBIT * n->n_len;
00285    ab = 4 - (bi + 3) % 4 -1;
00286    p  = &n->n_part[n->n_len -1];
00287 
00288    if ( (bi+3) / 4 >= l )
00289       return(EOF);
00290 
00291    b  = 0;
00292    while (bi) {
00293       b <<= (rsa_MAXBIT);
00294       b |= (unsigned long)*p--;
00295       bi -= rsa_MAXBIT;
00296       ab += rsa_MAXBIT;
00297       while (ab >= 4) {
00298          i = (b >> (ab - 4));
00299          b &= ( 1L << (ab - 4)) -1L;
00300          ab -= 4;
00301 
00302          if (first && !i)
00303             continue;
00304          first = 0;
00305          *s++ = gHEX[ i ];
00306       }
00307    }
00308    if (b)
00309       abort();
00310    *s = '\0';
00311 
00312    return (0);
00313 #else
00314    rsa_NUMBER r,q;
00315    int i,b,p,len,low,high;
00316    char *np;
00317 
00318    if (! ginit)
00319       num_init();
00320 
00321    a_assign( &q, n);
00322    len = l;
00323    np = s + l;
00324 
00325    for (; q.n_len && len > 1; len --) {
00326       a_div( &q, &gbits[4], &q, &r );
00327       for (p=8, b=0, i=3; i >= 0; i--, p /= 2) {
00328          if ( a_cmp( &r, &gbits[i]) >= 0) {
00329             a_sub( &r, &gbits[i], &r );
00330             b += p;
00331          }
00332       }
00333       *--np = gHEX[ b ];
00334    }
00335    if (q.n_len)
00336       return(EOF);
00337 
00338    l -= len;
00339    len = l;
00340    for (; l--; )
00341       *s++ = *np++;
00342 
00343    *s = '\0';
00344 
00345    return (0);
00346 #endif
00347 }
00348 
00349 
00350 int rsa_num_fput(rsa_NUMBER *n, FILE *f)
00351 {
00352    int j;
00353    char *np;
00354    char n_print[ rsa_STRLEN + 1 ];
00355 
00356    if ( rsa_num_sput( n, n_print, sizeof( n_print) ) == EOF )
00357       return(EOF);
00358 
00359    for (j=0, np=n_print; *np ; np++, j++) {
00360       if (j==64) {
00361          fputs("\n",f);
00362          j = 0;
00363       }
00364       putc((int)*np,f);
00365    }
00366 
00367    if (j)
00368       putc('\n',f);
00369 
00370    return(0);
00371 }
00372 
00373 
00374 int rsa_num_sget(rsa_NUMBER *n, char *s)
00375 {
00376 #if rsa_MAXINT == ( (1 << rsa_MAXBIT) - 1 )
00377    rsa_INT *p;
00378    const char *hp;
00379    int bi,ab,i;
00380    long b;
00381    int first = 1;
00382 
00383    bi = 4 * strlen(s);
00384    ab = rsa_MAXBIT - (bi + rsa_MAXBIT -1) % rsa_MAXBIT -1;
00385    i  =  (bi + rsa_MAXBIT-1) / rsa_MAXBIT;
00386    p  = &n->n_part[ i -1 ];
00387    n->n_len = i;
00388 
00389    if ( i > rsa_MAXLEN )
00390       return(EOF);
00391 
00392    b  = 0;
00393    while (bi > 0) {
00394       if ( (hp = strchr( gHEX, *s )) )
00395          i = hp - gHEX;
00396       else if ((hp = strchr( ghex, *s )) )
00397          i = hp - ghex;
00398       else
00399          return(EOF);
00400       s++;
00401 
00402       b <<= 4;
00403       b |= (unsigned long)i;
00404       bi -= 4;
00405       ab += 4;
00406       while (ab >= rsa_MAXBIT) {
00407          i = (b >> (ab - rsa_MAXBIT));
00408          b &= ( 1L << (ab - rsa_MAXBIT)) -1L;
00409          ab -= rsa_MAXBIT;
00410          if (first && !i) {
00411             p--;
00412             n->n_len--;
00413          }
00414          else {
00415             first = 0;
00416             *p-- = i;
00417          }
00418       }
00419    }
00420    if (b)
00421       abort();
00422    *s = '\0';
00423 
00424    return (0);
00425 #else
00426    char *p;
00427    int i,c;
00428 
00429    if (! ginit)
00430       num_init();
00431 
00432    n->n_len = 0;
00433    while ( (c = *s++ & 0xFF)) {
00434       if ( p= strchr( gHEX, c) )
00435          i = p - gHEX;
00436       else if ( p= strchr( ghex, c) )
00437          i = p - ghex;
00438       else
00439          return(EOF);
00440 
00441       a_mult( n, &gbits[4], n );
00442       if (i)
00443          a_add( n, &gint16[i-1], n );
00444    }
00445 
00446    return(0);
00447 #endif
00448 }
00449 
00450 int rsa_num_fget(rsa_NUMBER *n, FILE *f)
00451 {
00452    int j,c;
00453    char *np;
00454    char n_print[ rsa_STRLEN + 1 ];
00455 
00456    np = n_print;
00457    j = sizeof(n_print);
00458    while ( (c=getc(f)) != EOF && ( isxdigit(c) || isspace(c)) ) {
00459       if (isspace(c))
00460          continue;
00461       if (! --j)
00462          return(EOF);
00463       *np++ = (char)c;
00464    }
00465    *np = '\0';
00466 
00467    if (c != EOF)
00468       ungetc(c,f);
00469 
00470    if ( rsa_num_sget( n, n_print) == EOF )
00471       return( EOF );
00472 
00473    return(0);
00474 }
00475 
00476 int rsa_cmp(rsa_NUMBER *c1, rsa_NUMBER *c2)
00477 {
00478    int l;
00479    /* bei verschiedener Laenge klar*/
00480    if ( (l=c1->n_len) != c2->n_len)
00481       return( l - c2->n_len);
00482 
00483    /* vergleiche als arrays     */
00484    return( n_cmp( c1->n_part, c2->n_part, l) );
00485 }
00486 
00487 void rsa_assign(rsa_NUMBER *d, rsa_NUMBER *s)
00488 {
00489    int l;
00490 
00491    if (s == d)                  /* nichts zu kopieren           */
00492       return;
00493 
00494    if ((l=s->n_len))
00495       memcpy( d->n_part, s->n_part, sizeof(rsa_INT)*l);
00496 
00497    d->n_len = l;
00498 }

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