#if defined(__aarch64__) || defined(_M_ARM64)
#include "semq_sha256.h"
#include <arm_neon.h>
static inline uint32_t rotr(uint32_t x, uint32_t n) {
return (x >> n) | (x << (32u - n));
}
void semqi_sha256_block_arm(uint32_t state[8], const uint8_t block[64]) {
uint32_t words[64];
for (size_t i = 0u; i < 16u; i++) {
words[i] = ((uint32_t)block[i * 4u] << 24u)
| ((uint32_t)block[i * 4u + 1u] << 16u)
| ((uint32_t)block[i * 4u + 2u] << 8u)
| (uint32_t)block[i * 4u + 3u];
}
for (uint32_t i = 16u; i < 64u; i++) {
const uint32_t s0 = rotr(words[i - 15u], 7u) ^ rotr(words[i - 15u], 18u)
^ (words[i - 15u] >> 3u);
const uint32_t s1 = rotr(words[i - 2u], 17u) ^ rotr(words[i - 2u], 19u)
^ (words[i - 2u] >> 10u);
words[i] = words[i - 16u] + s0 + words[i - 7u] + s1;
}
uint32x4_t abcd = vld1q_u32(state);
uint32x4_t efgh = vld1q_u32(state + 4);
for (uint32_t i = 0u; i < 64u; i += 4u) {
const uint32_t wk[4] = {
words[i] + semqi_sha256_k[i],
words[i + 1u] + semqi_sha256_k[i + 1u],
words[i + 2u] + semqi_sha256_k[i + 2u],
words[i + 3u] + semqi_sha256_k[i + 3u],
};
const uint32x4_t schedule = vld1q_u32(wk);
const uint32x4_t prior_abcd = abcd;
abcd = vsha256hq_u32(abcd, efgh, schedule);
efgh = vsha256h2q_u32(efgh, prior_abcd, schedule);
}
abcd = vaddq_u32(abcd, vld1q_u32(state));
efgh = vaddq_u32(efgh, vld1q_u32(state + 4));
vst1q_u32(state, abcd);
vst1q_u32(state + 4, efgh);
}
#endif