blocks.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. //go:build (!arm && !amd64) || appengine || gccgo
  2. // +build !arm,!amd64 appengine gccgo
  3. package siphash
  4. func once(d *digest) {
  5. blocks(d, d.x[:])
  6. }
  7. func finalize(d *digest) uint64 {
  8. d0 := *d
  9. once(&d0)
  10. v0, v1, v2, v3 := d0.v0, d0.v1, d0.v2, d0.v3
  11. v2 ^= 0xff
  12. // Round 1.
  13. v0 += v1
  14. v1 = v1<<13 | v1>>(64-13)
  15. v1 ^= v0
  16. v0 = v0<<32 | v0>>(64-32)
  17. v2 += v3
  18. v3 = v3<<16 | v3>>(64-16)
  19. v3 ^= v2
  20. v0 += v3
  21. v3 = v3<<21 | v3>>(64-21)
  22. v3 ^= v0
  23. v2 += v1
  24. v1 = v1<<17 | v1>>(64-17)
  25. v1 ^= v2
  26. v2 = v2<<32 | v2>>(64-32)
  27. // Round 2.
  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 3.
  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. // Round 4.
  58. v0 += v1
  59. v1 = v1<<13 | v1>>(64-13)
  60. v1 ^= v0
  61. v0 = v0<<32 | v0>>(64-32)
  62. v2 += v3
  63. v3 = v3<<16 | v3>>(64-16)
  64. v3 ^= v2
  65. v0 += v3
  66. v3 = v3<<21 | v3>>(64-21)
  67. v3 ^= v0
  68. v2 += v1
  69. v1 = v1<<17 | v1>>(64-17)
  70. v1 ^= v2
  71. v2 = v2<<32 | v2>>(64-32)
  72. return v0 ^ v1 ^ v2 ^ v3
  73. }
  74. func blocks(d *digest, p []uint8) {
  75. v0, v1, v2, v3 := d.v0, d.v1, d.v2, d.v3
  76. for len(p) >= BlockSize {
  77. m := uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 |
  78. uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56
  79. v3 ^= m
  80. // Round 1.
  81. v0 += v1
  82. v1 = v1<<13 | v1>>(64-13)
  83. v1 ^= v0
  84. v0 = v0<<32 | v0>>(64-32)
  85. v2 += v3
  86. v3 = v3<<16 | v3>>(64-16)
  87. v3 ^= v2
  88. v0 += v3
  89. v3 = v3<<21 | v3>>(64-21)
  90. v3 ^= v0
  91. v2 += v1
  92. v1 = v1<<17 | v1>>(64-17)
  93. v1 ^= v2
  94. v2 = v2<<32 | v2>>(64-32)
  95. // Round 2.
  96. v0 += v1
  97. v1 = v1<<13 | v1>>(64-13)
  98. v1 ^= v0
  99. v0 = v0<<32 | v0>>(64-32)
  100. v2 += v3
  101. v3 = v3<<16 | v3>>(64-16)
  102. v3 ^= v2
  103. v0 += v3
  104. v3 = v3<<21 | v3>>(64-21)
  105. v3 ^= v0
  106. v2 += v1
  107. v1 = v1<<17 | v1>>(64-17)
  108. v1 ^= v2
  109. v2 = v2<<32 | v2>>(64-32)
  110. v0 ^= m
  111. p = p[BlockSize:]
  112. }
  113. d.v0, d.v1, d.v2, d.v3 = v0, v1, v2, v3
  114. }