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

📄 elgamal.cpp

📁 本项目实现Elgalma体制的加解密
💻 CPP
📖 第 1 页 / 共 2 页
字号:

	for(i=60;i<80;i++)  //第四轮
	{
		temp=E+f4+((A<<5)|(A>>27))+W[i]+K[3];
		E=D;D=C;
		C=(B<<30)|(B>>2);
		B=A;A=temp;
	}

	buffer[0]+=A;  //第四轮的输出与第一轮的输入相加
    buffer[1]+=B;
    buffer[2]+=C;
    buffer[3]+=D;
    buffer[4]+=E;
}

void Sha(char *inflie,char *hashfile)  //实现SHA-1算法的函数
{
	int i;
	unsigned char Message[64];  //512bits信息
	__int64 len,L,k;  
    FILE *in,*hashValue;

	if((in=fopen(inflie,"rb"))==NULL)
	{
		printf("Can not open file!\n");
		exit(0);
	}
	if((hashValue=fopen(hashfile,"wb"))==NULL)
	{
		printf("Can not open file!\n");
		exit(0);
	}
	//---------------获取消息的长度len-----------------------
	fseek(in,0,SEEK_END);  //把文件的位置指针移到文件尾
	len=ftell(in);
	fseek(in,0,SEEK_SET);
    k=len/64;
	L=len-64*k;

	Init();  //初始化缓冲区数据
    for(i=0;i<k;i++)  //先处理前k个512组数据
	{
		fread(Message,1,64,in); 
		Compress(Message);
	}
	//--------------------------处理附加信息---------------------------
	fread(Message,1,64,in);  
	if(L<56)  //添加附加信息,当消息长度小于448bits时
	{
		Message[L]=0x80;   //补充第一位为1
	    for(i=L+1;i<56;i++)
			Message[i]=0x00;  //其余为0
		//---------将原来未加附加位的信息的长度存入一组64bit存在最后------
	    Message[56]=(len&0xFF00000000000000)<<56;
	    Message[57]=(len&0x00FF000000000000)<<48;
	    Message[58]=(len&0x0000FF0000000000)<<40;
	    Message[59]=(len&0x000000FF00000000)<<32;
	    Message[60]=(len&0x00000000FF000000)<<24;
	    Message[61]=(len&0x0000000000FF0000)<<16;
	    Message[62]=(len&0x000000000000FF00)<<8;
	    Message[63]=(len&0x00000000000000FF);
		Compress(Message);
	}
	else  //当消息长度大于或等于448bits时
	{
		Message[L]=0x80;//补充第一位为1
		for(i=L+1;i<64;i++)
			Message[i]=0x00; //其余为0
		Compress(Message);
		//需要另外补充512bit
		for(i=0;i<56;i++)   //前448bit补0
			Message[i]=0x00;
		//---------将原来未加附加位的信息的长度存入一组64bit存在最后------
		Message[56]=(len&0xFF00000000000000)<<56;
	    Message[57]=(len&0x00FF000000000000)<<48;
	    Message[58]=(len&0x0000FF0000000000)<<40;
	    Message[59]=(len&0x000000FF00000000)<<32;
	    Message[60]=(len&0x00000000FF000000)<<24;
	    Message[61]=(len&0x0000000000FF0000)<<16;
	    Message[62]=(len&0x000000000000FF00)<<8;
	    Message[63]=(len&0x00000000000000FF);
		Compress(Message);
	}
	fprintf(hashValue,"%08x %08x %08x %08x %08x",buffer[0],buffer[1],buffer[2],buffer[3],buffer[4]);  //将最后得到的H(m)存入文件中
	fclose(in);
	fclose(hashValue);
}

//*------------------------------------------------------------------------*
//*----------------------------数据签名及认证------------------------------*
//*------------------------------------------------------------------------*
unsigned int gcd(unsigned int a,unsigned int b)   //用辗转相除法(扩展欧几里德算法)求a和b的最大公约数的函数(a>b)
{
	unsigned int r;  
	r=a%b;   //此算法根据:gcd(a,b)=gcd(b,r); 
	while(r!=0)  
    {
		a=b;
        b=r;
        r=a%b;
    }
    return b;  //当r=0时,说明a是b的倍数,则b即为他们的最大公约数
}

void Signature(char *infile,char *outfile,unsigned int r,unsigned int g,unsigned int p)
{
	FILE *in,*out;
	int temp[MAX],t[MAX];
	unsigned int s,sf,W,V,m,k;
    if((in=fopen(infile,"rb"))==NULL)
	{
		printf("Can not open the file!\n");
		exit(0);
	}
    if((out=fopen(outfile,"wb"))==NULL)
	{
		printf("Can not open the file!\n");
		exit(0);
	}

    s=3;  //取s
	while(gcd(s,p-1)!=1)
        s++;
	toBinary(s,temp);
	W=Mod(temp,g,p); //计算W=g^s mod p
	sf=getInverse(s,(p-1));	 //计算s的逆元
	fwrite(&W,4,1,out);
	fscanf(in,"%08x %08x %08x %08x %08x",&buffer[0],&buffer[1],&buffer[2],&buffer[3],&buffer[4]);
	for(i=0;i<5;i++)
	{
		m=buffer[i];
        V=(unsigned __int64)sf*((unsigned __int64)m+p-1-(unsigned __int64)r*(unsigned __int64)W)%(p-1);
		fwrite(&V,4,1,out);
	}
    fclose(out);
    fclose(in);
}

