forked from garlicoin-project/node-multi-hashing
-
Notifications
You must be signed in to change notification settings - Fork 4
/
sha1.c
59 lines (56 loc) · 1.51 KB
/
sha1.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include "sha1.h"
#include <string.h>
#include <openssl/sha.h>
inline void encodeb64(const unsigned char* pch, char* buff)
{
const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int mode = 0, left = 0;
const int len = 20;
const unsigned char *pchEnd = pch + len;
while (pch < pchEnd) {
int enc = *(pch++);
if (mode == 0) {
*buff++ = pbase64[enc >> 2];
left = (enc & 3) << 4;
mode = 1;
}
else if (mode == 1) {
*buff++ = pbase64[left | (enc >> 4)];
left = (enc & 15) << 2;
mode = 2;
}
else {
*buff++ = pbase64[left | (enc >> 6)];
*buff++ = pbase64[enc & 63];
mode = 0;
}
}
*buff = pbase64[left];
*(buff + 1) = 0;
}
void sha1_hash(const char* input, char* output, uint32_t len)
{
char str[38] __attribute__((aligned(32))); // 26 + 11 + 1
uint32_t prehash[5] __attribute__((aligned(32)));
uint32_t hash[5] __attribute__((aligned(32))) = { 0 };
int i = 0;
SHA_CTX ctx;
SHA1_Init(&ctx);
SHA1_Update(&ctx, (void *)input, len);
SHA1_Final((void *)prehash, &ctx);
encodeb64((const unsigned char *)prehash, str);
memcpy(&str[26], str, 11);
str[37] = 0;
for (i = 0; i < 26; i++) {
SHA1_Init(&ctx);
SHA1_Update(&ctx, (void *)&str[i], 12);
SHA1_Final((void *)prehash, &ctx);
hash[0] ^= prehash[0];
hash[1] ^= prehash[1];
hash[2] ^= prehash[2];
hash[3] ^= prehash[3];
hash[4] ^= prehash[4];
}
memset(output, 0, 32 - 20);
memcpy(&output[32 - 20], hash, 20);
}