8 #include <botan/threefish.h>
9 #include <botan/loadstor.h>
10 #include <botan/cpuid.h>
14 #define THREEFISH_ROUND(X0,X1,X2,X3,X4,X5,X6,X7,ROT1,ROT2,ROT3,ROT4) \
20 X4 = rotate_left(X4, ROT1); \
21 X5 = rotate_left(X5, ROT2); \
22 X6 = rotate_left(X6, ROT3); \
23 X7 = rotate_left(X7, ROT4); \
30 #define THREEFISH_INJECT_KEY(r) \
32 X0 += m_K[(r ) % 9]; \
33 X1 += m_K[(r+1) % 9]; \
34 X2 += m_K[(r+2) % 9]; \
35 X3 += m_K[(r+3) % 9]; \
36 X4 += m_K[(r+4) % 9]; \
37 X5 += m_K[(r+5) % 9] + m_T[(r ) % 3]; \
38 X6 += m_K[(r+6) % 9] + m_T[(r+1) % 3]; \
39 X7 += m_K[(r+7) % 9] + (r); \
42 #define THREEFISH_ENC_8_ROUNDS(R1,R2) \
44 THREEFISH_ROUND(X0,X2,X4,X6, X1,X3,X5,X7, 46,36,19,37); \
45 THREEFISH_ROUND(X2,X4,X6,X0, X1,X7,X5,X3, 33,27,14,42); \
46 THREEFISH_ROUND(X4,X6,X0,X2, X1,X3,X5,X7, 17,49,36,39); \
47 THREEFISH_ROUND(X6,X0,X2,X4, X1,X7,X5,X3, 44, 9,54,56); \
48 THREEFISH_INJECT_KEY(R1); \
50 THREEFISH_ROUND(X0,X2,X4,X6, X1,X3,X5,X7, 39,30,34,24); \
51 THREEFISH_ROUND(X2,X4,X6,X0, X1,X7,X5,X3, 13,50,10,17); \
52 THREEFISH_ROUND(X4,X6,X0,X2, X1,X3,X5,X7, 25,29,39,43); \
53 THREEFISH_ROUND(X6,X0,X2,X4, X1,X7,X5,X3, 8,35,56,22); \
54 THREEFISH_INJECT_KEY(R2); \
57 void Threefish_512::skein_feedfwd(
const secure_vector<uint64_t>& M,
58 const secure_vector<uint64_t>& T)
97 m_K[8] = m_K[0] ^ m_K[1] ^ m_K[2] ^ m_K[3] ^
98 m_K[4] ^ m_K[5] ^ m_K[6] ^ m_K[7] ^ 0x1BD11BDAA9FC1A22;
103 #if defined(BOTAN_HAS_THREEFISH_512_AVX2)
104 if(CPUID::has_avx2())
118 #if defined(BOTAN_HAS_THREEFISH_512_AVX2)
119 if(CPUID::has_avx2())
121 return avx2_encrypt_n(in, out, blocks);
127 uint64_t X0, X1, X2, X3, X4, X5, X6, X7;
146 #undef THREEFISH_ENC_8_ROUNDS
147 #undef THREEFISH_INJECT_KEY
148 #undef THREEFISH_ROUND
155 #if defined(BOTAN_HAS_THREEFISH_512_AVX2)
156 if(CPUID::has_avx2())
158 return avx2_decrypt_n(in, out, blocks);
162 #define THREEFISH_ROUND(X0,X1,X2,X3,X4,X5,X6,X7,ROT1,ROT2,ROT3,ROT4) \
168 X4 = rotate_right(X4, ROT1); \
169 X5 = rotate_right(X5, ROT2); \
170 X6 = rotate_right(X6, ROT3); \
171 X7 = rotate_right(X7, ROT4); \
178 #define THREEFISH_INJECT_KEY(r) \
180 X0 -= m_K[(r ) % 9]; \
181 X1 -= m_K[(r+1) % 9]; \
182 X2 -= m_K[(r+2) % 9]; \
183 X3 -= m_K[(r+3) % 9]; \
184 X4 -= m_K[(r+4) % 9]; \
185 X5 -= m_K[(r+5) % 9] + m_T[(r ) % 3]; \
186 X6 -= m_K[(r+6) % 9] + m_T[(r+1) % 3]; \
187 X7 -= m_K[(r+7) % 9] + (r); \
190 #define THREEFISH_DEC_8_ROUNDS(R1,R2) \
192 THREEFISH_ROUND(X6,X0,X2,X4, X1,X7,X5,X3, 8,35,56,22); \
193 THREEFISH_ROUND(X4,X6,X0,X2, X1,X3,X5,X7, 25,29,39,43); \
194 THREEFISH_ROUND(X2,X4,X6,X0, X1,X7,X5,X3, 13,50,10,17); \
195 THREEFISH_ROUND(X0,X2,X4,X6, X1,X3,X5,X7, 39,30,34,24); \
196 THREEFISH_INJECT_KEY(R1); \
198 THREEFISH_ROUND(X6,X0,X2,X4, X1,X7,X5,X3, 44, 9,54,56); \
199 THREEFISH_ROUND(X4,X6,X0,X2, X1,X3,X5,X7, 17,49,36,39); \
200 THREEFISH_ROUND(X2,X4,X6,X0, X1,X7,X5,X3, 33,27,14,42); \
201 THREEFISH_ROUND(X0,X2,X4,X6, X1,X3,X5,X7, 46,36,19,37); \
202 THREEFISH_INJECT_KEY(R2); \
207 uint64_t X0, X1, X2, X3, X4, X5, X6, X7;
225 #undef THREEFISH_DEC_8_ROUNDS
226 #undef THREEFISH_INJECT_KEY
227 #undef THREEFISH_ROUND
233 throw Exception(
"Threefish-512 requires 128 bit tweak");
237 m_T[2] = m_T[0] ^ m_T[1];
240 void Threefish_512::key_schedule(
const uint8_t key[],
size_t)
245 for(
size_t i = 0; i != 8; ++i)
248 m_K[8] = m_K[0] ^ m_K[1] ^ m_K[2] ^ m_K[3] ^
249 m_K[4] ^ m_K[5] ^ m_K[6] ^ m_K[7] ^ 0x1BD11BDAA9FC1A22;
std::string provider() const override
void zap(std::vector< T, Alloc > &vec)
#define THREEFISH_INJECT_KEY(r)
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
#define BOTAN_PARALLEL_FOR
#define BOTAN_ASSERT(expr, assertion_made)
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
uint64_t load_le< uint64_t >(const uint8_t in[], size_t off)
T load_le(const uint8_t in[], size_t off)
#define THREEFISH_DEC_8_ROUNDS(R1, R2)
void set_tweak(const uint8_t tweak[], size_t len)
#define THREEFISH_ENC_8_ROUNDS(R1, R2)
void store_le(uint16_t in, uint8_t out[2])
void zeroise(std::vector< T, Alloc > &vec)