diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9cc92b0b..fbd7244a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,11 +52,14 @@ jobs: compiler: gcc-13, cxxstd: '03,11,14,17,20', os: ubuntu-24.04 } # Clang isn't compatible with libstdc++-13, so use the slightly older one - { compiler: clang-15, cxxstd: '03,11,14,17,20', os: ubuntu-22.04, install: 'clang-15 g++-12', gcc_toolchain: 12 } - - { compiler: clang-16, cxxstd: '11,14,17,20,2b', os: ubuntu-24.04 } + - { compiler: clang-16, cxxstd: '11,14,17,20,2b', os: ubuntu-24.04, install: 'clang-16 g++-12', gcc_toolchain: 12 } # https://github.com/llvm/llvm-project/issues/59827: disabled 2b/23 for clang-17 with libstdc++13 in 24.04 - { compiler: clang-17, cxxstd: '11,14,17,20', os: ubuntu-24.04 } - { compiler: clang-18, cxxstd: '11,14,17,20,23,2c', os: ubuntu-24.04 } + - { name: Clang w/ sanitizers, sanitize: yes, + compiler: clang-18, cxxstd: '03,11,14,17,20', os: ubuntu-24.04 } + - { name: MacOS w/ clang and sanitizers, compiler: clang, cxxstd: '03,11,14,17,20,2b', os: macos-13, sanitize: yes } - { compiler: clang, cxxstd: '03,11,14,17,20,2b', os: macos-14 } @@ -348,8 +351,8 @@ jobs: fail-fast: false matrix: include: - - { os: ubuntu-20.04, build_shared: ON, build_type: Debug, generator: 'Unix Makefiles' } - - { os: ubuntu-20.04, build_shared: OFF, build_type: Debug, generator: 'Unix Makefiles' } + - { os: ubuntu-24.04, build_shared: ON, build_type: Debug, generator: 'Unix Makefiles' } + - { os: ubuntu-24.04, build_shared: OFF, build_type: Debug, generator: 'Unix Makefiles' } - { os: windows-2019, build_shared: ON, build_type: Debug, generator: 'Visual Studio 16 2019' } - { os: windows-2019, build_shared: OFF, build_type: Debug, generator: 'Visual Studio 16 2019' } diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 00694bab..4c921bfc 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -1,76 +1,202 @@ -# ------------------------------------------------------------------------------ -# Copyright Matt Borland 2023 - 2024. -# Copyright Christopher Kormanyos 2023 - 2024. -# Distributed under the Boost Software License, -# Version 1.0. (See accompanying file LICENSE_1_0.txt -# or copy at http://www.boost.org/LICENSE_1_0.txt) -# ------------------------------------------------------------------------------ - +# Copyright 2020-2021 Peter Dimov +# Copyright 2021 Andrey Semashev +# Copyright 2021 Alexander Grund +# Copyright 2022 James E. King III +# Copyright 2023 Matt Borland +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) +--- name: codecov + on: + pull_request: push: branches: - master - develop + - bugfix/** - feature/** - pull_request: - types: [opened, synchronize, reopened] + - fix/** + - pr/** + +env: + GIT_FETCH_JOBS: 8 + NET_RETRY_COUNT: 5 + B2_CI_VERSION: 1 + B2_VARIANT: debug,release + B2_LINK: shared,static + LCOV_BRANCH_COVERAGE: 0 + CODECOV_NAME: Github Actions + ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true + jobs: - gcc-gcov-native: - runs-on: ubuntu-latest + posix: defaults: run: shell: bash + strategy: fail-fast: false matrix: - standard: [ c++20 ] - compiler: [ g++ ] + include: + - { name: Collect coverage, coverage: yes, + compiler: gcc-13, cxxstd: '23', os: ubuntu-24.04, install: 'g++-13-multilib', address-model: '32,64' } + + timeout-minutes: 120 + runs-on: ${{matrix.os}} + container: ${{matrix.container}} + env: {B2_USE_CCACHE: 1} + steps: - - uses: actions/checkout@v4 + - name: Setup environment + run: | + if [ -f "/etc/debian_version" ]; then + echo "DEBIAN_FRONTEND=noninteractive" >> $GITHUB_ENV + export DEBIAN_FRONTEND=noninteractive + fi + if [ -n "${{matrix.container}}" ] && [ -f "/etc/debian_version" ]; then + apt-get -o Acquire::Retries=$NET_RETRY_COUNT update + apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common curl + # Need (newer) git, and the older Ubuntu container may require requesting the key manually using port 80 + curl -sSL --retry ${NET_RETRY_COUNT:-5} 'http://keyserver.ubuntu.com/pks/lookup?op=get&search=0xE1DD270288B4E6030699E45FA1715D88E1DF1F24' | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/git-core_ubuntu_ppa.gpg + for i in {1..${NET_RETRY_COUNT:-3}}; do sudo -E add-apt-repository -y ppa:git-core/ppa && break || sleep 10; done + apt-get -o Acquire::Retries=$NET_RETRY_COUNT update + osver=$(lsb_release -sr | cut -f1 -d.) + pkgs="g++ git" + # Ubuntu 22+ has only Python 3 in the repos + if [ -n "$osver" ] && [ "$osver" -ge "22" ]; then + pkgs+=" python-is-python3 libpython3-dev" + else + pkgs+=" python libpython-dev" + fi + apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y $pkgs + fi + # For jobs not compatible with ccache, use "ccache: no" in the matrix + if [[ "${{ matrix.ccache }}" == "no" ]]; then + echo "B2_USE_CCACHE=0" >> $GITHUB_ENV + fi + git config --global pack.threads 0 + + - uses: actions/checkout@v3 + with: + # For coverage builds fetch the whole history, else only 1 commit using a 'fake ternary' + fetch-depth: ${{ matrix.coverage && '0' || '1' }} + + - name: Cache ccache + uses: actions/cache@v3 + if: env.B2_USE_CCACHE + with: + path: ~/.ccache + key: ${{matrix.os}}-${{matrix.container}}-${{matrix.compiler}}-${{github.sha}} + restore-keys: ${{matrix.os}}-${{matrix.container}}-${{matrix.compiler}}- + + - name: Fetch Boost.CI + uses: actions/checkout@v3 with: - fetch-depth: '0' - - name: update-tools + repository: boostorg/boost-ci + ref: master + path: boost-ci-cloned + + - name: Get CI scripts folder + run: | + # Copy ci folder if not testing Boost.CI + [[ "$GITHUB_REPOSITORY" =~ "boost-ci" ]] || cp -r boost-ci-cloned/ci . + rm -rf boost-ci-cloned + + - name: Install packages + if: startsWith(matrix.os, 'ubuntu') run: | - sudo apt install lcov locales + SOURCE_KEYS=(${{join(matrix.source_keys, ' ')}}) + SOURCES=(${{join(matrix.sources, ' ')}}) + # Add this by default + SOURCES+=(ppa:ubuntu-toolchain-r/test) + for key in "${SOURCE_KEYS[@]}"; do + for i in {1..$NET_RETRY_COUNT}; do + keyfilename=$(basename -s .key $key) + curl -sSL --retry ${NET_RETRY_COUNT:-5} "$key" | sudo gpg --dearmor > /etc/apt/trusted.gpg.d/${keyfilename} && break || sleep 10 + done + done + for source in "${SOURCES[@]}"; do + for i in {1..$NET_RETRY_COUNT}; do + sudo add-apt-repository $source && break || sleep 10 + done + done + sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT update + if [[ -z "${{matrix.install}}" ]]; then + pkgs="${{matrix.compiler}}" + pkgs="${pkgs/gcc-/g++-}" + else + pkgs="${{matrix.install}}" + fi + sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y $pkgs locales sudo locale-gen de_DE.UTF-8 sudo update-locale - - name: clone-submods-bootstrap-headers-boost-develop + - name: Setup GCC Toolchain + if: matrix.gcc_toolchain run: | - git clone -b develop --depth 1 https://github.com/boostorg/boost.git ../boost-root - cd ../boost-root - git submodule update --init tools - git submodule update --init libs/assert - git submodule update --init libs/config - git submodule update --init libs/core - git submodule update --init libs/math - git submodule update --init libs/multiprecision - git submodule update --init libs/predef - git submodule update --init libs/static_assert - git submodule update --init libs/test - git submodule update --init libs/uuid - git submodule update --init libs/throw_exception - git submodule update --init libs/type_traits - ./bootstrap.sh - ./b2 headers - - name: gcc-gcov-native + GCC_TOOLCHAIN_ROOT="$HOME/gcc-toolchain" + echo "GCC_TOOLCHAIN_ROOT=$GCC_TOOLCHAIN_ROOT" >> $GITHUB_ENV + if ! command -v dpkg-architecture; then + apt-get install -y dpkg-dev + fi + MULTIARCH_TRIPLET="$(dpkg-architecture -qDEB_HOST_MULTIARCH)" + mkdir -p "$GCC_TOOLCHAIN_ROOT" + ln -s /usr/include "$GCC_TOOLCHAIN_ROOT/include" + ln -s /usr/bin "$GCC_TOOLCHAIN_ROOT/bin" + mkdir -p "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET" + ln -s "/usr/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}" "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}" + + - name: Setup multiarch + if: matrix.multiarch run: | - cd test/cover - echo "build and run gcov/lcov/genhtml" - echo "make prepare -f make_gcov_01_generic.gmk MY_ALL_COV=0 MY_BOOST_ROOT=../../../boost-root MY_CC=${{ matrix.compiler }} MY_STD=${{ matrix.standard }}" - echo - make prepare -f make_gcov_01_generic.gmk MY_ALL_COV=0 MY_BOOST_ROOT=../../../boost-root MY_CC=${{ matrix.compiler }} MY_STD=${{ matrix.standard }} - echo - echo "make gcov -f make_gcov_01_generic.gmk --jobs=8 MY_ALL_COV=0 MY_BOOST_ROOT=../../../boost-root MY_CC=${{ matrix.compiler }} MY_STD=${{ matrix.standard }}" - echo - make gcov -f make_gcov_01_generic.gmk --jobs=8 MY_ALL_COV=0 MY_BOOST_ROOT=../../../boost-root MY_CC=${{ matrix.compiler }} MY_STD=${{ matrix.standard }} - echo - - name: upload-codecov + sudo apt-get install --no-install-recommends -y binfmt-support qemu-user-static + sudo docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + git clone https://github.com/jeking3/bdde.git + echo "$(pwd)/bdde/bin/linux" >> ${GITHUB_PATH} + echo "BDDE_DISTRO=${{ matrix.distro }}" >> ${GITHUB_ENV} + echo "BDDE_EDITION=${{ matrix.edition }}" >> ${GITHUB_ENV} + echo "BDDE_ARCH=${{ matrix.arch }}" >> ${GITHUB_ENV} + echo "B2_WRAPPER=bdde" >> ${GITHUB_ENV} + + - name: Setup Boost + env: + B2_ADDRESS_MODEL: ${{matrix.address-model}} + B2_COMPILER: ${{matrix.compiler}} + B2_CXXSTD: ${{matrix.cxxstd}} + B2_SANITIZE: ${{matrix.sanitize}} + B2_STDLIB: ${{matrix.stdlib}} + B2_CXXFLAGS: ${{matrix.cxxflags}} + # More entries can be added in the same way, see the B2_ARGS assignment in ci/enforce.sh for the possible keys. + # B2_DEFINES: ${{matrix.defines}} + # Variables set here (to non-empty) will override the top-level environment variables, e.g. + # B2_VARIANT: ${{matrix.variant}} + # Set the (B2) target(s) to build, defaults to the test folder of the current library + # Can alternatively be done like this in the build step or in the build command of the build step, e.g. `run: B2_TARGETS=libs/$SELF/doc ci/build.sh` + # B2_TARGETS: libs/foo/test//bar + run: source ci/github/install.sh + + - name: Setup coverage collection + if: matrix.coverage + run: ci/github/codecov.sh "setup" + + - name: Run tests + if: '!matrix.coverity' + run: ci/build.sh + + - name: Upload coverage + if: matrix.coverage + run: ci/codecov.sh "upload" + env: + BOOST_CI_CODECOV_IO_UPLOAD: skip + + - name: Upload coverage + if: matrix.coverage uses: codecov/codecov-action@v4 with: - plugin: gcov - file: ${{ runner.workspace }}/crypt/test/cover/coverage.info - token: ${{ secrets.CODECOV_TOKEN }} - fail_ci_if_error: true - verbose: false + disable_search: true + file: coverage.info + name: Github Actions + token: ${{secrets.CODECOV_TOKEN}} + verbose: true diff --git a/.github/workflows/cuda.yml b/.github/workflows/cuda.yml index a249761b..17e7d1ef 100644 --- a/.github/workflows/cuda.yml +++ b/.github/workflows/cuda.yml @@ -23,25 +23,18 @@ jobs: fail-fast: false runs-on: gpu-runner-1 + container: + image: nvidia/cuda:12.6.3-devel-ubuntu24.04 + options: --gpus all steps: - - uses: Jimver/cuda-toolkit@v0.2.19 - id: cuda-toolkit - with: - cuda: '12.5.0' - method: 'network' - sub-packages: '["nvcc"]' - - - name: Output CUDA information - run: | - echo "Installed cuda version is: ${{steps.cuda-toolkit.outputs.cuda}}"+ - echo "Cuda install location: ${{steps.cuda-toolkit.outputs.CUDA_PATH}}" - nvcc -V - uses: actions/checkout@v4 - name: Install Packages run: | - sudo apt-get install -y cmake make + apt-get update + apt-get install -y wget cmake git python3 build-essential + - name: Setup Boost run: | echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY @@ -62,15 +55,34 @@ jobs: cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY git submodule update --init tools/boostdep python3 tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY + + - name: Check CUDA Installation + run: | + nvidia-smi + nvcc --version + ls -l /usr/local/cuda-12.6/bin/nvcc + - name: Configure run: | cd ../boost-root mkdir __build__ && cd __build__ - cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DBUILD_TESTING=ON -DCMAKE_CUDA_COMPILER=/usr/local/cuda/bin/nvcc -DBOOST_CRYPT_ENABLE_CUDA=1 -DCMAKE_CUDA_ARCHITECTURES=70 -DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-12.5 .. + cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY \ + -DBUILD_TESTING=ON \ + -DCMAKE_CUDA_COMPILER=/usr/local/cuda-12.6/bin/nvcc \ + -DBOOST_CRYPT_ENABLE_CUDA=1 \ + -DCMAKE_CUDA_ARCHITECTURES=70 \ + -DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-12.6 \ + -DCUDA_PATH=/usr/local/cuda-12.6 \ + -DCMAKE_VERBOSE_MAKEFILE=ON \ + -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ + .. \ + --debug-output + - name: Build tests run: | cd ../boost-root/__build__ - cmake --build . --target tests -j $(nproc) + cmake --build . --target tests -j $(nproc) --verbose + - name: Run tests run: | cd ../boost-root/__build__ diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index b54d3ac4..f21423e1 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -32,33 +32,9 @@ jobs: # Linux, clang # https://llvm.org/docs/LibFuzzer.html#fuzzer-usage - - toolset: clang - compiler: clang++-12 - cxxstd: "14,17,20" - os: ubuntu-22.04 - install: - - clang-12 - - toolset: clang - compiler: clang++-13 - cxxstd: "14,17,20" - os: ubuntu-22.04 - install: - - clang-13 - - toolset: clang - compiler: clang++-14 - cxxstd: "14,17,20" - os: ubuntu-22.04 - install: - - clang-14 - - toolset: clang - compiler: clang++-14 - cxxstd: "14-gnu,17-gnu,20-gnu" - os: ubuntu-22.04 - install: - - clang-14 - toolset: clang compiler: clang++-15 - cxxstd: "14,17,20" + cxxstd: "20" os: ubuntu-22.04 install: - clang-15 @@ -68,7 +44,7 @@ jobs: - "https://apt.llvm.org/llvm-snapshot.gpg.key" - toolset: clang compiler: clang++-16 - cxxstd: "14,17,20" + cxxstd: "20" os: ubuntu-22.04 install: - clang-16 @@ -78,7 +54,7 @@ jobs: - "https://apt.llvm.org/llvm-snapshot.gpg.key" - toolset: clang compiler: clang++-17 - cxxstd: "14,17,20" + cxxstd: "20" os: ubuntu-22.04 install: - clang-17 @@ -88,7 +64,7 @@ jobs: - "https://apt.llvm.org/llvm-snapshot.gpg.key" - toolset: clang compiler: clang++-18 - cxxstd: "14,17,20" + cxxstd: "20,23" os: ubuntu-24.04 install: - clang-18 @@ -98,7 +74,7 @@ jobs: - "https://apt.llvm.org/llvm-snapshot.gpg.key" - toolset: clang compiler: clang++-19 - cxxstd: "14,17,20" + cxxstd: "20,23" os: ubuntu-24.04 install: - clang-19 diff --git a/CMakeLists.txt b/CMakeLists.txt index 2059eaef..0be2896e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,9 +4,30 @@ # Distributed under the Boost Software License, Version 1.0. # https://www.boost.org/LICENSE_1_0.txt -cmake_minimum_required(VERSION 3.8...3.20) +cmake_minimum_required(VERSION 3.24) -project(boost_crypt VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX) +project(boost_crypt VERSION 1.0.0 LANGUAGES CXX) + +option(BOOST_CRYPT_ENABLE_CUDA "Build with CUDA" OFF) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +if(BOOST_CRYPT_ENABLE_CUDA) + + enable_language(CUDA) + + set(CMAKE_CUDA_STANDARD 20) + set(CMAKE_CUDA_STANDARD_REQUIRED ON) + + set(CMAKE_CUDA_EXTENSIONS OFF) + + set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} --expt-relaxed-constexpr") + + find_package(CUDAToolkit REQUIRED) + +endif() add_library(boost_crypt INTERFACE) diff --git a/fuzzing/fuzz_sha1.cpp b/fuzzing/fuzz_sha1.cpp index 2bc36618..2469cc12 100644 --- a/fuzzing/fuzz_sha1.cpp +++ b/fuzzing/fuzz_sha1.cpp @@ -2,7 +2,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt -#include +#include #include #include #include @@ -15,26 +15,20 @@ extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, std::size_t size std::string c_data_str {c_data, size}; // Guarantee null termination since we can't pass the size argument boost::crypt::sha1(c_data_str); - boost::crypt::sha1(c_data, size); - boost::crypt::sha1(data, size); - #ifdef BOOST_CRYPT_HAS_STRING_VIEW std::string_view view {c_data_str}; boost::crypt::sha1(view); - #endif - #ifdef BOOST_CRYPT_HAS_SPAN std::span data_span {c_data, size}; boost::crypt::sha1(data_span); - #endif // Fuzz the hasher object boost::crypt::sha1_hasher hasher; - hasher.process_bytes(data, size); - hasher.process_bytes(data, size); - hasher.process_bytes(data, size); + hasher.process_bytes(data_span); + hasher.process_bytes(data_span); + hasher.process_bytes(data_span); hasher.get_digest(); - hasher.process_bytes(data, size); // State is invalid but should not crash + hasher.process_bytes(data_span); // State is invalid but should not crash } catch(...) { diff --git a/include/boost/crypt/utility/config.hpp b/include/boost/crypt/utility/config.hpp index a334c617..c4ab9198 100644 --- a/include/boost/crypt/utility/config.hpp +++ b/include/boost/crypt/utility/config.hpp @@ -2,8 +2,8 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt -#ifndef BOOST_CRYPT_DETAIL_CONFIG_HPP -#define BOOST_CRYPT_DETAIL_CONFIG_HPP +#ifndef BOOST_CRYPT_OLD_DETAIL_CONFIG_HPP +#define BOOST_CRYPT_OLD_DETAIL_CONFIG_HPP #ifdef __CUDACC__ # ifndef BOOST_CRYPT_HAS_CUDA @@ -189,4 +189,4 @@ // ----- if constexpr ----- -#endif //BOOST_CRYPT_DETAIL_CONFIG_HPP +#endif //BOOST_CRYPT_OLD_DETAIL_CONFIG_HPP diff --git a/include/boost/crypt/utility/type_traits.hpp b/include/boost/crypt/utility/type_traits.hpp index 7d689822..160fa035 100644 --- a/include/boost/crypt/utility/type_traits.hpp +++ b/include/boost/crypt/utility/type_traits.hpp @@ -314,184 +314,184 @@ template using bool_constant = boost::crypt::integral_constant; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_void_v = boost::crypt::is_void::value; +inline constexpr bool is_void_v = boost::crypt::is_void::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_null_pointer_v = boost::crypt::is_null_pointer::value; +inline constexpr bool is_null_pointer_v = boost::crypt::is_null_pointer::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_integral_v = boost::crypt::is_integral::value; +inline constexpr bool is_integral_v = boost::crypt::is_integral::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_floating_point_v = boost::crypt::is_floating_point::value; +inline constexpr bool is_floating_point_v = boost::crypt::is_floating_point::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_array_v = boost::crypt::is_array::value; +inline constexpr bool is_array_v = boost::crypt::is_array::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_enum_v = boost::crypt::is_enum::value; +inline constexpr bool is_enum_v = boost::crypt::is_enum::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_union_v = boost::crypt::is_union::value; +inline constexpr bool is_union_v = boost::crypt::is_union::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_class_v = boost::crypt::is_class::value; +inline constexpr bool is_class_v = boost::crypt::is_class::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_function_v = boost::crypt::is_function::value; +inline constexpr bool is_function_v = boost::crypt::is_function::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_pointer_v = boost::crypt::is_pointer::value; +inline constexpr bool is_pointer_v = boost::crypt::is_pointer::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_lvalue_reference_v = boost::crypt::is_lvalue_reference::value; +inline constexpr bool is_lvalue_reference_v = boost::crypt::is_lvalue_reference::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_rvalue_reference_v = boost::crypt::is_rvalue_reference::value; +inline constexpr bool is_rvalue_reference_v = boost::crypt::is_rvalue_reference::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_member_object_pointer_v = boost::crypt::is_member_object_pointer::value; +inline constexpr bool is_member_object_pointer_v = boost::crypt::is_member_object_pointer::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_member_function_pointer_v = boost::crypt::is_member_function_pointer::value; +inline constexpr bool is_member_function_pointer_v = boost::crypt::is_member_function_pointer::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_fundamental_v = boost::crypt::is_fundamental::value; +inline constexpr bool is_fundamental_v = boost::crypt::is_fundamental::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_arithmetic_v = boost::crypt::is_arithmetic::value; +inline constexpr bool is_arithmetic_v = boost::crypt::is_arithmetic::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_scalar_v = boost::crypt::is_scalar::value; +inline constexpr bool is_scalar_v = boost::crypt::is_scalar::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_object_v = boost::crypt::is_object::value; +inline constexpr bool is_object_v = boost::crypt::is_object::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_compound_v = boost::crypt::is_compound::value; +inline constexpr bool is_compound_v = boost::crypt::is_compound::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_reference_v = boost::crypt::is_reference::value; +inline constexpr bool is_reference_v = boost::crypt::is_reference::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_member_pointer_v = boost::crypt::is_member_pointer::value; +inline constexpr bool is_member_pointer_v = boost::crypt::is_member_pointer::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_const_v = boost::crypt::is_const::value; +inline constexpr bool is_const_v = boost::crypt::is_const::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_volatile_v = boost::crypt::is_volatile::value; +inline constexpr bool is_volatile_v = boost::crypt::is_volatile::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_trivial_v = boost::crypt::is_trivial::value; +inline constexpr bool is_trivial_v = boost::crypt::is_trivial::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_trivially_copyable_v = boost::crypt::is_trivially_copyable::value; +inline constexpr bool is_trivially_copyable_v = boost::crypt::is_trivially_copyable::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_standard_layout_v = boost::crypt::is_standard_layout::value; +inline constexpr bool is_standard_layout_v = boost::crypt::is_standard_layout::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_empty_v = boost::crypt::is_empty::value; +inline constexpr bool is_empty_v = boost::crypt::is_empty::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_polymorphic_v = boost::crypt::is_polymorphic::value; +inline constexpr bool is_polymorphic_v = boost::crypt::is_polymorphic::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_abstract_v = boost::crypt::is_abstract::value; +inline constexpr bool is_abstract_v = boost::crypt::is_abstract::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_final_v = boost::crypt::is_final::value; +inline constexpr bool is_final_v = boost::crypt::is_final::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_signed_v = boost::crypt::is_signed::value; +inline constexpr bool is_signed_v = boost::crypt::is_signed::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_unsigned_v = boost::crypt::is_unsigned::value; +inline constexpr bool is_unsigned_v = boost::crypt::is_unsigned::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_constructible_v = boost::crypt::is_constructible::value; +inline constexpr bool is_constructible_v = boost::crypt::is_constructible::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_trivially_constructible_v = boost::crypt::is_trivially_constructible::value; +inline constexpr bool is_trivially_constructible_v = boost::crypt::is_trivially_constructible::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_nothrow_constructible_v = boost::crypt::is_nothrow_constructible::value; +inline constexpr bool is_nothrow_constructible_v = boost::crypt::is_nothrow_constructible::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_default_constructible_v = boost::crypt::is_default_constructible::value; +inline constexpr bool is_default_constructible_v = boost::crypt::is_default_constructible::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_trivially_default_constructible_v = boost::crypt::is_trivially_default_constructible::value; +inline constexpr bool is_trivially_default_constructible_v = boost::crypt::is_trivially_default_constructible::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_nothrow_default_constructible_v = boost::crypt::is_nothrow_default_constructible::value; +inline constexpr bool is_nothrow_default_constructible_v = boost::crypt::is_nothrow_default_constructible::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_copy_constructible_v = boost::crypt::is_copy_constructible::value; +inline constexpr bool is_copy_constructible_v = boost::crypt::is_copy_constructible::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_trivially_copy_constructible_v = boost::crypt::is_trivially_copy_constructible::value; +inline constexpr bool is_trivially_copy_constructible_v = boost::crypt::is_trivially_copy_constructible::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_nothrow_copy_constructible_v = boost::crypt::is_nothrow_copy_constructible::value; +inline constexpr bool is_nothrow_copy_constructible_v = boost::crypt::is_nothrow_copy_constructible::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_move_constructible_v = boost::crypt::is_move_constructible::value; +inline constexpr bool is_move_constructible_v = boost::crypt::is_move_constructible::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_trivially_move_constructible_v = boost::crypt::is_trivially_move_constructible::value; +inline constexpr bool is_trivially_move_constructible_v = boost::crypt::is_trivially_move_constructible::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_nothrow_move_constructible_v = boost::crypt::is_nothrow_move_constructible::value; +inline constexpr bool is_nothrow_move_constructible_v = boost::crypt::is_nothrow_move_constructible::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_assignable_v = boost::crypt::is_assignable::value; +inline constexpr bool is_assignable_v = boost::crypt::is_assignable::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_trivially_assignable_v = boost::crypt::is_trivially_assignable::value; +inline constexpr bool is_trivially_assignable_v = boost::crypt::is_trivially_assignable::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_nothrow_assignable_v = boost::crypt::is_nothrow_assignable::value; +inline constexpr bool is_nothrow_assignable_v = boost::crypt::is_nothrow_assignable::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_copy_assignable_v = boost::crypt::is_copy_assignable::value; +inline constexpr bool is_copy_assignable_v = boost::crypt::is_copy_assignable::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_trivially_copy_assignable_v = boost::crypt::is_trivially_copy_assignable::value; +inline constexpr bool is_trivially_copy_assignable_v = boost::crypt::is_trivially_copy_assignable::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_nothrow_copy_assignable_v = boost::crypt::is_nothrow_copy_assignable::value; +inline constexpr bool is_nothrow_copy_assignable_v = boost::crypt::is_nothrow_copy_assignable::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_move_assignable_v = boost::crypt::is_move_assignable::value; +inline constexpr bool is_move_assignable_v = boost::crypt::is_move_assignable::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_trivially_move_assignable_v = boost::crypt::is_trivially_move_assignable::value; +inline constexpr bool is_trivially_move_assignable_v = boost::crypt::is_trivially_move_assignable::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_nothrow_move_assignable_v = boost::crypt::is_nothrow_move_assignable::value; +inline constexpr bool is_nothrow_move_assignable_v = boost::crypt::is_nothrow_move_assignable::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_destructible_v = boost::crypt::is_destructible::value; +inline constexpr bool is_destructible_v = boost::crypt::is_destructible::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_trivially_destructible_v = boost::crypt::is_trivially_destructible::value; +inline constexpr bool is_trivially_destructible_v = boost::crypt::is_trivially_destructible::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_nothrow_destructible_v = boost::crypt::is_nothrow_destructible::value; +inline constexpr bool is_nothrow_destructible_v = boost::crypt::is_nothrow_destructible::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool has_virtual_destructor_v = boost::crypt::has_virtual_destructor::value; +inline constexpr bool has_virtual_destructor_v = boost::crypt::has_virtual_destructor::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_same_v = boost::crypt::is_same::value; +inline constexpr bool is_same_v = boost::crypt::is_same::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_base_of_v = boost::crypt::is_base_of::value; +inline constexpr bool is_base_of_v = boost::crypt::is_base_of::value; template -BOOST_CRYPT_INLINE_CONSTEXPR bool is_convertible_v = boost::crypt::is_convertible::value; +inline constexpr bool is_convertible_v = boost::crypt::is_convertible::value; } // namespace crypt } // namespace boost diff --git a/include/boost/crypt2/detail/clear_mem.hpp b/include/boost/crypt2/detail/clear_mem.hpp new file mode 100644 index 00000000..c7844114 --- /dev/null +++ b/include/boost/crypt2/detail/clear_mem.hpp @@ -0,0 +1,131 @@ +// Copyright 2024 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_CRYPT_DETAIL_SECURE_MEMSET_HPP +#define BOOST_CRYPT_DETAIL_SECURE_MEMSET_HPP + +#include +#include + +#ifdef BOOST_CRYPT_HAS_CUDA + +#include +#include +// There is no real secure memset here +namespace boost::crypt::detail { + +template +BOOST_CRYPT_GPU_ENABLED void clear_mem(cuda::std::span ptr) +{ + for (auto& byte : ptr) + { + byte = typename T::value_type{}; + } +} + +template +BOOST_CRYPT_GPU_ENABLED void clear_mem(T& arr) +{ + for (auto& byte : arr) + { + byte = typename T::value_type{}; + } +} + +} // End namespace + +#else + +#ifndef BOOST_CRYPT_BUILD_MODULE + +#include +#include +#include +#include +#include +#include +#include + +#endif + +namespace boost::crypt::detail { + +/* +using memset_span_t = void(*)(std::span); + +inline constexpr memset_span_t default_memset = [](std::span s) constexpr +{ + std::fill(s.begin(), s.end(), std::byte{0x00}); +}; + +// Define the runtime function separately with external linkage +// +// I am unaware of any other way to accomplish this under safe buffer, +// so we ignore the warning +inline void runtime_memset_impl(std::span s) +{ + #if defined(__clang__) && __clang_major__ >= 20 + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call" + #endif + + std::memset(s.data(), 0x00, s.size_bytes()); + + #if defined(__clang__) && __clang_major__ >= 20 + #pragma clang diagnostic pop + #endif +} + +// Now use the named function instead of lambda +inline volatile memset_span_t runtime_memset_func = runtime_memset_impl; + +constexpr void clear_mem(std::span data) +{ + if (std::is_constant_evaluated()) + { + default_memset(data); + } + else + { + runtime_memset_func(data); + } +} +*/ + +using generic_meset_t = void(*)(void*, size_t); + +inline void generic_runtime_memset_func_impl(void* ptr, size_t size) +{ + #if defined(__clang__) && __clang_major__ >= 20 + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call" + #endif + + std::memset(ptr, 0, size); + + #if defined(__clang__) && __clang_major__ >= 20 + #pragma clang diagnostic pop + #endif +} + +inline volatile generic_meset_t generic_runtime_memset_func = generic_runtime_memset_func_impl; + +template +constexpr void clear_mem(T& data) +{ + if (std::is_constant_evaluated()) + { + std::fill(data.begin(), data.end(), static_cast(0)); // LCOV_EXCL_LINE + } + else + { + generic_runtime_memset_func_impl(data.data(), data.size()); + } +} + +} // namespace boost::crypt::detail + +#endif + +#endif //BOOST_CRYPT_DETAIL_SECURE_MEMSET_HPP diff --git a/include/boost/crypt2/detail/compat.hpp b/include/boost/crypt2/detail/compat.hpp new file mode 100644 index 00000000..789b935d --- /dev/null +++ b/include/boost/crypt2/detail/compat.hpp @@ -0,0 +1,248 @@ +// Copyright 2024 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// Here we inject std and cuda std equivalents into our own namespace +// to help resolve ADL issues with CUDA + +#ifndef BOOST_CRYPT2_DETAIL_COMPAT_HPP +#define BOOST_CRYPT2_DETAIL_COMPAT_HPP + +#include + +#if !defined(BOOST_CRYPT_BUILD_MODULE) && !defined(BOOST_CRYPT_HAS_CUDA) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#elif defined(BOOST_CRYPT_HAS_CUDA) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif + +namespace boost::crypt::compat { + +// Fixed width types +#ifdef BOOST_CRYPT_HAS_CUDA +using size_t = cuda::std::size_t; +using uint32_t = cuda::std::uint32_t; +#else +using size_t = std::size_t; +using uint32_t = std::uint32_t; +#endif + +// Arrays and spans +template +#ifdef BOOST_CRYPT_HAS_CUDA +using array = cuda::std::array; +#else +using array = std::array; +#endif + +#ifdef BOOST_CRYPT_HAS_CUDA +template +using span = cuda::std::span; +#else +template +using span = std::span; +#endif + +// Byte and friends +#ifdef BOOST_CRYPT_HAS_CUDA +using byte = cuda::std::byte; +#else +using byte = std::byte; +#endif + +template +BOOST_CRYPT_GPU_ENABLED constexpr auto as_bytes(span s) noexcept +{ + #ifdef BOOST_CRYPT_HAS_CUDA + return cuda::std::as_bytes(s); + #else + return std::as_bytes(s); + #endif +} + +template +BOOST_CRYPT_GPU_ENABLED constexpr auto as_writable_bytes(span s) noexcept +{ + #ifdef BOOST_CRYPT_HAS_CUDA + return cuda::std::as_writable_bytes(s); + #else + return std::as_writable_bytes(s); + #endif +} + +// Type traits +#ifdef BOOST_CRYPT_HAS_CUDA +using true_type = cuda::std::true_type; +using false_type = cuda::std::false_type; +#else +using true_type = std::true_type; +using false_type = std::false_type; +#endif + +template +inline constexpr bool is_trivially_copyable_v = + #ifdef BOOST_CRYPT_HAS_CUDA + cuda::std::is_trivially_copyable_v; + #else + std::is_trivially_copyable_v; + #endif + +template +using remove_reference_t = + #ifdef BOOST_CRYPT_HAS_CUDA + cuda::std::remove_reference_t; + #else + std::remove_reference_t; + #endif + +template +using remove_cvref_t = + #ifdef BOOST_CRYPT_HAS_CUDA + cuda::std::remove_cv_t>; + #else + std::remove_cv_t>; + #endif + +// Ranges concepts and utilities +template +concept sized_range = + #ifdef BOOST_CRYPT_HAS_CUDA + cuda::std::ranges::sized_range; + #else + std::ranges::sized_range; + #endif + +template +concept output_range = + #ifdef BOOST_CRYPT_HAS_CUDA + cuda::std::ranges::output_range; + #else + std::ranges::output_range; + #endif + +template +using range_value_t = + #ifdef BOOST_CRYPT_HAS_CUDA + cuda::std::ranges::range_value_t; + #else + std::ranges::range_value_t; + #endif + +// Utilities +template +BOOST_CRYPT_GPU_ENABLED constexpr auto forward(remove_reference_t& t) noexcept -> T&& +{ + #ifdef BOOST_CRYPT_HAS_CUDA + return cuda::std::forward(t); + #else + return std::forward(t); + #endif +} + +template +BOOST_CRYPT_GPU_ENABLED constexpr auto forward(remove_reference_t&& t) noexcept -> T&& +{ + #ifdef BOOST_CRYPT_HAS_CUDA + return cuda::std::forward(cuda::std::move(t)); + #else + return std::forward(std::move(t)); + #endif +} + +// Helper functions +template +struct is_span : false_type {}; + +template +struct is_span> : true_type {}; + +template +struct is_span> : true_type {}; + +// Helper variable template +template +inline constexpr bool is_span_v = is_span::value; + +template +BOOST_CRYPT_GPU_ENABLED constexpr auto make_span(R&& r) +{ + if constexpr (is_span_v>) + { + #ifdef BOOST_CRYPT_HAS_CUDA + return cuda::std::forward(r); + #else + return std::forward(r); + #endif + } + else + { + #ifdef BOOST_CRYPT_HAS_CUDA + return cuda::std::span(cuda::std::forward(r)); + #else + return std::span(std::forward(r)); + #endif + } +} + +template +BOOST_CRYPT_GPU_ENABLED constexpr auto make_span(R& r) +{ + if constexpr (is_span_v>) + { + return r; + } + else + { + #ifdef BOOST_CRYPT_HAS_CUDA + return cuda::std::span(r); + #else + return std::span(r); + #endif + } +} + +// bit +template +BOOST_CRYPT_GPU_ENABLED constexpr auto rotl(T val, int shift) noexcept +{ + // Some clangs incorrectly warn on shift being an int instead of an unsigned int + // C++ standard says shift is to be int + #ifdef __clang__ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wsign-conversion" + #endif + + #ifdef BOOST_CRYPT_HAS_CUDA + return cuda::std::rotl(val, shift); + #else + return std::rotl(val, shift); + #endif + + #ifdef __clang__ + #pragma clang diagnostic pop + #endif +} + +} // namespace boost::crypt::compat + +#endif // BOOST_CRYPT2_DETAIL_COMPAT_HPP diff --git a/include/boost/crypt2/detail/config.hpp b/include/boost/crypt2/detail/config.hpp new file mode 100644 index 00000000..3591ae86 --- /dev/null +++ b/include/boost/crypt2/detail/config.hpp @@ -0,0 +1,67 @@ +// Copyright 2024 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_CRYPT_DETAIL_CONFIG_HPP +#define BOOST_CRYPT_DETAIL_CONFIG_HPP + +#ifdef __CUDACC__ +# ifndef BOOST_CRYPT_HAS_CUDA +# define BOOST_CRYPT_HAS_CUDA +# endif +# define BOOST_CRYPT_GPU_ENABLED __host__ __device__ +# define BOOST_CRYPT_GPU_HOST_ENABLED __host__ +# define BOOST_CRYPT_GPU_DEVICE_ENABLED __device__ +# define BOOST_CRYPT_GPU_ENABLED_CONSTEXPR __host__ __device__ +#endif + +#ifdef __CUDACC_RTC__ +# ifndef BOOST_CRYPT_HAS_CUDA +# define BOOST_CRYPT_HAS_CUDA +# endif +# define BOOST_CRYPT_HAS_NVRTC +# define BOOST_CRYPT_GPU_ENABLED __host__ __device__ +# define BOOST_CRYPT_GPU_HOST_ENABLED __host__ +# define BOOST_CRYPT_GPU_DEVICE_ENABLED __device__ +#endif + +#ifndef BOOST_CRYPT_GPU_ENABLED +# define BOOST_CRYPT_GPU_ENABLED +#endif + +#ifndef BOOST_CRYPT_GPU_ENABLED_CONSTEXPR +# define BOOST_CRYPT_GPU_ENABLED_CONSTEXPR constexpr +#endif + +#ifndef BOOST_CRYPT_GPU_HOST_ENABLED +# define BOOST_CRYPT_GPU_HOST_ENABLED +#endif + +#ifndef BOOST_CRYPT_GPU_DEVICE_ENABLED +# define BOOST_CRYPT_GPU_DEVICE_ENABLED +#endif + +#ifdef BOOST_CRYPT_BUILD_MODULE +# define BOOST_CRYPT_EXPORT export +#else +# define BOOST_CRYPT_EXPORT +#endif + +// See: https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#hardware-implementation +#if defined(_WIN32) || defined(BOOST_CRYPT_HAS_CUDA) + +#define BOOST_CRYPT_ENDIAN_BIG_BYTE 0 +#define BOOST_CRYPT_ENDIAN_LITTLE_BYTE 1 + +#elif defined(__BYTE_ORDER__) + +#define BOOST_CRYPT_ENDIAN_BIG_BYTE (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#define BOOST_CRYPT_ENDIAN_LITTLE_BYTE (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + +#else + +#error Could not determine endian type. Please file an issue at https://github.com/cppalliance/crypt with your architecture + +#endif // Determine endianness + +#endif // BOOST_CRYPT_DETAIL_CONFIG_HPP diff --git a/include/boost/crypt2/detail/file_reader.hpp b/include/boost/crypt2/detail/file_reader.hpp new file mode 100644 index 00000000..15f2ca47 --- /dev/null +++ b/include/boost/crypt2/detail/file_reader.hpp @@ -0,0 +1,104 @@ +// Copyright 2024 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_CRYPT_UTILITY_FILE_HPP +#define BOOST_CRYPT_UTILITY_FILE_HPP + +#include + +#ifndef BOOST_CRYPT_HAS_CUDA + +#ifndef BOOST_CRYPT_BUILD_MODULE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +namespace boost::crypt::detail { + +template +class file_reader +{ +public: + using buffer_type = std::array; + using iterator = typename buffer_type::iterator; + +private: + std::ifstream fd_; + buffer_type buffer_{}; + +public: + template + explicit file_reader(const T& filename) + requires std::is_convertible_v + : fd_(std::string{filename}, std::ios::binary | std::ios::in) + { + const std::string filename_str {filename}; + validate_file(filename_str); + } + + // Rule of 5 + file_reader(const file_reader&) = delete; + file_reader& operator=(const file_reader&) = delete; + file_reader(file_reader&&) noexcept = default; + file_reader& operator=(file_reader&&) noexcept = default; + ~file_reader() = default; // RAII handles file closing + + [[nodiscard]] iterator read_next_block() + { + if (!fd_.good()) + { + throw std::runtime_error("Attempt to read from invalid file stream"); // LCOV_EXCL_LINE + } + + fd_.read(reinterpret_cast(buffer_.data()), block_size); + + if (fd_.bad()) + { + throw std::runtime_error("Error occurred while reading file"); // LCOV_EXCL_LINE + } + + return buffer_.begin(); + } + + [[nodiscard]] std::size_t get_bytes_read() const noexcept + { + return static_cast(fd_.gcount()); + } + + [[nodiscard]] bool eof() const noexcept + { + return fd_.eof(); + } + + [[nodiscard]] const buffer_type& buffer() const noexcept + { + return buffer_; + } + +private: + void validate_file(const std::string_view filename) const + { + if (!fd_.is_open()) + { + throw std::runtime_error(std::string{"Error opening file: "} + std::string{filename}); + } + if (!fd_.good()) + { + throw std::runtime_error(std::string{"File stream not valid after opening: "} + std::string{filename}); // LCOV_EXCL_LINE + } + } +}; + +} // Namespace boost::crypt::detail + +#endif // BOOST_CRYPT_HAS_CUDA + +#endif //BOOST_CRYPT_UTILITY_FILE_HPP diff --git a/include/boost/crypt2/hash/detail/sha_1_2_hasher_base.hpp b/include/boost/crypt2/hash/detail/sha_1_2_hasher_base.hpp new file mode 100644 index 00000000..5ab4ac57 --- /dev/null +++ b/include/boost/crypt2/hash/detail/sha_1_2_hasher_base.hpp @@ -0,0 +1,286 @@ +// 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_DETAIL_SHA_1_2_HASHER_BASE_HPP +#define BOOST_CRYPT_HASH_DETAIL_SHA_1_2_HASHER_BASE_HPP + +#include +#include +#include +#include + +namespace boost::crypt::hash_detail { + +template +class sha_1_2_hasher_base +{ +public: + static constexpr compat::size_t block_size {64U}; + +protected: + + // Each hasher needs to process their own message block in their own way + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR virtual auto process_message_block() noexcept -> void = 0; + + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto pad_message() noexcept -> void; + + compat::array intermediate_hash_ {}; + compat::array buffer_ {}; + compat::size_t buffer_index_ {}; + compat::size_t low_ {}; + compat::size_t high_ {}; + bool computed_ {}; + bool corrupted_ {}; + + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto update(compat::span data) noexcept -> state; + + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto get_digest_impl(compat::span data); + +public: + + using return_type = compat::array; + + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR sha_1_2_hasher_base() noexcept { base_init(); } + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR ~sha_1_2_hasher_base() noexcept { destroy(); } + + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto process_bytes(compat::span data) noexcept -> state; + + template + BOOST_CRYPT_GPU_ENABLED auto process_bytes(Range&& data) noexcept -> state; + + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto finalize() noexcept -> state; + + [[nodiscard("Digest is the function return value")]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto get_digest() noexcept -> return_type; + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto get_digest(compat::span data) noexcept -> void; + + template + BOOST_CRYPT_GPU_ENABLED auto get_digest(Range&& data) noexcept -> void + requires compat::output_range> && + compat::sized_range && + compat::is_trivially_copyable_v>; + + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto base_init() noexcept -> void; + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto destroy() noexcept -> void; +}; + +template +template +auto sha_1_2_hasher_base::get_digest(Range&& data) noexcept -> void + requires compat::output_range> && + compat::sized_range && + compat::is_trivially_copyable_v> +{ + using value_type = compat::range_value_t; + + auto data_span {compat::span(compat::forward(data))}; + + if (data_span.size() * sizeof(value_type) < digest_size) + { + return; + } + + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-container" + #endif + + get_digest_impl(compat::span( + compat::as_writable_bytes(data_span).data(), + digest_size + )); + + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic pop + #endif +} + +template +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha_1_2_hasher_base::get_digest_impl(compat::span data) +{ + if (corrupted_) + { + return data; + } + if (!computed_) + { + finalize(); + } + + for (size_t i {}; i < data.size(); ++i) + { + data[i] = static_cast(intermediate_hash_[i >> 2U] >> 8U * (3U - (i & 0x03U))); + } + + return data; +} + +template +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto +sha_1_2_hasher_base::get_digest(compat::span data) noexcept -> void +{ + get_digest_impl(data); +} + +template +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto +sha_1_2_hasher_base::get_digest() noexcept -> sha_1_2_hasher_base::return_type +{ + return_type digest {}; + get_digest_impl(digest); + return digest; +} + +template +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha_1_2_hasher_base::finalize() noexcept -> state +{ + if (corrupted_) + { + // Return empty message on corruption + return state::state_error; + } + if (!computed_) + { + pad_message(); + + // Overwrite whatever is in the buffer in case it is sensitive + detail::clear_mem(buffer_); + low_ = 0U; + high_ = 0U; + computed_ = true; + } + + return state::success; +} + +template +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha_1_2_hasher_base::pad_message() noexcept -> void +{ + // 448 bits out of 512 + constexpr compat::size_t message_length_start_index {56U}; + + // We don't have enough space for everything we need + if (buffer_index_ >= message_length_start_index) + { + buffer_[buffer_index_++] = static_cast(0x80); + while (buffer_index_ < buffer_.size()) + { + buffer_[buffer_index_++] = static_cast(0x00); + } + + process_message_block(); + + while (buffer_index_ < message_length_start_index) + { + buffer_[buffer_index_++] = static_cast(0x00); + } + } + else + { + buffer_[buffer_index_++] = static_cast(0x80); + while (buffer_index_ < message_length_start_index) + { + buffer_[buffer_index_++] = static_cast(0x00); + } + } + + // Add the message length to the end of the buffer + // BOOST_CRYPT_ASSERT(buffer_index_ == message_length_start_index); + + buffer_[56U] = static_cast(high_ >> 24U); + buffer_[57U] = static_cast(high_ >> 16U); + buffer_[58U] = static_cast(high_ >> 8U); + buffer_[59U] = static_cast(high_); + buffer_[60U] = static_cast(low_ >> 24U); + buffer_[61U] = static_cast(low_ >> 16U); + buffer_[62U] = static_cast(low_ >> 8U); + buffer_[63U] = static_cast(low_); + + process_message_block(); +} + +template +template +auto sha_1_2_hasher_base::process_bytes(SizedRange&& data) noexcept -> state +{ + auto data_span {compat::make_span(compat::forward(data))}; + return update(compat::as_bytes(data_span)); +} + +template +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha_1_2_hasher_base::process_bytes(compat::span data) noexcept -> state +{ + return update(data); +} + +template +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha_1_2_hasher_base::update(compat::span data) noexcept -> state +{ + if (data.empty()) + { + return state::success; + } + if (computed_) + { + corrupted_ = true; + } + if (corrupted_) + { + return state::state_error; + } + + for (const auto val : data) + { + buffer_[buffer_index_++] = val; + low_ += 8U; + + if (low_ == 0U) [[unlikely]] + { + // Would indicate size_t rollover which should not happen on a single data stream + // LCOV_EXCL_START + ++high_; + if (high_ == 0U) [[unlikely]] + { + corrupted_ = true; + return state::input_too_long; + } + // LCOV_EXCL_STOP + } + + if (buffer_index_ == buffer_.size()) + { + process_message_block(); + buffer_index_ = 0U; + } + } + + return state::success; +} + +template +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha_1_2_hasher_base::destroy() noexcept -> void +{ + detail::clear_mem(intermediate_hash_); + detail::clear_mem(buffer_); + buffer_index_ = 0U; + low_ = 0U; + high_ = 0U; + computed_ = false; + corrupted_ = false; +} + +template +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha_1_2_hasher_base::base_init() noexcept -> void +{ + intermediate_hash_.fill(0U); + buffer_.fill(static_cast(0)); + buffer_index_ = 0U; + low_ = 0U; + high_ = 0U; + computed_ = false; + corrupted_ = false; +} + +} // namespace boost::crypt::hash_detail + +#endif //BOOST_CRYPT_HASH_DETAIL_SHA_1_2_HASHER_BASE_HPP diff --git a/include/boost/crypt2/hash/sha1.hpp b/include/boost/crypt2/hash/sha1.hpp new file mode 100644 index 00000000..53c1e81d --- /dev/null +++ b/include/boost/crypt2/hash/sha1.hpp @@ -0,0 +1,318 @@ +// Copyright 2024 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/rfc3174 + +#ifndef BOOST_CRYPT2_HASH_SHA1_HPP +#define BOOST_CRYPT2_HASH_SHA1_HPP + +#include +#include +#include + +#if !defined(BOOST_CRYPT_BUILD_MODULE) && !defined(BOOST_CRYPT_HAS_CUDA) +#include +#include +#elif defined(BOOST_CRYPT_HAS_CUDA) +#include +#include +#endif + +namespace boost::crypt { + +BOOST_CRYPT_EXPORT class sha1_hasher final : public hash_detail::sha_1_2_hasher_base<20U, 5U> +{ +private: + + friend class hash_detail::sha_1_2_hasher_base<20U, 5U>; + + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto process_message_block() noexcept -> void override; + +public: + + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR sha1_hasher() noexcept { init(); } + + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto init() noexcept -> void; +}; + +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha1_hasher::init() noexcept -> void +{ + hash_detail::sha_1_2_hasher_base<20U, 5U>::base_init(); + + intermediate_hash_[0] = 0x67452301; + intermediate_hash_[1] = 0xEFCDAB89; + intermediate_hash_[2] = 0x98BADCFE; + intermediate_hash_[3] = 0x10325476; + intermediate_hash_[4] = 0xC3D2E1F0; +} + +namespace sha1_detail { + +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto round1(compat::uint32_t& A, + compat::uint32_t& B, + compat::uint32_t& C, + compat::uint32_t& D, + compat::uint32_t& E, + compat::uint32_t W) +{ + const auto temp {compat::rotl(A, 5) + ((B & C) | ((~B) & D)) + E + W + 0x5A827999U}; + E = D; + D = C; + C = compat::rotl(B, 30); + B = A; + A = temp; +} + +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto round2(compat::uint32_t& A, + compat::uint32_t& B, + compat::uint32_t& C, + compat::uint32_t& D, + compat::uint32_t& E, + compat::uint32_t W) +{ + const auto temp {compat::rotl(A, 5) + (B ^ C ^ D) + E + W + 0x6ED9EBA1U}; + E = D; + D = C; + C = compat::rotl(B, 30); + B = A; + A = temp; +} + +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto round3(compat::uint32_t& A, + compat::uint32_t& B, + compat::uint32_t& C, + compat::uint32_t& D, + compat::uint32_t& E, + compat::uint32_t W) +{ + const auto temp {compat::rotl(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W + 0x8F1BBCDCU}; + E = D; + D = C; + C = compat::rotl(B, 30); + B = A; + A = temp; +} + +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto round4(compat::uint32_t& A, + compat::uint32_t& B, + compat::uint32_t& C, + compat::uint32_t& D, + compat::uint32_t& E, + compat::uint32_t W) +{ + const auto temp {compat::rotl(A, 5) + (B ^ C ^ D) + E + W + 0xCA62C1D6U}; + E = D; + D = C; + C = compat::rotl(B, 30); + B = A; + A = temp; +} + +} // Namespace sha1_detail + +// See definitions from the RFC on the rounds +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha1_hasher::process_message_block() noexcept -> void +{ + using namespace sha1_detail; + + compat::array W {}; + + // Init the first 16 words of W + for (compat::size_t i {}; i < 16UL; ++i) + { + W[i] = (static_cast(buffer_[i * 4U]) << 24U) | + (static_cast(buffer_[i * 4U + 1U]) << 16U) | + (static_cast(buffer_[i * 4U + 2U]) << 8U) | + (static_cast(buffer_[i * 4U + 3U])); + + } + + for (compat::size_t i {16U}; i < W.size(); ++i) + { + W[i] = compat::rotl(W[i - 3U] ^ W[i - 8U] ^ W[i - 14] ^ W[i - 16], 1); + } + + auto A {intermediate_hash_[0]}; + auto B {intermediate_hash_[1]}; + auto C {intermediate_hash_[2]}; + auto D {intermediate_hash_[3]}; + auto E {intermediate_hash_[4]}; + + // Round 1 + round1(A, B, C, D, E, W[0]); + round1(A, B, C, D, E, W[1]); + round1(A, B, C, D, E, W[2]); + round1(A, B, C, D, E, W[3]); + round1(A, B, C, D, E, W[4]); + round1(A, B, C, D, E, W[5]); + round1(A, B, C, D, E, W[6]); + round1(A, B, C, D, E, W[7]); + round1(A, B, C, D, E, W[8]); + round1(A, B, C, D, E, W[9]); + round1(A, B, C, D, E, W[10]); + round1(A, B, C, D, E, W[11]); + round1(A, B, C, D, E, W[12]); + round1(A, B, C, D, E, W[13]); + round1(A, B, C, D, E, W[14]); + round1(A, B, C, D, E, W[15]); + round1(A, B, C, D, E, W[16]); + round1(A, B, C, D, E, W[17]); + round1(A, B, C, D, E, W[18]); + round1(A, B, C, D, E, W[19]); + + // Round 2 + round2(A, B, C, D, E, W[20]); + round2(A, B, C, D, E, W[21]); + round2(A, B, C, D, E, W[22]); + round2(A, B, C, D, E, W[23]); + round2(A, B, C, D, E, W[24]); + round2(A, B, C, D, E, W[25]); + round2(A, B, C, D, E, W[26]); + round2(A, B, C, D, E, W[27]); + round2(A, B, C, D, E, W[28]); + round2(A, B, C, D, E, W[29]); + round2(A, B, C, D, E, W[30]); + round2(A, B, C, D, E, W[31]); + round2(A, B, C, D, E, W[32]); + round2(A, B, C, D, E, W[33]); + round2(A, B, C, D, E, W[34]); + round2(A, B, C, D, E, W[35]); + round2(A, B, C, D, E, W[36]); + round2(A, B, C, D, E, W[37]); + round2(A, B, C, D, E, W[38]); + round2(A, B, C, D, E, W[39]); + + // Round 3 + round3(A, B, C, D, E, W[40]); + round3(A, B, C, D, E, W[41]); + round3(A, B, C, D, E, W[42]); + round3(A, B, C, D, E, W[43]); + round3(A, B, C, D, E, W[44]); + round3(A, B, C, D, E, W[45]); + round3(A, B, C, D, E, W[46]); + round3(A, B, C, D, E, W[47]); + round3(A, B, C, D, E, W[48]); + round3(A, B, C, D, E, W[49]); + round3(A, B, C, D, E, W[50]); + round3(A, B, C, D, E, W[51]); + round3(A, B, C, D, E, W[52]); + round3(A, B, C, D, E, W[53]); + round3(A, B, C, D, E, W[54]); + round3(A, B, C, D, E, W[55]); + round3(A, B, C, D, E, W[56]); + round3(A, B, C, D, E, W[57]); + round3(A, B, C, D, E, W[58]); + round3(A, B, C, D, E, W[59]); + + // Round 4 + round4(A, B, C, D, E, W[60]); + round4(A, B, C, D, E, W[61]); + round4(A, B, C, D, E, W[62]); + round4(A, B, C, D, E, W[63]); + round4(A, B, C, D, E, W[64]); + round4(A, B, C, D, E, W[65]); + round4(A, B, C, D, E, W[66]); + round4(A, B, C, D, E, W[67]); + round4(A, B, C, D, E, W[68]); + round4(A, B, C, D, E, W[69]); + round4(A, B, C, D, E, W[70]); + round4(A, B, C, D, E, W[71]); + round4(A, B, C, D, E, W[72]); + round4(A, B, C, D, E, W[73]); + round4(A, B, C, D, E, W[74]); + round4(A, B, C, D, E, W[75]); + round4(A, B, C, D, E, W[76]); + round4(A, B, C, D, E, W[77]); + round4(A, B, C, D, E, W[78]); + round4(A, B, C, D, E, W[79]); + + intermediate_hash_[0] += A; + intermediate_hash_[1] += B; + intermediate_hash_[2] += C; + intermediate_hash_[3] += D; + intermediate_hash_[4] += E; + + buffer_index_ = 0U; +} + +#ifndef BOOST_CRYPT_HAS_CUDA + +// One shot functions +BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto sha1(std::span data) noexcept -> sha1_hasher::return_type +{ + sha1_hasher hasher; + hasher.process_bytes(data); + return hasher.get_digest(); +} + +template +BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED auto sha1(SizedRange&& data) noexcept -> sha1_hasher::return_type +{ + sha1_hasher hasher; + hasher.process_bytes(data); + return hasher.get_digest(); +} + +namespace detail { + +// 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 + +template +auto sha1_file_impl(detail::file_reader& reader) -> sha1_hasher::return_type +{ + sha1_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); + } + + return hasher.get_digest(); +} + +#if defined(__clang__) && __clang_major__ >= 19 +#pragma clang diagnostic pop +#endif + +} // namespace detail + +template +BOOST_CRYPT_EXPORT inline auto sha1_file(const T& filepath) + requires std::is_convertible_v +{ + detail::file_reader<64U> reader(filepath); + return detail::sha1_file_impl(reader); +} + +#else + +// One shot functions +BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED auto sha1(cuda::std::span data) noexcept -> sha1_hasher::return_type +{ + sha1_hasher hasher; + hasher.process_bytes(data); + return hasher.get_digest(); +} + +template +BOOST_CRYPT_EXPORT BOOST_CRYPT_GPU_ENABLED auto sha1(SizedRange&& data) noexcept -> sha1_hasher::return_type +{ + sha1_hasher hasher; + hasher.process_bytes(data); + return hasher.get_digest(); +} + +#endif // BOOST_CRYPT_GPU_ENABLED + +} // Namespace boost::crypt + +#endif // BOOST_CRYPT2_HASH_SHA1_HPP diff --git a/include/boost/crypt2/state.hpp b/include/boost/crypt2/state.hpp new file mode 100644 index 00000000..9b304493 --- /dev/null +++ b/include/boost/crypt2/state.hpp @@ -0,0 +1,28 @@ +// 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_HASHER_STATE_HPP +#define BOOST_CRYPT_HASH_HASHER_STATE_HPP + +#include + +namespace boost::crypt { + +BOOST_CRYPT_EXPORT 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 + insufficient_key_length, // The key is not of proscribed length + state_error // added more input after get_digest without re-init +}; + +} // namespace boost::crypt + +#endif // BOOST_CRYPT_HASH_HASHER_STATE_HPP diff --git a/module/Jamfile b/module/Jamfile index 8c917206..f4fb92b1 100644 --- a/module/Jamfile +++ b/module/Jamfile @@ -19,9 +19,9 @@ project msvc:latest gcc:-fmodules-ts - gcc:23 + gcc:20 - clang:23 + clang:20 ; obj crypt : crypt.cxx : msvc:-interface ; diff --git a/module/crypt.cxx b/module/crypt.cxx index 89d41596..1c21fc66 100644 --- a/module/crypt.cxx +++ b/module/crypt.cxx @@ -5,33 +5,22 @@ // Global module fragment required for non-module preprocessing module; -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include #include - -#include -#include #include #include -#include + +#ifdef _WIN32 +#include +#endif #define BOOST_CRYPT_BUILD_MODULE export module boost2.crypt; -#include -#include +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" +#endif + +#include diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c1a8f58a..4700efb0 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -6,36 +6,22 @@ include(BoostTestJamfile OPTIONAL RESULT_VARIABLE HAVE_BOOST_TEST) if(HAVE_BOOST_TEST) - - if (BOOST_CRYPT_ENABLE_CUDA) - - message(STATUS "Building boost.crypt with CUDA") - find_package(CUDA REQUIRED) - enable_language(CUDA) - set(CMAKE_CUDA_EXTENSIONS OFF) - - boost_test_jamfile(FILE nvcc_jamfile LINK_LIBRARIES Boost::crypt ${CUDA_LIBRARIES} INCLUDE_DIRECTORIES ${CUDA_INCLUDE_DIRS} ) - - elseif (BOOST_CRYPT_ENABLE_NVRTC) - - message(STATUS "Building boost.crypt with NVRTC") - find_package(CUDA REQUIRED) - set(CUDA_nvrtc_LIBRARY /usr/local/cuda/lib64/libnvrtc.so) - - if (BOOST_CRYPT_NVRTC_CI_RUN) - - boost_test_jamfile(FILE nvrtc_jamfile LINK_LIBRARIES Boost::crypt ${CUDA_nvrtc_LIBRARY} ${CUDA_LIBRARIES} ${CUDA_CUDA_LIBRARY} COMPILE_DEFINITIONS BOOST_CRYPT_NVRTC_CI_RUN=1 INCLUDE_DIRECTORIES ${CUDA_INCLUDE_DIRS}) - - else () - - boost_test_jamfile(FILE nvrtc_jamfile LINK_LIBRARIES Boost::crypt ${CUDA_nvrtc_LIBRARY} ${CUDA_LIBRARIES} ${CUDA_CUDA_LIBRARY} INCLUDE_DIRECTORIES ${CUDA_INCLUDE_DIRS} ) - - endif () - - else () - - boost_test_jamfile(FILE Jamfile LINK_LIBRARIES Boost::crypt Boost::core Boost::uuid) - - endif () - + if(BOOST_CRYPT_ENABLE_CUDA) + message(STATUS "Building boost.crypt tests with CUDA") + + boost_test_jamfile( + FILE nvcc_jamfile + LINK_LIBRARIES Boost::crypt Boost::core CUDA::cudart + INCLUDE_DIRECTORIES ${CUDAToolkit_INCLUDE_DIRS} + COMPILE_OPTIONS + --expt-relaxed-constexpr + ) + else() + message(STATUS "Building boost.crypt tests without CUDA") + + boost_test_jamfile( + FILE Jamfile + LINK_LIBRARIES Boost::crypt Boost::core + ) + endif() endif() diff --git a/test/Jamfile b/test/Jamfile index 646af8e1..0ea0954e 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -35,6 +35,8 @@ project : requirements clang:-Wundef clang:-Wold-style-cast clang:-Wfloat-equal + clang-19:-Wunsafe-buffer-usage + clang-20:-Wunsafe-buffer-usage msvc:on clang:on @@ -45,150 +47,149 @@ project : requirements # ODR Violations -run link_1.cpp link_2.cpp link_3.cpp ; +#run link_1.cpp link_2.cpp link_3.cpp ; # Basic Testing run quick.cpp ; -run test_md5.cpp ; run test_sha1.cpp ; -run test_sha224.cpp ; -run test_sha256.cpp ; -run test_sha384.cpp ; -run test_sha512.cpp ; -run test_sha512_224.cpp ; -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 ; -run test_shake128.cpp ; -run test_shake256.cpp ; +#run test_sha224.cpp ; +#run test_sha256.cpp ; +#run test_sha384.cpp ; +#run test_sha512.cpp ; +#run test_sha512_224.cpp ; +#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 ; +#run test_shake128.cpp ; +#run test_shake256.cpp ; -run test_hmac.cpp ; +#run test_hmac.cpp ; -run test_hmac_drbg.cpp ; +#run test_hmac_drbg.cpp ; -run test_hash_drbg.cpp ; +#run test_hash_drbg.cpp ; -run test_aes.cpp ; +#run test_aes.cpp ; # NIST standard testing -run test_nist_cavs_sha1_monte.cpp ; +#run test_nist_cavs_sha1_monte.cpp ; run test_nist_cavs_sha1_short_long.cpp ; -run test_nist_cavs_sha1_hmac.cpp ; -run test_nist_cavs_sha1_hmac_drbg.cpp ; -run test_nist_cavs_sha1_hash_drbg.cpp ; - -run test_nist_cavs_sha224_monte.cpp ; -run test_nist_cavs_sha224_short_long.cpp ; -run test_nist_cavs_sha224_hmac.cpp ; -run test_nist_cavs_sha224_hmac_drbg.cpp ; -run test_nist_cavs_sha224_hash_drbg.cpp ; - -run test_nist_cavs_sha256_monte.cpp ; -run test_nist_cavs_sha256_short_long.cpp ; -run test_nist_cavs_sha256_hmac.cpp ; -run test_nist_cavs_sha256_hmac_drbg.cpp ; -run test_nist_cavs_sha256_hash_drbg.cpp ; - -run test_nist_cavs_sha384_monte.cpp ; -run test_nist_cavs_sha384_short_long.cpp ; -run test_nist_cavs_sha384_hmac.cpp ; -run test_nist_cavs_sha384_hmac_drbg.cpp ; -run test_nist_cavs_sha384_hash_drbg.cpp ; - -run test_nist_cavs_sha512_monte.cpp ; -run test_nist_cavs_sha512_short_long.cpp ; -run test_nist_cavs_sha512_hmac.cpp ; -run test_nist_cavs_sha512_hmac_drbg.cpp ; -run test_nist_cavs_sha512_hash_drbg.cpp ; - -run test_nist_cavs_sha512_224_monte.cpp ; -run test_nist_cavs_sha512_224_short_long.cpp ; -run test_nist_cavs_sha512_224_hmac.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_hmac.cpp ; -run test_nist_cavs_sha512_256_hmac_drbg.cpp ; -run test_nist_cavs_sha512_256_hash_drbg.cpp ; - -run test_nist_cavs_sha3_512_monte.cpp ; -run test_nist_cavs_sha3_512_short_long.cpp ; -run test_nist_cavs_sha3_512_hmac.cpp ; - -run test_nist_cavs_sha3_384_monte.cpp ; -run test_nist_cavs_sha3_384_short_long.cpp ; -run test_nist_cavs_sha3_384_hmac.cpp ; - -run test_nist_cavs_sha3_256_monte.cpp ; -run test_nist_cavs_sha3_256_short_long.cpp ; -run test_nist_cavs_sha3_256_hmac.cpp ; - -run test_nist_cavs_sha3_224_monte.cpp ; -run test_nist_cavs_sha3_224_short_long.cpp ; -run test_nist_cavs_sha3_224_hmac.cpp ; - -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_aes128_kat_ecb.cpp ; -run test_nist_cavs_aes128_mmt_ecb.cpp ; -run test_nist_cavs_aes128_mct_ecb.cpp ; -run test_nist_cavs_aes128_kat_cbc.cpp ; -run test_nist_cavs_aes128_mmt_cbc.cpp ; -run test_nist_cavs_aes128_mct_cbc.cpp ; -run test_nist_cavs_aes128_kat_ofb.cpp ; -run test_nist_cavs_aes128_mmt_ofb.cpp ; -run test_nist_cavs_aes128_mct_ofb.cpp ; -run test_nist_cavs_aes128_kat_cfb8.cpp ; -run test_nist_cavs_aes128_mmt_cfb8.cpp ; -run test_nist_cavs_aes128_mct_cfb8.cpp ; -run test_nist_cavs_aes128_kat_cfb128.cpp ; -run test_nist_cavs_aes128_mmt_cfb128.cpp ; -run test_nist_cavs_aes128_mct_cfb128.cpp ; - -run test_nist_cavs_aes192_kat_ecb.cpp ; -run test_nist_cavs_aes192_mmt_ecb.cpp ; -run test_nist_cavs_aes192_mct_ecb.cpp ; -run test_nist_cavs_aes192_kat_cbc.cpp ; -run test_nist_cavs_aes192_mmt_cbc.cpp ; -run test_nist_cavs_aes192_mct_cbc.cpp ; -run test_nist_cavs_aes192_kat_ofb.cpp ; -run test_nist_cavs_aes192_mmt_ofb.cpp ; -run test_nist_cavs_aes192_mct_ofb.cpp ; -run test_nist_cavs_aes192_kat_cfb8.cpp ; -run test_nist_cavs_aes192_mmt_cfb8.cpp ; -run test_nist_cavs_aes192_mct_cfb8.cpp ; -run test_nist_cavs_aes192_kat_cfb128.cpp ; -run test_nist_cavs_aes192_mmt_cfb128.cpp ; -run test_nist_cavs_aes192_mct_cfb128.cpp ; - -run test_nist_cavs_aes256_kat_ecb.cpp ; -run test_nist_cavs_aes256_mmt_ecb.cpp ; -run test_nist_cavs_aes256_mct_ecb.cpp ; -run test_nist_cavs_aes256_kat_cbc.cpp ; -run test_nist_cavs_aes256_mmt_cbc.cpp ; -run test_nist_cavs_aes256_mct_cbc.cpp ; -run test_nist_cavs_aes256_kat_ofb.cpp ; -run test_nist_cavs_aes256_mmt_ofb.cpp ; -run test_nist_cavs_aes256_mct_ofb.cpp ; -run test_nist_cavs_aes256_kat_cfb8.cpp ; -run test_nist_cavs_aes256_mmt_cfb8.cpp ; -run test_nist_cavs_aes256_mct_cfb8.cpp ; -run test_nist_cavs_aes256_kat_cfb128.cpp ; -run test_nist_cavs_aes256_mmt_cfb128.cpp ; -run test_nist_cavs_aes256_mct_cfb128.cpp ; +#run test_nist_cavs_sha1_hmac.cpp ; +#run test_nist_cavs_sha1_hmac_drbg.cpp ; +#run test_nist_cavs_sha1_hash_drbg.cpp ; + +#run test_nist_cavs_sha224_monte.cpp ; +#run test_nist_cavs_sha224_short_long.cpp ; +#run test_nist_cavs_sha224_hmac.cpp ; +#run test_nist_cavs_sha224_hmac_drbg.cpp ; +#run test_nist_cavs_sha224_hash_drbg.cpp ; + +#run test_nist_cavs_sha256_monte.cpp ; +#run test_nist_cavs_sha256_short_long.cpp ; +#run test_nist_cavs_sha256_hmac.cpp ; +#run test_nist_cavs_sha256_hmac_drbg.cpp ; +#run test_nist_cavs_sha256_hash_drbg.cpp ; + +#run test_nist_cavs_sha384_monte.cpp ; +#run test_nist_cavs_sha384_short_long.cpp ; +#run test_nist_cavs_sha384_hmac.cpp ; +#run test_nist_cavs_sha384_hmac_drbg.cpp ; +#run test_nist_cavs_sha384_hash_drbg.cpp ; + +#run test_nist_cavs_sha512_monte.cpp ; +#run test_nist_cavs_sha512_short_long.cpp ; +#run test_nist_cavs_sha512_hmac.cpp ; +#run test_nist_cavs_sha512_hmac_drbg.cpp ; +#run test_nist_cavs_sha512_hash_drbg.cpp ; + +#run test_nist_cavs_sha512_224_monte.cpp ; +#run test_nist_cavs_sha512_224_short_long.cpp ; +#run test_nist_cavs_sha512_224_hmac.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_hmac.cpp ; +#run test_nist_cavs_sha512_256_hmac_drbg.cpp ; +#run test_nist_cavs_sha512_256_hash_drbg.cpp ; + +#run test_nist_cavs_sha3_512_monte.cpp ; +#run test_nist_cavs_sha3_512_short_long.cpp ; +#run test_nist_cavs_sha3_512_hmac.cpp ; + +#run test_nist_cavs_sha3_384_monte.cpp ; +#run test_nist_cavs_sha3_384_short_long.cpp ; +#run test_nist_cavs_sha3_384_hmac.cpp ; + +#run test_nist_cavs_sha3_256_monte.cpp ; +#run test_nist_cavs_sha3_256_short_long.cpp ; +#run test_nist_cavs_sha3_256_hmac.cpp ; + +#run test_nist_cavs_sha3_224_monte.cpp ; +#run test_nist_cavs_sha3_224_short_long.cpp ; +#run test_nist_cavs_sha3_224_hmac.cpp ; + +#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_aes128_kat_ecb.cpp ; +#run test_nist_cavs_aes128_mmt_ecb.cpp ; +#run test_nist_cavs_aes128_mct_ecb.cpp ; +#run test_nist_cavs_aes128_kat_cbc.cpp ; +#run test_nist_cavs_aes128_mmt_cbc.cpp ; +#run test_nist_cavs_aes128_mct_cbc.cpp ; +#run test_nist_cavs_aes128_kat_ofb.cpp ; +#run test_nist_cavs_aes128_mmt_ofb.cpp ; +#run test_nist_cavs_aes128_mct_ofb.cpp ; +#run test_nist_cavs_aes128_kat_cfb8.cpp ; +#run test_nist_cavs_aes128_mmt_cfb8.cpp ; +#run test_nist_cavs_aes128_mct_cfb8.cpp ; +#run test_nist_cavs_aes128_kat_cfb128.cpp ; +#run test_nist_cavs_aes128_mmt_cfb128.cpp ; +#run test_nist_cavs_aes128_mct_cfb128.cpp ; + +#run test_nist_cavs_aes192_kat_ecb.cpp ; +#run test_nist_cavs_aes192_mmt_ecb.cpp ; +#run test_nist_cavs_aes192_mct_ecb.cpp ; +#run test_nist_cavs_aes192_kat_cbc.cpp ; +#run test_nist_cavs_aes192_mmt_cbc.cpp ; +#run test_nist_cavs_aes192_mct_cbc.cpp ; +#run test_nist_cavs_aes192_kat_ofb.cpp ; +#run test_nist_cavs_aes192_mmt_ofb.cpp ; +#run test_nist_cavs_aes192_mct_ofb.cpp ; +#run test_nist_cavs_aes192_kat_cfb8.cpp ; +#run test_nist_cavs_aes192_mmt_cfb8.cpp ; +#run test_nist_cavs_aes192_mct_cfb8.cpp ; +#run test_nist_cavs_aes192_kat_cfb128.cpp ; +#run test_nist_cavs_aes192_mmt_cfb128.cpp ; +#run test_nist_cavs_aes192_mct_cfb128.cpp ; + +#run test_nist_cavs_aes256_kat_ecb.cpp ; +#run test_nist_cavs_aes256_mmt_ecb.cpp ; +#run test_nist_cavs_aes256_mct_ecb.cpp ; +#run test_nist_cavs_aes256_kat_cbc.cpp ; +#run test_nist_cavs_aes256_mmt_cbc.cpp ; +#run test_nist_cavs_aes256_mct_cbc.cpp ; +#run test_nist_cavs_aes256_kat_ofb.cpp ; +#run test_nist_cavs_aes256_mmt_ofb.cpp ; +#run test_nist_cavs_aes256_mct_ofb.cpp ; +#run test_nist_cavs_aes256_kat_cfb8.cpp ; +#run test_nist_cavs_aes256_mmt_cfb8.cpp ; +#run test_nist_cavs_aes256_mct_cfb8.cpp ; +#run test_nist_cavs_aes256_kat_cfb128.cpp ; +#run test_nist_cavs_aes256_mmt_cfb128.cpp ; +#run test_nist_cavs_aes256_mct_cfb128.cpp ; # Note these CTR test are not official but they offer decent coverage, # by proving we can roundtrip the provided text -run test_nist_cavs_aes128_mmt_ctr.cpp ; -run test_nist_cavs_aes192_mmt_ctr.cpp ; -run test_nist_cavs_aes256_mmt_ctr.cpp ; +#run test_nist_cavs_aes128_mmt_ctr.cpp ; +#run test_nist_cavs_aes192_mmt_ctr.cpp ; +#run test_nist_cavs_aes256_mmt_ctr.cpp ; diff --git a/test/cover/make_gcov_01_generic.gmk b/test/cover/make_gcov_01_generic.gmk index 14a4b8ce..edb8090c 100644 --- a/test/cover/make_gcov_01_generic.gmk +++ b/test/cover/make_gcov_01_generic.gmk @@ -63,7 +63,7 @@ gcov: objects @$(GNUECHO) @$(GNUECHO) +++ running lcov @$(LCOV) $(LCOV_BRANCH) -c --directory obj --output-file coverage_unfiltered.info - @$(LCOV) $(LCOV_BRANCH) --remove coverage_unfiltered.info $(LCOV_REMOVES) --output-file coverage.info + @$(LCOV) $(LCOV_BRANCH) --remove coverage_unfiltered.info $(LCOV_REMOVES) --ignore-errors unused --output-file coverage.info @$(GNUECHO) @$(GNUECHO) +++ running genhtml @$(GENHTML) coverage.info $(LCOV_BRANCH) --demangle-cpp --output-directory $(PATH_BIN)/report diff --git a/test/cover/make_gcov_03_flags.gmk b/test/cover/make_gcov_03_flags.gmk index 7605ad96..859b2327 100644 --- a/test/cover/make_gcov_03_flags.gmk +++ b/test/cover/make_gcov_03_flags.gmk @@ -33,7 +33,8 @@ CXXFLAGS = -march=native \ -Wall \ -fno-inline-functions \ -fprofile-arcs \ - -ftest-coverage + -ftest-coverage \ + -std=$(STD) C_DEFINES = @@ -67,7 +68,6 @@ ifneq ($(ALL_COV),0) LCOV_BRANCH := --rc lcov_branch_coverage=1 endif -LCOV_REMOVES = '*/test/mini_to_chars.hpp' \ - '*$(MY_BOOST_ROOT)*' \ +LCOV_REMOVES = '*$(MY_BOOST_ROOT)*' \ '*/boost-root/*' \ '/usr/*' diff --git a/test/cover/make_gcov_04_rules.gmk b/test/cover/make_gcov_04_rules.gmk index 05dc73a1..9c9247a9 100644 --- a/test/cover/make_gcov_04_rules.gmk +++ b/test/cover/make_gcov_04_rules.gmk @@ -11,8 +11,6 @@ # Note: Each file with threads must be specifically, manually listed here. # Note: TBD: We can/will use a similar method for libquadmath needs. # ----------------------------------------------------------------------------- -$(PATH_BIN)/test_frexp_ldexp.exe : $(CXXFLAGS) += -pthread -lpthread - # ----------------------------------------------------------------------------- # pattern rule for compilation of cpp-files diff --git a/test/nvcc_jamfile b/test/nvcc_jamfile index 7eef3612..df8b602e 100644 --- a/test/nvcc_jamfile +++ b/test/nvcc_jamfile @@ -9,17 +9,16 @@ project : requirements [ requires cxx14_decltype_auto cxx14_generic_lambdas cxx14_return_type_deduction cxx14_variable_templates cxx14_constexpr ] ; -run test_md5_nvcc.cu ; run test_sha1_nvcc.cu ; -run test_sha224_nvcc.cu ; -run test_sha256_nvcc.cu ; -run test_sha384_nvcc.cu ; -run test_sha512_nvcc.cu ; -run test_sha512_224_nvcc.cu ; -run test_sha512_256_nvcc.cu ; -run test_sha3_512_nvcc.cu ; -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_sha224_nvcc.cu ; +#run test_sha256_nvcc.cu ; +#run test_sha384_nvcc.cu ; +#run test_sha512_nvcc.cu ; +#run test_sha512_224_nvcc.cu ; +#run test_sha512_256_nvcc.cu ; +#run test_sha3_512_nvcc.cu ; +#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 ; diff --git a/test/quick.cpp b/test/quick.cpp index 24f6e599..c2eaa12c 100644 --- a/test/quick.cpp +++ b/test/quick.cpp @@ -2,9 +2,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt -#define BOOST_CRYPT_ENABLE_MD5 - -#include +#include auto main() -> int { diff --git a/test/test_nist_cavs_detail.hpp b/test/test_nist_cavs_detail.hpp index 0ed9c237..11a77f1a 100644 --- a/test/test_nist_cavs_detail.hpp +++ b/test/test_nist_cavs_detail.hpp @@ -6,7 +6,17 @@ #ifndef BOOST_CRYPT_TEST_NIST_CAVS_DETAIL_HPP #define BOOST_CRYPT_TEST_NIST_CAVS_DETAIL_HPP +#if defined(__clang__) && __clang_major__ >= 19 +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" +#endif + #include + +#if defined(__clang__) && __clang_major__ >= 19 +#pragma clang diagnostic pop +#endif + #include "boost/crypt/mac/hmac.hpp" #include "boost/crypt/aes/detail/cipher_mode.hpp" #include @@ -15,6 +25,9 @@ #include #include #include +#include + +// LCOV_EXCL_START namespace nist { namespace cavs { @@ -41,9 +54,18 @@ inline auto convert_hex_string_to_byte_container(const std::string& str_in) -> s // Get the next two characters represented as a substring of 2 chars. const std::string str = str_in.substr(pos, 2U); + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" + #endif + // Convert a 2-char hex string to unsigned long. const unsigned long ul = std::strtoul(str.c_str(), nullptr, 16); + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic pop + #endif + container_out.push_back(std::uint8_t(ul)); } @@ -65,7 +87,7 @@ struct test_object_hash // this hash test object. explicit test_object_hash(const std::string& str_result) - : my_result // LCOV_EXCL_LINE + : my_result { [&str_result]() { @@ -650,7 +672,7 @@ auto where_file(const std::string& test_vectors_filename, test_type test) -> std const bool file_01_is_open { in_01.is_open() }; - // LCOV_EXCL_START + if(file_01_is_open) { in_01.close(); @@ -728,7 +750,7 @@ auto where_file(const std::string& test_vectors_filename, test_type test) -> std } } } - // LCOV_EXCL_STOP + return test_vectors_filename_relative; } @@ -777,8 +799,16 @@ auto parse_file_vectors(const std::string& test_vectors_filename, test_vector_co { const std::string str_len = line.substr(6U, line.length() - 6U); + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" + #endif const unsigned long length_from_file = std::strtoul(str_len.c_str(), nullptr, 10U); + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic pop + #endif + length = static_cast(length_from_file / 8U); } @@ -938,8 +968,17 @@ auto parse_file_vectors_variable_xof(const std::string& test_vectors_filename, t { const std::string str_len = line.substr(12U, line.length() - 12U); + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" + #endif + const auto length_from_file = static_cast(std::strtoul(str_len.c_str(), nullptr, 10U)); + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic pop + #endif + lengths.push_back(length_from_file / 8U); } @@ -1019,8 +1058,17 @@ auto parse_file_monte(const std::string& test_monte_filename, test_vector_contai { const std::string str_cnt = line.substr(8U, line.length() - 8U); + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" + #endif + const unsigned long count_from_file = std::strtoul(str_cnt.c_str(), nullptr, 10U); + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic pop + #endif + count = static_cast(count_from_file); } @@ -1085,6 +1133,11 @@ auto parse_file_monte_xof(const std::string& test_monte_filename, test_vector_co const bool line_is_representation_is_output_len = (pos_output_len != std::string::npos); const bool line_is_representation_is_output = (pos_output != std::string::npos); + + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" + #endif // Get the next count. if(line_is_representation_is_cnt) { @@ -1103,6 +1156,9 @@ auto parse_file_monte_xof(const std::string& test_monte_filename, test_vector_co lengths.emplace_back(len_from_file); } + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic pop + #endif // Get the next (expected) result. if(line_is_representation_is_output) @@ -1634,11 +1690,25 @@ auto test_vectors_oneshot(const test_vector_container_type& test_vectors) -> boo this_hash.init(); - this_hash.process_bytes(test_vector.my_msg.data(), test_vector.my_msg.size()); + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" + #endif + const auto data_span {std::span(test_vector.my_msg.data(), test_vector.my_msg.size())}; + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic pop + #endif + + this_hash.process_bytes(data_span); const local_result_type result_01 { this_hash.get_digest() }; - const bool result_hash_01_is_ok { std::equal(test_vector.my_result.cbegin(), test_vector.my_result.cend(), result_01.cbegin()) }; + //const bool result_hash_01_is_ok { std::equal(test_vector.my_result.cbegin(), test_vector.my_result.cend(), result_01.cbegin()) }; + bool result_hash_01_is_ok { true }; + for (std::size_t i = 0U; i < test_vector.my_result.size(); ++i) + { + result_hash_01_is_ok &= (static_cast(test_vector.my_result[i]) == result_01[i]); + } BOOST_TEST(result_hash_01_is_ok); @@ -1650,11 +1720,15 @@ auto test_vectors_oneshot(const test_vector_container_type& test_vectors) -> boo this_hash.init(); - this_hash.process_bytes(test_vector.my_msg.data(), test_vector.my_msg.size()); + this_hash.process_bytes(data_span); const local_result_type result_02 { this_hash.get_digest() }; - const bool result_hash_02_is_ok { std::equal(test_vector.my_result.cbegin(), test_vector.my_result.cend(), result_02.cbegin()) }; + bool result_hash_02_is_ok { true }; + for (std::size_t i = 0U; i < test_vector.my_result.size(); ++i) + { + result_hash_01_is_ok &= (static_cast(test_vector.my_result[i]) == result_02[i]); + } BOOST_TEST(result_hash_02_is_ok); @@ -1684,10 +1758,10 @@ auto test_vectors_variable(const test_vector_container_type& test_vectors, const // Use the triple-combination of init/process/get-result functions. this_hash.init(); + const auto data_span {std::span(test_vector.my_msg.data(), test_vector.my_msg.size())}; + this_hash.process_bytes(data_span); - this_hash.process_bytes(test_vector.my_msg.data(), test_vector.my_msg.size()); - - std::vector bits {}; + std::vector bits {}; bits.resize(lengths[i]); const auto result_01 { this_hash.get_digest(bits) }; @@ -1697,7 +1771,7 @@ auto test_vectors_variable(const test_vector_container_type& test_vectors, const { if (!BOOST_TEST_EQ(test_vector.my_result[j], bits[j])) { - false_counter++; // LCOV_EXCL_LINE + false_counter++; } } @@ -1711,11 +1785,11 @@ auto test_vectors_variable(const test_vector_container_type& test_vectors, const this_hash.init(); - this_hash.process_bytes(test_vector.my_msg.data(), test_vector.my_msg.size()); + this_hash.process_bytes(data_span); for (auto& bit : bits) { - bit = static_cast(0); + bit = static_cast(0); } const auto result_02 { this_hash.get_digest(bits) }; @@ -1726,7 +1800,7 @@ auto test_vectors_variable(const test_vector_container_type& test_vectors, const { if (!BOOST_TEST_EQ(test_vector.my_result[j], bits[j])) { - false_counter++; // LCOV_EXCL_LINE + false_counter++; } } @@ -1937,7 +2011,7 @@ auto test_vectors_monte_xof(const nist::cavs::test_vector_container_type& test_v for (auto& val : MDi) { // LCOV skips the following line even though MDi is not empty - val = static_cast(0); // LCOV_EXCL_LINE + val = static_cast(0); } const auto output_length = this_hash.get_digest(MDi); @@ -2047,14 +2121,14 @@ auto test_vectors_drbg_no_reseed(const nist::cavs::test_vector_container_drbg_no { if (return_bits[i] != test_vector.result[i]) { - // LCOV_EXCL_START + result_is_ok = false; std::cerr << "Error with vector: " << count << "\nBeginning of entropy: " << std::to_string(test_vector.initial_entropy[0]) << ", " << std::to_string(test_vector.initial_entropy[1]) << ", " << std::to_string(test_vector.initial_entropy[2]) << std::endl; break; - // LCOV_EXCL_STOP + } } ++count; @@ -2094,14 +2168,14 @@ auto test_vectors_drbg_pr_false(const nist::cavs::test_vector_container_drbg_pr_ { if (return_bits[i] != test_vector.result[i]) { - // LCOV_EXCL_START + result_is_ok = false; std::cerr << "Error with vector: " << count << "\nBeginning of entropy: " << std::to_string(test_vector.initial_entropy[0]) << ", " << std::to_string(test_vector.initial_entropy[1]) << ", " << std::to_string(test_vector.initial_entropy[2]) << std::endl; break; - // LCOV_EXCL_STOP + } } ++count; @@ -2140,14 +2214,14 @@ auto test_vectors_drbg_pr_true(const nist::cavs::test_vector_container_drbg_pr_t { if (return_bits[i] != test_vector.result[i]) { - // LCOV_EXCL_START + result_is_ok = false; std::cerr << "Error with vector: " << count << "\nBeginning of entropy: " << std::to_string(test_vector.initial_entropy[0]) << ", " << std::to_string(test_vector.initial_entropy[1]) << ", " << std::to_string(test_vector.initial_entropy[2]) << std::endl; break; - // LCOV_EXCL_STOP + } } ++count; @@ -2188,10 +2262,10 @@ auto test_vectors_aes_ctr(const nist::cavs::test_vector_container_aes &test_vect if (plaintext != test_vector.plaintext) { - // LCOV_EXCL_START + result_is_ok = false; std::cerr << "Error with vector: " << count << std::endl; - // LCOV_EXCL_STOP + } ++count; @@ -2255,10 +2329,10 @@ auto test_vectors_aes_kat(const nist::cavs::test_vector_container_aes& test_vect if (plaintext != ciphertext) { - // LCOV_EXCL_START + result_is_ok = false; std::cerr << "Error with vector: " << count << std::endl; - // LCOV_EXCL_STOP + } ++count; @@ -2321,10 +2395,10 @@ auto test_vectors_aes_mmt(const nist::cavs::test_vector_container_aes& test_vect if (plaintext != ciphertext) { - // LCOV_EXCL_START + result_is_ok = false; std::cerr << "Error with vector: " << count << std::endl; - // LCOV_EXCL_STOP + } ++count; @@ -2449,10 +2523,10 @@ auto test_vectors_aes_mct(const nist::cavs::test_vector_container_aes& test_vect if (plaintext != ciphertext) { - // LCOV_EXCL_START + result_is_ok = false; std::cerr << "Error with vector: " << count << std::endl; - // LCOV_EXCL_STOP + } ++count; @@ -2468,4 +2542,6 @@ auto test_vectors_aes_mct(const nist::cavs::test_vector_container_aes& test_vect } // namespace cavs } // namespace nist +// LCOV_EXCL_STOP + #endif // BOOST_CRYPT_TEST_NIST_CAVS_DETAIL_HPP diff --git a/test/test_nist_cavs_sha1_short_long.cpp b/test/test_nist_cavs_sha1_short_long.cpp index ba8024fa..6f38ebe7 100644 --- a/test/test_nist_cavs_sha1_short_long.cpp +++ b/test/test_nist_cavs_sha1_short_long.cpp @@ -3,7 +3,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt -#include +#include #include "test_nist_cavs_detail.hpp" diff --git a/test/test_sha1.cpp b/test/test_sha1.cpp index b1241b33..f0b8fe46 100644 --- a/test/test_sha1.cpp +++ b/test/test_sha1.cpp @@ -2,27 +2,17 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt -#include -#include -#include "generate_random_strings.hpp" - -#ifdef __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wconversion" -# pragma clang diagnostic ignored "-Wold-style-cast" -#elif defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wconversion" -# pragma GCC diagnostic ignored "-Wsign-conversion" -# pragma GCC diagnostic ignored "-Wold-style-cast" +#include + +#if defined(__clang__) && __clang_major__ >= 19 +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" #endif -#include +#include -#ifdef __clang__ -# pragma clang diagnostic pop -#elif defined(__GNUC__) -# pragma GCC diagnostic pop +#if defined(__clang__) && __clang_major__ >= 19 +#pragma clang diagnostic pop #endif #include @@ -34,49 +24,37 @@ #include #include #include +#include +#include -auto get_boost_uuid_result(const char* str, size_t length) -{ - unsigned char digest[20]; - boost::uuids::detail::sha1 hasher; - hasher.process_bytes(str, length); - hasher.get_digest(digest); - - std::array return_array {}; - for (std::size_t i {}; i < 20U; ++i) - { - return_array[i] = digest[i]; - } - - return return_array; -} +using std::byte; -constexpr std::array>, 7> test_values = +const std::array>, 7> test_values = { // Start with the sample hashes from wiki - std::make_tuple("The quick brown fox jumps over the lazy dog", + std::make_tuple(std::string{"The quick brown fox jumps over the lazy dog"}, std::array{0x2f, 0xd4, 0xe1, 0xc6, 0x7a, 0x2d, 0x28, 0xfc, 0xed, 0x84, 0x9e, 0xe1, 0xbb, 0x76, 0xe7, 0x39, 0x1b, 0x93, 0xeb, 0x12}), - std::make_tuple("The quick brown fox jumps over the lazy cog", + std::make_tuple(std::string{"The quick brown fox jumps over the lazy cog"}, std::array{0xde, 0x9f, 0x2c, 0x7f, 0xd2, 0x5e, 0x1b, 0x3a, 0xfa, 0xd3, 0xe8, 0x5a, 0x0b, 0xd1, 0x7d, 0x9b, 0x10, 0x0d, 0xb4, 0xb3}), - std::make_tuple("", + std::make_tuple(std::string{""}, std::array{0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09}), // Now the ones from the RFC - std::make_tuple("abc", + std::make_tuple(std::string{"abc"}, std::array{0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D}), - std::make_tuple("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + std::make_tuple(std::string{"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, std::array{0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1}), - std::make_tuple("a", + std::make_tuple(std::string{"a"}, std::array{0x86, 0xf7, 0xe4, 0x37, 0xfa, 0xa5, 0xa7, 0xfc, 0xe1, 0x5d, 0x1d, 0xdc, 0xb9, 0xea, 0xea, 0xea, 0x37, 0x76, 0x67, 0xb8}), - std::make_tuple("0123456701234567012345670123456701234567012345670123456701234567", + std::make_tuple(std::string{"0123456701234567012345670123456701234567012345670123456701234567"}, std::array{0xe0, 0xc0, 0x94, 0xe8, 0x67, 0xef, 0x46, 0xc3, 0x50, 0xef, 0x54, 0xa7, 0xf5, 0x9d, 0xd6, 0x0b, 0xed, 0x92, 0xae, 0x83}), }; @@ -89,7 +67,7 @@ void basic_tests() const auto valid_result {std::get<1>(test_value)}; for (std::size_t i {}; i < message_result.size(); ++i) { - if (!BOOST_TEST_EQ(message_result[i], valid_result[i])) + if (!BOOST_TEST(message_result[i] == static_cast(valid_result[i]))) { // LCOV_EXCL_START std::cerr << "Failure with: " << std::get<0>(test_value) << '\n'; @@ -109,7 +87,7 @@ void string_test() const auto valid_result {std::get<1>(test_value)}; for (std::size_t i {}; i < message_result.size(); ++i) { - if (!BOOST_TEST_EQ(message_result[i], valid_result[i])) + if (!BOOST_TEST(message_result[i] == static_cast(valid_result[i]))) { // LCOV_EXCL_START std::cerr << "Failure with: " << std::get<0>(test_value) << '\n'; @@ -122,7 +100,6 @@ void string_test() void string_view_test() { - #ifdef BOOST_CRYPT_HAS_STRING_VIEW for (const auto& test_value : test_values) { const std::string string_message {std::get<0>(test_value)}; @@ -131,7 +108,7 @@ void string_view_test() const auto valid_result {std::get<1>(test_value)}; for (std::size_t i {}; i < message_result.size(); ++i) { - if (!BOOST_TEST_EQ(message_result[i], valid_result[i])) + if (!BOOST_TEST(message_result[i] == static_cast(valid_result[i]))) { // LCOV_EXCL_START std::cerr << "Failure with: " << std::get<0>(test_value) << '\n'; @@ -140,41 +117,6 @@ void string_view_test() } } } - #endif -} - -void bad_input() -{ - const auto null_message {boost::crypt::sha1(static_cast(nullptr))}; - BOOST_TEST_EQ(null_message[0], 0x0); - BOOST_TEST_EQ(null_message[1], 0x0); - BOOST_TEST_EQ(null_message[2], 0x0); - BOOST_TEST_EQ(null_message[3], 0x0); - - const auto null_message_len {boost::crypt::sha1(static_cast(nullptr), 100)}; - BOOST_TEST_EQ(null_message_len[0], 0x0); - BOOST_TEST_EQ(null_message_len[1], 0x0); - BOOST_TEST_EQ(null_message_len[2], 0x0); - BOOST_TEST_EQ(null_message_len[3], 0x0); - - const auto unsigned_null_message {boost::crypt::sha1(static_cast(nullptr))}; - BOOST_TEST_EQ(unsigned_null_message[0], 0x0); - BOOST_TEST_EQ(unsigned_null_message[1], 0x0); - BOOST_TEST_EQ(unsigned_null_message[2], 0x0); - BOOST_TEST_EQ(unsigned_null_message[3], 0x0); - - const auto unsigned_null_message_len {boost::crypt::sha1(static_cast(nullptr), 100)}; - BOOST_TEST_EQ(unsigned_null_message_len[0], 0x0); - BOOST_TEST_EQ(unsigned_null_message_len[1], 0x0); - BOOST_TEST_EQ(unsigned_null_message_len[2], 0x0); - BOOST_TEST_EQ(unsigned_null_message_len[3], 0x0); - - std::string test_str {"Test string"}; - const auto reveresed_input {boost::crypt::detail::sha1(test_str.end(), test_str.begin())}; - BOOST_TEST_EQ(reveresed_input[0], 0x0); - BOOST_TEST_EQ(reveresed_input[1], 0x0); - BOOST_TEST_EQ(reveresed_input[2], 0x0); - BOOST_TEST_EQ(reveresed_input[3], 0x0); } void test_class() @@ -183,14 +125,15 @@ void test_class() for (const auto& test_value : test_values) { + hasher.init(); const auto msg {std::get<0>(test_value)}; - hasher.process_bytes(msg, std::strlen(msg)); + hasher.process_bytes(msg); const auto message_result {hasher.get_digest()}; const auto valid_result {std::get<1>(test_value)}; for (std::size_t i {}; i < message_result.size(); ++i) { - if (!BOOST_TEST_EQ(message_result[i], valid_result[i])) + if (!BOOST_TEST(message_result[i] == static_cast(valid_result[i]))) { // LCOV_EXCL_START std::cerr << "Failure with: " << std::get<0>(test_value) << '\n'; @@ -198,108 +141,21 @@ void test_class() // LCOV_EXCL_STOP } } - - hasher.init(); - } -} - -template -void test_random_values() -{ - constexpr std::size_t max_str_len {65535U}; - std::mt19937_64 rng(42); - std::uniform_int_distribution str_len(1, max_str_len - 1); - - char* str {new char[max_str_len]}; - - for (std::size_t i {}; i < 1024; ++i) - { - std::memset(str, '\0', max_str_len); - 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)}; - - // boost::crypt::array is implicitly convertible to std::array - const std::array crypt_res = boost::crypt::sha1(str, current_str_len); - - for (std::size_t j {}; j < crypt_res.size(); ++j) - { - if (!BOOST_TEST_EQ(uuid_res[j], crypt_res[j])) - { - // LCOV_EXCL_START - std::cerr << "Failure with string: " << str << std::endl; - break; - // LCOV_EXCL_STOP - } - } } - delete[] str; + const std::string bad_update_msg {"bad"}; + BOOST_TEST(hasher.process_bytes(bad_update_msg) == boost::crypt::state::state_error); + BOOST_TEST(hasher.finalize() == boost::crypt::state::state_error); + BOOST_TEST(hasher.get_digest() == boost::crypt::sha1_hasher::return_type{}); } -template -void test_random_piecewise_values() -{ - constexpr std::size_t max_str_len {65535U}; - std::mt19937_64 rng(42); - std::uniform_int_distribution str_len(1, max_str_len - 1); - - char* str {new char[max_str_len]}; - char* str_2 {new char[max_str_len]}; - - for (std::size_t i {}; i < 1024; ++i) - { - boost::uuids::detail::sha1 boost_hasher; - boost::crypt::sha1_hasher sha1_hasher; - - std::memset(str, '\0', max_str_len); - std::memset(str_2, '\0', max_str_len); - - const std::size_t current_str_len {str_len(rng)}; - boost::crypt::generate_random_string(str, current_str_len); - boost::crypt::generate_random_string(str_2, current_str_len); - - boost_hasher.process_bytes(str, current_str_len); - boost_hasher.process_bytes(str_2, current_str_len); - boost_hasher.process_byte(52); // "4" - unsigned char digest[20]; - boost_hasher.get_digest(digest); - - std::array uuid_res {}; - for (std::size_t j {}; j < 20U; ++j) - { - uuid_res[j] = digest[j]; - } - - sha1_hasher.process_bytes(str, current_str_len); - sha1_hasher.process_bytes(str_2, current_str_len); - sha1_hasher.process_byte(52); // "4" - const auto crypt_res {sha1_hasher.get_digest()}; - - for (std::size_t j {}; j < crypt_res.size(); ++j) - { - if (!BOOST_TEST_EQ(uuid_res[j], crypt_res[j])) - { - // LCOV_EXCL_START - std::cerr << "Failure with string: " << str << std::endl; - break; - // LCOV_EXCL_STOP - } - } - } - - delete[] str; - delete[] str_2; -} - -template -void test_file(T filename, const std::array& res) +void test_file(const std::string& filename, const std::array& res) { const auto crypt_res {boost::crypt::sha1_file(filename)}; for (std::size_t j {}; j < crypt_res.size(); ++j) { - if (!BOOST_TEST_EQ(res[j], crypt_res[j])) + if (!BOOST_TEST(static_cast(res[j]) == crypt_res[j])) { // LCOV_EXCL_START std::cerr << "Failure with file: " << filename << std::endl; @@ -309,24 +165,17 @@ void test_file(T filename, const std::array& res) } } -template -void test_invalid_file(T filename) +// These tests end up showing red on LCOV becuase they are constexpr executed +// LCOV_EXCL_START +void test_invalid_file(const std::string& filename) { - constexpr std::array res{}; + constexpr std::array res{}; const auto crypt_res {boost::crypt::sha1_file(filename)}; - for (std::size_t j {}; j < crypt_res.size(); ++j) - { - if (!BOOST_TEST_EQ(res[j], crypt_res[j])) - { - // LCOV_EXCL_START - std::cerr << "Failure with file: " << filename << std::endl; - break; - // LCOV_EXCL_STOP - } - } + BOOST_TEST(res == crypt_res); } +// LCOV_EXCL_STOP void files_test() { @@ -392,15 +241,10 @@ void files_test() #endif const auto invalid_filename = "broken.bin"; - test_invalid_file(invalid_filename); + BOOST_TEST_THROWS(test_invalid_file(invalid_filename), std::runtime_error); const std::string str_invalid_filename {invalid_filename}; - test_invalid_file(str_invalid_filename); - - #ifdef BOOST_CRYPT_HAS_STRING_VIEW - const std::string_view str_view_invalid_filename {str_invalid_filename}; - test_invalid_file(str_view_invalid_filename); - #endif + BOOST_TEST_THROWS(test_invalid_file(str_invalid_filename), std::runtime_error); // On macOS 15 // sha1 test_file_2.txt @@ -409,100 +253,19 @@ void files_test() 0x47, 0x99, 0xb4, 0x7b, 0xd9, 0x25, 0x5a, 0xc9, 0xcb, 0x65}; test_file(filename_2, res_2); - - const char* test_null_file = nullptr; - test_invalid_file(test_null_file); } -void test_invalid_state() -{ - boost::crypt::sha1_hasher hasher; - auto current_state = hasher.process_bytes("test", 4); - BOOST_TEST(current_state == boost::crypt::state::success); - - hasher.get_digest(); - - const auto bad_state = hasher.process_bytes("test", 4); - BOOST_TEST(bad_state == boost::crypt::state::state_error); - - const auto digest = hasher.get_digest(); - - for (const auto& val : digest) - { - BOOST_TEST_EQ(val, static_cast(0)); - } - - hasher.init(); - - current_state = hasher.process_bytes("test", 4); - BOOST_TEST(current_state == boost::crypt::state::success); - const char* ptr = nullptr; - current_state = hasher.process_bytes(ptr, 4); - BOOST_TEST(current_state == boost::crypt::state::null); - - const char16_t* ptr16 = nullptr; - current_state = hasher.process_bytes(ptr16, 4); - BOOST_TEST(current_state == boost::crypt::state::null); - - const char32_t* ptr32 = nullptr; - current_state = hasher.process_bytes(ptr32, 4); - BOOST_TEST(current_state == boost::crypt::state::null); - - const wchar_t* wptr = nullptr; - current_state = hasher.process_bytes(wptr, 4); - BOOST_TEST(current_state == boost::crypt::state::null); -} - -// This ends up being completely calculated in a constexpr fashion so Codecov complains -// LCOV_EXCL_START -void test_span() -{ - #ifdef BOOST_CRYPT_HAS_SPAN - - // "abc" in hex - const std::byte vals[] = {std::byte{0x61}, std::byte{0x62}, std::byte{0x63}}; - std::span byte_span {vals}; - const auto expected_res = std::array{0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, - 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D}; - const auto res = boost::crypt::sha1(byte_span); - - for (std::size_t i {}; i < res.size(); ++i) - { - BOOST_TEST_EQ(res[i], expected_res[i]); - } - - #endif // BOOST_CRYPT_HAS_SPAN -} -// LCOV_EXCL_STOP - int main() { basic_tests(); string_test(); string_view_test(); - bad_input(); test_class(); - test_random_values(); - test_random_piecewise_values(); - - test_random_values(); - test_random_piecewise_values(); - - test_random_values(); - test_random_piecewise_values(); - - test_random_values(); - test_random_piecewise_values(); - // The Windows file system returns a different result than on UNIX platforms #if defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)) files_test(); #endif - test_invalid_state(); - - test_span(); - return boost::report_errors(); } diff --git a/test/test_sha1_nvcc.cu b/test/test_sha1_nvcc.cu index bfa5b3bd..f76623e0 100644 --- a/test/test_sha1_nvcc.cu +++ b/test/test_sha1_nvcc.cu @@ -3,7 +3,8 @@ // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#include +#include +#include #include "cuda_managed_ptr.hpp" #include "stopwatch.hpp" #include "generate_random_strings.hpp" @@ -11,10 +12,9 @@ #include #include #include +#include -#include - -using digest_type = boost::crypt::array; +using digest_type = cuda::std::array; // The kernel function __global__ void cuda_test(char** in, digest_type* out, int numElements) @@ -23,7 +23,8 @@ __global__ void cuda_test(char** in, digest_type* out, int numElements) if (i < numElements) { - out[i] = boost::crypt::sha1(in[i]); + auto in_span {cuda::std::span(in[i], 64)}; + out[i] = boost::crypt::sha1(in_span); } } @@ -59,7 +60,7 @@ int main() // Launch the Vector Add CUDA Kernel int threadsPerBlock = 256; - int blocksPerGrid =(numElements + threadsPerBlock - 1) / threadsPerBlock; + int blocksPerGrid = (numElements + threadsPerBlock - 1) / threadsPerBlock; std::cout << "CUDA kernel launch with " << blocksPerGrid << " blocks of " << threadsPerBlock << " threads" << std::endl; watch w; @@ -80,7 +81,8 @@ int main() w.reset(); for(int i = 0; i < numElements; ++i) { - results.emplace_back(boost::crypt::sha1(input_vector1[i])); + std::span in(input_vector1[i], elementSize); + results.emplace_back(boost::crypt::sha1(in)); } double t = w.elapsed();