⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rsa.cpp

📁 文件包括RSA算法原程序及详细注释。可以实现使用1024位以上大素数进行加解密。其中包括大整数的加、减、乘、除、模幂运算
💻 CPP
字号:
// RSA1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include   <time.h> 
//#include <fstream.h>

#define   MAX  200
#define   GREAT 1
#define   EQUAL 0
#define   LOW    -1
#define   PL 8

typedef struct
    {
	          int	length;
	 unsigned int  n[MAX];
	} Lint;


Lint ZERO,ONE,TWO;

int Init_Lint(Lint *a, int n,unsigned   int value)
  {
	int i;
	if (a==NULL)
	  return (0);
	else
	  {
	   a->length=0;
	   for (i=0;i<MAX;i++)
	   a->n[i]=0;
	   for (i=0;i<n;i++)
	   a->n[i]=value;
	   a->length=n;
       return (1);
       }
  }


void Set_Lint(Lint* a,int n,unsigned int value)
{
 if (a->length < n)
	 a->length =n;
     a->n[n-1]=value; 

}

int Cpy_Lint(Lint * a,Lint* b)
  {
    int i;
    if (a==NULL||b==NULL) return 0;
	if(b->length==0) 
	{Init_Lint(a,0,0);
	 return 1;
	}
    for(i=0;i<MAX;i++)
		a->n[i]=b->n[i];
	a->length=b->length;
	return 1;

  }
int Cpyblock_Lint(Lint * a,int p1, Lint* b,int p2, int n)
  {
    int i;

    if ((a==NULL||b==NULL)||((p2+n-1)>(b->length))||((p1+n-1)>=MAX)) return 0;
    for(i=p1;i<p1+n;i++)
		a->n[i]=b->n[p2+i-p1];
	return 1;

  }




int Split_Lint(Lint * a,Lint* b,int n1,int n2)
 {
  int i; 
  if(n1<1||n2>b->length) return 0;
  
  for (i=n1-1;i<n2;i++)
	a->n[i-n1+1]=b->n[i]; 
  a->length=n2-n1+1; 
  return 1;
 } 




int Cmp_Lint(Lint a,Lint b)
  {
    int i;
	i=a.length;
    while(1)
  { 
	  if ((a.n[i-1]==0 )&&(a.length>1))
       a.length-=1;
    else
       break;
    i--;
 
  } 
  i=b.length;
	while(1)
  { if ((b.n[i-1]==0 )&&(b.length>1))
       b.length-=1;
    else
       break;
    i--;
 
  } 

   if (a.length > b.length )
	   return GREAT;
   if (a.length < b.length )
	   return LOW;
   i=a.length-1;
   while(i>=0)
     {
		 if(a.n[i]>b.n[i]) return GREAT;
         if(a.n[i]<b.n[i]) return LOW;
		 i--;
     }
   if (i<0) return EQUAL;


  } 


void Lint_Add(Lint *a,Lint *b,Lint *c)
{
 unsigned long  temp=0;
 int i=0,carry=0;
 Init_Lint(c,0,0);
 while((i<a->length)&&(i<b->length))
  {
	  temp=a->n[i]+b->n[i]+carry;
      c->n[i]=temp%65536; 
	  carry=temp/65536;
	  i++;
	  c->length=i;
	}
   
  while (i<a->length)
    {
      temp=a->n[i]+carry;
      c->n[i]=temp%65536; 
	  carry=temp/65536;
	  i++;
      c->length=i;
    }
  while (i<b->length)
  {
	  temp=b->n[i]+carry;
      c->n[i]=temp%65536; 
	  carry=temp/65536;
	  i++;
      c->length=i;
   }
 
  if(carry>0)
   {
	   c->n[i]=carry;
	   c->length=i+1;

   }


}

int Lint_Sub(Lint *a,Lint *b,Lint *c)
{
 unsigned long  temp=0;
 int i=0,carry=1;
  Init_Lint(c,0,0);
 if (Cmp_Lint(*a,*b)==LOW)
	 return 0;
 while(i<b->length)
  {
   if(carry==1)
	   temp=a->n[i]-b->n[i]+65536;
   else
	   temp=a->n[i]-b->n[i]+65535;
       c->n[i]=temp%65536; 
	   carry=temp/65536;
	   i++;
       c->length=i;
   
  }

  while (i<a->length)
    {
      if(carry==1)
	   temp=a->n[i]+65536;
      else
	   temp=a->n[i]+65535;
       c->n[i]=temp%65536; 
	   carry=temp/65536;
	   i++;
	   c->length=i;
    }
  
  while(1)
  { if ((c->n[i-1]==0 )&&(c->length>1))
       c->length-=1;
    else
       break;
    i--;
 
  } 
  return 1;
}


