#ifndef ALCRYPTOLIB_STREAM_HASH_HASH_BASE_2019_04_17_H #define ALCRYPTOLIB_STREAM_HASH_HASH_BASE_2019_04_17_H #include #include #include #include #include #include #if(__cplusplus >= 201703L) namespace al::crypto::stream::hash { #else namespace al { namespace crypto { namespace stream { namespace hash { #endif template class hash_base : public al::crypto::stream::stream> { private: using base_class_type = al::crypto::stream::stream>; public: // AXIVION Next Line AutosarC++19_03-M11.0.1: AUTOSAR permitted static constexpr auto result_bit_count = static_cast(ResultBitCount); ~hash_base() override = default; auto initialize() -> void override { message_index = static_cast (0U); message_length_total = static_cast(0U); clear_message_buffer(); clear_transform_context(); } auto process_data(const std::uint8_t* message, const std::size_t count) -> void override { auto process_index = static_cast(0U); auto process_chunk_size = static_cast(0U); while(process_index < count) { message_index = static_cast (message_index + process_chunk_size); message_length_total = static_cast(message_length_total + process_chunk_size); process_index = static_cast (process_index + process_chunk_size); if(message_index == message_buffer_static_size) { // Note: the transform() method is responsible // for setting message_index back to 0. this->transform(); } const auto count_remaining = static_cast(count - process_index); const auto buf_available = static_cast(message_buffer_static_size - message_index); process_chunk_size = (std::min)(count_remaining, buf_available); static_cast ( // AXIVION Next Line AutosarC++19_03-M5.0.15: AUTOSAR permitted std::copy(message + process_index, // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) // AXIVION Next Line AutosarC++19_03-M5.0.15: AUTOSAR permitted message + (process_index + process_chunk_size), // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) // AXIVION Next Line AutosarC++19_03-M5.0.15: AUTOSAR permitted message_buffer.begin() + static_cast(message_index)) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) ); } } protected: using transform_context_value_type = ContextElementType; static constexpr auto conversion_scale() noexcept -> std::size_t { return static_cast ( std::numeric_limits::digits / static_cast(INT8_C(8)) ); } using message_buffer_type = std::array; // AXIVION Next Line AutosarC++19_03-M11.0.1: AUTOSAR permitted static constexpr auto message_buffer_static_size = static_cast ( std::tuple_size::value ); using transform_context_type = std::array::digits>; // AXIVION Next Line AutosarC++19_03-M11.0.1: AUTOSAR permitted std::size_t message_index { }; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes,misc-non-private-member-variables-in-classes) // AXIVION Next Line AutosarC++19_03-M11.0.1: AUTOSAR permitted std::uint_fast64_t message_length_total { }; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes,misc-non-private-member-variables-in-classes) // AXIVION Next Line AutosarC++19_03-M11.0.1: AUTOSAR permitted message_buffer_type message_buffer { }; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes,misc-non-private-member-variables-in-classes) // AXIVION Next Line AutosarC++19_03-M11.0.1: AUTOSAR permitted transform_context_type transform_context { }; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes,misc-non-private-member-variables-in-classes) hash_base() = default; hash_base(const hash_base&) = default; hash_base(hash_base&&) noexcept = default; // AXIVION Next Line AutosarC++19_03-A10.2.1: AUTOSAR permitted auto operator=(const hash_base&) -> hash_base& = default; // AXIVION Next Line AutosarC++19_03-A10.2.1: AUTOSAR permitted auto operator=(hash_base&&) noexcept -> hash_base& = default; virtual auto transform() -> void = 0; auto clear_message_buffer() -> void { const auto zero = static_cast(UINT8_C(0)); message_buffer.fill(zero); } auto clear_transform_context() -> void { const auto zero = static_cast(UINT8_C(0)); transform_context.fill(zero); } auto copy_message_buffer_forward(typename transform_context_type::pointer dest) const -> void { const auto local_conversion_scale = conversion_scale(); // AXIVION Next Line AutosarC++19_03-M6.5.4: AUTOSAR permitted for(auto copy_index = static_cast(UINT8_C(0)); copy_index < std::tuple_size::value; copy_index = static_cast(copy_index + local_conversion_scale)) { { const auto idx = static_cast ( copy_index / conversion_scale() ); *(dest + idx) = static_cast(0U); } for(auto j = static_cast(UINT8_C(0)); j < conversion_scale(); ++j) { const auto left_shift_amount = static_cast(j * static_cast(UINT8_C(8))); const auto dest_index = static_cast ( copy_index / conversion_scale() ); // AXIVION Next Line AutosarC++19_03-M5.0.15: AUTOSAR permitted *(dest + dest_index) |= static_cast(static_cast(message_buffer[copy_index + j]) << left_shift_amount); } } } auto copy_transform_context_forward ( typename base_class_type::result_type::pointer result_dest, const std::size_t src_offset = static_cast(UINT8_C(0))) const -> void { for(auto output_index = static_cast(0U); output_index < std::tuple_size::value; ++output_index) { const auto right_shift_amount = static_cast ( static_cast(output_index % conversion_scale()) * 8U ); const auto src_index = static_cast ( src_offset + (output_index / conversion_scale()) ); // AXIVION Next Line AutosarC++19_03-M5.0.15: AUTOSAR permitted *(result_dest + output_index) = static_cast ( transform_context[src_index] >> right_shift_amount ); } } auto copy_message_buffer_reverse(typename transform_context_type::pointer dest) const -> void { const auto local_conversion_scale = conversion_scale(); // AXIVION Next Line AutosarC++19_03-M6.5.4: AUTOSAR permitted for(auto copy_index = static_cast(UINT8_C(0)); copy_index < std::tuple_size::value; copy_index = static_cast(copy_index + local_conversion_scale)) { { const auto idx = static_cast ( copy_index / conversion_scale() ); // AXIVION Next Line AutosarC++19_03-M5.0.15: AUTOSAR permitted *(dest + idx) = static_cast(UINT8_C(0)); } for(auto j = static_cast(UINT8_C(0)); j < conversion_scale(); ++j) { const auto left_shift_amount = static_cast ( static_cast ( static_cast ( static_cast(conversion_scale() - static_cast(UINT8_C(1))) - j ) * static_cast(UINT8_C(8)) ) ); const auto dest_index = static_cast ( copy_index / conversion_scale() ); // AXIVION Next Line AutosarC++19_03-M5.0.15: AUTOSAR permitted *(dest + dest_index) |= static_cast(static_cast(message_buffer[copy_index + j]) << left_shift_amount); } } } auto copy_transform_context_reverse(typename base_class_type::result_type::pointer result_dest, const std::size_t src_offset = static_cast(UINT8_C(0))) const -> void { for(auto output_index = static_cast(UINT8_C(0)); output_index < std::tuple_size::value; ++output_index) { const auto right_shift_amount = static_cast ( static_cast ( static_cast ( static_cast(conversion_scale() - static_cast(UINT8_C(1))) - static_cast(output_index % conversion_scale()) ) * static_cast(UINT8_C(8)) ) ); const auto context_index = static_cast ( src_offset + (output_index / conversion_scale()) ); // AXIVION Next Line AutosarC++19_03-M5.0.15: AUTOSAR permitted *(result_dest + output_index) = static_cast ( transform_context[context_index] >> right_shift_amount ); } } }; #if(__cplusplus >= 201703L) } // namespace al::crypto::stream::hash #else } // namespace hash } // namespace stream } // namespace crypto } // namespace al #endif #endif // ALCRYPTOLIB_STREAM_HASH_HASH_BASE_2019_04_17_H