scrypt 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/.rspec +2 -0
- data/CHANGELOG +3 -0
- data/COPYING +28 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +24 -0
- data/README +19 -0
- data/Rakefile +42 -0
- data/Rakefile.old +104 -0
- data/autotest/discover.rb +1 -0
- data/ext/mri/Makefile +157 -0
- data/ext/mri/crypto_scrypt-ref.c +284 -0
- data/ext/mri/crypto_scrypt.h +46 -0
- data/ext/mri/extconf.rb +4 -0
- data/ext/mri/memlimit.c +302 -0
- data/ext/mri/memlimit.h +42 -0
- data/ext/mri/scrypt_calibrate.c +104 -0
- data/ext/mri/scrypt_calibrate.h +19 -0
- data/ext/mri/scrypt_ext.bundle +0 -0
- data/ext/mri/scrypt_ext.c +126 -0
- data/ext/mri/scrypt_platform.h +4 -0
- data/ext/mri/scryptenc_cpuperf.c +185 -0
- data/ext/mri/scryptenc_cpuperf.h +39 -0
- data/ext/mri/sha256.c +412 -0
- data/ext/mri/sha256.h +62 -0
- data/ext/mri/sysendian.h +140 -0
- data/lib/scrypt.rb +171 -0
- data/lib/scrypt/version.rb +3 -0
- data/scrypt.gemspec +27 -0
- data/spec/scrypt/engine_spec.rb +58 -0
- data/spec/scrypt/password_spec.rb +62 -0
- data/spec/spec_helper.rb +4 -0
- metadata +101 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
/*-
|
2
|
+
* Copyright 2009 Colin Percival
|
3
|
+
* All rights reserved.
|
4
|
+
*
|
5
|
+
* Redistribution and use in source and binary forms, with or without
|
6
|
+
* modification, are permitted provided that the following conditions
|
7
|
+
* are met:
|
8
|
+
* 1. Redistributions of source code must retain the above copyright
|
9
|
+
* notice, this list of conditions and the following disclaimer.
|
10
|
+
* 2. Redistributions in binary form must reproduce the above copyright
|
11
|
+
* notice, this list of conditions and the following disclaimer in the
|
12
|
+
* documentation and/or other materials provided with the distribution.
|
13
|
+
*
|
14
|
+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
15
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
16
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
17
|
+
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
18
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
19
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
20
|
+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
21
|
+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
22
|
+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
23
|
+
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
24
|
+
* SUCH DAMAGE.
|
25
|
+
*
|
26
|
+
* This file was originally written by Colin Percival as part of the Tarsnap
|
27
|
+
* online backup system.
|
28
|
+
*/
|
29
|
+
#ifndef _CRYPTO_SCRYPT_H_
|
30
|
+
#define _CRYPTO_SCRYPT_H_
|
31
|
+
|
32
|
+
#include <stdint.h>
|
33
|
+
|
34
|
+
/**
|
35
|
+
* crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
|
36
|
+
* Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
|
37
|
+
* p, buflen) and write the result into buf. The parameters r, p, and buflen
|
38
|
+
* must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N
|
39
|
+
* must be a power of 2 greater than 1.
|
40
|
+
*
|
41
|
+
* Return 0 on success; or -1 on error.
|
42
|
+
*/
|
43
|
+
int crypto_scrypt(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t,
|
44
|
+
uint32_t, uint32_t, uint8_t *, size_t);
|
45
|
+
|
46
|
+
#endif /* !_CRYPTO_SCRYPT_H_ */
|
data/ext/mri/extconf.rb
ADDED
data/ext/mri/memlimit.c
ADDED
@@ -0,0 +1,302 @@
|
|
1
|
+
/*-
|
2
|
+
* Copyright 2009 Colin Percival
|
3
|
+
* All rights reserved.
|
4
|
+
*
|
5
|
+
* Redistribution and use in source and binary forms, with or without
|
6
|
+
* modification, are permitted provided that the following conditions
|
7
|
+
* are met:
|
8
|
+
* 1. Redistributions of source code must retain the above copyright
|
9
|
+
* notice, this list of conditions and the following disclaimer.
|
10
|
+
* 2. Redistributions in binary form must reproduce the above copyright
|
11
|
+
* notice, this list of conditions and the following disclaimer in the
|
12
|
+
* documentation and/or other materials provided with the distribution.
|
13
|
+
*
|
14
|
+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
15
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
16
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
17
|
+
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
18
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
19
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
20
|
+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
21
|
+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
22
|
+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
23
|
+
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
24
|
+
* SUCH DAMAGE.
|
25
|
+
*
|
26
|
+
* This file was originally written by Colin Percival as part of the Tarsnap
|
27
|
+
* online backup system.
|
28
|
+
*/
|
29
|
+
#include "scrypt_platform.h"
|
30
|
+
|
31
|
+
#include <sys/types.h>
|
32
|
+
#include <sys/resource.h>
|
33
|
+
|
34
|
+
#ifdef HAVE_SYS_PARAM_H
|
35
|
+
#include <sys/param.h>
|
36
|
+
#endif
|
37
|
+
#ifdef HAVE_SYSCTL_HW_USERMEM
|
38
|
+
#include <sys/sysctl.h>
|
39
|
+
#endif
|
40
|
+
#ifdef HAVE_SYS_SYSINFO_H
|
41
|
+
#include <sys/sysinfo.h>
|
42
|
+
#endif
|
43
|
+
|
44
|
+
#include <errno.h>
|
45
|
+
#include <stddef.h>
|
46
|
+
#include <stdint.h>
|
47
|
+
#include <unistd.h>
|
48
|
+
|
49
|
+
#ifdef DEBUG
|
50
|
+
#include <stdio.h>
|
51
|
+
#endif
|
52
|
+
|
53
|
+
#include "memlimit.h"
|
54
|
+
|
55
|
+
#ifdef HAVE_SYSCTL_HW_USERMEM
|
56
|
+
static int
|
57
|
+
memlimit_sysctl_hw_usermem(size_t * memlimit)
|
58
|
+
{
|
59
|
+
int mib[2];
|
60
|
+
uint8_t usermembuf[8];
|
61
|
+
size_t usermemlen = 8;
|
62
|
+
uint64_t usermem;
|
63
|
+
|
64
|
+
/* Ask the kernel how much RAM we have. */
|
65
|
+
mib[0] = CTL_HW;
|
66
|
+
mib[1] = HW_USERMEM;
|
67
|
+
if (sysctl(mib, 2, usermembuf, &usermemlen, NULL, 0))
|
68
|
+
return (1);
|
69
|
+
|
70
|
+
/*
|
71
|
+
* Parse as either a uint64_t or a uint32_t based on the length of
|
72
|
+
* output the kernel reports having copied out. It appears that all
|
73
|
+
* systems providing a sysctl interface for reading integers copy
|
74
|
+
* them out as system-endian values, so we don't need to worry about
|
75
|
+
* parsing them.
|
76
|
+
*/
|
77
|
+
if (usermemlen == sizeof(uint64_t))
|
78
|
+
usermem = *(uint64_t *)usermembuf;
|
79
|
+
else if (usermemlen == sizeof(uint32_t))
|
80
|
+
usermem = *(uint32_t *)usermembuf;
|
81
|
+
else
|
82
|
+
return (1);
|
83
|
+
|
84
|
+
/* Return the sysctl value, but clamp to SIZE_MAX if necessary. */
|
85
|
+
#if UINT64_MAX > SIZE_MAX
|
86
|
+
if (usermem > SIZE_MAX)
|
87
|
+
*memlimit = SIZE_MAX;
|
88
|
+
else
|
89
|
+
*memlimit = usermem;
|
90
|
+
#else
|
91
|
+
*memlimit = usermem;
|
92
|
+
#endif
|
93
|
+
|
94
|
+
/* Success! */
|
95
|
+
return (0);
|
96
|
+
}
|
97
|
+
#endif
|
98
|
+
|
99
|
+
/* If we don't HAVE_STRUCT_SYSINFO, we can't use sysinfo. */
|
100
|
+
#ifndef HAVE_STRUCT_SYSINFO
|
101
|
+
#undef HAVE_SYSINFO
|
102
|
+
#endif
|
103
|
+
|
104
|
+
/* If we don't HAVE_STRUCT_SYSINFO_TOTALRAM, we can't use sysinfo. */
|
105
|
+
#ifndef HAVE_STRUCT_SYSINFO_TOTALRAM
|
106
|
+
#undef HAVE_SYSINFO
|
107
|
+
#endif
|
108
|
+
|
109
|
+
#ifdef HAVE_SYSINFO
|
110
|
+
static int
|
111
|
+
memlimit_sysinfo(size_t * memlimit)
|
112
|
+
{
|
113
|
+
struct sysinfo info;
|
114
|
+
uint64_t totalmem;
|
115
|
+
|
116
|
+
/* Get information from the kernel. */
|
117
|
+
if (sysinfo(&info))
|
118
|
+
return (1);
|
119
|
+
totalmem = info.totalram;
|
120
|
+
|
121
|
+
/* If we're on a modern kernel, adjust based on mem_unit. */
|
122
|
+
#ifdef HAVE_STRUCT_SYSINFO_MEM_UNIT
|
123
|
+
totalmem = totalmem * info.mem_unit;
|
124
|
+
#endif
|
125
|
+
|
126
|
+
/* Return the value, but clamp to SIZE_MAX if necessary. */
|
127
|
+
#if UINT64_MAX > SIZE_MAX
|
128
|
+
if (totalmem > SIZE_MAX)
|
129
|
+
*memlimit = SIZE_MAX;
|
130
|
+
else
|
131
|
+
*memlimit = totalmem;
|
132
|
+
#else
|
133
|
+
*memlimit = totalmem;
|
134
|
+
#endif
|
135
|
+
|
136
|
+
/* Success! */
|
137
|
+
return (0);
|
138
|
+
}
|
139
|
+
#endif /* HAVE_SYSINFO */
|
140
|
+
|
141
|
+
static int
|
142
|
+
memlimit_rlimit(size_t * memlimit)
|
143
|
+
{
|
144
|
+
struct rlimit rl;
|
145
|
+
uint64_t memrlimit;
|
146
|
+
|
147
|
+
/* Find the least of... */
|
148
|
+
memrlimit = (uint64_t)(-1);
|
149
|
+
|
150
|
+
/* ... RLIMIT_AS... */
|
151
|
+
#ifdef RLIMIT_AS
|
152
|
+
if (getrlimit(RLIMIT_AS, &rl))
|
153
|
+
return (1);
|
154
|
+
if ((rl.rlim_cur != RLIM_INFINITY) &&
|
155
|
+
((uint64_t)rl.rlim_cur < memrlimit))
|
156
|
+
memrlimit = rl.rlim_cur;
|
157
|
+
#endif
|
158
|
+
|
159
|
+
/* ... RLIMIT_DATA... */
|
160
|
+
if (getrlimit(RLIMIT_DATA, &rl))
|
161
|
+
return (1);
|
162
|
+
if ((rl.rlim_cur != RLIM_INFINITY) &&
|
163
|
+
((uint64_t)rl.rlim_cur < memrlimit))
|
164
|
+
memrlimit = rl.rlim_cur;
|
165
|
+
|
166
|
+
/* ... and RLIMIT_RSS. */
|
167
|
+
#ifdef RLIMIT_RSS
|
168
|
+
if (getrlimit(RLIMIT_RSS, &rl))
|
169
|
+
return (1);
|
170
|
+
if ((rl.rlim_cur != RLIM_INFINITY) &&
|
171
|
+
((uint64_t)rl.rlim_cur < memrlimit))
|
172
|
+
memrlimit = rl.rlim_cur;
|
173
|
+
#endif
|
174
|
+
|
175
|
+
/* Return the value, but clamp to SIZE_MAX if necessary. */
|
176
|
+
#if UINT64_MAX > SIZE_MAX
|
177
|
+
if (memrlimit > SIZE_MAX)
|
178
|
+
*memlimit = SIZE_MAX;
|
179
|
+
else
|
180
|
+
*memlimit = memrlimit;
|
181
|
+
#else
|
182
|
+
*memlimit = memrlimit;
|
183
|
+
#endif
|
184
|
+
|
185
|
+
/* Success! */
|
186
|
+
return (0);
|
187
|
+
}
|
188
|
+
|
189
|
+
#ifdef _SC_PHYS_PAGES
|
190
|
+
|
191
|
+
/* Some systems define _SC_PAGESIZE instead of _SC_PAGE_SIZE. */
|
192
|
+
#ifndef _SC_PAGE_SIZE
|
193
|
+
#define _SC_PAGE_SIZE _SC_PAGESIZE
|
194
|
+
#endif
|
195
|
+
|
196
|
+
static int
|
197
|
+
memlimit_sysconf(size_t * memlimit)
|
198
|
+
{
|
199
|
+
long pagesize;
|
200
|
+
long physpages;
|
201
|
+
uint64_t totalmem;
|
202
|
+
|
203
|
+
/* Set errno to 0 in order to distinguish "no limit" from "error". */
|
204
|
+
errno = 0;
|
205
|
+
|
206
|
+
/* Read the two limits. */
|
207
|
+
if (((pagesize = sysconf(_SC_PAGE_SIZE)) == -1) ||
|
208
|
+
((physpages = sysconf(_SC_PHYS_PAGES)) == -1)) {
|
209
|
+
/* Did an error occur? */
|
210
|
+
if (errno != 0)
|
211
|
+
return (1);
|
212
|
+
|
213
|
+
/* If not, there is no limit. */
|
214
|
+
totalmem = (uint64_t)(-1);
|
215
|
+
} else {
|
216
|
+
/* Compute the limit. */
|
217
|
+
totalmem = (uint64_t)(pagesize) * (uint64_t)(physpages);
|
218
|
+
}
|
219
|
+
|
220
|
+
/* Return the value, but clamp to SIZE_MAX if necessary. */
|
221
|
+
#if UINT64_MAX > SIZE_MAX
|
222
|
+
if (totalmem > SIZE_MAX)
|
223
|
+
*memlimit = SIZE_MAX;
|
224
|
+
else
|
225
|
+
*memlimit = totalmem;
|
226
|
+
#else
|
227
|
+
*memlimit = totalmem;
|
228
|
+
#endif
|
229
|
+
|
230
|
+
/* Success! */
|
231
|
+
return (0);
|
232
|
+
}
|
233
|
+
#endif
|
234
|
+
|
235
|
+
int
|
236
|
+
memtouse(size_t maxmem, double maxmemfrac, size_t * memlimit)
|
237
|
+
{
|
238
|
+
size_t sysctl_memlimit, sysinfo_memlimit, rlimit_memlimit;
|
239
|
+
size_t sysconf_memlimit;
|
240
|
+
size_t memlimit_min;
|
241
|
+
size_t memavail;
|
242
|
+
|
243
|
+
/* Get memory limits. */
|
244
|
+
#ifdef HAVE_SYSCTL_HW_USERMEM
|
245
|
+
if (memlimit_sysctl_hw_usermem(&sysctl_memlimit))
|
246
|
+
return (1);
|
247
|
+
#else
|
248
|
+
sysctl_memlimit = (size_t)(-1);
|
249
|
+
#endif
|
250
|
+
#ifdef HAVE_SYSINFO
|
251
|
+
if (memlimit_sysinfo(&sysinfo_memlimit))
|
252
|
+
return (1);
|
253
|
+
#else
|
254
|
+
sysinfo_memlimit = (size_t)(-1);
|
255
|
+
#endif
|
256
|
+
if (memlimit_rlimit(&rlimit_memlimit))
|
257
|
+
return (1);
|
258
|
+
#ifdef _SC_PHYS_PAGES
|
259
|
+
if (memlimit_sysconf(&sysconf_memlimit))
|
260
|
+
return (1);
|
261
|
+
#else
|
262
|
+
sysconf_memlimit = (size_t)(-1);
|
263
|
+
#endif
|
264
|
+
|
265
|
+
#ifdef DEBUG
|
266
|
+
fprintf(stderr, "Memory limits are %zu %zu %zu %zu\n",
|
267
|
+
sysctl_memlimit, sysinfo_memlimit, rlimit_memlimit,
|
268
|
+
sysconf_memlimit);
|
269
|
+
#endif
|
270
|
+
|
271
|
+
/* Find the smallest of them. */
|
272
|
+
memlimit_min = (size_t)(-1);
|
273
|
+
if (memlimit_min > sysctl_memlimit)
|
274
|
+
memlimit_min = sysctl_memlimit;
|
275
|
+
if (memlimit_min > sysinfo_memlimit)
|
276
|
+
memlimit_min = sysinfo_memlimit;
|
277
|
+
if (memlimit_min > rlimit_memlimit)
|
278
|
+
memlimit_min = rlimit_memlimit;
|
279
|
+
if (memlimit_min > sysconf_memlimit)
|
280
|
+
memlimit_min = sysconf_memlimit;
|
281
|
+
|
282
|
+
/* Only use the specified fraction of the available memory. */
|
283
|
+
if ((maxmemfrac > 0.5) || (maxmemfrac == 0.0))
|
284
|
+
maxmemfrac = 0.5;
|
285
|
+
memavail = maxmemfrac * memlimit_min;
|
286
|
+
|
287
|
+
/* Don't use more than the specified maximum. */
|
288
|
+
if ((maxmem > 0) && (memavail > maxmem))
|
289
|
+
memavail = maxmem;
|
290
|
+
|
291
|
+
/* But always allow at least 1 MiB. */
|
292
|
+
if (memavail < 1048576)
|
293
|
+
memavail = 1048576;
|
294
|
+
|
295
|
+
#ifdef DEBUG
|
296
|
+
fprintf(stderr, "Allowing up to %zu memory to be used\n", memavail);
|
297
|
+
#endif
|
298
|
+
|
299
|
+
/* Return limit via the provided pointer. */
|
300
|
+
*memlimit = memavail;
|
301
|
+
return (0);
|
302
|
+
}
|
data/ext/mri/memlimit.h
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
/*-
|
2
|
+
* Copyright 2009 Colin Percival
|
3
|
+
* All rights reserved.
|
4
|
+
*
|
5
|
+
* Redistribution and use in source and binary forms, with or without
|
6
|
+
* modification, are permitted provided that the following conditions
|
7
|
+
* are met:
|
8
|
+
* 1. Redistributions of source code must retain the above copyright
|
9
|
+
* notice, this list of conditions and the following disclaimer.
|
10
|
+
* 2. Redistributions in binary form must reproduce the above copyright
|
11
|
+
* notice, this list of conditions and the following disclaimer in the
|
12
|
+
* documentation and/or other materials provided with the distribution.
|
13
|
+
*
|
14
|
+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
15
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
16
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
17
|
+
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
18
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
19
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
20
|
+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
21
|
+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
22
|
+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
23
|
+
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
24
|
+
* SUCH DAMAGE.
|
25
|
+
*
|
26
|
+
* This file was originally written by Colin Percival as part of the Tarsnap
|
27
|
+
* online backup system.
|
28
|
+
*/
|
29
|
+
#ifndef _MEMLIMIT_H_
|
30
|
+
#define _MEMLIMIT_H_
|
31
|
+
|
32
|
+
#include <stddef.h>
|
33
|
+
|
34
|
+
/**
|
35
|
+
* memtouse(maxmem, maxmemfrac, memlimit):
|
36
|
+
* Examine the system and return via memlimit the amount of RAM which should
|
37
|
+
* be used -- the specified fraction of the available RAM, but no more than
|
38
|
+
* maxmem, and no less than 1MiB.
|
39
|
+
*/
|
40
|
+
int memtouse(size_t, double, size_t *);
|
41
|
+
|
42
|
+
#endif /* !_MEMLIMIT_H_ */
|
@@ -0,0 +1,104 @@
|
|
1
|
+
/*
|
2
|
+
* scrypt_calibrate.c
|
3
|
+
* scrypt
|
4
|
+
*
|
5
|
+
* Created by Patrick Hogan on 12/15/10.
|
6
|
+
* Copyright 2010 __MyCompanyName__. All rights reserved.
|
7
|
+
*
|
8
|
+
*/
|
9
|
+
|
10
|
+
#include "scrypt_platform.h"
|
11
|
+
|
12
|
+
#include <errno.h>
|
13
|
+
#include <fcntl.h>
|
14
|
+
#include <stdint.h>
|
15
|
+
#include <stdio.h>
|
16
|
+
#include <string.h>
|
17
|
+
#include <unistd.h>
|
18
|
+
|
19
|
+
#include "memlimit.h"
|
20
|
+
#include "scryptenc_cpuperf.h"
|
21
|
+
#include "sysendian.h"
|
22
|
+
|
23
|
+
#include "scrypt_calibrate.h"
|
24
|
+
|
25
|
+
|
26
|
+
static int
|
27
|
+
pickparams(size_t maxmem, double maxmemfrac, double maxtime,
|
28
|
+
int * logN, uint32_t * r, uint32_t * p)
|
29
|
+
{
|
30
|
+
size_t memlimit;
|
31
|
+
double opps;
|
32
|
+
double opslimit;
|
33
|
+
double maxN, maxrp;
|
34
|
+
int rc;
|
35
|
+
|
36
|
+
/* Figure out how much memory to use. */
|
37
|
+
if (memtouse(maxmem, maxmemfrac, &memlimit))
|
38
|
+
return (1);
|
39
|
+
|
40
|
+
/* Figure out how fast the CPU is. */
|
41
|
+
if ((rc = scryptenc_cpuperf(&opps)) != 0)
|
42
|
+
return (rc);
|
43
|
+
opslimit = opps * maxtime;
|
44
|
+
|
45
|
+
/* Allow a minimum of 2^15 salsa20/8 cores. */
|
46
|
+
if (opslimit < 32768)
|
47
|
+
opslimit = 32768;
|
48
|
+
|
49
|
+
/* Fix r = 8 for now. */
|
50
|
+
*r = 8;
|
51
|
+
|
52
|
+
/*
|
53
|
+
* The memory limit requires that 128Nr <= memlimit, while the CPU
|
54
|
+
* limit requires that 4Nrp <= opslimit. If opslimit < memlimit/32,
|
55
|
+
* opslimit imposes the stronger limit on N.
|
56
|
+
*/
|
57
|
+
#ifdef DEBUG
|
58
|
+
fprintf(stderr, "Requiring 128Nr <= %zu, 4Nrp <= %f\n",
|
59
|
+
memlimit, opslimit);
|
60
|
+
#endif
|
61
|
+
if (opslimit < memlimit/32) {
|
62
|
+
/* Set p = 1 and choose N based on the CPU limit. */
|
63
|
+
*p = 1;
|
64
|
+
maxN = opslimit / (*r * 4);
|
65
|
+
for (*logN = 1; *logN < 63; *logN += 1) {
|
66
|
+
if ((uint64_t)(1) << *logN > maxN / 2)
|
67
|
+
break;
|
68
|
+
}
|
69
|
+
} else {
|
70
|
+
/* Set N based on the memory limit. */
|
71
|
+
maxN = memlimit / (*r * 128);
|
72
|
+
for (*logN = 1; *logN < 63; *logN += 1) {
|
73
|
+
if ((uint64_t)(1) << *logN > maxN / 2)
|
74
|
+
break;
|
75
|
+
}
|
76
|
+
|
77
|
+
/* Choose p based on the CPU limit. */
|
78
|
+
maxrp = (opslimit / 4) / ((uint64_t)(1) << *logN);
|
79
|
+
if (maxrp > 0x3fffffff)
|
80
|
+
maxrp = 0x3fffffff;
|
81
|
+
*p = (uint32_t)(maxrp) / *r;
|
82
|
+
}
|
83
|
+
|
84
|
+
#ifdef DEBUG
|
85
|
+
fprintf(stderr, "N = %zu r = %d p = %d\n",
|
86
|
+
(size_t)(1) << *logN, (int)(*r), (int)(*p));
|
87
|
+
#endif
|
88
|
+
|
89
|
+
/* Success! */
|
90
|
+
return (0);
|
91
|
+
}
|
92
|
+
|
93
|
+
int
|
94
|
+
calibrate(size_t maxmem, double maxmemfrac, double maxtime,
|
95
|
+
uint64_t * n, uint32_t * r, uint32_t * p)
|
96
|
+
{
|
97
|
+
int logN = 0;
|
98
|
+
int result = pickparams( maxmem, maxmemfrac, maxtime, & logN, r, p );
|
99
|
+
if (result == 0)
|
100
|
+
{
|
101
|
+
*n = (uint64_t)(1) << logN;
|
102
|
+
}
|
103
|
+
return result;
|
104
|
+
}
|