8 #include <botan/idea.h>
9 #include <botan/loadstor.h>
10 #include <botan/cpuid.h>
11 #include <botan/internal/ct_utils.h>
20 inline uint16_t mul(uint16_t x, uint16_t y)
22 const uint32_t P =
static_cast<uint32_t
>(x) * y;
24 const uint16_t Z_mask =
static_cast<uint16_t
>(
CT::expand_mask(P) & 0xFFFF);
26 const uint32_t P_hi = P >> 16;
27 const uint32_t P_lo = P & 0xFFFF;
29 const uint16_t r_1 = (P_lo - P_hi) + (P_lo < P_hi);
30 const uint16_t r_2 = 1 - x - y;
46 uint16_t mul_inv(uint16_t x)
50 for(
size_t i = 0; i != 15; ++i)
62 void idea_op(
const uint8_t in[], uint8_t out[],
size_t blocks,
const uint16_t K[52])
64 const size_t BLOCK_SIZE = 8;
72 uint16_t X1, X2, X3, X4;
73 load_be(in + BLOCK_SIZE*i, X1, X2, X3, X4);
75 for(
size_t j = 0; j != 8; ++j)
77 X1 = mul(X1, K[6*j+0]);
80 X4 = mul(X4, K[6*j+3]);
83 X3 = mul(X3 ^ X1, K[6*j+4]);
86 X2 = mul((X2 ^ X4) + X3, K[6*j+5]);
100 store_be(out + BLOCK_SIZE*i, X1, X3, X2, X4);
112 #if defined(BOTAN_HAS_IDEA_SSE2)
113 if(CPUID::has_sse2())
127 #if defined(BOTAN_HAS_IDEA_SSE2)
128 if(CPUID::has_sse2())
132 sse2_idea_op_8(in, out, m_EK.data());
140 idea_op(in, out, blocks, m_EK.data());
148 #if defined(BOTAN_HAS_IDEA_SSE2)
149 if(CPUID::has_sse2())
153 sse2_idea_op_8(in, out, m_DK.data());
161 idea_op(in, out, blocks, m_DK.data());
167 void IDEA::key_schedule(
const uint8_t key[],
size_t)
176 for(
size_t i = 0; i != 8; ++i)
179 for(
size_t i = 1, j = 8, offset = 0; j != 52; i %= 8, ++i, ++j)
181 m_EK[i+7+offset] =
static_cast<uint16_t
>((m_EK[(i % 8) + offset] << 9) |
182 (m_EK[((i+1) % 8) + offset] >> 7));
183 offset += (i == 8) ? 8 : 0;
186 m_DK[51] = mul_inv(m_EK[3]);
189 m_DK[48] = mul_inv(m_EK[0]);
191 for(
size_t i = 1, j = 4, counter = 47; i != 8; ++i, j += 6)
193 m_DK[counter--] = m_EK[j+1];
194 m_DK[counter--] = m_EK[j];
195 m_DK[counter--] = mul_inv(m_EK[j+5]);
196 m_DK[counter--] = -m_EK[j+3];
197 m_DK[counter--] = -m_EK[j+4];
198 m_DK[counter--] = mul_inv(m_EK[j+2]);
203 m_DK[3] = mul_inv(m_EK[51]);
206 m_DK[0] = mul_inv(m_EK[48]);
void zap(std::vector< T, Alloc > &vec)
void store_be(uint16_t in, uint8_t out[2])
uint16_t load_be< uint16_t >(const uint8_t in[], size_t off)
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
std::string provider() const override
void poison(const T *p, size_t n)
#define BOTAN_PARALLEL_FOR
T load_be(const uint8_t in[], size_t off)
T select(T mask, T from0, T from1)
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
void unpoison(const T *p, size_t n)