diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 0000000..ff8f381 --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1,2 @@ +/pdf/ +/html/ diff --git a/doc/Jamfile b/doc/Jamfile new file mode 100644 index 0000000..65f8705 --- /dev/null +++ b/doc/Jamfile @@ -0,0 +1,25 @@ +# Copyright 2017, 2018 Peter Dimov +# Copyright 2024 Matt Borland +# Distributed under the Boost Software License, Version 1.0. +# https://www.boost.org/LICENSE_1_0.txt + +import asciidoctor ; + +html crypt.html : crypt.adoc + : /boost/boostlook//boostlook + crypt-docinfo-footer.html + ; + +install html_ : crypt.html : html ; + +pdf crypt.pdf : crypt.adoc ; +explicit crypt.pdf ; + +install pdf_ : crypt.pdf : pdf ; +explicit pdf_ ; + +############################################################################### +alias boostdoc ; +explicit boostdoc ; +alias boostrelease : html_ ; +explicit boostrelease ; diff --git a/doc/crypt-docinfo-footer.html b/doc/crypt-docinfo-footer.html new file mode 100644 index 0000000..622aa5f --- /dev/null +++ b/doc/crypt-docinfo-footer.html @@ -0,0 +1,6 @@ + diff --git a/doc/crypt.adoc b/doc/crypt.adoc new file mode 100644 index 0000000..093e482 --- /dev/null +++ b/doc/crypt.adoc @@ -0,0 +1,30 @@ +//// +Copyright 2024 Matt Borland +Distributed under the Boost Software License, Version 1.0. +https://www.boost.org/LICENSE_1_0.txt +//// + += Crypt: A Modern Cryptographic Module in C++14 +:toc: left +:toclevels: 4 +:idprefix: +:listing-caption: Code Example +:docinfo: private-footer +:source-highlighter: rouge +:source-language: c++ + +:leveloffset: +1 + +include::crypt/overview.adoc[] + +include::crypt/api_reference.adoc[] + +include::crypt/md5.adoc[] + +include::crypt/config.adoc[] + +include::crypt/reference.adoc[] + +include::crypt/copyright.adoc[] + +:leveloffset: -1 diff --git a/doc/crypt/api_reference.adoc b/doc/crypt/api_reference.adoc new file mode 100644 index 0000000..f4bb775 --- /dev/null +++ b/doc/crypt/api_reference.adoc @@ -0,0 +1,30 @@ +//// +Copyright 2024 Matt Borland +Distributed under the Boost Software License, Version 1.0. +https://www.boost.org/LICENSE_1_0.txt +//// + +[#api_reference] += API Reference +:idprefix: api_ref_ + +== Types + +- <> + +== Structures and Classes + +- <> +- <> + +== Enums + +- None + +== Constants + +- None + +== Macros + +See: <> diff --git a/doc/crypt/array.adoc b/doc/crypt/array.adoc new file mode 100644 index 0000000..3353bcd --- /dev/null +++ b/doc/crypt/array.adoc @@ -0,0 +1,70 @@ +//// +Copyright 2024 Matt Borland +Distributed under the Boost Software License, Version 1.0. +https://www.boost.org/LICENSE_1_0.txt +//// + +[#array] +:idprefix: array_ + +In order for this lab to use `` in a `constexpr` environment we would need to support C+\+17. +Additionally, CUDA environments do not directly support `std::array`. +For these reasons we reimplement `` in our namespace that both supports both C++14 and CUDA. +It is *IMPLICITLY* convertible to `std::array` for convenience. + +[source, c++] +---- +template +class array +{ +public: + using reference = T&; + using const_reference = const T&; + using iterator = T*; + using const_iterator = const T*; + using size_type = size_t; + using difference_type = ptrdiff_t; + using value_type = T; + using pointer = T*; + using const_pointer = const T*; + + T elements[N]; + + // Iterators + BOOST_CRYPT_GPU_ENABLED constexpr auto begin() noexcept -> iterator; + BOOST_CRYPT_GPU_ENABLED constexpr auto begin() const noexcept -> iterator; + BOOST_CRYPT_GPU_ENABLED constexpr auto cbegin() const noexcept -> const_iterator; + BOOST_CRYPT_GPU_ENABLED constexpr auto end() noexcept -> iterator; + BOOST_CRYPT_GPU_ENABLED constexpr auto end() const noexcept -> iterator; + BOOST_CRYPT_GPU_ENABLED constexpr auto cend() const noexcept -> const_iterator; + + // Sizing + BOOST_CRYPT_GPU_ENABLED constexpr auto size() const noexcept -> size_type; + BOOST_CRYPT_GPU_ENABLED constexpr auto max_size() const noexcept -> size_type; + + // Accessors + BOOST_CRYPT_GPU_ENABLED constexpr auto operator[](size_type n) noexcept; + + BOOST_CRYPT_GPU_ENABLED constexpr auto operator[](size_type n) const noexcept; + + // For at instead of throwing on out of range return the last element since throwing doesn't work on device + BOOST_CRYPT_GPU_ENABLED constexpr auto at(size_type n) noexcept -> reference; + + BOOST_CRYPT_GPU_ENABLED constexpr auto at(size_type n) const noexcept -> const_reference; + + BOOST_CRYPT_GPU_ENABLED constexpr auto front() noexcept -> reference { return elements[0]; } + BOOST_CRYPT_GPU_ENABLED constexpr auto front() const noexcept -> const_reference { return elements[0]; } + BOOST_CRYPT_GPU_ENABLED constexpr auto back() noexcept -> reference { return elements[N - 1]; } + BOOST_CRYPT_GPU_ENABLED constexpr auto back() const noexcept -> const_reference { return elements[N - 1]; } + + BOOST_CRYPT_GPU_ENABLED constexpr auto data() noexcept -> pointer { return elements; } + BOOST_CRYPT_GPU_ENABLED constexpr auto data() const noexcept -> const_pointer { return elements; } + + BOOST_CRYPT_GPU_ENABLED constexpr auto fill(const value_type& v) -> void; + + BOOST_CRYPT_GPU_ENABLED constexpr auto swap(array& a); + + // Conversion + constexpr operator std::array() noexcept; +}; +---- diff --git a/doc/crypt/config.adoc b/doc/crypt/config.adoc new file mode 100644 index 0000000..f252c37 --- /dev/null +++ b/doc/crypt/config.adoc @@ -0,0 +1,19 @@ +//// +Copyright 2023 Matt Borland +Distributed under the Boost Software License, Version 1.0. +https://www.boost.org/LICENSE_1_0.txt +//// + +[#configuration] += Configuration Macros +:idprefix: config_ + +== User Configurable Macros + +The following configuration macros are available: + +- None at this time + +== Automatic Configuration Macros + +- `BOOST_CRYPT_HAS_STRING_VIEW`: This is defined when compiling with at least C++17 and your standard library has a complete implementation of ``. diff --git a/doc/crypt/copyright.adoc b/doc/crypt/copyright.adoc new file mode 100644 index 0000000..f884e9c --- /dev/null +++ b/doc/crypt/copyright.adoc @@ -0,0 +1,12 @@ +//// +Copyright 2024 Matt Borland +Distributed under the Boost Software License, Version 1.0. +https://www.boost.org/LICENSE_1_0.txt +//// + +[#copyright] += Copyright and License +:idprefix: license_ + +This documentation is copyright 2024 Matt Borland and Chris Kormanyos and is distributed under +the http://www.boost.org/LICENSE_1_0.txt[Boost Software License, Version 1.0]. diff --git a/doc/crypt/md5.adoc b/doc/crypt/md5.adoc new file mode 100644 index 0000000..63b20fa --- /dev/null +++ b/doc/crypt/md5.adoc @@ -0,0 +1,115 @@ +//// +Copyright 2024 Matt Borland +Distributed under the Boost Software License, Version 1.0. +https://www.boost.org/LICENSE_1_0.txt +//// + +[#md5] +:idprefix: md5_ + += MD5 + +This library supports MD5 as described in https://www.ietf.org/rfc/rfc1321.txt[RFC 1321]. +There is a wide range of acceptable inputs for the base md5 function: + +== Hashing Functions + +[source, c++] +---- +namespace boost { +namespace crypt { + +uisng return_type = boost::crypt::array; + +BOOST_CRYPT_GPU_ENABLED constexpr auto md5(const char* str) noexcept -> return_type; + +BOOST_CRYPT_GPU_ENABLED constexpr auto md5(const char* str, size_t len) noexcept -> return_type; + +BOOST_CRYPT_GPU_ENABLED constexpr auto md5(const unsigned char* str) noexcept -> return_type; + +BOOST_CRYPT_GPU_ENABLED constexpr auto md5(const unsigned char* str, size_t len) noexcept -> return_type; + +BOOST_CRYPT_GPU_ENABLED constexpr auto md5(const char16_t* str) noexcept -> return_type; + +BOOST_CRYPT_GPU_ENABLED constexpr auto md5(const char16_t* str, size_t len) noexcept -> return_type; + +BOOST_CRYPT_GPU_ENABLED constexpr auto md5(const char32_t* str) noexcept -> return_type; + +BOOST_CRYPT_GPU_ENABLED constexpr auto md5(const char32_t* str, size_t len) noexcept -> return_type; + +BOOST_CRYPT_GPU_ENABLED constexpr auto md5(const wchar_t* str) noexcept -> return_type; + +BOOST_CRYPT_GPU_ENABLED constexpr auto md5(const wchar_t* str, size_t len) noexcept -> return_type; + +inline auto md5(const std::string& str) noexcept -> return_type; + +inline auto md5(const std::u16string& str) noexcept -> return_type; + +inline auto md5(const std::u32string& str) noexcept -> return_type; + +inline auto md5(const std::wstring& str) noexcept -> return_type; + +#ifdef BOOST_CRYPT_HAS_STRING_VIEW + +inline auto md5(std::string_view str) noexcept -> return_type; + +inline auto md5(std::u16string_view str) noexcept -> return_type; + +inline auto md5(std::u32string_view str) noexcept -> return_type; + +inline auto md5(std::wstring_view str) noexcept -> return_type; + +#endif // BOOST_CRYPT_HAS_STRING_VIEW + +} //namespace crypt +} //namespace boost +---- + +== File Hashing Functions + +We also have the ability to scan files and return the MD5 value: + +[source, c++] +---- +namespace boost { +namespace crypt { + +uisng return_type = boost::crypt::array; + +inline auto md5_file(const char* filepath) noexcept -> return_type; + +inline auto md5_file(const std::string& filepath) noexcept -> return_type; + +inline auto md5_file(std::string_view filepath) noexcept -> return_type; + +} // namespace crypt +} // namespace boost +---- + +== Hashing Object + +[#md5_hasher] +Lastly, there is also the ability to create a MD5 hashing object and feed it bytes as the user parses them. +This class does not use any dynamic memory allocation. + +[source, c++] +---- +namespace boost { +namespace crypt { + +class md5_hasher +{ + init(); + + template + BOOST_CRYPT_GPU_ENABLED constexpr auto process_byte(ByteType byte) noexcept -> void; + + template + BOOST_CRYPT_GPU_ENABLED constexpr auto process_bytes(ForwardIter buffer, size_t byte_count) noexcept -> void; + + constexpr auto get_digest() noexcept -> boost::crypt::array; +}; + +} // namespace crypt +} // namespace boost +---- diff --git a/doc/crypt/overview.adoc b/doc/crypt/overview.adoc new file mode 100644 index 0000000..1fab53d --- /dev/null +++ b/doc/crypt/overview.adoc @@ -0,0 +1,70 @@ +//// +Copyright 2023 Matt Borland +Distributed under the Boost Software License, Version 1.0. +https://www.boost.org/LICENSE_1_0.txt +//// + +[#overview] += Overview +:idprefix: overview_ + +== Description + +Boost.Decimal is an implementation of https://standards.ieee.org/ieee/754/6210/[IEEE 754] and https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2849.pdf[ISO/IEC DTR 24733] Decimal Floating Point numbers. +The library is header-only, has no dependencies, and requires C++14. + +== Motivation + +Current C++ floating point types store the significand (often incorrectly referred to as the mantissa) as binary digits. +Famously this leads to representation errors: https://0.30000000000000004.com. +Decimal floating point numbers avoid this issue by storing the significand in base-10 (decimal). +The other major difference between binary and decimal floating point types is that the latter allows for multiple representations of the same number. +For example 1e5 could also be stored as 0.1e6, 0.01e7, so on and so forth. +These are referred to as cohorts which binary does not have as there is only one way to represent each number in binary floating point. + +== Use Cases + +The use case for Decimal Floating Point numbers is where rounding errors are significantly impactful such as finance. +In applications where integer or fixed-point arithmetic are used to combat this issue Decimal Floating Point numbers can provide a significantly greater range of values. +For example, while a fixed-point representation that allocates 8 decimal digits and 2 decimal places can represent the numbers 123456.78, 8765.43, 123.00, and so on, a floating-point representation with 8 decimal digits could also represent 1.2345678, 1234567.8, 0.000012345678, 12345678000000000, and so on. + +== Supported Compilers + +Boost.Decimal 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 7 and later +* Clang 6 and later +* Visual Studio 2017 and later +* Intel OneAPI DPC++ + +Tested on https://github.com/cppalliance/decimal/actions[Github Actions] and https://drone.cpp.al/cppalliance/decimal[Drone]. +Coverage can be found on https://app.codecov.io/gh/cppalliance/decimal[Codecov]. + +== Basic Usage + +[source, c++] +---- +#include +#include +#include + +int main() +{ + using namespace boost::decimal; + + // Outputs 0.30000000000000004 + std::cout << std::setprecision(17) << 0.1 + 0.2; + + // Construct the two decimal values + constexpr decimal64 a {1, -1}; // 1e-1 or 0.1 + constexpr decimal64 b {2, -1}; // 2e-1 or 0.2 + + // Outputs 0.30000000000000000 + std::cout << a + b << std::endl; + + return 0; +} + +---- + diff --git a/doc/crypt/reference.adoc b/doc/crypt/reference.adoc new file mode 100644 index 0000000..87d49fc --- /dev/null +++ b/doc/crypt/reference.adoc @@ -0,0 +1,15 @@ +//// +Copyright 2024 Matt Borland +Distributed under the Boost Software License, Version 1.0. +https://www.boost.org/LICENSE_1_0.txt +//// + +[#reference] += References +:idprefix: ref_ + +The following books, papers and blog posts serve as the basis for the algorithms used in the library: + +:linkattrs: + +- Ronald L. Rivest, https://www.ietf.org/rfc/rfc1321.txt[RFC 1321: The MD5 Message-Digest Algorithm], 1992 diff --git a/include/boost/crypt/utility/array.hpp b/include/boost/crypt/utility/array.hpp index 302aefa..f13b1dd 100644 --- a/include/boost/crypt/utility/array.hpp +++ b/include/boost/crypt/utility/array.hpp @@ -10,6 +10,10 @@ #include #include +#ifndef BOOST_CRYPT_BUILD_MODULE +#include +#endif + namespace boost { namespace crypt { @@ -97,6 +101,17 @@ class array a = *this; *this = temp; } + + constexpr operator std::array() noexcept + { + std::array new_array{}; + for (boost::crypt::size_t i {}; i < N; ++i) + { + new_array[i] = elements[i]; + } + + return new_array; + } }; template diff --git a/test/test_md5.cpp b/test/test_md5.cpp index ab4429e..fb9ae41 100644 --- a/test/test_md5.cpp +++ b/test/test_md5.cpp @@ -224,7 +224,9 @@ void test_random_values() const std::size_t current_str_len {str_len(rng)}; boost::crypt::generate_random_string(str, current_str_len); const auto uuid_res {get_boost_uuid_result(str, current_str_len)}; - const auto crypt_res {boost::crypt::md5(str, current_str_len)}; + + // boost::crypt::array is implicitly convertible to std::array + const std::array crypt_res = boost::crypt::md5(str, current_str_len); for (std::size_t j {}; j < crypt_res.size(); ++j) {