Skip to content
Merged
80 changes: 61 additions & 19 deletions include/boost/crypt2/hash/detail/sha3_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,13 @@ class sha3_base final {

BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto process_message_block() noexcept -> void;

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

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

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

BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto init() noexcept -> void;

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

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

// In the fixed extent case where we check Extent == 0 this can make the rest of the code unreachable
// We consider this a good thing since this means our compile time checks are working
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4702)
#endif

template <compat::size_t digest_size, bool is_xof>
template <compat::size_t Extent>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
auto sha3_base<digest_size, is_xof>::update(compat::span<const compat::byte> data) noexcept -> state
auto sha3_base<digest_size, is_xof>::update(compat::span<const compat::byte, Extent> data) noexcept -> state
{
if (data.empty())
if constexpr (Extent == compat::dynamic_extent)
{
if (data.empty())
{
return state::success;
}
}
else if constexpr (Extent == 0U)
{
return state::success;
}

if (computed_)
{
corrupted_ = true;
Expand All @@ -271,6 +290,10 @@ auto sha3_base<digest_size, is_xof>::update(compat::span<const compat::byte> dat
return state::success;
}

#ifdef _MSC_VER
#pragma warning(pop)
#endif

template <compat::size_t digest_size, bool is_xof>
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR sha3_base<digest_size, is_xof>::~sha3_base() noexcept
{
Expand All @@ -292,8 +315,9 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha3_base<digest_size, is_xof>::init() no
}

template <compat::size_t digest_size, bool is_xof>
template <compat::size_t Extent>
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto
sha3_base<digest_size, is_xof>::process_bytes(compat::span<const compat::byte> data) noexcept -> state
sha3_base<digest_size, is_xof>::process_bytes(compat::span<const compat::byte, Extent> data) noexcept -> state
{
return update(data);
}
Expand Down Expand Up @@ -333,8 +357,9 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha3_base<digest_size, is_xof>::finalize(
}

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

Expand Down Expand Up @@ -390,11 +415,19 @@ sha3_base<digest_size, is_xof>::get_digest() noexcept
}

return_type digest {};
xof_digest_impl(digest, digest_size);
compat::span<compat::byte, digest_size> digest_span {digest};
xof_digest_impl(digest_span, digest_size);

return digest;
}

// In the fixed extent case where we check Extent < digest_size this can make the rest of the code unreachable
// We consider this a good thing since this means our compile time checks are working
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4702)
#endif

