Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions doc/crypt.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ include::crypt/sha384.adoc[]
include::crypt/sha512.adoc[]

include::crypt/sha512_224.adoc[]
////
include::crypt/sha512_256.adoc[]

include::crypt/sha512_256.adoc[]
////
include::crypt/sha3_224.adoc[]

include::crypt/sha3_256.adoc[]
Expand Down
151 changes: 37 additions & 114 deletions doc/crypt/sha512_256.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,94 +12,6 @@ https://www.boost.org/LICENSE_1_0.txt
This library supports sha512_256 as described in https://datatracker.ietf.org/doc/html/rfc6234[RFC 6234].
There is a wide range of acceptable inputs for the base sha512_256 function:

== Hashing Functions

[source, c++]
----
namespace boost {
namespace crypt {

uisng return_type = boost::crypt::array<uint8_t, 32>;

BOOST_CRYPT_GPU_ENABLED inline auto sha512_256(const char* str) noexcept -> return_type;

BOOST_CRYPT_GPU_ENABLED inline auto sha512_256(const char* str, size_t len) noexcept -> return_type;

BOOST_CRYPT_GPU_ENABLED inline auto sha512_256(const unsigned char* str) noexcept -> return_type;

BOOST_CRYPT_GPU_ENABLED inline auto sha512_256(const unsigned char* str, size_t len) noexcept -> return_type;

BOOST_CRYPT_GPU_ENABLED inline auto sha512_256(const char16_t* str) noexcept -> return_type;

BOOST_CRYPT_GPU_ENABLED inline auto sha512_256(const char16_t* str, size_t len) noexcept -> return_type;

BOOST_CRYPT_GPU_ENABLED inline auto sha512_256(const char32_t* str) noexcept -> return_type;

BOOST_CRYPT_GPU_ENABLED inline auto sha512_256(const char32_t* str, size_t len) noexcept -> return_type;

BOOST_CRYPT_GPU_ENABLED inline auto sha512_256(const wchar_t* str) noexcept -> return_type;

BOOST_CRYPT_GPU_ENABLED inline auto sha512_256(const wchar_t* str, size_t len) noexcept -> return_type;

inline auto sha512_256(const std::string& str) noexcept -> return_type;

inline auto sha512_256(const std::u16string& str) noexcept -> return_type;

inline auto sha512_256(const std::u32string& str) noexcept -> return_type;

inline auto sha512_256(const std::wstring& str) noexcept -> return_type;

#ifdef BOOST_CRYPT_HAS_STRING_VIEW

inline auto sha512_256(std::string_view str) noexcept -> return_type;

inline auto sha512_256(std::u16string_view str) noexcept -> return_type;

inline auto sha512_256(std::u32string_view str) noexcept -> return_type;

inline auto sha512_256(std::wstring_view str) noexcept -> return_type;

#endif // BOOST_CRYPT_HAS_STRING_VIEW

#ifdef BOOST_CRYPT_HAS_SPAN

template <typename T, std::size_t extent>
inline auto md5(std::span<T, extent> data) noexcept -> return_type;

#endif // BOOST_CRYPT_HAS_SPAN

#ifdef BOOST_CRYPT_HAS_CUDA

template <typename T, boost::crypt::size_t extent>
BOOST_CRYPT_GPU_ENABLED inline auto md5(cuda::std::span<T, extent> data) noexcept -> return_type;

#endif // BOOST_CRYPT_HAS_CUDA

} //namespace crypt
} //namespace boost
----

== File Hashing Functions

We also have the ability to scan files and return the sha512_256 value:

[source, c++]
----
namespace boost {
namespace crypt {

uisng return_type = boost::crypt::array<uint8_t, 32>;

inline auto sha512_256_file(const char* filepath) noexcept -> return_type;

inline auto sha512_256_file(const std::string& filepath) noexcept -> return_type;

inline auto sha512_256_file(std::string_view filepath) noexcept -> return_type;

} // namespace crypt
} // namespace boost
----

== Hashing Object

