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) {
21 const uint32_t A_rho = rho<2, 13, 22>(A);
22 const uint32_t E_rho = rho<6, 11, 25>(E);
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) {
31 const uint32_t A_rho = rho<2, 13, 22>(A);
32 const uint32_t E_rho = rho<6, 11, 25>(E);
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) {
82 uint32_t A = load_be<uint32_t>(in, 0);
83 uint32_t B = load_be<uint32_t>(in, 1);
84 uint32_t C = load_be<uint32_t>(in, 2);
85 uint32_t D = load_be<uint32_t>(in, 3);
86 uint32_t E = load_be<uint32_t>(in, 4);
87 uint32_t F = load_be<uint32_t>(in, 5);
88 uint32_t G = load_be<uint32_t>(in, 6);
89 uint32_t H = load_be<uint32_t>(in, 7);
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) {
138 uint32_t A = load_be<uint32_t>(in, 0);
139 uint32_t B = load_be<uint32_t>(in, 1);
140 uint32_t C = load_be<uint32_t>(in, 2);
141 uint32_t D = load_be<uint32_t>(in, 3);
142 uint32_t E = load_be<uint32_t>(in, 4);
143 uint32_t F = load_be<uint32_t>(in, 5);
144 uint32_t G = load_be<uint32_t>(in, 6);
145 uint32_t H = load_be<uint32_t>(in, 7);
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) {
192 const uint32_t sigma0_15 = sigma<7, 18, 3>(m_RK[i - 15]);
193 const uint32_t sigma1_2 = sigma<17, 19, 10>(m_RK[i - 2]);
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
constexpr void store_be(T in, OutR &&out_range)
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 T load_be(InR &&in_range)
constexpr void clear_mem(T *ptr, size_t n)