Botan 3.11.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/sponge_processing.h>
14
15#if defined(BOTAN_HAS_CPUID)
16 #include <botan/internal/cpuid.h>
17#endif
18
19namespace Botan {
20
21std::string Keccak_Permutation::provider() const {
22#if defined(BOTAN_HAS_KECCAK_PERM_AVX512)
23 if(auto feat = CPUID::check(CPUID::Feature::AVX512)) {
24 return *feat;
25 }
26#endif
27
28#if defined(BOTAN_HAS_KECCAK_PERM_BMI2)
29 if(auto feat = CPUID::check(CPUID::Feature::BMI)) {
30 return *feat;
31 }
32#endif
33
34 return "base";
35}
36
38 state() = {};
40}
41
42void Keccak_Permutation::absorb(std::span<const uint8_t> input) {
43 absorb_into_sponge(*this, input);
44}
45
46void Keccak_Permutation::squeeze(std::span<uint8_t> output) {
47 squeeze_from_sponge(*this, output);
48}
49
51 // The padding for Keccak[c]-based functions spans the entire remaining
52 // byterate until the next permute() call. At most that could be an entire
53 // byterate. First are a few bits of "custom" padding defined by the using
54 // function (e.g. SHA-3 uses "01"), then the remaining space is filled with
55 // "pad10*1" (see NIST FIPS 202 Section 5.1) followed by a final permute().
56
57 auto& S = state();
58
59 // Apply the custom padding + the left-most 1-bit of "pad10*1" to the current
60 // (partial) word of the sponge state
61
62 const uint64_t start_of_padding = (m_padding.padding | uint64_t(1) << m_padding.bit_len);
63 S[cursor() / word_bytes] ^= start_of_padding << (8 * (cursor() % word_bytes));
64
65 // XOR'ing the 0-bits of "pad10*1" into the state is a NOOP
66
67 // If the custom padding + the left-most 1-bit of "pad10*1" had resulted in a
68 // byte-aligned "partial padding", the final 1-bit of of "pad10*1" could
69 // potentially override parts of the already-appended "start_of_padding".
70 // In case we ever introduce a Keccak-based function with such a need, we
71 // have to modify this padding algorithm.
72 BOTAN_DEBUG_ASSERT(m_padding.bit_len % 8 != 7);
73
74 // Append the final bit of "pad10*1" into the last word of the input range
75 S[(byte_rate() / word_bytes) - 1] ^= uint64_t(0x8000000000000000);
76
77 // Perform the final permutation and reset the state cursor
78 permute();
80
82}
83
85#if defined(BOTAN_HAS_KECCAK_PERM_AVX512)
87 return permute_avx512();
88 }
89#endif
90
91#if defined(BOTAN_HAS_KECCAK_PERM_BMI2)
93 return permute_bmi2();
94 }
95#endif
96
97 static const uint64_t RC[24] = {0x0000000000000001, 0x0000000000008082, 0x800000000000808A, 0x8000000080008000,
98 0x000000000000808B, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
99 0x000000000000008A, 0x0000000000000088, 0x0000000080008009, 0x000000008000000A,
100 0x000000008000808B, 0x800000000000008B, 0x8000000000008089, 0x8000000000008003,
101 0x8000000000008002, 0x8000000000000080, 0x000000000000800A, 0x800000008000000A,
102 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008};
103
104 uint64_t T[25];
105
106 for(size_t i = 0; i != 24; i += 2) {
107 Keccak_Permutation_round(T, state().data(), RC[i + 0]);
108 Keccak_Permutation_round(state().data(), T, RC[i + 1]);
109 }
110}
111
112} // 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:30
constexpr auto & state()
Definition sponge.h:55
constexpr size_t byte_rate() const
Definition sponge.h:49
size_t cursor() const
Definition sponge.h:57
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)