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