📄 sha-1.c
字号:
/*
a C program for the "SHA-1"
Use "SHA-1" to compute the digest for the file "a.txt" in current directory
created by yaolei
2005-4-13
*/
#include <STDIO.H>
/*********************************Global var used to save the digest*/
/*state[0] = A, state[1] = B, state[2] = C, state[3] = D, state[4] = E*/
unsigned int state[5];
/*********************************Define the function used in SHA-1*/
unsigned int f1(unsigned int B, unsigned int C, unsigned int D)
{
return (B&C)|(~B&D);
}
unsigned int f2(unsigned int B, unsigned int C, unsigned int D)
{
return B^C^D;
}
unsigned int f3(unsigned int B, unsigned int C, unsigned int D)
{
return (B&C)|(B&D)|(C&D);
}
unsigned int f4(unsigned int B, unsigned int C, unsigned int D)
{
return B^C^D;
}
/*********************************Init the global var unsigned int state[5]*/
void Init()
{
state[0] = 0x67452301;
state[1] = 0xefcdab89;
state[2] = 0x98badcfe;
state[3] = 0x10325476;
state[4] = 0xc3d2e1f0;
}
/*********************************the end of the function*/
/*********************************the function used to compute the 80 loops and save the result into the global var state[]*/
void shaTran(unsigned char * buf,unsigned int * state)
{
int i,j;
unsigned int A,B,C,D,E,temp; /*the Register "A,B,C,D,E" and temp*/
unsigned int K[4]; /*the K[t] used in SHA-1*/
unsigned int W[80]; /*the W[t] used in SHA-1*/
unsigned char * p = (unsigned char *)W; /*the (unsigned char *)p point to W[0]*/
/*********************************init the Register "A,B,C,D,E"*/
A = state[0];
B = state[1];
C = state[2];
D = state[3];
E = state[4];
/*********************************init K*/
K[0] = 0x5a827999;
K[1] = 0x6ed9eba1;
K[2] = 0x8f1bbcdc;
K[3] = 0xca62c1d6;
/*********************************compute W[t]*/
/*compute W[t] 0<=t<=15*/
/*++++++++++++++++++++++++++++++++
Notice that
The IA32 System use little-endian to save data in Main Memory
So change the sequence before use it
++++++++++++++++++++++++++++++++*/
for(i=0;i<16;i++)
{
j = 4*i;
p[j+3] = buf[j];
p[j+2] = buf[j+1];
p[j+1] = buf[j+2];
p[j] = buf[j+3];
}
/*compute W[t] 16<=t<=79*/
for(i=16;i<80;i++)
{
W[i] = ((W[i-16]^W[i-14]^W[i-8]^W[i-3])<<1) | ((W[i-16]^W[i-14]^W[i-8]^W[i-3])>>31);
}
/*********************************compute 1st loop*/
for(i=0;i<20;i++)
{
temp = E + f1(B,C,D) + ((A<<5)|(A>>27)) + W[i] + K[0];
E = D;
D = C;
C = (B<<30)|(B>>2);
B = A;
A = temp;
}
/*********************************compute 2nd loop*/
for(i=20;i<40;i++)
{
temp = E + f2(B,C,D) + ((A<<5)|(A>>27)) + W[i] + K[1];
E = D;
D = C;
C = (B<<30)|(B>>2);
B = A;
A = temp;
}
/*********************************compute 3rd loop*/
for(i=40;i<60;i++)
{
temp = E + f3(B,C,D) + ((A<<5)|(A>>27)) + W[i] + K[2];
E = D;
D = C;
C = (B<<30)|(B>>2);
B = A;
A = temp;
}
/*********************************compute 4th loop*/
for(i=60;i<80;i++)
{
temp = E + f4(B,C,D) + ((A<<5)|(A>>27)) + W[i] + K[3];
E = D;
D = C;
C = (B<<30)|(B>>2);
B = A;
A = temp;
}
/*********************************add the vars back into the global var state[]*/
state[0] += A;
state[1] += B;
state[2] += C;
state[3] += D;
state[4] += E;
}
/*********************************the end of the function*/
/*********************************the function used to padding*/
void sha(unsigned char *buf, int len, unsigned int * state, unsigned int f1,unsigned int f2)
{
int i;
unsigned int floop1,floop2; /*use floop1:floop2 to represent the length of the file in bit*/
unsigned char flen[8]; /*use unsigned char flen[8] to transform the floop1:floop2 in last block*/
unsigned char *p1 = (unsigned char *)&floop1;
unsigned char *p2 = (unsigned char *)&floop2;
floop1 = f1;
floop2 = f2;
floop2 = floop2 + (unsigned int)(len*8); /*add the last block's length(in bit)*/
/*********************************compute the whole file's length*/
/*compute the length of the file and save it into unsigned char flen[8]*/
/*++++++++++++++++++++++++++++++++
Notice that
The IA32 System use little-endian to save data in Main Memory
So change the sequence before use it
++++++++++++++++++++++++++++++++*/
printf("floop1 = %08x\n",floop1);
printf("floop2 = %08x\n",floop2);
for(i=0; i<4; i++)
{
flen[3-i] = *p1;
flen[7-i] = *p2;
p1++;
p2++;
}
/*********************************do the padding*/
/*the file's length(bit) < 448 */
if(len<56)
{
/*pad it like 1000000...(bit) from the end(buf[len-1]) to the buf[55]*/
buf[len] = 0x80;
for(i=len+1; i<56; i++)
{
buf[i] = 0x00;
}
/*pad the last 64bit using flen[8](the length of the file computed before)*/
for(i=56; i<64; i++)
{
buf[i] = flen[i-56];
}
/*then call the function "shaTran" to do the loop*/
shaTran(buf,state);
}
/*the file's length(bit) >= 448 */
else
{
/*pad the 1st block with a number of bit 100000... until the end of the buf(buf[63])*/
buf[len] = 0x80;
for(i=len+1; i<64; i++)
{
buf[i] = 0x00;
}
/*call the function "shaTran" to do the loop*/
shaTran(buf,state);
/*pad the 1st block with a number of bit 000000... until the 448 bit(buf[55])*/
for(i=0; i<56; i++)
buf[i] = 0x00;
/*pad the last 64bit using flen[8](the length of the file computed before)*/
for(i=56; i<64; i++)
{
buf[i] = flen[i-56];
}
/*call the function "shaTran" to do the loop*/
shaTran(buf,state);
}
}
/*********************************the end of the function*/
int main()
{
unsigned char buf[64]; /*the input block of SHA-1*/
FILE * file;
int len; /*used to save the length of one read from the file (byte)*/
unsigned int floop1,floop2; /*use floop1:floop2 to represent the length of the file in bit*/
floop1 = floop2 = 0; /*at 1st make them equal 0*/
/*********************************Init the global var*/
Init();
/*********************************can not open file error*/
if (!(file = fopen("a.txt", "rb")))
{
printf("can not open file!!!\n");
return -1;
}
/*********************************read data from the file*/
while(!feof(file))
{
/*********************************each time read 64 bits into buf at most*/
len=fread(buf,1,64,file);/*len used to save the length of each read*/
/*********************************read file error*/
if(ferror(file))
{
printf("read file error!!!\n");
return -1;
}
/*********************************the buf[64] is full*/
if(len == 64)
{
/*use 2 unsigned int to represent 1 64bit number, floop1:floop2*/
if((floop1 == 0xffffffff) && (floop2 == 0xfffffe00))
{
printf("file larger than 2exp(64)");
return -1;
}
if(floop2 != 0xfffffe00)floop2+=512;
else
{
floop1++;
floop2 = 0;
}
/*call the function "shaTran" to do the loop*/
shaTran(buf,state);
}
/*********************************less than 512 bits need to pad*/
else
{
/*call the function "sha" to do the padding and other compute*/
sha(buf,len,state,floop1,floop2);
}
}
/*********************************print the digest*/
printf("%08x %08x %08x %08x %08x\n",state[0],state[1],state[2],state[3],state[4]);
getchar();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -