siphash.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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. /*
  11. static void INLINE
  12. U64TO8_LE(unsigned char *p, const uint64_t v) {
  13. *(uint64_t *)p = v;
  14. }
  15. */
  16. #define sipcompress() \
  17. v0 += v1; v2 += v3; \
  18. v1 = ROTL64(v1,13); v3 = ROTL64(v3,16); \
  19. v1 ^= v0; v3 ^= v2; \
  20. v0 = ROTL64(v0,32); \
  21. v2 += v1; v0 += v3; \
  22. v1 = ROTL64(v1,17); v3 = ROTL64(v3,21); \
  23. v1 ^= v2; v3 ^= v0; \
  24. v2 = ROTL64(v2,32);
  25. /* The 64bit 2-4 variant */
  26. uint64_t
  27. siphash(const unsigned char key[16], const unsigned char *m, size_t len) {
  28. uint64_t v0, v1, v2, v3;
  29. uint64_t mi, k0, k1;
  30. uint64_t last7;
  31. size_t i, blocks;
  32. k0 = U8TO64_LE(key + 0);
  33. k1 = U8TO64_LE(key + 8);
  34. v0 = k0 ^ 0x736f6d6570736575ull;
  35. v1 = k1 ^ 0x646f72616e646f6dull;
  36. v2 = k0 ^ 0x6c7967656e657261ull;
  37. v3 = k1 ^ 0x7465646279746573ull;
  38. last7 = (uint64_t)(len & 0xff) << 56;
  39. for (i = 0, blocks = (len & ~7); i < blocks; i += 8) {
  40. mi = U8TO64_LE(m + i);
  41. v3 ^= mi;
  42. sipcompress() /* 2 c rounds */
  43. sipcompress()
  44. v0 ^= mi;
  45. }
  46. switch (len - blocks) {
  47. case 7: last7 |= (uint64_t)m[i + 6] << 48;
  48. case 6: last7 |= (uint64_t)m[i + 5] << 40;
  49. case 5: last7 |= (uint64_t)m[i + 4] << 32;
  50. case 4: last7 |= (uint64_t)m[i + 3] << 24;
  51. case 3: last7 |= (uint64_t)m[i + 2] << 16;
  52. case 2: last7 |= (uint64_t)m[i + 1] << 8;
  53. case 1: last7 |= (uint64_t)m[i + 0] ;
  54. case 0:
  55. default:;
  56. };
  57. v3 ^= last7;
  58. sipcompress() /* 2 more c rounds */
  59. sipcompress()
  60. v0 ^= last7;
  61. v2 ^= 0xff;
  62. sipcompress() /* and 4 final d rounds */
  63. sipcompress()
  64. sipcompress()
  65. sipcompress()
  66. return v0 ^ v1 ^ v2 ^ v3;
  67. #undef sipcompress
  68. }
  69. /* The 64bit 1-3 variant */
  70. uint64_t
  71. siphash13(const unsigned char key[16], const unsigned char *m, size_t len) {
  72. uint64_t v0, v1, v2, v3;
  73. uint64_t mi, k0, k1;
  74. uint64_t last7;
  75. size_t i, blocks;
  76. k0 = U8TO64_LE(key + 0);
  77. k1 = U8TO64_LE(key + 8);
  78. v0 = k0 ^ 0x736f6d6570736575ull;
  79. v1 = k1 ^ 0x646f72616e646f6dull;
  80. v2 = k0 ^ 0x6c7967656e657261ull;
  81. v3 = k1 ^ 0x7465646279746573ull;
  82. last7 = (uint64_t)(len & 0xff) << 56;
  83. for (i = 0, blocks = (len & ~7); i < blocks; i += 8) {
  84. mi = U8TO64_LE(m + i);
  85. v3 ^= mi;
  86. sipcompress() /* 1 c round */
  87. v0 ^= mi;
  88. }
  89. switch (len - blocks) {
  90. case 7: last7 |= (uint64_t)m[i + 6] << 48;
  91. case 6: last7 |= (uint64_t)m[i + 5] << 40;
  92. case 5: last7 |= (uint64_t)m[i + 4] << 32;
  93. case 4: last7 |= (uint64_t)m[i + 3] << 24;
  94. case 3: last7 |= (uint64_t)m[i + 2] << 16;
  95. case 2: last7 |= (uint64_t)m[i + 1] << 8;
  96. case 1: last7 |= (uint64_t)m[i + 0] ;
  97. case 0:
  98. default:;
  99. };
  100. v3 ^= last7;
  101. sipcompress() /* 1 more c round */
  102. v0 ^= last7;
  103. v2 ^= 0xff;
  104. sipcompress() /* and 3 final d rounds */
  105. sipcompress()
  106. sipcompress()
  107. return v0 ^ v1 ^ v2 ^ v3;
  108. #undef sipcompress
  109. }
  110. #include "halfsiphash.c"