aboutsummaryrefslogtreecommitdiff
path: root/src/crypto/sha256.cpp
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2018-05-08 10:27:57 -0700
committerPieter Wuille <pieter.wuille@gmail.com>2018-05-29 14:18:05 -0700
commit230294bf5fdeba7213471cd0b795fb7aa36e5717 (patch)
tree2962394fa17f202a6becc73d8289d782358ee812 /src/crypto/sha256.cpp
parent1f0e7ca09c9d7c5787c218156fa5096a1bdf2ea8 (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.cpp25
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;