hash128.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. // +build !arm,!amd64 appengine gccgo
  2. // Written in 2012 by Dmitry Chestnykh.
  3. // Modifications 2014 for 128-bit hash function by Damian Gryski.
  4. //
  5. // To the extent possible under law, the authors have dedicated all copyright
  6. // and related and neighboring rights to this software to the public domain
  7. // worldwide. This software is distributed without any warranty.
  8. // http://creativecommons.org/publicdomain/zero/1.0/
  9. package siphash
  10. // Hash returns the 128-bit SipHash-2-4 of the given byte slice with two 64-bit
  11. // parts of 128-bit key: k0 and k1.
  12. //
  13. // Note that 128-bit SipHash is considered experimental by SipHash authors at this time.
  14. func Hash128(k0, k1 uint64, p []byte) (uint64, uint64) {
  15. // Initialization.
  16. v0 := k0 ^ 0x736f6d6570736575
  17. v1 := k1 ^ 0x646f72616e646f6d
  18. v2 := k0 ^ 0x6c7967656e657261
  19. v3 := k1 ^ 0x7465646279746573
  20. t := uint64(len(p)) << 56
  21. v1 ^= 0xee
  22. // Compression.
  23. for len(p) >= BlockSize {
  24. m := uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 |
  25. uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56
  26. v3 ^= m
  27. // Round 1.
  28. v0 += v1
  29. v1 = v1<<13 | v1>>(64-13)
  30. v1 ^= v0
  31. v0 = v0<<32 | v0>>(64-32)
  32. v2 += v3
  33. v3 = v3<<16 | v3>>(64-16)
  34. v3 ^= v2
  35. v0 += v3
  36. v3 = v3<<21 | v3>>(64-21)
  37. v3 ^= v0
  38. v2 += v1
  39. v1 = v1<<17 | v1>>(64-17)
  40. v1 ^= v2
  41. v2 = v2<<32 | v2>>(64-32)
  42. // Round 2.
  43. v0 += v1
  44. v1 = v1<<13 | v1>>(64-13)
  45. v1 ^= v0
  46. v0 = v0<<32 | v0>>(64-32)
  47. v2 += v3
  48. v3 = v3<<16 | v3>>(64-16)
  49. v3 ^= v2
  50. v0 += v3
  51. v3 = v3<<21 | v3>>(64-21)
  52. v3 ^= v0
  53. v2 += v1
  54. v1 = v1<<17 | v1>>(64-17)
  55. v1 ^= v2
  56. v2 = v2<<32 | v2>>(64-32)
  57. v0 ^= m
  58. p = p[BlockSize:]
  59. }
  60. // Compress last block.
  61. switch len(p) {
  62. case 7:
  63. t |= uint64(p[6]) << 48
  64. fallthrough
  65. case 6:
  66. t |= uint64(p[5]) << 40
  67. fallthrough
  68. case 5:
  69. t |= uint64(p[4]) << 32
  70. fallthrough
  71. case 4:
  72. t |= uint64(p[3]) << 24
  73. fallthrough
  74. case 3:
  75. t |= uint64(p[2]) << 16
  76. fallthrough
  77. case 2:
  78. t |= uint64(p[1]) << 8
  79. fallthrough
  80. case 1:
  81. t |= uint64(p[0])
  82. }
  83. v3 ^= t
  84. // Round 1.
  85. v0 += v1
  86. v1 = v1<<13 | v1>>(64-13)
  87. v1 ^= v0
  88. v0 = v0<<32 | v0>>(64-32)
  89. v2 += v3
  90. v3 = v3<<16 | v3>>(64-16)
  91. v3 ^= v2
  92. v0 += v3
  93. v3 = v3<<21 | v3>>(64-21)
  94. v3 ^= v0
  95. v2 += v1
  96. v1 = v1<<17 | v1>>(64-17)
  97. v1 ^= v2
  98. v2 = v2<<32 | v2>>(64-32)
  99. // Round 2.
  100. v0 += v1
  101. v1 = v1<<13 | v1>>(64-13)
  102. v1 ^= v0
  103. v0 = v0<<32 | v0>>(64-32)
  104. v2 += v3
  105. v3 = v3<<16 | v3>>(64-16)
  106. v3 ^= v2
  107. v0 += v3
  108. v3 = v3<<21 | v3>>(64-21)
  109. v3 ^= v0
  110. v2 += v1
  111. v1 = v1<<17 | v1>>(64-17)
  112. v1 ^= v2
  113. v2 = v2<<32 | v2>>(64-32)
  114. v0 ^= t
  115. // Finalization.
  116. v2 ^= 0xee
  117. // Round 1.
  118. v0 += v1
  119. v1 = v1<<13 | v1>>(64-13)
  120. v1 ^= v0
  121. v0 = v0<<32 | v0>>(64-32)
  122. v2 += v3
  123. v3 = v3<<16 | v3>>(64-16)
  124. v3 ^= v2
  125. v0 += v3
  126. v3 = v3<<21 | v3>>(64-21)
  127. v3 ^= v0
  128. v2 += v1
  129. v1 = v1<<17 | v1>>(64-17)
  130. v1 ^= v2
  131. v2 = v2<<32 | v2>>(64-32)
  132. // Round 2.
  133. v0 += v1
  134. v1 = v1<<13 | v1>>(64-13)
  135. v1 ^= v0
  136. v0 = v0<<32 | v0>>(64-32)
  137. v2 += v3
  138. v3 = v3<<16 | v3>>(64-16)
  139. v3 ^= v2
  140. v0 += v3
  141. v3 = v3<<21 | v3>>(64-21)
  142. v3 ^= v0
  143. v2 += v1
  144. v1 = v1<<17 | v1>>(64-17)
  145. v1 ^= v2
  146. v2 = v2<<32 | v2>>(64-32)
  147. // Round 3.
  148. v0 += v1
  149. v1 = v1<<13 | v1>>(64-13)
  150. v1 ^= v0
  151. v0 = v0<<32 | v0>>(64-32)
  152. v2 += v3
  153. v3 = v3<<16 | v3>>(64-16)
  154. v3 ^= v2
  155. v0 += v3
  156. v3 = v3<<21 | v3>>(64-21)
  157. v3 ^= v0
  158. v2 += v1
  159. v1 = v1<<17 | v1>>(64-17)
  160. v1 ^= v2
  161. v2 = v2<<32 | v2>>(64-32)
  162. // Round 4.
  163. v0 += v1
  164. v1 = v1<<13 | v1>>(64-13)
  165. v1 ^= v0
  166. v0 = v0<<32 | v0>>(64-32)
  167. v2 += v3
  168. v3 = v3<<16 | v3>>(64-16)
  169. v3 ^= v2
  170. v0 += v3
  171. v3 = v3<<21 | v3>>(64-21)
  172. v3 ^= v0
  173. v2 += v1
  174. v1 = v1<<17 | v1>>(64-17)
  175. v1 ^= v2
  176. v2 = v2<<32 | v2>>(64-32)
  177. r0 := v0 ^ v1 ^ v2 ^ v3
  178. v1 ^= 0xdd
  179. // Round 1.
  180. v0 += v1
  181. v1 = v1<<13 | v1>>(64-13)
  182. v1 ^= v0
  183. v0 = v0<<32 | v0>>(64-32)
  184. v2 += v3
  185. v3 = v3<<16 | v3>>(64-16)
  186. v3 ^= v2
  187. v0 += v3
  188. v3 = v3<<21 | v3>>(64-21)
  189. v3 ^= v0
  190. v2 += v1
  191. v1 = v1<<17 | v1>>(64-17)
  192. v1 ^= v2
  193. v2 = v2<<32 | v2>>(64-32)
  194. // Round 2.
  195. v0 += v1
  196. v1 = v1<<13 | v1>>(64-13)
  197. v1 ^= v0
  198. v0 = v0<<32 | v0>>(64-32)
  199. v2 += v3
  200. v3 = v3<<16 | v3>>(64-16)
  201. v3 ^= v2
  202. v0 += v3
  203. v3 = v3<<21 | v3>>(64-21)
  204. v3 ^= v0
  205. v2 += v1
  206. v1 = v1<<17 | v1>>(64-17)
  207. v1 ^= v2
  208. v2 = v2<<32 | v2>>(64-32)
  209. // Round 3.
  210. v0 += v1
  211. v1 = v1<<13 | v1>>(64-13)
  212. v1 ^= v0
  213. v0 = v0<<32 | v0>>(64-32)
  214. v2 += v3
  215. v3 = v3<<16 | v3>>(64-16)
  216. v3 ^= v2
  217. v0 += v3
  218. v3 = v3<<21 | v3>>(64-21)
  219. v3 ^= v0
  220. v2 += v1
  221. v1 = v1<<17 | v1>>(64-17)
  222. v1 ^= v2
  223. v2 = v2<<32 | v2>>(64-32)
  224. // Round 4.
  225. v0 += v1
  226. v1 = v1<<13 | v1>>(64-13)
  227. v1 ^= v0
  228. v0 = v0<<32 | v0>>(64-32)
  229. v2 += v3
  230. v3 = v3<<16 | v3>>(64-16)
  231. v3 ^= v2
  232. v0 += v3
  233. v3 = v3<<21 | v3>>(64-21)
  234. v3 ^= v0
  235. v2 += v1
  236. v1 = v1<<17 | v1>>(64-17)
  237. v1 ^= v2
  238. v2 = v2<<32 | v2>>(64-32)
  239. r1 := v0 ^ v1 ^ v2 ^ v3
  240. return r0, r1
  241. }