1.頭文件及循環(huán)左移.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SAL(x,n) (((x>>(32-n)))|(x<<n))
2.字符串擴充.
int sha1_pad_message(unsigned char *str, int len)
{
unsigned long high, low;
int u = len % 64;
high = 0;
low = len * 8;
if(u < 56)
{
str[len++] = 0x80;
u++;
while(u < 56)
{
str[len++] = 0x00;
u++;
}
}
else if(u > 56)
{
str[len++] = 0x80;
u++;
while(u < 56+64)
{
str[len++] = 0x00;
u++;
}
}
str[len++] = high >> 24;
str[len++] = high >> 16;
str[len++] = high >> 8;
str[len++] = high;
str[len++] = low >> 24;
str[len++] = low >> 16;
str[len++] = low >> 8;
str[len++] = low;
return len;
}
3.字符串打印.
int print_str(unsigned char *str, int len)
{
int i = 0;
printf("str=[");
for(i=0; i<len; i++)
{
printf("%02X", str[i]);
}
printf("], len=[%d]\n", len);
return 0;
}
4.信息分組處理.
int sha1_str_group_xor(unsigned char *a, unsigned char *b, unsigned char *c, unsigned char *d, unsigned char *e, int len)
{
int i = 0;
for(i=0; i<len; i++)
{
e[i] = a[i] ^ b[i] ^ c[i] ^ d[i];
}
return 0;
}
int sha1_str_group_sal(unsigned char *a, int len)
{
int x = 0;
int y = 0;
int i = 0;
for(i=len-1; i>=0; i--)
{
//printf("a[%d]=%d\n", i, a[i]);
x = a[i] >> 7;
a[i] <<= 1;
//printf("a[%d]=%d\n", i, a[i]);
a[i] |= y;
//printf("a[%d]=%d\n", i, a[i]);
y = x;
}
a[len-1] |= y;
return 0;
}
unsigned long sha1_str_to_long(unsigned char *a)
{
unsigned long x = 0;
unsigned char *b = (unsigned char *)&x;
b[0] = a[3];
b[1] = a[2];
b[2] = a[1];
b[3] = a[0];
return x;
}
int sha1_long_to_str(unsigned long a, unsigned char *b)
{
unsigned long x = a;
unsigned char *d = (unsigned char *)&x;
b[0] = d[3];
b[1] = d[2];
b[2] = d[1];
b[3] = d[0];
return 0;
}
int sha1_str_group(unsigned char *str, int len)
{
unsigned char M[64];
unsigned char W[80][4];
int u = len / 64;
int v = 64 / 16 * 80;
int i = 0;
int j = 0;
for(i=u-1; i>=0; i--)
{
memset(M, 0x00, sizeof(M));
memcpy(M, str+i*64, 64);
memcpy(str+i*v, M, 64);
for(j=0; j<16; j++)
{
memcpy(W[j], M+4*j, 4);
printf("W[%02d], ", j);
print_str(W[j], 4);
}
for(j=16; j<80; j++)
{
sha1_str_group_xor(W[j-3], W[j-8], W[j-14], W[j-16], W[j], 4);
//printf("W[%02d], ", j);
//print_str(W[j], 4);
sha1_str_group_sal(W[j], 4);
printf("W[%02d], ", j);
print_str(W[j], 4);
memcpy(str+i*v+4*j, W[j], 4);
//printf("W[%02d], ", j);
//print_str(W[j], 4);
}
}
return u * v;
}
5.計算信息摘要.
int sha1_str_summ(unsigned char *str, unsigned char *summ, int len)
{
unsigned char W[80][4];
unsigned char Q[20] = {0x67, 0x45, 0x23, 0x01, 0xEF, 0xCD, 0xAB, 0x89, 0x98, 0xBA, 0xDC, 0xFE, 0x10, 0x32, 0x54, 0x76, 0xC3, 0xD2, 0xE1, 0xF0};
unsigned long K[4]={0x5A827999,0x6ED9EBA1,0x8F1BBCDC,0xCA62C1D6};
unsigned long N[5]={0, 0, 0, 0, 0};
unsigned long A = sha1_str_to_long(Q);
unsigned long B = sha1_str_to_long(Q+4);
unsigned long C = sha1_str_to_long(Q+8);
unsigned long D = sha1_str_to_long(Q+12);
unsigned long E = sha1_str_to_long(Q+16);
unsigned long F = 0;
unsigned long G = 0;
unsigned long H = 0;
int u = len / 320;
int i = 0;
int j = 0;
int k = 0;
N[0] += A;
N[1] += B;
N[2] += C;
N[3] += D;
N[4] += E;
for(i=0; i<u; i++)
{
for(j=0; j<80; j++)
{
memcpy(W[j], str+i*320+j*4, 4);
}
A = N[0];
B = N[1];
C = N[2];
D = N[3];
E = N[4];
for(k=0; k<20; k++)
{
printf("A=[%08x]\n", A);
G = sha1_str_to_long(W[k]);
printf("W[%d]=[%08x]\n", i, G);
F = ((B & C) | (~B & D));
H = SAL(A,5) + F + E + G + K[0];
E = D;
D = C;
C = SAL(B,30);
B = A;
A = H;
printf("A=[%08x]\n", A);
}
for(k=20; k<40; k++)
{
G = sha1_str_to_long(W[k]);
F = (B ^ C ^ D);
H = SAL(A,5)+ F + E + G + K[1];
E = D;
D = C;
C = SAL(B,30);
B = A;
A = H;
printf("A=[%08x]\n", A);
}
for(k=40; k<60; k++)
{
G = sha1_str_to_long(W[k]);
F = ((B & C) | (B & D) | (C & D));
H = SAL(A,5)+ F + E + G + K[2];
E = D;
D = C;
C = SAL(B,30);
B = A;
A = H;
printf("A=[%08x]\n", A);
}
for(k=60; k<80; k++)
{
G = sha1_str_to_long(W[k]);
F = (B ^ C ^ D);
H = SAL(A,5)+ F + E + G + K[3];
E = D;
D = C;
C = SAL(B,30);
B = A;
A = H;
printf("A=[%08x]\n", A);
}
N[0] += A;
N[1] += B;
N[2] += C;
N[3] += D;
N[4] += E;
}
sha1_long_to_str(N[0], Q);
sha1_long_to_str(N[1], Q+4);
sha1_long_to_str(N[2], Q+8);
sha1_long_to_str(N[3], Q+12);
sha1_long_to_str(N[4], Q+16);
memcpy(summ, Q, 20);
return 0;
}
6.主函數(shù)部分.
int main()
{
unsigned char str[256/16*80] = {0};
unsigned char str_sha1[20];
int len = 6;
str[0] = 'a';
str[1] = 'b';
str[2] = 'c';
str[3] = 'd';
str[4] = 'e';
str[5] = 'f';
print_str(str, len);
len = sha1_pad_message(str, len);
print_str(str, len);
len = sha1_str_group(str, len);
print_str(str, len);
sha1_str_summ(str, str_sha1, len);
print_str(str_sha1, 20);
return 0;
}