8#include <botan/internal/threefish_512.h>
10#include <botan/internal/cpuid.h>
11#include <botan/internal/loadstor.h>
12#include <botan/internal/rotate.h>
16namespace Threefish_F {
18template <
size_t R1,
size_t R2,
size_t R3,
size_t R4>
20 uint64_t& X0, uint64_t& X1, uint64_t& X2, uint64_t& X3, uint64_t& X4, uint64_t& X5, uint64_t& X6, uint64_t& X7) {
35template <
size_t R1,
size_t R2,
size_t R3,
size_t R4>
37 uint64_t& X0, uint64_t& X1, uint64_t& X2, uint64_t& X3, uint64_t& X4, uint64_t& X5, uint64_t& X6, uint64_t& X7) {
54 Key_Inserter(
const uint64_t* K,
const uint64_t*
T) : m_K(K), m_T(
T) {}
66 X1 += m_K[(R + 1) % 9];
67 X2 += m_K[(R + 2) % 9];
68 X3 += m_K[(R + 3) % 9];
69 X4 += m_K[(R + 4) % 9];
70 X5 += m_K[(R + 5) % 9] + m_T[(R) % 3];
71 X6 += m_K[(R + 6) % 9] + m_T[(R + 1) % 3];
72 X7 += m_K[(R + 7) % 9] + R;
85 X1 -= m_K[(R + 1) % 9];
86 X2 -= m_K[(R + 2) % 9];
87 X3 -= m_K[(R + 3) % 9];
88 X4 -= m_K[(R + 4) % 9];
89 X5 -= m_K[(R + 5) % 9] + m_T[(R) % 3];
90 X6 -= m_K[(R + 6) % 9] + m_T[(R + 1) % 3];
91 X7 -= m_K[(R + 7) % 9] + R;
99template <
size_t R1,
size_t R2>
108 const Key_Inserter& key) {
109 e_round<46, 36, 19, 37>(X0, X2, X4, X6, X1, X3, X5, X7);
110 e_round<33, 27, 14, 42>(X2, X4, X6, X0, X1, X7, X5, X3);
111 e_round<17, 49, 36, 39>(X4, X6, X0, X2, X1, X3, X5, X7);
112 e_round<44, 9, 54, 56>(X6, X0, X2, X4, X1, X7, X5, X3);
113 key.e_add(R1, X0, X1, X2, X3, X4, X5, X6, X7);
115 e_round<39, 30, 34, 24>(X0, X2, X4, X6, X1, X3, X5, X7);
116 e_round<13, 50, 10, 17>(X2, X4, X6, X0, X1, X7, X5, X3);
117 e_round<25, 29, 39, 43>(X4, X6, X0, X2, X1, X3, X5, X7);
118 e_round<8, 35, 56, 22>(X6, X0, X2, X4, X1, X7, X5, X3);
119 key.e_add(R2, X0, X1, X2, X3, X4, X5, X6, X7);
122template <
size_t R1,
size_t R2>
131 const Key_Inserter& key) {
132 d_round<8, 35, 56, 22>(X6, X0, X2, X4, X1, X7, X5, X3);
133 d_round<25, 29, 39, 43>(X4, X6, X0, X2, X1, X3, X5, X7);
134 d_round<13, 50, 10, 17>(X2, X4, X6, X0, X1, X7, X5, X3);
135 d_round<39, 30, 34, 24>(X0, X2, X4, X6, X1, X3, X5, X7);
136 key.d_add(R1, X0, X1, X2, X3, X4, X5, X6, X7);
138 d_round<44, 9, 54, 56>(X6, X0, X2, X4, X1, X7, X5, X3);
139 d_round<17, 49, 36, 39>(X4, X6, X0, X2, X1, X3, X5, X7);
140 d_round<33, 27, 14, 42>(X2, X4, X6, X0, X1, X7, X5, X3);
141 d_round<46, 36, 19, 37>(X0, X2, X4, X6, X1, X3, X5, X7);
142 key.d_add(R2, X0, X1, X2, X3, X4, X5, X6, X7);
148 using namespace Threefish_F;
155 m_T[2] =
T[0] ^
T[1];
157 const Key_Inserter key(m_K.data(), m_T.data());
168 key.e_add(0, X0, X1, X2, X3, X4, X5, X6, X7);
170 e8_rounds<1, 2>(X0, X1, X2, X3, X4, X5, X6, X7, key);
171 e8_rounds<3, 4>(X0, X1, X2, X3, X4, X5, X6, X7, key);
172 e8_rounds<5, 6>(X0, X1, X2, X3, X4, X5, X6, X7, key);
173 e8_rounds<7, 8>(X0, X1, X2, X3, X4, X5, X6, X7, key);
174 e8_rounds<9, 10>(X0, X1, X2, X3, X4, X5, X6, X7, key);
175 e8_rounds<11, 12>(X0, X1, X2, X3, X4, X5, X6, X7, key);
176 e8_rounds<13, 14>(X0, X1, X2, X3, X4, X5, X6, X7, key);
177 e8_rounds<15, 16>(X0, X1, X2, X3, X4, X5, X6, X7, key);
178 e8_rounds<17, 18>(X0, X1, X2, X3, X4, X5, X6, X7, key);
189 m_K[8] = m_K[0] ^ m_K[1] ^ m_K[2] ^ m_K[3] ^ m_K[4] ^ m_K[5] ^ m_K[6] ^ m_K[7] ^ 0x1BD11BDAA9FC1A22;
193 using namespace Threefish_F;
197 const Key_Inserter key(m_K.data(), m_T.data());
199 for(
size_t i = 0; i < blocks; ++i) {
200 uint64_t X0, X1, X2, X3, X4, X5, X6, X7;
203 key.e_add(0, X0, X1, X2, X3, X4, X5, X6, X7);
205 e8_rounds<1, 2>(X0, X1, X2, X3, X4, X5, X6, X7, key);
206 e8_rounds<3, 4>(X0, X1, X2, X3, X4, X5, X6, X7, key);
207 e8_rounds<5, 6>(X0, X1, X2, X3, X4, X5, X6, X7, key);
208 e8_rounds<7, 8>(X0, X1, X2, X3, X4, X5, X6, X7, key);
209 e8_rounds<9, 10>(X0, X1, X2, X3, X4, X5, X6, X7, key);
210 e8_rounds<11, 12>(X0, X1, X2, X3, X4, X5, X6, X7, key);
211 e8_rounds<13, 14>(X0, X1, X2, X3, X4, X5, X6, X7, key);
212 e8_rounds<15, 16>(X0, X1, X2, X3, X4, X5, X6, X7, key);
213 e8_rounds<17, 18>(X0, X1, X2, X3, X4, X5, X6, X7, key);
220 using namespace Threefish_F;
224 const Key_Inserter key(m_K.data(), m_T.data());
226 for(
size_t i = 0; i < blocks; ++i) {
227 uint64_t X0, X1, X2, X3, X4, X5, X6, X7;
230 key.d_add(18, X0, X1, X2, X3, X4, X5, X6, X7);
232 d8_rounds<17, 16>(X0, X1, X2, X3, X4, X5, X6, X7, key);
233 d8_rounds<15, 14>(X0, X1, X2, X3, X4, X5, X6, X7, key);
234 d8_rounds<13, 12>(X0, X1, X2, X3, X4, X5, X6, X7, key);
235 d8_rounds<11, 10>(X0, X1, X2, X3, X4, X5, X6, X7, key);
236 d8_rounds<9, 8>(X0, X1, X2, X3, X4, X5, X6, X7, key);
237 d8_rounds<7, 6>(X0, X1, X2, X3, X4, X5, X6, X7, key);
238 d8_rounds<5, 4>(X0, X1, X2, X3, X4, X5, X6, X7, key);
239 d8_rounds<3, 2>(X0, X1, X2, X3, X4, X5, X6, X7, key);
240 d8_rounds<1, 0>(X0, X1, X2, X3, X4, X5, X6, X7, key);
252 m_T[2] = m_T[0] ^ m_T[1];
259void Threefish_512::key_schedule(std::span<const uint8_t> key) {
263 for(
size_t i = 0; i != 8; ++i) {
267 m_K[8] = m_K[0] ^ m_K[1] ^ m_K[2] ^ m_K[3] ^ m_K[4] ^ m_K[5] ^ m_K[6] ^ m_K[7] ^ 0x1BD11BDAA9FC1A22;
#define BOTAN_ARG_CHECK(expr, msg)
#define BOTAN_ASSERT(expr, assertion_made)
void assert_key_material_set() const
bool has_keying_material() const override
void set_tweak(const uint8_t tweak[], size_t len) override
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
#define BOTAN_FORCE_INLINE
BOTAN_FORCE_INLINE void d_round(uint64_t &X0, uint64_t &X1, uint64_t &X2, uint64_t &X3, uint64_t &X4, uint64_t &X5, uint64_t &X6, uint64_t &X7)
BOTAN_FORCE_INLINE void d8_rounds(uint64_t &X0, uint64_t &X1, uint64_t &X2, uint64_t &X3, uint64_t &X4, uint64_t &X5, uint64_t &X6, uint64_t &X7, const Key_Inserter &key)
BOTAN_FORCE_INLINE void e8_rounds(uint64_t &X0, uint64_t &X1, uint64_t &X2, uint64_t &X3, uint64_t &X4, uint64_t &X5, uint64_t &X6, uint64_t &X7, const Key_Inserter &key)
BOTAN_FORCE_INLINE void e_round(uint64_t &X0, uint64_t &X1, uint64_t &X2, uint64_t &X3, uint64_t &X4, uint64_t &X5, uint64_t &X6, uint64_t &X7)
void zeroise(std::vector< T, Alloc > &vec)
void zap(std::vector< T, Alloc > &vec)
constexpr T rotl(T input)
constexpr T rotr(T input)
constexpr auto store_le(ParamTs &&... params)
constexpr auto load_le(ParamTs &&... params)
std::vector< T, secure_allocator< T > > secure_vector