1// Copyright 2017 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
5package argon2
6
7import (
8	"encoding/binary"
9	"hash"
10
11	"golang.org/x/crypto/blake2b"
12)
13
14// blake2bHash computes an arbitrary long hash value of in
15// and writes the hash to out.
16func blake2bHash(out []byte, in []byte) {
17	var b2 hash.Hash
18	if n := len(out); n < blake2b.Size {
19		b2, _ = blake2b.New(n, nil)
20	} else {
21		b2, _ = blake2b.New512(nil)
22	}
23
24	var buffer [blake2b.Size]byte
25	binary.LittleEndian.PutUint32(buffer[:4], uint32(len(out)))
26	b2.Write(buffer[:4])
27	b2.Write(in)
28
29	if len(out) <= blake2b.Size {
30		b2.Sum(out[:0])
31		return
32	}
33
34	outLen := len(out)
35	b2.Sum(buffer[:0])
36	b2.Reset()
37	copy(out, buffer[:32])
38	out = out[32:]
39	for len(out) > blake2b.Size {
40		b2.Write(buffer[:])
41		b2.Sum(buffer[:0])
42		copy(out, buffer[:32])
43		out = out[32:]
44		b2.Reset()
45	}
46
47	if outLen%blake2b.Size > 0 { // outLen > 64
48		r := ((outLen + 31) / 32) - 2 // ⌈τ /32⌉-2
49		b2, _ = blake2b.New(outLen-32*r, nil)
50	}
51	b2.Write(buffer[:])
52	b2.Sum(out[:0])
53}
54