scrypt 1.0.5 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- scrypt (1.0.5)
4
+ scrypt (1.0.6)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
@@ -53,7 +53,7 @@ vendorarchdir = $(vendorlibdir)/$(sitearch)
53
53
 
54
54
  NULLCMD = :
55
55
 
56
- CC = /usr/bin/gcc-4.2 -Wall
56
+ CC = /usr/bin/gcc-4.2 -Wall -msse -msse2
57
57
  CXX = g++-4.2
58
58
  LIBRUBY = $(LIBRUBY_SO)
59
59
  LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
@@ -115,8 +115,8 @@ extout_prefix =
115
115
  target_prefix =
116
116
  LOCAL_LIBS =
117
117
  LIBS = $(LIBRUBYARG_SHARED) -lpthread -ldl -lobjc
118
- SRCS = crypto_scrypt-ref.c memlimit.c scrypt_calibrate.c scrypt_ext.c scryptenc_cpuperf.c sha256.c
119
- OBJS = crypto_scrypt-ref.o memlimit.o scrypt_calibrate.o scrypt_ext.o scryptenc_cpuperf.o sha256.o
118
+ SRCS = crypto_scrypt-sse.c memlimit.c scrypt_calibrate.c scrypt_ext.c scryptenc_cpuperf.c sha256.c
119
+ OBJS = crypto_scrypt-sse.o memlimit.o scrypt_calibrate.o scrypt_ext.o scryptenc_cpuperf.o sha256.o
120
120
  TARGET = scrypt_ext
121
121
  DLLIB = $(TARGET).bundle
122
122
  EXTSTATIC =
