sha3 2.2.1 → 2.2.3
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/.rubocop.yml +66 -0
- data/ext/sha3/common.h +118 -0
- data/ext/sha3/cshake.c +32 -105
- data/ext/sha3/cshake.h +3 -3
- data/ext/sha3/digest.c +101 -79
- data/ext/sha3/kmac.c +34 -109
- data/ext/sha3/kmac.h +5 -2
- data/ext/sha3/sp800_185.c +110 -119
- data/ext/sha3/sp800_185.h +69 -22
- data/lib/constants.rb +1 -1
- data/sha3.gemspec +4 -4
- data.tar.gz.sig +0 -0
- metadata +4 -3
- metadata.gz.sig +2 -1
data/ext/sha3/digest.c
CHANGED
@@ -79,15 +79,16 @@ static ID _shake_128_id;
|
|
79
79
|
static ID _shake_256_id;
|
80
80
|
|
81
81
|
/* TypedData structure for sha3_digest_context_t */
|
82
|
-
const rb_data_type_t
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
82
|
+
const rb_data_type_t sha3_digest_data_type = {"SHA3::Digest",
|
83
|
+
{
|
84
|
+
NULL,
|
85
|
+
sha3_digest_free_context,
|
86
|
+
sha3_digest_context_size,
|
87
|
+
NULL,
|
88
|
+
},
|
89
|
+
NULL,
|
90
|
+
NULL,
|
91
|
+
RUBY_TYPED_FREE_IMMEDIATELY};
|
91
92
|
|
92
93
|
void Init_sha3_digest(void) {
|
93
94
|
rb_require("digest");
|
@@ -154,10 +155,14 @@ void Init_sha3_digest(void) {
|
|
154
155
|
|
155
156
|
// Static inline functions replacing macros
|
156
157
|
static inline void get_sha3_digest_context(VALUE obj, sha3_digest_context_t **context) {
|
157
|
-
TypedData_Get_Struct((obj), sha3_digest_context_t, &
|
158
|
+
TypedData_Get_Struct((obj), sha3_digest_context_t, &sha3_digest_data_type, (*context));
|
158
159
|
if (!(*context)) {
|
159
160
|
rb_raise(rb_eRuntimeError, "Digest data not initialized!");
|
160
161
|
}
|
162
|
+
|
163
|
+
if (!(*context)->state) {
|
164
|
+
rb_raise(rb_eRuntimeError, "Digest state not initialized!");
|
165
|
+
}
|
161
166
|
}
|
162
167
|
|
163
168
|
static inline void safe_get_sha3_digest_context(VALUE obj, sha3_digest_context_t **context) {
|
@@ -170,36 +175,36 @@ static inline void safe_get_sha3_digest_context(VALUE obj, sha3_digest_context_t
|
|
170
175
|
|
171
176
|
static inline int is_shake_algorithm(sha3_digest_algorithms alg) { return alg == SHAKE_128 || alg == SHAKE_256; }
|
172
177
|
|
173
|
-
int get_hashbit_length(VALUE obj, sha3_digest_algorithms *algorithm) {
|
174
|
-
if (TYPE(obj)
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
178
|
+
static int get_hashbit_length(VALUE obj, sha3_digest_algorithms *algorithm) {
|
179
|
+
if (TYPE(obj) != T_SYMBOL) {
|
180
|
+
rb_raise(_sha3_digest_error_class, "hash algorithm must be a symbol");
|
181
|
+
}
|
182
|
+
|
183
|
+
ID symid = SYM2ID(obj);
|
184
|
+
|
185
|
+
if (symid == _sha3_224_id) {
|
186
|
+
*algorithm = SHA3_224;
|
187
|
+
return 224;
|
188
|
+
} else if (symid == _sha3_256_id) {
|
189
|
+
*algorithm = SHA3_256;
|
190
|
+
return 256;
|
191
|
+
} else if (symid == _sha3_384_id) {
|
192
|
+
*algorithm = SHA3_384;
|
193
|
+
return 384;
|
194
|
+
} else if (symid == _sha3_512_id) {
|
195
|
+
*algorithm = SHA3_512;
|
196
|
+
return 512;
|
197
|
+
} else if (symid == _shake_128_id) {
|
198
|
+
*algorithm = SHAKE_128;
|
199
|
+
return 128;
|
200
|
+
} else if (symid == _shake_256_id) {
|
201
|
+
*algorithm = SHAKE_256;
|
202
|
+
return 256;
|
203
|
+
}
|
204
|
+
|
205
|
+
rb_raise(rb_eArgError,
|
206
|
+
"invalid hash algorithm symbol (should be: :sha3_224, "
|
207
|
+
":sha3_256, :sha3_384, :sha3_512, :shake_128, or :shake_256)");
|
203
208
|
|
204
209
|
return 0; // Never reached, but silences compiler warnings
|
205
210
|
}
|
@@ -208,9 +213,10 @@ static void sha3_digest_free_context(void *ptr) {
|
|
208
213
|
sha3_digest_context_t *context = (sha3_digest_context_t *)ptr;
|
209
214
|
if (context) {
|
210
215
|
if (context->state) {
|
211
|
-
|
216
|
+
ruby_xfree(context->state);
|
217
|
+
context->state = NULL;
|
212
218
|
}
|
213
|
-
|
219
|
+
ruby_xfree(context);
|
214
220
|
}
|
215
221
|
}
|
216
222
|
|
@@ -245,21 +251,22 @@ static HashReturn keccak_hash_initialize(sha3_digest_context_t *context) {
|
|
245
251
|
}
|
246
252
|
|
247
253
|
static VALUE rb_sha3_digest_alloc(VALUE klass) {
|
248
|
-
sha3_digest_context_t *context = (sha3_digest_context_t
|
254
|
+
sha3_digest_context_t *context = RB_ALLOC(sha3_digest_context_t);
|
249
255
|
if (!context) {
|
250
256
|
rb_raise(_sha3_digest_error_class, "failed to allocate object memory");
|
251
257
|
}
|
252
258
|
|
253
|
-
context->state = (Keccak_HashInstance
|
259
|
+
context->state = RB_ALLOC(Keccak_HashInstance);
|
254
260
|
if (!context->state) {
|
255
|
-
|
261
|
+
ruby_xfree(context);
|
256
262
|
rb_raise(_sha3_digest_error_class, "failed to allocate state memory");
|
257
263
|
}
|
264
|
+
memset(context->state, 0, sizeof(*context->state));
|
258
265
|
|
259
|
-
VALUE obj = TypedData_Wrap_Struct(klass, &sha3_digest_data_type_t, context);
|
260
266
|
context->hashbitlen = 0;
|
261
|
-
context->algorithm = SHA3_256;
|
267
|
+
context->algorithm = SHA3_256;
|
262
268
|
|
269
|
+
VALUE obj = TypedData_Wrap_Struct(klass, &sha3_digest_data_type, context);
|
263
270
|
return obj;
|
264
271
|
}
|
265
272
|
|
@@ -342,7 +349,13 @@ static VALUE rb_sha3_digest_update(VALUE self, VALUE data) {
|
|
342
349
|
rb_raise(_sha3_digest_error_class, "cannot update with NULL data");
|
343
350
|
}
|
344
351
|
|
345
|
-
|
352
|
+
// Prevent integer overflow and validate size
|
353
|
+
size_t data_len = RSTRING_LEN(data);
|
354
|
+
if (data_len > SIZE_MAX / 8) {
|
355
|
+
rb_raise(_sha3_digest_error_class, "data too large (exceeds maximum size)");
|
356
|
+
}
|
357
|
+
|
358
|
+
dlen = (data_len * 8);
|
346
359
|
|
347
360
|
if (Keccak_HashUpdate(context->state, (BitSequence *)RSTRING_PTR(data), dlen) != KECCAK_SUCCESS) {
|
348
361
|
rb_raise(_sha3_digest_error_class, "failed to update hash data");
|
@@ -374,6 +387,10 @@ static VALUE rb_sha3_digest_reset(VALUE self) {
|
|
374
387
|
}
|
375
388
|
|
376
389
|
static int compare_contexts(const sha3_digest_context_t *context1, const sha3_digest_context_t *context2) {
|
390
|
+
if (!context1 || !context2 || !context1->state || !context2->state) {
|
391
|
+
return 0;
|
392
|
+
}
|
393
|
+
|
377
394
|
// First check the hashbitlen and algorithm
|
378
395
|
if (context1->hashbitlen != context2->hashbitlen || context1->algorithm != context2->algorithm) {
|
379
396
|
return 0;
|
@@ -429,7 +446,11 @@ static VALUE rb_sha3_digest_copy(VALUE self, VALUE other) {
|
|
429
446
|
}
|
430
447
|
|
431
448
|
safe_get_sha3_digest_context(other, &other_context);
|
432
|
-
|
449
|
+
safe_get_sha3_digest_context(self, &context);
|
450
|
+
|
451
|
+
if (!context || !other_context) {
|
452
|
+
rb_raise(_sha3_digest_error_class, "invalid context for copy");
|
453
|
+
}
|
433
454
|
|
434
455
|
context->hashbitlen = other_context->hashbitlen;
|
435
456
|
context->algorithm = other_context->algorithm;
|
@@ -489,17 +510,17 @@ static VALUE rb_sha3_digest_name(VALUE self) {
|
|
489
510
|
|
490
511
|
switch (context->algorithm) {
|
491
512
|
case SHA3_224:
|
492
|
-
return
|
513
|
+
return rb_str_new_cstr("SHA3-224");
|
493
514
|
case SHA3_256:
|
494
|
-
return
|
515
|
+
return rb_str_new_cstr("SHA3-256");
|
495
516
|
case SHA3_384:
|
496
|
-
return
|
517
|
+
return rb_str_new_cstr("SHA3-384");
|
497
518
|
case SHA3_512:
|
498
|
-
return
|
519
|
+
return rb_str_new_cstr("SHA3-512");
|
499
520
|
case SHAKE_128:
|
500
|
-
return
|
521
|
+
return rb_str_new_cstr("SHAKE128");
|
501
522
|
case SHAKE_256:
|
502
|
-
return
|
523
|
+
return rb_str_new_cstr("SHAKE256");
|
503
524
|
default:
|
504
525
|
rb_raise(_sha3_digest_error_class, "unknown algorithm");
|
505
526
|
}
|
@@ -560,15 +581,19 @@ static VALUE rb_sha3_digest_finish(int argc, VALUE *argv, VALUE self) {
|
|
560
581
|
static VALUE rb_sha3_digest_squeeze(VALUE self, VALUE length) {
|
561
582
|
sha3_digest_context_t *context;
|
562
583
|
VALUE str, copy;
|
563
|
-
|
584
|
+
long output_bytes;
|
564
585
|
|
565
586
|
Check_Type(length, T_FIXNUM);
|
566
|
-
output_bytes =
|
587
|
+
output_bytes = NUM2LONG(length);
|
567
588
|
|
568
589
|
if (output_bytes <= 0) {
|
569
590
|
rb_raise(_sha3_digest_error_class, "output length must be positive");
|
570
591
|
}
|
571
592
|
|
593
|
+
if (output_bytes > (1L << 20)) { // Limit to 1MB output
|
594
|
+
rb_raise(_sha3_digest_error_class, "output length too large (max 1MB)");
|
595
|
+
}
|
596
|
+
|
572
597
|
get_sha3_digest_context(self, &context);
|
573
598
|
|
574
599
|
// Only SHAKE algorithms support arbitrary-length output
|
@@ -578,6 +603,9 @@ static VALUE rb_sha3_digest_squeeze(VALUE self, VALUE length) {
|
|
578
603
|
|
579
604
|
// Create a copy of the digest object to avoid modifying the original
|
580
605
|
copy = rb_obj_clone(self);
|
606
|
+
if (NIL_P(copy)) {
|
607
|
+
rb_raise(_sha3_digest_error_class, "failed to clone digest object");
|
608
|
+
}
|
581
609
|
|
582
610
|
// Get the sha3_digest_context_t struct from the copy
|
583
611
|
sha3_digest_context_t *context_copy;
|
@@ -615,7 +643,7 @@ static VALUE rb_sha3_digest_hex_squeeze(VALUE self, VALUE length) {
|
|
615
643
|
// Get the binary output using the existing squeeze function
|
616
644
|
VALUE bin_str = rb_sha3_digest_squeeze(self, length);
|
617
645
|
// Use Ruby's built-in unpack method to convert to hex
|
618
|
-
return rb_funcall(bin_str, rb_intern("unpack1"), 1,
|
646
|
+
return rb_funcall(bin_str, rb_intern("unpack1"), 1, rb_str_new_cstr("H*"));
|
619
647
|
}
|
620
648
|
|
621
649
|
static VALUE prepare_shake_output(VALUE self, int argc, VALUE *argv, int hex_output) {
|
@@ -800,32 +828,26 @@ static VALUE rb_sha3_digest_self_digest(VALUE klass, VALUE name, VALUE data) {
|
|
800
828
|
* To squeeze a different length, use #hex_squeeze instance method.
|
801
829
|
*/
|
802
830
|
static VALUE rb_sha3_digest_self_hexdigest(VALUE klass, VALUE name, VALUE data) {
|
803
|
-
VALUE
|
831
|
+
VALUE digest;
|
804
832
|
|
805
|
-
|
806
|
-
|
833
|
+
if (NIL_P(name) || NIL_P(data)) {
|
834
|
+
rb_raise(_sha3_digest_error_class, "algorithm name and data cannot be nil");
|
835
|
+
}
|
807
836
|
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
if (symid == _shake_128_id || symid == _shake_256_id) {
|
812
|
-
/* Create a new digest instance with the specified algorithm */
|
813
|
-
VALUE digest = rb_class_new_instance(1, &name, klass);
|
837
|
+
if (TYPE(name) != T_SYMBOL) {
|
838
|
+
rb_raise(_sha3_digest_error_class, "algorithm name must be a symbol");
|
839
|
+
}
|
814
840
|
|
815
|
-
|
816
|
-
rb_sha3_digest_update(digest, data);
|
841
|
+
StringValue(data);
|
817
842
|
|
818
|
-
|
819
|
-
|
843
|
+
ID symid = SYM2ID(name);
|
844
|
+
digest = rb_class_new_instance(1, &name, klass);
|
845
|
+
rb_sha3_digest_update(digest, data);
|
820
846
|
|
821
|
-
|
822
|
-
|
823
|
-
|
847
|
+
if (symid == _shake_128_id || symid == _shake_256_id) {
|
848
|
+
int output_length = (symid == _shake_128_id) ? 16 : 32;
|
849
|
+
return rb_sha3_digest_hex_squeeze(digest, INT2NUM(output_length));
|
824
850
|
}
|
825
851
|
|
826
|
-
|
827
|
-
args[0] = data;
|
828
|
-
args[1] = name;
|
829
|
-
|
830
|
-
return rb_call_super(2, args);
|
852
|
+
return rb_funcall(digest, rb_intern("hexdigest"), 0);
|
831
853
|
}
|
data/ext/sha3/kmac.c
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
#include "kmac.h"
|
2
2
|
|
3
|
+
#include "common.h"
|
3
4
|
#include "sha3.h"
|
4
5
|
#include "sp800_185.h"
|
5
6
|
|
@@ -42,7 +43,7 @@ static ID _kmac_128_id;
|
|
42
43
|
static ID _kmac_256_id;
|
43
44
|
|
44
45
|
/* TypedData structure for sha3_kmac_context_t */
|
45
|
-
const rb_data_type_t
|
46
|
+
const rb_data_type_t sha3_kmac_data_type = {
|
46
47
|
"SHA3::KMAC",
|
47
48
|
{
|
48
49
|
NULL, sha3_kmac_free_context, sha3_kmac_context_size, NULL, /* dcompact field */
|
@@ -55,7 +56,7 @@ const rb_data_type_t sha3_kmac_data_type_t = {
|
|
55
56
|
// Helper function to extract context from a Ruby object
|
56
57
|
void get_kmac_context(VALUE obj, sp800_185_context_t **context) {
|
57
58
|
sha3_kmac_context_t *kmac_ctx;
|
58
|
-
TypedData_Get_Struct(obj, sha3_kmac_context_t, &
|
59
|
+
TypedData_Get_Struct(obj, sha3_kmac_context_t, &sha3_kmac_data_type, kmac_ctx);
|
59
60
|
*context = &kmac_ctx->base;
|
60
61
|
}
|
61
62
|
|
@@ -70,18 +71,15 @@ void Init_sha3_kmac(void) {
|
|
70
71
|
/*
|
71
72
|
* Document-class: SHA3::KMAC
|
72
73
|
*
|
73
|
-
*
|
74
|
-
*
|
74
|
+
* KMAC (Keccak Message Authentication Code) is a MAC algorithm based on the Keccak permutation.
|
75
|
+
* It is defined in NIST SP800-185 and provides both fixed-length and XOF (arbitrary-length) output modes.
|
75
76
|
*/
|
76
77
|
_sha3_kmac_class = rb_define_class_under(_sha3_module, "KMAC", rb_cObject);
|
77
78
|
|
78
79
|
/*
|
79
|
-
* Document-class: SHA3::KMAC::
|
80
|
+
* Document-class: SHA3::KMAC::Error
|
80
81
|
*
|
81
82
|
* All KMAC methods raise this exception on error.
|
82
|
-
*
|
83
|
-
* It is a subclass of the StandardError class -- see the Ruby documentation
|
84
|
-
* for more information.
|
85
83
|
*/
|
86
84
|
_sha3_kmac_error_class = rb_define_class_under(_sha3_kmac_class, "Error", rb_eStandardError);
|
87
85
|
|
@@ -107,25 +105,11 @@ void Init_sha3_kmac(void) {
|
|
107
105
|
return;
|
108
106
|
}
|
109
107
|
|
110
|
-
|
111
|
-
|
112
|
-
static size_t sha3_kmac_context_size(const void *ptr) {
|
113
|
-
return sp800_185_context_size((const sp800_185_context_t *)ptr, sizeof(sha3_kmac_context_t));
|
114
|
-
}
|
115
|
-
|
116
|
-
static VALUE rb_sha3_kmac_alloc(VALUE klass) {
|
117
|
-
sha3_kmac_context_t *context =
|
118
|
-
(sha3_kmac_context_t *)sp800_185_alloc_context(sizeof(sha3_kmac_context_t), sizeof(KMAC_Instance));
|
119
|
-
|
120
|
-
if (!context) {
|
121
|
-
rb_raise(_sha3_kmac_error_class, "failed to allocate memory");
|
122
|
-
}
|
123
|
-
|
124
|
-
// Create the Ruby object with TypedData - this will automatically handle freeing
|
125
|
-
VALUE obj = TypedData_Wrap_Struct(klass, &sha3_kmac_data_type_t, context);
|
108
|
+
/* Use common memory management functions */
|
109
|
+
DEFINE_SP800_185_MEMORY_FUNCS(sha3_kmac, sha3_kmac_context_t)
|
126
110
|
|
127
|
-
|
128
|
-
|
111
|
+
/* Use common allocation function */
|
112
|
+
DEFINE_SP800_185_ALLOC(sha3_kmac, sha3_kmac_context_t, KMAC_Instance, _sha3_kmac_error_class)
|
129
113
|
|
130
114
|
/*
|
131
115
|
* :call-seq:
|
@@ -182,7 +166,7 @@ static VALUE rb_sha3_kmac_init(int argc, VALUE *argv, VALUE self) {
|
|
182
166
|
}
|
183
167
|
|
184
168
|
sha3_kmac_context_t *context;
|
185
|
-
TypedData_Get_Struct(self, sha3_kmac_context_t, &
|
169
|
+
TypedData_Get_Struct(self, sha3_kmac_context_t, &sha3_kmac_data_type, context);
|
186
170
|
|
187
171
|
// Store the output length in bits
|
188
172
|
context->base.output_length = NUM2ULONG(output_length) * 8;
|
@@ -190,21 +174,28 @@ static VALUE rb_sha3_kmac_init(int argc, VALUE *argv, VALUE self) {
|
|
190
174
|
|
191
175
|
// Find the appropriate function table based on the algorithm
|
192
176
|
ID sym_id = SYM2ID(algorithm);
|
177
|
+
sp800_185_algorithm_t alg_type;
|
178
|
+
|
193
179
|
if (sym_id == _kmac_128_id) {
|
194
|
-
|
180
|
+
alg_type = SP800_185_KMAC_128;
|
195
181
|
} else if (sym_id == _kmac_256_id) {
|
196
|
-
|
182
|
+
alg_type = SP800_185_KMAC_256;
|
197
183
|
} else {
|
198
184
|
rb_raise(rb_eArgError, "invalid algorithm: %s", rb_id2name(sym_id));
|
199
185
|
}
|
200
186
|
|
201
|
-
|
187
|
+
context->base.functions = sp800_185_get_algorithm(alg_type);
|
188
|
+
if (!context->base.functions) {
|
189
|
+
rb_raise(_sha3_kmac_error_class, "algorithm not available: %s", rb_id2name(sym_id));
|
190
|
+
}
|
191
|
+
|
192
|
+
// Initialize using the safe accessor function
|
202
193
|
size_t key_len = RSTRING_LEN(key) * 8;
|
203
194
|
size_t customization_len = RSTRING_LEN(customization) * 8;
|
204
195
|
|
205
|
-
int result = context->base.functions
|
206
|
-
|
207
|
-
|
196
|
+
int result = sp800_185_init_kmac(context->base.functions, context->base.state,
|
197
|
+
(const BitSequence *)RSTRING_PTR(key), key_len, context->base.output_length,
|
198
|
+
(const BitSequence *)RSTRING_PTR(customization), customization_len);
|
208
199
|
|
209
200
|
if (result != 0) {
|
210
201
|
rb_raise(_sha3_kmac_error_class, "failed to initialize %s", context->base.functions->name);
|
@@ -225,31 +216,7 @@ static VALUE rb_sha3_kmac_init(int argc, VALUE *argv, VALUE self) {
|
|
225
216
|
* = example
|
226
217
|
* new_kmac = kmac.dup
|
227
218
|
*/
|
228
|
-
|
229
|
-
sha3_kmac_context_t *context, *other_context;
|
230
|
-
|
231
|
-
rb_check_frozen(self);
|
232
|
-
if (self == other) {
|
233
|
-
return self;
|
234
|
-
}
|
235
|
-
|
236
|
-
if (!rb_obj_is_kind_of(other, _sha3_kmac_class)) {
|
237
|
-
rb_raise(rb_eTypeError, "wrong argument (%s)! (expected %s)", rb_obj_classname(other),
|
238
|
-
rb_class2name(_sha3_kmac_class));
|
239
|
-
}
|
240
|
-
|
241
|
-
TypedData_Get_Struct(other, sha3_kmac_context_t, &sha3_kmac_data_type_t, other_context);
|
242
|
-
TypedData_Get_Struct(self, sha3_kmac_context_t, &sha3_kmac_data_type_t, context);
|
243
|
-
|
244
|
-
// Copy the base context attributes
|
245
|
-
context->base.functions = other_context->base.functions;
|
246
|
-
context->base.output_length = other_context->base.output_length;
|
247
|
-
|
248
|
-
// Copy the algorithm-specific state
|
249
|
-
memcpy(context->base.state, other_context->base.state, context->base.functions->state_size);
|
250
|
-
|
251
|
-
return self;
|
252
|
-
}
|
219
|
+
DEFINE_SP800_185_COPY_METHOD(rb_sha3_kmac_copy, sha3_kmac_context_t, sha3_kmac_data_type, _sha3_kmac_class)
|
253
220
|
|
254
221
|
/*
|
255
222
|
* :call-seq:
|
@@ -264,13 +231,7 @@ static VALUE rb_sha3_kmac_copy(VALUE self, VALUE other) {
|
|
264
231
|
* kmac.update("more data")
|
265
232
|
* kmac << "more data" # alias for update
|
266
233
|
*/
|
267
|
-
|
268
|
-
sp800_185_context_t *context;
|
269
|
-
get_kmac_context(self, &context);
|
270
|
-
sp800_185_update(context, data);
|
271
|
-
|
272
|
-
return self;
|
273
|
-
}
|
234
|
+
DEFINE_SP800_185_SIMPLE_METHOD(rb_sha3_kmac_update, sp800_185_rb_update, get_kmac_context)
|
274
235
|
|
275
236
|
/*
|
276
237
|
* :call-seq:
|
@@ -281,12 +242,7 @@ static VALUE rb_sha3_kmac_update(VALUE self, VALUE data) {
|
|
281
242
|
* = example
|
282
243
|
* kmac.name #=> "KMAC128" or "KMAC256"
|
283
244
|
*/
|
284
|
-
|
285
|
-
sp800_185_context_t *context;
|
286
|
-
get_kmac_context(self, &context);
|
287
|
-
|
288
|
-
return rb_str_new2(sp800_185_name(context));
|
289
|
-
}
|
245
|
+
DEFINE_SP800_185_RETURN_METHOD(rb_sha3_kmac_name, sp800_185_rb_name, get_kmac_context)
|
290
246
|
|
291
247
|
/*
|
292
248
|
* :call-seq:
|
@@ -300,14 +256,7 @@ static VALUE rb_sha3_kmac_name(VALUE self) {
|
|
300
256
|
* = example
|
301
257
|
* kmac.finish
|
302
258
|
*/
|
303
|
-
|
304
|
-
sp800_185_context_t *context;
|
305
|
-
get_kmac_context(self, &context);
|
306
|
-
|
307
|
-
VALUE output = argc > 0 ? argv[0] : Qnil;
|
308
|
-
|
309
|
-
return sp800_185_finish(context, output);
|
310
|
-
}
|
259
|
+
DEFINE_SP800_185_VARARGS_METHOD(rb_sha3_kmac_finish, sp800_185_rb_finish, get_kmac_context)
|
311
260
|
|
312
261
|
/*
|
313
262
|
* :call-seq:
|
@@ -325,14 +274,7 @@ static VALUE rb_sha3_kmac_finish(int argc, VALUE *argv, VALUE self) {
|
|
325
274
|
* kmac.digest
|
326
275
|
* kmac.digest('final chunk')
|
327
276
|
*/
|
328
|
-
|
329
|
-
sp800_185_context_t *context;
|
330
|
-
get_kmac_context(self, &context);
|
331
|
-
|
332
|
-
VALUE data = argc > 0 ? argv[0] : Qnil;
|
333
|
-
|
334
|
-
return sp800_185_digest(context, data);
|
335
|
-
}
|
277
|
+
DEFINE_SP800_185_VARARGS_METHOD(rb_sha3_kmac_digest, sp800_185_rb_digest, get_kmac_context)
|
336
278
|
|
337
279
|
/*
|
338
280
|
* :call-seq:
|
@@ -350,14 +292,7 @@ static VALUE rb_sha3_kmac_digest(int argc, VALUE *argv, VALUE self) {
|
|
350
292
|
* kmac.hexdigest
|
351
293
|
* kmac.hexdigest('final chunk')
|
352
294
|
*/
|
353
|
-
|
354
|
-
sp800_185_context_t *context;
|
355
|
-
get_kmac_context(self, &context);
|
356
|
-
|
357
|
-
VALUE data = argc > 0 ? argv[0] : Qnil;
|
358
|
-
|
359
|
-
return sp800_185_hexdigest(context, data);
|
360
|
-
}
|
295
|
+
DEFINE_SP800_185_VARARGS_METHOD(rb_sha3_kmac_hexdigest, sp800_185_rb_hexdigest, get_kmac_context)
|
361
296
|
|
362
297
|
/*
|
363
298
|
* :call-seq:
|
@@ -373,12 +308,7 @@ static VALUE rb_sha3_kmac_hexdigest(int argc, VALUE *argv, VALUE self) {
|
|
373
308
|
* = example
|
374
309
|
* kmac.squeeze(128)
|
375
310
|
*/
|
376
|
-
|
377
|
-
sp800_185_context_t *context;
|
378
|
-
get_kmac_context(self, &context);
|
379
|
-
|
380
|
-
return sp800_185_squeeze(context, length);
|
381
|
-
}
|
311
|
+
DEFINE_SP800_185_VALUE_METHOD(rb_sha3_kmac_squeeze, sp800_185_rb_squeeze, get_kmac_context)
|
382
312
|
|
383
313
|
/*
|
384
314
|
* :call-seq:
|
@@ -394,12 +324,7 @@ static VALUE rb_sha3_kmac_squeeze(VALUE self, VALUE length) {
|
|
394
324
|
* = example
|
395
325
|
* kmac.hex_squeeze(128)
|
396
326
|
*/
|
397
|
-
|
398
|
-
sp800_185_context_t *context;
|
399
|
-
get_kmac_context(self, &context);
|
400
|
-
|
401
|
-
return sp800_185_hex_squeeze(context, length);
|
402
|
-
}
|
327
|
+
DEFINE_SP800_185_VALUE_METHOD(rb_sha3_kmac_hex_squeeze, sp800_185_rb_hex_squeeze, get_kmac_context)
|
403
328
|
|
404
329
|
/*
|
405
330
|
* :call-seq:
|
@@ -428,7 +353,7 @@ static VALUE rb_sha3_kmac_self_digest(int argc, VALUE *argv, VALUE klass) {
|
|
428
353
|
rb_scan_args(argc, argv, "41", &algorithm, &data, &output_length, &key, &customization);
|
429
354
|
|
430
355
|
Check_Type(output_length, T_FIXNUM);
|
431
|
-
if (!NIL_P(output_length) && output_length <=
|
356
|
+
if (!NIL_P(output_length) && NUM2INT(output_length) <= 0) {
|
432
357
|
rb_raise(rb_eArgError, "class method digest does not support XOF mode");
|
433
358
|
}
|
434
359
|
|
@@ -464,7 +389,7 @@ static VALUE rb_sha3_kmac_self_hexdigest(int argc, VALUE *argv, VALUE klass) {
|
|
464
389
|
rb_scan_args(argc, argv, "41", &algorithm, &data, &output_length, &key, &customization);
|
465
390
|
|
466
391
|
Check_Type(output_length, T_FIXNUM);
|
467
|
-
if (!NIL_P(output_length) && output_length <=
|
392
|
+
if (!NIL_P(output_length) && NUM2INT(output_length) <= 0) {
|
468
393
|
rb_raise(rb_eArgError, "class method hexdigest does not support XOF mode");
|
469
394
|
}
|
470
395
|
|
data/ext/sha3/kmac.h
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
// Copyright (c) 2012 - 2025 Johanns Gregorian <io+sha3@jsg.io>
|
2
|
+
|
1
3
|
#ifndef _SHA3_KMAC_H_
|
2
4
|
#define _SHA3_KMAC_H_
|
3
5
|
|
@@ -5,10 +7,11 @@
|
|
5
7
|
extern "C" {
|
6
8
|
#endif
|
7
9
|
|
8
|
-
|
10
|
+
/* Function prototypes */
|
11
|
+
void Init_sha3_kmac(void);
|
9
12
|
|
10
13
|
#ifdef __cplusplus
|
11
14
|
}
|
12
15
|
#endif
|
13
16
|
|
14
|
-
#endif
|
17
|
+
#endif /* _SHA3_KMAC_H_ */
|