template <compat::size_t digest_size, bool is_xof>
template <bool Const, compat::size_t Extent>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
Expand All @@ -404,7 +437,15 @@ compat::enable_if_t<Const, state> sha3_base<digest_size, is_xof>::get_digest(com
{
return state::state_error;
}
if (data.size() < digest_size)

if constexpr (Extent == compat::dynamic_extent)
{
if (data.size() < digest_size)
{
return state::insufficient_output_length;
}
}
else if constexpr (Extent < digest_size)
{
return state::insufficient_output_length;
}
Expand All @@ -431,6 +472,10 @@ compat::enable_if_t<Const, state> sha3_base<digest_size, is_xof>::get_digest(com
return state::success;
}

#ifdef _MSC_VER
#pragma warning(pop)
#endif

template <compat::size_t digest_size, bool is_xof>
template <bool Const, compat::size_t Extent>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
Expand Down Expand Up @@ -459,15 +504,13 @@ compat::enable_if_t<Const, state> sha3_base<digest_size, is_xof>::get_digest(Ran
return state::state_error;
}

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

if (data_size < digest_size)
if (data_span.size_bytes() < digest_size)
{
return state::insufficient_output_length;
}

auto data_span {compat::span<value_type>(compat::forward<Range>(data))};

#if defined(__clang__) && __clang_major__ >= 19
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-container"
Expand Down Expand Up @@ -499,15 +542,14 @@ compat::enable_if_t<Const, state> sha3_base<digest_size, is_xof>::get_digest(Ran
return state::state_error;
}

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

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

xof_digest_impl(compat::span<compat::byte>(compat::as_writable_bytes(data_span).data(), data_size), data_size);
xof_digest_impl(compat::span<compat::byte>(compat::as_writable_bytes(data_span).data(), data_span.size_bytes()), data_span.size_bytes());

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

if (data.size() < amount)
if (data.size_bytes() < amount)
{
return state::insufficient_output_length;
}
Expand All @@ -549,13 +591,13 @@ compat::enable_if_t<Const, state> sha3_base<digest_size, is_xof>::get_digest(Ran
return state::state_error;
}

if (std::size(data) < amount)
auto data_span {compat::span<value_type>(compat::forward<Range>(data))};

if (data_span.size_bytes() < amount)
{
return state::insufficient_output_length;
}

auto data_span {compat::span<value_type>(compat::forward<Range>(data))};

#if defined(__clang__) && __clang_major__ >= 19
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-container"
Expand Down
22 changes: 17 additions & 5 deletions include/boost/crypt2/hash/detail/sha512_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ class sha512_base final

BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto process_message_block() noexcept -> void;

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

BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto pad_message() noexcept -> void;

Expand All @@ -56,7 +57,8 @@ class sha512_base final

BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto init() noexcept -> void;

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

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

template <compat::size_t digest_size>
template <compat::size_t Extent>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
auto sha512_base<digest_size>::update(compat::span<const compat::byte> data) noexcept -> state
auto sha512_base<digest_size>::update(compat::span<const compat::byte, Extent> data) noexcept -> state
{
if (data.empty())
if constexpr (Extent == compat::dynamic_extent)
{
if (data.empty())
{
return state::success;
}
}
else if constexpr (Extent == 0U)
{
return state::success;
}

if (computed_)
{
corrupted_ = true;
Expand Down Expand Up @@ -485,7 +496,8 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha512_base<digest_size>::process_message
}

template <compat::size_t digest_size>
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha512_base<digest_size>::process_bytes(compat::span<const compat::byte> data) noexcept -> state
template <compat::size_t Extent>
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha512_base<digest_size>::process_bytes(compat::span<const compat::byte, Extent> data) noexcept -> state
{
return update(data);
}
Expand Down
22 changes: 17 additions & 5 deletions include/boost/crypt2/hash/detail/sha_1_2_hasher_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ class sha_1_2_hasher_base
bool computed_ {};
bool corrupted_ {};

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

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

Expand All @@ -47,7 +48,8 @@ class sha_1_2_hasher_base
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR sha_1_2_hasher_base() noexcept { base_init(); }
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR ~sha_1_2_hasher_base() noexcept;

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

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

template <compat::size_t digest_size, compat::size_t intermediate_hash_size>
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
template <compat::size_t Extent>
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
{
return update(data);
}

template <compat::size_t digest_size, compat::size_t intermediate_hash_size>
template <compat::size_t Extent>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
auto sha_1_2_hasher_base<digest_size, intermediate_hash_size>::update(compat::span<const compat::byte> data) noexcept -> state
auto sha_1_2_hasher_base<digest_size, intermediate_hash_size>::update(compat::span<const compat::byte, Extent> data) noexcept -> state
{
if (data.empty())
if constexpr (Extent == compat::dynamic_extent)
{
if (data.empty())
{
return state::success;
}
}
else if constexpr (Extent == 0U)
{
return state::success;
}

if (computed_)
{
corrupted_ = true;
Expand Down
13 changes: 8 additions & 5 deletions include/boost/crypt2/mac/hmac.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class hmac

private:

using key_span = compat::span<const compat::byte, block_size>;

key_type inner_key_ {};
key_type outer_key_ {};
HasherType inner_hash_;
Expand Down Expand Up @@ -125,8 +127,8 @@ hmac<HasherType>::init_impl(const compat::span<const compat::byte, Extent> data)
outer_key_[i] = k0[i] ^ compat::byte{0x5C};
}

const auto inner_result {inner_hash_.process_bytes(inner_key_)};
const auto outer_result {outer_hash_.process_bytes(outer_key_)};
const auto inner_result {inner_hash_.process_bytes(key_span{inner_key_})};
const auto outer_result {outer_hash_.process_bytes(key_span{outer_key_})};

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

const auto inner_result {inner_hash_.process_bytes(inner_key)};
const auto outer_result {outer_hash_.process_bytes(outer_key)};
const auto inner_result {inner_hash_.process_bytes(key_span{inner_key})};
const auto outer_result {outer_hash_.process_bytes(key_span{outer_key})};

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

outer_hash_.process_bytes(r_inner.value());
compat::span<const compat::byte> r_inner_span {r_inner.value()};
outer_hash_.process_bytes(r_inner_span);
[[maybe_unused]] const auto outer_final_state {outer_hash_.finalize()};
BOOST_CRYPT_ASSERT(outer_final_state == state::success);

Expand Down
Loading
Loading