Botan 3.10.0
Crypto and TLS for C&
keccak_perm.cpp
Go to the documentation of this file.
1/*
2* Keccak Permutation
3* (C) 2010,2016 Jack Lloyd
4* (C) 2023 Falko Strenzke
5* (C) 2023,2025 René Meusel - Rohde & Schwarz Cybersecurity
6*
7* Botan is released under the Simplified BSD License (see license.txt)
8*/
9
10#include <botan/internal/keccak_perm.h>
11
12#include <botan/internal/keccak_perm_round.h>
13#include <botan/internal/loadstor.h>
14#include <botan/internal/sponge_processing.h>
15#include <botan/internal/stl_util.h>
16
17#if defined(BOTAN_HAS_CPUID)
18 #include <botan/internal/cpuid.h>
19#endif
20
21namespace Botan {
22
23std::string Keccak_Permutation::provider() const {
24#if defined(BOTAN_HAS_KECCAK_PERM_BMI2)
25 if(auto feat = CPUID::check(CPUID::Feature::BMI)) {
26 return *feat;
27 }
28#endif
29
30 return "base";
31}
32
34 state() = {};
36}
37
38void Keccak_Permutation::absorb(std::span<const uint8_t> input) {
39 absorb_into_sponge(*this, input);
40}
41
42void Keccak_Permutation::squeeze(std::span<uint8_t> output) {
43 squeeze_from_sponge(*this, output);
44}
45
47 // The padding for Keccak[c]-based functions spans the entire remaining
48 // byterate until the next permute() call. At most that could be an entire
49 // byterate. First are a few bits of "custom" padding defined by the using
50 // function (e.g. SHA-3 uses "01"), then the remaining space is filled with
51 // "pad10*1" (see NIST FIPS 202 Section 5.1) followed by a final permute().
52
53 auto& S = state();
54
55 // Apply the custom padding + the left-most 1-bit of "pad10*1" to the current
56 // (partial) word of the sponge state
57
58 const uint64_t start_of_padding = (m_padding.padding | uint64_t(1) << m_padding.bit_len);
59 S[cursor() / word_bytes] ^= start_of_padding << (8 * (cursor() % word_bytes));
60
61 // XOR'ing the 0-bits of "pad10*1" into the state is a NOOP
62
63 // If the custom padding + the left-most 1-bit of "pad10*1" had resulted in a
64 // byte-aligned "partial padding", the final 1-bit of of "pad10*1" could
65 // potentially override parts of the already-appended "start_of_padding".
66 // In case we ever introduce a Keccak-based function with such a need, we
67 // have to modify this padding algorithm.
68 BOTAN_DEBUG_ASSERT(m_padding.bit_len % 8 != 7);
69
70 // Append the final bit of "pad10*1" into the last word of the input range
71 S[(byte_rate() / word_bytes) - 1] ^= uint64_t(0x8000000000000000);
72
73 // Perform the final permutation and reset the state cursor
74 permute();
76
78}
79
81#if defined(BOTAN_HAS_KECCAK_PERM_BMI2)
83 return permute_bmi2();
84 }
85#endif
86
87 static const uint64_t RC[24] = {0x0000000000000001, 0x0000000000008082, 0x800000000000808A, 0x8000000080008000,
88 0x000000000000808B, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
89 0x000000000000008A, 0x0000000000000088, 0x0000000080008009, 0x000000008000000A,
90 0x000000008000808B, 0x800000000000008B, 0x8000000000008089, 0x8000000000008003,
91 0x8000000000008002, 0x8000000000000080, 0x000000000000800A, 0x800000008000000A,
92 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008};
93
94 uint64_t T[25];
95
96 for(size_t i = 0; i != 24; i += 2) {
97 Keccak_Permutation_round(T, state().data(), RC[i + 0]);
98 Keccak_Permutation_round(state().data(), T, RC[i + 1]);
99 }
100}
101
102} // namespace Botan
#define BOTAN_DEBUG_ASSERT(expr)
Definition assert.h:129
static std::optional< std::string > check(CPUID::Feature feat)
Definition cpuid.h:67
static bool has(CPUID::Feature feat)
Definition cpuid.h:94
void squeeze(std::span< uint8_t > output)
Expand output data from the current Keccak state.
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.
static constexpr size_t word_bytes
Definition sponge.h:29
constexpr auto & state()
Definition sponge.h:56
constexpr size_t byte_rate() const
Definition sponge.h:50
size_t cursor() const
Definition sponge.h:58
void squeeze_from_sponge(SpongeT &sponge, std::span< uint8_t > output, const detail::PermutationFn auto &permutation_fn)
BOTAN_FORCE_INLINE void Keccak_Permutation_round(uint64_t T[25], const uint64_t A[25], uint64_t RC)
void absorb_into_sponge(SpongeT &sponge, std::span< const uint8_t > input, const detail::PermutationFn auto &permutation_fn)