]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgo/go/crypto/sha1/sha1.go
Add Go frontend, libgo library, and Go testsuite.
[thirdparty/gcc.git] / libgo / go / crypto / sha1 / sha1.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 // This package implements the SHA1 hash algorithm as defined in RFC 3174.
6 package sha1
7
8 import (
9 "hash"
10 "os"
11 )
12
13 // The size of a SHA1 checksum in bytes.
14 const Size = 20
15
16 const (
17 _Chunk = 64
18 _Init0 = 0x67452301
19 _Init1 = 0xEFCDAB89
20 _Init2 = 0x98BADCFE
21 _Init3 = 0x10325476
22 _Init4 = 0xC3D2E1F0
23 )
24
25 // digest represents the partial evaluation of a checksum.
26 type digest struct {
27 h [5]uint32
28 x [_Chunk]byte
29 nx int
30 len uint64
31 }
32
33 func (d *digest) Reset() {
34 d.h[0] = _Init0
35 d.h[1] = _Init1
36 d.h[2] = _Init2
37 d.h[3] = _Init3
38 d.h[4] = _Init4
39 d.nx = 0
40 d.len = 0
41 }
42
43 // New returns a new hash.Hash computing the SHA1 checksum.
44 func New() hash.Hash {
45 d := new(digest)
46 d.Reset()
47 return d
48 }
49
50 func (d *digest) Size() int { return Size }
51
52 func (d *digest) Write(p []byte) (nn int, err os.Error) {
53 nn = len(p)
54 d.len += uint64(nn)
55 if d.nx > 0 {
56 n := len(p)
57 if n > _Chunk-d.nx {
58 n = _Chunk - d.nx
59 }
60 for i := 0; i < n; i++ {
61 d.x[d.nx+i] = p[i]
62 }
63 d.nx += n
64 if d.nx == _Chunk {
65 _Block(d, d.x[0:])
66 d.nx = 0
67 }
68 p = p[n:]
69 }
70 n := _Block(d, p)
71 p = p[n:]
72 if len(p) > 0 {
73 d.nx = copy(d.x[:], p)
74 }
75 return
76 }
77
78 func (d0 *digest) Sum() []byte {
79 // Make a copy of d0 so that caller can keep writing and summing.
80 d := new(digest)
81 *d = *d0
82
83 // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
84 len := d.len
85 var tmp [64]byte
86 tmp[0] = 0x80
87 if len%64 < 56 {
88 d.Write(tmp[0 : 56-len%64])
89 } else {
90 d.Write(tmp[0 : 64+56-len%64])
91 }
92
93 // Length in bits.
94 len <<= 3
95 for i := uint(0); i < 8; i++ {
96 tmp[i] = byte(len >> (56 - 8*i))
97 }
98 d.Write(tmp[0:8])
99
100 if d.nx != 0 {
101 panic("d.nx != 0")
102 }
103
104 p := make([]byte, 20)
105 j := 0
106 for _, s := range d.h {
107 p[j+0] = byte(s >> 24)
108 p[j+1] = byte(s >> 16)
109 p[j+2] = byte(s >> 8)
110 p[j+3] = byte(s >> 0)
111 j += 4
112 }
113 return p
114 }