9#include <botan/loadstor.h>
10#include <botan/cpuid.h>
11#include <botan/internal/ct_utils.h>
20inline uint16_t mul(uint16_t x, uint16_t y)
22 const uint32_t P =
static_cast<uint32_t
>(x) * y;
25 const uint32_t P_hi = P >> 16;
26 const uint32_t P_lo = P & 0xFFFF;
28 const uint16_t
carry = (P_lo < P_hi);
29 const uint16_t r_1 =
static_cast<uint16_t
>((P_lo - P_hi) +
carry);
30 const uint16_t r_2 = 1 - x - y;
32 return P_mask.select(r_2, r_1);
46uint16_t mul_inv(uint16_t x)
50 for(
size_t i = 0; i != 15; ++i)
62void 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]);
82 const uint16_t T0 = X3;
83 X3 = mul(X3 ^ X1, K[6*j+4]);
85 const uint16_t T1 = X2;
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())
124#if defined(BOTAN_HAS_IDEA_SSE2)
125 if(CPUID::has_sse2())
141#if defined(BOTAN_HAS_IDEA_SSE2)
142 if(CPUID::has_sse2())
146 sse2_idea_op_8(in, out, m_EK.data());
154 idea_op(in, out, blocks, m_EK.data());
164#if defined(BOTAN_HAS_IDEA_SSE2)
165 if(CPUID::has_sse2())
169 sse2_idea_op_8(in, out, m_DK.data());
177 idea_op(in, out, blocks, m_DK.data());
183void IDEA::key_schedule(
const uint8_t key[],
size_t)
197 for(
size_t off = 0; off != 48; off += 8)
199 for(
size_t i = 0; i != 8; ++i)
200 m_EK[off+i] =
static_cast<uint16_t
>(K[i/4] >> (48-16*(i % 4)));
202 const uint64_t Kx = (K[0] >> 39);
203 const uint64_t Ky = (K[1] >> 39);
205 K[0] = (K[0] << 25) | Ky;
206 K[1] = (K[1] << 25) | Kx;
209 for(
size_t i = 0; i != 4; ++i)
210 m_EK[48+i] =
static_cast<uint16_t
>(K[i/4] >> (48-16*(i % 4)));
212 m_DK[0] = mul_inv(m_EK[48]);
215 m_DK[3] = mul_inv(m_EK[51]);
217 for(
size_t i = 0; i != 8*6; i += 6)
219 m_DK[i+4] = m_EK[46-i];
220 m_DK[i+5] = m_EK[47-i];
221 m_DK[i+6] = mul_inv(m_EK[42-i]);
222 m_DK[i+7] = -m_EK[44-i];
223 m_DK[i+8] = -m_EK[43-i];
224 m_DK[i+9] = mul_inv(m_EK[45-i]);
227 std::swap(m_DK[49], m_DK[50]);
static Mask< T > is_zero(T x)
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
std::string provider() const override
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
size_t parallelism() const override
void verify_key_set(bool cond) const
#define BOTAN_PARALLEL_FOR
void poison(const T *p, size_t n)
void unpoison(const T *p, size_t n)
void zap(std::vector< T, Alloc > &vec)
void store_be(uint16_t in, uint8_t out[2])
T load_be(const uint8_t in[], size_t off)
void carry(int64_t &h0, int64_t &h1)
uint64_t load_be< uint64_t >(const uint8_t in[], size_t off)
std::vector< T, secure_allocator< T > > secure_vector