diff --git a/velox/docs/functions/binary.rst b/velox/docs/functions/binary.rst index ff5557881cdc..859bc4c8109b 100644 --- a/velox/docs/functions/binary.rst +++ b/velox/docs/functions/binary.rst @@ -26,6 +26,10 @@ Binary Functions Computes the HMAC with sha256 of ``binary`` with the given ``key``. +.. function:: hmac_sha512(binary, key) -> varbinary + + Computes the HMAC with sha512 of ``binary`` with the given ``key``. + .. function:: to_base64(binary) -> varchar Encodes ``binary`` into a base64 string representation. diff --git a/velox/functions/lib/string/StringImpl.h b/velox/functions/lib/string/StringImpl.h index 4852be18221b..e98011553ee6 100644 --- a/velox/functions/lib/string/StringImpl.h +++ b/velox/functions/lib/string/StringImpl.h @@ -231,13 +231,12 @@ FOLLY_ALWAYS_INLINE void replaceInPlace( /// Compute the MD5 Hash. template -FOLLY_ALWAYS_INLINE bool md5(TOutString& output, const TInString& input) { +FOLLY_ALWAYS_INLINE void md5(TOutString& output, const TInString& input) { static const auto kByteLength = 16; output.resize(kByteLength); crypto::MD5Context md5Context; md5Context.Add((const uint8_t*)input.data(), input.size()); md5Context.Finish((uint8_t*)output.data()); - return true; } /// Compute the MD5 Hash. @@ -271,12 +270,11 @@ FOLLY_ALWAYS_INLINE bool md5_radix( /// Compute the SHA256 Hash. template -FOLLY_ALWAYS_INLINE bool sha256(TOutString& output, const TInString& input) { +FOLLY_ALWAYS_INLINE void sha256(TOutString& output, const TInString& input) { output.resize(32); folly::ssl::OpenSSLHash::sha256( folly::MutableByteRange((uint8_t*)output.data(), output.size()), folly::ByteRange((const uint8_t*)input.data(), input.size())); - return true; } /// Compute the SHA512 Hash. @@ -290,14 +288,24 @@ FOLLY_ALWAYS_INLINE void sha512(TOutString& output, const TInString& input) { // Compute the HMAC-SHA256 Hash. template -FOLLY_ALWAYS_INLINE bool +FOLLY_ALWAYS_INLINE void HmacSha256(TOutString& output, const TInString& key, const TInString& data) { output.resize(32); folly::ssl::OpenSSLHash::hmac_sha256( folly::MutableByteRange((uint8_t*)output.data(), output.size()), folly::ByteRange((const uint8_t*)key.data(), key.size()), folly::ByteRange((const uint8_t*)data.data(), data.size())); - return true; +} + +// Compute the HMAC-SHA512 Hash. +template +FOLLY_ALWAYS_INLINE void +HmacSha512(TOutString& output, const TInString& key, const TInString& data) { + output.resize(64); + folly::ssl::OpenSSLHash::hmac_sha512( + folly::MutableByteRange((uint8_t*)output.data(), output.size()), + folly::ByteRange((const uint8_t*)key.data(), key.size()), + folly::ByteRange((const uint8_t*)data.data(), data.size())); } template diff --git a/velox/functions/prestosql/StringFunctions.h b/velox/functions/prestosql/StringFunctions.h index 2cb452c403f5..4179053c1aac 100644 --- a/velox/functions/prestosql/StringFunctions.h +++ b/velox/functions/prestosql/StringFunctions.h @@ -61,10 +61,9 @@ struct CRC32Function { VELOX_DEFINE_FUNCTION_TYPES(T); FOLLY_ALWAYS_INLINE - bool call(out_type& result, const arg_type& input) { + void call(out_type& result, const arg_type& input) { result = static_cast(folly::crc32_type( reinterpret_cast(input.data()), input.size())); - return true; } }; @@ -75,7 +74,7 @@ struct XxHash64Function { VELOX_DEFINE_FUNCTION_TYPES(T); FOLLY_ALWAYS_INLINE - bool call(out_type& result, const arg_type& input) { + void call(out_type& result, const arg_type& input) { // Seed is set to 0. int64_t hash = XXH64(input.data(), input.size(), 0); static const auto kLen = sizeof(int64_t); @@ -83,7 +82,6 @@ struct XxHash64Function { // Resizing output and copy result.resize(kLen); std::memcpy(result.data(), &hash, kLen); - return true; } }; @@ -93,8 +91,8 @@ struct Md5Function { VELOX_DEFINE_FUNCTION_TYPES(T); template - FOLLY_ALWAYS_INLINE bool call(TTo& result, const TFrom& input) { - return stringImpl::md5(result, input); + FOLLY_ALWAYS_INLINE void call(TTo& result, const TFrom& input) { + stringImpl::md5(result, input); } }; @@ -104,8 +102,8 @@ struct Sha256Function { VELOX_DEFINE_FUNCTION_TYPES(T); template - FOLLY_ALWAYS_INLINE bool call(TTo& result, const TFrom& input) { - return stringImpl::sha256(result, input); + FOLLY_ALWAYS_INLINE void call(TTo& result, const TFrom& input) { + stringImpl::sha256(result, input); } }; @@ -120,15 +118,27 @@ struct Sha512Function { } }; -/// sha1(varbinary) -> varbinary +/// hmac_sha256(varbinary) -> varbinary template struct HmacSha256Function { VELOX_DEFINE_FUNCTION_TYPES(T); - template - FOLLY_ALWAYS_INLINE bool - call(TOuput& result, const TInput& data, const TInput& key) { - return stringImpl::HmacSha256(result, key, data); + template + FOLLY_ALWAYS_INLINE void + call(TTo& result, const TFrom& data, const TFrom& key) { + stringImpl::HmacSha256(result, key, data); + } +}; + +/// hmac_sha512(varbinary) -> varbinary +template +struct HmacSha512Function { + VELOX_DEFINE_FUNCTION_TYPES(T); + + template + FOLLY_ALWAYS_INLINE void + call(TTo& result, const TFrom& data, const TFrom& key) { + stringImpl::HmacSha512(result, key, data); } }; diff --git a/velox/functions/prestosql/registration/StringFunctionsRegistration.cpp b/velox/functions/prestosql/registration/StringFunctionsRegistration.cpp index 9470fd1e0b28..298a5c19cd76 100644 --- a/velox/functions/prestosql/registration/StringFunctionsRegistration.cpp +++ b/velox/functions/prestosql/registration/StringFunctionsRegistration.cpp @@ -62,6 +62,8 @@ void registerSimpleFunctions() { registerFunction({"sha512"}); registerFunction( {"hmac_sha256"}); + registerFunction( + {"hmac_sha512"}); registerFunction({"to_hex"}); registerFunction({"from_hex"}); diff --git a/velox/functions/prestosql/tests/StringFunctionsTest.cpp b/velox/functions/prestosql/tests/StringFunctionsTest.cpp index 93cec47465a3..d535e0a98ab1 100644 --- a/velox/functions/prestosql/tests/StringFunctionsTest.cpp +++ b/velox/functions/prestosql/tests/StringFunctionsTest.cpp @@ -1232,6 +1232,24 @@ TEST_F(StringFunctionsTest, HmacSha256) { EXPECT_EQ(std::nullopt, hmacSha256(std::nullopt, "velox")); } +TEST_F(StringFunctionsTest, HmacSha512) { + const auto hmacSha512 = [&](std::optional arg, + std::optional key) { + return evaluateOnce( + "hmac_sha512(c0, c1)", {arg, key}, {VARBINARY(), VARBINARY()}); + }; + // Use the same expected value from TestVarbinaryFunctions of presto java + EXPECT_EQ( + hexToDec( + "84FA5AA0279BBC473267D05A53EA03310A987CECC4C1535FF29B6D76B8F1444A728DF3AADB89D4A9A6709E1998F373566E8F824A8CA93B1821F0B69BC2A2F65E"), + hmacSha512("", "key")); + EXPECT_EQ( + hexToDec( + "FEFA712B67DED871E1ED987F8B20D6A69EB9FCC87974218B9A1A6D5202B54C18ECDA4839A979DED22F07E0881CF40B762691992D120408F49D6212E112509D72"), + hmacSha512("hashme", "key")); + EXPECT_EQ(std::nullopt, hmacSha512(std::nullopt, "velox")); +} + void StringFunctionsTest::testReplaceInPlace( const std::vector>& tests, const std::string& search,