@@ -0,0 +1,340 @@
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
+ }
@@ -0,0 +1,368 @@
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 <emmintrin.h>
37
+ #include <errno.h>
38
+ #include <stdint.h>
39
+ #include <stdlib.h>
40
+ #include <string.h>
41
+
42
+ #include "sha256.h"
43
+ #include "sysendian.h"
44
+
45
+ #include "crypto_scrypt.h"
46
+
47
+ static void blkcpy(void *, void *, size_t);
48
+ static void blkxor(void *, void *, size_t);
49
+ static void salsa20_8(__m128i *);
50
+ static void blockmix_salsa8(__m128i *, __m128i *, __m128i *, size_t);
51
+ static uint64_t integerify(void *, size_t);
52
+ static void smix(uint8_t *, size_t, uint64_t, void *, void *);
53
+
54
+ static void
55
+ blkcpy(void * dest, void * src, size_t len)
56
+ {
57
+ __m128i * D = dest;
58
+ __m128i * S = src;
59
+ size_t L = len / 16;
60
+ size_t i;
61
+
62
+ for (i = 0; i < L; i++)
63
+ D[i] = S[i];
64
+ }
65
+
66
+ static void
67
+ blkxor(void * dest, void * src, size_t len)
68
+ {
69
+ __m128i * D = dest;
70
+ __m128i * S = src;
71
+ size_t L = len / 16;
72
+ size_t i;
73
+
74
+ for (i = 0; i < L; i++)
75
+ D[i] = _mm_xor_si128(D[i], S[i]);
76
+ }
77
+
78
+ /**
79
+ * salsa20_8(B):
80
+ * Apply the salsa20/8 core to the provided block.
81
+ */
82
+ static void
83
+ salsa20_8(__m128i B[4])
84
+ {
85
+ __m128i X0, X1, X2, X3;
86
+ __m128i T;
87
+ size_t i;
88
+
89
+ X0 = B[0];
90
+ X1 = B[1];
91
+ X2 = B[2];
92
+ X3 = B[3];
93
+
94
+ for (i = 0; i < 8; i += 2) {
95
+ /* Operate on "columns". */
96
+ T = _mm_add_epi32(X0, X3);
97
+ X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 7));
98
+ X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 25));
99
+ T = _mm_add_epi32(X1, X0);
100
+ X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9));
101
+ X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23));
102
+ T = _mm_add_epi32(X2, X1);
103
+ X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 13));
104
+ X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 19));
105
+ T = _mm_add_epi32(X3, X2);
106
+ X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18));
107
+ X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14));
108
+
109
+ /* Rearrange data. */
110
+ X1 = _mm_shuffle_epi32(X1, 0x93);
111
+ X2 = _mm_shuffle_epi32(X2, 0x4E);
112
+ X3 = _mm_shuffle_epi32(X3, 0x39);
113
+
114
+ /* Operate on "rows". */
115
+ T = _mm_add_epi32(X0, X1);
116
+ X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 7));
117
+ X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 25));
118
+ T = _mm_add_epi32(X3, X0);
119
+ X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9));
120
+ X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23));
121
+ T = _mm_add_epi32(X2, X3);
122
+ X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 13));
123
+ X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 19));
124
+ T = _mm_add_epi32(X1, X2);
125
+ X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18));
126
+ X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14));
127
+
128
+ /* Rearrange data. */
129
+ X1 = _mm_shuffle_epi32(X1, 0x39);
130
+ X2 = _mm_shuffle_epi32(X2, 0x4E);
131
+ X3 = _mm_shuffle_epi32(X3, 0x93);
132
+ }
133
+
134
+ B[0] = _mm_add_epi32(B[0], X0);
135
+ B[1] = _mm_add_epi32(B[1], X1);
136
+ B[2] = _mm_add_epi32(B[2], X2);
137
+ B[3] = _mm_add_epi32(B[3], X3);
138
+ }
139
+
140
+ /**
141
+ * blockmix_salsa8(Bin, Bout, X, r):
142
+ * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r
143
+ * bytes in length; the output Bout must also be the same size. The
144
+ * temporary space X must be 64 bytes.
145
+ */
146
+ static void
147
+ blockmix_salsa8(__m128i * Bin, __m128i * Bout, __m128i * X, size_t r)
148
+ {
149
+ size_t i;
150
+
151
+ /* 1: X <-- B_{2r - 1} */
152
+ blkcpy(X, &Bin[8 * r - 4], 64);
153
+
154
+ /* 2: for i = 0 to 2r - 1 do */
155
+ for (i = 0; i < r; i++) {
156
+ /* 3: X <-- H(X \xor B_i) */
157
+ blkxor(X, &Bin[i * 8], 64);
158
+ salsa20_8(X);
159
+
160
+ /* 4: Y_i <-- X */
161
+ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
162
+ blkcpy(&Bout[i * 4], X, 64);
163
+
164
+ /* 3: X <-- H(X \xor B_i) */
165
+ blkxor(X, &Bin[i * 8 + 4], 64);
166
+ salsa20_8(X);
167
+
168
+ /* 4: Y_i <-- X */
169
+ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
170
+ blkcpy(&Bout[(r + i) * 4], X, 64);
171
+ }
172
+ }
173
+
174
+ /**
175
+ * integerify(B, r):
176
+ * Return the result of parsing B_{2r-1} as a little-endian integer.
177
+ */
178
+ static uint64_t
179
+ integerify(void * B, size_t r)
180
+ {
181
+ uint32_t * X = (void *)((uintptr_t)(B) + (2 * r - 1) * 64);
182
+
183
+ return (((uint64_t)(X[13]) << 32) + X[0]);
184
+ }
185
+
186
+ /**
187
+ * smix(B, r, N, V, XY):
188
+ * Compute B = SMix_r(B, N). The input B must be 128r bytes in length;
189
+ * the temporary storage V must be 128rN bytes in length; the temporary
190
+ * storage XY must be 256r + 64 bytes in length. The value N must be a
191
+ * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a
192
+ * multiple of 64 bytes.
193
+ */
194
+ static void
195
+ smix(uint8_t * B, size_t r, uint64_t N, void * V, void * XY)
196
+ {
197
+ __m128i * X = XY;
198
+ __m128i * Y = (void *)((uintptr_t)(XY) + 128 * r);
199
+ __m128i * Z = (void *)((uintptr_t)(XY) + 256 * r);
200
+ uint32_t * X32 = (void *)X;
201
+ uint64_t i, j;
202
+ size_t k;
203
+
204
+ /* 1: X <-- B */
205
+ for (k = 0; k < 2 * r; k++) {
206
+ for (i = 0; i < 16; i++) {
207
+ X32[k * 16 + i] =
208
+ le32dec(&B[(k * 16 + (i * 5 % 16)) * 4]);
209
+ }
210
+ }
211
+
212
+ /* 2: for i = 0 to N - 1 do */
213
+ for (i = 0; i < N; i += 2) {
214
+ /* 3: V_i <-- X */
215
+ blkcpy((void *)((uintptr_t)(V) + i * 128 * r), X, 128 * r);
216
+
217
+ /* 4: X <-- H(X) */
218
+ blockmix_salsa8(X, Y, Z, r);
219
+
220
+ /* 3: V_i <-- X */
221
+ blkcpy((void *)((uintptr_t)(V) + (i + 1) * 128 * r),
222
+ Y, 128 * r);
223
+
224
+ /* 4: X <-- H(X) */
225
+ blockmix_salsa8(Y, X, Z, r);
226
+ }
227
+
228
+ /* 6: for i = 0 to N - 1 do */
229
+ for (i = 0; i < N; i += 2) {
230
+ /* 7: j <-- Integerify(X) mod N */
231
+ j = integerify(X, r) & (N - 1);
232
+
233
+ /* 8: X <-- H(X \xor V_j) */
234
+ blkxor(X, (void *)((uintptr_t)(V) + j * 128 * r), 128 * r);
235
+ blockmix_salsa8(X, Y, Z, r);
236
+
237
+ /* 7: j <-- Integerify(X) mod N */
238
+ j = integerify(Y, r) & (N - 1);
239
+
240
+ /* 8: X <-- H(X \xor V_j) */
241
+ blkxor(Y, (void *)((uintptr_t)(V) + j * 128 * r), 128 * r);
242
+ blockmix_salsa8(Y, X, Z, r);
243
+ }
244
+
245
+ /* 10: B' <-- X */
246
+ for (k = 0; k < 2 * r; k++) {
247
+ for (i = 0; i < 16; i++) {
248
+ le32enc(&B[(k * 16 + (i * 5 % 16)) * 4],
249
+ X32[k * 16 + i]);
250
+ }
251
+ }
252
+ }
253
+
254
+ /**
255
+ * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
256
+ * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
257
+ * p, buflen) and write the result into buf. The parameters r, p, and buflen
258
+ * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N
259
+ * must be a power of 2 greater than 1.
260
+ *
261
+ * Return 0 on success; or -1 on error.
262
+ */
263
+ int
264
+ crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
265
+ const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p,
266
+ uint8_t * buf, size_t buflen)
267
+ {
268
+ void * B0, * V0, * XY0;
269
+ uint8_t * B;
270
+ uint32_t * V;
271
+ uint32_t * XY;
272
+ uint32_t i;
273
+
274
+ /* Sanity-check parameters. */
275
+ #if SIZE_MAX > UINT32_MAX
276
+ if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
277
+ errno = EFBIG;
278
+ goto err0;
279
+ }
280
+ #endif
281
+ if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
282
+ errno = EFBIG;
283
+ goto err0;
284
+ }
285
+ if (((N & (N - 1)) != 0) || (N == 0)) {
286
+ errno = EINVAL;
287
+ goto err0;
288
+ }
289
+ if ((r > SIZE_MAX / 128 / p) ||
290
+ #if SIZE_MAX / 256 <= UINT32_MAX
291
+ (r > (SIZE_MAX - 64) / 256) ||
292
+ #endif
293
+ (N > SIZE_MAX / 128 / r)) {
294
+ errno = ENOMEM;
295
+ goto err0;
296
+ }
297
+
298
+ /* Allocate memory. */
299
+ #ifdef HAVE_POSIX_MEMALIGN
300
+ if ((errno = posix_memalign(&B0, 64, 128 * r * p)) != 0)
301
+ goto err0;
302
+ B = (uint8_t *)(B0);
303
+ if ((errno = posix_memalign(&XY0, 64, 256 * r + 64)) != 0)
304
+ goto err1;
305
+ XY = (uint32_t *)(XY0);
306
+ #ifndef MAP_ANON
307
+ if ((errno = posix_memalign(&V0, 64, 128 * r * N)) != 0)
308
+ goto err2;
309
+ V = (uint32_t *)(V0);
310
+ #endif
311
+ #else
312
+ if ((B0 = malloc(128 * r * p + 63)) == NULL)
313
+ goto err0;
314
+ B = (uint8_t *)(((uintptr_t)(B0) + 63) & ~ (uintptr_t)(63));
315
+ if ((XY0 = malloc(256 * r + 64 + 63)) == NULL)
316
+ goto err1;
317
+ XY = (uint32_t *)(((uintptr_t)(XY0) + 63) & ~ (uintptr_t)(63));
318
+ #ifndef MAP_ANON
319
+ if ((V0 = malloc(128 * r * N + 63)) == NULL)
320
+ goto err2;
321
+ V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63));
322
+ #endif
323
+ #endif
324
+ #ifdef MAP_ANON
325
+ if ((V0 = mmap(NULL, 128 * r * N, PROT_READ | PROT_WRITE,
326
+ #ifdef MAP_NOCORE
327
+ MAP_ANON | MAP_PRIVATE | MAP_NOCORE,
328
+ #else
329
+ MAP_ANON | MAP_PRIVATE,
330
+ #endif
331
+ -1, 0)) == MAP_FAILED)
332
+ goto err2;
333
+ V = (uint32_t *)(V0);
334
+ #endif
335
+
336
+ /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
337
+ PBKDF2_scrypt_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r);
338
+
339
+ /* 2: for i = 0 to p - 1 do */
340
+ for (i = 0; i < p; i++) {
341
+ /* 3: B_i <-- MF(B_i, N) */
342
+ smix(&B[i * 128 * r], r, N, V, XY);
343
+ }
344
+
345
+ /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
346
+ PBKDF2_scrypt_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);
347
+
348
+ /* Free memory. */
349
+ #ifdef MAP_ANON
350
+ if (munmap(V0, 128 * r * N))
351
+ goto err2;
352
+ #else
353
+ free(V0);
354
+ #endif
355
+ free(XY0);
356
+ free(B0);
357
+
358
+ /* Success! */
359
+ return (0);
360
+
361
+ err2:
362
+ free(XY0);
363
+ err1:
364
+ free(B0);
365
+ err0:
366
+ /* Failure! */
367
+ return (-1);
368
+ }
@@ -40,7 +40,6 @@
40
40
  *
