rsa_san.cpp
资源名称:rsa.rar [点击查看]
上传用户:sjzccgj
上传日期:2014-10-18
资源大小:17k
文件大小:9k
源码类别:
CA认证
开发平台:
Visual C++
- #include "stdafx.h"
- // This is a slow but easy RSA encryption class
- // By sanicle,2005.12
- // 3mn@3mn.net
- #include "stdio.h"
- #include "rsa_san.h"
- class Prime_factory_san
- {
- unsigned np;
- unsigned *pl;
- public:
- Prime_factory_san();
- ~Prime_factory_san();
- vlong find_prime( vlong & start );
- };
- // prime factory implementation
- static int is_probable_prime_san( const vlong &p )
- {
- // Test based on Fermats theorem a**(p-1) = 1 mod p for prime p
- // For 1000 bit numbers this can take quite a while
- const rep = 4;
- const unsigned any[rep] = { 2,3,5,7 };
- for ( unsigned i=0; i<rep; i+=1 )
- if ( modexp( any[i], p-vlong(1), p ) != vlong(1) )
- return 0;
- return 1;
- }
- Prime_factory_san::Prime_factory_san()
- {
- np = 0;
- unsigned NP = 200;
- pl = new unsigned[NP];
- // Initialise pl
- unsigned SS = 8*NP; // Rough estimate to fill pl
- char * b = new char[SS+1]; // one extra to stop search
- for (unsigned i=0;i<=SS;i+=1) b[i] = 1;
- unsigned p = 2;
- while (1)
- {
- // skip composites
- while ( b[p] == 0 ) p += 1;
- if ( p == SS ) break;
- pl[np] = p;
- np += 1;
- if ( np == NP ) break;
- // cross off multiples
- unsigned c = p*2;
- while ( c < SS )
- {
- b[c] = 0;
- c += p;
- }
- p += 1;
- }
- delete [] b;
- }
- Prime_factory_san::~Prime_factory_san()
- {
- delete [] pl;
- }
- vlong Prime_factory_san::find_prime( vlong & start )
- {
- unsigned SS = 1000; // should be enough unless we are unlucky
- char * b = new char[SS]; // bitset of candidate primes
- unsigned tested = 0;
- while (1)
- {
- unsigned i;
- for (i=0;i<SS;i++)
- b[i] = 1;
- for (i=0;i<np;i++)
- {
- unsigned p = pl[i];
- unsigned r = start % vlong(p); // not as fast as it should be - could do with special routine
- if (r) r = p - r;
- // cross off multiples of p
- while ( r < SS )
- {
- b[r] = 0;
- r += p;
- }
- }
- // now test candidates
- for (i=0;i<SS;i++)
- {
- if ( b[i] )
- {
- tested += 1;
- if ( is_probable_prime_san(start) )
- return start;
- }
- start += 1;
- }
- }
- delete [] b;
- }
- RSA_san::RSA_san()
- {
- // init vars
- prime_table_use=0;
- prime_p_index=0;
- prime_q_index=1;
- char *tmp;
- tmp="1234567890qwertyuiopasdfghjklzxcvb";
- for(int i=0;i<36;i++)
- r1[i]=tmp[i];
- tmp="9876543210poiuytrewqlkjhgfdsamnbvc";
- for(i=0;i<36;i++)
- r2[i]=tmp[i];
- // find primes p q
- find_prime();
- // mul to get n
- n = p*q;
- // get a public key
- random_e();
- // calculate the private key
- calculate_d();
- }
- RSA_san::~RSA_san()
- {
- }
- static vlong from_str_san( const char * s )
- {
- vlong x = 0;
- while (*s)
- {
- x = x * vlong(256) + vlong((unsigned char)*s);
- s += 1;
- }
- return x;
- }
- void RSA_san::find_prime()
- {
- // Choose primes
- Prime_factory_san pf;
- if (prime_table_use==0)
- {
- p = pf.find_prime( from_str_san(r1) );
- q = pf.find_prime( from_str_san(r2) );
- }
- else
- {
- p = prime_table[prime_p_index];
- q = prime_table[prime_q_index];
- }
- if ( p > q ) { vlong tmp = p; p = q; q = tmp; }
- }
- void RSA_san::random_e()
- {
- e = 50001; // must be odd since p-1 and q-1 are even
- while ( gcd(p-vlong(1),e) != vlong(1) || gcd(q-vlong(1),e) != vlong(1) ) e += 2;
- }
- void RSA_san::calculate_d()
- {
- d = modinv(e,(p-vlong(1))*(q-vlong(1)));
- }
- vlong RSA_san::encrypt( const vlong& x )
- {
- return modexp(x,e,n);
- }
- vlong RSA_san::decrypt( const vlong& y )
- {
- return modexp(y,d,n);
- }
- int RSA_san::RSA_san_en(char * s,unsigned n)
- {
- vlong t = 0;
- result = 0;
- for(unsigned i=0;i<n;i++)
- {
- t = t * vlong(256) + vlong((unsigned char)*s);
- s += 1;
- }
- result=encrypt(t);
- return 1;
- }
- int RSA_san::RSA_san_en_byte(char b)
- {
- result=0;
- result=encrypt(vlong((unsigned char)b));
- return 1;
- }
- int RSA_san::RSA_san_dn(char * s,unsigned n)
- {
- vlong t = 0;
- result = 0;
- for(unsigned i=0;i<n;i++)
- {
- t = t * vlong(256) + vlong((unsigned char)*s);
- s += 1;
- }
- result=decrypt(t);
- return 1;
- }
- int RSA_san::RSA_san_dn_hexstring(char * s)
- {
- unsigned i=0;
- vlong t = 0;
- result = 0;
- while(*s)
- {
- switch(*s)
- {
- case '0':i=0;break;
- case '1':i=1;break;
- case '2':i=2;break;
- case '3':i=3;break;
- case '4':i=4;break;
- case '5':i=5;break;
- case '6':i=6;break;
- case '7':i=7;break;
- case '8':i=8;break;
- case '9':i=9;break;
- case 'A':i=10;break;
- case 'B':i=11;break;
- case 'C':i=12;break;
- case 'D':i=13;break;
- case 'E':i=14;break;
- case 'F':i=15;break;
- }
- t = t * vlong(16) + vlong(i);
- s += 1;
- }
- result=decrypt(t);
- return 1;
- }
- int RSA_san::RSA_san_en_hexstring(char * s)
- {
- unsigned i=0;
- vlong t = 0;
- result = 0;
- while(*s)
- {
- switch(*s)
- {
- case '0':i=0;break;
- case '1':i=1;break;
- case '2':i=2;break;
- case '3':i=3;break;
- case '4':i=4;break;
- case '5':i=5;break;
- case '6':i=6;break;
- case '7':i=7;break;
- case '8':i=8;break;
- case '9':i=9;break;
- case 'A':i=10;break;
- case 'B':i=11;break;
- case 'C':i=12;break;
- case 'D':i=13;break;
- case 'E':i=14;break;
- case 'F':i=15;break;
- }
- t = t * vlong(16) + vlong(i);
- s += 1;
- }
- result=encrypt(t);
- return 1;
- }
- int RSA_san::set_e(char * r)
- {
- e = 0;
- while (*r)
- {
- e = e * vlong(256) + vlong((unsigned char)*r);
- r += 1;
- }
- if(e%vlong(2)==vlong(0))e-=1;
- while ( gcd(p-vlong(1),e) != vlong(1) || gcd(q-vlong(1),e) != vlong(1) ) e += 2;
- calculate_d();
- return 1;
- }
- int RSA_san::force_e(char * r,unsigned len)
- {
- e = 0;
- p=0;q=0;
- for(unsigned i=0;i<len;i++)
- {
- e = e * vlong(256) + vlong((unsigned char)*(r+i));
- }
- return 1;
- }
- int RSA_san::force_d(char * r,unsigned len)
- {
- d = 0;
- p=0;q=0;
- for(unsigned i=0;i<len;i++)
- {
- d = d * vlong(256) + vlong((unsigned char)*(r+i));
- }
- return 1;
- }
- int RSA_san::force_n(char * r,unsigned len)
- {
- n = 0;
- p=0;q=0;
- for(unsigned i=0;i<len;i++)
- {
- n = n * vlong(256) + vlong((unsigned char)*(r+i));
- }
- return 1;
- }
- int RSA_san::update_pq(char * ra,char * rb)
- {
- for(int i=0;i<35;i++)
- {
- if(ra[i])r1[i]=ra[i];else r1[i]='A';
- if(rb[i])r2[i]=rb[i];else r2[i]='B'; //should provent string interrupt like this~
- }
- find_prime();
- n = p*q;
- if(e%vlong(2)==vlong(0))e-=1;
- while ( gcd(p-vlong(1),e) != vlong(1) || gcd(q-vlong(1),e) != vlong(1) ) e += 2;
- calculate_d();
- return 1;
- }
- char* RSA_san::string2hexstring(char * s)//,unsigned len)
- {
- unsigned len=35; // only use this function like this in this situation:)
- char *ps;
- char *p;
- ps=new char[len*2+2];
- p=ps;
- for(unsigned i=0;i<len;i++)
- {
- p[0]='0';p[1]='0';
- sprintf(p,"%X",s[i]);
- if(p[1]==' ')
- {
- p[1]=p[0];
- p[0]='0';
- }
- p+=2;
- }
- *p=' ';
- return ps;
- }
- char* RSA_san::hexstring2string(char * h)
- {
- // if hexstring has 0 byte in it ,...be careful about ' '
- unsigned i,id;
- char *ph;
- char *t;
- id=0;
- i=(unsigned)strlen(h);
- t=new char[i];
- if(i%2)
- {
- ph=new char[i+1];
- *ph='0';
- ph++;
- for(unsigned j=0;j<i;j++)ph[j]=h[j];
- ph[i]=' ';
- ph--;
- }
- else ph=h;
- while(*ph)
- {
- switch(*ph)
- {
- case '0':i=0;break;
- case '1':i=16;break;
- case '2':i=32;break;
- case '3':i=48;break;
- case '4':i=64;break;
- case '5':i=80;break;
- case '6':i=96;break;
- case '7':i=112;break;
- case '8':i=128;break;
- case '9':i=144;break;
- case 'A':i=160;break;
- case 'B':i=176;break;
- case 'C':i=192;break;
- case 'D':i=208;break;
- case 'E':i=224;break;
- case 'F':i=240;break;
- }
- switch(*(ph+1))
- {
- case '0':i+=0;break;
- case '1':i+=1;break;
- case '2':i+=2;break;
- case '3':i+=3;break;
- case '4':i+=4;break;
- case '5':i+=5;break;
- case '6':i+=6;break;
- case '7':i+=7;break;
- case '8':i+=8;break;
- case '9':i+=9;break;
- case 'A':i+=10;break;
- case 'B':i+=11;break;
- case 'C':i+=12;break;
- case 'D':i+=13;break;
- case 'E':i+=14;break;
- case 'F':i+=15;break;
- }
- t[id]=i;
- id++;
- ph+=2;
- }
- t[id]=' ';
- return t;
- }
- char* RSA_san::vlong2hexstring( const vlong& v )
- {
- unsigned z,t,j,l;
- char st[9];
- char *ps;
- j=0;
- z=v.get_z()-1;
- for(int i=z;i>=0;i--)
- {
- t=v.get(i);
- //t to hex and save in char s[]
- for(int m=0;m<8;m++)st[m]=' ';
- sprintf(st,"%X",t);
- l=(unsigned)strlen(st);
- if(l!=8)
- {
- for(int m=0;m<8;m++)st[m]='0';
- sprintf(st+8-l,"%X",t);
- }
- for(int k=0;k<8;k++)
- {
- if(st[k]==' ')st[k]='0';
- s[j]=st[k];
- j++;
- }
- }
- s[j]=' ';
- ps=s;
- while(*ps=='0')ps++;
- if(*ps==' ')ps--;
- return ps;
- }
- /*
- unsigned* RSA_san::vlong2ints( const vlong& v )
- {
- unsigned z,j;
- j=0;
- z=v.get_z()-1;
- for(int i=z;i>=0;i--,j++)
- {
- u[j]=v.get(i);
- }
- u[j]=0;
- return u;
- }
- */
- char* RSA_san::vlong2shortints( const vlong& v )
- {
- // use this function only when RSA result has no ' ' in it!
- unsigned z,j;
- char *pi;
- j=0;
- z=v.get_z()-1;
- for(int i=z;i>=0;i--,j++)
- {
- u[j]=v.get(i);
- }
- u[j]=0;
- pi=(char *)u;
- while(!*pi)pi++;
- return pi;
- }