void Lint_Mul(Lint *l1,Lint *l2,Lint *c)
{
  int i,j;
  unsigned long  temp1=0,temp2=0,carry=0,m,n;
  Lint *a,*b,a1,b1;
  Cpy_Lint(&a1,l1);
  Cpy_Lint(&b1,l2);
   Init_Lint(c,0,0);
   if (Cmp_Lint(a1,b1)>0)
    {
      a=&b1;
	  b=&a1;
     }
   else
     {
       a=&a1;
	   b=&b1;

     }

  for(i=0;i<a->length;i++)
   {
      
	  for(j=0,carry=0;j<b->length;j++)
      {        

		temp1=a->n[i]*b->n[j]+c->n[i+j]+carry;
        c->n[i+j]=temp1%65536;
        carry=temp1/65536;

       }
      if(carry>0)
	   {
			 c->n[i+b->length]=carry;
	   
	    }
    }
  c->length=a->length+b->length;
  i=c->length;
  while(1)
  { if ((c->n[i-1]==0 )&&(c->length>1))
       c->length-=1;
    else
       break;
    i--;
 
  } 

}

int Lint_Div(Lint *a,Lint *b,Lint *q,Lint* r)
{
  Lint  R1,R2,B1,B2,temp_Lint0,temp_Lint1,temp_Lint2,Q1,Q_Lint,SubB,SubR,d;
  unsigned int i,j,n,Q,k;
  int flag1,flag2;
  unsigned long  temp ;


  Init_Lint(&d,0,0);
  Init_Lint(&R1,0,0);
  Init_Lint(&R2,0,0);
  Init_Lint(&Q1,0,0);
  Init_Lint(&B1,0,0);
  Init_Lint(&B2,0,0);
  Init_Lint(&temp_Lint0,0,0);
  Init_Lint(&temp_Lint1,0,0); 
  Init_Lint(&temp_Lint2,0,0);
  Init_Lint(&Q_Lint,0,0);
  Init_Lint(&SubB,0,0);
  Init_Lint(&SubR,0,0);

  Init_Lint(q,0,0);
  Init_Lint(r,0,0);
 j=a->length-b->length;
  Cpy_Lint(&R1,a);
  Set_Lint(&R1,a->length+1,0);
  Cpy_Lint(&B1,b);
  Cpy_Lint(&B2,b);
  Set_Lint(&d,1,1);
  Set_Lint(&d,1,1);
  
   i=R1.length-1;
   n=B1.length;
   flag1=Cmp_Lint(*b,ZERO);
   if(a==NULL||b==NULL||flag1==0) return 0;
   if(Cmp_Lint(B1,ZERO)==0) return 0;

   
   if(Cmp_Lint(R1,B1)<0)
   {
     Cpy_Lint(q,&ZERO);
     Cpy_Lint(r,a);
     return 1;
   }
    if(Cmp_Lint(R1,B1)==0)
   {
     Cpy_Lint(q,&ONE);
     Cpy_Lint(r,&ZERO);
     return 1;
   }
   while (i>=n)
   {
    if(Cmp_Lint(R1,B1)<=0)
     {
      Q=0;

      }
	else
	 {


   temp=(R1.n[i]*65536+R1.n[i-1])/B1.n[n-1];
   temp=(temp<65535)?temp:65535;
   
   
     if (n==1)
	 {
	 
	 Split_Lint(&SubB,&B1,1,1);
  
     Split_Lint(&SubR,&R1,i,i+1);
	 
	 
	 }

	 else
	 {
     Split_Lint(&SubB,&B1,n-1,n);
  
     Split_Lint(&SubR,&R1,i-1,i+1);
	 }   
   //Q++;
   do
   {
   //Q--;
   Set_Lint( &Q_Lint,1,temp);
   Lint_Mul(&SubB,&Q_Lint,&temp_Lint1);
 
   //Lint_Sub(&SubR,&temp_Lint1,&temp_Lint2);
   flag1=Cmp_Lint(SubR,temp_Lint1);

   Set_Lint( &Q_Lint,1,temp+1);
   Lint_Mul(&SubB,&Q_Lint,&temp_Lint1);
  // Lint_Sub(&SubR,&temp_Lint1,&temp_Lint2);

   flag2=Cmp_Lint(SubR,temp_Lint1);
   if(flag1==0)  {Q=temp;break;}
   if(flag2==0)  {Q=temp+1;break;}
   if(flag1<0&&flag2<0) temp--;
   if(flag1>0&&flag2<0) {Q=temp;break;}
   if(flag1>0&&flag2>0) temp++;

   }
   while(1);

    Set_Lint( &Q_Lint,1,Q);
   
   Split_Lint(&SubR,&R1,i-n+1,i+1);
  
   Lint_Mul(&B1,&Q_Lint,&temp_Lint2);

  // Lint_Sub(&SubR,&temp_Lint2,&temp_Lint0);
     Lint_Sub(&SubR,&temp_Lint2,&temp_Lint0);


  // Cpyblock_Lint(&R1,i-n,&temp_Lint0,1,n+1);
    for(k=0;k<=n;k++)
		R1.n[i-n+k]=temp_Lint0.n[k];
	}

///////////////////////////////////////////////////
   Set_Lint(&Q1,j+1,Q);
   i--;
   j--;
   }
   i=R1.length;
    while(1)
  { if ((R1.n[i-1]==0 )&&(R1.length>1))
       R1.length-=1;
    else
       break;
    i--;
 
  } 
  i=Q1.length;
	while(1)
  { if ((Q1.n[i-1]==0 )&&(Q1.length>1))
       Q1.length-=1;
    else
       break;
    i--;
 
  } 

   Cpy_Lint(r,&R1);
   Cpy_Lint(q,&Q1);
   return 1;


}


