/* bell3.c - Don Yang (uguu.org) 03/15/01 */ #include #include #include typedef unsigned int uint32; typedef unsigned char byte; struct { uint32 state[5], count[2]; byte buffer[64]; } ctx; typedef union { byte c[64]; uint32 l[16]; } CHAR64LONG16; CHAR64LONG16 *block; uint32 i, j, k, r[5]; byte buffer[16384], finalcount[8]; #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) #ifndef WORDS_BIGENDIAN #define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xff00ff00) \ |(rol(block->l[i],8)&0x00ff00ff)) #else #define blk0(i) block->l[i] #endif #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ ^block->l[(i+2)&15]^block->l[i&15],1)) void R0(uint32 *v, uint32 *w, uint32 *x, uint32 *y, uint32 *z) { *z += (((*w)&((*x)^(*y)))^(*y))+blk0(k)+0x5a827999+rol(*v,5); *w = rol(*w,30); } void R1(uint32 *v, uint32 *w, uint32 *x, uint32 *y, uint32 *z) { *z += (((*w)&((*x)^(*y)))^(*y))+blk(k)+0x5a827999+rol(*v,5); *w = rol(*w,30); } void R2(uint32 *v, uint32 *w, uint32 *x, uint32 *y, uint32 *z) { *z += ((*w)^(*x)^(*y))+blk(k)+0x6ed9eba1+rol(*v,5); *w = rol(*w,30); } void R3(uint32 *v, uint32 *w, uint32 *x, uint32 *y, uint32 *z) { *z += ((((*w)|(*x))&(*y))|((*w)&(*x)))+blk(k)+0x8f1bbcdc+rol(*v,5); *w = rol(*w,30); } void R4(uint32 *v, uint32 *w, uint32 *x, uint32 *y, uint32 *z) { *z += ((*w)^(*x)^(*y))+blk(k)+0xca62c1d6+rol(*v,5); *w = rol(*w,30); } void (*R)(uint32 *v, uint32 *w, uint32 *x, uint32 *y, uint32 *z); void SHA1Transform(byte buf[64]) { block = (CHAR64LONG16*)buf; for(k = 0; k < 5; k++) r[k] = ctx.state[k]; R = R0; for(k = 0; k < 80; k++) { if( k == 16 ) R = R1; if( k == 20 ) R = R2; if( k == 40 ) R = R3; if( k == 60 ) R = R4; R(&r[(80 - k) % 5], &r[(81 - k) % 5], &r[(82 - k) % 5], &r[(83 - k) % 5], &r[(84 - k) % 5]); } for(k = 0; k < 5; k++) ctx.state[k] += r[k]; } void SHA1Init(void) { ctx.state[0] = 0x67452301; ctx.state[1] = 0xefcdab89; ctx.state[2] = 0x98badcfe; ctx.state[3] = 0x10325476; ctx.state[4] = 0xc3d2e1f0; ctx.count[0] = ctx.count[1] = 0; } void SHA1Update(byte *data, uint32 len) { j = (ctx.count[0] >> 3) & 63; if( (ctx.count[0] += len << 3) < (len << 3) ) ctx.count[1]++; ctx.count[1] += (len >> 29); if( (j + len) > 63 ) { memmove(&ctx.buffer[j], data, (i = 64 - j)); SHA1Transform(ctx.buffer); for(; i + 63 < len; i += 64) SHA1Transform((byte*)&data[i]); j = 0; } else { i = 0; } memmove(&ctx.buffer[j], &data[i], len - i); } void SHA1Final(void) { for(k = 0; k < 8; k++) { finalcount[k] = (byte) ((ctx.count[(k >= 4 ? 0 : 1)] >> ((3 - (k & 3)) * 8)) & 255); } SHA1Update((byte*) "\x80", 1); while( (ctx.count[0] & 504) != 448 ) SHA1Update((byte*) "\0", 1); SHA1Update(finalcount, 8); for(k = 0; k < 20; k++) { buffer[k] = (byte) ((ctx.state[k >> 2] >> ((3 - (k & 3)) * 8)) & 255); } } int main(int argc, char **argv) { FILE *infile; if( argc < 2 || (infile = fopen(argv[1], "rb")) == NULL ) return 1; SHA1Init(); while( !feof(infile) ) { k = fread(buffer, 1, 16384, infile); SHA1Update(buffer, k); } SHA1Final(); for(i = 0; i < 20; i += 4) { printf("%02x%02x%02x%02x ", buffer[i], buffer[i + 1], buffer[i + 2], buffer[i + 3]); } putchar('\n'); fclose(infile); return 0; }