You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

451 lines
10 KiB

  1. // Use of this source code is governed by an ISC
  2. // license that can be found in the LICENSE file.
  3. package keccak
  4. import (
  5. "fmt"
  6. "gitlab.com/nitya-sattva/go-x11/hash"
  7. )
  8. // HashSize holds the size of a hash in bytes.
  9. const HashSize = int(64)
  10. // BlockSize holds the size of a block in bytes.
  11. const BlockSize = uintptr(72)
  12. ////////////////
  13. type digest struct {
  14. ptr uintptr
  15. cnt uintptr
  16. h [25]uint64
  17. b [144]byte
  18. }
  19. // New returns a new digest compute a KECCAK512 hash.
  20. func New() hash.Digest {
  21. ref := &digest{}
  22. ref.Reset()
  23. return ref
  24. }
  25. ////////////////
  26. // Reset resets the digest to its initial state.
  27. func (ref *digest) Reset() {
  28. ref.ptr = 0
  29. ref.cnt = 200 - (512 >> 2)
  30. h := ref.h[:]
  31. h[0] = uint64(0x0)
  32. h[1] = uint64(0xFFFFFFFFFFFFFFFF)
  33. h[2] = uint64(0xFFFFFFFFFFFFFFFF)
  34. h[3] = uint64(0x0)
  35. h[4] = uint64(0x0)
  36. h[5] = uint64(0x0)
  37. h[6] = uint64(0x0)
  38. h[7] = uint64(0x0)
  39. h[8] = uint64(0xFFFFFFFFFFFFFFFF)
  40. h[9] = uint64(0x0)
  41. h[10] = uint64(0x0)
  42. h[11] = uint64(0x0)
  43. h[12] = uint64(0xFFFFFFFFFFFFFFFF)
  44. h[13] = uint64(0x0)
  45. h[14] = uint64(0x0)
  46. h[15] = uint64(0x0)
  47. h[16] = uint64(0x0)
  48. h[17] = uint64(0xFFFFFFFFFFFFFFFF)
  49. h[18] = uint64(0x0)
  50. h[19] = uint64(0x0)
  51. h[20] = uint64(0xFFFFFFFFFFFFFFFF)
  52. h[21] = uint64(0x0)
  53. h[22] = uint64(0x0)
  54. h[23] = uint64(0x0)
  55. h[24] = uint64(0x0)
  56. }
  57. // Sum appends the current hash to dst and returns the result
  58. // as a slice. It does not change the underlying hash state.
  59. func (ref *digest) Sum(dst []byte) []byte {
  60. dgt := *ref
  61. hsh := [64]byte{}
  62. dgt.Close(hsh[:], 0, 0)
  63. return append(dst, hsh[:]...)
  64. }
  65. // Write more data to the running hash, never returns an error.
  66. func (ref *digest) Write(src []byte) (int, error) {
  67. sln := uintptr(len(src))
  68. fln := len(src)
  69. ptr := ref.ptr
  70. buf := ref.b[:]
  71. sta := ref.h[:]
  72. if sln < (BlockSize - ptr) {
  73. copy(ref.b[ptr:], src)
  74. ref.ptr += sln
  75. return int(sln), nil
  76. }
  77. for sln > 0 {
  78. cln := BlockSize - ptr
  79. if cln > sln {
  80. cln = sln
  81. }
  82. sln -= cln
  83. copy(ref.b[ptr:], src[:cln])
  84. src = src[cln:]
  85. ptr += cln
  86. if ptr == BlockSize {
  87. sta[0] ^= decUInt64le(buf[0:])
  88. sta[1] ^= decUInt64le(buf[8:])
  89. sta[2] ^= decUInt64le(buf[16:])
  90. sta[3] ^= decUInt64le(buf[24:])
  91. sta[4] ^= decUInt64le(buf[32:])
  92. sta[5] ^= decUInt64le(buf[40:])
  93. sta[6] ^= decUInt64le(buf[48:])
  94. sta[7] ^= decUInt64le(buf[56:])
  95. sta[8] ^= decUInt64le(buf[64:])
  96. for j := uintptr(0); j < 24; j++ {
  97. var t0, t1, t2, t3, t4, tp uint64
  98. {
  99. var tt0, tt1, tt2, tt3 uint64
  100. tt0 = sta[1] ^ sta[6]
  101. tt1 = sta[11] ^ sta[16]
  102. tt0 = tt0 ^ sta[21]
  103. tt0 = tt0 ^ tt1
  104. tt0 = (tt0 << 1) | (tt0 >> (64 - 1))
  105. tt2 = sta[4] ^ sta[9]
  106. tt3 = sta[14] ^ sta[19]
  107. tt0 = tt0 ^ sta[24]
  108. tt2 = tt2 ^ tt3
  109. t0 = tt0 ^ tt2
  110. tt0 = sta[2] ^ sta[7]
  111. tt1 = sta[12] ^ sta[17]
  112. tt0 = tt0 ^ sta[22]
  113. tt0 = tt0 ^ tt1
  114. tt0 = (tt0 << 1) | (tt0 >> (64 - 1))
  115. tt2 = sta[0] ^ sta[5]
  116. tt3 = sta[10] ^ sta[15]
  117. tt0 = tt0 ^ sta[20]
  118. tt2 = tt2 ^ tt3
  119. t1 = tt0 ^ tt2
  120. tt0 = sta[3] ^ sta[8]
  121. tt1 = sta[13] ^ sta[18]
  122. tt0 = tt0 ^ sta[23]
  123. tt0 = tt0 ^ tt1
  124. tt0 = (tt0 << 1) | (tt0 >> (64 - 1))
  125. tt2 = sta[1] ^ sta[6]
  126. tt3 = sta[11] ^ sta[16]
  127. tt0 = tt0 ^ sta[21]
  128. tt2 = tt2 ^ tt3
  129. t2 = tt0 ^ tt2
  130. tt0 = sta[4] ^ sta[9]
  131. tt1 = sta[14] ^ sta[19]
  132. tt0 = tt0 ^ sta[24]
  133. tt0 = tt0 ^ tt1
  134. tt0 = (tt0 << 1) | (tt0 >> (64 - 1))
  135. tt2 = sta[2] ^ sta[7]
  136. tt3 = sta[12] ^ sta[17]
  137. tt0 = tt0 ^ sta[22]
  138. tt2 = tt2 ^ tt3
  139. t3 = tt0 ^ tt2
  140. tt0 = sta[0] ^ sta[5]
  141. tt1 = sta[10] ^ sta[15]
  142. tt0 = tt0 ^ sta[20]
  143. tt0 = tt0 ^ tt1
  144. tt0 = (tt0 << 1) | (tt0 >> (64 - 1))
  145. tt2 = sta[3] ^ sta[8]
  146. tt3 = sta[13] ^ sta[18]
  147. tt0 = tt0 ^ sta[23]
  148. tt2 = tt2 ^ tt3
  149. t4 = tt0 ^ tt2
  150. }
  151. sta[0] = sta[0] ^ t0
  152. sta[1] = sta[1] ^ t1
  153. sta[2] = sta[2] ^ t2
  154. sta[3] = sta[3] ^ t3
  155. sta[4] = sta[4] ^ t4
  156. sta[5] = sta[5] ^ t0
  157. sta[6] = sta[6] ^ t1
  158. sta[7] = sta[7] ^ t2
  159. sta[8] = sta[8] ^ t3
  160. sta[9] = sta[9] ^ t4
  161. sta[10] = sta[10] ^ t0
  162. sta[11] = sta[11] ^ t1
  163. sta[12] = sta[12] ^ t2
  164. sta[13] = sta[13] ^ t3
  165. sta[14] = sta[14] ^ t4
  166. sta[15] = sta[15] ^ t0
  167. sta[16] = sta[16] ^ t1
  168. sta[17] = sta[17] ^ t2
  169. sta[18] = sta[18] ^ t3
  170. sta[23] = sta[23] ^ t3
  171. sta[19] = sta[19] ^ t4
  172. sta[20] = sta[20] ^ t0
  173. sta[22] = sta[22] ^ t2
  174. sta[21] = sta[21] ^ t1
  175. sta[24] = sta[24] ^ t4
  176. sta[1] = (sta[1] << 1) | (sta[1] >> (64 - 1))
  177. sta[2] = (sta[2] << 62) | (sta[2] >> (64 - 62))
  178. sta[3] = (sta[3] << 28) | (sta[3] >> (64 - 28))
  179. sta[4] = (sta[4] << 27) | (sta[4] >> (64 - 27))
  180. sta[5] = (sta[5] << 36) | (sta[5] >> (64 - 36))
  181. sta[6] = (sta[6] << 44) | (sta[6] >> (64 - 44))
  182. sta[7] = (sta[7] << 6) | (sta[7] >> (64 - 6))
  183. sta[8] = (sta[8] << 55) | (sta[8] >> (64 - 55))
  184. sta[9] = (sta[9] << 20) | (sta[9] >> (64 - 20))
  185. sta[10] = (sta[10] << 3) | (sta[10] >> (64 - 3))
  186. sta[11] = (sta[11] << 10) | (sta[11] >> (64 - 10))
  187. sta[12] = (sta[12] << 43) | (sta[12] >> (64 - 43))
  188. sta[13] = (sta[13] << 25) | (sta[13] >> (64 - 25))
  189. sta[14] = (sta[14] << 39) | (sta[14] >> (64 - 39))
  190. sta[15] = (sta[15] << 41) | (sta[15] >> (64 - 41))
  191. sta[16] = (sta[16] << 45) | (sta[16] >> (64 - 45))
  192. sta[17] = (sta[17] << 15) | (sta[17] >> (64 - 15))
  193. sta[18] = (sta[18] << 21) | (sta[18] >> (64 - 21))
  194. sta[19] = (sta[19] << 8) | (sta[19] >> (64 - 8))
  195. sta[20] = (sta[20] << 18) | (sta[20] >> (64 - 18))
  196. sta[21] = (sta[21] << 2) | (sta[21] >> (64 - 2))
  197. sta[22] = (sta[22] << 61) | (sta[22] >> (64 - 61))
  198. sta[23] = (sta[23] << 56) | (sta[23] >> (64 - 56))
  199. sta[24] = (sta[24] << 14) | (sta[24] >> (64 - 14))
  200. tp = ^sta[12]
  201. t0 = sta[6] | sta[12]
  202. t0 = sta[0] ^ t0
  203. t1 = tp | sta[18]
  204. t1 = sta[6] ^ t1
  205. t2 = sta[18] & sta[24]
  206. t2 = sta[12] ^ t2
  207. t3 = sta[24] | sta[0]
  208. t3 = sta[18] ^ t3
  209. t4 = sta[0] & sta[6]
  210. t4 = sta[24] ^ t4
  211. sta[0] = t0
  212. sta[6] = t1
  213. sta[12] = t2
  214. sta[18] = t3
  215. sta[24] = t4
  216. tp = ^sta[22]
  217. t0 = sta[9] | sta[10]
  218. t0 = sta[3] ^ t0
  219. t1 = sta[10] & sta[16]
  220. t1 = sta[9] ^ t1
  221. t2 = sta[16] | tp
  222. t2 = sta[10] ^ t2
  223. t3 = sta[22] | sta[3]
  224. t3 = sta[16] ^ t3
  225. t4 = sta[3] & sta[9]
  226. t4 = sta[22] ^ t4
  227. sta[3] = t0
  228. sta[9] = t1
  229. sta[10] = t2
  230. sta[16] = t3
  231. sta[22] = t4
  232. tp = ^sta[19]
  233. t0 = sta[7] | sta[13]
  234. t0 = sta[1] ^ t0
  235. t1 = sta[13] & sta[19]
  236. t1 = sta[7] ^ t1
  237. t2 = tp & sta[20]
  238. t2 = sta[13] ^ t2
  239. t3 = sta[20] | sta[1]
  240. t3 = tp ^ t3
  241. t4 = sta[1] & sta[7]
  242. t4 = sta[20] ^ t4
  243. sta[1] = t0
  244. sta[7] = t1
  245. sta[13] = t2
  246. sta[19] = t3
  247. sta[20] = t4
  248. tp = ^sta[17]
  249. t0 = sta[5] & sta[11]
  250. t0 = sta[4] ^ t0
  251. t1 = sta[11] | sta[17]
  252. t1 = sta[5] ^ t1
  253. t2 = tp | sta[23]
  254. t2 = sta[11] ^ t2
  255. t3 = sta[23] & sta[4]
  256. t3 = tp ^ t3
  257. t4 = sta[4] | sta[5]
  258. t4 = sta[23] ^ t4
  259. sta[4] = t0
  260. sta[5] = t1
  261. sta[11] = t2
  262. sta[17] = t3
  263. sta[23] = t4
  264. tp = ^sta[8]
  265. t0 = tp & sta[14]
  266. t0 = sta[2] ^ t0
  267. t1 = sta[14] | sta[15]
  268. t1 = tp ^ t1
  269. t2 = sta[15] & sta[21]
  270. t2 = sta[14] ^ t2
  271. t3 = sta[21] | sta[2]
  272. t3 = sta[15] ^ t3
  273. t4 = sta[2] & sta[8]
  274. t4 = sta[21] ^ t4
  275. sta[2] = t0
  276. sta[8] = t1
  277. sta[14] = t2
  278. sta[15] = t3
  279. sta[21] = t4
  280. sta[0] = sta[0] ^ kSpec[j+0]
  281. t0 = sta[5]
  282. sta[5] = sta[3]
  283. sta[3] = sta[18]
  284. sta[18] = sta[17]
  285. sta[17] = sta[11]
  286. sta[11] = sta[7]
  287. sta[7] = sta[10]
  288. sta[10] = sta[1]
  289. sta[1] = sta[6]
  290. sta[6] = sta[9]
  291. sta[9] = sta[22]
  292. sta[22] = sta[14]
  293. sta[14] = sta[20]
  294. sta[20] = sta[2]
  295. sta[2] = sta[12]
  296. sta[12] = sta[13]
  297. sta[13] = sta[19]
  298. sta[19] = sta[23]
  299. sta[23] = sta[15]
  300. sta[15] = sta[4]
  301. sta[4] = sta[24]
  302. sta[24] = sta[21]
  303. sta[21] = sta[8]
  304. sta[8] = sta[16]
  305. sta[16] = t0
  306. }
  307. ptr = 0
  308. }
  309. }
  310. ref.ptr = ptr
  311. return fln, nil
  312. }
  313. // Close the digest by writing the last bits and storing the hash
  314. // in dst. This prepares the digest for reuse by calling reset. A call
  315. // to Close with a dst that is smaller then HashSize will return an error.
  316. func (ref *digest) Close(dst []byte, bits uint8, bcnt uint8) error {
  317. if ln := len(dst); HashSize > ln {
  318. return fmt.Errorf("Keccak Close: dst min length: %d, got %d", HashSize, ln)
  319. }
  320. var tln uintptr
  321. var tmp [73]uint8
  322. off := uint8((uint16(0x100) | uint16(bits&0xFF)) >> (8 - bcnt))
  323. if ref.ptr == (72 - 1) {
  324. if bcnt == 7 {
  325. tmp[0] = off
  326. tmp[72] = 0x80
  327. tln = 1 + 72
  328. } else {
  329. tmp[0] = uint8(off | 0x80)
  330. tln = 1
  331. }
  332. } else {
  333. tln = 72 - ref.ptr
  334. tmp[0] = off
  335. tmp[tln-1] = 0x80
  336. }
  337. ref.Write(tmp[:tln])
  338. ref.h[1] = ^ref.h[1]
  339. ref.h[2] = ^ref.h[2]
  340. ref.h[8] = ^ref.h[8]
  341. ref.h[12] = ^ref.h[12]
  342. ref.h[17] = ^ref.h[17]
  343. ref.h[20] = ^ref.h[20]
  344. for u := uintptr(0); u < 64; u += 8 {
  345. encUInt64le(dst[u:], ref.h[(u>>3)])
  346. }
  347. ref.Reset()
  348. return nil
  349. }
  350. // Size returns the number of bytes required to store the hash.
  351. func (*digest) Size() int {
  352. return HashSize
  353. }
  354. // BlockSize returns the block size of the hash.
  355. func (*digest) BlockSize() int {
  356. return int(BlockSize)
  357. }
  358. ////////////////
  359. func decUInt64le(src []byte) uint64 {
  360. return (uint64(src[0]) |
  361. uint64(src[1])<<8 |
  362. uint64(src[2])<<16 |
  363. uint64(src[3])<<24 |
  364. uint64(src[4])<<32 |
  365. uint64(src[5])<<40 |
  366. uint64(src[6])<<48 |
  367. uint64(src[7])<<56)
  368. }
  369. func encUInt64le(dst []byte, src uint64) {
  370. dst[0] = uint8(src)
  371. dst[1] = uint8(src >> 8)
  372. dst[2] = uint8(src >> 16)
  373. dst[3] = uint8(src >> 24)
  374. dst[4] = uint8(src >> 32)
  375. dst[5] = uint8(src >> 40)
  376. dst[6] = uint8(src >> 48)
  377. dst[7] = uint8(src >> 56)
  378. }
  379. ////////////////
  380. var kSpec = []uint64{
  381. uint64(0x0000000000000001), uint64(0x0000000000008082),
  382. uint64(0x800000000000808A), uint64(0x8000000080008000),
  383. uint64(0x000000000000808B), uint64(0x0000000080000001),
  384. uint64(0x8000000080008081), uint64(0x8000000000008009),
  385. uint64(0x000000000000008A), uint64(0x0000000000000088),
  386. uint64(0x0000000080008009), uint64(0x000000008000000A),
  387. uint64(0x000000008000808B), uint64(0x800000000000008B),
  388. uint64(0x8000000000008089), uint64(0x8000000000008003),
  389. uint64(0x8000000000008002), uint64(0x8000000000000080),
  390. uint64(0x000000000000800A), uint64(0x800000008000000A),
  391. uint64(0x8000000080008081), uint64(0x8000000000008080),
  392. uint64(0x0000000080000001), uint64(0x8000000080008008),
  393. }