sha3 0.2.2 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sha3 might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/.gitignore +232 -17
- data/.travis.yml +21 -12
- data/.yardopts +1 -1
- data/ChangeLog.rdoc +16 -0
- data/Gemfile +1 -1
- data/Gemfile.ci +5 -5
- data/LICENSE.txt +1 -1
- data/README.md +120 -0
- data/Rakefile +15 -18
- data/ext/sha3/KeccakF-1600-interface.h +28 -34
- data/ext/sha3/KeccakHash.c +80 -0
- data/ext/sha3/KeccakHash.h +110 -0
- data/ext/sha3/KeccakSponge.c +127 -201
- data/ext/sha3/KeccakSponge.h +74 -37
- data/ext/sha3/Optimized64/KeccakF-1600-64.macros +2199 -0
- data/ext/sha3/Optimized64/KeccakF-1600-opt64-settings.h +3 -0
- data/ext/sha3/Optimized64/KeccakF-1600-opt64.c +508 -0
- data/ext/sha3/{KeccakF-1600-unrolling.macros → Optimized64/KeccakF-1600-unrolling.macros} +16 -14
- data/ext/sha3/Optimized64/SnP-interface.h +47 -0
- data/ext/sha3/Reference/KeccakF-1600-reference.c +311 -0
- data/ext/sha3/Reference/KeccakF-reference.h +26 -0
- data/ext/sha3/Reference/SnP-FBWL-default.c +96 -0
- data/ext/sha3/Reference/SnP-FBWL-default.h +26 -0
- data/ext/sha3/Reference/SnP-interface.h +42 -0
- data/ext/sha3/{displayIntermediateValues.c → Reference/displayIntermediateValues.c} +52 -11
- data/ext/sha3/{displayIntermediateValues.h → Reference/displayIntermediateValues.h} +11 -6
- data/ext/sha3/SnP-Relaned.h +249 -0
- data/ext/sha3/brg_endian.h +0 -0
- data/ext/sha3/digest.c +270 -0
- data/ext/sha3/digest.h +48 -0
- data/ext/sha3/extconf.rb +16 -9
- data/ext/sha3/sha3.c +62 -0
- data/ext/sha3/sha3.h +26 -0
- data/lib/sha3.rb +1 -1
- data/lib/sha3/doc.rb +121 -0
- data/lib/sha3/version.rb +6 -5
- data/sha3.gemspec +13 -15
- data/spec/generate_tests.rb +22 -56
- data/spec/sha3_core_spec.rb +113 -133
- data/spec/spec_helper.rb +2 -2
- data/tests.sh +11 -9
- metadata +53 -65
- data/README.rdoc +0 -133
- data/ext/sha3/KeccakF-1600-32-rvk.macros +0 -555
- data/ext/sha3/KeccakF-1600-32-s1.macros +0 -1187
- data/ext/sha3/KeccakF-1600-32-s2.macros +0 -1187
- data/ext/sha3/KeccakF-1600-32.macros +0 -26
- data/ext/sha3/KeccakF-1600-64.macros +0 -728
- data/ext/sha3/KeccakF-1600-int-set.h +0 -6
- data/ext/sha3/KeccakF-1600-opt.c +0 -504
- data/ext/sha3/KeccakF-1600-opt32-settings.h +0 -4
- data/ext/sha3/KeccakF-1600-opt32.c-arch +0 -524
- data/ext/sha3/KeccakF-1600-opt64-settings.h +0 -7
- data/ext/sha3/KeccakF-1600-opt64.c-arch +0 -504
- data/ext/sha3/KeccakF-1600-reference.c-arch +0 -300
- data/ext/sha3/KeccakF-1600-x86-64-gas.s +0 -766
- data/ext/sha3/KeccakF-1600-x86-64-shld-gas.s +0 -766
- data/ext/sha3/KeccakNISTInterface.c +0 -81
- data/ext/sha3/KeccakNISTInterface.h +0 -70
- data/ext/sha3/_sha3.c +0 -309
- data/ext/sha3/_sha3.h +0 -32
data/ext/sha3/brg_endian.h
CHANGED
File without changes
|
data/ext/sha3/digest.c
ADDED
@@ -0,0 +1,270 @@
|
|
1
|
+
/* Copyright (c) 2012 - 2013 Johanns Gregorian <io+sha3@jsani.com> */
|
2
|
+
|
3
|
+
#include "sha3.h"
|
4
|
+
|
5
|
+
VALUE cSHA3Digest;
|
6
|
+
VALUE eSHA3DigestError;
|
7
|
+
|
8
|
+
/*
|
9
|
+
* == Notes
|
10
|
+
*
|
11
|
+
* ::Digest::Class call sequence ->
|
12
|
+
* | .alloc() ->
|
13
|
+
* | .new() ->
|
14
|
+
* | .update() ->
|
15
|
+
* | .digest or .hexdigest or .inspect -> (Instance.digest or .hexdigest()) ->
|
16
|
+
* --| .alloc() ->
|
17
|
+
* | .copy() ->
|
18
|
+
* | .finish() ->
|
19
|
+
*
|
20
|
+
*/
|
21
|
+
|
22
|
+
static void free_allox(MDX *mdx)
|
23
|
+
{
|
24
|
+
if (mdx)
|
25
|
+
{
|
26
|
+
if (mdx->state)
|
27
|
+
{
|
28
|
+
free(mdx->state);
|
29
|
+
}
|
30
|
+
|
31
|
+
free(mdx);
|
32
|
+
}
|
33
|
+
|
34
|
+
return;
|
35
|
+
}
|
36
|
+
|
37
|
+
static VALUE c_digest_alloc(VALUE klass)
|
38
|
+
{
|
39
|
+
MDX *mdx;
|
40
|
+
VALUE obj;
|
41
|
+
|
42
|
+
mdx = (MDX *)malloc(sizeof(MDX));
|
43
|
+
if (!mdx)
|
44
|
+
{
|
45
|
+
rb_raise(eSHA3DigestError, "failed to allocate object memory");
|
46
|
+
}
|
47
|
+
|
48
|
+
mdx->state = (Keccak_HashInstance *)malloc(sizeof(Keccak_HashInstance));
|
49
|
+
if (!mdx->state)
|
50
|
+
{
|
51
|
+
free_allox(mdx);
|
52
|
+
rb_raise(eSHA3DigestError, "failed to allocate state memory");
|
53
|
+
}
|
54
|
+
|
55
|
+
obj = Data_Wrap_Struct(klass, 0, free_allox, mdx);
|
56
|
+
|
57
|
+
memset(mdx->state, 0, sizeof(Keccak_HashInstance));
|
58
|
+
mdx->hashbitlen = 0;
|
59
|
+
|
60
|
+
return obj;
|
61
|
+
}
|
62
|
+
|
63
|
+
static VALUE c_digest_update(VALUE, VALUE);
|
64
|
+
|
65
|
+
HashReturn c_keccak_hash_initialize(MDX *mdx)
|
66
|
+
{
|
67
|
+
HashReturn r = FAIL;
|
68
|
+
|
69
|
+
switch (mdx->hashbitlen)
|
70
|
+
{
|
71
|
+
case 224:
|
72
|
+
r = Keccak_HashInitialize_SHA3_224(mdx->state);
|
73
|
+
break;
|
74
|
+
case 256:
|
75
|
+
r = Keccak_HashInitialize_SHA3_256(mdx->state);
|
76
|
+
break;
|
77
|
+
case 384:
|
78
|
+
r = Keccak_HashInitialize_SHA3_384(mdx->state);
|
79
|
+
break;
|
80
|
+
case 512:
|
81
|
+
r = Keccak_HashInitialize_SHA3_512(mdx->state);
|
82
|
+
break;
|
83
|
+
}
|
84
|
+
|
85
|
+
return r;
|
86
|
+
}
|
87
|
+
|
88
|
+
// SHA3::Digest.new(type, [data]) -> self
|
89
|
+
static VALUE c_digest_init(int argc, VALUE *argv, VALUE self)
|
90
|
+
{
|
91
|
+
MDX *mdx;
|
92
|
+
VALUE hlen, data;
|
93
|
+
|
94
|
+
rb_scan_args(argc, argv, "02", &hlen, &data);
|
95
|
+
GETMDX(self, mdx);
|
96
|
+
|
97
|
+
if (!NIL_P(hlen))
|
98
|
+
{
|
99
|
+
mdx->hashbitlen = get_hlen(hlen);
|
100
|
+
}
|
101
|
+
else
|
102
|
+
{
|
103
|
+
mdx->hashbitlen = 256;
|
104
|
+
}
|
105
|
+
|
106
|
+
if (c_keccak_hash_initialize(mdx) != SUCCESS)
|
107
|
+
{
|
108
|
+
rb_raise(eSHA3DigestError, "failed to initialize algorithm state");
|
109
|
+
}
|
110
|
+
|
111
|
+
if (!NIL_P(data))
|
112
|
+
{
|
113
|
+
return c_digest_update(self, data);
|
114
|
+
}
|
115
|
+
|
116
|
+
return self;
|
117
|
+
}
|
118
|
+
|
119
|
+
// SHA3::Digest.update(data) -> self
|
120
|
+
static VALUE c_digest_update(VALUE self, VALUE data)
|
121
|
+
{
|
122
|
+
MDX *mdx;
|
123
|
+
DataLength dlen;
|
124
|
+
|
125
|
+
StringValue(data);
|
126
|
+
GETMDX(self, mdx);
|
127
|
+
|
128
|
+
dlen = (RSTRING_LEN(data) * 8);
|
129
|
+
|
130
|
+
if (Keccak_HashUpdate(mdx->state, (BitSequence *)RSTRING_PTR(data), dlen) != SUCCESS)
|
131
|
+
{
|
132
|
+
rb_raise(eSHA3DigestError, "failed to update hash data");
|
133
|
+
}
|
134
|
+
|
135
|
+
return self;
|
136
|
+
}
|
137
|
+
|
138
|
+
// SHA3::Digest.reset() -> self
|
139
|
+
static VALUE c_digest_reset(VALUE self)
|
140
|
+
{
|
141
|
+
MDX *mdx;
|
142
|
+
|
143
|
+
GETMDX(self, mdx);
|
144
|
+
|
145
|
+
memset(mdx->state, 0, sizeof(Keccak_HashInstance));
|
146
|
+
|
147
|
+
if (c_keccak_hash_initialize(mdx) != SUCCESS)
|
148
|
+
{
|
149
|
+
rb_raise(eSHA3DigestError, "failed to reset internal state");
|
150
|
+
}
|
151
|
+
|
152
|
+
return self;
|
153
|
+
}
|
154
|
+
|
155
|
+
static int cmp_states(MDX *mdx1, MDX *mdx2)
|
156
|
+
{
|
157
|
+
return (
|
158
|
+
(mdx1->hashbitlen == mdx2->hashbitlen) &&
|
159
|
+
(strcmp((const char *)mdx1->state->sponge.state, (const char *)mdx2->state->sponge.state) == 0) &&
|
160
|
+
(mdx1->state->sponge.rate == mdx2->state->sponge.rate) &&
|
161
|
+
(mdx1->state->sponge.byteIOIndex == mdx2->state->sponge.byteIOIndex) &&
|
162
|
+
(mdx1->state->sponge.squeezing == mdx2->state->sponge.squeezing) &&
|
163
|
+
(mdx1->state->fixedOutputLength == mdx2->state->fixedOutputLength) &&
|
164
|
+
(mdx1->state->delimitedSuffix == mdx2->state->delimitedSuffix));
|
165
|
+
}
|
166
|
+
|
167
|
+
// SHA3::Digest.copy(obj) -> self
|
168
|
+
static VALUE c_digest_copy(VALUE self, VALUE obj)
|
169
|
+
{
|
170
|
+
MDX *mdx1, *mdx2;
|
171
|
+
|
172
|
+
rb_check_frozen(self);
|
173
|
+
if (self == obj)
|
174
|
+
{
|
175
|
+
return self;
|
176
|
+
}
|
177
|
+
|
178
|
+
GETMDX(self, mdx1);
|
179
|
+
SAFEGETMDX(obj, mdx2);
|
180
|
+
|
181
|
+
memcpy(mdx1->state, mdx2->state, sizeof(Keccak_HashInstance));
|
182
|
+
mdx1->hashbitlen = mdx2->hashbitlen;
|
183
|
+
|
184
|
+
// Fetch the data again to make sure it was copied
|
185
|
+
GETMDX(self, mdx1);
|
186
|
+
SAFEGETMDX(obj, mdx2);
|
187
|
+
|
188
|
+
if (!cmp_states(mdx1, mdx2))
|
189
|
+
{
|
190
|
+
rb_raise(eSHA3DigestError, "failed to copy state");
|
191
|
+
}
|
192
|
+
|
193
|
+
return self;
|
194
|
+
}
|
195
|
+
|
196
|
+
// SHA3::Digest.digest_length -> Integer
|
197
|
+
static VALUE c_digest_length(VALUE self)
|
198
|
+
{
|
199
|
+
MDX *mdx;
|
200
|
+
GETMDX(self, mdx);
|
201
|
+
|
202
|
+
return ULL2NUM(mdx->hashbitlen / 8);
|
203
|
+
}
|
204
|
+
|
205
|
+
// SHA3::Digest.block_length -> Integer
|
206
|
+
static VALUE c_digest_block_length(VALUE self)
|
207
|
+
{
|
208
|
+
MDX *mdx;
|
209
|
+
GETMDX(self, mdx);
|
210
|
+
|
211
|
+
return ULL2NUM(200 - (2 * (mdx->hashbitlen / 8)));
|
212
|
+
}
|
213
|
+
|
214
|
+
// SHA3::Digest.name -> String
|
215
|
+
static VALUE c_digest_name(VALUE self)
|
216
|
+
{
|
217
|
+
return rb_str_new2("SHA3");
|
218
|
+
}
|
219
|
+
|
220
|
+
// SHA3::Digest.finish() -> String
|
221
|
+
static VALUE c_digest_finish(int argc, VALUE *argv, VALUE self)
|
222
|
+
{
|
223
|
+
MDX *mdx;
|
224
|
+
VALUE str;
|
225
|
+
|
226
|
+
rb_scan_args(argc, argv, "01", &str);
|
227
|
+
GETMDX(self, mdx);
|
228
|
+
|
229
|
+
if (NIL_P(str))
|
230
|
+
{
|
231
|
+
str = rb_str_new(0, mdx->hashbitlen / 8);
|
232
|
+
}
|
233
|
+
else
|
234
|
+
{
|
235
|
+
StringValue(str);
|
236
|
+
rb_str_resize(str, mdx->hashbitlen / 8);
|
237
|
+
}
|
238
|
+
|
239
|
+
if (Keccak_HashFinal(mdx->state, (BitSequence *)RSTRING_PTR(str)) != SUCCESS)
|
240
|
+
{
|
241
|
+
rb_raise(eSHA3DigestError, "failed to finalize digest");
|
242
|
+
}
|
243
|
+
|
244
|
+
return str;
|
245
|
+
}
|
246
|
+
|
247
|
+
void Init_sha3_n_digest()
|
248
|
+
{
|
249
|
+
rb_require("digest");
|
250
|
+
|
251
|
+
/* SHA3::Digest (class) */
|
252
|
+
cSHA3Digest = rb_define_class_under(mSHA3, "Digest", rb_path2class("Digest::Class"));
|
253
|
+
/* SHA3::Digest::DigestError (class) */
|
254
|
+
eSHA3DigestError = rb_define_class_under(cSHA3Digest, "DigestError", rb_eStandardError);
|
255
|
+
|
256
|
+
// SHA3::Digest (class) methods
|
257
|
+
rb_define_alloc_func(cSHA3Digest, c_digest_alloc);
|
258
|
+
rb_define_method(cSHA3Digest, "initialize", c_digest_init, -1);
|
259
|
+
rb_define_method(cSHA3Digest, "update", c_digest_update, 1);
|
260
|
+
rb_define_method(cSHA3Digest, "reset", c_digest_reset, 0);
|
261
|
+
rb_define_method(cSHA3Digest, "initialize_copy", c_digest_copy, 1);
|
262
|
+
rb_define_method(cSHA3Digest, "digest_length", c_digest_length, 0);
|
263
|
+
rb_define_method(cSHA3Digest, "block_length", c_digest_block_length, 0);
|
264
|
+
rb_define_method(cSHA3Digest, "name", c_digest_name, 0);
|
265
|
+
rb_define_private_method(cSHA3Digest, "finish", c_digest_finish, -1);
|
266
|
+
|
267
|
+
rb_define_alias(cSHA3Digest, "<<", "update");
|
268
|
+
|
269
|
+
return;
|
270
|
+
}
|
data/ext/sha3/digest.h
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
/* Copyright (c) 2012 - 2013 Johanns Gregorian <io+sha3@jsani.com> */
|
2
|
+
|
3
|
+
#ifndef _DIGEST_H_
|
4
|
+
#define _DIGEST_H_
|
5
|
+
|
6
|
+
#ifdef __cplusplus
|
7
|
+
extern "C"
|
8
|
+
{
|
9
|
+
#endif
|
10
|
+
|
11
|
+
// From ruby/ext/openssl/ossl_digest.c
|
12
|
+
#define GETMDX(obj, mdx) \
|
13
|
+
do \
|
14
|
+
{ \
|
15
|
+
Data_Get_Struct((obj), MDX, (mdx)); \
|
16
|
+
if (!(mdx)) \
|
17
|
+
{ \
|
18
|
+
rb_raise(rb_eRuntimeError, "Digest data not initialized!"); \
|
19
|
+
} \
|
20
|
+
} while (0)
|
21
|
+
|
22
|
+
#define SAFEGETMDX(obj, mdx) \
|
23
|
+
do \
|
24
|
+
{ \
|
25
|
+
if (!rb_obj_is_kind_of(obj, cSHA3Digest)) \
|
26
|
+
{ \
|
27
|
+
rb_raise(rb_eTypeError, "wrong argument (%s)! (expected %s)", \
|
28
|
+
rb_obj_classname(obj), rb_class2name(cSHA3Digest)); \
|
29
|
+
} \
|
30
|
+
GETMDX(obj, mdx); \
|
31
|
+
} while (0)
|
32
|
+
|
33
|
+
extern VALUE cSHA3Digest;
|
34
|
+
extern VALUE eSHA3DigestError;
|
35
|
+
|
36
|
+
typedef struct
|
37
|
+
{
|
38
|
+
Keccak_HashInstance *state;
|
39
|
+
int hashbitlen;
|
40
|
+
} MDX;
|
41
|
+
|
42
|
+
void Init_sha3_n_digest(void);
|
43
|
+
|
44
|
+
#ifdef __cplusplus
|
45
|
+
}
|
46
|
+
#endif
|
47
|
+
|
48
|
+
#endif
|
data/ext/sha3/extconf.rb
CHANGED
@@ -1,14 +1,21 @@
|
|
1
1
|
require 'mkmf'
|
2
|
+
require 'rbconfig'
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
FileUtils.cp "#{$srcdir}/
|
8
|
-
|
9
|
-
|
4
|
+
target_cpu = RbConfig::CONFIG['target_cpu']
|
5
|
+
|
6
|
+
if 1.size == 4 and target_cpu =~ /i386|x86_32/ # x86 32bit optimized code
|
7
|
+
Logging::message "=== Using reference ===\n"
|
8
|
+
FileUtils.cp Dir["#{$srcdir}/Reference/*"].collect { |f| File.expand_path(f) }, "#{$srcdir}/"
|
9
|
+
elsif 1.size == 8 and target_cpu =~ /i686|x86_64/
|
10
|
+
Logging::message "=== Using optimized (64-bit) ===\n"
|
11
|
+
FileUtils.cp Dir["#{$srcdir}/Optimized64/*"].collect { |f| File.expand_path(f) }, "#{$srcdir}/"
|
12
|
+
else
|
13
|
+
Logging::message "=== Using reference ===\n"
|
14
|
+
FileUtils.cp Dir["#{$srcdir}/Reference/*"].collect { |f| File.expand_path(f) }, "#{$srcdir}/"
|
10
15
|
end
|
11
16
|
|
12
|
-
|
13
|
-
|
17
|
+
find_header("sha3.h")
|
18
|
+
find_header("digest.h")
|
14
19
|
|
20
|
+
$CFLAGS = ' -fomit-frame-pointer -O3 -g0 -march=native '
|
21
|
+
create_makefile 'sha3_n'
|
data/ext/sha3/sha3.c
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
/* Copyright (c) 2012 - 2013 Johanns Gregorian <io+sha3@jsani.com> */
|
2
|
+
|
3
|
+
#include "sha3.h"
|
4
|
+
|
5
|
+
VALUE mSHA3;
|
6
|
+
VALUE eSHA3Error;
|
7
|
+
|
8
|
+
int get_hlen(VALUE obj)
|
9
|
+
{
|
10
|
+
int hlen;
|
11
|
+
|
12
|
+
if (TYPE(obj) == T_SYMBOL)
|
13
|
+
{
|
14
|
+
ID symid;
|
15
|
+
|
16
|
+
symid = SYM2ID(obj);
|
17
|
+
|
18
|
+
if (rb_intern("sha224") == symid)
|
19
|
+
{
|
20
|
+
hlen = 224;
|
21
|
+
}
|
22
|
+
else if (rb_intern("sha256") == symid)
|
23
|
+
{
|
24
|
+
hlen = 256;
|
25
|
+
}
|
26
|
+
else if (rb_intern("sha384") == symid)
|
27
|
+
{
|
28
|
+
hlen = 384;
|
29
|
+
}
|
30
|
+
else if (rb_intern("sha512") == symid)
|
31
|
+
{
|
32
|
+
hlen = 512;
|
33
|
+
}
|
34
|
+
else
|
35
|
+
{
|
36
|
+
rb_raise(eSHA3Error, "invalid hash bit symbol (should be: :sha224, :sha256, :sha384, or :sha512");
|
37
|
+
}
|
38
|
+
}
|
39
|
+
else if (TYPE(obj) == T_FIXNUM)
|
40
|
+
{
|
41
|
+
hlen = NUM2INT(obj);
|
42
|
+
|
43
|
+
if ((hlen != 224) && (hlen != 256) && (hlen != 384) && (hlen != 512))
|
44
|
+
{
|
45
|
+
rb_raise(rb_eArgError, "invalid hash bit length (should be: 224, 256, 384, or 512)");
|
46
|
+
}
|
47
|
+
}
|
48
|
+
else
|
49
|
+
{
|
50
|
+
rb_raise(eSHA3Error, "unknown type value");
|
51
|
+
}
|
52
|
+
|
53
|
+
return hlen;
|
54
|
+
}
|
55
|
+
|
56
|
+
void Init_sha3_n()
|
57
|
+
{
|
58
|
+
mSHA3 = rb_define_module("SHA3");
|
59
|
+
eSHA3Error = rb_define_class_under(mSHA3, "SHA3Error", rb_eStandardError);
|
60
|
+
|
61
|
+
Init_sha3_n_digest();
|
62
|
+
}
|
data/ext/sha3/sha3.h
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
/* Copyright (c) 2012 - 2013 Johanns Gregorian <io+sha3@jsani.com> */
|
2
|
+
|
3
|
+
#ifndef _SHA3_H_
|
4
|
+
#define _SHA3_H_
|
5
|
+
|
6
|
+
#include <ruby.h>
|
7
|
+
|
8
|
+
#include "KeccakHash.h"
|
9
|
+
#include "digest.h"
|
10
|
+
|
11
|
+
#ifdef __cplusplus
|
12
|
+
extern "C"
|
13
|
+
{
|
14
|
+
#endif
|
15
|
+
|
16
|
+
extern VALUE mSHA3;
|
17
|
+
extern VALUE eSHA3Error;
|
18
|
+
|
19
|
+
int get_hlen(VALUE);
|
20
|
+
void Init_sha3_n(void);
|
21
|
+
|
22
|
+
#ifdef __cplusplus
|
23
|
+
}
|
24
|
+
#endif
|
25
|
+
|
26
|
+
#endif
|