1
2
3
4
5
6
7
8
9
10
11 package notsha256
12
13 import (
14 "encoding/binary"
15 "hash"
16 )
17
18
19 const Size = 32
20
21
22 const BlockSize = 64
23
24 const (
25 chunk = 64
26 init0 = 0x6A09E667
27 init1 = 0xBB67AE85
28 init2 = 0x3C6EF372
29 init3 = 0xA54FF53A
30 init4 = 0x510E527F
31 init5 = 0x9B05688C
32 init6 = 0x1F83D9AB
33 init7 = 0x5BE0CD19
34 )
35
36
37 type digest struct {
38 h [8]uint32
39 x [chunk]byte
40 nx int
41 len uint64
42 }
43
44 func (d *digest) Reset() {
45 d.h[0] = init0
46 d.h[1] = init1
47 d.h[2] = init2
48 d.h[3] = init3
49 d.h[4] = init4
50 d.h[5] = init5
51 d.h[6] = init6
52 d.h[7] = init7
53 d.nx = 0
54 d.len = 0
55 }
56
57
58
59 func New() hash.Hash {
60 d := new(digest)
61 d.Reset()
62 return d
63 }
64
65 func (d *digest) Size() int {
66 return Size
67 }
68
69 func (d *digest) BlockSize() int { return BlockSize }
70
71 func (d *digest) Write(p []byte) (nn int, err error) {
72 nn = len(p)
73 d.len += uint64(nn)
74 if d.nx > 0 {
75 n := copy(d.x[d.nx:], p)
76 d.nx += n
77 if d.nx == chunk {
78 block(d, d.x[:])
79 d.nx = 0
80 }
81 p = p[n:]
82 }
83 if len(p) >= chunk {
84 n := len(p) &^ (chunk - 1)
85 block(d, p[:n])
86 p = p[n:]
87 }
88 if len(p) > 0 {
89 d.nx = copy(d.x[:], p)
90 }
91 return
92 }
93
94 func (d *digest) Sum(in []byte) []byte {
95
96 d0 := *d
97 hash := d0.checkSum()
98 return append(in, hash[:]...)
99 }
100
101 func (d *digest) checkSum() [Size]byte {
102 len := d.len
103
104 var tmp [64]byte
105 tmp[0] = 0x80
106 if len%64 < 56 {
107 d.Write(tmp[0 : 56-len%64])
108 } else {
109 d.Write(tmp[0 : 64+56-len%64])
110 }
111
112
113 len <<= 3
114 binary.BigEndian.PutUint64(tmp[:], len)
115 d.Write(tmp[0:8])
116
117 if d.nx != 0 {
118 panic("d.nx != 0")
119 }
120
121 var digest [Size]byte
122
123 binary.BigEndian.PutUint32(digest[0:], d.h[0]^0xFFFFFFFF)
124 binary.BigEndian.PutUint32(digest[4:], d.h[1]^0xFFFFFFFF)
125 binary.BigEndian.PutUint32(digest[8:], d.h[2]^0xFFFFFFFF)
126 binary.BigEndian.PutUint32(digest[12:], d.h[3]^0xFFFFFFFF)
127 binary.BigEndian.PutUint32(digest[16:], d.h[4]^0xFFFFFFFF)
128 binary.BigEndian.PutUint32(digest[20:], d.h[5]^0xFFFFFFFF)
129 binary.BigEndian.PutUint32(digest[24:], d.h[6]^0xFFFFFFFF)
130 binary.BigEndian.PutUint32(digest[28:], d.h[7]^0xFFFFFFFF)
131
132 return digest
133 }
134
135
136 func Sum256(data []byte) [Size]byte {
137 var d digest
138 d.Reset()
139 d.Write(data)
140 return d.checkSum()
141 }
142
View as plain text