/*
* sha1.c
*
* Created on: 2011-10-29
* Author: Administrator
*/
#include "sha1.h"
void init()
{
h0 = 0x67452301;
h1 = 0xEFCDAB89;
h2 = 0x98BADCFE;
h3 = 0x10325476;
h4 = 0xC3D2E1F0;
}
/*
* data 待处理字符串 非空
* blen data的字节数 必须为0~63的数
* sumlen 总字节数
* 先补一个1,然后再补0,直到长度满足对512取模后余数是448
* * 补位,最多512位(即补全了该组再补充一组)
* 操作仅限于0~PREBUFLEN - 1
*/
int Postprocessing(const unsigned char *data, unsigned blen,
unsigned long sumlen)
{
if (!data || blen > 63 || blen < 0) //非空且大小合适
return shaStateError;
int llen = blen / 4;
int ylen = blen % 4;
int i = 0, j = 0;
for (i = 0; i < llen; i++) //凑够多少个4字节
{
W[i] = data[j++] << 24;
W[i] |= data[j++] << 16;
W[i] |= data[j++] << 8;
W[i] |= data[j++];
}
switch (ylen)
//剩下的单字节,填充W[i]
{
case 0:
W[i] = 0x80 << 24; //数据后面添加一个1
break;
case 1:
W[i] = data[j++] << 24;
W[i] |= 0x80 << 16; //数据后面添加一个1
W[i] &= ~0xffff;
break;
case 2:
W[i] = data[j++] << 24;
W[i] |= data[j++] << 16;
W[i] |= 0x80 << 8; //数据后面添加一个1
W[i] &= ~0xff;
break;
case 3:
W[i] = data[j++] << 24;
W[i] |= data[j++] << 16;
W[i] |= data[j++] << 8;
W[i] |= 0x80; //数据后面添加一个1
break;
}
i++;
for (; i < PREBUFLEN; i++) //后面全清零
W[i] = 0;
if (blen > 55) //必需再增加一块
{
calOneW(); //计算刚组建好的那一块,然后后面组建下一补充块
for (i = 0; i < PREBUFLEN; i++)
{
W[i] = 0; //W全清零
}
}
W[PREBUFLEN - 2] = sumlen >> 27; //数据长度
W[PREBUFLEN - 1] = sumlen << 3;
//calOneW(); //计算最后一块
}
/*
* 扩展16个字到80个字
*/
void Extend()
{
int i;
for (i = 16; i < BUFLEN; i++)
{
W[i] = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];
W[i] = S(1,W[i]);
}
/*int ii = 0;
for (ii = 0; ii < 80; ii++)
{
printf("%x", W[ii]);
if (ii % 10 == 9)
printf("\n");
}*/
}
/*
* 计算
* 计算输入:16字节,h0~h4
*/
void calOneW()
{
Extend(); //扩展空间到80字
//初始化
a = h0;
b = h1;
c = h2;
d = h3;
e = h4;
//计算
int i;
unsigned long temp, f, k;
for (i = 0; i < BUFLEN; i++)
{
if (i >= 0 && i <= 19)
{
f = (b & c) | ((~b) & d);
k = 0x5A827999;
}
else if (i > 19 && i <= 39)
{
f = b ^ c ^ d;
k = 0x6ED9EBA1;
}
else if (i > 39 && i <= 59)
{
f = (b & c) | (b & d) | (c & d);
k = 0x8F1BBCDC;
}
else if (i > 59 && i <= 79)
{
f = b ^ c ^ d;
k = 0xCA62C1D6;
}
temp = S(5,a) + f + e + k + W[i];
e = d;
d = c;
c = S(30,b);
b = a;
a = temp;
}
//printf("%x %x %x %x %x \n", a, b, c, d, e);
h0 += a;
h1 += b;
h2 += c;
h3 += d;
h4 += e;
}
/*
* divide the data into several blocks ,every is 512 bits.
* then cal them one by one and then extend the last one and cal it
*/
int cal(unsigned char * data, unsigned long len, unsigned long result[5])
{
/*int xx=0;
for(xx=0;xx<len;xx++)
printf("%x ",data[xx]);
printf("\n");*/
init();
int t = len / (PREBUFLEN << 2); //总共需要几次完整数据块
int yu = len % (PREBUFLEN << 2); //剩下的字节数
//printf("%lu %d %d\n\n",len,t,yu);
int i, j;
unsigned long p = 0;
for (i = 0; i < t; i++)
{
for (j = 0; j < PREBUFLEN; j++)
{
W[j] = data[p++] << 24; //第一次为赋值,相当于清零然后赋值
W[j] |= data[p++] << 16;
W[j] |= data[p++] << 8;
W[j] |= data[p++];
}
calOneW(); //计算该块
}
Postprocessing(&data[p], yu, len);
calOneW(); //计算该块
result[0] = h0;
result[1] = h1;
result[2] = h2;
result[3] = h3;
result[4] = h4;
return shaSuccess;
}
- 1
- 2
- 3
前往页