41
41
  * Return 0 on success; or -1 on error.
42
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);
43
+ int crypto_scrypt(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t, uint32_t, uint32_t, uint8_t *, size_t);
45
44
 
46
45
  #endif /* !_CRYPTO_SCRYPT_H_ */
@@ -1,4 +1,5 @@
1
1
  require "mkmf"
2
2
  dir_config("scrypt_ext")
3
- CONFIG['CC'] << " -Wall "
3
+ CONFIG['CC'] << " -Wall -msse -msse2 "
4
+ CONFIG['CC'] << " -D_GNU_SOURCE=1 " if CONFIG["target_os"]["mingw"]
4
5
  create_makefile("scrypt_ext")
@@ -29,7 +29,9 @@
29
29
  #include "scrypt_platform.h"
30
30
 
31
31
  #include <sys/types.h>
32
+ #ifndef __MINGW32__
32
33
  #include <sys/resource.h>
34
+ #endif
33
35
 
34
36
  #ifdef HAVE_SYS_PARAM_H
35
37
  #include <sys/param.h>
@@ -141,6 +143,7 @@ memlimit_sysinfo(size_t * memlimit)
141
143
  static int
142
144
  memlimit_rlimit(size_t * memlimit)
143
145
  {
146
+ #ifndef __MINGW32__
144
147
  struct rlimit rl;
145
148
  uint64_t memrlimit;
146
149
 
@@ -181,7 +184,9 @@ memlimit_rlimit(size_t * memlimit)
181
184
  #else
182
185
  *memlimit = memrlimit;
183
186
  #endif
184
-
187
+ #else
188
+ *memlimit = SIZE_MAX;
189
+ #endif
185
190
  /* Success! */
186
191
  return (0);
187
192
  }
