Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
revoxhere
GitHub Repository: revoxhere/duino-coin
Path: blob/master/Arduino_Code/duco_hash.cpp
925 views
1
#include "duco_hash.h"
2
3
#pragma GCC optimize ("-Ofast")
4
5
#define sha1_rotl(bits,word) (((word) << (bits)) | ((word) >> (32 - (bits))))
6
7
void duco_hash_block(duco_hash_state_t * hasher) {
8
// NOTE: keeping this static improves performance quite a lot
9
static uint32_t w[16];
10
11
for (uint8_t i = 0, i4 = 0; i < 16; i++, i4 += 4) {
12
w[i] = (uint32_t(hasher->buffer[i4]) << 24) |
13
(uint32_t(hasher->buffer[i4 + 1]) << 16) |
14
(uint32_t(hasher->buffer[i4 + 2]) << 8) |
15
(uint32_t(hasher->buffer[i4 + 3]));
16
}
17
18
uint32_t a = hasher->tempState[0];
19
uint32_t b = hasher->tempState[1];
20
uint32_t c = hasher->tempState[2];
21
uint32_t d = hasher->tempState[3];
22
uint32_t e = hasher->tempState[4];
23
24
for (uint8_t i = 10; i < 80; i++) {
25
if (i >= 16) {
26
w[i & 15] = sha1_rotl(1, w[(i-3) & 15] ^ w[(i-8) & 15] ^ w[(i-14) & 15] ^ w[(i-16) & 15]);
27
}
28
29
uint32_t temp = sha1_rotl(5, a) + e + w[i & 15];
30
if (i < 20) {
31
temp += (b & c) | ((~b) & d);
32
temp += 0x5a827999;
33
} else if(i < 40) {
34
temp += b ^ c ^ d;
35
temp += 0x6ed9eba1;
36
} else if(i < 60) {
37
temp += (b & c) | (b & d) | (c & d);
38
temp += 0x8f1bbcdc;
39
} else {
40
temp += b ^ c ^ d;
41
temp += 0xca62c1d6;
42
}
43
44
e = d;
45
d = c;
46
c = sha1_rotl(30, b);
47
b = a;
48
a = temp;
49
}
50
51
a += 0x67452301;
52
b += 0xefcdab89;
53
c += 0x98badcfe;
54
d += 0x10325476;
55
e += 0xc3d2e1f0;
56
57
hasher->result[0 * 4 + 0] = a >> 24;
58
hasher->result[0 * 4 + 1] = a >> 16;
59
hasher->result[0 * 4 + 2] = a >> 8;
60
hasher->result[0 * 4 + 3] = a;
61
hasher->result[1 * 4 + 0] = b >> 24;
62
hasher->result[1 * 4 + 1] = b >> 16;
63
hasher->result[1 * 4 + 2] = b >> 8;
64
hasher->result[1 * 4 + 3] = b;
65
hasher->result[2 * 4 + 0] = c >> 24;
66
hasher->result[2 * 4 + 1] = c >> 16;
67
hasher->result[2 * 4 + 2] = c >> 8;
68
hasher->result[2 * 4 + 3] = c;
69
hasher->result[3 * 4 + 0] = d >> 24;
70
hasher->result[3 * 4 + 1] = d >> 16;
71
hasher->result[3 * 4 + 2] = d >> 8;
72
hasher->result[3 * 4 + 3] = d;
73
hasher->result[4 * 4 + 0] = e >> 24;
74
hasher->result[4 * 4 + 1] = e >> 16;
75
hasher->result[4 * 4 + 2] = e >> 8;
76
hasher->result[4 * 4 + 3] = e;
77
}
78
79
void duco_hash_init(duco_hash_state_t * hasher, char const * prevHash) {
80
memcpy(hasher->buffer, prevHash, 40);
81
82
if (prevHash == (void*)(0xffffffff)) {
83
// NOTE: THIS IS NEVER CALLED
84
// This is here to keep a live reference to hash_block
85
// Otherwise GCC tries to inline it entirely into the main loop
86
// Which causes massive perf degradation
87
duco_hash_block(nullptr);
88
}
89
90
// Do first 10 rounds as these are going to be the same all time
91
92
uint32_t a = 0x67452301;
93
uint32_t b = 0xefcdab89;
94
uint32_t c = 0x98badcfe;
95
uint32_t d = 0x10325476;
96
uint32_t e = 0xc3d2e1f0;
97
98
static uint32_t w[10];
99
100
for (uint8_t i = 0, i4 = 0; i < 10; i++, i4 += 4) {
101
w[i] = (uint32_t(hasher->buffer[i4]) << 24) |
102
(uint32_t(hasher->buffer[i4 + 1]) << 16) |
103
(uint32_t(hasher->buffer[i4 + 2]) << 8) |
104
(uint32_t(hasher->buffer[i4 + 3]));
105
}
106
107
for (uint8_t i = 0; i < 10; i++) {
108
uint32_t temp = sha1_rotl(5, a) + e + w[i & 15];
109
temp += (b & c) | ((~b) & d);
110
temp += 0x5a827999;
111
112
e = d;
113
d = c;
114
c = sha1_rotl(30, b);
115
b = a;
116
a = temp;
117
}
118
119
hasher->tempState[0] = a;
120
hasher->tempState[1] = b;
121
hasher->tempState[2] = c;
122
hasher->tempState[3] = d;
123
hasher->tempState[4] = e;
124
}
125
126
void duco_hash_set_nonce(duco_hash_state_t * hasher, char const * nonce) {
127
uint8_t * b = hasher->buffer;
128
129
uint8_t off = SHA1_HASH_LEN * 2;
130
for (uint8_t i = 0; i < 10 && nonce[i] != 0; i++) {
131
b[off++] = nonce[i];
132
}
133
134
uint8_t total_bytes = off;
135
136
b[off++] = 0x80;
137
while (off < 62) {
138
b[off++] = 0;
139
}
140
141
b[62] = total_bytes >> 5;
142
b[63] = total_bytes << 3;
143
}
144
145
uint8_t const * duco_hash_try_nonce(duco_hash_state_t * hasher, char const * nonce) {
146
duco_hash_set_nonce(hasher, nonce);
147
duco_hash_block(hasher);
148
149
return hasher->result;
150
}
151
152