Crypt: A Modern Cryptographic Module in C++20
Matt Borland and Chris Kormanyos
Overview
Description
Boost.Crypt is cryptographic module aiming for FIPS 140-3 certification. The primary goal of this library is to be the safest implemenation, not the fastest.
Warning
|
This library is currently uncertified |
The library is header-only, has no dependencies, and requires C++20.
Motivation
This library will be a ground-up, modern, and memory safe implementation of standard cryptographic routines. Since it is header only and has no dependencies it is trivial to integrate into any project. It also offers native CUDA support to massively parallelize these routines (such as hashing thousands of files simultaneously)
Use Cases
Anywhere where security is needed.
Supported Compilers
Boost.Crypt is tested natively on Ubuntu (x86_64, s390x, and aarch64), macOS (x86_64, and Apple Silicon), and Windows (x32 and x64); as well as emulated PPC64LE and STM32 using QEMU with the following compilers:
-
GCC 11 and later
-
Clang 15 and later
-
Visual Studio 2019 (14.2) and later
-
Intel OneAPI DPC++ 2024.2 and later
-
CUDA Toolkit 12.5 and later (Both NVCC and NVRTC)
Tested on Github Actions and Drone. Coverage can be found on Codecov.
API Reference
Namespace
-
compat
Any time you see the namespacecompat
it is an alias to eitherstd::
orcuda::std::
depending on the compiler being used
Types
-
boost::crypt::expected
- either an alias totl::expected
orcuda::std::expected
depending on context.
Structures and Classes
Hashers
SHA1
SHA2 Family of Hashers
SHA3 Family of Hashers
Extendable-Output Functions
Hash-Based Message Authentication Codes (HMAC)
Enums
Constants
-
None
Concepts
Macros
See: Configuration Macros
State
The state enum class
allows you to verify the validity of the state of an object.
The following are the possible states:
-
success
- The hasher is proceeding without issue -
null
- A null pointer was passed to hasher -
input_too_long
- The number of bytes passed to the hasher object has exceeded the range ofsize_t
-
insufficient_entropy
- The input entropy + nonce length is not at least 3/2 security strength -
out_of_memory
-ENOMEM
returned by memory allocation -
requires_reseed
- The number of cycles an object has been used exceeded the design amount -
uninitialized
- An object has not been initialized properly before use -
state_error
- A misuse has occurred such as a hasher object was not reinitialized after calling.get_digest()
. The simple solution is to call.init()
and try again.
namespace boost::crypt {
enum class state
{
success, // no issues
null, // nullptr as parameter
input_too_long, // input data too long (exceeded size_t)
insufficient_entropy, // Entropy + Nonce length was not at least 3/2 security strength
out_of_memory, // Memory exhaustion reported by a function
requires_reseed, // The number of cycles has exceeded the specified amount
uninitialized, // Random bits can not be provided since the generator is uninitialized
requested_too_many_bits, // 2^19 bits is all that's allowed per request
state_error // added more input after get_digest without re-init
};
} // namespace boost::crypt
SHA1
This library supports SHA1 as described in RFC 3174. There is a wide range of acceptable inputs for the base sha1 function:
Hashing Object
Lastly, there is also the ability to create a sha1 hashing object and feed it bytes as the user parses them. This class does not use any dynamic memory allocation.
namespace boost::crypt {
class sha1_hasher
{
public:
uisng return_type = compat::array<compat::byte, 20>;
// Initialize the hasher
BOOST_CRYPT_GPU_ENABLED constexpr void init() noexcept;
// Process bytes piecewise
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(compat::span<const compat::byte> data) noexcept;
template <concepts::sized_range Range>
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(Range&& data) noexcept;
// Finalize the calculation of the hash
BOOST_CRYPT_GPU_ENABLED constexpr state finalize() noexcept;
// Get the digest
[[nodiscard]] constexpr expected<return_type, state> get_digest() const noexcept;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR state get_digest(compat::span<compat::byte> data) const noexcept;
template <concepts::writable_output_range Range>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED state get_digest(Range&& data) const noexcept;
};
} // namespace boost::crypt
One-Shot Hashing Functions
namespace boost::crypt {
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED constexpr auto sha1(compat::span<const compat::byte> data) noexcept -> expected<sha1_hasher::return_type, state>;
template <concepts::sized_range SizedRange>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto sha1(SizedRange&& data) noexcept -> expected<sha1_hasher::return_type, state>;
} // namespace boost::crypt
File Hashing Functions
We also have the ability to scan files and return the sha1 value:
namespace boost::crypt {
template <concepts::file_system_path T>
[[nodiscard]] inline auto sha1_file(const T& filepath) -> expected<sha1_hasher::return_type, state>;
} // namespace boost::crypt
SHA224
This library supports sha224 as described in RFC 6234. There is a wide range of acceptable inputs for the base sha224 function:
Hashing Object
Lastly, there is also the ability to create a sha224 hashing object and feed it bytes as the user parses them. This class does not use any dynamic memory allocation.
namespace boost::crypt {
class sha224_hasher
{
public:
uisng return_type = compat::array<compat::byte, 28>;
// Initialize the hasher
BOOST_CRYPT_GPU_ENABLED constexpr void init() noexcept;
// Process bytes piecewise
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(compat::span<const compat::byte> data) noexcept;
template <concepts::sized_range Range>
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(Range&& data) noexcept;
// Finalize the calculation of the hash
BOOST_CRYPT_GPU_ENABLED constexpr state finalize() noexcept;
// Get the digest
[[nodiscard]] constexpr expected<return_type, state> get_digest() const noexcept;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR state get_digest(compat::span<compat::byte> data) const noexcept;
template <concepts::writable_output_range Range>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED state get_digest(Range&& data) const noexcept;
};
} // namespace boost::crypt
One-Shot Hashing Functions
namespace boost::crypt {
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED constexpr auto sha224(compat::span<const compat::byte> data) noexcept -> expected<sha224_hasher::return_type, state>;
template <concepts::sized_range SizedRange>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto sha224(SizedRange&& data) noexcept -> expected<sha224_hasher::return_type, state>;
} // namespace boost::crypt
File Hashing Functions
We also have the ability to scan files and return the sha224 value:
namespace boost::crypt {
template <concepts::file_system_path T>
[[nodiscard]] inline auto sha224_file(const T& filepath) -> expected<sha224_hasher::return_type, state>;
} // namespace boost::crypt
SHA256
This library supports sha256 as described in RFC 6234. There is a wide range of acceptable inputs for the base sha256 function:
Hashing Object
Lastly, there is also the ability to create a sha256 hashing object and feed it bytes as the user parses them. This class does not use any dynamic memory allocation.
namespace boost::crypt {
class sha256_hasher
{
public:
uisng return_type = compat::array<compat::byte, 32>;
// Initialize the hasher
BOOST_CRYPT_GPU_ENABLED constexpr void init() noexcept;
// Process bytes piecewise
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(compat::span<const compat::byte> data) noexcept;
template <concepts::sized_range Range>
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(Range&& data) noexcept;
// Finalize the calculation of the hash
BOOST_CRYPT_GPU_ENABLED constexpr state finalize() noexcept;
// Get the digest
[[nodiscard]] constexpr expected<return_type, state> get_digest() const noexcept;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR state get_digest(compat::span<compat::byte> data) const noexcept;
template <concepts::writable_output_range Range>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED state get_digest(Range&& data) const noexcept;
};
} // namespace boost::crypt
One-Shot Hashing Functions
namespace boost::crypt {
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED constexpr auto sha256(compat::span<const compat::byte> data) noexcept -> expected<sha256_hasher::return_type, state>;
template <concepts::sized_range SizedRange>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto sha256(SizedRange&& data) noexcept -> expected<sha256_hasher::return_type, state>;
} // namespace boost::crypt
File Hashing Functions
We also have the ability to scan files and return the sha256 value:
namespace boost::crypt {
template <concepts::file_system_path T>
[[nodiscard]] inline auto sha256_file(const T& filepath) -> expected<sha256_hasher::return_type, state>;
} // namespace boost::crypt
SHA384
This library supports sha384 as described in RFC 6234. There is a wide range of acceptable inputs for the base sha384 function:
Hashing Object
Lastly, there is also the ability to create a sha384 hashing object and feed it bytes as the user parses them. This class does not use any dynamic memory allocation.
namespace boost::crypt {
class sha384_hasher
{
public:
uisng return_type = compat::array<compat::byte, 48>;
// Initialize the hasher
BOOST_CRYPT_GPU_ENABLED constexpr void init() noexcept;
// Process bytes piecewise
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(compat::span<const compat::byte> data) noexcept;
template <concepts::sized_range Range>
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(Range&& data) noexcept;
// Finalize the calculation of the hash
BOOST_CRYPT_GPU_ENABLED constexpr state finalize() noexcept;
// Get the digest
[[nodiscard]] constexpr expected<return_type, state> get_digest() const noexcept;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR state get_digest(compat::span<compat::byte> data) const noexcept;
template <concepts::writable_output_range Range>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED state get_digest(Range&& data) const noexcept;
};
} // namespace boost::crypt
One-Shot Hashing Functions
namespace boost::crypt {
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED constexpr auto sha384(compat::span<const compat::byte> data) noexcept -> expected<sha384_hasher::return_type, state>;
template <concepts::sized_range SizedRange>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto sha384(SizedRange&& data) noexcept -> expected<sha384_hasher::return_type, state>;
} // namespace boost::crypt
File Hashing Functions
We also have the ability to scan files and return the sha384 value:
namespace boost::crypt {
template <concepts::file_system_path T>
[[nodiscard]] inline auto sha384_file(const T& filepath) -> expected<sha384_hasher::return_type, state>;
} // namespace boost::crypt
SHA512
This library supports sha512 as described in RFC 6234. There is a wide range of acceptable inputs for the base sha512 function:
Hashing Object
Lastly, there is also the ability to create a sha512 hashing object and feed it bytes as the user parses them. This class does not use any dynamic memory allocation.
namespace boost::crypt {
class sha512_hasher
{
public:
uisng return_type = compat::array<compat::byte, 64>;
// Initialize the hasher
BOOST_CRYPT_GPU_ENABLED constexpr void init() noexcept;
// Process bytes piecewise
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(compat::span<const compat::byte> data) noexcept;
template <concepts::sized_range Range>
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(Range&& data) noexcept;
// Finalize the calculation of the hash
BOOST_CRYPT_GPU_ENABLED constexpr state finalize() noexcept;
// Get the digest
[[nodiscard]] constexpr expected<return_type, state> get_digest() const noexcept;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR state get_digest(compat::span<compat::byte> data) const noexcept;
template <concepts::writable_output_range Range>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED state get_digest(Range&& data) const noexcept;
};
} // namespace boost::crypt
One-Shot Hashing Functions
namespace boost::crypt {
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED constexpr auto sha512(compat::span<const compat::byte> data) noexcept -> expected<sha512_hasher::return_type, state>;
template <concepts::sized_range SizedRange>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto sha512(SizedRange&& data) noexcept -> expected<sha512_hasher::return_type, state>;
} // namespace boost::crypt
File Hashing Functions
We also have the ability to scan files and return the sha512 value:
namespace boost::crypt {
template <concepts::file_system_path T>
[[nodiscard]] inline auto sha512_file(const T& filepath) -> expected<sha512_hasher::return_type, state>;
} // namespace boost::crypt
SHA512_224
This library supports sha512_224 as described in RFC 6234. There is a wide range of acceptable inputs for the base sha512_224 function:
Hashing Object
Lastly, there is also the ability to create a sha512_224 hashing object and feed it bytes as the user parses them. This class does not use any dynamic memory allocation.
namespace boost::crypt {
class sha512_224_hasher
{
public:
uisng return_type = compat::array<compat::byte, 28>;
// Initialize the hasher
BOOST_CRYPT_GPU_ENABLED constexpr void init() noexcept;
// Process bytes piecewise
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(compat::span<const compat::byte> data) noexcept;
template <concepts::sized_range Range>
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(Range&& data) noexcept;
// Finalize the calculation of the hash
BOOST_CRYPT_GPU_ENABLED constexpr state finalize() noexcept;
// Get the digest
[[nodiscard]] constexpr expected<return_type, state> get_digest() const noexcept;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR state get_digest(compat::span<compat::byte> data) const noexcept;
template <concepts::writable_output_range Range>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED state get_digest(Range&& data) const noexcept;
};
} // namespace boost::crypt
One-Shot Hashing Functions
namespace boost::crypt {
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED constexpr auto sha512_224(compat::span<const compat::byte> data) noexcept -> expected<sha512_224_hasher::return_type, state>;
template <concepts::sized_range SizedRange>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto sha512_224(SizedRange&& data) noexcept -> expected<sha512_224_hasher::return_type, state>;
} // namespace boost::crypt
File Hashing Functions
We also have the ability to scan files and return the sha512_224 value:
namespace boost::crypt {
template <concepts::file_system_path T>
[[nodiscard]] inline auto sha512_224_file(const T& filepath) -> expected<sha512_224_hasher::return_type, state>;
} // namespace boost::crypt
SHA512_256
This library supports sha512_256 as described in RFC 6234. There is a wide range of acceptable inputs for the base sha512_256 function:
Hashing Object
Lastly, there is also the ability to create a sha512_256 hashing object and feed it bytes as the user parses them. This class does not use any dynamic memory allocation.
namespace boost::crypt {
class sha512_256_hasher
{
public:
uisng return_type = compat::array<compat::byte, 28>;
// Initialize the hasher
BOOST_CRYPT_GPU_ENABLED constexpr void init() noexcept;
// Process bytes piecewise
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(compat::span<const compat::byte> data) noexcept;
template <concepts::sized_range Range>
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(Range&& data) noexcept;
// Finalize the calculation of the hash
BOOST_CRYPT_GPU_ENABLED constexpr state finalize() noexcept;
// Get the digest
[[nodiscard]] constexpr expected<return_type, state> get_digest() const noexcept;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR state get_digest(compat::span<compat::byte> data) const noexcept;
template <concepts::writable_output_range Range>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED state get_digest(Range&& data) const noexcept;
};
} // namespace boost::crypt
One-Shot Hashing Functions
namespace boost::crypt {
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED constexpr auto sha512_256(compat::span<const compat::byte> data) noexcept -> expected<sha512_256_hasher::return_type, state>;
template <concepts::sized_range SizedRange>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto sha512_256(SizedRange&& data) noexcept -> expected<sha512_256_hasher::return_type, state>;
} // namespace boost::crypt
File Hashing Functions
We also have the ability to scan files and return the sha512_256 value:
namespace boost::crypt {
template <concepts::file_system_path T>
[[nodiscard]] inline auto sha512_256_file(const T& filepath) -> expected<sha512_256_hasher::return_type, state>;
} // namespace boost::crypt
SHA3_224
This library supports sha3_224 as described in SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions. There is a wide range of acceptable inputs for the base sha3_224 function:
Hashing Object
Lastly, there is also the ability to create a sha3_224 hashing object and feed it bytes as the user parses them. This class does not use any dynamic memory allocation.
namespace boost::crypt {
class sha3_224_hasher
{
public:
uisng return_type = compat::array<compat::byte, 28U>;
// Initialize the hasher
BOOST_CRYPT_GPU_ENABLED constexpr void init() noexcept;
// Process bytes piecewise
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(compat::span<const compat::byte> data) noexcept;
template <concepts::sized_range Range>
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(Range&& data) noexcept;
// Finalize the calculation of the hash
BOOST_CRYPT_GPU_ENABLED constexpr state finalize() noexcept;
// Get the digest
[[nodiscard]] constexpr expected<return_type, state> get_digest() const noexcept;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR state get_digest(compat::span<compat::byte> data) const noexcept;
template <concepts::writable_output_range Range>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED state get_digest(Range&& data) const noexcept;
};
} // namespace boost::crypt
One-Shot Hashing Functions
namespace boost::crypt {
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED constexpr auto sha3_224(compat::span<const compat::byte> data) noexcept -> expected<sha3_224_hasher::return_type, state>;
template <concepts::sized_range SizedRange>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto sha3_224(SizedRange&& data) noexcept -> expected<sha3_224_hasher::return_type, state>;
} // namespace boost::crypt
File Hashing Functions
We also have the ability to scan files and return the sha3_224 value:
namespace boost::crypt {
template <concepts::file_system_path T>
[[nodiscard]] inline auto sha3_224_file(const T& filepath) -> expected<sha3_224_hasher::return_type, state>;
} // namespace boost::crypt
SHA3_256
This library supports sha3_256 as described in SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions. There is a wide range of acceptable inputs for the base sha3_256 function:
Hashing Object
Lastly, there is also the ability to create a sha3_256 hashing object and feed it bytes as the user parses them. This class does not use any dynamic memory allocation.
namespace boost::crypt {
class sha3_256_hasher
{
public:
uisng return_type = compat::array<compat::byte, 32U>;
// Initialize the hasher
BOOST_CRYPT_GPU_ENABLED constexpr void init() noexcept;
// Process bytes piecewise
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(compat::span<const compat::byte> data) noexcept;
template <concepts::sized_range Range>
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(Range&& data) noexcept;
// Finalize the calculation of the hash
BOOST_CRYPT_GPU_ENABLED constexpr state finalize() noexcept;
// Get the digest
[[nodiscard]] constexpr expected<return_type, state> get_digest() const noexcept;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR state get_digest(compat::span<compat::byte> data) const noexcept;
template <concepts::writable_output_range Range>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED state get_digest(Range&& data) const noexcept;
};
} // namespace boost::crypt
One-Shot Hashing Functions
namespace boost::crypt {
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED constexpr auto sha3_256(compat::span<const compat::byte> data) noexcept -> expected<sha3_256_hasher::return_type, state>;
template <concepts::sized_range SizedRange>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto sha3_256(SizedRange&& data) noexcept -> expected<sha3_256_hasher::return_type, state>;
} // namespace boost::crypt
File Hashing Functions
We also have the ability to scan files and return the sha3_256 value:
namespace boost::crypt {
template <concepts::file_system_path T>
[[nodiscard]] inline auto sha3_256_file(const T& filepath) -> expected<sha3_256_hasher::return_type, state>;
} // namespace boost::crypt
SHA3_384
This library supports sha3_384 as described in SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions. There is a wide range of acceptable inputs for the base sha3_384 function:
Hashing Object
Lastly, there is also the ability to create a sha3_384 hashing object and feed it bytes as the user parses them. This class does not use any dynamic memory allocation.
namespace boost::crypt {
class sha3_384_hasher
{
public:
uisng return_type = compat::array<compat::byte, 48U>;
// Initialize the hasher
BOOST_CRYPT_GPU_ENABLED constexpr void init() noexcept;
// Process bytes piecewise
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(compat::span<const compat::byte> data) noexcept;
template <concepts::sized_range Range>
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(Range&& data) noexcept;
// Finalize the calculation of the hash
BOOST_CRYPT_GPU_ENABLED constexpr state finalize() noexcept;
// Get the digest
[[nodiscard]] constexpr expected<return_type, state> get_digest() const noexcept;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR state get_digest(compat::span<compat::byte> data) const noexcept;
template <concepts::writable_output_range Range>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED state get_digest(Range&& data) const noexcept;
};
} // namespace boost::crypt
One-Shot Hashing Functions
namespace boost::crypt {
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED constexpr auto sha3_384(compat::span<const compat::byte> data) noexcept -> expected<sha3_384_hasher::return_type, state>;
template <concepts::sized_range SizedRange>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto sha3_384(SizedRange&& data) noexcept -> expected<sha3_384_hasher::return_type, state>;
} // namespace boost::crypt
File Hashing Functions
We also have the ability to scan files and return the sha3_384 value:
namespace boost::crypt {
template <concepts::file_system_path T>
[[nodiscard]] inline auto sha3_384_file(const T& filepath) -> expected<sha3_384_hasher::return_type, state>;
} // namespace boost::crypt
SHA3_512
This library supports sha3_512 as described in SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions. There is a wide range of acceptable inputs for the base sha3_512 function:
Hashing Object
Lastly, there is also the ability to create a sha3_512 hashing object and feed it bytes as the user parses them. This class does not use any dynamic memory allocation.
namespace boost::crypt {
class sha3_512_hasher
{
public:
uisng return_type = compat::array<compat::byte, 64U>;
// Initialize the hasher
BOOST_CRYPT_GPU_ENABLED constexpr void init() noexcept;
// Process bytes piecewise
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(compat::span<const compat::byte> data) noexcept;
template <concepts::sized_range Range>
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(Range&& data) noexcept;
// Finalize the calculation of the hash
BOOST_CRYPT_GPU_ENABLED constexpr state finalize() noexcept;
// Get the digest
[[nodiscard]] constexpr expected<return_type, state> get_digest() const noexcept;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR state get_digest(compat::span<compat::byte> data) const noexcept;
template <concepts::writable_output_range Range>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED state get_digest(Range&& data) const noexcept;
};
} // namespace boost::crypt
One-Shot Hashing Functions
namespace boost::crypt {
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED constexpr auto sha3_512(compat::span<const compat::byte> data) noexcept -> expected<sha3_512_hasher::return_type, state>;
template <concepts::sized_range SizedRange>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto sha3_512(SizedRange&& data) noexcept -> expected<sha3_512_hasher::return_type, state>;
} // namespace boost::crypt
File Hashing Functions
We also have the ability to scan files and return the sha3_512 value:
namespace boost::crypt {
template <concepts::file_system_path T>
[[nodiscard]] inline auto sha3_512_file(const T& filepath) -> expected<sha3_512_hasher::return_type, state>;
} // namespace boost::crypt
SHAKE128
This library supports shake128 as described in SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions. There is a wide range of acceptable inputs for the base shake128 function:
Hashing Object
Lastly, there is also the ability to create a shake128 hashing object and feed it bytes as the user parses them. This class does not use any dynamic memory allocation.
namespace boost::crypt {
class shake128_hasher
{
public:
uisng return_type = compat::array<compat::byte, 16U>;
// Initialize the hasher
BOOST_CRYPT_GPU_ENABLED constexpr void init() noexcept;
// Process bytes piecewise
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(compat::span<const compat::byte> data) noexcept;
template <concepts::sized_range Range>
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(Range&& data) noexcept;
// Finalize the calculation of the hash
BOOST_CRYPT_GPU_ENABLED constexpr state finalize() noexcept;
// Get the digest including variable length output
[[nodiscard]] constexpr expected<return_type, state> get_digest() noexcept;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR state get_digest(compat::span<compat::byte> data) noexcept;
template <concepts::writable_output_range Range>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED state get_digest(Range&& data) noexcept;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR state get_digest(compat::span<compat::byte> data, compat::size_t amount) noexcept;
template <concepts::writable_output_range Range>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED state get_digest(Range&& data, compat::size_t amount) noexcept;
};
} // namespace boost::crypt
Important
|
The get_digest methods here are not marked const as each time you call get_digest the state is updated and you will receive a different digest.
|
When a container is passed without the amount
parameter passed the hasher will fill the complete span or range being passed.
One-Shot Hashing Functions
namespace boost::crypt {
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED constexpr auto shake128(compat::span<const compat::byte> data) noexcept -> expected<shake128_hasher::return_type, state>;
template <concepts::sized_range SizedRange>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto shake128(SizedRange&& data) noexcept -> expected<shake128_hasher::return_type, state>;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED constexpr auto shake128(compat::span<const compat::byte> data, compat::span<compat::byte> return_container) noexcept -> expected<shake128_hasher::return_type, state>;
template <concepts::sized_range SizedRange, concepts::writeable_output_range OutputRange>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto shake128(SizedRange&& data, OutputRange&& output) noexcept -> expected<shake128_hasher::return_type, state>;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED constexpr auto shake128(compat::span<const compat::byte> data, compat::span<compat::byte> return_container, compat::size_t amount) noexcept -> expected<shake128_hasher::return_type, state>;
template <concepts::sized_range SizedRange, concepts::writeable_output_range OutputRange>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto shake128(SizedRange&& data, OutputRange&& output, std::size_t amount) noexcept -> expected<shake128_hasher::return_type, state>;
} // namespace boost::crypt
File Hashing Functions
We also have the ability to scan files and return the shake128 value:
namespace boost::crypt {
template <concepts::file_system_path T>
[[nodiscard]] inline auto shake128_file(const T& filepath) -> expected<shake128_hasher::return_type, state>;
template <concepts::file_system_path T, std::size_t Extent = std::dynamic_extent>
[[nodiscard]] inline auto shake128_file(const T& filepath, std::span<std::byte, Extent> out) -> state;
template <concepts::file_system_path T, std::size_t Extent = std::dynamic_extent>
[[nodiscard]] inline auto shake128_file(const T& filepath, std::span<std::byte, Extent> out, std::size_t amount) -> state;
template <concepts::file_system_path T, concepts::writeable_output_range OutputRange>
[[nodiscard]] inline auto shake128_file(const T& filepath, OutputRange&& out) -> state;
template <concepts::file_system_path T, concepts::writeable_output_range OutputRange>
[[nodiscard]] inline auto shake128_file(const T& filepath, OutputRange&& out, std::size_t amount) -> state;
} // namespace boost::crypt
SHAKE128
This library supports shake256 as described in SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions. There is a wide range of acceptable inputs for the base shake256 function:
Hashing Object
Lastly, there is also the ability to create a shake256 hashing object and feed it bytes as the user parses them. This class does not use any dynamic memory allocation.
namespace boost::crypt {
class shake256_hasher
{
public:
uisng return_type = compat::array<compat::byte, 32U>;
// Initialize the hasher
BOOST_CRYPT_GPU_ENABLED constexpr void init() noexcept;
// Process bytes piecewise
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(compat::span<const compat::byte> data) noexcept;
template <concepts::sized_range Range>
BOOST_CRYPT_GPU_ENABLED constexpr state process_bytes(Range&& data) noexcept;
// Finalize the calculation of the hash
BOOST_CRYPT_GPU_ENABLED constexpr state finalize() noexcept;
// Get the digest including variable length output
[[nodiscard]] constexpr expected<return_type, state> get_digest() noexcept;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR state get_digest(compat::span<compat::byte> data) noexcept;
template <concepts::writable_output_range Range>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED state get_digest(Range&& data) noexcept;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR state get_digest(compat::span<compat::byte> data, compat::size_t amount) noexcept;
template <concepts::writable_output_range Range>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED state get_digest(Range&& data, compat::size_t amount) noexcept;
};
} // namespace boost::crypt
Important
|
The get_digest methods here are not marked const as each time you call get_digest the state is updated and you will receive a different digest.
|
When a container is passed without the amount
parameter passed the hasher will fill the complete span or range being passed.
One-Shot Hashing Functions
namespace boost::crypt {
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED constexpr auto shake256(compat::span<const compat::byte> data) noexcept -> expected<shake256_hasher::return_type, state>;
template <concepts::sized_range SizedRange>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto shake256(SizedRange&& data) noexcept -> expected<shake256_hasher::return_type, state>;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED constexpr auto shake256(compat::span<const compat::byte> data, compat::span<compat::byte> return_container) noexcept -> expected<shake256_hasher::return_type, state>;
template <concepts::sized_range SizedRange, concepts::writeable_output_range OutputRange>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto shake256(SizedRange&& data, OutputRange&& output) noexcept -> expected<shake256_hasher::return_type, state>;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED constexpr auto shake256(compat::span<const compat::byte> data, compat::span<compat::byte> return_container, compat::size_t amount) noexcept -> expected<shake256_hasher::return_type, state>;
template <concepts::sized_range SizedRange, concepts::writeable_output_range OutputRange>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto shake256(SizedRange&& data, OutputRange&& output, std::size_t amount) noexcept -> expected<shake256_hasher::return_type, state>;
} // namespace boost::crypt
File Hashing Functions
We also have the ability to scan files and return the shake256 value:
namespace boost::crypt {
template <concepts::file_system_path T>
[[nodiscard]] inline auto shake256_file(const T& filepath) -> expected<shake256_hasher::return_type, state>;
template <concepts::file_system_path T, std::size_t Extent = std::dynamic_extent>
[[nodiscard]] inline auto shake256_file(const T& filepath, std::span<std::byte, Extent> out) -> state;
template <concepts::file_system_path T, std::size_t Extent = std::dynamic_extent>
[[nodiscard]] inline auto shake256_file(const T& filepath, std::span<std::byte, Extent> out, std::size_t amount) -> state;
template <concepts::file_system_path T, concepts::writeable_output_range OutputRange>
[[nodiscard]] inline auto shake256_file(const T& filepath, OutputRange&& out) -> state;
template <concepts::file_system_path T, concepts::writeable_output_range OutputRange>
[[nodiscard]] inline auto shake256_file(const T& filepath, OutputRange&& out, std::size_t amount) -> state;
} // namespace boost::crypt
HMAC
This library provides a robust implementation of HMAC (Hash-based Message Authentication Code) as specified in RFC 2104. HMAC is a widely used mechanism for message authentication that combines a cryptographic hash function with a secret key to ensure data integrity and authenticity.
Overview
HMAC is designed to provide a secure way to verify both the data integrity and the authenticity of a message. It uses a hash function (such as SHA-256, SHA-3/512, etc.) in combination with a secret key to generate a message authentication code (MAC). The MAC can then be used to verify that the message has not been altered and that it comes from an authenticated sender.
Template Class Implementation
Our HMAC implementation is designed as a template class, allowing it to work seamlessly with any of our hashers. This flexibility means you can choose the most appropriate hashing algorithm for your specific use case without needing to modify the HMAC code itself. Here’s how you might instantiate and use the HMAC class:
boost::crypt::hmac<boost::crypt::sha512_hasher> hmac;
const auto state_1 {hmac.init("key", 3)};
BOOST_TEST(state_1 == boost::crypt::state::success);
std::string msg {"The quick brown fox jumps over the lazy dog"};
const auto state_2 {hmac.process_bytes(msg)};
BOOST_TEST(state_2 == boost::crypt::state::success);
hmac.finalize();
const auto res {hmac.get_digest()};
Key Recovery and Reuse
One of the unique features of our HMAC implementation is the ability to recover the inner and outer keys after initialization. This can be useful in scenarios where you need to compute HMACs for short messages repeatedly, as it allows you to avoid recalculating these keys each time.
Continuing from our above example:
boost::crypt::hmac<boost::crypt::sha512_hasher> hmac;
const auto state_1 {hmac.init(std::string{"key"})};
BOOST_TEST(state_1 == boost::crypt::state::success);
std::string msg {"The quick brown fox jumps over the lazy dog"};
const auto state_2 {hmac.process_bytes(msg)};
BOOST_TEST(state_2 == boost::crypt::state::success);
BOOST_TEST(hmac.finalize() == boost::crypt::state::success);
const auto res {hmac.get_digest()};
const auto outer_key {hmac.get_outer_key()};
const auto inner_key {hmac.get_inner_key()};
// Do some stuff
boost::crypt::hmac<boost::crypt::sha512_hasher> hmac2;
hmac2.init_from_keys(inner_key, outer_key);
std::string msg2 {"The quick brown fox jumps over the lazy dog"};
const auto state_3 {hmac2.process_bytes(msg)};
BOOST_TEST(state_3 == boost::crypt::state::success);
hmac2.finalize();
const auto res2 {hmac2.get_digest()};
Security Considerations
It is crucial to treat the inner and outer keys with the same level of security as the original secret key. These keys should be stored securely and not exposed to unauthorized parties. By providing this flexibility and functionality, our HMAC implementation aims to offer a secure, efficient, and versatile solution for message authentication in your applications.
Reference
namespace boost {
namespace crypt {
BOOST_CRYPT_EXPORT template <typename HasherType>
class hmac
{
public:
static constexpr boost::crypt::size_t block_size {HasherType::block_size};
using return_type = typename HasherType::return_type;
using key_type = compat::array<compat::byte, block_size>;
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR hmac() noexcept = default;
template <compat::size_t Extent = compat::dynamic_extent>
explicit BOOST_CRYPT_GPU_ENABLED_CONSTEXPR hmac(const compat::span<const compat::byte, Extent> key) noexcept;
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR ~hmac() noexcept;
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto init_from_keys(const key_type& inner_key,
const key_type& outer_key) noexcept -> state;
template <compat::size_t Extent = compat::dynamic_extent>
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto init(compat::span<const compat::byte, Extent> data) noexcept -> state;
template <concepts::sized_range SizedRange>
BOOST_CRYPT_GPU_ENABLED auto init(SizedRange&& 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;
BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto finalize() noexcept -> state;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto get_digest() const noexcept -> compat::expected<return_type, state>;
template <compat::size_t Extent = compat::dynamic_extent>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR
auto get_digest(compat::span<compat::byte, Extent> data) const noexcept -> state;
template <concepts::writable_output_range Range>
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED auto get_digest(Range&& data) const noexcept -> state;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto get_outer_key() const noexcept -> key_type;
[[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto get_inner_key() const noexcept -> key_type;
} //namespace crypt
} //namespace boost
Concepts
The following are the definitions of the concepts used throughout the library to ensure consistency.
File System Path
Used for the one-shot hashing of files.
Allows a diverse range of ways to specify the file path.
This concept is disabled on CUDA because there is no std::ifstream
on that platform.
namespace boost::crypt::concepts {
#ifndef BOOST_CRYPT_HAS_CUDA
template <typename T>
concept file_system_path =
std::is_convertible_v<T, std::string> ||
std::is_convertible_v<T, std::string_view> ||
std::is_convertible_v<T, const char*> ||
std::is_same_v<std::remove_cvref_t<T>, std::filesystem::path> ||
std::is_same_v<std::remove_cvref_t<T>, char*>;
#endif
} // namespace boost::crypt::concepts
Writeable Output Range
This concept is used to define the ranges that we can write to such as the get_digest(Range&& data)
function of the hashers.
namespace boost::crypt::concepts {
template <typename Range>
concept writable_output_range = compat::output_range<Range, compat::range_value_t<Range>> &&
compat::sized_range<Range> &&
compat::is_trivially_copyable_v<compat::range_value_t<Range>>;
} // namespace boost::crypt::concepts
Configuration Macros
User Configurable Macros
-
None at this time
Automatic Configuration Macros
-
BOOST_CRYPT_HAS_CUDA
: This is defined when compiling with NVCC regardless of the host compiler.
References
The following books, papers and blog posts serve as the basis for the algorithms used in the library:
-
Ronald L. Rivest, RFC 1321: The MD5 Message-Digest Algorithm, 1992
-
Donald E. Eastlake and Paul E. Jones, RFC 3174: US Secure Hash Algorithm 1 (SHA1), 2001
-
Donald E. Eastlake and Tony Hansen, RFC 6234: US Secure Hash Algorithms, 2011
-
National Institute of Standards and Technology (NIST), FIPS PUB 180-4: Secure Hash Standard (SHS), 2015
-
National Institute of Standards and Technology (NIST), FIPS PUB 140-3: Security Requirements for Cryptographic Modules, 2019
Copyright and License
This documentation is copyright 2024 - 2025 Matt Borland and Chris Kormanyos and is distributed under the Boost Software License, Version 1.0.