@@ -24,31 +24,30 @@
24
24
 
25
25
 
26
26
  static int
27
- pickparams(size_t maxmem, double maxmemfrac, double maxtime,
28
- int * logN, uint32_t * r, uint32_t * p)
27
+ pickparams(size_t maxmem, double maxmemfrac, double maxtime, int * logN, uint32_t * r, uint32_t * p)
29
28
  {
30
29
  size_t memlimit;
31
30
  double opps;
32
31
  double opslimit;
33
32
  double maxN, maxrp;
34
33
  int rc;
35
-
34
+
36
35
  /* Figure out how much memory to use. */
37
36
  if (memtouse(maxmem, maxmemfrac, &memlimit))
38
37
  return (1);
39
-
38
+
40
39
  /* Figure out how fast the CPU is. */
41
40
  if ((rc = scryptenc_cpuperf(&opps)) != 0)
42
41
  return (rc);
43
42
  opslimit = opps * maxtime;
44
-
43
+
45
44
  /* Allow a minimum of 2^15 salsa20/8 cores. */
46
45
  if (opslimit < 32768)
47
46
  opslimit = 32768;
48
-
47
+
49
48
  /* Fix r = 8 for now. */
50
49
  *r = 8;
51
-
50
+
52
51
  /*
53
52
  * The memory limit requires that 128Nr <= memlimit, while the CPU
54
53
  * limit requires that 4Nrp <= opslimit. If opslimit < memlimit/32,
@@ -73,32 +72,31 @@ pickparams(size_t maxmem, double maxmemfrac, double maxtime,
73
72
  if ((uint64_t)(1) << *logN > maxN / 2)
74
73
  break;
75
74
  }
76
-
75
+
77
76
  /* Choose p based on the CPU limit. */
78
77
  maxrp = (opslimit / 4) / ((uint64_t)(1) << *logN);
79
78
  if (maxrp > 0x3fffffff)
80
79
  maxrp = 0x3fffffff;
81
80
  *p = (uint32_t)(maxrp) / *r;
82
81
  }
