diff options
Diffstat (limited to 'vendor/golang.org/x/crypto/blake2b/blake2b.go')
-rw-r--r-- | vendor/golang.org/x/crypto/blake2b/blake2b.go | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/vendor/golang.org/x/crypto/blake2b/blake2b.go b/vendor/golang.org/x/crypto/blake2b/blake2b.go new file mode 100644 index 0000000..d2e98d4 --- /dev/null +++ b/vendor/golang.org/x/crypto/blake2b/blake2b.go | |||
@@ -0,0 +1,291 @@ | |||
1 | // Copyright 2016 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 blake2b implements the BLAKE2b hash algorithm defined by RFC 7693 | ||
6 | // and the extendable output function (XOF) BLAKE2Xb. | ||
7 | // | ||
8 | // BLAKE2b is optimized for 64-bit platforms—including NEON-enabled ARMs—and | ||
9 | // produces digests of any size between 1 and 64 bytes. | ||
10 | // For a detailed specification of BLAKE2b see https://blake2.net/blake2.pdf | ||
11 | // and for BLAKE2Xb see https://blake2.net/blake2x.pdf | ||
12 | // | ||
13 | // If you aren't sure which function you need, use BLAKE2b (Sum512 or New512). | ||
14 | // If you need a secret-key MAC (message authentication code), use the New512 | ||
15 | // function with a non-nil key. | ||
16 | // | ||
17 | // BLAKE2X is a construction to compute hash values larger than 64 bytes. It | ||
18 | // can produce hash values between 0 and 4 GiB. | ||
19 | package blake2b | ||
20 | |||
21 | import ( | ||
22 | "encoding/binary" | ||
23 | "errors" | ||
24 | "hash" | ||
25 | ) | ||
26 | |||
27 | const ( | ||
28 | // The blocksize of BLAKE2b in bytes. | ||
29 | BlockSize = 128 | ||
30 | // The hash size of BLAKE2b-512 in bytes. | ||
31 | Size = 64 | ||
32 | // The hash size of BLAKE2b-384 in bytes. | ||
33 | Size384 = 48 | ||
34 | // The hash size of BLAKE2b-256 in bytes. | ||
35 | Size256 = 32 | ||
36 | ) | ||
37 | |||
38 | var ( | ||
39 | useAVX2 bool | ||
40 | useAVX bool | ||
41 | useSSE4 bool | ||
42 | ) | ||
43 | |||
44 | var ( | ||
45 | errKeySize = errors.New("blake2b: invalid key size") | ||
46 | errHashSize = errors.New("blake2b: invalid hash size") | ||
47 | ) | ||
48 | |||
49 | var iv = [8]uint64{ | ||
50 | 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, | ||
51 | 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179, | ||
52 | } | ||
53 | |||
54 | // Sum512 returns the BLAKE2b-512 checksum of the data. | ||
55 | func Sum512(data []byte) [Size]byte { | ||
56 | var sum [Size]byte | ||
57 | checkSum(&sum, Size, data) | ||
58 | return sum | ||
59 | } | ||
60 | |||
61 | // Sum384 returns the BLAKE2b-384 checksum of the data. | ||
62 | func Sum384(data []byte) [Size384]byte { | ||
63 | var sum [Size]byte | ||
64 | var sum384 [Size384]byte | ||
65 | checkSum(&sum, Size384, data) | ||
66 | copy(sum384[:], sum[:Size384]) | ||
67 | return sum384 | ||
68 | } | ||
69 | |||
70 | // Sum256 returns the BLAKE2b-256 checksum of the data. | ||
71 | func Sum256(data []byte) [Size256]byte { | ||
72 | var sum [Size]byte | ||
73 | var sum256 [Size256]byte | ||
74 | checkSum(&sum, Size256, data) | ||
75 | copy(sum256[:], sum[:Size256]) | ||
76 | return sum256 | ||
77 | } | ||
78 | |||
79 | // New512 returns a new hash.Hash computing the BLAKE2b-512 checksum. A non-nil | ||
80 | // key turns the hash into a MAC. The key must be between zero and 64 bytes long. | ||
81 | func New512(key []byte) (hash.Hash, error) { return newDigest(Size, key) } | ||
82 | |||
83 | // New384 returns a new hash.Hash computing the BLAKE2b-384 checksum. A non-nil | ||
84 | // key turns the hash into a MAC. The key must be between zero and 64 bytes long. | ||
85 | func New384(key []byte) (hash.Hash, error) { return newDigest(Size384, key) } | ||
86 | |||
87 | // New256 returns a new hash.Hash computing the BLAKE2b-256 checksum. A non-nil | ||
88 | // key turns the hash into a MAC. The key must be between zero and 64 bytes long. | ||
89 | func New256(key []byte) (hash.Hash, error) { return newDigest(Size256, key) } | ||
90 | |||
91 | // New returns a new hash.Hash computing the BLAKE2b checksum with a custom length. | ||
92 | // A non-nil key turns the hash into a MAC. The key must be between zero and 64 bytes long. | ||
93 | // The hash size can be a value between 1 and 64 but it is highly recommended to use | ||
94 | // values equal or greater than: | ||
95 | // - 32 if BLAKE2b is used as a hash function (The key is zero bytes long). | ||
96 | // - 16 if BLAKE2b is used as a MAC function (The key is at least 16 bytes long). | ||
97 | // When the key is nil, the returned hash.Hash implements BinaryMarshaler | ||
98 | // and BinaryUnmarshaler for state (de)serialization as documented by hash.Hash. | ||
99 | func New(size int, key []byte) (hash.Hash, error) { return newDigest(size, key) } | ||
100 | |||
101 | func newDigest(hashSize int, key []byte) (*digest, error) { | ||
102 | if hashSize < 1 || hashSize > Size { | ||
103 | return nil, errHashSize | ||
104 | } | ||
105 | if len(key) > Size { | ||
106 | return nil, errKeySize | ||
107 | } | ||
108 | d := &digest{ | ||
109 | size: hashSize, | ||
110 | keyLen: len(key), | ||
111 | } | ||
112 | copy(d.key[:], key) | ||
113 | d.Reset() | ||
114 | return d, nil | ||
115 | } | ||
116 | |||
117 | func checkSum(sum *[Size]byte, hashSize int, data []byte) { | ||
118 | h := iv | ||
119 | h[0] ^= uint64(hashSize) | (1 << 16) | (1 << 24) | ||
120 | var c [2]uint64 | ||
121 | |||
122 | if length := len(data); length > BlockSize { | ||
123 | n := length &^ (BlockSize - 1) | ||
124 | if length == n { | ||
125 | n -= BlockSize | ||
126 | } | ||
127 | hashBlocks(&h, &c, 0, data[:n]) | ||
128 | data = data[n:] | ||
129 | } | ||
130 | |||
131 | var block [BlockSize]byte | ||
132 | offset := copy(block[:], data) | ||
133 | remaining := uint64(BlockSize - offset) | ||
134 | if c[0] < remaining { | ||
135 | c[1]-- | ||
136 | } | ||
137 | c[0] -= remaining | ||
138 | |||
139 | hashBlocks(&h, &c, 0xFFFFFFFFFFFFFFFF, block[:]) | ||
140 | |||
141 | for i, v := range h[:(hashSize+7)/8] { | ||
142 | binary.LittleEndian.PutUint64(sum[8*i:], v) | ||
143 | } | ||
144 | } | ||
145 | |||
146 | type digest struct { | ||
147 | h [8]uint64 | ||
148 | c [2]uint64 | ||
149 | size int | ||
150 | block [BlockSize]byte | ||
151 | offset int | ||
152 | |||
153 | key [BlockSize]byte | ||
154 | keyLen int | ||
155 | } | ||
156 | |||
157 | const ( | ||
158 | magic = "b2b" | ||
159 | marshaledSize = len(magic) + 8*8 + 2*8 + 1 + BlockSize + 1 | ||
160 | ) | ||
161 | |||
162 | func (d *digest) MarshalBinary() ([]byte, error) { | ||
163 | if d.keyLen != 0 { | ||
164 | return nil, errors.New("crypto/blake2b: cannot marshal MACs") | ||
165 | } | ||
166 | b := make([]byte, 0, marshaledSize) | ||
167 | b = append(b, magic...) | ||
168 | for i := 0; i < 8; i++ { | ||
169 | b = appendUint64(b, d.h[i]) | ||
170 | } | ||
171 | b = appendUint64(b, d.c[0]) | ||
172 | b = appendUint64(b, d.c[1]) | ||
173 | // Maximum value for size is 64 | ||
174 | b = append(b, byte(d.size)) | ||
175 | b = append(b, d.block[:]...) | ||
176 | b = append(b, byte(d.offset)) | ||
177 | return b, nil | ||
178 | } | ||
179 | |||
180 | func (d *digest) UnmarshalBinary(b []byte) error { | ||
181 | if len(b) < len(magic) || string(b[:len(magic)]) != magic { | ||
182 | return errors.New("crypto/blake2b: invalid hash state identifier") | ||
183 | } | ||
184 | if len(b) != marshaledSize { | ||
185 | return errors.New("crypto/blake2b: invalid hash state size") | ||
186 | } | ||
187 | b = b[len(magic):] | ||
188 | for i := 0; i < 8; i++ { | ||
189 | b, d.h[i] = consumeUint64(b) | ||
190 | } | ||
191 | b, d.c[0] = consumeUint64(b) | ||
192 | b, d.c[1] = consumeUint64(b) | ||
193 | d.size = int(b[0]) | ||
194 | b = b[1:] | ||
195 | copy(d.block[:], b[:BlockSize]) | ||
196 | b = b[BlockSize:] | ||
197 | d.offset = int(b[0]) | ||
198 | return nil | ||
199 | } | ||
200 | |||
201 | func (d *digest) BlockSize() int { return BlockSize } | ||
202 | |||
203 | func (d *digest) Size() int { return d.size } | ||
204 | |||
205 | func (d *digest) Reset() { | ||
206 | d.h = iv | ||
207 | d.h[0] ^= uint64(d.size) | (uint64(d.keyLen) << 8) | (1 << 16) | (1 << 24) | ||
208 | d.offset, d.c[0], d.c[1] = 0, 0, 0 | ||
209 | if d.keyLen > 0 { | ||
210 | d.block = d.key | ||
211 | d.offset = BlockSize | ||
212 | } | ||
213 | } | ||
214 | |||
215 | func (d *digest) Write(p []byte) (n int, err error) { | ||
216 | n = len(p) | ||
217 | |||
218 | if d.offset > 0 { | ||
219 | remaining := BlockSize - d.offset | ||
220 | if n <= remaining { | ||
221 | d.offset += copy(d.block[d.offset:], p) | ||
222 | return | ||
223 | } | ||
224 | copy(d.block[d.offset:], p[:remaining]) | ||
225 | hashBlocks(&d.h, &d.c, 0, d.block[:]) | ||
226 | d.offset = 0 | ||
227 | p = p[remaining:] | ||
228 | } | ||
229 | |||
230 | if length := len(p); length > BlockSize { | ||
231 | nn := length &^ (BlockSize - 1) | ||
232 | if length == nn { | ||
233 | nn -= BlockSize | ||
234 | } | ||
235 | hashBlocks(&d.h, &d.c, 0, p[:nn]) | ||
236 | p = p[nn:] | ||
237 | } | ||
238 | |||
239 | if len(p) > 0 { | ||
240 | d.offset += copy(d.block[:], p) | ||
241 | } | ||
242 | |||
243 | return | ||
244 | } | ||
245 | |||
246 | func (d *digest) Sum(sum []byte) []byte { | ||
247 | var hash [Size]byte | ||
248 | d.finalize(&hash) | ||
249 | return append(sum, hash[:d.size]...) | ||
250 | } | ||
251 | |||
252 | func (d *digest) finalize(hash *[Size]byte) { | ||
253 | var block [BlockSize]byte | ||
254 | copy(block[:], d.block[:d.offset]) | ||
255 | remaining := uint64(BlockSize - d.offset) | ||
256 | |||
257 | c := d.c | ||
258 | if c[0] < remaining { | ||
259 | c[1]-- | ||
260 | } | ||
261 | c[0] -= remaining | ||
262 | |||
263 | h := d.h | ||
264 | hashBlocks(&h, &c, 0xFFFFFFFFFFFFFFFF, block[:]) | ||
265 | |||
266 | for i, v := range h { | ||
267 | binary.LittleEndian.PutUint64(hash[8*i:], v) | ||
268 | } | ||
269 | } | ||
270 | |||
271 | func appendUint64(b []byte, x uint64) []byte { | ||
272 | var a [8]byte | ||
273 | binary.BigEndian.PutUint64(a[:], x) | ||
274 | return append(b, a[:]...) | ||
275 | } | ||
276 | |||
277 | func appendUint32(b []byte, x uint32) []byte { | ||
278 | var a [4]byte | ||
279 | binary.BigEndian.PutUint32(a[:], x) | ||
280 | return append(b, a[:]...) | ||
281 | } | ||
282 | |||
283 | func consumeUint64(b []byte) ([]byte, uint64) { | ||
284 | x := binary.BigEndian.Uint64(b) | ||
285 | return b[8:], x | ||
286 | } | ||
287 | |||
288 | func consumeUint32(b []byte) ([]byte, uint32) { | ||
289 | x := binary.BigEndian.Uint32(b) | ||
290 | return b[4:], x | ||
291 | } | ||