From e6720ad3df308f04bc0a151f64a370b7a804f13a Mon Sep 17 00:00:00 2001 From: Valentin Gehrke Date: Fri, 14 Jul 2017 16:30:17 +0200 Subject: [PATCH] SHA1 Implementierung --- sha1.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 sha1.c diff --git a/sha1.c b/sha1.c new file mode 100644 index 0000000..1200def --- /dev/null +++ b/sha1.c @@ -0,0 +1,117 @@ +#include +#include +#include +#include + +typedef struct { + uint32_t h0; + uint32_t h1; + uint32_t h2; + uint32_t h3; + uint32_t h4; +} hash_t; + +hash_t* sha1(const char* s, hash_t* h); +void printhash(hash_t* h); + +void main(int argc, char** argv) { + hash_t h; + const char* str; + if(argc > 1) { + str = argv[1]; + } else { + str = "test"; + } + sha1(str,&h); + printhash(&h); +} + +void printhash(hash_t* h) { + printf("%08X%08X%08X%08X%08X\n", + h->h0, + h->h1, + h->h2, + h->h3, + h->h4); +} + +#define left_shift(n,X) (((X) << (n)) | ((X) >> (32-(n)))) + +void apply_round(const char* block, hash_t* state) { + uint32_t A,B,C,D,E; + uint32_t W[80]; + uint32_t temp, K, f; + + for(int i = 0; i < 16; i++) { + W[i] = (unsigned char)block[i*4] << 24; + W[i] |= (unsigned char)block[i*4+1] << 16; + W[i] |= (unsigned char)block[i*4+2] << 8; + W[i] |= (unsigned char)block[i*4+3]; + } + + for(int i = 16; i < 80; i++) { + W[i] = left_shift(1, W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16]); + } + + A = state->h0; + B = state->h1; + C = state->h2; + D = state->h3; + E = state->h4; + + for(int i = 0; i < 80; i++) { + if(0 <= i && i <= 19) { + f = (B & C) | ( (~B) & D ); + K = 0x5A827999; + } else if(20 <= i && i <= 39) { + f = B ^ C ^ D; + K = 0x6ED9EBA1; + } else if(40 <= i && i <= 59) { + f = (B & C) | (B & D) | (C & D); + K = 0x8F1BBCDC; + } else if(60 <= i && i <= 79) { + f = B ^ C ^ D; + K = 0xCA62C1D6; + } + + temp = left_shift(5,A) + f + E + W[i] + K; + E = D; D = C; C = left_shift(30,B); B = A; A = temp; + } + + state->h0 += A; + state->h1 += B; + state->h2 += C; + state->h3 += D; + state->h4 += E; +} + +hash_t* sha1(const char* s, hash_t* H) { + H->h0 = 0x67452301; + H->h1 = 0xEFCDAB89; + H->h2 = 0x98BADCFE; + H->h3 = 0x10325476; + H->h4 = 0xC3D2E1F0; + + size_t slen = strlen(s); + size_t bitlen = slen*8; + unsigned long long padlen = (slen + 64 - (slen%512)); + if(padlen - slen < 8) padlen += 64; + + char buf[padlen]; + + memset(buf, 0, sizeof(char) * padlen); + memcpy(buf, s, sizeof(char) * slen); + + buf[slen] = 0x80; + for(int i = 0; i < 8; i++) { + buf[padlen-i-1] = (bitlen >> (8*i)) & 0xFF; + } + + size_t numblocks = padlen / 64; + + for(int i = 0; i < numblocks; i++) { + apply_round(&(buf[i*64]),H); + } + + return H; +}