void Authentication(char *infile,char *outfile,unsigned int k,unsigned int g,unsigned int p)
{
    FILE *in,*out;
	int tempw[MAX],tempm[MAX],tempv[MAX];
	unsigned int s,W,V,left,right,m;
    if((in=fopen(infile,"rb"))==NULL)
	{
		printf("Can not open the file!\n");
		exit(0);
	}
    if((out=fopen(outfile,"rb"))==NULL)
	{
		printf("Can not open the file!\n");
		exit(0);
	}
	fscanf(in,"%08x %08x %08x %08x %08x",&buffer[0],&buffer[1],&buffer[2],&buffer[3],&buffer[4]);
	fread(&W,4,1,out);
	toBinary(W,tempw);
    for(i=0;i<5;i++)
	{
		m=buffer[i];
		fread(&V,4,1,out);
		toBinary(m,tempm);
		toBinary(V,tempv);
        left=Mod(tempm,g,p);  //左边=g^m mod p
		right=(unsigned __int64)Mod(tempw,k,p)*(unsigned __int64)Mod(tempv,W,p)%p; //右边=k^w * W^v mod p
		if(left!=right)
		{
			printf("Signature is Wrong!\n");
			exit(0);
		}
	}
	printf("Signature is Right!\n");
}

//*------------------------------------------------------------------------*
//*---------------------------------主函数---------------------------------*
//*------------------------------------------------------------------------*
int main() 
{
	FILE *pri,*pub;
	char infile[13],outfile[13],hashfile[13];
	int temp[MAX];
	unsigned int p,g,x,y,r,k;
	int j;
	i=0;
	while(i!=4)
	{
		printf("---------------------------------Main Interface--------------------------------\n");
	    printf("\t1.Generate keys!\n\t2.Data Encipher and Decipher!\n\t3.Digital Signature!\n\t4.Exit!\n");
	    printf("-------------------------------------------------------------------------------\n");
	    printf("Please choose: ");
	    scanf("%d",&i);
		switch(i)
		{
		case 1:  //生成密钥对
			{
				getKeys();printf("OK!\n");
			}break;
	    case 2:  //进行加解密操作
			{   //判断密钥是否存在
				if((pri=fopen("My.pri","rb"))==NULL||(pub=fopen("My.pub","rb"))==NULL)
				{
					printf("Error!—Keys are Null!\n");break;
				}
			    else //存在则进行加解密操作
				{
					printf("**********Data Encipher and Decipher**********\n");
					printf("   The Message inPath > "); scanf("%s",&infile);
					printf("   The Message outPath> "); scanf("%s",&outfile);
				    printf("\t1.Encipher!\n\t2.Decipher!\n");
					printf("**********************************************\n");
					printf("Please choose: ");
                    scanf("%d",&j);
					if(j==1)  //加密
					{
                        fscanf(pub,"%u,%u,%u",&y,&g,&p);  //公钥加密
						Encipher(infile,outfile,y,g,p);
						printf("OK!\n");
						break;
					}
					else if(j==2) //解密
					{
						fscanf(pri,"%u,%u,%u",&x,&g,&p);  //私钥解密
						Decipher(infile,outfile,x,p);
    
						printf("OK!\n");
						break;
					}
					else  //输入有误
						printf("Error!——Illegal input!\n");break;
				}//end if
			}
		case 3:  //进行签名操作
			{
				if((pri=fopen("My.pri","rb"))==NULL||(pub=fopen("My.pub","rb"))==NULL)
				{
					printf("Error!—Keys are Null!\n");break;
				}
				else
				{
					printf("****************Digital Signature*************\n");
					printf("   The Message inPath   > "); scanf("%s",&infile);
					printf("   The Hash inPath      > "); scanf("%s",&hashfile);
					printf("   The Signature outPath> "); scanf("%s",&outfile);
				    printf("\t1.Signature!\n\t2.Authentication!\n");
					printf("**********************************************\n");
					printf("Please choose: ");
					scanf("%d",&j);
					Sha(infile,hashfile); //生成hash摘要值
				    if(j==1)  //签名
					{
						fscanf(pri,"%u,%u,%u",&x,&g,&p);  //私钥签名
						printf("Please input the Privite key: ");
						scanf("%u",&r);
						toBinary(r,temp);
						k=Mod(temp,g,p);
						printf("The Publick key is: %d\n",k);
						Signature(hashfile,outfile,r,g,p);
						printf("OK!\n");
						break;
					}
					else if(j==2)  //验证签名
					{
						fscanf(pub,"%u,%u,%u",&y,&g,&p);  //公钥验证
						printf("Please input the Publick key: ");
						scanf("%u",&k);
						Authentication(hashfile,outfile,k,g,p);
						printf("OK!\n");
						break;
					}
					else  //输入有误
						printf("Error!——Illegal input!\n");break;
				}//end if
			}
		}//end switch
	}//end while
    fclose(pri);
	fclose(pub);
	return 0;
}

⌨️ 快捷键说明

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