sm3算法c语言实现
/*
2017.9.24 am 10:00 -11:50
2017.9.24 pm 14:00-17:00 19:00-23:00
2017.9.25 pm 14:00-17:30
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
unsigned int w0[70],w1[70];//用于压缩函数cf
//0-8用来表示A-H
unsigned int memory[8]={0x7380166f,0x4914b2b9,0x172442d7,0xda8a0600,0xa96f30bc,0x163138aa,0xe38dee4d,0xb0fb0e4e};
unsigned int memory1[8]={0x7380166f,0x4914b2b9,0x172442d7,0xda8a0600,0xa96f30bc,0x163138aa,0xe38dee4d,0xb0fb0e4e};
unsigned int T[64]={0};
//将四个字符压缩成1个32位的整数存储
unsigned int chars_unit32(unsigned int n,char b[],int i)
{
(n) = ( (unsigned int) (b)[(i) ] << 24 )
| ( (unsigned int) (b)[(i) + 1] << 16 )
| ( (unsigned int) (b)[(i) + 2] << 8 )
| ( (unsigned int) (b)[(i) + 3] );
return n;
}
//将1个32位的整数存储扩展位四个字符
void unit32_chars(unsigned int n,char b[],int i)
{
b[i ] = (char) ((n)>>24);
b[i+1] = (char) ((n)>>16);
b[i+2] = (char) ((n)>>8 );
b[i+3] = (char) ((n) );
}
//将n循环左移m位
unsigned int Rol(unsigned int n,int m)
{
n=((n)<<m)|(n>>(32-m));
return n;
}
//P0函数
unsigned int P0(unsigned int x)
{
x=x^Rol(x,9)^Rol(x,17);
return x;
}
//p1函数
unsigned int P1(unsigned int x)
{
x=x^Rol(x,15)^Rol(x,23);
return x;
}
//填充
//len1表示mes数组的长度
//len2表示消息的bit数 eg:b="abc",则mes[0]=0x616263,len2=24
void full(unsigned int mes[],unsigned int len1,unsigned int len2)
{
// printf("\nlen1=%d len2=%d\n",len1,len2);
if((len2%32)!=0)
mes[len1-1]=mes[len1-1]|(1<<(32-len2%32-1));
else
mes[len1]=mes[len1]|(1<<(32-len2%32-1));
mes[15+(len2/512)*16]=mes[15+(len2/256)*16]+len2;
}
//消息扩展
void extends(unsigned int w0[],unsigned int w1[],unsigned int mes[])
{
int i;
for(i=0;i<16;i++)
w0[i]=mes[i];
for(i=16;i<68;i++)
{
w0[i]=P1(w0[i-16]^w0[i-9]^Rol(w0[i-3],15))^Rol(w0[i-13],7)^w0[i-6];
}
printf("扩展后的消息:\n");
printf("W[0]-W[67]:\n");
for(i=0;i<68;i++)
{
printf("%08x ",w0[i]);
if((i+1)%8==0)
printf("\n");
}
for(i=0;i<64;i++)
w1[i]=w0[i]^w0[i+4];
printf("\nW'[0]-W'[63]:\n");
for(i=0;i<64;i++)
{
printf("%08x ",w1[i]);
if((i+1)%8==0)
printf("\n");
}
}
//FF函数
unsigned int FF(unsigned int x,unsigned int y,unsigned int z,int j)
{
if(j>=0&&j<=15)
return (x^y^z);
else if(j>=16&&j<=63)
return ((x&y)|(x&z)|(y&z));
}
//GG
unsigned int GG(unsigned int x,unsigned int y,unsigned int z,int j)
{
if(j>=0&&j<=15)
return (x^y^z);
else if(j>=16&&j<=63)
return ((x&y)|((~(x))&z));
}
void cf(unsigned int memory[],unsigned int w0[],unsigned int w1[])
{
int j,i;
unsigned int ss1,ss2,tt1,tt2;
for(j=0;j<=63;j++)
{
ss1 = Rol(Rol(memory[0],12)+memory[4]+Rol(T[j],j),7);
// printf("ss1=%08x ",ss1);
ss2 = ss1^Rol(memory[0],12);
tt1 = FF(memory[0],memory[1],memory[2],j)+memory[3]+ss2+w1[j];
tt2 = GG(memory[4],memory[5],memory[6],j)+memory[7]+ss1+w0[j];
memory[3] = memory[2];
memory[2] = Rol(memory[1],9);
memory[1] = memory[0];
memory[0] = tt1;
memory[7] = memory[6];
memory[6] = Rol(memory[5],19);
memory[5] = memory[4];
memory[4] = P0(tt2);
printf("\n");
printf("%2d %08x",j,memory[0]);
for(i=1;i<8;i++)
printf(" %08x",memory[i]);
printf("\n");
}
}
int main()
{
//b用来接受输入的字符串
//n用来表示循环左移的位数
//mes用来表示输入数据的ascii码值 eg:b="abc",则mes[0]=0x616263
//len表示b长度
//len1表示mes数组的长度
//len2表示消息的bit数 eg:b="abc",则mes[0]=0x616263,len2=24
FILE * fp1,*fp2;
char * b;
unsigned int n,mes[500],len,len1,len2;
int i,j;
if((fp1=fopen("input.txt","r"))==NULL)
{
printf("cannot open input.txt\n");
return 0;
}
freopen("output.txt","w",stdout);
fseek(fp1,0,SEEK_END);
len=ftell(fp1);
b= new char[len+1];//定义数组的长度
rewind(fp1);//把指针移到文件的开头
fgets(b,len+1,fp1);
//b[len]='/0';//把文件的最后一位写为0
printf("输入消息为:\n");
printf("%s\n",b);
len2=len*8;
memset(mes,0,sizeof(mes));
memset(w0,0,sizeof(w0));
memset(w1,0,sizeof(w1));
j=0;
for(i=0;i<len;i=i+4,j++)
{
mes[j]= chars_unit32(mes[j],b,i);
}
len1=j;
printf("其ASCII码为:\n");
for(i=0;i<len1;i++)
printf("%x",mes[i]);
full(mes,len1,len2);
printf("\n填充后的消息\n");
for(i=0;i<16+(len2/512)*16;i++)
{
printf("%08x ",mes[i]);
if((i+1)%8==0)
printf("\n");
}
for(int k=0;k<(len2/512)+1;k++)
{
printf("第%d个分组\n",k+1);
extends(w0,w1,mes+(k*16));
printf("迭代压缩中间值\n");
printf("j A B C D E F G H \n");
printf(" %08x %08x %08x %08x %08x %08x %08x %08x\n",memory[0],memory[1],memory[2],memory[3],memory[4],memory[5],memory[6],memory[7]);
for(j=0;j<=15;j++)
T[j]=0x79cc4519;
for(j=16;j<=63;j++)
T[j]=0x7a879d8a;
cf(memory,w0,w1);
for(i=0;i<8;i++)
{
memory[i]=memory[i]^memory1[i];
memory1[i]= memory[i];
}
}
printf("杂凑值:\n");
for( i=0;i<8;i++)
printf("%8x ",memory[i]);
printf("\n");
fclose(fp1);
return 0;
}