[#sha512_256_hasher]
Expand All @@ -108,50 +20,61 @@ This class does not use any dynamic memory allocation.

[source, c++]
----
namespace boost {
namespace crypt {
namespace boost::crypt {

class sha512_256_hasher
{
uisng return_type = boost::crypt::array<uint8_t, 32>;
public:
uisng return_type = compat::array<compat::byte, 28>;

void init();
// Initialize the hasher
BOOST_CRYPT_GPU_ENABLED constexpr void init() noexcept;

template <typename ByteType>
BOOST_CRYPT_GPU_ENABLED inline auto process_byte(ByteType byte) noexcept -> state;
// Process bytes piecewise
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(compat::span<const compat::byte> data) noexcept;

template <typename ForwardIter>
BOOST_CRYPT_GPU_ENABLED inline auto process_bytes(ForwardIter buffer, size_t byte_count) noexcept -> state;
template <compat::ranges::sized_range Range>
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(Range&& data) noexcept;

#ifdef BOOST_CRYPT_HAS_STRING_VIEW
// Finalize the calculation of the hash
BOOST_CRYPT_GPU_ENABLED constexpr state finalize() noexcept;

inline auto process_bytes(std::string_view str) noexcept -> state;
// Get the digest
[[nodiscard]] constexpr expected<return_type, state> get_digest() const noexcept;

inline auto process_bytes(std::u16string_view str) noexcept -> state;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR state get_digest(compat::span<compat::byte> data) const noexcept;

inline auto process_bytes(std::u32string_view str) noexcept -> state;
template <concepts::writable_output_range Range>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED state get_digest(Range&& data) const noexcept;
};

inline auto process_bytes(std::wstring_view str) noexcept -> state;
} // namespace boost::crypt
----

== One-Shot Hashing Functions

#endif // BOOST_CRYPT_HAS_STRING_VIEW
[source, c++]
----
namespace boost::crypt {

#ifdef BOOST_CRYPT_HAS_SPAN
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED constexpr auto sha512_256(compat::span<const compat::byte> data) noexcept -> expected<sha512_256_hasher::return_type, state>;

template <typename T, boost::crypt::size_t extent>
inline auto process_bytes(std::span<T, extent> data) noexcept -> state;
template <compat::ranges::sized_range SizedRange>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto sha512_256(SizedRange&& data) noexcept -> expected<sha512_256_hasher::return_type, state>;

#endif // BOOST_CRYPT_HAS_SPAN
} // namespace boost::crypt
----

#ifdef BOOST_CRYPT_HAS_CUDA
== File Hashing Functions

template <typename T, boost::crypt::size_t extent>
BOOST_CRYPT_GPU_ENABLED inline auto process_bytes(cuda::std::span<T, extent> data) noexcept -> state;
We also have the ability to scan files and return the sha512_256 value:

#endif // BOOST_CRYPT_HAS_CUDA
[source, c++]
----
namespace boost::crypt {

inline auto get_digest() noexcept -> return_type;
};
template <concepts::file_system_path T>
[[nodiscard]] inline auto sha512_256_file(const T& filepath) -> expected<sha512_256_hasher::return_type, state>;

} // namespace crypt
} // namespace boost
} // namespace boost::crypt
----
41 changes: 41 additions & 0 deletions fuzzing/fuzz_sha512_256.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2024 Matt Borland
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt

#include <boost/crypt2/hash/sha512_256.hpp>
#include <iostream>
#include <exception>
#include <string>

extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, std::size_t size)
{
try
{
auto c_data = reinterpret_cast<const char*>(data);
std::string c_data_str {c_data, size}; // Guarantee null termination since we can't pass the size argument

boost::crypt::sha512_256(c_data_str);

std::string_view view {c_data_str};
boost::crypt::sha512_256(view);

std::span data_span {c_data, size};
boost::crypt::sha512_256(data_span);

// Fuzz the hasher object
boost::crypt::sha512_256_hasher hasher;
hasher.process_bytes(data_span);
hasher.process_bytes(data_span);
hasher.process_bytes(data_span);
hasher.finalize();
[[maybe_unused]] const auto res = hasher.get_digest();
hasher.process_bytes(data_span); // State is invalid but should not crash
}
catch(...)
{
std::cerr << "Error with: " << data << std::endl;
std::terminate();
}

return 0;
}
92 changes: 92 additions & 0 deletions include/boost/crypt2/hash/sha512_256.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright 2024 - 2025 Matt Borland
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
//
// See: https://datatracker.ietf.org/doc/html/rfc4634
// See: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf

#ifndef BOOST_CRYPT2_HASH_SHA512_256_HPP
#define BOOST_CRYPT2_HASH_SHA512_256_HPP

