Skip to content

Commit

Permalink
Merge pull request #72 from cppalliance/SHA3-224
Browse files Browse the repository at this point in the history
Add SHA3-224
  • Loading branch information
mborland authored Oct 30, 2024
2 parents 2e17627 + df9905d commit b3bdd9d
Show file tree
Hide file tree
Showing 13 changed files with 2,439 additions and 0 deletions.
46 changes: 46 additions & 0 deletions fuzzing/fuzz_sha3_224.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2024 Matt Borland
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt

#include <boost/crypt/hash/sha3_224.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::sha3_224(c_data_str);
boost::crypt::sha3_224(c_data, size);
boost::crypt::sha3_224(data, size);

#ifdef BOOST_CRYPT_HAS_STRING_VIEW
std::string_view view {c_data_str};
boost::crypt::sha3_224(view);
#endif

#ifdef BOOST_CRYPT_HAS_SPAN
std::span data_span {c_data, size};
boost::crypt::sha3_224(data_span);
#endif

// Fuzz the hasher object
boost::crypt::sha3_224_hasher hasher;
hasher.process_bytes(data, size);
hasher.process_bytes(data, size);
hasher.process_bytes(data, size);
hasher.get_digest();
hasher.process_bytes(data, size); // State is invalid but should not crash
}
catch(...)
{
std::cerr << "Error with: " << data << std::endl;
std::terminate();
}

return 0;
}
18 changes: 18 additions & 0 deletions fuzzing/seedcorpus/fuzz_sha3_224/sha3_224.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"The quick brown fox jumps over the lazy dog"
"The quick brown fox jumps over the lazy dog."
""
"aB3$x9Yz"
"12345"
"!@#$%^&*()"
"FuzzTest123"
" "
"Lorem ipsum dolor sit amet"
"a"
"9876543210"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"ñÑáéíóúÁÉÍÓÚ"
"\n\r\t"
"0"
"ThisIsAVeryLongStringWithNoSpacesOrPunctuationToTestEdgeCases"
"<?php echo 'test'; ?>"
"SELECT * FROM users;"
298 changes: 298 additions & 0 deletions include/boost/crypt/hash/sha3_224.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,298 @@
// Copyright 2024 Matt Borland
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt


#ifndef BOOST_CRYPT_HASH_SHA3_224_HPP
#define BOOST_CRYPT_HASH_SHA3_224_HPP

#include <boost/crypt/hash/detail/sha3_base.hpp>

