diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2018-05-08 10:27:57 -0700 |
---|---|---|
committer | Pieter Wuille <pieter.wuille@gmail.com> | 2018-05-29 14:18:05 -0700 |
commit | 230294bf5fdeba7213471cd0b795fb7aa36e5717 (patch) | |
tree | 2962394fa17f202a6becc73d8289d782358ee812 /src/crypto/sha256.cpp | |
parent | 1f0e7ca09c9d7c5787c218156fa5096a1bdf2ea8 (diff) |
4-way SSE4.1 implementation for double SHA256 on 64-byte inputs
Diffstat (limited to 'src/crypto/sha256.cpp')
-rw-r--r-- | src/crypto/sha256.cpp | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/src/crypto/sha256.cpp b/src/crypto/sha256.cpp index 3b40254e63..2bf019ed34 100644 --- a/src/crypto/sha256.cpp +++ b/src/crypto/sha256.cpp @@ -19,6 +19,11 @@ void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks); #endif #endif +namespace sha256d64_sse41 +{ +void Transform_4way(unsigned char* out, const unsigned char* in); +} + // Internal implementation code. namespace { @@ -465,22 +470,28 @@ bool SelfTest(TransformType tr) { TransformType Transform = sha256::Transform; TransformD64Type TransformD64 = sha256::TransformD64; +TransformD64Type TransformD64_4way = nullptr; } // namespace std::string SHA256AutoDetect() { + std::string ret = "standard"; #if defined(USE_ASM) && (defined(__x86_64__) || defined(__amd64__)) uint32_t eax, ebx, ecx, edx; if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) && (ecx >> 19) & 1) { Transform = sha256_sse4::Transform; TransformD64 = TransformD64Wrapper<sha256_sse4::Transform>; - assert(SelfTest(Transform)); - return "sse4"; +#if defined(ENABLE_SSE41) && !defined(BUILD_BITCOIN_INTERNAL) + TransformD64_4way = sha256d64_sse41::Transform_4way; + ret = "sse4(1way+4way)"; +#else + ret = "sse4"; +#endif } #endif assert(SelfTest(Transform)); - return "standard"; + return ret; } ////// SHA-256 @@ -542,6 +553,14 @@ CSHA256& CSHA256::Reset() void SHA256D64(unsigned char* out, const unsigned char* in, size_t blocks) { + if (TransformD64_4way) { + while (blocks >= 4) { + TransformD64_4way(out, in); + out += 128; + in += 256; + blocks -= 4; + } + } while (blocks) { TransformD64(out, in); out += 32; |