1 //===--- SipHash.h - An ABI-stable string SipHash ---------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // An implementation of SipHash, a hash function optimized for speed on 10 // short inputs. Based on the SipHash reference implementation. 11 // 12 // Also provides one specific wrapper on top of SipHash-2-4-64 to compute 13 // compute ABI-stable ptrauth discriminators. 14 // 15 //===----------------------------------------------------------------------===// 16 17 #ifndef LLVM_SUPPORT_SIPHASH_H 18 #define LLVM_SUPPORT_SIPHASH_H 19 20 #include <cstdint> 21 22 namespace llvm { 23 24 template <typename T> class ArrayRef; 25 class StringRef; 26 27 /// Computes a SipHash-2-4 64-bit result. 28 void getSipHash_2_4_64(ArrayRef<uint8_t> In, const uint8_t (&K)[16], 29 uint8_t (&Out)[8]); 30 31 /// Computes a SipHash-2-4 128-bit result. 32 void getSipHash_2_4_128(ArrayRef<uint8_t> In, const uint8_t (&K)[16], 33 uint8_t (&Out)[16]); 34 35 /// Compute a stable non-zero 16-bit hash of the given string. 36 /// 37 /// The exact algorithm is the little-endian interpretation of the 38 /// non-doubled (i.e. 64-bit) result of applying a SipHash-2-4 using 39 /// a specific seed value which can be found in the source. 40 /// This 64-bit result is truncated to a non-zero 16-bit value. 41 /// 42 /// We use a 16-bit discriminator because ARM64 can efficiently load 43 /// a 16-bit immediate into the high bits of a register without disturbing 44 /// the remainder of the value, which serves as a nice blend operation. 45 /// 16 bits is also sufficiently compact to not inflate a loader relocation. 46 /// We disallow zero to guarantee a different discriminator from the places 47 /// in the ABI that use a constant zero. 48 uint16_t getPointerAuthStableSipHash(StringRef S); 49 50 } // end namespace llvm 51 52 #endif 53