# MY_RSA PROGRAM(demo)

/********************************************************************/
/*                                                                                                              */
/*                  MY_RSA PROGRAM(demo)                                          */
/*                  Author:lixiongwei                                                             */
/*                  Time: 5/14/2006 Sun.                                                     */
/*                  Chang'an University Computer lab.                            */
/*                  WIN XP+(TC/Win_TC/VC++6.0)                                   */
/*                                                                                                              */
/********************************************************************/

#include "stdlib.h"
#include "stdio.h"
#include "math.h"
/*=========================variable area======================================*/
typedef struct  rsa_temp
{
unsigned long int f;
unsigned long int n;
unsigned int e;
unsigned int d;
}rsa_pt; /*定义函数参数结构体*/

unsigned long int n;
unsigned long int f; /* f=(p-1)*(q-1)，不参与加密解密运算 */
int e; /*公匙，n=p*q，gcd(e,f)=1*/
int d; /*私匙，e*d=1 (mod f)，gcd(n,d)=1*/

unsigned int p,q; /*两个素数 */
unsigned long int s; /* 块长，满足2^s<=n的最大的s，即log2(n)  */

const static   g_PrimeTable[]=
{ 3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97 }; /*小素数表*/

const static int  l_PrimeTable[]=
{2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,
107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,
223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,
337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,
457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,
593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,
719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,
857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,
997};

const static  g_PrimeCount=sizeof(g_PrimeTable) / sizeof(int);
const static  l_PrimeCount=sizeof(l_PrimeTable) / sizeof(int);
/*==========================function antetype==================================*/
void build_rsa_param(unsigned int x, unsigned int y, rsa_pt *my_temp);

int gcd(unsigned long int,unsigned long int);
unsigned power(unsigned,unsigned,unsigned long);

void convert_16_to_8(unsigned int *a,unsigned char *b);
void convert_8_to_16(unsigned char *b,unsigned int *a);

void coder(unsigned char *original_str, unsigned int *encrypted_data,
unsigned int *decrypted_data) ;
void decoder(unsigned char *original_str, unsigned int *encrypted_data,
unsigned int *decrypted_data) ;
void en_de_code(); /*菜单一：RSA 加密解密函数*/
void explay_rsa(); /*菜单二：演示 p,q 的计算函数*/
void display_rsa();/*菜单三：自动显示一组PQNFED值的函数*/

int prime(int n); /* 判断素数 */
unsigned int random_prime(char bits);  /* 产生素数 */
long int rabin_miller(unsigned long int n, unsigned long int loop);/* 素数测试函数*/
long int RabinMillerKnl(unsigned long int n);/* 素数测试函数 */
unsigned long int EuclidGcd(unsigned long int p, unsigned long int q);
unsigned long int Euclid(unsigned long int a, unsigned long int b);

/*=================================MAIN=======================================*/
main()
{  while(1)
while(1)
{
{
case 1: en_de_code();
break;
case 2: explay_rsa();
break;
case 3: display_rsa();
case 4: exit(-1);
default:
fflush(stdin);
getchar();
}/* switch end */
}/* while end */
getch();
}

/*------------------------------------------*/
{
int ch;

system("cls");
fflush(stdin);

printf("/n================MY_RSA PROGRAM<demo>================/n/n");

printf("1.Encryption and Decryption data./n");
printf("2.Explain RSA(input P,Q return N,F,E,D etc.)/n");

printf("3.Display a group of(P,Q,N,F,E,D)./n");
printf("4.Quit RSA program./n");

scanf("%d",&ch);

return ch;
}
/*=============================function definition=============================*/
void en_de_code()
{
int i;
unsigned char *str;
unsigned char first_data[100];/*保存用户输入数据*/
unsigned int  code_data[100], decode_data[100];
rsa_pt *temp1,temp;
temp1=&temp;

system("cls");

build_rsa_param( random_prime(16),random_prime(16) ,temp1 );/* 初始化过程，自动产生 n,f,e,d,p,q,s*/
printf("/n/n<< n=%lu, f=%lu,e=%d, d=%d>>/n/n",temp1->n,temp1->f,temp1->e,temp1->d);

/*调用 random_prime 生成2个素数*/

str= (unsigned char *)first_data;
scanf("%s",str);

printf("******************************************************/n");

coder(str, code_data, decode_data) ;
printf("/nAfter encrypt data is:/n%s", str);
printf("/nAfter encrypt data<hex> is:/n");
for(i=0; i<strlen(str); i++)
printf("%0x ",str[i] );

decoder(str, code_data, decode_data) ;
printf("/n/n/nAfter decry data is:/n%s",str);
printf("/nAfter decrypt data<hex> is:/n");
for(i=0; i<strlen(str); i++)
printf("%0x ",str[i] );

printf("/n/n/nOperation is over,press any key restart.../n");
printf("*****************************************************/n");

printf("/n%c,%c",power(23,e,n),power(23,d,n));

getch();
}

