You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
3.0 KiB
C

#ifndef INCLUDED_NSHA1_H
#define INCLUDED_NSHA1_H
#include <stdint.h>
#include <errno.h>
#include <stdio.h>
uint32_t leftRotate32( uint32_t N, uint32_t D){
return ((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 = UINT32_C(0x67452301);
uint32_t h1 = UINT32_C(0xefcdab89);
uint32_t h2 = UINT32_C(0x98badcfe);
uint32_t h3 = UINT32_C(0x10325476);
uint32_t h4 = UINT32_C(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++;
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
}
// * 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 );
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 = UINT32_C(0x5a827999);
}else if ( i >= 20 && i <= 39){
f = b ^ c ^ d;
k = UINT32_C(0x6ed9eba1);
}else if (i >= 40 && i <= 59){
f = (b & c) ^ (b & d) ^ (c & d);
k = UINT32_C(0x8f1bbcdc);
}else if (i >= 60 && i <= 79){
f = b ^ c ^ d;
k = UINT32_C(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