hash128.go 4.7 KB

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