namespace boost {
namespace crypt {

BOOST_CRYPT_EXPORT using sha3_224_hasher = hash_detail::sha3_base<28U>;

namespace detail {

template <typename T>
BOOST_CRYPT_GPU_ENABLED constexpr auto sha3_224(T begin, T end) noexcept -> sha3_224_hasher::return_type
{
if (end < begin)
{
return sha3_224_hasher::return_type {};
}
else if (end == begin)
{
return sha3_224_hasher::return_type {
0x6b, 0x4e, 0x03, 0x42, 0x36, 0x67, 0xdb,
0xb7, 0x3b, 0x6e, 0x15, 0x45, 0x4f, 0x0e,
0xb1, 0xab, 0xd4, 0x59, 0x7f, 0x9a, 0x1b,
0x07, 0x8e, 0x3f, 0x5b, 0x5a, 0x6b, 0xc7
};
}

sha3_224_hasher hasher;
hasher.process_bytes(begin, static_cast<boost::crypt::size_t>(end - begin));
auto result {hasher.get_digest()};

return result;
}

} // namespace detail

BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED constexpr auto sha3_224(const char* str) noexcept -> sha3_224_hasher::return_type
{
if (str == nullptr)
{
return sha3_224_hasher::return_type{}; // LCOV_EXCL_LINE
}

const auto message_len {utility::strlen(str)};
return detail::sha3_224(str, str + message_len);
}

BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED constexpr auto sha3_224(const char* str, boost::crypt::size_t len) noexcept -> sha3_224_hasher::return_type
{
if (str == nullptr)
{
return sha3_224_hasher::return_type{}; // LCOV_EXCL_LINE
}

return detail::sha3_224(str, str + len);
}

BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED constexpr auto sha3_224(const boost::crypt::uint8_t* str) noexcept -> sha3_224_hasher::return_type
{
if (str == nullptr)
{
return sha3_224_hasher::return_type{}; // LCOV_EXCL_LINE
}

const auto message_len {utility::strlen(str)};
return detail::sha3_224(str, str + message_len);
}

BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED constexpr auto sha3_224(const boost::crypt::uint8_t* str, boost::crypt::size_t len) noexcept -> sha3_224_hasher::return_type
{
if (str == nullptr)
{
return sha3_224_hasher::return_type{}; // LCOV_EXCL_LINE
}

return detail::sha3_224(str, str + len);
}

BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED constexpr auto sha3_224(const char16_t* str) noexcept -> sha3_224_hasher::return_type
{
if (str == nullptr)
{
return sha3_224_hasher::return_type{}; // LCOV_EXCL_LINE
}

const auto message_len {utility::strlen(str)};
return detail::sha3_224(str, str + message_len);
}

BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED constexpr auto sha3_224(const char16_t* str, boost::crypt::size_t len) noexcept -> sha3_224_hasher::return_type
{
if (str == nullptr)
{
return sha3_224_hasher::return_type{}; // LCOV_EXCL_LINE
}

return detail::sha3_224(str, str + len);
}

BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED constexpr auto sha3_224(const char32_t* str) noexcept -> sha3_224_hasher::return_type
{
if (str == nullptr)
{
return sha3_224_hasher::return_type{}; // LCOV_EXCL_LINE
}

const auto message_len {utility::strlen(str)};
return detail::sha3_224(str, str + message_len);
}

BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED constexpr auto sha3_224(const char32_t* str, boost::crypt::size_t len) noexcept -> sha3_224_hasher::return_type
{
if (str == nullptr)
{
return sha3_224_hasher::return_type{}; // LCOV_EXCL_LINE
}

return detail::sha3_224(str, str + len);
}

// On some platforms wchar_t is 16 bits and others it's 32
// Since we check sizeof() the underlying with SFINAE in the actual implementation this is handled transparently
BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED constexpr auto sha3_224(const wchar_t* str) noexcept -> sha3_224_hasher::return_type
{
if (str == nullptr)
{
return sha3_224_hasher::return_type{}; // LCOV_EXCL_LINE
}

const auto message_len {utility::strlen(str)};
return detail::sha3_224(str, str + message_len);
}

BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED constexpr auto sha3_224(const wchar_t* str, boost::crypt::size_t len) noexcept -> sha3_224_hasher::return_type
{
if (str == nullptr)
{
return sha3_224_hasher::return_type{}; // LCOV_EXCL_LINE
}

return detail::sha3_224(str, str + len);
}

// ----- String and String view aren't in the libcu++ STL so they so not have device markers -----

#ifndef BOOST_CRYPT_HAS_CUDA

BOOST_CRYPT_EXPORT inline auto sha3_224(const std::string& str) noexcept -> sha3_224_hasher::return_type
{
return detail::sha3_224(str.begin(), str.end());
}

BOOST_CRYPT_EXPORT inline auto sha3_224(const std::u16string& str) noexcept -> sha3_224_hasher::return_type
{
return detail::sha3_224(str.begin(), str.end());
}

BOOST_CRYPT_EXPORT inline auto sha3_224(const std::u32string& str) noexcept -> sha3_224_hasher::return_type
{
return detail::sha3_224(str.begin(), str.end());
}

BOOST_CRYPT_EXPORT inline auto sha3_224(const std::wstring& str) noexcept -> sha3_224_hasher::return_type
{
return detail::sha3_224(str.begin(), str.end());
}

#ifdef BOOST_CRYPT_HAS_STRING_VIEW

BOOST_CRYPT_EXPORT constexpr auto sha3_224(std::string_view str) -> sha3_224_hasher::return_type
{
return detail::sha3_224(str.begin(), str.end());
}

BOOST_CRYPT_EXPORT constexpr auto sha3_224(std::u16string_view str) -> sha3_224_hasher::return_type
{
return detail::sha3_224(str.begin(), str.end());
}

BOOST_CRYPT_EXPORT constexpr auto sha3_224(std::u32string_view str) -> sha3_224_hasher::return_type
{
return detail::sha3_224(str.begin(), str.end());
}

BOOST_CRYPT_EXPORT constexpr auto sha3_224(std::wstring_view str) -> sha3_224_hasher::return_type
{
return detail::sha3_224(str.begin(), str.end());
}

#endif // BOOST_CRYPT_HAS_STRING_VIEW

// ---- CUDA also does not have the ability to consume files -----

namespace detail {

template <boost::crypt::size_t block_size>
auto sha3_224_file_impl(utility::file_reader<block_size>& reader) noexcept -> sha3_224_hasher::return_type
{
sha3_224_hasher hasher;
while (!reader.eof())
{
const auto buffer_iter {reader.read_next_block()};
const auto len {reader.get_bytes_read()};
hasher.process_bytes(buffer_iter, len);
}

return hasher.get_digest();
}

} // namespace detail

#ifndef BOOST_CRYPT_DISABLE_IOSTREAM

BOOST_CRYPT_EXPORT inline auto sha3_224_file(const std::string& filepath) noexcept -> sha3_224_hasher::return_type
{
try
{
utility::file_reader<144U> reader(filepath);
return detail::sha3_224_file_impl(reader);
}
catch (const std::runtime_error&)
{
return sha3_224_hasher::return_type{};
}
}

BOOST_CRYPT_EXPORT inline auto sha3_224_file(const char* filepath) noexcept -> sha3_224_hasher::return_type
{
try
{
if (filepath == nullptr)
{
return sha3_224_hasher::return_type{};
}

utility::file_reader<144U> reader(filepath);
return detail::sha3_224_file_impl(reader);
}
catch (const std::runtime_error&)
{
return sha3_224_hasher::return_type{};
}
}

#endif // !BOOST_CRYPT_DISABLE_IOSTREAM

#if (defined(BOOST_CRYPT_HAS_STRING_VIEW) && !defined(BOOST_CRYPT_DISABLE_IOSTREAM))

BOOST_CRYPT_EXPORT inline auto sha3_224_file(std::string_view filepath) noexcept -> sha3_224_hasher::return_type
{
try
{
utility::file_reader<144U> reader(filepath);
return detail::sha3_224_file_impl(reader);
}
catch (const std::runtime_error&)
{
return sha3_224_hasher::return_type{};
}
}

#endif // BOOST_CRYPT_HAS_STRING_VIEW && !BOOST_CRYPT_DISABLE_IOSTREAM

#endif // BOOST_CRYPT_HAS_CUDA

// ---- The CUDA versions that we support all offer <cuda/std/span> ----

#ifdef BOOST_CRYPT_HAS_SPAN

BOOST_CRYPT_EXPORT template <typename T, std::size_t extent>
constexpr auto sha3_224(std::span<T, extent> data) noexcept -> sha3_224_hasher::return_type
{
return detail::sha3_224(data.begin(), data.end());
}

#endif // BOOST_CRYPT_HAS_SPAN

#ifdef BOOST_CRYPT_HAS_CUDA

template <typename T, boost::crypt::size_t extent>
BOOST_CRYPT_GPU_ENABLED constexpr auto sha3_224(cuda::std::span<T, extent> data) noexcept -> sha3_224_hasher::return_type
{
return detail::sha3_224(data.begin(), data.end());
}

#endif // BOOST_CRYPT_HAS_CUDA

} // namespace crypt
} // namespace boost

#endif // BOOST_CRYPT_HASH_SHA3_224_HPP
4 changes: 4 additions & 0 deletions test/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ run test_sha512_256.cpp ;
run test_sha3_512.cpp ;
run test_sha3_384.cpp ;
run test_sha3_256.cpp ;
run test_sha3_224.cpp ;

# NIST standard testing
run test_nist_cavs_sha1_monte.cpp ;
Expand Down Expand Up @@ -91,3 +92,6 @@ run test_nist_cavs_sha3_384_short_long.cpp ;

run test_nist_cavs_sha3_256_monte.cpp ;
run test_nist_cavs_sha3_256_short_long.cpp ;

run test_nist_cavs_sha3_224_monte.cpp ;
run test_nist_cavs_sha3_224_short_long.cpp ;
Loading

0 comments on commit b3bdd9d

Please sign in to comment.