OSDN Git Service

14b8cfc7ecacf55a0e97dcb54649375dfb28c62b
[pf3gnuchains/gcc-fork.git] / libgo / go / 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-2.
7 package sha256
8
9 import (
10         "crypto"
11         "hash"
12 )
13
14 func init() {
15         crypto.RegisterHash(crypto.SHA224, New224)
16         crypto.RegisterHash(crypto.SHA256, New)
17 }
18
19 // The size of a SHA256 checksum in bytes.
20 const Size = 32
21
22 // The size of a SHA224 checksum in bytes.
23 const Size224 = 28
24
25 const (
26         _Chunk     = 64
27         _Init0     = 0x6A09E667
28         _Init1     = 0xBB67AE85
29         _Init2     = 0x3C6EF372
30         _Init3     = 0xA54FF53A
31         _Init4     = 0x510E527F
32         _Init5     = 0x9B05688C
33         _Init6     = 0x1F83D9AB
34         _Init7     = 0x5BE0CD19
35         _Init0_224 = 0xC1059ED8
36         _Init1_224 = 0x367CD507
37         _Init2_224 = 0x3070DD17
38         _Init3_224 = 0xF70E5939
39         _Init4_224 = 0xFFC00B31
40         _Init5_224 = 0x68581511
41         _Init6_224 = 0x64F98FA7
42         _Init7_224 = 0xBEFA4FA4
43 )
44
45 // digest represents the partial evaluation of a checksum.
46 type digest struct {
47         h     [8]uint32
48         x     [_Chunk]byte
49         nx    int
50         len   uint64
51         is224 bool // mark if this digest is SHA-224
52 }
53
54 func (d *digest) Reset() {
55         if !d.is224 {
56                 d.h[0] = _Init0
57                 d.h[1] = _Init1
58                 d.h[2] = _Init2
59                 d.h[3] = _Init3
60                 d.h[4] = _Init4
61                 d.h[5] = _Init5
62                 d.h[6] = _Init6
63                 d.h[7] = _Init7
64         } else {
65                 d.h[0] = _Init0_224
66                 d.h[1] = _Init1_224
67                 d.h[2] = _Init2_224
68                 d.h[3] = _Init3_224
69                 d.h[4] = _Init4_224
70                 d.h[5] = _Init5_224
71                 d.h[6] = _Init6_224
72                 d.h[7] = _Init7_224
73         }
74         d.nx = 0
75         d.len = 0
76 }
77
78 // New returns a new hash.Hash computing the SHA256 checksum.
79 func New() hash.Hash {
80         d := new(digest)
81         d.Reset()
82         return d
83 }
84
85 // New224 returns a new hash.Hash computing the SHA224 checksum.
86 func New224() hash.Hash {
87         d := new(digest)
88         d.is224 = true
89         d.Reset()
90         return d
91 }
92
93 func (d *digest) Size() int {
94         if !d.is224 {
95                 return Size
96         }
97         return Size224
98 }
99
100 func (d *digest) Write(p []byte) (nn int, err error) {
101         nn = len(p)
102         d.len += uint64(nn)
103         if d.nx > 0 {
104                 n := len(p)
105                 if n > _Chunk-d.nx {
106                         n = _Chunk - d.nx
107                 }
108                 for i := 0; i < n; i++ {
109                         d.x[d.nx+i] = p[i]
110                 }
111                 d.nx += n
112                 if d.nx == _Chunk {
113                         _Block(d, d.x[0:])
114                         d.nx = 0
115                 }
116                 p = p[n:]
117         }
118         n := _Block(d, p)
119         p = p[n:]
120         if len(p) > 0 {
121                 d.nx = copy(d.x[:], p)
122         }
123         return
124 }
125
126 func (d0 *digest) Sum() []byte {
127         // Make a copy of d0 so that caller can keep writing and summing.
128         d := new(digest)
129         *d = *d0
130
131         // Padding.  Add a 1 bit and 0 bits until 56 bytes mod 64.
132         len := d.len
133         var tmp [64]byte
134         tmp[0] = 0x80
135         if len%64 < 56 {
136                 d.Write(tmp[0 : 56-len%64])
137         } else {
138                 d.Write(tmp[0 : 64+56-len%64])
139         }
140
141         // Length in bits.
142         len <<= 3
143         for i := uint(0); i < 8; i++ {
144                 tmp[i] = byte(len >> (56 - 8*i))
145         }
146         d.Write(tmp[0:8])
147
148         if d.nx != 0 {
149                 panic("d.nx != 0")
150         }
151
152         p := make([]byte, 32)
153         j := 0
154         for _, s := range d.h {
155                 p[j+0] = byte(s >> 24)
156                 p[j+1] = byte(s >> 16)
157                 p[j+2] = byte(s >> 8)
158                 p[j+3] = byte(s >> 0)
159                 j += 4
160         }
161         if d.is224 {
162                 return p[0:28]
163         }
164         return p
165 }