?? rsa_san.cpp
字號:
#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]=='\0')
{
p[1]=p[0];
p[0]='0';
}
p+=2;
}
*p='\0';
return ps;
}
char* RSA_san::hexstring2string(char * h)
{
// if hexstring has 0 byte in it ,...be careful about '\0'
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]='\0';
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]='\0';
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]='\0';
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]=='\0')st[k]='0';
s[j]=st[k];
j++;
}
}
s[j]='\0';
ps=s;
while(*ps=='0')ps++;
if(*ps=='\0')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 '\0' 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;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -