]> Cypherpunks.ru repositories - gostls13.git/blob - src/crypto/sha256/sha256.go
[dev.cryptoboring] misc/boring: update README for Bazel
[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 appendUint64(b []byte, x uint64) []byte {
109         a := [8]byte{
110                 byte(x >> 56),
111                 byte(x >> 48),
112                 byte(x >> 40),
113                 byte(x >> 32),
114                 byte(x >> 24),
115                 byte(x >> 16),
116                 byte(x >> 8),
117                 byte(x),
118         }
119         return append(b, a[:]...)
120 }
121
122 func appendUint32(b []byte, x uint32) []byte {
123         a := [4]byte{
124                 byte(x >> 24),
125                 byte(x >> 16),
126                 byte(x >> 8),
127                 byte(x),
128         }
129         return append(b, a[:]...)
130 }
131
132 func consumeUint64(b []byte) ([]byte, uint64) {
133         _ = b[7]
134         x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
135                 uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
136         return b[8:], x
137 }
138
139 func consumeUint32(b []byte) ([]byte, uint32) {
140         _ = b[3]
141         x := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
142         return b[4:], x
143 }
144
145 func (d *digest) Reset() {
146         if !d.is224 {
147                 d.h[0] = init0
148                 d.h[1] = init1
149                 d.h[2] = init2
150                 d.h[3] = init3
151                 d.h[4] = init4
152                 d.h[5] = init5
153                 d.h[6] = init6
154                 d.h[7] = init7
155         } else {
156                 d.h[0] = init0_224
157                 d.h[1] = init1_224
158                 d.h[2] = init2_224
159                 d.h[3] = init3_224
160                 d.h[4] = init4_224
161                 d.h[5] = init5_224
162                 d.h[6] = init6_224
163                 d.h[7] = init7_224
164         }
165         d.nx = 0
166         d.len = 0
167 }
168
169 // New returns a new hash.Hash computing the SHA256 checksum. The Hash
170 // also implements encoding.BinaryMarshaler and
171 // encoding.BinaryUnmarshaler to marshal and unmarshal the internal
172 // state of the hash.
173 func New() hash.Hash {
174         if boring.Enabled {
175                 return boring.NewSHA256()
176         }
177         d := new(digest)
178         d.Reset()
179         return d
180 }
181
182 // New224 returns a new hash.Hash computing the SHA224 checksum.
183 func New224() hash.Hash {
184         if boring.Enabled {
185                 return boring.NewSHA224()
186         }
187         d := new(digest)
188         d.is224 = true
189         d.Reset()
190         return d
191 }
192
193 func (d *digest) Size() int {
194         if !d.is224 {
195                 return Size
196         }
197         return Size224
198 }
199
200 func (d *digest) BlockSize() int { return BlockSize }
201
202 func (d *digest) Write(p []byte) (nn int, err error) {
203         boring.Unreachable()
204         nn = len(p)
205         d.len += uint64(nn)
206         if d.nx > 0 {
207                 n := copy(d.x[d.nx:], p)
208                 d.nx += n
209                 if d.nx == chunk {
210                         block(d, d.x[:])
211                         d.nx = 0
212                 }
213                 p = p[n:]
214         }
215         if len(p) >= chunk {
216                 n := len(p) &^ (chunk - 1)
217                 block(d, p[:n])
218                 p = p[n:]
219         }
220         if len(p) > 0 {
221                 d.nx = copy(d.x[:], p)
222         }
223         return
224 }
225
226 func (d0 *digest) Sum(in []byte) []byte {
227         boring.Unreachable()
228         // Make a copy of d0 so that caller can keep writing and summing.
229         d := *d0
230         hash := d.checkSum()
231         if d.is224 {
232                 return append(in, hash[:Size224]...)
233         }
234         return append(in, hash[:]...)
235 }
236
237 func (d *digest) checkSum() [Size]byte {
238         len := d.len
239         // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
240         var tmp [64]byte
241         tmp[0] = 0x80
242         if len%64 < 56 {
243                 d.Write(tmp[0 : 56-len%64])
244         } else {
245                 d.Write(tmp[0 : 64+56-len%64])
246         }
247
248         // Length in bits.
249         len <<= 3
250         for i := uint(0); i < 8; i++ {
251                 tmp[i] = byte(len >> (56 - 8*i))
252         }
253         d.Write(tmp[0:8])
254
255         if d.nx != 0 {
256                 panic("d.nx != 0")
257         }
258
259         h := d.h[:]
260         if d.is224 {
261                 h = d.h[:7]
262         }
263
264         var digest [Size]byte
265         for i, s := range h {
266                 digest[i*4] = byte(s >> 24)
267                 digest[i*4+1] = byte(s >> 16)
268                 digest[i*4+2] = byte(s >> 8)
269                 digest[i*4+3] = byte(s)
270         }
271
272         return digest
273 }
274
275 // Sum256 returns the SHA256 checksum of the data.
276 func Sum256(data []byte) [Size]byte {
277         if boring.Enabled {
278                 h := New()
279                 h.Write(data)
280                 var ret [Size]byte
281                 h.Sum(ret[:0])
282                 return ret
283         }
284         var d digest
285         d.Reset()
286         d.Write(data)
287         return d.checkSum()
288 }
289
290 // Sum224 returns the SHA224 checksum of the data.
291 func Sum224(data []byte) (sum224 [Size224]byte) {
292         if boring.Enabled {
293                 h := New224()
294                 h.Write(data)
295                 var ret [Size224]byte
296                 h.Sum(ret[:0])
297                 return ret
298         }
299         var d digest
300         d.is224 = true
301         d.Reset()
302         d.Write(data)
303         sum := d.checkSum()
304         copy(sum224[:], sum[:Size224])
305         return
306 }