📄 elgamal.cpp
字号:
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 + -