Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 

200 wiersze
4.7 KiB

  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 ChaCha20 implements the core ChaCha20 function as specified in https://tools.ietf.org/html/rfc7539#section-2.3.
  5. package chacha20
  6. import "encoding/binary"
  7. const rounds = 20
  8. // core applies the ChaCha20 core function to 16-byte input in, 32-byte key k,
  9. // and 16-byte constant c, and puts the result into 64-byte array out.
  10. func core(out *[64]byte, in *[16]byte, k *[32]byte) {
  11. j0 := uint32(0x61707865)
  12. j1 := uint32(0x3320646e)
  13. j2 := uint32(0x79622d32)
  14. j3 := uint32(0x6b206574)
  15. j4 := binary.LittleEndian.Uint32(k[0:4])
  16. j5 := binary.LittleEndian.Uint32(k[4:8])
  17. j6 := binary.LittleEndian.Uint32(k[8:12])
  18. j7 := binary.LittleEndian.Uint32(k[12:16])
  19. j8 := binary.LittleEndian.Uint32(k[16:20])
  20. j9 := binary.LittleEndian.Uint32(k[20:24])
  21. j10 := binary.LittleEndian.Uint32(k[24:28])
  22. j11 := binary.LittleEndian.Uint32(k[28:32])
  23. j12 := binary.LittleEndian.Uint32(in[0:4])
  24. j13 := binary.LittleEndian.Uint32(in[4:8])
  25. j14 := binary.LittleEndian.Uint32(in[8:12])
  26. j15 := binary.LittleEndian.Uint32(in[12:16])
  27. x0, x1, x2, x3, x4, x5, x6, x7 := j0, j1, j2, j3, j4, j5, j6, j7
  28. x8, x9, x10, x11, x12, x13, x14, x15 := j8, j9, j10, j11, j12, j13, j14, j15
  29. for i := 0; i < rounds; i += 2 {
  30. x0 += x4
  31. x12 ^= x0
  32. x12 = (x12 << 16) | (x12 >> (16))
  33. x8 += x12
  34. x4 ^= x8
  35. x4 = (x4 << 12) | (x4 >> (20))
  36. x0 += x4
  37. x12 ^= x0
  38. x12 = (x12 << 8) | (x12 >> (24))
  39. x8 += x12
  40. x4 ^= x8
  41. x4 = (x4 << 7) | (x4 >> (25))
  42. x1 += x5
  43. x13 ^= x1
  44. x13 = (x13 << 16) | (x13 >> 16)
  45. x9 += x13
  46. x5 ^= x9
  47. x5 = (x5 << 12) | (x5 >> 20)
  48. x1 += x5
  49. x13 ^= x1
  50. x13 = (x13 << 8) | (x13 >> 24)
  51. x9 += x13
  52. x5 ^= x9
  53. x5 = (x5 << 7) | (x5 >> 25)
  54. x2 += x6
  55. x14 ^= x2
  56. x14 = (x14 << 16) | (x14 >> 16)
  57. x10 += x14
  58. x6 ^= x10
  59. x6 = (x6 << 12) | (x6 >> 20)
  60. x2 += x6
  61. x14 ^= x2
  62. x14 = (x14 << 8) | (x14 >> 24)
  63. x10 += x14
  64. x6 ^= x10
  65. x6 = (x6 << 7) | (x6 >> 25)
  66. x3 += x7
  67. x15 ^= x3
  68. x15 = (x15 << 16) | (x15 >> 16)
  69. x11 += x15
  70. x7 ^= x11
  71. x7 = (x7 << 12) | (x7 >> 20)
  72. x3 += x7
  73. x15 ^= x3
  74. x15 = (x15 << 8) | (x15 >> 24)
  75. x11 += x15
  76. x7 ^= x11
  77. x7 = (x7 << 7) | (x7 >> 25)
  78. x0 += x5
  79. x15 ^= x0
  80. x15 = (x15 << 16) | (x15 >> 16)
  81. x10 += x15
  82. x5 ^= x10
  83. x5 = (x5 << 12) | (x5 >> 20)
  84. x0 += x5
  85. x15 ^= x0
  86. x15 = (x15 << 8) | (x15 >> 24)
  87. x10 += x15
  88. x5 ^= x10
  89. x5 = (x5 << 7) | (x5 >> 25)
  90. x1 += x6
  91. x12 ^= x1
  92. x12 = (x12 << 16) | (x12 >> 16)
  93. x11 += x12
  94. x6 ^= x11
  95. x6 = (x6 << 12) | (x6 >> 20)
  96. x1 += x6
  97. x12 ^= x1
  98. x12 = (x12 << 8) | (x12 >> 24)
  99. x11 += x12
  100. x6 ^= x11
  101. x6 = (x6 << 7) | (x6 >> 25)
  102. x2 += x7
  103. x13 ^= x2
  104. x13 = (x13 << 16) | (x13 >> 16)
  105. x8 += x13
  106. x7 ^= x8
  107. x7 = (x7 << 12) | (x7 >> 20)
  108. x2 += x7
  109. x13 ^= x2
  110. x13 = (x13 << 8) | (x13 >> 24)
  111. x8 += x13
  112. x7 ^= x8
  113. x7 = (x7 << 7) | (x7 >> 25)
  114. x3 += x4
  115. x14 ^= x3
  116. x14 = (x14 << 16) | (x14 >> 16)
  117. x9 += x14
  118. x4 ^= x9
  119. x4 = (x4 << 12) | (x4 >> 20)
  120. x3 += x4
  121. x14 ^= x3
  122. x14 = (x14 << 8) | (x14 >> 24)
  123. x9 += x14
  124. x4 ^= x9
  125. x4 = (x4 << 7) | (x4 >> 25)
  126. }
  127. x0 += j0
  128. x1 += j1
  129. x2 += j2
  130. x3 += j3
  131. x4 += j4
  132. x5 += j5
  133. x6 += j6
  134. x7 += j7
  135. x8 += j8
  136. x9 += j9
  137. x10 += j10
  138. x11 += j11
  139. x12 += j12
  140. x13 += j13
  141. x14 += j14
  142. x15 += j15
  143. binary.LittleEndian.PutUint32(out[0:4], x0)
  144. binary.LittleEndian.PutUint32(out[4:8], x1)
  145. binary.LittleEndian.PutUint32(out[8:12], x2)
  146. binary.LittleEndian.PutUint32(out[12:16], x3)
  147. binary.LittleEndian.PutUint32(out[16:20], x4)
  148. binary.LittleEndian.PutUint32(out[20:24], x5)
  149. binary.LittleEndian.PutUint32(out[24:28], x6)
  150. binary.LittleEndian.PutUint32(out[28:32], x7)
  151. binary.LittleEndian.PutUint32(out[32:36], x8)
  152. binary.LittleEndian.PutUint32(out[36:40], x9)
  153. binary.LittleEndian.PutUint32(out[40:44], x10)
  154. binary.LittleEndian.PutUint32(out[44:48], x11)
  155. binary.LittleEndian.PutUint32(out[48:52], x12)
  156. binary.LittleEndian.PutUint32(out[52:56], x13)
  157. binary.LittleEndian.PutUint32(out[56:60], x14)
  158. binary.LittleEndian.PutUint32(out[60:64], x15)
  159. }
  160. // XORKeyStream crypts bytes from in to out using the given key and counters.
  161. // In and out may be the same slice but otherwise should not overlap. Counter
  162. // contains the raw ChaCha20 counter bytes (i.e. block counter followed by
  163. // nonce).
  164. func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
  165. var block [64]byte
  166. var counterCopy [16]byte
  167. copy(counterCopy[:], counter[:])
  168. for len(in) >= 64 {
  169. core(&block, &counterCopy, key)
  170. for i, x := range block {
  171. out[i] = in[i] ^ x
  172. }
  173. u := uint32(1)
  174. for i := 0; i < 4; i++ {
  175. u += uint32(counterCopy[i])
  176. counterCopy[i] = byte(u)
  177. u >>= 8
  178. }
  179. in = in[64:]
  180. out = out[64:]
  181. }
  182. if len(in) > 0 {
  183. core(&block, &counterCopy, key)
  184. for i, v := range in {
  185. out[i] = v ^ block[i]
  186. }
  187. }
  188. }