11#include <botan/internal/twofish.h> 
   13#include <botan/internal/loadstor.h> 
   14#include <botan/internal/rotate.h> 
   21   uint32_t A, uint32_t B, uint32_t& C, uint32_t& D, uint32_t RK1, uint32_t RK2, 
const secure_vector<uint32_t>& SB) {
 
   36   uint32_t A, uint32_t B, uint32_t& C, uint32_t& D, uint32_t RK1, uint32_t RK2, 
const secure_vector<uint32_t>& SB) {
 
   67      load_le(in, A0, B0, C0, D0, A1, B1, C1, D1);
 
   78      for(
size_t k = 8; k != 40; k += 4) {
 
   79         TF_E(A0, B0, C0, D0, m_RK[k + 0], m_RK[k + 1], m_SB);
 
   80         TF_E(A1, B1, C1, D1, m_RK[k + 0], m_RK[k + 1], m_SB);
 
   82         TF_E(C0, D0, A0, B0, m_RK[k + 2], m_RK[k + 3], m_SB);
 
   83         TF_E(C1, D1, A1, B1, m_RK[k + 2], m_RK[k + 3], m_SB);
 
   95      store_le(out, C0, D0, A0, B0, C1, D1, A1, B1);
 
  114      for(
size_t k = 8; k != 40; k += 4) {
 
  115         TF_E(A, B, C, D, m_RK[k], m_RK[k + 1], m_SB);
 
  116         TF_E(C, D, A, B, m_RK[k + 2], m_RK[k + 3], m_SB);
 
 
  143      load_le(in, A0, B0, C0, D0, A1, B1, C1, D1);
 
  154      for(
size_t k = 40; k != 8; k -= 4) {
 
  155         TF_D(A0, B0, C0, D0, m_RK[k - 2], m_RK[k - 1], m_SB);
 
  156         TF_D(A1, B1, C1, D1, m_RK[k - 2], m_RK[k - 1], m_SB);
 
  158         TF_D(C0, D0, A0, B0, m_RK[k - 4], m_RK[k - 3], m_SB);
 
  159         TF_D(C1, D1, A1, B1, m_RK[k - 4], m_RK[k - 3], m_SB);
 
  171      store_le(out, C0, D0, A0, B0, C1, D1, A1, B1);
 
  190      for(
size_t k = 40; k != 8; k -= 4) {
 
  191         TF_D(A, B, C, D, m_RK[k - 2], m_RK[k - 1], m_SB);
 
  192         TF_D(C, D, A, B, m_RK[k - 4], m_RK[k - 3], m_SB);
 
 
  205   return !m_SB.empty();
 
 
  211void Twofish::key_schedule(std::span<const uint8_t> key) {
 
  217   for(
size_t i = 0; i != key.size(); ++i) {
 
  222         uint8_t X = POLY_TO_EXP[key[i] - 1];
 
  224         uint8_t RS1 = RS[(4 * i) % 32];
 
  225         uint8_t RS2 = RS[(4 * i + 1) % 32];
 
  226         uint8_t RS3 = RS[(4 * i + 2) % 32];
 
  227         uint8_t RS4 = RS[(4 * i + 3) % 32];
 
  229         S[4 * (i / 8)] ^= EXP_TO_POLY[(X + POLY_TO_EXP[RS1 - 1]) % 255];
 
  230         S[4 * (i / 8) + 1] ^= EXP_TO_POLY[(X + POLY_TO_EXP[RS2 - 1]) % 255];
 
  231         S[4 * (i / 8) + 2] ^= EXP_TO_POLY[(X + POLY_TO_EXP[RS3 - 1]) % 255];
 
  232         S[4 * (i / 8) + 3] ^= EXP_TO_POLY[(X + POLY_TO_EXP[RS4 - 1]) % 255];
 
  236   if(key.size() == 16) {
 
  237      for(
size_t i = 0; i != 256; ++i) {
 
  238         m_SB[i] = MDS0[Q0[Q0[i] ^ S[0]] ^ S[4]];
 
  239         m_SB[256 + i] = MDS1[Q0[Q1[i] ^ S[1]] ^ S[5]];
 
  240         m_SB[512 + i] = MDS2[Q1[Q0[i] ^ S[2]] ^ S[6]];
 
  241         m_SB[768 + i] = MDS3[Q1[Q1[i] ^ S[3]] ^ S[7]];
 
  244      for(
size_t i = 0; i < 40; i += 2) {
 
  245         uint32_t X = MDS0[Q0[Q0[i] ^ key[8]] ^ key[0]] ^ MDS1[Q0[Q1[i] ^ key[9]] ^ key[1]] ^
 
  246                      MDS2[Q1[Q0[i] ^ key[10]] ^ key[2]] ^ MDS3[Q1[Q1[i] ^ key[11]] ^ key[3]];
 
  247         uint32_t Y = MDS0[Q0[Q0[i + 1] ^ key[12]] ^ key[4]] ^ MDS1[Q0[Q1[i + 1] ^ key[13]] ^ key[5]] ^
 
  248                      MDS2[Q1[Q0[i + 1] ^ key[14]] ^ key[6]] ^ MDS3[Q1[Q1[i + 1] ^ key[15]] ^ key[7]];
 
  256   } 
else if(key.size() == 24) {
 
  257      for(
size_t i = 0; i != 256; ++i) {
 
  258         m_SB[i] = MDS0[Q0[Q0[Q1[i] ^ S[0]] ^ S[4]] ^ S[8]];
 
  259         m_SB[256 + i] = MDS1[Q0[Q1[Q1[i] ^ S[1]] ^ S[5]] ^ S[9]];
 
  260         m_SB[512 + i] = MDS2[Q1[Q0[Q0[i] ^ S[2]] ^ S[6]] ^ S[10]];
 
  261         m_SB[768 + i] = MDS3[Q1[Q1[Q0[i] ^ S[3]] ^ S[7]] ^ S[11]];
 
  264      for(
size_t i = 0; i < 40; i += 2) {
 
  266            MDS0[Q0[Q0[Q1[i] ^ key[16]] ^ key[8]] ^ key[0]] ^ MDS1[Q0[Q1[Q1[i] ^ key[17]] ^ key[9]] ^ key[1]] ^
 
  267            MDS2[Q1[Q0[Q0[i] ^ key[18]] ^ key[10]] ^ key[2]] ^ MDS3[Q1[Q1[Q0[i] ^ key[19]] ^ key[11]] ^ key[3]];
 
  268         uint32_t Y = MDS0[Q0[Q0[Q1[i + 1] ^ key[20]] ^ key[12]] ^ key[4]] ^
 
  269                      MDS1[Q0[Q1[Q1[i + 1] ^ key[21]] ^ key[13]] ^ key[5]] ^
 
  270                      MDS2[Q1[Q0[Q0[i + 1] ^ key[22]] ^ key[14]] ^ key[6]] ^
 
  271                      MDS3[Q1[Q1[Q0[i + 1] ^ key[23]] ^ key[15]] ^ key[7]];
 
  279   } 
else if(key.size() == 32) {
 
  280      for(
size_t i = 0; i != 256; ++i) {
 
  281         m_SB[i] = MDS0[Q0[Q0[Q1[Q1[i] ^ S[0]] ^ S[4]] ^ S[8]] ^ S[12]];
 
  282         m_SB[256 + i] = MDS1[Q0[Q1[Q1[Q0[i] ^ S[1]] ^ S[5]] ^ S[9]] ^ S[13]];
 
  283         m_SB[512 + i] = MDS2[Q1[Q0[Q0[Q0[i] ^ S[2]] ^ S[6]] ^ S[10]] ^ S[14]];
 
  284         m_SB[768 + i] = MDS3[Q1[Q1[Q0[Q1[i] ^ S[3]] ^ S[7]] ^ S[11]] ^ S[15]];
 
  287      for(
size_t i = 0; i < 40; i += 2) {
 
  288         uint32_t X = MDS0[Q0[Q0[Q1[Q1[i] ^ key[24]] ^ key[16]] ^ key[8]] ^ key[0]] ^
 
  289                      MDS1[Q0[Q1[Q1[Q0[i] ^ key[25]] ^ key[17]] ^ key[9]] ^ key[1]] ^
 
  290                      MDS2[Q1[Q0[Q0[Q0[i] ^ key[26]] ^ key[18]] ^ key[10]] ^ key[2]] ^
 
  291                      MDS3[Q1[Q1[Q0[Q1[i] ^ key[27]] ^ key[19]] ^ key[11]] ^ key[3]];
 
  292         uint32_t Y = MDS0[Q0[Q0[Q1[Q1[i + 1] ^ key[28]] ^ key[20]] ^ key[12]] ^ key[4]] ^
 
  293                      MDS1[Q0[Q1[Q1[Q0[i + 1] ^ key[29]] ^ key[21]] ^ key[13]] ^ key[5]] ^
 
  294                      MDS2[Q1[Q0[Q0[Q0[i + 1] ^ key[30]] ^ key[22]] ^ key[14]] ^ key[6]] ^
 
  295                      MDS3[Q1[Q1[Q0[Q1[i + 1] ^ key[31]] ^ key[23]] ^ key[15]] ^ key[7]];
 
void assert_key_material_set() const
 
bool has_keying_material() const 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
 
constexpr uint8_t get_byte(T input)
 
void zap(std::vector< T, Alloc > &vec)
 
BOTAN_FORCE_INLINE constexpr T rotr(T input)
 
constexpr auto store_le(ParamTs &&... params)
 
BOTAN_FORCE_INLINE constexpr T rotl(T input)
 
constexpr auto load_le(ParamTs &&... params)
 
std::vector< T, secure_allocator< T > > secure_vector