8#include <botan/shacal2.h>
9#include <botan/loadstor.h>
10#include <botan/rotate.h>
11#include <botan/cpuid.h>
17inline void SHACAL2_Fwd(uint32_t A, uint32_t B, uint32_t C, uint32_t& D,
18 uint32_t E, uint32_t F, uint32_t G, uint32_t& H,
21 const uint32_t A_rho = rotr<2>(A) ^ rotr<13>(A) ^ rotr<22>(A);
22 const uint32_t E_rho = rotr<6>(E) ^ rotr<11>(E) ^ rotr<25>(E);
24 H += E_rho + ((E & F) ^ (~E & G)) + RK;
26 H += A_rho + ((A & B) | ((A | B) & C));
29inline void SHACAL2_Rev(uint32_t A, uint32_t B, uint32_t C, uint32_t& D,
30 uint32_t E, uint32_t F, uint32_t G, uint32_t& H,
33 const uint32_t A_rho = rotr<2>(A) ^ rotr<13>(A) ^ rotr<22>(A);
34 const uint32_t E_rho = rotr<6>(E) ^ rotr<11>(E) ^ rotr<25>(E);
36 H -= A_rho + ((A & B) | ((A | B) & C));
38 H -= E_rho + ((E & F) ^ (~E & G)) + RK;
50#if defined(BOTAN_HAS_SHACAL2_X86)
51 if(CPUID::has_intel_sha())
53 return x86_encrypt_blocks(in, out, blocks);
57#if defined(BOTAN_HAS_SHACAL2_AVX2)
62 avx2_encrypt_8(in, out);
70#if defined(BOTAN_HAS_SHACAL2_SIMD)
75 simd_encrypt_4(in, out);
83 for(
size_t i = 0; i != blocks; ++i)
94 for(
size_t r = 0; r != 64; r += 8)
96 SHACAL2_Fwd(A, B, C, D, E, F, G, H, m_RK[r+0]);
97 SHACAL2_Fwd(H, A, B, C, D, E, F, G, m_RK[r+1]);
98 SHACAL2_Fwd(G, H, A, B, C, D, E, F, m_RK[r+2]);
99 SHACAL2_Fwd(F, G, H, A, B, C, D, E, m_RK[r+3]);
100 SHACAL2_Fwd(E, F, G, H, A, B, C, D, m_RK[r+4]);
101 SHACAL2_Fwd(D, E, F, G, H, A, B, C, m_RK[r+5]);
102 SHACAL2_Fwd(C, D, E, F, G, H, A, B, m_RK[r+6]);
103 SHACAL2_Fwd(B, C, D, E, F, G, H, A, m_RK[r+7]);
106 store_be(out, A, B, C, D, E, F, G, H);
120#if defined(BOTAN_HAS_SHACAL2_AVX2)
121 if(CPUID::has_avx2())
125 avx2_decrypt_8(in, out);
133#if defined(BOTAN_HAS_SHACAL2_SIMD)
138 simd_decrypt_4(in, out);
146 for(
size_t i = 0; i != blocks; ++i)
157 for(
size_t r = 0; r != 64; r += 8)
159 SHACAL2_Rev(B, C, D, E, F, G, H, A, m_RK[63-r]);
160 SHACAL2_Rev(C, D, E, F, G, H, A, B, m_RK[62-r]);
161 SHACAL2_Rev(D, E, F, G, H, A, B, C, m_RK[61-r]);
162 SHACAL2_Rev(E, F, G, H, A, B, C, D, m_RK[60-r]);
163 SHACAL2_Rev(F, G, H, A, B, C, D, E, m_RK[59-r]);
164 SHACAL2_Rev(G, H, A, B, C, D, E, F, m_RK[58-r]);
165 SHACAL2_Rev(H, A, B, C, D, E, F, G, m_RK[57-r]);
166 SHACAL2_Rev(A, B, C, D, E, F, G, H, m_RK[56-r]);
169 store_be(out, A, B, C, D, E, F, G, H);
179void SHACAL2::key_schedule(
const uint8_t key[],
size_t len)
181 const uint32_t RC[64] = {
182 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
183 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
184 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
185 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
186 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
187 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
188 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
189 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
190 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
191 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
192 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
193 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
194 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
195 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
196 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
197 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
205 load_be(m_RK.data(), key, len/4);
207 for(
size_t i = 16; i != 64; ++i)
209 const uint32_t sigma0_15 = rotr< 7>(m_RK[i-15]) ^ rotr<18>(m_RK[i-15]) ^ (m_RK[i-15] >> 3);
210 const uint32_t sigma1_2 = rotr<17>(m_RK[i- 2]) ^ rotr<19>(m_RK[i- 2]) ^ (m_RK[i- 2] >> 10);
211 m_RK[i] = m_RK[i-16] + sigma0_15 + m_RK[i-7] + sigma1_2;
214 for(
size_t i = 0; i != 64; ++i)
222#if defined(BOTAN_HAS_SHACAL2_X86)
223 if(CPUID::has_intel_sha())
229#if defined(BOTAN_HAS_SHACAL2_AVX2)
230 if(CPUID::has_avx2())
236#if defined(BOTAN_HAS_SHACAL2_SIMD)
248#if defined(BOTAN_HAS_SHACAL2_X86)
249 if(CPUID::has_intel_sha())
255#if defined(BOTAN_HAS_SHACAL2_AVX2)
256 if(CPUID::has_avx2())
262#if defined(BOTAN_HAS_SHACAL2_SIMD)
static bool has_simd_32()
std::string provider() const override
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
size_t parallelism() const override
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
void verify_key_set(bool cond) const
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)
uint32_t load_be< uint32_t >(const uint8_t in[], size_t off)
void clear_mem(T *ptr, size_t n)