sha3 2.2.2 → 2.2.4

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/sp800_185.c CHANGED
@@ -22,38 +22,46 @@ static int kmac256_init_wrapper(void *state, void *params) {
22
22
  }
23
23
 
24
24
  /*** Function table for SP800-185 algorithms ***/
25
- sp800_185_function_table_t sp800_185_functions[] = {{.algorithm = SP800_185_CSHAKE_128,
26
- .name = "CSHAKE128",
27
- .state_size = sizeof(cSHAKE_Instance),
28
- .is_keyed = false,
29
- .init = cshake128_init_wrapper,
30
- .update = (sp800_185_update_fn)cSHAKE128_Update,
31
- .final = (sp800_185_final_fn)cSHAKE128_Final,
32
- .squeeze = (sp800_185_squeeze_fn)cSHAKE128_Squeeze},
33
- {.algorithm = SP800_185_CSHAKE_256,
34
- .name = "CSHAKE256",
35
- .state_size = sizeof(cSHAKE_Instance),
36
- .is_keyed = false,
37
- .init = cshake256_init_wrapper,
38
- .update = (sp800_185_update_fn)cSHAKE256_Update,
39
- .final = (sp800_185_final_fn)cSHAKE256_Final,
40
- .squeeze = (sp800_185_squeeze_fn)cSHAKE256_Squeeze},
41
- {.algorithm = SP800_185_KMAC_128,
42
- .name = "KMAC128",
43
- .state_size = sizeof(KMAC_Instance),
44
- .is_keyed = true,
45
- .init = kmac128_init_wrapper,
46
- .update = (sp800_185_update_fn)KMAC128_Update,
47
- .final = (sp800_185_final_fn)KMAC128_Final,
48
- .squeeze = (sp800_185_squeeze_fn)KMAC128_Squeeze},
49
- {.algorithm = SP800_185_KMAC_256,
50
- .name = "KMAC256",
51
- .state_size = sizeof(KMAC_Instance),
52
- .is_keyed = true,
53
- .init = kmac256_init_wrapper,
54
- .update = (sp800_185_update_fn)KMAC256_Update,
55
- .final = (sp800_185_final_fn)KMAC256_Final,
56
- .squeeze = (sp800_185_squeeze_fn)KMAC256_Squeeze}};
25
+ sp800_185_function_table_t sp800_185_functions[] = {{
26
+ .algorithm = SP800_185_CSHAKE_128,
27
+ .name = "CSHAKE128",
28
+ .state_size = sizeof(cSHAKE_Instance),
29
+ .is_keyed = false,
30
+ .init = cshake128_init_wrapper,
31
+ .update = (sp800_185_update_fn)cSHAKE128_Update,
32
+ .final = (sp800_185_final_fn)cSHAKE128_Final,
33
+ .squeeze = (sp800_185_squeeze_fn)cSHAKE128_Squeeze,
34
+ },
35
+ {
36
+ .algorithm = SP800_185_CSHAKE_256,
37
+ .name = "CSHAKE256",
38
+ .state_size = sizeof(cSHAKE_Instance),
39
+ .is_keyed = false,
40
+ .init = cshake256_init_wrapper,
41
+ .update = (sp800_185_update_fn)cSHAKE256_Update,
42
+ .final = (sp800_185_final_fn)cSHAKE256_Final,
43
+ .squeeze = (sp800_185_squeeze_fn)cSHAKE256_Squeeze,
44
+ },
45
+ {
46
+ .algorithm = SP800_185_KMAC_128,
47
+ .name = "KMAC128",
48
+ .state_size = sizeof(KMAC_Instance),
49
+ .is_keyed = true,
50
+ .init = kmac128_init_wrapper,
51
+ .update = (sp800_185_update_fn)KMAC128_Update,
52
+ .final = (sp800_185_final_fn)KMAC128_Final,
53
+ .squeeze = (sp800_185_squeeze_fn)KMAC128_Squeeze,
54
+ },
55
+ {
56
+ .algorithm = SP800_185_KMAC_256,
57
+ .name = "KMAC256",
58
+ .state_size = sizeof(KMAC_Instance),
59
+ .is_keyed = true,
60
+ .init = kmac256_init_wrapper,
61
+ .update = (sp800_185_update_fn)KMAC256_Update,
62
+ .final = (sp800_185_final_fn)KMAC256_Final,
63
+ .squeeze = (sp800_185_squeeze_fn)KMAC256_Squeeze,
64
+ }};
57
65
 
