Skip to content

Commit

Permalink
Merge pull request #207 from cppalliance/SHAKE256
Browse files Browse the repository at this point in the history
Upgrade Shake256
  • Loading branch information
mborland authored Jan 15, 2025
2 parents a971e00 + e553f9e commit 12a38f9
Show file tree
Hide file tree
Showing 12 changed files with 417 additions and 253 deletions.
80 changes: 73 additions & 7 deletions include/boost/crypt2/hash/detail/sha3_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class sha3_base final {
auto update(compat::span<const compat::byte> data) noexcept -> state;

BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
auto xof_digest_impl(compat::span<compat::byte> data) noexcept -> void;
auto xof_digest_impl(compat::span<compat::byte> 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 Down Expand Up @@ -73,6 +73,13 @@ class sha3_base final {

template <concepts::writable_output_range Range>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto get_digest(Range&& data) noexcept -> state;

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

template <concepts::writable_output_range Range>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto get_digest(Range&& data, std::size_t amount) noexcept -> state;
};

namespace sha3_detail {
Expand Down Expand Up @@ -310,9 +317,12 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha3_base<digest_size, is_xof>::finalize(

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

BOOST_CRYPT_ASSERT(data.size() >= amount);
for (compat::size_t i {}; i < amount; ++i)
{
if (buffer_index_ == buffer_.size())
{
Expand Down Expand Up @@ -347,7 +357,7 @@ auto sha3_base<digest_size, is_xof>::get_digest() noexcept -> compat::expected<r

if constexpr (is_xof)
{
xof_digest_impl(digest);
xof_digest_impl(digest, digest_size);
}
else
{
Expand Down Expand Up @@ -377,7 +387,7 @@ sha3_base<digest_size, is_xof>::get_digest(compat::span<compat::byte, Extent> da
// XOF will fill the entire provided span whereas SHA will only fill the digest size
if constexpr (is_xof)
{
xof_digest_impl(data);
xof_digest_impl(data, data.size());
}
else
{
Expand Down Expand Up @@ -414,9 +424,12 @@ template <concepts::writable_output_range Range>
{
return state::state_error;
}

const auto data_size {std::size(data)};

if constexpr (!is_xof)
{
if (std::size(data) < digest_size)
if (data_size < digest_size)
{
return state::insufficient_output_length;
}
Expand All @@ -431,7 +444,7 @@ template <concepts::writable_output_range Range>

if constexpr (is_xof)
{
xof_digest_impl(compat::span<compat::byte>(compat::as_writable_bytes(data_span).data(), std::size(data)));
xof_digest_impl(compat::span<compat::byte>(compat::as_writable_bytes(data_span).data(), data_size), data_size);
}
else
{
Expand All @@ -450,6 +463,59 @@ template <concepts::writable_output_range Range>
return state::success;
}

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>::get_digest(compat::span<compat::byte, Extent> data, std::size_t amount) noexcept -> state
{
if (!computed_ || corrupted_)
{
return state::state_error;
}

if (data.size() < amount)
{
return state::insufficient_output_length;
}

// XOF will fill the entire provided span whereas SHA will only fill the digest size
xof_digest_impl(data, amount);

return state::success;
}

template <compat::size_t digest_size, bool is_xof>
template <concepts::writable_output_range Range>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto sha3_base<digest_size, is_xof>::get_digest(Range&& data, std::size_t amount) noexcept -> state
{
using value_type = compat::range_value_t<Range>;

if (!computed_ || corrupted_)
{
return state::state_error;
}

if (std::size(data) < 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"
#endif

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

#if defined(__clang__) && __clang_major__ >= 19
#pragma clang diagnostic pop
#endif

return state::success;
}

} // namespace boost::crypt::hash_detail

#endif //BOOST_CRYPT2_HASH_DETAIL_SHA3_BASE_HPP
29 changes: 29 additions & 0 deletions include/boost/crypt2/hash/shake128.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,35 @@ auto shake128(SizedRange&& data, OutputRange&& out) noexcept -> state
return hasher.get_digest(out);
}

[[nodiscard]] BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
auto shake128(compat::span<const compat::byte> data, compat::span<compat::byte> out, compat::size_t amount) noexcept -> state
{
shake128_hasher hasher;
hasher.process_bytes(data);
hasher.finalize();
return hasher.get_digest(out, amount);
}

template <concepts::writable_output_range OutputRange>
[[nodiscard]] BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED
auto shake128(compat::span<const compat::byte> data, OutputRange&& out, compat::size_t amount) noexcept -> state
{
shake128_hasher hasher;
hasher.process_bytes(data);
hasher.finalize();
return hasher.get_digest(out, amount);
}

template <compat::sized_range SizedRange, concepts::writable_output_range OutputRange>
[[nodiscard]] BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED
auto shake128(SizedRange&& data, OutputRange&& out, compat::size_t amount) noexcept -> state
{
shake128_hasher hasher;
hasher.process_bytes(data);
hasher.finalize();
return hasher.get_digest(out, amount);
}

#if !BOOST_CRYPT_HAS_CUDA

template <concepts::file_system_path T>
Expand Down
109 changes: 109 additions & 0 deletions include/boost/crypt2/hash/shake256.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// Copyright 2024 - 2025 Matt Borland
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt

#ifndef BOOST_CRYPT2_HASH_SHAKE256_HPP
#define BOOST_CRYPT2_HASH_SHAKE256_HPP

#include <boost/crypt2/hash/detail/sha3_base.hpp>
#include <boost/crypt2/hash/detail/hash_file.hpp>
#include <boost/crypt2/detail/compat.hpp>
#include <boost/crypt2/detail/concepts.hpp>

namespace boost::crypt {

BOOST_CRYPT_EXPORT using shake256_hasher = hash_detail::sha3_base<32U, true>;

// One shot functions
[[nodiscard]] BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
auto shake256(compat::span<const compat::byte> data) noexcept -> compat::expected<shake256_hasher::return_type, state>
{
shake256_hasher hasher;
hasher.process_bytes(data);
hasher.finalize();
return hasher.get_digest();
}

template <compat::sized_range SizedRange>
[[nodiscard]] BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED
auto shake256(SizedRange&& data) noexcept -> compat::expected<shake256_hasher::return_type, state>
{
shake256_hasher hasher;
hasher.process_bytes(data);
hasher.finalize();
return hasher.get_digest();
}

// One shot functions that add the xof capability
[[nodiscard]] BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
auto shake256(compat::span<const compat::byte> data, compat::span<compat::byte> out) noexcept -> state
{
shake256_hasher hasher;
hasher.process_bytes(data);
hasher.finalize();
return hasher.get_digest(out);
}

template <concepts::writable_output_range OutputRange>
[[nodiscard]] BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED
auto shake256(compat::span<const compat::byte> data, OutputRange&& out) noexcept -> state
{
shake256_hasher hasher;
hasher.process_bytes(data);
hasher.finalize();
return hasher.get_digest(out);
}

template <compat::sized_range SizedRange, concepts::writable_output_range OutputRange>
[[nodiscard]] BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED
auto shake256(SizedRange&& data, OutputRange&& out) noexcept -> state
{
shake256_hasher hasher;
hasher.process_bytes(data);
hasher.finalize();
return hasher.get_digest(out);
}

[[nodiscard]] BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
auto shake256(compat::span<const compat::byte> data, compat::span<compat::byte> out, std::size_t amount) noexcept -> state
{
shake256_hasher hasher;
hasher.process_bytes(data);
hasher.finalize();
return hasher.get_digest(out, amount);
}

template <concepts::writable_output_range OutputRange>
[[nodiscard]] BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED
auto shake256(compat::span<const compat::byte> data, OutputRange&& out, std::size_t amount) noexcept -> state
{
shake256_hasher hasher;
hasher.process_bytes(data);
hasher.finalize();
return hasher.get_digest(out, amount);
}

template <compat::sized_range SizedRange, concepts::writable_output_range OutputRange>
[[nodiscard]] BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED
auto shake256(SizedRange&& data, OutputRange&& out, std::size_t amount) noexcept -> state
{
shake256_hasher hasher;
hasher.process_bytes(data);
hasher.finalize();
return hasher.get_digest(out, amount);
}

#if !BOOST_CRYPT_HAS_CUDA

template <concepts::file_system_path T>
[[nodiscard]] BOOST_CRYPT_EXPORT
auto shake256_file(const T& filepath) -> compat::expected<shake256_hasher::return_type, state>
{
return hash_detail::hash_file_impl<shake256_hasher>(filepath);
}

#endif // BOOST_CRYPT_HAS_CUDA

} // namespace boost::crypt

#endif //BOOST_CRYPT2_HASH_SHAKE256_HPP
8 changes: 4 additions & 4 deletions test/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ run test_sha3_384.cpp ;
run test_sha3_256.cpp ;
run test_sha3_224.cpp ;
run test_shake128.cpp ;
#run test_shake256.cpp ;
run test_shake256.cpp ;

#run test_hmac.cpp ;

Expand Down Expand Up @@ -144,9 +144,9 @@ run test_nist_cavs_shake128_short_long.cpp ;
run test_nist_cavs_shake128_monte.cpp ;
run test_nist_cavs_shake128_variable_output.cpp ;

#run test_nist_cavs_shake256_short_long.cpp ;
#run test_nist_cavs_shake256_monte.cpp ;
#run test_nist_cavs_shake256_variable_output.cpp ;
run test_nist_cavs_shake256_short_long.cpp ;
run test_nist_cavs_shake256_monte.cpp ;
run test_nist_cavs_shake256_variable_output.cpp ;

#run test_nist_cavs_aes128_kat_ecb.cpp ;
#run test_nist_cavs_aes128_mmt_ecb.cpp ;
Expand Down
2 changes: 1 addition & 1 deletion test/nvcc_jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ run test_sha3_384_nvcc.cu ;
run test_sha3_256_nvcc.cu ;
run test_sha3_224_nvcc.cu ;
run test_shake128_nvcc.cu ;
#run test_shake256_nvcc.cu ;
run test_shake256_nvcc.cu ;
Loading

0 comments on commit 12a38f9

Please sign in to comment.