8#include <botan/internal/shacal2.h>
10#include <botan/internal/bit_ops.h>
11#include <botan/internal/cpuid.h>
12#include <botan/internal/loadstor.h>
13#include <botan/internal/rotate.h>
19inline void SHACAL2_Fwd(
20 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) {
24 H += E_rho +
choose(E, F, G) + RK;
29inline void SHACAL2_Rev(
30 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) {
36 H -= E_rho +
choose(E, F, G) + RK;
47#if defined(BOTAN_HAS_SHACAL2_X86)
48 if(CPUID::has_intel_sha()) {
49 return x86_encrypt_blocks(in, out, blocks);
53#if defined(BOTAN_HAS_SHACAL2_ARMV8)
54 if(CPUID::has_arm_sha2()) {
55 return armv8_encrypt_blocks(in, out, blocks);
59#if defined(BOTAN_HAS_SHACAL2_AVX2)
60 if(CPUID::has_avx2()) {
62 avx2_encrypt_8(in, out);
70#if defined(BOTAN_HAS_SHACAL2_SIMD)
73 simd_encrypt_4(in, out);
81 for(
size_t i = 0; i != blocks; ++i) {
91 for(
size_t r = 0; r != 64; r += 8) {
92 SHACAL2_Fwd(A, B, C, D, E, F, G, H, m_RK[r + 0]);
93 SHACAL2_Fwd(H, A, B, C, D, E, F, G, m_RK[r + 1]);
94 SHACAL2_Fwd(G, H, A, B, C, D, E, F, m_RK[r + 2]);
95 SHACAL2_Fwd(F, G, H, A, B, C, D, E, m_RK[r + 3]);
96 SHACAL2_Fwd(E, F, G, H, A, B, C, D, m_RK[r + 4]);
97 SHACAL2_Fwd(D, E, F, G, H, A, B, C, m_RK[r + 5]);
98 SHACAL2_Fwd(C, D, E, F, G, H, A, B, m_RK[r + 6]);
99 SHACAL2_Fwd(B, C, D, E, F, G, H, A, m_RK[r + 7]);
102 store_be(out, A, B, C, D, E, F, G, H);
115#if defined(BOTAN_HAS_SHACAL2_AVX2)
116 if(CPUID::has_avx2()) {
118 avx2_decrypt_8(in, out);
126#if defined(BOTAN_HAS_SHACAL2_SIMD)
129 simd_decrypt_4(in, out);
137 for(
size_t i = 0; i != blocks; ++i) {
147 for(
size_t r = 0; r != 64; r += 8) {
148 SHACAL2_Rev(B, C, D, E, F, G, H, A, m_RK[63 - r]);
149 SHACAL2_Rev(C, D, E, F, G, H, A, B, m_RK[62 - r]);
150 SHACAL2_Rev(D, E, F, G, H, A, B, C, m_RK[61 - r]);
151 SHACAL2_Rev(E, F, G, H, A, B, C, D, m_RK[60 - r]);
152 SHACAL2_Rev(F, G, H, A, B, C, D, E, m_RK[59 - r]);
153 SHACAL2_Rev(G, H, A, B, C, D, E, F, m_RK[58 - r]);
154 SHACAL2_Rev(H, A, B, C, D, E, F, G, m_RK[57 - r]);
155 SHACAL2_Rev(A, B, C, D, E, F, G, H, m_RK[56 - r]);
158 store_be(out, A, B, C, D, E, F, G, H);
166 return !m_RK.empty();
172void SHACAL2::key_schedule(std::span<const uint8_t> key) {
173 const uint32_t RC[64] = {
174 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
175 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
176 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
177 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
178 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
179 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
180 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
181 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2};
189 load_be(m_RK.data(), key.data(), key.size() / 4);
191 for(
size_t i = 16; i != 64; ++i) {
194 m_RK[i] = m_RK[i - 16] + sigma0_15 + m_RK[i - 7] + sigma1_2;
197 for(
size_t i = 0; i != 64; ++i) {
203#if defined(BOTAN_HAS_SHACAL2_X86)
204 if(CPUID::has_intel_sha()) {
209#if defined(BOTAN_HAS_SHACAL2_ARMV8)
210 if(CPUID::has_arm_sha2()) {
215#if defined(BOTAN_HAS_SHACAL2_AVX2)
216 if(CPUID::has_avx2()) {
221#if defined(BOTAN_HAS_SHACAL2_SIMD)
231#if defined(BOTAN_HAS_SHACAL2_X86)
232 if(CPUID::has_intel_sha()) {
237#if defined(BOTAN_HAS_SHACAL2_ARMV8)
238 if(CPUID::has_arm_sha2()) {
243#if defined(BOTAN_HAS_SHACAL2_AVX2)
244 if(CPUID::has_avx2()) {
249#if defined(BOTAN_HAS_SHACAL2_SIMD)
static bool has_simd_32()
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)
constexpr T choose(T mask, T a, T b)
constexpr T majority(T a, T b, T c)
constexpr auto store_be(ParamTs &&... params)
constexpr void clear_mem(T *ptr, size_t n)
constexpr auto load_be(ParamTs &&... params)