/* bell2.c - Don Yang (uguu.org) 03/15/01 */ #include #include #include typedef unsigned int uint32; typedef unsigned char byte; struct { uint32 state[5]; uint32 count[2]; byte buffer[64]; } ctx; typedef union { byte c[64]; uint32 l[16]; } CHAR64LONG16; CHAR64LONG16 *block; #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, uint32 i) { *z += (((*w)&((*x)^(*y)))^(*y))+blk0(i)+0x5a827999+rol(*v,5); *w = rol(*w,30); } void R1(uint32 *v, uint32 *w, uint32 *x, uint32 *y, uint32 *z, uint32 i) { *z += (((*w)&((*x)^(*y)))^(*y))+blk(i)+0x5a827999+rol(*v,5); *w = rol(*w,30); } void R2(uint32 *v, uint32 *w, uint32 *x, uint32 *y, uint32 *z, uint32 i) { *z += ((*w)^(*x)^(*y))+blk(i)+0x6ed9eba1+rol(*v,5); *w = rol(*w,30); } void R3(uint32 *v, uint32 *w, uint32 *x, uint32 *y, uint32 *z, uint32 i) { *z += ((((*w)|(*x))&(*y))|((*w)&(*x)))+blk(i)+0x8f1bbcdc+rol(*v,5); *w = rol(*w,30); } void R4(uint32 *v, uint32 *w, uint32 *x, uint32 *y, uint32 *z, uint32 i) { *z += ((*w)^(*x)^(*y))+blk(i)+0xca62c1d6+rol(*v,5); *w = rol(*w,30); } void (*R)(uint32 *v, uint32 *w, uint32 *x, uint32 *y, uint32 *z, uint32 i); void SHA1Transform(uint32 state[5], byte buffer[64]) { uint32 r[5], i; block = (CHAR64LONG16*)buffer; for(i = 0; i < 5; i++) r[i] = state[i]; R = R0; for(i = 0; i < 80; i++) { if( i == 16 ) R = R1; if( i == 20 ) R = R2; if( i == 40 ) R = R3; if( i == 60 ) R = R4; R(&r[(80 - i) % 5], &r[(81 - i) % 5], &r[(82 - i) % 5], &r[(83 - i) % 5], &r[(84 - i) % 5], i); } for(i = 0; i < 5; i++) state[i] += r[i]; } 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) { uint32 i, j; 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.state, ctx.buffer); for(; i + 63 < len; i += 64) SHA1Transform(ctx.state, (byte*)&data[i]); j = 0; } else { i = 0; } memmove(&ctx.buffer[j], &data[i], len - i); } void SHA1Final(byte digest[20]) { byte finalcount[8]; uint32 i; for(i = 0; i < 8; i++) { finalcount[i] = (byte) ((ctx.count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255); } SHA1Update((byte*) "\200", 1); while( (ctx.count[0] & 504) != 448 ) SHA1Update((byte*) "\0", 1); SHA1Update(finalcount, 8); for(i = 0; i < 20; i++) { digest[i] = (byte) ((ctx.state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); } } int main(int argc, char **argv) { FILE *infile; byte buffer[16384]; uint32 i; if( argc < 2 || (infile = fopen(argv[1], "rb")) == NULL ) return 1; SHA1Init(); while( !feof(infile) ) { i = fread(buffer, 1, 16384, infile); SHA1Update(buffer, i); } SHA1Final(buffer); 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; }