10#include <botan/internal/keccak_perm.h>
12#include <botan/exceptn.h>
13#include <botan/internal/fmt.h>
14#include <botan/internal/keccak_perm_round.h>
15#include <botan/internal/loadstor.h>
16#include <botan/internal/stl_util.h>
18#if defined(BOTAN_HAS_CPUID)
19 #include <botan/internal/cpuid.h>
27 m_custom_padding(custom_padding),
28 m_custom_padding_bit_len(custom_padding_bit_len),
36#if defined(BOTAN_HAS_KECCAK_PERM_BMI2)
56 while(!input_slicer.
empty()) {
57 const size_t to_take_this_round = std::min(input_slicer.
remaining(), m_byterate - m_S_inpos);
61 for(; !input_this_round.
empty() && m_S_inpos % 8 > 0; ++m_S_inpos) {
62 m_S[m_S_inpos / 8] ^=
static_cast<uint64_t
>(input_this_round.
take_byte()) << (8 * (m_S_inpos % 8));
66 for(; input_this_round.
remaining() >= 8; m_S_inpos += 8) {
71 for(; !input_this_round.
empty(); ++m_S_inpos) {
72 m_S[m_S_inpos / 8] ^=
static_cast<uint64_t
>(input_this_round.
take_byte()) << (8 * (m_S_inpos % 8));
76 if(m_S_inpos == m_byterate) {
88 while(!output_stuffer.
full()) {
89 const size_t bytes_in_this_round = std::min(output_stuffer.
remaining_capacity(), m_byterate - m_S_outpos);
93 for(; !output_this_round.
full() && m_S_outpos % 8 != 0; ++m_S_outpos) {
94 output_this_round.
next_byte() =
static_cast<uint8_t
>(m_S[m_S_outpos / 8] >> (8 * (m_S_outpos % 8)));
99 store_le(m_S[m_S_outpos / 8], output_this_round.
next(8).data());
103 for(; !output_this_round.
full(); ++m_S_outpos) {
104 output_this_round.
next_byte() =
static_cast<uint8_t
>(m_S[m_S_outpos / 8] >> (8 * (m_S_outpos % 8)));
108 if(m_S_outpos == m_byterate) {
117 uint8_t init_pad =
static_cast<uint8_t
>(m_custom_padding | uint64_t(1) << m_custom_padding_bit_len);
118 m_S[m_S_inpos / 8] ^=
static_cast<uint64_t
>(init_pad) << (8 * (m_S_inpos % 8));
121 m_S[(m_byterate / 8) - 1] ^=
static_cast<uint64_t
>(0x80) << 56;
126void Keccak_Permutation::permute() {
127#if defined(BOTAN_HAS_KECCAK_PERM_BMI2)
129 return permute_bmi2();
133 static const uint64_t RC[24] = {0x0000000000000001, 0x0000000000008082, 0x800000000000808A, 0x8000000080008000,
134 0x000000000000808B, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
135 0x000000000000008A, 0x0000000000000088, 0x0000000080008009, 0x000000008000000A,
136 0x000000008000808B, 0x800000000000008B, 0x8000000000008089, 0x8000000000008003,
137 0x8000000000008002, 0x8000000000000080, 0x000000000000800A, 0x800000008000000A,
138 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008};
142 for(
size_t i = 0; i != 24; i += 2) {
#define BOTAN_ARG_CHECK(expr, msg)
std::span< const uint8_t > take(const size_t count)
Helper class to ease in-place marshalling of concatenated fixed-length values.
constexpr size_t remaining_capacity() const
constexpr std::span< uint8_t > next(size_t bytes)
constexpr uint8_t & next_byte()
constexpr bool full() const
static std::optional< std::string > check(CPUID::Feature feat)
static bool has(CPUID::Feature feat)
void squeeze(std::span< uint8_t > output)
Expand output data from the current Keccak state.
Keccak_Permutation(size_t capacity_bits, uint64_t custom_padding, uint8_t custom_padding_bit_len)
Instantiate a Keccak permutation.
std::string provider() const
void absorb(std::span< const uint8_t > input)
Absorb input data into the Keccak sponge.
void finish()
Add final padding (as provided in the constructor) and permute.
void zeroise(std::vector< T, Alloc > &vec)
constexpr auto store_le(ParamTs &&... params)
void Keccak_Permutation_round(uint64_t T[25], const uint64_t A[25], uint64_t RC)
constexpr auto load_le(ParamTs &&... params)