int  Mod_Sub(Lint a, Lint b,Lint *c,   Lint *m)
  {
   Lint temp0,temp1;
   if (Cmp_Lint(a,b)>=0)
     {
       Lint_Sub(&a,&b,&temp0);
	   Lint_Div(&temp0,m,&a,c);
     }
   else
   {
       Lint_Sub(&b,&a,&temp0);
	   Lint_Div(&temp0,m,&a,&temp1);
	   if (Cmp_Lint(temp1,ZERO)>0)
         Lint_Sub(m,&temp1,c);
	   else 
	     Cpy_Lint(c,&ZERO);

   }
  return 1;

  }

int  Euclid1(long n,long a,long* v)
{
  
  long u=1,g,v1=0,v3,q,t1=1,t3;
  g=a;
  v3=n;
  if (v3==0) return 0;
  while (v3>0)
  {
  q=g/v3;
  t3=g%v3;
  t1=(u-q*v1%n);
  u=v1;
  v1=t1;
 g=v3;
  
  v3=t3;
  }
  
  *v=u;
  return 1;
	

}

int  Euclid(Lint n,Lint a,Lint *v,Lint *gcd)
{
  
  Lint u,g,v1,v3,q,t1,t3,temp1,temp2,temp3;
  int i;
  Cpy_Lint(&u,&ONE);
  Cpy_Lint(&t1,&ONE);
  Cpy_Lint(&v1,&ZERO);
   Cpy_Lint(&g,&a);  
  Cpy_Lint(&v3,&n);
  i=Cmp_Lint(v3,ZERO);
  if (i==0) return 0;
  while (i>0)
  {
  
  Lint_Div(&g,&v3,&q,&t3);
  Lint_Mul(&q,&v1,&temp1);
  Lint_Div(&temp1,&n,&temp3,&temp2);
  Mod_Sub(u,temp2, &t1, &n);

  Cpy_Lint(&u,&v1); 
  Cpy_Lint(&v1,&t1);
  Cpy_Lint(&g,&v3);
  Cpy_Lint(&v3,&t3);
  i=Cmp_Lint(v3,ZERO);
  }
  
  Cpy_Lint(v,&u);
  Cpy_Lint(gcd,&g);
  return 1;
	

}
int  Mexp_Lint(Lint a,Lint e,Lint* p,Lint m)

