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.

192 lines
5.6 KiB

  1. // Copyright 2014 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 sha3
  5. // spongeDirection indicates the direction bytes are flowing through the sponge.
  6. type spongeDirection int
  7. const (
  8. // spongeAbsorbing indicates that the sponge is absorbing input.
  9. spongeAbsorbing spongeDirection = iota
  10. // spongeSqueezing indicates that the sponge is being squeezed.
  11. spongeSqueezing
  12. )
  13. const (
  14. // maxRate is the maximum size of the internal buffer. SHAKE-256
  15. // currently needs the largest buffer.
  16. maxRate = 168
  17. )
  18. type state struct {
  19. // Generic sponge components.
  20. a [25]uint64 // main state of the hash
  21. buf []byte // points into storage
  22. rate int // the number of bytes of state to use
  23. // dsbyte contains the "domain separation" bits and the first bit of
  24. // the padding. Sections 6.1 and 6.2 of [1] separate the outputs of the
  25. // SHA-3 and SHAKE functions by appending bitstrings to the message.
  26. // Using a little-endian bit-ordering convention, these are "01" for SHA-3
  27. // and "1111" for SHAKE, or 00000010b and 00001111b, respectively. Then the
  28. // padding rule from section 5.1 is applied to pad the message to a multiple
  29. // of the rate, which involves adding a "1" bit, zero or more "0" bits, and
  30. // a final "1" bit. We merge the first "1" bit from the padding into dsbyte,
  31. // giving 00000110b (0x06) and 00011111b (0x1f).
  32. // [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf
  33. // "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and
  34. // Extendable-Output Functions (May 2014)"
  35. dsbyte byte
  36. storage [maxRate]byte
  37. // Specific to SHA-3 and SHAKE.
  38. outputLen int // the default output size in bytes
  39. state spongeDirection // whether the sponge is absorbing or squeezing
  40. }
  41. // BlockSize returns the rate of sponge underlying this hash function.
  42. func (d *state) BlockSize() int { return d.rate }
  43. // Size returns the output size of the hash function in bytes.
  44. func (d *state) Size() int { return d.outputLen }
  45. // Reset clears the internal state by zeroing the sponge state and
  46. // the byte buffer, and setting Sponge.state to absorbing.
  47. func (d *state) Reset() {
  48. // Zero the permutation's state.
  49. for i := range d.a {
  50. d.a[i] = 0
  51. }
  52. d.state = spongeAbsorbing
  53. d.buf = d.storage[:0]
  54. }
  55. func (d *state) clone() *state {
  56. ret := *d
  57. if ret.state == spongeAbsorbing {
  58. ret.buf = ret.storage[:len(ret.buf)]
  59. } else {
  60. ret.buf = ret.storage[d.rate-cap(d.buf) : d.rate]
  61. }
  62. return &ret
  63. }
  64. // permute applies the KeccakF-1600 permutation. It handles
  65. // any input-output buffering.
  66. func (d *state) permute() {
  67. switch d.state {
  68. case spongeAbsorbing:
  69. // If we're absorbing, we need to xor the input into the state
  70. // before applying the permutation.
  71. xorIn(d, d.buf)
  72. d.buf = d.storage[:0]
  73. keccakF1600(&d.a)
  74. case spongeSqueezing:
  75. // If we're squeezing, we need to apply the permutatin before
  76. // copying more output.
  77. keccakF1600(&d.a)
  78. d.buf = d.storage[:d.rate]
  79. copyOut(d, d.buf)
  80. }
  81. }
  82. // pads appends the domain separation bits in dsbyte, applies
  83. // the multi-bitrate 10..1 padding rule, and permutes the state.
  84. func (d *state) padAndPermute(dsbyte byte) {
  85. if d.buf == nil {
  86. d.buf = d.storage[:0]
  87. }
  88. // Pad with this instance's domain-separator bits. We know that there's
  89. // at least one byte of space in d.buf because, if it were full,
  90. // permute would have been called to empty it. dsbyte also contains the
  91. // first one bit for the padding. See the comment in the state struct.
  92. d.buf = append(d.buf, dsbyte)
  93. zerosStart := len(d.buf)
  94. d.buf = d.storage[:d.rate]
  95. for i := zerosStart; i < d.rate; i++ {
  96. d.buf[i] = 0
  97. }
  98. // This adds the final one bit for the padding. Because of the way that
  99. // bits are numbered from the LSB upwards, the final bit is the MSB of
  100. // the last byte.
  101. d.buf[d.rate-1] ^= 0x80
  102. // Apply the permutation
  103. d.permute()
  104. d.state = spongeSqueezing
  105. d.buf = d.storage[:d.rate]
  106. copyOut(d, d.buf)
  107. }
  108. // Write absorbs more data into the hash's state. It produces an error
  109. // if more data is written to the ShakeHash after writing
  110. func (d *state) Write(p []byte) (written int, err error) {
  111. if d.state != spongeAbsorbing {
  112. panic("sha3: write to sponge after read")
  113. }
  114. if d.buf == nil {
  115. d.buf = d.storage[:0]
  116. }
  117. written = len(p)
  118. for len(p) > 0 {
  119. if len(d.buf) == 0 && len(p) >= d.rate {
  120. // The fast path; absorb a full "rate" bytes of input and apply the permutation.
  121. xorIn(d, p[:d.rate])
  122. p = p[d.rate:]
  123. keccakF1600(&d.a)
  124. } else {
  125. // The slow path; buffer the input until we can fill the sponge, and then xor it in.
  126. todo := d.rate - len(d.buf)
  127. if todo > len(p) {
  128. todo = len(p)
  129. }
  130. d.buf = append(d.buf, p[:todo]...)
  131. p = p[todo:]
  132. // If the sponge is full, apply the permutation.
  133. if len(d.buf) == d.rate {
  134. d.permute()
  135. }
  136. }
  137. }
  138. return
  139. }
  140. // Read squeezes an arbitrary number of bytes from the sponge.
  141. func (d *state) Read(out []byte) (n int, err error) {
  142. // If we're still absorbing, pad and apply the permutation.
  143. if d.state == spongeAbsorbing {
  144. d.padAndPermute(d.dsbyte)
  145. }
  146. n = len(out)
  147. // Now, do the squeezing.
  148. for len(out) > 0 {
  149. n := copy(out, d.buf)
  150. d.buf = d.buf[n:]
  151. out = out[n:]
  152. // Apply the permutation if we've squeezed the sponge dry.
  153. if len(d.buf) == 0 {
  154. d.permute()
  155. }
  156. }
  157. return
  158. }
  159. // Sum applies padding to the hash state and then squeezes out the desired
  160. // number of output bytes.
  161. func (d *state) Sum(in []byte) []byte {
  162. // Make a copy of the original hash so that caller can keep writing
  163. // and summing.
  164. dup := d.clone()
  165. hash := make([]byte, dup.outputLen)
  166. dup.Read(hash)
  167. return append(in, hash...)
  168. }