📄 sha1.c
字号:
#include "SHA1.H"
////////////////////////////////////////////////////////////////////////////////////////////////////
//
static u8 SHA1_Padding[64] = {
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//将字节串中的4字节转换成32位整型数,低地址为高位
#define GET_u32(num,bytes,index) \
{ \
(num) = ( (u32) (bytes)[(index) + 0] << 24 ) \
| ( (u32) (bytes)[(index) + 1] << 16 ) \
| ( (u32) (bytes)[(index) + 2] << 8 ) \
| ( (u32) (bytes)[(index) + 3] ); \
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//将32位整型数存放在字节串中指定位置,低地址放高位
#define PUT_u32(num,bytes,index) \
{ \
(bytes)[(index) + 0] = (u8) ( (num) >> 24 ); \
(bytes)[(index) + 1] = (u8) ( (num) >> 16 ); \
(bytes)[(index) + 2] = (u8) ( (num) >> 8 ); \
(bytes)[(index) + 3] = (u8) ( (num) ); \
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//SHA移位算法,将32位整型数移位n位
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
////////////////////////////////////////////////////////////////////////////////////////////////////
//SHA算法初始化,即中间变量赋初值
void SHA1_Init( SHA1_CONTEXT *ctx )
{
ctx->total[0] = 0;
ctx->total[1] = 0;
ctx->Hash[0] = 0x67452301;
ctx->Hash[1] = 0xEFCDAB89;
ctx->Hash[2] = 0x98BADCFE;
ctx->Hash[3] = 0x10325476;
ctx->Hash[4] = 0xC3D2E1F0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//SHA算法模块
void SHA1_Process( SHA1_CONTEXT *ctx, u8 data[64] )
{
u16 i;
u32 temp, W[16], A, B, C, D, E;
for(i=0;i<16;i++){
GET_u32(W[i],data,i*4);
}
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
#define R(t) \
( \
temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
W[(t - 14) & 0x0F] ^ W[(t -16) & 0x0F], \
( W[t & 0x0F] = S(temp,1) ) \
)
#define P(a,b,c,d,e,x) {e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);}
A = ctx->Hash[0];
B = ctx->Hash[1];
C = ctx->Hash[2];
D = ctx->Hash[3];
E = ctx->Hash[4];
#define F(x,y,z) (z ^ (x & (y ^ z)))
#define K 0x5A827999
for(i=0;i<20;i++){
if(i<16){
P( A, B, C, D, E, W[i] );
}else{
P( A, B, C, D, E, R(i) );
}
temp=E;
E=D;D=C;C=B;B=A;A=temp;
}
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0x6ED9EBA1
for(i=20;i<40;i++){
P( A, B, C, D, E, R(i) );
temp=E;
E=D;D=C;C=B;B=A;A=temp;
}
#undef K
#undef F
#define F(x,y,z) ((x & y) | (z & (x | y)))
#define K 0x8F1BBCDC
for(i=40;i<60;i++){
P( A, B, C, D, E, R(i) );
temp=E;
E=D;D=C;C=B;B=A;A=temp;
}
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0xCA62C1D6
for(i=60;i<80;i++){
P( A, B, C, D, E, R(i) );
temp=E;
E=D;D=C;C=B;B=A;A=temp;
}
#undef K
#undef F
ctx->Hash[0] += A;
ctx->Hash[1] += B;
ctx->Hash[2] += C;
ctx->Hash[3] += D;
ctx->Hash[4] += E;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//功能: 对输入数据的SHA算法
//输入: ctx: SHA1算法需要的上下文变量,
// input: 以字节为单位的输入数据指针
// length: 输入数据的字节长度
//输入: ctx:
void SHA1_Update( SHA1_CONTEXT *ctx, u8 *input, u32 length )
{
u32 left, fill;
u16 i;
if(!length) return;
left = ctx->total[0] & 0x3F; //64 Bytes = 512 bits
fill = 64 - left;
ctx->total[0] += length;
ctx->total[0] &= 0xFFFFFFFF;
if( ctx->total[0] < length )
ctx->total[1]++;
if( left && length >= fill ) {
for(i=0;i<fill;i++){
*(u8 *)(ctx->buffer + left+i) = *(u8 *)(input+i);
}
SHA1_Process( ctx, ctx->buffer );
length -= fill;
input += fill;
left = 0;
}
while( length >= 64 ){
SHA1_Process( ctx, input );
length -= 64;
input += 64;
}
if( length ){
for(i=0;i<length;i++){
*(u8 *)(ctx->buffer + left+i) = *(u8 *)(input+i);
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//功能: 对输入数据的SHA算法
//输入: ctx: SHA1算法需要的上下文变量,
//输出: digest: 输入信息的SHA1算法结果--摘要信息,以字节为单位存放
void SHA1_Finish( SHA1_CONTEXT *ctx, u8 digest[20] )
{
u32 last, padn;
u32 high, low;
u8 msglen[8];
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_u32( high, msglen, 0 );
PUT_u32( low, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
SHA1_Update( ctx, SHA1_Padding, padn );
SHA1_Update( ctx, msglen, 8 );
PUT_u32( ctx->Hash[0], digest, 0 );
PUT_u32( ctx->Hash[1], digest, 4 );
PUT_u32( ctx->Hash[2], digest, 8 );
PUT_u32( ctx->Hash[3], digest, 12 );
PUT_u32( ctx->Hash[4], digest, 16 );
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -