SHA1 Implementierung
This commit is contained in:
parent
cac5fec5ba
commit
e6720ad3df
1 changed files with 117 additions and 0 deletions
117
sha1.c
Normal file
117
sha1.c
Normal file
|
@ -0,0 +1,117 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
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;
|
||||
}
|
Loading…
Reference in a new issue