blake2b_generic.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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. func hashBlocksGeneric(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
  25. var m [16]uint64
  26. c0, c1 := c[0], c[1]
  27. for i := 0; i < len(blocks); {
  28. c0 += BlockSize
  29. if c0 < BlockSize {
  30. c1++
  31. }
  32. for j := range m {
  33. m[j] = binary.LittleEndian.Uint64(blocks[i:])
  34. i += 8
  35. }
  36. fGeneric(h, &m, c0, c1, flag, 12)
  37. }
  38. c[0], c[1] = c0, c1
  39. }
  40. func fGeneric(h *[8]uint64, m *[16]uint64, c0, c1 uint64, flag uint64, rounds uint64) {
  41. v0, v1, v2, v3, v4, v5, v6, v7 := h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]
  42. v8, v9, v10, v11, v12, v13, v14, v15 := iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]
  43. v12 ^= c0
  44. v13 ^= c1
  45. v14 ^= flag
  46. for i := 0; i < int(rounds); i++ {
  47. s := &(precomputed[i%10])
  48. v0 += m[s[0]]
  49. v0 += v4
  50. v12 ^= v0
  51. v12 = bits.RotateLeft64(v12, -32)
  52. v8 += v12
  53. v4 ^= v8
  54. v4 = bits.RotateLeft64(v4, -24)
  55. v1 += m[s[1]]
  56. v1 += v5
  57. v13 ^= v1
  58. v13 = bits.RotateLeft64(v13, -32)
  59. v9 += v13
  60. v5 ^= v9
  61. v5 = bits.RotateLeft64(v5, -24)
  62. v2 += m[s[2]]
  63. v2 += v6
  64. v14 ^= v2
  65. v14 = bits.RotateLeft64(v14, -32)
  66. v10 += v14
  67. v6 ^= v10
  68. v6 = bits.RotateLeft64(v6, -24)
  69. v3 += m[s[3]]
  70. v3 += v7
  71. v15 ^= v3
  72. v15 = bits.RotateLeft64(v15, -32)
  73. v11 += v15
  74. v7 ^= v11
  75. v7 = bits.RotateLeft64(v7, -24)
  76. v0 += m[s[4]]
  77. v0 += v4
  78. v12 ^= v0
  79. v12 = bits.RotateLeft64(v12, -16)
  80. v8 += v12
  81. v4 ^= v8
  82. v4 = bits.RotateLeft64(v4, -63)
  83. v1 += m[s[5]]
  84. v1 += v5
  85. v13 ^= v1
  86. v13 = bits.RotateLeft64(v13, -16)
  87. v9 += v13
  88. v5 ^= v9
  89. v5 = bits.RotateLeft64(v5, -63)
  90. v2 += m[s[6]]
  91. v2 += v6
  92. v14 ^= v2
  93. v14 = bits.RotateLeft64(v14, -16)
  94. v10 += v14
  95. v6 ^= v10
  96. v6 = bits.RotateLeft64(v6, -63)
  97. v3 += m[s[7]]
  98. v3 += v7
  99. v15 ^= v3
  100. v15 = bits.RotateLeft64(v15, -16)
  101. v11 += v15
  102. v7 ^= v11
  103. v7 = bits.RotateLeft64(v7, -63)
  104. v0 += m[s[8]]
  105. v0 += v5
  106. v15 ^= v0
  107. v15 = bits.RotateLeft64(v15, -32)
  108. v10 += v15
  109. v5 ^= v10
  110. v5 = bits.RotateLeft64(v5, -24)
  111. v1 += m[s[9]]
  112. v1 += v6
  113. v12 ^= v1
  114. v12 = bits.RotateLeft64(v12, -32)
  115. v11 += v12
  116. v6 ^= v11
  117. v6 = bits.RotateLeft64(v6, -24)
  118. v2 += m[s[10]]
  119. v2 += v7
  120. v13 ^= v2
  121. v13 = bits.RotateLeft64(v13, -32)
  122. v8 += v13
  123. v7 ^= v8
  124. v7 = bits.RotateLeft64(v7, -24)
  125. v3 += m[s[11]]
  126. v3 += v4
  127. v14 ^= v3
  128. v14 = bits.RotateLeft64(v14, -32)
  129. v9 += v14
  130. v4 ^= v9
  131. v4 = bits.RotateLeft64(v4, -24)
  132. v0 += m[s[12]]
  133. v0 += v5
  134. v15 ^= v0
  135. v15 = bits.RotateLeft64(v15, -16)
  136. v10 += v15
  137. v5 ^= v10
  138. v5 = bits.RotateLeft64(v5, -63)
  139. v1 += m[s[13]]
  140. v1 += v6
  141. v12 ^= v1
  142. v12 = bits.RotateLeft64(v12, -16)
  143. v11 += v12
  144. v6 ^= v11
  145. v6 = bits.RotateLeft64(v6, -63)
  146. v2 += m[s[14]]
  147. v2 += v7
  148. v13 ^= v2
  149. v13 = bits.RotateLeft64(v13, -16)
  150. v8 += v13
  151. v7 ^= v8
  152. v7 = bits.RotateLeft64(v7, -63)
  153. v3 += m[s[15]]
  154. v3 += v4
  155. v14 ^= v3
  156. v14 = bits.RotateLeft64(v14, -16)
  157. v9 += v14
  158. v4 ^= v9
  159. v4 = bits.RotateLeft64(v4, -63)
  160. }
  161. h[0] ^= v0 ^ v8
  162. h[1] ^= v1 ^ v9
  163. h[2] ^= v2 ^ v10
  164. h[3] ^= v3 ^ v11
  165. h[4] ^= v4 ^ v12
  166. h[5] ^= v5 ^ v13
  167. h[6] ^= v6 ^ v14
  168. h[7] ^= v7 ^ v15
  169. }