#ifndef INCLUDED_NSHA1_H #define INCLUDED_NSHA1_H #include #include #include #define leftRotate32(N,D) (N<>(32-D)) typedef struct NSHA1_Result{ uint32_t h0; uint32_t h1; uint32_t h2; uint32_t h3; uint32_t h4; } NSHA1_Result; NSHA1_Result nsha1file(char *filename){ FILE* file; NSHA1_Result r; uint32_t number_of_chuncks = 0; uint32_t size_in_bytes = 0; uint64_t size_in_bits = 0; uint32_t h0 = 0x67452301; uint32_t h1 = 0xefcdab89; uint32_t h2 = 0x98badcfe; uint32_t h3 = 0x10325476; uint32_t h4 = 0xc3d2e1f0; file = fopen(filename,"r"); if(errno != 0){ fprintf(stderr, "\nErrno : %d\n", errno); perror(filename); return r; } size_t bytes_read; uint8_t buffer[64]; int lastRound = 0; while(lastRound != 1){ bytes_read = fread(buffer, 1, 64, file); number_of_chuncks++; // printf("We read %d bytes\n", bytes_read); if(bytes_read != 64){ // * We need to convert to 512 bit * // size_in_bytes += bytes_read; // the final size is done here size_in_bits = size_in_bytes * 8; //padding buffer[bytes_read] = 0x80; bytes_read += 1; for(int i = bytes_read; i <= 55; i++) buffer[i] = 0; //adding size to end for(int i = 63; i >= 56; i--){ buffer[i] = size_in_bits % 256; size_in_bits /= 256; } lastRound = 1; // This is the last round } /** // Printing each byte of the chunk printf("------------------------------------------\n"); for(int i = 0; i < 64; i++) printf("%x i=%d\n", buffer[i], i); printf("------------------------------------------\n"); **/ // * We usually get a 512 bit chunk except the last chunck which we need to pad (which we do in the if above) * // size_in_bytes += 64; /////////////////////// ****************************************** //////////////////////////////////////////// uint32_t w[80]; for(int i = 0; i < 16; i++) w[i] = buffer[4*i] * 16777216 + buffer[(4*i)+1] * 65536 + buffer[(4*i)+2] * 256 + buffer[(4*i)+3]; for(int i = 16; i < 80; i++) w[i] = leftRotate32( w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i - 16] , 1 ); /** // Printing each w for the chunck printf("------------------------------------------\n"); for(int i = 0; i < 80; i++) printf("%x i=%d\n", w[i], i); printf("------------------------------------------\n"); **/ uint32_t a = h0; uint32_t b = h1; uint32_t c = h2; uint32_t d = h3; uint32_t e = h4; uint32_t f; uint32_t k; // The 80 iterations for(int i = 0; i < 80; i++){ if(i >= 0 && i <= 19){ f = (b & c) ^ ((~b) & d); k = 0x5a827999; }else if ( i >= 20 && i <= 39){ f = b ^ c ^ d; k = 0x6ed9eba1; }else if (i >= 40 && i <= 59){ f = (b & c) ^ (b & d) ^ (c & d); k = 0x8f1bbcdc; }else if (i >= 60 && i <= 79){ f = b ^ c ^ d; k = 0xca62c1d6; } uint32_t temp = leftRotate32(a,5) + f + e + k + w[i]; e = d; d = c; c = leftRotate32(b, 30); b = a; a = temp; } // Add this chunk's hash result h0 = h0 + a; h1 = h1 + b; h2 = h2 + c; h3 = h3 + d; h4 = h4 + e; /////////////////////// ****************************************** //////////////////////////////////////////// } fclose(file); r.h0 = h0; r.h1 = h1; r.h2 = h2; r.h3 = h3; r.h4 = h4; return r; } #endif