10#include <botan/internal/keccak_perm.h>
12#include <botan/exceptn.h>
13#include <botan/internal/cpuid.h>
14#include <botan/internal/fmt.h>
15#include <botan/internal/keccak_perm_round.h>
16#include <botan/internal/loadstor.h>
17#include <botan/internal/stl_util.h>
23 m_byterate((1600 - capacity) / 8),
24 m_custom_padding(custom_padding),
25 m_custom_padding_bit_len(custom_padding_bit_len),
33#if defined(BOTAN_HAS_KECCAK_PERM_BMI2)
34 if(CPUID::has_bmi2()) {
53 while(!input_slicer.
empty()) {
54 const size_t to_take_this_round = std::min(input_slicer.
remaining(), m_byterate - m_S_inpos);
58 for(; !input_this_round.
empty() && m_S_inpos % 8; ++m_S_inpos) {
59 m_S[m_S_inpos / 8] ^=
static_cast<uint64_t
>(input_this_round.
take_byte()) << (8 * (m_S_inpos % 8));
63 for(; input_this_round.
remaining() >= 8; m_S_inpos += 8) {
68 for(; !input_this_round.
empty(); ++m_S_inpos) {
69 m_S[m_S_inpos / 8] ^=
static_cast<uint64_t
>(input_this_round.
take_byte()) << (8 * (m_S_inpos % 8));
73 if(m_S_inpos == m_byterate) {
85 while(!output_stuffer.
full()) {
86 const size_t bytes_in_this_round = std::min(output_stuffer.
remaining_capacity(), m_byterate - m_S_outpos);
90 for(; !output_this_round.
full() && m_S_outpos % 8 != 0; ++m_S_outpos) {
91 output_this_round.
next_byte() =
static_cast<uint8_t
>(m_S[m_S_outpos / 8] >> (8 * (m_S_outpos % 8)));
96 store_le(m_S[m_S_outpos / 8], output_this_round.
next(8).data());
100 for(; !output_this_round.
full(); ++m_S_outpos) {
101 output_this_round.
next_byte() =
static_cast<uint8_t
>(m_S[m_S_outpos / 8] >> (8 * (m_S_outpos % 8)));
105 if(m_S_outpos == m_byterate) {
114 uint8_t init_pad =
static_cast<uint8_t
>(m_custom_padding | uint64_t(1) << m_custom_padding_bit_len);
115 m_S[m_S_inpos / 8] ^=
static_cast<uint64_t
>(init_pad) << (8 * (m_S_inpos % 8));
118 m_S[(m_byterate / 8) - 1] ^=
static_cast<uint64_t
>(0x80) << 56;
123void Keccak_Permutation::permute() {
124#if defined(BOTAN_HAS_KECCAK_PERM_BMI2)
125 if(CPUID::has_bmi2()) {
126 return permute_bmi2();
130 static const uint64_t RC[24] = {0x0000000000000001, 0x0000000000008082, 0x800000000000808A, 0x8000000080008000,
131 0x000000000000808B, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
132 0x000000000000008A, 0x0000000000000088, 0x0000000080008009, 0x000000008000000A,
133 0x000000008000808B, 0x800000000000008B, 0x8000000000008089, 0x8000000000008003,
134 0x8000000000008002, 0x8000000000000080, 0x000000000000800A, 0x800000008000000A,
135 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008};
139 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
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)