scrypt 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
}
|