25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 

194 satır
5.7 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. fixedOutput bool // whether this is a fixed-output-length instance
  39. outputLen int // the default output size in bytes
  40. state spongeDirection // whether the sponge is absorbing or squeezing
  41. }
  42. // BlockSize returns the rate of sponge underlying this hash function.
  43. func (d *state) BlockSize() int { return d.rate }
  44. // Size returns the output size of the hash function in bytes.
  45. func (d *state) Size() int { return d.outputLen }
  46. // Reset clears the internal state by zeroing the sponge state and
  47. // the byte buffer, and setting Sponge.state to absorbing.
  48. func (d *state) Reset() {
  49. // Zero the permutation's state.
  50. for i := range d.a {
  51. d.a[i] = 0
  52. }
  53. d.state = spongeAbsorbing
  54. d.buf = d.storage[:0]
  55. }
  56. func (d *state) clone() *state {
  57. ret := *d
  58. if ret.state == spongeAbsorbing {
  59. ret.buf = ret.storage[:len(ret.buf)]
  60. } else {
  61. ret.buf = ret.storage[d.rate-cap(d.buf) : d.rate]
  62. }
  63. return &ret
  64. }
  65. // permute applies the KeccakF-1600 permutation. It handles
  66. // any input-output buffering.
  67. func (d *state) permute() {
  68. switch d.state {
  69. case spongeAbsorbing:
  70. // If we're absorbing, we need to xor the input into the state
  71. // before applying the permutation.
  72. xorIn(d, d.buf)
  73. d.buf = d.storage[:0]
  74. keccakF1600(&d.a)
  75. case spongeSqueezing:
  76. // If we're squeezing, we need to apply the permutatin before
  77. // copying more output.
  78. keccakF1600(&d.a)
  79. d.buf = d.storage[:d.rate]
  80. copyOut(d, d.buf)
  81. }
  82. }
  83. // pads appends the domain separation bits in dsbyte, applies
  84. // the multi-bitrate 10..1 padding rule, and permutes the state.
  85. func (d *state) padAndPermute(dsbyte byte) {
  86. if d.buf == nil {
  87. d.buf = d.storage[:0]
  88. }
  89. // Pad with this instance's domain-separator bits. We know that there's
  90. // at least one byte of space in d.buf because, if it were full,
  91. // permute would have been called to empty it. dsbyte also contains the
  92. // first one bit for the padding. See the comment in the state struct.
  93. d.buf = append(d.buf, dsbyte)
  94. zerosStart := len(d.buf)
  95. d.buf = d.storage[:d.rate]
  96. for i := zerosStart; i < d.rate; i++ {
  97. d.buf[i] = 0
  98. }
  99. // This adds the final one bit for the padding. Because of the way that
  100. // bits are numbered from the LSB upwards, the final bit is the MSB of
  101. // the last byte.
  102. d.buf[d.rate-1] ^= 0x80
  103. // Apply the permutation
  104. d.permute()
  105. d.state = spongeSqueezing
  106. d.buf = d.storage[:d.rate]
  107. copyOut(d, d.buf)
  108. }
  109. // Write absorbs more data into the hash's state. It produces an error
  110. // if more data is written to the ShakeHash after writing
  111. func (d *state) Write(p []byte) (written int, err error) {
  112. if d.state != spongeAbsorbing {
  113. panic("sha3: write to sponge after read")
  114. }
  115. if d.buf == nil {
  116. d.buf = d.storage[:0]
  117. }
  118. written = len(p)
  119. for len(p) > 0 {
  120. if len(d.buf) == 0 && len(p) >= d.rate {
  121. // The fast path; absorb a full "rate" bytes of input and apply the permutation.
  122. xorIn(d, p[:d.rate])
  123. p = p[d.rate:]
  124. keccakF1600(&d.a)
  125. } else {
  126. // The slow path; buffer the input until we can fill the sponge, and then xor it in.
  127. todo := d.rate - len(d.buf)
  128. if todo > len(p) {
  129. todo = len(p)
  130. }
  131. d.buf = append(d.buf, p[:todo]...)
  132. p = p[todo:]
  133. // If the sponge is full, apply the permutation.
  134. if len(d.buf) == d.rate {
  135. d.permute()
  136. }
  137. }
  138. }
  139. return
  140. }
  141. // Read squeezes an arbitrary number of bytes from the sponge.
  142. func (d *state) Read(out []byte) (n int, err error) {
  143. // If we're still absorbing, pad and apply the permutation.
  144. if d.state == spongeAbsorbing {
  145. d.padAndPermute(d.dsbyte)
  146. }
  147. n = len(out)
  148. // Now, do the squeezing.
  149. for len(out) > 0 {
  150. n := copy(out, d.buf)
  151. d.buf = d.buf[n:]
  152. out = out[n:]
  153. // Apply the permutation if we've squeezed the sponge dry.
  154. if len(d.buf) == 0 {
  155. d.permute()
  156. }
  157. }
  158. return
  159. }
  160. // Sum applies padding to the hash state and then squeezes out the desired
  161. // number of output bytes.
  162. func (d *state) Sum(in []byte) []byte {
  163. // Make a copy of the original hash so that caller can keep writing
  164. // and summing.
  165. dup := d.clone()
  166. hash := make([]byte, dup.outputLen)
  167. dup.Read(hash)
  168. return append(in, hash...)
  169. }