[Support] Add SipHash-based 64-bit stable hash function (#160945)

Factor out the 64-bit hash calculation in getPointerAuthStableSipHash()
as getStableSipHash(). This allows using the full 64-bit hash where we
require a stable hash.

Similar to getPointerAuthStableSipHash(), the new hash function is meant
to be stable across platforms and compiler versions.
This commit is contained in:
Marco Elver 2025-09-29 15:56:54 +02:00 committed by GitHub
parent e5bbc9feae
commit 3408e6af75
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 22 additions and 3 deletions

View File

@ -33,6 +33,13 @@ LLVM_ABI void getSipHash_2_4_64(ArrayRef<uint8_t> In, const uint8_t (&K)[16],
LLVM_ABI void getSipHash_2_4_128(ArrayRef<uint8_t> In, const uint8_t (&K)[16],
uint8_t (&Out)[16]);
/// Compute a stable 64-bit hash of the given string.
///
/// The exact algorithm is the little-endian interpretation of the
/// non-doubled (i.e. 64-bit) result of applying a SipHash-2-4 using
/// a specific seed value which can be found in the source.
LLVM_ABI uint64_t getStableSipHash(StringRef Str);
/// Compute a stable non-zero 16-bit hash of the given string.
///
/// The exact algorithm is the little-endian interpretation of the

View File

@ -35,14 +35,19 @@ void llvm::getSipHash_2_4_128(ArrayRef<uint8_t> In, const uint8_t (&K)[16],
siphash<2, 4>(In.data(), In.size(), K, Out);
}
/// Compute an ABI-stable 16-bit hash of the given string.
uint16_t llvm::getPointerAuthStableSipHash(StringRef Str) {
/// Compute an ABI-stable 64-bit hash of the given string.
uint64_t llvm::getStableSipHash(StringRef Str) {
static const uint8_t K[16] = {0xb5, 0xd4, 0xc9, 0xeb, 0x79, 0x10, 0x4a, 0x79,
0x6f, 0xec, 0x8b, 0x1b, 0x42, 0x87, 0x81, 0xd4};
uint8_t RawHashBytes[8];
getSipHash_2_4_64(arrayRefFromStringRef(Str), K, RawHashBytes);
uint64_t RawHash = endian::read64le(RawHashBytes);
return endian::read64le(RawHashBytes);
}
/// Compute an ABI-stable 16-bit hash of the given string.
uint16_t llvm::getPointerAuthStableSipHash(StringRef Str) {
uint64_t RawHash = getStableSipHash(Str);
// Produce a non-zero 16-bit discriminator.
uint16_t Discriminator = (RawHash % 0xFFFF) + 1;

View File

@ -50,6 +50,13 @@ TEST(SipHashTest, SipHash_2_4_128) {
}
}
// Tests for the 64-bit stable SipHash wrapper.
TEST(SipHashTest, StableSipHash) {
EXPECT_EQ(0xB2BB69BB0A2AC0F1UL, getStableSipHash(""));
EXPECT_EQ(0x9304ABFF427B72E8UL, getStableSipHash("strlen"));
EXPECT_EQ(0x55F45179A08AE51BUL, getStableSipHash("_ZN1 ind; f"));
}
// Tests for the ptrauth-specific SipHash wrapper.
TEST(SipHashTest, PointerAuthSipHash) {
// Test some basic cases.