Skip to content

Commit 1c03fb2

Browse files
authored
Merge pull request #222 from cppalliance/consteval_hmac
Add `consteval` hmac testing and collected fixes for extents and byte sizing
2 parents b4f4c8a + 007f0c5 commit 1c03fb2

File tree

5 files changed

+193
-34
lines changed

5 files changed

+193
-34
lines changed

include/boost/crypt2/hash/detail/sha3_base.hpp

Lines changed: 61 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@ class sha3_base final {
3737

3838
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto process_message_block() noexcept -> void;
3939

40+
template <compat::size_t Extent = compat::dynamic_extent>
4041
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
41-
auto update(compat::span<const compat::byte> data) noexcept -> state;
42+
auto update(compat::span<const compat::byte, Extent> data) noexcept -> state;
4243

44+
template <compat::size_t Extent = compat::dynamic_extent>
4345
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
44-
auto xof_digest_impl(compat::span<compat::byte> data, compat::size_t amount) noexcept -> void;
46+
auto xof_digest_impl(compat::span<compat::byte, Extent> data, compat::size_t amount) noexcept -> void;
4547

4648
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
4749
auto sha_digest_impl(compat::span<compat::byte, digest_size> data) const noexcept -> void;
@@ -57,7 +59,8 @@ class sha3_base final {
5759

5860
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto init() noexcept -> void;
5961

60-
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto process_bytes(compat::span<const compat::byte> data) noexcept -> state;
62+
template <compat::size_t Extent = compat::dynamic_extent>
63+
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto process_bytes(compat::span<const compat::byte, Extent> data) noexcept -> state;
6164

6265
template <concepts::sized_range SizedRange>
6366
BOOST_CRYPT_GPU_ENABLED auto process_bytes(SizedRange&& data) noexcept -> state;
@@ -241,14 +244,30 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha3_base<digest_size, is_xof>::process_m
241244
buffer_index_ = 0U;
242245
}
243246

247+
// In the fixed extent case where we check Extent == 0 this can make the rest of the code unreachable
248+
// We consider this a good thing since this means our compile time checks are working
249+
#ifdef _MSC_VER
250+
#pragma warning(push)
251+
#pragma warning(disable : 4702)
252+
#endif
253+
244254
template <compat::size_t digest_size, bool is_xof>
255+
template <compat::size_t Extent>
245256
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
246-
auto sha3_base<digest_size, is_xof>::update(compat::span<const compat::byte> data) noexcept -> state
257+
auto sha3_base<digest_size, is_xof>::update(compat::span<const compat::byte, Extent> data) noexcept -> state
247258
{
248-
if (data.empty())
259+
if constexpr (Extent == compat::dynamic_extent)
260+
{
261+
if (data.empty())
262+
{
263+
return state::success;
264+
}
265+
}
266+
else if constexpr (Extent == 0U)
249267
{
250268
return state::success;
251269
}
270+
252271
if (computed_)
253272
{
254273
corrupted_ = true;
@@ -271,6 +290,10 @@ auto sha3_base<digest_size, is_xof>::update(compat::span<const compat::byte> dat
271290
return state::success;
272291
}
273292

293+
#ifdef _MSC_VER
294+
#pragma warning(pop)
295+
#endif
296+
274297
template <compat::size_t digest_size, bool is_xof>
275298
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR sha3_base<digest_size, is_xof>::~sha3_base() noexcept
276299
{
@@ -292,8 +315,9 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha3_base<digest_size, is_xof>::init() no
292315
}
293316

294317
template <compat::size_t digest_size, bool is_xof>
318+
template <compat::size_t Extent>
295319
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto
296-
sha3_base<digest_size, is_xof>::process_bytes(compat::span<const compat::byte> data) noexcept -> state
320+
sha3_base<digest_size, is_xof>::process_bytes(compat::span<const compat::byte, Extent> data) noexcept -> state
297321
{
298322
return update(data);
299323
}
@@ -333,8 +357,9 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha3_base<digest_size, is_xof>::finalize(
333357
}
334358

335359
template <compat::size_t digest_size, bool is_xof>
360+
template <compat::size_t Extent>
336361
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
337-
auto sha3_base<digest_size, is_xof>::xof_digest_impl(compat::span<compat::byte> data, std::size_t amount) noexcept -> void
362+
auto sha3_base<digest_size, is_xof>::xof_digest_impl(compat::span<compat::byte, Extent> data, std::size_t amount) noexcept -> void
338363
{
339364
static_assert(is_xof, "Calling for variable amounts of data is not allowed with non-XOF hashers");
340365

@@ -390,11 +415,19 @@ sha3_base<digest_size, is_xof>::get_digest() noexcept
390415
}
391416

392417
return_type digest {};
393-
xof_digest_impl(digest, digest_size);
418+
compat::span<compat::byte, digest_size> digest_span {digest};
419+
xof_digest_impl(digest_span, digest_size);
394420

395421
return digest;
396422
}
397423

424+
// In the fixed extent case where we check Extent < digest_size this can make the rest of the code unreachable
425+
// We consider this a good thing since this means our compile time checks are working
426+
#ifdef _MSC_VER
427+
#pragma warning(push)
428+
#pragma warning(disable : 4702)
429+
#endif
430+
398431
template <compat::size_t digest_size, bool is_xof>
399432
template <bool Const, compat::size_t Extent>
400433
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
@@ -404,7 +437,15 @@ compat::enable_if_t<Const, state> sha3_base<digest_size, is_xof>::get_digest(com
404437
{
405438
return state::state_error;
406439
}
407-
if (data.size() < digest_size)
440+
441+
if constexpr (Extent == compat::dynamic_extent)
442+
{
443+
if (data.size() < digest_size)
444+
{
445+
return state::insufficient_output_length;
446+
}
447+
}
448+
else if constexpr (Extent < digest_size)
408449
{
409450
return state::insufficient_output_length;
410451
}
@@ -431,6 +472,10 @@ compat::enable_if_t<Const, state> sha3_base<digest_size, is_xof>::get_digest(com
431472
return state::success;
432473
}
433474

475+
#ifdef _MSC_VER
476+
#pragma warning(pop)
477+
#endif
478+
434479
template <compat::size_t digest_size, bool is_xof>
435480
template <bool Const, compat::size_t Extent>
436481
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
@@ -459,15 +504,13 @@ compat::enable_if_t<Const, state> sha3_base<digest_size, is_xof>::get_digest(Ran
459504
return state::state_error;
460505
}
461506

462-
const auto data_size {std::size(data)};
507+
auto data_span {compat::span<value_type>(compat::forward<Range>(data))};
463508

464-
if (data_size < digest_size)
509+
if (data_span.size_bytes() < digest_size)
465510
{
466511
return state::insufficient_output_length;
467512
}
468513

469-
auto data_span {compat::span<value_type>(compat::forward<Range>(data))};
470-
471514
#if defined(__clang__) && __clang_major__ >= 19
472515
#pragma clang diagnostic push
473516
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-container"
@@ -499,15 +542,14 @@ compat::enable_if_t<Const, state> sha3_base<digest_size, is_xof>::get_digest(Ran
499542
return state::state_error;
500543
}
501544

502-
const auto data_size {std::size(data)};
503545
auto data_span {compat::span<value_type>(compat::forward<Range>(data))};
504546

505547
#if defined(__clang__) && __clang_major__ >= 19
506548
#pragma clang diagnostic push
507549
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-container"
508550
#endif
509551

510-
xof_digest_impl(compat::span<compat::byte>(compat::as_writable_bytes(data_span).data(), data_size), data_size);
552+
xof_digest_impl(compat::span<compat::byte>(compat::as_writable_bytes(data_span).data(), data_span.size_bytes()), data_span.size_bytes());
511553

512554
#if defined(__clang__) && __clang_major__ >= 19
513555
#pragma clang diagnostic pop
@@ -526,7 +568,7 @@ compat::enable_if_t<Const, state> sha3_base<digest_size, is_xof>::get_digest(com
526568
return state::state_error;
527569
}
528570

529-
if (data.size() < amount)
571+
if (data.size_bytes() < amount)
530572
{
531573
return state::insufficient_output_length;
532574
}
@@ -549,13 +591,13 @@ compat::enable_if_t<Const, state> sha3_base<digest_size, is_xof>::get_digest(Ran
549591
return state::state_error;
550592
}
551593

552-
if (std::size(data) < amount)
594+
auto data_span {compat::span<value_type>(compat::forward<Range>(data))};
595+
596+
if (data_span.size_bytes() < amount)
553597
{
554598
return state::insufficient_output_length;
555599
}
556600

557-
auto data_span {compat::span<value_type>(compat::forward<Range>(data))};
558-
559601
#if defined(__clang__) && __clang_major__ >= 19
560602
#pragma clang diagnostic push
561603
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-container"

include/boost/crypt2/hash/detail/sha512_base.hpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ class sha512_base final
4242

4343
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto process_message_block() noexcept -> void;
4444

45-
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto update(compat::span<const compat::byte> data) noexcept -> state;
45+
template <compat::size_t Extent = compat::dynamic_extent>
46+
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto update(compat::span<const compat::byte, Extent> data) noexcept -> state;
4647

4748
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto pad_message() noexcept -> void;
4849

@@ -56,7 +57,8 @@ class sha512_base final
5657

5758
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto init() noexcept -> void;
5859

59-
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto process_bytes(compat::span<const compat::byte> data) noexcept -> state;
60+
template <compat::size_t Extent = compat::dynamic_extent>
61+
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto process_bytes(compat::span<const compat::byte, Extent> data) noexcept -> state;
6062

6163
template <concepts::sized_range SizedRange>
6264
BOOST_CRYPT_GPU_ENABLED auto process_bytes(SizedRange&& data) noexcept -> state;
@@ -193,13 +195,22 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha512_base<digest_size>::finalize() noex
193195
}
194196

195197
template <compat::size_t digest_size>
198+
template <compat::size_t Extent>
196199
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
197-
auto sha512_base<digest_size>::update(compat::span<const compat::byte> data) noexcept -> state
200+
auto sha512_base<digest_size>::update(compat::span<const compat::byte, Extent> data) noexcept -> state
198201
{
199-
if (data.empty())
202+
if constexpr (Extent == compat::dynamic_extent)
203+
{
204+
if (data.empty())
205+
{
206+
return state::success;
207+
}
208+
}
209+
else if constexpr (Extent == 0U)
200210
{
201211
return state::success;
202212
}
213+
203214
if (computed_)
204215
{
205216
corrupted_ = true;
@@ -485,7 +496,8 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha512_base<digest_size>::process_message
485496
}
486497

487498
template <compat::size_t digest_size>
488-
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha512_base<digest_size>::process_bytes(compat::span<const compat::byte> data) noexcept -> state
499+
template <compat::size_t Extent>
500+
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha512_base<digest_size>::process_bytes(compat::span<const compat::byte, Extent> data) noexcept -> state
489501
{
490502
return update(data);
491503
}

include/boost/crypt2/hash/detail/sha_1_2_hasher_base.hpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ class sha_1_2_hasher_base
3636
bool computed_ {};
3737
bool corrupted_ {};
3838

39-
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto update(compat::span<const compat::byte> data) noexcept -> state;
39+
template <compat::size_t Extent = compat::dynamic_extent>
40+
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto update(compat::span<const compat::byte, Extent> data) noexcept -> state;
4041

4142
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto get_digest_impl(compat::span<compat::byte, digest_size> data) const noexcept -> state;
4243

@@ -47,7 +48,8 @@ class sha_1_2_hasher_base
4748
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR sha_1_2_hasher_base() noexcept { base_init(); }
4849
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR ~sha_1_2_hasher_base() noexcept;
4950

50-
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto process_bytes(compat::span<const compat::byte> data) noexcept -> state;
51+
template <compat::size_t Extent = compat::dynamic_extent>
52+
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto process_bytes(compat::span<const compat::byte, Extent> data) noexcept -> state;
5153

5254
template <concepts::sized_range SizedRange>
5355
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto process_bytes(SizedRange&& data) noexcept -> state;
@@ -236,19 +238,29 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha_1_2_hasher_base<digest_size, intermed
236238
}
237239

238240
template <compat::size_t digest_size, compat::size_t intermediate_hash_size>
239-
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha_1_2_hasher_base<digest_size, intermediate_hash_size>::process_bytes(compat::span<const compat::byte> data) noexcept -> state
241+
template <compat::size_t Extent>
242+
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha_1_2_hasher_base<digest_size, intermediate_hash_size>::process_bytes(compat::span<const compat::byte, Extent> data) noexcept -> state
240243
{
241244
return update(data);
242245
}
243246

244247
template <compat::size_t digest_size, compat::size_t intermediate_hash_size>
248+
template <compat::size_t Extent>
245249
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
246-
auto sha_1_2_hasher_base<digest_size, intermediate_hash_size>::update(compat::span<const compat::byte> data) noexcept -> state
250+
auto sha_1_2_hasher_base<digest_size, intermediate_hash_size>::update(compat::span<const compat::byte, Extent> data) noexcept -> state
247251
{
248-
if (data.empty())
252+
if constexpr (Extent == compat::dynamic_extent)
253+
{
254+
if (data.empty())
255+
{
256+
return state::success;
257+
}
258+
}
259+
else if constexpr (Extent == 0U)
249260
{
250261
return state::success;
251262
}
263+
252264
if (computed_)
253265
{
254266
corrupted_ = true;

include/boost/crypt2/mac/hmac.hpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ class hmac
2626

2727
private:
2828

29+
using key_span = compat::span<const compat::byte, block_size>;
30+
2931
key_type inner_key_ {};
3032
key_type outer_key_ {};
3133
HasherType inner_hash_;
@@ -125,8 +127,8 @@ hmac<HasherType>::init_impl(const compat::span<const compat::byte, Extent> data)
125127
outer_key_[i] = k0[i] ^ compat::byte{0x5C};
126128
}
127129

128-
const auto inner_result {inner_hash_.process_bytes(inner_key_)};
129-
const auto outer_result {outer_hash_.process_bytes(outer_key_)};
130+
const auto inner_result {inner_hash_.process_bytes(key_span{inner_key_})};
131+
const auto outer_result {outer_hash_.process_bytes(key_span{outer_key_})};
130132

131133
if (inner_result == state::success && outer_result == state::success) [[likely]]
132134
{
@@ -177,8 +179,8 @@ hmac<HasherType>::init_from_keys(const hmac::key_type& inner_key, const hmac::ke
177179
inner_key_ = inner_key;
178180
outer_key_ = outer_key;
179181

180-
const auto inner_result {inner_hash_.process_bytes(inner_key)};
181-
const auto outer_result {outer_hash_.process_bytes(outer_key)};
182+
const auto inner_result {inner_hash_.process_bytes(key_span{inner_key})};
183+
const auto outer_result {outer_hash_.process_bytes(key_span{outer_key})};
182184

183185
if (inner_result == state::success && outer_result == state::success) [[likely]]
184186
{
@@ -275,7 +277,8 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac<HasherType>::finalize() noexcept ->
275277
const auto r_inner {inner_hash_.get_digest()};
276278
BOOST_CRYPT_ASSERT(r_inner.has_value());
277279

278-
outer_hash_.process_bytes(r_inner.value());
280+
compat::span<const compat::byte> r_inner_span {r_inner.value()};
281+
outer_hash_.process_bytes(r_inner_span);
279282
[[maybe_unused]] const auto outer_final_state {outer_hash_.finalize()};
280283
BOOST_CRYPT_ASSERT(outer_final_state == state::success);
281284

0 commit comments

Comments
 (0)