Skip to content

Commit

Permalink
Add hmac_sha512 Presto Functions (#3406)
Browse files Browse the repository at this point in the history
Summary:
Add [hmac_sha512](https://prestodb.io/docs/current/functions/binary.html#:~:text=given%20key.-,hmac_sha512,-(binary%2C)) Presto Functions

```
hmac_sha512(binary, key) → varbinary
     Computes HMAC with sha512 of binary with the given key.
```

Pull Request resolved: #3406

Reviewed By: xiaoxmeng

Differential Revision: D41841164

Pulled By: Yuhta

fbshipit-source-id: e2feef92f0d544e1eee207d1fe2dcd9d7b7f86f5
  • Loading branch information
duanmeng authored and facebook-github-bot committed Dec 12, 2022
1 parent 04187f1 commit b1d6f40
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 19 deletions.
4 changes: 4 additions & 0 deletions velox/docs/functions/binary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
20 changes: 14 additions & 6 deletions velox/functions/lib/string/StringImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,12 @@ FOLLY_ALWAYS_INLINE void replaceInPlace(

/// Compute the MD5 Hash.
template <typename TOutString, typename TInString>
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.
Expand Down Expand Up @@ -271,12 +270,11 @@ FOLLY_ALWAYS_INLINE bool md5_radix(

/// Compute the SHA256 Hash.
template <typename TOutString, typename TInString>
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.
Expand All @@ -290,14 +288,24 @@ FOLLY_ALWAYS_INLINE void sha512(TOutString& output, const TInString& input) {

// Compute the HMAC-SHA256 Hash.
template <typename TOutString, typename TInString>
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 <typename TOutString, typename TInString>
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 <typename TOutString, typename TInString>
Expand Down
36 changes: 23 additions & 13 deletions velox/functions/prestosql/StringFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,9 @@ struct CRC32Function {
VELOX_DEFINE_FUNCTION_TYPES(T);

FOLLY_ALWAYS_INLINE
bool call(out_type<int64_t>& result, const arg_type<Varchar>& input) {
void call(out_type<int64_t>& result, const arg_type<Varchar>& input) {
result = static_cast<int64_t>(folly::crc32_type(
reinterpret_cast<const unsigned char*>(input.data()), input.size()));
return true;
}
};

Expand All @@ -75,15 +74,14 @@ struct XxHash64Function {
VELOX_DEFINE_FUNCTION_TYPES(T);

FOLLY_ALWAYS_INLINE
bool call(out_type<Varbinary>& result, const arg_type<Varbinary>& input) {
void call(out_type<Varbinary>& result, const arg_type<Varbinary>& input) {
// Seed is set to 0.
int64_t hash = XXH64(input.data(), input.size(), 0);
static const auto kLen = sizeof(int64_t);

// Resizing output and copy
result.resize(kLen);
std::memcpy(result.data(), &hash, kLen);
return true;
}
};

Expand All @@ -93,8 +91,8 @@ struct Md5Function {
VELOX_DEFINE_FUNCTION_TYPES(T);

template <typename TTo, typename TFrom>
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);
}
};

Expand All @@ -104,8 +102,8 @@ struct Sha256Function {
VELOX_DEFINE_FUNCTION_TYPES(T);

template <typename TTo, typename TFrom>
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);
}
};

Expand All @@ -120,15 +118,27 @@ struct Sha512Function {
}
};

/// sha1(varbinary) -> varbinary
/// hmac_sha256(varbinary) -> varbinary
template <typename T>
struct HmacSha256Function {
VELOX_DEFINE_FUNCTION_TYPES(T);

template <typename TOuput, typename TInput>
FOLLY_ALWAYS_INLINE bool
call(TOuput& result, const TInput& data, const TInput& key) {
return stringImpl::HmacSha256(result, key, data);
template <typename TTo, typename TFrom>
FOLLY_ALWAYS_INLINE void
call(TTo& result, const TFrom& data, const TFrom& key) {
stringImpl::HmacSha256(result, key, data);
}
};

/// hmac_sha512(varbinary) -> varbinary
template <typename T>
struct HmacSha512Function {
VELOX_DEFINE_FUNCTION_TYPES(T);

template <typename TTo, typename TFrom>
FOLLY_ALWAYS_INLINE void
call(TTo& result, const TFrom& data, const TFrom& key) {
stringImpl::HmacSha512(result, key, data);
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ void registerSimpleFunctions() {
registerFunction<Sha512Function, Varbinary, Varbinary>({"sha512"});
registerFunction<HmacSha256Function, Varbinary, Varbinary, Varbinary>(
{"hmac_sha256"});
registerFunction<HmacSha512Function, Varbinary, Varbinary, Varbinary>(
{"hmac_sha512"});

registerFunction<ToHexFunction, Varchar, Varbinary>({"to_hex"});
registerFunction<FromHexFunction, Varbinary, Varchar>({"from_hex"});
Expand Down
18 changes: 18 additions & 0 deletions velox/functions/prestosql/tests/StringFunctionsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string> arg,
std::optional<std::string> key) {
return evaluateOnce<std::string, std::string>(
"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<std::pair<std::string, std::string>>& tests,
const std::string& search,
Expand Down

0 comments on commit b1d6f40

Please sign in to comment.