1
2
3
4
5
6 package sha1
7
8 import (
9 "crypto"
10 "hash"
11 "os"
12 )
13
14 func init() {
15 crypto.RegisterHash(crypto.SHA1, New)
16 }
17
18
19 const Size = 20
20
21 const (
22 _Chunk = 64
23 _Init0 = 0x67452301
24 _Init1 = 0xEFCDAB89
25 _Init2 = 0x98BADCFE
26 _Init3 = 0x10325476
27 _Init4 = 0xC3D2E1F0
28 )
29
30
31 type digest struct {
32 h [5]uint32
33 x [_Chunk]byte
34 nx int
35 len uint64
36 }
37
38 func (d *digest) Reset() {
39 d.h[0] = _Init0
40 d.h[1] = _Init1
41 d.h[2] = _Init2
42 d.h[3] = _Init3
43 d.h[4] = _Init4
44 d.nx = 0
45 d.len = 0
46 }
47
48
49 func New() hash.Hash {
50 d := new(digest)
51 d.Reset()
52 return d
53 }
54
55 func (d *digest) Size() int { return Size }
56
57 func (d *digest) Write(p []byte) (nn int, err os.Error) {
58 nn = len(p)
59 d.len += uint64(nn)
60 if d.nx > 0 {
61 n := len(p)
62 if n > _Chunk-d.nx {
63 n = _Chunk - d.nx
64 }
65 for i := 0; i < n; i++ {
66 d.x[d.nx+i] = p[i]
67 }
68 d.nx += n
69 if d.nx == _Chunk {
70 _Block(d, d.x[0:])
71 d.nx = 0
72 }
73 p = p[n:]
74 }
75 n := _Block(d, p)
76 p = p[n:]
77 if len(p) > 0 {
78 d.nx = copy(d.x[:], p)
79 }
80 return
81 }
82
83 func (d0 *digest) Sum() []byte {
84
85 d := new(digest)
86 *d = *d0
87
88
89 len := d.len
90 var tmp [64]byte
91 tmp[0] = 0x80
92 if len%64 < 56 {
93 d.Write(tmp[0 : 56-len%64])
94 } else {
95 d.Write(tmp[0 : 64+56-len%64])
96 }
97
98
99 len <<= 3
100 for i := uint(0); i < 8; i++ {
101 tmp[i] = byte(len >> (56 - 8*i))
102 }
103 d.Write(tmp[0:8])
104
105 if d.nx != 0 {
106 panic("d.nx != 0")
107 }
108
109 p := make([]byte, 20)
110 j := 0
111 for _, s := range d.h {
112 p[j+0] = byte(s >> 24)
113 p[j+1] = byte(s >> 16)
114 p[j+2] = byte(s >> 8)
115 p[j+3] = byte(s >> 0)
116 j += 4
117 }
118 return p
119 }