siphash.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
  2. /* Copyright (C) 2016-2022 Jason A. Donenfeld <[email protected]>. All Rights Reserved.
  3. *
  4. * SipHash: a fast short-input PRF
  5. * https://131002.net/siphash/
  6. *
  7. * This implementation is specifically for SipHash2-4 for a secure PRF
  8. * and HalfSipHash1-3/SipHash1-3 for an insecure PRF only suitable for
  9. * hashtables.
  10. */
  11. #ifndef _LINUX_SIPHASH_H
  12. #define _LINUX_SIPHASH_H
  13. #include <linux/types.h>
  14. #include <linux/kernel.h>
  15. #define SIPHASH_ALIGNMENT __alignof__(u64)
  16. typedef struct {
  17. u64 key[2];
  18. } siphash_key_t;
  19. #define siphash_aligned_key_t siphash_key_t __aligned(16)
  20. static inline bool siphash_key_is_zero(const siphash_key_t *key)
  21. {
  22. return !(key->key[0] | key->key[1]);
  23. }
  24. u64 __siphash_aligned(const void *data, size_t len, const siphash_key_t *key);
  25. u64 __siphash_unaligned(const void *data, size_t len, const siphash_key_t *key);
  26. u64 siphash_1u64(const u64 a, const siphash_key_t *key);
  27. u64 siphash_2u64(const u64 a, const u64 b, const siphash_key_t *key);
  28. u64 siphash_3u64(const u64 a, const u64 b, const u64 c,
  29. const siphash_key_t *key);
  30. u64 siphash_4u64(const u64 a, const u64 b, const u64 c, const u64 d,
  31. const siphash_key_t *key);
  32. u64 siphash_1u32(const u32 a, const siphash_key_t *key);
  33. u64 siphash_3u32(const u32 a, const u32 b, const u32 c,
  34. const siphash_key_t *key);
  35. static inline u64 siphash_2u32(const u32 a, const u32 b,
  36. const siphash_key_t *key)
  37. {
  38. return siphash_1u64((u64)b << 32 | a, key);
  39. }
  40. static inline u64 siphash_4u32(const u32 a, const u32 b, const u32 c,
  41. const u32 d, const siphash_key_t *key)
  42. {
  43. return siphash_2u64((u64)b << 32 | a, (u64)d << 32 | c, key);
  44. }
  45. static inline u64 ___siphash_aligned(const __le64 *data, size_t len,
  46. const siphash_key_t *key)
  47. {
  48. if (__builtin_constant_p(len) && len == 4)
  49. return siphash_1u32(le32_to_cpup((const __le32 *)data), key);
  50. if (__builtin_constant_p(len) && len == 8)
  51. return siphash_1u64(le64_to_cpu(data[0]), key);
  52. if (__builtin_constant_p(len) && len == 16)
  53. return siphash_2u64(le64_to_cpu(data[0]), le64_to_cpu(data[1]),
  54. key);
  55. if (__builtin_constant_p(len) && len == 24)
  56. return siphash_3u64(le64_to_cpu(data[0]), le64_to_cpu(data[1]),
  57. le64_to_cpu(data[2]), key);
  58. if (__builtin_constant_p(len) && len == 32)
  59. return siphash_4u64(le64_to_cpu(data[0]), le64_to_cpu(data[1]),
  60. le64_to_cpu(data[2]), le64_to_cpu(data[3]),
  61. key);
  62. return __siphash_aligned(data, len, key);
  63. }
  64. /**
  65. * siphash - compute 64-bit siphash PRF value
  66. * @data: buffer to hash
  67. * @size: size of @data
  68. * @key: the siphash key
  69. */
  70. static inline u64 siphash(const void *data, size_t len,
  71. const siphash_key_t *key)
  72. {
  73. if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) ||
  74. !IS_ALIGNED((unsigned long)data, SIPHASH_ALIGNMENT))
  75. return __siphash_unaligned(data, len, key);
  76. return ___siphash_aligned(data, len, key);
  77. }
  78. #define HSIPHASH_ALIGNMENT __alignof__(unsigned long)
  79. typedef struct {
  80. unsigned long key[2];
  81. } hsiphash_key_t;
  82. u32 __hsiphash_aligned(const void *data, size_t len,
  83. const hsiphash_key_t *key);
  84. u32 __hsiphash_unaligned(const void *data, size_t len,
  85. const hsiphash_key_t *key);
  86. u32 hsiphash_1u32(const u32 a, const hsiphash_key_t *key);
  87. u32 hsiphash_2u32(const u32 a, const u32 b, const hsiphash_key_t *key);
  88. u32 hsiphash_3u32(const u32 a, const u32 b, const u32 c,
  89. const hsiphash_key_t *key);
  90. u32 hsiphash_4u32(const u32 a, const u32 b, const u32 c, const u32 d,
  91. const hsiphash_key_t *key);
  92. static inline u32 ___hsiphash_aligned(const __le32 *data, size_t len,
  93. const hsiphash_key_t *key)
  94. {
  95. if (__builtin_constant_p(len) && len == 4)
  96. return hsiphash_1u32(le32_to_cpu(data[0]), key);
  97. if (__builtin_constant_p(len) && len == 8)
  98. return hsiphash_2u32(le32_to_cpu(data[0]), le32_to_cpu(data[1]),
  99. key);
  100. if (__builtin_constant_p(len) && len == 12)
  101. return hsiphash_3u32(le32_to_cpu(data[0]), le32_to_cpu(data[1]),
  102. le32_to_cpu(data[2]), key);
  103. if (__builtin_constant_p(len) && len == 16)
  104. return hsiphash_4u32(le32_to_cpu(data[0]), le32_to_cpu(data[1]),
  105. le32_to_cpu(data[2]), le32_to_cpu(data[3]),
  106. key);
  107. return __hsiphash_aligned(data, len, key);
  108. }
  109. /**
  110. * hsiphash - compute 32-bit hsiphash PRF value
  111. * @data: buffer to hash
  112. * @size: size of @data
  113. * @key: the hsiphash key
  114. */
  115. static inline u32 hsiphash(const void *data, size_t len,
  116. const hsiphash_key_t *key)
  117. {
  118. if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) ||
  119. !IS_ALIGNED((unsigned long)data, HSIPHASH_ALIGNMENT))
  120. return __hsiphash_unaligned(data, len, key);
  121. return ___hsiphash_aligned(data, len, key);
  122. }
  123. /*
  124. * These macros expose the raw SipHash and HalfSipHash permutations.
  125. * Do not use them directly! If you think you have a use for them,
  126. * be sure to CC the maintainer of this file explaining why.
  127. */
  128. #define SIPHASH_PERMUTATION(a, b, c, d) ( \
  129. (a) += (b), (b) = rol64((b), 13), (b) ^= (a), (a) = rol64((a), 32), \
  130. (c) += (d), (d) = rol64((d), 16), (d) ^= (c), \
  131. (a) += (d), (d) = rol64((d), 21), (d) ^= (a), \
  132. (c) += (b), (b) = rol64((b), 17), (b) ^= (c), (c) = rol64((c), 32))
  133. #define SIPHASH_CONST_0 0x736f6d6570736575ULL
  134. #define SIPHASH_CONST_1 0x646f72616e646f6dULL
  135. #define SIPHASH_CONST_2 0x6c7967656e657261ULL
  136. #define SIPHASH_CONST_3 0x7465646279746573ULL
  137. #define HSIPHASH_PERMUTATION(a, b, c, d) ( \
  138. (a) += (b), (b) = rol32((b), 5), (b) ^= (a), (a) = rol32((a), 16), \
  139. (c) += (d), (d) = rol32((d), 8), (d) ^= (c), \
  140. (a) += (d), (d) = rol32((d), 7), (d) ^= (a), \
  141. (c) += (b), (b) = rol32((b), 13), (b) ^= (c), (c) = rol32((c), 16))
  142. #define HSIPHASH_CONST_0 0U
  143. #define HSIPHASH_CONST_1 0U
  144. #define HSIPHASH_CONST_2 0x6c796765U
  145. #define HSIPHASH_CONST_3 0x74656462U
  146. #endif /* _LINUX_SIPHASH_H */