00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 static int aux_rand()
00166 {
00167
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
00192 return rand();
00193 #endif
00194 }
00195
00196
00197
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
00217
00218 int n_cmp(rsa_INT *i1, rsa_INT *i2, int l)
00219 {
00220 i1 += (l-1);
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
00232
00233 int a_cmp(rsa_NUMBER *c1, rsa_NUMBER *c2)
00234 {
00235 int l;
00236
00237 if ( (l=c1->n_len) != c2->n_len)
00238 return( l - c2->n_len);
00239
00240
00241 return( n_cmp( c1->n_part, c2->n_part, l) );
00242 }
00243
00244
00245
00246
00247 void a_assign(rsa_NUMBER *d, rsa_NUMBER *s)
00248 {
00249 int l;
00250
00251 if (s == d)
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
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
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) {
00291 lo--;
00292 b = *p2++;
00293 }
00294 else
00295 b = 0;
00296
00297 sum += (rsa_LONG)*p1++ + (rsa_LONG)b;
00298 *p3++ = rsa_TOINT(sum);
00299
00300 if (sum > (rsa_LONG)rsa_MAXINT) {
00301 sum = 1;
00302 }
00303 else
00304 sum = 0;
00305
00306 if (!lo && same && !sum)
00307 break;
00308 }
00309
00310 if (sum) {
00311 ld++;
00312 *p3 = sum;
00313 }
00314
00315 d->n_len = ld;
00316 }
00317
00318
00319
00320
00321
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);
00331
00332 for (lc=1, ld=0; l--; lc++) {
00333 a = (rsa_LONG)*p1++;
00334 if (lo) {
00335 lo--;
00336 b = (rsa_LONG)*p2++;
00337 }
00338 else
00339 b=0;
00340
00341 if (over)
00342 b++;
00343 if ( b > a) {
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)
00355 ld = lc;
00356 if (!lo && same && !over) {
00357 if (l > 0)
00358 ld = lc + l;
00359 break;
00360 }
00361 }
00362
00363 return( ld );
00364 }
00365
00366
00367
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
00377
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) {
00391 l++;
00392 *d = mul;
00393 }
00394
00395 return( l );
00396 }
00397
00398
00399
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
00413
00414 void a_mult(rsa_NUMBER *m1, rsa_NUMBER *m2, rsa_NUMBER *d)
00415 {
00416 static rsa_INT id[ rsa_MAXLEN ];
00417 register rsa_INT *vp;
00418 register rsa_LONG sum;
00419 register rsa_LONG tp1;
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
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
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
00460
00461
00462
00463
00464 void n_div(rsa_NUMBER *d1, rsa_NUMBER *z2, rsa_NUMBER *q, rsa_NUMBER *r)
00465 {
00466 static rsa_NUMBER dummy_rest;
00467 static rsa_NUMBER dummy_quot;
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 );
00484
00485 l2= z2->n_len;
00486 l = r->n_len - l2;
00487
00488 lq= l +1;
00489 i3= q->n_part + l;
00490 i1= r->n_part + l;
00491 ld = l2;
00492
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
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
00516 ld = n_sub( i1, z2->n_part, i1, ld, l2 );
00517 (*i3) ++;
00518 #endif
00519 }
00520 }
00521
00522
00523 l ++;
00524 lq -= l;
00525 ld += l;
00526
00527 if (lq>0 && !q->n_part[lq -1])
00528 lq--;
00529
00530 q->n_len = lq;
00531 r->n_len = ld -1;
00532 }
00533
00534
00535
00536
00537
00538
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
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
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
00601 #else
00602 a_div( n, &a_two, n, rsa_NUM0P );
00603 #endif
00604 }
00605
00606
00607
00608
00609
00610
00611 static rsa_NUMBER g_mod_z2[ rsa_MAXBIT ];
00612
00613
00614
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
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
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
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
00690
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
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
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
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
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
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
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
00837
00838
00839
00840
00841
00842
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 )
00856 abort();
00857 if ( t[at].n_part[0] & 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 {
00865 ret *= jak_f( &t[nt] );
00866 a_div2( &t[at] );
00867 }
00868
00869 }
00870
00871 return(ret);
00872 }
00873
00874
00875
00876
00877
00878
00879
00880
00881
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 );
00894 a_assign( &n2, &n1 );
00895 a_div2( &n2 );
00896
00897 m_init( n, rsa_NUM0P );
00898
00899 w = 1;
00900 for (; w && m; m--) {
00901
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
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922 a_ggt( &a, n, > );
00923 if ( a_cmp( >, &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
00943
00944
00945
00946
00947
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
00956
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) )
00979 abort();
00980
00981 if ( k & 1 )
00982 a_sub( phi, &p[i1], e );
00983 else
00984 a_assign( e, &p[i1] );
00985 }
00986
00987
00988
00989
00990
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);
01027 }
01028 srand( seed );
01029 }
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
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