sha3 1.0.1 → 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 +5 -5
- data/.gitignore +232 -22
- data/.travis.yml +16 -15
- data/Gemfile +1 -1
- data/Gemfile.ci +3 -9
- data/README.md +10 -35
- data/Rakefile +12 -14
- data/ext/sha3/digest.c +149 -131
- data/ext/sha3/digest.h +36 -28
- data/ext/sha3/extconf.rb +1 -1
- data/ext/sha3/sha3.c +46 -30
- data/ext/sha3/sha3.h +8 -7
- data/lib/sha3/version.rb +2 -3
- data/sha3.gemspec +12 -14
- data/spec/generate_tests.rb +21 -20
- data/tests.sh +7 -7
- metadata +18 -20
data/ext/sha3/digest.c
CHANGED
@@ -21,232 +21,250 @@ VALUE eSHA3DigestError;
|
|
21
21
|
|
22
22
|
static void free_allox(MDX *mdx)
|
23
23
|
{
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
if (mdx)
|
25
|
+
{
|
26
|
+
if (mdx->state)
|
27
|
+
{
|
28
|
+
free(mdx->state);
|
29
|
+
}
|
30
|
+
|
31
|
+
free(mdx);
|
27
32
|
}
|
28
33
|
|
29
|
-
|
30
|
-
}
|
31
|
-
|
32
|
-
return;
|
34
|
+
return;
|
33
35
|
}
|
34
36
|
|
35
37
|
static VALUE c_digest_alloc(VALUE klass)
|
36
38
|
{
|
37
|
-
|
38
|
-
|
39
|
+
MDX *mdx;
|
40
|
+
VALUE obj;
|
39
41
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
42
|
+
mdx = (MDX *)malloc(sizeof(MDX));
|
43
|
+
if (!mdx)
|
44
|
+
{
|
45
|
+
rb_raise(eSHA3DigestError, "failed to allocate object memory");
|
46
|
+
}
|
44
47
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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
|
+
}
|
50
54
|
|
51
|
-
|
55
|
+
obj = Data_Wrap_Struct(klass, 0, free_allox, mdx);
|
52
56
|
|
53
|
-
|
54
|
-
|
57
|
+
memset(mdx->state, 0, sizeof(Keccak_HashInstance));
|
58
|
+
mdx->hashbitlen = 0;
|
55
59
|
|
56
|
-
|
60
|
+
return obj;
|
57
61
|
}
|
58
62
|
|
59
63
|
static VALUE c_digest_update(VALUE, VALUE);
|
60
64
|
|
61
65
|
HashReturn c_keccak_hash_initialize(MDX *mdx)
|
62
66
|
{
|
63
|
-
|
67
|
+
HashReturn r = FAIL;
|
64
68
|
|
65
|
-
|
69
|
+
switch (mdx->hashbitlen)
|
70
|
+
{
|
66
71
|
case 224:
|
67
|
-
|
68
|
-
|
72
|
+
r = Keccak_HashInitialize_SHA3_224(mdx->state);
|
73
|
+
break;
|
69
74
|
case 256:
|
70
|
-
|
71
|
-
|
75
|
+
r = Keccak_HashInitialize_SHA3_256(mdx->state);
|
76
|
+
break;
|
72
77
|
case 384:
|
73
|
-
|
74
|
-
|
78
|
+
r = Keccak_HashInitialize_SHA3_384(mdx->state);
|
79
|
+
break;
|
75
80
|
case 512:
|
76
|
-
|
77
|
-
|
81
|
+
r = Keccak_HashInitialize_SHA3_512(mdx->state);
|
82
|
+
break;
|
78
83
|
}
|
79
84
|
|
80
|
-
|
85
|
+
return r;
|
81
86
|
}
|
82
87
|
|
83
88
|
// SHA3::Digest.new(type, [data]) -> self
|
84
89
|
static VALUE c_digest_init(int argc, VALUE *argv, VALUE self)
|
85
90
|
{
|
86
|
-
|
87
|
-
|
91
|
+
MDX *mdx;
|
92
|
+
VALUE hlen, data;
|
88
93
|
|
89
|
-
|
90
|
-
|
94
|
+
rb_scan_args(argc, argv, "02", &hlen, &data);
|
95
|
+
GETMDX(self, mdx);
|
91
96
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
+
if (!NIL_P(hlen))
|
98
|
+
{
|
99
|
+
mdx->hashbitlen = get_hlen(hlen);
|
100
|
+
}
|
101
|
+
else
|
102
|
+
{
|
103
|
+
mdx->hashbitlen = 256;
|
104
|
+
}
|
97
105
|
|
98
|
-
|
99
|
-
|
100
|
-
|
106
|
+
if (c_keccak_hash_initialize(mdx) != SUCCESS)
|
107
|
+
{
|
108
|
+
rb_raise(eSHA3DigestError, "failed to initialize algorithm state");
|
109
|
+
}
|
101
110
|
|
102
|
-
|
103
|
-
|
104
|
-
|
111
|
+
if (!NIL_P(data))
|
112
|
+
{
|
113
|
+
return c_digest_update(self, data);
|
114
|
+
}
|
105
115
|
|
106
|
-
|
116
|
+
return self;
|
107
117
|
}
|
108
118
|
|
109
119
|
// SHA3::Digest.update(data) -> self
|
110
120
|
static VALUE c_digest_update(VALUE self, VALUE data)
|
111
121
|
{
|
112
|
-
|
113
|
-
|
122
|
+
MDX *mdx;
|
123
|
+
DataLength dlen;
|
114
124
|
|
115
|
-
|
116
|
-
|
125
|
+
StringValue(data);
|
126
|
+
GETMDX(self, mdx);
|
117
127
|
|
118
|
-
|
128
|
+
dlen = (RSTRING_LEN(data) * 8);
|
119
129
|
|
120
|
-
|
121
|
-
|
122
|
-
|
130
|
+
if (Keccak_HashUpdate(mdx->state, (BitSequence *)RSTRING_PTR(data), dlen) != SUCCESS)
|
131
|
+
{
|
132
|
+
rb_raise(eSHA3DigestError, "failed to update hash data");
|
133
|
+
}
|
123
134
|
|
124
|
-
|
135
|
+
return self;
|
125
136
|
}
|
126
137
|
|
127
138
|
// SHA3::Digest.reset() -> self
|
128
139
|
static VALUE c_digest_reset(VALUE self)
|
129
140
|
{
|
130
|
-
|
141
|
+
MDX *mdx;
|
131
142
|
|
132
|
-
|
143
|
+
GETMDX(self, mdx);
|
133
144
|
|
134
|
-
|
145
|
+
memset(mdx->state, 0, sizeof(Keccak_HashInstance));
|
135
146
|
|
136
|
-
|
137
|
-
|
138
|
-
|
147
|
+
if (c_keccak_hash_initialize(mdx) != SUCCESS)
|
148
|
+
{
|
149
|
+
rb_raise(eSHA3DigestError, "failed to reset internal state");
|
150
|
+
}
|
139
151
|
|
140
|
-
|
152
|
+
return self;
|
141
153
|
}
|
142
154
|
|
143
155
|
static int cmp_states(MDX *mdx1, MDX *mdx2)
|
144
156
|
{
|
145
157
|
return (
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
);
|
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));
|
154
165
|
}
|
155
166
|
|
156
167
|
// SHA3::Digest.copy(obj) -> self
|
157
168
|
static VALUE c_digest_copy(VALUE self, VALUE obj)
|
158
169
|
{
|
159
|
-
|
170
|
+
MDX *mdx1, *mdx2;
|
160
171
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
172
|
+
rb_check_frozen(self);
|
173
|
+
if (self == obj)
|
174
|
+
{
|
175
|
+
return self;
|
176
|
+
}
|
177
|
+
|
178
|
+
GETMDX(self, mdx1);
|
179
|
+
SAFEGETMDX(obj, mdx2);
|
165
180
|
|
166
|
-
|
167
|
-
|
181
|
+
memcpy(mdx1->state, mdx2->state, sizeof(Keccak_HashInstance));
|
182
|
+
mdx1->hashbitlen = mdx2->hashbitlen;
|
168
183
|
|
169
|
-
|
170
|
-
|
184
|
+
// Fetch the data again to make sure it was copied
|
185
|
+
GETMDX(self, mdx1);
|
186
|
+
SAFEGETMDX(obj, mdx2);
|
171
187
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
rb_raise(eSHA3DigestError, "failed to copy state");
|
177
|
-
}
|
188
|
+
if (!cmp_states(mdx1, mdx2))
|
189
|
+
{
|
190
|
+
rb_raise(eSHA3DigestError, "failed to copy state");
|
191
|
+
}
|
178
192
|
|
179
|
-
|
193
|
+
return self;
|
180
194
|
}
|
181
195
|
|
182
196
|
// SHA3::Digest.digest_length -> Integer
|
183
197
|
static VALUE c_digest_length(VALUE self)
|
184
198
|
{
|
185
|
-
|
186
|
-
|
199
|
+
MDX *mdx;
|
200
|
+
GETMDX(self, mdx);
|
187
201
|
|
188
|
-
|
202
|
+
return ULL2NUM(mdx->hashbitlen / 8);
|
189
203
|
}
|
190
204
|
|
191
205
|
// SHA3::Digest.block_length -> Integer
|
192
206
|
static VALUE c_digest_block_length(VALUE self)
|
193
207
|
{
|
194
|
-
|
195
|
-
|
208
|
+
MDX *mdx;
|
209
|
+
GETMDX(self, mdx);
|
196
210
|
|
197
|
-
|
211
|
+
return ULL2NUM(200 - (2 * (mdx->hashbitlen / 8)));
|
198
212
|
}
|
199
213
|
|
200
214
|
// SHA3::Digest.name -> String
|
201
215
|
static VALUE c_digest_name(VALUE self)
|
202
216
|
{
|
203
|
-
|
217
|
+
return rb_str_new2("SHA3");
|
204
218
|
}
|
205
219
|
|
206
220
|
// SHA3::Digest.finish() -> String
|
207
221
|
static VALUE c_digest_finish(int argc, VALUE *argv, VALUE self)
|
208
222
|
{
|
209
|
-
|
210
|
-
|
223
|
+
MDX *mdx;
|
224
|
+
VALUE str;
|
211
225
|
|
212
|
-
|
213
|
-
|
226
|
+
rb_scan_args(argc, argv, "01", &str);
|
227
|
+
GETMDX(self, mdx);
|
214
228
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
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
|
+
}
|
221
238
|
|
222
|
-
|
223
|
-
|
224
|
-
|
239
|
+
if (Keccak_HashFinal(mdx->state, (BitSequence *)RSTRING_PTR(str)) != SUCCESS)
|
240
|
+
{
|
241
|
+
rb_raise(eSHA3DigestError, "failed to finalize digest");
|
242
|
+
}
|
225
243
|
|
226
|
-
|
244
|
+
return str;
|
227
245
|
}
|
228
246
|
|
229
247
|
void Init_sha3_n_digest()
|
230
248
|
{
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
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;
|
252
270
|
}
|
data/ext/sha3/digest.h
CHANGED
@@ -3,37 +3,45 @@
|
|
3
3
|
#ifndef _DIGEST_H_
|
4
4
|
#define _DIGEST_H_
|
5
5
|
|
6
|
-
#ifdef
|
7
|
-
extern "C"
|
6
|
+
#ifdef __cplusplus
|
7
|
+
extern "C"
|
8
|
+
{
|
8
9
|
#endif
|
9
10
|
|
10
11
|
// From ruby/ext/openssl/ossl_digest.c
|
11
|
-
#define GETMDX(obj, mdx)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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
|
37
45
|
}
|
38
46
|
#endif
|
39
47
|
|