sha3 2.1.0 → 2.2.0
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.clang-format +4 -51
- data/.rubocop.yml +1 -1
- data/.vscode/launch.json +15 -0
- data/.vscode/settings.json +9 -0
- data/.vscode/tasks.json +29 -0
- data/CHANGELOG.md +15 -0
- data/README.md +103 -53
- data/ext/sha3/cshake.c +391 -0
- data/ext/sha3/cshake.h +17 -0
- data/ext/sha3/digest.c +90 -86
- data/ext/sha3/digest.h +2 -5
- data/ext/sha3/extconf.rb +11 -5
- data/ext/sha3/kmac.c +188 -218
- data/ext/sha3/kmac.h +3 -3
- data/ext/sha3/sha3.c +6 -2
- data/ext/sha3/sp800_185.c +311 -0
- data/ext/sha3/sp800_185.h +94 -0
- data/lib/constants.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +12 -5
- metadata.gz.sig +0 -0
data/ext/sha3/digest.c
CHANGED
@@ -22,32 +22,33 @@
|
|
22
22
|
typedef enum { SHA3_224 = 0, SHA3_256, SHA3_384, SHA3_512, SHAKE_128, SHAKE_256 } sha3_digest_algorithms;
|
23
23
|
|
24
24
|
typedef struct {
|
25
|
-
Keccak_HashInstance*
|
25
|
+
Keccak_HashInstance *state;
|
26
26
|
int hashbitlen;
|
27
27
|
sha3_digest_algorithms algorithm;
|
28
28
|
} sha3_digest_context_t;
|
29
29
|
|
30
|
-
typedef HashReturn (*keccak_init_func)(Keccak_HashInstance*);
|
30
|
+
typedef HashReturn (*keccak_init_func)(Keccak_HashInstance *);
|
31
31
|
|
32
32
|
/*** Function prototypes ***/
|
33
33
|
|
34
|
-
static int compare_contexts(const sha3_digest_context_t*, const sha3_digest_context_t*);
|
35
|
-
static inline void get_sha3_digest_context(VALUE, sha3_digest_context_t**);
|
36
|
-
static inline void safe_get_sha3_digest_context(VALUE, sha3_digest_context_t**);
|
34
|
+
static int compare_contexts(const sha3_digest_context_t *, const sha3_digest_context_t *);
|
35
|
+
static inline void get_sha3_digest_context(VALUE, sha3_digest_context_t **);
|
36
|
+
static inline void safe_get_sha3_digest_context(VALUE, sha3_digest_context_t **);
|
37
|
+
static inline int is_shake_algorithm(sha3_digest_algorithms);
|
37
38
|
|
38
|
-
static int get_hashbit_length(VALUE, sha3_digest_algorithms*);
|
39
|
-
static HashReturn keccak_hash_initialize(sha3_digest_context_t*);
|
39
|
+
static int get_hashbit_length(VALUE, sha3_digest_algorithms *);
|
40
|
+
static HashReturn keccak_hash_initialize(sha3_digest_context_t *);
|
40
41
|
|
41
|
-
static void sha3_digest_free_context(void*);
|
42
|
-
static size_t sha3_digest_context_size(const void*);
|
42
|
+
static void sha3_digest_free_context(void *);
|
43
|
+
static size_t sha3_digest_context_size(const void *);
|
43
44
|
|
44
45
|
/* Allocation and initialization */
|
45
46
|
static VALUE rb_sha3_digest_alloc(VALUE);
|
46
|
-
static VALUE rb_sha3_digest_init(int, VALUE*, VALUE);
|
47
|
+
static VALUE rb_sha3_digest_init(int, VALUE *, VALUE);
|
47
48
|
static VALUE rb_sha3_digest_copy(VALUE, VALUE);
|
48
49
|
|
49
50
|
/* Core digest operations */
|
50
|
-
static VALUE rb_sha3_digest_finish(int, VALUE*, VALUE);
|
51
|
+
static VALUE rb_sha3_digest_finish(int, VALUE *, VALUE);
|
51
52
|
static VALUE rb_sha3_digest_reset(VALUE);
|
52
53
|
static VALUE rb_sha3_digest_update(VALUE, VALUE);
|
53
54
|
|
@@ -57,8 +58,8 @@ static VALUE rb_sha3_digest_length(VALUE);
|
|
57
58
|
static VALUE rb_sha3_digest_name(VALUE);
|
58
59
|
|
59
60
|
/* Output methods */
|
60
|
-
static VALUE rb_sha3_digest_digest(int, VALUE*, VALUE);
|
61
|
-
static VALUE rb_sha3_digest_hexdigest(int, VALUE*, VALUE);
|
61
|
+
static VALUE rb_sha3_digest_digest(int, VALUE *, VALUE);
|
62
|
+
static VALUE rb_sha3_digest_hexdigest(int, VALUE *, VALUE);
|
62
63
|
static VALUE rb_sha3_digest_hex_squeeze(VALUE, VALUE);
|
63
64
|
static VALUE rb_sha3_digest_squeeze(VALUE, VALUE);
|
64
65
|
static VALUE rb_sha3_digest_self_digest(VALUE, VALUE, VALUE);
|
@@ -109,12 +110,12 @@ void Init_sha3_digest(void) {
|
|
109
110
|
*
|
110
111
|
* It is a subclass of the Digest::Class class, which provides a framework for
|
111
112
|
* creating and manipulating hash digest. Supported Algorithms are:
|
112
|
-
* - SHA3-224
|
113
|
-
* - SHA3-256
|
114
|
-
* - SHA3-384
|
115
|
-
* - SHA3-512
|
116
|
-
* - SHAKE128
|
117
|
-
* - SHAKE256
|
113
|
+
* - SHA3-224 (:sha3_224)
|
114
|
+
* - SHA3-256 (:sha3_256)
|
115
|
+
* - SHA3-384 (:sha3_384)
|
116
|
+
* - SHA3-512 (:sha3_512)
|
117
|
+
* - SHAKE128 (:shake_128)
|
118
|
+
* - SHAKE256 (:shake_256)
|
118
119
|
*/
|
119
120
|
_sha3_digest_class = rb_define_class_under(_sha3_module, "Digest", rb_path2class("Digest::Class"));
|
120
121
|
|
@@ -126,7 +127,7 @@ void Init_sha3_digest(void) {
|
|
126
127
|
* It is a subclass of the StandardError class -- see the Ruby documentation
|
127
128
|
* for more information.
|
128
129
|
*/
|
129
|
-
_sha3_digest_error_class = rb_define_class_under(_sha3_digest_class, "
|
130
|
+
_sha3_digest_error_class = rb_define_class_under(_sha3_digest_class, "Error", rb_eStandardError);
|
130
131
|
|
131
132
|
rb_define_alloc_func(_sha3_digest_class, rb_sha3_digest_alloc);
|
132
133
|
rb_define_method(_sha3_digest_class, "initialize", rb_sha3_digest_init, -1);
|
@@ -152,14 +153,14 @@ void Init_sha3_digest(void) {
|
|
152
153
|
}
|
153
154
|
|
154
155
|
// Static inline functions replacing macros
|
155
|
-
static inline void get_sha3_digest_context(VALUE obj, sha3_digest_context_t**
|
156
|
+
static inline void get_sha3_digest_context(VALUE obj, sha3_digest_context_t **context) {
|
156
157
|
TypedData_Get_Struct((obj), sha3_digest_context_t, &sha3_digest_data_type_t, (*context));
|
157
158
|
if (!(*context)) {
|
158
159
|
rb_raise(rb_eRuntimeError, "Digest data not initialized!");
|
159
160
|
}
|
160
161
|
}
|
161
162
|
|
162
|
-
static inline void safe_get_sha3_digest_context(VALUE obj, sha3_digest_context_t**
|
163
|
+
static inline void safe_get_sha3_digest_context(VALUE obj, sha3_digest_context_t **context) {
|
163
164
|
if (!rb_obj_is_kind_of(obj, _sha3_digest_class)) {
|
164
165
|
rb_raise(rb_eTypeError, "wrong argument (%s)! (expected %s)", rb_obj_classname(obj),
|
165
166
|
rb_class2name(_sha3_digest_class));
|
@@ -167,7 +168,9 @@ static inline void safe_get_sha3_digest_context(VALUE obj, sha3_digest_context_t
|
|
167
168
|
get_sha3_digest_context(obj, context);
|
168
169
|
}
|
169
170
|
|
170
|
-
int
|
171
|
+
static inline int is_shake_algorithm(sha3_digest_algorithms alg) { return alg == SHAKE_128 || alg == SHAKE_256; }
|
172
|
+
|
173
|
+
int get_hashbit_length(VALUE obj, sha3_digest_algorithms *algorithm) {
|
171
174
|
if (TYPE(obj) == T_SYMBOL) {
|
172
175
|
ID symid = SYM2ID(obj);
|
173
176
|
|
@@ -191,17 +194,18 @@ int get_hashbit_length(VALUE obj, sha3_digest_algorithms* algorithm) {
|
|
191
194
|
return 256;
|
192
195
|
}
|
193
196
|
|
194
|
-
rb_raise(
|
197
|
+
rb_raise(rb_eArgError,
|
195
198
|
"invalid hash algorithm symbol (should be: :sha3_224, "
|
196
199
|
":sha3_256, :sha3_384, :sha3_512, :shake_128, or :shake_256)");
|
197
200
|
}
|
198
201
|
|
199
202
|
rb_raise(_sha3_digest_error_class, "unknown type value");
|
203
|
+
|
200
204
|
return 0; // Never reached, but silences compiler warnings
|
201
205
|
}
|
202
206
|
|
203
|
-
static void sha3_digest_free_context(void*
|
204
|
-
sha3_digest_context_t*
|
207
|
+
static void sha3_digest_free_context(void *ptr) {
|
208
|
+
sha3_digest_context_t *context = (sha3_digest_context_t *)ptr;
|
205
209
|
if (context) {
|
206
210
|
if (context->state) {
|
207
211
|
free(context->state);
|
@@ -210,8 +214,8 @@ static void sha3_digest_free_context(void* ptr) {
|
|
210
214
|
}
|
211
215
|
}
|
212
216
|
|
213
|
-
static size_t sha3_digest_context_size(const void*
|
214
|
-
const sha3_digest_context_t*
|
217
|
+
static size_t sha3_digest_context_size(const void *ptr) {
|
218
|
+
const sha3_digest_context_t *context = (const sha3_digest_context_t *)ptr;
|
215
219
|
size_t size = sizeof(sha3_digest_context_t);
|
216
220
|
|
217
221
|
if (context && context->state) {
|
@@ -221,7 +225,7 @@ static size_t sha3_digest_context_size(const void* ptr) {
|
|
221
225
|
return size;
|
222
226
|
}
|
223
227
|
|
224
|
-
static HashReturn keccak_hash_initialize(sha3_digest_context_t*
|
228
|
+
static HashReturn keccak_hash_initialize(sha3_digest_context_t *context) {
|
225
229
|
switch (context->algorithm) {
|
226
230
|
case SHA3_224:
|
227
231
|
return Keccak_HashInitialize_SHA3_224(context->state);
|
@@ -241,12 +245,12 @@ static HashReturn keccak_hash_initialize(sha3_digest_context_t* context) {
|
|
241
245
|
}
|
242
246
|
|
243
247
|
static VALUE rb_sha3_digest_alloc(VALUE klass) {
|
244
|
-
sha3_digest_context_t*
|
248
|
+
sha3_digest_context_t *context = (sha3_digest_context_t *)malloc(sizeof(sha3_digest_context_t));
|
245
249
|
if (!context) {
|
246
250
|
rb_raise(_sha3_digest_error_class, "failed to allocate object memory");
|
247
251
|
}
|
248
252
|
|
249
|
-
context->state = (Keccak_HashInstance*)calloc(1, sizeof(Keccak_HashInstance));
|
253
|
+
context->state = (Keccak_HashInstance *)calloc(1, sizeof(Keccak_HashInstance));
|
250
254
|
if (!context->state) {
|
251
255
|
sha3_digest_free_context(context);
|
252
256
|
rb_raise(_sha3_digest_error_class, "failed to allocate state memory");
|
@@ -283,8 +287,8 @@ static VALUE rb_sha3_digest_alloc(VALUE klass) {
|
|
283
287
|
* SHA3::Digest.new(:sha3_256)
|
284
288
|
* SHA3::Digest.new(:shake_128, "initial data")
|
285
289
|
*/
|
286
|
-
static VALUE rb_sha3_digest_init(int argc, VALUE*
|
287
|
-
sha3_digest_context_t*
|
290
|
+
static VALUE rb_sha3_digest_init(int argc, VALUE *argv, VALUE self) {
|
291
|
+
sha3_digest_context_t *context;
|
288
292
|
VALUE hlen, data;
|
289
293
|
|
290
294
|
rb_scan_args(argc, argv, "02", &hlen, &data);
|
@@ -322,7 +326,7 @@ static VALUE rb_sha3_digest_init(int argc, VALUE* argv, VALUE self) {
|
|
322
326
|
* digest << "more data" # alias for update
|
323
327
|
*/
|
324
328
|
static VALUE rb_sha3_digest_update(VALUE self, VALUE data) {
|
325
|
-
sha3_digest_context_t*
|
329
|
+
sha3_digest_context_t *context;
|
326
330
|
BitLength dlen;
|
327
331
|
|
328
332
|
StringValue(data);
|
@@ -340,7 +344,7 @@ static VALUE rb_sha3_digest_update(VALUE self, VALUE data) {
|
|
340
344
|
|
341
345
|
dlen = (RSTRING_LEN(data) * 8);
|
342
346
|
|
343
|
-
if (Keccak_HashUpdate(context->state, (BitSequence*)RSTRING_PTR(data), dlen) != KECCAK_SUCCESS) {
|
347
|
+
if (Keccak_HashUpdate(context->state, (BitSequence *)RSTRING_PTR(data), dlen) != KECCAK_SUCCESS) {
|
344
348
|
rb_raise(_sha3_digest_error_class, "failed to update hash data");
|
345
349
|
}
|
346
350
|
|
@@ -357,7 +361,7 @@ static VALUE rb_sha3_digest_update(VALUE self, VALUE data) {
|
|
357
361
|
* digest.reset
|
358
362
|
*/
|
359
363
|
static VALUE rb_sha3_digest_reset(VALUE self) {
|
360
|
-
sha3_digest_context_t*
|
364
|
+
sha3_digest_context_t *context;
|
361
365
|
get_sha3_digest_context(self, &context);
|
362
366
|
|
363
367
|
memset(context->state, 0, sizeof(Keccak_HashInstance));
|
@@ -369,7 +373,7 @@ static VALUE rb_sha3_digest_reset(VALUE self) {
|
|
369
373
|
return self;
|
370
374
|
}
|
371
375
|
|
372
|
-
static int compare_contexts(const sha3_digest_context_t*
|
376
|
+
static int compare_contexts(const sha3_digest_context_t *context1, const sha3_digest_context_t *context2) {
|
373
377
|
// First check the hashbitlen and algorithm
|
374
378
|
if (context1->hashbitlen != context2->hashbitlen || context1->algorithm != context2->algorithm) {
|
375
379
|
return 0;
|
@@ -411,8 +415,8 @@ static int compare_contexts(const sha3_digest_context_t* context1, const sha3_di
|
|
411
415
|
* new_digest = digest.dup
|
412
416
|
*/
|
413
417
|
static VALUE rb_sha3_digest_copy(VALUE self, VALUE other) {
|
414
|
-
sha3_digest_context_t*
|
415
|
-
sha3_digest_context_t*
|
418
|
+
sha3_digest_context_t *context;
|
419
|
+
sha3_digest_context_t *other_context;
|
416
420
|
|
417
421
|
rb_check_frozen(self);
|
418
422
|
if (self == other) {
|
@@ -448,7 +452,7 @@ static VALUE rb_sha3_digest_copy(VALUE self, VALUE other) {
|
|
448
452
|
* digest.length #=> 32 for SHA3-256
|
449
453
|
*/
|
450
454
|
static VALUE rb_sha3_digest_length(VALUE self) {
|
451
|
-
sha3_digest_context_t*
|
455
|
+
sha3_digest_context_t *context;
|
452
456
|
get_sha3_digest_context(self, &context);
|
453
457
|
|
454
458
|
return ULL2NUM(context->hashbitlen / 8);
|
@@ -464,7 +468,7 @@ static VALUE rb_sha3_digest_length(VALUE self) {
|
|
464
468
|
* digest.block_length
|
465
469
|
*/
|
466
470
|
static VALUE rb_sha3_digest_block_length(VALUE self) {
|
467
|
-
sha3_digest_context_t*
|
471
|
+
sha3_digest_context_t *context;
|
468
472
|
get_sha3_digest_context(self, &context);
|
469
473
|
|
470
474
|
return ULL2NUM(200 - (2 * (context->hashbitlen / 8)));
|
@@ -480,7 +484,7 @@ static VALUE rb_sha3_digest_block_length(VALUE self) {
|
|
480
484
|
* digest.name #=> "SHA3-256"
|
481
485
|
*/
|
482
486
|
static VALUE rb_sha3_digest_name(VALUE self) {
|
483
|
-
sha3_digest_context_t*
|
487
|
+
sha3_digest_context_t *context;
|
484
488
|
get_sha3_digest_context(self, &context);
|
485
489
|
|
486
490
|
switch (context->algorithm) {
|
@@ -514,8 +518,8 @@ static VALUE rb_sha3_digest_name(VALUE self) {
|
|
514
518
|
* digest.finish
|
515
519
|
* digest.finish("final chunk")
|
516
520
|
*/
|
517
|
-
static VALUE rb_sha3_digest_finish(int argc, VALUE*
|
518
|
-
sha3_digest_context_t*
|
521
|
+
static VALUE rb_sha3_digest_finish(int argc, VALUE *argv, VALUE self) {
|
522
|
+
sha3_digest_context_t *context;
|
519
523
|
VALUE str;
|
520
524
|
int digest_bytes;
|
521
525
|
|
@@ -533,7 +537,7 @@ static VALUE rb_sha3_digest_finish(int argc, VALUE* argv, VALUE self) {
|
|
533
537
|
rb_str_resize(str, digest_bytes);
|
534
538
|
}
|
535
539
|
|
536
|
-
if (Keccak_HashFinal(context->state, (BitSequence*)RSTRING_PTR(str)) != KECCAK_SUCCESS) {
|
540
|
+
if (Keccak_HashFinal(context->state, (BitSequence *)RSTRING_PTR(str)) != KECCAK_SUCCESS) {
|
537
541
|
rb_raise(_sha3_digest_error_class, "failed to finalize digest");
|
538
542
|
}
|
539
543
|
|
@@ -554,7 +558,7 @@ static VALUE rb_sha3_digest_finish(int argc, VALUE* argv, VALUE self) {
|
|
554
558
|
* digest.squeeze(32) # Get 32 bytes of output
|
555
559
|
*/
|
556
560
|
static VALUE rb_sha3_digest_squeeze(VALUE self, VALUE length) {
|
557
|
-
sha3_digest_context_t*
|
561
|
+
sha3_digest_context_t *context;
|
558
562
|
VALUE str, copy;
|
559
563
|
int output_bytes;
|
560
564
|
|
@@ -568,7 +572,7 @@ static VALUE rb_sha3_digest_squeeze(VALUE self, VALUE length) {
|
|
568
572
|
get_sha3_digest_context(self, &context);
|
569
573
|
|
570
574
|
// Only SHAKE algorithms support arbitrary-length output
|
571
|
-
if (context->algorithm
|
575
|
+
if (!is_shake_algorithm(context->algorithm)) {
|
572
576
|
rb_raise(_sha3_digest_error_class, "squeeze is only supported for SHAKE algorithms");
|
573
577
|
}
|
574
578
|
|
@@ -576,7 +580,7 @@ static VALUE rb_sha3_digest_squeeze(VALUE self, VALUE length) {
|
|
576
580
|
copy = rb_obj_clone(self);
|
577
581
|
|
578
582
|
// Get the sha3_digest_context_t struct from the copy
|
579
|
-
sha3_digest_context_t*
|
583
|
+
sha3_digest_context_t *context_copy;
|
580
584
|
get_sha3_digest_context(copy, &context_copy);
|
581
585
|
|
582
586
|
str = rb_str_new(0, output_bytes);
|
@@ -587,7 +591,7 @@ static VALUE rb_sha3_digest_squeeze(VALUE self, VALUE length) {
|
|
587
591
|
}
|
588
592
|
|
589
593
|
// Then squeeze out the desired number of bytes
|
590
|
-
if (Keccak_HashSqueeze(context_copy->state, (BitSequence*)RSTRING_PTR(str), output_bytes * 8) != KECCAK_SUCCESS) {
|
594
|
+
if (Keccak_HashSqueeze(context_copy->state, (BitSequence *)RSTRING_PTR(str), output_bytes * 8) != KECCAK_SUCCESS) {
|
591
595
|
rb_raise(_sha3_digest_error_class, "failed to squeeze output");
|
592
596
|
}
|
593
597
|
|
@@ -614,6 +618,26 @@ static VALUE rb_sha3_digest_hex_squeeze(VALUE self, VALUE length) {
|
|
614
618
|
return rb_funcall(bin_str, rb_intern("unpack1"), 1, rb_str_new2("H*"));
|
615
619
|
}
|
616
620
|
|
621
|
+
static VALUE prepare_shake_output(VALUE self, int argc, VALUE *argv, int hex_output) {
|
622
|
+
sha3_digest_context_t *context;
|
623
|
+
VALUE length, data;
|
624
|
+
|
625
|
+
get_sha3_digest_context(self, &context);
|
626
|
+
rb_scan_args(argc, argv, "02", &length, &data);
|
627
|
+
|
628
|
+
if (NIL_P(length)) {
|
629
|
+
rb_raise(_sha3_digest_error_class, "output length must be specified for SHAKE algorithms");
|
630
|
+
}
|
631
|
+
|
632
|
+
Check_Type(length, T_FIXNUM);
|
633
|
+
|
634
|
+
if (!NIL_P(data)) {
|
635
|
+
rb_sha3_digest_update(self, data);
|
636
|
+
}
|
637
|
+
|
638
|
+
return hex_output ? rb_sha3_digest_hex_squeeze(self, length) : rb_sha3_digest_squeeze(self, length);
|
639
|
+
}
|
640
|
+
|
617
641
|
/*
|
618
642
|
* :call-seq:
|
619
643
|
* digest() -> string
|
@@ -636,31 +660,15 @@ static VALUE rb_sha3_digest_hex_squeeze(VALUE self, VALUE length) {
|
|
636
660
|
* digest.digest(12) # For SHAKE algorithms
|
637
661
|
* digest.digest(12, 'compute me') # For SHAKE algorithms
|
638
662
|
*/
|
639
|
-
static VALUE rb_sha3_digest_digest(int argc, VALUE*
|
640
|
-
sha3_digest_context_t*
|
663
|
+
static VALUE rb_sha3_digest_digest(int argc, VALUE *argv, VALUE self) {
|
664
|
+
sha3_digest_context_t *context;
|
641
665
|
get_sha3_digest_context(self, &context);
|
642
666
|
|
643
667
|
if (context->algorithm != SHAKE_128 && context->algorithm != SHAKE_256) {
|
644
668
|
return rb_call_super(argc, argv);
|
645
669
|
}
|
646
670
|
|
647
|
-
|
648
|
-
rb_scan_args(argc, argv, "02", &length, &data);
|
649
|
-
|
650
|
-
// For SHAKE algorithms
|
651
|
-
if (NIL_P(length)) {
|
652
|
-
rb_raise(_sha3_digest_error_class, "output length must be specified for SHAKE algorithms");
|
653
|
-
}
|
654
|
-
|
655
|
-
// Add type checking for length
|
656
|
-
Check_Type(length, T_FIXNUM);
|
657
|
-
|
658
|
-
// If data is provided, update the state before squeezing
|
659
|
-
if (!NIL_P(data)) {
|
660
|
-
rb_sha3_digest_update(self, data);
|
661
|
-
}
|
662
|
-
|
663
|
-
return rb_sha3_digest_squeeze(self, length);
|
671
|
+
return prepare_shake_output(self, argc, argv, 0);
|
664
672
|
}
|
665
673
|
|
666
674
|
/*
|
@@ -685,30 +693,15 @@ static VALUE rb_sha3_digest_digest(int argc, VALUE* argv, VALUE self) {
|
|
685
693
|
* digest.hexdigest(12) # For SHAKE algorithms
|
686
694
|
* digest.hexdigest(12, 'compute me') # For SHAKE algorithms
|
687
695
|
*/
|
688
|
-
static VALUE rb_sha3_digest_hexdigest(int argc, VALUE*
|
689
|
-
sha3_digest_context_t*
|
696
|
+
static VALUE rb_sha3_digest_hexdigest(int argc, VALUE *argv, VALUE self) {
|
697
|
+
sha3_digest_context_t *context;
|
690
698
|
get_sha3_digest_context(self, &context);
|
691
699
|
|
692
700
|
if (context->algorithm != SHAKE_128 && context->algorithm != SHAKE_256) {
|
693
701
|
return rb_call_super(argc, argv);
|
694
702
|
}
|
695
703
|
|
696
|
-
|
697
|
-
rb_scan_args(argc, argv, "02", &length, &data);
|
698
|
-
|
699
|
-
if (NIL_P(length)) {
|
700
|
-
rb_raise(_sha3_digest_error_class, "output length must be specified for SHAKE algorithms");
|
701
|
-
}
|
702
|
-
|
703
|
-
// Add type checking for length
|
704
|
-
Check_Type(length, T_FIXNUM);
|
705
|
-
|
706
|
-
// If data is provided, update the state before squeezing
|
707
|
-
if (!NIL_P(data)) {
|
708
|
-
rb_sha3_digest_update(self, data);
|
709
|
-
}
|
710
|
-
|
711
|
-
return rb_sha3_digest_hex_squeeze(self, length);
|
704
|
+
return prepare_shake_output(self, argc, argv, 1);
|
712
705
|
}
|
713
706
|
|
714
707
|
/*
|
@@ -738,6 +731,17 @@ static VALUE rb_sha3_digest_hexdigest(int argc, VALUE* argv, VALUE self) {
|
|
738
731
|
* To squeeze a different length, use #squeeze instance method.
|
739
732
|
*/
|
740
733
|
static VALUE rb_sha3_digest_self_digest(VALUE klass, VALUE name, VALUE data) {
|
734
|
+
// Add null checks
|
735
|
+
if (NIL_P(name) || NIL_P(data)) {
|
736
|
+
rb_raise(_sha3_digest_error_class, "algorithm name and data cannot be nil");
|
737
|
+
}
|
738
|
+
|
739
|
+
// Add type validation for name
|
740
|
+
if (TYPE(name) != T_SYMBOL) {
|
741
|
+
rb_raise(_sha3_digest_error_class, "algorithm name must be a symbol");
|
742
|
+
}
|
743
|
+
|
744
|
+
// Existing code...
|
741
745
|
VALUE args[2];
|
742
746
|
|
743
747
|
// Need to add type checking for the data parameter
|
data/ext/sha3/digest.h
CHANGED
data/ext/sha3/extconf.rb
CHANGED
@@ -12,6 +12,9 @@ dir_config(extension_name)
|
|
12
12
|
# Set compiler flags
|
13
13
|
$CFLAGS << ' -fomit-frame-pointer -O3 -g0 -fms-extensions'
|
14
14
|
|
15
|
+
# Add vectorization flags for better performance on supported platforms
|
16
|
+
$CFLAGS << ' -ftree-vectorize' if RUBY_PLATFORM =~ /x86_64|amd64|arm64/
|
17
|
+
|
15
18
|
# Add architecture-specific optimizations if enabled
|
16
19
|
$CFLAGS << ' -march=native' if enable_config('march-tune-native', false)
|
17
20
|
|
@@ -21,9 +24,6 @@ $CFLAGS << ' -D_FORTIFY_SOURCE=2 -fstack-protector-strong'
|
|
21
24
|
# Add warning flags to catch potential issues
|
22
25
|
$CFLAGS << ' -Wall -Wextra -Wformat -Wformat-security'
|
23
26
|
|
24
|
-
# Add vectorization flags for better performance on supported platforms
|
25
|
-
$CFLAGS << ' -ftree-vectorize' if RUBY_PLATFORM =~ /x86_64|amd64|arm64/
|
26
|
-
|
27
27
|
# Find all relevant subdirectories and filter appropriately
|
28
28
|
vpath_dirs = Dir.glob("#{$srcdir}/lib/**/*")
|
29
29
|
.select { |path| File.directory?(path) }
|
@@ -42,8 +42,14 @@ $INCFLAGS << vpath_dirs_processed
|
|
42
42
|
.map { |dir| " -I$(srcdir)#{dir}" }
|
43
43
|
.join
|
44
44
|
|
45
|
-
#
|
46
|
-
$srcs = [
|
45
|
+
# Define source files
|
46
|
+
$srcs = %w[
|
47
|
+
cshake.c
|
48
|
+
digest.c
|
49
|
+
kmac.c
|
50
|
+
sha3.c
|
51
|
+
sp800_185.c
|
52
|
+
]
|
47
53
|
|
48
54
|
# Find and add all .c files from the filtered directories
|
49
55
|
$srcs += vpath_dirs
|