58
66
  /* Algorithm lookup functions */
59
67
  const sp800_185_function_table_t *sp800_185_get_algorithm(sp800_185_algorithm_t algorithm) {
@@ -74,12 +82,12 @@ const sp800_185_function_table_t *sp800_185_get_algorithm_by_name(const char *na
74
82
 
75
83
  // Generic context allocation function
76
84
  sp800_185_context_t *sp800_185_alloc_context(size_t context_size, size_t state_size) {
77
- sp800_185_context_t *context = (sp800_185_context_t *)malloc(context_size);
85
+ sp800_185_context_t *context = (sp800_185_context_t *)ruby_xmalloc(context_size);
78
86
  if (!context) return NULL;
79
87
 
80
- context->state = calloc(1, state_size);
88
+ context->state = ruby_xcalloc(1, state_size);
81
89
  if (!context->state) {
82
- free(context);
90
+ ruby_xfree(context);
83
91
  return NULL;
84
92
  }
85
93
 
@@ -92,9 +100,9 @@ sp800_185_context_t *sp800_185_alloc_context(size_t context_size, size_t state_s
92
100
  void sp800_185_free_context(sp800_185_context_t *context) {
93
101
  if (context) {
94
102
  if (context->state) {
95
- free(context->state);
103
+ ruby_xfree(context->state);
96
104
  }
97
- free(context);
105
+ ruby_xfree(context);
98
106
  }
99
107
  }
100
108
 
@@ -112,7 +120,7 @@ void *sp800_185_copy_state(sp800_185_context_t *context) {
112
120
  if (context->functions->state_size <= 0) {
113
121
  rb_raise(context->error_class, "invalid state size");
114
122
  }
115
- void *state_copy = malloc(context->functions->state_size);
123
+ void *state_copy = ruby_xmalloc(context->functions->state_size);
116
124
 
117
125
  if (!state_copy) {
118
126
  rb_raise(rb_eNoMemError, "failed to allocate memory for state copy");
@@ -125,6 +133,12 @@ void *sp800_185_copy_state(sp800_185_context_t *context) {
125
133
 
126
134
  VALUE sp800_185_update(sp800_185_context_t *context, VALUE data) {
127
135
  StringValue(data);
136
+
137
+ // Check for NULL data pointer
138
+ if (RSTRING_PTR(data) == NULL && RSTRING_LEN(data) > 0) {
139
+ rb_raise(context->error_class, "cannot update with NULL data");
140
+ }
141
+
128
142
  size_t data_len = (RSTRING_LEN(data) * 8);
129
143
 
130
144
  if (data_len == 0) {
@@ -172,7 +186,7 @@ VALUE sp800_185_digest(sp800_185_context_t *context, VALUE data) {
172
186
  }
173
187
 
174
188
  // Create a copy of the state for processing
175
- void *state_copy = malloc(context->functions->state_size);
189
+ void *state_copy = ruby_xmalloc(context->functions->state_size);
176
190
  if (!state_copy) {
177
191
  rb_raise(rb_eNoMemError, "failed to allocate memory for state copy");
178
192
  }
@@ -190,7 +204,7 @@ VALUE sp800_185_digest(sp800_185_context_t *context, VALUE data) {
190
204
  result = context->functions->update(state_copy, (const BitSequence *)RSTRING_PTR(data), data_len);
191
205
 
192
206
  if (result != 0) {
193
- free(state_copy);
207
+ ruby_xfree(state_copy);
194
208
  rb_raise(context->error_class, "failed to update %s state", context->functions->name);
195
209
  }
196
210
  }
@@ -201,7 +215,7 @@ VALUE sp800_185_digest(sp800_185_context_t *context, VALUE data) {
201
215
 
202
216
  result = context->functions->final(state_copy, (BitSequence *)RSTRING_PTR(output));
203
217
 
204
- free(state_copy);
218
+ ruby_xfree(state_copy);
205
219
 
206
220
  if (result != 0) {
207
221
  rb_raise(context->error_class, "failed to finalize %s state", context->functions->name);
@@ -220,18 +234,23 @@ VALUE sp800_185_squeeze(sp800_185_context_t *context, VALUE length) {
220
234
  rb_raise(context->error_class, "use digest methods for fixed-length output");
221
235
  }
222
236
 
223
- size_t output_byte_len;
237
+ long output_byte_len;
224
238
  VALUE str;
225
239
 
226
240
  Check_Type(length, T_FIXNUM);
227
- output_byte_len = NUM2ULONG(length);
241
+ output_byte_len = NUM2LONG(length);
228
242
 
229
243
  if (output_byte_len <= 0) {
230
- rb_raise(context->error_class, "output length must be specified");
244
+ rb_raise(context->error_class, "output length must be positive");
245
+ }
246
+
247
+ // Limit output to 1MB for safety
248
+ if (output_byte_len > (1L << 20)) {
249
+ rb_raise(context->error_class, "output length too large (max 1MB)");
231
250
  }
232
251
 
233
252
  // Create a copy of the state for processing
234
- void *state_copy = malloc(context->functions->state_size);
253
+ void *state_copy = ruby_xmalloc(context->functions->state_size);
235
254
  if (!state_copy) {
236
255
  rb_raise(rb_eNoMemError, "failed to allocate memory for state copy");
237
256
  }
@@ -245,7 +264,7 @@ VALUE sp800_185_squeeze(sp800_185_context_t *context, VALUE length) {
245
264
  result = context->functions->final(state_copy, (BitSequence *)RSTRING_PTR(dummy_output));
246
265
 
247
266
  if (result != 0) {
248
- free(state_copy);
267
+ ruby_xfree(state_copy);
249
268
  rb_raise(context->error_class, "failed to finalize %s state", context->functions->name);
250
269
  }
251
270
 
@@ -255,7 +274,7 @@ VALUE sp800_185_squeeze(sp800_185_context_t *context, VALUE length) {
255
274
  // Use the function table to call the appropriate squeeze function
256
275
  result = context->functions->squeeze(state_copy, (BitSequence *)RSTRING_PTR(str), output_byte_len * 8);
257
276
 
258
- free(state_copy);
277
+ ruby_xfree(state_copy);
259
278
 
260
279
  if (result != 0) {
261
280
  rb_raise(context->error_class, "failed to squeeze %s", context->functions->name);
@@ -268,3 +287,24 @@ VALUE sp800_185_hex_squeeze(sp800_185_context_t *context, VALUE length) {
268
287
  VALUE binary_result = sp800_185_squeeze(context, length);
269
288
  return rb_funcall(binary_result, rb_intern("unpack1"), 1, rb_str_new2("H*"));
270
289
  }
290
+
291
+ /* Ruby wrapper functions for common method patterns */
292
+
293
+ VALUE sp800_185_rb_update(sp800_185_context_t *context, VALUE data) {
294
+ sp800_185_update(context, data);
295
+ return Qnil; // Caller will return self
296
+ }
297
+
298
+ VALUE sp800_185_rb_name(sp800_185_context_t *context) { return rb_str_new2(sp800_185_name(context)); }
299
+
300
+ VALUE sp800_185_rb_finish(sp800_185_context_t *context, VALUE output) { return sp800_185_finish(context, output); }
301
+
302
+ VALUE sp800_185_rb_digest(sp800_185_context_t *context, VALUE data) { return sp800_185_digest(context, data); }
303
+
304
+ VALUE sp800_185_rb_hexdigest(sp800_185_context_t *context, VALUE data) { return sp800_185_hexdigest(context, data); }
305
+
306
+ VALUE sp800_185_rb_squeeze(sp800_185_context_t *context, VALUE length) { return sp800_185_squeeze(context, length); }
307
+
308
+ VALUE sp800_185_rb_hex_squeeze(sp800_185_context_t *context, VALUE length) {
309
+ return sp800_185_hex_squeeze(context, length);
310
+ }
data/lib/constants.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SHA3
4
- VERSION = '2.2.2'
4
+ VERSION = '2.2.4'
5
5
  end
data/sha3.gemspec CHANGED
@@ -9,26 +9,26 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ['Johanns Gregorian']
10
10
  spec.email = ['io+sha3@jsg.io']
11
11
 
12
- spec.description = <<~EOF
12
+ spec.description = <<~DESC
13
13
  A high-performance native binding to the SHA3 (FIPS 202) cryptographic hashing algorithms, based on the XKCP - eXtended Keccak Code Package.
14
14
  This gem provides support for the standard SHA-3 fixed-length functions (224, 256, 384, and 512 bits),
15
15
  as well as the SHAKE128/SHAKE256 extendable-output functions (XOFs), cSHAKE128/256, and KMAC as specified in NIST SP 800-185.'
16
- EOF
16
+ DESC
17
17
  spec.summary = 'SHA-3 (FIPS 202), SHAKE128/SHAKE256, cSHAKE128/cSHAKE256, and KMAC (NIST SP 800-185), powered by XKCP.'
18
18
 
19
19
  spec.homepage = 'https://github.com/johanns/sha3'
20
20
  spec.license = 'MIT'
21
21
  spec.required_ruby_version = '>= 2.7.0'
22
22
 
23
- spec.metadata['changelog_uri'] = "#{spec.homepage}/CHANGELOG.md"
23
+ spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/main/CHANGELOG.md"
24
24
  spec.metadata['homepage_uri'] = spec.homepage
25
25
  spec.metadata['documentation_uri'] = 'https://docs.jsg.io/sha3/index.html'
26
26
 
27
- spec.post_install_message = <<-EOF
27
+ spec.post_install_message = <<-NOTICE
28
28
  [NOTICE] SHA3 version 2.0 introduces breaking changes to the API.
29
29
  Please review the changelog and ensure compatibility with your application.
30
30
  If you need the previous behavior, lock your Gemfile to version '~> 1.0'."
31
- EOF
31
+ NOTICE
32
32
 
33
33
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
34
34
  `git ls-files -z`.split("\x0").reject do |f|
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sha3
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.2
4
+ version: 2.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Johanns Gregorian
@@ -11,28 +11,28 @@ cert_chain:
11
11
  -----BEGIN CERTIFICATE-----
12
12
  MIIEYDCCAsigAwIBAgIBATANBgkqhkiG9w0BAQsFADA7MRAwDgYDVQQDDAdpb19z
13
13
  aGEzMRMwEQYKCZImiZPyLGQBGRYDanNnMRIwEAYKCZImiZPyLGQBGRYCaW8wHhcN
14
- MjUwMzAxMDYxMTE1WhcNMjYwMzAxMDYxMTE1WjA7MRAwDgYDVQQDDAdpb19zaGEz
14
+ MjYwNTE3MjAwNTE1WhcNMjgwNTE2MjAwNTE1WjA7MRAwDgYDVQQDDAdpb19zaGEz
15
15
  MRMwEQYKCZImiZPyLGQBGRYDanNnMRIwEAYKCZImiZPyLGQBGRYCaW8wggGiMA0G
16
- CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDMdO1oUQ9FzXYtfFktOXDx6oIf9uSk
17
- mg+yfo7uvcyNSa4gsF4+CY/TOYNBtwlD25AlgDqpxVCHFwUaBD+MHKyd8p6Eto1Q
18
- Bwb7YrjPOXlmCKQYr5sFfbjeUfQRKBUTAhzM0W/5Zh9C4gkOyZ/7SaU6mI/M/LgQ
19
- dZsw2y6l2bAl4aZaXgbnO7B1rPTPr6yQRZTveacmeTGHav1WACdE36Txqyv2QA7+
20
- +VdYx04fOe2FEipan7d4TA4XKW+0Z+VWyoWFNyyxJtiT53PB10lztPiycBqZ+A3L
21
- aA2VjZekn3NFbsXMOa4fbSTMddb784IWEeySmTMu6W/yYpo1B1PbgRaD/z2Zg0Qj
22
- SZ2ldqqk68nvFVWqUlRbT8ZY6McKC1VEbNLLk7jNvdbgr/VPo4Zu5TP3FXjsPlpz
23
- 1duXTtAGtHjPnS+tdkSinKv4OmbTHid9gnoDcRjlNpWxoULs9iSNb6lOCUeBxvF6
24
- 4Eh7nyIPmaTDwPQtg5/RTvjZMqprS8D3tKsCAwEAAaNvMG0wCQYDVR0TBAIwADAL
25
- BgNVHQ8EBAMCBLAwHQYDVR0OBBYEFLCWxOjmn5qTuhjFG7fwiPXzSIlFMBkGA1Ud
16
+ CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC16QqqWL49C7rqtj8HoYMippjH6T4A
17
+ MvK8w1nXPsGOhIP0BYcjNajdFxzOXZ9NcYPxosQAvY97THO7zEGsM2VrvPzsPL8J
18
+ 8DqRS6wHUezA2ZffGpUvsesNlIpzSkEXXXRTe/8dq2/TnIeKEyx4dhu1cKL6h/22
19
+ Mng14M25QJK0JI5xhQ/+i9UXeNCwFjwINbOzJD1XZ2VtOJkMm/yHZvB6ww8qu+gS
20
+ N4J2iiCbFRsbYRPuoVFVuSOD0lgX1tvwOtUucSdF1EzvEX5XW2avzOWsKab0V3ET
21
+ puZ9F36dmkfNan5n5GApyKkOZ/mfC8s9brjRXVlp4YPHBK3zFEU6VsCtIa08dPXI
22
+ axUZlmwQLhvtsnX3nkgvbGpvFZmhBs4JBssEur7Gf9bgLbXYngfmgIZv5WFRravJ
23
+ qvHCehkpVgqi+ebW15UzhPwQ5wNxdm/I+tAt/u08m0R4m6kQYbk2yAimjrVLx0f/
24
+ JPcoi+4QXrmYZujkhqhIw2lDPOCD2oKPUVECAwEAAaNvMG0wCQYDVR0TBAIwADAL
25
+ BgNVHQ8EBAMCBLAwHQYDVR0OBBYEFKuRt91muWm/9XZBRDt8Nkm1IdjdMBkGA1Ud
26
26
  EQQSMBCBDmlvK3NoYTNAanNnLmlvMBkGA1UdEgQSMBCBDmlvK3NoYTNAanNnLmlv
27
- MA0GCSqGSIb3DQEBCwUAA4IBgQC4Y5pXxtopzHiSBsg6fuozv7zHXXuYXOL2Bq2x
28
- l8C8lYjC2pN/Fh+FlgrJkqAoJ0wBlh3+wkhYPhSehkUy/2HaUYYTd1Zv4Odw+C/Q
29
- rQnN5+nIv+gMrLwoBXH9sFjAp/iYKd4cDz5aUVNrPqibj8zivcSqFJ9lsyOvIZO6
30
- tajU2HVxXOkpTtLzMgPEGdwlFEd2tB7VCGFbrTskxrpv243b0HdpeEVh2e9dNkl4
31
- XobOvUPXHzFTDucYe8jpCn7e7Cj43PpTZFnxIRJnO8cVpX6n7UG8+JgBSqvwuv5C
32
- YwFBqP6G2+0e0EdIIMdbCDBTmJbFyBr6y4pzED/FvEFzhAmCKOcZ6RJ8H7hkX5rh
33
- +L4c9pHTemc2sQl7kH+mrntu7pt6D4EM4FD5eyWujQN1ME7xvLIFm5SczqCzFDfe
34
- UjZtrp/rHLfHln46RvB+a1NlMRWxtJ7mQc/CMEbT+cpHlzuYa9qGakA4TmMpK10h
35
- uYUv/V6CD4iTEMby0dopwHt5NqE=
27
+ MA0GCSqGSIb3DQEBCwUAA4IBgQBI38LgcqdqpfkaiEGfr3fLtsOBkE1Q7mEHjeIS
28
+ JcEiu16sP0iR/0QzN/DS0vPMQUhl4dvkUl7euVOo8rp0mwzUyaSvq+MSQlpxwgjb
29
+ AQ5A8VAkkIMbTbCqRU9q9KQObmO8/NaFFFGgmRegp8eBEGdixbiIsReEeWzEICe1
30
+ TOmXWl1X7EBUF7CdSIHxBAjF16YXJoDJp16DonZ/pzbgeO85OzFmfnA+B9nsHXS4
31
+ 3CeJ/lKznIM8XWSXA1ruSkZeB5ouNtauqSAaBJoMkAB0DbOrZ6yo/mP8x3WtSLKY
32
+ SdQdy412nPewWa08VXIjZqd1Q+rI9Wq2pY6TOqML1Iu5nB2VMAr9PoHcIPz1P9N8
33
+ sM8XX4fXOsMtSc4SzMOqlkg2qRdo4/1eIjVSxCM84VqppRnH8syAzny6COQ0Xo+z
34
+ /PqqO8TUsynEGVsjIkBIa8Y5zoXBfcQ6PQpSbeY0bXhhsxclL3fKWSQQC4MN/OFE
35
+ 5aeBE+xHYdmI3UoIAXt1xB0hU9w=
36
36
  -----END CERTIFICATE-----
37
37
  date: 1980-01-02 00:00:00.000000000 Z
38
38
  dependencies: []
@@ -62,6 +62,7 @@ files:
62
62
  - Rakefile
63
63
  - certs/io+sha3@jsg.io.pem
64
64
  - doc/sha3.rb
65
+ - ext/sha3/common.h
65
66
  - ext/sha3/config.h
66
67
  - ext/sha3/cshake.c
67
68
  - ext/sha3/cshake.h
@@ -108,7 +109,7 @@ homepage: https://github.com/johanns/sha3
108
109
  licenses:
109
110
  - MIT
110
111
  metadata:
111
- changelog_uri: https://github.com/johanns/sha3/CHANGELOG.md
112
+ changelog_uri: https://github.com/johanns/sha3/blob/main/CHANGELOG.md
112
113
  homepage_uri: https://github.com/johanns/sha3
113
114
  documentation_uri: https://docs.jsg.io/sha3/index.html
114
115
  rubygems_mfa_required: 'true'
@@ -130,7 +131,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
130
131
  - !ruby/object:Gem::Version
131
132
  version: '0'
132
133
  requirements: []
133
- rubygems_version: 3.6.9
134
+ rubygems_version: 4.0.11
134
135
  specification_version: 4
135
136
  summary: SHA-3 (FIPS 202), SHAKE128/SHAKE256, cSHAKE128/cSHAKE256, and KMAC (NIST
136
137
  SP 800-185), powered by XKCP.
metadata.gz.sig CHANGED
Binary file