{
	unsigned int r,bit[]={1,2,4,8,16,32,64,128,256,512,1024,
		                   2048,4096,8192,16384,32768};
    int i,n,s,t;
	Lint temp0,temp1,temp2;
	Init_Lint(&temp0,0,0);
    Init_Lint(&temp1,0,0);
    Init_Lint(&temp2,0,0);
	if(Cmp_Lint(m,ZERO)==0) return 0;
    if(Cmp_Lint(m,ONE)==0)
	  {
		  Cpy_Lint(p,&ZERO);
		  return 1;
	  }
	else if (Cmp_Lint(a,ZERO)==0)
	   {
         if(Cmp_Lint(e,ZERO)==0)
		   {Cpy_Lint(p,&ONE);
		    return 1;
			}
		 if(Cmp_Lint(e,ZERO)>0)
		   {Cpy_Lint(p,&ZERO);
		    return 1;
			}
	   }
	
	n=e.length*16;
	r=e.n[e.length-1]&bit[15];
	if (r>0)
      Cpy_Lint(p,&a);
	else
      Cpy_Lint(p,&ONE);
	i=n-2;
	while(i>=0)
	 {
	   Lint_Mul(p,p,&temp1);
       Lint_Div(&temp1,&m,&temp0,p);
	  
	   s=(i)/16;
	   t=(i)%16;
	   r=e.n[s]&bit[t];
	   if(r>0)
	     {
	      Lint_Mul(p,&a,&temp0);
		  Lint_Div(&temp0,&m,&temp1,p);
	      
	     }
	   i--;
	 }
  return 1;
}
int  Rand_Lint(Lint *p , int n)
  {
   int i;
   unsigned long a = 65539,b = 65539,seed1,seed0; 
  unsigned long temp;
  unsigned long m = 65536;
   seed1=rand();
  seed0=rand();
  for(i=0;i<n;i++)
  {
    temp= (a * seed1 + b * seed0 ) % m;
	Set_Lint(p,i+1,(unsigned short)temp);

    seed1 = rand();  
	seed0 = temp;
 
  }
  

return 1;

  }
int Isprime(Lint n)
  {
	  int x[4]={2,3,4,5},i;
	  
     Lint  temp0,temp1,temp2;
	 Init_Lint(&temp0,0,0);
     Init_Lint(&temp1,0,0);
     Init_Lint(&temp2,0,0);
	  for(i=0;i<4;i++)
	  {
       Lint_Sub(&n,&ONE, &temp0);
	   Set_Lint(&temp2,1,x[i]);
	    Mexp_Lint( temp2,temp0, &temp1,n);
        if(Cmp_Lint(temp1,ONE)!=0)
			return 0;
	  
	  }
      return 1;

   }
int genprime(Lint *p , int n)
 {
   int i,flage;
   unsigned int primelist[64]={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};
   
   Lint temp0,temp1,temp2,temp3;
   Init_Lint(&temp0,0,0);
   Init_Lint(&temp1,0,0);
   Init_Lint(&temp2,0,0);
   Init_Lint(&temp3,0,0);

   Rand_Lint(&temp0 , n);
   temp0.n[0]=temp0.n[0]|1;
     i=0;
 while(1)
 {
    do 
	{
		flage =0;
        for(i=0;i<64;i++)
		{
		Set_Lint(&temp1,1,primelist[i]);
		Lint_Div(&temp0,&temp1,&temp2,&temp3);
	    if(Cmp_Lint(temp3,ZERO)==0)
		   {
			flage=1;
			break;
		   }
		
		}
        if(flage==1)
           { 
      
            Lint_Add(&temp0,&TWO,&temp1);
            Cpy_Lint(&temp0,&temp1);
   
         }
	}
    while(flage==1);

   if (Isprime(temp0)==1)
    {
     Cpy_Lint(p,&temp0);
     return 1;
    }
   else
	{ 
      
      Lint_Add(&temp0,&TWO,&temp1);
      Cpy_Lint(&temp0,&temp1);
   
     }

 }

}

int reset()
{

   Init_Lint(&ZERO,1,0);
   Init_Lint(&ONE,1,1);
   Init_Lint(&TWO,1,2);
   srand(time(NULL) );
   return 1;



}
int Encrypt(Lint M,Lint e,Lint n,Lint *C)
    {  
    Mexp_Lint(M,e,C,n);
    return 1;
    }

int Decrypt(Lint C,Lint d,Lint n,Lint *M)
    {  
    Mexp_Lint(C,d,M,n);
    return 1;
    }

