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.

152 lines
3.4 KiB
C

#ifndef INCLUDED_NSHA1_H
#define INCLUDED_NSHA1_H
#include <stdint.h>
#include <errno.h>
#include <stdio.h>
#define leftRotate32(N,D) (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