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.

349 lines
7.7 KiB

  1. // Copyright 2017-2018 DERO Project. All rights reserved.
  2. // Use of this source code in any form is governed by RESEARCH license.
  3. // license can be found in the LICENSE file.
  4. // GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8
  5. //
  6. //
  7. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
  8. // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  9. // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  10. // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  11. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  12. // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  13. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  14. // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  15. // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16. // TODO keccak is available in 3 of our packages we need to merge them when the alpha version is out
  17. // Package keccak implements the Keccak (SHA-3) hash algorithm.
  18. // http://keccak.noekeon.org / FIPS 202 draft.
  19. package cryptonight
  20. // import "fmt"
  21. import "hash"
  22. const (
  23. domainNone = 1
  24. domainSHA3 = 0x06
  25. domainSHAKE = 0x1f
  26. )
  27. const rounds = 24
  28. var roundConstants = []uint64{
  29. 0x0000000000000001, 0x0000000000008082,
  30. 0x800000000000808A, 0x8000000080008000,
  31. 0x000000000000808B, 0x0000000080000001,
  32. 0x8000000080008081, 0x8000000000008009,
  33. 0x000000000000008A, 0x0000000000000088,
  34. 0x0000000080008009, 0x000000008000000A,
  35. 0x000000008000808B, 0x800000000000008B,
  36. 0x8000000000008089, 0x8000000000008003,
  37. 0x8000000000008002, 0x8000000000000080,
  38. 0x000000000000800A, 0x800000008000000A,
  39. 0x8000000080008081, 0x8000000000008080,
  40. 0x0000000080000001, 0x8000000080008008,
  41. }
  42. type keccak struct {
  43. S [25]uint64
  44. size int
  45. blockSize int
  46. buf []byte
  47. domain byte
  48. }
  49. func newKeccak(capacity, output int, domain byte) hash.Hash {
  50. var h keccak
  51. h.size = output / 8
  52. h.blockSize = (200 - capacity/8)
  53. h.domain = domain
  54. return &h
  55. }
  56. func New224() hash.Hash {
  57. return newKeccak(224*2, 224, domainNone)
  58. }
  59. func New256() hash.Hash {
  60. return newKeccak(256*2, 256, domainNone)
  61. }
  62. func New384() hash.Hash {
  63. return newKeccak(384*2, 384, domainNone)
  64. }
  65. func New512() hash.Hash {
  66. return newKeccak(512*2, 512, domainNone)
  67. }
  68. func (k *keccak) Write(b []byte) (int, error) {
  69. n := len(b)
  70. if len(k.buf) > 0 {
  71. x := k.blockSize - len(k.buf)
  72. if x > len(b) {
  73. x = len(b)
  74. }
  75. k.buf = append(k.buf, b[:x]...)
  76. b = b[x:]
  77. if len(k.buf) < k.blockSize {
  78. return n, nil
  79. }
  80. k.absorb(k.buf)
  81. k.buf = nil
  82. }
  83. for len(b) >= k.blockSize {
  84. k.absorb(b[:k.blockSize])
  85. b = b[k.blockSize:]
  86. }
  87. k.buf = b
  88. return n, nil
  89. }
  90. func (k0 *keccak) Sum(b []byte) []byte {
  91. k := *k0
  92. k.final()
  93. return k.squeeze(b)
  94. }
  95. func (k *keccak) Reset() {
  96. for i := range k.S {
  97. k.S[i] = 0
  98. }
  99. k.buf = nil
  100. }
  101. func (k *keccak) Size() int {
  102. return k.size
  103. }
  104. func (k *keccak) BlockSize() int {
  105. return k.blockSize
  106. }
  107. func (k *keccak) absorb(block []byte) {
  108. if len(block) != k.blockSize {
  109. panic("absorb() called with invalid block size")
  110. }
  111. for i := 0; i < k.blockSize/8; i++ {
  112. k.S[i] ^= uint64le(block[i*8:])
  113. }
  114. keccakf(&k.S)
  115. }
  116. func (k *keccak) pad(block []byte) []byte {
  117. padded := make([]byte, k.blockSize)
  118. copy(padded, k.buf)
  119. padded[len(k.buf)] = k.domain
  120. padded[len(padded)-1] |= 0x80
  121. return padded
  122. }
  123. func (k *keccak) final() {
  124. last := k.pad(k.buf)
  125. k.absorb(last)
  126. }
  127. func (k *keccak) squeeze(b []byte) []byte {
  128. buf := make([]byte, 8*len(k.S))
  129. n := k.size
  130. for {
  131. for i := range k.S {
  132. putUint64le(buf[i*8:], k.S[i])
  133. }
  134. if n <= k.blockSize {
  135. b = append(b, buf[:n]...)
  136. break
  137. }
  138. b = append(b, buf[:k.blockSize]...)
  139. n -= k.blockSize
  140. keccakf(&k.S)
  141. }
  142. return b
  143. }
  144. func keccakf(S *[25]uint64) {
  145. var bc0, bc1, bc2, bc3, bc4 uint64
  146. var S0, S1, S2, S3, S4 uint64
  147. var S5, S6, S7, S8, S9 uint64
  148. var S10, S11, S12, S13, S14 uint64
  149. var S15, S16, S17, S18, S19 uint64
  150. var S20, S21, S22, S23, S24 uint64
  151. var tmp uint64
  152. //S[0]=0x2073692073696854;
  153. //S[1]=0x1747365742061
  154. // S[16]=0x8000000000000000;
  155. /* for i :=0; i< 25;i++{
  156. fmt.Printf("%2d %X\n", i, S[i])
  157. }
  158. */
  159. S0, S1, S2, S3, S4 = S[0], S[1], S[2], S[3], S[4]
  160. S5, S6, S7, S8, S9 = S[5], S[6], S[7], S[8], S[9]
  161. S10, S11, S12, S13, S14 = S[10], S[11], S[12], S[13], S[14]
  162. S15, S16, S17, S18, S19 = S[15], S[16], S[17], S[18], S[19]
  163. S20, S21, S22, S23, S24 = S[20], S[21], S[22], S[23], S[24]
  164. for r := 0; r < rounds; r++ {
  165. // theta
  166. bc0 = S0 ^ S5 ^ S10 ^ S15 ^ S20
  167. bc1 = S1 ^ S6 ^ S11 ^ S16 ^ S21
  168. bc2 = S2 ^ S7 ^ S12 ^ S17 ^ S22
  169. bc3 = S3 ^ S8 ^ S13 ^ S18 ^ S23
  170. bc4 = S4 ^ S9 ^ S14 ^ S19 ^ S24
  171. tmp = bc4 ^ (bc1<<1 | bc1>>(64-1))
  172. S0 ^= tmp
  173. S5 ^= tmp
  174. S10 ^= tmp
  175. S15 ^= tmp
  176. S20 ^= tmp
  177. tmp = bc0 ^ (bc2<<1 | bc2>>(64-1))
  178. S1 ^= tmp
  179. S6 ^= tmp
  180. S11 ^= tmp
  181. S16 ^= tmp
  182. S21 ^= tmp
  183. tmp = bc1 ^ (bc3<<1 | bc3>>(64-1))
  184. S2 ^= tmp
  185. S7 ^= tmp
  186. S12 ^= tmp
  187. S17 ^= tmp
  188. S22 ^= tmp
  189. tmp = bc2 ^ (bc4<<1 | bc4>>(64-1))
  190. S3 ^= tmp
  191. S8 ^= tmp
  192. S13 ^= tmp
  193. S18 ^= tmp
  194. S23 ^= tmp
  195. tmp = bc3 ^ (bc0<<1 | bc0>>(64-1))
  196. S4 ^= tmp
  197. S9 ^= tmp
  198. S14 ^= tmp
  199. S19 ^= tmp
  200. S24 ^= tmp
  201. // rho phi
  202. tmp = S1
  203. tmp, S10 = S10, tmp<<1|tmp>>(64-1)
  204. tmp, S7 = S7, tmp<<3|tmp>>(64-3)
  205. tmp, S11 = S11, tmp<<6|tmp>>(64-6)
  206. tmp, S17 = S17, tmp<<10|tmp>>(64-10)
  207. tmp, S18 = S18, tmp<<15|tmp>>(64-15)
  208. tmp, S3 = S3, tmp<<21|tmp>>(64-21)
  209. tmp, S5 = S5, tmp<<28|tmp>>(64-28)
  210. tmp, S16 = S16, tmp<<36|tmp>>(64-36)
  211. tmp, S8 = S8, tmp<<45|tmp>>(64-45)
  212. tmp, S21 = S21, tmp<<55|tmp>>(64-55)
  213. tmp, S24 = S24, tmp<<2|tmp>>(64-2)
  214. tmp, S4 = S4, tmp<<14|tmp>>(64-14)
  215. tmp, S15 = S15, tmp<<27|tmp>>(64-27)
  216. tmp, S23 = S23, tmp<<41|tmp>>(64-41)
  217. tmp, S19 = S19, tmp<<56|tmp>>(64-56)
  218. tmp, S13 = S13, tmp<<8|tmp>>(64-8)
  219. tmp, S12 = S12, tmp<<25|tmp>>(64-25)
  220. tmp, S2 = S2, tmp<<43|tmp>>(64-43)
  221. tmp, S20 = S20, tmp<<62|tmp>>(64-62)
  222. tmp, S14 = S14, tmp<<18|tmp>>(64-18)
  223. tmp, S22 = S22, tmp<<39|tmp>>(64-39)
  224. tmp, S9 = S9, tmp<<61|tmp>>(64-61)
  225. tmp, S6 = S6, tmp<<20|tmp>>(64-20)
  226. S1 = tmp<<44 | tmp>>(64-44)
  227. // chi
  228. bc0 = S0
  229. bc1 = S1
  230. bc2 = S2
  231. bc3 = S3
  232. bc4 = S4
  233. S0 ^= (^bc1) & bc2
  234. S1 ^= (^bc2) & bc3
  235. S2 ^= (^bc3) & bc4
  236. S3 ^= (^bc4) & bc0
  237. S4 ^= (^bc0) & bc1
  238. bc0 = S5
  239. bc1 = S6
  240. bc2 = S7
  241. bc3 = S8
  242. bc4 = S9
  243. S5 ^= (^bc1) & bc2
  244. S6 ^= (^bc2) & bc3
  245. S7 ^= (^bc3) & bc4
  246. S8 ^= (^bc4) & bc0
  247. S9 ^= (^bc0) & bc1
  248. bc0 = S10
  249. bc1 = S11
  250. bc2 = S12
  251. bc3 = S13
  252. bc4 = S14
  253. S10 ^= (^bc1) & bc2
  254. S11 ^= (^bc2) & bc3
  255. S12 ^= (^bc3) & bc4
  256. S13 ^= (^bc4) & bc0
  257. S14 ^= (^bc0) & bc1
  258. bc0 = S15
  259. bc1 = S16
  260. bc2 = S17
  261. bc3 = S18
  262. bc4 = S19
  263. S15 ^= (^bc1) & bc2
  264. S16 ^= (^bc2) & bc3
  265. S17 ^= (^bc3) & bc4
  266. S18 ^= (^bc4) & bc0
  267. S19 ^= (^bc0) & bc1
  268. bc0 = S20
  269. bc1 = S21
  270. bc2 = S22
  271. bc3 = S23
  272. bc4 = S24
  273. S20 ^= (^bc1) & bc2
  274. S21 ^= (^bc2) & bc3
  275. S22 ^= (^bc3) & bc4
  276. S23 ^= (^bc4) & bc0
  277. S24 ^= (^bc0) & bc1
  278. // iota
  279. S0 ^= roundConstants[r]
  280. }
  281. S[0], S[1], S[2], S[3], S[4] = S0, S1, S2, S3, S4
  282. S[5], S[6], S[7], S[8], S[9] = S5, S6, S7, S8, S9
  283. S[10], S[11], S[12], S[13], S[14] = S10, S11, S12, S13, S14
  284. S[15], S[16], S[17], S[18], S[19] = S15, S16, S17, S18, S19
  285. S[20], S[21], S[22], S[23], S[24] = S20, S21, S22, S23, S24
  286. }
  287. func uint64le(v []byte) uint64 {
  288. return uint64(v[0]) |
  289. uint64(v[1])<<8 |
  290. uint64(v[2])<<16 |
  291. uint64(v[3])<<24 |
  292. uint64(v[4])<<32 |
  293. uint64(v[5])<<40 |
  294. uint64(v[6])<<48 |
  295. uint64(v[7])<<56
  296. }
  297. func putUint64le(v []byte, x uint64) {
  298. v[0] = byte(x)
  299. v[1] = byte(x >> 8)
  300. v[2] = byte(x >> 16)
  301. v[3] = byte(x >> 24)
  302. v[4] = byte(x >> 32)
  303. v[5] = byte(x >> 40)
  304. v[6] = byte(x >> 48)
  305. v[7] = byte(x >> 56)
  306. }