int genKey(Lint p,Lint q,Lint e,Lint *d,Lint *n)
    {     
		  Lint z,temp;
          Init_Lint(&z,0,0);
          Init_Lint(&temp,0,0);
      
          Lint_Mul(&p,&q,n);
          Lint_Sub(&p,&ONE,&temp);
          Cpy_Lint(&p,&temp);
          Lint_Sub(&q,&ONE,&temp);
          Cpy_Lint(&q,&temp);
          Lint_Mul(&p,&q,&z);
		  Euclid( z, e,d,&temp);
          if (temp.n[0]!=1)
			  return 0;
		  return 1;


     }

int _tmain(int argc, _TCHAR* argv[])
{

	int i,j,k,fp1,fp2,fp3;
	unsigned short num1[42]={30175,45566,1776,26384,23087,7624,28551,
		                     30659,46466,9427,58089,53094,2259,16793,
							 13415,46155,6723,42095,29884,52304,26502,
							 44170,12295,52805,33766,5299,60285,1067,
							 45930,63331,18966,57389,58627,31623,34817,
							 32671,14731,57228,59797,65085,39474,54895},
		           num2[41]={16411,62909,61525,55893,16713,24008,39148,
				             14226,21974,56825,39555,33826,38231,17968,
							 20573,24545,33370,3478,34856,38695,50224,
							 24246,61805,65476,49626,19533,16354,50271,
							 34533,59318,26418,40454,3469,46800,58921,
							 59791,4907,25757,28309,19696,12074};
	Lint C,M,temp,T,t1,t2,t3;
    Lint e,z,d,p,q,n;
	
   Init_Lint(&C,0,0);
   Init_Lint(&M,0,0);
   Init_Lint(&temp,0,0);
   Init_Lint(&e,0,0);
   Init_Lint(&z,0,0);
   Init_Lint(&d,0,0);
   Init_Lint(&p,0,0);
   Init_Lint(&q,0,0);
   Init_Lint(&n,0,0);
  char str[400],select;
    union
    {
      char ch[2*(PL-1)+1];
	 
      unsigned short l[PL-1]; 
     } num,buffer;
	char *filename1="M:\\wp1",*filename2="M:\\wp2",
		*filename3="M:\\wp3";
	reset();
	if((fp1=open( filename1,0))==-1)
   
	 {
       printf("不能打开文件\n");
	   return 0;
	 }
	if((fp2=open( filename2,2))==-1)
   
	 {
       printf("不能打开文件\n");
	   return 0;
	 }
    if((fp3=open( filename3,2))==-1)
   
	 {
       printf("不能打开文件\n");
	   return 0;
	 }

	Set_Lint(&e,1,1);
	Set_Lint(&e,2,1);
	printf("\n****************************************************\n");
	  printf("**                                                **\n");
	  printf("**     1.使用已经生成的密钥进行加解密             **\n");
	  printf("**     2.重新生成密钥进行加解密(需要很长时间)   **\n");
	  printf("**     3.退出该程序                               **\n");
	  printf("****************************************************\n");
   printf("请选择(1、2或3):");
   while(1)
	{
   select=getch();
   printf("%c",select);
    if(select=='1')
	   {
	    for(i=0;i<42;i++)
			  Set_Lint(&p,i+1,num1[i]);

        for(i=0;i<41;i++)
			  Set_Lint(&q,i+1,num2[i]);
		goto ll;

	   }
	else if (select=='2')
	   {
	   genprime(&p ,PL);
        genprime(&q ,PL-1);
        genprime(&e ,2);
      goto ll;

		}
	else if (select=='3')
	   {
	     return 1;
	   }
	else 
	   {
	     printf("\n没有此项!重新选择。");
	     printf("请选择(1、2或3):");
	   }
  }
ll:	
   genKey(p,q,e,&d,&n);
   while(1)
	  { 
	    for(i=0;i<=2*PL-2;i++)
        num.ch[i]='\0';

          j=read(fp1,num.ch,2*(PL-1));
         
		if(j==-1||j==0)
			break;
		k=0;
		while(num.ch[k]!='\0')
			k++;
		
		for (j=k;j<2*(PL-1)+1;j++)
		  num.ch[j]='\0';
		Init_Lint(&M,0,0);
		for(i=0;i<(k+1)/2;i++)
         Set_Lint(&M,i+1,num.l[i]);
         Encrypt(M,e,n,&C);
        Decrypt(C,d,n,&M);
         for(i=0;i<M.length;i++)
            buffer.l[i]=M.n[i];
            buffer.ch[2*M.length]='\0';

            write(fp2,buffer.ch,2*M.length);
		  printf("%s",buffer.ch);


	  }
      return 1;


}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -