]> Cypherpunks.ru repositories - gostls13.git/blob - src/crypto/sha256/sha256.go
[dev.boringcrypto] all: merge master into dev.boringcrypto
[gostls13.git] / src / crypto / sha256 / sha256.go
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.
4
5 // Package sha256 implements the SHA224 and SHA256 hash algorithms as defined
6 // in FIPS 180-4.
7 package sha256
8
9 import (
10         "crypto"
11         "crypto/internal/boring"
12         "errors"
13         "hash"
14 )
15
16 func init() {
17         crypto.RegisterHash(crypto.SHA224, New224)
18         crypto.RegisterHash(crypto.SHA256, New)
19 }
20
21 // The size of a SHA256 checksum in bytes.
22 const Size = 32
23
24 // The size of a SHA224 checksum in bytes.
25 const Size224 = 28
26
27 // The blocksize of SHA256 and SHA224 in bytes.
28 const BlockSize = 64
29
30 const (
31         chunk     = 64
32         init0     = 0x6A09E667
33         init1     = 0xBB67AE85
34         init2     = 0x3C6EF372
35         init3     = 0xA54FF53A
36         init4     = 0x510E527F
37         init5     = 0x9B05688C
38         init6     = 0x1F83D9AB
39         init7     = 0x5BE0CD19
40         init0_224 = 0xC1059ED8
41         init1_224 = 0x367CD507
42         init2_224 = 0x3070DD17
43         init3_224 = 0xF70E5939
44         init4_224 = 0xFFC00B31
45         init5_224 = 0x68581511
46         init6_224 = 0x64F98FA7
47         init7_224 = 0xBEFA4FA4
48 )
49
50 // digest represents the partial evaluation of a checksum.
51 type digest struct {
52         h     [8]uint32
53         x     [chunk]byte
54         nx    int
55         len   uint64
56         is224 bool // mark if this digest is SHA-224
57 }
58
59 const (
60         magic224      = "sha\x02"
61         magic256      = "sha\x03"
62         marshaledSize = len(magic256) + 8*4 + chunk + 8
63 )
64
65 func (d *digest) MarshalBinary() ([]byte, error) {
66         b := make([]byte, 0, marshaledSize)
67         if d.is224 {
68                 b = append(b, magic224...)
69         } else {
70                 b = append(b, magic256...)
71         }
72         b = appendUint32(b, d.h[0])
73         b = appendUint32(b, d.h[1])
74         b = appendUint32(b, d.h[2])
75         b = appendUint32(b, d.h[3])
76         b = appendUint32(b, d.h[4])
77         b = appendUint32(b, d.h[5])
78         b = appendUint32(b, d.h[6])
79         b = appendUint32(b, d.h[7])
80         b = append(b, d.x[:d.nx]...)
81         b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
82         b = appendUint64(b, d.len)
83         return b, nil
84 }
85
86 func (d *digest) UnmarshalBinary(b []byte) error {
87         if len(b) < len(magic224) || (d.is224 && string(b[:len(magic224)]) != magic224) || (!d.is224 && string(b[:len(magic256)]) != magic256) {
88                 return errors.New("crypto/sha256: invalid hash state identifier")
89         }
90         if len(b) != marshaledSize {
91                 return errors.New("crypto/sha256: invalid hash state size")
92         }
93         b = b[len(magic224):]
94         b, d.h[0] = consumeUint32(b)
95         b, d.h[1] = consumeUint32(b)
96         b, d.h[2] = consumeUint32(b)
97         b, d.h[3] = consumeUint32(b)
98         b, d.h[4] = consumeUint32(b)
99         b, d.h[5] = consumeUint32(b)
100         b, d.h[6] = consumeUint32(b)
101         b, d.h[7] = consumeUint32(b)
102         b = b[copy(d.x[:], b):]
103         b, d.len = consumeUint64(b)
104         d.nx = int(d.len % chunk)
105         return nil
106 }
107
108 func putUint32(x []byte, s uint32) {
109         _ = x[3]
110         x[0] = byte(s >> 24)
111         x[1] = byte(s >> 16)
112         x[2] = byte(s >> 8)
113         x[3] = byte(s)
114 }
115
116 func putUint64(x []byte, s uint64) {
117         _ = x[7]
118         x[0] = byte(s >> 56)
119         x[1] = byte(s >> 48)
120         x[2] = byte(s >> 40)
121         x[3] = byte(s >> 32)
122         x[4] = byte(s >> 24)
123         x[5] = byte(s >> 16)
124         x[6] = byte(s >> 8)
125         x[7] = byte(s)
126 }
127
128 func appendUint64(b []byte, x uint64) []byte {
129         var a [8]byte
130         putUint64(a[:], x)
131         return append(b, a[:]...)
132 }
133
134 func appendUint32(b []byte, x uint32) []byte {
135         var a [4]byte
136         putUint32(a[:], x)
137         return append(b, a[:]...)
138 }
139
140 func consumeUint64(b []byte) ([]byte, uint64) {
141         _ = b[7]
142         x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
143                 uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
144         return b[8:], x
145 }
146
147 func consumeUint32(b []byte) ([]byte, uint32) {
148         _ = b[3]
149         x := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
150         return b[4:], x
151 }
152
153 func (d *digest) Reset() {
154         if !d.is224 {
155                 d.h[0] = init0
156                 d.h[1] = init1
157                 d.h[2] = init2
158                 d.h[3] = init3
159                 d.h[4] = init4
160                 d.h[5] = init5
161                 d.h[6] = init6
162                 d.h[7] = init7
163         } else {
164                 d.h[0] = init0_224
165                 d.h[1] = init1_224
166                 d.h[2] = init2_224
167                 d.h[3] = init3_224
168                 d.h[4] = init4_224
169                 d.h[5] = init5_224
170                 d.h[6] = init6_224
171                 d.h[7] = init7_224
172         }
173         d.nx = 0
174         d.len = 0
175 }
176
177 // New returns a new hash.Hash computing the SHA256 checksum. The Hash
178 // also implements encoding.BinaryMarshaler and
179 // encoding.BinaryUnmarshaler to marshal and unmarshal the internal
180 // state of the hash.
181 func New() hash.Hash {
182         if boring.Enabled {
183                 return boring.NewSHA256()
184         }
185         d := new(digest)
186         d.Reset()
187         return d
188 }
189
190 // New224 returns a new hash.Hash computing the SHA224 checksum.
191 func New224() hash.Hash {
192         if boring.Enabled {
193                 return boring.NewSHA224()
194         }
195         d := new(digest)
196         d.is224 = true
197         d.Reset()
198         return d
199 }
200
201 func (d *digest) Size() int {
202         if !d.is224 {
203                 return Size
204         }
205         return Size224
206 }
207
208 func (d *digest) BlockSize() int { return BlockSize }
209
210 func (d *digest) Write(p []byte) (nn int, err error) {
211         boring.Unreachable()
212         nn = len(p)
213         d.len += uint64(nn)
214         if d.nx > 0 {
215                 n := copy(d.x[d.nx:], p)
216                 d.nx += n
217                 if d.nx == chunk {
218                         block(d, d.x[:])
219                         d.nx = 0
220                 }
221                 p = p[n:]
222         }
223         if len(p) >= chunk {
224                 n := len(p) &^ (chunk - 1)
225                 block(d, p[:n])
226                 p = p[n:]
227         }
228         if len(p) > 0 {
229                 d.nx = copy(d.x[:], p)
230         }
231         return
232 }
233
234 func (d *digest) Sum(in []byte) []byte {
235         boring.Unreachable()
236         // Make a copy of d so that caller can keep writing and summing.
237         d0 := *d
238         hash := d0.checkSum()
239         if d0.is224 {
240                 return append(in, hash[:Size224]...)
241         }
242         return append(in, hash[:]...)
243 }
244
245 func (d *digest) checkSum() [Size]byte {
246         len := d.len
247         // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
248         var tmp [64]byte
249         tmp[0] = 0x80
250         if len%64 < 56 {
251                 d.Write(tmp[0 : 56-len%64])
252         } else {
253                 d.Write(tmp[0 : 64+56-len%64])
254         }
255
256         // Length in bits.
257         len <<= 3
258         putUint64(tmp[:], len)
259         d.Write(tmp[0:8])
260
261         if d.nx != 0 {
262                 panic("d.nx != 0")
263         }
264
265         var digest [Size]byte
266
267         putUint32(digest[0:], d.h[0])
268         putUint32(digest[4:], d.h[1])
269         putUint32(digest[8:], d.h[2])
270         putUint32(digest[12:], d.h[3])
271         putUint32(digest[16:], d.h[4])
272         putUint32(digest[20:], d.h[5])
273         putUint32(digest[24:], d.h[6])
274         if !d.is224 {
275                 putUint32(digest[28:], d.h[7])
276         }
277
278         return digest
279 }
280
281 // Sum256 returns the SHA256 checksum of the data.
282 func Sum256(data []byte) [Size]byte {
283         if boring.Enabled {
284                 h := New()
285                 h.Write(data)
286                 var ret [Size]byte
287                 h.Sum(ret[:0])
288                 return ret
289         }
290         var d digest
291         d.Reset()
292         d.Write(data)
293         return d.checkSum()
294 }
295
296 // Sum224 returns the SHA224 checksum of the data.
297 func Sum224(data []byte) (sum224 [Size224]byte) {
298         if boring.Enabled {
299                 h := New224()
300                 h.Write(data)
301                 var ret [Size224]byte
302                 h.Sum(ret[:0])
303                 return ret
304         }
305         var d digest
306         d.is224 = true
307         d.Reset()
308         d.Write(data)
309         sum := d.checkSum()
310         copy(sum224[:], sum[:Size224])
311         return
312 }