83
-
82
+
84
83
  #ifdef DEBUG
85
84
  fprintf(stderr, "N = %zu r = %d p = %d\n",
86
85
  (size_t)(1) << *logN, (int)(*r), (int)(*p));
87
86
  #endif
88
-
87
+
89
88
  /* Success! */
90
89
  return (0);
91
90
  }
92
91
 
93
92
  int
94
- calibrate(size_t maxmem, double maxmemfrac, double maxtime,
95
- uint64_t * n, uint32_t * r, uint32_t * p)
93
+ calibrate(size_t maxmem, double maxmemfrac, double maxtime, uint64_t * n, uint32_t * r, uint32_t * p)
96
94
  {
97
95
  int logN = 0;
98
96
  int result = pickparams( maxmem, maxmemfrac, maxtime, & logN, r, p );
99
97
  if (result == 0)
100
98
  {
101
99
  *n = (uint64_t)(1) << logN;
102
- }
100
+ }
103
101
  return result;
104
102
  }
@@ -26,7 +26,11 @@ static VALUE sc_calibrate( VALUE self, VALUE maxmem, VALUE maxmemfrac, VALUE max
26
26
  {
27
27
  char cost_str[33];
28
28
  memset( cost_str, '\0', 33 );
29
+ #ifdef __MINGW32__
30
+ sprintf( cost_str, "%lx$%x$%x$", (long unsigned int)n, (unsigned int)r, (unsigned int)p );
31
+ #else
29
32
  sprintf( cost_str, "%Lx$%x$%x$", n, r, p );
33
+ #endif
30
34
  return rb_str_new2( cost_str );
31
35
  }
32
36
 
@@ -36,6 +40,11 @@ static VALUE sc_calibrate( VALUE self, VALUE maxmem, VALUE maxmemfrac, VALUE max
36
40
 
37
41
  static VALUE sc_crypt( VALUE self, VALUE key, VALUE salt, VALUE cost )
38
42
  {
43
+ uint64_t n = 0;
44
+ uint32_t r = 0;
45
+ uint32_t p = 0;
46
+ int result;
47
+
39
48
  const char * safe_key = RSTRING_PTR(key) ? RSTRING_PTR(key) : "";
40
49
  const char * safe_salt = RSTRING_PTR(salt) ? RSTRING_PTR(salt) : "";
41
50
 
@@ -48,12 +57,13 @@ static VALUE sc_crypt( VALUE self, VALUE key, VALUE salt, VALUE cost )
48
57
  return Qnil;
49
58
  }
50
59
 
51
- uint64_t n = 0;
52
- uint32_t r = 0;
53
- uint32_t p = 0;
60
+ #ifdef __MINGW32__
61
+ sscanf( RSTRING_PTR( cost ), "%lx$%x$%x$", (long unsigned int*)& n, (unsigned int*)& r, (unsigned int*)& p );
62
+ #else
54
63
  sscanf( RSTRING_PTR( cost ), "%Lx$%x$%x$", & n, & r, & p );
64
+ #endif
55
65
 
56
- int result = crypto_scrypt(
66
+ result = crypto_scrypt(
57
67
  (uint8_t *) safe_key, strlen(safe_key),
58
68
  (uint8_t *) safe_salt, strlen(safe_salt),
59
69
  n, r, p,
@@ -38,6 +38,13 @@
38
38
 
39
39
  #include "scryptenc_cpuperf.h"
40
40
 
41
+ #ifdef __MINGW32__
42
+ struct timespec {
43
+ long tv_sec;
44
+ long tv_nsec;
45
+ };
46
+ #endif
47
+
41
48
  #ifdef HAVE_CLOCK_GETTIME
42
49
 
43
50
  static clock_t clocktouse;
@@ -116,7 +123,7 @@ getclockdiff(struct timespec * st, double * diffd)
116
123
  if (getclocktime(&en))
117
124
  return (1);
118
125
  *diffd = (en.tv_nsec - st->tv_nsec) * 0.000000001 +
119
- (en.tv_sec - st->tv_sec);
126
+ (en.tv_sec - st->tv_sec);
120
127
 
121
128
  return (0);
122
129
  }
@@ -176,7 +183,7 @@ scryptenc_cpuperf(double * opps)
176
183
 
177
184
  #ifdef DEBUG
178
185
  fprintf(stderr, "%ju salsa20/8 cores performed in %f seconds\n",
179
- (uintmax_t)i, diffd);
186
+ (uintmax_t)i, diffd);
180
187
  #endif
181
188
 
182
189
  /* We can do approximately i salsa20/8 cores per diffd seconds. */
@@ -80,10 +80,10 @@ be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len)
80
80
  /* Adjusted round function for rotating state */
81
81
  #define RNDr(S, W, i, k) \
82
82
  RND(S[(64 - i) % 8], S[(65 - i) % 8], \
83
- S[(66 - i) % 8], S[(67 - i) % 8], \
84
- S[(68 - i) % 8], S[(69 - i) % 8], \
85
- S[(70 - i) % 8], S[(71 - i) % 8], \
86
- W[i] + k)
83
+ S[(66 - i) % 8], S[(67 - i) % 8], \
84
+ S[(68 - i) % 8], S[(69 - i) % 8], \
85
+ S[(70 - i) % 8], S[(71 - i) % 8], \
86
+ W[i] + k)
87
87
 
