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.
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 sha3_digest_data_type_t = {"SHA3::Digest",
83
- {
84
- NULL,
85
- sha3_digest_free_context,
86
- sha3_digest_context_size,
87
- },
88
- NULL,
89
- NULL,
90
- RUBY_TYPED_FREE_IMMEDIATELY};
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, &sha3_digest_data_type_t, (*context));
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) == T_SYMBOL) {
175
- ID symid = SYM2ID(obj);
176
-
177
- if (symid == _sha3_224_id) {
178
- *algorithm = SHA3_224;
179
- return 224;
180
- } else if (symid == _sha3_256_id) {
181
- *algorithm = SHA3_256;
182
- return 256;
183
- } else if (symid == _sha3_384_id) {
184
- *algorithm = SHA3_384;
185
- return 384;
186
- } else if (symid == _sha3_512_id) {
187
- *algorithm = SHA3_512;
188
- return 512;
189
- } else if (symid == _shake_128_id) {
190
- *algorithm = SHAKE_128;
191
- return 128;
192
- } else if (symid == _shake_256_id) {
193
- *algorithm = SHAKE_256;
194
- return 256;
195
- }
196
-
197
- rb_raise(rb_eArgError,
198
- "invalid hash algorithm symbol (should be: :sha3_224, "
199
- ":sha3_256, :sha3_384, :sha3_512, :shake_128, or :shake_256)");
200
- }
201
-
202
- rb_raise(_sha3_digest_error_class, "unknown type value");
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
- free(context->state);
216
+ ruby_xfree(context->state);
217
+ context->state = NULL;
212
218
  }
213
- free(context);
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 *)malloc(sizeof(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 *)calloc(1, sizeof(Keccak_HashInstance));
259
+ context->state = RB_ALLOC(Keccak_HashInstance);
254
260
  if (!context->state) {
255
- sha3_digest_free_context(context);
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; // Default algorithm
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
- dlen = (RSTRING_LEN(data) * 8);
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
- get_sha3_digest_context(self, &context);
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 rb_str_new2("SHA3-224");
513
+ return rb_str_new_cstr("SHA3-224");
493
514
  case SHA3_256:
494
- return rb_str_new2("SHA3-256");
515
+ return rb_str_new_cstr("SHA3-256");
495
516
  case SHA3_384:
496
- return rb_str_new2("SHA3-384");
517
+ return rb_str_new_cstr("SHA3-384");
497
518
  case SHA3_512:
498
- return rb_str_new2("SHA3-512");
519
+ return rb_str_new_cstr("SHA3-512");
499
520
  case SHAKE_128:
500
- return rb_str_new2("SHAKE128");
521
+ return rb_str_new_cstr("SHAKE128");
501
522
  case SHAKE_256:
502
- return rb_str_new2("SHAKE256");
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
- int output_bytes;
584
+ long output_bytes;
564
585
 
565
586
  Check_Type(length, T_FIXNUM);
566
- output_bytes = NUM2INT(length);
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, rb_str_new2("H*"));
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 args[2];
831
+ VALUE digest;
804
832
 
805
- // Need to add type checking for the data parameter
806
- StringValue(data);
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
- /* For SHAKE algorithms, we need to handle them differently */
809
- if (TYPE(name) == T_SYMBOL) {
810
- ID symid = SYM2ID(name);
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
- /* Update it with the data */
816
- rb_sha3_digest_update(digest, data);
841
+ StringValue(data);
817
842
 
818
- /* For SHAKE algorithms, use a default output length based on the security strength */
819
- int output_length = (symid == _shake_128_id) ? 16 : 32; /* 128/8 or 256/8 */
843
+ ID symid = SYM2ID(name);
844
+ digest = rb_class_new_instance(1, &name, klass);
845
+ rb_sha3_digest_update(digest, data);
820
846
 
821
- /* Return the hexadecimal representation of the squeezed output */
822
- return rb_sha3_digest_hex_squeeze(digest, INT2NUM(output_length));
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
- /* Call the superclass method with arguments in reverse order */
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 sha3_kmac_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, &sha3_kmac_data_type_t, kmac_ctx);
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
- * It is a subclass of the Digest::Class class, which provides a framework for
74
- * creating and manipulating hash digests.
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::KMACError
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
- static void sha3_kmac_free_context(void *ptr) { sp800_185_free_context((sp800_185_context_t *)ptr); }
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
- return obj;
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, &sha3_kmac_data_type_t, context);
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
- context->base.functions = &sp800_185_functions[SP800_185_KMAC_128];
180
+ alg_type = SP800_185_KMAC_128;
195
181
  } else if (sym_id == _kmac_256_id) {
196
- context->base.functions = &sp800_185_functions[SP800_185_KMAC_256];
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
- // Initialize the KMAC instance
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->kmac.init(context->base.state, (const BitSequence *)RSTRING_PTR(key), key_len,
206
- context->base.output_length,
207
- (const BitSequence *)RSTRING_PTR(customization), customization_len);
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
- static VALUE rb_sha3_kmac_copy(VALUE self, VALUE other) {
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
- static VALUE rb_sha3_kmac_update(VALUE self, VALUE data) {
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
- static VALUE rb_sha3_kmac_name(VALUE self) {
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
- static VALUE rb_sha3_kmac_finish(int argc, VALUE *argv, VALUE self) {
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
- static VALUE rb_sha3_kmac_digest(int argc, VALUE *argv, VALUE self) {
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
- static VALUE rb_sha3_kmac_hexdigest(int argc, VALUE *argv, VALUE self) {
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
- static VALUE rb_sha3_kmac_squeeze(VALUE self, VALUE length) {
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
- static VALUE rb_sha3_kmac_hex_squeeze(VALUE self, VALUE length) {
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 <= INT2FIX(0)) {
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 <= INT2FIX(0)) {
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
- extern void Init_sha3_kmac(void);
10
+ /* Function prototypes */
11
+ void Init_sha3_kmac(void);
9
12
 
10
13
  #ifdef __cplusplus
11
14
  }
12
15
  #endif
13
16
 
14
- #endif // _SHA3_KMAC_H_
17
+ #endif /* _SHA3_KMAC_H_ */