scrypt 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore DELETED
@@ -1,9 +0,0 @@
1
- pkg/*
2
- doc/*
3
- *.gem
4
- .bundle
5
- ext/mri/*.bundle
6
- *.o
7
- .DS_Store
8
-
9
- ext/mri/Makefile
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --colour
2
- --backtrace
data/.rvmrc DELETED
@@ -1 +0,0 @@
1
- rvm use --create 1.9.3@scrypt
data/.travis.yml DELETED
@@ -1,4 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 1.8.7
4
- - 1.9.3
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- # Specify your gem's dependencies in scrypt.gemspec
4
- gemspec
data/Gemfile.lock DELETED
@@ -1,32 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- scrypt (1.1.0)
5
-
6
- GEM
7
- remote: http://rubygems.org/
8
- specs:
9
- awesome_print (1.0.2)
10
- diff-lcs (1.1.3)
11
- json (1.7.0)
12
- rake (0.9.2.2)
13
- rdoc (3.12)
14
- json (~> 1.4)
15
- rspec (2.9.0)
16
- rspec-core (~> 2.9.0)
17
- rspec-expectations (~> 2.9.0)
18
- rspec-mocks (~> 2.9.0)
19
- rspec-core (2.9.0)
20
- rspec-expectations (2.9.1)
21
- diff-lcs (~> 1.1.3)
22
- rspec-mocks (2.9.0)
23
-
24
- PLATFORMS
25
- ruby
26
-
27
- DEPENDENCIES
28
- awesome_print
29
- rake (~> 0.9.2)
30
- rdoc
31
- rspec
32
- scrypt!
@@ -1,340 +0,0 @@
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
- #ifndef __MINGW32__
33
- #include <sys/mman.h>
34
- #endif
35
-
36
- #include <errno.h>
37
- #include <stdint.h>
38
- #include <stdlib.h>
39
- #include <string.h>
40
-
41
- #include "sha256.h"
42
- #include "sysendian.h"
43
-
44
- #include "crypto_scrypt.h"
45
-
46
- static void blkcpy(void *, void *, size_t);
47
- static void blkxor(void *, void *, size_t);
48
- static void salsa20_8(uint32_t[16]);
49
- static void blockmix_salsa8(uint32_t *, uint32_t *, uint32_t *, size_t);
50
- static uint64_t integerify(void *, size_t);
51
- static void smix(uint8_t *, size_t, uint64_t, uint32_t *, uint32_t *);
52
-
53
- static void
54
- blkcpy(void * dest, void * src, size_t len)
55
- {
56
- size_t * D = dest;
57
- size_t * S = src;
58
- size_t L = len / sizeof(size_t);
59
- size_t i;
60
-
61
- for (i = 0; i < L; i++)
62
- D[i] = S[i];
63
- }
64
-
65
- static void
66
- blkxor(void * dest, void * src, size_t len)
67
- {
68
- size_t * D = dest;
69
- size_t * S = src;
70
- size_t L = len / sizeof(size_t);
71
- size_t i;
72
-
73
- for (i = 0; i < L; i++)
74
- D[i] ^= S[i];
75
- }
76
-
77
- /**
78
- * salsa20_8(B):
79
- * Apply the salsa20/8 core to the provided block.
80
- */
81
- static void
82
- salsa20_8(uint32_t B[16])
83
- {
84
- uint32_t x[16];
85
- size_t i;
86
-
87
- blkcpy(x, B, 64);
88
- for (i = 0; i < 8; i += 2) {
89
- #define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
90
- /* Operate on columns. */
91
- x[ 4] ^= R(x[ 0]+x[12], 7); x[ 8] ^= R(x[ 4]+x[ 0], 9);
92
- x[12] ^= R(x[ 8]+x[ 4],13); x[ 0] ^= R(x[12]+x[ 8],18);
93
-
94
- x[ 9] ^= R(x[ 5]+x[ 1], 7); x[13] ^= R(x[ 9]+x[ 5], 9);
95
- x[ 1] ^= R(x[13]+x[ 9],13); x[ 5] ^= R(x[ 1]+x[13],18);
96
-
97
- x[14] ^= R(x[10]+x[ 6], 7); x[ 2] ^= R(x[14]+x[10], 9);
98
- x[ 6] ^= R(x[ 2]+x[14],13); x[10] ^= R(x[ 6]+x[ 2],18);
99
-
100
- x[ 3] ^= R(x[15]+x[11], 7); x[ 7] ^= R(x[ 3]+x[15], 9);
101
- x[11] ^= R(x[ 7]+x[ 3],13); x[15] ^= R(x[11]+x[ 7],18);
102
-
103
- /* Operate on rows. */
104
- x[ 1] ^= R(x[ 0]+x[ 3], 7); x[ 2] ^= R(x[ 1]+x[ 0], 9);
105
- x[ 3] ^= R(x[ 2]+x[ 1],13); x[ 0] ^= R(x[ 3]+x[ 2],18);
106
-
107
- x[ 6] ^= R(x[ 5]+x[ 4], 7); x[ 7] ^= R(x[ 6]+x[ 5], 9);
108
- x[ 4] ^= R(x[ 7]+x[ 6],13); x[ 5] ^= R(x[ 4]+x[ 7],18);
109
-
110
- x[11] ^= R(x[10]+x[ 9], 7); x[ 8] ^= R(x[11]+x[10], 9);
111
- x[ 9] ^= R(x[ 8]+x[11],13); x[10] ^= R(x[ 9]+x[ 8],18);
112
-
113
- x[12] ^= R(x[15]+x[14], 7); x[13] ^= R(x[12]+x[15], 9);
114
- x[14] ^= R(x[13]+x[12],13); x[15] ^= R(x[14]+x[13],18);
115
- #undef R
116
- }
117
- for (i = 0; i < 16; i++)
118
- B[i] += x[i];
119
- }
120
-
121
- /**
122
- * blockmix_salsa8(Bin, Bout, X, r):
123
- * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r
124
- * bytes in length; the output Bout must also be the same size. The
125
- * temporary space X must be 64 bytes.
126
- */
127
- static void
128
- blockmix_salsa8(uint32_t * Bin, uint32_t * Bout, uint32_t * X, size_t r)
129
- {
130
- size_t i;
131
-
132
- /* 1: X <-- B_{2r - 1} */
133
- blkcpy(X, &Bin[(2 * r - 1) * 16], 64);
134
-
135
- /* 2: for i = 0 to 2r - 1 do */
136
- for (i = 0; i < 2 * r; i += 2) {
137
- /* 3: X <-- H(X \xor B_i) */
138
- blkxor(X, &Bin[i * 16], 64);
139
- salsa20_8(X);
140
-
141
- /* 4: Y_i <-- X */
142
- /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
143
- blkcpy(&Bout[i * 8], X, 64);
144
-
145
- /* 3: X <-- H(X \xor B_i) */
146
- blkxor(X, &Bin[i * 16 + 16], 64);
147
- salsa20_8(X);
148
-
149
- /* 4: Y_i <-- X */
150
- /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
151
- blkcpy(&Bout[i * 8 + r * 16], X, 64);
152
- }
153
- }
154
-
155
- /**
156
- * integerify(B, r):
157
- * Return the result of parsing B_{2r-1} as a little-endian integer.
158
- */
159
- static uint64_t
160
- integerify(void * B, size_t r)
161
- {
162
- uint32_t * X = (void *)((uintptr_t)(B) + (2 * r - 1) * 64);
163
-
164
- return (((uint64_t)(X[1]) << 32) + X[0]);
165
- }
166
-
167
- /**
168
- * smix(B, r, N, V, XY):
169
- * Compute B = SMix_r(B, N). The input B must be 128r bytes in length;
170
- * the temporary storage V must be 128rN bytes in length; the temporary
171
- * storage XY must be 256r + 64 bytes in length. The value N must be a
172
- * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a
173
- * multiple of 64 bytes.
174
- */
175
- static void
176
- smix(uint8_t * B, size_t r, uint64_t N, uint32_t * V, uint32_t * XY)
177
- {
178
- uint32_t * X = XY;
179
- uint32_t * Y = &XY[32 * r];
180
- uint32_t * Z = &XY[64 * r];
181
- uint64_t i;
182
- uint64_t j;
183
- size_t k;
184
-
185
- /* 1: X <-- B */
186
- for (k = 0; k < 32 * r; k++)
187
- X[k] = le32dec(&B[4 * k]);
188
-
189
- /* 2: for i = 0 to N - 1 do */
190
- for (i = 0; i < N; i += 2) {
191
- /* 3: V_i <-- X */
192
- blkcpy(&V[i * (32 * r)], X, 128 * r);
193
-
194
- /* 4: X <-- H(X) */
195
- blockmix_salsa8(X, Y, Z, r);
196
-
197
- /* 3: V_i <-- X */
198
- blkcpy(&V[(i + 1) * (32 * r)], Y, 128 * r);
199
-
200
- /* 4: X <-- H(X) */
201
- blockmix_salsa8(Y, X, Z, r);
202
- }
203
-
204
- /* 6: for i = 0 to N - 1 do */
205
- for (i = 0; i < N; i += 2) {
206
- /* 7: j <-- Integerify(X) mod N */
207
- j = integerify(X, r) & (N - 1);
208
-
209
- /* 8: X <-- H(X \xor V_j) */
210
- blkxor(X, &V[j * (32 * r)], 128 * r);
211
- blockmix_salsa8(X, Y, Z, r);
212
-
213
- /* 7: j <-- Integerify(X) mod N */
214
- j = integerify(Y, r) & (N - 1);
215
-
216
- /* 8: X <-- H(X \xor V_j) */
217
- blkxor(Y, &V[j * (32 * r)], 128 * r);
218
- blockmix_salsa8(Y, X, Z, r);
219
- }
220
-
221
- /* 10: B' <-- X */
222
- for (k = 0; k < 32 * r; k++)
223
- le32enc(&B[4 * k], X[k]);
224
- }
225
-
226
- /**
227
- * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
228
- * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
229
- * p, buflen) and write the result into buf. The parameters r, p, and buflen
230
- * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N
231
- * must be a power of 2 greater than 1.
232
- *
233
- * Return 0 on success; or -1 on error.
234
- */
235
- int
236
- crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
237
- const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p,
238
- uint8_t * buf, size_t buflen)
239
- {
240
- void * B0, * V0, * XY0;
241
- uint8_t * B;
242
- uint32_t * V;
243
- uint32_t * XY;
244
- uint32_t i;
245
-
246
- /* Sanity-check parameters. */
247
- #if SIZE_MAX > UINT32_MAX
248
- if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
249
- errno = EFBIG;
250
- goto err0;
251
- }
252
- #endif
253
- if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
254
- errno = EFBIG;
255
- goto err0;
256
- }
257
- if (((N & (N - 1)) != 0) || (N == 0)) {
258
- errno = EINVAL;
259
- goto err0;
260
- }
261
- if ((r > SIZE_MAX / 128 / p) ||
262
- #if SIZE_MAX / 256 <= UINT32_MAX
263
- (r > SIZE_MAX / 256) ||
264
- #endif
265
- (N > SIZE_MAX / 128 / r)) {
266
- errno = ENOMEM;
267
- goto err0;
268
- }
269
-
270
- /* Allocate memory. */
271
- #ifdef HAVE_POSIX_MEMALIGN
272
- if ((errno = posix_memalign(&B0, 64, 128 * r * p)) != 0)
273
- goto err0;
274
- B = (uint8_t *)(B0);
275
- if ((errno = posix_memalign(&XY0, 64, 256 * r + 64)) != 0)
276
- goto err1;
277
- XY = (uint32_t *)(XY0);
278
- #ifndef MAP_ANON
279
- if ((errno = posix_memalign(&V0, 64, 128 * r * N)) != 0)
280
- goto err2;
281
- V = (uint32_t *)(V0);
282
- #endif
283
- #else
284
- if ((B0 = malloc(128 * r * p + 63)) == NULL)
285
- goto err0;
286
- B = (uint8_t *)(((uintptr_t)(B0) + 63) & ~ (uintptr_t)(63));
287
- if ((XY0 = malloc(256 * r + 64 + 63)) == NULL)
288
- goto err1;
289
- XY = (uint32_t *)(((uintptr_t)(XY0) + 63) & ~ (uintptr_t)(63));
290
- #ifndef MAP_ANON
291
- if ((V0 = malloc(128 * r * N + 63)) == NULL)
292
- goto err2;
293
- V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63));
294
- #endif
295
- #endif
296
- #ifdef MAP_ANON
297
- if ((V0 = mmap(NULL, 128 * r * N, PROT_READ | PROT_WRITE,
298
- #ifdef MAP_NOCORE
299
- MAP_ANON | MAP_PRIVATE | MAP_NOCORE,
300
- #else
301
- MAP_ANON | MAP_PRIVATE,
302
- #endif
303
- -1, 0)) == MAP_FAILED)
304
- goto err2;
305
- V = (uint32_t *)(V0);
306
- #endif
307
-
308
- /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
309
- PBKDF2_scrypt_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r);
310
-
311
- /* 2: for i = 0 to p - 1 do */
312
- for (i = 0; i < p; i++) {
313
- /* 3: B_i <-- MF(B_i, N) */
314
- smix(&B[i * 128 * r], r, N, V, XY);
315
- }
316
-
317
- /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
318
- PBKDF2_scrypt_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);
319
-
320
- /* Free memory. */
321
- #ifdef MAP_ANON
322
- if (munmap(V0, 128 * r * N))
323
- goto err2;
324
- #else
325
- free(V0);
326
- #endif
327
- free(XY0);
328
- free(B0);
329
-
330
- /* Success! */
331
- return (0);
332
-
333
- err2:
334
- free(XY0);
335
- err1:
336
- free(B0);
337
- err0:
338
- /* Failure! */
339
- return (-1);
340
- }
@@ -1,284 +0,0 @@
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 <errno.h>
32
- #include <stdint.h>
33
- #include <stdlib.h>
34
- #include <string.h>
35
-
36
- #include "sha256.h"
37
- #include "sysendian.h"
38
-
39
- #include "crypto_scrypt.h"
40
-
41
- static void blkcpy(uint8_t *, uint8_t *, size_t);
42
- static void blkxor(uint8_t *, uint8_t *, size_t);
43
- static void salsa20_8(uint8_t[64]);
44
- static void blockmix_salsa8(uint8_t *, uint8_t *, size_t);
45
- static uint64_t integerify(uint8_t *, size_t);
46
- static void smix(uint8_t *, size_t, uint64_t, uint8_t *, uint8_t *);
47
-
48
- static void
49
- blkcpy(uint8_t * dest, uint8_t * src, size_t len)
50
- {
51
- size_t i;
52
-
53
- for (i = 0; i < len; i++)
54
- dest[i] = src[i];
55
- }
56
-
57
- static void
58
- blkxor(uint8_t * dest, uint8_t * src, size_t len)
59
- {
60
- size_t i;
61
-
62
- for (i = 0; i < len; i++)
63
- dest[i] ^= src[i];
64
- }
65
-
66
- /**
67
- * salsa20_8(B):
68
- * Apply the salsa20/8 core to the provided block.
69
- */
70
- static void
71
- salsa20_8(uint8_t B[64])
72
- {
73
- uint32_t B32[16];
74
- uint32_t x[16];
75
- size_t i;
76
-
77
- /* Convert little-endian values in. */
78
- for (i = 0; i < 16; i++)
79
- B32[i] = le32dec(&B[i * 4]);
80
-
81
- /* Compute x = doubleround^4(B32). */
82
- for (i = 0; i < 16; i++)
83
- x[i] = B32[i];
84
- for (i = 0; i < 8; i += 2) {
85
- #define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
86
- /* Operate on columns. */
87
- x[ 4] ^= R(x[ 0]+x[12], 7); x[ 8] ^= R(x[ 4]+x[ 0], 9);
88
- x[12] ^= R(x[ 8]+x[ 4],13); x[ 0] ^= R(x[12]+x[ 8],18);
89
-
90
- x[ 9] ^= R(x[ 5]+x[ 1], 7); x[13] ^= R(x[ 9]+x[ 5], 9);
91
- x[ 1] ^= R(x[13]+x[ 9],13); x[ 5] ^= R(x[ 1]+x[13],18);
92
-
93
- x[14] ^= R(x[10]+x[ 6], 7); x[ 2] ^= R(x[14]+x[10], 9);
94
- x[ 6] ^= R(x[ 2]+x[14],13); x[10] ^= R(x[ 6]+x[ 2],18);
95
-
96
- x[ 3] ^= R(x[15]+x[11], 7); x[ 7] ^= R(x[ 3]+x[15], 9);
97
- x[11] ^= R(x[ 7]+x[ 3],13); x[15] ^= R(x[11]+x[ 7],18);
98
-
99
- /* Operate on rows. */
100
- x[ 1] ^= R(x[ 0]+x[ 3], 7); x[ 2] ^= R(x[ 1]+x[ 0], 9);
101
- x[ 3] ^= R(x[ 2]+x[ 1],13); x[ 0] ^= R(x[ 3]+x[ 2],18);
102
-
103
- x[ 6] ^= R(x[ 5]+x[ 4], 7); x[ 7] ^= R(x[ 6]+x[ 5], 9);
104
- x[ 4] ^= R(x[ 7]+x[ 6],13); x[ 5] ^= R(x[ 4]+x[ 7],18);
105
-
106
- x[11] ^= R(x[10]+x[ 9], 7); x[ 8] ^= R(x[11]+x[10], 9);
107
- x[ 9] ^= R(x[ 8]+x[11],13); x[10] ^= R(x[ 9]+x[ 8],18);
108
-
109
- x[12] ^= R(x[15]+x[14], 7); x[13] ^= R(x[12]+x[15], 9);
110
- x[14] ^= R(x[13]+x[12],13); x[15] ^= R(x[14]+x[13],18);
111
- #undef R
112
- }
113
-
114
- /* Compute B32 = B32 + x. */
115
- for (i = 0; i < 16; i++)
116
- B32[i] += x[i];
117
-
118
- /* Convert little-endian values out. */
119
- for (i = 0; i < 16; i++)
120
- le32enc(&B[4 * i], B32[i]);
121
- }
122
-
123
- /**
124
- * blockmix_salsa8(B, Y, r):
125
- * Compute B = BlockMix_{salsa20/8, r}(B). The input B must be 128r bytes in
126
- * length; the temporary space Y must also be the same size.
127
- */
128
- static void
129
- blockmix_salsa8(uint8_t * B, uint8_t * Y, size_t r)
130
- {
131
- uint8_t X[64];
132
- size_t i;
133
-
134
- /* 1: X <-- B_{2r - 1} */
135
- blkcpy(X, &B[(2 * r - 1) * 64], 64);
136
-
137
- /* 2: for i = 0 to 2r - 1 do */
138
- for (i = 0; i < 2 * r; i++) {
139
- /* 3: X <-- H(X \xor B_i) */
140
- blkxor(X, &B[i * 64], 64);
141
- salsa20_8(X);
142
-
143
- /* 4: Y_i <-- X */
144
- blkcpy(&Y[i * 64], X, 64);
145
- }
146
-
147
- /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
148
- for (i = 0; i < r; i++)
149
- blkcpy(&B[i * 64], &Y[(i * 2) * 64], 64);
150
- for (i = 0; i < r; i++)
151
- blkcpy(&B[(i + r) * 64], &Y[(i * 2 + 1) * 64], 64);
152
- }
153
-
154
- /**
155
- * integerify(B, r):
156
- * Return the result of parsing B_{2r-1} as a little-endian integer.
157
- */
158
- static uint64_t
159
- integerify(uint8_t * B, size_t r)
160
- {
161
- uint8_t * X = &B[(2 * r - 1) * 64];
162
-
163
- return (le64dec(X));
164
- }
165
-
166
- /**
167
- * smix(B, r, N, V, XY):
168
- * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; the
169
- * temporary storage V must be 128rN bytes in length; the temporary storage
170
- * XY must be 256r bytes in length. The value N must be a power of 2.
171
- */
172
- static void
173
- smix(uint8_t * B, size_t r, uint64_t N, uint8_t * V, uint8_t * XY)
174
- {
175
- uint8_t * X = XY;
176
- uint8_t * Y = &XY[128 * r];
177
- uint64_t i;
178
- uint64_t j;
179
-
180
- /* 1: X <-- B */
181
- blkcpy(X, B, 128 * r);
182
-
183
- /* 2: for i = 0 to N - 1 do */
184
- for (i = 0; i < N; i++) {
185
- /* 3: V_i <-- X */
186
- blkcpy(&V[i * (128 * r)], X, 128 * r);
187
-
188
- /* 4: X <-- H(X) */
189
- blockmix_salsa8(X, Y, r);
190
- }
191
-
192
- /* 6: for i = 0 to N - 1 do */
193
- for (i = 0; i < N; i++) {
194
- /* 7: j <-- Integerify(X) mod N */
195
- j = integerify(X, r) & (N - 1);
196
-
197
- /* 8: X <-- H(X \xor V_j) */
198
- blkxor(X, &V[j * (128 * r)], 128 * r);
199
- blockmix_salsa8(X, Y, r);
200
- }
201
-
202
- /* 10: B' <-- X */
203
- blkcpy(B, X, 128 * r);
204
- }
205
-
206
- /**
207
- * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
208
- * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
209
- * p, buflen) and write the result into buf. The parameters r, p, and buflen
210
- * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N
211
- * must be a power of 2.
212
- *
213
- * Return 0 on success; or -1 on error.
214
- */
215
- int
216
- crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
217
- const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p,
218
- uint8_t * buf, size_t buflen)
219
- {
220
- uint8_t * B;
221
- uint8_t * V;
222
- uint8_t * XY;
223
- uint32_t i;
224
-
225
- /* Sanity-check parameters. */
226
- #if SIZE_MAX > UINT32_MAX
227
- if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
228
- errno = EFBIG;
229
- goto err0;
230
- }
231
- #endif
232
- if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
233
- errno = EFBIG;
234
- goto err0;
235
- }
236
- if (((N & (N - 1)) != 0) || (N == 0)) {
237
- errno = EINVAL;
238
- goto err0;
239
- }
240
- if ((r > SIZE_MAX / 128 / p) ||
241
- #if SIZE_MAX / 256 <= UINT32_MAX
242
- (r > SIZE_MAX / 256) ||
243
- #endif
244
- (N > SIZE_MAX / 128 / r)) {
245
- errno = ENOMEM;
246
- goto err0;
247
- }
248
-
249
- /* Allocate memory. */
250
- if ((B = malloc(128 * r * p)) == NULL)
251
- goto err0;
252
- if ((XY = malloc(256 * r)) == NULL)
253
- goto err1;
254
- if ((V = malloc(128 * r * N)) == NULL)
255
- goto err2;
256
-
257
- /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
258
- PBKDF2_scrypt_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r);
259
-
260
- /* 2: for i = 0 to p - 1 do */
261
- for (i = 0; i < p; i++) {
262
- /* 3: B_i <-- MF(B_i, N) */
263
- smix(&B[i * 128 * r], r, N, V, XY);
264
- }
265
-
266
- /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
267
- PBKDF2_scrypt_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);
268
-
269
- /* Free memory. */
270
- free(V);
271
- free(XY);
272
- free(B);
273
-
274
- /* Success! */
275
- return (0);
276
-
277
- err2:
278
- free(XY);
279
- err1:
280
- free(B);
281
- err0:
282
- /* Failure! */
283
- return (-1);
284
- }