Viewing file:
sha1.c (3.39 KB) -rw-rw-rw-Select action/file-type:

(
+) |

(
+) |

(
+) |
Code (
+) |
Session (
+) |

(
+) |
SDB (
+) |

(
+) |

(
+) |

(
+) |

(
+) |

(
+) |
/*
** Copyright 2001 Double Precision, Inc.
** See COPYING for distribution information.
*/
#define SHA1_INTERNAL
#include "sha1.h"
#include <string.h>
#include <stdlib.h>
#define K0 0x5A827999
#define K1 0x6ED9EBA1
#define K2 0x8F1BBCDC
#define K3 0XCA62C1D6
#define K20(x) x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x
static SHA1_WORD K[80] = { K20(K0), K20(K1), K20(K2), K20(K3) };
void sha1_context_init(struct SHA1_CONTEXT *c)
{
if (sizeof(SHA1_WORD) != 4)
abort();
c->H[0] = 0x67452301;
c->H[1] = 0xEFCDAB89;
c->H[2] = 0x98BADCFE;
c->H[3] = 0x10325476;
c->H[4] = 0xC3D2E1F0;
c->blk_ptr=0;
}
void sha1_context_hash(struct SHA1_CONTEXT *c,
const unsigned char blk[SHA1_BLOCK_SIZE])
{
SHA1_WORD A,B,C,D,E;
SHA1_WORD TEMP;
SHA1_WORD W[80];
unsigned i, t;
#define f(t,B,C,D) ( \
(t) < 20 ? ( (B) & (C) ) | ( (~(B)) & (D) ) : \
(t) >= 40 && (t) < 60 ? ( (B) & (C) ) | ( (B) & (D) ) | ( (C) & (D) ):\
(B) ^ (C) ^ (D) )
#define S(a,b) ( ((SHA1_WORD)(a) << (b)) | ((SHA1_WORD)(a) >> (32 - (b))))
for (i=t=0; t<16; t++)
{
W[t]= blk[i]; i++;
W[t] = (W[t] << 8) | blk[i]; i++;
W[t] = (W[t] << 8) | blk[i]; i++;
W[t] = (W[t] << 8) | blk[i]; i++;
}
for (t=16; t<80; t++)
{
TEMP= W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
W[t]= S(TEMP, 1);
}
A=c->H[0];
B=c->H[1];
C=c->H[2];
D=c->H[3];
E=c->H[4];
for (t=0; t<80; t++)
{
TEMP = S(A,5);
TEMP += f(t, B, C, D);
TEMP += E;
TEMP += W[t];
TEMP += K[t];
E=D;
D=C;
C= S(B, 30);
B=A;
A=TEMP;
}
c->H[0] += A;
c->H[1] += B;
c->H[2] += C;
c->H[3] += D;
c->H[4] += E;
}
void sha1_context_hashstream(struct SHA1_CONTEXT *c, const void *p, unsigned l)
{
const unsigned char *cp=(const unsigned char *)p;
unsigned ll;
while (l)
{
if (c->blk_ptr == 0 && l >= SHA1_BLOCK_SIZE)
{
sha1_context_hash(c, cp);
cp += SHA1_BLOCK_SIZE;
l -= SHA1_BLOCK_SIZE;
continue;
}
ll=l;
if (ll > SHA1_BLOCK_SIZE - c->blk_ptr)
ll=SHA1_BLOCK_SIZE - c->blk_ptr;
memcpy(c->blk + c->blk_ptr, cp, ll);
c->blk_ptr += ll;
cp += ll;
l -= ll;
if (c->blk_ptr >= SHA1_BLOCK_SIZE)
{
sha1_context_hash(c, c->blk);
c->blk_ptr=0;
}
}
}
void sha1_context_endstream(struct SHA1_CONTEXT *c, unsigned long l)
{
unsigned char buf[8];
static const unsigned char zero[SHA1_BLOCK_SIZE-8];
buf[0]=0x80;
sha1_context_hashstream(c, &buf, 1);
while (c->blk_ptr != SHA1_BLOCK_SIZE-8)
{
if (c->blk_ptr > SHA1_BLOCK_SIZE-8)
{
sha1_context_hashstream(c, zero,
SHA1_BLOCK_SIZE - c->blk_ptr);
continue;
}
sha1_context_hashstream(c, zero,
SHA1_BLOCK_SIZE-8-c->blk_ptr);
}
l *= 8;
buf[7] = l;
buf[6] = (l >>= 8);
buf[5] = (l >>= 8);
buf[4] = (l >> 8);
buf[3]=buf[2]=buf[1]=buf[0]=0;
sha1_context_hashstream(c, buf, 8);
}
void sha1_context_digest(struct SHA1_CONTEXT *c, SHA1_DIGEST d)
{
unsigned char *dp=d + SHA1_DIGEST_SIZE;
unsigned i;
for ( i=5; i; )
{
SHA1_WORD w=c->H[--i];
*--dp=w; w >>= 8;
*--dp=w; w >>= 8;
*--dp=w; w >>= 8;
*--dp=w;
}
}
void sha1_context_restore(struct SHA1_CONTEXT *c, const SHA1_DIGEST d)
{
const unsigned char *dp=d;
unsigned i;
for (i=0; i<5; i++)
{
SHA1_WORD w= *dp++;
w=(w << 8) | *dp++;
w=(w << 8) | *dp++;
w=(w << 8) | *dp++;
c->H[i]=w;
}
c->blk_ptr=0;
}
void sha1_digest(const void *msg, unsigned len, SHA1_DIGEST d)
{
struct SHA1_CONTEXT c;
sha1_context_init( &c );
sha1_context_hashstream(&c, msg, len);
sha1_context_endstream(&c, len);
sha1_context_digest( &c, d );
}