Line data Source code
1 : // Copyright (c) 2025 The Dash Core developers 2 : // Distributed under the MIT software license, see the accompanying 3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 : 5 : #if defined(HAVE_CONFIG_H) 6 : #include <config/bitcoin-config.h> 7 : #endif 8 : 9 : #include <crypto/x11/dispatch.h> 10 : 11 : #if !defined(DISABLE_OPTIMIZED_SHA256) 12 : #include <compat/cpuid.h> 13 : 14 : #if defined(ENABLE_ARM_AES) || defined(ENABLE_ARM_NEON) 15 : #if defined(__APPLE__) 16 : #include <sys/sysctl.h> 17 : #include <sys/types.h> 18 : #endif // __APPLE__ 19 : 20 : #if defined(__linux__) 21 : #include <asm/hwcap.h> 22 : #include <sys/auxv.h> 23 : #endif // __linux__ 24 : 25 : #if defined(__FreeBSD__) 26 : #include <machine/elf.h> 27 : #include <sys/auxv.h> 28 : #endif // __FreeBSD__ 29 : 30 : #if defined(_WIN32) 31 : #include <processthreadsapi.h> 32 : #include <winnt.h> 33 : #endif // _WIN32 34 : #endif // ENABLE_ARM_AES || ENABLE_ARM_NEON 35 : #endif // !DISABLE_OPTIMIZED_SHA256 36 : 37 : #include <cstddef> 38 : 39 : namespace sapphire { 40 : #if !defined(DISABLE_OPTIMIZED_SHA256) 41 : #if defined(ENABLE_ARM_AES) 42 : namespace arm_crypto_echo { 43 : void FullStateRound(uint64_t W[16][2], uint32_t& k0, uint32_t& k1, uint32_t& k2, uint32_t& k3); 44 : } // namespace arm_crypto_echo 45 : namespace arm_crypto_shavite { 46 : void Compress(sph_shavite_big_context *sc, const void *msg); 47 : } // namespace arm_crypto_shavite 48 : #endif // ENABLE_ARM_AES 49 : 50 : #if defined(ENABLE_ARM_NEON) 51 : namespace arm_neon_echo { 52 : void ShiftAndMix(uint64_t W[16][2]); 53 : } // namespace arm_neon_echo 54 : #endif // ENABLE_ARM_NEON 55 : 56 : #if defined(ENABLE_SSSE3) 57 : namespace ssse3_echo { 58 : void ShiftAndMix(uint64_t W[16][2]); 59 : } // namespace ssse3_echo 60 : #endif // ENABLE_SSSE3 61 : 62 : #if defined(ENABLE_SSE41) && defined(ENABLE_X86_AESNI) 63 : namespace x86_aesni_echo { 64 : void FullStateRound(uint64_t W[16][2], uint32_t& k0, uint32_t& k1, uint32_t& k2, uint32_t& k3); 65 : } // namespace x86_aesni_echo 66 : namespace x86_aesni_shavite { 67 : void Compress(sph_shavite_big_context *sc, const void *msg); 68 : } // namespace x86_aesni_shavite 69 : #endif // ENABLE_SSE41 && ENABLE_X86_AESNI 70 : #endif // !DISABLE_OPTIMIZED_SHA256 71 : 72 : namespace soft_echo { 73 : void FullStateRound(uint64_t W[16][2], uint32_t& k0, uint32_t& k1, uint32_t& k2, uint32_t& k3); 74 : void ShiftAndMix(uint64_t W[16][2]); 75 : } // namespace soft_echo 76 : namespace soft_shavite { 77 : void Compress(sph_shavite_big_context *sc, const void *msg); 78 : } // namespace soft_shavite 79 : } // namespace sapphire 80 : 81 : namespace { 82 : #if !defined(DISABLE_OPTIMIZED_SHA256) 83 : #if defined(ENABLE_ARM_AES) || defined(ENABLE_ARM_NEON) 84 : #if defined(__APPLE__) 85 7318 : bool IsSysCtlNonZero(const char* name) 86 : { 87 7318 : int val = 0; 88 7318 : size_t len = sizeof(val); 89 7318 : return ::sysctlbyname(name, &val, &len, nullptr, 0) == 0 && val != 0; 90 7318 : } 91 : #endif // __APPLE__ 92 : #endif // ENABLE_ARM_AES || ENABLE_ARM_NEON 93 : #endif // !DISABLE_OPTIMIZED_SHA256 94 : } // anonymous namespace 95 : 96 : extern sapphire::dispatch::EchoShiftMix echo_shift_mix; 97 : extern sapphire::dispatch::EchoRoundFn echo_round; 98 : extern sapphire::dispatch::ShaviteCompressFn shavite_c512; 99 : 100 3659 : void SapphireAutoDetect() 101 : { 102 3659 : echo_round = sapphire::soft_echo::FullStateRound; 103 3659 : echo_shift_mix = sapphire::soft_echo::ShiftAndMix; 104 3659 : shavite_c512 = sapphire::soft_shavite::Compress; 105 : 106 : #if !defined(DISABLE_OPTIMIZED_SHA256) 107 : #if defined(HAVE_GETCPUID) 108 : uint32_t eax, ebx, ecx, edx; 109 : GetCPUID(1, 0, eax, ebx, ecx, edx); 110 : #if defined(ENABLE_SSE41) && defined(ENABLE_X86_AESNI) 111 : const bool use_sse_4_1 = ((ecx >> 19) & 1); 112 : const bool use_aes_ni = ((ecx >> 25) & 1); 113 : if (use_sse_4_1 && use_aes_ni) { 114 : echo_round = sapphire::x86_aesni_echo::FullStateRound; 115 : shavite_c512 = sapphire::x86_aesni_shavite::Compress; 116 : } 117 : #endif // ENABLE_SSE41 && ENABLE_X86_AESNI 118 : #if defined(ENABLE_SSSE3) 119 : const bool use_ssse3 = ((ecx >> 9) & 1); 120 : if (use_ssse3) { 121 : echo_shift_mix = sapphire::ssse3_echo::ShiftAndMix; 122 : } 123 : #endif // ENABLE_SSSE3 124 : #endif // HAVE_GETCPUID 125 : 126 : #if defined(ENABLE_ARM_AES) || defined(ENABLE_ARM_NEON) 127 3659 : [[maybe_unused]] bool have_arm_aes = false; 128 3659 : [[maybe_unused]] bool have_arm_neon = false; 129 : 130 : #if defined(__APPLE__) 131 3659 : have_arm_aes = IsSysCtlNonZero("hw.optional.arm.FEAT_AES"); 132 3659 : have_arm_neon = IsSysCtlNonZero("hw.optional.neon") || IsSysCtlNonZero("hw.optional.AdvSIMD") || 133 0 : IsSysCtlNonZero("hw.optional.arm.AdvSIMD"); // See https://github.com/google/cpu_features/issues/390 134 : #endif // __APPLE__ 135 : 136 : #if defined(__linux__) 137 : #if defined(__arm__) 138 : have_arm_aes = (::getauxval(AT_HWCAP2) & HWCAP2_AES); 139 : have_arm_neon = (::getauxval(AT_HWCAP) & HWCAP_NEON); 140 : #endif // __arm__ 141 : #if defined(__aarch64__) 142 : have_arm_aes = (::getauxval(AT_HWCAP) & HWCAP_AES); 143 : have_arm_neon = (::getauxval(AT_HWCAP) & HWCAP_ASIMD); 144 : #endif // __aarch64__ 145 : #endif // __linux__ 146 : 147 : #if defined(__FreeBSD__) 148 : [[maybe_unused]] unsigned long hwcap{0}, hwcap2{0}; 149 : #if defined(__arm__) 150 : have_arm_aes = ((::elf_aux_info(AT_HWCAP2, &hwcap2, sizeof(hwcap2)) == 0) && ((hwcap2 & HWCAP2_AES) != 0)); 151 : have_arm_neon = ((::elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)) == 0) && ((hwcap & HWCAP_NEON) != 0)); 152 : #endif // __arm__ 153 : #if defined(__aarch64__) 154 : if (::elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)) == 0) { 155 : have_arm_aes = ((hwcap & HWCAP_AES) != 0); 156 : have_arm_neon = ((hwcap & HWCAP_ASIMD) != 0); 157 : } 158 : #endif // __aarch64__ 159 : #endif // __FreeBSD__ 160 : 161 : #if defined(_WIN32) 162 : have_arm_aes = ::IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE); 163 : have_arm_neon = ::IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE); 164 : #endif // _WIN32 165 : 166 : #if defined(ENABLE_ARM_AES) 167 3659 : if (have_arm_aes) { 168 3659 : echo_round = sapphire::arm_crypto_echo::FullStateRound; 169 3659 : shavite_c512 = sapphire::arm_crypto_shavite::Compress; 170 3659 : } 171 : #endif // ENABLE_ARM_AES 172 : 173 : #if defined (ENABLE_ARM_NEON) 174 3659 : if (have_arm_neon) { 175 3659 : echo_shift_mix = sapphire::arm_neon_echo::ShiftAndMix; 176 3659 : } 177 : #endif // ENABLE_ARM_NEON 178 : #endif // ENABLE_ARM_AES || ENABLE_ARM_NEON 179 : #endif // !DISABLE_OPTIMIZED_SHA256 180 3659 : }