88
88
  /*
89
89
  * scrypt_SHA256 block compression function. The 256-bit state is transformed via
@@ -56,7 +56,6 @@ void HMAC_scrypt_SHA256_Final(unsigned char [32], HMAC_scrypt_SHA256_CTX *);
56
56
  * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-scrypt_SHA256 as the PRF, and
57
57
  * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
58
58
  */
59
- void PBKDF2_scrypt_SHA256(const uint8_t *, size_t, const uint8_t *, size_t,
60
- uint64_t, uint8_t *, size_t);
59
+ void PBKDF2_scrypt_SHA256(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t, uint8_t *, size_t);
61
60
 
62
61
  #endif /* !_scrypt_SHA256_H_ */
@@ -50,7 +50,7 @@ be32dec(const void *pp)
50
50
  const uint8_t *p = (uint8_t const *)pp;
51
51
 
52
52
  return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) +
53
- ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24));
53
+ ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24));
54
54
  }
55
55
 
56
56
  static inline void
@@ -70,9 +70,9 @@ be64dec(const void *pp)
70
70
  const uint8_t *p = (uint8_t const *)pp;
71
71
 
72
72
  return ((uint64_t)(p[7]) + ((uint64_t)(p[6]) << 8) +
73
- ((uint64_t)(p[5]) << 16) + ((uint64_t)(p[4]) << 24) +
74
- ((uint64_t)(p[3]) << 32) + ((uint64_t)(p[2]) << 40) +
75
- ((uint64_t)(p[1]) << 48) + ((uint64_t)(p[0]) << 56));
73
+ ((uint64_t)(p[5]) << 16) + ((uint64_t)(p[4]) << 24) +
74
+ ((uint64_t)(p[3]) << 32) + ((uint64_t)(p[2]) << 40) +
75
+ ((uint64_t)(p[1]) << 48) + ((uint64_t)(p[0]) << 56));
76
76
  }
