1 // Copyright 2009 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.
5 // Package sha256 implements the SHA224 and SHA256 hash algorithms as defined
16 import "crypto/internal/boring"
19 crypto.RegisterHash(crypto.SHA224, New224)
20 crypto.RegisterHash(crypto.SHA256, New)
23 // The size of a SHA256 checksum in bytes.
26 // The size of a SHA224 checksum in bytes.
29 // The blocksize of SHA256 and SHA224 in bytes.
42 init0_224 = 0xC1059ED8
43 init1_224 = 0x367CD507
44 init2_224 = 0x3070DD17
45 init3_224 = 0xF70E5939
46 init4_224 = 0xFFC00B31
47 init5_224 = 0x68581511
48 init6_224 = 0x64F98FA7
49 init7_224 = 0xBEFA4FA4
52 // digest represents the partial evaluation of a checksum.
58 is224 bool // mark if this digest is SHA-224
64 marshaledSize = len(magic256) + 8*4 + chunk + 8
67 func (d *digest) MarshalBinary() ([]byte, error) {
68 b := make([]byte, 0, marshaledSize)
70 b = append(b, magic224...)
72 b = append(b, magic256...)
74 b = appendUint32(b, d.h[0])
75 b = appendUint32(b, d.h[1])
76 b = appendUint32(b, d.h[2])
77 b = appendUint32(b, d.h[3])
78 b = appendUint32(b, d.h[4])
79 b = appendUint32(b, d.h[5])
80 b = appendUint32(b, d.h[6])
81 b = appendUint32(b, d.h[7])
82 b = append(b, d.x[:d.nx]...)
83 b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
84 b = appendUint64(b, d.len)
88 func (d *digest) UnmarshalBinary(b []byte) error {
89 if len(b) < len(magic224) || (d.is224 && string(b[:len(magic224)]) != magic224) || (!d.is224 && string(b[:len(magic256)]) != magic256) {
90 return errors.New("crypto/sha256: invalid hash state identifier")
92 if len(b) != marshaledSize {
93 return errors.New("crypto/sha256: invalid hash state size")
96 b, d.h[0] = consumeUint32(b)
97 b, d.h[1] = consumeUint32(b)
98 b, d.h[2] = consumeUint32(b)
99 b, d.h[3] = consumeUint32(b)
100 b, d.h[4] = consumeUint32(b)
101 b, d.h[5] = consumeUint32(b)
102 b, d.h[6] = consumeUint32(b)
103 b, d.h[7] = consumeUint32(b)
104 b = b[copy(d.x[:], b):]
105 b, d.len = consumeUint64(b)
106 d.nx = int(d.len % chunk)
110 func appendUint64(b []byte, x uint64) []byte {
112 binary.BigEndian.PutUint64(a[:], x)
113 return append(b, a[:]...)
116 func appendUint32(b []byte, x uint32) []byte {
118 binary.BigEndian.PutUint32(a[:], x)
119 return append(b, a[:]...)
122 func consumeUint64(b []byte) ([]byte, uint64) {
124 x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
125 uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
129 func consumeUint32(b []byte) ([]byte, uint32) {
131 x := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
135 func (d *digest) Reset() {
159 // New returns a new hash.Hash computing the SHA256 checksum. The Hash
160 // also implements encoding.BinaryMarshaler and
161 // encoding.BinaryUnmarshaler to marshal and unmarshal the internal
162 // state of the hash.
163 func New() hash.Hash {
165 return boring.NewSHA256()
172 // New224 returns a new hash.Hash computing the SHA224 checksum.
173 func New224() hash.Hash {
175 return boring.NewSHA224()
183 func (d *digest) Size() int {
190 func (d *digest) BlockSize() int { return BlockSize }
192 func (d *digest) Write(p []byte) (nn int, err error) {
197 n := copy(d.x[d.nx:], p)
206 n := len(p) &^ (chunk - 1)
211 d.nx = copy(d.x[:], p)
216 func (d *digest) Sum(in []byte) []byte {
218 // Make a copy of d so that caller can keep writing and summing.
220 hash := d0.checkSum()
222 return append(in, hash[:Size224]...)
224 return append(in, hash[:]...)
227 func (d *digest) checkSum() [Size]byte {
229 // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
233 d.Write(tmp[0 : 56-len%64])
235 d.Write(tmp[0 : 64+56-len%64])
240 binary.BigEndian.PutUint64(tmp[:], len)
247 var digest [Size]byte
249 binary.BigEndian.PutUint32(digest[0:], d.h[0])
250 binary.BigEndian.PutUint32(digest[4:], d.h[1])
251 binary.BigEndian.PutUint32(digest[8:], d.h[2])
252 binary.BigEndian.PutUint32(digest[12:], d.h[3])
253 binary.BigEndian.PutUint32(digest[16:], d.h[4])
254 binary.BigEndian.PutUint32(digest[20:], d.h[5])
255 binary.BigEndian.PutUint32(digest[24:], d.h[6])
257 binary.BigEndian.PutUint32(digest[28:], d.h[7])
263 // Sum256 returns the SHA256 checksum of the data.
264 func Sum256(data []byte) [Size]byte {
278 // Sum224 returns the SHA224 checksum of the data.
279 func Sum224(data []byte) [Size224]byte {
283 var ret [Size224]byte
292 ap := (*[Size224]byte)(sum[:])