blake2s.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  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 blake2s implements the BLAKE2s hash algorithm defined by RFC 7693
  5. // and the extendable output function (XOF) BLAKE2Xs.
  6. //
  7. // BLAKE2s is optimized for 8- to 32-bit platforms and produces digests of any
  8. // size between 1 and 32 bytes.
  9. // For a detailed specification of BLAKE2s see https://blake2.net/blake2.pdf
  10. // and for BLAKE2Xs see https://blake2.net/blake2x.pdf
  11. //
  12. // If you aren't sure which function you need, use BLAKE2s (Sum256 or New256).
  13. // If you need a secret-key MAC (message authentication code), use the New256
  14. // function with a non-nil key.
  15. //
  16. // BLAKE2X is a construction to compute hash values larger than 32 bytes. It
  17. // can produce hash values between 0 and 65535 bytes.
  18. package blake2s
  19. import (
  20. "crypto"
  21. "encoding/binary"
  22. "errors"
  23. "hash"
  24. )
  25. const (
  26. // The blocksize of BLAKE2s in bytes.
  27. BlockSize = 64
  28. // The hash size of BLAKE2s-256 in bytes.
  29. Size = 32
  30. // The hash size of BLAKE2s-128 in bytes.
  31. Size128 = 16
  32. )
  33. var errKeySize = errors.New("blake2s: invalid key size")
  34. var iv = [8]uint32{
  35. 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
  36. 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
  37. }
  38. // Sum256 returns the BLAKE2s-256 checksum of the data.
  39. func Sum256(data []byte) [Size]byte {
  40. var sum [Size]byte
  41. checkSum(&sum, Size, data)
  42. return sum
  43. }
  44. // New256 returns a new hash.Hash computing the BLAKE2s-256 checksum. A non-nil
  45. // key turns the hash into a MAC. The key must between zero and 32 bytes long.
  46. // When the key is nil, the returned hash.Hash implements BinaryMarshaler
  47. // and BinaryUnmarshaler for state (de)serialization as documented by hash.Hash.
  48. func New256(key []byte) (hash.Hash, error) { return newDigest(Size, key) }
  49. func init() {
  50. crypto.RegisterHash(crypto.BLAKE2s_256, func() hash.Hash {
  51. h, _ := New256(nil)
  52. return h
  53. })
  54. }
  55. // New128 returns a new hash.Hash computing the BLAKE2s-128 checksum given a
  56. // non-empty key. Note that a 128-bit digest is too small to be secure as a
  57. // cryptographic hash and should only be used as a MAC, thus the key argument
  58. // is not optional.
  59. func New128(key []byte) (hash.Hash, error) {
  60. if len(key) == 0 {
  61. return nil, errors.New("blake2s: a key is required for a 128-bit hash")
  62. }
  63. return newDigest(Size128, key)
  64. }
  65. func newDigest(hashSize int, key []byte) (*digest, error) {
  66. if len(key) > Size {
  67. return nil, errKeySize
  68. }
  69. d := &digest{
  70. size: hashSize,
  71. keyLen: len(key),
  72. }
  73. copy(d.key[:], key)
  74. d.Reset()
  75. return d, nil
  76. }
  77. func checkSum(sum *[Size]byte, hashSize int, data []byte) {
  78. var (
  79. h [8]uint32
  80. c [2]uint32
  81. )
  82. h = iv
  83. h[0] ^= uint32(hashSize) | (1 << 16) | (1 << 24)
  84. if length := len(data); length > BlockSize {
  85. n := length &^ (BlockSize - 1)
  86. if length == n {
  87. n -= BlockSize
  88. }
  89. hashBlocks(&h, &c, 0, data[:n])
  90. data = data[n:]
  91. }
  92. var block [BlockSize]byte
  93. offset := copy(block[:], data)
  94. remaining := uint32(BlockSize - offset)
  95. if c[0] < remaining {
  96. c[1]--
  97. }
  98. c[0] -= remaining
  99. hashBlocks(&h, &c, 0xFFFFFFFF, block[:])
  100. for i, v := range h {
  101. binary.LittleEndian.PutUint32(sum[4*i:], v)
  102. }
  103. }
  104. type digest struct {
  105. h [8]uint32
  106. c [2]uint32
  107. size int
  108. block [BlockSize]byte
  109. offset int
  110. key [BlockSize]byte
  111. keyLen int
  112. }
  113. const (
  114. magic = "b2s"
  115. marshaledSize = len(magic) + 8*4 + 2*4 + 1 + BlockSize + 1
  116. )
  117. func (d *digest) MarshalBinary() ([]byte, error) {
  118. if d.keyLen != 0 {
  119. return nil, errors.New("crypto/blake2s: cannot marshal MACs")
  120. }
  121. b := make([]byte, 0, marshaledSize)
  122. b = append(b, magic...)
  123. for i := 0; i < 8; i++ {
  124. b = appendUint32(b, d.h[i])
  125. }
  126. b = appendUint32(b, d.c[0])
  127. b = appendUint32(b, d.c[1])
  128. // Maximum value for size is 32
  129. b = append(b, byte(d.size))
  130. b = append(b, d.block[:]...)
  131. b = append(b, byte(d.offset))
  132. return b, nil
  133. }
  134. func (d *digest) UnmarshalBinary(b []byte) error {
  135. if len(b) < len(magic) || string(b[:len(magic)]) != magic {
  136. return errors.New("crypto/blake2s: invalid hash state identifier")
  137. }
  138. if len(b) != marshaledSize {
  139. return errors.New("crypto/blake2s: invalid hash state size")
  140. }
  141. b = b[len(magic):]
  142. for i := 0; i < 8; i++ {
  143. b, d.h[i] = consumeUint32(b)
  144. }
  145. b, d.c[0] = consumeUint32(b)
  146. b, d.c[1] = consumeUint32(b)
  147. d.size = int(b[0])
  148. b = b[1:]
  149. copy(d.block[:], b[:BlockSize])
  150. b = b[BlockSize:]
  151. d.offset = int(b[0])
  152. return nil
  153. }
  154. func (d *digest) BlockSize() int { return BlockSize }
  155. func (d *digest) Size() int { return d.size }
  156. func (d *digest) Reset() {
  157. d.h = iv
  158. d.h[0] ^= uint32(d.size) | (uint32(d.keyLen) << 8) | (1 << 16) | (1 << 24)
  159. d.offset, d.c[0], d.c[1] = 0, 0, 0
  160. if d.keyLen > 0 {
  161. d.block = d.key
  162. d.offset = BlockSize
  163. }
  164. }
  165. func (d *digest) Write(p []byte) (n int, err error) {
  166. n = len(p)
  167. if d.offset > 0 {
  168. remaining := BlockSize - d.offset
  169. if n <= remaining {
  170. d.offset += copy(d.block[d.offset:], p)
  171. return
  172. }
  173. copy(d.block[d.offset:], p[:remaining])
  174. hashBlocks(&d.h, &d.c, 0, d.block[:])
  175. d.offset = 0
  176. p = p[remaining:]
  177. }
  178. if length := len(p); length > BlockSize {
  179. nn := length &^ (BlockSize - 1)
  180. if length == nn {
  181. nn -= BlockSize
  182. }
  183. hashBlocks(&d.h, &d.c, 0, p[:nn])
  184. p = p[nn:]
  185. }
  186. d.offset += copy(d.block[:], p)
  187. return
  188. }
  189. func (d *digest) Sum(sum []byte) []byte {
  190. var hash [Size]byte
  191. d.finalize(&hash)
  192. return append(sum, hash[:d.size]...)
  193. }
  194. func (d *digest) finalize(hash *[Size]byte) {
  195. var block [BlockSize]byte
  196. h := d.h
  197. c := d.c
  198. copy(block[:], d.block[:d.offset])
  199. remaining := uint32(BlockSize - d.offset)
  200. if c[0] < remaining {
  201. c[1]--
  202. }
  203. c[0] -= remaining
  204. hashBlocks(&h, &c, 0xFFFFFFFF, block[:])
  205. for i, v := range h {
  206. binary.LittleEndian.PutUint32(hash[4*i:], v)
  207. }
  208. }
  209. func appendUint32(b []byte, x uint32) []byte {
  210. var a [4]byte
  211. binary.BigEndian.PutUint32(a[:], x)
  212. return append(b, a[:]...)
  213. }
  214. func consumeUint32(b []byte) ([]byte, uint32) {
  215. x := binary.BigEndian.Uint32(b)
  216. return b[4:], x
  217. }