#include <boost/crypt2/hash/detail/sha512_base.hpp>
#include <boost/crypt2/detail/file_reader.hpp>
#include <boost/crypt2/detail/compat.hpp>
#include <boost/crypt2/detail/concepts.hpp>

namespace boost::crypt {

BOOST_CRYPT_EXPORT using sha512_256_hasher = hash_detail::sha512_base<32U>;

// One shot functions
[[nodiscard]] BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
auto sha512_256(compat::span<const compat::byte> data) noexcept -> compat::expected<sha512_256_hasher::return_type, state>
{
sha512_256_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 sha512_256(SizedRange&& data) noexcept -> compat::expected<sha512_256_hasher::return_type, state>
{
sha512_256_hasher hasher;
hasher.process_bytes(data);
hasher.finalize();
return hasher.get_digest();
}

#ifndef BOOST_CRYPT_HAS_CUDA

// Error: the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information [-Werror,-Wunsafe-buffer-usage-in-container]
// Since this is the way the file streams report sizing information we must use it
// If a bad read occurs an exception is thrown so there's little risk of a bad region
#if defined(__clang__) && __clang_major__ >= 19
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-container"
#endif

namespace detail {

[[nodiscard]] inline auto sha512_256_file_impl(detail::file_reader<64U>& reader) -> compat::expected<sha512_256_hasher::return_type, state>
{
sha512_256_hasher hasher;
while (!reader.eof())
{
const auto buffer_iter {reader.read_next_block()};
const auto len {reader.get_bytes_read()};
const auto buffer_span {std::span(buffer_iter, len)};
hasher.process_bytes(buffer_span);
}

hasher.finalize();
return hasher.get_digest();
}

} // namespace detail

template <concepts::file_system_path T>
[[nodiscard]] BOOST_CRYPT_EXPORT inline auto sha512_256_file(const T& filepath) -> compat::expected<sha512_256_hasher::return_type, state>
{
if constexpr (std::is_pointer_v<std::remove_cvref_t<T>>)
{
if (filepath == nullptr)
{
throw std::runtime_error("Invalid file path");
}
}

detail::file_reader<64U> reader(filepath);
return detail::sha512_256_file_impl(reader);
}

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

#endif

} // namespace boost::crypt

#endif //BOOST_CRYPT2_HASH_SHA512_256_HPP
6 changes: 3 additions & 3 deletions test/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ run test_sha256.cpp ;
run test_sha384.cpp ;
run test_sha512.cpp ;
run test_sha512_224.cpp ;
#run test_sha512_256.cpp ;
run test_sha512_256.cpp ;
#run test_sha3_512.cpp ;
#run test_sha3_384.cpp ;
#run test_sha3_256.cpp ;
Expand Down Expand Up @@ -118,8 +118,8 @@ run test_nist_cavs_sha512_224_short_long.cpp ;
#run test_nist_cavs_sha512_224_hmac_drbg.cpp ;
#run test_nist_cavs_sha512_224_hash_drbg.cpp ;

#run test_nist_cavs_sha512_256_monte.cpp ;
#run test_nist_cavs_sha512_256_short_long.cpp ;
run test_nist_cavs_sha512_256_monte.cpp ;
run test_nist_cavs_sha512_256_short_long.cpp ;
#run test_nist_cavs_sha512_256_hmac.cpp ;
#run test_nist_cavs_sha512_256_hmac_drbg.cpp ;
#run test_nist_cavs_sha512_256_hash_drbg.cpp ;
Expand Down
4 changes: 2 additions & 2 deletions test/test_nist_cavs_sha512_256_monte.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt

#include <boost/crypt/hash/sha512_256.hpp>
#include <boost/crypt2/hash/sha512_256.hpp>

#include "test_nist_cavs_detail.hpp"

auto main() -> int
{
bool result_is_ok { true };
bool result_is_ok { true };

{
nist::cavs::test_vector_container_type my_test_vectors_monte { };
Expand Down
2 changes: 1 addition & 1 deletion test/test_nist_cavs_sha512_256_short_long.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt

#include <boost/crypt/hash/sha512_256.hpp>
#include <boost/crypt2/hash/sha512_256.hpp>

#include "test_nist_cavs_detail.hpp"

Expand Down
Loading
Loading