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) ;
int menu(); /* 菜单函数 */
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)
  {
     switch(menu())
     {
       case 1: en_de_code();
               break;
       case 2: explay_rsa();
               break;
       case 3: display_rsa();
       case 4: exit(-1);
       default:
               printf("Enter error,please again!");
               fflush(stdin);
               getchar();
     }/* switch end */
  }/* while end */
  getch();
}

/*------------------------------------------*/
int menu() /* 主菜单 */
{
    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");

    printf("/nPlease enter your choice(1,2,3,4):/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;
    printf("/nPlease enter your text to code:/n");
    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");
    printf("Please enter 100/1000: ");
    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,否则
返回0。n是待测素数。注意:通过测试并不一定就
是素数,非素数通过测试的概率是1/4  */
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;
}
/*===================================================================*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值