scrypt 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
![KDF comparison](https://github.com/tarcieri/scrypt/raw/modern-readme/kdf-comparison.png)
|
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.
|