scrypt 1.0.3 → 1.0.4
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/Gemfile.lock +1 -1
- data/README.md +50 -0
- data/ext/mri/Makefile +119 -63
- data/ext/mri/crypto_scrypt-ref.c +2 -2
- data/ext/mri/sha256.c +50 -50
- data/ext/mri/sha256.h +18 -18
- data/kdf-comparison.png +0 -0
- data/lib/scrypt/version.rb +1 -1
- metadata +21 -12
- data/README +0 -42
data/Gemfile.lock
CHANGED
data/README.md
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
scrypt
|
2
|
+
======
|
3
|
+
|
4
|
+
The scrypt key derivation function is designed to be far more secure against hardware brute-force attacks than alternative functions such as PBKDF2 or bcrypt.
|
5
|
+
|
6
|
+
* http://www.tarsnap.com/scrypt.html
|
7
|
+
* http://github.com/pbhogan/scrypt
|
8
|
+
|
9
|
+
## Why you should use scrypt
|
10
|
+
|
11
|
+

|
12
|
+
|
13
|
+
The designers of scrypt estimate that on modern (2009) hardware, if 5 seconds are spent computing a derived key, the cost of a hardware brute-force attack against scrypt is roughly 4000 times greater than the cost of a similar attack against bcrypt (to find the same password), and 20000 times greater than a similar attack against PBKDF2.
|
14
|
+
|
15
|
+
## How to install scrypt
|
16
|
+
|
17
|
+
```
|
18
|
+
gem install scrypt
|
19
|
+
```
|
20
|
+
|
21
|
+
## How to use scrypt
|
22
|
+
|
23
|
+
It works pretty similarly to ruby-bcrypt with a few minor differences, especially where the cost factor is concerned.
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
include "scrypt"
|
27
|
+
|
28
|
+
# hash a user's password
|
29
|
+
@password = Password.create("my grand secret")
|
30
|
+
@password #=> "2000$8$1$f5f2fa5fe5484a7091f1299768fbe92b5a7fbc77$6a385f22c54d92c314b71a4fd5ef33967c93d679"
|
31
|
+
|
32
|
+
# store it safely
|
33
|
+
@user.update_attribute(:password, @password)
|
34
|
+
|
35
|
+
# read it back
|
36
|
+
@user.reload!
|
37
|
+
@db_password = Password.new(@user.password)
|
38
|
+
|
39
|
+
# compare it after retrieval
|
40
|
+
@db_password == "my grand secret" #=> true
|
41
|
+
@db_password == "a paltry guess" #=> false
|
42
|
+
```
|
43
|
+
|
44
|
+
Password.create takes three options which will determine the cost limits of the computation:
|
45
|
+
|
46
|
+
* `:max_time` specifies the maximum number of seconds the computation should take.
|
47
|
+
* `:max_mem` specifies the maximum number of bytes the computation should take. A value of 0 specifies no upper limit. The minimum is always 1 MB.
|
48
|
+
* `:max_memfrac` specifies the maximum memory in a fraction of available resources to use. Any value equal to 0 or greater than 0.5 will result in 0.5 being used.
|
49
|
+
|
50
|
+
Default options will result in calculation time of approx. 200 ms with 1 MB memory use.
|
data/ext/mri/Makefile
CHANGED
@@ -1,70 +1,97 @@
|
|
1
1
|
|
2
2
|
SHELL = /bin/sh
|
3
3
|
|
4
|
+
# V=0 quiet, V=1 verbose. other values don't work.
|
5
|
+
V = 0
|
6
|
+
Q1 = $(V:1=)
|
7
|
+
Q = $(Q1:0=@)
|
8
|
+
n=$(NULLCMD)
|
9
|
+
ECHO1 = $(V:1=@$n)
|
10
|
+
ECHO = $(ECHO1:0=@echo)
|
11
|
+
|
4
12
|
#### Start of system configuration section. ####
|
5
13
|
|
6
14
|
srcdir = .
|
7
|
-
topdir = /Users/pbhogan/.rvm/rubies/
|
8
|
-
hdrdir =
|
9
|
-
|
15
|
+
topdir = /Volumes/Secondary/Users/pbhogan/.rvm/rubies/ruby-1.9.3-p125/include/ruby-1.9.1
|
16
|
+
hdrdir = /Volumes/Secondary/Users/pbhogan/.rvm/rubies/ruby-1.9.3-p125/include/ruby-1.9.1
|
17
|
+
arch_hdrdir = /Volumes/Secondary/Users/pbhogan/.rvm/rubies/ruby-1.9.3-p125/include/ruby-1.9.1/$(arch)
|
18
|
+
VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
|
19
|
+
prefix = $(DESTDIR)/Volumes/Secondary/Users/pbhogan/.rvm/rubies/ruby-1.9.3-p125
|
20
|
+
rubylibprefix = $(libdir)/$(RUBY_BASE_NAME)
|
10
21
|
exec_prefix = $(prefix)
|
11
|
-
|
12
|
-
|
22
|
+
vendorhdrdir = $(rubyhdrdir)/vendor_ruby
|
23
|
+
sitehdrdir = $(rubyhdrdir)/site_ruby
|
24
|
+
rubyhdrdir = $(includedir)/$(RUBY_BASE_NAME)-$(ruby_version)
|
25
|
+
vendordir = $(rubylibprefix)/vendor_ruby
|
26
|
+
sitedir = $(rubylibprefix)/site_ruby
|
27
|
+
ridir = $(datarootdir)/$(RI_BASE_NAME)
|
13
28
|
mandir = $(datarootdir)/man
|
14
|
-
psdir = $(docdir)
|
15
|
-
oldincludedir = $(DESTDIR)/usr/include
|
16
29
|
localedir = $(datarootdir)/locale
|
17
|
-
|
18
|
-
|
19
|
-
|
30
|
+
libdir = $(exec_prefix)/lib
|
31
|
+
psdir = $(docdir)
|
32
|
+
pdfdir = $(docdir)
|
33
|
+
dvidir = $(docdir)
|
20
34
|
htmldir = $(docdir)
|
21
|
-
vendorarchdir = $(vendorlibdir)/$(sitearch)
|
22
|
-
includedir = $(prefix)/include
|
23
35
|
infodir = $(datarootdir)/info
|
24
|
-
vendorlibdir = $(vendordir)/$(ruby_version)
|
25
|
-
sysconfdir = $(prefix)/etc
|
26
|
-
libdir = $(exec_prefix)/lib
|
27
|
-
sbindir = $(exec_prefix)/sbin
|
28
|
-
rubylibdir = $(libdir)/ruby/$(ruby_version)
|
29
36
|
docdir = $(datarootdir)/doc/$(PACKAGE)
|
30
|
-
|
31
|
-
|
37
|
+
oldincludedir = $(DESTDIR)/usr/include
|
38
|
+
includedir = $(prefix)/include
|
39
|
+
localstatedir = $(prefix)/var
|
40
|
+
sharedstatedir = $(prefix)/com
|
41
|
+
sysconfdir = $(prefix)/etc
|
42
|
+
datadir = $(datarootdir)
|
32
43
|
datarootdir = $(prefix)/share
|
33
|
-
|
44
|
+
libexecdir = $(exec_prefix)/libexec
|
45
|
+
sbindir = $(exec_prefix)/sbin
|
46
|
+
bindir = $(exec_prefix)/bin
|
47
|
+
rubylibdir = $(rubylibprefix)/$(ruby_version)
|
34
48
|
archdir = $(rubylibdir)/$(arch)
|
35
|
-
sitearchdir = $(sitelibdir)/$(sitearch)
|
36
|
-
datadir = $(datarootdir)
|
37
|
-
localstatedir = $(prefix)/var
|
38
49
|
sitelibdir = $(sitedir)/$(ruby_version)
|
50
|
+
sitearchdir = $(sitelibdir)/$(sitearch)
|
51
|
+
vendorlibdir = $(vendordir)/$(ruby_version)
|
52
|
+
vendorarchdir = $(vendorlibdir)/$(sitearch)
|
53
|
+
|
54
|
+
NULLCMD = :
|
39
55
|
|
40
|
-
CC = gcc -Wall
|
41
|
-
|
56
|
+
CC = /usr/bin/gcc-4.2 -Wall
|
57
|
+
CXX = g++-4.2
|
58
|
+
LIBRUBY = $(LIBRUBY_SO)
|
42
59
|
LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
|
43
|
-
LIBRUBYARG_SHARED =
|
60
|
+
LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
|
44
61
|
LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
|
62
|
+
OUTFLAG = -o
|
63
|
+
COUTFLAG = -o
|
45
64
|
|
46
65
|
RUBY_EXTCONF_H =
|
47
|
-
|
48
|
-
|
66
|
+
cflags = $(optflags) $(debugflags) $(warnflags)
|
67
|
+
optflags = -O3
|
68
|
+
debugflags = -g
|
69
|
+
warnflags = -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration
|
70
|
+
CFLAGS = -fno-common $(cflags) -fno-common -pipe $(ARCH_FLAG)
|
71
|
+
INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
|
49
72
|
DEFS =
|
50
|
-
CPPFLAGS =
|
51
|
-
CXXFLAGS = $(CFLAGS)
|
52
|
-
ldflags = -L.
|
53
|
-
dldflags =
|
54
|
-
|
55
|
-
DLDFLAGS = $(ldflags) $(dldflags) $(
|
56
|
-
LDSHARED =
|
73
|
+
CPPFLAGS = -I/Volumes/Secondary/Users/pbhogan/.rvm/usr/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE $(DEFS) $(cppflags)
|
74
|
+
CXXFLAGS = $(CFLAGS) $(cxxflags)
|
75
|
+
ldflags = -L. -L/usr/local/lib
|
76
|
+
dldflags = -Wl,-undefined,dynamic_lookup -Wl,-multiply_defined,suppress -Wl,-flat_namespace
|
77
|
+
ARCH_FLAG =
|
78
|
+
DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG)
|
79
|
+
LDSHARED = $(CC) -dynamic -bundle
|
80
|
+
LDSHAREDXX = $(CXX) -dynamic -bundle
|
57
81
|
AR = ar
|
58
82
|
EXEEXT =
|
59
83
|
|
84
|
+
RUBY_BASE_NAME = ruby
|
60
85
|
RUBY_INSTALL_NAME = ruby
|
61
|
-
RUBY_SO_NAME = ruby
|
62
|
-
arch =
|
63
|
-
sitearch =
|
64
|
-
ruby_version = 1.
|
65
|
-
ruby = /Users/pbhogan/.rvm/rubies/
|
86
|
+
RUBY_SO_NAME = ruby.1.9.1
|
87
|
+
arch = x86_64-darwin11.3.0
|
88
|
+
sitearch = $(arch)
|
89
|
+
ruby_version = 1.9.1
|
90
|
+
ruby = /Volumes/Secondary/Users/pbhogan/.rvm/rubies/ruby-1.9.3-p125/bin/ruby
|
66
91
|
RUBY = $(ruby)
|
67
92
|
RM = rm -f
|
93
|
+
RM_RF = $(RUBY) -run -e rm -- -rf
|
94
|
+
RMDIRS = rmdir -p
|
68
95
|
MAKEDIRS = mkdir -p
|
69
96
|
INSTALL = /usr/bin/install -c
|
70
97
|
INSTALL_PROG = $(INSTALL) -m 0755
|
@@ -75,18 +102,19 @@ COPY = cp
|
|
75
102
|
|
76
103
|
preload =
|
77
104
|
|
78
|
-
libpath = . $(libdir)
|
79
|
-
LIBPATH = -L. -L$(libdir)
|
105
|
+
libpath = . $(libdir) /Volumes/Secondary/Users/pbhogan/.rvm/usr/lib
|
106
|
+
LIBPATH = -L. -L$(libdir) -L/Volumes/Secondary/Users/pbhogan/.rvm/usr/lib
|
80
107
|
DEFFILE =
|
81
108
|
|
82
109
|
CLEANFILES = mkmf.log
|
83
110
|
DISTCLEANFILES =
|
111
|
+
DISTCLEANDIRS =
|
84
112
|
|
85
113
|
extout =
|
86
114
|
extout_prefix =
|
87
115
|
target_prefix =
|
88
116
|
LOCAL_LIBS =
|
89
|
-
LIBS =
|
117
|
+
LIBS = $(LIBRUBYARG_SHARED) -lpthread -ldl -lobjc
|
90
118
|
SRCS = crypto_scrypt-ref.c memlimit.c scrypt_calibrate.c scrypt_ext.c scryptenc_cpuperf.c sha256.c
|
91
119
|
OBJS = crypto_scrypt-ref.o memlimit.o scrypt_calibrate.o scrypt_ext.o scryptenc_cpuperf.o sha256.o
|
92
120
|
TARGET = scrypt_ext
|
@@ -98,60 +126,88 @@ BINDIR = $(bindir)
|
|
98
126
|
RUBYCOMMONDIR = $(sitedir)$(target_prefix)
|
99
127
|
RUBYLIBDIR = $(sitelibdir)$(target_prefix)
|
100
128
|
RUBYARCHDIR = $(sitearchdir)$(target_prefix)
|
129
|
+
HDRDIR = $(rubyhdrdir)/ruby$(target_prefix)
|
130
|
+
ARCHHDRDIR = $(rubyhdrdir)/$(arch)/ruby$(target_prefix)
|
101
131
|
|
102
132
|
TARGET_SO = $(DLLIB)
|
103
|
-
CLEANLIBS = $(TARGET).bundle
|
104
|
-
CLEANOBJS = *.o
|
105
|
-
|
106
|
-
all:
|
107
|
-
static:
|
108
|
-
|
109
|
-
clean
|
133
|
+
CLEANLIBS = $(TARGET).bundle
|
134
|
+
CLEANOBJS = *.o *.bak
|
135
|
+
|
136
|
+
all: $(DLLIB)
|
137
|
+
static: $(STATIC_LIB)
|
138
|
+
.PHONY: all install static install-so install-rb
|
139
|
+
.PHONY: clean clean-so clean-rb
|
140
|
+
|
141
|
+
clean-rb-default::
|
142
|
+
clean-rb::
|
143
|
+
clean-so::
|
144
|
+
clean: clean-so clean-rb-default clean-rb
|
110
145
|
@-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)
|
111
146
|
|
112
|
-
distclean
|
147
|
+
distclean-rb-default::
|
148
|
+
distclean-rb::
|
149
|
+
distclean-so::
|
150
|
+
distclean: clean distclean-so distclean-rb-default distclean-rb
|
113
151
|
@-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
|
114
152
|
@-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
|
153
|
+
@-$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true
|
115
154
|
|
116
|
-
realclean:
|
155
|
+
realclean: distclean
|
117
156
|
install: install-so install-rb
|
118
157
|
|
119
158
|
install-so: $(RUBYARCHDIR)
|
120
159
|
install-so: $(RUBYARCHDIR)/$(DLLIB)
|
121
160
|
$(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
|
122
|
-
|
161
|
+
@-$(MAKEDIRS) $(@D)
|
162
|
+
$(INSTALL_PROG) $(DLLIB) $(@D)
|
123
163
|
install-rb: pre-install-rb install-rb-default
|
124
164
|
install-rb-default: pre-install-rb-default
|
125
165
|
pre-install-rb: Makefile
|
126
166
|
pre-install-rb-default: Makefile
|
167
|
+
pre-install-rb-default:
|
168
|
+
$(ECHO) installing default scrypt_ext libraries
|
127
169
|
$(RUBYARCHDIR):
|
128
|
-
$(MAKEDIRS) $@
|
170
|
+
$(Q) $(MAKEDIRS) $@
|
129
171
|
|
130
172
|
site-install: site-install-so site-install-rb
|
131
173
|
site-install-so: install-so
|
132
174
|
site-install-rb: install-rb
|
133
175
|
|
134
|
-
.SUFFIXES: .c .m .cc .cxx .cpp .C .o
|
176
|
+
.SUFFIXES: .c .m .cc .mm .cxx .cpp .C .o
|
135
177
|
|
136
178
|
.cc.o:
|
137
|
-
$(
|
179
|
+
$(ECHO) compiling $(<)
|
180
|
+
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
|
181
|
+
|
182
|
+
.mm.o:
|
183
|
+
$(ECHO) compiling $(<)
|
184
|
+
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
|
138
185
|
|
139
186
|
.cxx.o:
|
140
|
-
$(
|
187
|
+
$(ECHO) compiling $(<)
|
188
|
+
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
|
141
189
|
|
142
190
|
.cpp.o:
|
143
|
-
$(
|
191
|
+
$(ECHO) compiling $(<)
|
192
|
+
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
|
144
193
|
|
145
194
|
.C.o:
|
146
|
-
$(
|
195
|
+
$(ECHO) compiling $(<)
|
196
|
+
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
|
147
197
|
|
148
198
|
.c.o:
|
149
|
-
$(
|
199
|
+
$(ECHO) compiling $(<)
|
200
|
+
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<
|
201
|
+
|
202
|
+
.m.o:
|
203
|
+
$(ECHO) compiling $(<)
|
204
|
+
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<
|
150
205
|
|
151
206
|
$(DLLIB): $(OBJS) Makefile
|
152
|
-
|
153
|
-
|
207
|
+
$(ECHO) linking shared-object $(DLLIB)
|
208
|
+
@-$(RM) $(@)
|
209
|
+
$(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
|
154
210
|
|
155
211
|
|
156
212
|
|
157
|
-
$(OBJS): ruby.h defines.h
|
213
|
+
$(OBJS): $(hdrdir)/ruby.h $(hdrdir)/ruby/defines.h $(arch_hdrdir)/ruby/config.h
|
data/ext/mri/crypto_scrypt-ref.c
CHANGED
@@ -255,7 +255,7 @@ crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
|
|
255
255
|
goto err2;
|
256
256
|
|
257
257
|
/* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
|
258
|
-
|
258
|
+
PBKDF2_scrypt_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r);
|
259
259
|
|
260
260
|
/* 2: for i = 0 to p - 1 do */
|
261
261
|
for (i = 0; i < p; i++) {
|
@@ -264,7 +264,7 @@ crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
|
|
264
264
|
}
|
265
265
|
|
266
266
|
/* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
|
267
|
-
|
267
|
+
PBKDF2_scrypt_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);
|
268
268
|
|
269
269
|
/* Free memory. */
|
270
270
|
free(V);
|
data/ext/mri/sha256.c
CHANGED
@@ -60,7 +60,7 @@ be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len)
|
|
60
60
|
dst[i] = be32dec(src + i * 4);
|
61
61
|
}
|
62
62
|
|
63
|
-
/* Elementary functions used by
|
63
|
+
/* Elementary functions used by scrypt_SHA256 */
|
64
64
|
#define Ch(x, y, z) ((x & (y ^ z)) ^ z)
|
65
65
|
#define Maj(x, y, z) ((x & (y | z)) | (y & z))
|
66
66
|
#define SHR(x, n) (x >> n)
|
@@ -70,7 +70,7 @@ be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len)
|
|
70
70
|
#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
|
71
71
|
#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
|
72
72
|
|
73
|
-
/*
|
73
|
+
/* scrypt_SHA256 round function */
|
74
74
|
#define RND(a, b, c, d, e, f, g, h, k) \
|
75
75
|
t0 = h + S1(e) + Ch(e, f, g) + k; \
|
76
76
|
t1 = S0(a) + Maj(a, b, c); \
|
@@ -86,11 +86,11 @@ be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len)
|
|
86
86
|
W[i] + k)
|
87
87
|
|
88
88
|
/*
|
89
|
-
*
|
89
|
+
* scrypt_SHA256 block compression function. The 256-bit state is transformed via
|
90
90
|
* the 512-bit input block to produce a new state.
|
91
91
|
*/
|
92
92
|
static void
|
93
|
-
|
93
|
+
scrypt_SHA256_Transform(uint32_t * state, const unsigned char block[64])
|
94
94
|
{
|
95
95
|
uint32_t W[64];
|
96
96
|
uint32_t S[8];
|
@@ -190,7 +190,7 @@ static unsigned char PAD[64] = {
|
|
190
190
|
|
191
191
|
/* Add padding and terminating bit-count. */
|
192
192
|
static void
|
193
|
-
|
193
|
+
scrypt_SHA256_Pad(scrypt_SHA256_CTX * ctx)
|
194
194
|
{
|
195
195
|
unsigned char len[8];
|
196
196
|
uint32_t r, plen;
|
@@ -204,15 +204,15 @@ SHA256_Pad(SHA256_CTX * ctx)
|
|
204
204
|
/* Add 1--64 bytes so that the resulting length is 56 mod 64 */
|
205
205
|
r = (ctx->count[1] >> 3) & 0x3f;
|
206
206
|
plen = (r < 56) ? (56 - r) : (120 - r);
|
207
|
-
|
207
|
+
scrypt_SHA256_Update(ctx, PAD, (size_t)plen);
|
208
208
|
|
209
209
|
/* Add the terminating bit-count */
|
210
|
-
|
210
|
+
scrypt_SHA256_Update(ctx, len, 8);
|
211
211
|
}
|
212
212
|
|
213
213
|
/* SHA-256 initialization. Begins a SHA-256 operation. */
|
214
214
|
void
|
215
|
-
|
215
|
+
scrypt_SHA256_Init(scrypt_SHA256_CTX * ctx)
|
216
216
|
{
|
217
217
|
|
218
218
|
/* Zero bits processed so far */
|
@@ -231,7 +231,7 @@ SHA256_Init(SHA256_CTX * ctx)
|
|
231
231
|
|
232
232
|
/* Add bytes into the hash */
|
233
233
|
void
|
234
|
-
|
234
|
+
scrypt_SHA256_Update(scrypt_SHA256_CTX * ctx, const void *in, size_t len)
|
235
235
|
{
|
236
236
|
uint32_t bitlen[2];
|
237
237
|
uint32_t r;
|
@@ -257,13 +257,13 @@ SHA256_Update(SHA256_CTX * ctx, const void *in, size_t len)
|
|
257
257
|
|
258
258
|
/* Finish the current block */
|
259
259
|
memcpy(&ctx->buf[r], src, 64 - r);
|
260
|
-
|
260
|
+
scrypt_SHA256_Transform(ctx->state, ctx->buf);
|
261
261
|
src += 64 - r;
|
262
262
|
len -= 64 - r;
|
263
263
|
|
264
264
|
/* Perform complete blocks */
|
265
265
|
while (len >= 64) {
|
266
|
-
|
266
|
+
scrypt_SHA256_Transform(ctx->state, src);
|
267
267
|
src += 64;
|
268
268
|
len -= 64;
|
269
269
|
}
|
@@ -277,11 +277,11 @@ SHA256_Update(SHA256_CTX * ctx, const void *in, size_t len)
|
|
277
277
|
* and clears the context state.
|
278
278
|
*/
|
279
279
|
void
|
280
|
-
|
280
|
+
scrypt_SHA256_Final(unsigned char digest[32], scrypt_SHA256_CTX * ctx)
|
281
281
|
{
|
282
282
|
|
283
283
|
/* Add padding */
|
284
|
-
|
284
|
+
scrypt_SHA256_Pad(ctx);
|
285
285
|
|
286
286
|
/* Write the hash */
|
287
287
|
be32enc_vect(digest, ctx->state, 32);
|
@@ -290,80 +290,80 @@ SHA256_Final(unsigned char digest[32], SHA256_CTX * ctx)
|
|
290
290
|
memset((void *)ctx, 0, sizeof(*ctx));
|
291
291
|
}
|
292
292
|
|
293
|
-
/* Initialize an HMAC-
|
293
|
+
/* Initialize an HMAC-scrypt_SHA256 operation with the given key. */
|
294
294
|
void
|
295
|
-
|
295
|
+
HMAC_scrypt_SHA256_Init(HMAC_scrypt_SHA256_CTX * ctx, const void * _K, size_t Klen)
|
296
296
|
{
|
297
297
|
unsigned char pad[64];
|
298
298
|
unsigned char khash[32];
|
299
299
|
const unsigned char * K = _K;
|
300
300
|
size_t i;
|
301
301
|
|
302
|
-
/* If Klen > 64, the key is really
|
302
|
+
/* If Klen > 64, the key is really scrypt_SHA256(K). */
|
303
303
|
if (Klen > 64) {
|
304
|
-
|
305
|
-
|
306
|
-
|
304
|
+
scrypt_SHA256_Init(&ctx->ictx);
|
305
|
+
scrypt_SHA256_Update(&ctx->ictx, K, Klen);
|
306
|
+
scrypt_SHA256_Final(khash, &ctx->ictx);
|
307
307
|
K = khash;
|
308
308
|
Klen = 32;
|
309
309
|
}
|
310
310
|
|
311
|
-
/* Inner
|
312
|
-
|
311
|
+
/* Inner scrypt_SHA256 operation is scrypt_SHA256(K xor [block of 0x36] || data). */
|
312
|
+
scrypt_SHA256_Init(&ctx->ictx);
|
313
313
|
memset(pad, 0x36, 64);
|
314
314
|
for (i = 0; i < Klen; i++)
|
315
315
|
pad[i] ^= K[i];
|
316
|
-
|
316
|
+
scrypt_SHA256_Update(&ctx->ictx, pad, 64);
|
317
317
|
|
318
|
-
/* Outer
|
319
|
-
|
318
|
+
/* Outer scrypt_SHA256 operation is scrypt_SHA256(K xor [block of 0x5c] || hash). */
|
319
|
+
scrypt_SHA256_Init(&ctx->octx);
|
320
320
|
memset(pad, 0x5c, 64);
|
321
321
|
for (i = 0; i < Klen; i++)
|
322
322
|
pad[i] ^= K[i];
|
323
|
-
|
323
|
+
scrypt_SHA256_Update(&ctx->octx, pad, 64);
|
324
324
|
|
325
325
|
/* Clean the stack. */
|
326
326
|
memset(khash, 0, 32);
|
327
327
|
}
|
328
328
|
|
329
|
-
/* Add bytes to the HMAC-
|
329
|
+
/* Add bytes to the HMAC-scrypt_SHA256 operation. */
|
330
330
|
void
|
331
|
-
|
331
|
+
HMAC_scrypt_SHA256_Update(HMAC_scrypt_SHA256_CTX * ctx, const void *in, size_t len)
|
332
332
|
{
|
333
333
|
|
334
|
-
/* Feed data to the inner
|
335
|
-
|
334
|
+
/* Feed data to the inner scrypt_SHA256 operation. */
|
335
|
+
scrypt_SHA256_Update(&ctx->ictx, in, len);
|
336
336
|
}
|
337
337
|
|
338
|
-
/* Finish an HMAC-
|
338
|
+
/* Finish an HMAC-scrypt_SHA256 operation. */
|
339
339
|
void
|
340
|
-
|
340
|
+
HMAC_scrypt_SHA256_Final(unsigned char digest[32], HMAC_scrypt_SHA256_CTX * ctx)
|
341
341
|
{
|
342
342
|
unsigned char ihash[32];
|
343
343
|
|
344
|
-
/* Finish the inner
|
345
|
-
|
344
|
+
/* Finish the inner scrypt_SHA256 operation. */
|
345
|
+
scrypt_SHA256_Final(ihash, &ctx->ictx);
|
346
346
|
|
347
|
-
/* Feed the inner hash to the outer
|
348
|
-
|
347
|
+
/* Feed the inner hash to the outer scrypt_SHA256 operation. */
|
348
|
+
scrypt_SHA256_Update(&ctx->octx, ihash, 32);
|
349
349
|
|
350
|
-
/* Finish the outer
|
351
|
-
|
350
|
+
/* Finish the outer scrypt_SHA256 operation. */
|
351
|
+
scrypt_SHA256_Final(digest, &ctx->octx);
|
352
352
|
|
353
353
|
/* Clean the stack. */
|
354
354
|
memset(ihash, 0, 32);
|
355
355
|
}
|
356
356
|
|
357
357
|
/**
|
358
|
-
*
|
359
|
-
* Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-
|
358
|
+
* PBKDF2_scrypt_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
|
359
|
+
* Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-scrypt_SHA256 as the PRF, and
|
360
360
|
* write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
|
361
361
|
*/
|
362
362
|
void
|
363
|
-
|
363
|
+
PBKDF2_scrypt_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
|
364
364
|
size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
|
365
365
|
{
|
366
|
-
|
366
|
+
HMAC_scrypt_SHA256_CTX PShctx, hctx;
|
367
367
|
size_t i;
|
368
368
|
uint8_t ivec[4];
|
369
369
|
uint8_t U[32];
|
@@ -373,8 +373,8 @@ PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
|
|
373
373
|
size_t clen;
|
374
374
|
|
375
375
|
/* Compute HMAC state after processing P and S. */
|
376
|
-
|
377
|
-
|
376
|
+
HMAC_scrypt_SHA256_Init(&PShctx, passwd, passwdlen);
|
377
|
+
HMAC_scrypt_SHA256_Update(&PShctx, salt, saltlen);
|
378
378
|
|
379
379
|
/* Iterate through the blocks. */
|
380
380
|
for (i = 0; i * 32 < dkLen; i++) {
|
@@ -382,18 +382,18 @@ PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
|
|
382
382
|
be32enc(ivec, (uint32_t)(i + 1));
|
383
383
|
|
384
384
|
/* Compute U_1 = PRF(P, S || INT(i)). */
|
385
|
-
memcpy(&hctx, &PShctx, sizeof(
|
386
|
-
|
387
|
-
|
385
|
+
memcpy(&hctx, &PShctx, sizeof(HMAC_scrypt_SHA256_CTX));
|
386
|
+
HMAC_scrypt_SHA256_Update(&hctx, ivec, 4);
|
387
|
+
HMAC_scrypt_SHA256_Final(U, &hctx);
|
388
388
|
|
389
389
|
/* T_i = U_1 ... */
|
390
390
|
memcpy(T, U, 32);
|
391
391
|
|
392
392
|
for (j = 2; j <= c; j++) {
|
393
393
|
/* Compute U_j. */
|
394
|
-
|
395
|
-
|
396
|
-
|
394
|
+
HMAC_scrypt_SHA256_Init(&hctx, passwd, passwdlen);
|
395
|
+
HMAC_scrypt_SHA256_Update(&hctx, U, 32);
|
396
|
+
HMAC_scrypt_SHA256_Final(U, &hctx);
|
397
397
|
|
398
398
|
/* ... xor U_j ... */
|
399
399
|
for (k = 0; k < 32; k++)
|
@@ -408,5 +408,5 @@ PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
|
|
408
408
|
}
|
409
409
|
|
410
410
|
/* Clean PShctx, since we never called _Final on it. */
|
411
|
-
memset(&PShctx, 0, sizeof(
|
411
|
+
memset(&PShctx, 0, sizeof(HMAC_scrypt_SHA256_CTX));
|
412
412
|
}
|
data/ext/mri/sha256.h
CHANGED
@@ -26,37 +26,37 @@
|
|
26
26
|
* $FreeBSD: src/lib/libmd/sha256.h,v 1.2 2006/01/17 15:35:56 phk Exp $
|
27
27
|
*/
|
28
28
|
|
29
|
-
#ifndef
|
30
|
-
#define
|
29
|
+
#ifndef _scrypt_SHA256_H_
|
30
|
+
#define _scrypt_SHA256_H_
|
31
31
|
|
32
32
|
#include <sys/types.h>
|
33
33
|
|
34
34
|
#include <stdint.h>
|
35
35
|
|
36
|
-
typedef struct
|
36
|
+
typedef struct scrypt_SHA256Context {
|
37
37
|
uint32_t state[8];
|
38
38
|
uint32_t count[2];
|
39
39
|
unsigned char buf[64];
|
40
|
-
}
|
40
|
+
} scrypt_SHA256_CTX;
|
41
41
|
|
42
|
-
typedef struct
|
43
|
-
|
44
|
-
|
45
|
-
}
|
42
|
+
typedef struct HMAC_scrypt_SHA256Context {
|
43
|
+
scrypt_SHA256_CTX ictx;
|
44
|
+
scrypt_SHA256_CTX octx;
|
45
|
+
} HMAC_scrypt_SHA256_CTX;
|
46
46
|
|
47
|
-
void
|
48
|
-
void
|
49
|
-
void
|
50
|
-
void
|
51
|
-
void
|
52
|
-
void
|
47
|
+
void scrypt_SHA256_Init(scrypt_SHA256_CTX *);
|
48
|
+
void scrypt_SHA256_Update(scrypt_SHA256_CTX *, const void *, size_t);
|
49
|
+
void scrypt_SHA256_Final(unsigned char [32], scrypt_SHA256_CTX *);
|
50
|
+
void HMAC_scrypt_SHA256_Init(HMAC_scrypt_SHA256_CTX *, const void *, size_t);
|
51
|
+
void HMAC_scrypt_SHA256_Update(HMAC_scrypt_SHA256_CTX *, const void *, size_t);
|
52
|
+
void HMAC_scrypt_SHA256_Final(unsigned char [32], HMAC_scrypt_SHA256_CTX *);
|
53
53
|
|
54
54
|
/**
|
55
|
-
*
|
56
|
-
* Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-
|
55
|
+
* PBKDF2_scrypt_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
|
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
|
59
|
+
void PBKDF2_scrypt_SHA256(const uint8_t *, size_t, const uint8_t *, size_t,
|
60
60
|
uint64_t, uint8_t *, size_t);
|
61
61
|
|
62
|
-
#endif /* !
|
62
|
+
#endif /* !_scrypt_SHA256_H_ */
|
data/kdf-comparison.png
ADDED
Binary file
|
data/lib/scrypt/version.rb
CHANGED
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.
|
4
|
+
version: 1.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,12 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
13
|
-
default_executable:
|
12
|
+
date: 2012-04-11 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: rspec
|
17
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
18
17
|
none: false
|
19
18
|
requirements:
|
20
19
|
- - ! '>='
|
@@ -22,10 +21,15 @@ dependencies:
|
|
22
21
|
version: '0'
|
23
22
|
type: :development
|
24
23
|
prerelease: false
|
25
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
26
30
|
- !ruby/object:Gem::Dependency
|
27
31
|
name: rake
|
28
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
29
33
|
none: false
|
30
34
|
requirements:
|
31
35
|
- - ! '>='
|
@@ -33,7 +37,12 @@ dependencies:
|
|
33
37
|
version: '0'
|
34
38
|
type: :development
|
35
39
|
prerelease: false
|
36
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
37
46
|
description: ! " The scrypt key derivation function is designed to be far \n more
|
38
47
|
secure against hardware brute-force attacks than \n alternative functions such
|
39
48
|
as PBKDF2 or bcrypt.\n"
|
@@ -50,7 +59,7 @@ files:
|
|
50
59
|
- COPYING
|
51
60
|
- Gemfile
|
52
61
|
- Gemfile.lock
|
53
|
-
- README
|
62
|
+
- README.md
|
54
63
|
- Rakefile
|
55
64
|
- Rakefile.old
|
56
65
|
- autotest/discover.rb
|
@@ -69,13 +78,13 @@ files:
|
|
69
78
|
- ext/mri/sha256.c
|
70
79
|
- ext/mri/sha256.h
|
71
80
|
- ext/mri/sysendian.h
|
81
|
+
- kdf-comparison.png
|
72
82
|
- lib/scrypt.rb
|
73
83
|
- lib/scrypt/version.rb
|
74
84
|
- scrypt.gemspec
|
75
85
|
- spec/scrypt/engine_spec.rb
|
76
86
|
- spec/scrypt/password_spec.rb
|
77
87
|
- spec/spec_helper.rb
|
78
|
-
has_rdoc: true
|
79
88
|
homepage: ''
|
80
89
|
licenses: []
|
81
90
|
post_install_message:
|
@@ -90,7 +99,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
90
99
|
version: '0'
|
91
100
|
segments:
|
92
101
|
- 0
|
93
|
-
hash:
|
102
|
+
hash: 194968761822727959
|
94
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
104
|
none: false
|
96
105
|
requirements:
|
@@ -99,10 +108,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
108
|
version: '0'
|
100
109
|
segments:
|
101
110
|
- 0
|
102
|
-
hash:
|
111
|
+
hash: 194968761822727959
|
103
112
|
requirements: []
|
104
113
|
rubyforge_project: scrypt
|
105
|
-
rubygems_version: 1.
|
114
|
+
rubygems_version: 1.8.21
|
106
115
|
signing_key:
|
107
116
|
specification_version: 3
|
108
117
|
summary: scrypt password hashing algorithm.
|
data/README
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
= scrypt
|
2
|
-
|
3
|
-
The scrypt key derivation function is designed to be far more secure against hardware brute-force attacks than alternative functions such as PBKDF2 or bcrypt.
|
4
|
-
|
5
|
-
* http://www.tarsnap.com/scrypt.html
|
6
|
-
* http://github.com/pbhogan/scrypt
|
7
|
-
|
8
|
-
== Why you should use scrypt
|
9
|
-
|
10
|
-
The designers of scrypt estimate that on modern (2009) hardware, if 5 seconds are spent computing a derived key, the cost of a hardware brute-force attack against scrypt is roughly 4000 times greater than the cost of a similar attack against bcrypt (to find the same password), and 20000 times greater than a similar attack against PBKDF2.
|
11
|
-
|
12
|
-
== How to install scrypt
|
13
|
-
|
14
|
-
gem install scrypt
|
15
|
-
|
16
|
-
== How to use scrypt
|
17
|
-
|
18
|
-
It works pretty similarly to ruby-bcrypt with a few minor differences, especially where the cost factor is concerned.
|
19
|
-
|
20
|
-
include "scrypt"
|
21
|
-
|
22
|
-
# hash a user's password
|
23
|
-
@password = Password.create("my grand secret")
|
24
|
-
@password #=> "2000$8$1$f5f2fa5fe5484a7091f1299768fbe92b5a7fbc77$6a385f22c54d92c314b71a4fd5ef33967c93d679"
|
25
|
-
|
26
|
-
# store it safely
|
27
|
-
@user.update_attribute(:password, @password)
|
28
|
-
|
29
|
-
# read it back
|
30
|
-
@user.reload!
|
31
|
-
@db_password = Password.new(@user.password)
|
32
|
-
|
33
|
-
# compare it after retrieval
|
34
|
-
@db_password == "my grand secret" #=> true
|
35
|
-
@db_password == "a paltry guess" #=> false
|
36
|
-
|
37
|
-
Password.create takes three options which will determine the cost limits of the computation.
|
38
|
-
* :max_time specifies the maximum number of seconds the computation should take.
|
39
|
-
* :max_mem specifies the maximum number of bytes the computation should take. A value of 0 specifies no upper limit. The minimum is always 1 MB.
|
40
|
-
* :max_memfrac specifies the maximum memory in a fraction of available resources to use. Any value equal to 0 or greater than 0.5 will result in 0.5 being used.
|
41
|
-
|
42
|
-
Default options will result in calculation time of approx. 200 ms with 1 MB memory use.
|