diff --git a/vendor/README b/vendor/README index 771c571b..aadcf953 100644 --- a/vendor/README +++ b/vendor/README @@ -5,3 +5,8 @@ spdlog: https://github.com/gabime/spdlog/tree/v0.16.3/include/spdlog cryptopp: https://github.com/weidai11/cryptopp/tree/CRYPTOPP_8_0_0 - changed: added CMakeLists.txt and cryptopp-config.cmake from https://github.com/noloader/cryptopp-cmake/tree/CRYPTOPP_8_0_0 - changed: commented out line including winapifamily.h in CMakeLists.txt + - cherry-picked commits to get OpenMP for scrypt on Windows: + - https://github.com/weidai11/cryptopp/commit/aa043b38a7930725c31a0cd7016986d1c581c573 + - https://github.com/weidai11/cryptopp/commit/672f5c7f3dad8ae12b2d0ce0940ccb7c8e257bf8 + - https://github.com/weidai11/cryptopp/commit/7e96a283a3192d29aac5b60e5b4ff19248f00d9a + - https://github.com/weidai11/cryptopp/commit/ca32b63038d5f7b13e2e00809cd9184a1efe8c24 diff --git a/vendor/cryptopp/vendor_cryptopp/cryptest.nmake b/vendor/cryptopp/vendor_cryptopp/cryptest.nmake index e2a5db72..a15fc7b0 100644 --- a/vendor/cryptopp/vendor_cryptopp/cryptest.nmake +++ b/vendor/cryptopp/vendor_cryptopp/cryptest.nmake @@ -139,6 +139,7 @@ LDLIBS = # CXXFLAGS = $(CXXFLAGS) /DDEBUG /D_DEBUG /Oi /Oy- /Od /MTd # Release build. Add /OPT:REF to linker CXXFLAGS = $(CXXFLAGS) /DNDEBUG /D_NDEBUG /Oi /Oy /O2 /MT +# Linker flags. LDFLAGS = $(LDFLAGS) /OPT:REF # Attempt to detect when and are available diff --git a/vendor/cryptopp/vendor_cryptopp/salsa.cpp b/vendor/cryptopp/vendor_cryptopp/salsa.cpp index 148d970a..fb2dc03e 100644 --- a/vendor/cryptopp/vendor_cryptopp/salsa.cpp +++ b/vendor/cryptopp/vendor_cryptopp/salsa.cpp @@ -90,9 +90,14 @@ void Salsa20_Core(word32* data, unsigned int rounds) x[15] ^= rotlConstant<18>(x[14]+x[13]); } +#ifdef _MSC_VER + for (size_t i = 0; i < 16; ++i) + data[i] += x[i]; +#else #pragma omp simd for (size_t i = 0; i < 16; ++i) data[i] += x[i]; +#endif } std::string Salsa20_Policy::AlgorithmProvider() const diff --git a/vendor/cryptopp/vendor_cryptopp/scrypt.cpp b/vendor/cryptopp/vendor_cryptopp/scrypt.cpp index 3566c3e1..69f486d1 100644 --- a/vendor/cryptopp/vendor_cryptopp/scrypt.cpp +++ b/vendor/cryptopp/vendor_cryptopp/scrypt.cpp @@ -14,6 +14,8 @@ #include "sha.h" #include +#include + #ifdef _OPENMP # include #endif @@ -53,9 +55,14 @@ static inline void BlockCopy(byte* dest, byte* src, size_t len) static inline void BlockXOR(byte* dest, byte* src, size_t len) { +#ifdef _MSC_VER + for (size_t i = 0; i < len; ++i) + dest[i] ^= src[i]; +#else #pragma omp simd for (size_t i = 0; i < len; ++i) dest[i] ^= src[i]; +#endif } static inline void PBKDF2_SHA256(byte* buf, size_t dkLen, @@ -171,6 +178,16 @@ void Scrypt::ValidateParameters(size_t derivedLen, word64 cost, word64 blockSize } } + // https://github.com/weidai11/cryptopp/issues/787 + CRYPTOPP_ASSERT(parallelization <= std::numeric_limits::max()); + if (parallelization > static_cast(std::numeric_limits::max())) + { + std::ostringstream oss; + oss << " parallelization " << parallelization << " is larger than "; + oss << std::numeric_limits::max(); + throw InvalidArgument("Scrypt: " + oss.str()); + } + CRYPTOPP_ASSERT(IsPowerOf2(cost)); if (IsPowerOf2(cost) == false) throw InvalidArgument("Scrypt: cost must be a power of 2"); @@ -245,10 +262,13 @@ size_t Scrypt::DeriveKey(byte*derived, size_t derivedLen, const byte*secret, siz // 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) PBKDF2_SHA256(B, B.size(), secret, secretLen, salt, saltLen, 1); + // Visual Studio and OpenMP 2.0 fixup. We must use int, not size_t. + int maxParallel=0; + if (!SafeConvert(parallel, maxParallel)) + maxParallel = std::numeric_limits::max(); + #ifdef _OPENMP - int threads = STDMIN(omp_get_max_threads(), - static_cast(STDMIN(static_cast(parallel), - static_cast(std::numeric_limits::max())))); + int threads = STDMIN(omp_get_max_threads(), maxParallel); #endif // http://stackoverflow.com/q/49604260/608639 @@ -260,7 +280,7 @@ size_t Scrypt::DeriveKey(byte*derived, size_t derivedLen, const byte*secret, siz // 2: for i = 0 to p - 1 do #pragma omp for - for (size_t i = 0; i < static_cast(parallel); ++i) + for (int i = 0; i < maxParallel; ++i) { // 3: B_i <-- MF(B_i, N) const ptrdiff_t offset = static_cast(blockSize*i*128); diff --git a/vendor/cryptopp/vendor_cryptopp/scrypt.h b/vendor/cryptopp/vendor_cryptopp/scrypt.h index 129c5dc3..8c6f394f 100644 --- a/vendor/cryptopp/vendor_cryptopp/scrypt.h +++ b/vendor/cryptopp/vendor_cryptopp/scrypt.h @@ -76,7 +76,9 @@ public: /// \details The parameter blockSize ("r" in the documents) specifies the block /// size. /// \details The parallelization parameter ("p" in the documents) is a positive - /// integer less than or equal to ((2^32-1) * 32) / (128 * r). + /// integer less than or equal to ((2^32-1) * 32) / (128 * r). Due to Microsoft + /// and its OpenMP 2.0 implementation parallelization is limited to + /// std::numeric_limits::max(). /// \details Scrypt always returns 1 because it only performs 1 iteration. Other /// derivation functions, like PBKDF's, will return more interesting values. /// \details The Crypto++ implementation of Scrypt is limited by C++ datatypes. For