137 lines
2.7 KiB
C
137 lines
2.7 KiB
C
#include <limits.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
static uint64_t pad_length(uint64_t len) {
|
|
uint64_t space_needed = 1;
|
|
|
|
while(((len + space_needed) % 64) != 56) {
|
|
space_needed += 1;
|
|
}
|
|
|
|
return space_needed;
|
|
}
|
|
|
|
static uint32_t rotate(uint8_t bits, uint32_t word) {
|
|
return (word << bits) | (word >> (32 - bits));
|
|
}
|
|
|
|
unsigned char *sha1(const char *msg, uint64_t len) {
|
|
uint64_t ml = len * CHAR_BIT;
|
|
uint64_t needed = pad_length(len);
|
|
unsigned char *buf = malloc(len + needed + 8);
|
|
|
|
if(buf == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
strncpy((char *) buf, msg, len);
|
|
buf[len++] = 0x80;
|
|
|
|
for(; needed > 1; --needed) {
|
|
buf[len++] = 0x00;
|
|
}
|
|
|
|
uint8_t count = 8;
|
|
|
|
while(count--) {
|
|
buf[len++] = (ml & ((uint64_t) 0xFF << 56)) >> 56;
|
|
ml = ml << 8;
|
|
}
|
|
|
|
uint32_t h[] = {
|
|
0x67452301,
|
|
0xEFCDAB89,
|
|
0x98BADCFE,
|
|
0x10325476,
|
|
0xC3D2E1F0
|
|
};
|
|
|
|
uint64_t chunk = 0;
|
|
|
|
for(; chunk < len; chunk += 64) {
|
|
uint32_t w[80] = { 0 };
|
|
uint8_t i = 0;
|
|
|
|
for(; i < 16; i++) {
|
|
w[i] = buf[chunk + (i * 4)] << 24;
|
|
w[i] |= buf[chunk + (i * 4 + 1)] << 16;
|
|
w[i] |= buf[chunk + (i * 4 + 2)] << 8;
|
|
w[i] |= buf[chunk + (i * 4 + 3)];
|
|
}
|
|
|
|
for(i = 16; i < 80; ++i) {
|
|
w[i] = rotate(1, w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]);
|
|
}
|
|
|
|
uint32_t a = h[0];
|
|
uint32_t b = h[1];
|
|
uint32_t c = h[2];
|
|
uint32_t d = h[3];
|
|
uint32_t e = h[4];
|
|
|
|
for(i = 0; i < 80; ++i) {
|
|
uint32_t f = 0;
|
|
uint32_t k = 0;
|
|
|
|
if(i >= 0 && i <= 19) {
|
|
f = (b & c) | ((~b) & d);
|
|
k = (uint32_t) 0x5A827999;
|
|
} else if(i >= 20 && i <= 39) {
|
|
f = b ^ c ^ d;
|
|
k = (uint32_t) 0x6ED9EBA1;
|
|
} else if(i >= 40 && i <= 59) {
|
|
f = (b & c) | (b & d) | (c & d);
|
|
k = (uint32_t) 0x8F1BBCDC;
|
|
} else if(i >= 60 && i <= 79) {
|
|
f = b ^ c ^ d;
|
|
k = (uint32_t) 0xCA62C1D6;
|
|
}
|
|
|
|
uint32_t temp = rotate(5, a) + f + e + k + w[i];
|
|
e = d;
|
|
d = c;
|
|
c = rotate(30, b);
|
|
b = a;
|
|
a = temp;
|
|
}
|
|
|
|
h[0] += a;
|
|
h[1] += b;
|
|
h[2] += c;
|
|
h[3] += d;
|
|
h[4] += e;
|
|
}
|
|
|
|
unsigned char *hh = malloc(20);
|
|
|
|
if(hh == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
for(count = 0; count < 5; count++) {
|
|
hh[count * 4] = h[count] >> 24;
|
|
hh[(count * 4) + 1] = (h[count] >> 16) & 0xFF;
|
|
hh[(count * 4) + 2] = (h[count] >> 8) & 0xFF;
|
|
hh[(count * 4) + 3] = h[count] & 0xFF;
|
|
}
|
|
|
|
return hh;
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
for(++argv; argc > 1; ++argv, --argc) {
|
|
unsigned char *hash = sha1(*argv, strlen(*argv));
|
|
uint8_t count = 0;
|
|
|
|
for(; count < 20; ++count) {
|
|
printf("%02X", (unsigned) hash[count]);
|
|
}
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
return 0;
|
|
}
|