From 6faaf35195f49c9d478fdc7cd188c66d51be163e Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Mon, 2 Apr 2018 03:51:51 -0400 Subject: [PATCH] Add Salsa20_Core transform (GH #630) (#632) --- salsa.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ salsa.h | 9 +++++++++ scrypt.cpp | 53 +++--------------------------------------------- 3 files changed, 71 insertions(+), 50 deletions(-) diff --git a/salsa.cpp b/salsa.cpp index 5fc3a91a..c22d8144 100644 --- a/salsa.cpp +++ b/salsa.cpp @@ -36,6 +36,65 @@ void Salsa20_TestInstantiations() } #endif +void Salsa20_Core(word32* data, unsigned int rounds) +{ + CRYPTOPP_ASSERT(data != NULLPTR); + CRYPTOPP_ASSERT(rounds % 2 == 0); + + CRYPTOPP_ALIGN_DATA(16) word32 x[16]; + + for (size_t i = 0; i < 16; ++i) + x[i] = data[i]; + + // Rounds must be even + for (size_t i = 0; i < rounds; i += 2) + { + x[ 4] ^= rotlConstant< 7>(x[ 0]+x[12]); + x[ 8] ^= rotlConstant< 9>(x[ 4]+x[ 0]); + x[12] ^= rotlConstant<13>(x[ 8]+x[ 4]); + x[ 0] ^= rotlConstant<18>(x[12]+x[ 8]); + + x[ 9] ^= rotlConstant< 7>(x[ 5]+x[ 1]); + x[13] ^= rotlConstant< 9>(x[ 9]+x[ 5]); + x[ 1] ^= rotlConstant<13>(x[13]+x[ 9]); + x[ 5] ^= rotlConstant<18>(x[ 1]+x[13]); + + x[14] ^= rotlConstant< 7>(x[10]+x[ 6]); + x[ 2] ^= rotlConstant< 9>(x[14]+x[10]); + x[ 6] ^= rotlConstant<13>(x[ 2]+x[14]); + x[10] ^= rotlConstant<18>(x[ 6]+x[ 2]); + + x[ 3] ^= rotlConstant< 7>(x[15]+x[11]); + x[ 7] ^= rotlConstant< 9>(x[ 3]+x[15]); + x[11] ^= rotlConstant<13>(x[ 7]+x[ 3]); + x[15] ^= rotlConstant<18>(x[11]+x[ 7]); + + x[ 1] ^= rotlConstant< 7>(x[ 0]+x[ 3]); + x[ 2] ^= rotlConstant< 9>(x[ 1]+x[ 0]); + x[ 3] ^= rotlConstant<13>(x[ 2]+x[ 1]); + x[ 0] ^= rotlConstant<18>(x[ 3]+x[ 2]); + + x[ 6] ^= rotlConstant< 7>(x[ 5]+x[ 4]); + x[ 7] ^= rotlConstant< 9>(x[ 6]+x[ 5]); + x[ 4] ^= rotlConstant<13>(x[ 7]+x[ 6]); + x[ 5] ^= rotlConstant<18>(x[ 4]+x[ 7]); + + x[11] ^= rotlConstant< 7>(x[10]+x[ 9]); + x[ 8] ^= rotlConstant< 9>(x[11]+x[10]); + x[ 9] ^= rotlConstant<13>(x[ 8]+x[11]); + x[10] ^= rotlConstant<18>(x[ 9]+x[ 8]); + + x[12] ^= rotlConstant< 7>(x[15]+x[14]); + x[13] ^= rotlConstant< 9>(x[12]+x[15]); + x[14] ^= rotlConstant<13>(x[13]+x[12]); + x[15] ^= rotlConstant<18>(x[14]+x[13]); + } + + #pragma omp simd + for (size_t i = 0; i < 16; ++i) + data[i] += x[i]; +} + void Salsa20_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) { m_rounds = params.GetIntValueWithDefault(Name::Rounds(), 20); diff --git a/salsa.h b/salsa.h index fcbfd994..957f654a 100644 --- a/salsa.h +++ b/salsa.h @@ -16,6 +16,15 @@ NAMESPACE_BEGIN(CryptoPP) +/// \brief Salsa20 core transform +/// \param data the data to transform +/// \param rounds the number of rounds +/// \details Several algorithms, like CryptoBox and Scrypt, require access to +/// the core Salsa20 transform. The current Crypto++ implementation does not +/// lend itself to disgorging the Salsa20 cipher from the Salsa20 core transform. +/// Instead Salsa20_Core is provided with customary accelerations. +void Salsa20_Core(word32* data, unsigned int rounds); + /// \brief Salsa20 stream cipher information struct Salsa20_Info : public VariableKeyLength<32, 16, 32, 16, SimpleKeyingInterface::UNIQUE_IV, 8> { diff --git a/scrypt.cpp b/scrypt.cpp index 6d894461..452ec284 100644 --- a/scrypt.cpp +++ b/scrypt.cpp @@ -23,6 +23,7 @@ ANONYMOUS_NAMESPACE_BEGIN using CryptoPP::byte; using CryptoPP::word32; using CryptoPP::word64; +using CryptoPP::Salsa20_Core; using CryptoPP::rotlConstant; using CryptoPP::AlignedSecByteBlock; using CryptoPP::LITTLE_ENDIAN_ORDER; @@ -76,60 +77,12 @@ static inline void PBKDF2_SHA256(byte* buf, size_t dkLen, static inline void Salsa20_8(byte B[64]) { - word32 B32[16], x[16]; + word32 B32[16]; for (size_t i = 0; i < 16; ++i) B32[i] = LE32DEC(&B[i * 4]); - for (size_t i = 0; i < 16; ++i) - x[i] = B32[i]; - - for (size_t i = 0; i < 8; i += 2) - { - x[ 4] ^= rotlConstant< 7>(x[ 0]+x[12]); - x[ 8] ^= rotlConstant< 9>(x[ 4]+x[ 0]); - x[12] ^= rotlConstant<13>(x[ 8]+x[ 4]); - x[ 0] ^= rotlConstant<18>(x[12]+x[ 8]); - - x[ 9] ^= rotlConstant< 7>(x[ 5]+x[ 1]); - x[13] ^= rotlConstant< 9>(x[ 9]+x[ 5]); - x[ 1] ^= rotlConstant<13>(x[13]+x[ 9]); - x[ 5] ^= rotlConstant<18>(x[ 1]+x[13]); - - x[14] ^= rotlConstant< 7>(x[10]+x[ 6]); - x[ 2] ^= rotlConstant< 9>(x[14]+x[10]); - x[ 6] ^= rotlConstant<13>(x[ 2]+x[14]); - x[10] ^= rotlConstant<18>(x[ 6]+x[ 2]); - - x[ 3] ^= rotlConstant< 7>(x[15]+x[11]); - x[ 7] ^= rotlConstant< 9>(x[ 3]+x[15]); - x[11] ^= rotlConstant<13>(x[ 7]+x[ 3]); - x[15] ^= rotlConstant<18>(x[11]+x[ 7]); - - x[ 1] ^= rotlConstant< 7>(x[ 0]+x[ 3]); - x[ 2] ^= rotlConstant< 9>(x[ 1]+x[ 0]); - x[ 3] ^= rotlConstant<13>(x[ 2]+x[ 1]); - x[ 0] ^= rotlConstant<18>(x[ 3]+x[ 2]); - - x[ 6] ^= rotlConstant< 7>(x[ 5]+x[ 4]); - x[ 7] ^= rotlConstant< 9>(x[ 6]+x[ 5]); - x[ 4] ^= rotlConstant<13>(x[ 7]+x[ 6]); - x[ 5] ^= rotlConstant<18>(x[ 4]+x[ 7]); - - x[11] ^= rotlConstant< 7>(x[10]+x[ 9]); - x[ 8] ^= rotlConstant< 9>(x[11]+x[10]); - x[ 9] ^= rotlConstant<13>(x[ 8]+x[11]); - x[10] ^= rotlConstant<18>(x[ 9]+x[ 8]); - - x[12] ^= rotlConstant< 7>(x[15]+x[14]); - x[13] ^= rotlConstant< 9>(x[12]+x[15]); - x[14] ^= rotlConstant<13>(x[13]+x[12]); - x[15] ^= rotlConstant<18>(x[14]+x[13]); - } - - #pragma omp simd - for (size_t i = 0; i < 16; ++i) - B32[i] += x[i]; + Salsa20_Core(B32, 8); for (size_t i = 0; i < 16; ++i) LE32ENC(&B[4 * i], B32[i]);