9#ifndef BOTAN_SPONGE_PROCESSING_H_
10#define BOTAN_SPONGE_PROCESSING_H_
12#include <botan/exceptn.h>
13#include <botan/internal/loadstor.h>
14#include <botan/internal/stl_util.h>
23concept SpongeLike = std::unsigned_integral<
decltype(T::word_bytes)> &&
requires(
T a) {
26 { a.state() } -> std::same_as<typename T::state_t&>;
27 { a._cursor() } -> std::same_as<size_t&>;
28 { a.byte_rate() } -> std::same_as<size_t>;
33 { a.permute() } -> std::same_as<void>;
42template <SpongeLike SpongeT>
49 using word_t =
typename SpongeT::word_t;
50 constexpr static auto word_bytes = SpongeT::word_bytes;
58 std::array<uint8_t, word_bytes> partial_word_bytes{};
60 return load_le(partial_word_bytes);
68 const auto partial_word_bytes =
store_le(partial_word);
79 const auto mask = ((word_t(0) - 1) >> ((word_bytes -
length) * 8)) << (
offset * 8);
80 return (state_word & ~mask) | (partial_input_word & mask);
88template <SpongeLike SpongeT>
91 using word_t =
typename SpongeT::word_t;
92 constexpr static auto word_bytes = SpongeT::word_bytes;
105template <
typename T,
typename SpongeT,
typename ModifierT>
107 { std::invoke(fn,
word, bounds) } -> std::same_as<typename SpongeT::word_t>;
110template <
typename T,
typename SpongeT>
133template <detail::SpongeLike SpongeT>
135 size_t bytes_to_process,
138 if(bytes_to_process == 0) {
142 constexpr auto word_bytes = SpongeT::word_bytes;
143 const auto byte_rate = sponge.byte_rate();
144 auto& S = sponge.state();
145 auto& cursor = sponge._cursor();
148 const auto bytes_out_of_word_alignment =
static_cast<size_t>(cursor % word_bytes);
149 if(bytes_out_of_word_alignment > 0) {
150 const auto bytes_until_word_alignment = word_bytes - bytes_out_of_word_alignment;
151 const auto bytes_from_input = std::min(bytes_to_process, bytes_until_word_alignment);
154 S[cursor / word_bytes] = modifier_fn(S[cursor / word_bytes],
156 .offset = bytes_out_of_word_alignment,
157 .length = bytes_from_input,
159 cursor += bytes_from_input;
160 bytes_to_process -= bytes_from_input;
162 if(cursor == byte_rate) {
174 while(bytes_to_process >= word_bytes) {
177 while(bytes_to_process >= word_bytes && cursor < byte_rate) {
179 cursor += word_bytes;
180 bytes_to_process -= word_bytes;
183 if(cursor == byte_rate) {
193 if(bytes_to_process > 0) {
194 S[cursor / word_bytes] = modifier_fn(S[cursor / word_bytes],
197 .length = bytes_to_process,
199 cursor += bytes_to_process;
203template <detail::SpongeLikeWithTrivialPermute SpongeT>
205 size_t bytes_to_process,
208 sponge, bytes_to_process, [&sponge] { sponge.permute(); }, modifier_fn);
218template <detail::SpongeLike SpongeT>
220 std::span<const uint8_t> input,
222 using word_t =
typename SpongeT::word_t;
226 return state_word ^ bounds.read_from(input_slicer);
242template <detail::SpongeLike SpongeT>
244 std::span<uint8_t> output,
246 using word_t =
typename SpongeT::word_t;
250 bounds.write_into(output_stuffer, state_word);
#define BOTAN_ASSERT_NOMSG(expr)
#define BOTAN_DEBUG_ASSERT(expr)
void copy_into(std::span< uint8_t > sink)
std::span< const uint8_t > take(const size_t count)
Helper class to ease in-place marshalling of concatenated fixed-length values.
constexpr void append(std::span< const uint8_t > buffer)
constexpr bool full() const
word_t masked_assignment(word_t, word_t full_input_word) const
word_t read_from(BufferSlicer &slicer) const
void write_into(BufferStuffer &stuffer, word_t full_word) const
word_t masked_assignment(word_t state_word, word_t partial_input_word) const
void write_into(BufferStuffer &stuffer, word_t partial_word) const
word_t read_from(BufferSlicer &slicer) const
int(* final)(unsigned char *, CTX *)
#define BOTAN_FORCE_INLINE
BOTAN_FORCE_INLINE void process_bytes_in_sponge(SpongeT &sponge, size_t bytes_to_process, const detail::PermutationFn auto &permutation_fn, const detail::ModifierFn< SpongeT > auto &modifier_fn)
void squeeze_from_sponge(SpongeT &sponge, std::span< uint8_t > output, const detail::PermutationFn auto &permutation_fn)
constexpr auto store_le(ParamTs &&... params)
constexpr auto load_le(ParamTs &&... params)
void absorb_into_sponge(SpongeT &sponge, std::span< const uint8_t > input, const detail::PermutationFn auto &permutation_fn)
std::conditional_t< HasNative64BitRegisters, std::uint64_t, uint32_t > word