halfsiphash.c 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #include "siphash.h"
  2. #include "siphash_impl.h"
  3. #ifndef U8TO64
  4. #define U8TO64
  5. static uint64_t INLINE
  6. U8TO64_LE(const unsigned char *p) {
  7. return *(const uint64_t *)p;
  8. }
  9. #endif
  10. #define TRACE
  11. #define cROUNDS 2
  12. #define dROUNDS 4
  13. #define ROTL(x, b) (uint32_t)(((x) << (b)) | ((x) >> (32 - (b))))
  14. #define U8TO32_LE(p) \
  15. (((uint32_t)((p)[0])) | ((uint32_t)((p)[1]) << 8) | \
  16. ((uint32_t)((p)[2]) << 16) | ((uint32_t)((p)[3]) << 24))
  17. #define SIPROUND \
  18. do { \
  19. v0 += v1; \
  20. v1 = ROTL(v1, 5); \
  21. v1 ^= v0; \
  22. v0 = ROTL(v0, 16); \
  23. v2 += v3; \
  24. v3 = ROTL(v3, 8); \
  25. v3 ^= v2; \
  26. v0 += v3; \
  27. v3 = ROTL(v3, 7); \
  28. v3 ^= v0; \
  29. v2 += v1; \
  30. v1 = ROTL(v1, 13); \
  31. v1 ^= v2; \
  32. v2 = ROTL(v2, 16); \
  33. } while (0)
  34. /* the faster half 32bit variant for the linux kernel */
  35. uint32_t
  36. halfsiphash(const unsigned char key[16], const unsigned char *m, size_t len) {
  37. uint32_t v0 = 0;
  38. uint32_t v1 = 0;
  39. uint32_t v2 = 0x6c796765;
  40. uint32_t v3 = 0x74656462;
  41. uint32_t k0 = U8TO32_LE(key);
  42. uint32_t k1 = U8TO32_LE(key + 8);
  43. uint32_t mi;
  44. int i;
  45. const uint8_t *end = m + len - (len % sizeof(uint32_t));
  46. const int left = len & 3;
  47. uint32_t b = ((uint32_t)len) << 24;
  48. v3 ^= k1;
  49. v2 ^= k0;
  50. v1 ^= k1;
  51. v0 ^= k0;
  52. for (; m != end; m += 4) {
  53. mi = U8TO32_LE(m);
  54. v3 ^= mi;
  55. SIPROUND;
  56. SIPROUND;
  57. v0 ^= mi;
  58. }
  59. switch (left) {
  60. case 3:
  61. b |= ((uint32_t)m[2]) << 16;
  62. case 2:
  63. b |= ((uint32_t)m[1]) << 8;
  64. case 1:
  65. b |= ((uint32_t)m[0]);
  66. break;
  67. case 0:
  68. break;
  69. }
  70. v3 ^= b;
  71. SIPROUND;
  72. SIPROUND;
  73. v0 ^= b;
  74. v2 ^= 0xff;
  75. SIPROUND;
  76. SIPROUND;
  77. SIPROUND;
  78. SIPROUND;
  79. return v1 ^ v3;
  80. }