/*------------------------------------------*/
void explay_rsa() /* 用来演示RSA算法..............*/
{
int i=0,j=0;
unsigned my_p,my_q;

rsa_pt *temp2,temp;

temp2=&temp;
system("cls");

while(1)
{
i++;

printf("/nPlease enter two prime (my_p and my_q):/n");
scanf("%d %d",&my_p,&my_q);

if(prime(my_p) && prime(my_q))
{
printf("Very good,your enter two numbers is both prime number./n");
printf("Now program is compute n,f,e,d etc.please wait.... /n");

while(j<=5)
{
build_rsa_param(my_p, my_q, temp2 ); /* 初始化过程，自动产生 n,f,e,d,s*/
printf("/n/n<< n=%lu, f=%lu,e=%d, d=%d>>/n/n",temp2->n,temp2->f,temp2->e,temp2->d);
j++;
}

getch();
break;
}
else
{
printf("p or q is not a prime number,please again./n");
if(i>=3)
break;
}
} /* while end */

}

void display_rsa()
{
int i=0,flag=0;
unsigned my_p=3,my_q=3;

rsa_pt *temp3,temp;
temp3=&temp;

system("cls");

printf("Your want to display (P,Q)<100 or (P,Q)<1000?/n");
scanf("%d",&flag);

while(1)
{
i++;
if(flag==100)
{
my_p=g_PrimeTable[random(g_PrimeCount)];
my_q=g_PrimeTable[random(g_PrimeCount)];

}
else
{
my_p=l_PrimeTable[random(l_PrimeCount)];
my_q=l_PrimeTable[random(l_PrimeCount)];

}

if(my_p==my_q) continue;

printf("Now program is compute n,f,e,d etc.please wait.... /n");
build_rsa_param(my_p, my_q, temp3 ); /* 初始化过程，自动产生 n,f,e,d,s*/
printf("/n/n<< n=%lu, f=%lu,e=%d, d=%d>>/n/n",temp3->n,temp3->f,temp3->e,temp3->d);
getch();

if(i>=100) break;
} /* while end */

}
/*------------------------------------------*/
void build_rsa_param(unsigned int x, unsigned int y, rsa_pt *my_temp) /*产生公钥*/
{

unsigned int t;

/*随机生成两个素数*/
/* p=random_prime(16);
q=random_prime(16);
*/
p=x; q=y;
n=p * q;
f=(p - 1) * (q - 1);

do
{
e=random(65536);  /* 小于2^16，65536=2^16 */
e|=1;             /* 保证最低位是1，即保证是奇数，因f一定是偶数，要互素，只能是奇数 */
}while(EuclidGcd(e, f) != 1);

d=Euclid(e, f);

s=0;     /* s=log2(n) */
t=n >> 1;

while(t)
{
s++;
t>>=1;
}

printf("/n/n<<----------------p=%u, q=%u----------------->>",p,q);
my_temp->n=n;
my_temp->f=f;
my_temp->d=d;
my_temp->e=e;
}

/*------------------------------------------*/
/* 随机生成一个bits位(二进制位)的素数，最多32位 */
unsigned int random_prime(char bits)
{
unsigned  int    base;
do
{
base= (unsigned)1 << (bits - 1);   /*保证最高位是1*/
base+=random(base);               /*再加上一个随机数*/
base|=1;    /*保证最低位是1，即保证是奇数*/
} while(!rabin_miller(base, 30));    /*进行拉宾－米勒测试30次*/
return base;    /*全部通过认为是素数*/
}

/*------------------------------------------*/
unsigned long int EuclidGcd(unsigned long int p, unsigned long int q)
{
unsigned long int    a=p > q ? p : q;
unsigned long int   b=p < q ? p : q;
unsigned long int   t;
if(p == q)
{
return p;   /* 两数相等，最大公约数就是本身 */
}
else
{
while(b)    /* 辗转相除法，gcd(a,b)=gcd(b,a-qb) */
{
a=a % b;
t=a;
a=b;
b=t;
}
return a;
}

}

