From 600e2a8be4c1a75afbbc9078b79e481e2c3ca346 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Sat, 3 Nov 2018 10:33:35 -0400 Subject: [PATCH] Rewrite BLAKE2 classes to remove intermediate base class --- blake2.cpp | 318 ++++++++++++++++++++--------- blake2.h | 522 ++++++++++++++++++++++++++--------------------- blake2b-simd.cpp | 29 +-- blake2s-simd.cpp | 31 +-- 4 files changed, 521 insertions(+), 379 deletions(-) diff --git a/blake2.cpp b/blake2.cpp index c696169e..04e1316a 100644 --- a/blake2.cpp +++ b/blake2.cpp @@ -27,6 +27,28 @@ # undef CRYPTOPP_POWER8_AVAILABLE #endif +NAMESPACE_BEGIN(CryptoPP) + +// Export the tables to the SIMD files +extern const word32 BLAKE2S_IV[8]; +extern const word64 BLAKE2B_IV[8]; + +CRYPTOPP_ALIGN_DATA(16) +const word32 BLAKE2S_IV[8] = { + 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, + 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL +}; + +CRYPTOPP_ALIGN_DATA(16) +const word64 BLAKE2B_IV[8] = { + W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b), + W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1), + W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f), + W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179) +}; + +NAMESPACE_END + ANONYMOUS_NAMESPACE_BEGIN using CryptoPP::byte; @@ -34,27 +56,6 @@ using CryptoPP::word32; using CryptoPP::word64; using CryptoPP::rotrConstant; -template -struct BLAKE2_IV -{ - CRYPTOPP_ALIGN_DATA(16) - static const W iv[8]; -}; - -template <> -const word32 BLAKE2_IV::iv[8] = { - 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, - 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL -}; - -template <> -const word64 BLAKE2_IV::iv[8] = { - W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b), - W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1), - W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f), - W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179) -}; - CRYPTOPP_ALIGN_DATA(16) const byte BLAKE2S_SIGMA[10][16] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, @@ -141,28 +142,28 @@ ANONYMOUS_NAMESPACE_END NAMESPACE_BEGIN(CryptoPP) -void BLAKE2_Compress32_CXX(const byte* input, BLAKE2_State& state); -void BLAKE2_Compress64_CXX(const byte* input, BLAKE2_State& state); +void BLAKE2_Compress32_CXX(const byte* input, BLAKE2s_State& state); +void BLAKE2_Compress64_CXX(const byte* input, BLAKE2b_State& state); #if CRYPTOPP_SSE41_AVAILABLE -extern void BLAKE2_Compress32_SSE4(const byte* input, BLAKE2_State& state); -extern void BLAKE2_Compress64_SSE4(const byte* input, BLAKE2_State& state); +extern void BLAKE2_Compress32_SSE4(const byte* input, BLAKE2s_State& state); +extern void BLAKE2_Compress64_SSE4(const byte* input, BLAKE2b_State& state); #endif #if CRYPTOPP_ARM_NEON_AVAILABLE -extern void BLAKE2_Compress32_NEON(const byte* input, BLAKE2_State& state); -extern void BLAKE2_Compress64_NEON(const byte* input, BLAKE2_State& state); +extern void BLAKE2_Compress32_NEON(const byte* input, BLAKE2s_State& state); +extern void BLAKE2_Compress64_NEON(const byte* input, BLAKE2b_State& state); #endif #if CRYPTOPP_POWER7_AVAILABLE -extern void BLAKE2_Compress32_POWER7(const byte* input, BLAKE2_State& state); +extern void BLAKE2_Compress32_POWER7(const byte* input, BLAKE2s_State& state); #endif #if CRYPTOPP_POWER8_AVAILABLE -extern void BLAKE2_Compress64_POWER8(const byte* input, BLAKE2_State& state); +extern void BLAKE2_Compress64_POWER8(const byte* input, BLAKE2b_State& state); #endif -BLAKE2_ParameterBlock::BLAKE2_ParameterBlock(size_t digestLen, size_t keyLen, +BLAKE2s_ParameterBlock::BLAKE2s_ParameterBlock(size_t digestLen, size_t keyLen, const byte* saltStr, size_t saltLen, const byte* personalizationStr, size_t personalizationLen) { @@ -201,7 +202,7 @@ BLAKE2_ParameterBlock::BLAKE2_ParameterBlock(size_t digestLen, size_t key } } -BLAKE2_ParameterBlock::BLAKE2_ParameterBlock(size_t digestLen, size_t keyLen, +BLAKE2b_ParameterBlock::BLAKE2b_ParameterBlock(size_t digestLen, size_t keyLen, const byte* saltStr, size_t saltLen, const byte* personalizationStr, size_t personalizationLen) { @@ -241,8 +242,7 @@ BLAKE2_ParameterBlock::BLAKE2_ParameterBlock(size_t digestLen, size_t keyL } } -template<> // This specialization lacks rfu[] field -void BLAKE2_Base::UncheckedSetKey(const byte *key, unsigned int length, const CryptoPP::NameValuePairs& params) +void BLAKE2s::UncheckedSetKey(const byte *key, unsigned int length, const CryptoPP::NameValuePairs& params) { if (key && length) { @@ -297,8 +297,7 @@ void BLAKE2_Base::UncheckedSetKey(const byte *key, unsigned int l } } -template<> // This specialization has rfu[] field -void BLAKE2_Base::UncheckedSetKey(const byte *key, unsigned int length, const CryptoPP::NameValuePairs& params) +void BLAKE2b::UncheckedSetKey(const byte *key, unsigned int length, const CryptoPP::NameValuePairs& params) { if (key && length) { @@ -354,8 +353,24 @@ void BLAKE2_Base::UncheckedSetKey(const byte *key, unsigned int le } } -template -std::string BLAKE2_Base::AlgorithmProvider() const +std::string BLAKE2b::AlgorithmProvider() const +{ +#if defined(CRYPTOPP_SSE41_AVAILABLE) + if (HasSSE41()) + return "SSE4.1"; +#endif +#if (CRYPTOPP_ARM_NEON_AVAILABLE) + if (HasNEON()) + return "NEON"; +#endif +#if (CRYPTOPP_POWER8_AVAILABLE) + if (HasPower8()) + return "Power8"; +#endif + return "C++"; +} + +std::string BLAKE2s::AlgorithmProvider() const { #if defined(CRYPTOPP_SSE41_AVAILABLE) if (HasSSE41()) @@ -366,25 +381,13 @@ std::string BLAKE2_Base::AlgorithmProvider() const return "NEON"; #endif #if (CRYPTOPP_POWER7_AVAILABLE) - if (HasPower7() && T_64bit == false) + if (HasPower7()) return "Power7"; -#endif -#if (CRYPTOPP_POWER8_AVAILABLE) - if (HasPower8() && T_64bit == true) - return "Power8"; #endif return "C++"; } -template -BLAKE2_Base::BLAKE2_Base() : m_state(1), m_block(1), m_digestSize(DIGESTSIZE), m_treeMode(false) -{ - UncheckedSetKey(NULLPTR, 0, g_nullNameValuePairs); - Restart(); -} - -template -BLAKE2_Base::BLAKE2_Base(bool treeMode, unsigned int digestSize) : m_state(1), m_block(1), m_digestSize(digestSize), m_treeMode(treeMode) +BLAKE2s::BLAKE2s(bool treeMode, unsigned int digestSize) : m_state(1), m_block(1), m_digestSize(digestSize), m_treeMode(treeMode) { CRYPTOPP_ASSERT(digestSize <= DIGESTSIZE); @@ -392,8 +395,15 @@ BLAKE2_Base::BLAKE2_Base(bool treeMode, unsigned int digestSize) : m Restart(); } -template -BLAKE2_Base::BLAKE2_Base(const byte *key, size_t keyLength, const byte* salt, size_t saltLength, +BLAKE2b::BLAKE2b(bool treeMode, unsigned int digestSize) : m_state(1), m_block(1), m_digestSize(digestSize), m_treeMode(treeMode) +{ + CRYPTOPP_ASSERT(digestSize <= DIGESTSIZE); + + UncheckedSetKey(NULLPTR, 0, MakeParameters(Name::DigestSize(), (int)digestSize)(Name::TreeMode(), treeMode, false)); + Restart(); +} + +BLAKE2s::BLAKE2s(const byte *key, size_t keyLength, const byte* salt, size_t saltLength, const byte* personalization, size_t personalizationLength, bool treeMode, unsigned int digestSize) : m_state(1), m_block(1), m_digestSize(digestSize), m_treeMode(treeMode) { @@ -407,15 +417,33 @@ BLAKE2_Base::BLAKE2_Base(const byte *key, size_t keyLength, const by Restart(); } -template -void BLAKE2_Base::Restart() +BLAKE2b::BLAKE2b(const byte *key, size_t keyLength, const byte* salt, size_t saltLength, + const byte* personalization, size_t personalizationLength, bool treeMode, unsigned int digestSize) + : m_state(1), m_block(1), m_digestSize(digestSize), m_treeMode(treeMode) { - static const W zero[2] = {0,0}; + CRYPTOPP_ASSERT(keyLength <= MAX_KEYLENGTH); + CRYPTOPP_ASSERT(digestSize <= DIGESTSIZE); + CRYPTOPP_ASSERT(saltLength <= SALTSIZE); + CRYPTOPP_ASSERT(personalizationLength <= PERSONALIZATIONSIZE); + + UncheckedSetKey(key, static_cast(keyLength), MakeParameters(Name::DigestSize(),(int)digestSize)(Name::TreeMode(),treeMode, false) + (Name::Salt(), ConstByteArrayParameter(salt, saltLength))(Name::Personalization(), ConstByteArrayParameter(personalization, personalizationLength))); + Restart(); +} + +void BLAKE2s::Restart() +{ + static const word32 zero[2] = {0,0}; Restart(*m_block.data(), zero); } -template -void BLAKE2_Base::Restart(const BLAKE2_ParameterBlock& block, const W counter[2]) +void BLAKE2b::Restart() +{ + static const word64 zero[2] = {0,0}; + Restart(*m_block.data(), zero); +} + +void BLAKE2s::Restart(const BLAKE2s_ParameterBlock& block, const word32 counter[2]) { // We take a parameter block as a parameter to allow customized state. // Avoid the copy of the parameter block when we are passing our own block. @@ -435,8 +463,8 @@ void BLAKE2_Base::Restart(const BLAKE2_ParameterBlock& bloc state.t[1] = counter[1]; } - const W* iv = BLAKE2_IV::iv; - PutBlock put(m_block.data(), &state.h[0]); + const word32* iv = BLAKE2S_IV; + PutBlock put(m_block.data(), &state.h[0]); put(iv[0])(iv[1])(iv[2])(iv[3])(iv[4])(iv[5])(iv[6])(iv[7]); // When BLAKE2 is keyed, the input stream is simply {key||message}. Key it @@ -445,8 +473,38 @@ void BLAKE2_Base::Restart(const BLAKE2_ParameterBlock& bloc Update(m_key, m_key.size()); } -template -void BLAKE2_Base::Update(const byte *input, size_t length) + +void BLAKE2b::Restart(const BLAKE2b_ParameterBlock& block, const word64 counter[2]) +{ + // We take a parameter block as a parameter to allow customized state. + // Avoid the copy of the parameter block when we are passing our own block. + if (&block != m_block.data()) + { + memcpy_s(m_block.data(), sizeof(ParameterBlock), &block, sizeof(ParameterBlock)); + m_block.data()->digestLength = (byte)m_digestSize; + m_block.data()->keyLength = (byte)m_key.size(); + } + + State& state = *m_state.data(); + state.t[0] = state.t[1] = 0, state.f[0] = state.f[1] = 0, state.length = 0; + + if (counter != NULLPTR) + { + state.t[0] = counter[0]; + state.t[1] = counter[1]; + } + + const word64* iv = BLAKE2B_IV; + PutBlock put(m_block.data(), &state.h[0]); + put(iv[0])(iv[1])(iv[2])(iv[3])(iv[4])(iv[5])(iv[6])(iv[7]); + + // When BLAKE2 is keyed, the input stream is simply {key||message}. Key it + // during Restart to avoid FirstPut and friends. Key size == 0 means no key. + if (m_key.size()) + Update(m_key, m_key.size()); +} + +void BLAKE2s::Update(const byte *input, size_t length) { CRYPTOPP_ASSERT(!(input == NULLPTR && length != 0)); if (length == 0) { return; } @@ -482,19 +540,55 @@ void BLAKE2_Base::Update(const byte *input, size_t length) } } -template -void BLAKE2_Base::TruncatedFinal(byte *hash, size_t size) + +void BLAKE2b::Update(const byte *input, size_t length) +{ + CRYPTOPP_ASSERT(!(input == NULLPTR && length != 0)); + if (length == 0) { return; } + + State& state = *m_state.data(); + if (state.length + length > BLOCKSIZE) + { + // Complete current block + const size_t fill = BLOCKSIZE - state.length; + memcpy_s(&state.buffer[state.length], fill, input, fill); + + IncrementCounter(); + Compress(state.buffer); + state.length = 0; + + length -= fill, input += fill; + + // Compress in-place to avoid copies + while (length > BLOCKSIZE) + { + IncrementCounter(); + Compress(input); + length -= BLOCKSIZE, input += BLOCKSIZE; + } + } + + // Copy tail bytes + if (input && length) + { + CRYPTOPP_ASSERT(length <= BLOCKSIZE - state.length); + memcpy_s(&state.buffer[state.length], length, input, length); + state.length += static_cast(length); + } +} + +void BLAKE2s::TruncatedFinal(byte *hash, size_t size) { CRYPTOPP_ASSERT(hash != NULLPTR); this->ThrowIfInvalidTruncatedSize(size); // Set last block unconditionally State& state = *m_state.data(); - state.f[0] = ~static_cast(0); + state.f[0] = ~static_cast(0); // Set last node if tree mode if (m_treeMode) - state.f[1] = ~static_cast(0); + state.f[1] = ~static_cast(0); // Increment counter for tail bytes only IncrementCounter(state.length); @@ -508,40 +602,46 @@ void BLAKE2_Base::TruncatedFinal(byte *hash, size_t size) Restart(); } -template -void BLAKE2_Base::IncrementCounter(size_t count) +void BLAKE2b::TruncatedFinal(byte *hash, size_t size) +{ + CRYPTOPP_ASSERT(hash != NULLPTR); + this->ThrowIfInvalidTruncatedSize(size); + + // Set last block unconditionally + State& state = *m_state.data(); + state.f[0] = ~static_cast(0); + + // Set last node if tree mode + if (m_treeMode) + state.f[1] = ~static_cast(0); + + // Increment counter for tail bytes only + IncrementCounter(state.length); + + std::memset(state.buffer + state.length, 0x00, BLOCKSIZE - state.length); + Compress(state.buffer); + + // Copy to caller buffer + memcpy_s(hash, size, &state.h[0], size); + + Restart(); +} + +void BLAKE2s::IncrementCounter(size_t count) { State& state = *m_state.data(); - state.t[0] += static_cast(count); + state.t[0] += static_cast(count); state.t[1] += !!(state.t[0] < count); } -template <> -void BLAKE2_Base::Compress(const byte *input) +void BLAKE2b::IncrementCounter(size_t count) { -#if CRYPTOPP_SSE41_AVAILABLE - if(HasSSE41()) - { - return BLAKE2_Compress64_SSE4(input, *m_state.data()); - } -#endif -#if CRYPTOPP_ARM_NEON_AVAILABLE - if(HasNEON()) - { - return BLAKE2_Compress64_NEON(input, *m_state.data()); - } -#endif -#if CRYPTOPP_POWER8_AVAILABLE - if(HasPower8()) - { - return BLAKE2_Compress64_POWER8(input, *m_state.data()); - } -#endif - return BLAKE2_Compress64_CXX(input, *m_state.data()); + State& state = *m_state.data(); + state.t[0] += static_cast(count); + state.t[1] += !!(state.t[0] < count); } -template <> -void BLAKE2_Base::Compress(const byte *input) +void BLAKE2s::Compress(const byte *input) { #if CRYPTOPP_SSE41_AVAILABLE if(HasSSE41()) @@ -564,7 +664,30 @@ void BLAKE2_Base::Compress(const byte *input) return BLAKE2_Compress32_CXX(input, *m_state.data()); } -void BLAKE2_Compress64_CXX(const byte* input, BLAKE2_State& state) +void BLAKE2b::Compress(const byte *input) +{ +#if CRYPTOPP_SSE41_AVAILABLE + if(HasSSE41()) + { + return BLAKE2_Compress64_SSE4(input, *m_state.data()); + } +#endif +#if CRYPTOPP_ARM_NEON_AVAILABLE + if(HasNEON()) + { + return BLAKE2_Compress64_NEON(input, *m_state.data()); + } +#endif +#if CRYPTOPP_POWER8_AVAILABLE + if(HasPower8()) + { + return BLAKE2_Compress64_POWER8(input, *m_state.data()); + } +#endif + return BLAKE2_Compress64_CXX(input, *m_state.data()); +} + +void BLAKE2_Compress64_CXX(const byte* input, BLAKE2b_State& state) { word64 m[16], v[16]; @@ -574,7 +697,7 @@ void BLAKE2_Compress64_CXX(const byte* input, BLAKE2_State& state) GetBlock get2(&state.h[0]); get2(v[0])(v[1])(v[2])(v[3])(v[4])(v[5])(v[6])(v[7]); - const word64* iv = BLAKE2_IV::iv; + const word64* iv = BLAKE2B_IV; v[ 8] = iv[0]; v[ 9] = iv[1]; v[10] = iv[2]; @@ -601,7 +724,7 @@ void BLAKE2_Compress64_CXX(const byte* input, BLAKE2_State& state) state.h[i] = state.h[i] ^ ConditionalByteReverse(LittleEndian::ToEnum(), v[i] ^ v[i + 8]); } -void BLAKE2_Compress32_CXX(const byte* input, BLAKE2_State& state) +void BLAKE2_Compress32_CXX(const byte* input, BLAKE2s_State& state) { word32 m[16], v[16]; @@ -611,7 +734,7 @@ void BLAKE2_Compress32_CXX(const byte* input, BLAKE2_State& state GetBlock get2(&state.h[0]); get2(v[0])(v[1])(v[2])(v[3])(v[4])(v[5])(v[6])(v[7]); - const word32* iv = BLAKE2_IV::iv; + const word32* iv = BLAKE2S_IV; v[ 8] = iv[0]; v[ 9] = iv[1]; v[10] = iv[2]; @@ -636,7 +759,4 @@ void BLAKE2_Compress32_CXX(const byte* input, BLAKE2_State& state state.h[i] = state.h[i] ^ ConditionalByteReverse(LittleEndian::ToEnum(), v[i] ^ v[i + 8]); } -template class BLAKE2_Base; -template class BLAKE2_Base; - NAMESPACE_END diff --git a/blake2.h b/blake2.h index 4ef329e7..a7be88e5 100644 --- a/blake2.h +++ b/blake2.h @@ -24,251 +24,142 @@ NAMESPACE_BEGIN(CryptoPP) -/// \brief BLAKE2 hash information -/// \tparam T_64bit flag indicating 64-bit +/// \brief BLAKE2s hash information /// \since Crypto++ 5.6.4 -template -struct BLAKE2_Info : public VariableKeyLength<(T_64bit ? 64 : 32),0,(T_64bit ? 64 : 32),1,SimpleKeyingInterface::NOT_RESYNCHRONIZABLE> +struct BLAKE2s_Info : public VariableKeyLength<32,0,32,1,SimpleKeyingInterface::NOT_RESYNCHRONIZABLE> { - typedef VariableKeyLength<(T_64bit ? 64 : 32),0,(T_64bit ? 64 : 32),1,SimpleKeyingInterface::NOT_RESYNCHRONIZABLE> KeyBase; - CRYPTOPP_CONSTANT(MIN_KEYLENGTH = KeyBase::MIN_KEYLENGTH) - CRYPTOPP_CONSTANT(MAX_KEYLENGTH = KeyBase::MAX_KEYLENGTH) - CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH = KeyBase::DEFAULT_KEYLENGTH) + typedef VariableKeyLength<32,0,32,1,SimpleKeyingInterface::NOT_RESYNCHRONIZABLE> KeyBase; + CRYPTOPP_CONSTANT(MIN_KEYLENGTH = KeyBase::MIN_KEYLENGTH) + CRYPTOPP_CONSTANT(MAX_KEYLENGTH = KeyBase::MAX_KEYLENGTH) + CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH = KeyBase::DEFAULT_KEYLENGTH) - CRYPTOPP_CONSTANT(BLOCKSIZE = (T_64bit ? 128 : 64)) - CRYPTOPP_CONSTANT(DIGESTSIZE = (T_64bit ? 64 : 32)) - CRYPTOPP_CONSTANT(SALTSIZE = (T_64bit ? 16 : 8)) - CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = (T_64bit ? 16 : 8)) + CRYPTOPP_CONSTANT(BLOCKSIZE = 64) + CRYPTOPP_CONSTANT(DIGESTSIZE = 32) + CRYPTOPP_CONSTANT(SALTSIZE = 8) + CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = 8) - CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return (T_64bit ? "BLAKE2b" : "BLAKE2s");} + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "BLAKE2s";} }; -/// \brief BLAKE2 parameter block -/// \tparam T_64bit flag indicating 64-bit -/// \details BLAKE2b uses BLAKE2_ParameterBlock, while BLAKE2s -/// uses BLAKE2_ParameterBlock. +/// \brief BLAKE2b hash information /// \since Crypto++ 5.6.4 -template -struct CRYPTOPP_NO_VTABLE BLAKE2_ParameterBlock +struct BLAKE2b_Info : public VariableKeyLength<64,0,64,1,SimpleKeyingInterface::NOT_RESYNCHRONIZABLE> { + typedef VariableKeyLength<64,0,64,1,SimpleKeyingInterface::NOT_RESYNCHRONIZABLE> KeyBase; + CRYPTOPP_CONSTANT(MIN_KEYLENGTH = KeyBase::MIN_KEYLENGTH) + CRYPTOPP_CONSTANT(MAX_KEYLENGTH = KeyBase::MAX_KEYLENGTH) + CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH = KeyBase::DEFAULT_KEYLENGTH) + + CRYPTOPP_CONSTANT(BLOCKSIZE = 128) + CRYPTOPP_CONSTANT(DIGESTSIZE = 64) + CRYPTOPP_CONSTANT(SALTSIZE = 16) + CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = 16) + + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "BLAKE2b";} }; -/// \brief BLAKE2b parameter block specialization -template<> -struct CRYPTOPP_NO_VTABLE BLAKE2_ParameterBlock +/// \brief BLAKE2s parameter block +struct CRYPTOPP_NO_VTABLE BLAKE2s_ParameterBlock { - CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2_Info::SALTSIZE) - CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2_Info::DIGESTSIZE) - CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2_Info::PERSONALIZATIONSIZE) + CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2s_Info::SALTSIZE) + CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2s_Info::DIGESTSIZE) + CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2s_Info::PERSONALIZATIONSIZE) - BLAKE2_ParameterBlock() - { - memset(this, 0x00, sizeof(*this)); - digestLength = DIGESTSIZE; - fanout = depth = 1; - } + BLAKE2s_ParameterBlock() + { + memset(this, 0x00, sizeof(*this)); + digestLength = DIGESTSIZE; + fanout = depth = 1; + } - BLAKE2_ParameterBlock(size_t digestSize) - { - CRYPTOPP_ASSERT(digestSize <= DIGESTSIZE); - memset(this, 0x00, sizeof(*this)); - digestLength = (byte)digestSize; - fanout = depth = 1; - } + BLAKE2s_ParameterBlock(size_t digestSize) + { + CRYPTOPP_ASSERT(digestSize <= DIGESTSIZE); + memset(this, 0x00, sizeof(*this)); + digestLength = (byte)digestSize; + fanout = depth = 1; + } - BLAKE2_ParameterBlock(size_t digestSize, size_t keyLength, const byte* salt, size_t saltLength, - const byte* personalization, size_t personalizationLength); + BLAKE2s_ParameterBlock(size_t digestSize, size_t keyLength, const byte* salt, size_t saltLength, + const byte* personalization, size_t personalizationLength); - byte digestLength; - byte keyLength, fanout, depth; - byte leafLength[4]; - byte nodeOffset[8]; - byte nodeDepth, innerLength, rfu[14]; - byte salt[SALTSIZE]; - byte personalization[PERSONALIZATIONSIZE]; + byte digestLength; + byte keyLength, fanout, depth; + byte leafLength[4]; + byte nodeOffset[6]; + byte nodeDepth, innerLength; + byte salt[SALTSIZE]; + byte personalization[PERSONALIZATIONSIZE]; }; -/// \brief BLAKE2s parameter block specialization -template<> -struct CRYPTOPP_NO_VTABLE BLAKE2_ParameterBlock +/// \brief BLAKE2b parameter block +struct CRYPTOPP_NO_VTABLE BLAKE2b_ParameterBlock { - CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2_Info::SALTSIZE) - CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2_Info::DIGESTSIZE) - CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2_Info::PERSONALIZATIONSIZE) + CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2b_Info::SALTSIZE) + CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2b_Info::DIGESTSIZE) + CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2b_Info::PERSONALIZATIONSIZE) - BLAKE2_ParameterBlock() - { - memset(this, 0x00, sizeof(*this)); - digestLength = DIGESTSIZE; - fanout = depth = 1; - } + BLAKE2b_ParameterBlock() + { + memset(this, 0x00, sizeof(*this)); + digestLength = DIGESTSIZE; + fanout = depth = 1; + } - BLAKE2_ParameterBlock(size_t digestSize) - { - CRYPTOPP_ASSERT(digestSize <= DIGESTSIZE); - memset(this, 0x00, sizeof(*this)); - digestLength = (byte)digestSize; - fanout = depth = 1; - } + BLAKE2b_ParameterBlock(size_t digestSize) + { + CRYPTOPP_ASSERT(digestSize <= DIGESTSIZE); + memset(this, 0x00, sizeof(*this)); + digestLength = (byte)digestSize; + fanout = depth = 1; + } - BLAKE2_ParameterBlock(size_t digestSize, size_t keyLength, const byte* salt, size_t saltLength, - const byte* personalization, size_t personalizationLength); + BLAKE2b_ParameterBlock(size_t digestSize, size_t keyLength, const byte* salt, size_t saltLength, + const byte* personalization, size_t personalizationLength); - byte digestLength; - byte keyLength, fanout, depth; - byte leafLength[4]; - byte nodeOffset[6]; - byte nodeDepth, innerLength; - byte salt[SALTSIZE]; - byte personalization[PERSONALIZATIONSIZE]; + byte digestLength; + byte keyLength, fanout, depth; + byte leafLength[4]; + byte nodeOffset[8]; + byte nodeDepth, innerLength, rfu[14]; + byte salt[SALTSIZE]; + byte personalization[PERSONALIZATIONSIZE]; }; -/// \brief BLAKE2 state information -/// \tparam W word type -/// \tparam T_64bit flag indicating 64-bit -/// \details BLAKE2b uses BLAKE2_State, while BLAKE2s -/// uses BLAKE2_State. +/// \brief BLAKE2s state information /// \since Crypto++ 5.6.4 -template -struct CRYPTOPP_NO_VTABLE BLAKE2_State +struct CRYPTOPP_NO_VTABLE BLAKE2s_State { - CRYPTOPP_CONSTANT(BLOCKSIZE = BLAKE2_Info::BLOCKSIZE) + BLAKE2s_State() + { + // Set all members except scratch buffer[] + h[0]=h[1]=h[2]=h[3]=h[4]=h[5]=h[6]=h[7] = 0; + t[0]=t[1]=f[0]=f[1] = 0; + length = 0; + } - BLAKE2_State() - { - // Set all members except scratch buffer[] - h[0]=h[1]=h[2]=h[3]=h[4]=h[5]=h[6]=h[7] = 0; - t[0]=t[1]=f[0]=f[1] = 0; - length = 0; - } - - // SSE2, SSE4 and NEON depend upon t[] and f[] being side-by-side - W h[8], t[2], f[2]; - byte buffer[BLOCKSIZE]; - size_t length; + // SSE2, SSE4 and NEON depend upon t[] and f[] being side-by-side + word32 h[8], t[2], f[2]; + byte buffer[BLAKE2s_Info::BLOCKSIZE]; + size_t length; }; -/// \brief BLAKE2 hash implementation -/// \tparam W word type -/// \tparam T_64bit flag indicating 64-bit -/// \details BLAKE2b uses BLAKE2_Base, while BLAKE2s -/// uses BLAKE2_Base. +/// \brief BLAKE2b state information /// \since Crypto++ 5.6.4 -template -class BLAKE2_Base : public SimpleKeyingInterfaceImpl > +struct CRYPTOPP_NO_VTABLE BLAKE2b_State { -public: - CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH = BLAKE2_Info::DEFAULT_KEYLENGTH) - CRYPTOPP_CONSTANT(MIN_KEYLENGTH = BLAKE2_Info::MIN_KEYLENGTH) - CRYPTOPP_CONSTANT(MAX_KEYLENGTH = BLAKE2_Info::MAX_KEYLENGTH) + BLAKE2b_State() + { + // Set all members except scratch buffer[] + h[0]=h[1]=h[2]=h[3]=h[4]=h[5]=h[6]=h[7] = 0; + t[0]=t[1]=f[0]=f[1] = 0; + length = 0; + } - CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2_Info::DIGESTSIZE) - CRYPTOPP_CONSTANT(BLOCKSIZE = BLAKE2_Info::BLOCKSIZE) - CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2_Info::SALTSIZE) - CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2_Info::PERSONALIZATIONSIZE) - - typedef BLAKE2_State State; - typedef BLAKE2_ParameterBlock ParameterBlock; - typedef SecBlock > AlignedState; - typedef SecBlock > AlignedParameterBlock; - - virtual ~BLAKE2_Base() {} - - /// \brief Retrieve the static algorithm name - /// \returns the algorithm name (BLAKE2s or BLAKE2b) - CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return BLAKE2_Info::StaticAlgorithmName();} - - /// \brief Retrieve the object's name - /// \returns the object's algorithm name following RFC 7693 - /// \details Object algorithm name follows the naming described in - /// RFC 7693, The BLAKE2 Cryptographic Hash and - /// Message Authentication Code (MAC). For example, "BLAKE2b-512" and "BLAKE2s-256". - std::string AlgorithmName() const {return std::string(StaticAlgorithmName()) + "-" + IntToString(this->DigestSize()*8);} - - unsigned int DigestSize() const {return m_digestSize;} - unsigned int OptimalDataAlignment() const {return (CRYPTOPP_BOOL_ALIGN16 ? 16 : GetAlignmentOf());} - - void Update(const byte *input, size_t length); - void Restart(); - - /// \brief Restart a hash with parameter block and counter - /// \param block parameter block - /// \param counter counter array - /// \details Parameter block is persisted across calls to Restart(). - void Restart(const BLAKE2_ParameterBlock& block, const W counter[2]); - - /// \brief Set tree mode - /// \param mode the new tree mode - /// \details BLAKE2 has two finalization flags, called State::f[0] and State::f[1]. - /// If treeMode=false (default), then State::f[1] is never set. If - /// treeMode=true, then State::f[1] is set when State::f[0] is set. - /// Tree mode is persisted across calls to Restart(). - void SetTreeMode(bool mode) {m_treeMode=mode;} - - /// \brief Get tree mode - /// \returns the current tree mode - /// \details Tree mode is persisted across calls to Restart(). - bool GetTreeMode() const {return m_treeMode;} - - void TruncatedFinal(byte *hash, size_t size); - - std::string AlgorithmProvider() const; - -protected: - BLAKE2_Base(); - BLAKE2_Base(bool treeMode, unsigned int digestSize); - BLAKE2_Base(const byte *key, size_t keyLength, const byte* salt, size_t saltLength, - const byte* personalization, size_t personalizationLength, - bool treeMode, unsigned int digestSize); - - // Operates on state buffer and/or input. Must be BLOCKSIZE, final block will pad with 0's. - void Compress(const byte *input); - inline void IncrementCounter(size_t count=BLOCKSIZE); - - void UncheckedSetKey(const byte* key, unsigned int length, const CryptoPP::NameValuePairs& params); - -private: - AlignedState m_state; - AlignedParameterBlock m_block; - AlignedSecByteBlock m_key; - word32 m_digestSize; - bool m_treeMode; -}; - -/// \brief The BLAKE2b cryptographic hash function -/// \details BLAKE2b can function as both a hash and keyed hash. If you want only the hash, -/// then use the BLAKE2b constructor that accepts no parameters or digest size. If you -/// want a keyed hash, then use the constructor that accpts the key as a parameter. -/// Once a key and digest size are selected, its effectively immutable. The Restart() -/// method that accepts a ParameterBlock does not allow you to change it. -/// \sa Aumasson, Neves, Wilcox-O'Hearn and Winnerlein's -/// BLAKE2: simpler, smaller, fast as MD5 (2013.01.29). -/// \since Crypto++ 5.6.4 -class BLAKE2b : public BLAKE2_Base -{ -public: - typedef BLAKE2_Base ThisBase; // Early Visual Studio workaround - typedef BLAKE2_ParameterBlock ParameterBlock; - CRYPTOPP_COMPILE_ASSERT(sizeof(ParameterBlock) == 64); - - /// \brief Construct a BLAKE2b hash - /// \param digestSize the digest size, in bytes - /// \param treeMode flag indicating tree mode - BLAKE2b(bool treeMode=false, unsigned int digestSize = DIGESTSIZE) : ThisBase(treeMode, digestSize) {} - - /// \brief Construct a BLAKE2b hash - /// \param key a byte array used to key the cipher - /// \param keyLength the size of the byte array - /// \param salt a byte array used as salt - /// \param saltLength the size of the byte array - /// \param personalization a byte array used as prsonalization string - /// \param personalizationLength the size of the byte array - /// \param treeMode flag indicating tree mode - /// \param digestSize the digest size, in bytes - BLAKE2b(const byte *key, size_t keyLength, const byte* salt = NULLPTR, size_t saltLength = 0, - const byte* personalization = NULLPTR, size_t personalizationLength = 0, - bool treeMode=false, unsigned int digestSize = DIGESTSIZE) - : ThisBase(key, keyLength, salt, saltLength, personalization, personalizationLength, treeMode, digestSize) {} + // SSE2, SSE4 and NEON depend upon t[] and f[] being side-by-side + word64 h[8], t[2], f[2]; + byte buffer[BLAKE2b_Info::BLOCKSIZE]; + size_t length; }; /// \brief The BLAKE2s cryptographic hash function @@ -280,31 +171,194 @@ public: /// \sa Aumasson, Neves, Wilcox-O'Hearn and Winnerlein's /// BLAKE2: simpler, smaller, fast as MD5 (2013.01.29). /// \since Crypto++ 5.6.4 -class BLAKE2s : public BLAKE2_Base +class BLAKE2s : public SimpleKeyingInterfaceImpl { public: - typedef BLAKE2_Base ThisBase; // Early Visual Studio workaround - typedef BLAKE2_ParameterBlock ParameterBlock; - CRYPTOPP_COMPILE_ASSERT(sizeof(ParameterBlock) == 32); + CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH = BLAKE2s_Info::DEFAULT_KEYLENGTH) + CRYPTOPP_CONSTANT(MIN_KEYLENGTH = BLAKE2s_Info::MIN_KEYLENGTH) + CRYPTOPP_CONSTANT(MAX_KEYLENGTH = BLAKE2s_Info::MAX_KEYLENGTH) - /// \brief Construct a BLAKE2s hash - /// \param digestSize the digest size, in bytes - /// \param treeMode flag indicating tree mode - BLAKE2s(bool treeMode=false, unsigned int digestSize = DIGESTSIZE) : ThisBase(treeMode, digestSize) {} + CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2s_Info::DIGESTSIZE) + CRYPTOPP_CONSTANT(BLOCKSIZE = BLAKE2s_Info::BLOCKSIZE) + CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2s_Info::SALTSIZE) + CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2s_Info::PERSONALIZATIONSIZE) - /// \brief Construct a BLAKE2s hash - /// \param key a byte array used to key the cipher - /// \param keyLength the size of the byte array - /// \param salt a byte array used as salt - /// \param saltLength the size of the byte array - /// \param personalization a byte array used as prsonalization string - /// \param personalizationLength the size of the byte array - /// \param treeMode flag indicating tree mode - /// \param digestSize the digest size, in bytes - BLAKE2s(const byte *key, size_t keyLength, const byte* salt = NULLPTR, size_t saltLength = 0, - const byte* personalization = NULLPTR, size_t personalizationLength = 0, - bool treeMode=false, unsigned int digestSize = DIGESTSIZE) - : ThisBase(key, keyLength, salt, saltLength, personalization, personalizationLength, treeMode, digestSize) {} + typedef BLAKE2s_State State; + typedef BLAKE2s_ParameterBlock ParameterBlock; + typedef SecBlock > AlignedState; + typedef SecBlock > AlignedParameterBlock; + + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "BLAKE2s";} + + virtual ~BLAKE2s() {} + + /// \brief Construct a BLAKE2s hash + /// \param digestSize the digest size, in bytes + /// \param treeMode flag indicating tree mode + BLAKE2s(bool treeMode=false, unsigned int digestSize = DIGESTSIZE); + + /// \brief Construct a BLAKE2s hash + /// \param key a byte array used to key the cipher + /// \param keyLength the size of the byte array + /// \param salt a byte array used as salt + /// \param saltLength the size of the byte array + /// \param personalization a byte array used as prsonalization string + /// \param personalizationLength the size of the byte array + /// \param treeMode flag indicating tree mode + /// \param digestSize the digest size, in bytes + BLAKE2s(const byte *key, size_t keyLength, const byte* salt = NULLPTR, size_t saltLength = 0, + const byte* personalization = NULLPTR, size_t personalizationLength = 0, + bool treeMode=false, unsigned int digestSize = DIGESTSIZE); + + /// \brief Retrieve the object's name + /// \returns the object's algorithm name following RFC 7693 + /// \details Object algorithm name follows the naming described in + /// RFC 7693, The BLAKE2 Cryptographic Hash and + /// Message Authentication Code (MAC). For example, "BLAKE2b-512" and "BLAKE2s-256". + std::string AlgorithmName() const {return std::string(BLAKE2s_Info::StaticAlgorithmName()) + "-" + IntToString(this->DigestSize()*8);} + + unsigned int DigestSize() const {return m_digestSize;} + unsigned int OptimalDataAlignment() const {return (CRYPTOPP_BOOL_ALIGN16 ? 16 : GetAlignmentOf());} + + void Update(const byte *input, size_t length); + void Restart(); + + /// \brief Restart a hash with parameter block and counter + /// \param block parameter block + /// \param counter counter array + /// \details Parameter block is persisted across calls to Restart(). + void Restart(const BLAKE2s_ParameterBlock& block, const word32 counter[2]); + + /// \brief Set tree mode + /// \param mode the new tree mode + /// \details BLAKE2 has two finalization flags, called State::f[0] and State::f[1]. + /// If treeMode=false (default), then State::f[1] is never set. If + /// treeMode=true, then State::f[1] is set when State::f[0] is set. + /// Tree mode is persisted across calls to Restart(). + void SetTreeMode(bool mode) {m_treeMode=mode;} + + /// \brief Get tree mode + /// \returns the current tree mode + /// \details Tree mode is persisted across calls to Restart(). + bool GetTreeMode() const {return m_treeMode;} + + void TruncatedFinal(byte *hash, size_t size); + + std::string AlgorithmProvider() const; + +protected: + // Operates on state buffer and/or input. Must be BLOCKSIZE, final block will pad with 0's. + void Compress(const byte *input); + inline void IncrementCounter(size_t count=BLOCKSIZE); + + void UncheckedSetKey(const byte* key, unsigned int length, const CryptoPP::NameValuePairs& params); + +private: + AlignedState m_state; + AlignedParameterBlock m_block; + AlignedSecByteBlock m_key; + word32 m_digestSize; + bool m_treeMode; +}; + +/// \brief The BLAKE2b cryptographic hash function +/// \details BLAKE2b can function as both a hash and keyed hash. If you want only the hash, +/// then use the BLAKE2b constructor that accepts no parameters or digest size. If you +/// want a keyed hash, then use the constructor that accpts the key as a parameter. +/// Once a key and digest size are selected, its effectively immutable. The Restart() +/// method that accepts a ParameterBlock does not allow you to change it. +/// \sa Aumasson, Neves, Wilcox-O'Hearn and Winnerlein's +/// BLAKE2: simpler, smaller, fast as MD5 (2013.01.29). +/// \since Crypto++ 5.6.4 +class BLAKE2b : public SimpleKeyingInterfaceImpl +{ +public: + CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH = BLAKE2b_Info::DEFAULT_KEYLENGTH) + CRYPTOPP_CONSTANT(MIN_KEYLENGTH = BLAKE2b_Info::MIN_KEYLENGTH) + CRYPTOPP_CONSTANT(MAX_KEYLENGTH = BLAKE2b_Info::MAX_KEYLENGTH) + + CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2b_Info::DIGESTSIZE) + CRYPTOPP_CONSTANT(BLOCKSIZE = BLAKE2b_Info::BLOCKSIZE) + CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2b_Info::SALTSIZE) + CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2b_Info::PERSONALIZATIONSIZE) + + typedef BLAKE2b_State State; + typedef BLAKE2b_ParameterBlock ParameterBlock; + typedef SecBlock > AlignedState; + typedef SecBlock > AlignedParameterBlock; + + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "BLAKE2b";} + + virtual ~BLAKE2b() {} + + /// \brief Construct a BLAKE2b hash + /// \param digestSize the digest size, in bytes + /// \param treeMode flag indicating tree mode + BLAKE2b(bool treeMode=false, unsigned int digestSize = DIGESTSIZE); + + /// \brief Construct a BLAKE2b hash + /// \param key a byte array used to key the cipher + /// \param keyLength the size of the byte array + /// \param salt a byte array used as salt + /// \param saltLength the size of the byte array + /// \param personalization a byte array used as prsonalization string + /// \param personalizationLength the size of the byte array + /// \param treeMode flag indicating tree mode + /// \param digestSize the digest size, in bytes + BLAKE2b(const byte *key, size_t keyLength, const byte* salt = NULLPTR, size_t saltLength = 0, + const byte* personalization = NULLPTR, size_t personalizationLength = 0, + bool treeMode=false, unsigned int digestSize = DIGESTSIZE); + + /// \brief Retrieve the object's name + /// \returns the object's algorithm name following RFC 7693 + /// \details Object algorithm name follows the naming described in + /// RFC 7693, The BLAKE2 Cryptographic Hash and + /// Message Authentication Code (MAC). For example, "BLAKE2b-512" and "BLAKE2s-256". + std::string AlgorithmName() const {return std::string(BLAKE2b_Info::StaticAlgorithmName()) + "-" + IntToString(this->DigestSize()*8);} + + unsigned int DigestSize() const {return m_digestSize;} + unsigned int OptimalDataAlignment() const {return (CRYPTOPP_BOOL_ALIGN16 ? 16 : GetAlignmentOf());} + + void Update(const byte *input, size_t length); + void Restart(); + + /// \brief Restart a hash with parameter block and counter + /// \param block parameter block + /// \param counter counter array + /// \details Parameter block is persisted across calls to Restart(). + void Restart(const BLAKE2b_ParameterBlock& block, const word64 counter[2]); + + /// \brief Set tree mode + /// \param mode the new tree mode + /// \details BLAKE2 has two finalization flags, called State::f[0] and State::f[1]. + /// If treeMode=false (default), then State::f[1] is never set. If + /// treeMode=true, then State::f[1] is set when State::f[0] is set. + /// Tree mode is persisted across calls to Restart(). + void SetTreeMode(bool mode) {m_treeMode=mode;} + + /// \brief Get tree mode + /// \returns the current tree mode + /// \details Tree mode is persisted across calls to Restart(). + bool GetTreeMode() const {return m_treeMode;} + + void TruncatedFinal(byte *hash, size_t size); + + std::string AlgorithmProvider() const; + +protected: + + // Operates on state buffer and/or input. Must be BLOCKSIZE, final block will pad with 0's. + void Compress(const byte *input); + inline void IncrementCounter(size_t count=BLOCKSIZE); + + void UncheckedSetKey(const byte* key, unsigned int length, const CryptoPP::NameValuePairs& params); + +private: + AlignedState m_state; + AlignedParameterBlock m_block; + AlignedSecByteBlock m_key; + word32 m_digestSize; + bool m_treeMode; }; NAMESPACE_END diff --git a/blake2b-simd.cpp b/blake2b-simd.cpp index fa850e66..eaf6e7f0 100644 --- a/blake2b-simd.cpp +++ b/blake2b-simd.cpp @@ -45,27 +45,12 @@ # include "ppc-simd.h" #endif -ANONYMOUS_NAMESPACE_BEGIN - -using CryptoPP::word32; -using CryptoPP::word64; - -#if (CRYPTOPP_SSE41_AVAILABLE || CRYPTOPP_ARM_NEON_AVAILABLE || CRYPTOPP_POWER8_AVAILABLE) - -CRYPTOPP_ALIGN_DATA(16) -const word64 BLAKE2B_IV[8] = { - W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b), - W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1), - W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f), - W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179) -}; - -#endif // CRYPTOPP_SSE41_AVAILABLE || CRYPTOPP_ARM_NEON_AVAILABLE - -ANONYMOUS_NAMESPACE_END - NAMESPACE_BEGIN(CryptoPP) +// Exported by blake2.cpp +extern const word32 BLAKE2S_IV[8]; +extern const word64 BLAKE2B_IV[8]; + #if CRYPTOPP_SSE41_AVAILABLE #define LOADU(p) _mm_loadu_si128( (const __m128i *)(const void*)(p) ) @@ -73,7 +58,7 @@ NAMESPACE_BEGIN(CryptoPP) #define TOF(reg) _mm_castsi128_ps((reg)) #define TOI(reg) _mm_castps_si128((reg)) -void BLAKE2_Compress64_SSE4(const byte* input, BLAKE2_State& state) +void BLAKE2_Compress64_SSE4(const byte* input, BLAKE2b_State& state) { #define BLAKE2B_LOAD_MSG_0_1(b0, b1) \ do { \ @@ -500,7 +485,7 @@ void BLAKE2_Compress64_SSE4(const byte* input, BLAKE2_State& state #endif // CRYPTOPP_SSE41_AVAILABLE #if CRYPTOPP_ARM_NEON_AVAILABLE -void BLAKE2_Compress64_NEON(const byte* input, BLAKE2_State& state) +void BLAKE2_Compress64_NEON(const byte* input, BLAKE2b_State& state) { #define BLAKE2B_LOAD_MSG_0_1(b0, b1) \ do { b0 = vcombine_u64(vget_low_u64(m0), vget_low_u64(m1)); b1 = vcombine_u64(vget_low_u64(m2), vget_low_u64(m3)); } while(0) @@ -823,7 +808,7 @@ inline uint64x2_p VectorShiftLeftOctet(const uint64x2_p a, const uint64x2_p b) # define vec_merge_lo(a,b) vec_mergel(a,b) #endif -void BLAKE2_Compress64_POWER8(const byte* input, BLAKE2_State& state) +void BLAKE2_Compress64_POWER8(const byte* input, BLAKE2b_State& state) { // Permute masks. High is element 0 (most significant), // low is element 1 (least significant). diff --git a/blake2s-simd.cpp b/blake2s-simd.cpp index fd1bc006..af5e47e8 100644 --- a/blake2s-simd.cpp +++ b/blake2s-simd.cpp @@ -45,25 +45,12 @@ # include "ppc-simd.h" #endif -ANONYMOUS_NAMESPACE_BEGIN - -using CryptoPP::word32; -using CryptoPP::word64; - -#if (CRYPTOPP_SSE41_AVAILABLE || CRYPTOPP_ARM_NEON_AVAILABLE || CRYPTOPP_POWER7_AVAILABLE) - -CRYPTOPP_ALIGN_DATA(16) -const word32 BLAKE2S_IV[8] = { - 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, - 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL -}; - -#endif - -ANONYMOUS_NAMESPACE_END - NAMESPACE_BEGIN(CryptoPP) +// Exported by blake2.cpp +extern const word32 BLAKE2S_IV[8]; +extern const word64 BLAKE2B_IV[8]; + #if CRYPTOPP_SSE41_AVAILABLE #define LOADU(p) _mm_loadu_si128( (const __m128i *)(const void*)(p) ) @@ -71,7 +58,7 @@ NAMESPACE_BEGIN(CryptoPP) #define TOF(reg) _mm_castsi128_ps((reg)) #define TOI(reg) _mm_castps_si128((reg)) -void BLAKE2_Compress32_SSE4(const byte* input, BLAKE2_State& state) +void BLAKE2_Compress32_SSE4(const byte* input, BLAKE2s_State& state) { #define BLAKE2S_LOAD_MSG_0_1(buf) \ buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(2,0,2,0))); @@ -367,7 +354,7 @@ void BLAKE2_Compress32_SSE4(const byte* input, BLAKE2_State& stat #endif // CRYPTOPP_SSE41_AVAILABLE #if CRYPTOPP_ARM_NEON_AVAILABLE -void BLAKE2_Compress32_NEON(const byte* input, BLAKE2_State& state) +void BLAKE2_Compress32_NEON(const byte* input, BLAKE2s_State& state) { #define BLAKE2S_LOAD_MSG_0_1(buf) \ do { uint32x2_t t0, t1; \ @@ -656,10 +643,6 @@ void BLAKE2_Compress32_NEON(const byte* input, BLAKE2_State& stat BLAKE2S_UNDIAGONALIZE(row1,row2,row3,row4); \ } while(0) - CRYPTOPP_ASSERT(IsAlignedOn(&state.h[0],GetAlignmentOf())); - CRYPTOPP_ASSERT(IsAlignedOn(&state.t[0],GetAlignmentOf())); - CRYPTOPP_ASSERT(IsAlignedOn(&state.f[0],GetAlignmentOf())); - const uint32x4_t m0 = vreinterpretq_u32_u8(vld1q_u8((input + 00))); const uint32x4_t m1 = vreinterpretq_u32_u8(vld1q_u8((input + 16))); const uint32x4_t m2 = vreinterpretq_u32_u8(vld1q_u8((input + 32))); @@ -880,7 +863,7 @@ uint32x4_p VectorSet32<3,1,3,1>(const uint32x4_p a, const uint32x4_p b, return vec_perm(a, c, mask); } -void BLAKE2_Compress32_POWER7(const byte* input, BLAKE2_State& state) +void BLAKE2_Compress32_POWER7(const byte* input, BLAKE2s_State& state) { # define m1 m0 # define m2 m0