77
77
 
78
78
  static inline void
@@ -116,9 +116,9 @@ le64dec(const void *pp)
116
116
  const uint8_t *p = (uint8_t const *)pp;
117
117
 
118
118
  return ((uint64_t)(p[0]) + ((uint64_t)(p[1]) << 8) +
119
- ((uint64_t)(p[2]) << 16) + ((uint64_t)(p[3]) << 24) +
120
- ((uint64_t)(p[4]) << 32) + ((uint64_t)(p[5]) << 40) +
121
- ((uint64_t)(p[6]) << 48) + ((uint64_t)(p[7]) << 56));
119
+ ((uint64_t)(p[2]) << 16) + ((uint64_t)(p[3]) << 24) +
120
+ ((uint64_t)(p[4]) << 32) + ((uint64_t)(p[5]) << 40) +
121
+ ((uint64_t)(p[6]) << 48) + ((uint64_t)(p[7]) << 56));
122
122
  }
123
123
 
124
124
  static inline void
@@ -1,3 +1,3 @@
1
1
  module SCrypt
2
- VERSION = "1.0.5"
2
+ VERSION = "1.0.6"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scrypt
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 1.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-11 00:00:00.000000000 Z
12
+ date: 2012-05-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -80,7 +80,9 @@ files:
80
80
  - Rakefile
81
81
  - autotest/discover.rb
82
82
  - ext/mri/Makefile
83
- - ext/mri/crypto_scrypt-ref.c
83
+ - ext/mri/alt-impl/crypto_scrypt-nosse.c
84
+ - ext/mri/alt-impl/crypto_scrypt-ref.c
85
+ - ext/mri/crypto_scrypt-sse.c
84
86
  - ext/mri/crypto_scrypt.h
85
87
  - ext/mri/extconf.rb
86
88
  - ext/mri/memlimit.c
@@ -115,7 +117,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
115
117
  version: '0'
116
118
  segments:
117
119
  - 0
118
- hash: 2356724981074653609
120
+ hash: 4242054223667576181
119
121
  required_rubygems_version: !ruby/object:Gem::Requirement
120
122
  none: false
121
123
  requirements:
@@ -124,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
126
  version: '0'
125
127
  segments:
126
128
  - 0
127
- hash: 2356724981074653609
129
+ hash: 4242054223667576181
128
130
  requirements: []
129
131
  rubyforge_project: scrypt
130
132
  rubygems_version: 1.8.21