diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt index b9beb8341..48768bb9a 100644 --- a/src/crypto/CMakeLists.txt +++ b/src/crypto/CMakeLists.txt @@ -1,101 +1,102 @@ # Copyright (c) 2017-2019 The Bitcoin developers project(crypto) # The library add_library(crypto aes.cpp chacha20.cpp + hkdf_sha256_32.cpp hmac_sha256.cpp hmac_sha512.cpp ripemd160.cpp sha1.cpp sha256.cpp sha256_sse4.cpp sha512.cpp siphash.cpp ) target_include_directories(crypto PRIVATE .. PUBLIC # To access the config. ${CMAKE_CURRENT_BINARY_DIR}/.. ) target_compile_definitions(crypto PUBLIC HAVE_CONFIG_H) # Use assembly is specified option(CRYPTO_USE_ASM "Use assembly version of crypto primitives" ON) if(CRYPTO_USE_ASM) target_compile_definitions(crypto PRIVATE USE_ASM) endif() # Crypto libraries requiring hardware features macro(add_crypto_library NAME) add_library(${NAME} ${ARGN}) target_link_libraries(crypto ${NAME}) target_include_directories(${NAME} PRIVATE ..) endmacro() include(CheckCXXSourceCompiles) # SSE4.1 set(CRYPTO_SSE41_FLAGS -msse4.1) string(JOIN " " CMAKE_REQUIRED_FLAGS ${CRYPTO_SSE41_FLAGS}) check_cxx_source_compiles(" #include #include int main() { __m128i l = _mm_set1_epi32(0); return _mm_extract_epi32(l, 3); } " ENABLE_SSE41) if(ENABLE_SSE41) add_crypto_library(crypto_sse4.1 sha256_sse41.cpp) target_compile_definitions(crypto_sse4.1 PUBLIC ENABLE_SSE41) target_compile_options(crypto_sse4.1 PRIVATE ${CRYPTO_SSE41_FLAGS}) endif() # AVX2 set(CRYPTO_AVX2_FLAGS -mavx -mavx2) string(JOIN " " CMAKE_REQUIRED_FLAGS ${CRYPTO_AVX2_FLAGS}) check_cxx_source_compiles(" #include #include int main() { __m256i l = _mm256_set1_epi32(0); return _mm256_extract_epi32(l, 7); } " ENABLE_AVX2) if(ENABLE_AVX2) add_crypto_library(crypto_avx2 sha256_avx2.cpp) target_compile_definitions(crypto_avx2 PUBLIC ENABLE_AVX2) target_compile_options(crypto_avx2 PRIVATE ${CRYPTO_AVX2_FLAGS}) endif() # SHA-NI set(CRYPTO_SHANI_FLAGS -msse4 -msha) string(JOIN " " CMAKE_REQUIRED_FLAGS ${CRYPTO_SHANI_FLAGS}) check_cxx_source_compiles(" #include #include int main() { __m128i i = _mm_set1_epi32(0); __m128i j = _mm_set1_epi32(1); __m128i k = _mm_set1_epi32(2); return _mm_extract_epi32(_mm_sha256rnds2_epu32(i, i, k), 0); } " ENABLE_SHANI) if(ENABLE_SHANI) add_crypto_library(crypto_shani sha256_shani.cpp) target_compile_definitions(crypto_shani PUBLIC ENABLE_SHANI) target_compile_options(crypto_shani PRIVATE ${CRYPTO_SHANI_FLAGS}) endif() diff --git a/src/crypto/hkdf_sha256_32.cpp b/src/crypto/hkdf_sha256_32.cpp new file mode 100644 index 000000000..38ad9d057 --- /dev/null +++ b/src/crypto/hkdf_sha256_32.cpp @@ -0,0 +1,26 @@ +// Copyright (c) 2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include +#include + +CHKDF_HMAC_SHA256_L32::CHKDF_HMAC_SHA256_L32(const uint8_t *ikm, size_t ikmlen, + const std::string &salt) { + CHMAC_SHA256((const uint8_t *)salt.c_str(), salt.size()) + .Write(ikm, ikmlen) + .Finalize(m_prk); +} + +void CHKDF_HMAC_SHA256_L32::Expand32(const std::string &info, + uint8_t hash[OUTPUT_SIZE]) { + // expand a 32byte key (single round) + assert(info.size() <= 128); + static const uint8_t one[1] = {1}; + CHMAC_SHA256(m_prk, 32) + .Write((const uint8_t *)info.data(), info.size()) + .Write(one, 1) + .Finalize(hash); +} diff --git a/src/crypto/hkdf_sha256_32.h b/src/crypto/hkdf_sha256_32.h new file mode 100644 index 000000000..ce102f146 --- /dev/null +++ b/src/crypto/hkdf_sha256_32.h @@ -0,0 +1,28 @@ +// Copyright (c) 2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_CRYPTO_HKDF_SHA256_32_H +#define BITCOIN_CRYPTO_HKDF_SHA256_32_H + +#include + +#include +#include + +/** + * A rfc5869 HKDF implementation with HMAC_SHA256 and fixed key output length + * of 32 bytes (L=32) + */ +class CHKDF_HMAC_SHA256_L32 { +private: + uint8_t m_prk[32]; + static const size_t OUTPUT_SIZE = 32; + +public: + CHKDF_HMAC_SHA256_L32(const uint8_t *ikm, size_t ikmlen, + const std::string &salt); + void Expand32(const std::string &info, uint8_t hash[OUTPUT_SIZE]); +}; + +#endif // BITCOIN_CRYPTO_HKDF_SHA256_32_H