@@ -64,22 +64,39 @@ class sha3_base final {
64
64
65
65
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto finalize () noexcept -> state;
66
66
67
+ // SHA 3 get_digest is idempotent so make as const
68
+ template <bool Const = !is_xof>
67
69
[[nodiscard(" Digest is the function return value" )]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
68
- auto get_digest () noexcept -> compat::expected<return_type, state>;
70
+ compat:: enable_if_t <Const, compat::expected<return_type, state>> get_digest () const noexcept ;
69
71
70
- template <compat::size_t Extent = compat::dynamic_extent>
72
+ template <bool Const = !is_xof, compat::size_t Extent = compat::dynamic_extent>
71
73
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
72
- auto get_digest (compat::span<compat::byte, Extent> data) noexcept -> state ;
74
+ compat:: enable_if_t <Const, state> get_digest (compat::span<compat::byte, Extent> data) const noexcept ;
73
75
74
- template <concepts::writable_output_range Range>
75
- [[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto get_digest (Range&& data) noexcept -> state;
76
+ template <bool Const = !is_xof, concepts::writable_output_range Range>
77
+ [[nodiscard]] BOOST_CRYPT_GPU_ENABLED
78
+ compat::enable_if_t <Const, state> get_digest (Range&& data) const noexcept ;
76
79
77
- template <compat::size_t Extent = compat::dynamic_extent>
80
+ // XOF get_digest is not idempotent so we need separate impls
81
+ template <bool Const = is_xof>
82
+ [[nodiscard(" Digest is the function return value" )]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
83
+ compat::enable_if_t <Const, compat::expected<return_type, state>> get_digest () noexcept ;
84
+
85
+ template <bool Const = is_xof, compat::size_t Extent = compat::dynamic_extent>
86
+ [[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
87
+ compat::enable_if_t <Const, state> get_digest (compat::span<compat::byte, Extent> data) noexcept ;
88
+
89
+ template <bool Const = is_xof, concepts::writable_output_range Range>
90
+ [[nodiscard]] BOOST_CRYPT_GPU_ENABLED
91
+ compat::enable_if_t <Const, state> get_digest (Range&& data) noexcept ;
92
+
93
+ template <bool Const = is_xof, compat::size_t Extent = compat::dynamic_extent>
78
94
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
79
- auto get_digest (compat::span<compat::byte, Extent> data, std::size_t amount) noexcept -> state ;
95
+ compat:: enable_if_t <Const, state> get_digest (compat::span<compat::byte, Extent> data, std::size_t amount) noexcept ;
80
96
81
- template <concepts::writable_output_range Range>
82
- [[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto get_digest (Range&& data, std::size_t amount) noexcept -> state;
97
+ template <bool Const = is_xof, concepts::writable_output_range Range>
98
+ [[nodiscard]] BOOST_CRYPT_GPU_ENABLED
99
+ compat::enable_if_t <Const, state> get_digest (Range&& data, std::size_t amount) noexcept ;
83
100
};
84
101
85
102
namespace sha3_detail {
@@ -345,78 +362,95 @@ auto sha3_base<digest_size, is_xof>::sha_digest_impl(compat::span<compat::byte,
345
362
}
346
363
347
364
template <compat::size_t digest_size, bool is_xof>
365
+ template <bool Const>
348
366
[[nodiscard(" Digest is the function return value" )]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
349
- auto sha3_base<digest_size, is_xof>::get_digest() noexcept -> compat::expected<return_type, state>
367
+ compat::enable_if_t <Const, compat::expected<typename sha3_base<digest_size, is_xof>::return_type, state>>
368
+ sha3_base<digest_size, is_xof>::get_digest() const noexcept
350
369
{
351
- return_type digest {};
352
-
353
370
if (!computed_ || corrupted_)
354
371
{
355
372
return compat::unexpected<state>(state::state_error);
356
373
}
357
374
358
- if constexpr (is_xof)
359
- {
360
- xof_digest_impl (digest, digest_size);
361
- }
362
- else
375
+ return_type digest {};
376
+ sha_digest_impl (digest);
377
+
378
+ return digest;
379
+ }
380
+
381
+ template <compat::size_t digest_size, bool is_xof>
382
+ template <bool Const>
383
+ [[nodiscard(" Digest is the function return value" )]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
384
+ compat::enable_if_t <Const, compat::expected<typename sha3_base<digest_size, is_xof>::return_type, state>>
385
+ sha3_base<digest_size, is_xof>::get_digest() noexcept
386
+ {
387
+ if (!computed_ || corrupted_)
363
388
{
364
- sha_digest_impl (digest );
389
+ return compat::unexpected<state>(state::state_error );
365
390
}
366
391
392
+ return_type digest {};
393
+ xof_digest_impl (digest, digest_size);
394
+
367
395
return digest;
368
396
}
369
397
370
398
template <compat::size_t digest_size, bool is_xof>
371
- template <compat::size_t Extent>
372
- [[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto
373
- sha3_base<digest_size, is_xof>::get_digest(compat::span<compat::byte, Extent> data) noexcept -> state
399
+ template <bool Const, compat::size_t Extent>
400
+ [[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
401
+ compat:: enable_if_t <Const, state> sha3_base<digest_size, is_xof>::get_digest(compat::span<compat::byte, Extent> data) const noexcept
374
402
{
375
403
if (!computed_ || corrupted_)
376
404
{
377
405
return state::state_error;
378
406
}
379
- if constexpr (!is_xof )
407
+ if (data. size () < digest_size )
380
408
{
381
- if (data.size () < digest_size)
382
- {
383
- return state::insufficient_output_length;
384
- }
409
+ return state::insufficient_output_length;
385
410
}
386
411
387
- // XOF will fill the entire provided span whereas SHA will only fill the digest size
388
- if constexpr (is_xof)
412
+ if constexpr (Extent == digest_size)
389
413
{
390
- xof_digest_impl (data, data. size () );
414
+ sha_digest_impl (data);
391
415
}
392
416
else
393
417
{
394
- if constexpr (Extent == digest_size)
395
- {
396
- sha_digest_impl (data);
397
- }
398
- else
399
- {
400
- // We have verified the length of the span is correct so using a fixed length section of it is safe
401
- #if defined(__clang__) && __clang_major__ >= 19
402
- #pragma clang diagnostic push
403
- #pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-container"
404
- #endif
418
+ // We have verified the length of the span is correct so using a fixed length section of it is safe
419
+ #if defined(__clang__) && __clang_major__ >= 19
420
+ #pragma clang diagnostic push
421
+ #pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-container"
422
+ #endif
405
423
406
- sha_digest_impl (compat::span<compat::byte, digest_size>(data.data (), digest_size));
424
+ sha_digest_impl (compat::span<compat::byte, digest_size>(data.data (), digest_size));
407
425
408
- #if defined(__clang__) && __clang_major__ >= 19
409
- #pragma clang diagnostic pop
410
- #endif
411
- }
426
+ #if defined(__clang__) && __clang_major__ >= 19
427
+ #pragma clang diagnostic pop
428
+ #endif
412
429
}
413
430
414
431
return state::success;
415
432
}
416
433
417
434
template <compat::size_t digest_size, bool is_xof>
418
- template <concepts::writable_output_range Range>
419
- [[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto sha3_base<digest_size, is_xof>::get_digest(Range&& data) noexcept -> state
435
+ template <bool Const, compat::size_t Extent>
436
+ [[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
437
+ compat::enable_if_t <Const, state> sha3_base<digest_size, is_xof>::get_digest(compat::span<compat::byte, Extent> data) noexcept
438
+ {
439
+ if (!computed_ || corrupted_)
440
+ {
441
+ return state::state_error;
442
+ }
443
+
444
+ // XOF will fill the entire provided span whereas SHA will only fill the digest size
445
+ xof_digest_impl (data, data.size ());
446
+
447
+ return state::success;
448
+ }
449
+
450
+ template <compat::size_t digest_size, bool is_xof>
451
+ template <bool Const, concepts::writable_output_range Range>
452
+ [[nodiscard]] BOOST_CRYPT_GPU_ENABLED
453
+ compat::enable_if_t <Const, state> sha3_base<digest_size, is_xof>::get_digest(Range&& data) const noexcept
420
454
{
421
455
using value_type = compat::range_value_t <Range>;
422
456
@@ -427,12 +461,9 @@ template <concepts::writable_output_range Range>
427
461
428
462
const auto data_size {std::size (data)};
429
463
430
- if constexpr (!is_xof )
464
+ if (data_size < digest_size )
431
465
{
432
- if (data_size < digest_size)
433
- {
434
- return state::insufficient_output_length;
435
- }
466
+ return state::insufficient_output_length;
436
467
}
437
468
438
469
auto data_span {compat::span<value_type>(compat::forward<Range>(data))};
@@ -442,20 +473,42 @@ template <concepts::writable_output_range Range>
442
473
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-container"
443
474
#endif
444
475
445
- if constexpr (is_xof)
446
- {
447
- xof_digest_impl (compat::span<compat::byte>(compat::as_writable_bytes (data_span).data (), data_size), data_size);
448
- }
449
- else
476
+ sha_digest_impl (
477
+ compat::span<compat::byte, digest_size>(
478
+ compat::as_writable_bytes (data_span).data (),
479
+ digest_size
480
+ )
481
+ );
482
+
483
+ #if defined(__clang__) && __clang_major__ >= 19
484
+ #pragma clang diagnostic pop
485
+ #endif
486
+
487
+ return state::success;
488
+ }
489
+
490
+ template <compat::size_t digest_size, bool is_xof>
491
+ template <bool Const, concepts::writable_output_range Range>
492
+ [[nodiscard]] BOOST_CRYPT_GPU_ENABLED
493
+ compat::enable_if_t <Const, state> sha3_base<digest_size, is_xof>::get_digest(Range&& data) noexcept
494
+ {
495
+ using value_type = compat::range_value_t <Range>;
496
+
497
+ if (!computed_ || corrupted_)
450
498
{
451
- sha_digest_impl (
452
- compat::span<compat::byte, digest_size>(
453
- compat::as_writable_bytes (data_span).data (),
454
- digest_size
455
- )
456
- );
499
+ return state::state_error;
457
500
}
458
-
501
+
502
+ const auto data_size {std::size (data)};
503
+ auto data_span {compat::span<value_type>(compat::forward<Range>(data))};
504
+
505
+ #if defined(__clang__) && __clang_major__ >= 19
506
+ #pragma clang diagnostic push
507
+ #pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-container"
508
+ #endif
509
+
510
+ xof_digest_impl (compat::span<compat::byte>(compat::as_writable_bytes (data_span).data (), data_size), data_size);
511
+
459
512
#if defined(__clang__) && __clang_major__ >= 19
460
513
#pragma clang diagnostic pop
461
514
#endif
@@ -464,9 +517,9 @@ template <concepts::writable_output_range Range>
464
517
}
465
518
466
519
template <compat::size_t digest_size, bool is_xof>
467
- template <compat::size_t Extent>
468
- [[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto
469
- sha3_base<digest_size, is_xof>::get_digest(compat::span<compat::byte, Extent> data, std::size_t amount) noexcept -> state
520
+ template <bool Const, compat::size_t Extent>
521
+ [[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
522
+ compat:: enable_if_t <Const, state> sha3_base<digest_size, is_xof>::get_digest(compat::span<compat::byte, Extent> data, std::size_t amount) noexcept
470
523
{
471
524
if (!computed_ || corrupted_)
472
525
{
@@ -485,8 +538,9 @@ sha3_base<digest_size, is_xof>::get_digest(compat::span<compat::byte, Extent> da
485
538
}
486
539
487
540
template <compat::size_t digest_size, bool is_xof>
488
- template <concepts::writable_output_range Range>
489
- [[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto sha3_base<digest_size, is_xof>::get_digest(Range&& data, std::size_t amount) noexcept -> state
541
+ template <bool Const, concepts::writable_output_range Range>
542
+ [[nodiscard]] BOOST_CRYPT_GPU_ENABLED
543
+ compat::enable_if_t <Const, state> sha3_base<digest_size, is_xof>::get_digest(Range&& data, std::size_t amount) noexcept
490
544
{
491
545
using value_type = compat::range_value_t <Range>;
492
546
0 commit comments