scrypt 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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_ */
@@ -0,0 +1,4 @@
1
+ require "mkmf"
2
+ dir_config("scrypt_ext")
3
+ CONFIG['CC'] << " -Wall "
4
+ create_makefile("scrypt_ext")
@@ -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
+ }
@@ -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
+ }