Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tpruvot
GitHub Repository: tpruvot/cpuminer-multi
Path: blob/linux/algo/scrypt-jane.c
1201 views
1
#include "miner.h"
2
3
#include <stdlib.h>
4
#include <string.h>
5
#include "inttypes.h"
6
7
/* Hard-coded scrypt parameteres r and p - mikaelh */
8
#define SCRYPT_R 1
9
#define SCRYPT_P 1
10
11
/* Only the instrinsics versions are optimized for hard-coded values - mikaelh */
12
#define CPU_X86_FORCE_INTRINSICS
13
14
#undef SCRYPT_KECCAK512
15
#undef SCRYPT_CHACHA
16
#undef SCRYPT_CHOOSE_COMPILETIME
17
#define SCRYPT_KECCAK512
18
#define SCRYPT_CHACHA
19
#define SCRYPT_CHOOSE_COMPILETIME
20
21
//#include "scrypt-jane.h"
22
#include "../scryptjane/scrypt-jane-portable.h"
23
#include "../scryptjane/scrypt-jane-hash.h"
24
#include "../scryptjane/scrypt-jane-romix.h"
25
#include "../scryptjane/scrypt-jane-test-vectors.h"
26
27
28
#define scrypt_maxN 30 /* (1 << (30 + 1)) = ~2 billion */
29
#if (SCRYPT_BLOCK_BYTES == 64)
30
#define scrypt_r_32kb 8 /* (1 << 8) = 256 * 2 blocks in a chunk * 64 bytes = Max of 32kb in a chunk */
31
#elif (SCRYPT_BLOCK_BYTES == 128)
32
#define scrypt_r_32kb 7 /* (1 << 7) = 128 * 2 blocks in a chunk * 128 bytes = Max of 32kb in a chunk */
33
#elif (SCRYPT_BLOCK_BYTES == 256)
34
#define scrypt_r_32kb 6 /* (1 << 6) = 64 * 2 blocks in a chunk * 256 bytes = Max of 32kb in a chunk */
35
#elif (SCRYPT_BLOCK_BYTES == 512)
36
#define scrypt_r_32kb 5 /* (1 << 5) = 32 * 2 blocks in a chunk * 512 bytes = Max of 32kb in a chunk */
37
#endif
38
#define scrypt_maxr scrypt_r_32kb /* 32kb */
39
#define scrypt_maxp 25 /* (1 << 25) = ~33 million */
40
41
typedef struct scrypt_aligned_alloc_t {
42
uint8_t *mem, *ptr;
43
} scrypt_aligned_alloc;
44
45
static int
46
scrypt_alloc(uint64_t size, scrypt_aligned_alloc *aa) {
47
static const size_t max_alloc = (size_t)-1;
48
size += (SCRYPT_BLOCK_BYTES - 1);
49
if (size > max_alloc)
50
return 0; // scrypt_fatal_error("scrypt: not enough address space on this CPU to allocate required memory");
51
aa->mem = (uint8_t *)malloc((size_t)size);
52
aa->ptr = (uint8_t *)(((size_t)aa->mem + (SCRYPT_BLOCK_BYTES - 1)) & ~(SCRYPT_BLOCK_BYTES - 1));
53
if (!aa->mem)
54
return 0; // scrypt_fatal_error("scrypt: out of memory");
55
return 1;
56
}
57
58
static void
59
scrypt_free(scrypt_aligned_alloc *aa) {
60
free(aa->mem);
61
}
62
63
void
64
scrypt_N_1_1(const uint8_t *password, size_t password_len, const uint8_t *salt, size_t salt_len, uint32_t N, uint8_t *out, size_t bytes, uint8_t *X, uint8_t *Y, uint8_t *V) {
65
uint32_t chunk_bytes, i;
66
const uint32_t r = SCRYPT_R;
67
const uint32_t p = SCRYPT_P;
68
69
#if !defined(SCRYPT_CHOOSE_COMPILETIME)
70
scrypt_ROMixfn scrypt_ROMix = scrypt_getROMix();
71
#endif
72
73
chunk_bytes = SCRYPT_BLOCK_BYTES * r * 2;
74
75
/* 1: X = PBKDF2(password, salt) */
76
scrypt_pbkdf2_1(password, password_len, salt, salt_len, X, chunk_bytes * p);
77
78
/* 2: X = ROMix(X) */
79
for (i = 0; i < p; i++)
80
scrypt_ROMix_1((scrypt_mix_word_t *)(X + (chunk_bytes * i)), (scrypt_mix_word_t *)Y, (scrypt_mix_word_t *)V, N);
81
82
/* 3: Out = PBKDF2(password, X) */
83
scrypt_pbkdf2_1(password, password_len, X, chunk_bytes * p, out, bytes);
84
85
#ifdef SCRYPT_PREVENT_STATE_LEAK
86
/* This is an unnecessary security feature - mikaelh */
87
scrypt_ensure_zero(Y, (p + 1) * chunk_bytes);
88
#endif
89
}
90
91
92
// increasing Nfactor gradually
93
const unsigned char minNfactor = 4;
94
const unsigned char maxNfactor = 30;
95
96
unsigned char GetNfactor(unsigned int nTimestamp, unsigned int ntime) {
97
int l = 0;
98
unsigned long int s;
99
int n;
100
unsigned char N;
101
102
if (nTimestamp <= ntime)
103
return 4;
104
105
s = nTimestamp - ntime;
106
while ((s >> 1) > 3) {
107
l += 1;
108
s >>= 1;
109
}
110
111
s &= 3;
112
113
n = (l * 170 + s * 25 - 2320) / 100;
114
115
if (n < 0) n = 0;
116
117
if (n > 255) {
118
n = 255;
119
// printf("GetNfactor(%d) - something wrong(n == %d)\n", nTimestamp, n);
120
}
121
122
N = (unsigned char)n;
123
//printf("GetNfactor: %d -> %d %d : %d / %d\n", nTimestamp - nChainStartTime, l, s, n, min(max(N, minNfactor), maxNfactor));
124
125
if (N<minNfactor) return minNfactor;
126
if (N>maxNfactor) return maxNfactor;
127
return N;
128
}
129
130
131
int scanhash_scryptjane(int Nfactor, int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done)
132
{
133
scrypt_aligned_alloc YX, V;
134
uint8_t *X, *Y;
135
uint32_t N, chunk_bytes;
136
const uint32_t r = SCRYPT_R;
137
const uint32_t p = SCRYPT_P;
138
139
uint32_t *pdata = work->data;
140
uint32_t *ptarget = work->target;
141
uint32_t _ALIGN(64) endiandata[20];
142
const uint32_t first_nonce = pdata[19];
143
uint32_t nonce = first_nonce;
144
145
if (opt_benchmark)
146
ptarget[7] = 0x00ff;
147
148
for (int k = 0; k < 20; k++)
149
be32enc(&endiandata[k], pdata[k]);
150
151
//Nfactor = GetNfactor(data[17], ntime);
152
//if (Nfactor > scrypt_maxN) {
153
// return 1;
154
// //scrypt_fatal_error("scrypt: N out of range");
155
//}
156
157
N = (1 << (Nfactor + 1));
158
159
chunk_bytes = SCRYPT_BLOCK_BYTES * r * 2;
160
if (!scrypt_alloc((uint64_t)N * chunk_bytes, &V)) return 1;
161
if (!scrypt_alloc((p + 1) * chunk_bytes, &YX)) {
162
scrypt_free(&V);
163
return 1;
164
}
165
166
Y = YX.ptr;
167
X = Y + chunk_bytes;
168
169
do {
170
const uint32_t Htarg = ptarget[7];
171
uint32_t hash[8];
172
be32enc(&endiandata[19], nonce);
173
174
scrypt_N_1_1((unsigned char *)endiandata, 80,
175
(unsigned char *)endiandata, 80,
176
N, (unsigned char *)hash, 32, X, Y, V.ptr);
177
178
if (hash[7] <= Htarg && fulltest(hash, ptarget)) {
179
pdata[19] = nonce;
180
*hashes_done = pdata[19] - first_nonce;
181
scrypt_free(&V);
182
scrypt_free(&YX);
183
return 1;
184
}
185
nonce++;
186
187
} while (nonce < max_nonce && !work_restart[thr_id].restart);
188
189
pdata[19] = nonce;
190
*hashes_done = pdata[19] - first_nonce + 1;
191
192
scrypt_free(&V);
193
scrypt_free(&YX);
194
return 0;
195
}
196
197
/* simple cpu test (util.c) */
198
void scryptjanehash(void *output, const void *input, uint32_t Nfactor)
199
{
200
scrypt_aligned_alloc YX, V;
201
uint8_t *X, *Y;
202
uint32_t chunk_bytes;
203
uint32_t N = (1 << (Nfactor + 1));
204
const uint32_t r = SCRYPT_R;
205
const uint32_t p = SCRYPT_P;
206
207
memset(output, 0, 32);
208
209
chunk_bytes = SCRYPT_BLOCK_BYTES * r * 2;
210
if (!scrypt_alloc((uint64_t)N * chunk_bytes, &V)) return;
211
if (!scrypt_alloc((p + 1) * chunk_bytes, &YX)) {
212
scrypt_free(&V);
213
return;
214
}
215
216
Y = YX.ptr;
217
X = Y + chunk_bytes;
218
219
scrypt_N_1_1((unsigned char*)input, 80, (unsigned char*)input, 80,
220
N, (unsigned char*)output, 32, X, Y, V.ptr);
221
222
scrypt_free(&V);
223
scrypt_free(&YX);
224
}
225
226