/*------------------------------------------*/
/* 已知a、b，求x，满足a*x =1 (mod b) 相当于求解a*x-b*y=1的最小整数解 */
unsigned long int Euclid(unsigned long int a, unsigned long int b)
{
unsigned long int    m, e, i, j, x, y;
long int    xx, yy;
m=b;
e=a;
x=0;
y=1;
xx=1;
yy=1;

while(e)
{
i=m / e;
j=m % e;
m=e;
e=j;
j=y;
y*=i;

if(xx == yy)
{
if(x > y)
{
y=x - y;
}
else
{
y-=x;
yy=0;
}
}
else
{
y+=x;
xx=1 - xx;
yy=1 - yy;
}
x=j;

}

if(xx == 0)
{
x=b - x;
}
return x;
}

/*------------------------------------------*/
void convert_8_to_16(unsigned char *b,unsigned int *a)
{
int i;
for(i=0;i<100;i++)

a[i]=b[2*i]*256+b[2*i+1];
/* text_16[i]=text_8[2*i]*256+text_8[2*i+1];*/
}

/*------------------------------------------*/
void convert_16_to_8(unsigned int *a,unsigned char *b)
{
int i=0,flag=0;
unsigned int temp;

while(i<200&&flag<100)
{
temp=a[flag]/256;
b[i]=temp;
b[i+1]=a[flag]%256;
i+=2;
flag++;
}
}

/*------------------------------------------*/
void coder(unsigned char *original_str, unsigned int *encrypted_data, unsigned int *decrypted_data)  /* 对所给数据加密*/
{
int i;
i=0;
convert_8_to_16(original_str, decrypted_data);

while(decrypted_data[i]!=0)
{
encrypted_data[i]=power(decrypted_data[i],e,n);
i++;
}
convert_16_to_8(encrypted_data,original_str);
}

/*------------------------------------------*/
void decoder(unsigned char *original_str, unsigned int *encrypted_data, unsigned int *decrypted_data) /* 对所给数据解密*/
{
int i;
i=0;
while(encrypted_data[i]!=0)
{
decrypted_data[i]=power(encrypted_data[i],d,n);
i++;
}
convert_16_to_8(decrypted_data,original_str);
}

/*------------------------------------------*/
unsigned power(unsigned a,unsigned b,unsigned long c)   /*The power,you can get a,b,c*/
{
unsigned long z=1,t;
for(t=a;b>0;b>>=1)
{
if(b%2==1)z=(z*t)%c;
t=(t*t)%c;
}
return z;
}

/*------------------------------------------*/
/*  Rabin-Miller素数测试，通过测试返回1，否则

long int RabinMillerKnl(unsigned long int n)
{
unsigned long int    b, m, j, v, i;
m=n - 1;
j=0;    /* 0、先计算出m、j，使得n-1=m*2^j，其中m是正奇数，j是非负整数*/
while(!(m & 1))
{
++j;
m>>=1;
}    /*1、随机取一个b，2<=b<n-1*/
b=2 + random(n - 3);    /*2、计算v=b^m mod n*/
v=power(b, m, n);    /*3、如果v==1，通过测试*/
if(v == 1)
{
return 1;
}    /*4、令i=1  */
i=1;    /*5、如果v=n-1，通过测试*/
while(v != n - 1)
{
/*6、如果i==l，非素数，结束*/
if(i == j)
{
return 0;
}        /*7、v=v^2 mod n，i=i+1*/
v=power(v, 2, n);
++i;        /*8、循环到5*/
}    return 1;
}

/*------------------------------------------*/
/*Rabin-Miller素数测试，循环调用核心loop次全部通过返回1，否则返回0 */
long int rabin_miller(unsigned long int n, unsigned long int loop)
{

/* 先用小素数筛选一次，提高效率 */
long int i;
for(i=0; i < g_PrimeCount; i++)
{
if( n%g_PrimeTable[i] == 0)  /* 这里修改 */
{
return 0;
}
}

/*循环调用Rabin-Miller测试loop次，使得非素数通过测试的概率降为(1/4)^loop*/
for(i=0; i < loop; i++)
{
if(!RabinMillerKnl(n))
{
return 0;
}
}    return 1;

}

/*------------------------------------------*/
int prime(int n) /* 判断素数 */
{
int i,k;
k=sqrt(n);
for(i=2;i<=k;i++)
if(n%i==0) break;
if(i>k) return 1 ;
else return 0;
}
/*===================================================================*/

• 本文已收录于以下专栏：

举报原因： 您举报文章：MY_RSA PROGRAM(demo) 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)