blocks.go 2.1 KB

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