blake2b_generic.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // Copyright 2016 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package blake2b
  5. import (
  6. "encoding/binary"
  7. "math/bits"
  8. )
  9. // the precomputed values for BLAKE2b
  10. // there are 10 16-byte arrays - one for each round
  11. // the entries are calculated from the sigma constants.
  12. var precomputed = [10][16]byte{
  13. {0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15},
  14. {14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3},
  15. {11, 12, 5, 15, 8, 0, 2, 13, 10, 3, 7, 9, 14, 6, 1, 4},
  16. {7, 3, 13, 11, 9, 1, 12, 14, 2, 5, 4, 15, 6, 10, 0, 8},
  17. {9, 5, 2, 10, 0, 7, 4, 15, 14, 11, 6, 3, 1, 12, 8, 13},
  18. {2, 6, 0, 8, 12, 10, 11, 3, 4, 7, 15, 1, 13, 5, 14, 9},
  19. {12, 1, 14, 4, 5, 15, 13, 10, 0, 6, 9, 8, 7, 3, 2, 11},
  20. {13, 7, 12, 3, 11, 14, 1, 9, 5, 15, 8, 2, 0, 4, 6, 10},
  21. {6, 14, 11, 0, 15, 9, 3, 8, 12, 13, 1, 10, 2, 7, 4, 5},
  22. {10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0},
  23. }
  24. // nolint:unused,deadcode
  25. func hashBlocksGeneric(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
  26. var m [16]uint64
  27. c0, c1 := c[0], c[1]
  28. for i := 0; i < len(blocks); {
  29. c0 += BlockSize
  30. if c0 < BlockSize {
  31. c1++
  32. }
  33. for j := range m {
  34. m[j] = binary.LittleEndian.Uint64(blocks[i:])
  35. i += 8
  36. }
  37. fGeneric(h, &m, c0, c1, flag, 12)
  38. }
  39. c[0], c[1] = c0, c1
  40. }
  41. func fGeneric(h *[8]uint64, m *[16]uint64, c0, c1 uint64, flag uint64, rounds uint64) {
  42. v0, v1, v2, v3, v4, v5, v6, v7 := h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]
  43. v8, v9, v10, v11, v12, v13, v14, v15 := iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]
  44. v12 ^= c0
  45. v13 ^= c1
  46. v14 ^= flag
  47. for i := 0; i < int(rounds); i++ {
  48. s := &(precomputed[i%10])
  49. v0 += m[s[0]]
  50. v0 += v4
  51. v12 ^= v0
  52. v12 = bits.RotateLeft64(v12, -32)
  53. v8 += v12
  54. v4 ^= v8
  55. v4 = bits.RotateLeft64(v4, -24)
  56. v1 += m[s[1]]
  57. v1 += v5
  58. v13 ^= v1
  59. v13 = bits.RotateLeft64(v13, -32)
  60. v9 += v13
  61. v5 ^= v9
  62. v5 = bits.RotateLeft64(v5, -24)
  63. v2 += m[s[2]]
  64. v2 += v6
  65. v14 ^= v2
  66. v14 = bits.RotateLeft64(v14, -32)
  67. v10 += v14
  68. v6 ^= v10
  69. v6 = bits.RotateLeft64(v6, -24)
  70. v3 += m[s[3]]
  71. v3 += v7
  72. v15 ^= v3
  73. v15 = bits.RotateLeft64(v15, -32)
  74. v11 += v15
  75. v7 ^= v11
  76. v7 = bits.RotateLeft64(v7, -24)
  77. v0 += m[s[4]]
  78. v0 += v4
  79. v12 ^= v0
  80. v12 = bits.RotateLeft64(v12, -16)
  81. v8 += v12
  82. v4 ^= v8
  83. v4 = bits.RotateLeft64(v4, -63)
  84. v1 += m[s[5]]
  85. v1 += v5
  86. v13 ^= v1
  87. v13 = bits.RotateLeft64(v13, -16)
  88. v9 += v13
  89. v5 ^= v9
  90. v5 = bits.RotateLeft64(v5, -63)
  91. v2 += m[s[6]]
  92. v2 += v6
  93. v14 ^= v2
  94. v14 = bits.RotateLeft64(v14, -16)
  95. v10 += v14
  96. v6 ^= v10
  97. v6 = bits.RotateLeft64(v6, -63)
  98. v3 += m[s[7]]
  99. v3 += v7
  100. v15 ^= v3
  101. v15 = bits.RotateLeft64(v15, -16)
  102. v11 += v15
  103. v7 ^= v11
  104. v7 = bits.RotateLeft64(v7, -63)
  105. v0 += m[s[8]]
  106. v0 += v5
  107. v15 ^= v0
  108. v15 = bits.RotateLeft64(v15, -32)
  109. v10 += v15
  110. v5 ^= v10
  111. v5 = bits.RotateLeft64(v5, -24)
  112. v1 += m[s[9]]
  113. v1 += v6
  114. v12 ^= v1
  115. v12 = bits.RotateLeft64(v12, -32)
  116. v11 += v12
  117. v6 ^= v11
  118. v6 = bits.RotateLeft64(v6, -24)
  119. v2 += m[s[10]]
  120. v2 += v7
  121. v13 ^= v2
  122. v13 = bits.RotateLeft64(v13, -32)
  123. v8 += v13
  124. v7 ^= v8
  125. v7 = bits.RotateLeft64(v7, -24)
  126. v3 += m[s[11]]
  127. v3 += v4
  128. v14 ^= v3
  129. v14 = bits.RotateLeft64(v14, -32)
  130. v9 += v14
  131. v4 ^= v9
  132. v4 = bits.RotateLeft64(v4, -24)
  133. v0 += m[s[12]]
  134. v0 += v5
  135. v15 ^= v0
  136. v15 = bits.RotateLeft64(v15, -16)
  137. v10 += v15
  138. v5 ^= v10
  139. v5 = bits.RotateLeft64(v5, -63)
  140. v1 += m[s[13]]
  141. v1 += v6
  142. v12 ^= v1
  143. v12 = bits.RotateLeft64(v12, -16)
  144. v11 += v12
  145. v6 ^= v11
  146. v6 = bits.RotateLeft64(v6, -63)
  147. v2 += m[s[14]]
  148. v2 += v7
  149. v13 ^= v2
  150. v13 = bits.RotateLeft64(v13, -16)
  151. v8 += v13
  152. v7 ^= v8
  153. v7 = bits.RotateLeft64(v7, -63)
  154. v3 += m[s[15]]
  155. v3 += v4
  156. v14 ^= v3
  157. v14 = bits.RotateLeft64(v14, -16)
  158. v9 += v14
  159. v4 ^= v9
  160. v4 = bits.RotateLeft64(v4, -63)
  161. }
  162. h[0] ^= v0 ^ v8
  163. h[1] ^= v1 ^ v9
  164. h[2] ^= v2 ^ v10
  165. h[3] ^= v3 ^ v11
  166. h[4] ^= v4 ^ v12
  167. h[5] ^= v5 ^ v13
  168. h[6] ^= v6 ^ v14
  169. h[7] ^= v7 ^ v15
  170. }