8#include <botan/internal/shacal2.h>
10#include <botan/internal/bit_ops.h>
11#include <botan/internal/loadstor.h>
12#include <botan/internal/rotate.h>
14#if defined(BOTAN_HAS_CPUID)
15 #include <botan/internal/cpuid.h>
22inline void SHACAL2_Fwd(
23 uint32_t A, uint32_t B, uint32_t C, uint32_t& D, uint32_t E, uint32_t F, uint32_t G, uint32_t& H, uint32_t RK) {
27 H += E_rho +
choose(E, F, G) + RK;
32inline void SHACAL2_Rev(
33 uint32_t A, uint32_t B, uint32_t C, uint32_t& D, uint32_t E, uint32_t F, uint32_t G, uint32_t& H, uint32_t RK) {
39 H -= E_rho +
choose(E, F, G) + RK;
50#if defined(BOTAN_HAS_SHACAL2_AVX512)
52 size_t consumed = avx512_encrypt_blocks(in, out, blocks);
59#if defined(BOTAN_HAS_SHACAL2_X86)
61 return x86_encrypt_blocks(in, out, blocks);
65#if defined(BOTAN_HAS_SHACAL2_ARMV8)
67 return armv8_encrypt_blocks(in, out, blocks);
71#if defined(BOTAN_HAS_SHACAL2_AVX2)
74 avx2_encrypt_8(in, out);
82#if defined(BOTAN_HAS_SHACAL2_SIMD)
85 simd_encrypt_4(in, out);
93 for(
size_t i = 0; i != blocks; ++i) {
103 for(
size_t r = 0; r != 64; r += 8) {
104 SHACAL2_Fwd(A, B, C, D, E, F, G, H, m_RK[r + 0]);
105 SHACAL2_Fwd(H, A, B, C, D, E, F, G, m_RK[r + 1]);
106 SHACAL2_Fwd(G, H, A, B, C, D, E, F, m_RK[r + 2]);
107 SHACAL2_Fwd(F, G, H, A, B, C, D, E, m_RK[r + 3]);
108 SHACAL2_Fwd(E, F, G, H, A, B, C, D, m_RK[r + 4]);
109 SHACAL2_Fwd(D, E, F, G, H, A, B, C, m_RK[r + 5]);
110 SHACAL2_Fwd(C, D, E, F, G, H, A, B, m_RK[r + 6]);
111 SHACAL2_Fwd(B, C, D, E, F, G, H, A, m_RK[r + 7]);
114 store_be(out, A, B, C, D, E, F, G, H);
127#if defined(BOTAN_HAS_SHACAL2_AVX512)
129 size_t consumed = avx512_decrypt_blocks(in, out, blocks);
136#if defined(BOTAN_HAS_SHACAL2_AVX2)
139 avx2_decrypt_8(in, out);
147#if defined(BOTAN_HAS_SHACAL2_SIMD)
150 simd_decrypt_4(in, out);
158 for(
size_t i = 0; i != blocks; ++i) {
168 for(
size_t r = 0; r != 64; r += 8) {
169 SHACAL2_Rev(B, C, D, E, F, G, H, A, m_RK[63 - r]);
170 SHACAL2_Rev(C, D, E, F, G, H, A, B, m_RK[62 - r]);
171 SHACAL2_Rev(D, E, F, G, H, A, B, C, m_RK[61 - r]);
172 SHACAL2_Rev(E, F, G, H, A, B, C, D, m_RK[60 - r]);
173 SHACAL2_Rev(F, G, H, A, B, C, D, E, m_RK[59 - r]);
174 SHACAL2_Rev(G, H, A, B, C, D, E, F, m_RK[58 - r]);
175 SHACAL2_Rev(H, A, B, C, D, E, F, G, m_RK[57 - r]);
176 SHACAL2_Rev(A, B, C, D, E, F, G, H, m_RK[56 - r]);
179 store_be(out, A, B, C, D, E, F, G, H);
187 return !m_RK.empty();
193void SHACAL2::key_schedule(std::span<const uint8_t> key) {
194 const uint32_t RC[64] = {
195 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
196 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
197 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
198 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
199 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
200 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
201 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
202 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2};
210 load_be(m_RK.data(), key.data(), key.size() / 4);
212 for(
size_t i = 16; i != 64; ++i) {
215 m_RK[i] = m_RK[i - 16] + sigma0_15 + m_RK[i - 7] + sigma1_2;
218 for(
size_t i = 0; i != 64; ++i) {
224#if defined(BOTAN_HAS_SHACAL2_AVX512)
230#if defined(BOTAN_HAS_SHACAL2_X86)
236#if defined(BOTAN_HAS_SHACAL2_ARMV8)
242#if defined(BOTAN_HAS_SHACAL2_AVX2)
248#if defined(BOTAN_HAS_SHACAL2_SIMD)
258#if defined(BOTAN_HAS_SHACAL2_AVX512)
264#if defined(BOTAN_HAS_SHACAL2_X86)
270#if defined(BOTAN_HAS_SHACAL2_ARMV8)
276#if defined(BOTAN_HAS_SHACAL2_AVX2)
282#if defined(BOTAN_HAS_SHACAL2_SIMD)
static std::optional< std::string > check(CPUID::Feature feat)
static bool has(CPUID::Feature feat)
std::string provider() const override
bool has_keying_material() 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 assert_key_material_set() const
void zap(std::vector< T, Alloc > &vec)
BOTAN_FORCE_INLINE constexpr T majority(T a, T b, T c)
BOTAN_FORCE_INLINE constexpr T rho(T x)
BOTAN_FORCE_INLINE constexpr T sigma(T x)
BOTAN_FORCE_INLINE constexpr T choose(T mask, T a, T b)
constexpr auto store_be(ParamTs &&... params)
constexpr void clear_mem(T *ptr, size_t n)
constexpr auto load_be(ParamTs &&... params)